LibMultiSense/details/legacy/channel.cc
Go to the documentation of this file.
1 
37 #ifdef WIN32
38 #ifndef WIN32_LEAN_AND_MEAN
39 #define WIN32_LEAN_AND_MEAN 1
40 #endif
41 
42 #include <windows.h>
43 #include <winsock2.h>
44 
45 #else
46 #include <arpa/inet.h>
47 #endif
48 
49 #include <cstring>
50 #include <iostream>
51 #include <inttypes.h>
52 
53 #include <utility/Exception.hh>
54 #include <wire/Protocol.hh>
55 #include <utility/BufferStream.hh>
56 
60 #include <wire/CamConfigMessage.hh>
64 #include <wire/DisparityMessage.hh>
65 #include <wire/ImageMessage.hh>
66 #include <wire/ImageMetaMessage.hh>
67 #include <wire/ImuConfigMessage.hh>
68 #include <wire/ImuDataMessage.hh>
71 #include <wire/ImuInfoMessage.hh>
73 #include <wire/LedSetMessage.hh>
74 #include <wire/LedStatusMessage.hh>
87 #include <wire/SysMtuMessage.hh>
94 
98 #include "details/legacy/info.hh"
100 #include "details/legacy/status.hh"
102 
104 
105 namespace multisense {
106 namespace legacy {
107 
108 namespace {
112  constexpr uint16_t MAX_MTU = 9000;
113 
117  constexpr std::array<uint16_t, 10> MTUS_TO_TEST{9000, 8167, 7333, 6500, 5667, 4833, 4000, 3167, 2333, 1500};
118 }
119 
121  m_config(config),
126  m_message_assembler(m_buffer_pool)
127 {
128  if (config.connect_on_initialization && connect(config) != Status::OK)
129  {
130  CRL_EXCEPTION("Connection to MultiSense failed\n");
131  }
132 }
133 
135 {
136  disconnect();
137 }
138 
139 
140 Status LegacyChannel::start_streams(const std::vector<DataSource> &sources)
141 {
142  using namespace crl::multisense::details;
143  using namespace std::chrono_literals;
144 
145  if (!m_connected)
146  {
147  return Status::UNINITIALIZED;
148  }
149 
151 
152  cmd.enable(convert_sources(sources));
153 
154  if (const auto ack = wait_for_ack(m_message_assembler,
155  m_socket,
156  cmd,
157  m_transmit_id++,
160  {
161  if (ack->status != wire::Ack::Status_Ok)
162  {
163  CRL_DEBUG("Start streams ack invalid: %" PRIi32 "\n", ack->status);
164  return get_status(ack->status);
165  }
166 
167  for (const auto &source : sources)
168  {
169  const auto expanded = expand_source(source);
170  m_active_streams.insert(std::begin(expanded), std::end(expanded));
171  }
172 
173  return Status::OK;
174  }
175 
176  return Status::TIMEOUT;
177 }
178 
179 Status LegacyChannel::stop_streams(const std::vector<DataSource> &sources)
180 {
181  using namespace crl::multisense::details;
182  using namespace std::chrono_literals;
183 
184  if (!m_connected)
185  {
186  return Status::UNINITIALIZED;
187  }
188 
190 
191  cmd.disable(convert_sources(sources));
192 
193  if (const auto ack = wait_for_ack(m_message_assembler,
194  m_socket,
195  cmd,
196  m_transmit_id++,
199  {
200  if (ack->status != wire::Ack::Status_Ok)
201  {
202  CRL_DEBUG("Start streams ack invalid: %" PRIi32 "\n", ack->status);
203  return get_status(ack->status);
204  }
205 
206  for (const auto &source : sources)
207  {
208  m_active_streams.erase(source);
209  }
210 
211  return Status::OK;
212  }
213 
214  return Status::TIMEOUT;
215 }
216 
217 void LegacyChannel::add_image_frame_callback(std::function<void(const ImageFrame&)> callback)
218 {
219  std::lock_guard<std::mutex> lock(m_image_callback_mutex);
220 
221  m_user_image_frame_callback = callback;
222 }
223 
224 void LegacyChannel::add_imu_frame_callback(std::function<void(const ImuFrame&)> callback)
225 {
226  std::lock_guard<std::mutex> lock(m_imu_callback_mutex);
227 
228  m_user_imu_frame_callback = callback;
229 }
230 
232 {
233  using namespace crl::multisense::details;
234 
235  if (m_connected)
236  {
237  CRL_DEBUG("Channel is already connected to the MultiSense\n");
238  return Status::FAILED;
239  }
240 
241  std::lock_guard<std::mutex> lock(m_mutex);
242 
243  //
244  // Setup networking
245  //
246 #if WIN32
247  WSADATA wsaData;
248  int result = WSAStartup (MAKEWORD (0x02, 0x02), &wsaData);
249  if (result != 0)
250  {
251  CRL_EXCEPTION("WSAStartup() failed: %d\n", result);
252  }
253 
254 #endif
255 
257 
258  auto [sensor_socket, server_socket_port] = bind(config.interface, false);
259  m_socket.sensor_socket = sensor_socket;
260  m_socket.server_socket_port = server_socket_port;
261 
262  //
263  // Attach image callbacks to handle incoming image data
264  //
265  m_message_assembler.register_callback(wire::ImageMeta::ID,
266  std::bind(&LegacyChannel::image_meta_callback, this, std::placeholders::_1));
267 
268  m_message_assembler.register_callback(wire::Image::ID,
269  std::bind(&LegacyChannel::image_callback, this, std::placeholders::_1));
270 
271  m_message_assembler.register_callback(wire::Disparity::ID,
272  std::bind(&LegacyChannel::disparity_callback, this, std::placeholders::_1));
273 
274  m_message_assembler.register_callback(wire::ImuData::ID,
275  std::bind(&LegacyChannel::imu_callback, this, std::placeholders::_1));
276 
277  //
278  // Main thread which services incoming data and dispatches to callbacks and conditions attached to the channel
279  //
280  m_udp_receiver = std::make_unique<UdpReceiver>(m_socket, MAX_MTU,
281  [this](const std::vector<uint8_t>& data)
282  {
283  if (!this->m_message_assembler.process_packet(data))
284  {
285  CRL_DEBUG("Processing packet of %" PRIu64 " bytes failed\n",
286  static_cast<uint64_t>(data.size()));
287  }
288  });
289  //
290  // Set the user requested MTU
291  //
292  if (const auto status = set_mtu(config.mtu); status != Status::OK)
293  {
294  CRL_DEBUG("Unable to set MTU: %s\n", to_string(status).c_str());
295  return status;
296  }
297 
298  //
299  // Update our cached calibration
300  //
301  if (auto calibration = query_calibration(); calibration)
302  {
303  m_calibration = std::move(calibration.value());
304  }
305  else
306  {
307  CRL_EXCEPTION("Unable to query the camera's calibration");
308  }
309 
310  //
311  // Update our cached system info
312  //
313  if (auto info = query_info(); info)
314  {
315  m_info = std::move(info.value());
316  }
317  else
318  {
319  CRL_EXCEPTION("Unable to query the camera's info ");
320  }
321 
322  //
323  // Update our cached multisense configuration
324  //
325  if (auto cam_config = query_configuration(m_info.device.has_aux_camera(), m_info.imu.has_value(), false); cam_config)
326  {
327  m_multisense_config = std::move(cam_config.value());
328  }
329  else
330  {
331  CRL_EXCEPTION("Unable to query the camera's configuration");
332  }
333 
334  m_connected = true;
335 
336  return Status::OK;
337 }
338 
340 {
341  using namespace crl::multisense::details;
342 
343  if (!m_connected)
344  {
345  return;
346  }
347 
348  //
349  // Stop all our streams before disconnecting
350  //
352 
353  std::lock_guard<std::mutex> lock(m_mutex);
354 
355  m_connected = false;
356 
357  m_message_assembler.remove_callback(wire::Image::ID);
358 
360 
361  m_udp_receiver = nullptr;
362 
363  return;
364 }
365 
366 std::optional<ImageFrame> LegacyChannel::get_next_image_frame()
367 {
368  if (!m_connected)
369  {
370  return std::nullopt;
371  }
372 
374 }
375 
376 std::optional<ImuFrame> LegacyChannel::get_next_imu_frame()
377 {
378  if (!m_connected)
379  {
380  return std::nullopt;
381  }
382 
384 }
385 
387 {
388  std::lock_guard<std::mutex> lock(m_mutex);
389 
390  if (!m_connected)
391  {
392  CRL_DEBUG("Warning: MultiSense is not connected");
393  }
394 
395  return m_multisense_config;
396 }
397 
399 {
400  using namespace crl::multisense::details;
401 
402  if (!m_connected)
403  {
404  return Status::UNINITIALIZED;
405  }
406 
407  std::vector<Status> responses{};
408 
409  //
410  // For settings that impact camera hardware retry applying them
411  //
412  constexpr size_t setting_retries = 3;
413 
414  //
415  // Set the camera resolution
416  //
417  const auto res_ack = wait_for_ack(m_message_assembler,
418  m_socket,
419  convert<wire::CamSetResolution>(config),
420  m_transmit_id++,
423  setting_retries);
424 
425  if (!res_ack || res_ack->status != wire::Ack::Status_Ok)
426  {
427  responses.push_back(get_status(res_ack->status));
428  }
429 
430  //
431  // Set the generic camera controls
432  //
433  const auto cam_ack = wait_for_ack(m_message_assembler,
434  m_socket,
435  convert<wire::CamControl>(config),
436  m_transmit_id++,
439  setting_retries);
440 
441  if (!cam_ack || cam_ack->status != wire::Ack::Status_Ok)
442  {
443  responses.push_back(get_status(cam_ack->status));
444  }
445 
446  //
447  // Set aux controls if they are valid
448  //
449  if (config.aux_config && m_info.device.has_aux_camera())
450  {
451  //
452  // Set the aux camera controls
453  //
454  const auto aux_ack = wait_for_ack(m_message_assembler,
455  m_socket,
456  convert(config.aux_config.value()),
457  m_transmit_id++,
460  setting_retries);
461  if (!aux_ack || aux_ack->status != wire::Ack::Status_Ok)
462  {
463  responses.push_back(get_status(aux_ack->status));
464  }
465  }
466 
467  //
468  // Set imu controls if they are valid
469  //
470  if (config.imu_config && m_info.imu)
471  {
472  //
473  // Set the imu controls
474  //
475  const auto imu_ack = wait_for_ack(m_message_assembler,
476  m_socket,
477  convert(config.imu_config.value(),
478  m_info.imu.value(),
480  m_transmit_id++,
483  setting_retries);
484  if (!imu_ack || imu_ack->status != wire::Ack::Status_Ok)
485  {
486  responses.push_back(get_status(imu_ack->status));
487  }
488  }
489 
490  //
491  // Set lighting controls if they are valid
492  //
493  if (config.lighting_config)
494  {
495  //
496  // Set the lighting controls
497  //
498  const auto lighting_ack = wait_for_ack(m_message_assembler,
499  m_socket,
500  convert(config.lighting_config.value()),
501  m_transmit_id++,
504  setting_retries);
505  if (!lighting_ack || lighting_ack->status != wire::Ack::Status_Ok)
506  {
507  responses.push_back(get_status(lighting_ack->status));
508  }
509  }
510 
511  //
512  // Enable/disable ptp
513  //
514  if (config.time_config)
515  {
516  const auto ptp_ack = wait_for_ack(m_message_assembler,
517  m_socket,
518  convert(config.time_config.value()),
519  m_transmit_id++,
522 
523  if (!ptp_ack || ptp_ack->status != wire::Ack::Status_Ok)
524  {
525  responses.push_back(get_status(ptp_ack->status));
526  }
527  }
528 
529  //
530  // Set our packet delay
531  //
532  if (config.network_config)
533  {
534  const auto packet_ack = wait_for_ack(m_message_assembler,
535  m_socket,
536  convert<wire::SysPacketDelay>(config.network_config.value()),
537  m_transmit_id++,
540 
541  if (!packet_ack || packet_ack->status != wire::Ack::Status_Ok)
542  {
543  responses.push_back(get_status(packet_ack->status));
544  }
545  }
546 
547  const auto errors = std::any_of(std::begin(responses), std::end(responses),
548  [](const auto &e)
549  {
550  return (e == Status::INTERNAL_ERROR ||
551  e == Status::FAILED ||
552  e == Status::EXCEPTION);
553  });
554 
555  if (errors)
556  {
557  return Status::INTERNAL_ERROR;
558  }
559 
560  //
561  // Update our internal cached image config after we successfully set everything
562  //
563  const auto ptp_enabled = config.time_config && config.time_config->ptp_enabled;
564  if (const auto new_config = query_configuration(m_info.device.has_aux_camera(),
565  m_info.imu.has_value(),
566  ptp_enabled); new_config)
567  {
568  std::lock_guard<std::mutex> lock(m_mutex);
569 
570  m_multisense_config = new_config.value();
571 
572  //
573  // If our input does not match our queried output it means the camera does not support one of
574  // our configuration settings
575  //
576  if (config == new_config.value())
577  {
578  return Status::OK;
579  }
580 
582  }
583 
584  return Status::INTERNAL_ERROR;
585 }
586 
588 {
589  std::lock_guard<std::mutex> lock(m_mutex);
590 
591  if (!m_connected)
592  {
593  CRL_DEBUG("Warning: MultiSense is not connected");
594  }
595 
596  return m_calibration;
597 }
598 
600 {
601  using namespace crl::multisense::details;
602 
603  if (!m_connected)
604  {
605  return Status::UNINITIALIZED;
606  }
607 
608  const wire::SysCameraCalibration wire_calibration = convert(calibration);
609 
610  if (const auto ack = wait_for_ack(m_message_assembler,
611  m_socket,
612  wire_calibration,
613  m_transmit_id++,
616  {
617  //
618  // If we successfully set the calibration re-query it to update our internal cached value
619  //
620  if (ack->status == wire::Ack::Status_Ok)
621  {
622  if (const auto new_cal = query_calibration(); new_cal)
623  {
624  std::lock_guard<std::mutex> lock(m_mutex);
625  m_calibration = new_cal.value();
626  }
627  }
628 
629  return get_status(ack->status);
630  }
631 
632  return Status::TIMEOUT;
633 }
634 
636 {
637  std::lock_guard<std::mutex> lock(m_mutex);
638 
639  if (!m_connected)
640  {
641  CRL_DEBUG("Warning: MultiSense is not connected");
642  }
643 
644  return m_info;
645 }
646 
647 Status LegacyChannel::set_device_info(const MultiSenseInfo::DeviceInfo &device_info, const std::string &key)
648 {
649  using namespace crl::multisense::details;
650 
651  const wire::SysDeviceInfo wire_device_info = convert(device_info, key);
652 
653  if (const auto ack = wait_for_ack(m_message_assembler,
654  m_socket,
655  wire_device_info,
656  m_transmit_id++,
659  {
660  //
661  // If we successfully set the device info re-query it to update our internal cached value
662  //
663  if (ack->status == wire::Ack::Status_Ok)
664  {
665  if (const auto new_device_info = query_device_info(); new_device_info)
666  {
667  std::lock_guard<std::mutex> lock(m_mutex);
668  m_info.device = new_device_info.value();
669  }
670  }
671 
672  return get_status(ack->status);
673  }
674 
675  return Status::TIMEOUT;
676 }
677 
678 std::optional<MultiSenseStatus> LegacyChannel::get_system_status()
679 {
680  using namespace crl::multisense::details;
681 
682  if (!m_connected)
683  {
684  return std::nullopt;
685  }
686 
687  //
688  // Query the main status info, and time when we send the ack, and when we receive the response
689  //
690  const auto status = wait_for_data_timed<wire::StatusResponse>(m_message_assembler,
691  m_socket,
693  m_transmit_id++,
696 
697  if (!status)
698  {
699  CRL_DEBUG("Unable to query status\n");
700  return std::nullopt;
701  }
702 
703  std::optional<wire::PtpStatusResponse> ptp_status = std::nullopt;
705  {
706 
707  if (ptp_status = wait_for_data<wire::PtpStatusResponse>(m_message_assembler,
708  m_socket,
710  m_transmit_id++,
712  m_config.receive_timeout); !ptp_status)
713  {
714  CRL_DEBUG("Unable to query ptp status\n");
715  return std::nullopt;
716  }
717  }
718 
719  //
720  // To compute our network delay (i.e. offset between client host time and the camera uptime take our
721  // total roundtrip and divide by 2 to account for the transmit/receive
722  //
723  MultiSenseStatus::TimeStatus time_status{std::chrono::nanoseconds{status->message.uptime.getNanoSeconds()},
724  status->host_start_transmit_time,
725  status->host_transmit_receive_roundtrip / 2};
726 
727  const auto message_stats = m_message_assembler.get_message_statistics();
728  MultiSenseStatus::ClientNetworkStatus client_stats{message_stats.received_messages,
729  message_stats.dropped_messages,
730  message_stats.invalid_packets};
731 
732  return MultiSenseStatus{system_ok(status->message),
733  (ptp_status ? std::make_optional(convert(ptp_status.value())) : std::nullopt),
734  convert<MultiSenseStatus::CameraStatus>(status->message),
735  convert<MultiSenseStatus::TemperatureStatus>(status->message),
736  convert<MultiSenseStatus::PowerStatus>(status->message),
737  std::move(client_stats),
738  std::move(time_status)};
739 }
740 
742  const std::optional<std::string> &broadcast_interface)
743 {
744  using namespace crl::multisense::details;
745 
746  if (config.ip_address == "0.0.0.0" || config.ip_address == "255.255.255.255" ||
747  config.gateway == "0.0.0.0" || config.gateway == "255.255.255.255" ||
748  config.netmask == "0.0.0.0" || config.netmask == "255.255.255.255")
749  {
750  return Status::UNSUPPORTED;
751  }
752 
753  if (broadcast_interface)
754  {
755  auto broadcast_address = get_broadcast_sockaddr(m_config.command_port);
756 
757  auto [socket, socket_port] = multisense::legacy::bind(broadcast_interface.value(), true);
758 
759  NetworkSocket broadcast_socket{std::move(broadcast_address), std::move(socket), std::move(socket_port)};
760 
761  publish_data(broadcast_socket, serialize(convert(config), 0, m_current_mtu));
762 
763  return Status::OK;
764  }
765  else
766  {
767  if (!m_connected)
768  {
769  return Status::UNINITIALIZED;
770  }
771 
772  if (const auto ack = wait_for_ack(m_message_assembler,
773  m_socket,
774  convert(config),
775  m_transmit_id++,
778  {
779  return get_status(ack->status);
780  }
781  }
782 
783  return Status::TIMEOUT;
784 }
785 
787 {
788  using namespace crl::multisense::details;
789 
790  if (const auto test_mtu = wait_for_data<wire::SysTestMtuResponse>(m_message_assembler,
791  m_socket,
792  wire::SysTestMtu(mtu),
793  m_transmit_id++,
795  m_config.receive_timeout); !test_mtu)
796  {
797  CRL_DEBUG("Testing MTU of %" PRIu16 " bytes failed."
798  " Please verify you can ping the MultiSense with a MTU of %" PRIu16 " bytes at %s.\n",
799  mtu, mtu, inet_ntoa(m_socket.sensor_address->sin_addr));
800  return Status::INTERNAL_ERROR;
801  }
802 
803  if (const auto ack = wait_for_ack(m_message_assembler,
804  m_socket,
805  wire::SysMtu(mtu),
806  m_transmit_id++,
809  {
810  if (ack->status != wire::Ack::Status_Ok)
811  {
812  CRL_DEBUG("Unable to set MTU to %" PRIu16 " bytes: %i\n", mtu, ack->status);
813  return get_status(ack->status);
814  }
815  }
816 
817  m_current_mtu = mtu;
818  return Status::OK;
819 }
820 
821 Status LegacyChannel::set_mtu(const std::optional<uint16_t> &mtu)
822 {
823  using namespace crl::multisense::details;
824 
825  if (mtu)
826  {
827  return set_mtu(mtu.value());
828  }
829  else
830  {
831  for (const auto &value : MTUS_TO_TEST)
832  {
833  if (const auto status = set_mtu(value); status == Status::OK)
834  {
835  CRL_DEBUG("Auto-setting MTU to %" PRIu16 " bytes \n", value);
836  return status;
837  }
838  }
839  CRL_DEBUG("Unable to find a MTU that works with the MultiSense. "
840  "Please verify you can ping the MultiSense at %s\n", inet_ntoa(m_socket.sensor_address->sin_addr));
841  }
842 
843  return Status::INTERNAL_ERROR;
844 }
845 
846 std::optional<MultiSenseConfig> LegacyChannel::query_configuration(bool has_aux_camera,
847  bool has_imu,
848  bool ptp_enabled)
849 {
850  using namespace crl::multisense::details;
851 
852  const auto camera_config = wait_for_data<wire::CamConfig>(m_message_assembler,
853  m_socket,
855  m_transmit_id++,
858 
859  const auto aux_config = has_aux_camera ? wait_for_data<wire::AuxCamConfig>(m_message_assembler,
860  m_socket,
862  m_transmit_id++,
864  m_config.receive_timeout): std::nullopt;
865 
866  const auto imu_config = has_imu ? wait_for_data<wire::ImuConfig>(m_message_assembler,
867  m_socket,
869  m_transmit_id++,
871  m_config.receive_timeout): std::nullopt;
872 
873 
874  const auto led_config = wait_for_data<wire::LedStatus>(m_message_assembler,
875  m_socket,
877  m_transmit_id++,
880 
881  const auto packet_delay = wait_for_data<wire::SysPacketDelay>(m_message_assembler,
882  m_socket,
884  m_transmit_id++,
887 
888  if (camera_config)
889  {
890  return convert(camera_config.value(),
891  aux_config,
892  imu_config,
893  led_config,
894  packet_delay ? packet_delay.value() : wire::SysPacketDelay{false},
895  ptp_enabled,
896  m_info.device,
897  m_info.imu);
898  }
899 
900  CRL_DEBUG("Unable to query the camera's configuration\n");
901 
902  return std::nullopt;
903 }
904 
905 std::optional<StereoCalibration> LegacyChannel::query_calibration()
906 {
907  using namespace crl::multisense::details;
908 
909  if (const auto new_cal = wait_for_data<wire::SysCameraCalibration>(m_message_assembler,
910  m_socket,
912  m_transmit_id++,
914  m_config.receive_timeout); new_cal)
915  {
916  return std::make_optional(convert(new_cal.value()));
917  }
918 
919  return std::nullopt;
920 }
921 
922 std::optional<MultiSenseInfo> LegacyChannel::query_info()
923 {
924  using namespace crl::multisense::details;
925 
926  const auto device_info = query_device_info();
927 
928  if (!device_info)
929  {
930  CRL_DEBUG("Unable to query the device info\n");
931  return std::nullopt;
932  }
933 
934  const auto version = wait_for_data<wire::VersionResponse>(m_message_assembler,
935  m_socket,
937  m_transmit_id++,
940  if (!version)
941  {
942  CRL_DEBUG("Unable to query the version info\n");
943  return std::nullopt;
944  }
945 
946  const auto device_modes = wait_for_data<wire::SysDeviceModes>(m_message_assembler,
947  m_socket,
949  m_transmit_id++,
952 
953  if (!device_modes)
954  {
955  CRL_DEBUG("Unable to query the device modes\n");
956  return std::nullopt;
957  }
958 
959  const auto imu_info = wait_for_data<wire::ImuInfo>(m_message_assembler,
960  m_socket,
962  m_transmit_id++,
965 
966  if (imu_info)
967  {
968  m_max_batched_imu_messages = imu_info->maxSamplesPerMessage;
969  m_imu_scalars = get_imu_scalars(imu_info.value());
970  }
971 
972  const auto network_info = wait_for_data<wire::SysNetwork>(m_message_assembler,
973  m_socket,
975  m_transmit_id++,
978 
979  if (!network_info)
980  {
981  CRL_DEBUG("Unable to query the network info\n");
982  return std::nullopt;
983  }
984 
985  return MultiSenseInfo{device_info.value(),
986  convert(version.value()),
987  convert(device_modes.value()),
988  imu_info ? std::make_optional(convert(imu_info.value())) : std::nullopt,
989  convert(network_info.value())};
990 }
991 
992 std::optional<MultiSenseInfo::DeviceInfo> LegacyChannel::query_device_info()
993 {
994  using namespace crl::multisense::details;
995 
996  if (const auto device_info = wait_for_data<wire::SysDeviceInfo>(m_message_assembler,
997  m_socket,
999  m_transmit_id++,
1000  m_current_mtu,
1001  m_config.receive_timeout); device_info)
1002  {
1003  return std::make_optional(convert(device_info.value()));
1004  }
1005 
1006  return std::nullopt;
1007 }
1008 
1009 void LegacyChannel::image_meta_callback(std::shared_ptr<const std::vector<uint8_t>> data)
1010 {
1011  using namespace crl::multisense::details;
1012 
1013  const auto wire_meta = deserialize<wire::ImageMeta>(*data);
1014 
1015  m_meta_cache[wire_meta.frameId] = wire_meta;
1016 }
1017 
1018 void LegacyChannel::image_callback(std::shared_ptr<const std::vector<uint8_t>> data)
1019 {
1020  using namespace crl::multisense::details;
1021  using namespace std::chrono;
1022 
1023  const auto wire_image = deserialize<wire::Image>(*data);
1024 
1025  const auto meta = m_meta_cache.find(wire_image.frameId);
1026  if (meta == std::end(m_meta_cache))
1027  {
1028  CRL_DEBUG("Missing corresponding meta for frame_id %" PRIu64 "\n", wire_image.frameId);
1029  return;
1030  }
1031 
1032  const nanoseconds capture_time{seconds{meta->second.timeSeconds} +
1033  microseconds{meta->second.timeMicroSeconds}};
1034 
1035  const TimeT capture_time_point{capture_time};
1036 
1037  const TimeT ptp_capture_time_point{nanoseconds{meta->second.ptpNanoSeconds}};
1038 
1040  switch (wire_image.bitsPerPixel)
1041  {
1042  case 8: {pixel_format = Image::PixelFormat::MONO8; break;}
1043  case 16: {pixel_format = Image::PixelFormat::MONO16; break;}
1044  default: {CRL_DEBUG("Unknown pixel format %" PRIu32 "\n", wire_image.bitsPerPixel);}
1045  }
1046 
1047  const auto source = convert_sources(static_cast<uint64_t>(wire_image.sourceExtended) << 32 | wire_image.source);
1048  if (source.size() != 1)
1049  {
1050  CRL_DEBUG("invalid image source\n");
1051  return;
1052  }
1053 
1054  //
1055  // Copy our calibration and device info locally to make this thread safe
1056  //
1057  StereoCalibration cal;
1059  {
1060  std::lock_guard<std::mutex> lock(m_mutex);
1061  cal = m_calibration;
1062  info = m_info.device;
1063  }
1064 
1065  const auto cal_x_scale = static_cast<double>(wire_image.width) / static_cast<double>(info.imager_width);
1066  const auto cal_y_scale = static_cast<double>(wire_image.height) / static_cast<double>(info.imager_height);
1067 
1068  Image image{data,
1069  static_cast<const uint8_t*>(wire_image.dataP) - data->data(),
1070  ((wire_image.bitsPerPixel / 8) * wire_image.width * wire_image.height),
1071  pixel_format,
1072  wire_image.width,
1073  wire_image.height,
1074  capture_time_point,
1075  ptp_capture_time_point,
1076  source.front(),
1077  scale_calibration(select_calibration(cal, source.front()), cal_x_scale, cal_y_scale)};
1078 
1079  handle_and_dispatch(std::move(image),
1080  wire_image.frameId,
1081  scale_calibration(cal, cal_x_scale, cal_y_scale),
1082  capture_time_point,
1083  ptp_capture_time_point);
1084 }
1085 
1086 void LegacyChannel::disparity_callback(std::shared_ptr<const std::vector<uint8_t>> data)
1087 {
1088  using namespace crl::multisense::details;
1089  using namespace std::chrono;
1090 
1091  const auto wire_image = deserialize<wire::Disparity>(*data);
1092 
1093  const auto meta = m_meta_cache.find(wire_image.frameId);
1094  if (meta == std::end(m_meta_cache))
1095  {
1096  CRL_DEBUG("Missing corresponding meta for frame_id %" PRIu64 "\n", wire_image.frameId);
1097  return;
1098  }
1099 
1100  const nanoseconds capture_time{seconds{meta->second.timeSeconds} +
1101  microseconds{meta->second.timeMicroSeconds}};
1102 
1103  const TimeT capture_time_point{capture_time};
1104 
1105  const TimeT ptp_capture_time_point{nanoseconds{meta->second.ptpNanoSeconds}};
1106 
1108  switch (wire::Disparity::API_BITS_PER_PIXEL)
1109  {
1110  case 8: {pixel_format = Image::PixelFormat::MONO8; break;}
1111  case 16: {pixel_format = Image::PixelFormat::MONO16; break;}
1112  default: {CRL_DEBUG("Unknown pixel format %" PRIu8 "\n", wire::Disparity::API_BITS_PER_PIXEL);}
1113  }
1114 
1115  const auto source = DataSource::LEFT_DISPARITY_RAW;
1116 
1117  const auto disparity_length =
1118  static_cast<size_t>(((static_cast<double>(wire::Disparity::API_BITS_PER_PIXEL) / 8.0) *
1119  wire_image.width *
1120  wire_image.height));
1121 
1122  //
1123  // Copy our calibration and device info locally to make this thread safe
1124  //
1125  StereoCalibration cal;
1127  {
1128  std::lock_guard<std::mutex> lock(m_mutex);
1129  cal = m_calibration;
1130  info = m_info.device;
1131  }
1132 
1133  const auto cal_x_scale = static_cast<double>(wire_image.width) / static_cast<double>(info.imager_width);
1134  const auto cal_y_scale = static_cast<double>(wire_image.height) / static_cast<double>(info.imager_height);
1135 
1136  Image image{data,
1137  static_cast<const uint8_t*>(wire_image.dataP) - data->data(),
1138  disparity_length,
1139  pixel_format,
1140  wire_image.width,
1141  wire_image.height,
1142  capture_time_point,
1143  ptp_capture_time_point,
1144  source,
1145  scale_calibration(select_calibration(cal, source), cal_x_scale, cal_y_scale)};
1146 
1147  handle_and_dispatch(std::move(image),
1148  wire_image.frameId,
1149  scale_calibration(cal, cal_x_scale, cal_y_scale),
1150  capture_time_point,
1151  ptp_capture_time_point);
1152 
1153 }
1154 
1155 void LegacyChannel::imu_callback(std::shared_ptr<const std::vector<uint8_t>> data)
1156 {
1157  using namespace crl::multisense::details;
1158 
1160  {
1161  CRL_EXCEPTION("Invalid IMU config\n");
1162  return;
1163  }
1164 
1165  const auto wire_imu = deserialize<wire::ImuData>(*data);
1166 
1167  for (const auto &wire_sample : wire_imu.samples)
1168  {
1169  const TimeT camera_time{std::chrono::nanoseconds{wire_sample.timeNanoSeconds}};
1170  const TimeT ptp_time{std::chrono::nanoseconds{wire_sample.ptpNanoSeconds}};
1171 
1172  if (!m_current_imu_frame.samples.empty() && m_current_imu_frame.samples.back().sample_time == camera_time &&
1173  m_current_imu_frame.samples.back().ptp_sample_time == ptp_time)
1174  {
1175  const size_t i = m_current_imu_frame.samples.size() - 1;
1177  wire_sample,
1178  m_imu_scalars);
1179  }
1180  else
1181  {
1185  if (m_current_imu_frame.samples.size() >= m_multisense_config.imu_config->samples_per_frame)
1186  {
1187  m_imu_frame_notifier.set_and_notify(m_current_imu_frame);
1188 
1189  std::lock_guard<std::mutex> lock(m_imu_callback_mutex);
1191  {
1193  }
1194 
1195  m_current_imu_frame.samples.clear();
1196  }
1197 
1198  ImuSample sample{std::nullopt, std::nullopt, std::nullopt, camera_time, ptp_time};
1199  sample = add_wire_sample(std::move(sample), wire_sample, m_imu_scalars);
1200  m_current_imu_frame.samples.push_back(std::move(sample));
1201  }
1202  }
1203 }
1204 
1206  int64_t frame_id,
1207  const StereoCalibration &calibration,
1208  const TimeT &capture_time,
1209  const TimeT &ptp_capture_time)
1210 {
1211  //
1212  // Create a new frame if one does not exist, or add the input image to the corresponding frame
1213  //
1214  if (m_frame_buffer.count(frame_id) == 0)
1215  {
1216  const auto source = image.source;
1217  ImageFrame frame{frame_id,
1218  std::map<DataSource, Image>{std::make_pair(source, std::move(image))},
1219  calibration,
1220  capture_time,
1221  ptp_capture_time,
1223 
1224  m_frame_buffer.emplace(frame_id, std::move(frame));
1225  }
1226  else
1227  {
1228  m_frame_buffer[frame_id].add_image(std::move(image));
1229  }
1230 
1231  //
1232  // Check if our frame is valid, if so dispatch to our callbacks and notify anyone who is waiting on
1233  // the next frame
1234  //
1235  if (const auto &frame = m_frame_buffer[frame_id];
1236  std::all_of(std::begin(m_active_streams),
1237  std::end(m_active_streams),
1238  [&frame](const auto &e){return is_image_source(e) ? frame.has_image(e) : true;}))
1239  {
1240  //
1241  // Notify anyone waiting on the next frame
1242  //
1243  m_image_frame_notifier.set_and_notify(frame);
1244 
1245  //
1246  // Service the callback if it's valid
1247  //
1248  {
1249  std::lock_guard<std::mutex> lock(m_image_callback_mutex);
1251  {
1253  }
1254  }
1255 
1256 
1257  //
1258  // Remove our image frame from our frame buffer and the associated image metadata since we are
1259  // now done with it internally
1260  //
1261  m_frame_buffer.erase(frame_id);
1262  m_meta_cache.erase(frame_id);
1263  }
1264 
1265  //
1266  // Since frames will only monotonically increase, it's safe to also delete all the frame_ids earlier than
1267  // the current frame id.
1268  //
1269  m_frame_buffer.erase(std::begin(m_frame_buffer), m_frame_buffer.lower_bound(frame_id));
1270  m_meta_cache.erase(std::begin(m_meta_cache), m_meta_cache.lower_bound(frame_id));
1271 }
1272 
1273 }
1274 }
multisense::legacy::LegacyChannel::m_current_imu_frame
ImuFrame m_current_imu_frame
A cache of IMU samples which will be internally filled until it reaches the sample threshold for disp...
Definition: LibMultiSense/include/details/legacy/channel.hh:398
crl::multisense::details::wire::VersionRequest
Definition: VersionRequestMessage.hh:50
multisense::MultiSenseInfo::DeviceInfo::has_aux_camera
constexpr bool has_aux_camera() const
Determine if the MultiSense has a Aux color camera.
Definition: LibMultiSense/include/MultiSense/MultiSenseTypes.hh:1473
StatusResponseMessage.hh
multisense::legacy::LegacyChannel::m_connected
std::atomic_bool m_connected
Atomic flag to determine if we are connected to an active camera.
Definition: LibMultiSense/include/details/legacy/channel.hh:312
SysMtuMessage.hh
multisense::Status::INCOMPLETE_APPLICATION
@ INCOMPLETE_APPLICATION
CamControlMessage.hh
multisense::legacy::LegacyChannel::query_configuration
std::optional< MultiSenseConfig > query_configuration(bool has_aux_camera, bool has_imu, bool ptp_enabled)
Query the full configuration.
Definition: LibMultiSense/details/legacy/channel.cc:846
multisense::MultiSenseInfo::NetworkInfo
The network configuration for the MultiSense.
Definition: LibMultiSense/include/MultiSense/MultiSenseTypes.hh:1267
VersionResponseMessage.hh
AuxCamConfigMessage.hh
multisense::MultiSenseConfig
Complete configuration object for configuring the MultiSense. Can be updated during camera operation.
Definition: LibMultiSense/include/MultiSense/MultiSenseTypes.hh:478
crl::multisense::Status_Ok
static CRL_CONSTEXPR Status Status_Ok
Definition: Legacy/include/MultiSense/MultiSenseTypes.hh:99
crl::multisense::details
Definition: Legacy/details/channel.cc:63
multisense::StereoCalibration
Definition: LibMultiSense/include/MultiSense/MultiSenseTypes.hh:166
multisense::Status::UNINITIALIZED
@ UNINITIALIZED
StreamControlMessage.hh
multisense::legacy::LegacyChannel::m_image_callback_mutex
std::mutex m_image_callback_mutex
Internal mutex used to handle user callbacks for image data.
Definition: LibMultiSense/include/details/legacy/channel.hh:302
multisense::legacy::LegacyChannel::disparity_callback
void disparity_callback(std::shared_ptr< const std::vector< uint8_t >> data)
Disparity callback used to internally receive images sent from the MultiSense.
Definition: LibMultiSense/details/legacy/channel.cc:1086
multisense::legacy::scale_calibration
CameraCalibration scale_calibration(const CameraCalibration &input, double x_scale, double y_scale)
Scale a calibration used to update a full-res calibration based on the current operating resolution.
Definition: calibration.cc:183
multisense::StereoCalibration::aux
std::optional< CameraCalibration > aux
Calibration information for the aux camera (optional 3rd center camera)
Definition: LibMultiSense/include/MultiSense/MultiSenseTypes.hh:181
CRL_DEBUG
#define CRL_DEBUG(fmt,...)
Definition: Exception.hh:71
multisense::legacy::NetworkSocket::sensor_address
std::unique_ptr< sockaddr_in > sensor_address
Definition: udp.hh:53
multisense::legacy::LegacyChannel::m_imu_frame_notifier
FrameNotifier< ImuFrame > m_imu_frame_notifier
Notifier used to service the get_next_imu_frame member function.
Definition: LibMultiSense/include/details/legacy/channel.hh:372
multisense::MultiSenseInfo::DeviceInfo::imager_width
uint32_t imager_width
The native width of the primary imager.
Definition: LibMultiSense/include/MultiSense/MultiSenseTypes.hh:1426
Exception.hh
multisense::Status
Status
Definition: LibMultiSense/include/MultiSense/MultiSenseTypes.hh:67
multisense::legacy::LegacyChannel::get_calibration
StereoCalibration get_calibration() final override
Get the current stereo calibration. The output calibration will correspond to the full-resolution ope...
Definition: LibMultiSense/details/legacy/channel.cc:587
SysNetworkMessage.hh
multisense::MultiSenseInfo::DeviceInfo::imager_height
uint32_t imager_height
The native height of the primary imager.
Definition: LibMultiSense/include/MultiSense/MultiSenseTypes.hh:1431
multisense::legacy::LegacyChannel::m_imu_scalars
ImuSampleScalars m_imu_scalars
Scalars to convert imu samples from wire units to standard LibMultiSense units.
Definition: LibMultiSense/include/details/legacy/channel.hh:392
multisense::Channel::ReceiveBufferConfig::large_buffer_size
size_t large_buffer_size
The size of each small buffer in bytes.
Definition: LibMultiSense/include/MultiSense/MultiSenseChannel.hh:82
multisense::legacy::LegacyChannel::m_max_batched_imu_messages
std::atomic_uint32_t m_max_batched_imu_messages
The max number of IMU messages which can be batched over the wire.
Definition: LibMultiSense/include/details/legacy/channel.hh:387
multisense::ImageFrame
A frame containing multiple images (indexed by DataSource).
Definition: LibMultiSense/include/MultiSense/MultiSenseTypes.hh:300
multisense::legacy::LegacyChannel::m_config
Config m_config
Channel config.
Definition: LibMultiSense/include/details/legacy/channel.hh:322
MultiSenseUtilities.hh
ImuConfigMessage.hh
multisense::legacy::LegacyChannel::get_info
MultiSenseInfo get_info() final override
Get the device info associated with the camera.
Definition: LibMultiSense/details/legacy/channel.cc:635
multisense::legacy::LegacyChannel::m_udp_receiver
std::unique_ptr< UdpReceiver > m_udp_receiver
Helper object to receive UDP traffic. Internally manages a receive thread.
Definition: LibMultiSense/include/details/legacy/channel.hh:408
multisense::legacy::get_broadcast_sockaddr
std::unique_ptr< sockaddr_in > get_broadcast_sockaddr(uint16_t command_port)
Create a socketaddr_in object to boradcast to a given port.
Definition: ip.cc:70
multisense::legacy::LegacyChannel::set_mtu
Status set_mtu(uint16_t mtu)
Try and set the MTU.
Definition: LibMultiSense/details/legacy/channel.cc:786
multisense::Image::PixelFormat::UNKNOWN
@ UNKNOWN
multisense::Channel::Config::mtu
std::optional< int16_t > mtu
The MTU to use for sending and receiving data from the camera. Setting the MTU to nullopt will trigge...
Definition: LibMultiSense/include/MultiSense/MultiSenseChannel.hh:97
multisense::Image::PixelFormat::MONO8
@ MONO8
crl::multisense::details::wire::SysCameraCalibration
Definition: SysCameraCalibrationMessage.hh:70
multisense::legacy::LegacyChannel::image_callback
void image_callback(std::shared_ptr< const std::vector< uint8_t >> data)
Image callback used to internally receive images sent from the MultiSense.
Definition: LibMultiSense/details/legacy/channel.cc:1018
ImageMetaMessage.hh
BufferStream.hh
multisense::legacy::MessageAssembler::process_packet
bool process_packet(const std::vector< uint8_t > &raw_data)
Definition: message.cc:175
multisense::Channel::Config::interface
std::optional< std::string > interface
An optional name of network interface to bind to. (i.e. eth0)
Definition: LibMultiSense/include/MultiSense/MultiSenseChannel.hh:114
message.hh
channel.hh
utilities.hh
ImuGetConfigMessage.hh
multisense::legacy::NetworkSocket::sensor_socket
socket_t sensor_socket
Definition: udp.hh:54
multisense::TimeT
std::chrono::time_point< std::chrono::system_clock, std::chrono::nanoseconds > TimeT
Definition: LibMultiSense/include/MultiSense/MultiSenseTypes.hh:65
multisense::legacy::LegacyChannel::start_streams
Status start_streams(const std::vector< DataSource > &sources) final override
Start a collection of image streams. Repeated calls to this function will not implicitly stop the pre...
Definition: LibMultiSense/details/legacy/channel.cc:140
DisparityMessage.hh
ImageMessage.hh
LedStatusMessage.hh
multisense::legacy::LegacyChannel::add_image_frame_callback
void add_image_frame_callback(std::function< void(const ImageFrame &)> callback) final override
Add a image frame callback to get serviced inline with the receipt of a new frame....
Definition: LibMultiSense/details/legacy/channel.cc:217
CamConfigMessage.hh
configuration.hh
multisense::legacy::LegacyChannel::set_network_config
Status set_network_config(const MultiSenseInfo::NetworkInfo &config, const std::optional< std::string > &broadcast_interface) final override
Update the network configuration of the MultiSense. This will require a hardware reboot of the MultiS...
Definition: LibMultiSense/details/legacy/channel.cc:741
crl::multisense::details::wire::SysGetDeviceInfo
Definition: SysGetDeviceInfoMessage.hh:49
multisense::ImuFrame::samples
std::vector< ImuSample > samples
A batched collection of IMU samples.
Definition: LibMultiSense/include/MultiSense/MultiSenseTypes.hh:423
multisense::legacy::get_imu_scalars
ImuSampleScalars get_imu_scalars(const crl::multisense::details::wire::ImuInfo &info)
Get IMU scalars from the cameras's reported IMU info.
Definition: legacy/utilities.cc:316
multisense::legacy::LegacyChannel::query_device_info
std::optional< MultiSenseInfo::DeviceInfo > query_device_info()
Query the device_info from the camera.
Definition: LibMultiSense/details/legacy/channel.cc:992
multisense::legacy::LegacyChannel::get_system_status
std::optional< MultiSenseStatus > get_system_status() final override
Query the current MultiSense status.
Definition: LibMultiSense/details/legacy/channel.cc:678
multisense::MultiSenseConfig::time_config
std::optional< TimeConfig > time_config
Config for the MultiSense time-sync options.
Definition: LibMultiSense/include/MultiSense/MultiSenseTypes.hh:1041
multisense::legacy::LegacyChannel::stop_streams
Status stop_streams(const std::vector< DataSource > &sources) final override
Stop a collection of streams.
Definition: LibMultiSense/details/legacy/channel.cc:179
multisense::legacy::LegacyChannel::disconnect
void disconnect() final override
Disconnect from the camera.
Definition: LibMultiSense/details/legacy/channel.cc:339
PtpStatusRequestMessage.hh
multisense::Channel::Config
Definition: LibMultiSense/include/MultiSense/MultiSenseChannel.hh:85
multisense::Image::PixelFormat
PixelFormat
Pixel formats.
Definition: LibMultiSense/include/MultiSense/MultiSenseTypes.hh:192
crl::multisense::details::wire::StreamControl::enable
void enable(SourceType mask)
Definition: StreamControlMessage.hh:62
multisense::Channel::Config::command_port
uint16_t command_port
The UDP port on the MultiSense which accepts user commands. All production firmware builds use port 9...
Definition: LibMultiSense/include/MultiSense/MultiSenseChannel.hh:109
multisense::legacy::add_wire_sample
ImuSample add_wire_sample(ImuSample sample, const crl::multisense::details::wire::ImuSample &wire, const ImuSampleScalars &scalars)
Add a wire sample to a ImuSample.
Definition: legacy/utilities.cc:188
multisense::MultiSenseInfo::NetworkInfo::gateway
std::string gateway
The gateway of the camera (i.e. X.X.X.X)
Definition: LibMultiSense/include/MultiSense/MultiSenseTypes.hh:1277
crl::multisense::details::wire::SysGetNetwork
Definition: SysGetNetworkMessage.hh:47
multisense::ImuFrame
A collection of IMU samples from the camera.
Definition: LibMultiSense/include/MultiSense/MultiSenseTypes.hh:418
multisense::legacy::MessageAssembler::remove_callback
void remove_callback(const crl::multisense::details::wire::IdType &message_id)
Remove a callback for a specific message type.
Definition: message.cc:329
crl::multisense::details::wire::AuxCamGetConfig
Definition: AuxCamGetConfigMessage.hh:49
multisense::MultiSenseStatus::ClientNetworkStatus
Definition: LibMultiSense/include/MultiSense/MultiSenseTypes.hh:1167
multisense::legacy::LegacyChannel::get_next_image_frame
std::optional< ImageFrame > get_next_image_frame() final override
A blocking call that waits for one image frame from the camera.
Definition: LibMultiSense/details/legacy/channel.cc:366
multisense::Image::source
DataSource source
The camera data source which this image corresponds to.
Definition: LibMultiSense/include/MultiSense/MultiSenseTypes.hh:248
crl::multisense::details::wire::SysGetCameraCalibration
Definition: SysGetCameraCalibrationMessage.hh:49
CRL_EXCEPTION
#define CRL_EXCEPTION(fmt,...)
Definition: Exception.hh:85
crl::multisense::details::wire::ImuGetConfig
Definition: ImuGetConfigMessage.hh:47
multisense::legacy::LegacyChannel::m_meta_cache
std::map< int64_t, crl::multisense::details::wire::ImageMeta > m_meta_cache
A cache of image metadata associated with a specific frame id.
Definition: LibMultiSense/include/details/legacy/channel.hh:377
info.hh
SysGetCameraCalibrationMessage.hh
multisense::legacy::bind
std::tuple< socket_t, uint16_t > bind(const std::optional< std::string > &interface_name, bool broadcast)
Create a UDP socket to communicate with the MultiSense. Optionally bind to a specific interface.
Definition: ip.cc:80
multisense::legacy::serialize
std::vector< uint8_t > serialize(const T &message, uint16_t sequence_id, size_t mtu)
Serialize a MultiSense Wire message for transmission. This adds the wire header to the message for tr...
Definition: message.hh:103
multisense::legacy::MessageAssembler::register_callback
void register_callback(const crl::multisense::details::wire::IdType &message_id, std::function< void(std::shared_ptr< const std::vector< uint8_t >>)> callback)
Register a callback to receive valid messages of a given id. Note currently only one callback can be ...
Definition: message.cc:322
multisense::DataSource::ALL
@ ALL
crl::multisense::details::wire::PtpStatusRequest
Definition: PtpStatusRequestMessage.hh:49
multisense::legacy::LegacyChannel::m_user_imu_frame_callback
std::function< void(const ImuFrame &)> m_user_imu_frame_callback
The currently active imu frame user callback.
Definition: LibMultiSense/include/details/legacy/channel.hh:362
multisense::legacy::LegacyChannel::m_current_mtu
std::atomic_uint16_t m_current_mtu
The current MTU the camera is operating with.
Definition: LibMultiSense/include/details/legacy/channel.hh:317
crl::multisense::details::wire::SysDeviceInfo
Definition: SysDeviceInfoMessage.hh:69
calibration.hh
multisense::legacy::LegacyChannel::imu_callback
void imu_callback(std::shared_ptr< const std::vector< uint8_t >> data)
Disparity callback used to internally receive images sent from the MultiSense.
Definition: LibMultiSense/details/legacy/channel.cc:1155
multisense::MultiSenseConfig::lighting_config
std::optional< LightingConfig > lighting_config
The lighting configuration for the camera. If invalid, the camera does not support lighting configura...
Definition: LibMultiSense/include/MultiSense/MultiSenseTypes.hh:1057
multisense::legacy::LegacyChannel::m_info
MultiSenseInfo m_info
The current cached device info stored here for convenience.
Definition: LibMultiSense/include/details/legacy/channel.hh:342
crl::multisense::details::wire::SysPacketDelay
Definition: SysPacketDelayMessage.hh:49
crl::multisense::details::wire::SysMtu
Definition: SysMtuMessage.hh:48
multisense::ImuSample
A single IMU sample from the camera.
Definition: LibMultiSense/include/MultiSense/MultiSenseTypes.hh:365
multisense::legacy::LegacyChannel::m_active_streams
std::set< DataSource > m_active_streams
The current set of active data streams the MultiSense is transmitting.
Definition: LibMultiSense/include/details/legacy/channel.hh:352
multisense::legacy::publish_data
int64_t publish_data(const NetworkSocket &socket, const std::vector< uint8_t > &data)
Convenience function used to user specified data out on the host's UDP socket.
Definition: udp.cc:137
multisense::legacy::get_status
Status get_status(const crl::multisense::details::wire::Ack::AckStatus &status)
Definition: legacy/utilities.cc:72
multisense::legacy::LegacyChannel::query_info
std::optional< MultiSenseInfo > query_info()
Query the MultiSense Info.
Definition: LibMultiSense/details/legacy/channel.cc:922
multisense::legacy::NetworkSocket
Convenience network socket object which contains the data corresponding to our connection.
Definition: udp.hh:51
multisense::Image::PixelFormat::MONO16
@ MONO16
multisense::legacy::LegacyChannel::m_frame_buffer
std::map< int64_t, ImageFrame > m_frame_buffer
A cache of image frames associated with a specific frame id.
Definition: LibMultiSense/include/details/legacy/channel.hh:382
AuxCamControlMessage.hh
multisense::legacy::convert_sources
std::vector< DataSource > convert_sources(const crl::multisense::details::wire::SourceType &source)
Convert wire sources to a vector of DataSources.
Definition: legacy/utilities.cc:108
multisense::MultiSenseInfo::NetworkInfo::netmask
std::string netmask
The netmask of the camera (i.e. X.X.X.X)
Definition: LibMultiSense/include/MultiSense/MultiSenseTypes.hh:1282
multisense::legacy::LegacyChannel::m_message_assembler
MessageAssembler m_message_assembler
Helper object to assemble raw UDP packets into complete MultiSense wire messages.
Definition: LibMultiSense/include/details/legacy/channel.hh:413
SysGetPacketDelayMessage.hh
multisense::legacy::LegacyChannel::m_calibration
StereoCalibration m_calibration
The current cached calibration stored here for convenience.
Definition: LibMultiSense/include/details/legacy/channel.hh:337
multisense::legacy::wait_for_ack
std::optional< crl::multisense::details::wire::Ack > wait_for_ack(MessageAssembler &assembler, const NetworkSocket &socket, const QueryMessage &query, uint16_t sequence_id, uint16_t mtu, const std::optional< std::chrono::duration< Rep, Period >> &wait_time, size_t attempts=1)
Helper to wait for ack from the camera from a given query command. Once a query command is sent to th...
Definition: utilities.hh:176
multisense::MultiSenseInfo::imu
std::optional< ImuInfo > imu
Supported operating modes for the IMU sensors (accelerometer, gyroscope, magnetometer)....
Definition: LibMultiSense/include/MultiSense/MultiSenseTypes.hh:1656
multisense::MultiSenseInfo::DeviceInfo
The Device information associated with the MultiSense. The DeviceInfo is used to determine what featu...
Definition: LibMultiSense/include/MultiSense/MultiSenseTypes.hh:1290
multisense::legacy::LegacyChannel::~LegacyChannel
virtual ~LegacyChannel()
Definition: LibMultiSense/details/legacy/channel.cc:134
multisense::Status::EXCEPTION
@ EXCEPTION
multisense::Status::UNSUPPORTED
@ UNSUPPORTED
Protocol.hh
multisense::legacy::convert
CameraCalibration convert(const crl::multisense::details::wire::CameraCalData &cal)
Convert a wire calibration to our API calibration object.
Definition: calibration.cc:56
multisense::legacy::system_ok
bool system_ok(const crl::multisense::details::wire::StatusResponse &status)
Summarize the status info and determine fit the MultiSense system is operating properly.
Definition: status.cc:42
multisense::legacy::LegacyChannel::m_mutex
std::mutex m_mutex
Internal mutex used to handle updates from users.
Definition: LibMultiSense/include/details/legacy/channel.hh:297
multisense::Status::OK
@ OK
multisense::legacy::BufferPool
Object to handle the management and delivery of buffers to used to store incoming data without needin...
Definition: LibMultiSense/include/details/legacy/storage.hh:58
multisense::legacy::LegacyChannel::set_calibration
Status set_calibration(const StereoCalibration &calibration) final override
Set the current stereo calibration. The calibration is expected to be or the full-resolution operatin...
Definition: LibMultiSense/details/legacy/channel.cc:599
multisense::Status::TIMEOUT
@ TIMEOUT
multisense::Channel::Config::ip_address
std::string ip_address
the IP address of the MultiSense camera to connect to
Definition: LibMultiSense/include/MultiSense/MultiSenseChannel.hh:90
multisense::legacy::BufferPoolConfig
Definition: LibMultiSense/include/details/legacy/storage.hh:46
multisense::legacy::select_calibration
CameraCalibration select_calibration(const StereoCalibration &input, const DataSource &source)
Get the correct calibration corresponding to the input source.
Definition: calibration.cc:145
multisense::legacy::LegacyChannel::handle_and_dispatch
void handle_and_dispatch(Image image, int64_t frame_id, const StereoCalibration &calibration, const TimeT &capture_time, const TimeT &ptp_capture_time)
Handle internal process, and potentially dispatch a image.
Definition: LibMultiSense/details/legacy/channel.cc:1205
multisense::legacy::LegacyChannel::get_config
MultiSenseConfig get_config() final override
Get the current MultiSense configuration.
Definition: LibMultiSense/details/legacy/channel.cc:386
multisense::legacy::NetworkSocket::server_socket_port
uint16_t server_socket_port
Definition: udp.hh:55
multisense::MultiSenseInfo::NetworkInfo::ip_address
std::string ip_address
The ip address of the camera (i.e. X.X.X.X)
Definition: LibMultiSense/include/MultiSense/MultiSenseTypes.hh:1272
multisense::legacy::LegacyChannel::m_multisense_config
MultiSenseConfig m_multisense_config
The current cached MultiSense configuration stored for convenience.
Definition: LibMultiSense/include/details/legacy/channel.hh:347
StatusRequestMessage.hh
ImuGetInfoMessage.hh
ImuInfoMessage.hh
SysDeviceModesMessage.hh
multisense::legacy::LegacyChannel::get_next_imu_frame
std::optional< ImuFrame > get_next_imu_frame() final override
A blocking call that waits for one imu frame from the camera.
Definition: LibMultiSense/details/legacy/channel.cc:376
crl::multisense::details::wire::ImuGetInfo
Definition: ImuGetInfoMessage.hh:47
PtpStatusResponseMessage.hh
multisense
Definition: factory.cc:39
VersionRequestMessage.hh
multisense::Status::FAILED
@ FAILED
multisense::Channel::ReceiveBufferConfig::num_small_buffers
size_t num_small_buffers
The number of small buffers to preallocate for receiving small MultiSense messages.
Definition: LibMultiSense/include/MultiSense/MultiSenseChannel.hh:70
multisense::Channel::Config::receive_buffer_configuration
ReceiveBufferConfig receive_buffer_configuration
Config for the number and size of internal buffers used to receive data without recurring memory allo...
Definition: LibMultiSense/include/MultiSense/MultiSenseChannel.hh:120
multisense::legacy::is_image_source
bool is_image_source(const DataSource &source)
Determine if a datasource is a image source.
Definition: legacy/utilities.cc:45
multisense::ColorImageEncoding::YCBCR420
@ YCBCR420
crl::multisense::details::wire::LedGetStatus
Definition: LedGetStatusMessage.hh:51
std
multisense::ColorImageEncoding::NONE
@ NONE
multisense::MultiSenseInfo
Static status info for the MultiSense. Will not change during camera operation.
Definition: LibMultiSense/include/MultiSense/MultiSenseTypes.hh:1262
multisense::legacy::LegacyChannel::m_user_image_frame_callback
std::function< void(const ImageFrame &)> m_user_image_frame_callback
The currently active image frame user callback.
Definition: LibMultiSense/include/details/legacy/channel.hh:357
crl::multisense::details::wire::CamGetConfig
Definition: CamGetConfigMessage.hh:50
multisense::legacy::LegacyChannel::connect
Status connect(const Config &config) final override
Initialize the connection to the camera.
Definition: LibMultiSense/details/legacy/channel.cc:231
LedGetStatusMessage.hh
CamGetConfigMessage.hh
SysTestMtuMessage.hh
SysGetDeviceInfoMessage.hh
multisense::legacy::LegacyChannel::set_config
Status set_config(const MultiSenseConfig &config) final override
Get set the current MultiSense configuration.
Definition: LibMultiSense/details/legacy/channel.cc:398
multisense::Image
Represents a single image plus metadata.
Definition: LibMultiSense/include/MultiSense/MultiSenseTypes.hh:187
status.hh
SysTestMtuResponseMessage.hh
crl::multisense::details::wire::StreamControl
Definition: StreamControlMessage.hh:47
multisense::legacy::LegacyChannel::query_calibration
std::optional< StereoCalibration > query_calibration()
Query the calibration from the camera.
Definition: LibMultiSense/details/legacy/channel.cc:905
crl::multisense::details::wire::SysGetPacketDelay
Definition: SysGetPacketDelayMessage.hh:49
SysGetTransmitDelayMessage.hh
multisense::legacy::LegacyChannel::m_socket
NetworkSocket m_socket
Active network socket for receiving and transmitting data.
Definition: LibMultiSense/include/details/legacy/channel.hh:327
multisense::MultiSenseInfo::device
DeviceInfo device
Device info.
Definition: LibMultiSense/include/MultiSense/MultiSenseTypes.hh:1640
CamSetResolutionMessage.hh
multisense::MultiSenseConfig::network_config
std::optional< NetworkTransmissionConfig > network_config
Config to control network transmission settings.
Definition: LibMultiSense/include/MultiSense/MultiSenseTypes.hh:1046
multisense::legacy::get_sockaddr
std::unique_ptr< sockaddr_in > get_sockaddr(const std::string &ip_address, uint16_t command_port)
Create a socketaddr_in object for a given IP address and port.
Definition: ip.cc:44
crl::multisense::details::wire::StreamControl::disable
void disable(SourceType mask)
Definition: StreamControlMessage.hh:65
SysGetNetworkMessage.hh
multisense::legacy::LegacyChannel::LegacyChannel
LegacyChannel(const Config &config)
Definition: LibMultiSense/details/legacy/channel.cc:120
multisense::legacy::expand_source
std::vector< DataSource > expand_source(const DataSource &source)
Expand sources since some sources may represent multiple sources on the wire.
Definition: legacy/utilities.cc:172
multisense::legacy::LegacyChannel::set_device_info
Status set_device_info(const MultiSenseInfo::DeviceInfo &device_info, const std::string &key) final override
Set the camera's device info. This setting is protected via a key since invalid values in the device ...
Definition: LibMultiSense/details/legacy/channel.cc:647
multisense::legacy::MessageAssembler::get_message_statistics
MessageStatistics get_message_statistics() const
Definition: message.hh:257
multisense::Channel::ReceiveBufferConfig::num_large_buffers
size_t num_large_buffers
The number of large buffers to preallocate for receiving MultiSense sensor data.
Definition: LibMultiSense/include/MultiSense/MultiSenseChannel.hh:78
crl::multisense::details::wire::SysTestMtu
Definition: SysTestMtuMessage.hh:47
SysGetDeviceModesMessage.hh
multisense::MultiSenseConfig::imu_config
std::optional< ImuConfig > imu_config
The imu configuration to use for the camera. Will be invalid if sensor does not contain an IMU.
Definition: LibMultiSense/include/MultiSense/MultiSenseTypes.hh:1051
ImuDataMessage.hh
crl::multisense::details::wire::SysGetDeviceModes
Definition: SysGetDeviceModesMessage.hh:47
multisense::legacy::LegacyChannel::m_transmit_id
std::atomic_uint16_t m_transmit_id
Monotonically increasing internal id used to uniquely identify requests sent to the camera.
Definition: LibMultiSense/include/details/legacy/channel.hh:332
multisense::Channel::Config::receive_timeout
std::optional< std::chrono::milliseconds > receive_timeout
Timeout to use when waiting for MultiSense command responses. Setting the timeout to nullopt will res...
Definition: LibMultiSense/include/MultiSense/MultiSenseChannel.hh:103
multisense::MultiSenseStatus::ClientNetworkStatus::received_messages
size_t received_messages
The total number of valid messages received from the client.
Definition: LibMultiSense/include/MultiSense/MultiSenseTypes.hh:1172
multisense::legacy::LegacyChannel::add_imu_frame_callback
void add_imu_frame_callback(std::function< void(const ImuFrame &)> callback) final override
Add a imu frame callback to get serviced inline with the receipt of a new frame. Only a single imu fr...
Definition: LibMultiSense/details/legacy/channel.cc:224
multisense::MultiSenseStatus::TimeStatus
Definition: LibMultiSense/include/MultiSense/MultiSenseTypes.hh:1185
multisense::Channel::ReceiveBufferConfig::small_buffer_size
size_t small_buffer_size
The size of each small buffer in bytes.
Definition: LibMultiSense/include/MultiSense/MultiSenseChannel.hh:74
multisense::Image::width
int width
Width of the image in pixels.
Definition: LibMultiSense/include/MultiSense/MultiSenseTypes.hh:226
SysDeviceInfoMessage.hh
crl::multisense::details::wire::StatusRequest
Definition: StatusRequestMessage.hh:50
AuxCamGetConfigMessage.hh
multisense::to_string
std::string to_string(const Status &status)
Convert a status object to a user readable string.
Definition: utilities.cc:137
LedSetMessage.hh
multisense::legacy::LegacyChannel::image_meta_callback
void image_meta_callback(std::shared_ptr< const std::vector< uint8_t >> data)
Image meta callback used to internally receive images sent from the MultiSense.
Definition: LibMultiSense/details/legacy/channel.cc:1009
multisense::Status::INTERNAL_ERROR
@ INTERNAL_ERROR
multisense::legacy::LegacyChannel::m_imu_callback_mutex
std::mutex m_imu_callback_mutex
Internal mutex used to handle user callbacks imu data.
Definition: LibMultiSense/include/details/legacy/channel.hh:307
multisense::legacy::LegacyChannel::m_image_frame_notifier
FrameNotifier< ImageFrame > m_image_frame_notifier
Notifier used to service the get_next_image_frame member function.
Definition: LibMultiSense/include/details/legacy/channel.hh:367
multisense::MultiSenseConfig::aux_config
std::optional< AuxConfig > aux_config
The image configuration to use for the aux camera if present.
Definition: LibMultiSense/include/MultiSense/MultiSenseTypes.hh:1036
multisense::DataSource::LEFT_DISPARITY_RAW
@ LEFT_DISPARITY_RAW
multisense::MultiSenseStatus
Consolidated status information which can be queried on demand from the MultiSense....
Definition: LibMultiSense/include/MultiSense/MultiSenseTypes.hh:1082


multisense_lib
Author(s):
autogenerated on Thu Apr 17 2025 02:49:08