Commit 2b2fff2d authored by Jussi Lindgren's avatar Jussi Lindgren

Applications: Added VRPN->OpenViBE tutorial example

parent 45292aba
PROJECT(openvibe-examples-vrpn-to-openvibe)
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})
INCLUDE("FindThirdPartyVRPN_Check")
IF(NOT PATH_VRPN)
MESSAGE(STATUS " --> Not building ${PROJECT_NAME}")
RETURN()
ENDIF(NOT PATH_VRPN)
FILE(GLOB_RECURSE source_files src/*.cpp src/*.h src/*.hpp src/*.inl include/*.h)
INCLUDE_DIRECTORIES(include)
ADD_EXECUTABLE(${PROJECT_NAME} ${source_files})
INCLUDE("FindThirdPartyVRPN")
INCLUDE("FindThirdPartyPThread") # needed on Linux for VRPN
# ---------------------------------
# Target macros
# Defines target operating system
# Defines target architecture
# Defines target compiler
# ---------------------------------
IF(WIN32)
ADD_DEFINITIONS(-D_CRT_SECURE_NO_DEPRECATE)
ADD_DEFINITIONS(-DTARGET_OS_Windows)
ADD_DEFINITIONS(-DTARGET_ARCHITECTURE_i386)
ADD_DEFINITIONS(-DTARGET_COMPILER_VisualStudio)
ENDIF(WIN32)
IF(UNIX)
# ADD_DEFINITIONS(-fvisibility=hidden) # This flag should be present... man gcc
ADD_DEFINITIONS(-g)
ADD_DEFINITIONS(-fnon-call-exceptions)
ADD_DEFINITIONS(-DTARGET_OS_Linux)
ADD_DEFINITIONS(-DTARGET_ARCHITECTURE_i386)
ADD_DEFINITIONS(-DTARGET_COMPILER_GCC)
ENDIF(UNIX)
# ----------------------
# Generate launch script
# ----------------------
OV_INSTALL_LAUNCH_SCRIPT("openvibe-examples-vrpn-to-openvibe")
# -----------------------------
# Install files
# -----------------------------
INSTALL(TARGETS ${PROJECT_NAME}
RUNTIME DESTINATION ${CMAKE_INSTALL_FULL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR})
INSTALL(DIRECTORY box-tutorials/ DESTINATION ${CMAKE_INSTALL_FULL_DATADIR}/openvibe/scenarios/box-tutorials PATTERN ".svn" EXCLUDE)
#INSTALL(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_FULL_INCLUDEDIR}/ FILES_MATCHING PATTERN "*.h" PATTERN ".svn" EXCLUDE)
#include "GenericVRPNServer.h"
#include <vrpn_Connection.h>
#include <vrpn_Button.h>
#include <vrpn_Analog.h>
#include <cstdarg>
GenericVRPNServer* GenericVRPNServer::serverInstance = NULL;
GenericVRPNServer::GenericVRPNServer(int port)
{
_connection = vrpn_create_server_connection(port);
}
GenericVRPNServer* GenericVRPNServer::getInstance(int port)
{
if (serverInstance == NULL)
{
serverInstance = new GenericVRPNServer(port);
}
return serverInstance;
}
void GenericVRPNServer::loop()
{
for (std::map<std::string, ButtonServer>::iterator it = _buttonServer.begin(); it != _buttonServer.end(); ++it)
{
it->second.server->mainloop();
}
for (std::map<std::string, AnalogServer>::iterator it = _analogServer.begin(); it != _analogServer.end(); ++it)
{
it->second.server->mainloop();
}
_connection->mainloop();
}
void GenericVRPNServer::addButton(std::string name, int buttonCount)
{
ButtonServer serverObject;
serverObject.server = new vrpn_Button_Server(name.c_str(), _connection, buttonCount);
serverObject.buttonCount = buttonCount;
_buttonServer.insert(std::pair<std::string, ButtonServer>(name, serverObject));
_buttonServer[name].cache.clear();
_buttonServer[name].cache.resize(buttonCount);
}
void GenericVRPNServer::changeButtonState(std::string name, int index, int state)
{
_buttonServer[name].server->set_button(index, state);
_buttonServer[name].cache[index] = state;
}
int GenericVRPNServer::getButtonState(std::string name, int index)
{
return _buttonServer[name].cache[index];
}
void GenericVRPNServer::addAnalog(std::string name, int channelCount)
{
AnalogServer serverObject;
serverObject.server = new vrpn_Analog_Server(name.c_str(), _connection, channelCount);
serverObject.channelCount = channelCount;
_analogServer.insert(std::pair<std::string, AnalogServer>(name, serverObject));
}
void GenericVRPNServer::changeAnalogState(std::string name, ...)
{
double* channels = _analogServer[name].server->channels();
va_list list;
va_start(list, name);
for (int i = 0; i < _analogServer[name].channelCount; i++)
{
channels[i] = va_arg(list, double);
}
va_end(list);
_analogServer[name].server->report();
}
double* GenericVRPNServer::getAnalogChannels(std::string name)
{
return _analogServer[name].server->channels();
}
void GenericVRPNServer::reportAnalogChanges(std::string name)
{
_analogServer[name].server->report();
}
/**
* \file GenericVRPNServer.h
* \author Jozef Legény
*
* Copyright : Inria (2012)
* License : LGPLv2 -> AGPL3
*/
#ifndef __GenericVRPNServer__
#define __GenericVRPNServer__
#include <map>
#include <vector>
#include <string>
class vrpn_Connection;
class vrpn_Button_Server;
class vrpn_Analog_Server;
/**
* \class GenericVRPNServer
* \brief A class providing a very simple generic VRPN server capable of creating Analog and Button controls.
*/
class GenericVRPNServer
{
public:
struct ButtonServer {
vrpn_Button_Server* server;
int buttonCount;
std::vector<int> cache;
};
struct AnalogServer {
vrpn_Analog_Server* server;
int channelCount;
};
/// Public singleton factory
static GenericVRPNServer* getInstance(int port);
/// Public destructor
~GenericVRPNServer();
/// The loop() method has to be called periodically in order for vrpn to work
void loop();
/** Creates a new button object within the VRPN server
* \param name name of the vrpn peripheral
* \param buttonCount number of virtual buttons in the peripeheral
*/
void addButton(std::string name, int buttonCount);
/** Change the button state of a button inside a created VRPN peripheral
* \param name name of the vrpn peripheral containing the button
* \param index index of the button (beginning by 0)
* \param state new state of the button 0 = off, 1 = on
*/
void changeButtonState(std::string name, int index, int state);
/** Get the state of a button
* \param name name of the vrpn peripheral containing the button
* \param index index of the button (beginning by 0)
* \return the state of the button
*/
int getButtonState(std::string name, int index);
/** Creates a new analog object within the VRPN server
* \param name name of the vrpn peripheral
* \param channelCount number of channels in the peripeheral
*/
void addAnalog(std::string name, int channelCount);
/** Change the state of channels of an analog VRPN peripheral
* \param name name of the vrpn peripheral containing the analog control
* \param ellipsis list of the values (double)
*/
void changeAnalogState(std::string name, ...);
/** Gets a pointer to the channel array
* \param name name of the vrpn peripheral containing the analog control
* \return pointer to the array containing the channels
*/
double* getAnalogChannels(std::string name);
/** Marks the selected analog server channels as modified so the values are sent in the next loop
* \param name name of the vrpn peripheral containing the analog control
*/
void reportAnalogChanges(std::string name);
private:
static GenericVRPNServer* serverInstance;
GenericVRPNServer(int port);
vrpn_Connection* _connection;
std::map<std::string, ButtonServer> _buttonServer;
std::map<std::string, AnalogServer> _analogServer;
};
#endif // __GenericVRPNServer__
#if !defined(WIN32)
#include "GenericVRPNServer.h"
#include <iostream>
#include <cmath>
#define DEFAULT_PORT 50555
int main(int argc, char** argv)
{
GenericVRPNServer* vrpnServer = GenericVRPNServer::getInstance(DEFAULT_PORT);
vrpnServer->addButton("button_test", 1);
vrpnServer->addAnalog("analog_test", 2);
double time = 0;
double period = 0;
while (true)
{
if (period >= 2 * M_PI)
{
vrpnServer->changeButtonState("button_test", 0, 1 - vrpnServer->getButtonState("button_test", 0));
period = 0;
}
vrpnServer->changeAnalogState("analog_test", sin(time), cos(time));
time = time + 0.01;
period = period + 0.01;
vrpnServer->loop();
// sleep for 10 miliseconds (on Unix)
usleep(10000);
}
return 0;
}
#endif // !WIN32
\ No newline at end of file
#if defined(WIN32)
#include "GenericVRPNServer.h"
#include <iostream>
#define _USE_MATH_DEFINES
#include <math.h>
#include <windows.h>
#define DEFAULT_PORT 50555
int main(int argc, char** argv)
{
GenericVRPNServer* vrpnServer = GenericVRPNServer::getInstance(DEFAULT_PORT);
vrpnServer->addButton("button_test", 1);
vrpnServer->addAnalog("analog_test", 2);
double time = 0;
double period = 0;
while (true)
{
if (period >= 2 * M_PI)
{
vrpnServer->changeButtonState("button_test", 0, 1 - vrpnServer->getButtonState("button_test", 0));
period = 0;
}
vrpnServer->changeAnalogState("analog_test", sin(time), cos(time));
time = time + 0.01;
period = period + 0.01;
vrpnServer->loop();
// sleep for 10 miliseconds
Sleep(10);
}
return 0;
}
#endif // WIN32
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment