channel.cc
Go to the documentation of this file.
1 
37 #include "details/channel.hh"
38 #include "details/query.hh"
39 
47 
49 
50 #ifndef WIN32
51 #include <netdb.h>
52 #endif
53 #include <errno.h>
54 #include <fcntl.h>
55 
56 namespace crl {
57 namespace multisense {
58 namespace details {
59 
60 //
61 // Implementation constructor
62 
63 impl::impl(const std::string& address) :
64  m_serverSocket(-1),
65  m_serverSocketPort(0),
66  m_sensorAddress(),
67  m_sensorMtu(MAX_MTU_SIZE),
68  m_incomingBuffer(MAX_MTU_SIZE),
69  m_txSeqId(0),
70  m_lastRxSeqId(-1),
71  m_unWrappedRxSeqId(0),
72  m_udpTrackerCache(UDP_TRACKER_CACHE_DEPTH, 0),
73  m_rxLargeBufferPool(),
74  m_rxSmallBufferPool(),
75  m_imageMetaCache(IMAGE_META_CACHE_DEPTH, 0),
76  m_udpAssemblerMap(),
77  m_dispatchLock(),
78  m_streamLock(),
79  m_threadsRunning(false),
80  m_rxThreadP(NULL),
81  m_rxLock(),
82  m_statusThreadP(NULL),
83  m_imageListeners(),
84  m_lidarListeners(),
85  m_ppsListeners(),
86  m_imuListeners(),
87  m_watch(),
88  m_messages(),
89  m_streamsEnabled(0),
90  m_timeLock(),
91  m_timeOffsetInit(false),
92  m_timeOffset(0),
93  m_networkTimeSyncEnabled(true),
94  m_sensorVersion()
95 {
96 #if WIN32
97  WSADATA wsaData;
98  int result = WSAStartup (MAKEWORD (0x02, 0x02), &wsaData);
99  if (result != 0)
100  CRL_EXCEPTION("WSAStartup() failed: %d", result);
101 #endif
102 
103  //
104  // Make sure the sensor address is sane
105 
106  struct hostent *hostP = gethostbyname(address.c_str());
107  if (NULL == hostP)
108  CRL_EXCEPTION("unable to resolve \"%s\": %s",
109  address.c_str(), strerror(errno));
110 
111  //
112  // Set up the address for transmission
113 
114  in_addr addr;
115 
116  memcpy(&(addr.s_addr), hostP->h_addr, hostP->h_length);
117  memset(&m_sensorAddress, 0, sizeof(m_sensorAddress));
118 
119  m_sensorAddress.sin_family = AF_INET;
120  m_sensorAddress.sin_port = htons(DEFAULT_SENSOR_TX_PORT);
121  m_sensorAddress.sin_addr = addr;
122 
123  //
124  // Create a pool of RX buffers
125 
126  for(uint32_t i=0; i<RX_POOL_LARGE_BUFFER_COUNT; i++)
128  for(uint32_t i=0; i<RX_POOL_SMALL_BUFFER_COUNT; i++)
130 
131  //
132  // Bind to the port
133 
134  bind();
135 
136  //
137  // Register any special UDP reassemblers
138 
140 
141  //
142  // Create UDP reception thread
143 
144  m_threadsRunning = true;
145  m_rxThreadP = new utility::Thread(rxThread, this);
146 
147  //
148  // Request the current operating MTU of the device
149 
150  wire::SysMtu mtu;
151 
152  Status status = waitData(wire::SysGetMtu(), mtu);
153  if (Status_Ok != status) {
154  cleanup();
155  CRL_EXCEPTION("failed to establish comms with the sensor at \"%s\"",
156  address.c_str());
157  } else {
158 
159  //
160  // Use the same MTU for TX
161 
162  m_sensorMtu = mtu.mtu;
163  }
164 
165  //
166  // Request version info from the device
167 
169  if (Status_Ok != status) {
170  cleanup();
171  CRL_EXCEPTION("failed to request version info from sensor at \"%s\"",
172  address.c_str());
173  }
174 
175  //
176  // Create status thread
177 
179 }
180 
181 //
182 // Implementation cleanup
183 
185 {
186  m_threadsRunning = false;
187 
188  if (m_rxThreadP)
189  delete m_rxThreadP;
190  if (m_statusThreadP)
191  delete m_statusThreadP;
192 
193  std::list<ImageListener*>::const_iterator iti;
194  for(iti = m_imageListeners.begin();
195  iti != m_imageListeners.end();
196  iti ++)
197  delete *iti;
198  std::list<LidarListener*>::const_iterator itl;
199  for(itl = m_lidarListeners.begin();
200  itl != m_lidarListeners.end();
201  itl ++)
202  delete *itl;
203  std::list<PpsListener*>::const_iterator itp;
204  for(itp = m_ppsListeners.begin();
205  itp != m_ppsListeners.end();
206  itp ++)
207  delete *itp;
208  std::list<ImuListener*>::const_iterator itm;
209  for(itm = m_imuListeners.begin();
210  itm != m_imuListeners.end();
211  itm ++)
212  delete *itm;
213 
214  BufferPool::const_iterator it;
215  for(it = m_rxLargeBufferPool.begin();
216  it != m_rxLargeBufferPool.end();
217  ++it)
218  delete *it;
219  for(it = m_rxSmallBufferPool.begin();
220  it != m_rxSmallBufferPool.end();
221  ++it)
222  delete *it;
223 
224  if (m_serverSocket > 0)
226 
227 #if WIN32
228  WSACleanup ();
229 #endif
230 }
231 
232 //
233 // Implementation destructor
234 
236 {
237  cleanup();
238 }
239 
240 //
241 // Binds the communications channel, preparing it to send/receive data
242 // over the network.
243 
245 {
246  //
247  // Create the socket.
248 
249  m_serverSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
250  if (m_serverSocket < 0)
251  CRL_EXCEPTION("failed to create the UDP socket: %s",
252  strerror(errno));
253 
254  //
255  // Turn non-blocking on.
256 #if WIN32
257  u_long ioctl_arg = 1;
258  if (0 != ioctlsocket(m_serverSocket, FIONBIO, &ioctl_arg))
259  CRL_EXCEPTION("failed to make a socket non-blocking: %d",WSAGetLastError ());
260 #else
261  const int flags = fcntl(m_serverSocket, F_GETFL, 0);
262 
263  if (0 != fcntl(m_serverSocket, F_SETFL, flags | O_NONBLOCK))
264  CRL_EXCEPTION("failed to make a socket non-blocking: %s",
265  strerror(errno));
266 #endif
267 
268  //
269  // Allow reusing sockets.
270 
271  int reuseSocket = 1;
272 
273  if (0 != setsockopt(m_serverSocket, SOL_SOCKET, SO_REUSEADDR, (char*) &reuseSocket,
274  sizeof(reuseSocket)))
275  CRL_EXCEPTION("failed to turn on socket reuse flag: %s",
276  strerror(errno));
277 
278  //
279  // We want very large buffers to store several images
280 
281  int bufferSize = 48 * 1024 * 1024;
282 
283  if (0 != setsockopt(m_serverSocket, SOL_SOCKET, SO_RCVBUF, (char*) &bufferSize,
284  sizeof(bufferSize)) ||
285  0 != setsockopt(m_serverSocket, SOL_SOCKET, SO_SNDBUF, (char*) &bufferSize,
286  sizeof(bufferSize)))
287  CRL_EXCEPTION("failed to adjust socket buffer sizes (%d bytes): %s",
288  bufferSize, strerror(errno));
289 
290  //
291  // Bind the connection to the port.
292 
293  struct sockaddr_in address;
294 
295  address.sin_family = AF_INET;
296  address.sin_port = htons(0); // system assigned
297  address.sin_addr.s_addr = htonl(INADDR_ANY);
298 
299  if (0 != ::bind(m_serverSocket, (struct sockaddr*) &address, sizeof(address)))
300  CRL_EXCEPTION("failed to bind the server socket to system-assigned port: %s",
301  strerror(errno));
302 
303  //
304  // Retrieve the system assigned local UDP port
305 #if WIN32
306  int len = sizeof(address);
307 #else
308  socklen_t len = sizeof(address);
309 #endif
310  if (0 != getsockname(m_serverSocket, (struct sockaddr*) &address, &len))
311  CRL_EXCEPTION("getsockname() failed: %s", strerror(errno));
312  m_serverSocketPort = htons(address.sin_port);
313 }
314 
315 //
316 // Publish a stream to the sensor
317 
319 {
320  //
321  // Install the header
322 
323  wire::Header& header = *(reinterpret_cast<wire::Header*>(stream.data()));
324 
325  header.magic = wire::HEADER_MAGIC;
326  header.version = wire::HEADER_VERSION;
327  header.group = wire::HEADER_GROUP;
328  header.flags = 0;
329 #if WIN32
330  // TBD: This returns the post-incremented value
331  header.sequenceIdentifier = InterlockedIncrement16((short*)&m_txSeqId);
332 #else
333  // TBD: This returns the pre-incremented value
334  header.sequenceIdentifier = __sync_fetch_and_add(&m_txSeqId, 1);
335 #endif
336  header.messageLength = stream.tell() - sizeof(wire::Header);
337  header.byteOffset = 0;
338 
339  //
340  // Send the packet along
341 
342  const int32_t ret = sendto(m_serverSocket, (char*)stream.data(), stream.tell(), 0,
343  (struct sockaddr *) &m_sensorAddress,
344  sizeof(m_sensorAddress));
345 
346  if (static_cast<size_t>(ret) != stream.tell())
347  CRL_EXCEPTION("error sending data to sensor, %d/%d bytes written: %s",
348  ret, stream.tell(), strerror(errno));
349 }
350 
351 //
352 // Convert data source types from wire<->API. These match 1:1 right now, but we
353 // want the freedom to change the wire protocol as we see fit.
354 
356 {
357  wire::SourceType wire_mask = 0;
358 
359  if (mask & Source_Raw_Left) wire_mask |= wire::SOURCE_RAW_LEFT;
360  if (mask & Source_Raw_Right) wire_mask |= wire::SOURCE_RAW_RIGHT;
361  if (mask & Source_Luma_Left) wire_mask |= wire::SOURCE_LUMA_LEFT;
362  if (mask & Source_Luma_Right) wire_mask |= wire::SOURCE_LUMA_RIGHT;
365  if (mask & Source_Chroma_Left) wire_mask |= wire::SOURCE_CHROMA_LEFT;
366  if (mask & Source_Chroma_Right) wire_mask |= wire::SOURCE_CHROMA_RIGHT;
367  if (mask & Source_Disparity) wire_mask |= wire::SOURCE_DISPARITY;
368  if (mask & Source_Disparity_Right) wire_mask |= wire::SOURCE_DISPARITY_RIGHT;
369  if (mask & Source_Disparity_Cost) wire_mask |= wire::SOURCE_DISPARITY_COST;
370  if (mask & Source_Jpeg_Left) wire_mask |= wire::SOURCE_JPEG_LEFT;
371  if (mask & Source_Rgb_Left) wire_mask |= wire::SOURCE_RGB_LEFT;
372  if (mask & Source_Lidar_Scan) wire_mask |= wire::SOURCE_LIDAR_SCAN;
373  if (mask & Source_Imu) wire_mask |= wire::SOURCE_IMU;
374  if (mask & Source_Pps) wire_mask |= wire::SOURCE_PPS;
375 
376  return wire_mask;
377 };
378 
380 {
381  DataSource api_mask = 0;
382 
383  if (mask & wire::SOURCE_RAW_LEFT) api_mask |= Source_Raw_Left;
384  if (mask & wire::SOURCE_RAW_RIGHT) api_mask |= Source_Raw_Right;
385  if (mask & wire::SOURCE_LUMA_LEFT) api_mask |= Source_Luma_Left;
386  if (mask & wire::SOURCE_LUMA_RIGHT) api_mask |= Source_Luma_Right;
389  if (mask & wire::SOURCE_CHROMA_LEFT) api_mask |= Source_Chroma_Left;
390  if (mask & wire::SOURCE_CHROMA_RIGHT) api_mask |= Source_Chroma_Right;
391  if (mask & wire::SOURCE_DISPARITY) api_mask |= Source_Disparity;
393  if (mask & wire::SOURCE_DISPARITY_COST) api_mask |= Source_Disparity_Cost;
394  if (mask & wire::SOURCE_JPEG_LEFT) api_mask |= Source_Jpeg_Left;
395  if (mask & wire::SOURCE_RGB_LEFT) api_mask |= Source_Rgb_Left;
396  if (mask & wire::SOURCE_LIDAR_SCAN) api_mask |= Source_Lidar_Scan;
397  if (mask & wire::SOURCE_IMU) api_mask |= Source_Imu;
398  if (mask & wire::SOURCE_PPS) api_mask |= Source_Pps;
399 
400  return api_mask;
401 };
402 
403 uint32_t impl::hardwareApiToWire(uint32_t a)
404 {
405  switch(a) {
413  default:
414  CRL_DEBUG("unknown API hardware type \"%d\"\n", a);
415  return a; // pass through
416  }
417 }
418 uint32_t impl::hardwareWireToApi(uint32_t w)
419 {
420  switch(w) {
428  default:
429  CRL_DEBUG("unknown WIRE hardware type \"%d\"\n", w);
430  return w; // pass through
431  }
432 }
433 uint32_t impl::imagerApiToWire(uint32_t a)
434 {
435  switch(a) {
441  default:
442  CRL_DEBUG("unknown API imager type \"%d\"\n", a);
443  return a; // pass through
444  }
445 }
446 uint32_t impl::imagerWireToApi(uint32_t w)
447 {
448  switch(w) {
454  default:
455  CRL_DEBUG("unknown WIRE imager type \"%d\"\n", w);
456  return w; // pass through
457  }
458 }
459 
460 //
461 // Apply a time offset correction
462 
463 void impl::applySensorTimeOffset(const double& offset)
464 {
466 
467  if (false == m_timeOffsetInit) {
468  m_timeOffset = offset; // seed
469  m_timeOffsetInit = true;
470  return;
471  }
472 
473  const double samples = static_cast<double>(TIME_SYNC_OFFSET_DECAY);
474 
476 }
477 
478 //
479 // Return the corrected time
480 
481 double impl::sensorToLocalTime(const double& sensorTime)
482 {
484  return m_timeOffset + sensorTime;
485 }
486 
487 //
488 // Correct the time, populate seconds/microseconds
489 
490 void impl::sensorToLocalTime(const double& sensorTime,
491  uint32_t& seconds,
492  uint32_t& microseconds)
493 {
494  double corrected = sensorToLocalTime(sensorTime);
495  seconds = static_cast<uint32_t>(corrected);
496  microseconds = static_cast<uint32_t>(1e6 * (corrected - static_cast<double>(seconds)));
497 }
498 
499 //
500 // An internal thread for status/time-synchroniziation
501 
502 #ifdef WIN32
503 DWORD impl::statusThread(void *userDataP)
504 #else
505 void *impl::statusThread(void *userDataP)
506 #endif
507 {
508  impl *selfP = reinterpret_cast<impl*>(userDataP);
509 
510  //
511  // Loop until shutdown
512 
513  while(selfP->m_threadsRunning) {
514 
515  try {
516 
517  //
518  // Setup handler for the status response
519 
521 
522  //
523  // Send the status request, recording the (approx) local time
524 
525  const double ping = utility::TimeStamp::getCurrentTime();
526  selfP->publish(wire::StatusRequest());
527 
528  //
529  // Wait for the response
530 
531  Status status;
532  if (ack.wait(status, 0.010)) {
533 
534  //
535  // Record (approx) time of response
536 
537  const double pong = utility::TimeStamp::getCurrentTime();
538 
539  //
540  // Extract the response payload
541 
543  selfP->m_messages.extract(msg);
544 
545 
546  //
547  // Estimate 'msg.uptime' capture using half of the round trip period
548 
549  const double latency = (pong - ping) / 2.0;
550 
551  //
552  // Compute and apply the estimated time offset
553 
554  const double offset = (ping + latency) - static_cast<double>(msg.uptime);
555  selfP->applySensorTimeOffset(offset);
556 
557  //
558  // Cache the status message
559 
560  selfP->m_statusResponseMessage = msg;
561  }
562 
563  } catch (const std::exception& e) {
564 
565  CRL_DEBUG("exception: %s\n", e.what());
566 
567  } catch (...) {
568 
569  CRL_DEBUG("unknown exception\n");
570  }
571 
572  //
573  // Recompute offset at ~1Hz
574 
575  usleep(static_cast<unsigned int> (1e6));
576  }
577 
578  return NULL;
579 }
580 
581 }; // namespace details
582 
583 Channel* Channel::Create(const std::string& address)
584 {
585  try {
586 
587  return new details::impl(address);
588 
589  } catch (const std::exception& e) {
590 
591  CRL_DEBUG("exception: %s\n", e.what());
592  return NULL;
593  }
594 }
595 
596 void Channel::Destroy(Channel *instanceP)
597 {
598  try {
599 
600  if (instanceP)
601  delete static_cast<details::impl*>(instanceP);
602 
603  } catch (const std::exception& e) {
604 
605  CRL_DEBUG("exception: %s\n", e.what());
606  }
607 }
608 
609 const char *Channel::statusString(Status status)
610 {
611  switch(status) {
612  case Status_Ok: return "Ok";
613  case Status_TimedOut: return "Timed out";
614  case Status_Error: return "Error";
615  case Status_Failed: return "Failed";
616  case Status_Unsupported: return "Unsupported";
617  case Status_Unknown: return "Unknown command";
618  case Status_Exception: return "Exception";
619  }
620 
621  return "Unknown Error";
622 }
623 
624 }; // namespace multisense
625 }; // namespace crl
static CRL_CONSTEXPR DataSource Source_Disparity_Cost
std::list< ImageListener * > m_imageListeners
Definition: channel.hh:363
static uint32_t imagerWireToApi(uint32_t h)
Definition: channel.cc:446
#define CRL_EXCEPTION(fmt,...)
Definition: Exception.hh:71
static uint32_t hardwareWireToApi(uint32_t h)
Definition: channel.cc:418
static CRL_CONSTEXPR SourceType SOURCE_DISPARITY
Definition: Protocol.h:222
static CRL_CONSTEXPR DataSource Source_Disparity_Right
double sensorToLocalTime(const double &sensorTime)
Definition: channel.cc:481
static CRL_CONSTEXPR uint32_t HARDWARE_REV_MULTISENSE_SL
static CRL_CONSTEXPR DataSource Source_Jpeg_Left
static CRL_CONSTEXPR uint32_t IMAGER_TYPE_CMV4000_COLOR
static const char * statusString(Status status)
Definition: channel.cc:609
static CRL_CONSTEXPR DataSource Source_Disparity
struct sockaddr_in m_sensorAddress
Definition: channel.hh:290
static CRL_CONSTEXPR uint32_t IMAGER_TYPE_CMV2000_GREY
static CRL_CONSTEXPR SourceType SOURCE_DISPARITY_RIGHT
Definition: Protocol.h:224
static CRL_CONSTEXPR DataSource Source_Chroma_Left
static CRL_CONSTEXPR uint32_t HARDWARE_REV_MULTISENSE_S21
UdpAssemblerMap m_udpAssemblerMap
Definition: channel.hh:332
static CRL_CONSTEXPR uint32_t HARDWARE_REV_MULTISENSE_ST21
static Channel * Create(const std::string &sensorAddress)
Definition: channel.cc:583
static CRL_CONSTEXPR Status Status_Unsupported
void applySensorTimeOffset(const double &offset)
Definition: channel.cc:463
wire::StatusResponse m_statusResponseMessage
Definition: channel.hh:399
static wire::SourceType sourceApiToWire(DataSource mask)
Definition: channel.cc:355
static CRL_CONSTEXPR DataSource Source_Luma_Left
std::list< PpsListener * > m_ppsListeners
Definition: channel.hh:365
std_msgs::Header * header(M &m)
#define closesocket
Definition: Portability.hh:89
static CRL_CONSTEXPR Status Status_Failed
static CRL_CONSTEXPR SourceType SOURCE_LUMA_LEFT
Definition: Protocol.h:216
utility::Thread * m_rxThreadP
Definition: channel.hh:352
static CRL_CONSTEXPR uint16_t HEADER_VERSION
Definition: Protocol.h:67
static CRL_CONSTEXPR uint32_t HARDWARE_REV_MULTISENSE_S7
static CRL_CONSTEXPR SourceType SOURCE_CHROMA_RIGHT
Definition: Protocol.h:221
static CRL_CONSTEXPR uint32_t RX_POOL_SMALL_BUFFER_COUNT
Definition: channel.hh:204
#define MSG_ID(x)
Definition: Protocol.h:248
static CRL_CONSTEXPR uint32_t RX_POOL_SMALL_BUFFER_SIZE
Definition: channel.hh:203
static CRL_CONSTEXPR uint32_t HARDWARE_REV_MULTISENSE_SL
static CRL_CONSTEXPR SourceType SOURCE_LUMA_RECT_RIGHT
Definition: Protocol.h:219
static CRL_CONSTEXPR DataSource Source_Lidar_Scan
static CRL_CONSTEXPR uint32_t HARDWARE_REV_MULTISENSE_M
static CRL_CONSTEXPR DataSource Source_Luma_Right
static CRL_CONSTEXPR DataSource Source_Imu
static CRL_CONSTEXPR uint32_t IMAGER_TYPE_CMV4000_GREY
static CRL_CONSTEXPR uint32_t HARDWARE_REV_MULTISENSE_S7S
static CRL_CONSTEXPR uint32_t HARDWARE_REV_MULTISENSE_ST21
static CRL_CONSTEXPR uint16_t DEFAULT_SENSOR_TX_PORT
Definition: channel.hh:200
static CRL_CONSTEXPR uint32_t IMAGER_TYPE_IMX104_COLOR
static CRL_CONSTEXPR uint32_t HARDWARE_REV_MULTISENSE_S21
Definition: channel.cc:56
static CRL_CONSTEXPR SourceType SOURCE_CHROMA_LEFT
Definition: Protocol.h:220
static CRL_CONSTEXPR Status Status_TimedOut
static CRL_CONSTEXPR uint32_t RX_POOL_LARGE_BUFFER_COUNT
Definition: channel.hh:202
static CRL_CONSTEXPR Status Status_Ok
static CRL_CONSTEXPR SourceType SOURCE_RAW_RIGHT
Definition: Protocol.h:215
static CRL_CONSTEXPR DataSource Source_Pps
static CRL_CONSTEXPR DataSource Source_Rgb_Left
wire::VersionResponse m_sensorVersion
Definition: channel.hh:394
static CRL_CONSTEXPR uint32_t IMAGER_TYPE_CMV4000_GREY
static CRL_CONSTEXPR uint32_t HARDWARE_REV_MULTISENSE_S7S
static CRL_CONSTEXPR SourceType SOURCE_IMU
Definition: Protocol.h:229
static uint32_t imagerApiToWire(uint32_t h)
Definition: channel.cc:433
static CRL_CONSTEXPR uint32_t HARDWARE_REV_BCAM
static CRL_CONSTEXPR SourceType SOURCE_LUMA_RECT_LEFT
Definition: Protocol.h:218
static CRL_CONSTEXPR uint16_t HEADER_MAGIC
Definition: Protocol.h:66
static CRL_CONSTEXPR SourceType SOURCE_DISPARITY_COST
Definition: Protocol.h:225
static CRL_CONSTEXPR DataSource Source_Raw_Right
#define CRL_DEBUG(fmt,...)
Definition: Exception.hh:77
static CRL_CONSTEXPR SourceType SOURCE_RGB_LEFT
Definition: Protocol.h:227
static CRL_CONSTEXPR uint32_t RX_POOL_LARGE_BUFFER_SIZE
Definition: channel.hh:201
std::list< LidarListener * > m_lidarListeners
Definition: channel.hh:364
static CRL_CONSTEXPR DataSource Source_Raw_Left
bool wait(Status &status, const double &timeout)
Definition: signal.hh:125
static uint32_t hardwareApiToWire(uint32_t h)
Definition: channel.cc:403
static void Destroy(Channel *instanceP)
Definition: channel.cc:596
impl(const std::string &address)
Definition: channel.cc:63
static CRL_CONSTEXPR uint32_t HARDWARE_REV_MULTISENSE_M
static CRL_CONSTEXPR uint16_t HEADER_GROUP
Definition: Protocol.h:72
static void assembler(utility::BufferStreamWriter &stream, const uint8_t *dataP, uint32_t offset, uint32_t length)
static CRL_CONSTEXPR DataSource Source_Luma_Rectified_Right
void publish(const T &message)
Definition: query.hh:50
static CRL_CONSTEXPR SourceType SOURCE_RAW_LEFT
Definition: Protocol.h:214
static CRL_CONSTEXPR uint32_t IMAGER_TYPE_CMV2000_GREY
static CRL_CONSTEXPR uint32_t IMAGER_TYPE_CMV4000_COLOR
static CRL_CONSTEXPR SourceType SOURCE_LIDAR_SCAN
Definition: Protocol.h:228
static CRL_CONSTEXPR SourceType SOURCE_PPS
Definition: Protocol.h:230
static void * rxThread(void *userDataP)
Definition: dispatch.cc:698
static CRL_CONSTEXPR SourceType SOURCE_LUMA_RIGHT
Definition: Protocol.h:217
std::list< ImuListener * > m_imuListeners
Definition: channel.hh:366
static CRL_CONSTEXPR Status Status_Exception
Type decayedAverage(Type const &previous, Type const &samples, Type const &newest)
Definition: Functional.hh:67
static CRL_CONSTEXPR uint32_t IMAGER_TYPE_CMV2000_COLOR
static CRL_CONSTEXPR uint32_t TIME_SYNC_OFFSET_DECAY
Definition: channel.hh:210
static CRL_CONSTEXPR uint32_t IMAGER_TYPE_CMV2000_COLOR
Status waitData(const T &command, U &data, const double &timeout=DEFAULT_ACK_TIMEOUT(), int32_t attempts=DEFAULT_ACK_ATTEMPTS)
Definition: query.hh:120
static void * statusThread(void *userDataP)
Definition: channel.cc:505
static CRL_CONSTEXPR Status Status_Error
static CRL_CONSTEXPR uint32_t IMAGER_TYPE_IMX104_COLOR
static CRL_CONSTEXPR SourceType SOURCE_JPEG_LEFT
Definition: Protocol.h:226
utility::Thread * m_statusThreadP
Definition: channel.hh:358
static DataSource sourceWireToApi(wire::SourceType mask)
Definition: channel.cc:379
static CRL_CONSTEXPR DataSource Source_Chroma_Right
static CRL_CONSTEXPR Status Status_Unknown
static CRL_CONSTEXPR uint32_t HARDWARE_REV_MULTISENSE_S7
static CRL_CONSTEXPR DataSource Source_Luma_Rectified_Left


multisense_lib
Author(s):
autogenerated on Sat Apr 6 2019 02:16:46