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

Can update options automatically, get notification of value change #12483

Merged
merged 20 commits into from
Jan 2, 2024
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
ff66099
Add options_updater class
OhadMeir Dec 4, 2023
3f8a59d
Add option_value_update callback to the API, syntethic_sensor uses op…
OhadMeir Dec 4, 2023
efddef6
Handle PR#12483 comments. Rename to options_watcher, better use of su…
OhadMeir Dec 11, 2023
ad468ab
More PR#12483 comments. Callback registration at sensor_interface lev…
OhadMeir Dec 12, 2023
8f5c4a9
Set options_watcher interval from settings
OhadMeir Dec 12, 2023
01511e0
Fix includes
OhadMeir Dec 13, 2023
5370268
Register all options to option-watcher
OhadMeir Dec 13, 2023
ec27297
Fix cppcheck issue
OhadMeir Dec 13, 2023
7117f5d
Catch options-watcher query exceptions
OhadMeir Dec 17, 2023
0f75400
Fix unit-tests compilation errors
OhadMeir Dec 17, 2023
ad5658e
Catch options-watcher initialization query exception
OhadMeir Dec 17, 2023
2c650b1
options-watcher using one map. API callbacks function renamed
OhadMeir Dec 20, 2023
5fa97e6
Fix cpp unit tests. options-watcher thread stops as soon as possible
OhadMeir Dec 24, 2023
6730ac6
options-watcher queries option before starting thread
OhadMeir Dec 24, 2023
3af987f
Powering on UVC before updating options. Using condition variable to …
OhadMeir Dec 26, 2023
a128169
Fix typo. Thread loop waits first because update happens right before…
OhadMeir Dec 26, 2023
cd0b14e
Adding destruction flag to stop queries as soon as possible
OhadMeir Dec 26, 2023
08f25fb
options-watcher catching join exception in stop. viewer catches excep…
OhadMeir Dec 26, 2023
9bbe102
Add on option changed to python wrapper. Add options-watcher unit test
OhadMeir Dec 28, 2023
649bffe
Add test cases to the options-wathcer unit test
OhadMeir Jan 1, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions common/subdevice-model.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,17 @@ namespace rs2
auto opt = static_cast<rs2_option>(i);

opt_container[opt] = create_option_model(opt, opt_base_label, model, options, options_invalidated, error_message);
model->s->on_options_changed( [model]( const options_list & list )
{
for( auto opt_id : list )
{
auto it = model->options_metadata.find( opt_id );
if( it != model->options_metadata.end() )
{
it->second.value = it->second.endpoint->get_option( opt_id );
}
}
} );
}
}

Expand Down
12 changes: 7 additions & 5 deletions include/librealsense2/h/rs_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,20 @@ rs2_context* rs2_create_context(int api_version, rs2_error** error);
* \param[in] api_version Users are expected to pass their version of \c RS2_API_VERSION to make sure they are running the correct librealsense version.
* \param[in] json_settings Pointer to a string containing a JSON configuration to use, or null if none
* Possible <setting>:<default-value> :
* inherit: true - (bool) whether to inherit and override library configuration file values:
* inherit: true - (bool) whether to inherit and override library configuration file values:
* the 'context' key in the file is taken as-is
* '<executable-name>/context' is merged, if it exists
* then the context-settings are merged
* dds: {} - (requires BUILD_WITH_DDS) false disables DDS; otherwise the DDS settings:
* domain: 0 - (int) the number of the DDS domain [0-232]
* participant: <exe name> - (string) the name of the participant
* dds: {} - (requires BUILD_WITH_DDS) false disables DDS; otherwise the DDS settings:
* domain: 0 - (int) the number of the DDS domain [0-232]
* participant: <exe name> - (string) the name of the participant
* (see additional settings in realdds/doc/device.md#Settings)
* format-conversion: full - (string) how to convert formats
* format-conversion: full - (string) how to convert formats
* full: provide all conversions (e.g., YUYV -> RGB8 etc.)
* basic: use mostly raw camera formats (no RGB8 etc.); convert interleaved (Y8I -> 2xY8)
* raw: leave all formats from camera as they are
* options-update-interval: 1000 - (uint32_t) time interval in milliseconds for option value change notifications
* (see rs2_set_options_changed_callback)
* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored.
* \return Context object
*/
Expand Down
22 changes: 22 additions & 0 deletions include/librealsense2/h/rs_option.h
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,28 @@ extern "C" {
*/
const char* rs2_get_option_value_description(const rs2_options* options, rs2_option option, float value, rs2_error ** error);

/**
* Sets a callback in case an option in this options container value is updated.
* Will create a thread that will periodically check the options in the container for updates.
* The update period is determined by the context's 'options-update-interval' setting.
* \param[in] options the options container
* \param[in] callback callback function pointer to update on value changes
maloel marked this conversation as resolved.
Show resolved Hide resolved
* \param[out] error if non-null, receives any error that occurs during this call, otherwise, errors are ignored
*/
void rs2_set_options_changed_callback( rs2_options * options,
rs2_options_changed_callback_ptr callback,
rs2_error ** error );

/**
* Sets a callback in case an option in this options container value is updated
* \param[in] options the options container
* \param[in] callback callback object created from c++ application. ownership over the callback object is moved to librealsense
* \param[out] error if non-null, receives any error that occurs during this call, otherwise, errors are ignored
*/
void rs2_set_options_changed_callback_cpp( rs2_options * options,
rs2_options_changed_callback * callback,
rs2_error ** error );

#ifdef __cplusplus
}
#endif
Expand Down
7 changes: 5 additions & 2 deletions include/librealsense2/h/rs_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ typedef enum rs2_matchers
} rs2_matchers;
const char* rs2_matchers_to_string(rs2_matchers stream);


