hdr-config.cpp
Go to the documentation of this file.
1 // License: Apache 2.0. See LICENSE file in root directory.
2 // Copyright(c) 2020 Intel Corporation. All Rights Reserved.
3 
4 #include "hdr-config.h"
5 #include "ds5/ds5-private.h"
6 
7 namespace librealsense
8 {
9  hdr_config::hdr_config(hw_monitor& hwm, std::shared_ptr<sensor_base> depth_ep,
10  const option_range& exposure_range, const option_range& gain_range) :
11  _hwm(hwm),
12  _sensor(depth_ep),
13  _is_enabled(false),
14  _is_config_in_process(false),
15  _has_config_changed(false),
16  _current_hdr_sequence_index(DEFAULT_CURRENT_HDR_SEQUENCE_INDEX),
17  _auto_exposure_to_be_restored(false),
18  _emitter_on_off_to_be_restored(false),
19  _id(DEFAULT_HDR_ID),
20  _sequence_size(DEFAULT_HDR_SEQUENCE_SIZE),
21  _exposure_range(exposure_range),
22  _gain_range(gain_range),
23  _use_workaround(true),
24  _pre_hdr_exposure(0.f)
25  {
26  _hdr_sequence_params.clear();
28 
29  // restoring current HDR configuration if such subpreset is active
30  bool existing_subpreset_restored = false;
31  std::vector<byte> res;
32  if (is_hdr_enabled_in_device(res))
33  existing_subpreset_restored = configure_hdr_as_in_fw(res);
34 
35  if (!existing_subpreset_restored)
36  {
37  // setting default config
38  float exposure_default_value = _exposure_range.def-1000.f; // D455 W/A
39  float gain_default_value = _gain_range.def;
40  hdr_params params_0(0, exposure_default_value, gain_default_value);
41  _hdr_sequence_params[0] = params_0;
42 
43  float exposure_low_value = _exposure_range.min;
44  float gain_min_value = _gain_range.min;
45  hdr_params params_1(1, exposure_low_value, gain_min_value);
46  _hdr_sequence_params[1] = params_1;
47  }
48  }
49 
50  bool hdr_config::is_hdr_enabled_in_device(std::vector<byte>& result) const
51  {
53  bool hdr_enabled_in_device = false;
54  try {
55  result = _hwm.send(cmd);
56  hdr_enabled_in_device = (result.size() && is_current_subpreset_hdr(result));
57  }
58  catch (std::exception ex) {
59  LOG_WARNING("In hdr_config::hdr_config() - hw command failed: " << ex.what());
60  }
61  return hdr_enabled_in_device;
62  }
63 
64  bool hdr_config::is_current_subpreset_hdr(const std::vector<byte>& current_subpreset) const
65  {
66  bool result = false;
67  if (current_subpreset.size() > 0)
68  {
69  int current_subpreset_id = current_subpreset[1];
70  result = is_hdr_id(current_subpreset_id);
71  }
72  return result;
73  }
74 
75  bool hdr_config::is_hdr_id(int id) const
76  {
77  return id >= 0 && id <= 3;
78  }
79 
80  bool hdr_config::configure_hdr_as_in_fw(const std::vector<byte>& current_subpreset)
81  {
82  // parsing subpreset pattern, considering:
83  // SubPresetHeader::iterations always equals 0 (continuous subpreset)
84  // SubPresetHeader::numOfItems always equals 2 - for gain and exposure
85  // SubPresetItemHeader::iterations always equals 1 - only one frame on each sequence ID in the sequence
86  const int size_of_subpreset_header = 5;
87  const int size_of_subpreset_item_header = 4;
88  const int size_of_control_id = 1;
89  const int size_of_control_value = 4;
90 
91  int subpreset_size = size_of_subpreset_header + 2 * (size_of_subpreset_item_header +
92  2 * (size_of_control_id + size_of_control_value));
93 
94  if (current_subpreset.size() != subpreset_size)
95  return false;
96 
97  int offset = 0;
98  offset += size_of_subpreset_header;
99  offset += size_of_subpreset_item_header;
100 
101  if (current_subpreset[offset] != CONTROL_ID_EXPOSURE)
102  return false;
103  offset += size_of_control_id;
104  float exposure_0
105  = (float)*reinterpret_cast< const uint32_t * >( &( current_subpreset[offset] ) );
106  offset += size_of_control_value;
107 
108  if (current_subpreset[offset] != CONTROL_ID_GAIN)
109  return false;
110  offset += size_of_control_id;
111  float gain_0
112  = (float)*reinterpret_cast< const uint32_t * >( &( current_subpreset[offset] ) );
113  offset += size_of_control_value;
114 
115  offset += size_of_subpreset_item_header;
116 
117  if (current_subpreset[offset] != CONTROL_ID_EXPOSURE)
118  return false;
119  offset += size_of_control_id;
120  float exposure_1
121  = (float)*reinterpret_cast< const uint32_t * >( &( current_subpreset[offset] ) );
122  offset += size_of_control_value;
123 
124  if (current_subpreset[offset] != CONTROL_ID_GAIN)
125  return false;
126  offset += size_of_control_id;
127  float gain_1
128  = (float)*reinterpret_cast< const uint32_t * >( &( current_subpreset[offset] ) );
129  offset += size_of_control_value;
130 
131  _hdr_sequence_params[0]._exposure = exposure_0;
132  _hdr_sequence_params[0]._gain = gain_0;
133  _hdr_sequence_params[1]._exposure = exposure_1;
134  _hdr_sequence_params[1]._gain = gain_1;
135 
136  return true;
137  }
138 
140  {
141  float rv = 0.f;
142  switch (option)
143  {
145  rv = static_cast<float>(_id);
146  break;
148  rv = static_cast<float>(_sequence_size);
149  break;
151  rv = static_cast<float>(_current_hdr_sequence_index + 1);
152  break;
154  rv = static_cast<float>(is_enabled());
155  break;
156  case RS2_OPTION_EXPOSURE:
157  try {
159  }
160  // should never happen
161  catch (std::out_of_range)
162  {
163  throw invalid_value_exception(to_string() << "hdr_config::get(...) failed! Index is above the sequence size.");
164  }
165  break;
166  case RS2_OPTION_GAIN:
167  try {
169  }
170  // should never happen
171  catch (std::out_of_range)
172  {
173  throw invalid_value_exception(to_string() << "hdr_config::get(...) failed! Index is above the sequence size.");
174  }
175  break;
176  default:
177  throw invalid_value_exception(to_string() << "option: " << rs2_option_to_string(option) << " is not an HDR option");
178  }
179  return rv;
180  }
181 
183  {
185  throw invalid_value_exception(to_string() << "hdr_config::set(...) failed! value: " << value <<
186  " is out of the option range: [" << range.min << ", " << range.max << "].");
187 
188  switch (option)
189  {
191  set_id(value);
192  break;
194  set_sequence_size(value);
195  break;
197  set_sequence_index(value);
198  break;
200  set_enable_status(value);
201  break;
202  case RS2_OPTION_EXPOSURE:
203  set_exposure(value);
204  break;
205  case RS2_OPTION_GAIN:
206  set_gain(value);
207  break;
208  default:
209  throw invalid_value_exception("option is not an HDR option");
210  }
211 
212  // subpreset configuration change is immediately sent to firmware if HDR is already running
214  {
216  }
217  }
218 
220  {
221  return _is_config_in_process;
222  }
223 
225  {
226  // status in the firmware must be checked in case this is a new instance but the HDR in enabled in firmware
227  if (!_is_enabled)
228  {
229  float rv = 0.f;
231  // if no subpreset is streaming, the firmware returns "ON_DATA_TO_RETURN" error
232  try {
233  auto res = _hwm.send(cmd);
234  // if a subpreset is streaming, checking this is the current HDR sub preset
235  if (res.size())
236  rv = (is_hdr_id(res[0])) ? 1.0f : 0.f;
237  }
238  catch (...)
239  {
240  rv = 0.f;
241  }
242 
243  _is_enabled = (rv == 1.f);
244  }
245 
246  return _is_enabled;
247  }
248 
250  {
251  if (value)
252  {
253  if (validate_config())
254  {
255  std::vector<byte> res;
257  if (!_is_enabled)
258  {
259  // saving status of options that are not compatible with hdr,
260  // so that they could be reenabled after hdr disable
262 
263  if (_use_workaround)
264  {
265  try {
266  // the following statement is needed in order to get/set the UVC exposure
267  // instead of one of the hdr's configuration exposure
269  _pre_hdr_exposure = _sensor.lock()->get_option(RS2_OPTION_EXPOSURE).query();
270  _sensor.lock()->get_option(RS2_OPTION_EXPOSURE).set(PRE_ENABLE_HDR_EXPOSURE);
271  } catch (...) {
272  LOG_WARNING("HDR: enforced exposure failed");
273  }
274  }
275 
277  _has_config_changed = false;
278  }
279  }
280  else
281  // msg to user to be improved later on
282  throw invalid_value_exception("config is not valid");
283  }
284  else
285  {
286  disable();
287  _is_enabled = false;
288 
289  if (_use_workaround)
290  {
291  // this sleep is needed to let the fw restore the manual exposure
292  std::this_thread::sleep_for(std::chrono::milliseconds(70));
293 
295  {
296  try {
297  // the following statement is needed in order to get the UVC exposure
298  // instead of one of the hdr's configuration exposure
300  _sensor.lock()->get_option(RS2_OPTION_EXPOSURE).set(_pre_hdr_exposure);
301  } catch (...) {
302  LOG_WARNING("HDR failed to restore manual exposure");
303  }
304  }
305  }
306 
307  // re-enabling options that were disabled in order to permit the hdr
309  }
310  }
311 
312 
314  {
315  // AUTO EXPOSURE
316  if (_sensor.lock()->supports_option(RS2_OPTION_ENABLE_AUTO_EXPOSURE))
317  {
318  if (_sensor.lock()->get_option(RS2_OPTION_ENABLE_AUTO_EXPOSURE).query())
319  {
320  _sensor.lock()->get_option(RS2_OPTION_ENABLE_AUTO_EXPOSURE).set(0.f);
322  }
323  }
324 
325 
326  // EMITTER ON OFF
327  if (_sensor.lock()->supports_option(RS2_OPTION_EMITTER_ON_OFF))
328  {
329  if (_sensor.lock()->get_option(RS2_OPTION_EMITTER_ON_OFF).query())
330  {
331  _sensor.lock()->get_option(RS2_OPTION_EMITTER_ON_OFF).set(0.f);
333  }
334  }
335  }
336 
338  {
339  // AUTO EXPOSURE
341  {
342  _sensor.lock()->get_option(RS2_OPTION_ENABLE_AUTO_EXPOSURE).set(1.f);
344  }
345 
346  // EMITTER ON OFF
348  {
349  _sensor.lock()->get_option(RS2_OPTION_EMITTER_ON_OFF).set(1.f);
351  }
352  }
353 
355  {
356  bool result = false;
357  // prepare sub-preset command
359  try {
360  auto res = _hwm.send(cmd);
361  result = true;
362  }
363  catch (std::exception ex) {
364  LOG_WARNING("In hdr_config::send_sub_preset_to_fw() - hw command failed: " << ex.what());
365  }
366  return result;
367  }
368 
370  {
371  // sending empty sub preset
372  std::vector<uint8_t> pattern{};
373 
374  // TODO - make it usable not only for ds - use _sensor
375  command cmd(ds::SETSUBPRESET, static_cast<int>(pattern.size()));
376  cmd.data = pattern;
377  try {
378  auto res = _hwm.send(cmd);
379  }
380  catch (std::exception ex) {
381  LOG_WARNING("In hdr_config::disable() - hw command failed: " << ex.what());
382  }
383  }
384 
386  {
387  std::vector<uint8_t> subpreset_header = prepare_sub_preset_header();
388  std::vector<uint8_t> subpreset_frames_config = prepare_sub_preset_frames_config();
389 
390  std::vector<uint8_t> pattern{};
391  if (subpreset_frames_config.size() > 0)
392  {
393  pattern.insert(pattern.end(), &subpreset_header[0], &subpreset_header[0] + subpreset_header.size());
394  pattern.insert(pattern.end(), &subpreset_frames_config[0], &subpreset_frames_config[0] + subpreset_frames_config.size());
395  }
396 
397  command cmd(ds::SETSUBPRESET, static_cast<int>(pattern.size()));
398  cmd.data = pattern;
399  return cmd;
400  }
401 
402  std::vector<uint8_t> hdr_config::prepare_sub_preset_header() const
403  {
404  //size
405  uint8_t header_size = 5;
406  //id - from member (uint8_t)
407  //iterations - always 0 so that it will be continuous until stopped
408  uint16_t iterations = 0;
409  //sequence size
410  uint8_t num_of_items = static_cast<uint8_t>(_sequence_size);
411 
412  std::vector<uint8_t> header;
413  header.insert(header.end(), &header_size, &header_size + 1);
414  header.insert(header.end(), &_id, &_id + 1);
415  header.insert(header.end(), (uint8_t*)&iterations, (uint8_t*)&iterations + 2);
416  header.insert(header.end(), &num_of_items, &num_of_items + 1);
417 
418  return header;
419  }
420 
421  std::vector<uint8_t> hdr_config::prepare_sub_preset_frames_config() const
422  {
423  //size for each frame header
424  uint8_t frame_header_size = 4;
425  //number of iterations for each frame
426  uint16_t iterations = 1;
427  // number of Controls for current frame
428  uint8_t num_of_controls = 2;
429 
430  std::vector<uint8_t> frame_header;
431  frame_header.insert(frame_header.end(), &frame_header_size, &frame_header_size + 1);
432  frame_header.insert(frame_header.end(), (uint8_t*)&iterations, (uint8_t*)&iterations + 2);
433  frame_header.insert(frame_header.end(), &num_of_controls, &num_of_controls + 1);
434 
435  std::vector<uint8_t> frames_config;
436  for (int i = 0; i < _sequence_size; ++i)
437  {
438  frames_config.insert(frames_config.end(), &frame_header[0], &frame_header[0] + frame_header.size());
439 
440  uint32_t exposure_value = static_cast<uint32_t>(_hdr_sequence_params[i]._exposure);
441  frames_config.insert(frames_config.end(), &CONTROL_ID_EXPOSURE, &CONTROL_ID_EXPOSURE + 1);
442  frames_config.insert(frames_config.end(), (uint8_t*)&exposure_value, (uint8_t*)&exposure_value + 4);
443 
444  uint32_t gain_value = static_cast<uint32_t>(_hdr_sequence_params[i]._gain);
445  frames_config.insert(frames_config.end(), &CONTROL_ID_GAIN, &CONTROL_ID_GAIN + 1);
446  frames_config.insert(frames_config.end(), (uint8_t*)&gain_value, (uint8_t*)&gain_value + 4);
447  }
448 
449  return frames_config;
450  }
451 
453  {
454  // to be elaborated or deleted
455  return true;
456  }
457 
459  {
460  int new_id = static_cast<int>(value);
461 
462  if (new_id != _id)
463  {
464  _id = new_id;
465  }
466  }
467 
469  {
470  size_t new_size = static_cast<size_t>(value);
471  if (new_size > 3 || new_size < 2)
472  throw invalid_value_exception(to_string() << "hdr_config::set_sequence_size(...) failed! Only size 2 or 3 are supported.");
473 
474  if (new_size != _sequence_size)
475  {
476  _hdr_sequence_params.resize(new_size);
477  _sequence_size = new_size;
478  }
479  }
480 
482  {
483  size_t new_index = static_cast<size_t>(value);
484 
485  _is_config_in_process = (new_index != 0);
486 
487  if (new_index <= _hdr_sequence_params.size())
488  {
489  _current_hdr_sequence_index = (int)new_index - 1;
490  }
491  else
492  throw invalid_value_exception(to_string() << "hdr_config::set_sequence_index(...) failed! Index above sequence size.");
493  }
494 
496  {
498  _has_config_changed = true;
499  }
500 
502  {
504  _has_config_changed = true;
505  }
506 
507 
509  _sequence_id(0),
510  _exposure(0.f),
511  _gain(0.f)
512  {}
513 
514  hdr_params::hdr_params(int sequence_id, float exposure, float gain) :
515  _sequence_id(sequence_id),
516  _exposure(exposure),
517  _gain(gain)
518  {}
519 
521  {
522  _sequence_id = other._sequence_id;
523  _exposure = other._exposure;
524  _gain = other._gain;
525 
526  return *this;
527  }
528 
529 
530  // explanation for the sub-preset:
531  /* the structure is:
532 
533  #define SUB_PRESET_BUFFER_SIZE 0x400
534  #pragma pack(push, 1)
535  typedef struct SubPresetHeader
536  {
537  uint8_t headerSize;
538  uint8_t id;
539  uint16_t iterations;
540  uint8_t numOfItems;
541  }SubPresetHeader;
542 
543  typedef struct SubPresetItemHeader
544  {
545  uint8_t headerSize;
546  uint16_t iterations;
547  uint8_t numOfControls;
548  }SubPresetItemHeader;
549 
550  typedef struct SubPresetControl
551  {
552  uint8_t controlId;
553  uint32_t controlValue;
554  }SubPresetControl;
555  #pragma pack(pop)
556  */
557 
558 
559 }
bool validate_config() const
Definition: hdr-config.cpp:452
rs2_option
Defines general configuration controls. These can generally be mapped to camera UVC controls...
Definition: rs_option.h:22
void set_id(float value)
Definition: hdr-config.cpp:458
bool configure_hdr_as_in_fw(const std::vector< byte > &current_subpreset)
Definition: hdr-config.cpp:80
static color_map pattern
Definition: colorizer.cpp:84
#define LOG_WARNING(...)
Definition: src/types.h:241
const char * rs2_option_to_string(rs2_option option)
Definition: rs.cpp:1265
bool is_current_subpreset_hdr(const std::vector< byte > &current_subpreset) const
Definition: hdr-config.cpp:64
GLfloat value
void set_exposure(float value)
Definition: hdr-config.cpp:495
void set_sequence_size(float value)
Definition: hdr-config.cpp:468
float get(rs2_option option) const
Definition: hdr-config.cpp:139
unsigned short uint16_t
Definition: stdint.h:79
std_msgs::Header * header(M &m)
returns Header<M>::pointer(m);
unsigned char uint8_t
Definition: stdint.h:78
void set_sequence_index(float value)
Definition: hdr-config.cpp:481
bool is_enabled() const
Definition: hdr-config.cpp:224
GLdouble f
const uint8_t CONTROL_ID_EXPOSURE
Definition: hdr-config.h:60
std::vector< hdr_params > _hdr_sequence_params
Definition: hdr-config.h:78
void set_options_to_be_restored_after_disable()
Definition: hdr-config.cpp:313
command prepare_hdr_sub_preset_command() const
Definition: hdr-config.cpp:385
std::vector< uint8_t > send(std::vector< uint8_t > const &data) const
Definition: hw-monitor.cpp:115
unsigned int uint32_t
Definition: stdint.h:80
std::vector< uint8_t > prepare_sub_preset_frames_config() const
Definition: hdr-config.cpp:421
std::vector< uint8_t > prepare_sub_preset_header() const
Definition: hdr-config.cpp:402
option_range _gain_range
Definition: hdr-config.h:88
std::vector< uint8_t > data
Definition: hw-monitor.h:240
hdr_params & operator=(const hdr_params &other)
Definition: hdr-config.cpp:520
bool is_config_in_process() const
Definition: hdr-config.cpp:219
std::weak_ptr< sensor_base > _sensor
Definition: hdr-config.h:86
const int DEFAULT_HDR_SEQUENCE_SIZE
Definition: hdr-config.h:54
void set(rs2_option option, float value, option_range range)
Definition: hdr-config.cpp:182
void set_gain(float value)
Definition: hdr-config.cpp:501
bool is_hdr_enabled_in_device(std::vector< byte > &result) const
Definition: hdr-config.cpp:50
const float PRE_ENABLE_HDR_EXPOSURE
Definition: hdr-config.h:57
GLsizei range
int i
option_range _exposure_range
Definition: hdr-config.h:87
GLuint res
Definition: glext.h:8856
hdr_config(hw_monitor &hwm, std::shared_ptr< sensor_base > depth_ep, const option_range &exposure_range, const option_range &gain_range)
Definition: hdr-config.cpp:9
GLushort pattern
GLuint64EXT * result
Definition: glext.h:10921
const uint8_t CONTROL_ID_GAIN
Definition: hdr-config.h:61
GLintptr offset
void set_enable_status(float value)
Definition: hdr-config.cpp:249
bool is_hdr_id(int id) const
Definition: hdr-config.cpp:75
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:16