10#define CM_TO_METERS (1/100.0)
13vrpn_Tracker_G4::vrpn_Tracker_G4 (
const char *name,
vrpn_Connection *c,
const char *filepath, vrpn_float64 Hz,
const char *rcmd, vrpn_Tracker_G4_HubMap * pHMap) :
16 srcCalPath = LPCTSTR(filepath);
18 register_server_handlers();
21 cout<<
"G4: Could not initialize\r\n";
24 else if (pHMap && !(InitDigIOBtns()))
26 cout<<
"G4: Could not configure DigIO buttons\r\n";
31 cout<<
"G4: Could not connect\r\n";
35 else if(!(SetupDevice()))
37 cout<<
"G4: Could not setup device\r\n";
40 else if(!(StartCont())){
41 cout<<
"G4: Failed to enter continuous mode\r\n";
45 cout<<
"G4: Initialization Complete\r\n";
51vrpn_Tracker_G4::~vrpn_Tracker_G4(
void){
61 fprintf(stderr,
"vrpn_Tracker_G4::~vrpn_Tracker_G4(): delete failed\n");
69void vrpn_Tracker_G4::mainloop()
71 struct timeval current_time;
79 DisplayCont(current_time);
88int vrpn_Tracker_G4::encode_to(
char *buf)
108 return 1000 - buflen;
114BOOL vrpn_Tracker_G4::Initialize(VOID){
122 pdiG4.Trace(TRUE, 5);
131BOOL vrpn_Tracker_G4::InitDigIOBtns()
138 HUBMAP_ENTRY * pHub = m_pHMap->Begin();
144 try { pHub->pBtnSrv =
new vrpn_Button_Server(pHub->BtnName, d_connection, pHub->nBtnCount ); }
147 cout <<
"Cannot create button device " << pHub->BtnName << endl;
160BOOL vrpn_Tracker_G4::Connect(VOID)
162 if (!(pdiG4.CnxReady()))
164 if(pdiG4.ConnectG4(srcCalPath)){
165 cout<<
"G4: Connected\r\n";
169 cout<<
"G4: Already Connected\r\n";
172 return pdiG4.CnxReady();
176VOID vrpn_Tracker_G4::Disconnect(VOID)
179 if (!(pdiG4.CnxReady()))
181 cout <<
"G4: Already disconnected\r\n";
186 cout<<
"G4: Disconnected\r\n";
192BOOL vrpn_Tracker_G4::SetupDevice( VOID )
195 pdiG4.GetStationMap( dwStationMap );
196 while(dwStationMap == 0 && i<30)
199 pdiG4.GetStationMap( dwStationMap );
203 OriUnits = E_PDI_ORI_QUATERNION;
204 pdiG4.SetPNOOriUnits( OriUnits );
206 PosUnits = E_PDI_POS_METER;
207 pdiG4.SetPNOPosUnits( PosUnits );
209 pdiG4.SetPnoBuffer( pMotionBuf, VRPN_PDI_BUFFER_SIZE );
221 pch = strtok (pcmd,
"\n");
224 pcmd += strlen(pch) + 1;
227 pch = strtok (pcmd,
"\n");
244 if(dwStationMap != 0)
252VOID vrpn_Tracker_G4::UpdateStationMap( VOID )
254 pdiG4.GetStationMap( dwStationMap );
255 printf(
"Set GetStationMap Result: %s\r\n", pdiG4.GetLastResultStr() );
261void vrpn_Tracker_G4::sendCommand(
char *scmd)
263 char command = scmd[0];
264 printf(
"G4: Received Command: %s\n",scmd);
268 DoBoresightCmd(&scmd[1]);
279 DoIncrementCmd(scmd);
282 DoTipOffsetCmd(scmd);
296 printf(
"\tIgnoring 'U' command: VRPN Position Units standard is Meters.\r\n");
309 printf(
"\tIgnoring 'O' command: VRPN Orientation standard is Quaternion XYZW.\r\n");
312 printf(
"\tUnrecognized Command: %c\r\n", scmd[1]);
317#define CMD_ACTION_SET 1
318#define CMD_ACTION_RESET 2
319void vrpn_Tracker_G4::DoBoresightCmd(
char *scmd)
322 PDIori threeVec = {0.0,0.0,0.0};
323 PDI4vec fourVec = {1.0,0.0,0.0,0.0};
325 char delims[] =
",\n";
341 pAct = strtok(pArgs,comma);
348 nAction = pAct[0] -
'0';
350 pHub = strtok(NULL,comma);
357 nHub = (pHub[0] ==
'*') ? -1 : atoi(pHub);
359 pSens = strtok(NULL, delims);
366 nSensor = (pSens[0] ==
'*') ? -1 : atoi(pSens);
368 pRef = strtok(NULL, eol);
371 nParams += sscanf( pRef,
"%f,%f,%f,%f", &fP[1],&fP[2],&fP[3],&fP[0] );
379 printf(
"\tERROR: Invalid Boresight Command Syntax : B%s\r\n", scmd);
385 case (CMD_ACTION_SET):
388 pdiG4.SetSBoresight(nHub, nSensor, fP);
389 printf(
"\tSet Boresight Result: %s\r\n", pdiG4.GetLastResultStr() );
391 else if (nParams == 3)
393 pdiG4.SetSBoresight(nHub, nSensor, fourVec);
394 printf(
"\tSet Boresight Result: %s\r\n", pdiG4.GetLastResultStr() );
398 printf(
"\tERROR: Unexpected Boresight Argument count: %d\r\n", nParams);
401 case (CMD_ACTION_RESET):
402 pdiG4.ResetSBoresight(nHub, nSensor);
403 printf(
"\tReset Boresight Result: %s\r\n", pdiG4.GetLastResultStr() );
406 printf(
"\tERROR: Unrecognized Boresight Action: %s\r\n", pAct);
413void vrpn_Tracker_G4::DoFilterCmd(
char *scmd)
415 char delims[] =
",\n\r\\";
418 char * pArgs = &scmd[1];
431 float F=0, FLow=0, FHigh=0, Factor=0;
433 char * pLevelName = 0;
435 pAct = strtok(pArgs,comma);
442 nAction = pAct[0] -
'0';
445 pHub = strtok(NULL,delims);
452 nHub = (pHub[0] ==
'*') ? -1 : atoi(pHub);
455 if (nAction == CMD_ACTION_SET)
457 pLev = strtok(NULL, delims);
467 if (nLev == E_PDI_FILTER_CUSTOM)
469 pCust = strtok(NULL, eol);
476 nParams += sscanf( pCust,
"%f,%f,%f,%f", &f.m_fSensitivity,
479 &f.m_fMaxTransRate );
482 printf(
"\tERROR: Unexpected Filter Argument count: %d\r\n", nParams);
494 printf(
"\tERROR: Invalid Filter Command Syntax: %s\r\n", scmd);
498 if (nLev == E_PDI_FILTER_NONE)
500 nAction = CMD_ACTION_RESET;
505 case (CMD_ACTION_SET):
506 SetFilterPreset( nLev, f, &pLevelName);
509 pdiG4.SetHPosFilter( nHub, f);
513 pdiG4.SetHAttFilter( nHub, f);
515 printf(
"\tSet Filter Cmd %c %s Result: %s\r\n", cmd, pLevelName, pdiG4.GetLastResultStr() );
518 case (CMD_ACTION_RESET):
521 pdiG4.ResetHPosFilter( nHub );
525 pdiG4.ResetHAttFilter( nHub );
527 printf(
"\tReset Filter Cmd %c Result: %s\r\n", cmd, pdiG4.GetLastResultStr() );
531 printf(
"\tERROR: Unrecognized Filter Action: %c\r\n", *pAct);
538CPDIfilter FilterPresets[4] =
540 CPDIfilter(0.0f, 1.0f, 0.0f, 0.0f),
541 CPDIfilter(0.2f, 0.2f, 0.8f, 0.95f),
542 CPDIfilter(0.05f, 0.05f, 0.8f, 0.95f),
543 CPDIfilter(0.02f, 0.02f, 0.8f, 0.95f)
545char * PresetNames[5] =
547 "NONE",
"LIGHT",
"MEDIUM",
"HEAVY",
"CUSTOM"
550void vrpn_Tracker_G4::SetFilterPreset(
int nLev, CPDIfilter & f,
char **pLevName )
554 case E_PDI_FILTER_NONE:
555 case E_PDI_FILTER_LIGHT:
556 case E_PDI_FILTER_MED:
557 case E_PDI_FILTER_HEAVY:
558 f = FilterPresets[nLev];
559 *pLevName = PresetNames[nLev];
561 case E_PDI_FILTER_CUSTOM:
562 *pLevName = PresetNames[nLev];
565 f = FilterPresets[E_PDI_FILTER_HEAVY];
566 *pLevName = PresetNames[E_PDI_FILTER_HEAVY];
571void vrpn_Tracker_G4::DoFORCmd(
char *scmd )
573 char delims[] =
",\n\r\\";
576 char * pArgs = &scmd[1];
589 pAct = strtok(pArgs,comma);
596 nAction = pAct[0] -
'0';
599 if (nAction == CMD_ACTION_SET)
601 pFOR = strtok( NULL, eol );
608 nParams += sscanf( pFOR,
"%f,%f,%f", &pos[0], &pos[1], &pos[2] );
613 nParams += sscanf( pFOR,
"%f,%f,%f,%f", &qtrn[1], &qtrn[2], &qtrn[3], &qtrn[0] );
617 if (nParams != nParamSpec)
619 printf(
"\tERROR: Unexpected Frame of Reference %c Argument count: %d\r\n", cmd, nParams);
627 printf(
"\tERROR: Invalid Frame of Reference Command Syntax: %s\r\n", scmd);
633 case (CMD_ACTION_SET):
636 pdiG4.SetFrameOfRefTRANS( pos );
640 pdiG4.SetFrameOfRefROT( qtrn );
642 printf(
"\tSet Frame of Ref %c Result: %s\r\n", cmd, pdiG4.GetLastResultStr() );
645 case (CMD_ACTION_RESET):
648 pdiG4.ResetFrameOfRefTRANS();
652 pdiG4.ResetFrameOfRefROT();
654 printf(
"\tReset Frams of Ref Cmd %c Result: %s\r\n", cmd, pdiG4.GetLastResultStr() );
658 printf(
"\tERROR: Unrecognized Frame Of Reference Action: %c\r\n", *pAct);
668void vrpn_Tracker_G4::DoIncrementCmd(
char *scmd)
672 char delims[] =
" ,\r\n\\";
675 char *pArgs = &scmd[1];
688 float fPosIncr, fOriIncr;
691 pAct = strtok(pArgs,comma);
698 nAction = pAct[0] -
'0';
700 pHub = strtok(NULL,comma);
707 nHub = (pHub[0] ==
'*') ? -1 : atoi(pHub);
709 pSens = strtok(NULL, delims);
716 nSensor = (pSens[0] ==
'*') ? -1 : atoi(pSens);
719 if (nAction == CMD_ACTION_SET)
721 pIncrs = strtok(NULL, eol);
728 nParams += sscanf( pIncrs,
"%f,%f", &fPosIncr, &fOriIncr );
731 if (nParams != nParamSpec)
733 printf(
"\tERROR: Unexpected Increment Cmd Argument count: %d\r\n", nParams);
743 printf(
"\tERROR: Invalid Increment Command Syntax : %s\r\n", scmd);
747 pdiG4.SetPNOOriUnits(E_PDI_ORI_EULER_DEGREE);
748 printf(
"\tSet Ori Units DEGREES Result: %s\r\n", pdiG4.GetLastResultStr() );
751 case (CMD_ACTION_SET):
752 pdiG4.SetSIncrement(nHub, nSensor, fPosIncr, fOriIncr);
753 printf(
"\tSet Increment Result: %s\r\n", pdiG4.GetLastResultStr() );
756 case (CMD_ACTION_RESET):
757 pdiG4.ResetSIncrement(nHub, nSensor);
758 printf(
"\tReset Increment Result: %s\r\n", pdiG4.GetLastResultStr() );
762 printf(
"\tERROR: Unrecognized Increment Action: %s\r\n", pAct);
765 pdiG4.SetPNOOriUnits(E_PDI_ORI_QUATERNION);
766 printf(
"\tSet Ori Units QUATERNION Result: %s\r\n", pdiG4.GetLastResultStr() );
772void vrpn_Tracker_G4::DoTipOffsetCmd(
char *scmd)
776 char delims[] =
" ,\n\r\\";
779 char *pArgs = &scmd[1];
795 pAct = strtok(pArgs,comma);
802 nAction = pAct[0] -
'0';
804 pHub = strtok(NULL,comma);
811 nHub = (pHub[0] ==
'*') ? -1 : atoi(pHub);
813 pSens = strtok(NULL, delims);
820 nSensor = (pSens[0] ==
'*') ? -1 : atoi(pSens);
823 if (nAction == CMD_ACTION_SET)
825 pTO = strtok(NULL, eol);
832 nParams += sscanf( pTO,
"%f,%f,%f", &pos[0], &pos[1], &pos[2] );
835 if (nParams != nParamSpec)
837 printf(
"\tERROR: Unexpected Tip Offset Cmd Argument count: %d\r\n", nParams);
847 printf(
"\tERROR: Invalid Tip Offset Command Syntax : %s\r\n", scmd);
853 case (CMD_ACTION_SET):
854 pdiG4.SetSTipOffset(nHub, nSensor, pos);
855 printf(
"\tSet Tip Offset Result: %s\r\n", pdiG4.GetLastResultStr() );
857 case (CMD_ACTION_RESET):
858 pdiG4.ResetSTipOffset(nHub, nSensor);
859 printf(
"\tReset Tip Offset Result: %s\r\n", pdiG4.GetLastResultStr() );
862 printf(
"\tERROR: Unrecognized Tip Offset Action: %s\r\n", pAct);
872BOOL vrpn_Tracker_G4::StartCont( VOID )
874 cout<<
"G4: Start Continuous Mode\r\n";
878 if (!(pdiG4.StartContPnoG4(hwnd)))
892BOOL vrpn_Tracker_G4::StopCont( VOID )
894 cout<<
"G4: Stop Continuous Mode\r\n";
897 if (!(pdiG4.StopContPnoG4()))
907 ::ResetEvent(hContEvent);
913BOOL vrpn_Tracker_G4::DisplayCont( timeval ct )
921 if (!(pdiG4.LastPnoPtr(pBuf, dwSize)))
924 else if ((pBuf == 0) || (dwSize == 0))
927 else if (pLastBuf && (pBuf > pLastBuf))
929 ParseG4NativeFrame( pLastBuf+dwLastSize, dwSize+(pBuf-pLastBuf-dwLastSize), ct );
934 else if (pBuf != pLastBuf)
937 cout <<
"wrapped" << endl;
941 ParseG4NativeFrame( pBuf, dwSize, ct );
951BOOL vrpn_Tracker_G4::DisplaySingle( timeval ct )
957 if (!(pdiG4.ReadSinglePnoBufG4(pBuf, dwSize)))
961 else if ((pBuf == 0) || (dwSize == 0))
966 ParseG4NativeFrame( pBuf, dwSize, ct );
976void vrpn_Tracker_G4::ParseG4NativeFrame( PBYTE pBuf, DWORD dwSize, timeval current_time )
981 LPG4_HUBDATA pHubFrame;
985 pHubFrame = (LPG4_HUBDATA)(&pBuf[dw]);
987 dw +=
sizeof(G4_HUBDATA);
989 UINT nHubID = pHubFrame->nHubID;
990 UINT nFrameNum = pHubFrame->nFrameCount;
991 UINT nSensorMap = pHubFrame->dwSensorMap;
992 UINT nDigIO = pHubFrame->dwDigIO;
994 HUBMAP_ENTRY * pH = 0;
997 if (m_pHMap && (pH = m_pHMap->Find( nHubID )) && (nButtons = pH->nBtnCount) )
999 for (
int i=0; i<nButtons; i++)
1001 pH->pBtnSrv->set_button(i, (nDigIO & (1<<i)) >> i);
1002 pH->pBtnSrv->mainloop();
1008 for (
int j=0; j<G4_MAX_SENSORS_PER_HUB; j++)
1010 if (((nSensMask << j) & nSensorMap) != 0)
1012 G4_SENSORDATA * pSD = &(pHubFrame->sd[j]);
1013 d_sensor = (nHubID*10)+j;
1015 pos[0] = pSD->pos[0];
1016 pos[1] = pSD->pos[1];
1017 pos[2] = pSD->pos[2];
1019 quat[0] = pSD->ori[1];
1020 quat[1] = pSD->ori[2];
1021 quat[2] = pSD->ori[3];
1022 quat[3] = pSD->ori[0];
1025 timestamp.tv_sec = current_time.tv_sec;
1026 timestamp.tv_usec = current_time.tv_usec;
1030 len = encode_to(msgbuf);
1031 d_connection->pack_message(len, timestamp,
1032 position_m_id, d_sender_id, msgbuf,
1044vrpn_Tracker_FastrakPDI::vrpn_Tracker_FastrakPDI (
const char * name,
vrpn_Connection *cn,
1045 vrpn_float64 Hz,
const char * rcmd,
unsigned int nStylusMap) :
1047 , m_nStylusMap(nStylusMap)
1049 , m_nFrameSize(nStylusMap?33:31)
1051 cmd = (
char*)(rcmd);
1052 register_server_handlers();
1053 if(!(Initialize())){
1056 else if (nStylusMap & !(InitStylusBtns()))
1060 else if(!(Connect())){
1063 else if(!(SetupDevice())){
1065 cout <<
"FasTrakPDI: Device setup failed\r\n";
1067 else if(!(StartCont())){
1069 cout <<
"FastrakPDI: Failed to enter continuous mode\r\n";
1073 cout <<
"FastrakPDI: Initialization Complete\r\n";
1079vrpn_Tracker_FastrakPDI::~vrpn_Tracker_FastrakPDI(
void)
1085 for (
int i=0; i<FT_MAX_SENSORS; i++)
1087 if (FTstylusBtns[i]) {
1089 delete FTstylusBtns[i];
1091 fprintf(stderr,
"vrpn_Tracker_FastrakPDI::~vrpn_Tracker_FastrakPDI(): delete failed\n");
1099VOID vrpn_Tracker_FastrakPDI::mainloop()
1101 struct timeval current_time;
1109 DisplayCont(current_time);
1118int vrpn_Tracker_FastrakPDI::encode_to(
char *buf)
1138 return 1000 - buflen;
1143BOOL vrpn_Tracker_FastrakPDI::Initialize(VOID)
1147 pos[0]=0; pos[1]=0; pos[2]=0;
1148 d_quat[0]=0; d_quat[1]=0; d_quat[2]=0; d_quat[3]=0;
1150 memset( FTstylusBtns, 0,
sizeof(FTstylusBtns));
1154 dwOverflowCount = 0;
1157 pdiDev.Trace(TRUE, 5);
1165BOOL vrpn_Tracker_FastrakPDI::InitStylusBtns()
1169 for (
int i=0; i<FT_MAX_SENSORS; i++)
1171 if (((1<<i) & m_nStylusMap) != 0)
1174 snprintf( btnName, 512,
"%.450sStylus%d", d_servicename, i+1);
1178 cout <<
"Cannot create button device " << btnName << endl;
1183 cout <<
"Button device " << btnName <<
" created." << endl;
1191BOOL vrpn_Tracker_FastrakPDI::Connect( VOID )
1193 if (!(pdiDev.CnxReady()))
1195 pdiDev.SetSerialIF( &pdiSer );
1199 eType = pdiDev.DiscoverCnx();
1201 while (eType != PI_CNX_USB && eType != PI_CNX_SERIAL && attempts < 10){
1205 cout <<
"FastrakPDI: USB Connection\r\n";
1209 cout <<
"FastrakPDI: Serial Connection\r\n";
1213 printf(
"FastrakPDI: %s\r\n", pdiDev.GetLastResultStr() );
1214 eType = pdiDev.DiscoverCnx();
1222 num_sensors = pdiDev.StationCount();
1225 pdiDev.GetBITErrs( cBE );
1228 cBE.Parse( sz, 100 );
1230 if(!(cBE.IsClear()))
1231 pdiDev.ClearBITErrs();
1238 pdiMDat.Append(PDI_MODATA_STYLUS);
1240 pdiMDat.Append( PDI_MODATA_POS );
1241 pdiMDat.Append( PDI_MODATA_QTRN );
1242 pdiDev.SetSDataList( -1, pdiMDat );
1243 pdiDev.SetMetric(TRUE);
1247 pdiDev.SetPnoBuffer( pMotionBuf, VRPN_PDI_BUFFER_SIZE );
1251 bCnxReady = pdiDev.CnxReady();
1254 cout <<
"FastrakPDI: Already connected\r\n";
1262VOID vrpn_Tracker_FastrakPDI::Disconnect(VOID)
1265 if (!(pdiDev.CnxReady()))
1267 cout <<
"FastrakPDI: Already disconnected\r\n";
1271 pdiDev.Disconnect();
1272 cout <<
"FastrakPDI: Disconnected\r\n";
1278BOOL vrpn_Tracker_FastrakPDI::SetupDevice( VOID )
1281 if(strlen(pcmd) > 0){
1282 char * pch = strchr(pcmd,
'\\');
1283 while (pch != NULL){
1286 pcmd = pch +
sizeof(char);
1287 pch = strchr(pcmd,
'\\');
1293 if (isBinary == FALSE)
1294 cout <<
"FastrakPDI: Warning! Tracker is still in ASCII mode!\r\n";
1300VOID vrpn_Tracker_FastrakPDI::UpdateStationMap( VOID )
1302 pdiDev.GetStationMap( dwStationMap );
1306VOID vrpn_Tracker_FastrakPDI::SendCommand(
char *scmd){
1307 char szCmd[PI_MAX_CMD_BUF_LEN] =
"\0";
1308 DWORD dwRspSize = 5000;
1309 char szRsp[5000] =
"\0";
1310 bool parseErr =
false;
1313 cout <<
"FastrakPDI: reset command ";
1315 while (scmd[i] !=
'\0'){
1317 if (scmd[i] !=
'\n' && scmd[i] !=
'\r')
1322 for (i = 0; i < strlen(scmd); i++){
1328 strncat(szCmd,
"\x0b", 1);
1331 strncat(szCmd,
"\x11", 1);
1334 strncat(szCmd,
"\x13", 1);
1337 strncat(szCmd,
"\x19", 1);
1346 if (scmd[i] !=
'>'){
1351 strncat(szCmd,
"\r\n", 1);
1360 strncat(szCmd, &scmd[i], 1);
1368 CPDIdev * pDev = (CPDIdev*) (&pdiDev);
1370 if (parseErr ==
true)
1371 cout <<
"\r\n\t<unrecognized command>\r\n";
1373 strncat(szCmd,
"\0", 1);
1377 cout <<
"\r\n\t<command ignored, use P instead>\r\n";
1380 pDev->TxtCmd(szCmd,dwRspSize,szRsp);
1381 cout <<
"\r\n\t<tracker will be set to VRPN defaults on reconnect>\r\n";
1388 pDev->TxtCmd(szCmd,dwRspSize,szRsp);
1389 if (isBinary == TRUE)
1390 pdiDev.GetMetric(isMetric);
1393 pDev->SetBinary(TRUE);
1394 pdiDev.GetMetric(isMetric);
1395 pDev->SetBinary(FALSE);
1397 if (isMetric == FALSE)
1398 cout <<
"\r\n\t<position units set to inches>\r\n";
1400 cout <<
"\r\n\t<position units set to meters>\r\n";
1404 pDev->TxtCmd(szCmd,dwRspSize,szRsp);
1405 pdiDev.GetBinary(isBinary);
1406 if (isBinary == FALSE)
1407 cout <<
"\r\n\t<response frames set to ASCII>\r\n";
1409 cout <<
"\r\n\t<response frames set to binary>\r\n";
1412 cout <<
"\r\n\t<pno frame format changed (use extreme caution)>";
1414 if (isBinary == TRUE)
1415 cout <<
"\r\n\t<suggestion: use ASCII response frames (reset command F)>";
1417 pDev->TxtCmd(szCmd,dwRspSize,szRsp);
1418 if (dwRspSize != 0 && dwRspSize != 5000){
1419 if (isBinary == TRUE)
1420 cout <<
"\r\n\t<binary response bgn>\r\n\t";
1422 cout <<
"\r\n\t<ASCII response bgn>\r\n\t";
1423 for (i = 0; i < dwRspSize; i++){
1424 if (szRsp[i] !=
'\r')
1425 printf(
"%c",szRsp[i]);
1426 if (szRsp[i] ==
'\n')
1429 if (isBinary == TRUE)
1430 cout <<
"\r\n\t<binary response end>\r\n";
1432 cout <<
"\r\n\t<ASCII response end>\r\n";
1435 cout <<
"\r\n\t<command sent>\r\n";
1442BOOL vrpn_Tracker_FastrakPDI::StartCont( VOID )
1444 cout <<
"FastrakPDI: Start Continuous Mode\r\n";
1448 if (!(pdiDev.StartContPno(hwnd)))
1454 dwOverflowCount = 0;
1462BOOL vrpn_Tracker_FastrakPDI::StopCont( VOID )
1464 cout <<
"FastrakPDI: Stop Continuous Mode\r\n";
1467 if (!(pdiDev.StopContPno()))
1477 ::ResetEvent(hContEvent);
1483BOOL vrpn_Tracker_FastrakPDI::DisplayCont( timeval ct )
1490 if (!(pdiDev.LastPnoPtr(pBuf, dwSize)))
1493 else if ((pBuf == 0) || (dwSize == 0))
1496 else if (pLastBuf && (pBuf > pLastBuf))
1498 ParseFastrakFrame( pLastBuf+dwLastSize, dwSize+(pBuf-pLastBuf-dwLastSize), ct );
1500 dwLastSize = dwSize;
1503 else if (pBuf != pLastBuf)
1506 cout <<
"wrapped\r\n";
1509 dwLastSize = dwSize;
1510 ParseFastrakFrame( pBuf, dwSize, ct );
1519VOID vrpn_Tracker_FastrakPDI::DisplaySingle( timeval ct )
1528 if (!(pdiDev.ReadSinglePnoBuf(pBuf, dwSize)))
1532 else if ((pBuf == 0) || (dwSize == 0))
1537 ParseFastrakFrame( pBuf, dwSize, ct );
1543VOID vrpn_Tracker_FastrakPDI::ParseFastrakFrame( PBYTE pBuf, DWORD dwSize, timeval current_time )
1550 while (index < dwSize){
1552 BYTE ucSensor = pBuf[dw+1];
1553 BYTE ucInitCommand = pBuf[dw];
1554 BYTE ucErrorNum = pBuf[dw+2];
1555 d_sensor = atoi((
char*)(&ucSensor));
1558 dw += m_nHeaderSize;
1562 if (ucInitCommand !=
'0'){
1563 printf(
"FastrakPDI: received record type %x while in continuous mode, record error byte was %x \r\n", ucInitCommand, ucErrorNum);
1569 if ((m_nStylusMap & (1 << (d_sensor-1))) != 0)
1571 CHAR StyFlag = pBuf[dw+1];
1573 FTstylusBtns[d_sensor-1]->set_button(0, StyFlag -
'0');
1574 FTstylusBtns[d_sensor-1]->mainloop();
1579 PFLOAT pPno = (PFLOAT)(&pBuf[dw]);
1581 if (isMetric == TRUE){
1582 pos[0] = float(pPno[0])*CM_TO_METERS;
1583 pos[1] = float(pPno[1])*CM_TO_METERS;
1584 pos[2] = float(pPno[2])*CM_TO_METERS;
1587 pos[0] = float(pPno[0]);
1588 pos[1] = float(pPno[1]);
1589 pos[2] = float(pPno[2]);
1593 d_quat[0] = float(pPno[4]);
1594 d_quat[1] = float(pPno[5]);
1595 d_quat[2] = float(pPno[6]);
1596 d_quat[3] = float(pPno[3]);
1600 timestamp.tv_sec = current_time.tv_sec;
1601 timestamp.tv_usec = current_time.tv_usec;
1604 len = encode_to(msgbuf);
1605 d_connection->pack_message(len, timestamp,
1609 index += m_nFrameSize;
1614vrpn_Tracker_LibertyPDI::vrpn_Tracker_LibertyPDI (
const char * name,
vrpn_Connection *cn,
1615 vrpn_float64 Hz,
const char * rcmd,
unsigned int nStylusMap) :
1617 , m_nStylusMap(nStylusMap)
1619 , m_nFrameSize(nStylusMap?40:36)
1621 cmd = (
char*)(rcmd);
1622 register_server_handlers();
1623 if(!(Initialize())){
1626 else if (nStylusMap & !(InitStylusBtns()))
1630 else if(!(Connect())){
1633 else if(!(SetupDevice())){
1636 else if(!(StartCont())){
1638 cout <<
"LibertyPDI: Failed to enter continuous mode\r\n";
1642 cout <<
"LibertyPDI: Initialization Complete\r\n";
1648vrpn_Tracker_LibertyPDI::~vrpn_Tracker_LibertyPDI(
void){
1653 for (
int i=0; i<LIBERTY_MAX_SENSORS; i++)
1655 if (StylusBtns[i]) {
1657 delete StylusBtns[i];
1659 fprintf(stderr,
"vrpn_Tracker_LibertyPDI::~vrpn_Tracker_LibertyPDI(): delete failed\n");
1667VOID vrpn_Tracker_LibertyPDI::mainloop()
1669 struct timeval current_time;
1677 DisplayCont(current_time);
1686int vrpn_Tracker_LibertyPDI::encode_to(
char *buf)
1706 return 1000 - buflen;
1711BOOL vrpn_Tracker_LibertyPDI::Initialize(VOID){
1713 pos[0]=0; pos[1]=0; pos[2]=0;
1714 d_quat[0]=0; d_quat[1]=0; d_quat[2]=0; d_quat[3]=0;
1716 memset( StylusBtns, 0,
sizeof(StylusBtns));
1720 dwOverflowCount = 0;
1724 pdiDev.Trace(TRUE, 5);
1733BOOL vrpn_Tracker_LibertyPDI::InitStylusBtns()
1737 for (
int i=0; i<LIBERTY_MAX_SENSORS; i++)
1739 if (((1<<i) & m_nStylusMap) != 0)
1742 snprintf( btnName, 512,
"%.450sStylus%d", d_servicename, i+1);
1746 cout <<
"Cannot create button device " << btnName << endl;
1751 cout <<
"Button device " << btnName <<
" created." << endl;
1760BOOL vrpn_Tracker_LibertyPDI::Connect( VOID )
1762 if (!(pdiDev.CnxReady()))
1764 pdiDev.SetSerialIF( &pdiSer );
1768 eType = pdiDev.DiscoverCnx();
1770 while (eType != PI_CNX_USB && eType != PI_CNX_SERIAL && attempts < 10){
1774 cout <<
"LibertyPDI: USB Connection\r\n";
1778 cout <<
"LibertyPDI: Serial Connection\r\n";
1782 printf(
"LibertyPDI: %s\r\n", pdiDev.GetLastResultStr() );
1783 eType = pdiDev.DiscoverCnx();
1791 num_sensors = pdiDev.StationCount();
1794 pdiDev.GetBITErrs( cBE );
1797 cBE.Parse( sz, 100 );
1799 if(!(cBE.IsClear()))
1800 pdiDev.ClearBITErrs();
1806 pdiMDat.Append(PDI_MODATA_STYLUS);
1808 pdiMDat.Append( PDI_MODATA_POS );
1809 pdiMDat.Append( PDI_MODATA_QTRN );
1810 pdiDev.SetSDataList( -1, pdiMDat );
1812 pdiDev.SetMetric(TRUE);
1818 pdiDev.SetPnoBuffer( pMotionBuf, VRPN_PDI_BUFFER_SIZE );
1822 bCnxReady = pdiDev.CnxReady();
1825 cout <<
"LibertyPDI: Already connected\r\n";
1833VOID vrpn_Tracker_LibertyPDI::Disconnect(VOID)
1836 if (!(pdiDev.CnxReady()))
1838 cout <<
"LibertyPDI: Already disconnected\r\n";
1842 pdiDev.Disconnect();
1843 cout <<
"LibertyPDI: Disconnected\r\n";
1849BOOL vrpn_Tracker_LibertyPDI::SetupDevice( VOID )
1852 if(strlen(pcmd) > 0){
1853 char * pch = strchr(pcmd,
'\\');
1854 while (pch != NULL){
1857 pcmd = pch +
sizeof(char);
1858 pch = strchr(pcmd,
'\\');
1864 if (isBinary == FALSE)
1865 cout <<
"LibertyPDI: Warning! Tracker is still in ASCII mode!\r\n";
1871VOID vrpn_Tracker_LibertyPDI::UpdateStationMap( VOID )
1873 pdiDev.GetStationMap( dwStationMap );
1877VOID vrpn_Tracker_LibertyPDI::SendCommand(
char *scmd)
1879 char szCmd[PI_MAX_CMD_BUF_LEN] =
"\0";
1880 DWORD dwRspSize = 5000;
1881 char szRsp[5000] =
"\0";
1882 bool parseErr =
false;
1885 cout <<
"LibertyPDI: reset command ";
1887 while (scmd[i] !=
'\0'){
1889 if (scmd[i] !=
'\n' && scmd[i] !=
'\r')
1895 for (i = 0; i < strlen(scmd); i++){
1901 strncat(szCmd,
"\x01", 1);
1904 strncat(szCmd,
"\x02", 1);
1907 strncat(szCmd,
"\x04", 1);
1910 strncat(szCmd,
"\x05", 1);
1913 strncat(szCmd,
"\x06", 1);
1916 strncat(szCmd,
"\x07", 1);
1919 strncat(szCmd,
"\x0b", 1);
1922 strncat(szCmd,
"\x0c", 1);
1925 strncat(szCmd,
"\x0e", 1);
1928 strncat(szCmd,
"\x0f", 1);
1931 strncat(szCmd,
"\x10", 1);
1934 strncat(szCmd,
"\x12", 1);
1937 strncat(szCmd,
"\x13", 1);
1940 strncat(szCmd,
"\x14", 1);
1943 strncat(szCmd,
"\x15", 1);
1946 strncat(szCmd,
"\x16", 1);
1949 strncat(szCmd,
"\x17", 1);
1952 strncat(szCmd,
"\x18", 1);
1955 strncat(szCmd,
"\x19", 1);
1958 strncat(szCmd,
"\x1a", 1);
1967 if (scmd[i] !=
'>'){
1972 strncat(szCmd,
"\r\n", 1);
1981 strncat(szCmd, &scmd[i], 1);
1985 if (parseErr ==
true)
1986 cout <<
"\r\n\t<unrecognized command>\r\n";
1988 strncat(szCmd,
"\0", 1);
1992 cout <<
"\r\n\t<command ignored, use P instead>\r\n";
1995 pdiDev.TxtCmd(szCmd,dwRspSize,szRsp);
1996 cout <<
"\r\n\t<tracker will be set to VRPN defaults on reconnect>\r\n";
2002 pdiDev.TxtCmd(szCmd,dwRspSize,szRsp);
2003 if (isBinary == TRUE)
2004 pdiDev.GetMetric(isMetric);
2006 pdiDev.SetBinary(TRUE);
2007 pdiDev.GetMetric(isMetric);
2008 pdiDev.SetBinary(FALSE);
2010 if (isMetric == FALSE)
2011 cout <<
"\r\n\t<position units set to inches>\r\n";
2013 cout <<
"\r\n\t<position units set to meters>\r\n";
2016 pdiDev.TxtCmd(szCmd,dwRspSize,szRsp);
2017 pdiDev.GetBinary(isBinary);
2018 if (isBinary == FALSE)
2019 cout <<
"\r\n\t<response frames set to ascii>\r\n";
2021 cout <<
"\r\n\t<response frames set to binary>\r\n";
2024 pdiDev.TxtCmd(szCmd,dwRspSize,szRsp);
2025 cout <<
"\r\n\t<pno frame format changed (use extreme caution)>\r\n";
2028 pdiDev.TxtCmd(szCmd,dwRspSize,szRsp);
2029 if (isBinary == TRUE && dwRspSize != 0 && dwRspSize != 5000){
2030 char * pRsp = szRsp;
2032 if (*pRsp == 0x00 || *pRsp == 0x20)
2033 cout <<
"\r\n\t<binary response contained no error>\r\n";
2036 cout <<
"\r\n\t<binary error response bgn>\r\n\t";
2037 for (
int i = 2; i < 2 + short(*pRsp); i++){
2038 if (szRsp[i] !=
'\r')
2039 printf(
"%c",pRsp[i]);
2040 if (szRsp[i] ==
'\n')
2043 cout <<
"\r\n\t<binary error response end>\r\n";
2046 else if (dwRspSize != 0 && dwRspSize != 5000){
2047 cout <<
"\r\n\t<ASCII response bgn>\r\n\t";
2048 for (
unsigned int i = 0; i < dwRspSize; i++){
2049 if (szRsp[i] !=
'\r')
2050 printf(
"%c",szRsp[i]);
2051 if (szRsp[i] ==
'\n')
2054 cout <<
"\r\n\t<ASCII response end>\r\n";
2057 cout <<
"\r\n\t<command sent>\r\n";
2063BOOL vrpn_Tracker_LibertyPDI::StartCont( VOID )
2065 cout <<
"LibertyPDI: Start Continuous Mode\r\n";
2069 if (!(pdiDev.StartContPno(hwnd)))
2075 dwOverflowCount = 0;
2083BOOL vrpn_Tracker_LibertyPDI::StopCont( VOID )
2085 cout <<
"LibertyPDI: Stop Continuous Mode\r\n";
2088 if (!(pdiDev.StopContPno()))
2098 ::ResetEvent(hContEvent);
2104BOOL vrpn_Tracker_LibertyPDI::DisplayCont( timeval ct )
2111 if (!(pdiDev.LastPnoPtr(pBuf, dwSize)))
2114 else if ((pBuf == 0) || (dwSize == 0))
2117 else if (pLastBuf && (pBuf > pLastBuf))
2119 ParseLibertyFrame( pLastBuf+dwLastSize, dwSize+(pBuf-pLastBuf-dwLastSize), ct );
2121 dwLastSize = dwSize;
2124 else if (pBuf != pLastBuf)
2127 cout <<
"wrapped\n";
2130 dwLastSize = dwSize;
2131 ParseLibertyFrame( pBuf, dwSize, ct );
2140VOID vrpn_Tracker_LibertyPDI::DisplaySingle( timeval ct )
2149 if (!(pdiDev.ReadSinglePnoBuf(pBuf, dwSize)))
2153 else if ((pBuf == 0) || (dwSize == 0))
2158 ParseLibertyFrame( pBuf, dwSize, ct );
2164VOID vrpn_Tracker_LibertyPDI::ParseLibertyFrame( PBYTE pBuf, DWORD dwSize, timeval current_time )
2171 while (index < dwSize){
2173 BYTE ucSensor = pBuf[dw+2];
2174 BYTE ucInitCommand = pBuf[dw+3];
2175 BYTE ucErrorNum = pBuf[dw+4];
2176 SHORT shSize = pBuf[dw+6];
2177 d_sensor =
unsigned short(ucSensor);
2180 dw += m_nHeaderSize;
2184 if (ucInitCommand !=
'C' && ucInitCommand !=
'P'){
2185 printf(
"LibertyPDI: received command %x while in continuous mode, tracker response was %x \r\n", ucInitCommand, ucErrorNum);
2190 if ((m_nStylusMap & (1 << (d_sensor-1))) != 0)
2192 DWORD m_dwStylus = *((DWORD*)&pBuf[dw]);
2194 StylusBtns[d_sensor-1]->set_button(0, m_dwStylus);
2195 StylusBtns[d_sensor-1]->mainloop();
2197 dw +=
sizeof(DWORD);;
2201 PFLOAT pPno = (PFLOAT)(&pBuf[dw]);
2203 if (isMetric == TRUE){
2204 pos[0] = float(pPno[0])*CM_TO_METERS;
2205 pos[1] = float(pPno[1])*CM_TO_METERS;
2206 pos[2] = float(pPno[2])*CM_TO_METERS;
2209 pos[0] = float(pPno[0]);
2210 pos[1] = float(pPno[1]);
2211 pos[2] = float(pPno[2]);
2215 d_quat[0] = float(pPno[4]);
2216 d_quat[1] = float(pPno[5]);
2217 d_quat[2] = float(pPno[6]);
2218 d_quat[3] = float(pPno[3]);
2221 timestamp.tv_sec = current_time.tv_sec;
2222 timestamp.tv_usec = current_time.tv_usec;
2225 len = encode_to(msgbuf);
2226 d_connection->pack_message(len, timestamp,
2230 index += m_nFrameSize;
Generic connection class not specific to the transport mechanism.
const vrpn_uint32 vrpn_CONNECTION_LOW_LATENCY
unsigned long vrpn_TimevalDuration(struct timeval endT, struct timeval startT)
Return number of microseconds between startT and endT.
VRPN_API int vrpn_buffer(char **insertPt, vrpn_int32 *buflen, const timeval t)
Utility routine for placing a timeval struct into a buffer that is to be sent as a message.
#define vrpn_gettimeofday
const int vrpn_TRACKER_FAIL
const int vrpn_TRACKER_SYNCING
const int vrpn_TRACKER_REPORT_READY
class VRPN_API vrpn_Button_Server