l500-color.cpp
Go to the documentation of this file.
1 // License: Apache 2.0. See LICENSE file in root directory.
2 // Copyright(c) 2018 Intel Corporation. All Rights Reserved.
3 
4 #include "l500-color.h"
5 
6 #include <cstddef>
7 #include <mutex>
8 
9 
10 
11 #include "l500-private.h"
13 #include "ac-trigger.h"
16 
17 
18 namespace librealsense
19 {
20  using namespace ivcam2;
21 
22  std::map<uint32_t, rs2_format> l500_color_fourcc_to_rs2_format = {
23  {rs_fourcc('Y','U','Y','2'), RS2_FORMAT_YUYV},
24  {rs_fourcc('Y','U','Y','V'), RS2_FORMAT_YUYV},
25  {rs_fourcc('U','Y','V','Y'), RS2_FORMAT_UYVY}
26  };
27 
28  std::map<uint32_t, rs2_stream> l500_color_fourcc_to_rs2_stream = {
29  {rs_fourcc('Y','U','Y','2'), RS2_STREAM_COLOR},
30  {rs_fourcc('Y','U','Y','V'), RS2_STREAM_COLOR},
31  {rs_fourcc('U','Y','V','Y'), RS2_STREAM_COLOR}
32  };
33 
34  std::shared_ptr<synthetic_sensor> l500_color::create_color_device(std::shared_ptr<context> ctx, const std::vector<platform::uvc_device_info>& color_devices_info)
35  {
36  auto&& backend = ctx->get_backend();
37 
38  std::unique_ptr<frame_timestamp_reader> timestamp_reader_metadata(new ivcam2::l500_timestamp_reader_from_metadata(backend.create_time_service()));
39  auto enable_global_time_option = std::shared_ptr<global_time_option>(new global_time_option());
40  auto raw_color_ep = std::make_shared<uvc_sensor>("RGB Camera", ctx->get_backend().create_uvc_device(color_devices_info.front()),
41  std::unique_ptr<frame_timestamp_reader>(new global_timestamp_reader(std::move(timestamp_reader_metadata), _tf_keeper, enable_global_time_option)),
42  this);
43  auto color_ep = std::make_shared<l500_color_sensor>(this, raw_color_ep, ctx, l500_color_fourcc_to_rs2_format, l500_color_fourcc_to_rs2_stream);
44 
45  color_ep->register_info(RS2_CAMERA_INFO_PHYSICAL_PORT, color_devices_info.front().device_path);
46 
47  // processing blocks
48  if( _autocal )
49  {
50  color_ep->register_processing_block(
51  processing_block_factory::create_pbf_vector< yuy2_converter >(
52  RS2_FORMAT_YUYV, // from
53  map_supported_color_formats( RS2_FORMAT_YUYV ), RS2_STREAM_COLOR, // to
54  [=]( std::shared_ptr< generic_processing_block > pb )
55  {
56  auto cpb = std::make_shared< composite_processing_block >();
57  cpb->add(std::make_shared< ac_trigger::color_processing_block >(_autocal));
58  cpb->add( pb );
59  return cpb;
60  } ) );
61  }
62  else
63  {
64  color_ep->register_processing_block(
65  processing_block_factory::create_pbf_vector< yuy2_converter >(
66  RS2_FORMAT_YUYV, // from
67  map_supported_color_formats( RS2_FORMAT_YUYV ), RS2_STREAM_COLOR ) ); // to
68  }
69 
70  // options
71  color_ep->register_option(RS2_OPTION_GLOBAL_TIME_ENABLED, enable_global_time_option);
72  color_ep->get_option(RS2_OPTION_GLOBAL_TIME_ENABLED).set(0);
73  color_ep->register_pu(RS2_OPTION_BACKLIGHT_COMPENSATION);
74  color_ep->register_pu(RS2_OPTION_BRIGHTNESS);
75  color_ep->register_pu(RS2_OPTION_CONTRAST);
76  color_ep->register_pu(RS2_OPTION_GAIN);
77  color_ep->register_pu(RS2_OPTION_HUE);
78  color_ep->register_pu(RS2_OPTION_SATURATION);
79  color_ep->register_pu(RS2_OPTION_SHARPNESS);
80  color_ep->register_pu(RS2_OPTION_AUTO_EXPOSURE_PRIORITY);
81 
82  color_ep->register_option(RS2_OPTION_GLOBAL_TIME_ENABLED, enable_global_time_option);
83 
84  auto white_balance_option = std::make_shared<uvc_pu_option>(*raw_color_ep, RS2_OPTION_WHITE_BALANCE);
85  auto auto_white_balance_option = std::make_shared<uvc_pu_option>(*raw_color_ep, RS2_OPTION_ENABLE_AUTO_WHITE_BALANCE);
86  color_ep->register_option(RS2_OPTION_WHITE_BALANCE, white_balance_option);
87  color_ep->register_option(RS2_OPTION_ENABLE_AUTO_WHITE_BALANCE, auto_white_balance_option);
88  color_ep->register_option(RS2_OPTION_WHITE_BALANCE,
89  std::make_shared<auto_disabling_control>(
90  white_balance_option,
91  auto_white_balance_option));
92 
93  auto exposure_option = std::make_shared<uvc_pu_option>(*raw_color_ep, RS2_OPTION_EXPOSURE);
94  auto auto_exposure_option = std::make_shared<uvc_pu_option>(*raw_color_ep, RS2_OPTION_ENABLE_AUTO_EXPOSURE);
95  color_ep->register_option(RS2_OPTION_EXPOSURE, exposure_option);
96  color_ep->register_option(RS2_OPTION_ENABLE_AUTO_EXPOSURE, auto_exposure_option);
97  color_ep->register_option(RS2_OPTION_EXPOSURE,
98  std::make_shared<auto_disabling_control>(
100  auto_exposure_option));
101 
102  color_ep->register_option(RS2_OPTION_POWER_LINE_FREQUENCY,
103  std::make_shared<uvc_pu_option>(*raw_color_ep, RS2_OPTION_POWER_LINE_FREQUENCY,
104  std::map<float, std::string>{ { 0.f, "Disabled"},
105  { 1.f, "50Hz" },
106  { 2.f, "60Hz" },
107  { 3.f, "Auto" }, }));
108 
109 
110  // option to enable workaround for help weak usb hosts to support L515 devices
111  // with improved performance and stability
112  if(_fw_version >= firmware_version( "1.5.1.0" ) )
113  {
114  rs2_host_perf_mode launch_perf_mode = RS2_HOST_PERF_DEFAULT;
115 
116 #ifdef __ANDROID__
117  // android devices most likely low power low performance host
118  launch_perf_mode = RS2_HOST_PERF_LOW;
119 #else
120  // other hosts use default settings from firmware, user still have the option to change later after launch
121  launch_perf_mode = RS2_HOST_PERF_DEFAULT;
122 #endif
123 
124  color_ep->register_option(RS2_OPTION_HOST_PERFORMANCE, std::make_shared<librealsense::float_option_with_description<rs2_host_perf_mode>>(option_range{ RS2_HOST_PERF_DEFAULT, RS2_HOST_PERF_COUNT - 1, 1, (float) launch_perf_mode }, "Optimize based on host performance, low power low performance host or high power high performance host"));
125  }
126 
127  // metadata
128  // attributes of md_capture_timing
129  auto md_prop_offset = offsetof(metadata_raw, mode) +
130  offsetof(md_rgb_normal_mode, intel_capture_timing);
131 
135 
136  // attributes of md_capture_stats
137  md_prop_offset = offsetof(metadata_raw, mode) +
138  offsetof(md_rgb_normal_mode, intel_capture_stats);
139 
141 
142  // attributes of md_rgb_control
143  md_prop_offset = offsetof(metadata_raw, mode) +
144  offsetof(md_rgb_normal_mode, intel_rgb_control);
145 
149  [](rs2_metadata_type param) { return (param != 1); }));
162 
163  // We manipulate several controls when the CAH process turn on/off the color stream
164  // This should be done after registration of the device options
165  if (_autocal)
166  {
167  color_ep->register_calibration_controls();
168  }
169 
170  return color_ep;
171  }
172 
174  :device(ctx, group),
175  l500_device(ctx, group),
176  _color_stream(new stream(RS2_STREAM_COLOR))
177  {
178  auto color_devs_info = filter_by_mi(group.uvc_devices, 4);
179  if (color_devs_info.size() != 1)
180  throw invalid_value_exception(to_string() << "L500 with RGB models are expected to include a single color device! - "
181  << color_devs_info.size() << " found");
182 
183  _color_intrinsics_table = [this]() { return read_intrinsics_table(); };
184  _color_extrinsics_table_raw = [this]() { return get_raw_extrinsics_table(); };
185 
186  // This lazy instance will get shared between all the extrinsics edges. If you ever need to override
187  // it, be careful not to overwrite the shared-ptr itself (register_extrinsics) or the sharing
188  // will get ruined. Instead, overwriting the lazy<> function should do it:
189  // *_color_extrinsic = [=]() { return extr; };
190  _color_extrinsic = std::make_shared<lazy<rs2_extrinsics>>(
191  [this]()
192  {
194  } );
197 
198  _thermal_table = [this]() {
199 
200  hwmon_response response;
203  response );
204  if( response != hwm_Success )
205  {
206  AC_LOG( WARNING,
207  "Failed to read FW table 0x"
208  << std::hex
211  to_string() << "Failed to read FW table 0x" << std::hex
213  }
214 
215  if( data.size() > sizeof( table_header ))
216  data.erase( data.begin(), data.begin() + sizeof( table_header ) );
218  };
219 
220  _color_device_idx = add_sensor(create_color_device(ctx, color_devs_info));
221  }
222 
224  {
225  return &dynamic_cast< l500_color_sensor & >( get_sensor( _color_device_idx ));
226  }
227 
228 
230  uint32_t const height ) const
231  {
232  using namespace ivcam2;
233 
234  auto & intrinsic = *_owner->_color_intrinsics_table;
235 
236  auto num_of_res = intrinsic.resolution.num_of_resolutions;
237 
238  for( auto i = 0; i < num_of_res; i++ )
239  {
240  auto model = intrinsic.resolution.intrinsic_resolution[i];
241  if( model.height == height && model.width == width )
242  {
244  intrinsics.width = model.width;
245  intrinsics.height = model.height;
246  intrinsics.fx = model.ipm.focal_length.x;
247  intrinsics.fy = model.ipm.focal_length.y;
248  intrinsics.ppx = model.ipm.principal_point.x;
249  intrinsics.ppy = model.ipm.principal_point.y;
250 
251  if( model.distort.radial_k1 || model.distort.radial_k2
252  || model.distort.tangential_p1 || model.distort.tangential_p2
253  || model.distort.radial_k3 )
254  {
255  intrinsics.coeffs[0] = model.distort.radial_k1;
256  intrinsics.coeffs[1] = model.distort.radial_k2;
257  intrinsics.coeffs[2] = model.distort.tangential_p1;
258  intrinsics.coeffs[3] = model.distort.tangential_p2;
259  intrinsics.coeffs[4] = model.distort.radial_k3;
260 
261  intrinsics.model = l500_distortion;
262 
263  }
264 
265  return intrinsics;
266  }
267  }
268  throw std::runtime_error( to_string() << "intrinsics for resolution " << width << ","
269  << height << " don't exist" );
270  }
271 
273  {
274  auto res = intr;
275  res.fx = 2 * intr.fx / intr.width;
276  res.fy = 2 * intr.fy / intr.height;
277  res.ppx = 2 * intr.ppx / intr.width - 1;
278  res.ppy = 2 * intr.ppy / intr.height - 1;
279 
280  return res;
281  }
282 
285  {
286  auto res = intr;
287 
288  res.fx = intr.fx * width / 2;
289  res.fy = intr.fy * height / 2;
290  res.ppx = ( intr.ppx + 1 ) * width / 2;
291  res.ppy = ( intr.ppy + 1 ) * height / 2;
292 
293  res.width = width;
294  res.height = height;
295 
296  return res;
297  }
298 
299 
301  {
302  if( ! _k_thermal_intrinsics)
303  {
304  // Until we've calculated temp-based intrinsics, simply use the camera-specified
305  // intrinsics
306  return get_raw_intrinsics( profile.width, profile.height );
307  }
308 
309  return denormalize( *_k_thermal_intrinsics, profile.width, profile.height );
310  }
311 
312 
314  {
315  // TODO: we currently use the wrong distortion model, but all the code is
316  // written to expect the INVERSE brown. The table assumes REGULAR brown.
317  return { width, height,
318  intr.px, intr.py, // NOTE: this is normalized!
319  intr.fx, intr.fy, // NOTE: this is normalized!
320  RS2_DISTORTION_INVERSE_BROWN_CONRADY, // see comment above
321  { intr.d[0], intr.d[1], intr.d[2], intr.d[3], intr.d[4] } };
322  }
323 
325  {
326  // The table in FW is resolution-agnostic; it can apply to ALL resolutions. To
327  // do this, the focal length and principal point are normalized:
328  auto norm = normalize( i );
329 
330  width = i.width;
331  height = i.height;
332  intr.fx = norm.fx;
333  intr.fy = norm.fy;
334  intr.px = norm.ppx;
335  intr.py = norm.ppy;
336  intr.d[0] = i.coeffs[0];
337  intr.d[1] = i.coeffs[1];
338  intr.d[2] = i.coeffs[2];
339  intr.d[3] = i.coeffs[3];
340  intr.d[4] = i.coeffs[4];
341  }
342 
343 
345  {
346  // The distortion model is not part of the table. The FW assumes it is brown,
347  // but in LRS we (mistakenly) use INVERSE brown. We therefore make sure the user
348  // has not tried to change anything from the intrinsics reported:
349 
350  if( intr.model != l500_distortion)
351  throw invalid_value_exception("invalid intrinsics distortion model");
352 
354  AC_LOG( DEBUG, "Reading RGB calibration table 0x" << std::hex << table.table_id );
355  ivcam2::read_fw_table( *_owner->_hw_monitor, table.table_id, &table );
356  AC_LOG( DEBUG, " version: " << table.version );
357  AC_LOG( DEBUG, " timestamp: " << table.timestamp << "; incrementing" );
358  AC_LOG( DEBUG, " type: " << table.type << "; setting to 0x10" );
359  AC_LOG( DEBUG, " intrinsics: " << table.get_intrinsics() );
360  table.set_intrinsics( intr );
361  AC_LOG( INFO, "Overriding intr: " << intr );
362  AC_LOG( DEBUG, " normalized: " << table.get_intrinsics() );
363  table.update_write_fields();
364  write_fw_table( *_owner->_hw_monitor, table.table_id, table );
365  AC_LOG( DEBUG, " done" );
366 
367  // Intrinsics are resolution-specific, so all the rest of the profile info is not
368  // important
369  _owner->_color_intrinsics_table.reset();
370  reset_k_thermal_intrinsics();
371  }
372 
374  {
376  AC_LOG( DEBUG, "Reading RGB calibration table 0x" << std::hex << table.table_id );
377  ivcam2::read_fw_table( *_owner->_hw_monitor, table.table_id, &table );
378  AC_LOG( DEBUG, " version: " << table.version );
379  AC_LOG( DEBUG, " timestamp: " << table.timestamp << "; incrementing" );
380  AC_LOG( DEBUG, " type: " << table.type << "; setting to 0x10" );
381  AC_LOG( DEBUG, " raw extr: " << table.get_extrinsics() );
382  table.extr = to_raw_extrinsics(extr);
383  AC_LOG( INFO , "Overriding extr: " << extr );
384  table.update_write_fields();
385  AC_LOG( DEBUG, " as raw: " << table.get_extrinsics());
386  ivcam2::write_fw_table( *_owner->_hw_monitor, table.table_id, table );
387  AC_LOG( DEBUG, " done" );
388 
389 
390  environment::get_instance().get_extrinsics_graph().override_extrinsics( *_owner->_depth_stream, *_owner->_color_stream, extr );
391  }
392 
394  {
395  throw std::logic_error( "color sensor does not support DSM parameters" );
396  }
397 
399  {
400  throw std::logic_error( "color sensor does not support DSM parameters" );
401  }
402 
404  {
405 
406  _k_thermal_intrinsics = std::make_shared< rs2_intrinsics >( normalize(intr) );
407  }
408 
410  {
411  _k_thermal_intrinsics.reset();
412  }
413 
415  {
416  return *_owner->_thermal_table;
417  }
418 
420  {
421  // We don't touch the version...
422  //version = ;
423 
424  // This signifies AC results:
425  type = 0x10;
426 
427  // The time-stamp is simply a sequential number that we increment
428  ++timestamp;
429  }
430 
432  {
433  // Read from EEPROM (factory defaults), write to FLASH (current)
434  // Note that factory defaults may be different than the trinsics at the time of
435  // our initialization!
437  AC_LOG( DEBUG, "Reading factory calibration from table 0x" << std::hex << table.eeprom_table_id );
438  ivcam2::read_fw_table( *_owner->_hw_monitor, table.eeprom_table_id, &table );
439  AC_LOG( DEBUG, " version: " << table.version );
440  AC_LOG( DEBUG, " timestamp: " << table.timestamp << "; incrementing" );
441  AC_LOG( DEBUG, " type: " << table.type << "; setting to 0x10" );
442  AC_LOG( DEBUG, "Normalized:" );
443  AC_LOG( DEBUG, " intrinsics: " << table.get_intrinsics() );
444  AC_LOG( DEBUG, " extrinsics: " << table.get_extrinsics() );
445  AC_LOG( DEBUG, "Writing RGB calibration table 0x" << std::hex << table.table_id );
446  ivcam2::write_fw_table( *_owner->_hw_monitor, table.table_id, table );
447  AC_LOG( DEBUG, " done" );
448 
449  _owner->_color_intrinsics_table.reset();
450  reset_k_thermal_intrinsics();
451 
453  *_owner->_depth_stream,
454  *_owner->_color_stream,
455  from_raw_extrinsics( table.get_extrinsics() ) );
456  AC_LOG( INFO, "Color sensor calibration has been reset" );
457  }
458 
460  {
461  std::lock_guard<std::mutex> lock(_state_mutex);
462 
463  if (_state != sensor_state::OWNED_BY_USER)
464  throw wrong_api_call_sequence_exception("tried to start an unopened sensor");
465 
466  if (supports_option(RS2_OPTION_HOST_PERFORMANCE))
467  {
468  // option to improve performance and stability on weak android hosts
469  // please refer to following bug report for details
470  // RS5-8011 [Android-L500 Hard failure] Device detach and disappear from system during stream
471 
472  auto host_perf = get_option(RS2_OPTION_HOST_PERFORMANCE).query();
473 
474  if (host_perf == RS2_HOST_PERF_LOW || host_perf == RS2_HOST_PERF_HIGH)
475  {
476  // TPROC USB Granularity and TRB threshold settings for improved performance and stability
477  // on hosts with weak cpu and system performance
478  // settings values are validated through many experiments, do not change
479 
480  // on low power low performance host, usb trb set to larger granularity to reduce number of transactions
481  // and improve performance
482  int usb_trb = 7; // 7 KB
483 
484  if (host_perf == RS2_HOST_PERF_LOW)
485  {
486  usb_trb = 32; // 32 KB
487  }
488 
489  try {
490  // Keep the USB power on while triggering multiple calls on it.
491  ivcam2::group_multiple_fw_calls(*this, [&]() {
492  // endpoint 5 - 32KB
493  command cmdTprocGranEp5(ivcam2::TPROC_USB_GRAN_SET, 5, usb_trb);
494  _owner->_hw_monitor->send(cmdTprocGranEp5);
495 
496  command cmdTprocThresholdEp5(ivcam2::TPROC_TRB_THRSLD_SET, 5, 1);
497  _owner->_hw_monitor->send(cmdTprocThresholdEp5);
498  });
499  LOG_DEBUG("Color usb tproc granularity and TRB threshold updated.");
500  } catch (...)
501  {
502  LOG_WARNING("Failed to update color usb tproc granularity and TRB threshold. performance and stability maybe impacted on certain platforms.");
503  }
504  }
505  else if (host_perf == RS2_HOST_PERF_DEFAULT)
506  {
507  LOG_DEBUG("Default host performance mode, color usb tproc granularity and TRB threshold not changed");
508  }
509  }
510 
511  delayed_start(callback);
512  }
513 
514 
516  {
517  std::lock_guard<std::mutex> lock(_state_mutex);
518 
519  // Protect not stopping the calibration color stream due to wrong API sequence
520  if (_state != sensor_state::OWNED_BY_USER)
521  throw wrong_api_call_sequence_exception("tried to stop sensor without starting it");
522 
523  delayed_stop();
524  }
525 
526 
527  void l500_color_sensor::open( const stream_profiles & requests )
528  {
529  std::lock_guard< std::mutex > lock( _state_mutex );
530 
531  if( sensor_state::OWNED_BY_AUTO_CAL == _state )
532  {
533  if( is_streaming() )
534  {
535  delayed_stop();
536  }
537  if( is_opened() )
538  {
539  AC_LOG( DEBUG, "Calibration color stream was on, Closing color sensor..." );
541  }
542 
543  restore_pre_calibration_controls();
544 
545  set_sensor_state( sensor_state::CLOSED );
546  }
547 
548  synthetic_sensor::open( requests );
549  set_sensor_state( sensor_state::OWNED_BY_USER );
550  }
551 
552 
554  {
555  std::lock_guard< std::mutex > lock( _state_mutex );
556 
557  if( _state != sensor_state::OWNED_BY_USER )
558  throw wrong_api_call_sequence_exception( "tried to close sensor without opening it" );
559 
561  set_sensor_state(sensor_state::CLOSED);
562  }
563 
564  // Helper function for start stream callback
565  template<class T>
567  {
568  return {
570  [](rs2_frame_callback* p) { p->release(); }
571  };
572  }
573 
575  {
576  std::lock_guard< std::mutex > lock( _state_mutex );
577 
578  // Allow calibration process to open the color stream only if it is not started by the user.
579  if( _state == sensor_state::CLOSED )
580  {
581  set_calibration_controls_to_defaults();
582 
583  synthetic_sensor::open(requests);
584  set_sensor_state(sensor_state::OWNED_BY_AUTO_CAL);
585  AC_LOG( DEBUG, "Starting color sensor stream -- for calibration" );
586  delayed_start( make_frame_callback( [&]( frame_holder fref ) {} ) );
587  return true;
588  }
589  if( ! is_streaming() )
590  {
591  // This is a corner case that is not covered at the moment: The user opened the sensor
592  // but did not start it.
593  AC_LOG( WARNING,
594  "The color sensor was opened but never started by the user; streaming may not work" );
595  }
596  else
597  AC_LOG( DEBUG, "Color sensor is already streaming (" << state_to_string(_state) << ")" );
598  return false;
599  }
600 
602  {
603  std::lock_guard< std::mutex > lock( _state_mutex );
604 
605  if( _state == sensor_state::OWNED_BY_AUTO_CAL )
606  {
607  AC_LOG(DEBUG, "Closing color sensor stream from calibration");
608 
609  if( is_streaming() )
610  {
611  delayed_stop();
612 
613  }
614  if (is_opened())
615  {
617  }
618 
619  restore_pre_calibration_controls();
620 
621  // If we got here with no exception it means the start has succeeded.
622  set_sensor_state( sensor_state::CLOSED );
623  }
624  else
625  {
626  AC_LOG( DEBUG, "Color sensor was not opened by us; no need to close" );
627  }
628  }
629 
631  {
632  switch (state)
633  {
634  case sensor_state::CLOSED:
635  return "CLOSED";
636  case sensor_state::OWNED_BY_AUTO_CAL:
637  return "OWNED_BY_AUTO_CAL";
638  case sensor_state::OWNED_BY_USER:
639  return "OWNED_BY_USER";
640  default:
641  LOG_DEBUG("Invalid color sensor state: " << static_cast<int>(state));
642  return "Unknown state";
643  }
644  }
645 
646 
648  {
649  for (auto && calib_control : _calib_controls)
650  {
651  auto && control = get_option(calib_control.option);
652 
653  auto curr_val = control.query();
654  if (curr_val != calib_control.default_value)
655  {
656  AC_LOG(DEBUG, "Calibration - changed option: " << rs2_option_to_string( calib_control.option ) << " value,"
657  << " from: " << curr_val
658  << " to: " << calib_control.default_value );
659  calib_control.need_to_restore = true;
660  calib_control.previous_value = curr_val;
661  control.set(calib_control.default_value);
662  }
663  else
664  {
665  AC_LOG(DEBUG, "Calibration - no need to changed option: " << rs2_option_to_string(calib_control.option) << " value,"
666  << " current value is: " << curr_val
667  << " which is the default value");
668  }
669  }
670  }
671 
673  {
674  for (auto && calib_control : _calib_controls)
675  {
676  auto && control = get_option(calib_control.option);
677 
678  auto curr_val = control.query();
679  if( calib_control.need_to_restore &&
680  ( curr_val == calib_control.default_value ) )
681  {
682  AC_LOG(DEBUG, "Calibration - restored option: " << rs2_option_to_string(calib_control.option) << " value,"
683  << " from: " << curr_val
684  << " to: " << calib_control.previous_value);
685  control.set(calib_control.previous_value);
686  }
687  else
688  {
689  std::stringstream ss;
690  ss << "Calibration - no need to restore option : "
691  << rs2_option_to_string( calib_control.option ) << " value, "
692  << " current value is: " << curr_val;
693 
694  if( curr_val == calib_control.default_value ) ss << " which is the default value";
695  else ss << " which is the user value";
696 
697  AC_LOG(DEBUG, ss.str());
698  }
699  calib_control.need_to_restore = false;
700  }
701  }
702 
704  {
705  for( auto && option : { RS2_OPTION_ENABLE_AUTO_EXPOSURE,
709  {
710  auto && control = get_option(option);
711  _calib_controls.push_back({ option, control.get_range().def });
712  }
713  }
714 
715  std::vector<tagged_profile> l500_color::get_profiles_tags() const
716  {
717  std::vector<tagged_profile> tags;
718 
720 
721  int width = usb3mode ? 1280 : 960;
722  int height = usb3mode ? 720 : 540;
723 
725 
726  return tags;
727  }
728 
730  {
731  // Get RAW data from firmware
732  AC_LOG(DEBUG, "RGB_INTRINSIC_GET");
733  std::vector< uint8_t > response_vec = _hw_monitor->send(command{ RGB_INTRINSIC_GET });
734 
735  if (response_vec.empty())
736  throw invalid_value_exception("Calibration data invalid,buffer size is zero");
737 
738  auto resolutions_rgb_table_ptr = reinterpret_cast<const ivcam2::intrinsic_rgb *>(response_vec.data());
739  auto num_of_resolutions = resolutions_rgb_table_ptr->resolution.num_of_resolutions;
740 
741  // Get full maximum size of the resolution array and deduct the unused resolutions size from it
742  size_t expected_size = sizeof( ivcam2::intrinsic_rgb )
744  - num_of_resolutions)
745  * sizeof( pinhole_camera_model ) );
746 
747  // Validate table size
748  // FW API guarantee only as many bytes as required for the given number of resolutions,
749  // The FW keeps the right to send more bytes.
750  if (expected_size > response_vec.size() ||
751  num_of_resolutions > MAX_NUM_OF_RGB_RESOLUTIONS)
752  {
754  to_string() << "Calibration data invalid, number of resolutions is: " << num_of_resolutions <<
755  ", expected size: " << expected_size << " , actual size: " << response_vec.size());
756  }
757 
758  // Set a new memory allocated intrinsics struct (Full size 5 resolutions)
759  // Copy the relevant data from the dynamic resolution received from the FW
760  ivcam2::intrinsic_rgb resolutions_rgb_table_output;
761  librealsense::copy(&resolutions_rgb_table_output, resolutions_rgb_table_ptr, expected_size);
762 
763  return resolutions_rgb_table_output;
764  }
765  std::vector<uint8_t> l500_color::get_raw_extrinsics_table() const
766  {
767  AC_LOG( DEBUG, "RGB_EXTRINSIC_GET" );
768  return _hw_monitor->send(command{ RGB_EXTRINSIC_GET });
769  }
770 }
std::shared_ptr< hw_monitor > _hw_monitor
Definition: l500-device.h:91
static const textual_icon lock
Definition: model-views.h:218
std::shared_ptr< lazy< rs2_extrinsics > > _color_extrinsic
Definition: l500-color.h:45
void start(frame_callback_ptr callback) override
Definition: l500-color.cpp:459
l500_color(std::shared_ptr< context > ctx, const platform::backend_device_group &group)
Definition: l500-color.cpp:173
std::string state_to_string(sensor_state state)
Definition: l500-color.cpp:630
void open(const stream_profiles &requests) override
Definition: sensor.cpp:1422
metadata_raw - metadata structure layout as transmitted and received by backend
Definition: src/metadata.h:678
std::shared_ptr< rs2_frame_callback > frame_callback_ptr
Definition: src/types.h:1071
GLfloat GLfloat p
Definition: glext.h:12687
void open(const stream_profiles &requests) override
Definition: l500-color.cpp:527
std::shared_ptr< stream_interface > _color_stream
Definition: l500-color.h:36
rs2_dsm_params get_dsm_params() const override
Definition: l500-color.cpp:393
#define LOG_WARNING(...)
Definition: src/types.h:241
const char * rs2_option_to_string(rs2_option option)
Definition: rs.cpp:1265
Video DSM (Digital Sync Module) parameters for calibration (same layout as in FW ac_depth_params) Thi...
Definition: rs_types.h:74
void set_intrinsics(rs2_intrinsics const &)
Definition: l500-color.cpp:324
rs2_intrinsics denormalize(const rs2_intrinsics &intr, const uint32_t &width, const uint32_t &height)
Definition: l500-color.cpp:284
std::map< uint32_t, rs2_format > l500_color_fourcc_to_rs2_format
Definition: l500-color.cpp:22
void override_dsm_params(rs2_dsm_params const &dsm_params) override
Definition: l500-color.cpp:398
float coeffs[5]
Definition: rs_types.h:67
GLsizei const GLchar *const * string
void override_extrinsics(const stream_interface &from, const stream_interface &to, rs2_extrinsics const &extr)
Definition: environment.cpp:55
platform::usb_spec _usb_mode
Definition: l500-device.h:114
rs2_host_perf_mode
values for RS2_OPTION_HOST_PERFORMANCE option.
Definition: rs_option.h:202
std::shared_ptr< stream_interface > _depth_stream
Definition: l500-device.h:98
rs2_intrinsics get_raw_intrinsics(uint32_t width, uint32_t height) const
Definition: l500-color.cpp:229
virtual void release()=0
ivcam2::intrinsic_rgb read_intrinsics_table() const
Definition: l500-color.cpp:729
algo::thermal_loop::l500::thermal_calibration_table get_thermal_table() const
Definition: l500-color.cpp:414
void register_extrinsics(const stream_interface &from, const stream_interface &to, std::weak_ptr< lazy< rs2_extrinsics >> extr)
Definition: environment.cpp:28
GLenum mode
GLuint GLenum option
Definition: glext.h:5923
rs2_extrinsics to_raw_extrinsics(rs2_extrinsics extr)
Definition: types.cpp:26
rs2_extrinsics from_raw_extrinsics(rs2_extrinsics extr)
Definition: types.cpp:39
unsigned int uint32_t
Definition: stdint.h:80
GLboolean GLuint group
Definition: glext.h:5688
uint32_t rs_fourcc(const T a, const T b, const T c, const T d)
Definition: src/types.h:1846
GLint GLsizei GLsizei height
rs2_intrinsics get_intrinsics(const stream_profile &profile) const override
Definition: l500-color.cpp:300
rs2_intrinsics normalize(const rs2_intrinsics &intr)
Definition: l500-color.cpp:272
static std::vector< byte > read_fw_table_raw(const hw_monitor &hwm, int table_id, hwmon_response &response)
Definition: l500-private.h:95
def callback(frame)
Definition: t265_stereo.py:91
frame_callback_ptr make_frame_callback(T callback)
Definition: l500-color.cpp:566
void override_extrinsics(rs2_extrinsics const &extr) override
Definition: l500-color.cpp:373
std::shared_ptr< md_attribute_parser_base > make_uvc_header_parser(Attribute St::*attribute, attrib_modifyer mod=nullptr)
A utility function to create UVC metadata header parser.
l500_color_sensor * get_color_sensor() override
Definition: l500-color.cpp:223
void write_fw_table(hw_monitor &hwm, uint16_t const table_id, T const &table, uint16_t const version=0x0100)
Definition: l500-private.h:149
std::vector< std::shared_ptr< stream_profile_interface >> stream_profiles
Definition: streaming.h:165
dictionary intrinsics
Definition: t265_stereo.py:142
static environment & get_instance()
int add_sensor(const std::shared_ptr< sensor_interface > &sensor_base)
Definition: device.cpp:163
#define AC_LOG(TYPE, MSG)
extrinsics_graph & get_extrinsics_graph()
std::vector< uint8_t > get_raw_extrinsics_table() const
Definition: l500-color.cpp:765
std::shared_ptr< synthetic_sensor > create_color_device(std::shared_ptr< context > ctx, const std::vector< platform::uvc_device_info > &color_devices_info)
Definition: l500-color.cpp:34
sensor_interface & get_sensor(size_t subdevice) override
Definition: device.cpp:187
GLenum GLenum GLsizei void * table
lazy< std::vector< uint8_t > > _color_extrinsics_table_raw
Definition: l500-color.h:44
Cross-stream extrinsics: encodes the topology describing how the different devices are oriented...
Definition: rs_sensor.h:96
rs2_distortion model
Definition: rs_types.h:66
std::shared_ptr< md_attribute_parser_base > make_attribute_parser(Attribute S::*attribute, Flag flag, unsigned long long offset, attrib_modifyer mod=nullptr)
A helper function to create a specialized attribute parser. Return it as a pointer to a base-class...
long long rs2_metadata_type
Definition: rs_types.h:301
GLenum type
lazy< ivcam2::intrinsic_rgb > _color_intrinsics_table
Definition: l500-color.h:43
rs2_extrinsics extr
Definition: test-pose.cpp:258
GLenum GLfloat param
static const int MAX_NUM_OF_RGB_RESOLUTIONS
Definition: l500-private.h:12
typename::boost::move_detail::remove_reference< T >::type && move(T &&t) BOOST_NOEXCEPT
Video stream intrinsics.
Definition: rs_types.h:58
std::vector< tagged_profile > get_profiles_tags() const override
Definition: l500-color.cpp:715
bool start_stream_for_calibration(const stream_profiles &requests)
Definition: l500-color.cpp:574
void register_stream_to_extrinsic_group(const stream_interface &stream, uint32_t groupd_index)
Definition: device.cpp:246
void read_fw_table(hw_monitor &hwm, int table_id, T *ptable, table_header *pheader=nullptr, std::function< void() > init=nullptr)
Definition: l500-private.h:109
auto group_multiple_fw_calls(synthetic_sensor &s, T action) -> decltype(action())
Definition: l500-private.h:615
int i
#define offsetof(STRUCTURE, FIELD)
Definition: sqlite3.c:11372
GLuint res
Definition: glext.h:8856
#define INFO(msg)
Definition: catch.hpp:17429
#define LOG_DEBUG(...)
Definition: src/types.h:239
std::vector< platform::uvc_device_info > filter_by_mi(const std::vector< platform::uvc_device_info > &devices, uint32_t mi)
Definition: context.cpp:644
std::vector< uvc_device_info > uvc_devices
Definition: backend.h:525
void override_intrinsics(rs2_intrinsics const &intr) override
Definition: l500-color.cpp:344
pose get_color_stream_extrinsic(const std::vector< uint8_t > &raw_data)
void set_k_thermal_intrinsics(rs2_intrinsics const &intr)
Definition: l500-color.cpp:403
lazy< algo::thermal_loop::l500::thermal_calibration_table > _thermal_table
Definition: l500-color.h:46
Definition: parser.hpp:150
GLint GLsizei width
const rs2_distortion l500_distortion
Definition: l500-color.h:19
rs2_extrinsics const & get_extrinsics() const
Definition: l500-private.h:228
void copy(void *dst, void const *src, size_t size)
Definition: types.cpp:836
std::string to_string(T value)
std::map< uint32_t, rs2_stream > l500_color_fourcc_to_rs2_stream
Definition: l500-color.cpp:28


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