SafeVisionaryData.cpp
Go to the documentation of this file.
1 // -- BEGIN LICENSE BLOCK ----------------------------------------------
20 // -- END LICENSE BLOCK ------------------------------------------------
21 
22 #include <cstdio>
23 
27 #include <iostream>
28 // TinyXML-2 XML DOM parser
30 
31 namespace visionary {
32 
33 constexpr float SafeVisionaryData::DISTANCE_MAP_UNIT = 0.25f;
34 
35 namespace {
37 constexpr std::uint16_t VERSION_SEGMENT_DEPTHMAP = 0x0002u;
38 
40 constexpr std::uint16_t VERSION_SEGMENT_DEVICESTATUS = 0x0001u;
41 
43 constexpr std::uint16_t VERSION_SEGMENT_ROI = 0x0001u;
44 
46 constexpr std::uint16_t VERSION_SEGMENT_LOCALIOS = 0x0001u;
47 
49 constexpr std::uint16_t VERSION_SEGMENT_FIELDINFORMATION = 0x0001u;
50 
52 constexpr std::uint16_t VERSION_SEGMENT_LOGICSIGNALS = 0x0001u;
53 
55 constexpr std::uint16_t VERSION_SEGMENT_IMU = 0x0001u;
56 
58 constexpr std::uint16_t DISTANCE_MAP_FILTERED_FLAG = 1u << 0;
59 
61 constexpr std::uint16_t INTRUDED_PIXEL_STATE_VALID_FLAG = 1u << 1;
62 
64 constexpr std::uint16_t DATA_STREAM_THROTTLED_FLAG = 1u << 2;
65 
66 } // namespace
68  : VisionaryData()
69  , m_distanceByteDepth(0u)
70  , m_intensityByteDepth(0u)
71  , m_stateByteDepth(0u)
72  , m_deviceStatus(DEVICE_STATUS::DEVICE_STATUS_INVALID)
73  , m_flags(0u)
74  , m_lastDataHandlerError(DataHandlerError::OK)
75 {
76 }
77 
79 
80 bool SafeVisionaryData::parseXML(const std::string& xmlString, uint32_t changeCounter)
81 {
82  //-----------------------------------------------
83  // Check if the segment data changed since last receive
84  if (m_changeCounter == changeCounter)
85  {
86  return true; // Same XML content as on last received blob
87  }
88 
90 
91  //-----------------------------------------------
92  // Parse XML string into DOM
93  tinyxml2::XMLDocument xmlTree;
94  auto tXMLError = xmlTree.Parse(xmlString.c_str());
95  if (tXMLError != tinyxml2::XMLError::XML_SUCCESS)
96  {
97  std::printf("Reading XML tree in BLOB failed.");
99  return false;
100  }
101 
102  //-----------------------------------------------
103  // Check whether datasets entry exists and whether it has a depthmap
104  bool oParseOk = true;
105  tinyxml2::XMLNode const* ptDataSetsTree = 0;
106  {
107  ptDataSetsTree = xmlTree.FirstChildElement("SickRecord");
108 
109  if (ptDataSetsTree != 0)
110  {
111  ptDataSetsTree = ptDataSetsTree->FirstChildElement("DataSets");
112  }
113 
114  if (ptDataSetsTree != 0)
115  {
116  auto const* ptHasNodeOrZero = ptDataSetsTree->FirstChildElement("DataSetDepthMap");
117  m_dataSetsActive.hasDataSetDepthMap = (ptHasNodeOrZero != 0);
118 
119  ptHasNodeOrZero = ptDataSetsTree->FirstChildElement("DataSetDeviceStatus");
120  m_dataSetsActive.hasDataSetDeviceStatus = (ptHasNodeOrZero != 0);
121 
122  ptHasNodeOrZero = ptDataSetsTree->FirstChildElement("DataSetROI");
123  m_dataSetsActive.hasDataSetROI = (ptHasNodeOrZero != 0);
124 
125  ptHasNodeOrZero = ptDataSetsTree->FirstChildElement("DataSetLocalIOs");
126  m_dataSetsActive.hasDataSetLocalIOs = (ptHasNodeOrZero != 0);
127 
128  ptHasNodeOrZero = ptDataSetsTree->FirstChildElement("DataSetFieldInformation");
129  m_dataSetsActive.hasDataSetFieldInfo = (ptHasNodeOrZero != 0);
130 
131  ptHasNodeOrZero = ptDataSetsTree->FirstChildElement("DataSetLogicalSignals");
132  m_dataSetsActive.hasDataSetLogicSignals = (ptHasNodeOrZero != 0);
133 
134  ptHasNodeOrZero = ptDataSetsTree->FirstChildElement("DataSetIMU");
135  m_dataSetsActive.hasDataSetIMU = (ptHasNodeOrZero != 0);
136  }
137  else
138  {
139  oParseOk = false;
140  }
141  }
142 
143  // DataSetDepthMap specific data
144  if (oParseOk)
145  {
146  auto const* ptDataStreamTree = ptDataSetsTree->FirstChildElement("DataSetDepthMap");
147 
148  if (ptDataStreamTree != 0)
149  {
150  ptDataStreamTree = ptDataStreamTree->FirstChildElement("FormatDescriptionDepthMap");
151  }
152 
153  if (ptDataStreamTree != 0)
154  {
155  ptDataStreamTree = ptDataStreamTree->FirstChildElement("DataStream");
156  }
157  else
158  {
159  oParseOk = false;
160  }
161 
162  // Image width/height
163  if (oParseOk and (ptDataStreamTree != 0))
164  {
165  auto const* ptWidthElem = ptDataStreamTree->FirstChildElement("Width");
166  if (ptWidthElem != 0)
167  {
168  tXMLError = ptWidthElem->QueryIntText(&m_cameraParams.width);
169  if (tXMLError != tinyxml2::XMLError::XML_SUCCESS)
170  {
171  oParseOk = false;
172  }
173  }
174  else
175  {
176  oParseOk = false;
177  }
178 
179  auto const* ptHeightElem = ptDataStreamTree->FirstChildElement("Height");
180  if (ptHeightElem != 0)
181  {
182  tXMLError = ptHeightElem->QueryIntText(&m_cameraParams.height);
183  if (tXMLError != tinyxml2::XMLError::XML_SUCCESS)
184  {
185  oParseOk = false;
186  }
187  }
188  else
189  {
190  oParseOk = false;
191  }
192  }
193 
194  // Camera transformation matrix
195  if (m_dataSetsActive.hasDataSetDepthMap and (ptDataStreamTree != 0))
196  {
197  auto const* ptCameraToWorldTransform =
198  ptDataStreamTree->FirstChildElement("CameraToWorldTransform");
199  if (ptCameraToWorldTransform != 0)
200  {
201  auto const* ptMatrixEntry = ptCameraToWorldTransform->FirstChildElement();
202  for (auto idx = 0; idx < 4 * 4; ++idx)
203  {
204  tXMLError = ptMatrixEntry->QueryDoubleText(&m_cameraParams.cam2worldMatrix[idx]);
205  ptMatrixEntry = ptMatrixEntry->NextSiblingElement();
206  if ((tXMLError != tinyxml2::XMLError::XML_SUCCESS) or
207  ((idx < 4 * 4 - 1) and (ptMatrixEntry == 0)))
208  {
209  oParseOk = false;
210  break;
211  }
212  }
213  }
214  else
215  {
216  oParseOk = false;
217  }
218  }
219  else
220  {
221  // Identity matrix
227  }
228 
229  // Camera intrinsics
230  // Lambda: read double-type entry or set to zero
231  auto getDoubleEntry = [&](const std::vector<char const*>& path, double* target) {
232  auto const* ptEntry = ptDataStreamTree;
233  for (auto* part : path)
234  {
235  if (ptEntry != 0)
236  {
237  ptEntry = ptEntry->FirstChildElement(part);
238  }
239  }
240 
241  if (ptEntry != 0)
242  {
243  tXMLError = ptEntry->QueryDoubleText(target);
244  if (tXMLError != tinyxml2::XMLError::XML_SUCCESS)
245  {
246  oParseOk = false;
247  }
248  }
249  else
250  {
251  oParseOk = false;
252  }
253  };
254  getDoubleEntry({"CameraMatrix", "FX"}, &m_cameraParams.fx);
255  getDoubleEntry({"CameraMatrix", "FY"}, &m_cameraParams.fy);
256  getDoubleEntry({"CameraMatrix", "CX"}, &m_cameraParams.cx);
257  getDoubleEntry({"CameraMatrix", "CY"}, &m_cameraParams.cy);
258 
259  getDoubleEntry({"CameraDistortionParams", "K1"}, &m_cameraParams.k1);
260  getDoubleEntry({"CameraDistortionParams", "K2"}, &m_cameraParams.k2);
261  getDoubleEntry({"CameraDistortionParams", "P1"}, &m_cameraParams.p1);
262  getDoubleEntry({"CameraDistortionParams", "P2"}, &m_cameraParams.p2);
263  getDoubleEntry({"CameraDistortionParams", "K3"}, &m_cameraParams.k3);
264 
265  // Set f2rc to 0 as the f2rc value is already included in the cameraToWorldMatrix
266  // NOTE: this does NOT hold for the yellow device; SafeVisionary has to use that entry
267  getDoubleEntry({"FocalToRayCross"}, &m_cameraParams.f2rc);
268  // m_cameraParams.f2rc = 0u;
269 
270  // Read datatypes of image maps
271  // Lambda: read text entry or set to empty string
272  auto getText = [&](char const* name) {
273  if (ptDataStreamTree == 0)
274  {
275  return "";
276  }
277 
278  auto const* ptEntry = ptDataStreamTree->FirstChildElement(name);
279  if (ptEntry != 0)
280  {
281  return ptEntry->GetText();
282  }
283  else
284  {
285  return "";
286  }
287  };
288  // Lookup byte widths of datatypes
289  m_distanceByteDepth = getItemLength(getText("Distance"));
290  m_intensityByteDepth = getItemLength(getText("Intensity"));
291  m_stateByteDepth = getItemLength(getText("Confidence"));
292 
293  // const auto distanceDecimalExponent =
294  // dataStreamTree.get<int>("Distance.<xmlattr>.decimalexponent", 0); Scaling is fixed to 0.25mm
296  }
297 
298  if (not oParseOk)
299  {
300  m_cameraParams.width = 0;
302 
303  m_cameraParams.fx = 0.0;
304  m_cameraParams.fy = 0.0;
305  m_cameraParams.cx = 0.0;
306  m_cameraParams.cy = 0.0;
307 
308  m_cameraParams.k1 = 0.0;
309  m_cameraParams.k2 = 0.0;
310  m_cameraParams.p1 = 0.0;
311  m_cameraParams.p2 = 0.0;
312  m_cameraParams.k3 = 0.0;
313 
314  m_cameraParams.f2rc = 0.0;
315 
319 
320  // Identity matrix
326  }
327 
328  m_changeCounter = changeCounter;
329 
330  return true;
331 }
332 
333 bool SafeVisionaryData::parseBinaryData(std::vector<uint8_t>::iterator itBuf, size_t size)
334 {
335  const size_t numPixel = m_cameraParams.width * m_cameraParams.height;
336  const size_t numBytesDistance = numPixel * m_distanceByteDepth;
337  const size_t numBytesIntensity = numPixel * m_intensityByteDepth;
338  const size_t numBytesState = numPixel * m_stateByteDepth;
339 
340  // get length of data segment DepthMap
341  const uint32_t length = readUnalignLittleEndian<uint32_t>(&*itBuf);
342  itBuf += sizeof(uint32_t);
343 
344  //-----------------------------------------------
345  // Data ends with a CRC32 field and a copy of the length byte
346  const uint32_t dataSize = length - 8u;
347  const uint32_t crc32 = readUnalignLittleEndian<uint32_t>(&*(itBuf + dataSize));
348  const uint32_t crc32Calculated = ~CRC_calcCrc32Block(&*itBuf, dataSize, CRC_DEFAULT_INIT_VALUE32);
349 
350  if (crc32 != crc32Calculated)
351  {
352  std::printf("Malformed data, CRC32 checksum in data segment depth map does not match.\n");
354  return false;
355  }
356 
357  // length does not include the second length field, so add 4 bytes
358  if ((length + sizeof(uint32_t)) != size)
359  {
360  std::printf(
361  "Malformed data, length in data segment depth map header does not match package size.\n");
363  return false;
364  }
365 
366  // get second length field
367  const uint32_t lengthCopy = readUnalignLittleEndian<uint32_t>(&*(itBuf + dataSize + 4));
368 
369  // check whether length matches
370  if (length != lengthCopy)
371  {
372  std::printf("Malformed data, length of data segment depth map header does not match data "
373  "segment size.\n");
375  return false;
376  }
377 
378  m_blobTimestamp = readUnalignLittleEndian<uint64_t>(&*itBuf);
380  itBuf += sizeof(uint64_t);
381 
382  const uint16_t version = readUnalignLittleEndian<uint16_t>(&*itBuf);
383  itBuf += sizeof(uint16_t);
384 
385  if (version != VERSION_SEGMENT_DEPTHMAP)
386  {
387  std::printf("Unsupported version of data segment Depthmap\n");
389  return false;
390  }
391 
392  // more frame information follows in this case: frame number, device status and flags
393  m_frameNum = readUnalignLittleEndian<uint32_t>(&*itBuf);
394  itBuf += sizeof(uint32_t);
395 
396  m_deviceStatus = static_cast<DEVICE_STATUS>(readUnalignLittleEndian<uint8_t>(&*itBuf));
397  itBuf += sizeof(uint8_t);
398 
399  m_flags = readUnalignLittleEndian<uint16_t>(&*itBuf);
400  itBuf += sizeof(uint16_t);
401 
402  //-----------------------------------------------
403  // Extract the Images depending on the informations extracted from the XML part
404  if (numBytesDistance != 0)
405  {
406  m_distanceMap.resize(numPixel);
407  memcpy(&m_distanceMap[0], &*itBuf, numBytesDistance);
408  itBuf += numBytesDistance;
409  }
410  else
411  {
412  m_distanceMap.clear();
413  }
414  if (numBytesIntensity != 0)
415  {
416  m_intensityMap.resize(numPixel);
417  memcpy(&m_intensityMap[0], &*itBuf, numBytesIntensity);
418  itBuf += numBytesIntensity;
419  }
420  else
421  {
422  m_intensityMap.clear();
423  }
424  if (numBytesState != 0)
425  {
426  m_stateMap.resize(numPixel);
427  memcpy(&m_stateMap[0], &*itBuf, numBytesState);
428  itBuf += numBytesState;
429  }
430  else
431  {
432  m_stateMap.clear();
433  }
434 
435  return true;
436 }
437 
438 bool SafeVisionaryData::parseRoiData(std::vector<uint8_t>::iterator itBuf, size_t size)
439 {
440  // get length of data segment ROI
441  const uint32_t length = readUnalignLittleEndian<uint32_t>(&*itBuf);
442  itBuf += sizeof(uint32_t);
443 
444  //-----------------------------------------------
445  // Data ends with a CRC32 field and a copy of the length byte
446  const uint32_t dataSize = length - 8u;
447  const uint32_t crc32 = readUnalignLittleEndian<uint32_t>(&*(itBuf + dataSize));
448  const uint32_t crc32Calculated = ~CRC_calcCrc32Block(&*itBuf, dataSize, CRC_DEFAULT_INIT_VALUE32);
449 
450  if (crc32 != crc32Calculated)
451  {
452  std::printf("Malformed data, CRC32 checksum of data segment ROI does not match.\n");
454  return false;
455  }
456 
457  // length does not include the second length field, so add 4 bytes
458  if ((length + sizeof(uint32_t)) != size)
459  {
460  std::printf("Malformed data, length of data segment ROI does not match package size.\n");
462  return false;
463  }
464 
465  // get second length field
466  const uint32_t lengthCopy = readUnalignLittleEndian<uint32_t>(&*(itBuf + dataSize + 4));
467 
468  // check whether length matches
469  if (length != lengthCopy)
470  {
471  std::printf("Malformed data, length does not match ROI data segment size.\n");
473  return false;
474  }
475 
476  m_blobTimestamp = readUnalignLittleEndian<uint64_t>(&*itBuf);
478  itBuf += sizeof(uint64_t);
479 
480  const uint16_t version = readUnalignLittleEndian<uint16_t>(&*itBuf);
481  itBuf += sizeof(uint16_t);
482 
483  if (version != VERSION_SEGMENT_ROI)
484  {
485  std::printf("Unsupported version of data segment ROI\n");
487  return false;
488  }
489 
490  // copy ROI data
491  memcpy(&m_roiData, &*itBuf, sizeof(m_roiData));
492 
493  return true;
494 }
495 
496 bool SafeVisionaryData::parseDeviceStatusData(std::vector<uint8_t>::iterator itBuf, size_t size)
497 {
498  // get length of data segment Device Status
499  const uint32_t length = readUnalignLittleEndian<uint32_t>(&*itBuf);
500  itBuf += sizeof(uint32_t);
501 
502  //-----------------------------------------------
503  // Data ends with a CRC32 field and a copy of the length byte
504  const uint32_t dataSize = length - 8u;
505  const uint32_t crc32 = readUnalignLittleEndian<uint32_t>(&*(itBuf + dataSize));
506  const uint32_t crc32Calculated = ~CRC_calcCrc32Block(&*itBuf, dataSize, CRC_DEFAULT_INIT_VALUE32);
507 
508  if (crc32 != crc32Calculated)
509  {
510  std::printf("Malformed data, CRC32 checksum of data segment Device Status does not match.\n");
512  return false;
513  }
514 
515  // length does not include the second length field, so add 4 bytes
516  if ((length + sizeof(uint32_t)) != size)
517  {
518  std::printf("Malformed data, length of Device Status header does not match package size.\n");
520  return false;
521  }
522 
523  // get second length field
524  const uint32_t lengthCopy = readUnalignLittleEndian<uint32_t>(&*(itBuf + dataSize + 4));
525 
526  // check whether length matches
527  if (length != lengthCopy)
528  {
529  std::printf("Malformed data, length does not match Device Status data segment size.\n");
531  return false;
532  }
533 
534  m_blobTimestamp = readUnalignLittleEndian<uint64_t>(&*itBuf);
536  itBuf += sizeof(uint64_t);
537 
538  const uint16_t version = readUnalignLittleEndian<uint16_t>(&*itBuf);
539  itBuf += sizeof(uint16_t);
540 
541  if (version != VERSION_SEGMENT_DEVICESTATUS)
542  {
543  std::printf("Unsupported version of data segment Device Status\n");
545  return false;
546  }
547 
548  // copy device status data
549  memcpy(&m_deviceStatusData, &*itBuf, sizeof(m_deviceStatusData));
550 
551  return true;
552 }
553 
554 bool SafeVisionaryData::parseLocalIOsData(std::vector<uint8_t>::iterator itBuf, size_t size)
555 {
556  // get length of data segment Local I/Os
557  const uint32_t length = readUnalignLittleEndian<uint32_t>(&*itBuf);
558  itBuf += sizeof(uint32_t);
559 
560  //-----------------------------------------------
561  // Data ends with a CRC32 field and a copy of the length byte
562  const uint32_t dataSize = length - 8u;
563  const uint32_t crc32 = readUnalignLittleEndian<uint32_t>(&*(itBuf + dataSize));
564  const uint32_t crc32Calculated = ~CRC_calcCrc32Block(&*itBuf, dataSize, CRC_DEFAULT_INIT_VALUE32);
565 
566  if (crc32 != crc32Calculated)
567  {
568  std::printf("Malformed data, CRC32 checksum of data segment Device Status does not match.\n");
570  return false;
571  }
572 
573  // length does not include the second length field, so add 4 bytes
574  if ((length + sizeof(uint32_t)) != size)
575  {
576  std::printf("Malformed data, length of Device Status header does not match package size.\n");
578  return false;
579  }
580 
581  // get second length field
582  const uint32_t lengthCopy = readUnalignLittleEndian<uint32_t>(&*(itBuf + dataSize + 4));
583 
584  // check whether length matches
585  if (length != lengthCopy)
586  {
587  std::printf("Malformed data, length does not match Local I/Os data segment size.\n");
589  return false;
590  }
591 
592  m_blobTimestamp = readUnalignLittleEndian<uint64_t>(&*itBuf);
594  itBuf += sizeof(uint64_t);
595 
596  const uint16_t version = readUnalignLittleEndian<uint16_t>(&*itBuf);
597  itBuf += sizeof(uint16_t);
598 
599  if (version != VERSION_SEGMENT_LOCALIOS)
600  {
601  std::printf("Unsupported version of data segment Local IO\n");
603  return false;
604  }
605 
606  // copy Local I/Os data
607  memcpy(&m_localIOsData, &*itBuf, sizeof(m_localIOsData));
608  return true;
609 }
610 //
611 bool SafeVisionaryData::parseFieldInformationData(std::vector<uint8_t>::iterator itBuf, size_t size)
612 {
613  // get length of data segment FieldInformation
614  const uint32_t length = readUnalignLittleEndian<uint32_t>(&*itBuf);
615  itBuf += sizeof(uint32_t);
616 
617  //-----------------------------------------------
618  // Data ends with a CRC32 field and a copy of the length byte
619  const uint32_t dataSize = length - 8u;
620  const uint32_t crc32 = readUnalignLittleEndian<uint32_t>(&*(itBuf + dataSize));
621  const uint32_t crc32Calculated = ~CRC_calcCrc32Block(&*itBuf, dataSize, CRC_DEFAULT_INIT_VALUE32);
622 
623  if (crc32 != crc32Calculated)
624  {
625  std::printf(
626  "Malformed data, CRC32 checksum of data segment Field Information does not match.\n");
628  return false;
629  }
630 
631  // length does not include the second length field, so add 4 bytes
632  if ((length + sizeof(uint32_t)) != size)
633  {
634  std::printf(
635  "Malformed data, length of data segment Field Information does not match package size.\n");
637  return false;
638  }
639 
640  // get second length field
641  const uint32_t lengthCopy = readUnalignLittleEndian<uint32_t>(&*(itBuf + dataSize + 4));
642 
643  // check whether length matches
644  if (length != lengthCopy)
645  {
646  std::printf("Malformed data, length does not match Field Information data segment size.\n");
648  return false;
649  }
650 
651  m_blobTimestamp = readUnalignLittleEndian<uint64_t>(&*itBuf);
653 
654  itBuf += sizeof(uint64_t);
655 
656  const uint16_t version = readUnalignLittleEndian<uint16_t>(&*itBuf);
657  itBuf += sizeof(uint16_t);
658 
659  if (version != VERSION_SEGMENT_FIELDINFORMATION)
660  {
661  std::printf("Unsupported version of data segment Field Information\n");
663  return false;
664  }
665 
666  // copy Field Information data
667  memcpy(&m_fieldInformationData, &*itBuf, sizeof(m_fieldInformationData));
668 
669  return true;
670 }
671 
672 bool SafeVisionaryData::parseLogicSignalsData(std::vector<uint8_t>::iterator itBuf, size_t size)
673 {
674  // get length of data segment Logic Signals
675  const uint32_t length = readUnalignLittleEndian<uint32_t>(&*itBuf);
676 
677  itBuf += sizeof(uint32_t);
678 
679  //-----------------------------------------------
680  // Data ends with a CRC32 field and a copy of the length byte
681  const uint32_t dataSize = length - 8u;
682  const uint32_t crc32 = readUnalignLittleEndian<uint32_t>(&*(itBuf + dataSize));
683  const uint32_t crc32Calculated = ~CRC_calcCrc32Block(&*itBuf, dataSize, CRC_DEFAULT_INIT_VALUE32);
684 
685  if (crc32 != crc32Calculated)
686  {
687  std::printf("Malformed data, CRC32 checksum of data segment Logic Signals does not match.\n");
689  return false;
690  }
691 
692  // length does not include the second length field, so add 4 bytes
693  if ((length + sizeof(uint32_t)) != size)
694  {
695  std::printf(
696  "Malformed data, length of data segment Logic Signals does not match package size.\n");
698  return false;
699  }
700 
701  // get second length field
702  const uint32_t lengthCopy = readUnalignLittleEndian<uint32_t>(&*(itBuf + dataSize + 4));
703 
704  // check whether length matches
705  if (length != lengthCopy)
706  {
707  std::printf("Malformed data, length does not match Logic Signals data segment size.\n");
709  return false;
710  }
711 
712  m_blobTimestamp = readUnalignLittleEndian<uint64_t>(&*itBuf);
714  itBuf += sizeof(uint64_t);
715 
716  const uint16_t version = readUnalignLittleEndian<uint16_t>(&*itBuf);
717  itBuf += sizeof(uint16_t);
718 
719  if (version != VERSION_SEGMENT_LOGICSIGNALS)
720  {
721  std::printf("Unsupported version of data segment Logic Signals \n");
723  return false;
724  }
725 
726  // copy Logic Signal data
727  memcpy(&m_logicSignalsData, &*itBuf, sizeof(m_logicSignalsData));
728 
729  return true;
730 }
731 
732 bool SafeVisionaryData::parseIMUData(std::vector<uint8_t>::iterator itBuf, size_t size)
733 {
734  // get length of data segment IMU
735  const uint32_t length = readUnalignLittleEndian<uint32_t>(&*itBuf);
736 
737  itBuf += sizeof(uint32_t);
738 
739  //-----------------------------------------------
740  // Data ends with a CRC32 field and a copy of the length byte
741  const uint32_t dataSize = length - 8u;
742  const uint32_t crc32 = readUnalignLittleEndian<uint32_t>(&*(itBuf + dataSize));
743  const uint32_t crc32Calculated = ~CRC_calcCrc32Block(&*itBuf, dataSize, CRC_DEFAULT_INIT_VALUE32);
744 
745  if (crc32 != crc32Calculated)
746  {
747  std::printf("Malformed data, CRC32 checksum of data segment IMU does not match.\n");
749  return false;
750  }
751 
752  // length does not include the second length field, so add 4 bytes
753  if ((length + sizeof(uint32_t)) != size)
754  {
755  std::printf("Malformed data, length of data segment IMU does not match package size.\n");
757  return false;
758  }
759 
760  // get second length field
761  const uint32_t lengthCopy = readUnalignLittleEndian<uint32_t>(&*(itBuf + dataSize + 4));
762 
763  // check whether length matches
764  if (length != lengthCopy)
765  {
766  std::printf("Malformed data, length does not match IMU data segment size.\n");
768  return false;
769  }
770 
771  m_blobTimestamp = readUnalignLittleEndian<uint64_t>(&*itBuf);
773  itBuf += sizeof(uint64_t);
774 
775  const uint16_t version = readUnalignLittleEndian<uint16_t>(&*itBuf);
776  itBuf += sizeof(uint16_t);
777 
778  if (version != VERSION_SEGMENT_IMU)
779  {
780  std::printf("Unsupported version of data segment IMU \n");
782  return false;
783  }
784 
785  // copy IMU data
786  memcpy(&m_IMUData, &*itBuf, sizeof(m_IMUData));
787 
788  return true;
789 }
790 
791 //
792 void SafeVisionaryData::generatePointCloud(std::vector<PointXYZ>& pointCloud)
793 {
795 }
796 
797 const std::vector<uint16_t>& SafeVisionaryData::getDistanceMap() const
798 {
799  return m_distanceMap;
800 }
801 
802 const std::vector<uint16_t>& SafeVisionaryData::getIntensityMap() const
803 {
804  return m_intensityMap;
805 }
806 
807 const std::vector<uint8_t>& SafeVisionaryData::getStateMap() const
808 {
809  return m_stateMap;
810 }
811 
813 {
814  return m_deviceStatus;
815 }
816 
818 {
819  return (m_flags & DISTANCE_MAP_FILTERED_FLAG);
820 }
821 
823 {
824  return (m_flags & INTRUDED_PIXEL_STATE_VALID_FLAG);
825 }
826 
828 {
829  return m_flags;
830 }
831 
833 {
834  return m_roiData;
835 }
836 
838 {
839  return m_deviceStatusData;
840 }
841 
843 {
844  return m_localIOsData;
845 }
846 
848 {
849  return m_fieldInformationData;
850 }
851 
853 {
854  return m_logicSignalsData;
855 }
856 
858 {
859  return m_IMUData;
860 }
861 
863 {
864  return m_lastDataHandlerError;
865 }
866 
868 {
869  return m_dataSetsActive;
870 }
871 
872 void SafeVisionaryData::clearData(uint32_t changedCounter)
873 {
875  {
876  m_distanceMap.clear();
877  m_intensityMap.clear();
878  m_stateMap.clear();
879 
880  // In case data segment "Depthmap" is not available use the changed counter as frame number.
881  // The changed counter is incremented each Blob and is identical to the frame number.
882  m_frameNum = changedCounter;
883  }
884 
886  {
887  memset(&m_deviceStatusData, 0u, sizeof(m_deviceStatusData));
888  }
889 
891  {
892  memset(&m_roiData, 0u, sizeof(m_roiData));
893  }
894 
896  {
897  memset(&m_localIOsData, 0u, sizeof(m_localIOsData));
898  }
899 
901  {
902  memset(&m_fieldInformationData, 0u, sizeof(m_fieldInformationData));
903  }
904 
906  {
907  memset(&m_logicSignalsData, 0u, sizeof(m_logicSignalsData));
908  }
909 
911  {
912  memset(&m_IMUData, 0u, sizeof(m_IMUData));
913  }
914 }
915 
916 } // namespace visionary
visionary::SafeVisionaryData::DISTANCE_MAP_UNIT
static const float DISTANCE_MAP_UNIT
factor to convert Radial distance map from fixed point to floating point
Definition: SafeVisionaryData.h:422
visionary::SafeVisionaryData::m_deviceStatus
DEVICE_STATUS m_deviceStatus
Contains the received device status.
Definition: SafeVisionaryData.h:502
visionary::FIELDINFORMATION_DATA
Definition: SafeVisionaryData.h:288
visionary::SafeVisionaryData::getDeviceStatus
DEVICE_STATUS getDeviceStatus() const
Definition: SafeVisionaryData.cpp:812
visionary::CameraParameters::fy
double fy
Definition: VisionaryData.h:44
visionary::DataSetsActive::hasDataSetDeviceStatus
bool hasDataSetDeviceStatus
Definition: VisionaryData.h:56
visionary::SafeVisionaryData::m_lastDataHandlerError
DataHandlerError m_lastDataHandlerError
Stores the last error which occurred while parsing the Blob data segments.
Definition: SafeVisionaryData.h:526
visionary::DataSetsActive::hasDataSetFieldInfo
bool hasDataSetFieldInfo
Definition: VisionaryData.h:59
visionary::SafeVisionaryData::clearData
void clearData(uint32_t changedCounter)
Definition: SafeVisionaryData.cpp:872
VisionaryEndian.h
visionary::CameraParameters::p1
double p1
Definition: VisionaryData.h:46
LOCALIOS_SEGMENT
#define LOCALIOS_SEGMENT
Definition: SafeVisionaryData.h:32
visionary::SafeVisionaryData::getFlags
uint16_t getFlags() const
Definition: SafeVisionaryData.cpp:827
visionary::SafeVisionaryData::m_dataSetsActive
DataSetsActive m_dataSetsActive
Definition: SafeVisionaryData.h:481
visionary::VisionaryData::UNKNOWN
@ UNKNOWN
Definition: VisionaryData.h:200
SafeVisionaryData.h
visionary::SafeVisionaryData::getRoiData
const ROI_DATA & getRoiData() const
Definition: SafeVisionaryData.cpp:832
visionary::CameraParameters::cy
double cy
Definition: VisionaryData.h:44
visionary::SafeVisionaryData::isDistanceMapFiltered
bool isDistanceMapFiltered() const
Definition: SafeVisionaryData.cpp:817
visionary::VisionaryData::generatePointCloud
virtual void generatePointCloud(std::vector< PointXYZ > &pointCloud)=0
visionary::DataHandlerError::INVALID_CRC_SEGMENT_ROI
@ INVALID_CRC_SEGMENT_ROI
visionary
Definition: AuthenticationLegacy.h:25
visionary::SafeVisionaryData::getIMUData
const IMU_ELEMENT getIMUData() const
Definition: SafeVisionaryData.cpp:857
visionary::DataHandlerError::INVALID_VERSION_SEGMENT_FIELDINFORMATION
@ INVALID_VERSION_SEGMENT_FIELDINFORMATION
visionary::SafeVisionaryData::parseRoiData
bool parseRoiData(std::vector< uint8_t >::iterator itBuf, size_t length)
Definition: SafeVisionaryData.cpp:438
visionary::CRC_calcCrc32Block
uint32_t CRC_calcCrc32Block(const void *const pvData, uint32_t u32Length, uint32_t u32InitVal)
Compute the CRC-32 value of a data block based on a start value.
Definition: CRC.cpp:86
visionary::DEVICE_STATUS::DEVICE_STATUS_INVALID
@ DEVICE_STATUS_INVALID
visionary::SafeVisionaryData::getDeviceStatusData
DEVICE_STATUS_ELEMENT getDeviceStatusData() const
Gets Device Status element.
Definition: SafeVisionaryData.cpp:837
visionary::DataSetsActive
Definition: VisionaryData.h:51
visionary::CameraParameters::fx
double fx
Camera Matrix.
Definition: VisionaryData.h:44
FIELDINFORMATION_SEGMENT
#define FIELDINFORMATION_SEGMENT
Definition: SafeVisionaryData.h:33
visionary::DataHandlerError::INVALID_CRC_SEGMENT_DEPTHMAP
@ INVALID_CRC_SEGMENT_DEPTHMAP
visionary::SafeVisionaryData::m_fieldInformationData
FIELDINFORMATION_DATA m_fieldInformationData
Definition: SafeVisionaryData.h:514
visionary::CameraParameters::k3
double k3
Definition: VisionaryData.h:46
visionary::SafeVisionaryData::parseDeviceStatusData
bool parseDeviceStatusData(std::vector< uint8_t >::iterator itBuf, size_t length)
Definition: SafeVisionaryData.cpp:496
visionary::DataHandlerError::INVALID_CRC_SEGMENT_DEVICESTATUS
@ INVALID_CRC_SEGMENT_DEVICESTATUS
visionary::DataHandlerError
DataHandlerError
Definition: SafeVisionaryData.h:171
visionary::VisionaryData::m_changeCounter
uint_fast32_t m_changeCounter
Change counter to detect changes in XML.
Definition: VisionaryData.h:230
visionary::DataHandlerError::INVALID_LENGTH_SEGMENT_DEVICESTATUS
@ INVALID_LENGTH_SEGMENT_DEVICESTATUS
visionary::DataHandlerError::INVALID_LENGTH_SEGMENT_FIELDINFORMATION
@ INVALID_LENGTH_SEGMENT_FIELDINFORMATION
tinyxml2::XMLElement::QueryIntText
XMLError QueryIntText(int *ival) const
Definition: tinyxml2.cpp:1911
visionary::SafeVisionaryData::parseBinaryData
bool parseBinaryData(std::vector< uint8_t >::iterator itBuf, size_t length)
Definition: SafeVisionaryData.cpp:333
visionary::SafeVisionaryData::getLastError
DataHandlerError getLastError()
Definition: SafeVisionaryData.cpp:862
visionary::DataHandlerError::INVALID_VERSION_SEGMENT_DEVICESTATUS
@ INVALID_VERSION_SEGMENT_DEVICESTATUS
visionary::DataHandlerError::INVALID_CRC_SEGMENT_LOCALIOS
@ INVALID_CRC_SEGMENT_LOCALIOS
visionary::LOCALIOS_ELEMENT
Definition: SafeVisionaryData.h:255
visionary::VisionaryData::m_preCalcCamInfoType
ImageType m_preCalcCamInfoType
Definition: VisionaryData.h:247
CRC.h
visionary::SafeVisionaryData::isIntrudedPixelStateValid
bool isIntrudedPixelStateValid() const
Definition: SafeVisionaryData.cpp:822
visionary::IMU_ELEMENT
Definition: SafeVisionaryData.h:347
visionary::SafeVisionaryData::m_IMUData
IMU_ELEMENT m_IMUData
Definition: SafeVisionaryData.h:520
visionary::VisionaryData::m_blobTimestamp
uint64_t m_blobTimestamp
Definition: VisionaryData.h:239
visionary::DataSetsActive::hasDataSetROI
bool hasDataSetROI
Definition: VisionaryData.h:57
visionary::SafeVisionaryData::SafeVisionaryData
SafeVisionaryData()
Definition: SafeVisionaryData.cpp:67
CRC_DEFAULT_INIT_VALUE32
#define CRC_DEFAULT_INIT_VALUE32
Default initial value for CRC-32.
Definition: CRC.h:29
visionary::SafeVisionaryData::parseLogicSignalsData
bool parseLogicSignalsData(std::vector< uint8_t >::iterator itBuf, size_t length)
Definition: SafeVisionaryData.cpp:672
visionary::DataHandlerError::INVALID_LENGTH_SEGMENT_LOGICSIGNALS
@ INVALID_LENGTH_SEGMENT_LOGICSIGNALS
tinyxml2::XML_SUCCESS
@ XML_SUCCESS
Definition: tinyxml2.h:559
visionary::SafeVisionaryData::parseFieldInformationData
bool parseFieldInformationData(std::vector< uint8_t >::iterator itBuf, size_t length)
Definition: SafeVisionaryData.cpp:611
visionary::DEVICE_STATUS
DEVICE_STATUS
Definition: SafeVisionaryData.h:39
visionary::SafeVisionaryData::~SafeVisionaryData
virtual ~SafeVisionaryData()
Definition: SafeVisionaryData.cpp:78
visionary::SafeVisionaryData::getDataSetsActive
DataSetsActive getDataSetsActive()
Definition: SafeVisionaryData.cpp:867
visionary::SafeVisionaryData::m_distanceByteDepth
uint32_t m_distanceByteDepth
Byte depth of depth map.
Definition: SafeVisionaryData.h:484
visionary::SafeVisionaryData::getLogicSignalsData
const LOGICSIGNALS_DATA & getLogicSignalsData() const
Definition: SafeVisionaryData.cpp:852
visionary::DataSetsActive::hasDataSetLocalIOs
bool hasDataSetLocalIOs
Definition: VisionaryData.h:58
visionary::SafeVisionaryData::m_intensityMap
std::vector< uint16_t > m_intensityMap
Vector containing the intensity map.
Definition: SafeVisionaryData.h:496
visionary::DataHandlerError::INVALID_LENGTH_SEGMENT_ROI
@ INVALID_LENGTH_SEGMENT_ROI
DEPTHMAP_SEGMENT
#define DEPTHMAP_SEGMENT
Definition: SafeVisionaryData.h:29
visionary::DataSetsActive::hasDataSetIMU
bool hasDataSetIMU
Definition: VisionaryData.h:61
visionary::SafeVisionaryData::parseXML
bool parseXML(const std::string &xmlString, uint32_t changeCounter)
Definition: SafeVisionaryData.cpp:80
visionary::SafeVisionaryData::generatePointCloud
void generatePointCloud(std::vector< PointXYZ > &pointCloud) override
Definition: SafeVisionaryData.cpp:792
visionary::VisionaryData::m_frameNum
uint_fast32_t m_frameNum
Definition: VisionaryData.h:235
visionary::DataHandlerError::INVALID_LENGTH_SEGMENT_IMU
@ INVALID_LENGTH_SEGMENT_IMU
visionary::CameraParameters::cx
double cx
Definition: VisionaryData.h:44
visionary::DataHandlerError::INVALID_VERSION_SEGMENT_LOCALIOS
@ INVALID_VERSION_SEGMENT_LOCALIOS
visionary::ROI_DATA
Definition: SafeVisionaryData.h:200
visionary::SafeVisionaryData::m_deviceStatusData
DEVICE_STATUS_ELEMENT m_deviceStatusData
Definition: SafeVisionaryData.h:508
visionary::DataHandlerError::INVALID_LENGTH_SEGMENT_DEPTHMAP
@ INVALID_LENGTH_SEGMENT_DEPTHMAP
visionary::DataHandlerError::INVALID_LENGTH_SEGMENT_LOCALIOS
@ INVALID_LENGTH_SEGMENT_LOCALIOS
visionary::DataHandlerError::INVALID_VERSION_SEGMENT_IMU
@ INVALID_VERSION_SEGMENT_IMU
visionary::CameraParameters::height
int height
The height of the frame in pixels.
Definition: VisionaryData.h:38
visionary::DataHandlerError::INVALID_CRC_SEGMENT_LOGICSIGNALS
@ INVALID_CRC_SEGMENT_LOGICSIGNALS
visionary::SafeVisionaryData::m_logicSignalsData
LOGICSIGNALS_DATA m_logicSignalsData
Definition: SafeVisionaryData.h:517
visionary::SafeVisionaryData::m_localIOsData
LOCALIOS_ELEMENT m_localIOsData
Definition: SafeVisionaryData.h:511
visionary::SafeVisionaryData::parseIMUData
bool parseIMUData(std::vector< uint8_t >::iterator itBuf, size_t length)
Definition: SafeVisionaryData.cpp:732
visionary::VisionaryData
Definition: VisionaryData.h:72
visionary::DataSetsActive::hasDataSetLogicSignals
bool hasDataSetLogicSignals
Definition: VisionaryData.h:60
visionary::DEVICE_STATUS_ELEMENT
Definition: SafeVisionaryData.h:102
visionary::SafeVisionaryData::m_roiData
ROI_DATA m_roiData
Contains the ROI data.
Definition: SafeVisionaryData.h:505
visionary::VisionaryData::m_scaleZ
float m_scaleZ
Factor to convert unit of distance image to mm.
Definition: VisionaryData.h:227
visionary::CameraParameters::k2
double k2
Definition: VisionaryData.h:46
visionary::SafeVisionaryData::getStateMap
const std::vector< uint8_t > & getStateMap() const
Definition: SafeVisionaryData.cpp:807
tinyxml2::XMLNode
Definition: tinyxml2.h:716
visionary::CameraParameters::width
int width
The width of the frame in pixels.
Definition: VisionaryData.h:40
DEVICESTATUS_SEGMENT
#define DEVICESTATUS_SEGMENT
Definition: SafeVisionaryData.h:30
IMU_SEGMENT
#define IMU_SEGMENT
Definition: SafeVisionaryData.h:35
visionary::SafeVisionaryData::getFieldInformationData
const FIELDINFORMATION_DATA & getFieldInformationData() const
Definition: SafeVisionaryData.cpp:847
visionary::DataHandlerError::INVALID_VERSION_SEGMENT_ROI
@ INVALID_VERSION_SEGMENT_ROI
visionary::DataHandlerError::INVALID_VERSION_SEGMENT_LOGICSIGNALS
@ INVALID_VERSION_SEGMENT_LOGICSIGNALS
visionary::SafeVisionaryData::getDistanceMap
const std::vector< uint16_t > & getDistanceMap() const
Definition: SafeVisionaryData.cpp:797
visionary::SafeVisionaryData::getLocalIOData
LOCALIOS_ELEMENT getLocalIOData() const
Definition: SafeVisionaryData.cpp:842
visionary::CameraParameters::f2rc
double f2rc
FocalToRayCross - Correction Offset for depth info.
Definition: VisionaryData.h:48
visionary::SafeVisionaryData::m_stateByteDepth
uint32_t m_stateByteDepth
Byte depth of pixel state map.
Definition: SafeVisionaryData.h:490
tinyxml2::XMLDocument
Definition: tinyxml2.h:1751
visionary::VisionaryData::m_cameraParams
CameraParameters m_cameraParams
Definition: VisionaryData.h:223
visionary::SafeVisionaryData::getIntensityMap
const std::vector< uint16_t > & getIntensityMap() const
Definition: SafeVisionaryData.cpp:802
visionary::CameraParameters::p2
double p2
Definition: VisionaryData.h:46
visionary::SafeVisionaryData::m_distanceMap
std::vector< uint16_t > m_distanceMap
Vector containing the depth map.
Definition: SafeVisionaryData.h:493
visionary::DataSetsActive::hasDataSetDepthMap
bool hasDataSetDepthMap
Definition: VisionaryData.h:53
visionary::DataHandlerError::PARSE_XML_ERROR
@ PARSE_XML_ERROR
visionary::CameraParameters::cam2worldMatrix
double cam2worldMatrix[4 *4]
Camera to world transformation matrix.
Definition: VisionaryData.h:42
tinyxml2.h
visionary::DataHandlerError::INVALID_VERSION_SEGMENT_DEPTHMAP
@ INVALID_VERSION_SEGMENT_DEPTHMAP
visionary::SafeVisionaryData::m_stateMap
std::vector< uint8_t > m_stateMap
Vector containing the pixel state map.
Definition: SafeVisionaryData.h:499
visionary::DataHandlerError::INVALID_CRC_SEGMENT_FIELDINFORMATION
@ INVALID_CRC_SEGMENT_FIELDINFORMATION
visionary::VisionaryData::getItemLength
int getItemLength(std::string dataType)
Definition: VisionaryData.cpp:46
visionary::VisionaryData::RADIAL
@ RADIAL
Definition: VisionaryData.h:202
ROI_SEGMENT
#define ROI_SEGMENT
Definition: SafeVisionaryData.h:31
visionary::SafeVisionaryData::m_flags
uint16_t m_flags
Contains the received flags.
Definition: SafeVisionaryData.h:523
visionary::SafeVisionaryData::parseLocalIOsData
bool parseLocalIOsData(std::vector< uint8_t >::iterator itBuf, size_t length)
Definition: SafeVisionaryData.cpp:554
tinyxml2::XMLDocument::Parse
XMLError Parse(const char *xml, size_t nBytes=static_cast< size_t >(-1))
Definition: tinyxml2.cpp:2645
visionary::CameraParameters::k1
double k1
Camera Distortion Parameters.
Definition: VisionaryData.h:46
visionary::SafeVisionaryData::m_intensityByteDepth
uint32_t m_intensityByteDepth
Byte depth of intensity map.
Definition: SafeVisionaryData.h:487
visionary::VisionaryData::m_segmentTimestamp
uint64_t m_segmentTimestamp[TOTAL_SEGMENT_NUMBER]
Definition: VisionaryData.h:243
tinyxml2::XMLNode::FirstChildElement
const XMLElement * FirstChildElement(const char *name=0) const
Definition: tinyxml2.cpp:1094
LOGICSIGNALS_SEGMENT
#define LOGICSIGNALS_SEGMENT
Definition: SafeVisionaryData.h:34
visionary::DataHandlerError::INVALID_CRC_SEGMENT_IMU
@ INVALID_CRC_SEGMENT_IMU
visionary::LOGICSIGNALS_DATA
Definition: SafeVisionaryData.h:318


sick_safevisionary_base
Author(s):
autogenerated on Sat Oct 21 2023 02:24:26