181 lines
5.8 KiB
C++
181 lines
5.8 KiB
C++
//======================================================================================================
|
|
// Copyright 2023, NaturalPoint Inc.
|
|
//======================================================================================================
|
|
/**
|
|
* GloveDeviceBase/GloveDeviceFactory class extends the cPluginDeviceBase and configures data channels and device properties required
|
|
* by a glove device in Motive. The purpose of this class is to abstract out setups needed for creating glove device as demonstrated
|
|
* in the ExampleGloveDevice. When developing a glove plugin to animate fingers in Motive, the following class can be inherited if needed.
|
|
*/
|
|
|
|
#include <memory>
|
|
#include <list>
|
|
#include <mutex>
|
|
#include <thread>
|
|
|
|
// OptiTrack Peripheral Device API
|
|
#include "PluginDevice.h"
|
|
#include "PluginDeviceFactory.h"
|
|
#include "GloveDataFormat.h"
|
|
|
|
namespace OptiTrackPluginDevices
|
|
{
|
|
class GloveDeviceBase;
|
|
class GloveDeviceFactoryBase;
|
|
|
|
/**
|
|
* Common glove device properties used in Motive.
|
|
*/
|
|
namespace GloveDeviceProperties
|
|
{
|
|
static const int kHandSideCount = 3;
|
|
static const char* GloveHandSide[kHandSideCount] =
|
|
{
|
|
"Uninitialized",
|
|
"Left",
|
|
"Right"
|
|
};
|
|
// Glove type needs to be set at the device level (0 = uninitialized, 1 = left, 2 = right)
|
|
static const char* GloveDeviceProp_HandSide = "Hand Side";
|
|
static const char* GloveDeviceProp_Battery = "Battery";
|
|
static const char* GloveDeviceProp_SignalStrength = "Signal Strength";
|
|
static const char* GloveDeviceProp_ServerAddress = "Server Address";
|
|
static const char* GloveDeviceProp_Reconnect = "Reconnect";
|
|
static const char* GloveDeviceProp_Solver = "Glove Solver";
|
|
static const int GloveDeviceProp_BatteryUninitialized = -1;
|
|
static const int GloveDeviceProp_SignalStrengthUnitialized = -1;
|
|
static const int kGloveAnalogChannelCount = 60;
|
|
}
|
|
|
|
/**
|
|
* GloveDeviceFactory class demonstrates how plugin device factory can be set up for creating a glove device in Motive.
|
|
* To create a device in Motive, an instance of PLuginDeviceFactory must be created per each device, and then, its ownership must be
|
|
* transferred to Motive by using Create method. The GloveDeviceFactory inherits from PLuginDeviceFactory and demonstrates common
|
|
* glove properties and data channels can be configured; which is demonstrated in this base class.
|
|
*/
|
|
class GloveDeviceFactoryBase : public AnalogSystem::PluginDeviceFactory
|
|
{
|
|
public:
|
|
GloveDeviceFactoryBase(std::string deviceName, uint32_t serial) :
|
|
AnalogSystem::PluginDeviceFactory(deviceName.c_str()), mDeviceSerial(serial) {}
|
|
|
|
uint32_t mDeviceSerial = -1;
|
|
int mDeviceIndex = 0;
|
|
|
|
protected:
|
|
void SetDeviceIndex(int t_index);
|
|
|
|
/**
|
|
* Sets up quaternion data channels for delivering local rotation of the finger nodes.
|
|
* Motive skeleton's hand consists of total 15 finger nodes, 3 per each finger.
|
|
* These data channels will get populated by the collection thread running on each device.
|
|
* Quaternion values are expected, resulting in total 60 float channels (15 finger nodes * 4 quat floats / node).
|
|
* Local rotation data is expected, and both hand data expects right-handed coordinate system with +x axis
|
|
* pointing towards the finger tip for left hand and towards the wrist/body for right hand.
|
|
*/
|
|
void SetQuaternionDataChannels(GloveDeviceBase* pDevice) const;
|
|
|
|
/**
|
|
* Set Common Glove device properties
|
|
*/
|
|
void SetCommonGloveDeviceProperties(GloveDeviceBase* pDevice) const;
|
|
};
|
|
|
|
/**
|
|
* cGloveDeviceBase class is an example class which glove devices could inherit from.
|
|
* This class includes basic setups and configurations for glove devices in Motive.
|
|
*/
|
|
class GloveDeviceBase : public AnalogSystem::cPluginDevice<float>
|
|
{
|
|
friend class GloveDeviceFactoryBase;
|
|
|
|
public:
|
|
GloveDeviceBase();
|
|
~GloveDeviceBase() = default;
|
|
|
|
void SetCommonDeviceProperties();
|
|
void SetCommonGloveDeviceProperties();
|
|
|
|
protected:
|
|
// Device status
|
|
bool bIsEnabled = false;
|
|
bool bIsCollecting = false;
|
|
bool bIsInitialized = false;
|
|
bool bIsConfigured = false;
|
|
|
|
// Device info
|
|
sGloveDeviceBaseInfo mGloveInfo;
|
|
std::string mDeviceSerial = "";
|
|
eGloveHandSide mHandSide = eGloveHandSide::Unknown;
|
|
int mBatteryLevel = 0;
|
|
int mSignalStrength = 0;
|
|
double mDeviceRateFPS = 0;
|
|
double mRequestedRateMS = 0.0;
|
|
|
|
// Glove data
|
|
sGloveDeviceData mLastGloveData;
|
|
|
|
// Collection thread must be created on the device class. Defined in ExampleGloveDevice class.
|
|
virtual unsigned long DoCollectionThread() = 0;
|
|
|
|
/**
|
|
* Configure device rate
|
|
*/
|
|
void SetDeviceRate(int rate);
|
|
|
|
/**
|
|
* Configure hand side
|
|
*/
|
|
void SetHandSide(eGloveHandSide side);
|
|
|
|
/**
|
|
* Enable or disable device
|
|
*/
|
|
void SetEnabled(bool enabled);
|
|
|
|
/**
|
|
* Set collection status
|
|
*/
|
|
void SetCollecting(bool collecting);
|
|
|
|
/**
|
|
* Set device serial string each device must have unique serial
|
|
*/
|
|
bool SetDeviceSerial(std::string serial);
|
|
|
|
/**
|
|
* Set device data
|
|
*/
|
|
bool SetDeviceData(sGloveDeviceData data);
|
|
|
|
/**
|
|
* Set device battery level (1-100)
|
|
*/
|
|
bool SetBatteryLevel(int level);
|
|
|
|
/**
|
|
* Sets the signal stregth (1-128)
|
|
*/
|
|
bool SetSignalStrength(int signal);
|
|
|
|
|
|
bool IsEnabled() { return bIsEnabled; };
|
|
bool IsCollecting() { return bIsCollecting; };
|
|
int GetSignalStrength() { return mSignalStrength; }
|
|
int GetBatteryLevel() { return mBatteryLevel; }
|
|
double GetDeviceRate() { return mDeviceRateFPS; }
|
|
sGloveDeviceData GetLastestData() { return mLastGloveData; };
|
|
|
|
/**
|
|
* Initialize the properties for the glove device
|
|
*/
|
|
void InitializeGloveProperty();
|
|
|
|
/**
|
|
* Updates the device properties. Gets called periodically within collection thread.
|
|
* Mainly updates the battery level and signal strength.
|
|
*/
|
|
void UpdateGloveProperty(const sGloveDeviceBaseInfo& deviceInfo);
|
|
sGloveDeviceBaseInfo mDeviceInfo;
|
|
};
|
|
}
|