Auto Exp/Gain Limit feature addition to D435i and D455 - #12582
Conversation
| //#test:donotrun | ||
|
|
||
| #include "../../catch.h" | ||
| #include "../../unit-tests-common.h" |
There was a problem hiding this comment.
Please change
//#test:device D400* !D457
to specific D435i && D455 and remove the are_limit_options_supported logic.
This test will pass even if you forgot to register this option
Let's make sure this test actually run
| public: | ||
| auto_exposure_limit_option(hw_monitor& hwm, sensor_base* depth_ep, option_range range, std::shared_ptr<limits_option> exposure_limit_enable); | ||
| auto_exposure_limit_option( hw_monitor & hwm, | ||
| sensor_base * depth_ep, |
There was a problem hiding this comment.
I think we can remove this parameter completely, it is not used.
In other places we used a weak_ptr to check the sensor before sending HMC, but looking now I see that it is checked by locked_transfer so no need here.
We still need to do some order in all this, command_transfer_over_xu might need a weak_ptr and there are still options using direct reference to the sensor. In another PR.
| public: | ||
| auto_gain_limit_option(hw_monitor& hwm, sensor_base* depth_ep, option_range range, std::shared_ptr<limits_option> gain_limit_enable); | ||
| auto_gain_limit_option( hw_monitor & hwm, | ||
| sensor_base * depth_ep, |
| @@ -100,52 +109,101 @@ namespace librealsense | |||
| hw_monitor& _hwm; | |||
| sensor_base* _sensor; | |||
| dev_info, d400_device::_hw_monitor, get_firmware_logs_command(), get_flash_logs_command() ) | ||
| { | ||
| check_and_restore_rgb_stream_extrinsic(); | ||
| firmware_version fw_ver = firmware_version( get_info( RS2_CAMERA_INFO_FIRMWARE_VERSION ) ); |
There was a problem hiding this comment.
I think we already have _fw_version set no?
| dev_info, d400_device::_hw_monitor, get_firmware_logs_command(), get_flash_logs_command() ) | ||
| , d400_thermal_tracking( d400_device::_thermal_monitor ) | ||
| { | ||
| firmware_version fw_ver = firmware_version( get_info( RS2_CAMERA_INFO_FIRMWARE_VERSION ) ); |
|
|
||
| auto_exposure_limit_option::auto_exposure_limit_option(hw_monitor& hwm, sensor_base* ep, option_range range, std::shared_ptr<limits_option> exposure_limit_enable) | ||
| : option_base(range), _hwm(hwm), _sensor(ep), _exposure_limit_toggle(exposure_limit_enable) | ||
| auto_exposure_limit_option::auto_exposure_limit_option( hw_monitor & hwm, |
There was a problem hiding this comment.
Can we place in the feature file?
Or does it really complicate things?
There was a problem hiding this comment.
We can place non generic options in the feature file, but we need to consider the right place for the feature as well.
This is a d400 option, is the feature d400 only? Is it relevant to d500? If not then ds/features is not the right place for it.
| auto_exposure_limit_option::auto_exposure_limit_option(hw_monitor& hwm, sensor_base* ep, option_range range, std::shared_ptr<limits_option> exposure_limit_enable) | ||
| : option_base(range), _hwm(hwm), _sensor(ep), _exposure_limit_toggle(exposure_limit_enable) | ||
| auto_exposure_limit_option::auto_exposure_limit_option( hw_monitor & hwm, | ||
| sensor_base * ep, |
| auto_gain_limit_option::auto_gain_limit_option(hw_monitor& hwm, sensor_base* ep, option_range range, std::shared_ptr <limits_option> gain_limit_enable) | ||
| : option_base(range), _hwm(hwm), _sensor(ep), _gain_limit_toggle(gain_limit_enable) | ||
| auto_gain_limit_option::auto_gain_limit_option( hw_monitor & hwm, | ||
| sensor_base * ep, |
| command cmd(ds::AUTO_CALIB); | ||
| cmd.param1 = 5; | ||
| float ret; | ||
| if( _ae_gain_limits_new_opcode ) |
There was a problem hiding this comment.
Maybe we need 2 features?
instead of using if/else everywhere?
| cmd.param2 = *(reinterpret_cast<uint32_t*>(ret.data())); | ||
| cmd.param3 = static_cast<int>(set_limit); | ||
| if (_option == RS2_OPTION_AUTO_EXPOSURE_LIMIT_TOGGLE) | ||
| if( _ae_gain_limits_new_opcode ) |
There was a problem hiding this comment.
I think we need 2 features (see another comment) but here it is splitting to 2 options.
At least using helper functions.
if( _new_opcode )
set_using_new_opcode()
else
set_using_old_opcode()
| auto exposure_range = sensor.get_option( RS2_OPTION_EXPOSURE ).get_range(); | ||
| auto gain_range = sensor.get_option( RS2_OPTION_GAIN ).get_range(); | ||
|
|
||
| bool auto_exposure_new_opcode = false; |
There was a problem hiding this comment.
Why initialize a value you are about to change? Declare and initialize in the same expression.
|
|
||
| bool auto_exposure_new_opcode = false; | ||
| auto fw_ver = firmware_version(sensor.get_info( RS2_CAMERA_INFO_FIRMWARE_VERSION )); | ||
| auto_exposure_new_opcode = (fw_ver >= firmware_version( 5, 13, 0, 200 )) ? true : false; |
There was a problem hiding this comment.
Trinary expression ( ?: ) redundant.
Use bool opcode = fw_ver >= firmware_version( 5, 13, 0, 200 )
| hw_monitor& _hwm; | ||
| sensor_base* _sensor; | ||
| std::weak_ptr<limits_option> _exposure_limit_toggle; | ||
| bool _ae_gain_limits_new_opcode; |
There was a problem hiding this comment.
No need to mention gain in AE option, rename _new_opcode.
Same goes for other occurences of this name.
| std::vector< uint8_t > res; | ||
| if( _ae_gain_limits_new_opcode ) | ||
| { | ||
| offset = 8; |
|
|
||
| virtual void set(float value) override | ||
| { | ||
| auto set_limit = _cached_limit; |
There was a problem hiding this comment.
Move implementation to cpp file
| offset = 8; | ||
| if( _option == RS2_OPTION_AUTO_GAIN_LIMIT_TOGGLE ) |
There was a problem hiding this comment.
It might be better to have ae_limits_option and gain_limits_option inheriting limits_option, each calling a shared function passing a different offset value.
| _hwm.send(cmd); | ||
| _record_action(*this); | ||
| if( _ae_gain_limits_new_opcode ) | ||
| { |
There was a problem hiding this comment.
Use helper function for readability. Same for other places in these options.
if( _new_opcode )
use_ae_limits_opcode();
else
use_auto_calib_opcode();
| class synthetic_sensor; | ||
| class hw_monitor; | ||
|
|
||
| class auto_exposure_gain_limit_feature : public feature_interface |
There was a problem hiding this comment.
I think we need to seperate it to a range_limit_featrue that is inherited by auto_exposure_limit_feature and gain_limit_feature.
Maybe we will need later for other ranges as well - brightness, hue, contrast etc...
| // auto-limits option is deprecated currently [LRS-487] | ||
| //#test:donotrun | ||
|
|
||
| #include "../../catch.h" |
There was a problem hiding this comment.
Won't it be better to change to a python test?
| class synthetic_sensor; | ||
| class hw_monitor; | ||
|
|
||
| class range_limit_feature : public feature_interface |
There was a problem hiding this comment.
Not exactly what I meant. As it is now, there is no need for range_limit_feature, it serves no purpose.
option 1 - Having 2 completely separate features for AE and gain.
Delete range_limit_feature and split auto_exposure_limit_feature and gain_limit_feature into separate files.
option 2 - Using range_limit_feature for common implementation.
Delete the public interface, we won't have objects of this type.
For instance you can have protected API with functions like:
option_range get_range( rs2_option opt );
std::shared_ptr< limits_option > create_limits_option( rs2_option opt, const char * description );
...
Or each inheriting feature will set members that a common function will use.
Your call which option you prefer
| : option_base( range ) | ||
| , _hwm( hwm ) | ||
| , _sensor( ep ) | ||
| , _exposure_limit_toggle( exposure_limit_enable ) |
There was a problem hiding this comment.
You can use exposure_limit_enable in line 85 without the need to lock.
| if (ret< get_range().min || ret > get_range().max) | ||
| float ret; | ||
| if( _new_opcode ) | ||
| { |
There was a problem hiding this comment.
The current coding convention is not to add braces for one line if/else expressions
|
|
||
| auto ret = static_cast<float>(*(reinterpret_cast<uint32_t*>(res.data()))); | ||
| if (ret< get_range().min || ret > get_range().max) | ||
| float ret; |
There was a problem hiding this comment.
Make a habit of initializing all declared variables.
float ret = get_range().def;
or
float ret = _new_opcode ? query_using_new_opcode() : query_using_old_opcode();
| if( ret.empty() ) | ||
| throw invalid_value_exception( "auto_exposure_limit_option::query result is empty!" ); | ||
|
|
||
| static const int offset = 12; |
There was a problem hiding this comment.
Use more verbose names. Is this max_ae_offset?
| public: | ||
| static const feature_id ID; | ||
|
|
||
| gain_limit_feature( synthetic_sensor & depth_sensor, std::shared_ptr< hw_monitor > hw_monitor ); |
There was a problem hiding this comment.
Pass const std::shared_ptr< hw_monitor > & as parameter.
If you pass by value there are unneeded calls to increase and decrease the ref count.
|
|
||
| class synthetic_sensor; | ||
| class hw_monitor; | ||
| class limits_option; |
| #include <src/feature-interface.h> | ||
|
|
||
| #include <memory> | ||
| #include <librealsense2/hpp/rs_options.hpp> |
There was a problem hiding this comment.
Can it be included only in the cpp?
| from rspy import test | ||
|
|
||
| ############################################################################################# | ||
| with test.closure("Gain/Exposure auto limits"): |
There was a problem hiding this comment.
Split into separate tests - gain toggle one device, gain toggle 2 devices, ae toggle one device, ae toggle 2 devices.
Also are these all the use cases? Test trying to set value when toggle is off etc...
5550864 to
8f78079
Compare
Tracked by RSDSO-19409