diff --git a/include/librealsense2/h/rs_pipeline.h b/include/librealsense2/h/rs_pipeline.h index 8afa03035b..e0143847cf 100644 --- a/include/librealsense2/h/rs_pipeline.h +++ b/include/librealsense2/h/rs_pipeline.h @@ -41,6 +41,14 @@ extern "C" { */ void rs2_pipeline_stop(rs2_pipeline* pipe, rs2_error ** error); + /** + * Set the device to be used in the pipline. + * The function is used to assign the device, useful when the user wish to set controls that cannot be set while streaming. + * \param[in] pipe the pipeline. + * \param[in] device the device to be used in the pipline. + */ + void rs2_pipeline_set_device( rs2_pipeline * pipe, rs2_device * device, rs2_error ** error ); + /** * Wait until a new set of frames becomes available. * The frames set includes time-synchronized frames of each enabled stream in the pipeline. diff --git a/include/librealsense2/hpp/rs_pipeline.hpp b/include/librealsense2/hpp/rs_pipeline.hpp index a7f06da8b9..982db9a667 100644 --- a/include/librealsense2/hpp/rs_pipeline.hpp +++ b/include/librealsense2/hpp/rs_pipeline.hpp @@ -492,6 +492,18 @@ namespace rs2 error::handle(e); } + /** + * Set the device to be used in the pipline. + * The function is used to assign the device, useful when the user wish to set controls that cannot be set while streaming. + * \param[in] device the device to be used in the pipline. + */ + void set_device( rs2::device* device ) + { + rs2_error * e = nullptr; + rs2_pipeline_set_device( _pipeline.get(), device->get().get(), &e ); + error::handle( e ); + } + /** * Wait until a new set of frames becomes available. * The frames set includes time-synchronized frames of each enabled stream in the pipeline. diff --git a/src/pipeline/config.cpp b/src/pipeline/config.cpp index d8c5912571..34a7794e30 100644 --- a/src/pipeline/config.cpp +++ b/src/pipeline/config.cpp @@ -190,8 +190,11 @@ namespace librealsense std::lock_guard lock(_mtx); _resolved_profile.reset(); + std::shared_ptr< librealsense::device_interface > requested_device = pipe->get_device(); + if(! requested_device ) + requested_device = resolve_device_requests( pipe, timeout ); + //Resolve the the device that was specified by the user, this call will wait in case the device is not availabe. - auto requested_device = resolve_device_requests(pipe, timeout); if (requested_device != nullptr) { _resolved_profile = resolve(requested_device); diff --git a/src/pipeline/pipeline.cpp b/src/pipeline/pipeline.cpp index db8b07c1b3..f5eed03229 100644 --- a/src/pipeline/pipeline.cpp +++ b/src/pipeline/pipeline.cpp @@ -46,6 +46,16 @@ namespace librealsense return unsafe_get_active_profile(); } + void pipeline::set_device( std::shared_ptr< librealsense::device_interface > dev ) + { + _dev = dev; + } + + std::shared_ptr< librealsense::device_interface > pipeline::get_device() + { + return _dev; + } + std::shared_ptr pipeline::get_active_profile() const { std::lock_guard lock(_mtx); diff --git a/src/pipeline/pipeline.h b/src/pipeline/pipeline.h index 985cb4e670..5fb306b1b6 100644 --- a/src/pipeline/pipeline.h +++ b/src/pipeline/pipeline.h @@ -36,6 +36,8 @@ namespace librealsense std::shared_ptr wait_for_device(const std::chrono::milliseconds& timeout = std::chrono::hours::max(), const std::string& serial = ""); std::shared_ptr get_context() const; + void set_device( std::shared_ptr< librealsense::device_interface > dev ); + std::shared_ptr< librealsense::device_interface > get_device(); protected: rs2_frame_callback_sptr get_callback(std::vector unique_ids); @@ -61,6 +63,7 @@ namespace librealsense rs2_frame_callback_sptr _streams_callback; std::vector _synced_streams; + std::shared_ptr< librealsense::device_interface > _dev = nullptr; }; } } diff --git a/src/realsense.def b/src/realsense.def index 109bcfaab0..14de1fb873 100644 --- a/src/realsense.def +++ b/src/realsense.def @@ -306,6 +306,7 @@ EXPORTS rs2_pipeline_get_active_profile rs2_pipeline_profile_get_device rs2_pipeline_profile_get_streams + rs2_pipeline_set_device rs2_delete_pipeline_profile rs2_create_config diff --git a/src/rs.cpp b/src/rs.cpp index 970c3e632d..aa9e6e490a 100644 --- a/src/rs.cpp +++ b/src/rs.cpp @@ -2201,7 +2201,16 @@ void rs2_pipeline_stop(rs2_pipeline* pipe, rs2_error ** error) BEGIN_API_CALL } HANDLE_EXCEPTIONS_AND_RETURN(, pipe) -rs2_frame* rs2_pipeline_wait_for_frames(rs2_pipeline* pipe, unsigned int timeout_ms, rs2_error ** error) BEGIN_API_CALL +void rs2_pipeline_set_device( rs2_pipeline * pipe, rs2_device * device, rs2_error ** error ) BEGIN_API_CALL +{ + VALIDATE_NOT_NULL( pipe ); + VALIDATE_NOT_NULL( device ); + + pipe->pipeline->set_device( device->device ); +} +HANDLE_EXCEPTIONS_AND_RETURN(, pipe, device ) + +rs2_frame* rs2_pipeline_wait_for_frames(rs2_pipeline* pipe, unsigned int timeout_ms, rs2_error ** error)BEGIN_API_CALL { VALIDATE_NOT_NULL(pipe); diff --git a/unit-tests/live/d400/test-pipeline-set-device.py b/unit-tests/live/d400/test-pipeline-set-device.py new file mode 100644 index 0000000000..e6ce35bb50 --- /dev/null +++ b/unit-tests/live/d400/test-pipeline-set-device.py @@ -0,0 +1,33 @@ +# License: Apache 2.0. See LICENSE file in root directory. +# Copyright(c) 2024 Intel Corporation. All Rights Reserved. + +# LibCI doesn't have D435i so //test:device D435I// is disabled for now +# test:device D455 + +import pyrealsense2 as rs +from rspy import test + +gyro_sensitivity_value = 4.0 + +with test.closure("pipeline - set device"): + cfg = rs.config() + ctx = rs.context() + + dev = test.find_first_device_or_exit() + motion_sensor = dev.first_motion_sensor() + pipe = rs.pipeline(ctx) + pipe.set_device(dev) + + motion_sensor.set_option(rs.option.gyro_sensitivity, gyro_sensitivity_value) + + cfg.enable_stream(rs.stream.accel) + cfg.enable_stream(rs.stream.gyro) + + profile = pipe.start(cfg) + device_from_profile = profile.get_device() + sensor = device_from_profile.first_motion_sensor() + sensor_gyro_sensitivity_value = sensor.get_option(rs.option.gyro_sensitivity) + test.check_equal(gyro_sensitivity_value, sensor_gyro_sensitivity_value) + pipe.stop() + +test.print_results_and_exit() \ No newline at end of file diff --git a/wrappers/python/pyrs_pipeline.cpp b/wrappers/python/pyrs_pipeline.cpp index f1ceb75929..c00e7fb7de 100644 --- a/wrappers/python/pyrs_pipeline.cpp +++ b/wrappers/python/pyrs_pipeline.cpp @@ -169,6 +169,9 @@ void init_pipeline(py::module &m) { auto success = self.try_wait_for_frames(&fs, timeout_ms); return std::make_tuple(success, fs); }, "timeout_ms"_a = 5000, py::call_guard()) - .def("get_active_profile", &rs2::pipeline::get_active_profile); // No docstring in C++ + .def("get_active_profile", &rs2::pipeline::get_active_profile) // No docstring in C++ + .def( "set_device", &rs2::pipeline::set_device, + "The function is used to assign the device, useful when the user wish to set controls that cannot be set while streaming. ", + "device"_a ); /** end rs_pipeline.hpp **/ }