Programming Reference:BCI2000Remote Class: Difference between revisions

From BCI2000 Wiki
Jump to navigation Jump to search
Line 104: Line 104:
  BCI2000/src/core/Operator/BCI2000Remote/BCI2000Connection.cpp
  BCI2000/src/core/Operator/BCI2000Remote/BCI2000Connection.cpp
  BCI2000/src/shared/utils/SockStream.cpp
  BCI2000/src/shared/utils/SockStream.cpp
Also, on Windows you will need to link against these additional libraries:
Also, on Windows you will need to link against this additional library:
  WS2_32 SHLWAPI
  WS2_32


==Example==
==Example==

Revision as of 17:27, 4 June 2012

Synopsis

BCI2000Remote is a proxy interface class to the BCI2000 Operator module, and allows to start up, configure, and control BCI2000 from other applications. Internally, it maintains a telnet connection to the Operator module, and sends Operator Scripting commands to control it. However, no knowledge of these scripting commands is required in order to use the BCI2000Remote class from your own application.

BCI2000Remote is most useful when writing C++ applications. For controlling BCI2000 under Windows from MATLAB, Windows Automation compatible scripting languages, or .NET languages, there exists a separate automation interface. For controlling BCI2000 from shell scripts (such as the Windows command interpreter, or Unix shells like bash), there exists a BCI2000 command executable.

Location

BCI2000/src/core/Operator/BCI2000Remote

Functional Description

After instantiating a BCI2000Remote object, set its OperatorPath property to point to the desired BCI2000 Operator module. Then, call its Connect() method to start up that module, and connect to it.. You may then use the StartupModules() method in order to start up BCI2000 core modules.

Alternatively, you may specify the path to a BCI2000 batch file in the BCI2000/batch directory. An appropriate batch file should start up Operator and core modules, and needs to forward its command line arguments to the Operator module. All batch files coming with BCI2000 fulfil this condition. When a batch file is specified, there is no need to call the StartupModules() method.

As yet another option, you may connect to an Operator module that is already running, e.g., on a remote machine on the network. In this case, set the BCI2000Remote object's OperatorPath property to an empty string, and its TelnetAddress property to the address that the remote Operator module is listening on, i.e. the remote machine's IP address, followed with a colon, and the port specified when starting up the remote Operator module. The remote Operator module must have been started with the "--Telnet" command line option, followed with the address to listen on. On the remote machine, this would typically be "localhost:3999". Don't use any of the ports between 4000 and 4002, as this will interfere with the communication between the Operator module, and BCI2000 core modules. Depending on whether the remote Operator module has been started up together with its core modules, or not, you may then call the StartupModules() method in order to start up BCI2000 core modules on the remote machine.

Once all BCI2000 modules are running, you may load parameter files locally or remotely using the LoadParametersLocal() and LoadParametersRemote() methods. Subject ID, Session ID, and data directory are set using the respective BCI2000Remote properties.

A recording may then be started by calling the Start() method. Depending on configuration, the recording will terminate automatically, or needs to be terminated by a call to the Stop() method.

To run BCI2000 in a different configuration (i.e., with different core modules), it is not necessary to terminate the Operator module. Rather, you may execute StartupModules() multiple times in order to terminate currently running core modules, and start different ones.

Once you are done using BCI2000, you may close the connection by calling the Disconnect() method, or by deleting the BCI2000Remote object. Depending on whether the Operator module was started up by the previous Connect() call, this will terminate the Operator module as well. When connection was made to an already running Operator module, local or remote, the connection will be closed but the Operator module will remain running.

BCI2000Remote Members

The BCI2000Remote class has the following members:

Properties

double Timeout=5 (rw)

Timeout in seconds. Applies to all actions and communication between BCI2000Remote and BCI2000.

string OperatorPath="" (rw)

Path to Operator module, or batch file. When empty, BCI2000Remote tries to connect to an already running Operator module which may be on a different machine.

string TelnetAddress="localhost:3999" (rw)

Telnet address to use for connection. Defaults to localhost:3999. When an operator path is specified, this must be a local address which will be used for communication. To connect to a remote machine, specify the machine's IP address, followed with BCI2000's listening port. You should take care to avoid specifying a port that is used by BCI2000's internal connections between Operator and core modules. By default, these are 4000, 4001, and 4002.

bool WindowVisible=true (rw)

Visibility of the BCI2000 main window.

string WindowTitle (rw)

The title of the BCI2000 main window.

string Result (r)

Text output of the previously executed command, or an error message when the previously executed command failed.

Recording information

string SubjectID (rw)

The subject ID for the next recording. When this property is empty, the subject ID is taken from the current value of the SubjectName parameter.

string SessionID (rw)

The session ID for the next recording. When this property is empty, the session ID is taken from the SubjectSession parameter.

string DataDirectory (rw)

The data directory for the next recording. When a relative path is given, it is taken relative to BCI2000/data. When this property is empty, the data directory is taken from the DataDirectory parameter.

Connection methods

bool Connect()

Connect to BCI2000. When OperatorPath is not empty, this starts up the operator module before connecting. Will return true on success.

bool Connect( BCI2000Remote )

Connects to the same Operator module as the BCI2000Remote instance given as an argument. This will not start BCI2000 when it is not running, thus it is necessary that Connect() has been called on the argument.

bool Disconnect()

Disconnect from an existing connection. Terminates the running operator module if it was started by the previous Connect() call.

