Reset Auto Exp/Gain Limit back to default value 0 - #9692
Conversation
ev-mp
left a comment
There was a problem hiding this comment.
I can't find the segment that shows how the manual control overrides the toggle
| RS2_OPTION_ENABLE_EXPOSURE_LIMIT, /**< Enable / disable color image auto-exposure*/ | ||
| RS2_OPTION_ENABLE_GAIN_LIMIT, /**< Enable / disable color image auto-gain*/ |
There was a problem hiding this comment.
Options must be added at the end of enum for back-compat.
Rename the according to the main controls: auto_exposure_limit_on, auto_gain_limit_on
|
|
||
| // Limits Enable/ Disable | ||
|
|
||
| class limits_option : public option |
| virtual ~limits_option() = default; | ||
| virtual void set(float value) override | ||
| { | ||
| _value = value; // 0: gain limit set by user is enabled, 1 : gain limit is disabled (all range 16-248 is valid) |
There was a problem hiding this comment.
0 should correspond to off, 1 -> On
| if (value == 1) // disabled: save current limit | ||
| _cached_limit = _sensor->get_option(RS2_OPTION_AUTO_GAIN_LIMIT).query(); |
There was a problem hiding this comment.
1.Shouldn't be in the base class
2. What happens in case polling the data returns 0?
| case RS2_OPTION_ENABLE_GAIN_LIMIT: return "Disable gain limit"; | ||
| case RS2_OPTION_ENABLE_EXPOSURE_LIMIT: return "Disable exposure limit"; |
| RS2_OPTION_VERTICAL_BINNING, /**< Enables vertical binning which increases the maximal sensed distance. */ | ||
| RS2_OPTION_RECEIVER_SENSITIVITY, /**< Control receiver sensitivity to incoming light, both projected and ambient (same as APD on L515). */ | ||
| RS2_OPTION_COUNT /**< Number of enumeration values. Not a valid input: intended to be used in for-loops. */ | ||
| RS2_OPTION_COUNT, /**< Number of enumeration values. Not a valid input: intended to be used in for-loops. */ |
There was a problem hiding this comment.
Add those before count which must remain last
| std::shared_ptr<auto_exposure_limit_option> auto_exposure_limit_enable_option = nullptr; | ||
| std::shared_ptr<auto_gain_limit_option> auto_gain_limit_enable_option = nullptr; |
There was a problem hiding this comment.
Combine the declaration and allocation into a single statement
| auto_exposure_limit_enable_option = std::make_shared<auto_exposure_limit_option>(*_hw_monitor, &depth_sensor, exposure_range); | ||
| auto_gain_limit_enable_option = std::make_shared<auto_gain_limit_option>(*_hw_monitor, &depth_sensor, gain_range); | ||
|
|
||
| option_range enable_range = { 0.f /*min*/, 1.f /*max*/, 1.f /*step*/, 1.f /*default*/ }; |
|
|
||
| //GAIN Limit | ||
| std::shared_ptr<gain_limit_option> gain_limit_enable_option = nullptr; | ||
| gain_limit_enable_option = std::make_shared<gain_limit_option>(RS2_OPTION_AUTO_GAIN_LIMIT_ON, enable_range, auto_gain_limit_enable_option.get()); |
There was a problem hiding this comment.
Pass the dependent option with via shared/weak_ptr according to the content
| void auto_exposure_limit_option::set(float value) | ||
| { | ||
| if (!is_valid(value)) | ||
| if (!is_valid(value) && value != 0) |
There was a problem hiding this comment.
is_valid shall handle all cases, why the extra clause?
| if (value != 0) | ||
| _cached_limit = value; | ||
| else | ||
| value = get_range().max; |
There was a problem hiding this comment.
Injecting "0" is not a valid use-case for the control, - must have the same range as the corresponding UVC control
| void auto_gain_limit_option::set(float value) | ||
| { | ||
| if (!is_valid(value)) | ||
| if (!is_valid(value) && value != 0) |
| case RS2_OPTION_AUTO_GAIN_LIMIT_ON: return "Enable gain limit"; | ||
| case RS2_OPTION_AUTO_EXPOSURE_LIMIT_ON: return "Enable exposure limit"; |
There was a problem hiding this comment.
It is required by design
| virtual ~limits_option() = default; | ||
| virtual void set(float) override = 0; | ||
| virtual float query() const override { return _value; }; | ||
| virtual option_range get_range() const override { return _toggle_range; }; | ||
| virtual bool is_enabled() const override { return true; } | ||
| virtual const char* get_description() const override { return "Enable Limits Option"; }; | ||
| virtual void enable_recording(std::function<void(const option&)> record_action) override { _record_action = record_action; } |
There was a problem hiding this comment.
most of the override re-implement the base-class functionality.
Needs refactoring
| _cached_limit = value; | ||
|
|
||
| _exposure_limit_enable->set_cached_limit(value); | ||
| if (value != get_range().max && _exposure_limit_enable->query() == 0.f) |
There was a problem hiding this comment.
Why the max value is not allowed?
There was a problem hiding this comment.
I wanted to keep the toggle off at the beginning but I can remove the max-value condition.
The second part of the condition is relevant to prevent redundant commands to FW.
|
|
||
| auto_exposure_limit_option::auto_exposure_limit_option(hw_monitor& hwm, sensor_base* ep, option_range range) | ||
| : option_base(range), _hwm(hwm), _sensor(ep) | ||
| auto_exposure_limit_option::auto_exposure_limit_option(hw_monitor& hwm, sensor_base* ep, option_range range, limits_option* exposure_limit_enable) |
There was a problem hiding this comment.
As discussed, pass and store the option's handler via weak_ptr
| std::shared_ptr<limits_option> exposure_limit_enable_option = std::make_shared<limits_option>(RS2_OPTION_AUTO_EXPOSURE_LIMIT_ON, enable_range, "Enable Exposure auto-Limit", *_hw_monitor); | ||
| std::shared_ptr<auto_exposure_limit_option> auto_exposure_limit_enable_option = std::make_shared<auto_exposure_limit_option>(*_hw_monitor, &depth_sensor, exposure_range, exposure_limit_enable_option.get()); | ||
| depth_sensor.register_option(RS2_OPTION_AUTO_EXPOSURE_LIMIT_ON, exposure_limit_enable_option); |
There was a problem hiding this comment.
The names are confusing, make it more distinct, like "ae_limit_toggle_control", "ae_limit_value_control"
| //GAIN Limit | ||
| std::shared_ptr<gain_limit_option> gain_limit_enable_option = std::make_shared<gain_limit_option>(RS2_OPTION_AUTO_GAIN_LIMIT_ON, enable_range, auto_gain_limit_enable_option.get()); | ||
| depth_sensor.register_option(RS2_OPTION_AUTO_GAIN_LIMIT, auto_gain_limit_enable_option); | ||
| std::shared_ptr<limits_option> gain_limit_enable_option = std::make_shared<limits_option>(RS2_OPTION_AUTO_GAIN_LIMIT_ON, enable_range, "Enable Gain auto-Limit", *_hw_monitor); |
There was a problem hiding this comment.
"Enable Gain auto-Limit" -> "Toggle Auto-Gain Limit"
| CASE(RECEIVER_SENSITIVITY) | ||
| case RS2_OPTION_AUTO_GAIN_LIMIT_ON: return "Enable gain limit"; | ||
| case RS2_OPTION_AUTO_EXPOSURE_LIMIT_ON: return "Enable exposure limit"; | ||
| CASE(AUTO_GAIN_LIMIT_ON) |
There was a problem hiding this comment.
Pls rename the options to RS2_OPTION_AUTO_XXX_LIMIT_TOGGLE
|
|
||
| auto_gain_limit_option::auto_gain_limit_option(hw_monitor& hwm, sensor_base* ep, option_range range) | ||
| : option_base(range), _hwm(hwm), _sensor(ep) | ||
| auto_gain_limit_option::auto_gain_limit_option(hw_monitor& hwm, sensor_base* ep, option_range range, limits_option* gain_limit_enable) |
There was a problem hiding this comment.
replace flat pointer with smart
| throw invalid_value_exception("set(enable_auto_gain) failed! Invalid Auto-Gain mode request " + std::to_string(value)); | ||
|
|
||
| _gain_limit_enable->set_cached_limit(value); | ||
| if(value != get_range().max && _gain_limit_enable->query() == 0.f) |
There was a problem hiding this comment.
As long as the value is valid the toggle shall be set on.
At this point the valid is already verified to be within the range - I don't think the check is required
| { | ||
| public: | ||
| auto_exposure_limit_option(hw_monitor& hwm, sensor_base* depth_ep, option_range range); | ||
| auto_exposure_limit_option(hw_monitor& hwm, sensor_base* depth_ep, option_range range, limits_option* exposure_limit_enable); |
There was a problem hiding this comment.
use smart_ptrs here and below
| std::cout << "1. Check if initial values of limit control is set to max value" << std::endl; | ||
| auto init_limit = s.get_option(limit_control); | ||
| //auto enable = s.get_option(enable_limit); | ||
| REQUIRE(init_limit == range.max); |
There was a problem hiding this comment.
we can't use this assumption, the value is stored in FW only
| // 1. Toggle : | ||
| // - if toggle is off check that control limit value is 0 | ||
| // - if toggle is on check that control value is in the correct range | ||
| auto limit = s.get_option(limits_value[i]); | ||
| auto toggle = s.get_option(limits_toggle[i]); | ||
| if (toggle == 0) | ||
| REQUIRE(limit == 0); |
There was a problem hiding this comment.
For the limit control zero is not in the valid range. It is only applicable to the toggle
| s.set_option(enable_limit, 0.f); | ||
| auto post_disable = s.get_option(limit_control); | ||
| REQUIRE(post_disable == range.max); | ||
| for (auto i = 0; i < 2; i++) // exposure or gain |
There was a problem hiding this comment.
Also run the following check:
- toggle on both dev1 and dev2 and set two distinct values for the auto-exposure /gain.
- toggle both dev1 and dev2 off.
- toggle dev1 on:
- verify that the limit value is the value that was stored (cached) in dev1.
- verify that for dev2 both the limit and the toggle values are similar to those of dev1
| std::string val = s.get_info(RS2_CAMERA_INFO_NAME); | ||
| if (!s.supports(limits_value[i])) |
There was a problem hiding this comment.
to simplify the flow extract the depth sensor and check if the option is supported in
std::array < std::vector, 2> sensors = { dev1.query_sensors(), dev2.query_sensors() };
|
Note that there is a merge conflict with the dev branch - needs to be resolved |
ev-mp
left a comment
There was a problem hiding this comment.
There are multiple unrequired files in src/types_XXX.cpp form to be removed
| float query_limit_value() | ||
| { | ||
| auto offset = 0; | ||
| if (_option == RS2_OPTION_AUTO_GAIN_LIMIT_TOGGLE) | ||
| offset = 4; | ||
| command cmd(ds::AUTO_CALIB); | ||
| cmd.param1 = 5; | ||
| auto res = _hwm.send(cmd); | ||
| if (res.empty()) | ||
| throw invalid_value_exception("auto_exposure_limit_option::query result is empty!"); | ||
|
|
||
| return static_cast<float>(*(reinterpret_cast<uint32_t*>(res.data() + offset))); | ||
| }; |
There was a problem hiding this comment.
The call returns the actual value stored, rather than [0,1]. Is it intended?
There was a problem hiding this comment.
This func is redundant - removed
There was a problem hiding this comment.
Rebase the code - this segment has been moved to "ro-string.cpp"
| float _value; | ||
| option_range _toggle_range; | ||
| const std::map<float, std::string> _description_per_value; | ||
| float _cached_limit; |
There was a problem hiding this comment.
No need here - use the original "float _value;"
There was a problem hiding this comment.
Add maintainer's comment then
| std::shared_ptr<lazy<rs2_extrinsics>> _color_extrinsic; | ||
| bool _is_locked = true; | ||
|
|
||
| std::shared_ptr<limits_option> _gain_limit_toggle_control; |
There was a problem hiding this comment.
_gain_limit_toggle_control and _ae_limit_toggle_control are registered directly into the options container. No need for extra owner
| hw_monitor& _hwm; | ||
| sensor_base* _sensor; | ||
| std::shared_ptr<limits_option> _exposure_limit_enable; | ||
| std::shared_ptr<limits_option> _exposure_limit_toggle; |
There was a problem hiding this comment.
Store a weak_ptr to the handle
There was a problem hiding this comment.
It doesn't work with weak_ptr
| hw_monitor& _hwm; | ||
| sensor_base* _sensor; | ||
| std::shared_ptr<limits_option> _gain_limit_enable; | ||
| std::shared_ptr<limits_option> _gain_limit_toggle; |
| virtual bool is_enabled() const override { return true; } | ||
| virtual const char* get_description() const override { return _description; }; |
There was a problem hiding this comment.
Check if those already exist in the base class
There was a problem hiding this comment.
Those are not implemented in base class
| float query_limit_value() | ||
| { | ||
| auto offset = 0; | ||
| if (_option == RS2_OPTION_AUTO_GAIN_LIMIT_TOGGLE) | ||
| offset = 4; | ||
| command cmd(ds::AUTO_CALIB); | ||
| cmd.param1 = 5; | ||
| auto res = _hwm.send(cmd); | ||
| if (res.empty()) | ||
| throw invalid_value_exception("auto_exposure_limit_option::query result is empty!"); | ||
|
|
||
| return static_cast<float>(*(reinterpret_cast<uint32_t*>(res.data() + offset))); | ||
| }; |
There was a problem hiding this comment.
I can't see references in code - where is it used?
63bfa6a to
6fee1ac
Compare
| return range; | ||
| }; | ||
| _exposure_limit_toggle->set_cached_limit(range.max); | ||
| _exposure_limit_toggle.lock()->set_cached_limit(range.max); |
There was a problem hiding this comment.
Add check for weak->share ptr conversion is successful
| _exposure_limit_toggle->set_cached_limit(value); | ||
| if (_exposure_limit_toggle->query() == 0.f) | ||
| _exposure_limit_toggle->set(1); | ||
| _exposure_limit_toggle.lock()->set_cached_limit(value); |
There was a problem hiding this comment.
Also here and below in 703, 720, 728-30, 759
Track on DSO-17393