typedef struct rs2_device_info rs2_device_info;
typedef struct rs2_device rs2_device;
typedef struct rs2_error rs2_error;
Expand Down Expand Up @@ -250,6 +251,7 @@ typedef struct rs2_sensor_list rs2_sensor_list;
typedef struct rs2_sensor rs2_sensor;
typedef struct rs2_options rs2_options;
typedef struct rs2_options_list rs2_options_list;
typedef struct rs2_options_changed_callback rs2_options_changed_callback;
typedef struct rs2_devices_changed_callback rs2_devices_changed_callback;
typedef struct rs2_notification rs2_notification;
typedef struct rs2_notifications_callback rs2_notifications_callback;
Expand All @@ -259,11 +261,12 @@ typedef struct rs2_firmware_log_parser rs2_firmware_log_parser;
typedef struct rs2_terminal_parser rs2_terminal_parser;
typedef void (*rs2_log_callback_ptr)(rs2_log_severity, rs2_log_message const *, void * arg);
typedef void (*rs2_notification_callback_ptr)(rs2_notification*, void*);
typedef void(*rs2_software_device_destruction_callback_ptr)(void*);
typedef void (*rs2_software_device_destruction_callback_ptr)(void*);
typedef void (*rs2_devices_changed_callback_ptr)(rs2_device_list*, rs2_device_list*, void*);
typedef void (*rs2_frame_callback_ptr)(rs2_frame*, void*);
typedef void (*rs2_frame_processor_callback_ptr)(rs2_frame*, rs2_source*, void*);
typedef void(*rs2_update_progress_callback_ptr)(const float, void*);
typedef void (*rs2_update_progress_callback_ptr)(const float, void*);
typedef void (*rs2_options_changed_callback_ptr)(const rs2_options_list *);

typedef double rs2_time_t; /**< Timestamp format. units are milliseconds */
typedef long long rs2_metadata_type; /**< Metadata attribute type is defined as 64 bit signed integer*/
Expand Down
118 changes: 114 additions & 4 deletions include/librealsense2/hpp/rs_options.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,107 @@
#define LIBREALSENSE_RS2_OPTIONS_HPP

#include "rs_types.hpp"
#include "../h/rs_types.h"

#include <memory>


