ds5-auto-calibration.cpp
Go to the documentation of this file.
1 // License: Apache 2.0. See LICENSE file in root directory.
2 // Copyright(c) 2016 Intel Corporation. All Rights Reserved.
3 
4 #include "../third-party/json.hpp"
5 #include "ds5-device.h"
6 #include "ds5-private.h"
7 #include "ds5-thermal-monitor.h"
8 #include "ds5-auto-calibration.h"
9 
10 namespace librealsense
11 {
12 #pragma pack(push, 1)
13 #pragma pack(1)
15  {
16  uint16_t status; // DscStatus
18  uint16_t stepSize; // 1/1000 of a pixel
19  uint32_t pixelCountThreshold; // minimum number of pixels in
20  // selected bin
21  uint16_t minDepth; // Depth range for FWHM
23  uint32_t rightPy; // 1/1000000 of normalized unit
24  float healthCheck;
25  float rightRotation[9]; // Right rotation
26  };
27 
29  {
30  uint16_t status; // DscStatus
32  uint16_t scanRange; // 1/1000 of a pixel
33  float rightFy;
34  float rightFx;
35  float leftFy;
36  float leftFx;
38  uint16_t fillFactor0; // first of the setCount number of fill factor, 1/100 of a percent
39  };
40 
42  {
43  uint16_t headerSize; // 10 bytes for status & health numbers
44  uint16_t status; // DscStatus
45  float healthCheck;
47  uint16_t tableSize; // 512 bytes
48  };
49 
51  {
54  };
55 
57  {
61  };
62 
64  {
73  };
74 
75 #pragma pack(pop)
76 
78  {
89  };
90 
92  {
98  };
99 
101  {
102  very_high = 0, //(0.025%)
103  high = 1, //(0.05%)
104  medium = 2, //(0.1%)
105  low = 3 //(0.2%)
106  };
107 
109  {
110  polling = 0,
112  };
113 
115  {
116  py_scan = 0,
118  };
119 
121  {
126  };
127 
128  struct params4
129  {
130  int scan_parameter : 1;
131  int reserved : 2;
132  int data_sampling : 1;
133  };
134 
136  {
138  int param3;
139  };
140 
141  union param4
142  {
144  int param_4;
145  };
146 
147  const int DEFAULT_CALIB_TYPE = 0;
148 
150  const int DEFAULT_STEP_COUNT = 20;
151  const int DEFAULT_ACCURACY = subpixel_accuracy::medium;
155 
156  const int DEFAULT_FL_STEP_COUNT = 100;
157  const int DEFAULT_FY_SCAN_RANGE = 40;
161 
163 
166  const int DEFAULT_WHITE_WALL_MODE = 0;
167 
168  auto_calibrated::auto_calibrated(std::shared_ptr<hw_monitor>& hwm)
169  : _hw_monitor(hwm){}
170 
171  std::map<std::string, int> auto_calibrated::parse_json(std::string json_content)
172  {
173  using json = nlohmann::json;
174 
175  auto j = json::parse(json_content);
176 
177  std::map<std::string, int> values;
178 
179  for (json::iterator it = j.begin(); it != j.end(); ++it)
180  {
181  values[it.key()] = it.value();
182  }
183 
184  return values;
185  }
186 
187  void try_fetch(std::map<std::string, int> jsn, std::string key, int* value)
188  {
189  std::replace(key.begin(), key.end(), '_', ' '); // Treat _ as space
190  if (jsn.find(key) != jsn.end())
191  {
192  *value = jsn[key];
193  }
194  }
195 
196  // RAII to handle auto-calibration with the thermal compensation disabled
198  {
199  public:
201  restart_tl(false), snr(nullptr)
202  {
203  if (Is<librealsense::device>(handle))
204  {
205  try
206  {
207  // The depth sensor is assigned first by design
208  snr = &(As<librealsense::device>(handle)->get_sensor(0));
209 
210  if (snr->supports_option(RS2_OPTION_THERMAL_COMPENSATION))
211  restart_tl = static_cast<bool>(snr->get_option(RS2_OPTION_THERMAL_COMPENSATION).query());
212  if (restart_tl)
213  {
214  snr->get_option(RS2_OPTION_THERMAL_COMPENSATION).set(0.f);
215  // Allow for FW changes to propagate
216  std::this_thread::sleep_for(std::chrono::milliseconds(100));
217  }
218  }
219  catch(...) {
220  LOG_WARNING("Thermal Compensation guard failed to invoke");
221  }
222  }
223  }
225  {
226  try
227  {
228  if (snr && restart_tl)
229  snr->get_option(RS2_OPTION_THERMAL_COMPENSATION).set(1.f);
230  }
231  catch (...) {
232  LOG_WARNING("Thermal Compensation guard failed to complete");
233  }
234  }
235 
236  protected:
239 
240  private:
241  // Disable copy/assignment ctors
244  };
245 
246  std::vector<uint8_t> auto_calibrated::run_on_chip_calibration(int timeout_ms, std::string json, float* health, update_progress_callback_ptr progress_callback)
247  {
248  int calib_type = DEFAULT_CALIB_TYPE;
249 
250  int speed = DEFAULT_SPEED;
251  int speed_fl = auto_calib_speed::speed_slow;
254  int apply_preset = 1;
255 
256  int fl_step_count = DEFAULT_FL_STEP_COUNT;
257  int fy_scan_range = DEFAULT_FY_SCAN_RANGE;
258  int keep_new_value_after_sucessful_scan = DEFAULT_KEEP_NEW_VALUE_AFTER_SUCESSFUL_SCAN;
259  int fl_data_sampling = DEFAULT_FL_SAMPLING;
260  int adjust_both_sides = DEFAULT_ADJUST_BOTH_SIDES;
261 
262  int fl_scan_location = DEFAULT_OCC_FL_SCAN_LOCATION;
263  int fy_scan_direction = DEFAULT_FY_SCAN_DIRECTION;
264  int white_wall_mode = DEFAULT_WHITE_WALL_MODE;
265 
266  float h_1 = 0.0f;
267  float h_2 = 0.0f;
268 
269  //Enforce Thermal Compensation off during OCC
270  volatile thermal_compensation_guard grd(this);
271 
272  if (json.size() > 0)
273  {
274  auto jsn = parse_json(json);
275  try_fetch(jsn, "calib type", &calib_type);
276 
277  if (calib_type == 0)
278  try_fetch(jsn, "speed", &speed);
279  else
280  try_fetch(jsn, "speed", &speed_fl);
281 
282  try_fetch(jsn, "scan parameter", &scan_parameter);
283  try_fetch(jsn, "data sampling", &data_sampling);
284  try_fetch(jsn, "apply preset", &apply_preset);
285 
286  try_fetch(jsn, "fl step count", &fl_step_count);
287  try_fetch(jsn, "fy scan range", &fy_scan_range);
288  try_fetch(jsn, "keep new value after sucessful scan", &keep_new_value_after_sucessful_scan);
289  try_fetch(jsn, "fl data sampling", &fl_data_sampling);
290  try_fetch(jsn, "adjust both sides", &adjust_both_sides);
291 
292  try_fetch(jsn, "fl scan location", &fl_scan_location);
293  try_fetch(jsn, "fy scan direction", &fy_scan_direction);
294  try_fetch(jsn, "white wall mode", &white_wall_mode);
295  }
296 
297  std::vector<uint8_t> res;
298  if (calib_type == 0)
299  {
300  LOG_INFO("run_on_chip_calibration with parameters: speed = " << speed << " scan_parameter = " << scan_parameter << " data_sampling = " << data_sampling);
301  check_params(speed, scan_parameter, data_sampling);
302 
303  param4 param{ (byte)scan_parameter, 0, (byte)data_sampling };
304 
305  std::shared_ptr<ds5_advanced_mode_base> preset_recover;
306  if (speed == speed_white_wall && apply_preset)
307  preset_recover = change_preset();
308 
309  std::this_thread::sleep_for(std::chrono::milliseconds(200));
310 
311  // Begin auto-calibration
312  _hw_monitor->send(command{ ds::AUTO_CALIB, py_rx_calib_begin, speed, 0, param.param_4 });
313 
315 
316  int count = 0;
317  bool done = false;
318 
320  auto now = start;
321 
322  // While not ready...
323  do
324  {
325  std::this_thread::sleep_for(std::chrono::milliseconds(200));
326 
327  // Check calibration status
328  try
329  {
331 
332  if (res.size() < sizeof(DirectSearchCalibrationResult))
333  throw std::runtime_error("Not enough data from CALIB_STATUS!");
334 
335  result = *reinterpret_cast<DirectSearchCalibrationResult*>(res.data());
337  }
338  catch (const std::exception& ex)
339  {
340  LOG_WARNING(ex.what());
341  }
342  if (progress_callback)
343  progress_callback->on_update_progress(count++ * (2.f * speed)); //curently this number does not reflect the actual progress
344 
346 
347  } while (now - start < std::chrono::milliseconds(timeout_ms) && !done);
348 
349 
350  // If we exit due to timeout, report timeout
351  if (!done)
352  {
353  throw std::runtime_error("Operation timed-out!\n"
354  "Calibration state did not converged in time");
355  }
356 
357  std::this_thread::sleep_for(std::chrono::milliseconds(100));
358 
359  auto status = (rs2_dsc_status)result.status;
360 
361  // Handle errors from firmware
363  {
365  }
366 
367  res = get_calibration_results(health);
368  }
369  else if (calib_type == 1)
370  {
371  LOG_INFO("run_on_chip_focal_length_calibration with parameters: step count = " << fl_step_count
372  << ", fy scan range = " << fy_scan_range << ", keep new value after sucessful scan = " << keep_new_value_after_sucessful_scan
373  << ", interrrupt data sampling " << fl_data_sampling << ", adjust both sides = " << adjust_both_sides
374  << ", fl scan location = " << fl_scan_location << ", fy scan direction = " << fy_scan_direction << ", white wall mode = " << white_wall_mode);
375  check_focal_length_params(fl_step_count, fy_scan_range, keep_new_value_after_sucessful_scan, fl_data_sampling, adjust_both_sides, fl_scan_location, fy_scan_direction, white_wall_mode);
376 
377  // Begin auto-calibration
378  int p4 = 0;
379  if (keep_new_value_after_sucessful_scan)
380  p4 |= (1 << 1);
381  if (fl_data_sampling)
382  p4 |= (1 << 3);
383  if (adjust_both_sides)
384  p4 |= (1 << 4);
385  if (fl_scan_location)
386  p4 |= (1 << 5);
387  if (fy_scan_direction)
388  p4 |= (1 << 6);
389  if (white_wall_mode)
390  p4 |= (1 << 7);
391  _hw_monitor->send(command{ ds::AUTO_CALIB, focal_length_calib_begin, fl_step_count, fy_scan_range, p4 });
392 
394 
395  int count = 0;
396  bool done = false;
397 
399  auto now = start;
400 
401  // While not ready...
402  do
403  {
404  std::this_thread::sleep_for(std::chrono::milliseconds(200));
405 
406  // Check calibration status
407  try
408  {
410 
411  if (res.size() < sizeof(FocalLengthCalibrationResult))
412  throw std::runtime_error("Not enough data from CALIB_STATUS!");
413 
414  result = *reinterpret_cast<FocalLengthCalibrationResult*>(res.data());
416  }
417  catch (const std::exception& ex)
418  {
419  LOG_WARNING(ex.what());
420  }
421 
422  if (progress_callback)
423  progress_callback->on_update_progress(count++ * (2.f * 3)); //curently this number does not reflect the actual progress
424 
426 
427  } while (now - start < std::chrono::milliseconds(timeout_ms) && !done);
428 
429 
430  // If we exit due to timeout, report timeout
431  if (!done)
432  {
433  throw std::runtime_error("Operation timed-out!\n"
434  "Calibration state did not converged in time");
435  }
436 
437  std::this_thread::sleep_for(std::chrono::milliseconds(100));
438 
439  auto status = (rs2_dsc_status)result.status;
440 
441  // Handle errors from firmware
443  {
445  }
446 
447  res = get_calibration_results(health);
448  }
449  else
450  {
451  LOG_INFO("run_on_chip_calibration with parameters: speed = " << speed_fl
452  << ", keep new value after sucessful scan = " << keep_new_value_after_sucessful_scan
453  << " data_sampling = " << data_sampling << ", adjust both sides = " << adjust_both_sides
454  << ", fl scan location = " << fl_scan_location << ", fy scan direction = " << fy_scan_direction << ", white wall mode = " << white_wall_mode);
455  check_one_button_params(speed, keep_new_value_after_sucessful_scan, data_sampling, adjust_both_sides, fl_scan_location, fy_scan_direction, white_wall_mode);
456 
457  int p4 = 0;
458  if (scan_parameter)
459  p4 |= 1;
460  if (keep_new_value_after_sucessful_scan)
461  p4 |= (1 << 1);
462  if (fl_data_sampling)
463  p4 |= (1 << 3);
464  if (adjust_both_sides)
465  p4 |= (1 << 4);
466  if (fl_scan_location)
467  p4 |= (1 << 5);
468  if (fy_scan_direction)
469  p4 |= (1 << 6);
470  if (white_wall_mode)
471  p4 |= (1 << 7);
472 
473  std::shared_ptr<ds5_advanced_mode_base> preset_recover;
474  if (speed == speed_white_wall && apply_preset)
475  preset_recover = change_preset();
476 
477  std::this_thread::sleep_for(std::chrono::milliseconds(200));
478 
479  // Begin auto-calibration
480  _hw_monitor->send(command{ ds::AUTO_CALIB, py_rx_plus_fl_calib_begin, speed_fl, 0, p4 });
481 
483 
484  int count = 0;
485  bool done = false;
486 
488  auto now = start;
489  float progress = 0.0f;
490 
491  // While not ready...
492  do
493  {
494  std::this_thread::sleep_for(std::chrono::milliseconds(200));
495 
496  // Check calibration status
497  try
498  {
500 
501  if (res.size() < sizeof(DscPyRxFLCalibrationTableResult))
502  throw std::runtime_error("Not enough data from CALIB_STATUS!");
503 
504  result = *reinterpret_cast<DscPyRxFLCalibrationTableResult*>(res.data());
506  }
507  catch (const std::exception& ex)
508  {
509  LOG_WARNING(ex.what());
510  }
511 
512  if (progress_callback)
513  {
514  progress = count++ * (2.f * speed);
515  progress_callback->on_update_progress(progress); //curently this number does not reflect the actual progress
516  }
517 
519 
520  } while (now - start < std::chrono::milliseconds(timeout_ms) && !done);
521 
522  // If we exit due to timeout, report timeout
523  if (!done)
524  {
525  throw std::runtime_error("Operation timed-out!\n"
526  "Calibration state did not converged in time");
527  }
528 
529  std::this_thread::sleep_for(std::chrono::milliseconds(100));
530 
531  auto status = (rs2_dsc_status)result.status;
532 
533  // Handle errors from firmware
536 
537  res = get_PyRxFL_calibration_results(&h_1 , &h_2);
538 
539  int health_1 = static_cast<int>(abs(h_1) * 1000.0f + 0.5f);
540  health_1 &= 0xFFF;
541 
542  int health_2 = static_cast<int>(abs(h_2) * 1000.0f + 0.5f);
543  health_2 &= 0xFFF;
544 
545  int sign = 0;
546  if (h_1 < 0.0f)
547  sign = 1;
548  if (h_2 < 0.0f)
549  sign |= 2;
550 
551  int h = health_1;
552  h |= health_2 << 12;
553  h |= sign << 24;
554  *health = static_cast<float>(h);
555  }
556 
557  return res;
558  }
559 
560  std::vector<uint8_t> auto_calibrated::run_tare_calibration(int timeout_ms, float ground_truth_mm, std::string json, update_progress_callback_ptr progress_callback)
561  {
562  int average_step_count = DEFAULT_AVERAGE_STEP_COUNT;
563  int step_count = DEFAULT_STEP_COUNT;
564  int accuracy = DEFAULT_ACCURACY;
565  int speed = DEFAULT_SPEED;
568  int apply_preset = 1;
569 
570  //Enforce Thermal Compensation off during Tare calibration
571  volatile thermal_compensation_guard grd(this);
572 
573  if (json.size() > 0)
574  {
575  auto jsn = parse_json(json);
576  try_fetch(jsn, "speed", &speed);
577  try_fetch(jsn, "average step count", &average_step_count);
578  try_fetch(jsn, "step count", &step_count);
579  try_fetch(jsn, "accuracy", &accuracy);
580  try_fetch(jsn, "scan parameter", &scan_parameter);
581  try_fetch(jsn, "data sampling", &data_sampling);
582  try_fetch(jsn, "apply preset", &apply_preset);
583  }
584 
585  LOG_INFO("run_tare_calibration with parameters: speed = " << speed << " average_step_count = " << average_step_count << " step_count = " << step_count << " accuracy = " << accuracy << " scan_parameter = " << scan_parameter << " data_sampling = " << data_sampling);
586  check_tare_params(speed, scan_parameter, data_sampling, average_step_count, step_count, accuracy);
587 
588  std::shared_ptr<ds5_advanced_mode_base> preset_recover;
589  if (apply_preset)
590  preset_recover = change_preset();
591 
592  auto param2 = (int)ground_truth_mm * 100;
593 
594  tare_calibration_params param3{ (byte)average_step_count, (byte)step_count, (byte)accuracy, 0};
595 
596  param4 param{ (byte)scan_parameter, 0, (byte)data_sampling };
597 
598  _hw_monitor->send(command{ ds::AUTO_CALIB, tare_calib_begin, param2, param3.param3, param.param_4});
599 
601 
602  // While not ready...
603  int count = 0;
604  bool done = false;
605 
607  auto now = start;
608 
609  do
610  {
611  memset(&result, 0, sizeof(DirectSearchCalibrationResult));
612 
613  std::this_thread::sleep_for(std::chrono::milliseconds(200));
614 
615  // Check calibration status
616  try
617  {
619  if (res.size() < sizeof(DirectSearchCalibrationResult))
620  throw std::runtime_error("Not enough data from CALIB_STATUS!");
621 
622  result = *reinterpret_cast<DirectSearchCalibrationResult*>(res.data());
623  done = result.status != RS2_DSC_STATUS_RESULT_NOT_READY;
624  }
625 
626  catch (const std::exception& ex)
627  {
628  LOG_WARNING(ex.what());
629  }
630 
631  if (progress_callback)
632  progress_callback->on_update_progress(count++ * (2.f * speed)); //curently this number does not reflect the actual progress
633 
635 
636  } while (now - start < std::chrono::milliseconds(timeout_ms) && !done);
637 
638  // If we exit due to timeout, report timeout
639  if (!done)
640  {
641  throw std::runtime_error("Operation timed-out!\n"
642  "Calibration state did not converged in time");
643  }
644 
645  auto status = (rs2_dsc_status)result.status;
646 
647  // Handle errors from firmware
649  {
651  }
652 
653  return get_calibration_results();
654  }
655 
656  std::shared_ptr<ds5_advanced_mode_base> auto_calibrated::change_preset()
657  {
658  preset old_preset_values;
659  rs2_rs400_visual_preset old_preset;
660 
661  auto advanced_mode = dynamic_cast<ds5_advanced_mode_base*>(this);
662  if (advanced_mode)
663  {
664  old_preset = (rs2_rs400_visual_preset)(int)advanced_mode->_preset_opt->query();
665  if (old_preset == RS2_RS400_VISUAL_PRESET_CUSTOM)
666  old_preset_values = advanced_mode->get_all();
667  advanced_mode->_preset_opt->set(RS2_RS400_VISUAL_PRESET_HIGH_ACCURACY);
668  }
669 
670  std::shared_ptr<ds5_advanced_mode_base> recover_preset(advanced_mode, [old_preset, advanced_mode, old_preset_values](ds5_advanced_mode_base* adv)
671  {
672  if (old_preset == RS2_RS400_VISUAL_PRESET_CUSTOM)
673  {
674  advanced_mode->_preset_opt->set(RS2_RS400_VISUAL_PRESET_CUSTOM);
675  adv->set_all(old_preset_values);
676  }
677  else
678  advanced_mode->_preset_opt->set(static_cast<float>(old_preset));
679  });
680 
681  return recover_preset;
682  }
683 
685  {
686  if (speed < speed_very_fast || speed > speed_white_wall)
687  throw invalid_value_exception(to_string() << "Auto calibration failed! Given value of 'speed' " << speed << " is out of range (0 - 4).");
688  if (scan_parameter != py_scan && scan_parameter != rx_scan)
689  throw invalid_value_exception(to_string() << "Auto calibration failed! Given value of 'scan parameter' " << scan_parameter << " is out of range (0 - 1).");
690  if (data_sampling != polling && data_sampling != interrupt)
691  throw invalid_value_exception(to_string() << "Auto calibration failed! Given value of 'data sampling' " << data_sampling << " is out of range (0 - 1).");
692  }
693 
694  void auto_calibrated::check_tare_params(int speed, int scan_parameter, int data_sampling, int average_step_count, int step_count, int accuracy)
695  {
696  check_params(speed, scan_parameter, data_sampling);
697 
698  if (average_step_count < 1 || average_step_count > 30)
699  throw invalid_value_exception(to_string() << "Auto calibration failed! Given value of 'number of frames to average' " << average_step_count << " is out of range (1 - 30).");
700  if (step_count < 5 || step_count > 30)
701  throw invalid_value_exception(to_string() << "Auto calibration failed! Given value of 'max iteration steps' " << step_count << " is out of range (5 - 30).");
702  if (accuracy < very_high || accuracy > low)
703  throw invalid_value_exception(to_string() << "Auto calibration failed! Given value of 'subpixel accuracy' " << accuracy << " is out of range (0 - 3).");
704  }
705 
706  void auto_calibrated::check_focal_length_params(int step_count, int fy_scan_range, int keep_new_value_after_sucessful_scan, int interrrupt_data_samling, int adjust_both_sides, int fl_scan_location, int fy_scan_direction, int white_wall_mode) const
707  {
708  if (step_count < 8 || step_count > 256)
709  throw invalid_value_exception(to_string() << "Auto calibration failed! Given value of 'step_count' " << step_count << " is out of range (8 - 256).");
710  if (fy_scan_range < 1 || fy_scan_range > 60000)
711  throw invalid_value_exception(to_string() << "Auto calibration failed! Given value of 'fy_scan_range' " << fy_scan_range << " is out of range (1 - 60000).");
712  if (keep_new_value_after_sucessful_scan < 0 || keep_new_value_after_sucessful_scan > 1)
713  throw invalid_value_exception(to_string() << "Auto calibration failed! Given value of 'keep_new_value_after_sucessful_scan' " << keep_new_value_after_sucessful_scan << " is out of range (0 - 1).");
714  if (interrrupt_data_samling < 0 || interrrupt_data_samling > 1)
715  throw invalid_value_exception(to_string() << "Auto calibration failed! Given value of 'interrrupt_data_samling' " << interrrupt_data_samling << " is out of range (0 - 1).");
716  if (adjust_both_sides < 0 || adjust_both_sides > 1)
717  throw invalid_value_exception(to_string() << "Auto calibration failed! Given value of 'adjust_both_sides' " << adjust_both_sides << " is out of range (0 - 1).");
718  if (fl_scan_location < 0 || fl_scan_location > 1)
719  throw invalid_value_exception(to_string() << "Auto calibration failed! Given value of 'fl_scan_location' " << fl_scan_location << " is out of range (0 - 1).");
720  if (fy_scan_direction < 0 || fy_scan_direction > 1)
721  throw invalid_value_exception(to_string() << "Auto calibration failed! Given value of 'fy_scan_direction' " << fy_scan_direction << " is out of range (0 - 1).");
722  if (white_wall_mode < 0 || white_wall_mode > 1)
723  throw invalid_value_exception(to_string() << "Auto calibration failed! Given value of 'white_wall_mode' " << white_wall_mode << " is out of range (0 - 1).");
724  }
725 
726  void auto_calibrated::check_one_button_params(int speed, int keep_new_value_after_sucessful_scan, int data_sampling, int adjust_both_sides, int fl_scan_location, int fy_scan_direction, int white_wall_mode) const
727  {
728  if (speed < speed_very_fast || speed > speed_white_wall)
729  throw invalid_value_exception(to_string() << "Auto calibration failed! Given value of 'speed' " << speed << " is out of range (0 - 4).");
730  if (keep_new_value_after_sucessful_scan < 0 || keep_new_value_after_sucessful_scan > 1)
731  throw invalid_value_exception(to_string() << "Auto calibration failed! Given value of 'keep_new_value_after_sucessful_scan' " << keep_new_value_after_sucessful_scan << " is out of range (0 - 1).");
732  if (data_sampling != polling && data_sampling != interrupt)
733  throw invalid_value_exception(to_string() << "Auto calibration failed! Given value of 'data sampling' " << data_sampling << " is out of range (0 - 1).");
734  if (adjust_both_sides < 0 || adjust_both_sides > 1)
735  throw invalid_value_exception(to_string() << "Auto calibration failed! Given value of 'adjust_both_sides' " << adjust_both_sides << " is out of range (0 - 1).");
736  if (fl_scan_location < 0 || fl_scan_location > 1)
737  throw invalid_value_exception(to_string() << "Auto calibration failed! Given value of 'fl_scan_location' " << fl_scan_location << " is out of range (0 - 1).");
738  if (fy_scan_direction < 0 || fy_scan_direction > 1)
739  throw invalid_value_exception(to_string() << "Auto calibration failed! Given value of 'fy_scan_direction' " << fy_scan_direction << " is out of range (0 - 1).");
740  if (white_wall_mode < 0 || white_wall_mode > 1)
741  throw invalid_value_exception(to_string() << "Auto calibration failed! Given value of 'white_wall_mode' " << white_wall_mode << " is out of range (0 - 1).");
742  }
743 
745  {
746  if (status == RS2_DSC_STATUS_EDGE_TOO_CLOSE)
747  {
748  throw std::runtime_error("Calibration didn't converge! (EDGE_TO_CLOSE)\n"
749  "Please retry in different lighting conditions");
750  }
751  else if (status == RS2_DSC_STATUS_FILL_FACTOR_TOO_LOW)
752  {
753  throw std::runtime_error("Not enough depth pixels! (FILL_FACTOR_LOW)\n"
754  "Please retry in different lighting conditions");
755  }
756  else if (status == RS2_DSC_STATUS_NOT_CONVERGE)
757  {
758  throw std::runtime_error("Calibration didn't converge! (NOT_CONVERGE)\n"
759  "Please retry in different lighting conditions");
760  }
761  else if (status == RS2_DSC_STATUS_NO_DEPTH_AVERAGE)
762  {
763  throw std::runtime_error("Calibration didn't converge! (NO_AVERAGE)\n"
764  "Please retry in different lighting conditions");
765  }
766  else throw std::runtime_error(to_string() << "Calibration didn't converge! (RESULT=" << int(status) << ")");
767  }
768 
769  std::vector<uint8_t> auto_calibrated::get_calibration_results(float* health) const
770  {
771  using namespace ds;
772 
773  // Get new calibration from the firmware
775  if (res.size() < sizeof(DscResultBuffer))
776  throw std::runtime_error("Not enough data from CALIB_STATUS!");
777 
778  auto reslt = (DscResultBuffer*)(res.data());
779 
780  table_header* header = reinterpret_cast<table_header*>(res.data() + sizeof(DscResultBuffer));
781 
782  if (res.size() < sizeof(DscResultBuffer) + sizeof(table_header) + header->table_size)
783  throw std::runtime_error("Table truncated in CALIB_STATUS!");
784 
785  std::vector<uint8_t> calib;
786 
787  calib.resize(sizeof(table_header) + header->table_size, 0);
788  memcpy(calib.data(), header, calib.size()); // Copy to new_calib
789 
790  if(health)
791  *health = reslt->m_dscResultParams.m_healthCheck;
792 
793  return calib;
794  }
795 
796  std::vector<uint8_t> auto_calibrated::get_PyRxFL_calibration_results(float* health, float* health_fl) const
797  {
798  using namespace ds;
799 
800  // Get new calibration from the firmware
802  if (res.size() < sizeof(DscPyRxFLCalibrationTableResult))
803  throw std::runtime_error("Not enough data from CALIB_STATUS!");
804 
805  auto reslt = (DscPyRxFLCalibrationTableResult*)(res.data());
806 
807  table_header* header = reinterpret_cast<table_header*>(res.data() + sizeof(DscPyRxFLCalibrationTableResult));
808 
809  if (res.size() < sizeof(DscPyRxFLCalibrationTableResult) + sizeof(table_header) + header->table_size)
810  throw std::runtime_error("Table truncated in CALIB_STATUS!");
811 
812  std::vector<uint8_t> calib;
813  calib.resize(sizeof(table_header) + header->table_size, 0);
814  memcpy(calib.data(), header, calib.size()); // Copy to new_calib
815 
816  if (health_fl)
817  *health_fl = reslt->FL_heathCheck;
818 
819  if (health)
820  *health = reslt->healthCheck;
821 
822  return calib;
823  }
824 
825  std::vector<uint8_t> auto_calibrated::get_calibration_table() const
826  {
827  using namespace ds;
828 
829  std::vector<uint8_t> res;
830 
831  // Fetch current calibration using GETINITCAL command
833  auto calib = _hw_monitor->send(cmd);
834 
835  if (calib.size() < sizeof(table_header)) throw std::runtime_error("Missing calibration header from GETINITCAL!");
836 
837  auto table = (uint8_t*)(calib.data() + sizeof(table_header));
838  auto hd = (table_header*)(calib.data());
839 
840  if (calib.size() < sizeof(table_header) + hd->table_size)
841  throw std::runtime_error("Table truncated from GETINITCAL!");
842 
843  res.resize(sizeof(table_header) + hd->table_size, 0);
844  memcpy(res.data(), hd, res.size()); // Copy to old_calib
845 
846  return res;
847  }
848 
850  {
851  using namespace ds;
852 
853  if(_curr_calibration.size() < sizeof(table_header))
854  throw std::runtime_error("Write calibration can be called only after set calibration table was called");
855 
856  command write_calib( ds::SETINTCAL, set_coefficients );
857  write_calib.data = _curr_calibration;
858  _hw_monitor->send(write_calib);
859  }
860 
861  void auto_calibrated::set_calibration_table(const std::vector<uint8_t>& calibration)
862  {
863  using namespace ds;
864 
865  table_header* hd = (table_header*)(calibration.data());
866  uint8_t* table = (uint8_t*)(calibration.data() + sizeof(table_header));
867  command write_calib(ds::CALIBRECALC, 0, 0, 0, 0xcafecafe);
868  write_calib.data.insert(write_calib.data.end(), (uint8_t*)table, ((uint8_t*)table) + hd->table_size);
869  _hw_monitor->send(write_calib);
870 
871  _curr_calibration = calibration;
872  }
873 
875  {
877  _hw_monitor->send(cmd);
878  }
879 }
std::vector< uint8_t > get_PyRxFL_calibration_results(float *health=nullptr, float *health_fl=nullptr) const
const int DEFAULT_WHITE_WALL_MODE
void write_calibration() const override
const int DEFAULT_FL_SAMPLING
static basic_json parse(T(&array)[N], const parser_callback_t cb=nullptr)
deserialize from an array
Definition: json.hpp:5979
std::vector< uint8_t > run_tare_calibration(int timeout_ms, float ground_truth_mm, std::string json, update_progress_callback_ptr progress_callback) override
thermal_compensation_guard(auto_calibrated_interface *handle)
#define LOG_WARNING(...)
Definition: src/types.h:241
const int DEFAULT_ADJUST_BOTH_SIDES
GLuint64 GLenum void * handle
Definition: glext.h:7785
a class to store JSON values
Definition: json.hpp:221
GLfloat value
def progress(args)
Definition: log.py:43
unsigned short uint16_t
Definition: stdint.h:79
GLsizei const GLchar *const * string
std_msgs::Header * header(M &m)
returns Header<M>::pointer(m);
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:1960
unsigned char uint8_t
Definition: stdint.h:78
std::shared_ptr< advanced_mode_preset_option > _preset_opt
const int DEFAULT_FY_SCAN_RANGE
const int DEFAULT_STEP_COUNT
status
Defines return codes that SDK interfaces use. Negative values indicate errors, a zero value indicates...
std::shared_ptr< ds5_advanced_mode_base > change_preset()
std::shared_ptr< rs2_update_progress_callback > update_progress_callback_ptr
Definition: src/types.h:1077
GLuint64 key
Definition: glext.h:8966
void reset_to_factory_calibration() const override
GLdouble f
auto_calibrated(std::shared_ptr< hw_monitor > &hwm)
void check_tare_params(int speed, int scan_parameter, int data_sampling, int average_step_count, int step_count, int accuracy)
unsigned int uint32_t
Definition: stdint.h:80
const int DEFAULT_AVERAGE_STEP_COUNT
std::vector< uint8_t > _curr_calibration
std::vector< uint8_t > data
Definition: hw-monitor.h:240
const int DEFAULT_FL_STEP_COUNT
const int DEFAULT_TARE_SAMPLING
GLuint start
static int done
GLint j
void try_fetch(std::map< std::string, int > jsn, std::string key, int *value)
void handle_calibration_error(int status) const
const int DEFAULT_FY_SCAN_DIRECTION
GLenum GLenum GLsizei void * table
GLsizei const GLfloat * values
std::shared_ptr< hw_monitor > & _hw_monitor
LOG_INFO("Log message using LOG_INFO()")
unsigned char byte
Definition: src/types.h:52
static auto it
void check_params(int speed, int scan_parameter, int data_sampling) const
GLenum GLfloat param
GLint GLsizei count
std::vector< uint8_t > get_calibration_results(float *health=nullptr) const
rs2_rs400_visual_preset
For RS400 devices: provides optimized settings (presets) for specific types of usage.
Definition: rs_option.h:137
void check_focal_length_params(int step_count, int fy_scan_range, int keep_new_value_after_sucessful_scan, int interrrupt_data_samling, int adjust_both_sides, int fl_scan_location, int fy_scan_direction, int white_wall_mode) const
const int DEFAULT_CALIB_TYPE
GLuint res
Definition: glext.h:8856
std::vector< uint8_t > run_on_chip_calibration(int timeout_ms, std::string json, float *health, update_progress_callback_ptr progress_callback) override
basic_json<> json
default JSON class
Definition: json.hpp:12124
std::map< std::string, int > parse_json(std::string json)
GLuint64EXT * result
Definition: glext.h:10921
void set_calibration_table(const std::vector< uint8_t > &calibration) override
const int DEFAULT_OCC_FL_SCAN_LOCATION
a template for a random access iterator for the basic_json class
Definition: json.hpp:231
const int DEFAULT_KEEP_NEW_VALUE_AFTER_SUCESSFUL_SCAN
void check_one_button_params(int speed, int keep_new_value_after_sucessful_scan, int data_sampling, int adjust_both_sides, int fl_scan_location, int fy_scan_direction, int white_wall_mode) const
std::vector< uint8_t > get_calibration_table() const override
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:12