Page 1 of 1

App Connector Example/Explanation

Posted: 10 Jan 2011, 22:40
by Yuliy
I am rather new to BCI2000. I am trying to send BCI signals to Borland C++. I'm looking at the App Connector example and I am wondering what it is supposed to do. When I run it, and the prompt module pops up it is a blank window even when I simultaneously execute a BCI module. Can anyone explain this code to me and how to implement it. My ultimate goal is to send out data from BCI to a created game which will be coded/designed in C++.

Code:
#include <iostream>
#include "SockStream.h"

using namespace std;

int main( int argc, char** argv )
{
const char* address = "localhost:5000";
if( argc > 1 )
address = argv[ 1 ];

receiving_udpsocket socket( address );
sockstream connection( socket );
string line;
// Print each line of BCI2000 input to stdout.
while( getline( connection, line ) )
cout << line << endl;

return 0;
}

Posted: 11 Jan 2011, 09:04
by mellinger
Yuliy,

the AppConnector Example opens a UDP socket (by default, at localhost:5000), and writes whatever is written to that socket to stdout (the "blank window" is a console window waiting for data to come in over the socket).
To use it, start BCI2000, set the "ConnectorOutput" parameter to "localhost:5000", click "Set Config", run the AppConnector Example, and click "Start". You should now see a list of state variables running down the example program's window.

In your game, you will need to open a UDP socket as in the example program, and then filter out the state variable or signal that encodes BCI control, which most likely is "Signal(0,1)".

For more details about the AppConnector, please see http://www.bci2000.org/wiki/index.php/T ... _Connector

Best regards,
Juergen

Posted: 13 Jan 2011, 21:16
by Yuliy
Thank you, we got the UDP to read. My next question is from where does the information come from. Is the information coming from the ConnectorInput or the ConnectorOutput. I am running the cursor task application. I would also like to know where the control signals are being sent in the actual CursorTask code.

Posted: 14 Jan 2011, 09:51
by mellinger
Yuliy,

BCI2000 consists of a chain of filters, in which each filter's output is the input of the next filter in the chain.
The ConnectorOutput filter is located after SignalProcessing, which computes control signals, and the CursorTask filter, which displays control signals in form of cursor movement on the screen, and forwards them unchanged to the ConnectorOutput filter. The ConnectorOutput filter sends state information, together with control signals, to the UDP port specified in the ConnectorOutputAddress parameter.

HTH,
Juergen

Posted: 14 Jan 2011, 20:53
by Yuliy
Thank you, we finally found what we needed to control in the actual code.

Now we have another issue we are facing. We were trying to do a simple test. We are hooking up a frequency generator to our ADC. We are using the M Series 6224 (http://sine.ni.com/nips/cds/view/p/lang/en/nid/14134) to do our converting of the signal. Our goal is to show that BCI takes in the signal correctly and that the signal is reconstructed back correctly in the Matlab .dat file that BCI produces.

We configured a module to take in our ADC correctly and the only problem we are facing now is that we tried passing through a 100Hz signal (into BCI), but the Matlab file (.dat) shows the signal is still not getting reconstructed correctly. We are using the cursor task and AR filter applications. In BCI, we have a sampling rate of 2048 Hz. It was set so high because it was the only sampling rate that showed the almost full reconstruction of the 100Hz signal in real-time.

The input voltage we are using is +-5V and the signal itself was around +-4.3V. When we use lower values with the frequency generator, there was no problem in acquiring the signal back exactly. Now is this error with the 100Hz signal mean that the parameters we are using are wrong or is it the ADC?

Posted: 17 Jan 2011, 09:01
by mellinger
Yuliy,

sorry, I do not understand your questions. What do you mean by "signal getting reconstructed correctly"? What kind of error are you referring to in your last question?

Juergen

Posted: 19 Jan 2011, 17:29
by Yuliy
All we are trying to do is prove BCI can take in a 100hz signal and reconstruct (the sinusoid) by showing the plot of the signal in Matlab. We are also to play that signal (in matlab) and make sure it sounds like 100hz.

The trouble is the signal doesn't get reconstructed exactly. It seems to not be a smooth sinusoid. Even though we have the sampling rate at a high number. We tried 512hz, 1024hz, 2048hz, and 8192hz.

Does this mean the ADC is not working properly, the setting aren't right to handle a 100hz signal, or is it the .dat file (that contains the signal) not being written to properly?

Posted: 19 Jan 2011, 21:13
by jawilson
Yuliy and Juergen,
If the ARfilter signal processing is being used, shouldn't the output from the app connector be the final signal processing result, i.e., the normalized X and Y (and Z?) control signals. Yuliy, you will not see a sinusoid at all, but rather the final output of the processing chain, like this:
raw signal -> spatial filter -> AR filter -> classifier -> normalizer -> app connector
The control signal that the application receives (such as the cursor control task) is the same that you get from the app connector.
Does this make sense?
Adam

signals

Posted: 20 Jan 2011, 07:47
by gschalk
Yuliy,

From what I understand, your first goal is simply to show that BCI2000 can record signals. To do this, you do not need online processing, or online access to any signals (e.g., through the AppConnector). All you need to do is to record some data, use Matlab to load the data, and interpret it.

From your explanation, it seems as if, when you do that, the signal is not exactly a sinusoid. Without knowing more, there may me many reasons for this. One reason is that your sine wave is very small, so that 1) you see noise from the function generator; or 2) you see discretization effects from the A/D converter (check the input range and bit/voltage resolution of the A/D converter).

Gerv

Re: App Connector Example/Explanation

Posted: 23 May 2012, 19:36
by gmicros
Hello


i have been working on a project that uses BCI data to control an external application-specifically a game. Your earlier posts have been helpful in establishing the UDP port. I have BCI200o outputing data to a specified port. Im not sure how to receive this data on the application end. In other words, how do i receive the data from the UDP port and control the external application with it?
Thank you

Re: App Connector Example/Explanation

Posted: 24 May 2012, 08:23
by mellinger
Hi,

in your external application, you need to open the respective UDP port for reading, and read data from it. How exactly you do this depends on the programming language and/or programming libraries you use to write your external application.

For examples in C++ and Matlab, please see
http://www.bci2000.org/tracproj/browser ... plications
(log in with your BCI2000 account).
For details about the data packets sent between BCI2000 and an external application, please see
http://www.bci2000.org/wiki/index.php/T ... _Connector

Regards,
Juergen

Re: App Connector Example/Explanation

Posted: 29 May 2012, 16:07
by gmicros
Hello,

the external application im using is a pinball game i found on the internet and i do not have access to the source code. How do i open and read from the post in this situation?

Re: App Connector Example/Explanation

Posted: 31 May 2012, 08:23
by mellinger
In this case, you will need to write a third application that connects to BCI2000 via UDP, and controls the pinball game by generating synthetic keypress events, which are then picked up by the pinball game when it is running in the foreground.

For an example how to create synthetic keypresses, see the KeystrokeFilter at src/shared/modules/application/human_interface_devices/KeystrokeFilter. That filter creates synthetic keypresses from BCI2000 states. Rather than developing a third application, you might also choose to adapt the KeystrokeFilter such that it directly creates the keypress events required for the pinball game to work.

Regards,
Juergen