namespace rs2
{
{
class options_list
{
public:
explicit options_list( std::shared_ptr< rs2_options_list > list )
: _list( std::move( list ) )
{
}

options_list & operator=( std::shared_ptr< rs2_options_list > list )
{
_list = std::move( list );
return *this;
}

rs2_option operator[]( size_t index ) const
{
rs2_error * e = nullptr;
rs2_option opt = rs2_get_option_from_list( _list.get(), static_cast< int >( index ), &e );
error::handle( e );
return opt;
}

size_t size() const
{
rs2_error * e = nullptr;
auto size = rs2_get_options_list_size( _list.get(), &e );
error::handle( e );
return size;
}

rs2_option front() const { return ( *this )[0]; }
rs2_option back() const { return ( *this )[size() - 1]; }

class options_list_iterator
{
options_list_iterator( const options_list & list, size_t index )
: _list( list )
, _index( index )
{
}

public:
rs2_option operator*() const { return _list[_index]; }
bool operator!=( const options_list_iterator & other ) const
{
return other._index != _index || &other._list != &_list;
}

bool operator==( const options_list_iterator & other ) const
{
return ! ( *this != other );
}

options_list_iterator & operator++()
{
_index++;
return *this;
}

private:
friend options_list;
const options_list & _list;
size_t _index;
};

options_list_iterator begin() const { return options_list_iterator( *this, 0 ); }
options_list_iterator end() const { return options_list_iterator( *this, size() ); }

operator std::shared_ptr< rs2_options_list >() { return _list; };

private:
std::shared_ptr< rs2_options_list > _list;
};

class options_changed_callback : public rs2_options_changed_callback
{
std::function< void( const options_list & ) > _callback;

public:
explicit options_changed_callback( const std::function< void( const options_list & ) > & callback )
: _callback( callback )
{
}

void on_value_changed( rs2_options_list * list ) override
{
std::shared_ptr< rs2_options_list > sptr( list, rs2_delete_options_list );
options_list opt_list( sptr );
_callback( opt_list );
}

void release() override { delete this; }
Nir-Az marked this conversation as resolved.
Show resolved Hide resolved
};

class options
{
public:
Expand Down Expand Up @@ -116,13 +214,22 @@ namespace rs2
return res > 0;
}

/**
* sets a callback in case an option in this options container value is updated
* \param[in] callback the callback function
*/
void on_options_changed( std::function< void( const options_list & ) > callback ) const
{
rs2_error * e = nullptr;
rs2_set_options_changed_callback_cpp( _options, new options_changed_callback( callback ), &e );
error::handle( e );
}

std::vector<rs2_option> get_supported_options()
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 change this to return an options_list?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Affects to many places, will consider doing it in a future PR.
I will open a ticket for it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is also an API change. Are you sure about this?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Should be fairly compatible: we'll return an options_list that can be used as a vector and iterated over.
If the unit-tests pass, I think it's a good sign.
You can also easily add a couple of lines to a C++ example and check.
But if you want to keep like this for now, I'm OK with it.

{
std::vector<rs2_option> res;
rs2_error* e = nullptr;
std::shared_ptr<rs2_options_list> options_list(
rs2_get_options_list(_options, &e),
rs2_delete_options_list);
std::shared_ptr< rs2_options_list > options_list( rs2_get_options_list(_options, &e), rs2_delete_options_list);

for (auto opt = 0; opt < rs2_get_options_list_size(options_list.get(), &e);opt++)
{
Expand All @@ -140,6 +247,7 @@ namespace rs2
options(const options& other) : _options(other._options) {}

virtual ~options() = default;

protected:
explicit options(rs2_options* o = nullptr) : _options(o)
{
Expand All @@ -155,5 +263,7 @@ namespace rs2
private:
rs2_options* _options;
};


}
#endif // LIBREALSENSE_RS2_OIPTIONS_HPP
8 changes: 8 additions & 0 deletions include/librealsense2/hpp/rs_types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,14 @@ struct rs2_update_progress_callback
};
typedef std::shared_ptr<rs2_update_progress_callback> rs2_update_progress_callback_sptr;

struct rs2_options_changed_callback
{
virtual void on_value_changed( rs2_options_list * list ) = 0;
virtual void release() = 0;
virtual ~rs2_options_changed_callback() {}
};
typedef std::shared_ptr< rs2_options_changed_callback > rs2_options_changed_callback_sptr;

namespace rs2
{
class error : public std::runtime_error
Expand Down
2 changes: 2 additions & 0 deletions src/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ target_sources(${LRS_TARGET}
"${CMAKE_CURRENT_LIST_DIR}/options-interface.h"
"${CMAKE_CURRENT_LIST_DIR}/options-registry.h"
"${CMAKE_CURRENT_LIST_DIR}/options-registry.cpp"
"${CMAKE_CURRENT_LIST_DIR}/options-watcher.h"
"${CMAKE_CURRENT_LIST_DIR}/options-watcher.cpp"
"${CMAKE_CURRENT_LIST_DIR}/info.h"
"${CMAKE_CURRENT_LIST_DIR}/extension.h"
"${CMAKE_CURRENT_LIST_DIR}/pose-frame.h"
Expand Down
Loading
Loading