- NB: Document written for OpenViBE 2.1.0 (19.11.2018)
Introduction
This tutorial describes how to make an OpenViBE plugin library (.so or .dll) that can be loaded by Designer. A plugin library can contain one or more box plugins, such as users see in Designer. If you are developing several related box plugins, it can make sense to collect them together into one plugin. In this tutorial we provide a template archive containing the folders and files necessary for the creation of a new plugin library.
Prerequisites
From this point we assume that you have downloaded the sources of OpenViBE and already built the whole software using the provided scripts at least once.
For those who want to catch up, download the sources or checkout the code, and then follow the build instructions.
Coding Rules
If you eventually intend to contribute your plugin library sources to OpenViBE, it would be a good idea to already initially make your code follow the Coding Rules, as this would be requested at the latest in the merging stage. Folders and filenames must not contain spaces.
- Folder Name convention :
folder-name
Directory structure
All plugin library directories in OpenViBE source tree follow a specific directory organization:
plugin-name
bci-examples
: Any useful scenarios to create an example of BCI.
this folder can contain the different scenarios (*.xml). As well as the scripts (lua, python …) if necessary.
If the example is composed of several scenarios, the name of the files must indicate the order of launch of the scenarios. Ex:0-Monitoring.xml
1-Acquisition.xml
2-Classifier-Training.xml
3-Online.xml
4-Replay.xml
box-tutorials
: this folder can contain the different scenarios (*.xml) to illustrate the boxes in the plugin. As well as the scripts (lua, python …) to use your boxes.signals
: This folder can contain the different signals your tutorials might need. Prefer generic types such as *.gdf or *.ov. For storage of matrices or streamed matrices you can use the CSV format. It is however not recommended to commit large binaries to git.doc
: This folder MUST contain the documentation of your plugin including the *.dox-part of your boxes. See Writing Box Documentation.src
: This folder must contain all source code of your boxes and algorithm.test
: This folder must contain all source code of your unit tests and scenario tests.
This part is highly recommended. A good code is a tested code.CMakeLists.txt
: the CMakelist file describing how to build the plugin.
Making the CmakeList.txt
This CmakeList
finds sources and dependencies and tells the compiler what to include and link. The CMakeLists.txt files are automatically parsed when you build your OpenViBE with the plugin.
Note: The following cmakelists includes a lot of commented out lines (for example). In a real cmakelists, its recommended to keep it tidy, and not include unnecessary dependencies or lines.
PROJECT(openvibe-plugins-template) SET(PROJECT_VERSION_MAJOR ${OV_GLOBAL_VERSION_MAJOR}) SET(PROJECT_VERSION_MINOR ${OV_GLOBAL_VERSION_MINOR}) SET(PROJECT_VERSION_PATCH ${OV_GLOBAL_VERSION_PATCH}) SET(PROJECT_VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}) FILE(GLOB_RECURSE source_files src/*.cpp src/*.hpp src/*.h src/*.inl src/*.c) ADD_LIBRARY(${PROJECT_NAME} SHARED ${source_files} # "../../../contrib/packages/wavelet2d/wavelet2s.h" # If You need Some files, you can add it here and ) SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION ${PROJECT_VERSION_MAJOR} COMPILE_FLAGS "-DOVP_Exports -DOVP_Shared -D_LARGEFILE64_SOURCE -D_LARGEFILE_SOURCE") #INCLUDE_DIRECTORIES("../../../contrib/packages/wavelet2d") # If You need Some directories, you can add it here and # --------------------------------- # OpenVibe Modules (uncomment usefull package) # --------------------------------- # OpenViBE Base #INCLUDE("FindOpenViBE") #INCLUDE("FindOpenViBECommon") #INCLUDE("FindOpenViBEToolkit") # OpenViBE Module #INCLUDE("FindOpenViBEModuleSystem") #INCLUDE("FindOpenViBEModuleXML") #INCLUDE("FindOpenViBEModuleEBML") #INCLUDE("FindOpenViBEModuleCSV") #INCLUDE("FindOpenViBEModuleSocket") #INCLUDE("FindOpenViBEModuleCommunication") #INCLUDE("FindOpenViBEModuleFS") # OpenViBE Third Party #INCLUDE("FindThirdPartyEigen") #INCLUDE("FindThirdPartyITPP") #INCLUDE("FindThirdPartyFFTW3") #INCLUDE("FindThirdPartyBoost") #INCLUDE("FindThirdPartyBoost_FileSystem") #INCLUDE("FindThirdPartyBoost_Chrono") #INCLUDE("FindThirdPartyExpat") #INCLUDE("FindThirdPartyXerces") #INCLUDE("FindThirdPartyWinsock2") #INCLUDE("FindThirdPartyFTDI") #INCLUDE("FindThirdPartyGTK") # --------------------------------- # Target macros # Defines target operating system # Defines target architecture # Defines target compiler # --------------------------------- SET_BUILD_PLATFORM() # ----------------------------- # Install files (uncomment usefull line) # ----------------------------- INSTALL(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION ${DIST_BINDIR} LIBRARY DESTINATION ${DIST_LIBDIR} ARCHIVE DESTINATION ${DIST_LIBDIR}) #INSTALL(DIRECTORY bci-tutorials/ DESTINATION ${DIST_DATADIR}/openvibe/scenarios/bci-tutorials/) #INSTALL(DIRECTORY box-tutorials/ DESTINATION ${DIST_DATADIR}/openvibe/scenarios/box-tutorials/) #INSTALL(DIRECTORY signals/ DESTINATION ${DIST_DATADIR}/openvibe/scenarios/signals/) # --------------------------------- # Test applications (uncomment to enable your test directory) # --------------------------------- #IF(OV_COMPILE_TESTS) # ADD_SUBDIRECTORY(test) #ENDIF(OV_COMPILE_TESTS)
Source Folder
With your boxes and algorithms source folder you must have two files : ovp_define.h
and ovp_main.cpp
Note: The following examples should be updated to be consistent, i.e. that IDs actually refer to the box actual code included.
#pragma once // All define you need. For Ex : // #define OVP_TypeId_EpochAverageMethod OpenViBE::CIdentifier(0x6530BDB1, 0xD057BBFE)
#include <openvibe/ov_all.h> #include "ovp_defines.h" // Boxes Includes #include "boxes/ovpCBoxAlgorithmMyBox.h" OVP_Declare_Begin(); // Register boxes OVP_Declare_New(OpenViBEPlugins::MyPlugin::ovpCBoxAlgorithmMyBoxDesc); OVP_Declare_End();
Test Folder
Scenario Output Test
To write test specification for a simple Box, You can use DartTestfile.txt
. In this case, you have to create a short scenario with output to compare with a reference output. The Test manager run the scenario quickly and compare the output with the ref.
For Example : The test is called MyTest (it’s an example, use an explicit name) they have a CSV on Input and a CSV on Output
MyTest-test.xml
MyTest-input.csv
MyTest-ref.csv
IF(WIN32) SET(EXT cmd) SET(OS_FLAGS "--no-pause") ELSE() SET(EXT sh) SET(OS_FLAGS "") ENDIF() ############ SET(TEST_NAME MyTest) # To compare CSV with correct name file it's the only line to change SET(SCENARIO_TO_TEST "${TEST_NAME}-test.xml") ADD_TEST(clean_${TEST_NAME} "${CMAKE_COMMAND}" "-E" "remove" "-f" "${TEST_NAME}-output.csv") ADD_TEST(run_${TEST_NAME} "$ENV{OV_BINARY_PATH}/openvibe-designer.${EXT}" ${OS_FLAGS} "--no-session-management" "--invisible" "--play-fast" ${SCENARIO_TO_TEST}) ADD_TEST(compare_${TEST_NAME} "$ENV{OV_BINARY_PATH}/test_thresholdDataComparison.${EXT}" ${OS_FLAGS} "${TEST_NAME}-output.csv" "${TEST_NAME}-ref.csv" 0.0001) SET_TESTS_PROPERTIES(run_${TEST_NAME} PROPERTIES ATTACHED_FILES_ON_FAIL ${OV_CONFIG_SUBDIR}) SET_TESTS_PROPERTIES(compare_${TEST_NAME} PROPERTIES ATTACHED_FILES_ON_FAIL "${TEST_NAME}-output.csv") SET_TESTS_PROPERTIES(compare_${TEST_NAME} PROPERTIES DEPENDS run_${TEST_NAME}) SET_TESTS_PROPERTIES(run_${TEST_NAME} PROPERTIES DEPENDS clean_${TEST_NAME}) ##############
Unit Test
The Second type of test is more standard, OpenViBE Unit Test use Google Test Framework. You must add a short CMakeList.txt
in test
folder. The project name is test_
+ pluginname
PROJECT(test_template) ADD_EXECUTABLE(${PROJECT_NAME} test_template.cpp #Add you src files #../src/myAlgorithm.cpp ) SET_BUILD_PLATFORM() #INCLUDE_DIRECTORIES("${CMAKE_CURRENT_SOURCE_DIR}/../src/boxes") # if your source folder have subfolder SET(GTEST_ROOT ${OV_DEPENDENCY_CMD_PATH}/${CMAKE_FIND_LIBRARY_PREFIXES}gtest) FIND_PACKAGE(GTest REQUIRED) TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${GTEST_BOTH_LIBRARIES}) INCLUDE_DIRECTORIES(${GTEST_INCLUDE_DIRS}) # --------------------------------- # OpenVibe Modules (uncomment usefull package) # --------------------------------- #INCLUDE("FindOpenViBE") #.......... ADD_TEST(NAME test_myplugin COMMAND ${PROJECT_NAME}) OV_INSTALL_LAUNCH_SCRIPT(SCRIPT_PREFIX "${PROJECT_NAME}" EXECUTABLE_NAME "${PROJECT_NAME}") INSTALL(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION ${DIST_BINDIR} LIBRARY DESTINATION ${DIST_LIBDIR} ARCHIVE DESTINATION ${DIST_LIBDIR})
Add your test to the toolchain
To add your test in OpenViBE toolchain, open the CTestTestfile.cmake
in "OpenViBERootDir/extras/test/"
and add your test dir path to the list.
Ex : subdirs("${CTEST_SOURCE_DIRECTORY}/externals/template/test")
Next call "ctest -T Test"
in folder build/extras-Release/
. If you have keep all subdir test have a coffee and after a while you have some lines like :
Start 10: clean_MyTest Test #10: clean_MyTest ........................... Passed 0.03 sec Start 11: run_MyTest Test #11: run_MyTest ............................. Passed 1.47 sec Start 12: compare_MyTest Test #12: compare_MyTest ......................... Passed 0.06 sec
Template zip folder
Here’s a folder that includes the plugin library folder structure we just described.