Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Auto Exp/Gain Limit feature addition to D435i and D455 #12582

Merged

Conversation

noacoohen
Copy link
Contributor

  • FW version < 5.12.11.0 No exp/gain limit support
  • FW version >= 5.12.11.0 AND FW version < 5.13.0.200 using AUTO_CALIB command
  • FW Version >= 5.13.0.200 using GETAELIMITS, SETAELIMITS commands
  • reactivated test-auto-limits.cpp

Tracked by RSDSO-19409

@noacoohen noacoohen requested a review from Nir-Az January 17, 2024 14:58
@@ -6,8 +6,6 @@
/////////////////////////////////////////////////////////////////////////////

//#test:device D400* !D457
// auto-limits option is deprecated currently [LRS-487]
//#test:donotrun

#include "../../catch.h"
#include "../../unit-tests-common.h"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

@@ -57,7 +57,11 @@ namespace librealsense
class auto_exposure_limit_option : public option_base
{
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,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@OhadMeir do we want a weak_ptr here?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

};

class auto_gain_limit_option : public option_base
{
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,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same, weak_ptr?

@@ -100,52 +109,101 @@ namespace librealsense
hw_monitor& _hwm;
sensor_base* _sensor;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

weak_ptr?

@@ -669,6 +669,10 @@ namespace librealsense
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 ) );
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we already have _fw_version set no?

@@ -1046,6 +1050,10 @@ namespace librealsense
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 ) );
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same?

@@ -67,8 +67,16 @@ namespace librealsense
return option_range{ -40, 125, 0, 0 };
}

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,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we place in the feature file?
Or does it really complicate things?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

weak_ptr?

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,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

weak_ptr?

command cmd(ds::AUTO_CALIB);
cmd.param1 = 5;
float ret;
if( _ae_gain_limits_new_opcode )
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 )
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 features?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trinary expression ( ?: ) redundant.
Use bool opcode = fw_ver >= firmware_version( 5, 13, 0, 200 )

@@ -76,12 +80,17 @@ namespace librealsense
hw_monitor& _hwm;
sensor_base* _sensor;
std::weak_ptr<limits_option> _exposure_limit_toggle;
bool _ae_gain_limits_new_opcode;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indentation

, _toggle_range( range )
, _description( description )
, _hwm( hwm )
, _ae_gain_limits_new_opcode( ae_gain_limits_new_opcode ){};

virtual void set(float value) override
{
auto set_limit = _cached_limit;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move implementation to cpp file

Comment on lines 186 to 187
offset = 8;
if( _option == RS2_OPTION_AUTO_GAIN_LIMIT_TOGGLE )
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 )
{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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...

@@ -6,8 +6,6 @@
/////////////////////////////////////////////////////////////////////////////

//#test:device D400* !D457
// auto-limits option is deprecated currently [LRS-487]
//#test:donotrun

#include "../../catch.h"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Won't it be better to change to a python test?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

class synthetic_sensor;
class hw_monitor;

class range_limit_feature : public feature_interface
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 )
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 )
{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not needed here

#include <src/feature-interface.h>

#include <memory>
#include <librealsense2/hpp/rs_options.hpp>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can it be included only in the cpp?

@Tamir91 Tamir91 requested review from Nir-Az and removed request for Nir-Az January 29, 2024 11:39
from rspy import test

#############################################################################################
with test.closure("Gain/Exposure auto limits"):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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...

@noacoohen noacoohen force-pushed the auto_exp_and_gain_limit_missing branch from 5550864 to 8f78079 Compare January 31, 2024 12:53
@OhadMeir OhadMeir merged commit 52fc021 into IntelRealSense:development Feb 1, 2024
17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants