////====================================================================================================== //// 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 #include #include #include #include #include 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 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; } }; /// /// Simple simulator for outputting sine wave channel data. /// class HardwareSimulator { public: HardwareSimulator(); ~HardwareSimulator(); void AddSimulatedGlove(int deviceId, int nodeCount, int handedness); void RegisterFrameDataCallback(std::function&)> data_callback); void RegisterDeviceInfoCallback(std::function&)> 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& data); std::vector mSimulatedFrameDataSet; std::vector mSimulatedDeviceInfoSet; std::vector mNewDeviceInfo; std::function&)> mOnFrameDataUpdate; std::function&)> mOnDeviceInfoUpdate; const double mDataSampleRate = DATA_SAMPLERATE; protected: std::recursive_mutex mDataLock; }; }