258 lines
10 KiB
C++
258 lines
10 KiB
C++
//======================================================================================================
|
|
// Copyright 2022, NaturalPoint Inc.
|
|
//======================================================================================================
|
|
#include "dllcommon.h"
|
|
#include "GloveDeviceBase.h"
|
|
|
|
// Optitrack Peripheral Device API
|
|
#include "AnalogChannelDescriptor.h"
|
|
#include "IDeviceManager.h"
|
|
#include "GloveDataFormat.h"
|
|
using namespace AnalogSystem;
|
|
using namespace OptiTrackPluginDevices;
|
|
using namespace GloveDeviceProperties;
|
|
|
|
OptiTrackPluginDevices::GloveDeviceBase::GloveDeviceBase()
|
|
{
|
|
this->SetCommonDeviceProperties();
|
|
this->SetCommonGloveDeviceProperties();
|
|
}
|
|
|
|
void OptiTrackPluginDevices::GloveDeviceBase::SetCommonDeviceProperties()
|
|
{
|
|
// Set appropriate default property values (and set advanced state)
|
|
ModifyProperty(cPluginDeviceBase::kModelPropName, true, true, false);
|
|
ModifyProperty(cPluginDeviceBase::kOrderPropName, true, false, true);
|
|
ModifyProperty(cPluginDeviceBase::kDisplayNamePropName, false, false, false);
|
|
|
|
// Reveal glove related prop name
|
|
ModifyProperty(cPluginDeviceBase::kAssetPropName, false, false, false); // name of the paired skeleton asset
|
|
|
|
// hide default properties that aren't relevant to glove device
|
|
ModifyProperty(cPluginDeviceBase::kSyncModePropName, true, true, true);
|
|
ModifyProperty(cPluginDeviceBase::kSyncStatusPropName, true, true, true);
|
|
ModifyProperty(cPluginDeviceBase::kUseExternalClockPropName, true, true, true);
|
|
ModifyProperty(cPluginDeviceBase::kMocapRateMultiplePropName, true, true, true);
|
|
ModifyProperty(cPluginDeviceBase::kScalePropName, true, true, true);
|
|
ModifyProperty(cPluginDeviceBase::kCalOffsetPropName, true, true, true);
|
|
ModifyProperty(cPluginDeviceBase::kCalSquareRotationPropName, true, true, true);
|
|
ModifyProperty(cPluginDeviceBase::kUserDataPropName, true, true, true);
|
|
ModifyProperty(cPluginDeviceBase::kZeroPropName, true, true, true);
|
|
ModifyProperty(cPluginDeviceBase::kGroupNamePropName, true, true, true);
|
|
|
|
// hide advanced properties
|
|
ModifyProperty(cPluginDeviceBase::kConnectedPropName, true, false, true);
|
|
ModifyProperty(cPluginDeviceBase::kNamePropName, true, false, true);
|
|
ModifyProperty(cPluginDeviceBase::kChannelCountPropName, true, false, true);
|
|
ModifyProperty(cPluginDeviceBase::kAppRunModePropName, true, false, true);
|
|
ModifyProperty(cPluginDeviceBase::kMocapSyncFramePropName, true, false, true);
|
|
ModifyProperty(cPluginDeviceBase::kSyncFramePropName, true, false, true);
|
|
ModifyProperty(cPluginDeviceBase::kNeedDeviceSyncFramePropName, false, false, true);
|
|
ModifyProperty(cPluginDeviceBase::kNeedMocapSyncFramePropName, false, false, true);
|
|
ModifyProperty(cPluginDeviceBase::kUseDriftCorrectionPropName, false, false, true);
|
|
ModifyProperty(cPluginDeviceBase::kMasterSerialPropName, true, false, true);
|
|
ModifyProperty(cPluginDeviceBase::kDriftCorrectionPropName, true, false , true);
|
|
SetProperty(cPluginDeviceBase::kEnabledPropName, true);
|
|
SetProperty(cPluginDeviceBase::kConnectedPropName, true);
|
|
SetProperty(cPluginDeviceBase::kMocapRateMultiplePropName, 1);
|
|
}
|
|
|
|
void OptiTrackPluginDevices::GloveDeviceBase::SetCommonGloveDeviceProperties()
|
|
{
|
|
// Add glove related properties
|
|
AddProperty(GloveDeviceProperties::GloveDeviceProp_HandSide, GloveHandSide, kHandSideCount, 0, "Settings", false);
|
|
AddProperty(GloveDeviceProperties::GloveDeviceProp_Battery, GloveDeviceProp_BatteryUninitialized, "Settings", false);
|
|
AddProperty(GloveDeviceProperties::GloveDeviceProp_SignalStrength, GloveDeviceProp_SignalStrengthUnitialized, "Settings", false);
|
|
//AddProperty(GloveDeviceProperties::GloveDeviceProp_Reconnect, false, "Settings", false);
|
|
|
|
// Modify property visibility
|
|
ModifyProperty(GloveDeviceProperties::GloveDeviceProp_SignalStrength, true, false, false, false);
|
|
ModifyProperty(GloveDeviceProperties::GloveDeviceProp_HandSide, true, false, false);
|
|
ModifyProperty(GloveDeviceProperties::GloveDeviceProp_Battery, true, false, false, false);
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Setter: Glove Device
|
|
//
|
|
void OptiTrackPluginDevices::GloveDeviceBase::SetDeviceRate(int rate)
|
|
{
|
|
mDeviceRateFPS = rate;
|
|
mRequestedRateMS = (1.0f / mDeviceRateFPS) * 1000.0f;
|
|
return;
|
|
}
|
|
|
|
void OptiTrackPluginDevices::GloveDeviceBase::SetHandSide(eGloveHandSide side)
|
|
{
|
|
mHandSide = side;
|
|
return;
|
|
}
|
|
|
|
void OptiTrackPluginDevices::GloveDeviceBase::SetEnabled(bool enabled)
|
|
{
|
|
bIsEnabled = enabled;
|
|
}
|
|
|
|
void OptiTrackPluginDevices::GloveDeviceBase::SetCollecting(bool collecting)
|
|
{
|
|
bIsCollecting = collecting;
|
|
}
|
|
|
|
bool OptiTrackPluginDevices::GloveDeviceBase::SetDeviceSerial(std::string serial)
|
|
{
|
|
mDeviceSerial = serial;
|
|
// Set device serial property
|
|
return false;
|
|
}
|
|
|
|
bool OptiTrackPluginDevices::GloveDeviceBase::SetDeviceData(sGloveDeviceData data)
|
|
{
|
|
mLastGloveData = data;
|
|
return true;
|
|
}
|
|
|
|
bool OptiTrackPluginDevices::GloveDeviceBase::SetBatteryLevel(int level)
|
|
{
|
|
if (SetProperty(GloveDeviceProperties::GloveDeviceProp_Battery, (int)level))
|
|
{
|
|
mBatteryLevel = level;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool OptiTrackPluginDevices::GloveDeviceBase::SetSignalStrength(int signal)
|
|
{
|
|
if (SetProperty(GloveDeviceProperties::GloveDeviceProp_SignalStrength, (int)signal))
|
|
{
|
|
mSignalStrength = signal;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void OptiTrackPluginDevices::GloveDeviceBase::InitializeGloveProperty()
|
|
{
|
|
if (mDeviceInfo.handSide == eGloveHandSide::Left)
|
|
{
|
|
SetProperty(GloveDeviceProperties::GloveDeviceProp_HandSide, 1);
|
|
SetProperty(cPluginDeviceBase::kOrderPropName, 1);
|
|
bIsInitialized = true;
|
|
}
|
|
else if (mDeviceInfo.handSide == eGloveHandSide::Right)
|
|
{
|
|
SetProperty(GloveDeviceProperties::GloveDeviceProp_HandSide, 2);
|
|
SetProperty(cPluginDeviceBase::kOrderPropName, 2);
|
|
bIsInitialized = true;
|
|
}
|
|
return;
|
|
}
|
|
|
|
|
|
void OptiTrackPluginDevices::GloveDeviceBase::UpdateGloveProperty(const sGloveDeviceBaseInfo& deviceInfo)
|
|
{
|
|
// update glove property when the device is receiving data.
|
|
int deviceState = 0;
|
|
GetProperty(kDataStatePropName, deviceState);
|
|
if (deviceState == DeviceDataState::DeviceState_ReceivingData)
|
|
{
|
|
if (mSignalStrength != 1)
|
|
{
|
|
mSignalStrength = deviceInfo.signalStrength;
|
|
double signal = fabs(mSignalStrength);
|
|
SetProperty(GloveDeviceProp_SignalStrength, (int)signal);
|
|
}
|
|
SetProperty(GloveDeviceProp_SignalStrength, -100);
|
|
|
|
if (mBatteryLevel != deviceInfo.battery)
|
|
{
|
|
mBatteryLevel = (int)(deviceInfo.battery); //Battery level percentage.
|
|
SetProperty(GloveDeviceProp_Battery, (int)mBatteryLevel);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Glove Device Factory
|
|
//
|
|
void OptiTrackPluginDevices::GloveDeviceFactoryBase::SetCommonGloveDeviceProperties(GloveDeviceBase* pDevice) const
|
|
{
|
|
// REQUIRED: Set device name/model/serial
|
|
pDevice->SetProperty(cPluginDeviceBase::kNamePropName, (char*)DeviceName());
|
|
pDevice->SetProperty(cPluginDeviceBase::kDisplayNamePropName, (char*)DeviceName());
|
|
pDevice->SetProperty(cPluginDeviceBase::kModelPropName, "Glove Model"); // model
|
|
char mDeviceSerial[MAX_PATH];
|
|
sprintf_s(mDeviceSerial, "%s-serial", DeviceName());
|
|
pDevice->SetProperty(cPluginDeviceBase::kSerialPropName, mDeviceSerial); // device serial (must be unique!)
|
|
pDevice->SetProperty(cPluginDeviceBase::kDeviceTypePropName, (long)DeviceType_Glove); // set device type as glove
|
|
pDevice->SetProperty(cPluginDeviceBase::kRatePropName, 120.0); // glove sampling rate
|
|
pDevice->SetProperty(cPluginDeviceBase::kUseDriftCorrectionPropName, true); // drift correction to fetch most recent data.
|
|
pDevice->SetProperty(cPluginDeviceBase::kOrderPropName, (int) eGloveHandSide::Unknown); // device order: (0 = uninitialized, 1=left, 2=right)
|
|
}
|
|
|
|
|
|
void OptiTrackPluginDevices::GloveDeviceFactoryBase::SetDeviceIndex(int t_index)
|
|
{
|
|
mDeviceIndex = t_index;
|
|
return;
|
|
}
|
|
|
|
void OptiTrackPluginDevices::GloveDeviceFactoryBase::SetQuaternionDataChannels(GloveDeviceBase* pDevice) const
|
|
{
|
|
// Set glove data channels:
|
|
// 5 fingers * 3 joints per finger * 4 floats per quat (x/y/z/w) = 60 channels
|
|
int channelIndex;
|
|
int gloveAnalogChannelCount = 60;
|
|
char szChannelNames[MAX_PATH];
|
|
|
|
// add channels
|
|
for (int i = 0; i < gloveAnalogChannelCount; i++)
|
|
{
|
|
int finger = i / 12; // 12 channels per finger
|
|
switch (finger)
|
|
{
|
|
case 0: sprintf_s(szChannelNames, "T"); break;
|
|
case 1: sprintf_s(szChannelNames, "I"); break;
|
|
case 2: sprintf_s(szChannelNames, "M"); break;
|
|
case 3: sprintf_s(szChannelNames, "R"); break;
|
|
case 4: sprintf_s(szChannelNames, "P"); break;
|
|
}
|
|
|
|
int joint = (i / 4) % 3; // 3 joints per finger
|
|
switch (joint)
|
|
{
|
|
case 0: sprintf_s(szChannelNames, "%s-MCP", szChannelNames); break;
|
|
case 1: sprintf_s(szChannelNames, "%s-PIP", szChannelNames); break;
|
|
case 2: sprintf_s(szChannelNames, "%s-DIP", szChannelNames); break;
|
|
}
|
|
|
|
int axis = i % 4; // 4 floats per joint
|
|
switch (axis)
|
|
{
|
|
case 0: sprintf_s(szChannelNames, "%s W", szChannelNames); break;
|
|
case 1: sprintf_s(szChannelNames, "%s X", szChannelNames); break;
|
|
case 2: sprintf_s(szChannelNames, "%s Y", szChannelNames); break;
|
|
case 3: sprintf_s(szChannelNames, "%s Z", szChannelNames); break;
|
|
}
|
|
channelIndex = pDevice->AddChannelDescriptor(szChannelNames, ChannelType_Float);
|
|
|
|
}
|
|
|
|
// enable all channels by default
|
|
for (int i = 0; i <= channelIndex; i++)
|
|
{
|
|
// data channel enabled by default
|
|
pDevice->ChannelDescriptor(i)->SetProperty(ChannelProp_Enabled, true);
|
|
|
|
// hide unused channel properties
|
|
pDevice->ChannelDescriptor(i)->ModifyProperty(ChannelProp_Units, true, true);
|
|
pDevice->ChannelDescriptor(i)->ModifyProperty(ChannelProp_Name, true, true);
|
|
pDevice->ChannelDescriptor(i)->ModifyProperty(ChannelProp_MinVoltage, true, true);
|
|
pDevice->ChannelDescriptor(i)->ModifyProperty(ChannelProp_MaxVoltage, true, true);
|
|
pDevice->ChannelDescriptor(i)->ModifyProperty(ChannelProp_TerminalName, true, true);
|
|
pDevice->ChannelDescriptor(i)->ModifyProperty(ChannelProp_TerminalType, true, true);
|
|
pDevice->ChannelDescriptor(i)->ModifyProperty(ChannelProp_MaxVoltage, true, true);
|
|
}
|
|
} |