sot-talos-balance  1.7.0
RTProtocol.cpp
Go to the documentation of this file.
1 #define _CRT_SECURE_NO_WARNINGS
2 #define NOMINMAX
3 
4 #include <float.h>
5 #include <cctype>
6 #include <thread>
7 #include <string.h>
8 #include <cmath>
9 #include <algorithm>
10 #include <locale>
11 
15 
16 #ifdef _WIN32
17 #include <iphlpapi.h>
18 // import the internet protocol helper library.
19 #pragma comment(lib, "IPHLPAPI.lib")
20 #else
21 #include <arpa/inet.h>
22 
23 #endif
24 
25 namespace
26 {
27  inline void ToLower(std::string& str)
28  {
29  std::transform(str.begin(), str.end(), str.begin(), [](int c)
30  {
31  return std::tolower(c);
32  });
33  }
34 
35  inline void RemoveInvalidChars(std::string& str)
36  {
37  auto isInvalidChar = [](int c) -> int
38  {
39  // iscntrl: control codes(NUL, etc.), '\t', '\n', '\v', '\f', '\r', backspace (DEL)
40  // isspace: some common checks but also 0x20 (SPACE)
41  // return != 0 --> invalid char
42  return std::iscntrl(c) + std::isspace(c);
43  };
44  str.erase(std::remove_if(str.begin(), str.end(), isInvalidChar), str.end());
45  }
46 
47 }
48 
50 {
51  mpoNetwork = new CNetwork();
52  mpoRTPacket = nullptr;
53  meLastEvent = CRTPacket::EventCaptureStopped;
55  mnMajorVersion = 1;
56  mnMinorVersion = 0;
57  mbBigEndian = false;
58  maErrorStr[0] = 0;
59  mnBroadcastPort = 0;
60  mpFileBuffer = nullptr;
61  mDataBuffSize = 65535;
62  maDataBuff = new char[mDataBuffSize];
63  mbIsMaster = false;
64 } // CRTProtocol
65 
66 
68 {
69  if (mpoNetwork)
70  {
71  delete mpoNetwork;
72  mpoNetwork = nullptr;
73  }
74  if (mpoRTPacket)
75  {
76  delete mpoRTPacket;
77  mpoRTPacket = nullptr;
78  }
79 } // ~CRTProtocol
80 
81 
82 bool CRTProtocol::Connect(const char* pServerAddr, unsigned short nPort, unsigned short* pnUDPServerPort, int nMajorVersion, int nMinorVersion, bool bBigEndian)
83 {
85  char tTemp[100];
86  char pResponseStr[256];
87 
88  mbBigEndian = bBigEndian;
89  mbIsMaster = false;
90 
91  mnMajorVersion = 1;
92  if ((nMajorVersion == 1) && (nMinorVersion == 0))
93  {
94  mnMinorVersion = 0;
95  }
96  else
97  {
98  mnMinorVersion = 1;
99  if (mbBigEndian)
100  {
101  nPort += 2;
102  }
103  else
104  {
105  nPort += 1;
106  }
107  }
108 
109  if (mpoRTPacket)
110  {
111  delete mpoRTPacket;
112  }
113  mpoRTPacket = new CRTPacket(nMajorVersion, nMinorVersion, bBigEndian);
114 
115  if (mpoRTPacket == nullptr)
116  {
117  strcpy(maErrorStr, "Could not allocate data packet.");
118  return false;
119  }
120 
121  if (mpoNetwork->Connect(pServerAddr, nPort))
122  {
123  if (pnUDPServerPort != nullptr)
124  {
125  if (mpoNetwork->CreateUDPSocket(*pnUDPServerPort) == false)
126  {
127  sprintf(maErrorStr, "CreateUDPSocket failed. %s", mpoNetwork->GetErrorString());
128  Disconnect();
129  return false;
130  }
131  }
132 
133  // Welcome message
134  auto received = ReceiveRTPacket(eType, true);
135  if (received > 0)
136  {
137  if (eType == CRTPacket::PacketError)
138  {
139  strcpy(maErrorStr, mpoRTPacket->GetErrorString());
140  Disconnect();
141  return false;
142  }
143  else if (eType == CRTPacket::PacketCommand)
144  {
145  const std::string welcomeMessage("QTM RT Interface connected");
146  if (strncmp(welcomeMessage.c_str(), mpoRTPacket->GetCommandString(), welcomeMessage.size()) == 0)
147  {
148  // Set protocol version
149  if (SetVersion(nMajorVersion, nMinorVersion))
150  {
151  // Set byte order.
152  // Unless we use protocol version 1.0, we have set the byte order by selecting the correct port.
153 
154  if ((mnMajorVersion == 1) && (mnMinorVersion == 0))
155  {
156  if (mbBigEndian)
157  {
158  strcpy(tTemp, "ByteOrder BigEndian");
159  }
160  else
161  {
162  strcpy(tTemp, "ByteOrder LittleEndian");
163  }
164 
165  if (SendCommand(tTemp, pResponseStr))
166  {
167  return true;
168  }
169  else
170  {
171  strcpy(maErrorStr, "Set byte order failed.");
172  }
173  }
174  else
175  {
176  GetState(meState, true);
177  return true;
178  }
179  }
180  Disconnect();
181  return false;
182  }
183  }
184  }
185  }
186  else
187  {
188  if (mpoNetwork->GetError() == 10061)
189  {
190  strcpy(maErrorStr, "Check if QTM is running on target machine.");
191  }
192  else
193  {
194  strcpy(maErrorStr, mpoNetwork->GetErrorString());
195  }
196  }
197  Disconnect();
198  return false;
199 } // Connect
200 
201 
203 {
204  if (mpoNetwork)
205  {
206  return mpoNetwork->GetUdpServerPort();
207  }
208  return 0;
209 }
210 
211 
213 {
214  mpoNetwork->Disconnect();
215  mnBroadcastPort = 0;
216  if (mpoRTPacket)
217  {
218  delete mpoRTPacket;
219  mpoRTPacket = nullptr;
220  }
221  mbIsMaster = false;
222 } // Disconnect
223 
224 
226 {
227  return mpoNetwork->Connected();
228 }
229 
230 
231 bool CRTProtocol::SetVersion(int nMajorVersion, int nMinorVersion)
232 {
233  char tTemp[256];
234  char pResponseStr[256];
235 
236  sprintf(tTemp, "Version %u.%u", nMajorVersion, nMinorVersion);
237 
238  if (SendCommand(tTemp, pResponseStr))
239  {
240  sprintf(tTemp, "Version set to %u.%u", nMajorVersion, nMinorVersion);
241 
242  if (strcmp(pResponseStr, tTemp) == 0)
243  {
244  mnMajorVersion = nMajorVersion;
245  mnMinorVersion = nMinorVersion;
246  mpoRTPacket->SetVersion(mnMajorVersion, mnMinorVersion);
247  return true;
248  }
249 
250  if (pResponseStr)
251  {
252  sprintf(maErrorStr, "%s.", pResponseStr);
253  }
254  else
255  {
256  strcpy(maErrorStr, "Set Version failed.");
257  }
258  }
259  else
260  {
261  strcpy(tTemp, maErrorStr);
262  sprintf(maErrorStr, "Send Version failed. %s.", tTemp);
263  }
264  return false;
265 }
266 
267 
268 bool CRTProtocol::GetVersion(unsigned int &nMajorVersion, unsigned int &nMinorVersion)
269 {
270  if (!Connected())
271  {
272  return false;
273  }
274 
275  nMajorVersion = mnMajorVersion;
276  nMinorVersion = mnMinorVersion;
277 
278  return true;
279 }
280 
281 
282 bool CRTProtocol::GetQTMVersion(char* pVersion, unsigned int nVersionLen)
283 {
284  if (SendCommand("QTMVersion", pVersion, nVersionLen))
285  {
286  return true;
287  }
288  strcpy(maErrorStr, "Get QTM Version failed.");
289  return false;
290 }
291 
292 
293 bool CRTProtocol::GetByteOrder(bool &bBigEndian)
294 {
295  char pResponseStr[256];
296 
297  if (SendCommand("ByteOrder", pResponseStr))
298  {
299  bBigEndian = (strcmp(pResponseStr, "Byte order is big endian") == 0);
300  return true;
301  }
302  strcpy(maErrorStr, "Get Byte order failed.");
303  return false;
304 }
305 
306 
307 bool CRTProtocol::CheckLicense(const char* pLicenseCode)
308 {
309  char tTemp[100];
310  char pResponseStr[256];
311 
312  if (strlen(pLicenseCode) <= 85)
313  {
314  sprintf(tTemp, "CheckLicense %s", pLicenseCode);
315 
316  if (SendCommand(tTemp, pResponseStr))
317  {
318  if (strcmp(pResponseStr, "License pass") == 0)
319  {
320  return true;
321  }
322  strcpy(maErrorStr, "Wrong license code.");
323  }
324  else
325  {
326  strcpy(maErrorStr, "CheckLicense failed.");
327  }
328  }
329  else
330  {
331  strcpy(maErrorStr, "License code too long.");
332  }
333  return false;
334 }
335 
336 
337 bool CRTProtocol::DiscoverRTServer(unsigned short nServerPort, bool bNoLocalResponses, unsigned short nDiscoverPort)
338 {
339  char pData[10];
340  SDiscoverResponse sResponse;
341 
342  if (mnBroadcastPort == 0)
343  {
344  if (!mpoNetwork->CreateUDPSocket(nServerPort, true))
345  {
346  strcpy(maErrorStr, mpoNetwork->GetErrorString());
347  return false;
348  }
349  mnBroadcastPort = nServerPort;
350  }
351  else
352  {
353  nServerPort = mnBroadcastPort;
354  }
355 
356  *((unsigned int*)pData) = (unsigned int)10;
357  *((unsigned int*)(pData + 4)) = (unsigned int)CRTPacket::PacketDiscover;
358  *((unsigned short*)(pData + 8)) = htons(nServerPort);
359 
360  if (mpoNetwork->SendUDPBroadcast(pData, 10, nDiscoverPort))
361  {
362  mvsDiscoverResponseList.clear();
363 
364  int nReceived;
365  do
366  {
367  unsigned int nAddr = 0;
368  nReceived = mpoNetwork->Receive(maDataBuff, mDataBuffSize, false, 100000, &nAddr);
369 
370  if (nReceived != -1 && nReceived > 8)
371  {
372  if (CRTPacket::GetType(maDataBuff) == CRTPacket::PacketCommand)
373  {
374  char* response = CRTPacket::GetCommandString(maDataBuff);
375  sResponse.nAddr = nAddr;
376  sResponse.nBasePort = CRTPacket::GetDiscoverResponseBasePort(maDataBuff);
377 
378  if (response && (!bNoLocalResponses || !mpoNetwork->IsLocalAddress(nAddr)))
379  {
380  strcpy(sResponse.message, response);
381  mvsDiscoverResponseList.push_back(sResponse);
382  }
383  }
384  }
385  } while (nReceived != -1 && nReceived > 8); // Keep reading until no more responses.
386 
387  return true;
388  }
389  return false;
390 }
391 
392 
394 {
395  return (int)mvsDiscoverResponseList.size();
396 }
397 
398 
399 bool CRTProtocol::GetDiscoverResponse(unsigned int nIndex, unsigned int &nAddr, unsigned short &nBasePort, std::string& message)
400 {
401  if (nIndex < mvsDiscoverResponseList.size())
402  {
403  nAddr = mvsDiscoverResponseList[nIndex].nAddr;
404  nBasePort = mvsDiscoverResponseList[nIndex].nBasePort;
405  message = mvsDiscoverResponseList[nIndex].message;
406  return true;
407  }
408  return false;
409 }
410 
411 
412 bool CRTProtocol::GetCurrentFrame(unsigned int nComponentType, const SComponentOptions& componentOptions)
413 {
414  char pCommandStr[256];
415  strcpy(pCommandStr, "GetCurrentFrame ");
416 
417  std::string::size_type nCommandStrSize = strlen(pCommandStr);
418  if (GetComponentString(pCommandStr + (int)nCommandStrSize, nComponentType, componentOptions))
419  {
420  if (SendCommand(pCommandStr))
421  {
422  return true;
423  }
424  strcpy(maErrorStr, "GetCurrentFrame failed.");
425  }
426  else
427  {
428  strcpy(maErrorStr, "DataComponent missing.");
429  }
430  return false;
431 }
432 
433 
434 bool CRTProtocol::StreamFrames(EStreamRate eRate, unsigned int nRateArg, unsigned short nUDPPort, const char* pUDPAddr,
435  unsigned int nComponentType, const SComponentOptions& componentOptions)
436 {
437  char pCommandStr[256];
438 
439  if (eRate == RateFrequencyDivisor)
440  {
441  sprintf(pCommandStr, "StreamFrames FrequencyDivisor:%d ", nRateArg);
442  }
443  else if (eRate == RateFrequency)
444  {
445  sprintf(pCommandStr, "StreamFrames Frequency:%d ", nRateArg);
446  }
447  else if (eRate == RateAllFrames)
448  {
449  sprintf(pCommandStr, "StreamFrames AllFrames ");
450  }
451  else
452  {
453  strcpy(maErrorStr, "No valid rate.");
454  return false;
455  }
456 
457  if (nUDPPort > 0)
458  {
459  if (pUDPAddr != nullptr && strlen(pUDPAddr) > 64)
460  {
461  strcpy(maErrorStr, "UDP address string too long.");
462  return false;
463  }
464  sprintf(pCommandStr, "%s UDP%s%s:%d ", pCommandStr, pUDPAddr != nullptr ? ":" : "", pUDPAddr != nullptr ? pUDPAddr : "", nUDPPort);
465  }
466 
467  std::string::size_type nCommandStrSize = strlen(pCommandStr);
468  if (GetComponentString(pCommandStr + (int)nCommandStrSize, nComponentType, componentOptions))
469  {
470  if (SendCommand(pCommandStr))
471  {
472  return true;
473  }
474  strcpy(maErrorStr, "StreamFrames failed.");
475  }
476  else
477  {
478  strcpy(maErrorStr, "DataComponent missing.");
479  }
480 
481  return false;
482 }
483 
484 
486 {
487  if (SendCommand("StreamFrames Stop"))
488  {
489  return true;
490  }
491  strcpy(maErrorStr, "StreamFrames Stop failed.");
492  return false;
493 }
494 
495 
496 bool CRTProtocol::GetState(CRTPacket::EEvent &eEvent, bool bUpdate, int nTimeout)
497 {
499 
500  if (bUpdate)
501  {
502  bool result;
503  if (mnMajorVersion > 1 || mnMinorVersion > 9)
504  {
505  result = SendCommand("GetState");
506  }
507  else
508  {
509  result = SendCommand("GetLastEvent");
510  }
511  if (result)
512  {
513  int nReceived;
514  do
515  {
516  nReceived = ReceiveRTPacket(eType, false, nTimeout);
517  if (nReceived > 0)
518  {
519  if (mpoRTPacket->GetEvent(eEvent))
520  {
521  return true;
522  }
523  }
524  } while (nReceived > 0);
525  }
526  strcpy(maErrorStr, "GetLastEvent failed.");
527  }
528  else
529  {
530  eEvent = meState;
531  return true;
532  }
533  return false;
534 }
535 
536 
537 bool CRTProtocol::GetCapture(const char* pFileName, bool bC3D)
538 {
540  char pResponseStr[256];
541 
542  mpFileBuffer = fopen(pFileName, "wb");
543  if (mpFileBuffer != nullptr)
544  {
545  if (bC3D)
546  {
547  // C3D file
548  if (SendCommand((mnMajorVersion > 1 || mnMinorVersion > 7) ? "GetCaptureC3D" : "GetCapture", pResponseStr))
549  {
550  if (strcmp(pResponseStr, "Sending capture") == 0)
551  {
552  if (ReceiveRTPacket(eType, true, 5000000) > 0) // Wait for C3D file in 5 seconds.
553  {
554  if (eType == CRTPacket::PacketC3DFile)
555  {
556  if (mpFileBuffer != nullptr)
557  {
558  fclose(mpFileBuffer);
559  return true;
560  }
561  strcpy(maErrorStr, "Writing C3D file failed.");
562  }
563  else
564  {
565  strcpy(maErrorStr, "Wrong packet type received.");
566  }
567  }
568  else
569  {
570  strcpy(maErrorStr, "No packet received.");
571  }
572  }
573  else
574  {
575  sprintf(maErrorStr, "%s failed.", (mnMajorVersion > 1 || mnMinorVersion > 7) ? "GetCaptureC3D" : "GetCapture");
576  }
577  }
578  else
579  {
580  sprintf(maErrorStr, "%s failed.", (mnMajorVersion > 1 || mnMinorVersion > 7) ? "GetCaptureC3D" : "GetCapture");
581  }
582  }
583  else
584  {
585  // QTM file
586  if (SendCommand("GetCaptureQTM", pResponseStr))
587  {
588  if (strcmp(pResponseStr, "Sending capture") == 0)
589  {
590  if (ReceiveRTPacket(eType, true, 5000000) > 0) // Wait for QTM file in 5 seconds.
591  {
592  if (eType == CRTPacket::PacketQTMFile)
593  {
594  if (mpFileBuffer != nullptr)
595  {
596  fclose(mpFileBuffer);
597  return true;
598  }
599  strcpy(maErrorStr, "Writing QTM file failed.");
600  }
601  else
602  {
603  strcpy(maErrorStr, "Wrong packet type received.");
604  }
605  }
606  else
607  {
608  sprintf(maErrorStr, "No packet received. %s.", maErrorStr);
609  }
610  }
611  else
612  {
613  strcpy(maErrorStr, "GetCaptureQTM failed.");
614  }
615  }
616  else
617  {
618  strcpy(maErrorStr, "GetCaptureQTM failed.");
619  }
620  }
621  }
622  if (mpFileBuffer)
623  {
624  fclose(mpFileBuffer);
625  }
626 
627  return false;
628 }
629 
630 
632 {
633  char pResponseStr[256];
634 
635  if (SendCommand("Trig", pResponseStr))
636  {
637  if (strcmp(pResponseStr, "Trig ok") == 0)
638  {
639  return true;
640  }
641  }
642  if (pResponseStr)
643  {
644  sprintf(maErrorStr, "%s.", pResponseStr);
645  }
646  else
647  {
648  strcpy(maErrorStr, "Trig failed.");
649  }
650  return false;
651 }
652 
653 
654 bool CRTProtocol::SetQTMEvent(const char* pLabel)
655 {
656  char tTemp[100];
657  char pResponseStr[256];
658 
659  if (strlen(pLabel) <= 92)
660  {
661  sprintf(tTemp, "%s %s", (mnMajorVersion > 1 || mnMinorVersion > 7) ? "SetQTMEvent" : "Event", pLabel);
662 
663  if (SendCommand(tTemp, pResponseStr))
664  {
665  if (strcmp(pResponseStr, "Event set") == 0)
666  {
667  return true;
668  }
669  }
670  if (pResponseStr)
671  {
672  sprintf(maErrorStr, "%s.", pResponseStr);
673  }
674  else
675  {
676  sprintf(maErrorStr, "%s failed.", (mnMajorVersion > 1 || mnMinorVersion > 7) ? "SetQTMEvent" : "Event");
677  }
678  }
679  else
680  {
681  strcpy(maErrorStr, "Event label too long.");
682  }
683  return false;
684 }
685 
686 
687 bool CRTProtocol::TakeControl(const char* pPassword)
688 {
689  char pResponseStr[256];
690  char pCmd[64];
691 
692  strcpy(pCmd, "TakeControl");
693  if (pPassword != nullptr)
694  {
695  // Add password
696  if (pPassword[0] != 0)
697  {
698  strcat(pCmd, " ");
699  strcat(pCmd, pPassword);
700  }
701  }
702  if (SendCommand(pCmd, pResponseStr))
703  {
704  if (strcmp("You are now master", pResponseStr) == 0 ||
705  strcmp("You are already master", pResponseStr) == 0)
706  {
707  mbIsMaster = true;
708  return true;
709  }
710  }
711  if (pResponseStr)
712  {
713  sprintf(maErrorStr, "%s.", pResponseStr);
714  }
715  else
716  {
717  strcpy(maErrorStr, "TakeControl failed.");
718  }
719  mbIsMaster = false;
720  return false;
721 } // TakeControl
722 
723 
725 {
726  char pResponseStr[256];
727 
728  if (SendCommand("ReleaseControl", pResponseStr))
729  {
730  if (strcmp("You are now a regular client", pResponseStr) == 0 ||
731  strcmp("You are already a regular client", pResponseStr) == 0)
732  {
733  mbIsMaster = false;
734  return true;
735  }
736  }
737  if (pResponseStr)
738  {
739  sprintf(maErrorStr, "%s.", pResponseStr);
740  }
741  else
742  {
743  strcpy(maErrorStr, "ReleaseControl failed.");
744  }
745  return false;
746 } // ReleaseControl
747 
748 
750 {
751  return mbIsMaster;
752 }
753 
754 
756 {
757  char pResponseStr[256];
758 
759  if (SendCommand("New", pResponseStr))
760  {
761  if (strcmp(pResponseStr, "Creating new connection") == 0 ||
762  strcmp(pResponseStr, "Already connected") == 0)
763  {
764  return true;
765  }
766  }
767  if (pResponseStr)
768  {
769  sprintf(maErrorStr, "%s.", pResponseStr);
770  }
771  else
772  {
773  strcpy(maErrorStr, "New failed.");
774  }
775  return false;
776 }
777 
779 {
780  char pResponseStr[256];
781 
782  if (SendCommand("Close", pResponseStr))
783  {
784  if (strcmp(pResponseStr, "Closing connection") == 0 ||
785  strcmp(pResponseStr, "File closed") == 0 ||
786  strcmp(pResponseStr, "Closing file") == 0 ||
787  strcmp(pResponseStr, "No connection to close") == 0)
788  {
789  return true;
790  }
791  }
792  if (pResponseStr)
793  {
794  sprintf(maErrorStr, "%s.", pResponseStr);
795  }
796  else
797  {
798  strcpy(maErrorStr, "Close failed.");
799  }
800  return false;
801 }
802 
803 
805 {
806  char pResponseStr[256];
807 
808  if (SendCommand("Start", pResponseStr))
809  {
810  if (strcmp(pResponseStr, "Starting measurement") == 0)
811  {
812  return true;
813  }
814  }
815  if (pResponseStr)
816  {
817  sprintf(maErrorStr, "%s.", pResponseStr);
818  }
819  else
820  {
821  strcpy(maErrorStr, "Start failed.");
822  }
823  return false;
824 }
825 
826 
828 {
829  char pResponseStr[256];
830 
831  if (SendCommand("Start rtfromfile", pResponseStr))
832  {
833  if (strcmp(pResponseStr, "Starting RT from file") == 0)
834  {
835  return true;
836  }
837  }
838  if (pResponseStr)
839  {
840  if (strcmp(pResponseStr, "RT from file already running") == 0)
841  {
842  return true;
843  }
844  sprintf(maErrorStr, "%s.", pResponseStr);
845  }
846  else
847  {
848  strcpy(maErrorStr, "Starting RT from file failed.");
849  }
850  return false;
851 }
852 
853 
855 {
856  char pResponseStr[256];
857 
858  if (SendCommand("Stop", pResponseStr))
859  {
860  if (strcmp(pResponseStr, "Stopping measurement") == 0)
861  {
862  return true;
863  }
864  }
865  if (pResponseStr)
866  {
867  sprintf(maErrorStr, "%s.", pResponseStr);
868  }
869  else
870  {
871  strcpy(maErrorStr, "Stop failed.");
872  }
873  return false;
874 }
875 
876 
877 bool CRTProtocol::LoadCapture(const char* pFileName)
878 {
879  char tTemp[100];
880  char pResponseStr[256];
881 
882  if (strlen(pFileName) <= 94)
883  {
884  sprintf(tTemp, "Load %s", pFileName);
885 
886  if (SendCommand(tTemp, pResponseStr, 20000000)) // Set timeout to 20 s for Load command.
887  {
888  if (strcmp(pResponseStr, "Measurement loaded") == 0)
889  {
890  return true;
891  }
892  }
893  if (strlen(pResponseStr) > 0)
894  {
895  sprintf(maErrorStr, "%s.", pResponseStr);
896  }
897  else
898  {
899  strcpy(maErrorStr, "Load failed.");
900  }
901  }
902  else
903  {
904  strcpy(maErrorStr, "File name too long.");
905  }
906  return false;
907 }
908 
909 
910 bool CRTProtocol::SaveCapture(const char* pFileName, bool bOverwrite, char* pNewFileName, int nSizeOfNewFileName)
911 {
912  char tTemp[100];
913  char pResponseStr[256];
914  char tNewFileNameTmp[300];
915 
916  tNewFileNameTmp[0] = 0;
917 
918  if (strlen(pFileName) <= 94)
919  {
920  sprintf(tTemp, "Save %s%s", pFileName, bOverwrite ? " Overwrite" : "");
921 
922  if (SendCommand(tTemp, pResponseStr))
923  {
924  if (strcmp(pResponseStr, "Measurement saved") == 0)
925  {
926  if (pNewFileName && nSizeOfNewFileName > 0)
927  {
928  pNewFileName[0] = 0;
929  }
930  return true;
931  }
932  if (sscanf(pResponseStr, "Measurement saved as '%[^']'", tNewFileNameTmp) == 1)
933  {
934  if (pNewFileName)
935  {
936  strcpy(pNewFileName, tNewFileNameTmp);
937  }
938  return true;
939  }
940  }
941  if (pResponseStr)
942  {
943  sprintf(maErrorStr, "%s.", pResponseStr);
944  }
945  else
946  {
947  strcpy(maErrorStr, "Save failed.");
948  }
949  }
950  else
951  {
952  strcpy(maErrorStr, "File name too long.");
953  }
954  return false;
955 }
956 
957 
958 bool CRTProtocol::LoadProject(const char* pFileName)
959 {
960  char tTemp[100];
961  char pResponseStr[256];
962 
963  if (strlen(pFileName) <= 94)
964  {
965  sprintf(tTemp, "LoadProject %s", pFileName);
966 
967  if (SendCommand(tTemp, pResponseStr))
968  {
969  if (strcmp(pResponseStr, "Project loaded") == 0)
970  {
971  return true;
972  }
973  }
974  if (pResponseStr)
975  {
976  sprintf(maErrorStr, "%s.", pResponseStr);
977  }
978  else
979  {
980  strcpy(maErrorStr, "Load project failed.");
981  }
982  }
983  else
984  {
985  strcpy(maErrorStr, "File name too long.");
986  }
987  return false;
988 }
989 
990 
992 {
993  char pResponseStr[256];
994 
995  if (SendCommand("Reprocess", pResponseStr))
996  {
997  if (strcmp(pResponseStr, "Reprocessing file") == 0)
998  {
999  return true;
1000  }
1001  }
1002  if (pResponseStr)
1003  {
1004  sprintf(maErrorStr, "%s.", pResponseStr);
1005  }
1006  else
1007  {
1008  strcpy(maErrorStr, "Reprocess failed.");
1009  }
1010  return false;
1011 }
1012 
1013 
1015 {
1016  switch (eEvent)
1017  {
1018  case CRTPacket::EventConnected: strcpy(pStr, "Connected");
1019  break;
1020  case CRTPacket::EventConnectionClosed: strcpy(pStr, "Connection Closed");
1021  break;
1022  case CRTPacket::EventCaptureStarted: strcpy(pStr, "Capture Started");
1023  break;
1024  case CRTPacket::EventCaptureStopped: strcpy(pStr, "Capture Stopped");
1025  break;
1026  case CRTPacket::EventCaptureFetchingFinished: strcpy(pStr, "Fetching Finished");
1027  break;
1028  case CRTPacket::EventCalibrationStarted: strcpy(pStr, "Calibration Started");
1029  break;
1030  case CRTPacket::EventCalibrationStopped: strcpy(pStr, "Calibration Finished");
1031  break;
1032  case CRTPacket::EventRTfromFileStarted: strcpy(pStr, "RT From File Started");
1033  break;
1034  case CRTPacket::EventRTfromFileStopped: strcpy(pStr, "RT From File Stopped");
1035  break;
1036  case CRTPacket::EventWaitingForTrigger: strcpy(pStr, "Waiting For Trigger");
1037  break;
1038  case CRTPacket::EventCameraSettingsChanged: strcpy(pStr, "Camera Settings Changed");
1039  break;
1040  case CRTPacket::EventQTMShuttingDown: strcpy(pStr, "QTM Shutting Down");
1041  break;
1042  case CRTPacket::EventCaptureSaved: strcpy(pStr, "Capture Saved");
1043  break;
1044  case CRTPacket::EventReprocessingStarted: strcpy(pStr, "Reprocessing Started");
1045  break;
1046  case CRTPacket::EventReprocessingStopped: strcpy(pStr, "Reprocessing Stopped");
1047  break;
1048  case CRTPacket::EventTrigger: strcpy(pStr, "Trigger");
1049  break;
1050  default:
1051  return false;
1052  }
1053  return true;
1054 }
1055 
1056 
1057 bool CRTProtocol::ConvertRateString(const char* pRate, EStreamRate &eRate, unsigned int &nRateArg)
1058 {
1059  std::string rateString;
1060 
1061  rateString.assign(pRate);
1062  std::transform(rateString.begin(), rateString.end(), rateString.begin(), ::tolower);
1063 
1064  eRate = RateNone;
1065 
1066  if (rateString.compare(0, 9, "allframes", 9) == 0)
1067  {
1068  eRate = RateAllFrames;
1069  }
1070  else if (rateString.compare(0, 10, "frequency:") == 0)
1071  {
1072  nRateArg = atoi(rateString.substr(10).c_str());
1073  if (nRateArg > 0)
1074  {
1075  eRate = RateFrequency;
1076  }
1077  }
1078  else if (rateString.compare(0, 17, "frequencydivisor:") == 0)
1079  {
1080  nRateArg = atoi(rateString.substr(17).c_str());
1081  if (nRateArg > 0)
1082  {
1083  eRate = RateFrequencyDivisor;
1084  }
1085  }
1086 
1087  return eRate != RateNone;
1088 }
1089 
1090 
1091 unsigned int CRTProtocol::ConvertComponentString(const char* pComponentType)
1092 {
1093  std::string componentString;
1094  unsigned int componentTypes = 0;
1095 
1096  componentString.assign(pComponentType);
1097  // Make string lower case.
1098  std::transform(componentString.begin(), componentString.end(), componentString.begin(), ::tolower);
1099 
1100  if (componentString.find("2d") != std::string::npos)
1101  {
1102  componentTypes += CRTProtocol::cComponent2d;
1103  }
1104  if (componentString.find("2dlin") != std::string::npos)
1105  {
1106  componentTypes += CRTProtocol::cComponent2dLin;
1107  }
1108  if (componentString.find("3d") != std::string::npos)
1109  {
1110  componentTypes += CRTProtocol::cComponent3d;
1111  }
1112  if (componentString.find("3dres") != std::string::npos)
1113  {
1114  componentTypes += CRTProtocol::cComponent3dRes;
1115  }
1116  if (componentString.find("3dnolabels") != std::string::npos)
1117  {
1118  componentTypes += CRTProtocol::cComponent3dNoLabels;
1119  }
1120  if (componentString.find("3dnolabelsres") != std::string::npos)
1121  {
1122  componentTypes += CRTProtocol::cComponent3dNoLabelsRes;
1123  }
1124  if (componentString.find("analog") != std::string::npos)
1125  {
1126  componentTypes += CRTProtocol::cComponentAnalog;
1127  }
1128  if (componentString.find("analogsingle") != std::string::npos)
1129  {
1130  componentTypes += CRTProtocol::cComponentAnalogSingle;
1131  }
1132  if (componentString.find("force") != std::string::npos)
1133  {
1134  componentTypes += CRTProtocol::cComponentForce;
1135  }
1136  if (componentString.find("forcesingle") != std::string::npos)
1137  {
1138  componentTypes += CRTProtocol::cComponentForceSingle;
1139  }
1140  if (componentString.find("6d") != std::string::npos)
1141  {
1142  componentTypes += CRTProtocol::cComponent6d;
1143  }
1144  if (componentString.find("6dres") != std::string::npos)
1145  {
1146  componentTypes += CRTProtocol::cComponent6dRes;
1147  }
1148  if (componentString.find("6deuler") != std::string::npos)
1149  {
1150  componentTypes += CRTProtocol::cComponent6dEuler;
1151  }
1152  if (componentString.find("6deulerres") != std::string::npos)
1153  {
1154  componentTypes += CRTProtocol::cComponent6dEulerRes;
1155  }
1156  if (componentString.find("image") != std::string::npos)
1157  {
1158  componentTypes += CRTProtocol::cComponentImage;
1159  }
1160  if (componentString.find("gazevector") != std::string::npos)
1161  {
1162  componentTypes += CRTProtocol::cComponentGazeVector;
1163  }
1164  if (componentString.find("timecode") != std::string::npos)
1165  {
1166  componentTypes += CRTProtocol::cComponentTimecode;
1167  }
1168  if (componentString.find("skeleton") != std::string::npos)
1169  {
1170  componentTypes += CRTProtocol::cComponentSkeleton;
1171  }
1172  return componentTypes;
1173 }
1174 
1175 
1176 bool CRTProtocol::GetComponentString(char* pComponentStr, unsigned int nComponentType, const SComponentOptions& options)
1177 {
1178  pComponentStr[0] = 0;
1179 
1180  if (nComponentType & cComponent2d)
1181  {
1182  strcat(pComponentStr, "2D ");
1183  }
1184  if (nComponentType & cComponent2dLin)
1185  {
1186  strcat(pComponentStr, "2DLin ");
1187  }
1188  if (nComponentType & cComponent3d)
1189  {
1190  strcat(pComponentStr, "3D ");
1191  }
1192  if (nComponentType & cComponent3dRes)
1193  {
1194  strcat(pComponentStr, "3DRes ");
1195  }
1196  if (nComponentType & cComponent3dNoLabels)
1197  {
1198  strcat(pComponentStr, "3DNoLabels ");
1199  }
1200  if (nComponentType & cComponent3dNoLabelsRes)
1201  {
1202  strcat(pComponentStr, "3DNoLabelsRes ");
1203  }
1204  if (nComponentType & cComponent6d)
1205  {
1206  strcat(pComponentStr, "6D ");
1207  }
1208  if (nComponentType & cComponent6dRes)
1209  {
1210  strcat(pComponentStr, "6DRes ");
1211  }
1212  if (nComponentType & cComponent6dEuler)
1213  {
1214  strcat(pComponentStr, "6DEuler ");
1215  }
1216  if (nComponentType & cComponent6dEulerRes)
1217  {
1218  strcat(pComponentStr, "6DEulerRes ");
1219  }
1220  if (nComponentType & cComponentAnalog)
1221  {
1222  strcat(pComponentStr, "Analog");
1223 
1224  if (options.mAnalogChannels != nullptr)
1225  {
1226  strcat(pComponentStr, ":");
1227  strcat(pComponentStr, options.mAnalogChannels);
1228  }
1229 
1230  strcat(pComponentStr, " ");
1231  }
1232  if (nComponentType & cComponentAnalogSingle)
1233  {
1234  strcat(pComponentStr, "AnalogSingle");
1235 
1236  if (options.mAnalogChannels != nullptr)
1237  {
1238  strcat(pComponentStr, ":");
1239  strcat(pComponentStr, options.mAnalogChannels);
1240  }
1241 
1242  strcat(pComponentStr, " ");
1243  }
1244  if (nComponentType & cComponentForce)
1245  {
1246  strcat(pComponentStr, "Force ");
1247  }
1248  if (nComponentType & cComponentForceSingle)
1249  {
1250  strcat(pComponentStr, "ForceSingle ");
1251  }
1252  if (nComponentType & cComponentGazeVector)
1253  {
1254  strcat(pComponentStr, "GazeVector ");
1255  }
1256  if (nComponentType & cComponentImage)
1257  {
1258  strcat(pComponentStr, "Image ");
1259  }
1260  if (nComponentType & cComponentTimecode)
1261  {
1262  strcat(pComponentStr, "Timecode ");
1263  }
1264  if (nComponentType & cComponentSkeleton)
1265  {
1266  strcat(pComponentStr, "Skeleton");
1267 
1268  if (options.mSkeletonGlobalData)
1269  {
1270  strcat(pComponentStr, ":global");
1271  }
1272 
1273  strcat(pComponentStr, " ");
1274  }
1275 
1276  return (pComponentStr[0] != 0);
1277 }
1278 
1279 
1280 int CRTProtocol::ReceiveRTPacket(CRTPacket::EPacketType &eType, bool bSkipEvents, int nTimeout)
1281 {
1282  int nRecved = 0;
1283  unsigned int nRecvedTotal = 0;
1284  unsigned int nFrameSize;
1285 
1286  eType = CRTPacket::PacketNone;
1287 
1288  do
1289  {
1290  nRecved = 0;
1291  nRecvedTotal = 0;
1292 
1293  nRecved = mpoNetwork->Receive(maDataBuff, mDataBuffSize, true, nTimeout);
1294  if (nRecved == 0)
1295  {
1296  // Receive timeout.
1297  strcpy(maErrorStr, "Data receive timeout.");
1298  return 0;
1299  }
1300  if (nRecved < (int)(sizeof(int) * 2))
1301  {
1302  // QTM header not received.
1303  strcpy(maErrorStr, "Couldn't read header bytes.");
1304  return -1;
1305  }
1306  if (nRecved <= -1)
1307  {
1308  strcpy(maErrorStr, "Socket Error.");
1309  return -1;
1310  }
1311  nRecvedTotal += nRecved;
1312 
1313  bool bBigEndian = (mbBigEndian || (mnMajorVersion == 1 && mnMinorVersion == 0));
1314  nFrameSize = mpoRTPacket->GetSize(maDataBuff, bBigEndian);
1315  eType = mpoRTPacket->GetType(maDataBuff, bBigEndian);
1316 
1317  unsigned int nReadSize;
1318 
1319  if (eType == CRTPacket::PacketC3DFile || eType == CRTPacket::PacketQTMFile)
1320  {
1321  if (mpFileBuffer != nullptr)
1322  {
1323  rewind(mpFileBuffer); // Start from the beginning
1324  if (fwrite(maDataBuff + sizeof(int) * 2, 1, nRecvedTotal - sizeof(int) * 2, mpFileBuffer) !=
1325  nRecvedTotal - sizeof(int) * 2)
1326  {
1327  strcpy(maErrorStr, "Failed to write file to disk.");
1328  fclose(mpFileBuffer);
1329  mpFileBuffer = nullptr;
1330  return -1;
1331  }
1332  // Receive more data until we have read the whole packet
1333  while (nRecvedTotal < nFrameSize)
1334  {
1335  nReadSize = nFrameSize - nRecvedTotal;
1336  if (nFrameSize > mDataBuffSize)
1337  {
1338  nReadSize = mDataBuffSize;
1339  }
1340  // As long as we haven't received enough data, wait for more
1341  nRecved = mpoNetwork->Receive(&(maDataBuff[sizeof(int) * 2]), nReadSize, false, nTimeout);
1342  if (nRecved <= 0)
1343  {
1344  strcpy(maErrorStr, "Socket Error.");
1345  fclose(mpFileBuffer);
1346  mpFileBuffer = nullptr;
1347  return -1;
1348  }
1349  if (fwrite(maDataBuff + sizeof(int) * 2, 1, nRecved, mpFileBuffer) != (size_t)nRecved)
1350  {
1351  strcpy(maErrorStr, "Failed to write file to disk.");
1352  fclose(mpFileBuffer);
1353  mpFileBuffer = nullptr;
1354  return -1;
1355  }
1356  nRecvedTotal += nRecved;
1357  }
1358  }
1359  else
1360  {
1361  strcpy(maErrorStr, "Receive file buffer not opened.");
1362  if (mpFileBuffer)
1363  {
1364  fclose(mpFileBuffer);
1365  }
1366  mpFileBuffer = nullptr;
1367  return -1;
1368  }
1369  }
1370  else
1371  {
1372  if (nFrameSize > mDataBuffSize)
1373  {
1374  char* buf = new char[nFrameSize];
1375  memcpy(buf, maDataBuff, mDataBuffSize);
1376  delete maDataBuff;
1377  maDataBuff = buf;
1378  mDataBuffSize = nFrameSize;
1379  }
1380 
1381  // Receive more data until we have read the whole packet
1382  while (nRecvedTotal < nFrameSize)
1383  {
1384  // As long as we haven't received enough data, wait for more
1385  nRecved = mpoNetwork->Receive(&(maDataBuff[nRecvedTotal]), nFrameSize - nRecvedTotal, false, nTimeout);
1386  if (nRecved <= 0)
1387  {
1388  strcpy(maErrorStr, "Socket Error.");
1389  return -1;
1390  }
1391  nRecvedTotal += nRecved;
1392  }
1393  }
1394 
1395  mpoRTPacket->SetData(maDataBuff);
1396  if (mpoRTPacket->GetEvent(meLastEvent)) // Update last event if there is an event
1397  {
1398  if (meLastEvent != CRTPacket::EventCameraSettingsChanged)
1399  {
1400  meState = meLastEvent;
1401  }
1402  }
1403  } while (bSkipEvents && eType == CRTPacket::PacketEvent);
1404 
1405  if (nRecvedTotal == nFrameSize)
1406  {
1407  return nRecvedTotal;
1408  }
1409  strcpy(maErrorStr, "Packet truncated.");
1410 
1411  return -1;
1412 } // ReceiveRTPacket
1413 
1414 
1416 {
1417  return mpoRTPacket;
1418 }
1419 
1420 
1421 bool CRTProtocol::ReadXmlBool(CMarkup* xml, const std::string& element, bool& value) const
1422 {
1423  if (!xml->FindChildElem(element.c_str()))
1424  {
1425  return false;
1426  }
1427 
1428  auto str = xml->GetChildData();
1429  RemoveInvalidChars(str);
1430  ToLower(str);
1431 
1432  if (str == "true")
1433  {
1434  value = true;
1435  }
1436  else if (str == "false")
1437  {
1438  value = false;
1439  }
1440  else
1441  {
1442  // Don't change value, just report error.
1443  return false;
1444  }
1445 
1446  return true;
1447 }
1448 
1450 {
1451  CRTPacket::EPacketType eType;
1452  CMarkup oXML;
1453  std::string tStr;
1454 
1455  msGeneralSettings.vsCameras.clear();
1456 
1457  if (!SendCommand("GetParameters General"))
1458  {
1459  strcpy(maErrorStr, "GetParameters General failed");
1460  return false;
1461  }
1462 
1463  auto received = ReceiveRTPacket(eType, true);
1464  if (received <= 0)
1465  {
1466  if (received == 0)
1467  {
1468  // Receive timeout.
1469  strcat(maErrorStr, " Expected XML packet.");
1470  }
1471  return false;
1472  }
1473 
1474  if (eType != CRTPacket::PacketXML)
1475  {
1476  if (eType == CRTPacket::PacketError)
1477  {
1478  sprintf(maErrorStr, "%s.", mpoRTPacket->GetErrorString());
1479  }
1480  else
1481  {
1482  sprintf(maErrorStr, "GetParameters General returned wrong packet type. Got type %d expected type 2.", eType);
1483  }
1484  return false;
1485  }
1486 
1487  oXML.SetDoc(mpoRTPacket->GetXMLString());
1488 
1489  // ==================== General ====================
1490  if (!oXML.FindChildElem("General"))
1491  {
1492  return false;
1493  }
1494  oXML.IntoElem();
1495 
1496  if (!oXML.FindChildElem("Frequency"))
1497  {
1498  return false;
1499  }
1500  msGeneralSettings.nCaptureFrequency = atoi(oXML.GetChildData().c_str());
1501 
1502  if (!oXML.FindChildElem("Capture_Time"))
1503  {
1504  return false;
1505  }
1506  msGeneralSettings.fCaptureTime = (float)atof(oXML.GetChildData().c_str());
1507 
1508  // Refactored variant of all this copy/paste code. TODO: Refactor everything else.
1509  if (!ReadXmlBool(&oXML, "Start_On_External_Trigger", msGeneralSettings.bStartOnExternalTrigger))
1510  {
1511  return false;
1512  }
1513  if (mnMajorVersion > 1 || mnMinorVersion > 14)
1514  {
1515  if (!ReadXmlBool(&oXML, "Start_On_Trigger_NO", msGeneralSettings.bStartOnTrigNO))
1516  {
1517  return false;
1518  }
1519  if (!ReadXmlBool(&oXML, "Start_On_Trigger_NC", msGeneralSettings.bStartOnTrigNC))
1520  {
1521  return false;
1522  }
1523  if (!ReadXmlBool(&oXML, "Start_On_Trigger_Software", msGeneralSettings.bStartOnTrigSoftware))
1524  {
1525  return false;
1526  }
1527  }
1528 
1529  // ==================== External time base ====================
1530  if (!oXML.FindChildElem("External_Time_Base"))
1531  {
1532  return false;
1533  }
1534  oXML.IntoElem();
1535 
1536  if (!oXML.FindChildElem("Enabled"))
1537  {
1538  return false;
1539  }
1540  tStr = oXML.GetChildData();
1541  std::transform(tStr.begin(), tStr.end(), tStr.begin(), ::tolower);
1542  msGeneralSettings.sExternalTimebase.bEnabled = (tStr == "true");
1543 
1544  if (!oXML.FindChildElem("Signal_Source"))
1545  {
1546  return false;
1547  }
1548  tStr = oXML.GetChildData();
1549  std::transform(tStr.begin(), tStr.end(), tStr.begin(), ::tolower);
1550  if (tStr == "control port")
1551  {
1552  msGeneralSettings.sExternalTimebase.eSignalSource = SourceControlPort;
1553  }
1554  else if (tStr == "ir receiver")
1555  {
1556  msGeneralSettings.sExternalTimebase.eSignalSource = SourceIRReceiver;
1557  }
1558  else if (tStr == "smpte")
1559  {
1560  msGeneralSettings.sExternalTimebase.eSignalSource = SourceSMPTE;
1561  }
1562  else if (tStr == "irig")
1563  {
1564  msGeneralSettings.sExternalTimebase.eSignalSource = SourceIRIG;
1565  }
1566  else if (tStr == "video sync")
1567  {
1568  msGeneralSettings.sExternalTimebase.eSignalSource = SourceVideoSync;
1569  }
1570  else
1571  {
1572  return false;
1573  }
1574 
1575  if (!oXML.FindChildElem("Signal_Mode"))
1576  {
1577  return false;
1578  }
1579  tStr = oXML.GetChildData();
1580  std::transform(tStr.begin(), tStr.end(), tStr.begin(), ::tolower);
1581  if (tStr == "periodic")
1582  {
1583  msGeneralSettings.sExternalTimebase.bSignalModePeriodic = true;
1584  }
1585  else if (tStr == "non-periodic")
1586  {
1587  msGeneralSettings.sExternalTimebase.bSignalModePeriodic = false;
1588  }
1589  else
1590  {
1591  return false;
1592  }
1593 
1594  if (!oXML.FindChildElem("Frequency_Multiplier"))
1595  {
1596  return false;
1597  }
1598  unsigned int nMultiplier;
1599  tStr = oXML.GetChildData();
1600  if (sscanf(tStr.c_str(), "%u", &nMultiplier) == 1)
1601  {
1602  msGeneralSettings.sExternalTimebase.nFreqMultiplier = nMultiplier;
1603  }
1604  else
1605  {
1606  return false;
1607  }
1608 
1609  if (!oXML.FindChildElem("Frequency_Divisor"))
1610  {
1611  return false;
1612  }
1613  unsigned int nDivisor;
1614  tStr = oXML.GetChildData();
1615  if (sscanf(tStr.c_str(), "%u", &nDivisor) == 1)
1616  {
1617  msGeneralSettings.sExternalTimebase.nFreqDivisor = nDivisor;
1618  }
1619  else
1620  {
1621  return false;
1622  }
1623 
1624  if (!oXML.FindChildElem("Frequency_Tolerance"))
1625  {
1626  return false;
1627  }
1628  unsigned int nTolerance;
1629  tStr = oXML.GetChildData();
1630  if (sscanf(tStr.c_str(), "%u", &nTolerance) == 1)
1631  {
1632  msGeneralSettings.sExternalTimebase.nFreqTolerance = nTolerance;
1633  }
1634  else
1635  {
1636  return false;
1637  }
1638 
1639  if (!oXML.FindChildElem("Nominal_Frequency"))
1640  {
1641  return false;
1642  }
1643  tStr = oXML.GetChildData();
1644  std::transform(tStr.begin(), tStr.end(), tStr.begin(), ::tolower);
1645 
1646  if (tStr == "none")
1647  {
1648  msGeneralSettings.sExternalTimebase.fNominalFrequency = -1; // -1 = disabled
1649  }
1650  else
1651  {
1652  float fFrequency;
1653  if (sscanf(tStr.c_str(), "%f", &fFrequency) == 1)
1654  {
1655  msGeneralSettings.sExternalTimebase.fNominalFrequency = fFrequency;
1656  }
1657  else
1658  {
1659  return false;
1660  }
1661  }
1662 
1663  if (!oXML.FindChildElem("Signal_Edge"))
1664  {
1665  return false;
1666  }
1667  tStr = oXML.GetChildData();
1668  std::transform(tStr.begin(), tStr.end(), tStr.begin(), ::tolower);
1669  if (tStr == "negative")
1670  {
1671  msGeneralSettings.sExternalTimebase.bNegativeEdge = true;
1672  }
1673  else if (tStr == "positive")
1674  {
1675  msGeneralSettings.sExternalTimebase.bNegativeEdge = false;
1676  }
1677  else
1678  {
1679  return false;
1680  }
1681 
1682  if (!oXML.FindChildElem("Signal_Shutter_Delay"))
1683  {
1684  return false;
1685  }
1686  unsigned int nDelay;
1687  tStr = oXML.GetChildData();
1688  if (sscanf(tStr.c_str(), "%u", &nDelay) == 1)
1689  {
1690  msGeneralSettings.sExternalTimebase.nSignalShutterDelay = nDelay;
1691  }
1692  else
1693  {
1694  return false;
1695  }
1696 
1697  if (!oXML.FindChildElem("Non_Periodic_Timeout"))
1698  {
1699  return false;
1700  }
1701  float fTimeout;
1702  tStr = oXML.GetChildData();
1703  if (sscanf(tStr.c_str(), "%f", &fTimeout) == 1)
1704  {
1705  msGeneralSettings.sExternalTimebase.fNonPeriodicTimeout = fTimeout;
1706  }
1707  else
1708  {
1709  return false;
1710  }
1711 
1712  oXML.OutOfElem(); // External_Time_Base
1713 
1714  const char* processings[3] = { "Processing_Actions", "RealTime_Processing_Actions", "Reprocessing_Actions" };
1715  EProcessingActions* processingActions[3] =
1716  {
1717  &msGeneralSettings.eProcessingActions,
1718  &msGeneralSettings.eRtProcessingActions,
1719  &msGeneralSettings.eReprocessingActions
1720  };
1721  auto actionsCount = (mnMajorVersion > 1 || mnMinorVersion > 13) ? 3 : 1;
1722  for (auto i = 0; i < actionsCount; i++)
1723  {
1724  // ==================== Processing actions ====================
1725  if (!oXML.FindChildElem(processings[i]))
1726  {
1727  return false;
1728  }
1729  oXML.IntoElem();
1730 
1731  *processingActions[i] = ProcessingNone;
1732 
1733  if (mnMajorVersion > 1 || mnMinorVersion > 13)
1734  {
1735  if (!oXML.FindChildElem("PreProcessing2D"))
1736  {
1737  return false;
1738  }
1739  if (CompareNoCase(oXML.GetChildData(), "true"))
1740  {
1741  *processingActions[i] = (EProcessingActions)(*processingActions[i] + ProcessingPreProcess2D);
1742  }
1743  }
1744 
1745  if (!oXML.FindChildElem("Tracking"))
1746  {
1747  return false;
1748  }
1749  tStr = oXML.GetChildData();
1750  std::transform(tStr.begin(), tStr.end(), tStr.begin(), ::tolower);
1751  if (tStr == "3d")
1752  {
1753  *processingActions[i] = (EProcessingActions)(*processingActions[i] + ProcessingTracking3D);
1754  }
1755  else if (tStr == "2d" && i != 1) // i != 1 => Not RtProcessingSettings
1756  {
1757  *processingActions[i] = (EProcessingActions)(*processingActions[i] + ProcessingTracking2D);
1758  }
1759 
1760  if (i != 1) //Not RtProcessingSettings
1761  {
1762  if (!oXML.FindChildElem("TwinSystemMerge"))
1763  {
1764  return false;
1765  }
1766  if (CompareNoCase(oXML.GetChildData(), "true"))
1767  {
1768  *processingActions[i] = (EProcessingActions)(*processingActions[i] + ProcessingTwinSystemMerge);
1769  }
1770 
1771  if (!oXML.FindChildElem("SplineFill"))
1772  {
1773  return false;
1774  }
1775  if (CompareNoCase(oXML.GetChildData(), "true"))
1776  {
1777  *processingActions[i] = (EProcessingActions)(*processingActions[i] + ProcessingSplineFill);
1778  }
1779  }
1780 
1781  if (!oXML.FindChildElem("AIM"))
1782  {
1783  return false;
1784  }
1785  if (CompareNoCase(oXML.GetChildData(), "true"))
1786  {
1787  *processingActions[i] = (EProcessingActions)(*processingActions[i] + ProcessingAIM);
1788  }
1789 
1790  if (!oXML.FindChildElem("Track6DOF"))
1791  {
1792  return false;
1793  }
1794  if (CompareNoCase(oXML.GetChildData(), "true"))
1795  {
1796  *processingActions[i] = (EProcessingActions)(*processingActions[i] + Processing6DOFTracking);
1797  }
1798 
1799  if (!oXML.FindChildElem("ForceData"))
1800  {
1801  return false;
1802  }
1803  if (CompareNoCase(oXML.GetChildData(), "true"))
1804  {
1805  *processingActions[i] = (EProcessingActions)(*processingActions[i] + ProcessingForceData);
1806  }
1807 
1808  if (mnMajorVersion > 1 || mnMinorVersion > 11)
1809  {
1810  if (!oXML.FindChildElem("GazeVector"))
1811  {
1812  return false;
1813  }
1814  if (CompareNoCase(oXML.GetChildData(), "true"))
1815  {
1816  *processingActions[i] = (EProcessingActions)(*processingActions[i] + ProcessingGazeVector);
1817  }
1818  }
1819 
1820  if (i != 1) //Not RtProcessingSettings
1821  {
1822  if (!oXML.FindChildElem("ExportTSV"))
1823  {
1824  return false;
1825  }
1826  if (CompareNoCase(oXML.GetChildData(), "true"))
1827  {
1828  *processingActions[i] = (EProcessingActions)(*processingActions[i] + ProcessingExportTSV);
1829  }
1830 
1831  if (!oXML.FindChildElem("ExportC3D"))
1832  {
1833  return false;
1834  }
1835  if (CompareNoCase(oXML.GetChildData(), "true"))
1836  {
1837  *processingActions[i] = (EProcessingActions)(*processingActions[i] + ProcessingExportC3D);
1838  }
1839 
1840  if (!oXML.FindChildElem("ExportMatlabFile"))
1841  {
1842  return false;
1843  }
1844  if (CompareNoCase(oXML.GetChildData(), "true"))
1845  {
1846  *processingActions[i] = (EProcessingActions)(*processingActions[i] + ProcessingExportMatlabFile);
1847  }
1848 
1849  if (mnMajorVersion > 1 || mnMinorVersion > 11)
1850  {
1851  if (!oXML.FindChildElem("ExportAviFile"))
1852  {
1853  return false;
1854  }
1855  if (CompareNoCase(oXML.GetChildData(), "true"))
1856  {
1857  *processingActions[i] = (EProcessingActions)(*processingActions[i] + ProcessingExportAviFile);
1858  }
1859  }
1860  }
1861  oXML.OutOfElem(); // Processing_Actions
1862  }
1863 
1864 
1865  // ==================== Camera ====================
1866  msGeneralSettings.sCameraSystem.eType = ECameraSystemType::Unknown;
1867  if (oXML.FindChildElem("Camera_System") && oXML.IntoElem())
1868  {
1869  if (oXML.FindChildElem("Type"))
1870  {
1871  tStr = oXML.GetChildData();
1872  if (CompareNoCase(tStr, "oqus"))
1873  {
1874  msGeneralSettings.sCameraSystem.eType = ECameraSystemType::Oqus;
1875  }
1876  else if (CompareNoCase(tStr, "miqus"))
1877  {
1878  msGeneralSettings.sCameraSystem.eType = ECameraSystemType::Miqus;
1879  }
1880  }
1881  oXML.OutOfElem();
1882  }
1883 
1884 
1885  SSettingsGeneralCamera sCameraSettings;
1886 
1887  while (oXML.FindChildElem("Camera"))
1888  {
1889  oXML.IntoElem();
1890 
1891  if (!oXML.FindChildElem("ID"))
1892  {
1893  return false;
1894  }
1895  sCameraSettings.nID = atoi(oXML.GetChildData().c_str());
1896 
1897  if (!oXML.FindChildElem("Model"))
1898  {
1899  return false;
1900  }
1901  tStr = oXML.GetChildData();
1902  std::transform(tStr.begin(), tStr.end(), tStr.begin(), ::tolower);
1903 
1904  if (tStr == "macreflex")
1905  {
1906  sCameraSettings.eModel = ModelMacReflex;
1907  }
1908  else if (tStr == "proreflex 120")
1909  {
1910  sCameraSettings.eModel = ModelProReflex120;
1911  }
1912  else if (tStr == "proreflex 240")
1913  {
1914  sCameraSettings.eModel = ModelProReflex240;
1915  }
1916  else if (tStr == "proreflex 500")
1917  {
1918  sCameraSettings.eModel = ModelProReflex500;
1919  }
1920  else if (tStr == "proreflex 1000")
1921  {
1922  sCameraSettings.eModel = ModelProReflex1000;
1923  }
1924  else if (tStr == "oqus 100")
1925  {
1926  sCameraSettings.eModel = ModelOqus100;
1927  }
1928  else if (tStr == "oqus 200" || tStr == "oqus 200 c")
1929  {
1930  sCameraSettings.eModel = ModelOqus200C;
1931  }
1932  else if (tStr == "oqus 300")
1933  {
1934  sCameraSettings.eModel = ModelOqus300;
1935  }
1936  else if (tStr == "oqus 300 plus")
1937  {
1938  sCameraSettings.eModel = ModelOqus300Plus;
1939  }
1940  else if (tStr == "oqus 400")
1941  {
1942  sCameraSettings.eModel = ModelOqus400;
1943  }
1944  else if (tStr == "oqus 500")
1945  {
1946  sCameraSettings.eModel = ModelOqus500;
1947  }
1948  else if (tStr == "oqus 500 plus")
1949  {
1950  sCameraSettings.eModel = ModelOqus500Plus;
1951  }
1952  else if (tStr == "oqus 700")
1953  {
1954  sCameraSettings.eModel = ModelOqus700;
1955  }
1956  else if (tStr == "oqus 700 plus")
1957  {
1958  sCameraSettings.eModel = ModelOqus700Plus;
1959  }
1960  else if (tStr == "oqus 600 plus")
1961  {
1962  sCameraSettings.eModel = ModelOqus600Plus;
1963  }
1964  else if (tStr == "miqus m1")
1965  {
1966  sCameraSettings.eModel = ModelMiqusM1;
1967  }
1968  else if (tStr == "miqus m3")
1969  {
1970  sCameraSettings.eModel = ModelMiqusM3;
1971  }
1972  else if (tStr == "miqus m5")
1973  {
1974  sCameraSettings.eModel = ModelMiqusM5;
1975  }
1976  else if (tStr == "miqus sync unit")
1977  {
1978  sCameraSettings.eModel = ModelMiqusSyncUnit;
1979  }
1980  else if (tStr == "miqus video")
1981  {
1982  sCameraSettings.eModel = ModelMiqusVideo;
1983  }
1984  else if (tStr == "miqus video color")
1985  {
1986  sCameraSettings.eModel = ModelMiqusVideoColor;
1987  }
1988  else
1989  {
1990  return false;
1991  }
1992 
1993  // Only available from protocol version 1.10 and later.
1994  if (oXML.FindChildElem("Underwater"))
1995  {
1996  tStr = oXML.GetChildData();
1997  std::transform(tStr.begin(), tStr.end(), tStr.begin(), ::tolower);
1998  sCameraSettings.bUnderwater = (tStr == "true");
1999  }
2000 
2001  if (oXML.FindChildElem("Supports_HW_Sync"))
2002  {
2003  tStr = oXML.GetChildData();
2004  std::transform(tStr.begin(), tStr.end(), tStr.begin(), ::tolower);
2005  sCameraSettings.bSupportsHwSync = (tStr == "true");
2006  }
2007 
2008  if (!oXML.FindChildElem("Serial"))
2009  {
2010  return false;
2011  }
2012  sCameraSettings.nSerial = atoi(oXML.GetChildData().c_str());
2013 
2014  // ==================== Camera Mode ====================
2015  if (!oXML.FindChildElem("Mode"))
2016  {
2017  return false;
2018  }
2019  tStr = oXML.GetChildData();
2020  std::transform(tStr.begin(), tStr.end(), tStr.begin(), ::tolower);
2021  if (tStr == "marker")
2022  {
2023  sCameraSettings.eMode = ModeMarker;
2024  }
2025  else if (tStr == "marker intensity")
2026  {
2027  sCameraSettings.eMode = ModeMarkerIntensity;
2028  }
2029  else if (tStr == "video")
2030  {
2031  sCameraSettings.eMode = ModeVideo;
2032  }
2033  else
2034  {
2035  return false;
2036  }
2037 
2038  if (mnMajorVersion > 1 || mnMinorVersion > 11)
2039  {
2040  // ==================== Video frequency ====================
2041  if (!oXML.FindChildElem("Video_Frequency"))
2042  {
2043  return false;
2044  }
2045  sCameraSettings.nVideoFrequency = atoi(oXML.GetChildData().c_str());
2046  }
2047 
2048  // ==================== Video Resolution ====================
2049  if (oXML.FindChildElem("Video_Resolution"))
2050  {
2051  tStr = oXML.GetChildData();
2052  std::transform(tStr.begin(), tStr.end(), tStr.begin(), ::tolower);
2053  if (tStr == "1080p")
2054  {
2055  sCameraSettings.eVideoResolution = VideoResolution1080p;
2056  }
2057  else if (tStr == "720p")
2058  {
2059  sCameraSettings.eVideoResolution = VideoResolution720p;
2060  }
2061  else if (tStr == "540p")
2062  {
2063  sCameraSettings.eVideoResolution = VideoResolution540p;
2064  }
2065  else if (tStr == "480p")
2066  {
2067  sCameraSettings.eVideoResolution = VideoResolution480p;
2068  }
2069  }
2070  else
2071  {
2072  sCameraSettings.eVideoResolution = VideoResolutionNone;
2073  }
2074 
2075  // ==================== Video AspectRatio ====================
2076  if (oXML.FindChildElem("Video_Aspect_Ratio"))
2077  {
2078  tStr = oXML.GetChildData();
2079  std::transform(tStr.begin(), tStr.end(), tStr.begin(), ::tolower);
2080  if (tStr == "16x9")
2081  {
2082  sCameraSettings.eVideoAspectRatio = VideoAspectRatio16x9;
2083  }
2084  else if (tStr == "4x3")
2085  {
2086  sCameraSettings.eVideoAspectRatio = VideoAspectRatio4x3;
2087  }
2088  else if (tStr == "1x1")
2089  {
2090  sCameraSettings.eVideoAspectRatio = VideoAspectRatio1x1;
2091  }
2092  }
2093  else
2094  {
2095  sCameraSettings.eVideoAspectRatio = VideoAspectRatioNone;
2096  }
2097 
2098  // ==================== Video exposure ====================
2099  if (!oXML.FindChildElem("Video_Exposure"))
2100  {
2101  return false;
2102  }
2103  oXML.IntoElem();
2104 
2105  if (!oXML.FindChildElem("Current"))
2106  {
2107  return false;
2108  }
2109  sCameraSettings.nVideoExposure = atoi(oXML.GetChildData().c_str());
2110 
2111  if (!oXML.FindChildElem("Min"))
2112  {
2113  return false;
2114  }
2115  sCameraSettings.nVideoExposureMin = atoi(oXML.GetChildData().c_str());
2116 
2117  if (!oXML.FindChildElem("Max"))
2118  {
2119  return false;
2120  }
2121  sCameraSettings.nVideoExposureMax = atoi(oXML.GetChildData().c_str());
2122  oXML.OutOfElem(); // Video_Exposure
2123 
2124  // ==================== Video flash time ====================
2125  if (!oXML.FindChildElem("Video_Flash_Time"))
2126  {
2127  return false;
2128  }
2129  oXML.IntoElem();
2130 
2131  if (!oXML.FindChildElem("Current"))
2132  {
2133  return false;
2134  }
2135  sCameraSettings.nVideoFlashTime = atoi(oXML.GetChildData().c_str());
2136 
2137  if (!oXML.FindChildElem("Min"))
2138  {
2139  return false;
2140  }
2141  sCameraSettings.nVideoFlashTimeMin = atoi(oXML.GetChildData().c_str());
2142 
2143  if (!oXML.FindChildElem("Max"))
2144  {
2145  return false;
2146  }
2147  sCameraSettings.nVideoFlashTimeMax = atoi(oXML.GetChildData().c_str());
2148  oXML.OutOfElem(); // Video_Flash_Time
2149 
2150  // ==================== Marker exposure ====================
2151  if (!oXML.FindChildElem("Marker_Exposure"))
2152  {
2153  return false;
2154  }
2155  oXML.IntoElem();
2156 
2157  if (!oXML.FindChildElem("Current"))
2158  {
2159  return false;
2160  }
2161  sCameraSettings.nMarkerExposure = atoi(oXML.GetChildData().c_str());
2162 
2163  if (!oXML.FindChildElem("Min"))
2164  {
2165  return false;
2166  }
2167  sCameraSettings.nMarkerExposureMin = atoi(oXML.GetChildData().c_str());
2168 
2169  if (!oXML.FindChildElem("Max"))
2170  {
2171  return false;
2172  }
2173  sCameraSettings.nMarkerExposureMax = atoi(oXML.GetChildData().c_str());
2174 
2175  oXML.OutOfElem(); // Marker_Exposure
2176 
2177  // ==================== Marker threshold ====================
2178  if (!oXML.FindChildElem("Marker_Threshold"))
2179  {
2180  return false;
2181  }
2182  oXML.IntoElem();
2183 
2184  if (!oXML.FindChildElem("Current"))
2185  {
2186  return false;
2187  }
2188  sCameraSettings.nMarkerThreshold = atoi(oXML.GetChildData().c_str());
2189 
2190  if (!oXML.FindChildElem("Min"))
2191  {
2192  return false;
2193  }
2194  sCameraSettings.nMarkerThresholdMin = atoi(oXML.GetChildData().c_str());
2195 
2196  if (!oXML.FindChildElem("Max"))
2197  {
2198  return false;
2199  }
2200  sCameraSettings.nMarkerThresholdMax = atoi(oXML.GetChildData().c_str());
2201 
2202  oXML.OutOfElem(); // Marker_Threshold
2203 
2204  // ==================== Position ====================
2205  if (!oXML.FindChildElem("Position"))
2206  {
2207  return false;
2208  }
2209  oXML.IntoElem();
2210 
2211  if (!oXML.FindChildElem("X"))
2212  {
2213  return false;
2214  }
2215  sCameraSettings.fPositionX = (float)atoi(oXML.GetChildData().c_str());
2216 
2217  if (!oXML.FindChildElem("Y"))
2218  {
2219  return false;
2220  }
2221  sCameraSettings.fPositionY = (float)atoi(oXML.GetChildData().c_str());
2222 
2223  if (!oXML.FindChildElem("Z"))
2224  {
2225  return false;
2226  }
2227  sCameraSettings.fPositionZ = (float)atoi(oXML.GetChildData().c_str());
2228 
2229  if (!oXML.FindChildElem("Rot_1_1"))
2230  {
2231  return false;
2232  }
2233  sCameraSettings.fPositionRotMatrix[0][0] = (float)atof(oXML.GetChildData().c_str());
2234 
2235  if (!oXML.FindChildElem("Rot_2_1"))
2236  {
2237  return false;
2238  }
2239  sCameraSettings.fPositionRotMatrix[1][0] = (float)atof(oXML.GetChildData().c_str());
2240 
2241  if (!oXML.FindChildElem("Rot_3_1"))
2242  {
2243  return false;
2244  }
2245  sCameraSettings.fPositionRotMatrix[2][0] = (float)atof(oXML.GetChildData().c_str());
2246 
2247  if (!oXML.FindChildElem("Rot_1_2"))
2248  {
2249  return false;
2250  }
2251  sCameraSettings.fPositionRotMatrix[0][1] = (float)atof(oXML.GetChildData().c_str());
2252 
2253  if (!oXML.FindChildElem("Rot_2_2"))
2254  {
2255  return false;
2256  }
2257  sCameraSettings.fPositionRotMatrix[1][1] = (float)atof(oXML.GetChildData().c_str());
2258 
2259  if (!oXML.FindChildElem("Rot_3_2"))
2260  {
2261  return false;
2262  }
2263  sCameraSettings.fPositionRotMatrix[2][1] = (float)atof(oXML.GetChildData().c_str());
2264 
2265  if (!oXML.FindChildElem("Rot_1_3"))
2266  {
2267  return false;
2268  }
2269  sCameraSettings.fPositionRotMatrix[0][2] = (float)atof(oXML.GetChildData().c_str());
2270 
2271  if (!oXML.FindChildElem("Rot_2_3"))
2272  {
2273  return false;
2274  }
2275  sCameraSettings.fPositionRotMatrix[1][2] = (float)atof(oXML.GetChildData().c_str());
2276 
2277  if (!oXML.FindChildElem("Rot_3_3"))
2278  {
2279  return false;
2280  }
2281  sCameraSettings.fPositionRotMatrix[2][2] = (float)atof(oXML.GetChildData().c_str());
2282 
2283  oXML.OutOfElem(); // Position
2284 
2285 
2286  if (!oXML.FindChildElem("Orientation"))
2287  {
2288  return false;
2289  }
2290  sCameraSettings.nOrientation = atoi(oXML.GetChildData().c_str());
2291 
2292  // ==================== Marker exposure ====================
2293  if (!oXML.FindChildElem("Marker_Res"))
2294  {
2295  return false;
2296  }
2297  oXML.IntoElem();
2298 
2299  if (!oXML.FindChildElem("Width"))
2300  {
2301  return false;
2302  }
2303  sCameraSettings.nMarkerResolutionWidth = atoi(oXML.GetChildData().c_str());
2304 
2305  if (!oXML.FindChildElem("Height"))
2306  {
2307  return false;
2308  }
2309  sCameraSettings.nMarkerResolutionHeight = atoi(oXML.GetChildData().c_str());
2310 
2311  oXML.OutOfElem(); // Marker_Res
2312 
2313  // ==================== Marker resolution ====================
2314  if (!oXML.FindChildElem("Video_Res"))
2315  {
2316  return false;
2317  }
2318  oXML.IntoElem();
2319 
2320  if (!oXML.FindChildElem("Width"))
2321  {
2322  return false;
2323  }
2324  sCameraSettings.nVideoResolutionWidth = atoi(oXML.GetChildData().c_str());
2325 
2326  if (!oXML.FindChildElem("Height"))
2327  {
2328  return false;
2329  }
2330  sCameraSettings.nVideoResolutionHeight = atoi(oXML.GetChildData().c_str());
2331 
2332  oXML.OutOfElem(); // Video_Res
2333 
2334  // ==================== Marker FOV ====================
2335  if (!oXML.FindChildElem("Marker_FOV"))
2336  {
2337  return false;
2338  }
2339  oXML.IntoElem();
2340 
2341  if (!oXML.FindChildElem("Left"))
2342  {
2343  return false;
2344  }
2345  sCameraSettings.nMarkerFOVLeft = atoi(oXML.GetChildData().c_str());
2346 
2347  if (!oXML.FindChildElem("Top"))
2348  {
2349  return false;
2350  }
2351  sCameraSettings.nMarkerFOVTop = atoi(oXML.GetChildData().c_str());
2352 
2353  if (!oXML.FindChildElem("Right"))
2354  {
2355  return false;
2356  }
2357  sCameraSettings.nMarkerFOVRight = atoi(oXML.GetChildData().c_str());
2358 
2359  if (!oXML.FindChildElem("Bottom"))
2360  {
2361  return false;
2362  }
2363  sCameraSettings.nMarkerFOVBottom = atoi(oXML.GetChildData().c_str());
2364 
2365  oXML.OutOfElem(); // Marker_FOV
2366 
2367  // ==================== Video FOV ====================
2368  if (!oXML.FindChildElem("Video_FOV"))
2369  {
2370  return false;
2371  }
2372  oXML.IntoElem();
2373 
2374  if (!oXML.FindChildElem("Left"))
2375  {
2376  return false;
2377  }
2378  sCameraSettings.nVideoFOVLeft = atoi(oXML.GetChildData().c_str());
2379 
2380  if (!oXML.FindChildElem("Top"))
2381  {
2382  return false;
2383  }
2384  sCameraSettings.nVideoFOVTop = atoi(oXML.GetChildData().c_str());
2385 
2386  if (!oXML.FindChildElem("Right"))
2387  {
2388  return false;
2389  }
2390  sCameraSettings.nVideoFOVRight = atoi(oXML.GetChildData().c_str());
2391 
2392  if (!oXML.FindChildElem("Bottom"))
2393  {
2394  return false;
2395  }
2396  sCameraSettings.nVideoFOVBottom = atoi(oXML.GetChildData().c_str());
2397 
2398  oXML.OutOfElem(); // Video_FOV
2399 
2400  // ==================== Sync out ====================
2401  // Only available from protocol version 1.10 and later.
2402  for (int port = 0; port < 3; port++)
2403  {
2404  char syncOutStr[16];
2405  sprintf(syncOutStr, "Sync_Out%s", port == 0 ? "" : (port == 1 ? "2" : "_MT"));
2406  if (oXML.FindChildElem(syncOutStr))
2407  {
2408  oXML.IntoElem();
2409 
2410  if (port < 2)
2411  {
2412  if (!oXML.FindChildElem("Mode"))
2413  {
2414  return false;
2415  }
2416  tStr = oXML.GetChildData();
2417  std::transform(tStr.begin(), tStr.end(), tStr.begin(), ::tolower);
2418  if (tStr == "shutter out")
2419  {
2420  sCameraSettings.eSyncOutMode[port] = ModeShutterOut;
2421  }
2422  else if (tStr == "multiplier")
2423  {
2424  sCameraSettings.eSyncOutMode[port] = ModeMultiplier;
2425  }
2426  else if (tStr == "divisor")
2427  {
2428  sCameraSettings.eSyncOutMode[port] = ModeDivisor;
2429  }
2430  else if (tStr == "camera independent")
2431  {
2432  sCameraSettings.eSyncOutMode[port] = ModeActualFreq;
2433  }
2434  else if (tStr == "measurement time")
2435  {
2436  sCameraSettings.eSyncOutMode[port] = ModeMeasurementTime;
2437  }
2438  else if (tStr == "continuous 100hz")
2439  {
2440  sCameraSettings.eSyncOutMode[port] = ModeFixed100Hz;
2441  }
2442  else
2443  {
2444  return false;
2445  }
2446 
2447  if (sCameraSettings.eSyncOutMode[port] == ModeMultiplier ||
2448  sCameraSettings.eSyncOutMode[port] == ModeDivisor ||
2449  sCameraSettings.eSyncOutMode[port] == ModeActualFreq)
2450  {
2451  if (!oXML.FindChildElem("Value"))
2452  {
2453  return false;
2454  }
2455  sCameraSettings.nSyncOutValue[port] = atoi(oXML.GetChildData().c_str());
2456 
2457  if (!oXML.FindChildElem("Duty_Cycle"))
2458  {
2459  return false;
2460  }
2461  sCameraSettings.fSyncOutDutyCycle[port] = (float)atof(oXML.GetChildData().c_str());
2462  }
2463  }
2464  if (port == 2 ||
2465  (sCameraSettings.eSyncOutMode[port] != ModeFixed100Hz))
2466  {
2467  if (!oXML.FindChildElem("Signal_Polarity"))
2468  {
2469  return false;
2470  }
2471  if (CompareNoCase(oXML.GetChildData(), "negative"))
2472  {
2473  sCameraSettings.bSyncOutNegativePolarity[port] = true;
2474  }
2475  else
2476  {
2477  sCameraSettings.bSyncOutNegativePolarity[port] = false;
2478  }
2479  }
2480  oXML.OutOfElem(); // Sync_Out
2481  }
2482  else
2483  {
2484  sCameraSettings.eSyncOutMode[port] = ModeActualFreq;
2485  sCameraSettings.nSyncOutValue[port] = 0;
2486  sCameraSettings.fSyncOutDutyCycle[port] = 0;
2487  sCameraSettings.bSyncOutNegativePolarity[port] = false;
2488  }
2489  }
2490 
2491  if (oXML.FindChildElem("LensControl"))
2492  {
2493  oXML.IntoElem();
2494  if (oXML.FindChildElem("Focus"))
2495  {
2496  oXML.IntoElem();
2497  float focus;
2498  if (sscanf(oXML.GetAttrib("Value").c_str(), "%f", &focus) == 1)
2499  {
2500  sCameraSettings.fFocus = focus;
2501  }
2502  oXML.OutOfElem();
2503  }
2504  if (oXML.FindChildElem("Aperture"))
2505  {
2506  oXML.IntoElem();
2507  float aperture;
2508  if (sscanf(oXML.GetAttrib("Value").c_str(), "%f", &aperture) == 1)
2509  {
2510  sCameraSettings.fAperture = aperture;
2511  }
2512  oXML.OutOfElem();
2513  }
2514  oXML.OutOfElem();
2515  }
2516  else
2517  {
2518  sCameraSettings.fFocus = std::numeric_limits<float>::quiet_NaN();
2519  sCameraSettings.fAperture = std::numeric_limits<float>::quiet_NaN();
2520  }
2521 
2522  if (oXML.FindChildElem("AutoExposure"))
2523  {
2524  oXML.IntoElem();
2525  if (CompareNoCase(oXML.GetAttrib("Enabled"), "true"))
2526  {
2527  sCameraSettings.autoExposureEnabled = true;
2528  }
2529  float autoExposureCompensation;
2530  if (sscanf(oXML.GetAttrib("Compensation").c_str(), "%f", &autoExposureCompensation) == 1)
2531  {
2532  sCameraSettings.autoExposureCompensation = autoExposureCompensation;
2533  }
2534  oXML.OutOfElem();
2535  }
2536  else
2537  {
2538  sCameraSettings.autoExposureEnabled = false;
2539  sCameraSettings.autoExposureCompensation = std::numeric_limits<float>::quiet_NaN();
2540  }
2541 
2542  if (oXML.FindChildElem("AutoWhiteBalance"))
2543  {
2544  sCameraSettings.autoWhiteBalance = CompareNoCase(oXML.GetChildData().c_str(), "true") ? 1 : 0;
2545  }
2546  else
2547  {
2548  sCameraSettings.autoWhiteBalance = -1;
2549  }
2550 
2551  oXML.OutOfElem(); // Camera
2552 
2553  msGeneralSettings.vsCameras.push_back(sCameraSettings);
2554  }
2555 
2556  return true;
2557 } // ReadGeneralSettings
2558 
2559 bool CRTProtocol::Read3DSettings(bool &bDataAvailable)
2560 {
2561  CRTPacket::EPacketType eType;
2562  CMarkup oXML;
2563  std::string tStr;
2564 
2565  bDataAvailable = false;
2566 
2567  ms3DSettings.s3DLabels.clear();
2568  ms3DSettings.pCalibrationTime[0] = 0;
2569 
2570  if (!SendCommand("GetParameters 3D"))
2571  {
2572  strcpy(maErrorStr, "GetParameters 3D failed");
2573  return false;
2574  }
2575 
2576  auto received = ReceiveRTPacket(eType, true);
2577  if (received <= 0)
2578  {
2579  if (received == 0)
2580  {
2581  // Receive timeout.
2582  strcat(maErrorStr, " Expected XML packet.");
2583  }
2584  return false;
2585  }
2586 
2587  if (eType != CRTPacket::PacketXML)
2588  {
2589  if (eType == CRTPacket::PacketError)
2590  {
2591  sprintf(maErrorStr, "%s.", mpoRTPacket->GetErrorString());
2592  }
2593  else
2594  {
2595  sprintf(maErrorStr, "GetParameters 3D returned wrong packet type. Got type %d expected type 2.", eType);
2596  }
2597  return false;
2598  }
2599 
2600  oXML.SetDoc(mpoRTPacket->GetXMLString());
2601 
2602  if (!oXML.FindChildElem("The_3D"))
2603  {
2604  // No 3D data available.
2605  return true;
2606  }
2607  oXML.IntoElem();
2608 
2609  if (!oXML.FindChildElem("AxisUpwards"))
2610  {
2611  return false;
2612  }
2613  tStr = oXML.GetChildData();
2614  std::transform(tStr.begin(), tStr.end(), tStr.begin(), ::tolower);
2615 
2616  if (tStr == "+x")
2617  {
2618  ms3DSettings.eAxisUpwards = XPos;
2619  }
2620  else if (tStr == "-x")
2621  {
2622  ms3DSettings.eAxisUpwards = XNeg;
2623  }
2624  else if (tStr == "+y")
2625  {
2626  ms3DSettings.eAxisUpwards = YPos;
2627  }
2628  else if (tStr == "-y")
2629  {
2630  ms3DSettings.eAxisUpwards = YNeg;
2631  }
2632  else if (tStr == "+z")
2633  {
2634  ms3DSettings.eAxisUpwards = ZPos;
2635  }
2636  else if (tStr == "-z")
2637  {
2638  ms3DSettings.eAxisUpwards = ZNeg;
2639  }
2640  else
2641  {
2642  return false;
2643  }
2644 
2645  if (!oXML.FindChildElem("CalibrationTime"))
2646  {
2647  return false;
2648  }
2649  tStr = oXML.GetChildData();
2650  strcpy(ms3DSettings.pCalibrationTime, tStr.c_str());
2651 
2652  if (!oXML.FindChildElem("Labels"))
2653  {
2654  return false;
2655  }
2656  unsigned int nNumberOfLabels = atoi(oXML.GetChildData().c_str());
2657 
2658  ms3DSettings.s3DLabels.resize(nNumberOfLabels);
2659  SSettings3DLabel sLabel;
2660 
2661  for (unsigned int iLabel = 0; iLabel < nNumberOfLabels; iLabel++)
2662  {
2663  if (oXML.FindChildElem("Label"))
2664  {
2665  oXML.IntoElem();
2666  if (oXML.FindChildElem("Name"))
2667  {
2668  sLabel.oName = oXML.GetChildData();
2669  if (oXML.FindChildElem("RGBColor"))
2670  {
2671  sLabel.nRGBColor = atoi(oXML.GetChildData().c_str());
2672  }
2673  ms3DSettings.s3DLabels[iLabel] = sLabel;
2674  }
2675  oXML.OutOfElem();
2676  }
2677  else
2678  {
2679  return false;
2680  }
2681  }
2682 
2683  ms3DSettings.sBones.clear();
2684  if (oXML.FindChildElem("Bones"))
2685  {
2686  oXML.IntoElem();
2687  while (oXML.FindChildElem("Bone"))
2688  {
2689  oXML.IntoElem();
2690  SSettingsBone bone = { };
2691  bone.fromName = oXML.GetAttrib("From").c_str();
2692  bone.toName = oXML.GetAttrib("To").c_str();
2693 
2694  auto colorString = oXML.GetAttrib("Color");
2695  if (!colorString.empty())
2696  {
2697  bone.color = atoi(colorString.c_str());
2698  }
2699  ms3DSettings.sBones.push_back(bone);
2700  oXML.OutOfElem();
2701  }
2702  oXML.OutOfElem();
2703  }
2704 
2705  bDataAvailable = true;
2706  return true;
2707 } // Read3DSettings
2708 
2709 bool CRTProtocol::Read6DOFSettings(bool &bDataAvailable)
2710 {
2711  CRTPacket::EPacketType eType;
2712  CMarkup oXML;
2713 
2714  bDataAvailable = false;
2715 
2716  mvs6DOFSettings.bodySettings.clear();
2717 
2718  if (!SendCommand("GetParameters 6D"))
2719  {
2720  strcpy(maErrorStr, "GetParameters 6D failed");
2721  return false;
2722  }
2723 
2724  auto received = ReceiveRTPacket(eType, true);
2725  if (received <= 0)
2726  {
2727  if (received == 0)
2728  {
2729  // Receive timeout.
2730  strcat(maErrorStr, " Expected XML packet.");
2731  }
2732  return false;
2733  }
2734 
2735  if (eType != CRTPacket::PacketXML)
2736  {
2737  if (eType == CRTPacket::PacketError)
2738  {
2739  sprintf(maErrorStr, "%s.", mpoRTPacket->GetErrorString());
2740  }
2741  else
2742  {
2743  sprintf(maErrorStr, "GetParameters 6D returned wrong packet type. Got type %d expected type 2.", eType);
2744  }
2745  return false;
2746  }
2747 
2748  oXML.SetDoc(mpoRTPacket->GetXMLString());
2749 
2750  //
2751  // Read 6DOF bodies
2752  //
2753  if (!oXML.FindChildElem("The_6D"))
2754  {
2755  return true; // NO 6DOF data available.
2756  }
2757  oXML.IntoElem();
2758 
2759  if (!oXML.FindChildElem("Bodies"))
2760  {
2761  return false;
2762  }
2763  int nBodies = atoi(oXML.GetChildData().c_str());
2764  SSettings6DOFBody s6DOFBodySettings;
2765  SPoint sPoint;
2766 
2767  for (int iBody = 0; iBody < nBodies; iBody++)
2768  {
2769  if (!oXML.FindChildElem("Body"))
2770  {
2771  return false;
2772  }
2773  oXML.IntoElem();
2774 
2775  if (!oXML.FindChildElem("Name"))
2776  {
2777  return false;
2778  }
2779  s6DOFBodySettings.oName = oXML.GetChildData();
2780 
2781  if (!oXML.FindChildElem("RGBColor"))
2782  {
2783  return false;
2784  }
2785  s6DOFBodySettings.vsPoints.clear();
2786  s6DOFBodySettings.nRGBColor = atoi(oXML.GetChildData().c_str());
2787 
2788  while (oXML.FindChildElem("Point"))
2789  {
2790  oXML.IntoElem();
2791  if (!oXML.FindChildElem("X"))
2792  {
2793  return false;
2794  }
2795  sPoint.fX = (float)atof(oXML.GetChildData().c_str());
2796 
2797  if (!oXML.FindChildElem("Y"))
2798  {
2799  return false;
2800  }
2801  sPoint.fY = (float)atof(oXML.GetChildData().c_str());
2802 
2803  if (!oXML.FindChildElem("Z"))
2804  {
2805  return false;
2806  }
2807  sPoint.fZ = (float)atof(oXML.GetChildData().c_str());
2808 
2809  oXML.OutOfElem(); // Point
2810  s6DOFBodySettings.vsPoints.push_back(sPoint);
2811  }
2812  mvs6DOFSettings.bodySettings.push_back(s6DOFBodySettings);
2813  oXML.OutOfElem(); // Body
2814  }
2815 
2816  if (mnMajorVersion > 1 || mnMinorVersion > 15)
2817  {
2818  if (oXML.FindChildElem("Euler"))
2819  {
2820  oXML.IntoElem();
2821  if (!oXML.FindChildElem("First"))
2822  {
2823  return false;
2824  }
2825  mvs6DOFSettings.eulerFirst = oXML.GetChildData();
2826  if (!oXML.FindChildElem("Second"))
2827  {
2828  return false;
2829  }
2830  mvs6DOFSettings.eulerSecond = oXML.GetChildData();
2831  if (!oXML.FindChildElem("Third"))
2832  {
2833  return false;
2834  }
2835  mvs6DOFSettings.eulerThird = oXML.GetChildData();
2836  oXML.OutOfElem(); // Euler
2837  }
2838  }
2839 
2840  bDataAvailable = true;
2841  return true;
2842 } // Read6DOFSettings
2843 
2844 bool CRTProtocol::ReadGazeVectorSettings(bool &bDataAvailable)
2845 {
2846  CRTPacket::EPacketType eType;
2847  CMarkup oXML;
2848 
2849  bDataAvailable = false;
2850 
2851  mvsGazeVectorSettings.clear();
2852 
2853  if (!SendCommand("GetParameters GazeVector"))
2854  {
2855  strcpy(maErrorStr, "GetParameters GazeVector failed");
2856  return false;
2857  }
2858 
2859  auto received = ReceiveRTPacket(eType, true);
2860  if (received <= 0)
2861  {
2862  if (received == 0)
2863  {
2864  // Receive timeout.
2865  strcat(maErrorStr, " Expected XML packet.");
2866  }
2867  return false;
2868  }
2869 
2870  if (eType != CRTPacket::PacketXML)
2871  {
2872  if (eType == CRTPacket::PacketError)
2873  {
2874  sprintf(maErrorStr, "%s.", mpoRTPacket->GetErrorString());
2875  }
2876  else
2877  {
2878  sprintf(maErrorStr, "GetParameters GazeVector returned wrong packet type. Got type %d expected type 2.", eType);
2879  }
2880  return false;
2881  }
2882 
2883  oXML.SetDoc(mpoRTPacket->GetXMLString());
2884 
2885  //
2886  // Read gaze vectors
2887  //
2888  if (!oXML.FindChildElem("Gaze_Vector"))
2889  {
2890  return true; // NO gaze vector data available.
2891  }
2892  oXML.IntoElem();
2893 
2894  std::string tGazeVectorName;
2895 
2896  int nGazeVectorCount = 0;
2897 
2898  while (oXML.FindChildElem("Vector"))
2899  {
2900  oXML.IntoElem();
2901 
2902  if (!oXML.FindChildElem("Name"))
2903  {
2904  return false;
2905  }
2906  tGazeVectorName = oXML.GetChildData();
2907 
2908  float frequency = 0;
2909  if (oXML.FindChildElem("Frequency"))
2910  {
2911  frequency = (float)atof(oXML.GetChildData().c_str());
2912  }
2913 
2914  mvsGazeVectorSettings.push_back({ tGazeVectorName, frequency });
2915  nGazeVectorCount++;
2916  oXML.OutOfElem(); // Vector
2917  }
2918 
2919  bDataAvailable = true;
2920  return true;
2921 } // ReadGazeVectorSettings
2922 
2923 bool CRTProtocol::ReadAnalogSettings(bool &bDataAvailable)
2924 {
2925  CRTPacket::EPacketType eType;
2926  CMarkup oXML;
2927 
2928  bDataAvailable = false;
2929  mvsAnalogDeviceSettings.clear();
2930 
2931  if (!SendCommand("GetParameters Analog"))
2932  {
2933  strcpy(maErrorStr, "GetParameters Analog failed");
2934  return false;
2935  }
2936 
2937  auto received = ReceiveRTPacket(eType, true);
2938  if (received <= 0)
2939  {
2940  if (received == 0)
2941  {
2942  // Receive timeout.
2943  strcat(maErrorStr, " Expected XML packet.");
2944  }
2945  return false;
2946  }
2947 
2948  if (eType != CRTPacket::PacketXML)
2949  {
2950  if (eType == CRTPacket::PacketError)
2951  {
2952  sprintf(maErrorStr, "%s.", mpoRTPacket->GetErrorString());
2953  }
2954  else
2955  {
2956  sprintf(maErrorStr, "GetParameters Analog returned wrong packet type. Got type %d expected type 2.", eType);
2957  }
2958  return false;
2959  }
2960 
2961  oXML.SetDoc(mpoRTPacket->GetXMLString());
2962 
2963  if (!oXML.FindChildElem("Analog"))
2964  {
2965  // No analog data available.
2966  return true;
2967  }
2968 
2969  SAnalogDevice sAnalogDevice;
2970 
2971  oXML.IntoElem();
2972 
2973  if (mnMajorVersion == 1 && mnMinorVersion == 0)
2974  {
2975  sAnalogDevice.nDeviceID = 1; // Always channel 1
2976  sAnalogDevice.oName = "AnalogDevice";
2977  if (!oXML.FindChildElem("Channels"))
2978  {
2979  return false;
2980  }
2981  sAnalogDevice.nChannels = atoi(oXML.GetChildData().c_str());
2982  if (!oXML.FindChildElem("Frequency"))
2983  {
2984  return false;
2985  }
2986  sAnalogDevice.nFrequency = atoi(oXML.GetChildData().c_str());
2987  if (!oXML.FindChildElem("Unit"))
2988  {
2989  return false;
2990  }
2991  sAnalogDevice.oUnit = oXML.GetChildData();
2992  if (!oXML.FindChildElem("Range"))
2993  {
2994  return false;
2995  }
2996  oXML.IntoElem();
2997  if (!oXML.FindChildElem("Min"))
2998  {
2999  return false;
3000  }
3001  sAnalogDevice.fMinRange = (float)atof(oXML.GetChildData().c_str());
3002  if (!oXML.FindChildElem("Max"))
3003  {
3004  return false;
3005  }
3006  sAnalogDevice.fMaxRange = (float)atof(oXML.GetChildData().c_str());
3007  mvsAnalogDeviceSettings.push_back(sAnalogDevice);
3008  bDataAvailable = true;
3009  return true;
3010  }
3011  else
3012  {
3013  while (oXML.FindChildElem("Device"))
3014  {
3015  sAnalogDevice.voLabels.clear();
3016  sAnalogDevice.voUnits.clear();
3017  oXML.IntoElem();
3018  if (!oXML.FindChildElem("Device_ID"))
3019  {
3020  oXML.OutOfElem(); // Device
3021  continue;
3022  }
3023  sAnalogDevice.nDeviceID = atoi(oXML.GetChildData().c_str());
3024 
3025  if (!oXML.FindChildElem("Device_Name"))
3026  {
3027  oXML.OutOfElem(); // Device
3028  continue;
3029  }
3030  sAnalogDevice.oName = oXML.GetChildData();
3031 
3032  if (!oXML.FindChildElem("Channels"))
3033  {
3034  oXML.OutOfElem(); // Device
3035  continue;
3036  }
3037  sAnalogDevice.nChannels = atoi(oXML.GetChildData().c_str());
3038 
3039  if (!oXML.FindChildElem("Frequency"))
3040  {
3041  oXML.OutOfElem(); // Device
3042  continue;
3043  }
3044  sAnalogDevice.nFrequency = atoi(oXML.GetChildData().c_str());
3045 
3046  if (mnMajorVersion == 1 && mnMinorVersion < 11)
3047  {
3048  if (!oXML.FindChildElem("Unit"))
3049  {
3050  oXML.OutOfElem(); // Device
3051  continue;
3052  }
3053  sAnalogDevice.oUnit = oXML.GetChildData();
3054  }
3055  if (!oXML.FindChildElem("Range"))
3056  {
3057  oXML.OutOfElem(); // Device
3058  continue;
3059  }
3060  oXML.IntoElem();
3061 
3062  if (!oXML.FindChildElem("Min"))
3063  {
3064  oXML.OutOfElem(); // Device
3065  oXML.OutOfElem(); // Range
3066  continue;
3067  }
3068  sAnalogDevice.fMinRange = (float)atof(oXML.GetChildData().c_str());
3069 
3070  if (!oXML.FindChildElem("Max"))
3071  {
3072  oXML.OutOfElem(); // Device
3073  oXML.OutOfElem(); // Range
3074  continue;
3075  }
3076  sAnalogDevice.fMaxRange = (float)atof(oXML.GetChildData().c_str());
3077  oXML.OutOfElem(); // Range
3078 
3079  if (mnMajorVersion == 1 && mnMinorVersion < 11)
3080  {
3081  for (unsigned int i = 0; i < sAnalogDevice.nChannels; i++)
3082  {
3083  if (oXML.FindChildElem("Label"))
3084  {
3085  sAnalogDevice.voLabels.push_back(oXML.GetChildData());
3086  }
3087  }
3088  if (sAnalogDevice.voLabels.size() != sAnalogDevice.nChannels)
3089  {
3090  oXML.OutOfElem(); // Device
3091  continue;
3092  }
3093  }
3094  else
3095  {
3096  while (oXML.FindChildElem("Channel"))
3097  {
3098  oXML.IntoElem();
3099  if (oXML.FindChildElem("Label"))
3100  {
3101  sAnalogDevice.voLabels.push_back(oXML.GetChildData());
3102  }
3103  if (oXML.FindChildElem("Unit"))
3104  {
3105  sAnalogDevice.voUnits.push_back(oXML.GetChildData());
3106  }
3107  oXML.OutOfElem(); // Channel
3108  }
3109  if (sAnalogDevice.voLabels.size() != sAnalogDevice.nChannels ||
3110  sAnalogDevice.voUnits.size() != sAnalogDevice.nChannels)
3111  {
3112  oXML.OutOfElem(); // Device
3113  continue;
3114  }
3115  }
3116  oXML.OutOfElem(); // Device
3117  mvsAnalogDeviceSettings.push_back(sAnalogDevice);
3118  bDataAvailable = true;
3119  }
3120  }
3121 
3122  return true;
3123 } // ReadAnalogSettings
3124 
3125 bool CRTProtocol::ReadForceSettings(bool &bDataAvailable)
3126 {
3127  CRTPacket::EPacketType eType;
3128  CMarkup oXML;
3129 
3130  bDataAvailable = false;
3131 
3132  msForceSettings.vsForcePlates.clear();
3133 
3134  if (!SendCommand("GetParameters Force"))
3135  {
3136  strcpy(maErrorStr, "GetParameters Force failed");
3137  return false;
3138  }
3139 
3140  auto received = ReceiveRTPacket(eType, true);
3141  if (received <= 0)
3142  {
3143  if (received == 0)
3144  {
3145  // Receive timeout.
3146  strcat(maErrorStr, " Expected XML packet.");
3147  }
3148  return false;
3149  }
3150 
3151  if (eType != CRTPacket::PacketXML)
3152  {
3153  if (eType == CRTPacket::PacketError)
3154  {
3155  sprintf(maErrorStr, "%s.", mpoRTPacket->GetErrorString());
3156  }
3157  else
3158  {
3159  sprintf(maErrorStr, "GetParameters Force returned wrong packet type. Got type %d expected type 2.", eType);
3160  }
3161  return false;
3162  }
3163 
3164  oXML.SetDoc(mpoRTPacket->GetXMLString());
3165  //
3166  // Read some force plate parameters
3167  //
3168  if (!oXML.FindChildElem("Force"))
3169  {
3170  return true;
3171  }
3172 
3173  oXML.IntoElem();
3174 
3175  SForcePlate sForcePlate;
3176  sForcePlate.bValidCalibrationMatrix = false;
3177  sForcePlate.nCalibrationMatrixRows = 6;
3178  sForcePlate.nCalibrationMatrixColumns = 6;
3179 
3180  if (!oXML.FindChildElem("Unit_Length"))
3181  {
3182  return false;
3183  }
3184  msForceSettings.oUnitLength = oXML.GetChildData();
3185 
3186  if (!oXML.FindChildElem("Unit_Force"))
3187  {
3188  return false;
3189  }
3190  msForceSettings.oUnitForce = oXML.GetChildData();
3191 
3192  int iPlate = 1;
3193  while (oXML.FindChildElem("Plate"))
3194  {
3195  //
3196  // Get name and type of the plates
3197  //
3198  oXML.IntoElem(); // "Plate"
3199  if (oXML.FindChildElem("Force_Plate_Index")) // Version 1.7 and earlier.
3200  {
3201  sForcePlate.nID = atoi(oXML.GetChildData().c_str());
3202  }
3203  else if (oXML.FindChildElem("Plate_ID")) // Version 1.8 and later.
3204  {
3205  sForcePlate.nID = atoi(oXML.GetChildData().c_str());
3206  }
3207  else
3208  {
3209  return false;
3210  }
3211 
3212  if (oXML.FindChildElem("Analog_Device_ID"))
3213  {
3214  sForcePlate.nAnalogDeviceID = atoi(oXML.GetChildData().c_str());
3215  }
3216  else
3217  {
3218  sForcePlate.nAnalogDeviceID = 0;
3219  }
3220 
3221  if (!oXML.FindChildElem("Frequency"))
3222  {
3223  return false;
3224  }
3225  sForcePlate.nFrequency = atoi(oXML.GetChildData().c_str());
3226 
3227  if (oXML.FindChildElem("Type"))
3228  {
3229  sForcePlate.oType = oXML.GetChildData();
3230  }
3231  else
3232  {
3233  sForcePlate.oType = "unknown";
3234  }
3235 
3236  if (oXML.FindChildElem("Name"))
3237  {
3238  sForcePlate.oName = oXML.GetChildData();
3239  }
3240  else
3241  {
3242  sForcePlate.oName = CMarkup::Format("#%d", iPlate);
3243  }
3244 
3245  if (oXML.FindChildElem("Length"))
3246  {
3247  sForcePlate.fLength = (float)atof(oXML.GetChildData().c_str());
3248  }
3249  if (oXML.FindChildElem("Width"))
3250  {
3251  sForcePlate.fWidth = (float)atof(oXML.GetChildData().c_str());
3252  }
3253 
3254  if (oXML.FindChildElem("Location"))
3255  {
3256  oXML.IntoElem();
3257  if (oXML.FindChildElem("Corner1"))
3258  {
3259  oXML.IntoElem();
3260  if (oXML.FindChildElem("X"))
3261  {
3262  sForcePlate.asCorner[0].fX = (float)atof(oXML.GetChildData().c_str());
3263  }
3264  if (oXML.FindChildElem("Y"))
3265  {
3266  sForcePlate.asCorner[0].fY = (float)atof(oXML.GetChildData().c_str());
3267  }
3268  if (oXML.FindChildElem("Z"))
3269  {
3270  sForcePlate.asCorner[0].fZ = (float)atof(oXML.GetChildData().c_str());
3271  }
3272  oXML.OutOfElem();
3273  }
3274  if (oXML.FindChildElem("Corner2"))
3275  {
3276  oXML.IntoElem();
3277  if (oXML.FindChildElem("X"))
3278  {
3279  sForcePlate.asCorner[1].fX = (float)atof(oXML.GetChildData().c_str());
3280  }
3281  if (oXML.FindChildElem("Y"))
3282  {
3283  sForcePlate.asCorner[1].fY = (float)atof(oXML.GetChildData().c_str());
3284  }
3285  if (oXML.FindChildElem("Z"))
3286  {
3287  sForcePlate.asCorner[1].fZ = (float)atof(oXML.GetChildData().c_str());
3288  }
3289  oXML.OutOfElem();
3290  }
3291  if (oXML.FindChildElem("Corner3"))
3292  {
3293  oXML.IntoElem();
3294  if (oXML.FindChildElem("X"))
3295  {
3296  sForcePlate.asCorner[2].fX = (float)atof(oXML.GetChildData().c_str());
3297  }
3298  if (oXML.FindChildElem("Y"))
3299  {
3300  sForcePlate.asCorner[2].fY = (float)atof(oXML.GetChildData().c_str());
3301  }
3302  if (oXML.FindChildElem("Z"))
3303  {
3304  sForcePlate.asCorner[2].fZ = (float)atof(oXML.GetChildData().c_str());
3305  }
3306  oXML.OutOfElem();
3307  }
3308  if (oXML.FindChildElem("Corner4"))
3309  {
3310  oXML.IntoElem();
3311  if (oXML.FindChildElem("X"))
3312  {
3313  sForcePlate.asCorner[3].fX = (float)atof(oXML.GetChildData().c_str());
3314  }
3315  if (oXML.FindChildElem("Y"))
3316  {
3317  sForcePlate.asCorner[3].fY = (float)atof(oXML.GetChildData().c_str());
3318  }
3319  if (oXML.FindChildElem("Z"))
3320  {
3321  sForcePlate.asCorner[3].fZ = (float)atof(oXML.GetChildData().c_str());
3322  }
3323  oXML.OutOfElem();
3324  }
3325  oXML.OutOfElem();
3326  }
3327 
3328  if (oXML.FindChildElem("Origin"))
3329  {
3330  oXML.IntoElem();
3331  if (oXML.FindChildElem("X"))
3332  {
3333  sForcePlate.sOrigin.fX = (float)atof(oXML.GetChildData().c_str());
3334  }
3335  if (oXML.FindChildElem("Y"))
3336  {
3337  sForcePlate.sOrigin.fY = (float)atof(oXML.GetChildData().c_str());
3338  }
3339  if (oXML.FindChildElem("Z"))
3340  {
3341  sForcePlate.sOrigin.fZ = (float)atof(oXML.GetChildData().c_str());
3342  }
3343  oXML.OutOfElem();
3344  }
3345 
3346  sForcePlate.vChannels.clear();
3347  if (oXML.FindChildElem("Channels"))
3348  {
3349  oXML.IntoElem();
3350  SForceChannel sForceChannel;
3351  while (oXML.FindChildElem("Channel"))
3352  {
3353  oXML.IntoElem();
3354  if (oXML.FindChildElem("Channel_No"))
3355  {
3356  sForceChannel.nChannelNumber = atoi(oXML.GetChildData().c_str());
3357  }
3358  if (oXML.FindChildElem("ConversionFactor"))
3359  {
3360  sForceChannel.fConversionFactor = (float)atof(oXML.GetChildData().c_str());
3361  }
3362  sForcePlate.vChannels.push_back(sForceChannel);
3363  oXML.OutOfElem();
3364  }
3365  oXML.OutOfElem();
3366  }
3367 
3368  if (oXML.FindChildElem("Calibration_Matrix"))
3369  {
3370  oXML.IntoElem();
3371  int nRow = 0;
3372 
3373  if (mnMajorVersion == 1 && mnMinorVersion < 12)
3374  {
3375  char strRow[16];
3376  char strCol[16];
3377  sprintf(strRow, "Row%d", nRow + 1);
3378  while (oXML.FindChildElem(strRow))
3379  {
3380  oXML.IntoElem();
3381  int nCol = 0;
3382  sprintf(strCol, "Col%d", nCol + 1);
3383  while (oXML.FindChildElem(strCol))
3384  {
3385  sForcePlate.afCalibrationMatrix[nRow][nCol] = (float)atof(oXML.GetChildData().c_str());
3386  nCol++;
3387  sprintf(strCol, "Col%d", nCol + 1);
3388  }
3389  sForcePlate.nCalibrationMatrixColumns = nCol;
3390 
3391  nRow++;
3392  sprintf(strRow, "Row%d", nRow + 1);
3393  oXML.OutOfElem(); // RowX
3394  }
3395  }
3396  else
3397  {
3398  //<Rows>
3399  if (oXML.FindChildElem("Rows"))
3400  {
3401  oXML.IntoElem();
3402 
3403  while (oXML.FindChildElem("Row"))
3404  {
3405  oXML.IntoElem();
3406 
3407  //<Columns>
3408  if (oXML.FindChildElem("Columns"))
3409  {
3410  oXML.IntoElem();
3411 
3412  int nCol = 0;
3413  while (oXML.FindChildElem("Column"))
3414  {
3415  sForcePlate.afCalibrationMatrix[nRow][nCol] = (float)atof(oXML.GetChildData().c_str());
3416  nCol++;
3417  }
3418  sForcePlate.nCalibrationMatrixColumns = nCol;
3419 
3420  nRow++;
3421  oXML.OutOfElem(); // Columns
3422  }
3423  oXML.OutOfElem(); // Row
3424  }
3425  oXML.OutOfElem(); // Rows
3426  }
3427  }
3428  sForcePlate.nCalibrationMatrixRows = nRow;
3429  sForcePlate.bValidCalibrationMatrix = true;
3430 
3431  oXML.OutOfElem(); // "Calibration_Matrix"
3432  }
3433  oXML.OutOfElem(); // "Plate"
3434 
3435  bDataAvailable = true;
3436  msForceSettings.vsForcePlates.push_back(sForcePlate);
3437  }
3438 
3439  return true;
3440 } // Read force settings
3441 
3442 bool CRTProtocol::ReadImageSettings(bool &bDataAvailable)
3443 {
3444  CRTPacket::EPacketType eType;
3445  CMarkup oXML;
3446 
3447  bDataAvailable = false;
3448 
3449  mvsImageSettings.clear();
3450 
3451  if (!SendCommand("GetParameters Image"))
3452  {
3453  strcpy(maErrorStr, "GetParameters Image failed");
3454  return false;
3455  }
3456 
3457  auto received = ReceiveRTPacket(eType, true);
3458  if (received <= 0)
3459  {
3460  if (received == 0)
3461  {
3462  // Receive timeout.
3463  strcat(maErrorStr, " Expected XML packet.");
3464  }
3465  return false;
3466  }
3467 
3468  if (eType != CRTPacket::PacketXML)
3469  {
3470  if (eType == CRTPacket::PacketError)
3471  {
3472  sprintf(maErrorStr, "%s.", mpoRTPacket->GetErrorString());
3473  }
3474  else
3475  {
3476  sprintf(maErrorStr, "GetParameters Image returned wrong packet type. Got type %d expected type 2.", eType);
3477  }
3478  return false;
3479  }
3480 
3481  oXML.SetDoc(mpoRTPacket->GetXMLString());
3482  //
3483  // Read some Image parameters
3484  //
3485  if (!oXML.FindChildElem("Image"))
3486  {
3487  return true;
3488  }
3489  oXML.IntoElem();
3490 
3491  while (oXML.FindChildElem("Camera"))
3492  {
3493  oXML.IntoElem();
3494 
3495  SImageCamera sImageCamera;
3496 
3497  if (!oXML.FindChildElem("ID"))
3498  {
3499  return false;
3500  }
3501  sImageCamera.nID = atoi(oXML.GetChildData().c_str());
3502 
3503  if (!oXML.FindChildElem("Enabled"))
3504  {
3505  return false;
3506  }
3507  std::string tStr;
3508  tStr = oXML.GetChildData();
3509  std::transform(tStr.begin(), tStr.end(), tStr.begin(), ::tolower);
3510 
3511  if (tStr == "true")
3512  {
3513  sImageCamera.bEnabled = true;
3514  }
3515  else
3516  {
3517  sImageCamera.bEnabled = false;
3518  }
3519 
3520  if (!oXML.FindChildElem("Format"))
3521  {
3522  return false;
3523  }
3524  tStr = oXML.GetChildData();
3525  std::transform(tStr.begin(), tStr.end(), tStr.begin(), ::tolower);
3526 
3527  if (tStr == "rawgrayscale")
3528  {
3529  sImageCamera.eFormat = CRTPacket::FormatRawGrayscale;
3530  }
3531  else if (tStr == "rawbgr")
3532  {
3533  sImageCamera.eFormat = CRTPacket::FormatRawBGR;
3534  }
3535  else if (tStr == "jpg")
3536  {
3537  sImageCamera.eFormat = CRTPacket::FormatJPG;
3538  }
3539  else if (tStr == "png")
3540  {
3541  sImageCamera.eFormat = CRTPacket::FormatPNG;
3542  }
3543  else
3544  {
3545  return false;
3546  }
3547 
3548  if (!oXML.FindChildElem("Width"))
3549  {
3550  return false;
3551  }
3552  sImageCamera.nWidth = atoi(oXML.GetChildData().c_str());
3553 
3554  if (!oXML.FindChildElem("Height"))
3555  {
3556  return false;
3557  }
3558  sImageCamera.nHeight = atoi(oXML.GetChildData().c_str());
3559 
3560  if (!oXML.FindChildElem("Left_Crop"))
3561  {
3562  return false;
3563  }
3564  sImageCamera.fCropLeft = (float)atof(oXML.GetChildData().c_str());
3565 
3566  if (!oXML.FindChildElem("Top_Crop"))
3567  {
3568  return false;
3569  }
3570  sImageCamera.fCropTop = (float)atof(oXML.GetChildData().c_str());
3571 
3572  if (!oXML.FindChildElem("Right_Crop"))
3573  {
3574  return false;
3575  }
3576  sImageCamera.fCropRight = (float)atof(oXML.GetChildData().c_str());
3577 
3578  if (!oXML.FindChildElem("Bottom_Crop"))
3579  {
3580  return false;
3581  }
3582  sImageCamera.fCropBottom = (float)atof(oXML.GetChildData().c_str());
3583 
3584  oXML.OutOfElem(); // "Camera"
3585 
3586  mvsImageSettings.push_back(sImageCamera);
3587  bDataAvailable = true;
3588  }
3589 
3590  return true;
3591 } // ReadImageSettings
3592 
3593 
3594 bool CRTProtocol::ReadSkeletonSettings(bool &bDataAvailable, bool skeletonGlobalData)
3595 {
3596  CRTPacket::EPacketType eType;
3597  CMarkup oXML;
3598 
3599  bDataAvailable = false;
3600 
3601  mSkeletonSettings.clear();
3602 
3603  std::string cmd("GetParameters Skeleton");
3604  if (skeletonGlobalData)
3605  {
3606  cmd += ":global";
3607  }
3608  if (!SendCommand(cmd.c_str()))
3609  {
3610  strcpy(maErrorStr, "GetParameters Skeleton failed");
3611  return false;
3612  }
3613 
3614  auto received = ReceiveRTPacket(eType, true);
3615  if (received <= 0)
3616  {
3617  if (received == 0)
3618  {
3619  // Receive timeout.
3620  strcat(maErrorStr, " Expected XML packet.");
3621  }
3622  return false;
3623  }
3624 
3625  if (eType != CRTPacket::PacketXML)
3626  {
3627  if (eType == CRTPacket::PacketError)
3628  {
3629  sprintf(maErrorStr, "%s.", mpoRTPacket->GetErrorString());
3630  }
3631  else
3632  {
3633  sprintf(maErrorStr, "GetParameters Skeleton returned wrong packet type. Got type %d expected type 2.", eType);
3634  }
3635  return false;
3636  }
3637 
3638  oXML.SetDoc(mpoRTPacket->GetXMLString());
3639 
3640  if (!oXML.FindChildElem("Skeletons"))
3641  {
3642  return true;
3643  }
3644  oXML.IntoElem();
3645 
3646  std::string skeletonName;
3647  int segmentIndex;
3648  std::map<int, int> segmentIdIndexMap;
3649 
3650  while (oXML.FindChildElem("Skeleton"))
3651  {
3652  SSettingsSkeleton skeleton;
3653  segmentIndex = 0;
3654 
3655  oXML.IntoElem();
3656 
3657  skeleton.name = oXML.GetAttrib("Name");
3658  while (oXML.FindChildElem("Segment"))
3659  {
3660  oXML.IntoElem();
3661 
3662  SSettingsSkeletonSegment segment;
3663 
3664  segment.name = oXML.GetAttrib("Name");
3665  if (segment.name.size() == 0 || sscanf(oXML.GetAttrib("ID").c_str(), "%u", &segment.id) != 1)
3666  {
3667  return false;
3668  }
3669 
3670  segmentIdIndexMap[segment.id] = segmentIndex++;
3671 
3672  int parentId;
3673  if (sscanf(oXML.GetAttrib("Parent_ID").c_str(), "%d", &parentId) != 1)
3674  {
3675  segment.parentId = -1;
3676  segment.parentIndex = -1;
3677  }
3678  else if (segmentIdIndexMap.count(parentId) > 0)
3679  {
3680  segment.parentId = parentId;
3681  segment.parentIndex = segmentIdIndexMap[parentId];
3682  }
3683 
3684  if (oXML.FindChildElem("Position"))
3685  {
3686  oXML.IntoElem();
3687  float x, y, z;
3688  if (sscanf(oXML.GetAttrib("X").c_str(), "%f", &x) == 1)
3689  {
3690  segment.positionX = x;
3691  }
3692  if (sscanf(oXML.GetAttrib("Y").c_str(), "%f", &y) == 1)
3693  {
3694  segment.positionY = y;
3695  }
3696  if (sscanf(oXML.GetAttrib("Z").c_str(), "%f", &z) == 1)
3697  {
3698  segment.positionZ = z;
3699  }
3700  oXML.OutOfElem();
3701  }
3702 
3703  if (oXML.FindChildElem("Rotation"))
3704  {
3705  oXML.IntoElem();
3706  float x, y, z, w;
3707  if (sscanf(oXML.GetAttrib("X").c_str(), "%f", &x) == 1)
3708  {
3709  segment.rotationX = x;
3710  }
3711  if (sscanf(oXML.GetAttrib("Y").c_str(), "%f", &y) == 1)
3712  {
3713  segment.rotationY = y;
3714  }
3715  if (sscanf(oXML.GetAttrib("Z").c_str(), "%f", &z) == 1)
3716  {
3717  segment.rotationZ = z;
3718  }
3719  if (sscanf(oXML.GetAttrib("W").c_str(), "%f", &w) == 1)
3720  {
3721  segment.rotationW = w;
3722  }
3723  oXML.OutOfElem();
3724  }
3725 
3726  skeleton.segments.push_back(segment);
3727 
3728  oXML.OutOfElem(); // Segment
3729  }
3730 
3731  mSkeletonSettings.push_back(skeleton);
3732 
3733  oXML.OutOfElem(); // Skeleton
3734  }
3735 
3736  oXML.OutOfElem(); // Skeletons
3737 
3738  bDataAvailable = true;
3739  return true;
3740 } // ReadSkeletonSettings
3741 
3742 
3744  unsigned int &nCaptureFrequency, float &fCaptureTime,
3745  bool& bStartOnExtTrig, bool& startOnTrigNO, bool& startOnTrigNC, bool& startOnTrigSoftware,
3746  EProcessingActions &eProcessingActions, EProcessingActions &eRtProcessingActions, EProcessingActions &eReprocessingActions) const
3747 {
3748  nCaptureFrequency = msGeneralSettings.nCaptureFrequency;
3749  fCaptureTime = msGeneralSettings.fCaptureTime;
3750  bStartOnExtTrig = msGeneralSettings.bStartOnExternalTrigger;
3751  startOnTrigNO = msGeneralSettings.bStartOnTrigNO;
3752  startOnTrigNC = msGeneralSettings.bStartOnTrigNC;
3753  startOnTrigSoftware = msGeneralSettings.bStartOnTrigSoftware;
3754  eProcessingActions = msGeneralSettings.eProcessingActions;
3755  eRtProcessingActions = msGeneralSettings.eRtProcessingActions;
3756  eReprocessingActions = msGeneralSettings.eReprocessingActions;
3757 }
3758 
3759 
3760 // External time base settings only available in version 1.10 of the rt protocol and later
3762  bool &bEnabled, ESignalSource &eSignalSource,
3763  bool &bSignalModePeriodic, unsigned int &nFreqMultiplier,
3764  unsigned int &nFreqDivisor, unsigned int &nFreqTolerance,
3765  float &fNominalFrequency, bool &bNegativeEdge,
3766  unsigned int &nSignalShutterDelay, float &fNonPeriodicTimeout) const
3767 {
3768  bEnabled = msGeneralSettings.sExternalTimebase.bEnabled;
3769  eSignalSource = msGeneralSettings.sExternalTimebase.eSignalSource;
3770  bSignalModePeriodic = msGeneralSettings.sExternalTimebase.bSignalModePeriodic;
3771  nFreqMultiplier = msGeneralSettings.sExternalTimebase.nFreqMultiplier;
3772  nFreqDivisor = msGeneralSettings.sExternalTimebase.nFreqDivisor;
3773  nFreqTolerance = msGeneralSettings.sExternalTimebase.nFreqTolerance;
3774  fNominalFrequency = msGeneralSettings.sExternalTimebase.fNominalFrequency;
3775  bNegativeEdge = msGeneralSettings.sExternalTimebase.bNegativeEdge;
3776  nSignalShutterDelay = msGeneralSettings.sExternalTimebase.nSignalShutterDelay;
3777  fNonPeriodicTimeout = msGeneralSettings.sExternalTimebase.fNonPeriodicTimeout;
3778 }
3779 
3780 
3781 unsigned int CRTProtocol::GetCameraCount() const
3782 {
3783  return (unsigned int)msGeneralSettings.vsCameras.size();
3784 }
3785 
3786 
3788  unsigned int nCameraIndex, unsigned int &nID, ECameraModel &eModel,
3789  bool &bUnderwater, bool &bSupportsHwSync, unsigned int &nSerial, ECameraMode &eMode) const
3790 {
3791  if (nCameraIndex < msGeneralSettings.vsCameras.size())
3792  {
3793  nID = msGeneralSettings.vsCameras[nCameraIndex].nID;
3794  eModel = msGeneralSettings.vsCameras[nCameraIndex].eModel;
3795  bUnderwater = msGeneralSettings.vsCameras[nCameraIndex].bUnderwater;
3796  bSupportsHwSync = msGeneralSettings.vsCameras[nCameraIndex].bSupportsHwSync;
3797  nSerial = msGeneralSettings.vsCameras[nCameraIndex].nSerial;
3798  eMode = msGeneralSettings.vsCameras[nCameraIndex].eMode;
3799  return true;
3800  }
3801  return false;
3802 }
3803 
3804 
3806  unsigned int nCameraIndex, unsigned int &nCurrentExposure, unsigned int &nMinExposure,
3807  unsigned int &nMaxExposure, unsigned int &nCurrentThreshold,
3808  unsigned int &nMinThreshold, unsigned int &nMaxThreshold) const
3809 {
3810  if (nCameraIndex < msGeneralSettings.vsCameras.size())
3811  {
3812  nCurrentExposure = msGeneralSettings.vsCameras[nCameraIndex].nMarkerExposure;
3813  nMinExposure = msGeneralSettings.vsCameras[nCameraIndex].nMarkerExposureMin;
3814  nMaxExposure = msGeneralSettings.vsCameras[nCameraIndex].nMarkerExposureMax;
3815  nCurrentThreshold = msGeneralSettings.vsCameras[nCameraIndex].nMarkerThreshold;
3816  nMinThreshold = msGeneralSettings.vsCameras[nCameraIndex].nMarkerThresholdMin;
3817  nMaxThreshold = msGeneralSettings.vsCameras[nCameraIndex].nMarkerThresholdMax;
3818  return true;
3819  }
3820  return false;
3821 }
3822 
3823 
3825  unsigned int nCameraIndex, EVideoResolution &eVideoResolution,
3826  EVideoAspectRatio &eVideoAspectRatio, unsigned int &nVideoFrequency,
3827  unsigned int &nCurrentExposure, unsigned int &nMinExposure,
3828  unsigned int &nMaxExposure, unsigned int &nCurrentFlashTime,
3829  unsigned int &nMinFlashTime, unsigned int &nMaxFlashTime) const
3830 {
3831  if (nCameraIndex < msGeneralSettings.vsCameras.size())
3832  {
3833  eVideoResolution = msGeneralSettings.vsCameras[nCameraIndex].eVideoResolution;
3834  eVideoAspectRatio = msGeneralSettings.vsCameras[nCameraIndex].eVideoAspectRatio;
3835  nVideoFrequency = msGeneralSettings.vsCameras[nCameraIndex].nVideoFrequency;
3836  nCurrentExposure = msGeneralSettings.vsCameras[nCameraIndex].nVideoExposure;
3837  nMinExposure = msGeneralSettings.vsCameras[nCameraIndex].nVideoExposureMin;
3838  nMaxExposure = msGeneralSettings.vsCameras[nCameraIndex].nVideoExposureMax;
3839  nCurrentFlashTime = msGeneralSettings.vsCameras[nCameraIndex].nVideoFlashTime;
3840  nMinFlashTime = msGeneralSettings.vsCameras[nCameraIndex].nVideoFlashTimeMin;
3841  nMaxFlashTime = msGeneralSettings.vsCameras[nCameraIndex].nVideoFlashTimeMax;
3842  return true;
3843  }
3844  return false;
3845 }
3846 
3847 
3849  unsigned int nCameraIndex, unsigned int portNumber, ESyncOutFreqMode &eSyncOutMode,
3850  unsigned int &nSyncOutValue, float &fSyncOutDutyCycle,
3851  bool &bSyncOutNegativePolarity) const
3852 {
3853  if (nCameraIndex < msGeneralSettings.vsCameras.size())
3854  {
3855  if (portNumber == 1 || portNumber == 2)
3856  {
3857  eSyncOutMode = msGeneralSettings.vsCameras[nCameraIndex].eSyncOutMode[portNumber - 1];
3858  nSyncOutValue = msGeneralSettings.vsCameras[nCameraIndex].nSyncOutValue[portNumber - 1];
3859  fSyncOutDutyCycle = msGeneralSettings.vsCameras[nCameraIndex].fSyncOutDutyCycle[portNumber - 1];
3860  }
3861  if (portNumber > 0 && portNumber < 4)
3862  {
3863  bSyncOutNegativePolarity = msGeneralSettings.vsCameras[nCameraIndex].bSyncOutNegativePolarity[portNumber - 1];
3864  }
3865  else
3866  {
3867  return false;
3868  }
3869  return true;
3870  }
3871  return false;
3872 }
3873 
3874 
3876  unsigned int nCameraIndex, SPoint &sPoint, float fvRotationMatrix[3][3]) const
3877 {
3878  if (nCameraIndex < msGeneralSettings.vsCameras.size())
3879  {
3880  sPoint.fX = msGeneralSettings.vsCameras[nCameraIndex].fPositionX;
3881  sPoint.fY = msGeneralSettings.vsCameras[nCameraIndex].fPositionY;
3882  sPoint.fZ = msGeneralSettings.vsCameras[nCameraIndex].fPositionZ;
3883  memcpy(fvRotationMatrix, msGeneralSettings.vsCameras[nCameraIndex].fPositionRotMatrix, 9 * sizeof(float));
3884  return true;
3885  }
3886  return false;
3887 }
3888 
3889 
3891  unsigned int nCameraIndex, int &nOrientation) const
3892 {
3893  if (nCameraIndex < msGeneralSettings.vsCameras.size())
3894  {
3895  nOrientation = msGeneralSettings.vsCameras[nCameraIndex].nOrientation;
3896  return true;
3897  }
3898  return false;
3899 }
3900 
3902  unsigned int nCameraIndex, unsigned int &nMarkerWidth, unsigned int &nMarkerHeight,
3903  unsigned int &nVideoWidth, unsigned int &nVideoHeight) const
3904 {
3905  if (nCameraIndex < msGeneralSettings.vsCameras.size())
3906  {
3907  nMarkerWidth = msGeneralSettings.vsCameras[nCameraIndex].nMarkerResolutionWidth;
3908  nMarkerHeight = msGeneralSettings.vsCameras[nCameraIndex].nMarkerResolutionHeight;
3909  nVideoWidth = msGeneralSettings.vsCameras[nCameraIndex].nVideoResolutionWidth;
3910  nVideoHeight = msGeneralSettings.vsCameras[nCameraIndex].nVideoResolutionHeight;
3911  return true;
3912  }
3913  return false;
3914 }
3915 
3917  unsigned int nCameraIndex, unsigned int &nMarkerLeft, unsigned int &nMarkerTop,
3918  unsigned int &nMarkerRight, unsigned int &nMarkerBottom,
3919  unsigned int &nVideoLeft, unsigned int &nVideoTop,
3920  unsigned int &nVideoRight, unsigned int &nVideoBottom) const
3921 {
3922  if (nCameraIndex < msGeneralSettings.vsCameras.size())
3923  {
3924  nMarkerLeft = msGeneralSettings.vsCameras[nCameraIndex].nMarkerFOVLeft;
3925  nMarkerTop = msGeneralSettings.vsCameras[nCameraIndex].nMarkerFOVTop;
3926  nMarkerRight = msGeneralSettings.vsCameras[nCameraIndex].nMarkerFOVRight;
3927  nMarkerBottom = msGeneralSettings.vsCameras[nCameraIndex].nMarkerFOVBottom;
3928  nVideoLeft = msGeneralSettings.vsCameras[nCameraIndex].nVideoFOVLeft;
3929  nVideoTop = msGeneralSettings.vsCameras[nCameraIndex].nVideoFOVTop;
3930  nVideoRight = msGeneralSettings.vsCameras[nCameraIndex].nVideoFOVRight;
3931  nVideoBottom = msGeneralSettings.vsCameras[nCameraIndex].nVideoFOVBottom;
3932  return true;
3933  }
3934  return false;
3935 }
3936 
3937 bool CRTProtocol::GetCameraLensControlSettings(const unsigned int nCameraIndex, float* focus, float* aperture) const
3938 {
3939  if (nCameraIndex < msGeneralSettings.vsCameras.size())
3940  {
3941  *focus = msGeneralSettings.vsCameras[nCameraIndex].fFocus;
3942  if (std::isnan(*focus))
3943  return false;
3944  *aperture = msGeneralSettings.vsCameras[nCameraIndex].fAperture;
3945  return true;
3946  }
3947  return false;
3948 }
3949 
3950 bool CRTProtocol::GetCameraAutoExposureSettings(const unsigned int nCameraIndex, bool* autoExposureEnabled, float* autoExposureCompensation) const
3951 {
3952  if (nCameraIndex < msGeneralSettings.vsCameras.size())
3953  {
3954  *autoExposureCompensation = msGeneralSettings.vsCameras[nCameraIndex].autoExposureCompensation;
3955  if (std::isnan(*autoExposureCompensation))
3956  return false;
3957  *autoExposureEnabled = msGeneralSettings.vsCameras[nCameraIndex].autoExposureEnabled;
3958  return true;
3959  }
3960  return false;
3961 }
3962 
3963 bool CRTProtocol::GetCameraAutoWhiteBalance(const unsigned int nCameraIndex, bool* autoWhiteBalanceEnabled) const
3964 {
3965  if (nCameraIndex < msGeneralSettings.vsCameras.size() && msGeneralSettings.vsCameras[nCameraIndex].autoWhiteBalance >= 0)
3966  {
3967  *autoWhiteBalanceEnabled = msGeneralSettings.vsCameras[nCameraIndex].autoWhiteBalance == 1;
3968  return true;
3969  }
3970  return false;
3971 }
3972 
3974 {
3975  return ms3DSettings.eAxisUpwards;
3976 }
3977 
3978 const char* CRTProtocol::Get3DCalibrated() const
3979 {
3980  return ms3DSettings.pCalibrationTime;
3981 }
3982 
3984 {
3985  return (unsigned int)ms3DSettings.s3DLabels.size();
3986 }
3987 
3988 const char* CRTProtocol::Get3DLabelName(unsigned int nMarkerIndex) const
3989 {
3990  if (nMarkerIndex < ms3DSettings.s3DLabels.size())
3991  {
3992  return ms3DSettings.s3DLabels[nMarkerIndex].oName.c_str();
3993  }
3994  return nullptr;
3995 }
3996 
3997 unsigned int CRTProtocol::Get3DLabelColor(unsigned int nMarkerIndex) const
3998 {
3999  if (nMarkerIndex < ms3DSettings.s3DLabels.size())
4000  {
4001  return ms3DSettings.s3DLabels[nMarkerIndex].nRGBColor;
4002  }
4003  return 0;
4004 }
4005 
4006 
4007 unsigned int CRTProtocol::Get3DBoneCount() const
4008 {
4009  return (unsigned int)ms3DSettings.sBones.size();
4010 }
4011 
4012 const char* CRTProtocol::Get3DBoneFromName(unsigned int boneIndex) const
4013 {
4014  if (boneIndex < ms3DSettings.sBones.size())
4015  {
4016  return ms3DSettings.sBones[boneIndex].fromName.c_str();
4017  }
4018  return nullptr;
4019 }
4020 
4021 const char* CRTProtocol::Get3DBoneToName(unsigned int boneIndex) const
4022 {
4023  if (boneIndex < ms3DSettings.sBones.size())
4024  {
4025  return ms3DSettings.sBones[boneIndex].toName.c_str();
4026  }
4027  return nullptr;
4028 }
4029 
4030 void CRTProtocol::Get6DOFEulerNames(std::string &first, std::string &second, std::string &third) const
4031 {
4032  first = mvs6DOFSettings.eulerFirst;
4033  second = mvs6DOFSettings.eulerSecond;
4034  third = mvs6DOFSettings.eulerThird;
4035 }
4036 
4037 
4038 unsigned int CRTProtocol::Get6DOFBodyCount() const
4039 {
4040  return (unsigned int)mvs6DOFSettings.bodySettings.size();
4041 }
4042 
4043 
4044 const char* CRTProtocol::Get6DOFBodyName(unsigned int nBodyIndex) const
4045 {
4046  if (nBodyIndex < mvs6DOFSettings.bodySettings.size())
4047  {
4048  return mvs6DOFSettings.bodySettings[nBodyIndex].oName.c_str();
4049  }
4050  return nullptr;
4051 }
4052 
4053 
4054 unsigned int CRTProtocol::Get6DOFBodyColor(unsigned int nBodyIndex) const
4055 {
4056  if (nBodyIndex < mvs6DOFSettings.bodySettings.size())
4057  {
4058  return mvs6DOFSettings.bodySettings[nBodyIndex].nRGBColor;
4059  }
4060  return 0;
4061 }
4062 
4063 
4064 unsigned int CRTProtocol::Get6DOFBodyPointCount(unsigned int nBodyIndex) const
4065 {
4066  if (nBodyIndex < mvs6DOFSettings.bodySettings.size())
4067  {
4068  return (unsigned int)mvs6DOFSettings.bodySettings.at(nBodyIndex).vsPoints.size();
4069  }
4070  return false;
4071 }
4072 
4073 
4074 bool CRTProtocol::Get6DOFBodyPoint(unsigned int nBodyIndex, unsigned int nMarkerIndex, SPoint &sPoint) const
4075 {
4076  if (nBodyIndex < mvs6DOFSettings.bodySettings.size())
4077  {
4078  if (nMarkerIndex < mvs6DOFSettings.bodySettings.at(nBodyIndex).vsPoints.size())
4079  {
4080  sPoint.fX = mvs6DOFSettings.bodySettings.at(nBodyIndex).vsPoints[nMarkerIndex].fX;
4081  sPoint.fY = mvs6DOFSettings.bodySettings.at(nBodyIndex).vsPoints[nMarkerIndex].fY;
4082  sPoint.fZ = mvs6DOFSettings.bodySettings.at(nBodyIndex).vsPoints[nMarkerIndex].fZ;
4083  return true;
4084  }
4085  }
4086  return false;
4087 }
4088 
4089 
4091 {
4092  return (unsigned int)mvsGazeVectorSettings.size();
4093 }
4094 
4095 
4096 const char* CRTProtocol::GetGazeVectorName(unsigned int nGazeVectorIndex) const
4097 {
4098  if (nGazeVectorIndex < mvsGazeVectorSettings.size())
4099  {
4100  return mvsGazeVectorSettings[nGazeVectorIndex].name.c_str();
4101  }
4102  return nullptr;
4103 }
4104 
4105 float CRTProtocol::GetGazeVectorFrequency(unsigned int nGazeVectorIndex) const
4106 {
4107  if (nGazeVectorIndex < mvsGazeVectorSettings.size())
4108  {
4109  return mvsGazeVectorSettings[nGazeVectorIndex].frequency;
4110  }
4111  return 0;
4112 }
4113 
4114 
4116 {
4117  return (unsigned int)mvsAnalogDeviceSettings.size();
4118 }
4119 
4120 
4121 bool CRTProtocol::GetAnalogDevice(unsigned int nDeviceIndex, unsigned int &nDeviceID, unsigned int &nChannels,
4122  char* &pName, unsigned int &nFrequency, char* &pUnit,
4123  float &fMinRange, float &fMaxRange) const
4124 {
4125  if (nDeviceIndex < mvsAnalogDeviceSettings.size())
4126  {
4127  nDeviceID = mvsAnalogDeviceSettings.at(nDeviceIndex).nDeviceID;
4128  pName = (char*)mvsAnalogDeviceSettings.at(nDeviceIndex).oName.c_str();
4129  nChannels = mvsAnalogDeviceSettings.at(nDeviceIndex).nChannels;
4130  nFrequency = mvsAnalogDeviceSettings.at(nDeviceIndex).nFrequency;
4131  pUnit = (char*)mvsAnalogDeviceSettings.at(nDeviceIndex).oUnit.c_str();
4132  fMinRange = mvsAnalogDeviceSettings.at(nDeviceIndex).fMinRange;
4133  fMaxRange = mvsAnalogDeviceSettings.at(nDeviceIndex).fMaxRange;
4134 
4135  return true;
4136  }
4137  return false;
4138 }
4139 
4140 
4141 const char* CRTProtocol::GetAnalogLabel(unsigned int nDeviceIndex, unsigned int nChannelIndex) const
4142 {
4143  if (nDeviceIndex < mvsAnalogDeviceSettings.size())
4144  {
4145  if (nChannelIndex < mvsAnalogDeviceSettings.at(nDeviceIndex).voLabels.size())
4146  {
4147  return mvsAnalogDeviceSettings.at(nDeviceIndex).voLabels.at(nChannelIndex).c_str();
4148  }
4149  }
4150  return nullptr;
4151 }
4152 
4153 
4154 const char* CRTProtocol::GetAnalogUnit(unsigned int nDeviceIndex, unsigned int nChannelIndex) const
4155 {
4156  if (nDeviceIndex < mvsAnalogDeviceSettings.size())
4157  {
4158  if (nChannelIndex < mvsAnalogDeviceSettings.at(nDeviceIndex).voUnits.size())
4159  {
4160  return mvsAnalogDeviceSettings.at(nDeviceIndex).voUnits.at(nChannelIndex).c_str();
4161  }
4162  }
4163  return nullptr;
4164 }
4165 
4166 
4167 void CRTProtocol::GetForceUnits(char* &pLength, char* &pForce) const
4168 {
4169  pLength = (char*)msForceSettings.oUnitLength.c_str();
4170  pForce = (char*)msForceSettings.oUnitForce.c_str();
4171 }
4172 
4173 
4175 {
4176  return (unsigned int)msForceSettings.vsForcePlates.size();
4177 }
4178 
4179 
4180 bool CRTProtocol::GetForcePlate(unsigned int nPlateIndex, unsigned int &nID, unsigned int &nAnalogDeviceID,
4181  unsigned int &nFrequency, char* &pType, char* &pName, float &fLength, float &fWidth) const
4182 {
4183  if (nPlateIndex < msForceSettings.vsForcePlates.size())
4184  {
4185  nID = msForceSettings.vsForcePlates[nPlateIndex].nID;
4186  nAnalogDeviceID = msForceSettings.vsForcePlates[nPlateIndex].nAnalogDeviceID;
4187  nFrequency = msForceSettings.vsForcePlates[nPlateIndex].nFrequency;
4188  pType = (char*)msForceSettings.vsForcePlates[nPlateIndex].oType.c_str();
4189  pName = (char*)msForceSettings.vsForcePlates[nPlateIndex].oName.c_str();
4190  fLength = msForceSettings.vsForcePlates[nPlateIndex].fLength;
4191  fWidth = msForceSettings.vsForcePlates[nPlateIndex].fWidth;
4192  return true;
4193  }
4194  return false;
4195 }
4196 
4197 
4198 bool CRTProtocol::GetForcePlateLocation(unsigned int nPlateIndex, SPoint sCorner[4]) const
4199 {
4200  if (nPlateIndex < msForceSettings.vsForcePlates.size())
4201  {
4202  memcpy(sCorner, msForceSettings.vsForcePlates[nPlateIndex].asCorner, 3 * 4 * sizeof(float));
4203  return true;
4204  }
4205  return false;
4206 }
4207 
4208 
4209 bool CRTProtocol::GetForcePlateOrigin(unsigned int nPlateIndex, SPoint &sOrigin) const
4210 {
4211  if (nPlateIndex < msForceSettings.vsForcePlates.size())
4212  {
4213  sOrigin = msForceSettings.vsForcePlates[nPlateIndex].sOrigin;
4214  return true;
4215  }
4216  return false;
4217 }
4218 
4219 
4220 unsigned int CRTProtocol::GetForcePlateChannelCount(unsigned int nPlateIndex) const
4221 {
4222  if (nPlateIndex < msForceSettings.vsForcePlates.size())
4223  {
4224  return (unsigned int)msForceSettings.vsForcePlates[nPlateIndex].vChannels.size();
4225  }
4226  return 0;
4227 }
4228 
4229 
4230 bool CRTProtocol::GetForcePlateChannel(unsigned int nPlateIndex, unsigned int nChannelIndex,
4231  unsigned int &nChannelNumber, float &fConversionFactor) const
4232 {
4233  if (nPlateIndex < msForceSettings.vsForcePlates.size())
4234  {
4235  if (nChannelIndex < msForceSettings.vsForcePlates[nPlateIndex].vChannels.size())
4236  {
4237  nChannelNumber = msForceSettings.vsForcePlates[nPlateIndex].vChannels[nChannelIndex].nChannelNumber;
4238  fConversionFactor = msForceSettings.vsForcePlates[nPlateIndex].vChannels[nChannelIndex].fConversionFactor;
4239  return true;
4240  }
4241  }
4242  return false;
4243 }
4244 
4245 
4246 bool CRTProtocol::GetForcePlateCalibrationMatrix(unsigned int nPlateIndex, float fvCalMatrix[12][12], unsigned int* rows, unsigned int* columns) const
4247 {
4248  if (nPlateIndex < msForceSettings.vsForcePlates.size())
4249  {
4250  if (msForceSettings.vsForcePlates[nPlateIndex].bValidCalibrationMatrix)
4251  {
4252  *rows = msForceSettings.vsForcePlates[nPlateIndex].nCalibrationMatrixRows;
4253  *columns = msForceSettings.vsForcePlates[nPlateIndex].nCalibrationMatrixColumns;
4254  memcpy(
4255  fvCalMatrix,
4256  msForceSettings.vsForcePlates[nPlateIndex].afCalibrationMatrix,
4257  msForceSettings.vsForcePlates[nPlateIndex].nCalibrationMatrixRows * msForceSettings.vsForcePlates[nPlateIndex].nCalibrationMatrixColumns * sizeof(float));
4258  return true;
4259  }
4260  }
4261  return false;
4262 }
4263 
4264 
4266 {
4267  return (unsigned int)mvsImageSettings.size();
4268 }
4269 
4270 
4271 bool CRTProtocol::GetImageCamera(unsigned int nCameraIndex, unsigned int &nCameraID, bool &bEnabled,
4272  CRTPacket::EImageFormat &eFormat, unsigned int &nWidth, unsigned int &nHeight,
4273  float &fCropLeft, float &fCropTop, float &fCropRight, float &fCropBottom) const
4274 {
4275  if (nCameraIndex < mvsImageSettings.size())
4276  {
4277  nCameraID = mvsImageSettings[nCameraIndex].nID;
4278  bEnabled = mvsImageSettings[nCameraIndex].bEnabled;
4279  eFormat = mvsImageSettings[nCameraIndex].eFormat;
4280  nWidth = mvsImageSettings[nCameraIndex].nWidth;
4281  nHeight = mvsImageSettings[nCameraIndex].nHeight;
4282  fCropLeft = mvsImageSettings[nCameraIndex].fCropLeft;
4283  fCropTop = mvsImageSettings[nCameraIndex].fCropTop;
4284  fCropRight = mvsImageSettings[nCameraIndex].fCropRight;
4285  fCropBottom = mvsImageSettings[nCameraIndex].fCropBottom;
4286  return true;
4287  }
4288  return false;
4289 }
4290 
4291 unsigned int CRTProtocol::GetSkeletonCount() const
4292 {
4293  return (unsigned int)mSkeletonSettings.size();
4294 }
4295 
4296 
4297 const char* CRTProtocol::GetSkeletonName(unsigned int skeletonIndex)
4298 {
4299  if (skeletonIndex < mSkeletonSettings.size())
4300  {
4301  return (char*)mSkeletonSettings[skeletonIndex].name.c_str();
4302  }
4303  return nullptr;
4304 }
4305 
4306 
4307 unsigned int CRTProtocol::GetSkeletonSegmentCount(unsigned int skeletonIndex)
4308 {
4309  if (skeletonIndex < mSkeletonSettings.size())
4310  {
4311  return static_cast<long unsigned>(mSkeletonSettings[skeletonIndex].segments.size());
4312  }
4313  return 0;
4314 }
4315 
4316 bool CRTProtocol::GetSkeleton(unsigned int skeletonIndex, SSettingsSkeleton* skeleton)
4317 {
4318  if (skeleton == nullptr)
4319  return false;
4320 
4321  if (skeletonIndex < mSkeletonSettings.size())
4322  {
4323  *skeleton = mSkeletonSettings[skeletonIndex];
4324  return true;
4325  }
4326  return false;
4327 }
4328 
4329 bool CRTProtocol::GetSkeletonSegment(unsigned int skeletonIndex, unsigned int segmentIndex, SSettingsSkeletonSegment* segment)
4330 {
4331  if (segment == nullptr)
4332  return false;
4333 
4334  if (skeletonIndex < mSkeletonSettings.size())
4335  {
4336  if (segmentIndex < mSkeletonSettings[skeletonIndex].segments.size())
4337  {
4338  *segment = mSkeletonSettings[skeletonIndex].segments[segmentIndex];
4339  return true;
4340  }
4341  }
4342  return false;
4343 }
4344 
4345 
4347 {
4348  return msGeneralSettings.sCameraSystem.eType;
4349 }
4350 
4351 
4353  const unsigned int* pnCaptureFrequency, const float* pfCaptureTime,
4354  const bool* pbStartOnExtTrig, const bool* startOnTrigNO, const bool* startOnTrigNC, const bool* startOnTrigSoftware,
4355  const EProcessingActions* peProcessingActions, const EProcessingActions* peRtProcessingActions, const EProcessingActions* peReprocessingActions)
4356 {
4357  CMarkup oXML;
4358 
4359  oXML.AddElem("QTM_Settings");
4360  oXML.IntoElem();
4361  oXML.AddElem("General");
4362  oXML.IntoElem();
4363 
4364  if (pnCaptureFrequency)
4365  {
4366  AddXMLElementUnsignedInt(&oXML, "Frequency", pnCaptureFrequency);
4367  }
4368  if (pfCaptureTime)
4369  {
4370  AddXMLElementFloat(&oXML, "Capture_Time", pfCaptureTime, 3);
4371  }
4372  if (pbStartOnExtTrig)
4373  {
4374  AddXMLElementBool(&oXML, "Start_On_External_Trigger", pbStartOnExtTrig);
4375  if (mnMajorVersion > 1 || mnMinorVersion > 14)
4376  {
4377  AddXMLElementBool(&oXML, "Start_On_Trigger_NO", startOnTrigNO);
4378  AddXMLElementBool(&oXML, "Start_On_Trigger_NC", startOnTrigNC);
4379  AddXMLElementBool(&oXML, "Start_On_Trigger_Software", startOnTrigSoftware);
4380  }
4381  }
4382 
4383  const char* processings[3] = { "Processing_Actions", "RealTime_Processing_Actions", "Reprocessing_Actions" };
4384  const EProcessingActions* processingActions[3] = { peProcessingActions, peRtProcessingActions, peReprocessingActions };
4385 
4386  auto actionsCount = (mnMajorVersion > 1 || mnMinorVersion > 13) ? 3 : 1;
4387 
4388  for (auto i = 0; i < actionsCount; i++)
4389  {
4390  if (processingActions[i])
4391  {
4392  oXML.AddElem(processings[i]);
4393  oXML.IntoElem();
4394 
4395  if (mnMajorVersion > 1 || mnMinorVersion > 13)
4396  {
4397  AddXMLElementBool(&oXML, "PreProcessing2D", (*processingActions[i] & ProcessingPreProcess2D) != 0);
4398  }
4399  if (*processingActions[i] & ProcessingTracking2D && i != 1) // i != 1 => Not RtProcessingSettings
4400  {
4401  oXML.AddElem("Tracking", "2D");
4402  }
4403  else if (*processingActions[i] & ProcessingTracking3D)
4404  {
4405  oXML.AddElem("Tracking", "3D");
4406  }
4407  else
4408  {
4409  oXML.AddElem("Tracking", "False");
4410  }
4411  if (i != 1) //Not RtProcessingSettings
4412  {
4413  AddXMLElementBool(&oXML, "TwinSystemMerge", (*processingActions[i] & ProcessingTwinSystemMerge) != 0);
4414  AddXMLElementBool(&oXML, "SplineFill", (*processingActions[i] & ProcessingSplineFill) != 0);
4415  }
4416  AddXMLElementBool(&oXML, "AIM", (*processingActions[i] & ProcessingAIM) != 0);
4417  AddXMLElementBool(&oXML, "Track6DOF", (*processingActions[i] & Processing6DOFTracking) != 0);
4418  AddXMLElementBool(&oXML, "ForceData", (*processingActions[i] & ProcessingForceData) != 0);
4419  AddXMLElementBool(&oXML, "GazeVector", (*processingActions[i] & ProcessingGazeVector) != 0);
4420  if (i != 1) //Not RtProcessingSettings
4421  {
4422  AddXMLElementBool(&oXML, "ExportTSV", (*processingActions[i] & ProcessingExportTSV) != 0);
4423  AddXMLElementBool(&oXML, "ExportC3D", (*processingActions[i] & ProcessingExportC3D) != 0);
4424  AddXMLElementBool(&oXML, "ExportMatlabFile", (*processingActions[i] & ProcessingExportMatlabFile) != 0);
4425  AddXMLElementBool(&oXML, "ExportAviFile", (*processingActions[i] & ProcessingExportAviFile) != 0);
4426  }
4427  oXML.OutOfElem(); // Processing_Actions
4428  }
4429  }
4430  oXML.OutOfElem(); // General
4431  oXML.OutOfElem(); // QTM_Settings
4432 
4433  if (SendXML(oXML.GetDoc().c_str()))
4434  {
4435  return true;
4436  }
4437 
4438  return false;
4439 } // SetGeneral
4440 
4441 
4443  const bool* pbEnabled, const ESignalSource* peSignalSource,
4444  const bool* pbSignalModePeriodic, const unsigned int* pnFreqMultiplier,
4445  const unsigned int* pnFreqDivisor, const unsigned int* pnFreqTolerance,
4446  const float* pfNominalFrequency, const bool* pbNegativeEdge,
4447  const unsigned int* pnSignalShutterDelay, const float* pfNonPeriodicTimeout)
4448 {
4449  CMarkup oXML;
4450 
4451  oXML.AddElem("QTM_Settings");
4452  oXML.IntoElem();
4453  oXML.AddElem("General");
4454  oXML.IntoElem();
4455  oXML.AddElem("External_Time_Base");
4456  oXML.IntoElem();
4457 
4458  AddXMLElementBool(&oXML, "Enabled", pbEnabled);
4459 
4460  if (peSignalSource)
4461  {
4462  switch (*peSignalSource)
4463  {
4464  case SourceControlPort :
4465  oXML.AddElem("Signal_Source", "Control port");
4466  break;
4467  case SourceIRReceiver :
4468  oXML.AddElem("Signal_Source", "IR receiver");
4469  break;
4470  case SourceSMPTE :
4471  oXML.AddElem("Signal_Source", "SMPTE");
4472  break;
4473  case SourceVideoSync :
4474  oXML.AddElem("Signal_Source", "Video sync");
4475  break;
4476  case SourceIRIG:
4477  oXML.AddElem("Signal_Source", "IRIG");
4478  break;
4479  }
4480  }
4481 
4482  AddXMLElementBool(&oXML, "Signal_Mode", pbSignalModePeriodic, "Periodic", "Non-periodic");
4483  AddXMLElementUnsignedInt(&oXML, "Frequency_Multiplier", pnFreqMultiplier);
4484  AddXMLElementUnsignedInt(&oXML, "Frequency_Divisor", pnFreqDivisor);
4485  AddXMLElementUnsignedInt(&oXML, "Frequency_Tolerance", pnFreqTolerance);
4486 
4487  if (pfNominalFrequency)
4488  {
4489  if (*pfNominalFrequency < 0)
4490  {
4491  oXML.AddElem("Nominal_Frequency", "None");
4492  }
4493  else
4494  {
4495  AddXMLElementFloat(&oXML, "Nominal_Frequency", pfNominalFrequency, 3);
4496  }
4497  }
4498 
4499  AddXMLElementBool(&oXML, "Signal_Edge", pbNegativeEdge, "Negative", "Positive");
4500  AddXMLElementUnsignedInt(&oXML, "Signal_Shutter_Delay", pnSignalShutterDelay);
4501  AddXMLElementFloat(&oXML, "Non_Periodic_Timeout", pfNonPeriodicTimeout, 3);
4502 
4503  oXML.OutOfElem(); // External_Time_Base
4504  oXML.OutOfElem(); // General
4505  oXML.OutOfElem(); // QTM_Settings
4506 
4507  if (SendXML(oXML.GetDoc().c_str()))
4508  {
4509  return true;
4510  }
4511 
4512  return false;
4513 } // SetGeneralExtTimeBase
4514 
4515 
4516 // nCameraID starts on 1. If nCameraID < 0 then settings are applied to all cameras.
4518  const unsigned int nCameraID, const ECameraMode* peMode,
4519  const float* pfMarkerExposure, const float* pfMarkerThreshold,
4520  const int* pnOrientation)
4521 {
4522  CMarkup oXML;
4523 
4524  oXML.AddElem("QTM_Settings");
4525  oXML.IntoElem();
4526  oXML.AddElem("General");
4527  oXML.IntoElem();
4528 
4529  oXML.AddElem("Camera");
4530  oXML.IntoElem();
4531 
4532  AddXMLElementUnsignedInt(&oXML, "ID", &nCameraID);
4533 
4534  if (peMode)
4535  {
4536  switch (*peMode)
4537  {
4538  case ModeMarker :
4539  oXML.AddElem("Mode", "Marker");
4540  break;
4541  case ModeMarkerIntensity :
4542  oXML.AddElem("Mode", "Marker Intensity");
4543  break;
4544  case ModeVideo :
4545  oXML.AddElem("Mode", "Video");
4546  break;
4547  }
4548  }
4549  AddXMLElementFloat(&oXML, "Marker_Exposure", pfMarkerExposure);
4550  AddXMLElementFloat(&oXML, "Marker_Threshold", pfMarkerThreshold);
4551  AddXMLElementInt(&oXML, "Orientation", pnOrientation);
4552 
4553  oXML.OutOfElem(); // Camera
4554  oXML.OutOfElem(); // General
4555  oXML.OutOfElem(); // QTM_Settings
4556 
4557  if (SendXML(oXML.GetDoc().c_str()))
4558  {
4559  return true;
4560  }
4561 
4562  return false;
4563 } // SetGeneralCamera
4564 
4565 
4566 // nCameraID starts on 1. If nCameraID < 0 then settings are applied to all cameras.
4568  const unsigned int nCameraID, const EVideoResolution* eVideoResolution,
4569  const EVideoAspectRatio* eVideoAspectRatio, const unsigned int* pnVideoFrequency,
4570  const float* pfVideoExposure, const float* pfVideoFlashTime)
4571 {
4572  CMarkup oXML;
4573 
4574  oXML.AddElem("QTM_Settings");
4575  oXML.IntoElem();
4576  oXML.AddElem("General");
4577  oXML.IntoElem();
4578 
4579  oXML.AddElem("Camera");
4580  oXML.IntoElem();
4581 
4582  AddXMLElementUnsignedInt(&oXML, "ID", &nCameraID);
4583  if (eVideoResolution)
4584  {
4585  switch (*eVideoResolution)
4586  {
4587  case VideoResolution1080p:
4588  oXML.AddElem("Video_Resolution", "1080p");
4589  break;
4590  case VideoResolution720p:
4591  oXML.AddElem("Video_Resolution", "720p");
4592  break;
4593  case VideoResolution540p:
4594  oXML.AddElem("Video_Resolution", "540p");
4595  break;
4596  case VideoResolution480p:
4597  oXML.AddElem("Video_Resolution", "480p");
4598  break;
4599  case VideoResolutionNone:
4600  break;
4601  }
4602  }
4603  if (eVideoAspectRatio)
4604  {
4605  switch (*eVideoAspectRatio)
4606  {
4607  case VideoAspectRatio16x9:
4608  oXML.AddElem("Video_Aspect_Ratio", "16x9");
4609  break;
4610  case VideoAspectRatio4x3:
4611  oXML.AddElem("Video_Aspect_Ratio", "4x3");
4612  break;
4613  case VideoAspectRatio1x1:
4614  oXML.AddElem("Video_Aspect_Ratio", "1x1");
4615  break;
4616  case VideoAspectRatioNone:
4617  break;
4618  }
4619  }
4620  AddXMLElementUnsignedInt(&oXML, "Video_Frequency", pnVideoFrequency);
4621  AddXMLElementFloat(&oXML, "Video_Exposure", pfVideoExposure);
4622  AddXMLElementFloat(&oXML, "Video_Flash_Time", pfVideoFlashTime);
4623 
4624  oXML.OutOfElem(); // Camera
4625  oXML.OutOfElem(); // General
4626  oXML.OutOfElem(); // QTM_Settings
4627 
4628  if (SendXML(oXML.GetDoc().c_str()))
4629  {
4630  return true;
4631  }
4632 
4633  return false;
4634 } // SetGeneralCameraVideo
4635 
4636 
4637 // nCameraID starts on 1. If nCameraID < 0 then settings are applied to all cameras.
4639  const unsigned int nCameraID, const unsigned int portNumber, const ESyncOutFreqMode* peSyncOutMode,
4640  const unsigned int* pnSyncOutValue, const float* pfSyncOutDutyCycle,
4641  const bool* pbSyncOutNegativePolarity)
4642 {
4643  CMarkup oXML;
4644 
4645  oXML.AddElem("QTM_Settings");
4646  oXML.IntoElem();
4647  oXML.AddElem("General");
4648  oXML.IntoElem();
4649 
4650  oXML.AddElem("Camera");
4651  oXML.IntoElem();
4652 
4653  AddXMLElementUnsignedInt(&oXML, "ID", &nCameraID);
4654 
4655  int port = portNumber - 1;
4656  if (((port == 0 || port == 1) && peSyncOutMode) || (port == 2))
4657  {
4658  oXML.AddElem(port == 0 ? "Sync_Out" : (port == 1 ? "Sync_Out2" : "Sync_Out_MT"));
4659  oXML.IntoElem();
4660 
4661  if (port == 0 || port == 1)
4662  {
4663  switch (*peSyncOutMode)
4664  {
4665  case ModeShutterOut:
4666  oXML.AddElem("Mode", "Shutter out");
4667  break;
4668  case ModeMultiplier:
4669  oXML.AddElem("Mode", "Multiplier");
4670  break;
4671  case ModeDivisor:
4672  oXML.AddElem("Mode", "Divisor");
4673  break;
4674  case ModeActualFreq:
4675  oXML.AddElem("Mode", "Camera independent");
4676  break;
4677  case ModeMeasurementTime:
4678  oXML.AddElem("Mode", "Measurement time");
4679  break;
4680  case ModeFixed100Hz:
4681  oXML.AddElem("Mode", "Continuous 100Hz");
4682  break;
4683  default:
4684  return false; // Should never happen
4685  }
4686 
4687  if (*peSyncOutMode == ModeMultiplier ||
4688  *peSyncOutMode == ModeDivisor ||
4689  *peSyncOutMode == ModeActualFreq)
4690  {
4691  if (pnSyncOutValue)
4692  {
4693  AddXMLElementUnsignedInt(&oXML, "Value", pnSyncOutValue);
4694  }
4695  if (pfSyncOutDutyCycle)
4696  {
4697  AddXMLElementFloat(&oXML, "Duty_Cycle", pfSyncOutDutyCycle, 3);
4698  }
4699  }
4700  }
4701  if (pbSyncOutNegativePolarity && (port == 2 ||
4702  (peSyncOutMode && *peSyncOutMode != ModeFixed100Hz)))
4703  {
4704  AddXMLElementBool(&oXML, "Signal_Polarity", pbSyncOutNegativePolarity, "Negative", "Positive");
4705  }
4706  oXML.OutOfElem(); // Sync_Out
4707  }
4708  oXML.OutOfElem(); // Camera
4709  oXML.OutOfElem(); // General
4710  oXML.OutOfElem(); // QTM_Settings
4711 
4712  if (SendXML(oXML.GetDoc().c_str()))
4713  {
4714  return true;
4715  }
4716 
4717  return false;
4718 } // SetGeneralCameraSyncOut
4719 
4720 
4721  // nCameraID starts on 1. If nCameraID < 0 then settings are applied to all cameras.
4722 bool CRTProtocol::SetCameraLensControlSettings(const unsigned int nCameraID, const float focus, const float aperture)
4723 {
4724  CMarkup oXML;
4725 
4726  oXML.AddElem("QTM_Settings");
4727  oXML.IntoElem();
4728  oXML.AddElem("General");
4729  oXML.IntoElem();
4730 
4731  oXML.AddElem("Camera");
4732  oXML.IntoElem();
4733 
4734  AddXMLElementUnsignedInt(&oXML, "ID", &nCameraID);
4735 
4736  oXML.AddElem("LensControl");
4737  oXML.IntoElem();
4738 
4739  oXML.AddElem("Focus");
4740  oXML.AddAttrib("Value", CMarkup::Format("%f", focus).c_str());
4741  oXML.AddElem("Aperture");
4742  oXML.AddAttrib("Value", CMarkup::Format("%f", aperture).c_str());
4743 
4744  oXML.OutOfElem(); // LensControl
4745  oXML.OutOfElem(); // Camera
4746  oXML.OutOfElem(); // General
4747  oXML.OutOfElem(); // QTM_Settings
4748 
4749  if (SendXML(oXML.GetDoc().c_str()))
4750  {
4751  return true;
4752  }
4753 
4754  return false;
4755 }
4756 
4757 // nCameraID starts on 1. If nCameraID < 0 then settings are applied to all cameras.
4758 bool CRTProtocol::SetCameraAutoExposureSettings(const unsigned int nCameraID, const bool autoExposure, const float compensation)
4759 {
4760  CMarkup oXML;
4761 
4762  oXML.AddElem("QTM_Settings");
4763  oXML.IntoElem();
4764  oXML.AddElem("General");
4765  oXML.IntoElem();
4766 
4767  oXML.AddElem("Camera");
4768  oXML.IntoElem();
4769 
4770  AddXMLElementUnsignedInt(&oXML, "ID", &nCameraID);
4771 
4772  oXML.AddElem("LensControl");
4773  oXML.IntoElem();
4774 
4775  oXML.AddElem("AutoExposure");
4776  oXML.AddAttrib("Enabled", autoExposure ? "true" : "false");
4777  oXML.AddAttrib("Compensation", CMarkup::Format("%f", compensation).c_str());
4778 
4779  oXML.OutOfElem(); // AutoExposure
4780  oXML.OutOfElem(); // Camera
4781  oXML.OutOfElem(); // General
4782  oXML.OutOfElem(); // QTM_Settings
4783 
4784  if (SendXML(oXML.GetDoc().c_str()))
4785  {
4786  return true;
4787  }
4788 
4789  return false;
4790 }
4791 
4792 // nCameraID starts on 1. If nCameraID < 0 then settings are applied to all cameras.
4793 bool CRTProtocol::SetCameraAutoWhiteBalance(const unsigned int nCameraID, const bool enable)
4794 {
4795  CMarkup oXML;
4796 
4797  oXML.AddElem("QTM_Settings");
4798  oXML.IntoElem();
4799  oXML.AddElem("General");
4800  oXML.IntoElem();
4801 
4802  oXML.AddElem("Camera");
4803  oXML.IntoElem();
4804 
4805  AddXMLElementUnsignedInt(&oXML, "ID", &nCameraID);
4806 
4807  oXML.AddElem("AutoWhiteBalance", enable ? "true" : "false");
4808 
4809  oXML.OutOfElem(); // Camera
4810  oXML.OutOfElem(); // General
4811  oXML.OutOfElem(); // QTM_Settings
4812 
4813  if (SendXML(oXML.GetDoc().c_str()))
4814  {
4815  return true;
4816  }
4817 
4818  return false;
4819 }
4820 
4821 
4823  const unsigned int nCameraID, const bool* pbEnable, const CRTPacket::EImageFormat* peFormat,
4824  const unsigned int* pnWidth, const unsigned int* pnHeight, const float* pfLeftCrop,
4825  const float* pfTopCrop, const float* pfRightCrop, const float* pfBottomCrop)
4826 {
4827  CMarkup oXML;
4828 
4829  oXML.AddElem("QTM_Settings");
4830  oXML.IntoElem();
4831  oXML.AddElem("Image");
4832  oXML.IntoElem();
4833 
4834  oXML.AddElem("Camera");
4835  oXML.IntoElem();
4836 
4837  AddXMLElementUnsignedInt(&oXML, "ID", &nCameraID);
4838 
4839  AddXMLElementBool(&oXML, "Enabled", pbEnable);
4840 
4841  if (peFormat)
4842  {
4843  switch (*peFormat)
4844  {
4846  oXML.AddElem("Format", "RAWGrayscale");
4847  break;
4849  oXML.AddElem("Format", "RAWBGR");
4850  break;
4851  case CRTPacket::FormatJPG :
4852  oXML.AddElem("Format", "JPG");
4853  break;
4854  case CRTPacket::FormatPNG :
4855  oXML.AddElem("Format", "PNG");
4856  break;
4857  }
4858  }
4859  AddXMLElementUnsignedInt(&oXML, "Width", pnWidth);
4860  AddXMLElementUnsignedInt(&oXML, "Height", pnHeight);
4861  AddXMLElementFloat(&oXML, "Left_Crop", pfLeftCrop);
4862  AddXMLElementFloat(&oXML, "Top_Crop", pfTopCrop);
4863  AddXMLElementFloat(&oXML, "Right_Crop", pfRightCrop);
4864  AddXMLElementFloat(&oXML, "Bottom_Crop", pfBottomCrop);
4865 
4866  oXML.OutOfElem(); // Camera
4867  oXML.OutOfElem(); // Image
4868  oXML.OutOfElem(); // QTM_Settings
4869 
4870  if (SendXML(oXML.GetDoc().c_str()))
4871  {
4872  return true;
4873  }
4874 
4875  return false;
4876 } // SetImageSettings
4877 
4878 
4880  const unsigned int nPlateID, const SPoint* psCorner1, const SPoint* psCorner2,
4881  const SPoint* psCorner3, const SPoint* psCorner4)
4882 {
4883  CMarkup oXML;
4884 
4885  if (nPlateID > 0)
4886  {
4887  oXML.AddElem("QTM_Settings");
4888  oXML.IntoElem();
4889  oXML.AddElem("Force");
4890  oXML.IntoElem();
4891 
4892  oXML.AddElem("Plate");
4893  oXML.IntoElem();
4894 
4895  if (mnMajorVersion > 1 || mnMinorVersion > 7)
4896  {
4897  AddXMLElementUnsignedInt(&oXML, "Plate_ID", &nPlateID);
4898  }
4899  else
4900  {
4901  AddXMLElementUnsignedInt(&oXML, "Force_Plate_Index", &nPlateID);
4902  }
4903  if (psCorner1)
4904  {
4905  oXML.AddElem("Corner1");
4906  oXML.IntoElem();
4907  AddXMLElementFloat(&oXML, "X", &(psCorner1->fX));
4908  AddXMLElementFloat(&oXML, "Y", &(psCorner1->fY));
4909  AddXMLElementFloat(&oXML, "Z", &(psCorner1->fZ));
4910  oXML.OutOfElem(); // Corner1
4911  }
4912  if (psCorner2)
4913  {
4914  oXML.AddElem("Corner2");
4915  oXML.IntoElem();
4916  AddXMLElementFloat(&oXML, "X", &(psCorner2->fX));
4917  AddXMLElementFloat(&oXML, "Y", &(psCorner2->fY));
4918  AddXMLElementFloat(&oXML, "Z", &(psCorner2->fZ));
4919  oXML.OutOfElem(); // Corner2
4920  }
4921  if (psCorner3)
4922  {
4923  oXML.AddElem("Corner3");
4924  oXML.IntoElem();
4925  AddXMLElementFloat(&oXML, "X", &(psCorner3->fX));
4926  AddXMLElementFloat(&oXML, "Y", &(psCorner3->fY));
4927  AddXMLElementFloat(&oXML, "Z", &(psCorner3->fZ));
4928  oXML.OutOfElem(); // Corner3
4929  }
4930  if (psCorner4)
4931  {
4932  oXML.AddElem("Corner4");
4933  oXML.IntoElem();
4934  AddXMLElementFloat(&oXML, "X", &(psCorner4->fX));
4935  AddXMLElementFloat(&oXML, "Y", &(psCorner4->fY));
4936  AddXMLElementFloat(&oXML, "Z", &(psCorner4->fZ));
4937  oXML.OutOfElem(); // Corner4
4938  }
4939  oXML.OutOfElem(); // Plate
4940 
4941  oXML.OutOfElem(); // Force
4942  oXML.OutOfElem(); // QTM_Settings
4943 
4944  if (SendXML(oXML.GetDoc().c_str()))
4945  {
4946  return true;
4947  }
4948  }
4949  else
4950  {
4951  sprintf(maErrorStr, "Illegal force plate id: %d.", nPlateID);
4952  }
4953  return false;
4954 } // SetForceSettings
4955 
4956 
4958 {
4959  return maErrorStr;
4960 }
4961 
4962 
4963 bool CRTProtocol::SendString(const char* pCmdStr, int nType)
4964 {
4965  auto nCmdStrLen = strlen(pCmdStr);
4966  static char aSendBuffer[5000];
4967 
4968  if (nCmdStrLen > sizeof(aSendBuffer))
4969  {
4970  strcpy(maErrorStr, "String is larger than send buffer.");
4971  return false;
4972  }
4973 
4974  //
4975  // Header size + length of the string + terminating null char
4976  //
4977  unsigned int nSize = 8 + (unsigned int)nCmdStrLen + 1;
4978 
4979  memcpy(aSendBuffer + 8, pCmdStr, nCmdStrLen + 1);
4980 
4981  if ((mnMajorVersion == 1 && mnMinorVersion == 0) || mbBigEndian)
4982  {
4983  *((unsigned int*)aSendBuffer) = htonl(nSize);
4984  *((unsigned int*)(aSendBuffer + 4)) = htonl(nType);
4985  }
4986  else
4987  {
4988  *((unsigned int*)aSendBuffer) = nSize;
4989  *((unsigned int*)(aSendBuffer + 4)) = nType;
4990  }
4991 
4992  if (mpoNetwork->Send(aSendBuffer, nSize) == false)
4993  {
4994  strcpy(maErrorStr, mpoNetwork->GetErrorString());
4995  return false;
4996  }
4997 
4998  return true;
4999 } // SendString
5000 
5001 
5002 bool CRTProtocol::SendCommand(const char* pCmdStr)
5003 {
5004  return SendString(pCmdStr, CRTPacket::PacketCommand);
5005 } // SendCommand
5006 
5007 
5008 bool CRTProtocol::SendCommand(const char* pCmdStr, char* pCommandResponseStr, unsigned int timeout)
5009 {
5010  CRTPacket::EPacketType eType;
5011 
5012  if (SendString(pCmdStr, CRTPacket::PacketCommand))
5013  {
5014  while (ReceiveRTPacket(eType, true, timeout) > 0)
5015  {
5016  if (eType == CRTPacket::PacketCommand)
5017  {
5018  strcpy(pCommandResponseStr, mpoRTPacket->GetCommandString());
5019  return true;
5020  }
5021  if (eType == CRTPacket::PacketError)
5022  {
5023  strcpy(pCommandResponseStr, mpoRTPacket->GetErrorString());
5024  return false;
5025  }
5026  }
5027  }
5028  else
5029  {
5030  char pTmpStr[256];
5031  strcpy(pTmpStr, maErrorStr);
5032  sprintf(maErrorStr, "\'%s\' command failed. %s", pCmdStr, pTmpStr);
5033  }
5034  pCommandResponseStr[0] = 0;
5035  return false;
5036 } // SendCommand
5037 
5038 
5039 bool CRTProtocol::SendXML(const char* pCmdStr)
5040 {
5041  CRTPacket::EPacketType eType;
5042 
5043  if (SendString(pCmdStr, CRTPacket::PacketXML))
5044  {
5045  if (ReceiveRTPacket(eType, true) > 0)
5046  {
5047  if (eType == CRTPacket::PacketCommand)
5048  {
5049  if (strcmp(mpoRTPacket->GetCommandString(), "Setting parameters succeeded") == 0)
5050  {
5051  return true;
5052  }
5053  else
5054  {
5055  sprintf(maErrorStr,
5056  "Expected command response \"Setting parameters succeeded\". Got \"%s\".",
5057  mpoRTPacket->GetCommandString());
5058  }
5059  }
5060  else
5061  {
5062  sprintf(maErrorStr, "Expected command response packet. Got packet type %d.", (int)eType);
5063  }
5064  }
5065  else
5066  {
5067  strcpy(maErrorStr, "Missing command response packet.");
5068  }
5069  }
5070  else
5071  {
5072  char pTmpStr[256];
5073  strcpy(pTmpStr, maErrorStr);
5074  sprintf(maErrorStr, "Failed to send XML string. %s", pTmpStr);
5075  }
5076  return false;
5077 } // SendXML
5078 
5079 
5080 void CRTProtocol::AddXMLElementBool(CMarkup* oXML, const char* tTag, const bool* pbValue, const char* tTrue, const char* tFalse)
5081 {
5082  if (pbValue)
5083  {
5084  oXML->AddElem(tTag, *pbValue ? tTrue : tFalse);
5085  }
5086 }
5087 
5088 
5089 void CRTProtocol::AddXMLElementBool(CMarkup* oXML, const char* tTag, const bool pbValue, const char* tTrue, const char* tFalse)
5090 {
5091  oXML->AddElem(tTag, pbValue ? tTrue : tFalse);
5092 }
5093 
5094 
5095 void CRTProtocol::AddXMLElementInt(CMarkup* oXML, const char* tTag, const int* pnValue)
5096 {
5097  if (pnValue)
5098  {
5099  std::string tVal;
5100 
5101  tVal = CMarkup::Format("%d", *pnValue);
5102  oXML->AddElem(tTag, tVal.c_str());
5103  }
5104 }
5105 
5106 
5107 void CRTProtocol::AddXMLElementUnsignedInt(CMarkup* oXML, const char* tTag, const unsigned int* pnValue)
5108 {
5109  if (pnValue)
5110  {
5111  std::string tVal;
5112 
5113  tVal = CMarkup::Format("%u", *pnValue);
5114  oXML->AddElem(tTag, tVal.c_str());
5115  }
5116 }
5117 
5118 void CRTProtocol::AddXMLElementFloat(CMarkup* oXML, const char* tTag, const float* pfValue, unsigned int pnDecimals)
5119 {
5120  if (pfValue)
5121  {
5122  std::string tVal;
5123  char fFormat[10];
5124 
5125  sprintf(fFormat, "%%.%df", pnDecimals);
5126  tVal = CMarkup::Format(fFormat, *pfValue);
5127  oXML->AddElem(tTag, tVal.c_str());
5128  }
5129 }
5130 
5131 bool CRTProtocol::CompareNoCase(std::string tStr1, const char* tStr2) const
5132 {
5133  std::transform(tStr1.begin(), tStr1.end(), tStr1.begin(), ::tolower);
5134  return tStr1.compare(tStr2) == 0;
5135 }
void Get6DOFEulerNames(std::string &first, std::string &second, std::string &third) const
int Receive(char *rtDataBuff, int nDataBufSize, bool bHeader, int nTimeout, unsigned int *ipAddr=nullptr)
Definition: Network.cpp:266
bool GetDiscoverResponse(unsigned int nIndex, unsigned int &nAddr, unsigned short &nBasePort, std::string &message)
Definition: RTProtocol.cpp:399
static const unsigned int cComponentImage
Definition: RTProtocol.h:44
bool GetCameraMarkerSettings(unsigned int nCameraIndex, unsigned int &nCurrentExposure, unsigned int &nMinExposure, unsigned int &nMaxExposure, unsigned int &nCurrentThreshold, unsigned int &nMinThreshold, unsigned int &nMaxThreshold) const
bool AddElem(const char *szName, const char *szData=NULL)
Definition: Markup.h:37
bool GetForcePlateLocation(unsigned int nPlateIndex, SPoint sCorner[4]) const
const char * GetAnalogUnit(unsigned int nDeviceIndex, unsigned int nChannelIndex) const
unsigned short GetUdpServerPort()
Definition: RTProtocol.cpp:202
bool SendTrig()
Definition: RTProtocol.cpp:631
void Disconnect()
Definition: RTProtocol.cpp:212
const char * Get6DOFBodyName(unsigned int nBodyIndex) const
bool Reprocess()
Definition: RTProtocol.cpp:991
bool LoadProject(const char *pFileName)
Definition: RTProtocol.cpp:958
static const unsigned int cComponent2d
Definition: RTProtocol.h:37
bool SetVersion(int nMajorVersion, int nMinorVersion)
Definition: RTProtocol.cpp:231
unsigned short GetUdpServerPort()
Definition: Network.cpp:254
bool SetForceSettings(const unsigned int nPlateID, const SPoint *psCorner1, const SPoint *psCorner2, const SPoint *psCorner3, const SPoint *psCorner4)
unsigned int GetSkeletonCount() const
std::vector< SSettingsSkeletonSegment > segments
Definition: RTProtocol.h:413
void GetForceUnits(char *&pLength, char *&pForce) const
void GetSystemSettings(unsigned int &nCaptureFrequency, float &fCaptureTime, bool &bStartOnExtTrig, bool &trigNO, bool &trigNC, bool &trigSoftware, EProcessingActions &eProcessingActions, EProcessingActions &eRtProcessingActions, EProcessingActions &eReprocessingActions) const
bool CreateUDPSocket(unsigned short &nUDPPort, bool bBroadcast=false)
Definition: Network.cpp:176
bool GetCurrentFrame(unsigned int nComponentType, const SComponentOptions &componentOptions={ })
Definition: RTProtocol.cpp:412
bool GetCameraFOV(unsigned int nCameraIndex, unsigned int &nMarkerLeft, unsigned int &nMarkerTop, unsigned int &nMarkerRight, unsigned int &nMarkerBottom, unsigned int &nVideoLeft, unsigned int &nVideoTop, unsigned int &nVideoRight, unsigned int &nVideoBottom) const
const char * Get3DBoneToName(unsigned int boneIndex) const
bool OutOfElem()
Definition: Markup.cpp:165
CRTPacket * GetRTPacket()
bool SetCameraVideoSettings(const unsigned int nCameraID, const EVideoResolution *eVideoResolution, const EVideoAspectRatio *eVideoAspectRatio, const unsigned int *pnVideoFrequency, const float *pfVideoExposure, const float *pfVideoFlashTime)
const char * Get3DLabelName(unsigned int nMarkerIndex) const
bool GetCameraLensControlSettings(const unsigned int nCameraIndex, float *focus, float *aperture) const
void GetExtTimeBaseSettings(bool &bEnabled, ESignalSource &eSignalSource, bool &bSignalModePeriodic, unsigned int &nFreqMultiplier, unsigned int &nFreqDivisor, unsigned int &nFreqTolerance, float &fNominalFrequency, bool &bNegativeEdge, unsigned int &nSignalShutterDelay, float &fNonPeriodicTimeout) const
static const unsigned int cComponent6d
Definition: RTProtocol.h:35
std::string GetAttrib(const char *szAttrib) const
Definition: Markup.h:58
bool SetDoc(const char *szDoc)
Definition: Markup.cpp:44
void Disconnect()
Definition: Network.cpp:157
bool LoadCapture(const char *pFileName)
Definition: RTProtocol.cpp:877
bool SetCameraLensControlSettings(const unsigned int nCameraID, const float focus, const float aperture)
unsigned int Get6DOFBodyPointCount(unsigned int nBodyIndex) const
static const unsigned int cComponent3dRes
Definition: RTProtocol.h:39
bool GetCapture(const char *pFileName, bool bC3D)
Definition: RTProtocol.cpp:537
bool GetCameraSettings(unsigned int nCameraIndex, unsigned int &nID, ECameraModel &eModel, bool &bUnderwater, bool &bSupportsHwSync, unsigned int &nSerial, ECameraMode &eMode) const
unsigned int GetSize()
Definition: RTPacket.cpp:292
bool GetForcePlate(unsigned int nPlateIndex, unsigned int &nID, unsigned int &nAnalogDeviceID, unsigned int &nFrequency, char *&pType, char *&pName, float &fLength, float &fWidth) const
static const unsigned int cComponentForceSingle
Definition: RTProtocol.h:45
Definition: Markup.h:23
char * GetXMLString()
Definition: RTPacket.cpp:432
float GetGazeVectorFrequency(unsigned int nGazeVectorIndex) const
bool StartCapture()
Definition: RTProtocol.cpp:804
bool ReadSkeletonSettings(bool &bDataAvailable, bool skeletonGlobalData=false)
bool StopCapture()
Definition: RTProtocol.cpp:854
unsigned int Get6DOFBodyCount() const
unsigned int GetForcePlateCount() const
bool Get6DOFBodyPoint(unsigned int nBodyIndex, unsigned int nMarkerIndex, SPoint &sPoint) const
const char * Get3DCalibrated() const
static bool GetComponentString(char *pComponentStr, unsigned int nComponentType, const SComponentOptions &options=SComponentOptions())
unsigned int GetImageCameraCount() const
int GetError() const
Definition: Network.cpp:514
bool StartRTOnFile()
Definition: RTProtocol.cpp:827
char * GetCommandString()
Definition: RTPacket.cpp:412
static const unsigned int cComponent6dEulerRes
Definition: RTProtocol.h:42
bool SetCameraAutoWhiteBalance(const unsigned int nCameraID, const bool enable)
const char * GetGazeVectorName(unsigned int nGazeVectorIndex) const
unsigned int GetCameraCount() const
bool SetQTMEvent(const char *pLabel)
Definition: RTProtocol.cpp:654
static const unsigned int cComponentAnalogSingle
Definition: RTProtocol.h:43
unsigned int Get3DLabelColor(unsigned int nMarkerIndex) const
unsigned int Get3DLabeledMarkerCount() const
bool ReadAnalogSettings(bool &bDataAvailable)
bool ReadImageSettings(bool &bDataAvailable)
unsigned int GetForcePlateChannelCount(unsigned int nPlateIndex) const
bool GetCameraAutoExposureSettings(const unsigned int nCameraIndex, bool *autoExposureEnabled, float *autoExposureCompensation) const
bool ReadXmlBool(CMarkup *xml, const std::string &element, bool &value) const
ECameraSystemType GetCameraSystemType() const
bool SetCameraSettings(const unsigned int nCameraID, const ECameraMode *peMode, const float *pfMarkerExposure, const float *pfMarkerThreshold, const int *pnOrientation)
void SetData(char *ptr)
Definition: RTPacket.cpp:74
static const unsigned int cComponent2dLin
Definition: RTProtocol.h:38
bool IsControlling()
Definition: RTProtocol.cpp:749
static std::string Format(const char *fmt,...)
Definition: Markup.cpp:1154
bool Read3DSettings(bool &bDataAvailable)
static const unsigned int cComponentTimecode
Definition: RTProtocol.h:47
bool CheckLicense(const char *pLicenseCode)
Definition: RTProtocol.cpp:307
unsigned int GetAnalogDeviceCount() const
bool GetForcePlateChannel(unsigned int nPlateIndex, unsigned int nChannelIndex, unsigned int &nChannelNumber, float &fConversionFactor) const
EAxis Get3DUpwardAxis() const
static bool ConvertRateString(const char *pRate, EStreamRate &eRate, unsigned int &nRateArg)
bool ReadCameraSystemSettings()
bool GetSkeletonSegment(unsigned int skeletonIndex, unsigned int segmentIndex, SSettingsSkeletonSegment *segment)
const char * GetAnalogLabel(unsigned int nDeviceIndex, unsigned int nChannelIndex) const
bool GetCameraOrientation(unsigned int nCameraIndex, int &nOrientation) const
bool ReleaseControl()
Definition: RTProtocol.cpp:724
bool GetByteOrder(bool &bBigEndian)
Definition: RTProtocol.cpp:293
bool GetCameraAutoWhiteBalance(const unsigned int nCameraIndex, bool *autoWhiteBalanceEnabled) const
bool GetCameraResolution(unsigned int nCameraIndex, unsigned int &nMarkerWidth, unsigned int &nMarkerHeight, unsigned int &nVideoWidth, unsigned int &nVideoHeight) const
bool Read6DOFSettings(bool &bDataAvailable)
bool DiscoverRTServer(unsigned short nServerPort, bool bNoLocalResponses, unsigned short nDiscoverPort=DEFAULT_AUTO_DESCOVER_PORT)
Definition: RTProtocol.cpp:337
static bool GetEventString(CRTPacket::EEvent eEvent, char *pStr)
bool Send(const char *pSendBuf, int nSize)
Definition: Network.cpp:374
bool TakeControl(const char *pPassword=nullptr)
Definition: RTProtocol.cpp:687
std::string GetDoc() const
Definition: Markup.h:36
bool SetSystemSettings(const unsigned int *pnCaptureFrequency, const float *pfCaptureTime, const bool *pbStartOnExtTrig, const bool *trigNO, const bool *trigNC, const bool *trigSoftware, const EProcessingActions *peProcessingActions, const EProcessingActions *peRtProcessingActions, const EProcessingActions *peReprocessingActions)
char * GetErrorString()
Definition: Network.cpp:508
short GetDiscoverResponseBasePort()
Definition: RTPacket.cpp:442
static const unsigned int cComponentSkeleton
Definition: RTProtocol.h:48
bool GetSkeleton(unsigned int skeletonIndex, SSettingsSkeleton *skeleton)
unsigned int Get6DOFBodyColor(unsigned int nBodyIndex) const
bool GetCameraVideoSettings(unsigned int nCameraIndex, EVideoResolution &eVideoResolution, EVideoAspectRatio &eVideoAspectRatio, unsigned int &nVideoFrequency, unsigned int &nCurrentExposure, unsigned int &nMinExposure, unsigned int &nMaxExposure, unsigned int &nCurrentFlashTime, unsigned int &nMinFlashTime, unsigned int &nMaxFlashTime) const
bool StreamFramesStop()
Definition: RTProtocol.cpp:485
bool ReadForceSettings(bool &bDataAvailable)
bool GetForcePlateCalibrationMatrix(unsigned int nPlateIndex, float fvCalMatrix[12][12], unsigned int *rows, unsigned int *columns) const
bool SetExtTimeBaseSettings(const bool *pbEnabled, const ESignalSource *peSignalSource, const bool *pbSignalModePeriodic, const unsigned int *pnFreqMultiplier, const unsigned int *pnFreqDivisor, const unsigned int *pnFreqTolerance, const float *pfNominalFrequency, const bool *pbNegativeEdge, const unsigned int *pnSignalShutterDelay, const float *pfNonPeriodicTimeout)
bool FindChildElem(const char *szName=NULL)
Definition: Markup.cpp:114
EImageFormat
Definition: RTPacket.h:65
bool SendUDPBroadcast(const char *pSendBuf, int nSize, short nPort, unsigned int nFilterAddr=0)
Definition: Network.cpp:393
bool GetCameraSyncOutSettings(unsigned int nCameraIndex, unsigned int portNumber, ESyncOutFreqMode &eSyncOutMode, unsigned int &nSyncOutValue, float &fSyncOutDutyCycle, bool &bSyncOutNegativePolarity) const
bool Connect(const char *pServerAddr, unsigned short nPort, unsigned short *pnUDPServerPort=nullptr, int nMajorVersion=MAJOR_VERSION, int nMinorVersion=MINOR_VERSION, bool bBigEndian=false)
Definition: RTProtocol.cpp:82
bool GetQTMVersion(char *pVersion, unsigned int nVersionLen)
Definition: RTProtocol.cpp:282
static const unsigned int cComponent3dNoLabelsRes
Definition: RTProtocol.h:40
static unsigned int ConvertComponentString(const char *pComponentType)
bool Connected() const
Definition: Network.cpp:171
char * GetErrorString()
Definition: RTPacket.cpp:402
std::string GetChildData() const
Definition: Markup.h:57
bool ReadGazeVectorSettings(bool &bDataAvailable)
void SetVersion(unsigned int nMajorVersion, unsigned int nMinorVersion)
Definition: RTPacket.cpp:32
bool AddAttrib(const char *szAttrib, const char *szValue)
Definition: Markup.h:39
bool GetState(CRTPacket::EEvent &eEvent, bool bUpdate=true, int nTimeout=WAIT_FOR_DATA_TIMEOUT)
Definition: RTProtocol.cpp:496
bool Connected() const
Definition: RTProtocol.cpp:225
char * GetErrorString()
static const unsigned int cComponent3d
Definition: RTProtocol.h:31
bool Connect(const char *pServerAddr, unsigned short nPort)
Definition: Network.cpp:87
bool GetCameraPosition(unsigned int nCameraIndex, SPoint &sPoint, float fvRotationMatrix[3][3]) const
bool SetCameraAutoExposureSettings(const unsigned int nCameraID, const bool autoExposure, const float compensation)
bool IsLocalAddress(unsigned int nAddr) const
Definition: Network.cpp:520
unsigned int Get3DBoneCount() const
bool StreamFrames(EStreamRate eRate, unsigned int nRateArg, unsigned short nUDPPort, const char *pUDPAddr, unsigned int nComponentType, const SComponentOptions &componentOptions={ })
Definition: RTProtocol.cpp:434
bool SetImageSettings(const unsigned int nCameraID, const bool *pbEnable, const CRTPacket::EImageFormat *peFormat, const unsigned int *pnWidth, const unsigned int *pnHeight, const float *pfLeftCrop, const float *pfTopCrop, const float *pfRightCrop, const float *pfBottomCrop)
bool SaveCapture(const char *pFileName, bool bOverwrite, char *pNewFileName=nullptr, int nSizeOfNewFileName=0)
Definition: RTProtocol.cpp:910
unsigned int GetGazeVectorCount() const
bool GetImageCamera(unsigned int nCameraIndex, unsigned int &nCameraID, bool &bEnabled, CRTPacket::EImageFormat &eFormat, unsigned int &nWidth, unsigned int &nHeight, float &fCropLeft, float &fCropTop, float &fCropRight, float &fCropBottom) const
const char * Get3DBoneFromName(unsigned int boneIndex) const
bool IntoElem()
Definition: Markup.cpp:147
int GetNumberOfDiscoverResponses()
Definition: RTProtocol.cpp:393
int ReceiveRTPacket(CRTPacket::EPacketType &eType, bool bSkipEvents=true, int nTimeout=WAIT_FOR_DATA_TIMEOUT)
static const unsigned int cComponent6dEuler
Definition: RTProtocol.h:36
static const unsigned int cComponent3dNoLabels
Definition: RTProtocol.h:32
bool GetForcePlateOrigin(unsigned int nPlateIndex, SPoint &sOrigin) const
bool GetAnalogDevice(unsigned int nDeviceIndex, unsigned int &nDeviceID, unsigned int &nChannels, char *&pName, unsigned int &nFrequency, char *&pUnit, float &fMinRange, float &fMaxRange) const
bool GetVersion(unsigned int &nMajorVersion, unsigned int &nMinorVersion)
Definition: RTProtocol.cpp:268
static const unsigned int cComponent6dRes
Definition: RTProtocol.h:41
static const unsigned int cComponentGazeVector
Definition: RTProtocol.h:46
bool NewMeasurement()
Definition: RTProtocol.cpp:755
EPacketType GetType()
Definition: RTPacket.cpp:305
static const unsigned int cComponentAnalog
Definition: RTProtocol.h:33
bool CloseMeasurement()
Definition: RTProtocol.cpp:778
unsigned int GetSkeletonSegmentCount(unsigned int skeletonIndex)
const char * GetSkeletonName(unsigned int skeletonIndex)
bool GetEvent(EEvent &eEvent)
Definition: RTPacket.cpp:466
static const unsigned int cComponentForce
Definition: RTProtocol.h:34
bool SetCameraSyncOutSettings(const unsigned int nCameraID, const unsigned int portNumber, const ESyncOutFreqMode *peSyncOutMode, const unsigned int *pnSyncOutValue, const float *pfSyncOutDutyCycle, const bool *pbSyncOutNegativePolarity)