ros_reader.cpp
Go to the documentation of this file.
1 // License: Apache 2.0. See LICENSE file in root directory.
2 // Copyright(c) 2019 Intel Corporation. All Rights Reserved.
3 
4 #include <cstring>
5 #include "ros_reader.h"
6 #include "ds5/ds5-device.h"
7 #include "ivcam/sr300.h"
8 #include "l500/l500-depth.h"
10 #include "proc/decimation-filter.h"
11 #include "proc/threshold.h"
12 #include "proc/spatial-filter.h"
13 #include "proc/temporal-filter.h"
15 #include "proc/zero-order.h"
16 #include "proc/depth-decompress.h"
17 #include "proc/hdr-merge.h"
20 
21 namespace librealsense
22 {
23  using namespace device_serializer;
24 
25  ros_reader::ros_reader(const std::string& file, const std::shared_ptr<context>& ctx) :
26  m_metadata_parser_map(md_constant_parser::create_metadata_parser_map()),
27  m_total_duration(0),
28  m_file_path(file),
29  m_context(ctx),
30  m_version(0)
31  {
32  try
33  {
34  reset(); //Note: calling a virtual function inside c'tor, safe while base function is pure virtual
36  }
37  catch (const std::exception& e)
38  {
39  //Rethrowing with better clearer message
40  throw io_exception(to_string() << "Failed to create ros reader: " << e.what());
41  }
42  }
43 
45  {
46  return read_device_description(time);
47  }
48 
49  std::shared_ptr<serialized_data> ros_reader::read_next_data()
50  {
51  if (m_samples_view == nullptr || m_samples_itrator == m_samples_view->end())
52  {
53  LOG_DEBUG("End of file reached");
54  return std::make_shared<serialized_end_of_file>();
55  }
56 
59 
60  if (next_msg.isType<sensor_msgs::Image>()
61  || next_msg.isType<sensor_msgs::Imu>()
62  || next_msg.isType<realsense_legacy_msgs::pose>()
63  || next_msg.isType<geometry_msgs::Transform>())
64  {
65  LOG_DEBUG("Next message is a frame");
66  return create_frame(next_msg);
67  }
68 
69  if (m_version >= 3)
70  {
71  if (next_msg.isType<std_msgs::Float32>())
72  {
73  LOG_DEBUG("Next message is an option");
74  auto timestamp = to_nanoseconds(next_msg.getTime());
75  auto sensor_id = ros_topic::get_sensor_identifier(next_msg.getTopic());
76  auto option = create_option(m_file, next_msg);
77  return std::make_shared<serialized_option>(timestamp, sensor_id, option.first, option.second);
78  }
79 
80  if (next_msg.isType<realsense_msgs::Notification>())
81  {
82  LOG_DEBUG("Next message is a notification");
83  auto timestamp = to_nanoseconds(next_msg.getTime());
84  auto sensor_id = ros_topic::get_sensor_identifier(next_msg.getTopic());
85  auto notification = create_notification(m_file, next_msg);
86  return std::make_shared<serialized_notification>(timestamp, sensor_id, notification);
87  }
88  }
89 
90  std::string err_msg = to_string() << "Unknown message type: " << next_msg.getDataType() << "(Topic: " << next_msg.getTopic() << ")";
91  LOG_ERROR(err_msg);
92  throw invalid_value_exception(err_msg);
93  }
94 
95  void ros_reader::seek_to_time(const nanoseconds& seek_time)
96  {
97  if (seek_time > m_total_duration)
98  {
99  throw invalid_value_exception(to_string() << "Requested time is out of playback length. (Requested = " << seek_time.count() << ", Duration = " << m_total_duration.count() << ")");
100  }
101  auto seek_time_as_secs = std::chrono::duration_cast<std::chrono::duration<double>>(seek_time);
102  auto seek_time_as_rostime = rs2rosinternal::Time(seek_time_as_secs.count());
103 
105 
106  //Using cached topics here and not querying them (before reseting) since a previous call to seek
107  // could have changed the view and some streams that should be streaming were dropped.
108  //E.g: Recording Depth+Color, stopping Depth, starting IR, stopping IR and Color. Play IR+Depth: will play only depth, then only IR, then we seek to a point only IR was streaming, and then to 0.
109  for (auto topic : m_enabled_streams_topics)
110  {
111  m_samples_view->addQuery(m_file, rosbag::TopicQuery(topic), seek_time_as_rostime);
112  }
114  }
115 
116  std::vector<std::shared_ptr<serialized_data>> ros_reader::fetch_last_frames(const nanoseconds& seek_time)
117  {
118  std::vector<std::shared_ptr<serialized_data>> result;
120  auto as_rostime = to_rostime(seek_time);
121  auto start_time = to_rostime(get_static_file_info_timestamp());
122 
123  for (auto topic : m_enabled_streams_topics)
124  {
125  view.addQuery(m_file, rosbag::TopicQuery(topic), start_time, as_rostime);
126  }
127  std::map<device_serializer::stream_identifier, rs2rosinternal::Time> last_frames;
128  for (auto&& m : view)
129  {
130  if (m.isType<sensor_msgs::Image>() || m.isType<sensor_msgs::Imu>())
131  {
132  auto id = ros_topic::get_stream_identifier(m.getTopic());
133  last_frames[id] = m.getTime();
134  }
135  }
136  for (auto&& kvp : last_frames)
137  {
138  auto topic = ros_topic::frame_data_topic(kvp.first);
139  rosbag::View view(m_file, rosbag::TopicQuery(topic), kvp.second, kvp.second);
140  auto msg = view.begin();
141  auto new_frame = create_frame(*msg);
142  result.push_back(new_frame);
143  }
144  return result;
145  }
147  {
148  return m_total_duration;
149  }
150 
152  {
153  m_file.close();
156  m_samples_view = nullptr;
157  m_frame_source = std::make_shared<frame_source>(m_version == 1 ? 128 : 32);
160  }
161 
162  void ros_reader::enable_stream(const std::vector<device_serializer::stream_identifier>& stream_ids)
163  {
164  rs2rosinternal::Time start_time = rs2rosinternal::TIME_MIN + rs2rosinternal::Duration{ 0, 1 }; //first non 0 timestamp and afterward
165  if (m_samples_view == nullptr) //Starting to stream
166  {
167  m_samples_view = std::unique_ptr<rosbag::View>(new rosbag::View(m_file, FalseQuery()));
168  m_samples_view->addQuery(m_file, OptionsQuery(), start_time);
169  m_samples_view->addQuery(m_file, NotificationsQuery(), start_time);
171  }
172  else //Already streaming
173  {
174  if (m_samples_itrator != m_samples_view->end())
175  {
177  start_time = sample_msg.getTime();
178  }
179  }
180  auto currently_streaming = get_topics(m_samples_view);
181  //empty the view
182  m_samples_view = std::unique_ptr<rosbag::View>(new rosbag::View(m_file, FalseQuery()));
183 
184  for (auto&& stream_id : stream_ids)
185  {
186  //add new stream to view
188  {
190  }
191  else
192  {
193  m_samples_view->addQuery(m_file, StreamQuery(stream_id), start_time);
194  }
195  }
196 
197  //add already existing streams
198  for (auto topic : currently_streaming)
199  {
200  m_samples_view->addQuery(m_file, rosbag::TopicQuery(topic), start_time);
201  }
204  }
205 
206  void ros_reader::disable_stream(const std::vector<device_serializer::stream_identifier>& stream_ids)
207  {
208  if (m_samples_view == nullptr)
209  {
210  return;
211  }
212  rs2rosinternal::Time curr_time;
213  if (m_samples_itrator == m_samples_view->end())
214  {
215  curr_time = m_samples_view->getEndTime();
216  }
217  else
218  {
220  curr_time = sample_msg.getTime();
221  }
222  auto currently_streaming = get_topics(m_samples_view);
223  m_samples_view = std::unique_ptr<rosbag::View>(new rosbag::View(m_file, FalseQuery()));
224  for (auto topic : currently_streaming)
225  {
226  //Find if this topic is one of the streams that should be disabled
227  auto it = std::find_if(stream_ids.begin(), stream_ids.end(), [&topic](const device_serializer::stream_identifier& s) {
228  //return topic.starts_with(s);
229  return topic.find(ros_topic::stream_full_prefix(s)) != std::string::npos;
230  });
231  bool should_topic_remain = (it == stream_ids.end());
232  if (should_topic_remain)
233  {
234  m_samples_view->addQuery(m_file, rosbag::TopicQuery(topic), curr_time);
235  }
236  }
239  }
240 
242  {
243  return m_file_path;
244  }
245 
246  std::shared_ptr<serialized_frame> ros_reader::create_frame(const rosbag::MessageInstance& msg)
247  {
248  auto next_msg_topic = msg.getTopic();
249  auto next_msg_time = msg.getTime();
250 
251  nanoseconds timestamp = to_nanoseconds(next_msg_time);
254  {
255  stream_id = legacy_file_format::get_stream_identifier(next_msg_topic);
256  }
257  else
258  {
259  stream_id = ros_topic::get_stream_identifier(next_msg_topic);
260  }
261  frame_holder frame{ nullptr };
262  if (msg.isType<sensor_msgs::Image>())
263  {
265  }
266  else if (msg.isType<sensor_msgs::Imu>())
267  {
269  }
271  {
272  frame = create_pose_sample(msg);
273  }
274  else
275  {
276  std::string err_msg = to_string() << "Unknown frame type: " << msg.getDataType() << "(Topic: " << next_msg_topic << ")";
277  LOG_ERROR(err_msg);
278  throw invalid_value_exception(err_msg);
279  }
280 
281  if (frame.frame == nullptr)
282  {
283  return std::make_shared<serialized_invalid_frame>(timestamp, stream_id);
284  }
285  return std::make_shared<serialized_frame>(timestamp, stream_id, std::move(frame));
286  }
287 
289  {
290  std::function<bool(rosbag::ConnectionInfo const* info)> query;
291  if (version == legacy_file_format::file_version())
293  else
294  query = FrameQuery();
295  rosbag::View all_frames_view(file, query);
296  auto streaming_duration = all_frames_view.getEndTime() - all_frames_view.getBeginTime();
297  return nanoseconds(streaming_duration.toNSec());
298  }
299 
302  const rosbag::MessageInstance &msg,
303  frame_additional_data& additional_data)
304  {
305  uint32_t total_md_size = 0;
306  rosbag::View frame_metadata_view(bag, legacy_file_format::FrameInfoExt(stream_id), msg.getTime(), msg.getTime());
307  assert(frame_metadata_view.size() <= 1);
308  for (auto message_instance : frame_metadata_view)
309  {
310  auto info = instantiate_msg<realsense_legacy_msgs::frame_info>(message_instance);
311  for (auto&& fmd : info->frame_metadata)
312  {
313  if (fmd.type == legacy_file_format::SYSTEM_TIMESTAMP)
314  {
315  additional_data.system_time = *reinterpret_cast<const int64_t*>(fmd.data.data());
316  }
317  else
318  {
320  if (!legacy_file_format::convert_metadata_type(fmd.type, type))
321  {
322  continue;
323  }
324  rs2_metadata_type value = *reinterpret_cast<const rs2_metadata_type*>(fmd.data.data());
325  auto size_of_enum = sizeof(rs2_frame_metadata_value);
326  auto size_of_data = sizeof(rs2_metadata_type);
327  if (total_md_size + size_of_enum + size_of_data > 255)
328  {
329  continue; //stop adding metadata to frame
330  }
331  memcpy(additional_data.metadata_blob.data() + total_md_size, &type, size_of_enum);
332  total_md_size += static_cast<uint32_t>(size_of_enum);
333  memcpy(additional_data.metadata_blob.data() + total_md_size, &value, size_of_data);
334  total_md_size += static_cast<uint32_t>(size_of_data);
335  }
336  }
337 
338  try
339  {
340  additional_data.timestamp_domain = legacy_file_format::convert(info->time_stamp_domain);
341  }
342  catch (const std::exception& e)
343  {
344  LOG_WARNING("Failed to get timestamp_domain. Error: " << e.what());
345  }
346  }
347  }
348 
349  std::map<std::string, std::string> ros_reader::get_frame_metadata(const rosbag::Bag& bag,
350  const std::string& topic,
352  const rosbag::MessageInstance &msg,
353  frame_additional_data& additional_data)
354  {
355  uint32_t total_md_size = 0;
356  std::map<std::string, std::string> remaining;
357  rosbag::View frame_metadata_view(bag, rosbag::TopicQuery(topic), msg.getTime(), msg.getTime());
358 
359  for (auto message_instance : frame_metadata_view)
360  {
361  auto key_val_msg = instantiate_msg<diagnostic_msgs::KeyValue>(message_instance);
362  if (key_val_msg->key == TIMESTAMP_DOMAIN_MD_STR)
363  {
364  if (!safe_convert(key_val_msg->value, additional_data.timestamp_domain))
365  {
366  remaining[key_val_msg->key] = key_val_msg->value;
367  }
368  }
369  else if (key_val_msg->key == SYSTEM_TIME_MD_STR)
370  {
371  if (!safe_convert(key_val_msg->value, additional_data.system_time))
372  {
373  remaining[key_val_msg->key] = key_val_msg->value;
374  }
375  }
376  else
377  {
379  if (!safe_convert(key_val_msg->key, type))
380  {
381  remaining[key_val_msg->key] = key_val_msg->value;
382  continue;
383  }
385  if (!safe_convert(key_val_msg->value, md))
386  {
387  remaining[key_val_msg->key] = key_val_msg->value;
388  continue;
389  }
390  auto size_of_enum = sizeof(rs2_frame_metadata_value);
391  auto size_of_data = sizeof(rs2_metadata_type);
392  if (total_md_size + size_of_enum + size_of_data > 255)
393  {
394  continue; //stop adding metadata to frame
395  }
396  memcpy(additional_data.metadata_blob.data() + total_md_size, &type, size_of_enum);
397  total_md_size += static_cast<uint32_t>(size_of_enum);
398  memcpy(additional_data.metadata_blob.data() + total_md_size, &md, size_of_data);
399  total_md_size += static_cast<uint32_t>(size_of_data);
400  }
401  }
402  additional_data.metadata_size = total_md_size;
403  return remaining;
404  }
405 
407  {
408  LOG_DEBUG("Trying to create an image frame from message");
409  auto msg = instantiate_msg<sensor_msgs::Image>(image_data);
410  frame_additional_data additional_data{};
411  std::chrono::duration<double, std::milli> timestamp_ms(std::chrono::duration<double>(msg->header.stamp.toSec()));
412  additional_data.timestamp = timestamp_ms.count();
413  additional_data.frame_number = msg->header.seq;
414  additional_data.fisheye_ae_mode = false;
415 
418  {
419  //Version 1 legacy
420  stream_id = legacy_file_format::get_stream_identifier(image_data.getTopic());
421  get_legacy_frame_metadata(m_file, stream_id, image_data, additional_data);
422  }
423  else
424  {
425  //Version 2 and above
426  stream_id = ros_topic::get_stream_identifier(image_data.getTopic());
427  auto info_topic = ros_topic::frame_metadata_topic(stream_id);
428  get_frame_metadata(m_file, info_topic, stream_id, image_data, additional_data);
429  }
430 
432  msg->data.size(), additional_data, true);
433  if (frame == nullptr)
434  {
435  LOG_WARNING("Failed to allocate new frame");
436  return nullptr;
437  }
439  video_frame->assign(msg->width, msg->height, msg->step, msg->step / msg->width * 8);
441  convert(msg->encoding, stream_format);
442  //attaching a temp stream to the frame. Playback sensor should assign the real stream
443  frame->set_stream(std::make_shared<video_stream_profile>(platform::stream_profile{}));
444  frame->get_stream()->set_format(stream_format);
445  frame->get_stream()->set_stream_index(int(stream_id.stream_index));
446  frame->get_stream()->set_stream_type(stream_id.stream_type);
447  video_frame->data = std::move(msg->data);
448  librealsense::frame_holder fh{ video_frame };
449  LOG_DEBUG("Created image frame: " << stream_id << " " << video_frame->get_width() << "x" << video_frame->get_height() << " " << stream_format);
450 
451  return fh;
452  }
453 
455  {
456  LOG_DEBUG("Trying to create a motion frame from message");
457 
458  auto msg = instantiate_msg<sensor_msgs::Imu>(motion_data);
459 
460  frame_additional_data additional_data{};
461  std::chrono::duration<double, std::milli> timestamp_ms(std::chrono::duration<double>(msg->header.stamp.toSec()));
462  additional_data.timestamp = timestamp_ms.count();
463  additional_data.frame_number = msg->header.seq;
464  additional_data.fisheye_ae_mode = false; //TODO: where should this come from?
465 
468  {
469  //Version 1 legacy
470  stream_id = legacy_file_format::get_stream_identifier(motion_data.getTopic());
471  get_legacy_frame_metadata(m_file, stream_id, motion_data, additional_data);
472  }
473  else
474  {
475  //Version 2 and above
476  stream_id = ros_topic::get_stream_identifier(motion_data.getTopic());
477  auto info_topic = ros_topic::frame_metadata_topic(stream_id);
478  get_frame_metadata(m_file, info_topic, stream_id, motion_data, additional_data);
479  }
480 
481  frame_interface* frame = m_frame_source->alloc_frame(RS2_EXTENSION_MOTION_FRAME, 3 * sizeof(float), additional_data, true);
482  if (frame == nullptr)
483  {
484  LOG_WARNING("Failed to allocate new frame");
485  return nullptr;
486  }
488  //attaching a temp stream to the frame. Playback sensor should assign the real stream
489  frame->set_stream(std::make_shared<motion_stream_profile>(platform::stream_profile{}));
490  frame->get_stream()->set_format(RS2_FORMAT_MOTION_XYZ32F);
491  frame->get_stream()->set_stream_index(stream_id.stream_index);
492  frame->get_stream()->set_stream_type(stream_id.stream_type);
493  if (stream_id.stream_type == RS2_STREAM_ACCEL)
494  {
495  auto data = reinterpret_cast<float*>(motion_frame->data.data());
496  data[0] = static_cast<float>(msg->linear_acceleration.x);
497  data[1] = static_cast<float>(msg->linear_acceleration.y);
498  data[2] = static_cast<float>(msg->linear_acceleration.z);
499  LOG_DEBUG("RS2_STREAM_ACCEL " << motion_frame);
500  }
501  else if (stream_id.stream_type == RS2_STREAM_GYRO)
502  {
503  auto data = reinterpret_cast<float*>(motion_frame->data.data());
504  data[0] = static_cast<float>(msg->angular_velocity.x);
505  data[1] = static_cast<float>(msg->angular_velocity.y);
506  data[2] = static_cast<float>(msg->angular_velocity.z);
507  LOG_DEBUG("RS2_STREAM_GYRO " << motion_frame);
508  }
509  else
510  {
511  throw io_exception(to_string() << "Unsupported stream type " << stream_id.stream_type);
512  }
513  librealsense::frame_holder fh{ motion_frame };
514  LOG_DEBUG("Created motion frame: " << stream_id);
515 
516  return std::move(fh);
517  }
518 
520  {
521  float3 f{};
522  f.x = v.x;
523  f.y = v.y;
524  f.z = v.z;
525  return f;
526  }
527 
529  {
530  float4 f{};
531  f.x = q.x;
532  f.y = q.y;
533  f.z = q.z;
534  f.w = q.w;
535  return f;
536  }
537 
539  {
540  LOG_DEBUG("Trying to create a pose frame from message");
541 
543  std::chrono::duration<double, std::milli> timestamp_ms;
544  size_t frame_size = sizeof(pose);
546  frame_additional_data additional_data{};
547 
548  additional_data.fisheye_ae_mode = false;
549 
551 
553  {
554  auto pose_msg = instantiate_msg<realsense_legacy_msgs::pose>(msg);
555  pose.rotation = to_float4(pose_msg->rotation);
556  pose.translation = to_float3(pose_msg->translation);
557  pose.angular_acceleration = to_float3(pose_msg->angular_acceleration);
558  pose.acceleration = to_float3(pose_msg->acceleration);
559  pose.angular_velocity = to_float3(pose_msg->angular_velocity);
560  pose.velocity = to_float3(pose_msg->velocity);
561  //pose.confidence = not supported in legacy format
562  timestamp_ms = std::chrono::duration<double, std::milli>(static_cast<double>(pose_msg->timestamp));
563  }
564  else
565  {
566  assert(msg.getTopic().find("pose/transform") != std::string::npos); // Assuming that the samples iterator of the reader only reads the pose/transform topic
567  // and we will be reading the rest in here (see ../readme.md#Topics under Pose-Data for more information
568  auto transform_msg = instantiate_msg<geometry_msgs::Transform>(msg);
569 
570  auto stream_id = ros_topic::get_stream_identifier(msg.getTopic());
571  std::string accel_topic = ros_topic::pose_accel_topic(stream_id);
572  rosbag::View accel_view(m_file, rosbag::TopicQuery(accel_topic), msg.getTime(), msg.getTime());
573  assert(accel_view.size() == 1);
574  auto accel_msg = instantiate_msg<geometry_msgs::Accel>(*accel_view.begin());
575 
576  std::string twist_topic = ros_topic::pose_twist_topic(stream_id);
577  rosbag::View twist_view(m_file, rosbag::TopicQuery(twist_topic), msg.getTime(), msg.getTime());
578  assert(twist_view.size() == 1);
579  auto twist_msg = instantiate_msg<geometry_msgs::Twist>(*twist_view.begin());
580 
581  pose.rotation = to_float4(transform_msg->rotation);
582  pose.translation = to_float3(transform_msg->translation);
583  pose.angular_acceleration = to_float3(accel_msg->angular);
584  pose.acceleration = to_float3(accel_msg->linear);
585  pose.angular_velocity = to_float3(twist_msg->angular);
586  pose.velocity = to_float3(twist_msg->linear);
587 
588  }
589 
591  {
592  //Version 1 legacy
594  get_legacy_frame_metadata(m_file, stream_id, msg, additional_data);
595  }
596  else
597  {
598  //Version 2 and above
599  stream_id = ros_topic::get_stream_identifier(msg.getTopic());
600  auto info_topic = ros_topic::frame_metadata_topic(stream_id);
601  auto remaining = get_frame_metadata(m_file, info_topic, stream_id, msg, additional_data);
602  for (auto&& kvp : remaining)
603  {
604  if (kvp.first == MAPPER_CONFIDENCE_MD_STR)
605  {
606  pose.mapper_confidence = std::stoul(kvp.second);
607  }
608  else if (kvp.first == FRAME_TIMESTAMP_MD_STR)
609  {
610  std::istringstream iss(kvp.second);
611  double ts = std::strtod(iss.str().c_str(), NULL);
612  timestamp_ms = std::chrono::duration<double, std::milli>(ts);
613  }
614  else if (kvp.first == TRACKER_CONFIDENCE_MD_STR)
615  {
616  pose.tracker_confidence = std::stoul(kvp.second);
617  }
618  else if (kvp.first == FRAME_NUMBER_MD_STR)
619  {
620  additional_data.frame_number = std::stoul(kvp.second);
621  }
622  }
623  }
624 
625  additional_data.timestamp = timestamp_ms.count();
626 
627  frame_interface* new_frame = m_frame_source->alloc_frame(frame_type, frame_size, additional_data, true);
628  if (new_frame == nullptr)
629  {
630  LOG_WARNING("Failed to allocate new frame");
631  return nullptr;
632  }
634  //attaching a temp stream to the frame. Playback sensor should assign the real stream
635  new_frame->set_stream(std::make_shared<pose_stream_profile>(platform::stream_profile{}));
636  new_frame->get_stream()->set_format(RS2_FORMAT_6DOF);
637  new_frame->get_stream()->set_stream_index(int(stream_id.stream_index));
638  new_frame->get_stream()->set_stream_type(stream_id.stream_type);
639  byte* data = pose_frame->data.data();
640  memcpy(data, &pose, frame_size);
641  frame_holder fh{ new_frame };
642  LOG_DEBUG("Created new frame " << frame_type);
643  return fh;
644  }
645 
647  {
648  auto version_topic = ros_topic::file_version_topic();
649  rosbag::View view(file, rosbag::TopicQuery(version_topic));
650 
651  auto legacy_version_topic = legacy_file_format::file_version_topic();
652  rosbag::View legacy_view(file, rosbag::TopicQuery(legacy_version_topic));
653  if (legacy_view.size() == 0 && view.size() == 0)
654  {
655  throw io_exception(to_string() << "Invalid file format, file does not contain topic \"" << version_topic << "\" nor \"" << legacy_version_topic << "\"");
656  }
657  assert((view.size() + legacy_view.size()) == 1); //version message is expected to be a single one
658  if (view.size() != 0)
659  {
660  auto item = *view.begin();
661  auto msg = instantiate_msg<std_msgs::UInt32>(item);
662  if (msg->data < get_minimum_supported_file_version())
663  {
664  throw std::runtime_error(to_string() << "Unsupported file version \"" << msg->data << "\"");
665  }
666  return msg->data;
667  }
668  else if (legacy_view.size() != 0)
669  {
670  auto item = *legacy_view.begin();
671  auto msg = instantiate_msg<std_msgs::UInt32>(item);
673  {
674  throw std::runtime_error(to_string() << "Unsupported legacy file version \"" << msg->data << "\"");
675  }
676  return msg->data;
677  }
678  throw std::logic_error("Unreachable code path");
679  }
681  {
682  std::string topic;
683  if (stream_id.stream_type == RS2_STREAM_ACCEL || stream_id.stream_type == RS2_STREAM_GYRO)
684  {
685  topic = to_string() << "/camera/rs_motion_stream_info/" << stream_id.sensor_index;
686  }
687  else if (legacy_file_format::is_camera(stream_id.stream_type))
688  {
689  topic = to_string() << "/camera/rs_stream_info/" << stream_id.sensor_index;
690  }
691  else
692  {
693  return false;
694  }
695  rosbag::View extrinsics_view(m_file, rosbag::TopicQuery(topic));
696  if (extrinsics_view.size() == 0)
697  {
698  return false;
699  }
700  for (auto&& msg : extrinsics_view)
701  {
703  {
704  auto msi_msg = instantiate_msg<realsense_legacy_msgs::motion_stream_info>(msg);
705  auto parsed_stream_id = legacy_file_format::parse_stream_type(msi_msg->motion_type);
706  if (stream_id.stream_type != parsed_stream_id.type || stream_id.stream_index != static_cast<uint32_t>(parsed_stream_id.index))
707  {
708  continue;
709  }
710  std::copy(std::begin(msi_msg->stream_extrinsics.extrinsics.rotation),
711  std::end(msi_msg->stream_extrinsics.extrinsics.rotation),
712  std::begin(extrinsic.rotation));
713  std::copy(std::begin(msi_msg->stream_extrinsics.extrinsics.translation),
714  std::end(msi_msg->stream_extrinsics.extrinsics.translation),
715  std::begin(extrinsic.translation));
716  group_id = static_cast<uint32_t>(msi_msg->stream_extrinsics.reference_point_id);
717  return true;
718  }
719  else if (msg.isType<realsense_legacy_msgs::stream_info>())
720  {
721  auto si_msg = instantiate_msg<realsense_legacy_msgs::stream_info>(msg);
722  auto parsed_stream_id = legacy_file_format::parse_stream_type(si_msg->stream_type);
723  if (stream_id.stream_type != parsed_stream_id.type || stream_id.stream_index != static_cast<uint32_t>(parsed_stream_id.index))
724  {
725  continue;
726  }
727  std::copy(std::begin(si_msg->stream_extrinsics.extrinsics.rotation),
728  std::end(si_msg->stream_extrinsics.extrinsics.rotation),
729  std::begin(extrinsic.rotation));
730  std::copy(std::begin(si_msg->stream_extrinsics.extrinsics.translation),
731  std::end(si_msg->stream_extrinsics.extrinsics.translation),
732  std::begin(extrinsic.translation));
733  group_id = static_cast<uint32_t>(si_msg->stream_extrinsics.reference_point_id);
734  return true;
735  }
736  else
737  {
738  throw io_exception(to_string() <<
739  "Expected either \"realsense_legacy_msgs::motion_stream_info\" or \"realsense_legacy_msgs::stream_info\", but got "
740  << msg.getDataType());
741  }
742  }
743  return false;
744  }
746  {
748  {
749  return try_read_legacy_stream_extrinsic(stream_id, group_id, extrinsic);
750  }
751  rosbag::View tf_view(m_file, ExtrinsicsQuery(stream_id));
752  if (tf_view.size() == 0)
753  {
754  return false;
755  }
756  assert(tf_view.size() == 1); //There should be 1 message per stream
757  auto msg = *tf_view.begin();
758  auto tf_msg = instantiate_msg<geometry_msgs::Transform>(msg);
759  group_id = ros_topic::get_extrinsic_group_index(msg.getTopic());
760  convert(*tf_msg, extrinsic);
761  return true;
762  }
763 
764  void ros_reader::update_sensor_options(const rosbag::Bag& file, uint32_t sensor_index, const nanoseconds& time, uint32_t file_version, snapshot_collection& sensor_extensions, uint32_t version)
765  {
766  if (version == legacy_file_format::file_version())
767  {
768  LOG_DEBUG("Not updating options from legacy files");
769  return;
770  }
771  auto sensor_options = read_sensor_options(file, { get_device_index(), sensor_index }, time, file_version);
772  sensor_extensions[RS2_EXTENSION_OPTIONS] = sensor_options;
773 
774  if (sensor_options->supports_option(RS2_OPTION_DEPTH_UNITS))
775  {
776  auto&& dpt_opt = sensor_options->get_option(RS2_OPTION_DEPTH_UNITS);
777  sensor_extensions[RS2_EXTENSION_DEPTH_SENSOR] = std::make_shared<depth_sensor_snapshot>(dpt_opt.query());
778 
779  if (sensor_options->supports_option(RS2_OPTION_STEREO_BASELINE))
780  {
781  auto&& bl_opt = sensor_options->get_option(RS2_OPTION_STEREO_BASELINE);
782  sensor_extensions[RS2_EXTENSION_DEPTH_STEREO_SENSOR] = std::make_shared<depth_stereo_sensor_snapshot>(dpt_opt.query(), bl_opt.query());
783  }
784  }
785  }
786 
787  void ros_reader::update_proccesing_blocks(const rosbag::Bag& file, uint32_t sensor_index, const nanoseconds& time, uint32_t file_version, snapshot_collection& sensor_extensions, uint32_t version, std::string pid, std::string sensor_name)
788  {
789  if (version == legacy_file_format::file_version())
790  {
791  LOG_DEBUG("Legacy file - processing blocks are not supported");
792  return;
793  }
794  auto options_snapshot = sensor_extensions.find(RS2_EXTENSION_OPTIONS);
795  if (options_snapshot == nullptr)
796  {
797  LOG_WARNING("Recorded file does not contain sensor options");
798  }
799  auto options_api = As<options_interface>(options_snapshot);
800  if (options_api == nullptr)
801  {
802  throw invalid_value_exception("Failed to get options interface from sensor snapshots");
803  }
804  auto proccesing_blocks = read_proccesing_blocks(file, { get_device_index(), sensor_index }, time, options_api, file_version, pid, sensor_name);
805  sensor_extensions[RS2_EXTENSION_RECOMMENDED_FILTERS] = proccesing_blocks;
806  }
807 
809  {
812 
813  for (auto i = 0;i < data.num_of_resolution; i++)
814  {
819 
824 
825  }
826  return res;
827  }
828 
829  void ros_reader::add_sensor_extension(snapshot_collection & sensor_extensions, std::string sensor_name)
830  {
831  if (is_color_sensor(sensor_name))
832  {
833  sensor_extensions[RS2_EXTENSION_COLOR_SENSOR] = std::make_shared<color_sensor_snapshot>();
834  }
835  if (is_motion_module_sensor(sensor_name))
836  {
837  sensor_extensions[RS2_EXTENSION_MOTION_SENSOR] = std::make_shared<motion_sensor_snapshot>();
838  }
839  if (is_fisheye_module_sensor(sensor_name))
840  {
841  sensor_extensions[RS2_EXTENSION_FISHEYE_SENSOR] = std::make_shared<fisheye_sensor_snapshot>();
842  }
843  }
844 
845  void ros_reader::update_l500_depth_sensor(const rosbag::Bag & file, uint32_t sensor_index, const nanoseconds & time, uint32_t file_version, snapshot_collection & sensor_extensions, uint32_t version, std::string pid, std::string sensor_name)
846  {
847  //Taking all messages from the beginning of the bag until the time point requested
848  std::string l500_depth_intrinsics_topic = ros_topic::l500_data_blocks_topic({ get_device_index(), sensor_index });
849 
850  rosbag::View option_view(file, rosbag::TopicQuery(l500_depth_intrinsics_topic), to_rostime(get_static_file_info_timestamp()), to_rostime(time));
851  auto it = option_view.begin();
852 
853  auto depth_to_disparity = true;
854 
855  rosbag::View::iterator last_item;
856 
857  while (it != option_view.end())
858  {
859  last_item = it++;
860  auto l500_intrinsic = create_l500_intrinsic_depth(*last_item);
861 
862  sensor_extensions[RS2_EXTENSION_L500_DEPTH_SENSOR] = std::make_shared<l500_depth_sensor_snapshot>(ros_l500_depth_data_to_intrinsic_depth(l500_intrinsic), l500_intrinsic.baseline);
863  }
864  }
865 
867  {
868  if (sensor_name.compare("Stereo Module") == 0 || sensor_name.compare("Coded-Light Depth Sensor") == 0)
869  return true;
870  return false;
871  }
872 
874  {
875  if (sensor_name.compare("RGB Camera") == 0)
876  return true;
877  return false;
878  }
879 
881  {
882  if (sensor_name.compare("Motion Module") == 0)
883  return true;
884  return false;
885  }
886 
888  {
889  if (sensor_name.compare("Wide FOV Camera") == 0)
890  return true;
891  return false;
892  }
893 
895  {
896  using namespace ds;
897 
898  auto it = std::find_if(rs400_sku_pid.begin(), rs400_sku_pid.end(), [&](int ds5_pid)
899  {
900  return pid == ds5_pid;
901  });
902 
903  return it != rs400_sku_pid.end();
904  }
905 
907  {
908  std::vector<int> sr300_PIDs =
909  {
910  SR300_PID,
911  SR300v2_PID,
912  SR306_PID
913  };
914 
915  auto it = std::find_if(sr300_PIDs.begin(), sr300_PIDs.end(), [&](int sr300_pid)
916  {
917  return pid == sr300_pid;
918  });
919 
920  return it != sr300_PIDs.end();
921  }
922 
924  {
925  return pid == L500_PID;
926  }
927 
928  std::shared_ptr<recommended_proccesing_blocks_snapshot> ros_reader::read_proccesing_blocks_for_version_under_4(std::string pid, std::string sensor_name, std::shared_ptr<options_interface> options)
929  {
930  std::stringstream ss;
931  ss << pid;
932  int int_pid;
933  ss >> std::hex >> int_pid;
934 
935  if (is_ds5_PID(int_pid))
936  {
937  if (is_depth_sensor(sensor_name))
938  {
939  return std::make_shared<recommended_proccesing_blocks_snapshot>(get_ds5_depth_recommended_proccesing_blocks());
940  }
941  else if (is_color_sensor(sensor_name))
942  {
943  return std::make_shared<recommended_proccesing_blocks_snapshot>(get_color_recommended_proccesing_blocks());
944  }
945  else if (is_motion_module_sensor(sensor_name))
946  {
947  return std::make_shared<recommended_proccesing_blocks_snapshot>(processing_blocks{});
948  }
949  throw io_exception("Unrecognized sensor name" + sensor_name);
950  }
951 
952  if (is_sr300_PID(int_pid))
953  {
954  if (is_depth_sensor(sensor_name))
955  {
956  return std::make_shared<recommended_proccesing_blocks_snapshot>(sr300_camera::sr300_depth_sensor::get_sr300_depth_recommended_proccesing_blocks());
957  }
958  else if (is_color_sensor(sensor_name))
959  {
960  return std::make_shared<recommended_proccesing_blocks_snapshot>(get_color_recommended_proccesing_blocks());
961  }
962  throw io_exception("Unrecognized sensor name");
963  }
964 
965  if (is_l500_PID(int_pid))
966  {
967  if (is_depth_sensor(sensor_name))
968  {
969  return std::make_shared<recommended_proccesing_blocks_snapshot>(l500_depth_sensor::get_l500_recommended_proccesing_blocks());
970  }
971  throw io_exception("Unrecognized sensor name");
972  }
973  //Unrecognized sensor
974  return std::make_shared<recommended_proccesing_blocks_snapshot>(processing_blocks{});
975  }
976 
977  std::shared_ptr<recommended_proccesing_blocks_snapshot> ros_reader::read_proccesing_blocks(const rosbag::Bag& file, device_serializer::sensor_identifier sensor_id, const nanoseconds& timestamp,
978  std::shared_ptr<options_interface> options, uint32_t file_version, std::string pid, std::string sensor_name)
979  {
980  processing_blocks blocks;
981  std::shared_ptr<recommended_proccesing_blocks_snapshot> res;
982 
984  {
985  return read_proccesing_blocks_for_version_under_4(pid, sensor_name, options);
986  }
987  else
988  {
989  //Taking all messages from the beginning of the bag until the time point requested
990  std::string proccesing_block_topic = ros_topic::post_processing_blocks_topic(sensor_id);
991  rosbag::View option_view(file, rosbag::TopicQuery(proccesing_block_topic), to_rostime(get_static_file_info_timestamp()), to_rostime(timestamp));
992  auto it = option_view.begin();
993 
994  auto depth_to_disparity = true;
995 
996  rosbag::View::iterator last_item;
997  while (it != option_view.end())
998  {
999  last_item = it++;
1000 
1001  auto block = create_processing_block(*last_item, depth_to_disparity, options);
1002  assert(block);
1003  blocks.push_back(block);
1004  }
1005 
1006  res = std::make_shared<recommended_proccesing_blocks_snapshot>(blocks);
1007  }
1008  return res;
1009  }
1010 
1012  {
1013  if (time == get_static_file_info_timestamp())
1014  {
1015  if (reset)
1016  {
1017  snapshot_collection device_extensions;
1018 
1020  device_extensions[RS2_EXTENSION_INFO] = info;
1021 
1022  std::vector<sensor_snapshot> sensor_descriptions;
1023  auto sensor_indices = read_sensor_indices(get_device_index());
1024  std::map<stream_identifier, std::pair<uint32_t, rs2_extrinsics>> extrinsics_map;
1025 
1026  for (auto sensor_index : sensor_indices)
1027  {
1028  snapshot_collection sensor_extensions;
1029  auto streams_snapshots = read_stream_info(get_device_index(), sensor_index);
1030  for (auto stream_profile : streams_snapshots)
1031  {
1032  auto stream_id = stream_identifier{ get_device_index(), sensor_index, stream_profile->get_stream_type(), static_cast<uint32_t>(stream_profile->get_stream_index()) };
1033  uint32_t reference_id;
1034  rs2_extrinsics stream_extrinsic;
1035  if (try_read_stream_extrinsic(stream_id, reference_id, stream_extrinsic))
1036  {
1037  extrinsics_map[stream_id] = std::make_pair(reference_id, stream_extrinsic);
1038  }
1039  }
1040 
1041  //Update infos
1042  std::shared_ptr<info_container> sensor_info;
1044  {
1045  sensor_info = read_legacy_info_snapshot(sensor_index);
1046  }
1047  else
1048  {
1049  sensor_info = read_info_snapshot(ros_topic::sensor_info_topic({ get_device_index(), sensor_index }));
1050  }
1051  sensor_extensions[RS2_EXTENSION_INFO] = sensor_info;
1052  //Update options
1053  update_sensor_options(m_file, sensor_index, time, m_version, sensor_extensions, m_version);
1054 
1055  std::string pid = "";
1056  std::string sensor_name = "";
1057 
1058  if (info->supports_info(RS2_CAMERA_INFO_PRODUCT_ID))
1059  pid = info->get_info(RS2_CAMERA_INFO_PRODUCT_ID);
1060 
1061  if (sensor_info->supports_info(RS2_CAMERA_INFO_NAME))
1062  sensor_name = sensor_info->get_info(RS2_CAMERA_INFO_NAME);
1063 
1064  add_sensor_extension(sensor_extensions, sensor_name);
1065  update_proccesing_blocks(m_file, sensor_index, time, m_version, sensor_extensions, m_version, pid, sensor_name);
1066  update_l500_depth_sensor(m_file, sensor_index, time, m_version, sensor_extensions, m_version, pid, sensor_name);
1067 
1068  sensor_descriptions.emplace_back(sensor_index, sensor_extensions, streams_snapshots);
1069  }
1070 
1071  m_initial_device_description = device_snapshot(device_extensions, sensor_descriptions, extrinsics_map);
1072  }
1074  }
1075  else
1076  {
1077  //update only:
1080  {
1081  auto& sensor_extensions = sensor.get_sensor_extensions_snapshots();
1082  update_sensor_options(m_file, sensor.get_sensor_index(), time, m_version, sensor_extensions, m_version);
1083  }
1084  return device_snapshot;
1085  }
1086  }
1087 
1088  std::shared_ptr<info_container> ros_reader::read_legacy_info_snapshot(uint32_t sensor_index) const
1089  {
1090  std::map<rs2_camera_info, std::string> values;
1091  rosbag::View view(m_file, rosbag::TopicQuery(to_string() << "/info/" << sensor_index));
1092  auto infos = std::make_shared<info_container>();
1093  //TODO: properly implement, currently assuming TM2 devices
1094  infos->register_info(RS2_CAMERA_INFO_NAME, to_string() << "Sensor " << sensor_index);
1095  for (auto message_instance : view)
1096  {
1097  auto info_msg = instantiate_msg<realsense_legacy_msgs::vendor_data>(message_instance);
1098  try
1099  {
1101  if (legacy_file_format::info_from_string(info_msg->name, info))
1102  {
1103  infos->register_info(info, info_msg->value);
1104  }
1105  }
1106  catch (const std::exception& e)
1107  {
1108  std::cerr << e.what() << std::endl;
1109  }
1110  }
1111 
1112  return infos;
1113  }
1114  std::shared_ptr<info_container> ros_reader::read_info_snapshot(const std::string& topic) const
1115  {
1116  auto infos = std::make_shared<info_container>();
1118  {
1119  //TODO: properly implement, currently assuming TM2 devices and Movidius PID
1120  infos->register_info(RS2_CAMERA_INFO_NAME, "Intel RealSense TM2");
1121  infos->register_info(RS2_CAMERA_INFO_PRODUCT_ID, "2150");
1122  infos->register_info(RS2_CAMERA_INFO_SERIAL_NUMBER, "N/A");
1123  }
1124  std::map<rs2_camera_info, std::string> values;
1126  for (auto message_instance : view)
1127  {
1128  diagnostic_msgs::KeyValueConstPtr info_msg = instantiate_msg<diagnostic_msgs::KeyValue>(message_instance);
1129  try
1130  {
1132  convert(info_msg->key, info);
1133  infos->register_info(info, info_msg->value);
1134  }
1135  catch (const std::exception& e)
1136  {
1137  std::cerr << e.what() << std::endl;
1138  }
1139  }
1140 
1141  return infos;
1142  }
1143 
1144  std::set<uint32_t> ros_reader::read_sensor_indices(uint32_t device_index) const
1145  {
1146  std::set<uint32_t> sensor_indices;
1148  {
1149  rosbag::View device_info(m_file, rosbag::TopicQuery("/info/4294967295"));
1150  if (device_info.size() == 0)
1151  {
1152  throw io_exception("Missing sensor count message for legacy file");
1153  }
1154  for (auto info : device_info)
1155  {
1156  auto msg = instantiate_msg<realsense_legacy_msgs::vendor_data>(info);
1157  if (msg->name == "sensor_count")
1158  {
1159  int sensor_count = std::stoi(msg->value);
1160  while (--sensor_count >= 0)
1161  sensor_indices.insert(sensor_count);
1162  }
1163  }
1164  }
1165  else
1166  {
1167  rosbag::View sensor_infos(m_file, SensorInfoQuery(device_index));
1168  for (auto sensor_info : sensor_infos)
1169  {
1170  auto msg = instantiate_msg<diagnostic_msgs::KeyValue>(sensor_info);
1171  sensor_indices.insert(static_cast<uint32_t>(ros_topic::get_sensor_index(sensor_info.getTopic())));
1172  }
1173  }
1174  return sensor_indices;
1175  }
1176  std::shared_ptr<pose_stream_profile> ros_reader::create_pose_profile(uint32_t stream_index, uint32_t fps)
1177  {
1179  auto profile = std::make_shared<pose_stream_profile>(platform::stream_profile{ 0, 0, fps, static_cast<uint32_t>(format) });
1180  profile->set_stream_index(stream_index);
1181  profile->set_stream_type(RS2_STREAM_POSE);
1182  profile->set_format(format);
1183  profile->set_framerate(fps);
1184  return profile;
1185  }
1186 
1187  std::shared_ptr<motion_stream_profile> ros_reader::create_motion_stream(rs2_stream stream_type, uint32_t stream_index, uint32_t fps, rs2_format format, rs2_motion_device_intrinsic intrinsics)
1188  {
1189  auto profile = std::make_shared<motion_stream_profile>(platform::stream_profile{ 0, 0, fps, static_cast<uint32_t>(format) });
1190  profile->set_stream_index(stream_index);
1191  profile->set_stream_type(stream_type);
1192  profile->set_format(format);
1193  profile->set_framerate(fps);
1194  profile->set_intrinsics([intrinsics]() {return intrinsics; });
1195  return profile;
1196  }
1197 
1198  std::shared_ptr<video_stream_profile> ros_reader::create_video_stream_profile(const platform::stream_profile& sp,
1199  const sensor_msgs::CameraInfo& ci,
1200  const stream_descriptor& sd)
1201  {
1202  auto profile = std::make_shared<video_stream_profile>(sp);
1204  intrinsics.height = ci.height;
1205  intrinsics.width = ci.width;
1206  intrinsics.fx = ci.K[0];
1207  intrinsics.ppx = ci.K[2];
1208  intrinsics.fy = ci.K[4];
1209  intrinsics.ppy = ci.K[5];
1212  {
1213  if (strcmp(ci.distortion_model.c_str(), rs2_distortion_to_string(static_cast<rs2_distortion>(i))) == 0)
1214  {
1215  intrinsics.model = static_cast<rs2_distortion>(i);
1216  break;
1217  }
1218  }
1219  for (size_t i = 0; i < ci.D.size() && i < sizeof(intrinsics.coeffs)/sizeof(intrinsics.coeffs[0]); ++i)
1220  {
1221  intrinsics.coeffs[i] = ci.D[i];
1222  }
1223  profile->set_intrinsics([intrinsics]() {return intrinsics; });
1224  profile->set_stream_index(sd.index);
1225  profile->set_stream_type(sd.type);
1226  profile->set_dims(ci.width, ci.height);
1227  profile->set_format(static_cast<rs2_format>(sp.format));
1228  profile->set_framerate(sp.fps);
1229  return profile;
1230  }
1231 
1233  {
1234  //legacy files have the form of "/(camera|imu)/<stream type><stream index>/(image_imu)_raw/<sensor_index>
1235  //6DoF streams have no streaming profiles in the file - handling them seperatly
1237  rosbag::View stream_infos_view(m_file, RegexTopicQuery(to_string() << R"RRR(/camera/(rs_stream_info|rs_motion_stream_info)/)RRR" << sensor_index));
1238  for (auto infos_msg : stream_infos_view)
1239  {
1240  if (infos_msg.isType<realsense_legacy_msgs::motion_stream_info>())
1241  {
1242  auto motion_stream_info_msg = instantiate_msg<realsense_legacy_msgs::motion_stream_info>(infos_msg);
1243  auto fps = motion_stream_info_msg->fps;
1244 
1245  std::string stream_name = motion_stream_info_msg->motion_type;
1249  //TODO: intrinsics = motion_stream_info_msg->stream_intrinsics;
1250  auto profile = create_motion_stream(stream_id.type, stream_id.index, fps, format, intrinsics);
1251  streams.push_back(profile);
1252  }
1253  else if (infos_msg.isType<realsense_legacy_msgs::stream_info>())
1254  {
1255  auto stream_info_msg = instantiate_msg<realsense_legacy_msgs::stream_info>(infos_msg);
1256  auto fps = stream_info_msg->fps;
1258  convert(stream_info_msg->encoding, format);
1259  std::string stream_name = stream_info_msg->stream_type;
1262  platform::stream_profile{ stream_info_msg->camera_info.width, stream_info_msg->camera_info.height, fps, static_cast<uint32_t>(format) },
1263  stream_info_msg->camera_info,
1264  stream_id);
1265  streams.push_back(profile);
1266  }
1267  else
1268  {
1269  throw io_exception(to_string()
1270  << "Invalid file format, expected "
1273  << " message but got: " << infos_msg.getDataType()
1274  << "(Topic: " << infos_msg.getTopic() << ")");
1275  }
1276  }
1277  std::unique_ptr<rosbag::View> entire_bag = std::unique_ptr<rosbag::View>(new rosbag::View(m_file, rosbag::View::TrueQuery()));
1278  std::vector<uint32_t> indices;
1279  for (auto&& topic : get_topics(entire_bag))
1280  {
1281  std::regex r(R"RRR(/camera/rs_6DoF(\d+)/\d+)RRR");
1282  std::smatch sm;
1283  if (std::regex_search(topic, sm, r))
1284  {
1285  for (int i = 1; i < sm.size(); i++)
1286  {
1287  indices.push_back(std::stoul(sm[i].str()));
1288  }
1289  }
1290  }
1291  for (auto&& index : indices)
1292  {
1293  auto profile = create_pose_profile(index, 0); //TODO: Where to read the fps from?
1294  streams.push_back(profile);
1295  }
1296  return streams;
1297  }
1298 
1300  {
1302  {
1303  return read_legacy_stream_info(sensor_index);
1304  }
1306  //The below regex matches both stream info messages and also video \ imu stream info (both have the same prefix)
1307  rosbag::View stream_infos_view(m_file, RegexTopicQuery("/device_" + std::to_string(device_index) + "/sensor_" + std::to_string(sensor_index) + R"RRR(/(\w)+_(\d)+/info)RRR"));
1308  for (auto infos_view : stream_infos_view)
1309  {
1310  if (infos_view.isType<realsense_msgs::StreamInfo>() == false)
1311  {
1312  continue;
1313  }
1314 
1316  auto stream_info_msg = instantiate_msg<realsense_msgs::StreamInfo>(infos_view);
1317  //auto is_recommended = stream_info_msg->is_recommended;
1318  auto fps = stream_info_msg->fps;
1320  convert(stream_info_msg->encoding, format);
1321 
1322  auto video_stream_topic = ros_topic::video_stream_info_topic(stream_id);
1323  rosbag::View video_stream_infos_view(m_file, rosbag::TopicQuery(video_stream_topic));
1324  if (video_stream_infos_view.size() > 0)
1325  {
1326  assert(video_stream_infos_view.size() == 1);
1327  auto video_stream_msg_ptr = *video_stream_infos_view.begin();
1328  auto video_stream_msg = instantiate_msg<sensor_msgs::CameraInfo>(video_stream_msg_ptr);
1330  platform::stream_profile{ video_stream_msg->width ,video_stream_msg->height, fps, static_cast<uint32_t>(format) }
1331  , *video_stream_msg,
1332  { stream_id.stream_type, static_cast<int>(stream_id.stream_index) });
1333  streams.push_back(profile);
1334  }
1335 
1336  auto imu_stream_topic = ros_topic::imu_intrinsic_topic(stream_id);
1337  rosbag::View imu_intrinsic_view(m_file, rosbag::TopicQuery(imu_stream_topic));
1338  if (imu_intrinsic_view.size() > 0)
1339  {
1340  assert(imu_intrinsic_view.size() == 1);
1341  auto motion_intrinsics_msg = instantiate_msg<realsense_msgs::ImuIntrinsic>(*imu_intrinsic_view.begin());
1343  std::copy(std::begin(motion_intrinsics_msg->bias_variances), std::end(motion_intrinsics_msg->bias_variances), std::begin(intrinsics.bias_variances));
1344  std::copy(std::begin(motion_intrinsics_msg->noise_variances), std::end(motion_intrinsics_msg->noise_variances), std::begin(intrinsics.noise_variances));
1345  std::copy(std::begin(motion_intrinsics_msg->data), std::end(motion_intrinsics_msg->data), &intrinsics.data[0][0]);
1346  auto profile = create_motion_stream(stream_id.stream_type, stream_id.stream_index, fps, format, intrinsics);
1347  streams.push_back(profile);
1348  }
1349 
1350  if (stream_id.stream_type == RS2_STREAM_POSE)
1351  {
1352  auto profile = create_pose_profile(stream_id.stream_index, fps);
1353  streams.push_back(profile);
1354  }
1355 
1356  if (video_stream_infos_view.size() == 0 && imu_intrinsic_view.size() == 0 && stream_id.stream_type != RS2_STREAM_POSE)
1357  {
1358  throw io_exception(to_string() << "Every StreamInfo is expected to have a complementary video/imu message, but none was found");
1359  }
1360  }
1361  return streams;
1362  }
1363 
1365  {
1366  rosbag::View option_description_view(file, rosbag::TopicQuery(topic));
1367  if (option_description_view.size() == 0)
1368  {
1369  LOG_ERROR("File does not contain topics for: " << topic);
1370  return "N/A";
1371  }
1372  assert(option_description_view.size() == 1); //There should be only 1 message for each option
1373  auto description_message_instance = *option_description_view.begin();
1374  auto option_desc_msg = instantiate_msg<std_msgs::String>(description_message_instance);
1375  return option_desc_msg->data;
1376  }
1377 
1378  /*Until Version 2 (including)*/
1379  std::pair<rs2_option, std::shared_ptr<librealsense::option>> ros_reader::create_property(const rosbag::MessageInstance& property_message_instance)
1380  {
1381  auto property_msg = instantiate_msg<diagnostic_msgs::KeyValue>(property_message_instance);
1382  rs2_option id;
1383  convert(property_msg->key, id);
1384  float value = std::stof(property_msg->value);
1385  std::string description = to_string() << "Read only option of " << id;
1386  return std::make_pair(id, std::make_shared<const_value_option>(description, value));
1387  }
1388 
1389  /*Starting version 3*/
1390  std::pair<rs2_option, std::shared_ptr<librealsense::option>> ros_reader::create_option(const rosbag::Bag& file, const rosbag::MessageInstance& value_message_instance)
1391  {
1392  auto option_value_msg = instantiate_msg<std_msgs::Float32>(value_message_instance);
1393  auto value_topic = value_message_instance.getTopic();
1394  std::string option_name = ros_topic::get_option_name(value_topic);
1396  rs2_option id;
1397  std::replace(option_name.begin(), option_name.end(), '_', ' ');
1398  convert(option_name, id);
1399  float value = option_value_msg->data;
1400  auto description_topic = value_topic.replace(value_topic.find_last_of("value") - sizeof("value") + 2, sizeof("value"), "description");
1401  std::string description = read_option_description(file, description_topic);
1402  return std::make_pair(id, std::make_shared<const_value_option>(description, value));
1403  }
1404 
1405  std::shared_ptr<librealsense::processing_block_interface> ros_reader::create_processing_block(const rosbag::MessageInstance& value_message_instance, bool& depth_to_disparity, std::shared_ptr<options_interface> options)
1406  {
1407  auto processing_block_msg = instantiate_msg<std_msgs::String>(value_message_instance);
1408  rs2_extension id;
1409  convert(processing_block_msg->data, id);
1410  std::shared_ptr<librealsense::processing_block_interface> disparity;
1411 
1412  switch (id)
1413  {
1420  depth_to_disparity = false;
1421  return disparity;
1436  default:
1437  return nullptr;
1438  }
1439  }
1440 
1442  {
1444 
1445  auto intrinsic_msg = instantiate_msg<std_msgs::Float32MultiArray>(value_message_instance);
1446 
1447  res = *(ros_reader::l500_depth_data*)intrinsic_msg->data.data();
1448 
1449  return res;
1450  }
1451 
1453  {
1454  auto notification_msg = instantiate_msg<realsense_msgs::Notification>(message_instance);
1455  rs2_notification_category category;
1457  convert(notification_msg->category, category);
1458  convert(notification_msg->severity, severity);
1459  int type = 0; //TODO: what is this for?
1460  notification n(category, type, severity, notification_msg->description);
1461  n.timestamp = to_nanoseconds(notification_msg->timestamp).count();
1462  n.serialized_data = notification_msg->serialized_data;
1463  return n;
1464  }
1465 
1467  {
1468  auto options = std::make_shared<options_container>();
1469  if (file_version == 2)
1470  {
1471  rosbag::View sensor_options_view(file, rosbag::TopicQuery(ros_topic::property_topic(sensor_id)));
1472  for (auto message_instance : sensor_options_view)
1473  {
1474  auto id_option = create_property(message_instance);
1475  options->register_option(id_option.first, id_option.second);
1476  }
1477  }
1478  else
1479  {
1480  //Taking all messages from the beginning of the bag until the time point requested
1481  for (int i = 0; i < static_cast<int>(RS2_OPTION_COUNT); i++)
1482  {
1483  rs2_option id = static_cast<rs2_option>(i);
1484  auto value_topic = ros_topic::option_value_topic(sensor_id, id);
1485  std::string option_name = ros_topic::get_option_name(value_topic);
1486  auto rs2_option_name = rs2_option_to_string(id); //option name with space seperator
1487  auto alternate_value_topic = value_topic;
1488  alternate_value_topic.replace(value_topic.find(option_name), option_name.length(), rs2_option_name);
1489 
1490  std::vector<std::string> option_topics{ value_topic, alternate_value_topic };
1491  rosbag::View option_view(file, rosbag::TopicQuery(option_topics), to_rostime(get_static_file_info_timestamp()), to_rostime(timestamp));
1492  auto it = option_view.begin();
1493  if (it == option_view.end())
1494  {
1495  continue;
1496  }
1497  rosbag::View::iterator last_item;
1498  while (it != option_view.end())
1499  {
1500  last_item = it++;
1501  }
1502  auto option = create_option(file, *last_item);
1503  assert(id == option.first);
1504  options->register_option(option.first, option.second);
1505  }
1506  }
1507  return options;
1508  }
1509 
1510  std::vector<std::string> ros_reader::get_topics(std::unique_ptr<rosbag::View>& view)
1511  {
1512  std::vector<std::string> topics;
1513  if (view != nullptr)
1514  {
1515  auto connections = view->getConnections();
1516  std::transform(connections.begin(), connections.end(), std::back_inserter(topics), [](const rosbag::ConnectionInfo* connection) { return connection->topic; });
1517  }
1518  return topics;
1519  }
1520 }
l500_depth_data create_l500_intrinsic_depth(const rosbag::MessageInstance &value_message_instance)
int get_width() const
Definition: archive.h:279
rs2_camera_info
Read-only strings that can be queried from the device. Not all information attributes are available o...
Definition: rs_sensor.h:22
static processing_blocks get_sr300_depth_recommended_proccesing_blocks()
Definition: sr300.cpp:699
static std::string frame_data_topic(const device_serializer::stream_identifier &stream_id)
float stof(const std::string &value)
GLuint GLuint end
constexpr uint32_t file_version()
static std::string post_processing_blocks_topic(const device_serializer::sensor_identifier &sensor_id)
constexpr const char * FRAME_NUMBER_MD_STR
metadata parser class - support metadata in format: rs2_frame_metadata_value, rs2_metadata_type ...
std::istringstream istringstream
Definition: Arg.h:43
nanoseconds query_duration() const override
Definition: ros_reader.cpp:146
static std::string l500_data_blocks_topic(const device_serializer::sensor_identifier &sensor_id)
GLenum GLuint GLenum severity
static bool safe_convert(const std::string &key, T &val)
Definition: ros_reader.h:52
intrinsic_per_resolution intrinsic_resolution[MAX_NUM_OF_DEPTH_RESOLUTIONS]
Definition: l500-private.h:361
std::shared_ptr< recommended_proccesing_blocks_snapshot > read_proccesing_blocks_for_version_under_4(std::string pid, std::string sensor_name, std::shared_ptr< options_interface > options)
Definition: ros_reader.cpp:928
rs2rosinternal::Time getEndTime()
Definition: view.cpp:202
static std::string sensor_info_topic(const device_serializer::sensor_identifier &sensor_id)
bool try_read_stream_extrinsic(const stream_identifier &stream_id, uint32_t &group_id, rs2_extrinsics &extrinsic) const
Definition: ros_reader.cpp:745
device_snapshot read_device_description(const nanoseconds &time, bool reset=false)
processing_blocks get_ds5_depth_recommended_proccesing_blocks()
rs2_option
Defines general configuration controls. These can generally be mapped to camera UVC controls...
Definition: rs_option.h:22
GLdouble s
static std::string get_option_name(const std::string &topic)
static float4 to_float4(const geometry_msgs::Quaternion &q)
Definition: ros_reader.cpp:528
void open(std::string const &filename, uint32_t mode=bagmode::Read)
Open a bag file.
Definition: bag.cpp:101
device_serializer::nanoseconds to_nanoseconds(const rs2rosinternal::Time &t)
const GLfloat * m
Definition: glext.h:6814
GLboolean reset
rs2_distortion
Distortion model: defines how pixel coordinates should be mapped to sensor coordinates.
Definition: rs_types.h:45
float translation[3]
Definition: rs_sensor.h:99
rs2rosinternal::Time to_rostime(const device_serializer::nanoseconds &t)
#define LOG_WARNING(...)
Definition: src/types.h:241
ros_reader(const std::string &file, const std::shared_ptr< context > &ctx)
Definition: ros_reader.cpp:25
static std::shared_ptr< librealsense::processing_block_interface > create_processing_block(const rosbag::MessageInstance &value_message_instance, bool &depth_to_disparity, std::shared_ptr< options_interface > options)
const char * rs2_option_to_string(rs2_option option)
Definition: rs.cpp:1265
constexpr const char * FRAME_TIMESTAMP_MD_STR
nanoseconds m_total_duration
Definition: ros_reader.h:137
static notification create_notification(const rosbag::Bag &file, const rosbag::MessageInstance &message_instance)
const char * rs2_distortion_to_string(rs2_distortion distortion)
Definition: rs.cpp:1264
processing_blocks get_color_recommended_proccesing_blocks()
Definition: sensor.cpp:216
GLfloat value
frame_holder create_image_from_message(const rosbag::MessageInstance &image_data) const
Definition: ros_reader.cpp:406
virtual void enable_stream(const std::vector< device_serializer::stream_identifier > &stream_ids) override
Definition: ros_reader.cpp:162
static uint32_t get_sensor_index(const std::string &topic)
static std::string video_stream_info_topic(const device_serializer::stream_identifier &stream_id)
static std::shared_ptr< options_container > read_sensor_options(const rosbag::Bag &file, device_serializer::sensor_identifier sensor_id, const nanoseconds &timestamp, uint32_t file_version)
const uint16_t SR300v2_PID
void convert(rs2_format source, std::string &target)
std::shared_ptr< recommended_proccesing_blocks_snapshot > read_proccesing_blocks(const rosbag::Bag &file, device_serializer::sensor_identifier sensor_id, const nanoseconds &timestamp, std::shared_ptr< options_interface > options, uint32_t file_version, std::string pid, std::string sensor_name)
Definition: ros_reader.cpp:977
static processing_blocks get_l500_recommended_proccesing_blocks()
Definition: l500-depth.cpp:481
static std::string device_info_topic(uint32_t device_id)
GLsizei const GLchar *const * string
bool is_l500_PID(int pid)
Definition: ros_reader.cpp:923
constexpr const char * TRACKER_CONFIDENCE_MD_STR
static float3 to_float3(const geometry_msgs::Vector3 &v)
Definition: ros_reader.cpp:519
Specialize to provide the datatype for a message.
std::unique_ptr< rosbag::View > m_samples_view
Definition: ros_reader.h:141
stream_profiles read_legacy_stream_info(uint32_t sensor_index) const
An iterator that points to a MessageInstance from a bag.
Definition: view.h:60
GLdouble n
Definition: glext.h:1966
stream_profiles read_stream_info(uint32_t device_index, uint32_t sensor_index) const
e
Definition: rmse.py:177
rs2rosinternal::Time getBeginTime()
Definition: view.cpp:187
static std::pair< rs2_option, std::shared_ptr< librealsense::option > > create_option(const rosbag::Bag &file, const rosbag::MessageInstance &value_message_instance)
bool convert_metadata_type(uint64_t type, rs2_frame_metadata_value &res)
device_snapshot m_initial_device_description
Definition: ros_reader.h:136
virtual void disable_stream(const std::vector< device_serializer::stream_identifier > &stream_ids) override
Definition: ros_reader.cpp:206
static void get_legacy_frame_metadata(const rosbag::Bag &bag, const device_serializer::stream_identifier &stream_id, const rosbag::MessageInstance &msg, frame_additional_data &additional_data)
Definition: ros_reader.cpp:300
::realsense_legacy_msgs::pose_< std::allocator< void > > pose
Definition: pose.h:88
float rotation[9]
Definition: rs_sensor.h:98
GLenum GLuint id
std::shared_ptr< info_container > read_info_snapshot(const std::string &topic) const
GLuint index
std::shared_ptr< frame_source > m_frame_source
Definition: ros_reader.h:139
void close()
Close the bag file.
Definition: bag.cpp:161
static device_serializer::stream_identifier get_stream_identifier(const std::string &topic)
Definition: parser.hpp:154
def info(name, value, persistent=False)
Definition: test.py:301
rs2rosinternal::Time const & getTime() const
not_this_one begin(...)
void reset() override
Definition: ros_reader.cpp:151
GLdouble f
Duration representation for use with the Time class.
Definition: duration.h:108
std::set< uint32_t > read_sensor_indices(uint32_t device_index) const
uint32_t size()
Definition: view.cpp:229
std::shared_ptr< ::diagnostic_msgs::KeyValue const > KeyValueConstPtr
Definition: KeyValue.h:55
static std::shared_ptr< motion_stream_profile > create_motion_stream(rs2_stream stream_type, uint32_t stream_index, uint32_t fps, rs2_format format, rs2_motion_device_intrinsic intrinsics)
GLsizei GLenum const void * indices
dictionary streams
Definition: t265_stereo.py:140
std::vector< std::string > m_enabled_streams_topics
Definition: ros_reader.h:143
static std::map< std::string, std::string > get_frame_metadata(const rosbag::Bag &bag, const std::string &topic, const device_serializer::stream_identifier &stream_id, const rosbag::MessageInstance &msg, frame_additional_data &additional_data)
Definition: ros_reader.cpp:349
bool isType() const
Test whether the underlying message of the specified type.
static device_serializer::sensor_identifier get_sensor_identifier(const std::string &topic)
GLdouble GLdouble r
ivcam2::intrinsic_depth ros_l500_depth_data_to_intrinsic_depth(ros_reader::l500_depth_data data)
Definition: ros_reader.cpp:808
std::shared_ptr< serialized_frame > create_frame(const rosbag::MessageInstance &msg)
Definition: ros_reader.cpp:246
std::shared_ptr< extension_snapshot > find(rs2_extension t) const
static const std::set< std::uint16_t > rs400_sku_pid
Definition: ds5-private.h:65
std::shared_ptr< metadata_parser_map > m_metadata_parser_map
Definition: ros_reader.h:135
unsigned int uint32_t
Definition: stdint.h:80
constexpr uint32_t get_maximum_supported_legacy_file_version()
A class pointing into a bag file.
static std::string pose_accel_topic(const device_serializer::stream_identifier &stream_id)
static uint32_t read_file_version(const rosbag::Bag &file)
Definition: ros_reader.cpp:646
GLint GLint GLsizei GLint GLenum format
bool is_depth_sensor(std::string sensor_name)
Definition: ros_reader.cpp:866
Time representation. May either represent wall clock time or ROS clock time.
Definition: time.h:177
bool info_from_string(const std::string &str, rs2_camera_info &out)
rs2_format
A stream&#39;s format identifies how binary data is encoded within a frame.
Definition: rs_sensor.h:59
static std::string file_version_topic()
#define LOG_ERROR(...)
Definition: src/types.h:242
const std::string & get_file_name() const override
Definition: ros_reader.cpp:241
static std::string property_topic(const device_serializer::sensor_identifier &sensor_id)
void seek_to_time(const nanoseconds &seek_time) override
Definition: ros_reader.cpp:95
constexpr const char * SYSTEM_TIME_MD_STR
static std::string imu_intrinsic_topic(const device_serializer::stream_identifier &stream_id)
void add_sensor_extension(snapshot_collection &sensor_extensions, std::string sensor_name)
Definition: ros_reader.cpp:829
static std::string read_option_description(const rosbag::Bag &file, const std::string &topic)
constexpr const char * MAPPER_CONFIDENCE_MD_STR
std::vector< std::shared_ptr< stream_profile_interface >> stream_profiles
Definition: streaming.h:165
dictionary intrinsics
Definition: t265_stereo.py:142
rs2_stream
Streams are different types of data provided by RealSense devices.
Definition: rs_sensor.h:42
constexpr const char * TIMESTAMP_DOMAIN_MD_STR
std::chrono::duration< uint64_t, std::nano > nanoseconds
static void update_sensor_options(const rosbag::Bag &file, uint32_t sensor_index, const nanoseconds &time, uint32_t file_version, snapshot_collection &sensor_extensions, uint32_t version)
Definition: ros_reader.cpp:764
static std::string pose_twist_topic(const device_serializer::stream_identifier &stream_id)
std::shared_ptr< serialized_data > read_next_data() override
Definition: ros_reader.cpp:49
std::vector< std::shared_ptr< serialized_data > > fetch_last_frames(const nanoseconds &seek_time) override
Definition: ros_reader.cpp:116
static std::string frame_metadata_topic(const device_serializer::stream_identifier &stream_id)
device_serializer::stream_identifier get_stream_identifier(const std::string &topic)
GLsizei const GLfloat * values
_distortion_model_type distortion_model
Definition: CameraInfo.h:79
Cross-stream extrinsics: encodes the topology describing how the different devices are oriented...
Definition: rs_sensor.h:96
virtual std::shared_ptr< stream_profile_interface > get_stream() const =0
float disparity
Definition: t265_stereo.py:241
stream_descriptor parse_stream_type(const std::string &source)
std::shared_ptr< info_container > read_legacy_info_snapshot(uint32_t sensor_index) const
void assign(int width, int height, int stride, int bpp)
Definition: archive.h:284
unsigned char byte
Definition: src/types.h:52
GLdouble GLdouble GLdouble q
constexpr device_serializer::nanoseconds get_static_file_info_timestamp()
static nanoseconds get_file_duration(const rosbag::Bag &file, uint32_t version)
Definition: ros_reader.cpp:288
static std::string option_value_topic(const device_serializer::sensor_identifier &sensor_id, rs2_option option_type)
rs2_extension
Specifies advanced interfaces (capabilities) objects may implement.
Definition: rs_types.h:166
ROSTIME_DECL const Time TIME_MIN
static std::pair< rs2_option, std::shared_ptr< librealsense::option > > create_property(const rosbag::MessageInstance &property_message_instance)
GLenum query
rs2_notification_category
Category of the librealsense notification.
Definition: rs_types.h:17
int stream_id
Definition: sync.h:17
static auto it
long long rs2_metadata_type
Definition: rs_types.h:301
GLenum type
bool is_ds5_PID(int pid)
Definition: ros_reader.cpp:894
iterator end()
Default constructed iterator signifies end.
Definition: view.cpp:227
rs2_timestamp_domain timestamp_domain
Definition: archive.h:32
constexpr uint32_t get_minimum_supported_file_version()
rs2_timestamp_domain convert(uint64_t source)
void update_l500_depth_sensor(const rosbag::Bag &file, uint32_t sensor_index, const nanoseconds &time, uint32_t file_version, snapshot_collection &sensor_extensions, uint32_t version, std::string pid, std::string sensor_name)
Definition: ros_reader.cpp:845
signed __int64 int64_t
Definition: stdint.h:89
std::string const & getTopic() const
const uint16_t SR306_PID
static uint32_t get_extrinsic_group_index(const std::string &topic)
iterator begin()
Simply copy the merge_queue state into the iterator.
Definition: view.cpp:221
typename::boost::move_detail::remove_reference< T >::type && move(T &&t) BOOST_NOEXCEPT
Video stream intrinsics.
Definition: rs_types.h:58
void update_proccesing_blocks(const rosbag::Bag &file, uint32_t sensor_index, const nanoseconds &time, uint32_t file_version, snapshot_collection &sensor_extensions, uint32_t version, std::string pid, std::string sensor_name)
Definition: ros_reader.cpp:787
device_snapshot query_device_description(const nanoseconds &time) override
Definition: ros_reader.cpp:44
bool is_fisheye_module_sensor(std::string sensor_name)
Definition: ros_reader.cpp:887
std::string const & getDataType() const
std::ostream & cerr()
bool is_color_sensor(std::string sensor_name)
Definition: ros_reader.cpp:873
int stoi(const std::string &value)
Motion device intrinsics: scale, bias, and variances.
Definition: rs_types.h:103
bool is_motion_module_sensor(std::string sensor_name)
Definition: ros_reader.cpp:880
#define NULL
Definition: tinycthread.c:47
int i
static std::shared_ptr< video_stream_profile > create_video_stream_profile(const platform::stream_profile &sp, const sensor_msgs::CameraInfo &ci, const stream_descriptor &sd)
GLuint res
Definition: glext.h:8856
rosbag::View::iterator m_samples_itrator
Definition: ros_reader.h:142
GLuint GLenum GLenum transform
Definition: glext.h:11553
#define LOG_DEBUG(...)
Definition: src/types.h:239
const uint16_t SR300_PID
frame_holder create_pose_sample(const rosbag::MessageInstance &msg) const
Definition: ros_reader.cpp:538
bool try_read_legacy_stream_extrinsic(const stream_identifier &stream_id, uint32_t &group_id, rs2_extrinsics &extrinsic) const
Definition: ros_reader.cpp:680
frame_holder create_motion_sample(const rosbag::MessageInstance &motion_data) const
Definition: ros_reader.cpp:454
::std_msgs::Time_< std::allocator< void > > Time
Definition: Time.h:47
void addQuery(Bag const &bag, rs2rosinternal::Time const &start_time=rs2rosinternal::TIME_MIN, rs2rosinternal::Time const &end_time=rs2rosinternal::TIME_MAX)
Add a query to a view.
Definition: view.cpp:248
rs2_log_severity
Severity of the librealsense logger.
Definition: rs_types.h:153
std::array< uint8_t, MAX_META_DATA_SIZE > metadata_blob
Definition: archive.h:37
std::vector< sensor_snapshot > get_sensors_snapshots() const
pinhole_camera_model pinhole_cam_model
Definition: l500-private.h:345
GLuint64EXT * result
Definition: glext.h:10921
static std::vector< std::string > get_topics(std::unique_ptr< rosbag::View > &view)
GLdouble v
const uint16_t L500_PID
Definition: l500-private.h:20
Definition: parser.hpp:150
rs2_frame_metadata_value
Per-Frame-Metadata is the set of read-only properties that might be exposed for each individual frame...
Definition: rs_frame.h:29
int get_height() const
Definition: archive.h:280
void copy(void *dst, void const *src, size_t size)
Definition: types.cpp:836
l500_data_per_resolution data[MAX_NUM_OF_DEPTH_RESOLUTIONS]
Definition: ros_reader.h:124
constexpr uint32_t get_device_index()
std::vector< byte > data
Definition: archive.h:100
bool is_sr300_PID(int pid)
Definition: ros_reader.cpp:906
virtual void set_stream(std::shared_ptr< stream_profile_interface > sp)=0
unsigned long stoul(const std::string &value)
static std::string stream_full_prefix(const device_serializer::stream_identifier &stream_id)
static std::shared_ptr< pose_stream_profile > create_pose_profile(uint32_t stream_index, uint32_t fps)
std::string to_string(T value)


librealsense2
Author(s): Sergey Dorodnicov , Doron Hirshberg , Mark Horn , Reagan Lopez , Itay Carpis
autogenerated on Mon May 3 2021 02:47:40