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,87 @@
#include "GenericVRPNServer.h"
#include <vrpn_Connection.h>
#include <vrpn_Button.h>
#include <vrpn_Analog.h>
#include <cstdarg>
CGenericVrpnServer* CGenericVrpnServer::m_serverInstance = nullptr;
CGenericVrpnServer::CGenericVrpnServer(const int port) { m_connection = vrpn_create_server_connection(port); }
CGenericVrpnServer::~CGenericVrpnServer() { deleteInstance(); }
CGenericVrpnServer* CGenericVrpnServer::getInstance(const int port)
{
if (m_serverInstance == nullptr) { m_serverInstance = new CGenericVrpnServer(port); }
return m_serverInstance;
}
void CGenericVrpnServer::deleteInstance()
{
for (auto it = m_serverInstance->m_buttonServer.begin(); it != m_serverInstance->m_buttonServer.end(); ++it) { delete it->second.server; }
m_serverInstance->m_buttonServer.clear();
for (auto it = m_serverInstance->m_analogServer.begin(); it != m_serverInstance->m_analogServer.end(); ++it) { delete it->second.server; }
m_serverInstance->m_analogServer.clear();
delete m_serverInstance;
m_serverInstance = nullptr;
}
void CGenericVrpnServer::loop()
{
for (auto it = m_buttonServer.begin(); it != m_buttonServer.end(); ++it) { it->second.server->mainloop(); }
for (auto it = m_analogServer.begin(); it != m_analogServer.end(); ++it) { it->second.server->mainloop(); }
m_connection->mainloop();
}
void CGenericVrpnServer::addButton(const std::string& name, const int buttonCount)
{
SButtonServer serverObject;
serverObject.server = new vrpn_Button_Server(name.c_str(), m_connection, buttonCount);
serverObject.nButton = buttonCount;
m_buttonServer.insert(std::pair<std::string, SButtonServer>(name, serverObject));
m_buttonServer[name].cache.clear();
m_buttonServer[name].cache.resize(buttonCount);
}
void CGenericVrpnServer::changeButtonState(const std::string& name, const int index, const int state)
{
m_buttonServer[name].server->set_button(index, state);
m_buttonServer[name].cache[index] = state;
}
int CGenericVrpnServer::getButtonState(const std::string& name, const int index) { return m_buttonServer[name].cache[index]; }
void CGenericVrpnServer::addAnalog(const std::string& name, const int nChannel)
{
SAnalogServer serverObject;
serverObject.server = new vrpn_Analog_Server(name.c_str(), m_connection, nChannel);
serverObject.nChannel = nChannel;
m_analogServer.insert(std::pair<std::string, SAnalogServer>(name, serverObject));
}
void CGenericVrpnServer::changeAnalogState(const std::string& name, ...)
{
double* channels = m_analogServer[name].server->channels();
va_list list;
va_start(list, name);
for (int i = 0; i < m_analogServer[name].nChannel; ++i) { channels[i] = va_arg(list, double); }
va_end(list);
m_analogServer[name].server->report();
}
double* CGenericVrpnServer::getAnalogChannels(const std::string& name) { return m_analogServer[name].server->channels(); }
void CGenericVrpnServer::reportAnalogChanges(const std::string& name) { m_analogServer[name].server->report(); }
@@ -0,0 +1,103 @@
/**
* \file GenericVRPNServer.h
* \author Jozef Legény
*
* Copyright : Inria (2012)
* License : LGPLv2 -> AGPL3
*/
#pragma once
#include <map>
#include <vector>
#include <string>
class vrpn_Connection;
class vrpn_Button_Server;
class vrpn_Analog_Server;
/**
* \class CGenericVrpnServer
* \brief A class providing a very simple generic VRPN server capable of creating Analog and Button controls.
*/
class CGenericVrpnServer
{
public:
struct SButtonServer
{
vrpn_Button_Server* server;
int nButton;
std::vector<int> cache;
};
struct SAnalogServer
{
vrpn_Analog_Server* server;
int nChannel;
};
/// Public singleton factory
static CGenericVrpnServer* getInstance(const int port);
static void deleteInstance();
/// Public destructor
~CGenericVrpnServer();
/// 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(const std::string& name, const 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(const std::string& name, const int index, const 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(const std::string& name, const int index);
/** Creates a new analog object within the VRPN server
* \param name name of the vrpn peripheral
* \param nChannel number of channels in the peripeheral
*/
void addAnalog(const std::string& name, const int nChannel);
/** Change the state of channels of an analog VRPN peripheral
* \param name name of the vrpn peripheral containing the analog control
* \param ... : list of the values (double)
*/
void changeAnalogState(const 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(const 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(const std::string& name);
protected:
static CGenericVrpnServer* m_serverInstance;
explicit CGenericVrpnServer(const int port);
vrpn_Connection* m_connection = nullptr;
std::map<std::string, SButtonServer> m_buttonServer;
std::map<std::string, SAnalogServer> m_analogServer;
};
@@ -0,0 +1,50 @@
#if !defined(WIN32)
#include "GenericVRPNServer.h"
#include <iostream>
#include <cmath>
#include <unistd.h>
#define DEFAULT_PORT 50555
int main(int argc, char** argv)
{
CGenericVrpnServer* vrpnServer = CGenericVrpnServer::getInstance(DEFAULT_PORT);
const char* buttonDevice = "button_test";
const char* analogDevice = "analog_test";
std::cout << "Creating devices [" << buttonDevice << "] and [" << analogDevice << "] using port [" << DEFAULT_PORT << "]\n";
vrpnServer->addButton(buttonDevice, 1);
vrpnServer->addAnalog(analogDevice, 2);
double time = 0;
double period = 0;
while (true)
{
if (period >= 2 * M_PI)
{
vrpnServer->changeButtonState(buttonDevice, 0, 1 - vrpnServer->getButtonState(buttonDevice, 0));
period = 0;
}
vrpnServer->changeAnalogState(analogDevice, sin(time), cos(time));
time = time + 0.01;
period = period + 0.01;
vrpnServer->loop();
// sleep for 10 miliseconds (on Unix)
usleep(10000);
}
CGenericVrpnServer::deleteInstance();
vrpnServer = nullptr;
return 0;
}
#endif // !WIN32
@@ -0,0 +1,51 @@
#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*/)
{
CGenericVrpnServer* vrpnServer = CGenericVrpnServer::getInstance(DEFAULT_PORT);
const char* buttonDevice = "button_test";
const char* analogDevice = "analog_test";
std::cout << "Creating devices [" << buttonDevice << "] and [" << analogDevice << "] using port [" << DEFAULT_PORT << "]\n";
vrpnServer->addButton(buttonDevice, 1);
vrpnServer->addAnalog(analogDevice, 2);
double time = 0;
double period = 0;
while (true)
{
if (period >= 2 * M_PI)
{
vrpnServer->changeButtonState(buttonDevice, 0, 1 - vrpnServer->getButtonState(buttonDevice, 0));
period = 0;
}
vrpnServer->changeAnalogState(analogDevice, sin(time), cos(time));
time = time + 0.01;
period = period + 0.01;
vrpnServer->loop();
// sleep for 10 miliseconds
Sleep(10);
}
CGenericVrpnServer::deleteInstance();
vrpnServer = nullptr;
return 0;
}
#endif // WIN32