dispatch.cc
Go to the documentation of this file.
1 
38 
40 
43 
52 
54 
56 
58 
60 
62 
73 
75 
79 
81 
84 
85 #include <limits>
86 
87 namespace crl {
88 namespace multisense {
89 namespace details {
90 namespace {
91 
92 //
93 // Default UDP assembler
94 
95 void defaultUdpAssembler(utility::BufferStreamWriter& stream,
96  const uint8_t *dataP,
97  uint32_t offset,
98  uint32_t length)
99 {
100  stream.seek(offset);
101  stream.write(dataP, length);
102 }
103 
104 } // anonymous
105 
106 //
107 // Publish an image
108 
110  image::Header& header)
111 {
113 
114  std::list<ImageListener*>::const_iterator it;
115 
116  for(it = m_imageListeners.begin();
117  it != m_imageListeners.end();
118  it ++)
119  (*it)->dispatch(buffer, header);
120 }
121 
122 //
123 // Publish a laser scan
124 
126  lidar::Header& header)
127 {
129 
130  std::list<LidarListener*>::const_iterator it;
131 
132  for(it = m_lidarListeners.begin();
133  it != m_lidarListeners.end();
134  it ++)
135  (*it)->dispatch(buffer, header);
136 }
137 //
138 // Publish a PPS event
139 
141 {
143 
144  std::list<PpsListener*>::const_iterator it;
145 
146  for(it = m_ppsListeners.begin();
147  it != m_ppsListeners.end();
148  it ++)
149  (*it)->dispatch(header);
150 }
151 
152 //
153 // Publish an IMU event
154 
156 {
158 
159  std::list<ImuListener*>::const_iterator it;
160 
161  for(it = m_imuListeners.begin();
162  it != m_imuListeners.end();
163  it ++)
164  (*it)->dispatch(header);
165 }
166 
167 //
168 // Publish a compressed image
169 
171  compressed_image::Header& header)
172 {
174 
175  std::list<CompressedImageListener*>::const_iterator it;
176 
177  for(it = m_compressedImageListeners.begin();
178  it != m_compressedImageListeners.end();
179  it ++)
180  (*it)->dispatch(buffer, header);
181 }
182 
183 //
184 // Publish a Ground Surface Spline event
185 
187 {
189 
190  std::list<GroundSurfaceSplineListener*>::const_iterator it;
191 
192  for(it = m_groundSurfaceSplineListeners.begin();
193  it != m_groundSurfaceSplineListeners.end();
194  it ++)
195  (*it)->dispatch(header);
196 }
197 
198 //
199 // Publish an AprilTag detection event
200 
202 {
204 
205  std::list<AprilTagDetectionListener*>::const_iterator it;
206 
207  for(it = m_aprilTagDetectionListeners.begin();
208  it != m_aprilTagDetectionListeners.end();
209  it ++)
210  (*it)->dispatch(header);
211 }
212 
213 
214 //
215 // Dispatch incoming messages
216 
218 {
219  utility::BufferStreamReader stream(buffer);
220 
221  //
222  // Extract the type and version fields, which are stored
223  // first in the stream
224 
225  wire::IdType id;
226  wire::VersionType version;
227 
228  stream & id;
229  stream & version;
230 
231  //
232  // Handle the message.
233  //
234  // Simple, low-rate messages are dynamically stored
235  // off for possible presentation to the user in a signal
236  // handler.
237  //
238  // Larger data types use a threaded dispatch
239  // mechanism with a reference-counted buffer back-end.
240 
241  switch(id) {
243  {
244  wire::LidarData scan(stream, version);
246 
247  const int32_t scanArc = static_cast<int32_t> (utility::degreesToRadians(270.0) * 1e6); // microradians
248  const uint32_t maxRange = static_cast<uint32_t> (30.0 * 1e3); // mm
249 
250  if (false == m_networkTimeSyncEnabled) {
251 
252  header.timeStartSeconds = scan.timeStartSeconds;
254  header.timeEndSeconds = scan.timeEndSeconds;
256 
257  } else {
258 
260  header.timeStartSeconds, header.timeStartMicroSeconds);
261 
263  header.timeEndSeconds, header.timeEndMicroSeconds);
264  }
265 
266  header.scanId = scan.scanCount;
267  header.spindleAngleStart = scan.angleStart;
268  header.spindleAngleEnd = scan.angleEnd;
269  header.scanArc = scanArc;
270  header.maxRange = maxRange;
271  header.pointCount = scan.points;
272  header.rangesP = scan.distanceP;
273  header.intensitiesP = scan.intensityP;
274 
275  dispatchLidar(buffer, header);
276 
277  break;
278  }
280  {
281  wire::ImageMeta *metaP = new (std::nothrow) wire::ImageMeta(stream, version);
282 
283  if (NULL == metaP)
284  CRL_EXCEPTION_RAW("unable to allocate metadata");
285 
286  m_imageMetaCache.insert(metaP->frameId, metaP); // destroys oldest
287 
288  break;
289  }
291  {
292  wire::JpegImage image(stream, version);
293 
294  const wire::ImageMeta *metaP = m_imageMetaCache.find(image.frameId);
295  if (NULL == metaP)
296  break;
297  //CRL_EXCEPTION("no meta cached for frameId %d", image.frameId);
298 
300 
301  getImageTime(metaP, header.timeSeconds, header.timeMicroSeconds);
302 
303  header.source = sourceWireToApi(image.source);
304  header.bitsPerPixel = 0;
305  header.width = image.width;
306  header.height = image.height;
307  header.frameId = image.frameId;
308  header.exposure = metaP->exposureTime;
309  header.gain = metaP->gain;
310  header.framesPerSecond = metaP->framesPerSecond;
311  header.imageDataP = image.dataP;
312  header.imageLength = image.length;
313 
314  dispatchImage(buffer, header);
315 
316  break;
317  }
318  case MSG_ID(wire::Image::ID):
319  {
320  wire::Image image(stream, version);
321 
322  const wire::ImageMeta *metaP = m_imageMetaCache.find(image.frameId);
323  if (NULL == metaP)
324  break;
325  //CRL_EXCEPTION("no meta cached for frameId %d", image.frameId);
326 
328 
329  getImageTime(metaP, header.timeSeconds, header.timeMicroSeconds);
330 
331  header.source = sourceWireToApi(image.source);
332  header.bitsPerPixel = image.bitsPerPixel;
333  header.width = image.width;
334  header.height = image.height;
335  header.frameId = image.frameId;
336  if (version >= 2) {
337  header.exposure = image.exposure;
338  header.gain = image.gain;
339  } else {
340  header.exposure = metaP->exposureTime;
341  header.gain = metaP->gain;
342  }
343  header.framesPerSecond = metaP->framesPerSecond;
344  header.imageDataP = image.dataP;
345  header.imageLength = static_cast<uint32_t>(std::ceil(((double) image.bitsPerPixel / 8.0) * image.width * image.height));
346 
347  dispatchImage(buffer, header);
348 
349  break;
350  }
352  {
353  wire::Disparity image(stream, version);
354 
355  const wire::ImageMeta *metaP = m_imageMetaCache.find(image.frameId);
356  if (NULL == metaP)
357  break;
358  //CRL_EXCEPTION("no meta cached for frameId %d", image.frameId);
359 
361 
362  getImageTime(metaP, header.timeSeconds, header.timeMicroSeconds);
363 
364  header.source = Source_Disparity;
366  header.width = image.width;
367  header.height = image.height;
368  header.frameId = image.frameId;
369  header.exposure = metaP->exposureTime;
370  header.gain = metaP->gain;
371  header.framesPerSecond = metaP->framesPerSecond;
372  header.imageDataP = image.dataP;
373  header.imageLength = static_cast<uint32_t>(std::ceil(((double) wire::Disparity::API_BITS_PER_PIXEL / 8.0) * image.width * image.height));
374 
375  dispatchImage(buffer, header);
376 
377  break;
378  }
379  case MSG_ID(wire::SysPps::ID):
380  {
381  wire::SysPps pps(stream, version);
382 
384 
385  header.sensorTime = pps.ppsNanoSeconds;
386 
388  header.timeSeconds, header.timeMicroSeconds);
389 
390  dispatchPps(header);
391 
392  break;
393  }
395  {
396  wire::ImuData imu(stream, version);
397 
399 
400  header.sequence = imu.sequence;
401  header.samples.resize(imu.samples.size());
402 
403  for(uint32_t i=0; i<imu.samples.size(); i++) {
404 
405  const wire::ImuSample& w = imu.samples[i];
406  imu::Sample& a = header.samples[i];
407 
409  {
411  }
412  else {
413  if (false == m_networkTimeSyncEnabled) {
414 
416 
417  } else
420  }
421 
422  switch(w.type) {
426  default: CRL_EXCEPTION("unknown wire IMU type: %d", w.type);
427  }
428 
429  a.x = w.x; a.y = w.y; a.z = w.z;
430  }
431 
432  dispatchImu(header);
433 
434  break;
435  }
437  {
438  wire::CompressedImage image(stream, version);
439 
440  const wire::ImageMeta *metaP = m_imageMetaCache.find(image.frameId);
441  if (NULL == metaP)
442  break;
443  //CRL_EXCEPTION("no meta cached for frameId %d", image.frameId);
444 
446 
447  getImageTime(metaP, header.timeSeconds, header.timeMicroSeconds);
448 
449  header.source = sourceWireToApi(image.source);
450  header.bitsPerPixel = image.bitsPerPixel;
451  header.codec = image.codec;
452  header.width = image.width;
453  header.height = image.height;
454  header.frameId = image.frameId;
455  header.exposure = image.exposure;
456  header.gain = image.gain;
457  header.framesPerSecond = metaP->framesPerSecond;
458  header.imageDataP = image.dataP;
459  header.imageLength = image.compressedDataBufferSize;
460 
461  dispatchCompressedImage(buffer, header);
462  break;
463  }
465  {
466  wire::GroundSurfaceModel spline(stream, version);
467 
469 
470  header.frameId = spline.frameId;
471  header.timestamp = spline.timestamp;
472  header.success = spline.success;
473 
475  header.controlPointsWidth = spline.controlPointsWidth;
478 
479  for (unsigned int i = 0; i < 2; i++)
480  {
481  header.xzCellOrigin[i] = spline.xzCellOrigin[i];
482  header.xzCellSize[i] = spline.xzCellSize[i];
483  header.xzLimit[i] = spline.xzLimit[i];
484  header.minMaxAzimuthAngle[i] = spline.minMaxAzimuthAngle[i];
485  }
486 
487  for (unsigned int i = 0; i < 6; i++)
488  {
489  header.extrinsics[i] = spline.extrinsics[i];
490  header.quadraticParams[i] = spline.quadraticParams[i];
491  }
492 
494  break;
495  }
497  {
498  wire::ApriltagDetections apriltag(stream, version);
499 
501 
502  header.frameId = apriltag.frameId;
503  header.timestamp = apriltag.timestamp;
504  header.imageSource = std::string(apriltag.imageSource);
505  header.success = apriltag.success;
506  header.numDetections = apriltag.numDetections;
507 
508  // Loop over detections and convert from wire to header type
509  for (size_t index = 0 ; index < apriltag.detections.size() ; ++index)
510  {
511  const wire::ApriltagDetection incoming = apriltag.detections[index];
512 
513  apriltag::Header::ApriltagDetection outgoing;
514 
515  outgoing.family = std::string(incoming.family);
516  outgoing.id = incoming.id;
517  outgoing.hamming = incoming.hamming;
518  outgoing.decisionMargin = incoming.decisionMargin;
519 
520  for (unsigned int i = 0; i < 3; i++)
521  {
522  for (unsigned int j = 0; j < 3; j++)
523  {
524  outgoing.tagToImageHomography[i][j] = incoming.tagToImageHomography[i][j];
525  }
526  }
527 
528  outgoing.center[0] = incoming.center[0];
529  outgoing.center[1] = incoming.center[1];
530 
531  for (unsigned int i = 0; i < 4; i++)
532  {
533  for (unsigned int j = 0; j < 2; j++)
534  {
535  outgoing.corners[i][j] = incoming.corners[i][j];
536  }
537  }
538 
539  header.detections.push_back(outgoing);
540  }
541 
543  break;
544  }
545  case MSG_ID(wire::Ack::ID):
546  break; // handle below
548  m_messages.store(wire::CamConfig(stream, version));
549  break;
551  m_messages.store(wire::AuxCamConfig(stream, version));
552  break;
554  m_messages.store(wire::RemoteHeadConfig(stream, version));
555  break;
557  m_messages.store(wire::CamHistory(stream, version));
558  break;
560  m_messages.store(wire::LedStatus(stream, version));
561  break;
563  m_messages.store(wire::LedSensorStatus(stream, version));
564  break;
566  m_messages.store(wire::MotorPoll(stream, version));
567  break;
569  m_messages.store(wire::SysFlashResponse(stream, version));
570  break;
572  m_messages.store(wire::SysDeviceInfo(stream, version));
573  break;
575  m_messages.store(wire::SysCameraCalibration(stream, version));
576  break;
578  m_messages.store(wire::SysSensorCalibration(stream, version));
579  break;
581  m_messages.store(wire::SysTransmitDelay(stream, version));
582  break;
584  m_messages.store(wire::SysLidarCalibration(stream, version));
585  break;
586  case MSG_ID(wire::SysMtu::ID):
587  m_messages.store(wire::SysMtu(stream, version));
588  break;
590  m_messages.store(wire::SysNetwork(stream, version));
591  break;
593  m_messages.store(wire::SysDeviceModes(stream, version));
594  break;
596  m_messages.store(wire::VersionResponse(stream, version));
597  break;
599  m_messages.store(wire::StatusResponse(stream, version));
600  break;
602  m_messages.store(wire::ImuConfig(stream, version));
603  break;
605  m_messages.store(wire::ImuInfo(stream, version));
606  break;
608  m_messages.store(wire::SysTestMtuResponse(stream, version));
609  break;
612  break;
613  default:
614 
615  CRL_DEBUG("unknown message received: id=%d, version=%d\n",
616  id, version);
617  return;
618  }
619 
620  //
621  // Signal any listeners (_after_ the message is stored/dispatched)
622  //
623  // A [n]ack is a special case where we signal
624  // the returned status code of the ack'd command,
625  // otherwise we signal valid reception of this message.
626 
627  switch(id) {
628  case MSG_ID(wire::Ack::ID):
629  m_watch.signal(wire::Ack(stream, version));
630  break;
631  default:
632  m_watch.signal(id);
633  break;
634  }
635 }
636 
637 //
638 // Get a UDP assembler for this message type. We are given
639 // the first UDP packet in the stream
640 
641 impl::UdpAssembler impl::getUdpAssembler(const uint8_t *firstDatagramP,
642  uint32_t length)
643 {
644  //
645  // Get the message type, it is stored after wire::Header
646 
647  utility::BufferStreamReader stream(firstDatagramP, length);
648  stream.seek(sizeof(wire::Header));
649 
650  wire::IdType messageType;
651  stream & messageType;
652 
653  //
654  // See if a custom handler has been registered
655 
656  UdpAssemblerMap::const_iterator it = m_udpAssemblerMap.find(messageType);
657 
658  if (m_udpAssemblerMap.end() != it)
659  return it->second;
660  else
661  return defaultUdpAssembler;
662 }
663 
664 //
665 // Find a suitably sized buffer for the incoming message
666 
668 {
669  BufferPool *bP = NULL;
670 
671  if (messageLength <= RX_POOL_SMALL_BUFFER_SIZE)
672  bP = &(m_rxSmallBufferPool);
673  else if (messageLength <= RX_POOL_LARGE_BUFFER_SIZE)
674  bP = &(m_rxLargeBufferPool);
675  else
676  CRL_EXCEPTION("message too large: %d bytes", messageLength);
677 
678  //
679  // TODO: re-think the shared() mechanism of the buffers, so we do not
680  // have to walk this vector.
681 
682  BufferPool::const_iterator it = bP->begin();
683  for(; it != bP->end(); it++)
684  if (false == (*it)->shared())
685  return *(*it);
686 
687  CRL_EXCEPTION("no free RX buffers (%d in use by consumers)\n", bP->size());
688 }
689 
690 //
691 // Unwrap a 16-bit wire sequence ID into a unique 64-bit local ID
692 
693 const int64_t& impl::unwrapSequenceId(uint16_t wireId)
694 {
695  //
696  // Look for a sequence change
697 
698  if (wireId != m_lastRxSeqId) {
699 
700  CRL_CONSTEXPR uint16_t ID_MAX = std::numeric_limits<uint16_t>::max();
701  CRL_CONSTEXPR uint16_t ID_MASK = 0xF000;
702  CRL_CONSTEXPR uint16_t ID_HIGH = 0xF000;
703  CRL_CONSTEXPR uint16_t ID_LOW = 0x0000;
704 
705  //
706  // Seed
707 
708  if (-1 == m_lastRxSeqId)
710 
711  //
712  // Detect forward 16-bit wrap
713 
714  else if (((wireId & ID_MASK) == ID_LOW) &&
715  ((m_lastRxSeqId & ID_MASK) == ID_HIGH)) {
716 
717  m_unWrappedRxSeqId += 1 + (static_cast<int64_t>(ID_MAX) - m_lastRxSeqId) + wireId;
718 
719  //
720  // Normal case
721 
722  } else
723  m_unWrappedRxSeqId += static_cast<int64_t>(wireId) - m_lastRxSeqId;
724 
725  //
726  // Remember change
727 
728  m_lastRxSeqId = wireId;
729  }
730 
731  return m_unWrappedRxSeqId;
732 }
733 
734 //
735 // Handles any incoming packets
736 
738 {
740 
741  for(;;) {
742 
743  //
744  // Receive the packet
745 
746 // disable MSVC warning for narrowing conversion.
747 #ifdef WIN32
748 #pragma warning (push)
749 #pragma warning (disable : 4267)
750 #endif
751  const int bytesRead = recvfrom(m_serverSocket,
752  (char*)m_incomingBuffer.data(),
753  m_incomingBuffer.size(),
754  0, NULL, NULL);
755 #ifdef WIN32
756 #pragma warning (pop)
757 #endif
758 
759  //
760  // Nothing left to read
761 
762  if (bytesRead < 0)
763  break;
764 
765  //
766  // Check for undersized packets
767 
768  else if (bytesRead < (int)sizeof(wire::Header))
769  CRL_EXCEPTION("undersized packet: %d/%d bytes\n",
770  bytesRead, sizeof(wire::Header));
771 
772  //
773  // For convenience below
774 
775  const uint8_t *inP = reinterpret_cast<const uint8_t*>(m_incomingBuffer.data());
776 
777  //
778  // Validate the header
779 
780  const wire::Header& header = *(reinterpret_cast<const wire::Header*>(inP));
781 
782  if (wire::HEADER_MAGIC != header.magic)
783  CRL_EXCEPTION("bad protocol magic: 0x%x, expecting 0x%x",
784  header.magic, wire::HEADER_MAGIC);
785  else if (wire::HEADER_VERSION != header.version)
786  CRL_EXCEPTION("bad protocol version: 0x%x, expecting 0x%x",
787  header.version, wire::HEADER_VERSION);
788  else if (wire::HEADER_GROUP != header.group)
789  CRL_EXCEPTION("bad protocol group: 0x%x, expecting 0x%x",
790  header.group, wire::HEADER_GROUP);
791 
792  //
793  // Unwrap the sequence identifier
794 
795  const int64_t& sequence = unwrapSequenceId(header.sequenceIdentifier);
796 
797  //
798  // See if we are already tracking this messge ID
799 
800  UdpTracker *trP = m_udpTrackerCache.find(sequence);
801  if (NULL == trP) {
802 
803  //
804  // If we drop first packet, we will drop entire message. Currently we
805  // require the first datagram in order to assign an assembler.
806  // TODO: re-think this.
807 
808  if (0 != header.byteOffset)
809  continue;
810  else {
811 
812  //
813  // Create a new tracker for this sequence id.
814 
815  trP = new UdpTracker(header.messageLength,
816  getUdpAssembler(inP, bytesRead),
817  findFreeBuffer(header.messageLength));
818  }
819  }
820 
821  //
822  // Assemble the datagram into the message stream, returns true if the
823  // assembly is complete.
824 
825  if (true == trP->assemble(bytesRead - sizeof(wire::Header),
826  header.byteOffset,
827  &(inP[sizeof(wire::Header)]))) {
828 
829  //
830  // Dispatch to any listeners
831 
832  dispatch(trP->stream());
833 
834  //
835  // Release the tracker
836 
837  if (1 == trP->packets())
838  delete trP; // has not yet been cached
839  else
840  m_udpTrackerCache.remove(sequence);
841 
842  } else if (1 == trP->packets()) {
843 
844  //
845  // Cache the tracker, as more UDP packets are
846  // forthcoming for this message.
847 
848  m_udpTrackerCache.insert(sequence, trP);
849  }
850  }
851 }
852 
853 //
854 // This thread waits for UDP packets
855 
856 #if WIN32
857 DWORD impl::rxThread(void *userDataP)
858 #else
859 void *impl::rxThread(void *userDataP)
860 #endif
861 {
862  impl *selfP = reinterpret_cast<impl*>(userDataP);
863  const impl::socket_t server = selfP->m_serverSocket;
864  fd_set readSet;
865 
866  //
867  // Loop until shutdown
868 
869  while(selfP->m_threadsRunning) {
870 
871  //
872  // Add the server socket to the read set.
873 
874  FD_ZERO(&readSet);
875  FD_SET(server, &readSet);
876 
877  //
878  // Wait for a new packet to arrive, timing out every once in awhile
879 
880  struct timeval tv = {0, 200000}; // 5Hz
881 #ifdef WIN32
882  // Windows is "special" and doesn't have the same call semantics as posix
883  const int result = select (1, &readSet, NULL, NULL, &tv);
884 #else
885  const int result = select (server + 1, &readSet, NULL, NULL, &tv);
886 #endif
887  if (result <= 0)
888  continue;
889 
890  //
891  // Let the comm object handle decoding
892 
893  try {
894 
895  selfP->handle();
896 
897  } catch (const std::exception& e) {
898 
899  CRL_DEBUG("exception while decoding packet: %s\n", e.what());
900 
901  } catch ( ... ) {
902 
903  CRL_DEBUG_RAW("unknown exception while decoding packet\n");
904  }
905  }
906 
907  return NULL;
908 }
909 
910 }}} // namespaces
std::list< ImageListener * > m_imageListeners
Definition: channel.hh:458
#define CRL_EXCEPTION(fmt,...)
Definition: Exception.hh:85
static CRL_CONSTEXPR Type Type_Accelerometer
#define CRL_DEBUG_RAW(fmt)
Definition: Exception.hh:78
static CRL_CONSTEXPR IdType ID
static CRL_CONSTEXPR IdType ID
Definition: AckMessage.hh:49
void dispatchCompressedImage(utility::BufferStream &buffer, compressed_image::Header &header)
Definition: dispatch.cc:170
static CRL_CONSTEXPR DataSource Source_Disparity
bool assemble(uint32_t bytes, uint32_t offset, const uint8_t *dataP)
Definition: channel.hh:348
std::vector< Sample > samples
void dispatchGroundSurfaceSpline(ground_surface::Header &header)
Definition: dispatch.cc:186
UdpAssemblerMap m_udpAssemblerMap
Definition: channel.hh:427
std::list< PpsListener * > m_ppsListeners
Definition: channel.hh:460
std_msgs::Header * header(M &m)
std::list< AprilTagDetectionListener * > m_aprilTagDetectionListeners
Definition: channel.hh:464
DepthCache< int64_t, wire::ImageMeta > m_imageMetaCache
Definition: channel.hh:420
static CRL_CONSTEXPR Type Type_Magnetometer
void dispatch(utility::BufferStreamWriter &buffer)
Definition: dispatch.cc:217
DepthCache< int64_t, UdpTracker > m_udpTrackerCache
Definition: channel.hh:407
std::vector< ApriltagDetection > detections
static CRL_CONSTEXPR IdType ID
void dispatchAprilTagDetections(apriltag::Header &header)
Definition: dispatch.cc:201
UdpAssembler getUdpAssembler(const uint8_t *udpDatagramP, uint32_t length)
Definition: dispatch.cc:641
static CRL_CONSTEXPR uint16_t HEADER_VERSION
Definition: Protocol.hh:76
void getImageTime(const WireT *wire, uint32_t &seconds, uint32_t &microSeconds)
Definition: channel.hh:241
std::vector< uint8_t > m_incomingBuffer
Definition: channel.hh:395
static CRL_CONSTEXPR uint32_t RX_POOL_SMALL_BUFFER_SIZE
Definition: channel.hh:282
void signal(wire::IdType id, Status status=Status_Ok)
Definition: signal.hh:57
void(* UdpAssembler)(utility::BufferStreamWriter &stream, const uint8_t *dataP, uint32_t offset, uint32_t length)
Definition: channel.hh:223
utility::Mutex m_dispatchLock
Definition: channel.hh:432
const IntensityType * intensitiesP
#define CRL_EXCEPTION_RAW(fmt)
Definition: Exception.hh:91
static CRL_CONSTEXPR uint16_t TYPE_GYRO
Definition: channel.cc:58
static CRL_CONSTEXPR uint16_t TYPE_ACCEL
#define MSG_ID(x)
Definition: Protocol.hh:311
utility::BufferStreamWriter & stream()
Definition: channel.hh:345
std::list< CompressedImageListener * > m_compressedImageListeners
Definition: channel.hh:462
const int64_t & unwrapSequenceId(uint16_t id)
Definition: dispatch.cc:693
utility::BufferStreamWriter & findFreeBuffer(uint32_t messageLength)
Definition: dispatch.cc:667
std::list< GroundSurfaceSplineListener * > m_groundSurfaceSplineListeners
Definition: channel.hh:463
void toHeaderTime(T nanoSeconds, uint32_t &seconds, uint32_t &microSeconds) const
Definition: channel.hh:229
static CRL_CONSTEXPR uint16_t HEADER_MAGIC
Definition: Protocol.hh:75
void dispatchImu(imu::Header &header)
Definition: dispatch.cc:155
void dispatchPps(pps::Header &header)
Definition: dispatch.cc:140
Type degreesToRadians(Type const &value)
Definition: Units.hh:55
#define CRL_DEBUG(fmt,...)
Definition: Exception.hh:71
static CRL_CONSTEXPR uint32_t RX_POOL_LARGE_BUFFER_SIZE
Definition: channel.hh:280
std::list< LidarListener * > m_lidarListeners
Definition: channel.hh:459
utility::TimeStamp sensorToLocalTime(const utility::TimeStamp &sensorTime)
Definition: channel.cc:637
static CRL_CONSTEXPR uint16_t HEADER_GROUP
Definition: Protocol.hh:81
static void * rxThread(void *userDataP)
Definition: dispatch.cc:859
void dispatchLidar(utility::BufferStream &buffer, lidar::Header &header)
Definition: dispatch.cc:125
std::list< ImuListener * > m_imuListeners
Definition: channel.hh:461
std::vector< utility::BufferStreamWriter * > BufferPool
Definition: channel.hh:412
static CRL_CONSTEXPR uint16_t TYPE_MAG
static CRL_CONSTEXPR IdType ID
static CRL_CONSTEXPR Type Type_Gyroscope
#define CRL_CONSTEXPR
Definition: Portability.hh:49
static DataSource sourceWireToApi(wire::SourceType mask)
Definition: channel.cc:477
void dispatchImage(utility::BufferStream &buffer, image::Header &header)
Definition: dispatch.cc:109


multisense_lib
Author(s):
autogenerated on Sat Jun 24 2023 03:01:21