Control of operation

bool StartupModules( vector(string) modules )

Start BCI2000 core modules, listed by executable name, including possible command line arguments. Each entry in the array corresponds to a single core module, given relative to the Operator module's working directory, which defaults to BCI2000/prog. You do not need to call this function if the OperatorPath property specifies a batch file rather than the Operator module itself.

bool SetConfig()

Applies the current set of parameters. Will be called from Start() automatically. Returns false if parameters could not be set, e.g. because the system was in running state, or because there was a preflight error when applying parameters. Use the Result property to obtain more error information.

bool Start()

Starts a new run (recording) with current parameters. Returns false if the run could not be started. Use the Result property to obtain more error information.

bool Stop()

Stops the current run (recording).

Parameters and system state

bool GetParameter( string name, string& value )

Copies the specified parameter's value into the value output argument. Returns false if parameter does not exist.

bool SetParameter( string name, string value )

Sets the specified parameter to the given value. The parameter must exist in the system. To add a parameter, use the Execute() method in conjunction with the INSERT PARAMETER scripting command.

bool LoadParametersLocal( string file )

Load parameters from a file, relative to the working directory of the calling application. This function returns false if the specified file was not found but will not provide information whether parameters were sent successfully. Rather, illegal parameter lines will be silently ignored.

bool LoadParametersRemote( string file )

Load parameters from a file, relative to the working directory of the Operator module connected to. Unless explicitly changed, that working directory is the BCI2000/prog directory in which the Operator module resides.

bool AddStateVariable( string name, int bitWidth, double initialValue )

Adds a state variable to the system. This is only possible before core modules have connected to the Operator module.

bool GetStateVariable( string name, double& value )

Gets the value of a named BCI2000 state variable. If no error occurred, the value will be copied into the "value" output variable.

bool SetStateVariable( string name, double value )

Sets the value of the named BCI2000 state variable to the given value. Returns false on error.

bool GetSystemState( string& state )

Gets the current system state (i.e., state of operation). If no error occurred, the "state" output variable will contain the name of the current system state, which will be one of the names listed at User Reference:Operator Module Scripting#GET_SYSTEM_STATE.

bool GetControlSignal( int channel, int element, double& value )

Copies the value of the control signal at the given indices into the "value" output variable. Indices are 1-based. Typically, the control signal has only a single element, and the number of output channels corresponds to the number of feedback dimensions in feedback experiments, or is 1 in evoked potential experiments.

Scripting methods

int Execute( string command )

Execute a BCI2000 scripting command. If the command executed a shell command, returns the command's exit code, and 0 otherwise. This is different from other methods, whose boolean return value indicates success or failure. A documentation of BCI2000 Operator scripting commands may be found under User Reference:Operator Module Scripting.

bool SetScript( string handlers, string script )

Associate a sequence of BCI2000 scripting commands with the specified events. Events are given by name, as defined in the scripting reference. Multiple handler names may be specified, concatenated with a pipe '|' character.

bool GetScript( string handler, string& script )

Copy the handler script into the script output variable.

Dependencies

To facilitate the use of BCI2000Remote, it only depends on very few files from the BCI2000 framework. To use BCI2000Remote in a C++ project, you will need to add the following cpp files to the project, and their parent directories to the list of include paths:

BCI2000/src/core/Operator/BCI2000Remote/BCI2000Remote.cpp
BCI2000/src/core/Operator/BCI2000Remote/BCI2000Connection.cpp
BCI2000/src/shared/utils/SockStream.cpp

Also, on Windows you will need to link against this additional library:

WS2_32

Example

#include "BCI2000Remote.h"
#include <string>
#include <vector>
#include <iostream>

int main( int argc, char* argv[] )
{
  // Instantiate a BCI2000Remote object
  BCI2000Remote bci;
  // Assume that Operator executable resides in the same directory as this program.
  std::string path = ( argc > 0 ) ? argv[0] : "";
  size_t pos = path.find_last_of( "\\/" );
  path = ( pos != std::string::npos ) ? path.substr( 0, pos + 1 ) : "";
  // Start the Operator module, and connect
  bci.OperatorPath( path + "Operator" );
  if( !bci.Connect() )
  {
    std::cerr << bci.Result();
    return -1;
  }
  // Startup modules
  const char* modules[] = { "SignalGenerator --LogMouse=1", "ARSignalProcessing", "CursorTask" };
  std::vector<std::string> vModules( &modules[0], &modules[0] + sizeof( modules ) / sizeof( *modules ) );
  if( !bci.StartupModules( vModules ) )
  {
    std::cerr << bci.Result();
    return -1;
  }
  // Load a parameter file, and set subject information
  bci.LoadParametersRemote( "../parms/examples/CursorTask_SignalGenerator.prm" );
  bci.SubjectID( "SUB" );
  // Start a run
  if( !bci.Start() )
  {
    std::cerr << bci.Result();
    return -1;
  }
  // Print feedback signal
  std::string state;
  while( bci.GetSystemState( state ) && state == "Running" )
  {
    double value = 0;
    bci.GetControlSignal( 1, 1, value );
    std::cout << "Control signal: " << value << ", press Enter to proceed" << std::flush;
    std::string line;
    std::getline( std::cin, line );
  }
  return 0;
}

See also

Contributions:BCI2000Automation, Contributions:BCI2000PresentationLink, Contributions:BCI2000Command, Contributions:BCI2000PythonBindings, Contributions:Applications