From b6d36db7bc98db5135cc4fd4904200a090c0c517 Mon Sep 17 00:00:00 2001 From: aangerma Date: Tue, 28 Jan 2020 16:21:37 +0200 Subject: [PATCH] Code review fixes. --- common/model-views.cpp | 82 ++++---- common/model-views.h | 5 +- include/CMakeLists.txt | 1 + include/librealsense2/h/rs_device.h | 6 + include/librealsense2/h/rs_option.h | 28 ++- include/librealsense2/h/rs_types.h | 2 +- .../hpp/rs_serializable_device.hpp | 57 ++++++ include/librealsense2/rs.hpp | 2 + include/librealsense2/rs_advanced_mode.h | 6 - include/librealsense2/rs_advanced_mode.hpp | 49 +---- include/librealsense2/rsutil.h | 1 - src/ds5/advanced_mode/rs_advanced_mode.cpp | 17 -- src/l500/CMakeLists.txt | 4 +- src/l500/l500-controls.cpp | 181 ------------------ src/l500/l500-depth.cpp | 58 +++--- src/l500/l500-depth.h | 3 +- src/l500/l500-factory.cpp | 6 +- src/l500/l500-options.cpp | 177 +++++++++++++++++ src/l500/{l500-controls.h => l500-options.h} | 67 ++----- src/l500/l500-private.cpp | 2 +- src/l500/l500-private.h | 4 +- src/option.h | 50 +++-- src/realsense.def | 2 + src/rs.cpp | 20 +- src/types.cpp | 34 +++- src/types.h | 4 + unit-tests/unit-tests-live.cpp | 72 ++++--- 27 files changed, 493 insertions(+), 447 deletions(-) create mode 100644 include/librealsense2/hpp/rs_serializable_device.hpp delete mode 100644 src/l500/l500-controls.cpp create mode 100644 src/l500/l500-options.cpp rename src/l500/{l500-controls.h => l500-options.h} (51%) diff --git a/common/model-views.cpp b/common/model-views.cpp index dbde26fed1..a51ecac38f 100644 --- a/common/model-views.cpp +++ b/common/model-views.cpp @@ -32,8 +32,16 @@ using namespace rs400; using namespace nlohmann; -const int XGA = 0; -const int VGA = 1; + +rs2_sensor_mode resolution_from_width_height(int width, int height) +{ + if ((width == 640 && height == 480) || (height == 640 && width == 480)) + return RS2_SENSOR_MODE_VGA; + else if ((width == 1024 && height == 768) || (height == 768 && width == 1024)) + return RS2_SENSOR_MODE_XGA; + else + return RS2_SENSOR_MODE_COUNT; +} ImVec4 flip(const ImVec4& c) { @@ -739,7 +747,7 @@ namespace rs2 ImGui::PopStyleColor(); if (ImGui::IsItemHovered()) - ImGui::SetTooltip("Selectcustom region of interest for the auto-exposure algorithm\nClick the button, then draw a rect on the frame"); + ImGui::SetTooltip("Select custom region of interest for the auto-exposure algorithm\nClick the button, then draw a rect on the frame"); } } @@ -825,8 +833,7 @@ namespace rs2 bool* options_invalidated, std::string& error_message) { - - for (auto&& i:options->get_supported_options()) + for (auto&& i: options->get_supported_options()) { auto opt = static_cast(i); @@ -903,6 +910,7 @@ namespace rs2 depth_decoder(std::make_shared()), viewer(viewer) { + supported_options = s->get_supported_options(); restore_processing_block("colorizer", depth_colorizer); restore_processing_block("yuy2rgb", yuy2rgb); @@ -1121,8 +1129,8 @@ namespace rs2 get_default_selection_index(res_values, resolution_constrain, &selection_index); ui.selected_res_id = selection_index; - if (s->supports(RS2_OPTION_CAMERA_MODE)) - s->set_option(RS2_OPTION_CAMERA_MODE, res_values[ui.selected_res_id].first == 640 || res_values[ui.selected_res_id].second == 640 ? VGA : XGA); + if (s->supports(RS2_OPTION_SENSOR_MODE)) + s->set_option(RS2_OPTION_SENSOR_MODE, resolution_from_width_height(res_values[ui.selected_res_id].first, res_values[ui.selected_res_id].second)); while (ui.selected_res_id >= 0 && !is_selected_combination_supported()) ui.selected_res_id--; last_valid_ui = ui; @@ -1221,17 +1229,13 @@ namespace rs2 res = true; _options_invalidated = true; - if (s->supports(RS2_OPTION_CAMERA_MODE)) + if (s->supports(RS2_OPTION_SENSOR_MODE)) { - const int XGA = 0; - const int VGA = 1; - auto width = res_values[ui.selected_res_id].first; auto height = res_values[ui.selected_res_id].second; - if (width == 640 || height == 640) - s->set_option(RS2_OPTION_CAMERA_MODE, VGA); - else - s->set_option(RS2_OPTION_CAMERA_MODE, XGA); + auto res = resolution_from_width_height(width, height); + if (res >= RS2_SENSOR_MODE_XGA && res <= RS2_SENSOR_MODE_VGA) + s->set_option(RS2_OPTION_SENSOR_MODE, res); } } ImGui::PopStyleColor(); @@ -1869,12 +1873,13 @@ namespace rs2 for (auto&& pbm : post_processing) pbm->save_to_config_file(); } - auto option = 0; - if (option++ < s->get_supported_options().size()) + + if (next_option < supported_options.size()) { - if (options_metadata.find(static_cast(next_option)) != options_metadata.end()) + auto next = supported_options[next_option]; + if (options_metadata.find(static_cast(next)) != options_metadata.end()) { - auto& opt_md = options_metadata[static_cast(next_option)]; + auto& opt_md = options_metadata[static_cast(next)]; opt_md.update_all_fields(error_message, notifications); if (next_option == RS2_OPTION_ENABLE_AUTO_EXPOSURE) @@ -4960,8 +4965,9 @@ namespace rs2 ImGui::PushStyleColor(ImGuiCol_TextSelectedBg, light_grey); ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(5, 5)); ImGui::PushFont(window.get_font()); + auto serializable = dev.as(); - const auto load_json = [&](const std::string f) { + const auto load_json = [&, serializable](const std::string f) { std::ifstream file(f); if (!file.good()) { @@ -4971,9 +4977,10 @@ namespace rs2 throw std::runtime_error(to_string() << "Failed to read configuration file:\n\"" << f << "\"\nRemoving it from presets."); } std::string str((std::istreambuf_iterator(file)), std::istreambuf_iterator()); - if (auto advanced = dev.as()) + + if (serializable) { - advanced.load_json(str); + serializable.load_json(str); for (auto&& sub : subdevices) { //If json was loaded correctly, we want the presets combo box to show the name of the configuration file @@ -4996,15 +5003,14 @@ namespace rs2 viewer.not_model.add_log(to_string() << "Loaded settings from \"" << f << "\"..."); }; - const auto save_to_json = [&](std::string full_filename) + const auto save_to_json = [&, serializable](std::string full_filename) { - auto advanced = dev.as(); if (!ends_with(to_lower(full_filename), ".json")) full_filename += ".json"; std::ofstream outfile(full_filename); json saved_configuraion; - if (auto advanced = dev.as()) + if (serializable) { - saved_configuraion = json::parse(advanced.serialize_json()); + saved_configuraion = json::parse(serializable.serialize_json()); } save_viewer_configurations(outfile, saved_configuraion); outfile << saved_configuraion.dump(4); @@ -5104,7 +5110,10 @@ namespace rs2 else { //File was chosen - auto f = full_files_names[selected - static_cast(labels.size() - files_labels.size())]; + auto file = selected - static_cast(labels.size() - files_labels.size()); + if(file < 0 || file > full_files_names.size()) + throw std::runtime_error("not a valid format"); + auto f = full_files_names[file]; error_message = safe_call([&]() { load_json(f); }); selected_file_preset = f; } @@ -5135,17 +5144,17 @@ namespace rs2 const ImVec2 icons_size{ 20, 20 }; //TODO: Change this once we have support for loading jsons with more data than only advanced controls bool is_streaming = std::any_of(subdevices.begin(), subdevices.end(), [](const std::shared_ptr& sm) { return sm->streaming; }); - const int buttons_flags = dev.is() ? 0 : ImGuiButtonFlags_Disabled; + const int buttons_flags = serializable ? 0 : ImGuiButtonFlags_Disabled; static bool require_advanced_mode_enable_prompt = false; auto advanced_dev = dev.as(); - bool is_advanced_mode_enabled = true; + auto is_advanced_device = false; + auto is_advanced_mode_enabled = false; if (advanced_dev) { + is_advanced_device = true; is_advanced_mode_enabled = advanced_dev.is_enabled(); } - auto serializable_dev = dev.is(); - ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 3); //////////////////////////////////////// @@ -5157,7 +5166,7 @@ namespace rs2 if (ImGui::ButtonEx(upload_button_name.c_str(), icons_size, (is_streaming && !load_json_if_streaming) ? ImGuiButtonFlags_Disabled : buttons_flags)) { - if (serializable_dev && is_advanced_mode_enabled) + if (serializable && (!is_advanced_device || is_advanced_mode_enabled)) { json_loading([&]() { @@ -5189,7 +5198,7 @@ namespace rs2 ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 1); //Align the two icons to buttom if (ImGui::ButtonEx(save_button_name.c_str(), icons_size, buttons_flags)) { - if (serializable_dev && is_advanced_mode_enabled) + if (serializable && (!is_advanced_device || is_advanced_mode_enabled)) { auto ret = file_dialog_open(save_file, "JavaScript Object Notation (JSON)\0*.json\0", NULL, NULL); if (ret) @@ -5412,7 +5421,8 @@ namespace rs2 //////////////////////////////////////// // draw advanced mode panel //////////////////////////////////////// - if (dev.is()) + auto serializable = dev.is(); + if (serializable) { pos = ImGui::GetCursorPos(); const float vertical_space_before_advanced_mode_control = 10.0f; @@ -5674,7 +5684,7 @@ namespace rs2 if (show_stream_selection) sub->draw_stream_selection(); - static const std::vector drawing_order = dev.is() ? + static const std::vector drawing_order = serializable ? std::vector{ RS2_OPTION_EMITTER_ENABLED, RS2_OPTION_ENABLE_AUTO_EXPOSURE } : std::vector{ RS2_OPTION_VISUAL_PRESET, RS2_OPTION_EMITTER_ENABLED, RS2_OPTION_ENABLE_AUTO_EXPOSURE }; @@ -5698,7 +5708,7 @@ namespace rs2 if (skip_option(opt)) continue; if (std::find(drawing_order.begin(), drawing_order.end(), opt) == drawing_order.end()) { - if (dev.is() && opt == RS2_OPTION_VISUAL_PRESET) + if (serializable && opt == RS2_OPTION_VISUAL_PRESET) continue; if (sub->draw_option(opt, dev.is() || update_read_only_options, error_message, viewer.not_model)) { diff --git a/common/model-views.h b/common/model-views.h index 413b52f500..e60a31b661 100644 --- a/common/model-views.h +++ b/common/model-views.h @@ -270,7 +270,7 @@ namespace rs2 opt == RS2_OPTION_STREAM_FORMAT_FILTER || opt == RS2_OPTION_STREAM_INDEX_FILTER || opt == RS2_OPTION_FRAMES_QUEUE_SIZE || - opt == RS2_OPTION_CAMERA_MODE) + opt == RS2_OPTION_SENSOR_MODE) return true; return false; } @@ -689,7 +689,8 @@ namespace rs2 frame_queues queues; std::mutex _queue_lock; bool _options_invalidated = false; - int next_option = RS2_OPTION_COUNT; + int next_option = 0; + std::vector supported_options; bool streaming = false; rect normalized_zoom{0, 0, 1, 1}; diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index 8fd7b3d8f0..81d8cdc93c 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -20,6 +20,7 @@ target_sources(${LRS_TARGET} "${CMAKE_CURRENT_LIST_DIR}/librealsense2/hpp/rs_types.hpp" "${CMAKE_CURRENT_LIST_DIR}/librealsense2/hpp/rs_context.hpp" "${CMAKE_CURRENT_LIST_DIR}/librealsense2/hpp/rs_device.hpp" + "${CMAKE_CURRENT_LIST_DIR}/librealsense2/hpp/rs_serializable_device.hpp" "${CMAKE_CURRENT_LIST_DIR}/librealsense2/hpp/rs_export.hpp" "${CMAKE_CURRENT_LIST_DIR}/librealsense2/hpp/rs_frame.hpp" "${CMAKE_CURRENT_LIST_DIR}/librealsense2/hpp/rs_processing.hpp" diff --git a/include/librealsense2/h/rs_device.h b/include/librealsense2/h/rs_device.h index 29ef852265..43ba91b8d3 100644 --- a/include/librealsense2/h/rs_device.h +++ b/include/librealsense2/h/rs_device.h @@ -347,6 +347,12 @@ const rs2_raw_data_buffer* rs2_get_calibration_table(const rs2_device* dev, rs2_ */ void rs2_set_calibration_table(const rs2_device* device, const void* calibration, int calibration_size, rs2_error** error); +/* Serialize JSON content, returns ASCII-serialized JSON string on success. otherwise nullptr */ +rs2_raw_data_buffer* rs2_serialize_json(rs2_device* dev, rs2_error** error); + +/* Load JSON and apply advanced-mode controls */ +void rs2_load_json(rs2_device* dev, const void* json_content, unsigned content_size, rs2_error** error); + #ifdef __cplusplus } #endif diff --git a/include/librealsense2/h/rs_option.h b/include/librealsense2/h/rs_option.h index fec872f88e..9cad43b222 100644 --- a/include/librealsense2/h/rs_option.h +++ b/include/librealsense2/h/rs_option.h @@ -84,13 +84,13 @@ extern "C" { RS2_OPTION_LED_POWER, /**< Power of the LED (light emitting diode), with 0 meaning LED off*/ RS2_OPTION_ZERO_ORDER_ENABLED, /**< Toggle Zero-Order mode */ RS2_OPTION_ENABLE_MAP_PRESERVATION, /**< Preserve previous map when starting */ - RS2_OPTION_AVALANCHE_PHOTO_DIODE, /**< Changes the Avalanche Photo Diode in the reciever */ + RS2_OPTION_AVALANCHE_PHOTO_DIODE, /**< Changes the exposure time of Avalanche Photo Diode in the reciever */ RS2_OPTION_POST_PROCESSING_SHARPENING, /**< Changes the amount of sharpening in the post-processed image */ RS2_OPTION_PRE_PROCESSING_SHARPENING, /**< Changes the amount of sharpening in the pre-processed image */ RS2_OPTION_NOISE_FILTERING, /**< Control edges and background noise */ RS2_OPTION_INVALIDATION_BYPASS, /**< Enable\disable pixel invalidation */ - RS2_OPTION_SENSETIVITY, /**< Canges the depth sensetivity to ambient: 1 for no ambient and 2 for low ambient*/ - RS2_OPTION_CAMERA_MODE, /**< Device specific for L515: 0 for XGA and 1 for VGA */ + RS2_OPTION_AMBIENT_LIGHT, /**< Change the depth ambient light to ambient: 1 for no ambient and 2 for low ambient */ + RS2_OPTION_SENSOR_MODE, /**< Device specific for L515: 0 for XGA and 1 for VGA */ RS2_OPTION_COUNT /**< Number of enumeration values. Not a valid input: intended to be used in for-loops. */ } rs2_option; @@ -129,6 +129,28 @@ extern "C" { } rs2_rs400_visual_preset; const char* rs2_rs400_visual_preset_to_string(rs2_rs400_visual_preset preset); + /** \brief For L500 devices: provides optimized settings (presets) for specific types of usage. */ + typedef enum rs2_l500_visual_preset + { + RS2_L500_VISUAL_PRESET_CUSTOM, + RS2_L500_VISUAL_PRESET_DEFAULT, + RS2_L500_VISUAL_PRESET_NO_AMBIENT, + RS2_L500_VISUAL_PRESET_LOW_AMBIENT, + RS2_L500_VISUAL_PRESET_MAX_RANGE, + RS2_L500_VISUAL_PRESET_SHORT_RANGE, + RS2_L500_VISUAL_PRESET_COUNT + }rs2_l500_visual_preset; + const char* rs2_l500_visual_preset_to_string(rs2_l500_visual_preset preset); + + /** \brief For setting the camera_mode option */ + typedef enum rs2_sensor_mode + { + RS2_SENSOR_MODE_XGA, + RS2_SENSOR_MODE_VGA, + RS2_SENSOR_MODE_COUNT + } rs2_sensor_mode; + const char* rs2_sensor_mode_to_string(rs2_sensor_mode preset); + /** * check if an option is read-only * \param[in] options the options container diff --git a/include/librealsense2/h/rs_types.h b/include/librealsense2/h/rs_types.h index ee43416cd6..6637d3737d 100644 --- a/include/librealsense2/h/rs_types.h +++ b/include/librealsense2/h/rs_types.h @@ -179,7 +179,7 @@ typedef enum rs2_extension RS2_EXTENSION_MOTION_SENSOR, RS2_EXTENSION_FISHEYE_SENSOR, RS2_EXTENSION_DEPTH_HUFFMAN_DECODER, - RS2_EXTENSION_SERIALIZABLE_DEVICE, + RS2_EXTENSION_SERIALIZABLE_DEVICE, RS2_EXTENSION_COUNT } rs2_extension; const char* rs2_extension_type_to_string(rs2_extension type); diff --git a/include/librealsense2/hpp/rs_serializable_device.hpp b/include/librealsense2/hpp/rs_serializable_device.hpp new file mode 100644 index 0000000000..2a77d0792b --- /dev/null +++ b/include/librealsense2/hpp/rs_serializable_device.hpp @@ -0,0 +1,57 @@ +// License: Apache 2.0. See LICENSE file in root directory. +// Copyright(c) 2020 Intel Corporation. All Rights Reserved. + +#pragma once +#include "rs_types.hpp" +#include "rs_device.hpp" +#include +#include + +namespace rs2 +{ + class serializable_device : public rs2::device + { + public: + serializable_device(rs2::device d) + : rs2::device(d.get()) + { + rs2_error* e = nullptr; + if (rs2_is_device_extendable_to(_dev.get(), RS2_EXTENSION_SERIALIZABLE_DEVICE, &e) == 0 && !e) + { + _dev = nullptr; + } + rs2::error::handle(e); + } + + std::string serialize_json() const + { + std::string results; + + rs2_error* e = nullptr; + std::shared_ptr json_data( + rs2_serialize_json(_dev.get(), &e), + rs2_delete_raw_data); + rs2::error::handle(e); + + auto size = rs2_get_raw_data_size(json_data.get(), &e); + rs2::error::handle(e); + + auto start = rs2_get_raw_data(json_data.get(), &e); + rs2::error::handle(e); + + results.insert(results.begin(), start, start + size); + + return results; + } + + void load_json(const std::string& json_content) const + { + rs2_error* e = nullptr; + rs2_load_json(_dev.get(), + json_content.data(), + (unsigned int)json_content.size(), + &e); + rs2::error::handle(e); + } + }; +} diff --git a/include/librealsense2/rs.hpp b/include/librealsense2/rs.hpp index 600539405e..2a9ee2e334 100644 --- a/include/librealsense2/rs.hpp +++ b/include/librealsense2/rs.hpp @@ -146,5 +146,7 @@ inline std::ostream & operator << (std::ostream & o, rs2_notification_category n inline std::ostream & operator << (std::ostream & o, rs2_sr300_visual_preset preset) { return o << rs2_sr300_visual_preset_to_string(preset); } inline std::ostream & operator << (std::ostream & o, rs2_exception_type exception_type) { return o << rs2_exception_type_to_string(exception_type); } inline std::ostream & operator << (std::ostream & o, rs2_playback_status status) { return o << rs2_playback_status_to_string(status); } +inline std::ostream & operator << (std::ostream & o, rs2_l500_visual_preset preset) {return o << rs2_l500_visual_preset_to_string(preset);} +inline std::ostream & operator << (std::ostream & o, rs2_sensor_mode mode) { return o << rs2_sensor_mode_to_string(mode); } #endif // LIBREALSENSE_RS2_HPP diff --git a/include/librealsense2/rs_advanced_mode.h b/include/librealsense2/rs_advanced_mode.h index 6954ccc854..a963037e71 100644 --- a/include/librealsense2/rs_advanced_mode.h +++ b/include/librealsense2/rs_advanced_mode.h @@ -93,12 +93,6 @@ void rs2_set_amp_factor(rs2_device* dev, const STAFactor* group, rs2_error** er /* Gets new values for STAFactor, returns 0 if success */ void rs2_get_amp_factor(rs2_device* dev, STAFactor* group, int mode, rs2_error** error); -/* Load JSON and apply advanced-mode controls, returns 0 if success */ -void rs2_load_json(rs2_device* dev, const void* json_content, unsigned content_size, rs2_error** error); - -/* Serialize JSON content, returns 0 if success */ -rs2_raw_data_buffer* rs2_serialize_json(rs2_device* dev, rs2_error** error); - #ifdef __cplusplus } #endif diff --git a/include/librealsense2/rs_advanced_mode.hpp b/include/librealsense2/rs_advanced_mode.hpp index 7069ebe1cb..aa12bb7ac6 100644 --- a/include/librealsense2/rs_advanced_mode.hpp +++ b/include/librealsense2/rs_advanced_mode.hpp @@ -7,54 +7,11 @@ #include #include "rs.hpp" #include "rs_advanced_mode.h" +#include "hpp/rs_serializable_device.hpp" namespace rs400 { - class serializable_device : public rs2::device - { - public: - serializable_device(rs2::device d) - : rs2::device(d.get()) - { - rs2_error* e = nullptr; - if (rs2_is_device_extendable_to(_dev.get(), RS2_EXTENSION_SERIALIZABLE_DEVICE, &e) == 0 && !e) - { - _dev = nullptr; - } - rs2::error::handle(e); - } - - std::string serialize_json() const - { - std::string results; - - rs2_error* e = nullptr; - std::shared_ptr json_data( - rs2_serialize_json(_dev.get(), &e), - rs2_delete_raw_data); - rs2::error::handle(e); - - auto size = rs2_get_raw_data_size(json_data.get(), &e); - rs2::error::handle(e); - - auto start = rs2_get_raw_data(json_data.get(), &e); - rs2::error::handle(e); - - results.insert(results.begin(), start, start + size); - - return results; - } - - void load_json(const std::string& json_content) - { - rs2_error* e = nullptr; - rs2_load_json(_dev.get(), - json_content.data(), - (unsigned int)json_content.size(), - &e); - rs2::error::handle(e); - } - }; + using namespace rs2; class advanced_mode : public serializable_device { @@ -63,7 +20,7 @@ namespace rs400 : serializable_device(d) { rs2_error* e = nullptr; - if(rs2_is_device_extendable_to(_dev.get(), RS2_EXTENSION_ADVANCED_MODE, &e) == 0 && !e) + if(_dev && rs2_is_device_extendable_to(_dev.get(), RS2_EXTENSION_ADVANCED_MODE, &e) == 0 && !e) { _dev = nullptr; } diff --git a/include/librealsense2/rsutil.h b/include/librealsense2/rsutil.h index cb64a69214..4242c4a282 100644 --- a/include/librealsense2/rsutil.h +++ b/include/librealsense2/rsutil.h @@ -212,5 +212,4 @@ static void rs2_project_color_pixel_to_depth_pixel(float to_pixel[2], } } } - #endif diff --git a/src/ds5/advanced_mode/rs_advanced_mode.cpp b/src/ds5/advanced_mode/rs_advanced_mode.cpp index 8b199dab87..f5579ae2ae 100644 --- a/src/ds5/advanced_mode/rs_advanced_mode.cpp +++ b/src/ds5/advanced_mode/rs_advanced_mode.cpp @@ -292,20 +292,3 @@ HANDLE_EXCEPTIONS_AND_RETURN(, dev, group, mode) void rs2_set_amp_factor(rs2_device* dev, const STAFactor* group, rs2_error** error); void rs2_get_amp_factor(rs2_device* dev, STAFactor* group, int mode, rs2_error** error); - -void rs2_load_json(rs2_device* dev, const void* json_content, unsigned content_size, rs2_error** error) BEGIN_API_CALL -{ - VALIDATE_NOT_NULL(dev); - VALIDATE_NOT_NULL(json_content); - auto advanced_mode = VALIDATE_INTERFACE(dev->device, librealsense::serializable_interface); - advanced_mode->load_json(std::string(static_cast(json_content), content_size)); -} -HANDLE_EXCEPTIONS_AND_RETURN(, dev, json_content, content_size) - -rs2_raw_data_buffer* rs2_serialize_json(rs2_device* dev, rs2_error** error) BEGIN_API_CALL -{ - VALIDATE_NOT_NULL(dev); - auto serializable = VALIDATE_INTERFACE(dev->device, librealsense::serializable_interface); - return new rs2_raw_data_buffer{ serializable->serialize_json() }; -} -HANDLE_EXCEPTIONS_AND_RETURN(nullptr, dev) diff --git a/src/l500/CMakeLists.txt b/src/l500/CMakeLists.txt index 22e1eb5625..4dc6e76512 100644 --- a/src/l500/CMakeLists.txt +++ b/src/l500/CMakeLists.txt @@ -10,7 +10,7 @@ target_sources(${LRS_TARGET} "${CMAKE_CURRENT_LIST_DIR}/l500-factory.cpp" "${CMAKE_CURRENT_LIST_DIR}/l500-fw-update-device.cpp" "${CMAKE_CURRENT_LIST_DIR}/l500-serializable.cpp" - "${CMAKE_CURRENT_LIST_DIR}/l500-controls.cpp" + "${CMAKE_CURRENT_LIST_DIR}/l500-options.cpp" "${CMAKE_CURRENT_LIST_DIR}/l500-depth.h" "${CMAKE_CURRENT_LIST_DIR}/l500-private.h" "${CMAKE_CURRENT_LIST_DIR}/l500-color.h" @@ -19,5 +19,5 @@ target_sources(${LRS_TARGET} "${CMAKE_CURRENT_LIST_DIR}/l500-factory.h" "${CMAKE_CURRENT_LIST_DIR}/l500-fw-update-device.h" "${CMAKE_CURRENT_LIST_DIR}/l500-serializable.h" - "${CMAKE_CURRENT_LIST_DIR}/l500-controls.h" + "${CMAKE_CURRENT_LIST_DIR}/l500-options.h" ) diff --git a/src/l500/l500-controls.cpp b/src/l500/l500-controls.cpp deleted file mode 100644 index 6942d8fe2b..0000000000 --- a/src/l500/l500-controls.cpp +++ /dev/null @@ -1,181 +0,0 @@ -//// License: Apache 2.0. See LICENSE file in root directory. -//// Copyright(c) 2018 Intel Corporation. All Rights Reserved. - -#include "l500-controls.h" -#include "l500-private.h" -#include "l500-depth.h" - -#define CONTROLS_FIRMWARE_VERSION "1.3.8.0" - -namespace librealsense -{ - using namespace ivcam2; - - float l500_hw_controls::query() const - { - return query(_resolution->query()); - } - - void l500_hw_controls::set(float value) - { - _hw_monitor->send(command{ AMCSET, _type, (int)value }); - } - - option_range l500_hw_controls::get_range() const - { - return _range; - } - - l500_hw_controls::l500_hw_controls(hw_monitor* hw_monitor, l500_control type, option* resolution) - :_hw_monitor(hw_monitor), - _type(type), - _resolution(resolution) - { - auto min = _hw_monitor->send(command{ AMCGET, _type, get_min }); - auto max = _hw_monitor->send(command{ AMCGET, _type, get_max }); - auto step = _hw_monitor->send(command{ AMCGET, _type, get_step }); - - auto def = query(_resolution->query()); - - _range = option_range{ float(*(reinterpret_cast(min.data()))), - float(*(reinterpret_cast(max.data()))), - float(*(reinterpret_cast(step.data()))), - def }; - } - - void l500_hw_controls::enable_recording(std::function recording_action) - {} - - float l500_hw_controls::query(int mode) const - { - auto res = _hw_monitor->send(command{ AMCGET, _type, get_current, mode }); - auto val = *(reinterpret_cast((void*)res.data())); - return val; - } - - l500_controls::l500_controls(std::shared_ptr ctx, const platform::backend_device_group & group) : - device(ctx, group), - l500_device(ctx, group) - { - auto& raw_depth_sensor = get_raw_depth_sensor(); - auto& depth_sensor = get_depth_sensor(); - - if (_fw_version < firmware_version(CONTROLS_FIRMWARE_VERSION)) - { - depth_sensor.register_option - (RS2_OPTION_VISUAL_PRESET, std::make_shared>(raw_depth_sensor, ivcam2::depth_xu, ivcam2::L500_AMBIENT, - "Canges the depth sensetivity to ambient: 1 for no ambient and 2 for low ambient", - std::map{ { sensetivity_long, "No Ambient"}, - { sensetivity_short, "Low Ambient" }})); - } - else - { - auto resolution_option = std::make_shared(option_range{ XGA,VGA,1, XGA }, "Resolution mode", std::map{ - { XGA, "XGA"}, - { VGA, "VGA" }}); - - depth_sensor.register_option(RS2_OPTION_CAMERA_MODE, resolution_option); - - _hw_options[RS2_OPTION_POST_PROCESSING_SHARPENING] = register_option(RS2_OPTION_POST_PROCESSING_SHARPENING, _hw_monitor.get(), post_processing_sharpness, resolution_option.get()); - _hw_options[RS2_OPTION_PRE_PROCESSING_SHARPENING] = register_option(RS2_OPTION_PRE_PROCESSING_SHARPENING, _hw_monitor.get(), pre_processing_sharpness, resolution_option.get()); - _hw_options[RS2_OPTION_NOISE_FILTERING] = register_option(RS2_OPTION_NOISE_FILTERING, _hw_monitor.get(), noise_filtering, resolution_option.get()); - _hw_options[RS2_OPTION_AVALANCHE_PHOTO_DIODE] = register_option(RS2_OPTION_AVALANCHE_PHOTO_DIODE, _hw_monitor.get(), apd, resolution_option.get()); - _hw_options[RS2_OPTION_CONFIDENCE_THRESHOLD] = register_option(RS2_OPTION_CONFIDENCE_THRESHOLD, _hw_monitor.get(), confidence, resolution_option.get()); - _hw_options[RS2_OPTION_LASER_POWER] = register_option(RS2_OPTION_LASER_POWER, _hw_monitor.get(), laser_gain, resolution_option.get()); - _hw_options[RS2_OPTION_MIN_DISTANCE] = register_option(RS2_OPTION_MIN_DISTANCE, _hw_monitor.get(), min_distance, resolution_option.get()); - _hw_options[RS2_OPTION_INVALIDATION_BYPASS] = register_option(RS2_OPTION_INVALIDATION_BYPASS, _hw_monitor.get(), invalidation_bypass, resolution_option.get()); - - _sensitivity = register_option, uvc_sensor&, platform::extension_unit, uint8_t, std::string, const std::map& > - (RS2_OPTION_SENSETIVITY, raw_depth_sensor, ivcam2::depth_xu, ivcam2::L500_AMBIENT, - "Canges the depth sensetivity to ambient: 1 for no ambient and 2 for low ambient", - std::map{ { sensetivity_long, "No Ambient"}, - { sensetivity_short, "Low Ambient" }}); - - - _preset = register_option > - (RS2_OPTION_VISUAL_PRESET, option_range{ custom , short_range, 1, custom }, - "Preset to calibrate the camera to environment ambient no ambient or low ambient. 1 is no ambient and 2 is low ambient", - std::map{ - { custom , "custom " }, - { no_ambient, "No Ambient" }, - { low_ambient, "Low Ambient-max range" }, - { max_range ,"No Ambient max range" }, - { short_range ,"Low Ambient " }}); - - _advanced_option = get_advanced_controlls(); - } - } - - std::vector l500_controls::get_advanced_controlls() - { - std::vector res; - - res.push_back(RS2_OPTION_SENSETIVITY); - for (auto o : _hw_options) - res.push_back(o.first); - - return res; - } - - void l500_controls::on_set_option(rs2_option opt, float value) - { - if (opt == RS2_OPTION_VISUAL_PRESET) - { - change_preset(static_cast(int(value))); - } - else - { - move_to_custom (); - } - } - - void l500_controls::change_preset(preset_values preset) - { - if (preset != custom ) - reset_hw_controls(); - - switch (preset) - { - case no_ambient: - _sensitivity->set_with_no_signal(sensetivity_long); - break; - case low_ambient: - _sensitivity->set_with_no_signal(sensetivity_short); - set_max_laser(); - break; - case max_range: - _sensitivity->set_with_no_signal(sensetivity_long); - set_max_laser(); - break; - case short_range: - _sensitivity->set_with_no_signal(sensetivity_short); - break; - case custom : - move_to_custom (); - break; - default: break; - }; - } - - void l500_controls::move_to_custom () - { - for (auto o : _hw_options) - { - auto val = o.second->query(); - o.second->set_with_no_signal(val); - } - _preset->set_with_no_signal(custom ); - } - - void l500_controls::reset_hw_controls() - { - for (auto o : _hw_options) - o.second->set_with_no_signal(-1); - } - - void l500_controls::set_max_laser() - { - auto range = _hw_options[RS2_OPTION_LASER_POWER]->get_range(); - _hw_options[RS2_OPTION_LASER_POWER]->set_with_no_signal(range.max); - } -} diff --git a/src/l500/l500-depth.cpp b/src/l500/l500-depth.cpp index 1fd194230b..68bc3898e4 100644 --- a/src/l500/l500-depth.cpp +++ b/src/l500/l500-depth.cpp @@ -15,7 +15,7 @@ #include "proc/zero-order.h" #include #include "metadata-parser.h" -#include "l500-controls.h" +#include "l500-options.h" #define MM_TO_METER 1/1000 #define MIN_ALGO_VERSION 115 @@ -74,33 +74,6 @@ namespace librealsense depth_sensor.register_option(RS2_OPTION_APD_TEMPERATURE, std::make_shared (_hw_monitor.get(), RS2_OPTION_APD_TEMPERATURE)); - //depth_sensor.register_option(RS2_OPTION_CONFIDENCE_THRESHOLD, - // std::make_shared (_hw_monitor.get(), confidence)); - - //depth_sensor.register_option(RS2_OPTION_SHARPNESS, - // std::make_shared (_hw_monitor.get(), sharpness)); - - //depth_sensor.register_option(RS2_OPTION_RAST_BILT, - // std::make_shared (_hw_monitor.get(), rast_bilt)); - - //depth_sensor.register_option(RS2_OPTION_EDGE, - // std::make_shared (_hw_monitor.get(), edge)); - - //depth_sensor.register_option(RS2_OPTION_APD, - // std::make_shared (_hw_monitor.get(), apd)); - - //depth_sensor.register_option(RS2_OPTION_LASER_POWER, - // std::make_shared (_hw_monitor.get(), laser_gain)); - - ///*depth_sensor.register_option(RS2_OPTION_MIN_DISTANCE, - // std::make_shared (_hw_monitor.get(), min_distance));*/ - - //depth_sensor.register_option(RS2_OPTION_MIN_DISTANCE, - // std::make_shared (_hw_monitor.get(), min_distance)); - - //depth_sensor.register_option(RS2_OPTION_INVALIDATION_BYPASS, - // std::make_shared (_hw_monitor.get(), min_distance)); - environment::get_instance().get_extrinsics_graph().register_same_extrinsics(*_depth_stream, *_ir_stream); environment::get_instance().get_extrinsics_graph().register_same_extrinsics(*_depth_stream, *_confidence_stream); @@ -297,6 +270,16 @@ namespace librealsense }); } + rs2_sensor_mode get_resolution_from_width_height(int width, int height) + { + if ((width == 640 && height == 480) || (height == 640 && width == 480)) + return RS2_SENSOR_MODE_VGA; + else if ((width == 1024 && height == 768) || (height == 768 && width == 1024)) + return RS2_SENSOR_MODE_XGA; + else + throw std::runtime_error(to_string() << "Invalid resolution " << width << "x" << height); + } + void l500_depth_sensor::open(const stream_profiles& requests) { try @@ -344,14 +327,21 @@ namespace librealsense auto dp = std::find_if(requests.begin(), requests.end(), [](std::shared_ptr sp) {return sp->get_stream_type() == RS2_STREAM_DEPTH;}); - const int XGA = 0; - const int VGA = 1; - - if (dp != requests.end() && supports_option(RS2_OPTION_CAMERA_MODE)) + if (dp != requests.end() && supports_option(RS2_OPTION_SENSOR_MODE)) { - auto&& camera_mode_option = get_option(RS2_OPTION_CAMERA_MODE); + auto&& sensor_mode_option = get_option(RS2_OPTION_SENSOR_MODE); auto vs = dynamic_cast((*dp).get()); - camera_mode_option.set(vs->get_width() == 640 || vs->get_height() == 640 ? VGA : XGA); + if (supports_option(RS2_OPTION_VISUAL_PRESET)) + { + auto&& preset_option = get_option(RS2_OPTION_VISUAL_PRESET); + if (preset_option.query() == RS2_L500_VISUAL_PRESET_CUSTOM) + { + if(sensor_mode_option.query() != get_resolution_from_width_height(vs->get_width(), vs->get_height())) + throw std::runtime_error(to_string() << "sensor mode option is incompatible with requsted resolution"); + } + } + + sensor_mode_option.set(get_resolution_from_width_height(vs->get_width(), vs->get_height())); } diff --git a/src/l500/l500-depth.h b/src/l500/l500-depth.h index bf3c63c1e2..85e7a5bbff 100644 --- a/src/l500/l500-depth.h +++ b/src/l500/l500-depth.h @@ -17,7 +17,7 @@ #include "l500-private.h" #include "error-handling.h" #include "frame-validator.h" -#include "l500-controls.h" +#include "l500-options.h" namespace librealsense { @@ -266,6 +266,5 @@ namespace librealsense stream_profiles _validator_requests; bool _depth_invalidation_enabled; std::shared_ptr _depth_invalidation_option; - std::function _on_open_callback; }; } diff --git a/src/l500/l500-factory.cpp b/src/l500/l500-factory.cpp index 6749becbac..1ac2fbfe6e 100644 --- a/src/l500/l500-factory.cpp +++ b/src/l500/l500-factory.cpp @@ -24,7 +24,7 @@ namespace librealsense // l515 class rs515_device : public l500_depth, - public l500_controls, + public l500_options, public l500_color, public l500_motion, public l500_serializable_base @@ -36,10 +36,10 @@ namespace librealsense : device(ctx, group, register_device_notifications), l500_device(ctx, group), l500_depth(ctx, group), - l500_controls(ctx, group), + l500_options(ctx, group), l500_color(ctx, group), l500_motion(ctx, group), - l500_serializable_base(l500_depth::_hw_monitor, get_depth_sensor()) + l500_serializable_base(l500_device::_hw_monitor, get_depth_sensor()) {} std::shared_ptr create_matcher(const frame_holder& frame) const override; diff --git a/src/l500/l500-options.cpp b/src/l500/l500-options.cpp new file mode 100644 index 0000000000..9c69680cc1 --- /dev/null +++ b/src/l500/l500-options.cpp @@ -0,0 +1,177 @@ +//// License: Apache 2.0. See LICENSE file in root directory. +//// Copyright(c) 2020 Intel Corporation. All Rights Reserved. + +#include "l500-options.h" +#include "l500-private.h" +#include "l500-depth.h" + +const std::string MIN_CONTROLS_FW_VERSION("1.3.8.0"); + +namespace librealsense +{ + using namespace ivcam2; + + float l500_hw_options::query() const + { + return query(_resolution->query()); + } + + void l500_hw_options::set(float value) + { + _hw_monitor->send(command{ AMCSET, _type, (int)value }); + } + + option_range l500_hw_options::get_range() const + { + return _range; + } + + l500_hw_options::l500_hw_options(hw_monitor* hw_monitor, l500_control type, option* resolution) + :_hw_monitor(hw_monitor), + _type(type), + _resolution(resolution) + { + auto min = _hw_monitor->send(command{ AMCGET, _type, get_min }); + auto max = _hw_monitor->send(command{ AMCGET, _type, get_max }); + auto step = _hw_monitor->send(command{ AMCGET, _type, get_step }); + + auto def = query(_resolution->query()); + + _range = option_range{ float(*(reinterpret_cast(min.data()))), + float(*(reinterpret_cast(max.data()))), + float(*(reinterpret_cast(step.data()))), + def }; + } + + void l500_hw_options::enable_recording(std::function recording_action) + {} + + float l500_hw_options::query(int mode) const + { + auto res = _hw_monitor->send(command{ AMCGET, _type, get_current, mode }); + auto val = *(reinterpret_cast((void*)res.data())); + return val; + } + + l500_options::l500_options(std::shared_ptr ctx, const platform::backend_device_group & group) : + device(ctx, group), + l500_device(ctx, group) + { + auto& raw_depth_sensor = get_raw_depth_sensor(); + auto& depth_sensor = get_depth_sensor(); + + if (_fw_version < firmware_version(MIN_CONTROLS_FW_VERSION)) + { + depth_sensor.register_option + (RS2_OPTION_VISUAL_PRESET, std::make_shared>(raw_depth_sensor, ivcam2::depth_xu, ivcam2::L500_AMBIENT, + "Change the depth ambient light to ambient: 1 for no ambient and 2 for low ambient", + std::map{ { no_ambient, "No Ambient"}, + { low_ambient, "Low Ambient" }})); + } + else + { + auto resolution_option = std::make_shared>(option_range{ RS2_SENSOR_MODE_XGA,RS2_SENSOR_MODE_VGA,1, RS2_SENSOR_MODE_XGA }, "Notify the sensor about the intended streaming mode. Required for preset "); + + depth_sensor.register_option(RS2_OPTION_SENSOR_MODE, resolution_option); + + _hw_options[RS2_OPTION_POST_PROCESSING_SHARPENING] = register_option(RS2_OPTION_POST_PROCESSING_SHARPENING, _hw_monitor.get(), post_processing_sharpness, resolution_option.get()); + _hw_options[RS2_OPTION_PRE_PROCESSING_SHARPENING] = register_option(RS2_OPTION_PRE_PROCESSING_SHARPENING, _hw_monitor.get(), pre_processing_sharpness, resolution_option.get()); + _hw_options[RS2_OPTION_NOISE_FILTERING] = register_option(RS2_OPTION_NOISE_FILTERING, _hw_monitor.get(), noise_filtering, resolution_option.get()); + _hw_options[RS2_OPTION_AVALANCHE_PHOTO_DIODE] = register_option(RS2_OPTION_AVALANCHE_PHOTO_DIODE, _hw_monitor.get(), apd, resolution_option.get()); + _hw_options[RS2_OPTION_CONFIDENCE_THRESHOLD] = register_option(RS2_OPTION_CONFIDENCE_THRESHOLD, _hw_monitor.get(), confidence, resolution_option.get()); + _hw_options[RS2_OPTION_LASER_POWER] = register_option(RS2_OPTION_LASER_POWER, _hw_monitor.get(), laser_gain, resolution_option.get()); + _hw_options[RS2_OPTION_MIN_DISTANCE] = register_option(RS2_OPTION_MIN_DISTANCE, _hw_monitor.get(), min_distance, resolution_option.get()); + _hw_options[RS2_OPTION_INVALIDATION_BYPASS] = register_option(RS2_OPTION_INVALIDATION_BYPASS, _hw_monitor.get(), invalidation_bypass, resolution_option.get()); + + _ambient_light = register_option, uvc_sensor&, platform::extension_unit, uint8_t, std::string, const std::map& > + (RS2_OPTION_AMBIENT_LIGHT, raw_depth_sensor, ivcam2::depth_xu, ivcam2::L500_AMBIENT, + "Change the depth ambient light to ambient: 1 for no ambient and 2 for low ambient", + std::map{ { no_ambient, "No Ambient"}, + { low_ambient, "Low Ambient" }}); + + + _preset = register_option , option_range> + (RS2_OPTION_VISUAL_PRESET, option_range{ RS2_L500_VISUAL_PRESET_CUSTOM , RS2_L500_VISUAL_PRESET_SHORT_RANGE, 1, RS2_L500_VISUAL_PRESET_DEFAULT }, + "Preset to calibrate the camera to environment ambient, no ambient or low ambient. 1 is no ambient and 2 is low ambient"); + + _advanced_option = get_advanced_controls(); + } + } + + std::vector l500_options::get_advanced_controls() + { + std::vector res; + + res.push_back(RS2_OPTION_AMBIENT_LIGHT); + for (auto&& o : _hw_options) + res.push_back(o.first); + + return res; + } + + void l500_options::on_set_option(rs2_option opt, float value) + { + if (opt == RS2_OPTION_VISUAL_PRESET) + { + change_preset(static_cast(int(value))); + } + else + { + auto advanced_controls = get_advanced_controls(); + if (std::find(advanced_controls.begin(), advanced_controls.end(), opt) != advanced_controls.end()) + move_to_custom (); + else + throw wrong_api_call_sequence_exception(to_string() << "on_set_option support advanced controlls only "<< opt<<" injected"); + } + } + + void l500_options::change_preset(rs2_l500_visual_preset preset) + { + if (preset != RS2_L500_VISUAL_PRESET_CUSTOM) + reset_hw_controls(); + + switch (preset) + { + case RS2_L500_VISUAL_PRESET_NO_AMBIENT: + _ambient_light->set_with_no_signal(no_ambient); + break; + case RS2_L500_VISUAL_PRESET_LOW_AMBIENT: + _ambient_light->set_with_no_signal(low_ambient); + set_max_laser(); + break; + case RS2_L500_VISUAL_PRESET_MAX_RANGE: + _ambient_light->set_with_no_signal(no_ambient); + set_max_laser(); + break; + case RS2_L500_VISUAL_PRESET_SHORT_RANGE: + _ambient_light->set_with_no_signal(low_ambient); + break; + case RS2_L500_VISUAL_PRESET_CUSTOM: + move_to_custom (); + break; + default: break; + }; + } + + void l500_options::move_to_custom () + { + for (auto& o : _hw_options) + { + auto val = o.second->query(); + o.second->set_with_no_signal(val); + } + _preset->set_with_no_signal(RS2_L500_VISUAL_PRESET_CUSTOM); + } + + void l500_options::reset_hw_controls() + { + for (auto& o : _hw_options) + o.second->set_with_no_signal(-1); + } + + void l500_options::set_max_laser() + { + auto range = _hw_options[RS2_OPTION_LASER_POWER]->get_range(); + _hw_options[RS2_OPTION_LASER_POWER]->set_with_no_signal(range.max); + } +} diff --git a/src/l500/l500-controls.h b/src/l500/l500-options.h similarity index 51% rename from src/l500/l500-controls.h rename to src/l500/l500-options.h index 46173263ae..e20a6ae8a4 100644 --- a/src/l500/l500-controls.h +++ b/src/l500/l500-options.h @@ -1,10 +1,9 @@ // License: Apache 2.0. See LICENSE file in root directory. -// Copyright(c) 2018 Intel Corporation. All Rights Reserved. +// Copyright(c) 2020 Intel Corporation. All Rights Reserved. #pragma once #include "hw-monitor.h" #include "l500-device.h" -//#include "option.h" namespace librealsense { @@ -28,28 +27,13 @@ namespace librealsense get_step = 3 }; - enum preset_values + enum rs2_ambient_light { - custom = 0, no_ambient = 1, - low_ambient = 2, - max_range = 3, - short_range = 4 + low_ambient = 2 }; - enum sensetivity - { - sensetivity_long = 1, - sensetivity_short = 2 - }; - - enum resulotion - { - XGA = 0, - VGA = 1 - }; - - class l500_hw_controls : public option + class l500_hw_options : public option { public: float query() const override; @@ -62,7 +46,7 @@ namespace librealsense const char* get_description() const override { return ""; } - l500_hw_controls(hw_monitor* hw_monitor, l500_control type, option* resolution); + l500_hw_options(hw_monitor* hw_monitor, l500_control type, option* resolution); void enable_recording(std::function recording_action) override; @@ -77,54 +61,31 @@ namespace librealsense option* _resolution; }; - template - class signaled_option : public T, public observable_option - { - public: - template - signaled_option(rs2_option opt, Args&&... args) : - T(std::forward(args)...), _opt(opt){} - - void set(float value) override - { - notify(value); - T::set(value); - } - - void set_with_no_signal(float value) - { - T::set(value); - } - private: - std::function _callback; - rs2_option _opt; - }; - - class l500_controls: public virtual l500_device + class l500_options: public virtual l500_device { public: - l500_controls(std::shared_ptr ctx, + l500_options(std::shared_ptr ctx, const platform::backend_device_group& group); - std::vector get_advanced_controlls(); + std::vector get_advanced_controls(); private: void on_set_option(rs2_option opt, float value); - void change_preset(preset_values preset); + void change_preset(rs2_l500_visual_preset preset); void move_to_custom (); void reset_hw_controls(); void set_max_laser(); - std::map>> _hw_options; - std::shared_ptr< signaled_option>> _sensitivity; - std::shared_ptr< signaled_option> _preset; + std::map>> _hw_options; + std::shared_ptr< cascade_option>> _ambient_light; + std::shared_ptr< cascade_option>> _preset; template - std::shared_ptr> register_option(rs2_option opt, Args... args) + std::shared_ptr> register_option(rs2_option opt, Args... args) { auto& depth_sensor = get_depth_sensor(); - auto signaled_opt = std::make_shared >(opt, std::forward(args)...); + auto signaled_opt = std::make_shared >(opt, std::forward(args)...); signaled_opt->add_observer([opt, this](float val) {on_set_option(opt, val);}); depth_sensor.register_option(opt, std::dynamic_pointer_cast