This commit is contained in:
2021-10-14 13:47:35 +02:00
commit 6625a8dfaa
4026 changed files with 844291 additions and 0 deletions
@@ -0,0 +1,42 @@
PROJECT(openvibe-examples-openvibe-to-vrpn)
SET(PROJECT_VERSION_MAJOR ${OV_GLOBAL_VERSION_MAJOR})
SET(PROJECT_VERSION ${OV_GLOBAL_VERSION_STRING})
INCLUDE("FindThirdPartyVRPN_Check")
IF(NOT PATH_VRPN)
MESSAGE(STATUS " --> Not building ${PROJECT_NAME}")
RETURN()
ENDIF(NOT PATH_VRPN)
FILE(GLOB_RECURSE SRC_FILES src/*.cpp src/*.h src/*.hpp src/*.inl include/*.h)
INCLUDE_DIRECTORIES(include)
ADD_EXECUTABLE(${PROJECT_NAME} ${SRC_FILES})
SET_PROPERTY(TARGET ${PROJECT_NAME} PROPERTY FOLDER ${APP_FOLDER})
INCLUDE("FindThirdPartyVRPN")
INCLUDE("FindThirdPartyPThread") # needed on Linux for VRPN
# ---------------------------------
# ---------------------------------
# ----------------------
# Generate launch script
# ----------------------
OV_INSTALL_LAUNCH_SCRIPT(SCRIPT_PREFIX "${PROJECT_NAME}" EXECUTABLE_NAME "${PROJECT_NAME}")
# -----------------------------
# Install files
# -----------------------------
INSTALL(TARGETS ${PROJECT_NAME}
RUNTIME DESTINATION ${DIST_BINDIR}
LIBRARY DESTINATION ${DIST_LIBDIR}
ARCHIVE DESTINATION ${DIST_LIBDIR})
INSTALL(DIRECTORY box-tutorials/ DESTINATION ${DIST_DATADIR}/openvibe/scenarios/box-tutorials)
@@ -0,0 +1,456 @@
<OpenViBE-Scenario>
<FormatVersion>2</FormatVersion>
<Creator>OpenViBE Designer</Creator>
<CreatorVersion>2.1.0</CreatorVersion>
<Settings></Settings>
<Inputs></Inputs>
<Outputs></Outputs>
<Boxes>
<Box>
<Identifier>(0x00002376, 0x00000c86)</Identifier>
<Name>Analog VRPN Server</Name>
<AlgorithmClassIdentifier>(0x0ddc3a7e, 0x6f6e6401)</AlgorithmClassIdentifier>
<Inputs>
<Input>
<TypeIdentifier>(0x544a003e, 0x6dcba5f6)</TypeIdentifier>
<Name>Input 1</Name>
</Input>
</Inputs>
<Settings>
<Setting>
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
<Name>Peripheral name</Name>
<DefaultValue>openvibe-vrpn</DefaultValue>
<Value>openvibe_vrpn_analog</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>400</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>176</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x2f4c9e00, 0x5dc619e4)</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>1</Value>
</Attribute>
<Attribute>
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
<Value>1</Value>
</Attribute>
<Attribute>
<Identifier>(0xfba64161, 0x65304e21)</Identifier>
<Value></Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x000027ff, 0x00005a50)</Identifier>
<Name>Sinus oscillator</Name>
<AlgorithmClassIdentifier>(0x7e33bdb8, 0x68194a4a)</AlgorithmClassIdentifier>
<Outputs>
<Output>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Generated signal</Name>
</Output>
</Outputs>
<Settings>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>Channel count</Name>
<DefaultValue>4</DefaultValue>
<Value>1</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>Sampling frequency</Name>
<DefaultValue>512</DefaultValue>
<Value>1</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>Generated epoch sample count</Name>
<DefaultValue>32</DefaultValue>
<Value>1</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>144</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>224</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x0b214ed8, 0x1f9ad83a)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc80ce8af, 0xf699f813)</Identifier>
<Value>1</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>3</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x00002cc0, 0x00006f7a)</Identifier>
<Name>Keyboard stimulator</Name>
<AlgorithmClassIdentifier>(0x00d317b9, 0x6324c3ff)</AlgorithmClassIdentifier>
<Outputs>
<Output>
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
<Name>Outgoing Stimulations</Name>
</Output>
</Outputs>
<Settings>
<Setting>
<TypeIdentifier>(0x330306dd, 0x74a95f98)</TypeIdentifier>
<Name>Filename</Name>
<DefaultValue>${Path_Data}/plugins/stimulation/simple-keyboard-to-stimulations.txt</DefaultValue>
<Value>${Path_Data}/plugins/stimulation/simple-keyboard-to-stimulations.txt</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>144</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>448</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x9b5dd008, 0x475a2ecd)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc80ce8af, 0xf699f813)</Identifier>
<Value>1</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>1</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x00002d5e, 0x00007cd2)</Identifier>
<Name>Signal display</Name>
<AlgorithmClassIdentifier>(0x0055be5f, 0x087bdd12)</AlgorithmClassIdentifier>
<Inputs>
<Input>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Data</Name>
</Input>
<Input>
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
<Name>Stimulations</Name>
</Input>
<Input>
<TypeIdentifier>(0x6ab26b81, 0x0f8c02f3)</TypeIdentifier>
<Name>Channel Units</Name>
</Input>
</Inputs>
<Settings>
<Setting>
<TypeIdentifier>(0x5de046a6, 0x086340aa)</TypeIdentifier>
<Name>Display Mode</Name>
<DefaultValue>Scan</DefaultValue>
<Value>Scan</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x33a30739, 0x00d5299b)</TypeIdentifier>
<Name>Auto vertical scale</Name>
<DefaultValue>Per channel</DefaultValue>
<Value>Per channel</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Scale refresh interval (secs)</Name>
<DefaultValue>5</DefaultValue>
<Value>5</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Vertical Scale</Name>
<DefaultValue>100</DefaultValue>
<Value>100</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Vertical Offset</Name>
<DefaultValue>0</DefaultValue>
<Value>0</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Time Scale</Name>
<DefaultValue>10</DefaultValue>
<Value>10</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
<Name>Horizontal ruler</Name>
<DefaultValue>true</DefaultValue>
<Value>true</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
<Name>Vertical ruler</Name>
<DefaultValue>false</DefaultValue>
<Value>false</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
<Name>Multiview</Name>
<DefaultValue>false</DefaultValue>
<Value>false</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>256</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>320</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x92c056a7, 0x2dc71aff)</Value>
</Attribute>
<Attribute>
<Identifier>(0x527ad68d, 0x16d746a0)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier>
<Value>false</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>9</Value>
</Attribute>
<Attribute>
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
<Value>3</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x00007850, 0x00005bfd)</Identifier>
<Name>Button VRPN Server</Name>
<AlgorithmClassIdentifier>(0x0e382e6f, 0x5be1f00c)</AlgorithmClassIdentifier>
<Inputs>
<Input>
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
<Name>Input 1</Name>
</Input>
<Input>
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
<Name>Input 2</Name>
</Input>
</Inputs>
<Settings>
<Setting>
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
<Name>Peripheral name</Name>
<DefaultValue>openvibe-vrpn</DefaultValue>
<Value>openvibe_vrpn_button</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2c132d6e, 0x44ab0d97)</TypeIdentifier>
<Name>Button 1 ON</Name>
<DefaultValue>OVTK_GDF_Feedback_Continuous</DefaultValue>
<Value>OVTK_StimulationId_Label_01</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2c132d6e, 0x44ab0d97)</TypeIdentifier>
<Name>Button 1 OFF</Name>
<DefaultValue>OVTK_GDF_End_Of_Trial</DefaultValue>
<Value>OVTK_StimulationId_Label_00</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2c132d6e, 0x44ab0d97)</TypeIdentifier>
<Name>Button 2 ON</Name>
<DefaultValue>OVTK_GDF_Feedback_Continuous</DefaultValue>
<Value>OVTK_StimulationId_Label_02</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2c132d6e, 0x44ab0d97)</TypeIdentifier>
<Name>Button 2 OFF</Name>
<DefaultValue>OVTK_GDF_End_Of_Trial</DefaultValue>
<Value>OVTK_StimulationId_Label_00</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>400</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>480</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x1473765a, 0x12eb3520)</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>3</Value>
</Attribute>
<Attribute>
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
<Value>1</Value>
</Attribute>
<Attribute>
<Identifier>(0xfba64161, 0x65304e21)</Identifier>
<Value></Value>
</Attribute>
</Attributes>
</Box>
</Boxes>
<Links>
<Link>
<Identifier>(0x000031fc, 0x000020b2)</Identifier>
<Source>
<BoxIdentifier>(0x000027ff, 0x00005a50)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x00002d5e, 0x00007cd2)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
</Link>
<Link>
<Identifier>(0x000057e0, 0x0000296b)</Identifier>
<Source>
<BoxIdentifier>(0x00002cc0, 0x00006f7a)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x00007850, 0x00005bfd)</BoxIdentifier>
<BoxInputIndex>1</BoxInputIndex>
</Target>
</Link>
<Link>
<Identifier>(0x0000597d, 0x00006474)</Identifier>
<Source>
<BoxIdentifier>(0x00002cc0, 0x00006f7a)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x00002d5e, 0x00007cd2)</BoxIdentifier>
<BoxInputIndex>1</BoxInputIndex>
</Target>
</Link>
<Link>
<Identifier>(0x00005e72, 0x000010d3)</Identifier>
<Source>
<BoxIdentifier>(0x000027ff, 0x00005a50)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x00002376, 0x00000c86)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
</Link>
<Link>
<Identifier>(0x0000778f, 0x00004d50)</Identifier>
<Source>
<BoxIdentifier>(0x00002cc0, 0x00006f7a)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x00007850, 0x00005bfd)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
</Link>
</Links>
<Comments>
<Comment>
<Identifier>(0x00005985, 0x000006ab)</Identifier>
<Text>This scenario is described in
http://openvibe.inria.fr/vrpn-tutorial-sending-data-from-openvibe-to-an-external-application/
Its used together with &lt;b&gt;openvibe-examples-openvibe-to-vrpn&lt;/b&gt; application.</Text>
<Attributes>
<Attribute>
<Identifier>(0x473d9a43, 0x97fc0a97)</Identifier>
<Value>336</Value>
</Attribute>
<Attribute>
<Identifier>(0x7234b86b, 0x2b8651a5)</Identifier>
<Value>64</Value>
</Attribute>
</Attributes>
</Comment>
</Comments>
<Metadata>
<Entry>
<Identifier>(0x0000775c, 0x000078ff)</Identifier>
<Type>(0x3bcce5d2, 0x43f2d968)</Type>
<Data>[{"boxIdentifier":"(0x00002d5e, 0x00007cd2)","childCount":0,"identifier":"(0x00001268, 0x00000dc0)","parentIdentifier":"(0xffffffff, 0xffffffff)","type":3},{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":1,"height":320,"identifier":"(0x00003d74, 0x00007c81)","name":"Default window","parentIdentifier":"(0xffffffff, 0xffffffff)","type":1,"width":480},{"boxIdentifier":"(0x00002cc0, 0x00006f7a)","childCount":0,"identifier":"(0x000049f0, 0x00007d33)","parentIdentifier":"(0xffffffff, 0xffffffff)","type":3},{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":1,"identifier":"(0x0000561d, 0x00000276)","index":0,"name":"Default tab","parentIdentifier":"(0x00003d74, 0x00007c81)","type":2},{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":0,"identifier":"(0x0000198f, 0x000068c3)","index":0,"name":"Empty","parentIdentifier":"(0x0000561d, 0x00000276)","type":0}]</Data>
</Entry>
</Metadata>
<Attributes>
<Attribute>
<Identifier>(0x790d75b8, 0x3bb90c33)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0x8c1fc55b, 0x7b433dc2)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0x9f5c4075, 0x4a0d3666)</Identifier>
<Value>OpenViBE to VRPN tutorial</Value>
</Attribute>
<Attribute>
<Identifier>(0xf36a1567, 0xd13c53da)</Identifier>
<Value>http://openvibe.inria.fr/vrpn-tutorial-sending-data-from-openvibe-to-an-external-application/</Value>
</Attribute>
<Attribute>
<Identifier>(0xf6b2e3fa, 0x7bd43926)</Identifier>
<Value>Examples</Value>
</Attribute>
<Attribute>
<Identifier>(0xf8034a49, 0x8b3f37cc)</Identifier>
<Value>Inria</Value>
</Attribute>
</Attributes>
</OpenViBE-Scenario>
@@ -0,0 +1,69 @@
/*
* Receives data from OpenViBE's VRPN boxes
*
* See here: http://openvibe.inria.fr/vrpn-tutorial-sending-data-from-openvibe-to-an-external-application/
*
*/
#include <iostream>
#include <vrpn_Button.h>
#include <vrpn_Analog.h>
void VRPN_CALLBACK VrpnButtonCallback(void* userData, vrpn_BUTTONCB button)
{
std::cout << "Button ID : " << button.button << " / Button State : " << button.state << std::endl;
if (button.button == 1)
{
std::cout << "Quit requested by button press" << std::endl;
*static_cast<bool*>(userData) = false;
}
}
void VRPN_CALLBACK VrpnAnalogCallback(void* /*user_data*/, vrpn_ANALOGCB analog)
{
for (int i = 0; i < analog.num_channel; ++i) { std::cout << "Analog Channel : " << i << " / Analog Value : " << analog.channel[i] << std::endl; }
}
int main(const int argc, char** argv)
{
if (argc != 1 && argc != 3)
{
std::cout << "Usage:\n\n" << argv[0] << " [buttonDevice] [analogDevice]\n";
return 1;
}
const char* buttonDevice = "openvibe_vrpn_button@localhost";
const char* analogDevice = "openvibe_vrpn_analog@localhost";
if (argc == 3)
{
buttonDevice = argv[1];
analogDevice = argv[2];
}
std::cout << "Polling these VRPN devices\n Button: " << buttonDevice << "\n Analog: " << analogDevice << "\n";
/* flag used to stop the program execution */
bool running = true;
/* Binding of the VRPN Button to a callback */
vrpn_Button_Remote* vrpnButton = new vrpn_Button_Remote(buttonDevice);
vrpnButton->register_change_handler(&running, VrpnButtonCallback);
/* Binding of the VRPN Analog to a callback */
vrpn_Analog_Remote* vrpnAnalog = new vrpn_Analog_Remote(analogDevice);
vrpnAnalog->register_change_handler(nullptr, VrpnAnalogCallback);
/* The main loop of the program, each VRPN object must be called in order to process data */
while (running) { vrpnButton->mainloop(); }
vrpnAnalog->unregister_change_handler(nullptr, VrpnAnalogCallback);
vrpnButton->unregister_change_handler(&running, VrpnButtonCallback);
delete vrpnButton;
delete vrpnAnalog;
return 0;
}