111 lines
3.2 KiB
C++

////======================================================================================================
//// Copyright 2023, NaturalPoint Inc.
////======================================================================================================
/*
* SimulatedHardware class is used for demonstrating third-party glove SDK DLL to simulate a third-party hardware.
* For the purpose of the example glove device, the finger tracking data is read from the csv file.
*/
#pragma once
#define DATA_SAMPLERATE 120
#include <thread>
#include <mutex>
#include <vector>
#include <functional>
#include <cmath>
#include <unordered_map>
namespace SimulatedPluginDevices {
class HardwareSimulator;
struct SimulatedFingerData
{
float quat_x = 0;
float quat_y = 0;
float quat_z = 0;
float quat_w = 0;
float pos_x = 0;
float pos_y = 0;
float pos_z = 0;
SimulatedFingerData() {};
SimulatedFingerData(float x, float y, float z, float w) :
quat_x(x), quat_y(y), quat_z(z), quat_w(w) {}
};
struct SimulatedGloveFrameData {
int mDeviceSerial = 0;
int mChannelCount = 0;
int kChannelPerNode = 4;
int mNodeCount = 0;
std::vector<SimulatedFingerData> gloveFingerData; // for glove data
SimulatedGloveFrameData() {}
SimulatedGloveFrameData(int deviceSerial, int nodeCount) :
mDeviceSerial(deviceSerial),
mNodeCount(nodeCount)
{
mChannelCount = mNodeCount * kChannelPerNode;
gloveFingerData.resize(mNodeCount);
}
};
struct SimulatedDeviceInfo {
int mDeviceSerial = 0; // device serial id
int mBattery = 100;
int mSignalStrength = 100;
int mHandSide = 0;
int mNodeCount = 0;
int mChannelCount = 0;
int kChannelPerNode = 4;
SimulatedDeviceInfo() {}
SimulatedDeviceInfo(int deviceSerial, int channelCount):
mDeviceSerial(deviceSerial), mChannelCount(channelCount)
{}
SimulatedDeviceInfo(int deviceSerial, int nodeCount, int handSide) :
mDeviceSerial(deviceSerial), mHandSide(handSide), mNodeCount(nodeCount)
{
mChannelCount = nodeCount * kChannelPerNode;
}
};
/// <summary>
/// Simple simulator for outputting sine wave channel data.
/// </summary>
class HardwareSimulator {
public:
HardwareSimulator();
~HardwareSimulator();
void AddSimulatedGlove(int deviceId, int nodeCount, int handedness);
void RegisterFrameDataCallback(std::function<void(std::vector<SimulatedGloveFrameData>&)> data_callback);
void RegisterDeviceInfoCallback(std::function<void(std::vector<SimulatedDeviceInfo>&)> device_info_callback);
void StartData();
void Shutdown();
private:
bool bIsRunning = false;
std::thread mUpdateThread;
void NotifyDataCallback();
void NotifyInfoCallback();
bool ReadDataFromCSV();
static std::string GetExePath();
void UpdateAllDevicesWithData(std::vector<SimulatedFingerData>& data);
std::vector<SimulatedGloveFrameData> mSimulatedFrameDataSet;
std::vector<SimulatedDeviceInfo> mSimulatedDeviceInfoSet;
std::vector<SimulatedDeviceInfo> mNewDeviceInfo;
std::function<void(std::vector<SimulatedGloveFrameData>&)> mOnFrameDataUpdate;
std::function<void(std::vector<SimulatedDeviceInfo>&)> mOnDeviceInfoUpdate;
const double mDataSampleRate = DATA_SAMPLERATE;
protected:
std::recursive_mutex mDataLock;
};
}