From f800d7f833bab54ecd48d9464f9b975c6de811e7 Mon Sep 17 00:00:00 2001 From: Lior Ramati Date: Wed, 28 Aug 2019 15:42:26 +0300 Subject: [PATCH 01/20] add new frame_queue API to matlab binding --- include/librealsense2/hpp/rs_processing.hpp | 11 ++++++++++- wrappers/matlab/frame_queue.m | 4 ++++ wrappers/matlab/librealsense_mex.cpp | 12 +++++++++++- wrappers/python/pyrs_processing.cpp | 6 ++++-- 4 files changed, 29 insertions(+), 4 deletions(-) diff --git a/include/librealsense2/hpp/rs_processing.hpp b/include/librealsense2/hpp/rs_processing.hpp index 8accfa0621..e2831c2518 100644 --- a/include/librealsense2/hpp/rs_processing.hpp +++ b/include/librealsense2/hpp/rs_processing.hpp @@ -119,8 +119,9 @@ namespace rs2 * create frame queue. frame queues are the simplest x-platform synchronization primitive provided by librealsense * to help developers who are not using async APIs * param[in] capacity size of the frame queue + * param[in] keep_frames if set to true, the queue automatically calls keep() on every frame enqueued into it. */ - explicit frame_queue(unsigned int capacity) : _capacity(capacity) + explicit frame_queue(unsigned int capacity, bool keep_frames = false) : _capacity(capacity), _keep(keep_frames) { rs2_error* e = nullptr; _queue = std::shared_ptr( @@ -137,6 +138,7 @@ namespace rs2 */ void enqueue(frame f) const { + if (_keep) f.keep(); rs2_enqueue_frame(f.frame_ref, _queue.get()); // noexcept f.frame_ref = nullptr; // frame has been essentially moved from } @@ -194,9 +196,16 @@ namespace rs2 */ size_t capacity() const { return _capacity; } + /** + * Return whether or not the queue calls keep on enqueued frames + * \return keeping frames + */ + bool keep_frames() const { return _keep; } + private: std::shared_ptr _queue; size_t _capacity; + bool _keep; }; /** diff --git a/wrappers/matlab/frame_queue.m b/wrappers/matlab/frame_queue.m index b85dc58813..e04edffc7f 100644 --- a/wrappers/matlab/frame_queue.m +++ b/wrappers/matlab/frame_queue.m @@ -39,5 +39,9 @@ function delete(this) function cap = capacity(this) cap = realsense.librealsense_mex('rs2::frame_queue', 'capacity', this.objectHandle); end + function keep = keep_frames(this) + cap = realsense.librealsense_mex('rs2::frame_queue', 'keep_frames', this.objectHandle); + end + end end end \ No newline at end of file diff --git a/wrappers/matlab/librealsense_mex.cpp b/wrappers/matlab/librealsense_mex.cpp index dbcb56aa79..8d1b3f0f1e 100644 --- a/wrappers/matlab/librealsense_mex.cpp +++ b/wrappers/matlab/librealsense_mex.cpp @@ -917,7 +917,7 @@ void make_factory(){ // rs2::processing_block [?] { ClassFactory frame_queue_factory("rs2::frame_queue"); - frame_queue_factory.record("new", 1, 0, 1, [](int outc, mxArray* outv[], int inc, const mxArray* inv[]) + frame_queue_factory.record("new", 1, 0, 2, [](int outc, mxArray* outv[], int inc, const mxArray* inv[]) { if (inc == 0) { outv[0] = MatlabParamParser::wrap(rs2::frame_queue()); @@ -926,6 +926,11 @@ void make_factory(){ auto capacity = MatlabParamParser::parse(inv[0]); outv[0] = MatlabParamParser::wrap(rs2::frame_queue(capacity)); } + else if (inc == 2) { + auto capacity = MatlabParamParser::parse(inv[0]); + auto keep_frames = MatlabParamParser::parse(inv[1]); + outv[0] = MatlabParamParser::wrap(rs2::frame_queue(capacity, keep_frames)); + } }); // rs2::frame_queue::enqueue(frame) [?] frame_queue_factory.record("wait_for_frame", 1, 1, 2, [](int outc, mxArray* outv[], int inc, const mxArray* inv[]) @@ -945,6 +950,11 @@ void make_factory(){ auto thiz = MatlabParamParser::parse(inv[0]); outv[0] = MatlabParamParser::wrap(thiz.capacity()); }); + frame_queue_factory.record("keep_frames", 1, 1, [](int outc, mxArray* outv[], int inc, const mxArray* inv[]) + { + auto thiz = MatlabParamParser::parse(inv[0]); + outv[0] = MatlabParamParser::wrap(thiz.keep_frames()); + }); factory->record(frame_queue_factory); } // TODO: need to understand how to call matlab functions from within C++ before async things can be implemented. diff --git a/wrappers/python/pyrs_processing.cpp b/wrappers/python/pyrs_processing.cpp index ab38fe3763..a901f3ea68 100644 --- a/wrappers/python/pyrs_processing.cpp +++ b/wrappers/python/pyrs_processing.cpp @@ -26,6 +26,7 @@ void init_processing(py::module &m) { "developers who are not using async APIs."); frame_queue.def(py::init()) .def(py::init<>()) + .def(py::init(), "capacity"_a, "keep_frames"_a = false) .def("enqueue", &rs2::frame_queue::enqueue, "Enqueue a new frame into the queue.", "f"_a) .def("wait_for_frame", &rs2::frame_queue::wait_for_frame, "Wait until a new frame " "becomes available in the queue and dequeue it.", "timeout_ms"_a = 5000, py::call_guard()) @@ -39,8 +40,9 @@ void init_processing(py::module &m) { auto success = self.try_wait_for_frame(&frame, timeout_ms); return std::make_tuple(success, frame); }, "timeout_ms"_a = 5000, py::call_guard()) // No docstring in C++ - .def("__call__", &rs2::frame_queue::operator(), "Identical to calling enqueue", "f"_a) - .def("capacity", &rs2::frame_queue::capacity, "Return the capacity of the queue"); + .def("__call__", &rs2::frame_queue::operator(), "Identical to calling enqueue.", "f"_a) + .def("capacity", &rs2::frame_queue::capacity, "Return the capacity of the queue.") + .def("keep_frames", &rs2::frame_queue::keep_frames, "Return whether or not the queue calls keep on enqueued frames."); py::class_ processing_block(m, "processing_block", "Define the processing block workflow, inherit this class to " "generate your own processing_block."); From b72fcd750b6db9cac69cb2215d8a7fd5cfed2daa Mon Sep 17 00:00:00 2001 From: Lior Ramati Date: Wed, 28 Aug 2019 17:17:25 +0300 Subject: [PATCH 02/20] Add python example explaining frame queue usage --- .../python/examples/frame_queue_example.py | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 wrappers/python/examples/frame_queue_example.py diff --git a/wrappers/python/examples/frame_queue_example.py b/wrappers/python/examples/frame_queue_example.py new file mode 100644 index 0000000000..f2100db783 --- /dev/null +++ b/wrappers/python/examples/frame_queue_example.py @@ -0,0 +1,75 @@ +## License: Apache 2.0. See LICENSE file in root directory. +## Copyright(c) 2019 Intel Corporation. All Rights Reserved. + +##################################################### +## Frame Queues ## +##################################################### + +# First import the library +import pyrealsense2 as rs +import time + +# Implement two callbacks +def slow_callback(frame): + n = frame.get_frame_number() + if n % 20 == 0: + time.sleep(.5) + print n + +def slower_callback(frame): + n = frame.get_frame_number() + if n % 20 == 0: + time.sleep(1) + print n + +# Create a pipeline +pipeline = rs.pipeline() + +#Create a config and configure the pipeline to stream +# different resolutions of color and depth streams +config = rs.config() +config.enable_stream(rs.stream.depth, 640, 360, rs.format.z16, 30) +config.enable_stream(rs.stream.color, 640, 480, rs.format.bgr8, 30) + +# Start streaming to the slow callback. +# This stream will lag, causing the occasional frame drop. +print("Slow callback") +pipeline.start(config, slow_callback) +pipeline.sleep(10) +pipeline.stop() + +# Start streaming to the the slow callback by way of the frame queue. +# This stream will occasionally hiccup, but the frame_queue will prevent frame loss. +print("Slow callback + queue") +queue = rs.frame_queue(50) +pipeline.start(config, queue) +start = time.time() +while time.time() - start < 10: + frames = queue.wait_for_frames() + slow_callback(frames) +pipeline.stop() + +# Start streaming to the the slower callback by way of the frame queue. +# This stream will drop frames because the delays are long enough that the backed up +# frames use the entire internal frame pool preventing the SDK from creating more frames. +print("Slower callback + queue") +queue = rs.frame_queue(50) +pipeline.start(config, queue) +start = time.time() +while time.time() - start < 10: + frames = queue.wait_for_frames() + slower_callback(frames) +pipeline.stop() + +# Start streaming to the slower callback by way of a keeping frame queue. +# This stream will no longer drop frames because the frame queue tells the SDK +# to remove the frames it holds from the internal frame queue, allowing the SDK to +# allocate space for and create more frames . +print("Slower callback + keeping queue") +queue = rs.frame_queue(50, keep_frames=True) +pipeline.start(config, queue) +start = time.time() +while time.time() - start < 10: + frames = queue.wait_for_frames() + slower_callback(frames) +pipeline.stop() \ No newline at end of file From 210ec5830fac3c640fdb152ec09ee52366626952 Mon Sep 17 00:00:00 2001 From: Lior Ramati Date: Sun, 1 Sep 2019 17:24:26 +0300 Subject: [PATCH 03/20] Add missing EOF newlines --- wrappers/matlab/frame_queue.m | 2 +- wrappers/python/examples/frame_queue_example.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/wrappers/matlab/frame_queue.m b/wrappers/matlab/frame_queue.m index e04edffc7f..77a5c02e25 100644 --- a/wrappers/matlab/frame_queue.m +++ b/wrappers/matlab/frame_queue.m @@ -44,4 +44,4 @@ function delete(this) end end end -end \ No newline at end of file +end diff --git a/wrappers/python/examples/frame_queue_example.py b/wrappers/python/examples/frame_queue_example.py index f2100db783..31ed2f4fa0 100644 --- a/wrappers/python/examples/frame_queue_example.py +++ b/wrappers/python/examples/frame_queue_example.py @@ -72,4 +72,4 @@ def slower_callback(frame): while time.time() - start < 10: frames = queue.wait_for_frames() slower_callback(frames) -pipeline.stop() \ No newline at end of file +pipeline.stop() From ca341c016ef82b7482790f8fb4b17c861165c313 Mon Sep 17 00:00:00 2001 From: Lior Ramati Date: Mon, 2 Sep 2019 14:16:46 +0300 Subject: [PATCH 04/20] Update frame_queue example --- .../python/examples/frame_queue_example.py | 127 ++++++++++-------- 1 file changed, 69 insertions(+), 58 deletions(-) diff --git a/wrappers/python/examples/frame_queue_example.py b/wrappers/python/examples/frame_queue_example.py index 31ed2f4fa0..952c339109 100644 --- a/wrappers/python/examples/frame_queue_example.py +++ b/wrappers/python/examples/frame_queue_example.py @@ -9,67 +9,78 @@ import pyrealsense2 as rs import time -# Implement two callbacks -def slow_callback(frame): - n = frame.get_frame_number() - if n % 20 == 0: - time.sleep(.5) - print n - -def slower_callback(frame): - n = frame.get_frame_number() - if n % 20 == 0: - time.sleep(1) - print n +# Implement two "processing" functions, each of which +# occassionally lags and takes longer to process a frame. +def slow_processing(frame): + n = frame.get_frame_number() + if n % 20 == 0: + time.sleep(1/4) + print(n) -# Create a pipeline -pipeline = rs.pipeline() +def slower_processing(frame): + n = frame.get_frame_number() + if n % 20 == 0: + time.sleep(1) + print(n) -#Create a config and configure the pipeline to stream -# different resolutions of color and depth streams -config = rs.config() -config.enable_stream(rs.stream.depth, 640, 360, rs.format.z16, 30) -config.enable_stream(rs.stream.color, 640, 480, rs.format.bgr8, 30) +try: + # Create a pipeline + pipeline = rs.pipeline() -# Start streaming to the slow callback. -# This stream will lag, causing the occasional frame drop. -print("Slow callback") -pipeline.start(config, slow_callback) -pipeline.sleep(10) -pipeline.stop() + # Create a config and configure the pipeline to stream + # different resolutions of color and depth streams + config = rs.config() + config.enable_stream(rs.stream.depth, 640, 360, rs.format.z16, 30) -# Start streaming to the the slow callback by way of the frame queue. -# This stream will occasionally hiccup, but the frame_queue will prevent frame loss. -print("Slow callback + queue") -queue = rs.frame_queue(50) -pipeline.start(config, queue) -start = time.time() -while time.time() - start < 10: - frames = queue.wait_for_frames() - slow_callback(frames) -pipeline.stop() + # Start streaming to the slow processing function. + # This stream will lag, causing the occasional frame drop. + print("Slow callback") + pipeline.start(config) + start = time.time() + while time.time() - start < 5: + frames = pipeline.wait_for_frames() + slow_processing(frames) + pipeline.stop() -# Start streaming to the the slower callback by way of the frame queue. -# This stream will drop frames because the delays are long enough that the backed up -# frames use the entire internal frame pool preventing the SDK from creating more frames. -print("Slower callback + queue") -queue = rs.frame_queue(50) -pipeline.start(config, queue) -start = time.time() -while time.time() - start < 10: - frames = queue.wait_for_frames() - slower_callback(frames) -pipeline.stop() + # Start streaming to the the slow processing function by way of a frame queue. + # This stream will occasionally hiccup, but the frame_queue will prevent frame loss. + print("Slow callback + queue") + queue = rs.frame_queue(50) + pipeline.start(config, queue) + start = time.time() + while time.time() - start < 5: + frames = queue.wait_for_frame() + slow_processing(frames) + pipeline.stop() -# Start streaming to the slower callback by way of a keeping frame queue. -# This stream will no longer drop frames because the frame queue tells the SDK -# to remove the frames it holds from the internal frame queue, allowing the SDK to -# allocate space for and create more frames . -print("Slower callback + keeping queue") -queue = rs.frame_queue(50, keep_frames=True) -pipeline.start(config, queue) -start = time.time() -while time.time() - start < 10: - frames = queue.wait_for_frames() - slower_callback(frames) -pipeline.stop() + # Start streaming to the the slower processing function by way of a frame queue. + # This stream will drop frames because the delays are long enough that the backed up + # frames use the entire internal frame pool preventing the SDK from creating more frames. + print("Slower callback + queue") + queue = rs.frame_queue(50) + pipeline.start(config, queue) + start = time.time() + while time.time() - start < 5: + frames = queue.wait_for_frame() + slower_processing(frames) + pipeline.stop() + + # Start streaming to the slower processing function by way of a keeping frame queue. + # This stream will no longer drop frames because the frame queue tells the SDK + # to remove the frames it holds from the internal frame queue, allowing the SDK to + # allocate space for and create more frames . + print("Slower callback + keeping queue") + queue = rs.frame_queue(50, keep_frames=True) + pipeline.start(config, queue) + start = time.time() + while time.time() - start < 5: + frames = queue.wait_for_frame() + slower_processing(frames) + pipeline.stop() + +except Exception as e: + print(e) +except: + print("A different Error") +else: + print("Done") \ No newline at end of file From 6ac3f1beabee6393e26c00860131f89d3ef4f9af Mon Sep 17 00:00:00 2001 From: Lior Ramati Date: Wed, 4 Sep 2019 19:05:48 +0300 Subject: [PATCH 05/20] Fix python docstring display glitch --- wrappers/python/pyrs_context.cpp | 2 +- wrappers/python/pyrs_processing.cpp | 2 +- wrappers/python/pyrs_record_playback.cpp | 4 ++-- wrappers/python/pyrsutil.cpp | 11 +++++++---- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/wrappers/python/pyrs_context.cpp b/wrappers/python/pyrs_context.cpp index 03d81000c8..5de84cab76 100644 --- a/wrappers/python/pyrs_context.cpp +++ b/wrappers/python/pyrs_context.cpp @@ -31,7 +31,7 @@ void init_context(py::module &m) { self.set_devices_changed_callback(callback); }, "Register devices changed callback.", "callback"_a) .def("load_device", &rs2::context::load_device, "Creates a devices from a RealSense file.\n" - "On successful load, the device will be appended to the context and a devices_changed event triggered." + "On successful load, the device will be appended to the context and a devices_changed event triggered.", "filename"_a) .def("unload_device", &rs2::context::unload_device, "filename"_a) // No docstring in C++ .def("unload_tracking_module", &rs2::context::unload_tracking_module); // No docstring in C++ diff --git a/wrappers/python/pyrs_processing.cpp b/wrappers/python/pyrs_processing.cpp index ab38fe3763..7b39c8e7a0 100644 --- a/wrappers/python/pyrs_processing.cpp +++ b/wrappers/python/pyrs_processing.cpp @@ -9,7 +9,7 @@ void init_processing(py::module &m) { py::class_ frame_source(m, "frame_source", "The source used to generate frames, which is usually done by the low level driver for each sensor. " "frame_source is one of the parameters of processing_block's callback function, which can be used to re-generate the " "frame and via frame_ready invoke another callback function to notify application frame is ready."); - frame_source.def("allocate_video_frame", &rs2::frame_source::allocate_video_frame, "Allocate a new video frame with given params" + frame_source.def("allocate_video_frame", &rs2::frame_source::allocate_video_frame, "Allocate a new video frame with given params", "profile"_a, "original"_a, "new_bpp"_a = 0, "new_width"_a = 0, "new_height"_a = 0, "new_stride"_a = 0, "frame_type"_a = RS2_EXTENSION_VIDEO_FRAME) .def("allocate_points", &rs2::frame_source::allocate_points, "profile"_a, diff --git a/wrappers/python/pyrs_record_playback.cpp b/wrappers/python/pyrs_record_playback.cpp index 8db2e8cde3..f01f732a5f 100644 --- a/wrappers/python/pyrs_record_playback.cpp +++ b/wrappers/python/pyrs_record_playback.cpp @@ -16,12 +16,12 @@ void init_record_playback(py::module &m) { .def("file_name", &rs2::playback::file_name, "The name of the playback file.") .def("get_position", &rs2::playback::get_position, "Retrieves the current position of the playback in the file in terms of time. Units are expressed in nanoseconds.") .def("get_duration", &rs2::playback::get_duration, "Retrieves the total duration of the file.") - .def("seek", &rs2::playback::seek, "Sets the playback to a specified time point of the played data." "time"_a) + .def("seek", &rs2::playback::seek, "Sets the playback to a specified time point of the played data.", "time"_a) .def("is_real_time", &rs2::playback::is_real_time, "Indicates if playback is in real time mode or non real time.") .def("set_real_time", &rs2::playback::set_real_time, "Set the playback to work in real time or non real time. In real time mode, playback will " "play the same way the file was recorded. If the application takes too long to handle the callback, frames may be dropped. In non real time " "mode, playback will wait for each callback to finish handling the data before reading the next frame. In this mode no frames will be dropped, " - "and the application controls the framerate of playback via callback duration." "real_time"_a) + "and the application controls the framerate of playback via callback duration.", "real_time"_a) // set_playback_speed? .def("set_status_changed_callback", [](rs2::playback& self, std::function callback) { self.set_status_changed_callback(callback); diff --git a/wrappers/python/pyrsutil.cpp b/wrappers/python/pyrsutil.cpp index 8f52c40243..6256e7c4ba 100644 --- a/wrappers/python/pyrsutil.cpp +++ b/wrappers/python/pyrsutil.cpp @@ -11,27 +11,30 @@ void init_util(py::module &m) { std::array pixel{}; rs2_project_point_to_pixel(pixel.data(), &intrin, point.data()); return pixel; - }, "Given a point in 3D space, compute the corresponding pixel coordinates in an image with no distortion or forward distortion coefficients produced by the same camera"); + }, "Given a point in 3D space, compute the corresponding pixel coordinates in an image with no distortion or forward distortion coefficients produced by the same camera", + "intrin"_a, "point"_a); m.def("rs2_deproject_pixel_to_point", [](const rs2_intrinsics& intrin, const std::array& pixel, float depth)->std::array { std::array point{}; rs2_deproject_pixel_to_point(point.data(), &intrin, pixel.data(), depth); return point; - }, "Given pixel coordinates and depth in an image with no distortion or inverse distortion coefficients, compute the corresponding point in 3D space relative to the same camera"); + }, "Given pixel coordinates and depth in an image with no distortion or inverse distortion coefficients, compute the corresponding point in 3D space relative to the same camera", + "intrin"_a, "pixel"_a, "depth"_a); m.def("rs2_transform_point_to_point", [](const rs2_extrinsics& extrin, const std::array& from_point)->std::array { std::array to_point{}; rs2_transform_point_to_point(to_point.data(), &extrin, from_point.data()); return to_point; - }, "Transform 3D coordinates relative to one sensor to 3D coordinates relative to another viewpoint"); + }, "Transform 3D coordinates relative to one sensor to 3D coordinates relative to another viewpoint", + "extrin"_a, "from_point"_a); m.def("rs2_fov", [](const rs2_intrinsics& intrin)->std::array { std::array to_fow{}; rs2_fov(&intrin, to_fow.data()); return to_fow; - }, "Calculate horizontal and vertical field of view, based on video intrinsics"); + }, "Calculate horizontal and vertical field of view, based on video intrinsics", "intrin"_a); /** end rsutil.h **/ } From b128f0b430a589e299d8b2110dfb4f30c579dc15 Mon Sep 17 00:00:00 2001 From: Lior Ramati Date: Thu, 5 Sep 2019 14:42:44 +0300 Subject: [PATCH 06/20] Add STAFactor to python wrapper to fix advanced_mode.get/set_amp_factor --- wrappers/python/pyrs_advanced_mode.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/wrappers/python/pyrs_advanced_mode.cpp b/wrappers/python/pyrs_advanced_mode.cpp index 3586d17839..c9cf51d132 100644 --- a/wrappers/python/pyrs_advanced_mode.cpp +++ b/wrappers/python/pyrs_advanced_mode.cpp @@ -211,6 +211,15 @@ void init_advanced_mode(py::module &m) { return ss.str(); }); + py::class_ _STAFactor(m, "STAFactor"); + _STAFactor.def(py::init<>()) + .def_readwrite("amplitude", &STAFactor::amplitude) + .def("__repr__", [](const STAFactor &e) { + std::stringstream ss; + ss << "amplitude: " << e.amplitude; + return ss.str(); + }); + py::class_ rs400_advanced_mode(m, "rs400_advanced_mode"); rs400_advanced_mode.def(py::init(), "device"_a) .def("toggle_advanced_mode", &rs400::advanced_mode::toggle_advanced_mode, "enable"_a) From 9f28362ca2ddce6cbb7dc381d937ce4a1f0c3da0 Mon Sep 17 00:00:00 2001 From: Lior Ramati Date: Thu, 5 Sep 2019 15:40:21 +0300 Subject: [PATCH 07/20] Rename STAFactor.amplitude --- wrappers/python/pyrs_advanced_mode.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wrappers/python/pyrs_advanced_mode.cpp b/wrappers/python/pyrs_advanced_mode.cpp index c9cf51d132..72085a96fb 100644 --- a/wrappers/python/pyrs_advanced_mode.cpp +++ b/wrappers/python/pyrs_advanced_mode.cpp @@ -213,10 +213,10 @@ void init_advanced_mode(py::module &m) { py::class_ _STAFactor(m, "STAFactor"); _STAFactor.def(py::init<>()) - .def_readwrite("amplitude", &STAFactor::amplitude) + .def_readwrite("a_factor", &STAFactor::amplitude) .def("__repr__", [](const STAFactor &e) { std::stringstream ss; - ss << "amplitude: " << e.amplitude; + ss << "a_factor: " << e.amplitude; return ss.str(); }); From 04c676cfd1c4d47e850f40a92bfcc6ed2c5b0464 Mon Sep 17 00:00:00 2001 From: Lior Ramati Date: Thu, 5 Sep 2019 15:54:01 +0300 Subject: [PATCH 08/20] store depth_units in save_single_frameset for depth reconstruction --- include/librealsense2/hpp/rs_export.hpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/librealsense2/hpp/rs_export.hpp b/include/librealsense2/hpp/rs_export.hpp index ce7a6bfe98..3fa36efcd6 100644 --- a/include/librealsense2/hpp/rs_export.hpp +++ b/include/librealsense2/hpp/rs_export.hpp @@ -184,6 +184,10 @@ namespace rs2 auto vp = profile.as(); rs2_video_stream stream{ vp.stream_type(), vp.stream_index(), uid++, vp.width(), vp.height(), vp.fps(), vf.get_bytes_per_pixel(), vp.format(), vp.get_intrinsics() }; software_profile = s.add_video_stream(stream); + if (f.is()) { + auto ds = sensor_from_frame(f)->as(); + s.add_read_only_option(RS2_OPTION_DEPTH_UNITS, ds.get_option(RS2_OPTION_DEPTH_UNITS)); + } } else if (f.is()) { auto mp = profile.as(); rs2_motion_stream stream{ mp.stream_type(), mp.stream_index(), uid++, mp.fps(), mp.format(), mp.get_motion_intrinsics() }; From bf17c750715f30b6d7dcac5bd0b9c7e765e00bdf Mon Sep 17 00:00:00 2001 From: Lior Ramati Date: Thu, 5 Sep 2019 16:24:39 +0300 Subject: [PATCH 09/20] Store extrinsics in save_single_frameset --- include/librealsense2/hpp/rs_export.hpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/include/librealsense2/hpp/rs_export.hpp b/include/librealsense2/hpp/rs_export.hpp index 3fa36efcd6..46ffcc9dd9 100644 --- a/include/librealsense2/hpp/rs_export.hpp +++ b/include/librealsense2/hpp/rs_export.hpp @@ -170,6 +170,8 @@ namespace rs2 software_device dev; std::vector> sensors; + std::vector> extrinsics; + if (auto fs = data.as()) { int uid = 0; for (int i = 0; i < fs.size(); ++i) { @@ -200,8 +202,24 @@ namespace rs2 assert(false); } sensors.emplace_back(s, software_profile, i); + + bool found_extrin = false; + for (auto& root : extrinsics) { + try { + std::get<0>(root).register_extrinsics_to(software_profile, + std::get<1>(root).get_extrinsics_to(profile) + ); + found_extrin = true; + break; + } catch (...) {} + } + if (!found_extrin) { + extrinsics.emplace_back(software_profile, profile); + } } + + // Recorder needs sensors to already exist when its created std::stringstream name; name << fname << data.get_frame_number() << ".bag"; From 6ddd5ddcd8887c791152042609a47fc10f6ddbf5 Mon Sep 17 00:00:00 2001 From: Phillip Schmidt Date: Mon, 9 Sep 2019 16:05:37 -0700 Subject: [PATCH 10/20] unit test Wheel_Odometry_API: use default configuration, check for existence of calibration file --- unit-tests/unit-tests-live.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/unit-tests/unit-tests-live.cpp b/unit-tests/unit-tests-live.cpp index b34d26751d..7f653ab1a2 100644 --- a/unit-tests/unit-tests-live.cpp +++ b/unit-tests/unit-tests-live.cpp @@ -5548,7 +5548,6 @@ TEST_CASE("Wheel_Odometry_API", "[live]") REQUIRE(profile); REQUIRE_NOTHROW(dev = profile.get_device()); REQUIRE(dev); - disable_sensitive_options_for(dev); dev_type PID = get_PID(dev); CAPTURE(PID.first); @@ -5570,7 +5569,7 @@ TEST_CASE("Wheel_Odometry_API", "[live]") THEN("Load wheel odometry calibration") { std::ifstream calibrationFile("calibration_odometry.json"); - if (calibrationFile) + REQUIRE(calibrationFile); { const std::string json_str((std::istreambuf_iterator(calibrationFile)), std::istreambuf_iterator()); From 0d729cb85b42864ccf537a236fc9247de6cc749d Mon Sep 17 00:00:00 2001 From: Phillip Schmidt Date: Mon, 9 Sep 2019 16:16:07 -0700 Subject: [PATCH 11/20] unit test Wheel_Odometry_API: copy calibration file to build folder --- unit-tests/CMakeLists.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/unit-tests/CMakeLists.txt b/unit-tests/CMakeLists.txt index 4cd5dd95b8..fd8f013007 100644 --- a/unit-tests/CMakeLists.txt +++ b/unit-tests/CMakeLists.txt @@ -51,6 +51,13 @@ add_custom_command(TARGET live-test POST_BUILD ${Deployment_Location} ) +# copy wheel odometry calibration file to build folder +add_custom_command(TARGET live-test POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy + ${CMAKE_CURRENT_SOURCE_DIR}/resources/calibration_odometry.json + ${CMAKE_CURRENT_BINARY_DIR}/calibration_odometry.json +) + #Post-Processing data set for unit-tests #message(STATUS "Post processing deployment directory=${Deployment_Location}") list(APPEND PP_Tests_List 1551257764229 # D415_DS(2) From 9d3f3830216cd6bfd1811aa7fcbf5816982ea4ce Mon Sep 17 00:00:00 2001 From: "Katz, Matan" Date: Tue, 10 Sep 2019 13:05:45 +0300 Subject: [PATCH 12/20] android - roi sensor added --- src/android/jni/sensor.cpp | 36 +++++++++++++++++++ .../librealsense/RegionOfInterest.java | 16 +++++++++ .../realsense/librealsense/RoiSensor.java | 26 ++++++++++++++ .../intel/realsense/librealsense/Sensor.java | 10 +++++- 4 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 wrappers/android/librealsense/src/main/java/com/intel/realsense/librealsense/RegionOfInterest.java create mode 100644 wrappers/android/librealsense/src/main/java/com/intel/realsense/librealsense/RoiSensor.java diff --git a/src/android/jni/sensor.cpp b/src/android/jni/sensor.cpp index 6e227e7eee..baeb668463 100644 --- a/src/android/jni/sensor.cpp +++ b/src/android/jni/sensor.cpp @@ -40,3 +40,39 @@ Java_com_intel_realsense_librealsense_Sensor_nGetStreamProfiles(JNIEnv *env, jcl env->SetLongArrayRegion(rv, 0, profiles.size(), reinterpret_cast(profiles.data())); return rv; } + +extern "C" +JNIEXPORT void JNICALL +Java_com_intel_realsense_librealsense_RoiSensor_nSetRegionOfInterest(JNIEnv *env, jclass clazz, + jlong handle, jint min_x, + jint min_y, jint max_x, + jint max_y) { + rs2_error* e = nullptr; + rs2_set_region_of_interest(reinterpret_cast(handle), min_x, min_y, max_x, max_y, &e); + handle_error(env, e); +} + +extern "C" +JNIEXPORT void JNICALL +Java_com_intel_realsense_librealsense_RoiSensor_nGetRegionOfInterest(JNIEnv *env, jclass type, + jlong handle, jobject roi) { + int min_x, min_y, max_x, max_y; + rs2_error *e = nullptr; + rs2_get_region_of_interest(reinterpret_cast(handle), &min_x, &min_y, &max_x, &max_y, &e); + handle_error(env, e); + + if(e) + return; + + jclass clazz = env->GetObjectClass(roi); + + jfieldID min_x_field = env->GetFieldID(clazz, "minX", "I"); + jfieldID min_y_field = env->GetFieldID(clazz, "minY", "I"); + jfieldID max_x_field = env->GetFieldID(clazz, "maxX", "I"); + jfieldID max_y_field = env->GetFieldID(clazz, "maxY", "I"); + + env->SetIntField(roi, min_x_field, min_x); + env->SetIntField(roi, min_y_field, min_y); + env->SetIntField(roi, max_x_field, max_x); + env->SetIntField(roi, max_y_field, max_y); +} \ No newline at end of file diff --git a/wrappers/android/librealsense/src/main/java/com/intel/realsense/librealsense/RegionOfInterest.java b/wrappers/android/librealsense/src/main/java/com/intel/realsense/librealsense/RegionOfInterest.java new file mode 100644 index 0000000000..7843eaf182 --- /dev/null +++ b/wrappers/android/librealsense/src/main/java/com/intel/realsense/librealsense/RegionOfInterest.java @@ -0,0 +1,16 @@ +package com.intel.realsense.librealsense; + +public class RegionOfInterest { + public int minX; + public int minY; + public int maxX; + public int maxY; + + public RegionOfInterest(){} + public RegionOfInterest(int minX,int minY, int maxX, int maxY){ + this.minX = minX; + this.minY = minY; + this.maxX = maxX; + this.maxY = maxY; + } +} diff --git a/wrappers/android/librealsense/src/main/java/com/intel/realsense/librealsense/RoiSensor.java b/wrappers/android/librealsense/src/main/java/com/intel/realsense/librealsense/RoiSensor.java new file mode 100644 index 0000000000..5742485079 --- /dev/null +++ b/wrappers/android/librealsense/src/main/java/com/intel/realsense/librealsense/RoiSensor.java @@ -0,0 +1,26 @@ +package com.intel.realsense.librealsense; + +public class RoiSensor extends Sensor { + + RoiSensor(long handle) { + super(handle); + mOwner = false; + } + + public void setRegionOfInterest(RegionOfInterest roi) throws Exception{ + nSetRegionOfInterest(mHandle, roi.minX, roi.minY, roi.maxX, roi.maxY); + } + + public void setRegionOfInterest(int minX, int minY, int maxX, int maxY) throws Exception{ + nSetRegionOfInterest(mHandle, minX, minY, maxX, maxY); + } + + public RegionOfInterest getRegionOfInterest() throws Exception { + RegionOfInterest rv = new RegionOfInterest(); + nGetRegionOfInterest(mHandle, rv); + return rv; + } + + private static native void nSetRegionOfInterest(long handle, int minX, int minY, int maxX, int maxY); + private static native void nGetRegionOfInterest(long handle, RegionOfInterest roi); +} diff --git a/wrappers/android/librealsense/src/main/java/com/intel/realsense/librealsense/Sensor.java b/wrappers/android/librealsense/src/main/java/com/intel/realsense/librealsense/Sensor.java index abf1d6310f..c5882866e8 100644 --- a/wrappers/android/librealsense/src/main/java/com/intel/realsense/librealsense/Sensor.java +++ b/wrappers/android/librealsense/src/main/java/com/intel/realsense/librealsense/Sensor.java @@ -18,9 +18,17 @@ public List getStreamProfiles(){ return rv; } + public T as(Extension extension) { + switch (extension){ + case ROI: return (T) new RoiSensor(mHandle); + } + throw new RuntimeException("this sensor is not extendable to " + extension.name()); + } + @Override public void close() { - nRelease(mHandle); + if(mOwner) + nRelease(mHandle); } private static native long[] nGetStreamProfiles(long handle); From 3a4d5a8ed35a54a9a45f8cf8bb2f665579d0277c Mon Sep 17 00:00:00 2001 From: Lior Ramati Date: Wed, 11 Sep 2019 17:45:04 +0300 Subject: [PATCH 13/20] Remove redundant variable from rs_export.hpp --- include/librealsense2/hpp/rs_export.hpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/include/librealsense2/hpp/rs_export.hpp b/include/librealsense2/hpp/rs_export.hpp index 46ffcc9dd9..127c4e20b5 100644 --- a/include/librealsense2/hpp/rs_export.hpp +++ b/include/librealsense2/hpp/rs_export.hpp @@ -173,18 +173,17 @@ namespace rs2 std::vector> extrinsics; if (auto fs = data.as()) { - int uid = 0; for (int i = 0; i < fs.size(); ++i) { frame f = fs[i]; auto profile = f.get_profile(); std::stringstream sname; - sname << "Sensor (" << uid << ")"; + sname << "Sensor (" << i << ")"; auto s = dev.add_sensor(sname.str()); stream_profile software_profile; if (auto vf = f.as()) { auto vp = profile.as(); - rs2_video_stream stream{ vp.stream_type(), vp.stream_index(), uid++, vp.width(), vp.height(), vp.fps(), vf.get_bytes_per_pixel(), vp.format(), vp.get_intrinsics() }; + rs2_video_stream stream{ vp.stream_type(), vp.stream_index(), i, vp.width(), vp.height(), vp.fps(), vf.get_bytes_per_pixel(), vp.format(), vp.get_intrinsics() }; software_profile = s.add_video_stream(stream); if (f.is()) { auto ds = sensor_from_frame(f)->as(); @@ -192,10 +191,10 @@ namespace rs2 } } else if (f.is()) { auto mp = profile.as(); - rs2_motion_stream stream{ mp.stream_type(), mp.stream_index(), uid++, mp.fps(), mp.format(), mp.get_motion_intrinsics() }; + rs2_motion_stream stream{ mp.stream_type(), mp.stream_index(), i, mp.fps(), mp.format(), mp.get_motion_intrinsics() }; software_profile = s.add_motion_stream(stream); } else if (f.is()) { - rs2_pose_stream stream{ profile.stream_type(), profile.stream_index(), uid++, profile.fps(), profile.format() }; + rs2_pose_stream stream{ profile.stream_type(), profile.stream_index(), i, profile.fps(), profile.format() }; software_profile = s.add_pose_stream(stream); } else { // TODO: How to handle other frame types? (e.g. points) @@ -241,6 +240,8 @@ namespace rs2 s.on_pose_frame({ const_cast(f.get_data()), [](void*) {}, f.get_timestamp(), f.get_frame_timestamp_domain(), static_cast(f.get_frame_number()), profile }); } + s.stop(); + s.close(); } } else { // single frame From f586ed85374439682479328b810914ead9531c01 Mon Sep 17 00:00:00 2001 From: Lior Ramati Date: Wed, 11 Sep 2019 17:46:55 +0300 Subject: [PATCH 14/20] Modify software device so that it builds it's internal extrinsic map based on the environment's extrinsics graph. This allows extrinsics set using stream_profile.register_extrinsics_to() between streams on two different sensors on the same software_device to be visible to dev.get_extrinsics() --- src/software-device.cpp | 17 ++++++++++++++--- src/software-device.h | 2 +- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/software-device.cpp b/src/software-device.cpp index d366b4cbda..88a977d075 100644 --- a/src/software-device.cpp +++ b/src/software-device.cpp @@ -21,9 +21,20 @@ namespace librealsense return *sensor; } - void software_device::register_extrinsic(const stream_interface& stream, uint32_t groupd_index) + void software_device::register_extrinsic(const stream_interface& stream) { - register_stream_to_extrinsic_group(stream, groupd_index); + uint32_t max_idx = 0; + std::set bad_groups; + for (auto & pair : _extrinsics) { + if (pair.second.first > max_idx) max_idx = pair.second.first; + if (bad_groups.count(pair.second.first)) continue; // already tried the group + rs2_extrinsics ext; + if (environment::get_instance().get_extrinsics_graph().try_fetch_extrinsics(stream, *pair.second.second, &ext)) { + register_stream_to_extrinsic_group(stream, pair.second.first); + return; + } + } + register_stream_to_extrinsic_group(stream, max_idx+1); } software_sensor& software_device::get_software_sensor(int index) @@ -265,7 +276,7 @@ namespace librealsense }, software_frame.pixels }); auto sd = dynamic_cast(_owner); - sd->register_extrinsic(*vid_profile, _unique_id); + sd->register_extrinsic(*vid_profile); _source.invoke_callback(frame); } diff --git a/src/software-device.h b/src/software-device.h index db95503a2e..a3d6a91ea7 100644 --- a/src/software-device.h +++ b/src/software-device.h @@ -31,7 +31,7 @@ namespace librealsense std::vector markers; return markers; }; - void register_extrinsic(const stream_interface& stream, uint32_t groupd_index); + void register_extrinsic(const stream_interface& stream); private: std::vector> _software_sensors; From f80dd790f052483ff3b34d2feec9b78f137685ad Mon Sep 17 00:00:00 2001 From: "Dorodnicov, Sergey" Date: Sun, 15 Sep 2019 08:09:52 -0700 Subject: [PATCH 15/20] Auto-calibration adjustments --- common/fw-update-helper.cpp | 4 +- common/model-views.cpp | 6 ++- common/on-chip-calib.cpp | 80 +++++++++++++++++++++++++++---------- src/ds5/ds5-color.cpp | 5 +++ 4 files changed, 71 insertions(+), 24 deletions(-) diff --git a/common/fw-update-helper.cpp b/common/fw-update-helper.cpp index d4ed2c99b2..f43a1fb7b2 100644 --- a/common/fw-update-helper.cpp +++ b/common/fw-update-helper.cpp @@ -56,7 +56,9 @@ namespace rs2 if (product_line == RS2_PRODUCT_LINE_D400 && allow_rc_firmware) return FW_D4XX_RC_IMAGE_VERSION; else if (product_line == RS2_PRODUCT_LINE_D400) return FW_D4XX_FW_IMAGE_VERSION; - else if (product_line == RS2_PRODUCT_LINE_SR300) return FW_SR3XX_FW_IMAGE_VERSION; + // NOTE: For now removing recommended firmware version for SR30x series + // TODO: Re-enable in future release + //else if (product_line == RS2_PRODUCT_LINE_SR300) return FW_SR3XX_FW_IMAGE_VERSION; else return ""; } diff --git a/common/model-views.cpp b/common/model-views.cpp index 4377cf05ab..a08c585ef6 100644 --- a/common/model-views.cpp +++ b/common/model-views.cpp @@ -3030,8 +3030,10 @@ namespace rs2 n->snoozed = true; } - viewer.not_model.add_notification(n); - related_notifications.push_back(n); + // NOTE: For now do not pre-emptively suggest auto-calibration + // TODO: Revert in later release + //viewer.not_model.add_notification(n); + //related_notifications.push_back(n); } } } diff --git a/common/on-chip-calib.cpp b/common/on-chip-calib.cpp index ee7dbcaf4a..3da9831bdc 100644 --- a/common/on-chip-calib.cpp +++ b/common/on-chip-calib.cpp @@ -428,7 +428,7 @@ namespace rs2 { std::this_thread::sleep_for(std::chrono::milliseconds(200)); - uint8_t speed = 4 - _speed; + uint8_t speed = 4; // NOTE: Start the calibration in slow mode bool repeat = true; while (repeat) // Repeat until we got a result @@ -875,9 +875,45 @@ namespace rs2 ImGui::SetCursorScreenPos({ float(x + 15), float(y + 33) }); - if (!recommend_keep) ImGui::Text("%s", "Camera original calibration is OK"); - else if (health > 0.2f) ImGui::Text("%s", "We found much better calibration!"); - else ImGui::Text("%s", "We found better calibration for the device!"); + ImGui::Text("Calibration Status: "); + + std::stringstream ss; ss << std::fixed << std::setprecision(2) << health; + auto health_str = ss.str(); + + std::string text_name = to_string() << "##notification_text_" << index; + + ImGui::SetCursorScreenPos({ float(x + 136), float(y + 30) }); + ImGui::PushStyleColor(ImGuiCol_Text, white); + ImGui::PushStyleColor(ImGuiCol_FrameBg, transparent); + ImGui::PushStyleColor(ImGuiCol_ScrollbarBg, transparent); + ImGui::PushStyleColor(ImGuiCol_ScrollbarGrab, transparent); + ImGui::PushStyleColor(ImGuiCol_ScrollbarGrabActive, transparent); + ImGui::PushStyleColor(ImGuiCol_ScrollbarGrabHovered, transparent); + ImGui::PushStyleColor(ImGuiCol_TextSelectedBg, white); + ImGui::InputTextMultiline(text_name.c_str(), const_cast(health_str.c_str()), + strlen(health_str.c_str()) + 1, { 50, + ImGui::GetTextLineHeight() + 6 }, + ImGuiInputTextFlags_ReadOnly); + ImGui::PopStyleColor(7); + + ImGui::SetCursorScreenPos({ float(x + 172), float(y + 33) }); + + if (!recommend_keep) + { + ImGui::PushStyleColor(ImGuiCol_Text, greenish); + ImGui::Text("(Good)"); + } + else if (health < 0.25f) + { + ImGui::PushStyleColor(ImGuiCol_Text, yellowish); + ImGui::Text("(Can be Improved)"); + } + else + { + ImGui::PushStyleColor(ImGuiCol_Text, redish); + ImGui::Text("(Requires Calibration)"); + } + ImGui::PopStyleColor(); auto old_fr = get_manager().get_metric(false).first; auto new_fr = get_manager().get_metric(true).first; @@ -901,7 +937,9 @@ namespace rs2 new_units = "cm"; } - if (fr_improvement > 1.f || rms_improvement > 1.f) + // NOTE: Disabling metrics temporarily + // TODO: Re-enable in future release + if (/* fr_improvement > 1.f || rms_improvement > 1.f */ false) { std::string txt = to_string() << " Fill-Rate: " << std::setprecision(1) << std::fixed << new_fr << "%%"; @@ -985,29 +1023,29 @@ namespace rs2 { ImGui::PushStyleColor(ImGuiCol_Button, saturate(sensor_header_light_blue, sat)); ImGui::PushStyleColor(ImGuiCol_ButtonHovered, saturate(sensor_header_light_blue, 1.5f)); - } - std::string button_name = to_string() << "Apply New" << "##apply" << index; - if (!use_new_calib) button_name = to_string() << "Keep Original" << "##original" << index; + std::string button_name = to_string() << "Apply New" << "##apply" << index; + if (!use_new_calib) button_name = to_string() << "Keep Original" << "##original" << index; - ImGui::SetCursorScreenPos({ float(x + 5), float(y + height - 25) }); - if (ImGui::Button(button_name.c_str(), { float(bar_width), 20.f })) - { - if (use_new_calib) + ImGui::SetCursorScreenPos({ float(x + 5), float(y + height - 25) }); + if (ImGui::Button(button_name.c_str(), { float(bar_width), 20.f })) { - get_manager().keep(); - update_state = RS2_CALIB_STATE_COMPLETE; - pinned = false; - enable_dismiss = false; - last_progress_time = last_interacted = system_clock::now() + milliseconds(500); + if (use_new_calib) + { + get_manager().keep(); + update_state = RS2_CALIB_STATE_COMPLETE; + pinned = false; + enable_dismiss = false; + last_progress_time = last_interacted = system_clock::now() + milliseconds(500); + } + else dismiss(false); + + get_manager().restore_workspace([this](std::function a) { a(); }); } - else dismiss(false); - get_manager().restore_workspace([this](std::function a){ a(); }); + ImGui::PopStyleColor(2); } - if (recommend_keep) ImGui::PopStyleColor(2); - if (ImGui::IsItemHovered()) { ImGui::SetTooltip("%s", "New calibration values will be saved in device memory"); diff --git a/src/ds5/ds5-color.cpp b/src/ds5/ds5-color.cpp index 3618183dd6..b7ad1cc7fd 100644 --- a/src/ds5/ds5-color.cpp +++ b/src/ds5/ds5-color.cpp @@ -74,6 +74,11 @@ namespace librealsense color_ep->register_pu(RS2_OPTION_BACKLIGHT_COMPENSATION); color_ep->register_pu(RS2_OPTION_AUTO_EXPOSURE_PRIORITY); } + // From 5.11.15 auto-exposure priority is supported on the D465 + else if (_fw_version >= firmware_version("5.11.15.0")) + { + color_ep->register_pu(RS2_OPTION_AUTO_EXPOSURE_PRIORITY); + } if (color_devices_info.front().pid == ds::RS465_PID) color_ep->register_pixel_format(pf_mjpg); From 39e157bed9476f65567c09bee7967c01133e2ac2 Mon Sep 17 00:00:00 2001 From: aangerma Date: Mon, 16 Sep 2019 11:24:08 +0300 Subject: [PATCH 16/20] Change depth_invalidation_enabled to false by default. --- src/l500/l500-depth.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/l500/l500-depth.h b/src/l500/l500-depth.h index cc34592dd8..a5d58c1e4f 100644 --- a/src/l500/l500-depth.h +++ b/src/l500/l500-depth.h @@ -86,7 +86,7 @@ namespace librealsense explicit l500_depth_sensor(l500_device* owner, std::shared_ptr uvc_device, std::unique_ptr timestamp_reader) : uvc_sensor("L500 Depth Sensor", uvc_device, move(timestamp_reader), owner), _owner(owner), - _depth_invalidation_enabled(true) + _depth_invalidation_enabled(false) { register_option(RS2_OPTION_DEPTH_UNITS, std::make_shared("Number of meters represented by a single depth unit", lazy([&]() { @@ -100,7 +100,7 @@ namespace librealsense 0, 1, 1, - 1, + 0, &_depth_invalidation_enabled, "depth invalidation enabled"); _depth_invalidation_option->on_set([this](float val) From f96a16960992a12904ebf48078cb90c981af0735 Mon Sep 17 00:00:00 2001 From: "Dorodnicov, Sergey" Date: Mon, 16 Sep 2019 05:10:01 -0700 Subject: [PATCH 17/20] More minor fixes to auto-calibration --- common/model-views.cpp | 4 +- common/on-chip-calib.cpp | 338 ++++++++++++++++++++++----------------- common/on-chip-calib.h | 7 +- common/viewer.cpp | 8 +- 4 files changed, 198 insertions(+), 159 deletions(-) diff --git a/common/model-views.cpp b/common/model-views.cpp index a08c585ef6..d42b68962f 100644 --- a/common/model-views.cpp +++ b/common/model-views.cpp @@ -4383,13 +4383,11 @@ namespace rs2 viewer.not_model.add_notification(n); n->forced = true; - n->update_state = autocalib_notification_model::RS2_CALIB_STATE_CALIB_IN_PROCESS; + n->update_state = autocalib_notification_model::RS2_CALIB_STATE_SELF_INPUT; for (auto&& n : related_notifications) if (dynamic_cast(n.get())) n->dismiss(false); - - manager->start(n); } catch (const error& e) { diff --git a/common/on-chip-calib.cpp b/common/on-chip-calib.cpp index 3da9831bdc..bf63b0b7a2 100644 --- a/common/on-chip-calib.cpp +++ b/common/on-chip-calib.cpp @@ -412,7 +412,7 @@ namespace rs2 log(to_string() << "Warning: " << ex.what()); } - _progress = count * (2 * _speed); + _progress = count * (2 * speed); } while (count++ < 200 && !done); // If we exit due to counter, report timeout @@ -428,86 +428,67 @@ namespace rs2 { std::this_thread::sleep_for(std::chrono::milliseconds(200)); - uint8_t speed = 4; // NOTE: Start the calibration in slow mode + // Begin auto-calibration + std::vector cmd = + { + 0x14, 0x00, 0xab, 0xcd, + 0x80, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, + (uint8_t)speed, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 + }; + + safe_send_command(cmd, "START_CALIB"); - bool repeat = true; - while (repeat) // Repeat until we got a result + memset(&result, 0, sizeof(DirectSearchCalibrationResult)); + + // While not ready... + int count = 0; + bool done = false; + do { - // Begin auto-calibration - std::vector cmd = + std::this_thread::sleep_for(std::chrono::milliseconds(200)); + + // Check calibration status + cmd = { 0x14, 0x00, 0xab, 0xcd, 0x80, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, - speed, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - safe_send_command(cmd, "START_CALIB"); - - memset(&result, 0, sizeof(DirectSearchCalibrationResult)); - - // While not ready... - int count = 0; - bool done = false; - do + try { - std::this_thread::sleep_for(std::chrono::milliseconds(200)); - - // Check calibration status - cmd = - { - 0x14, 0x00, 0xab, 0xcd, - 0x80, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 - }; - - try - { - auto res = safe_send_command(cmd, "CALIB_STATUS"); - - if (res.size() < sizeof(int32_t) + sizeof(DirectSearchCalibrationResult)) - throw std::runtime_error("Not enough data from CALIB_STATUS!"); - - result = *reinterpret_cast(res.data()); - done = result.status != RS2_DSC_STATUS_RESULT_NOT_READY; - } - catch (const std::exception& ex) - { - log(to_string() << "Warning: " << ex.what()); - } - - _progress = count * (2 * _speed); + auto res = safe_send_command(cmd, "CALIB_STATUS"); - } while (count++ < 200 && !done); + if (res.size() < sizeof(int32_t) + sizeof(DirectSearchCalibrationResult)) + throw std::runtime_error("Not enough data from CALIB_STATUS!"); - // If we exit due to counter, report timeout - if (!done) + result = *reinterpret_cast(res.data()); + done = result.status != RS2_DSC_STATUS_RESULT_NOT_READY; + } + catch (const std::exception& ex) { - throw std::runtime_error("Operation timed-out!\n" - "Calibration state did not converged in time"); + log(to_string() << "Warning: " << ex.what()); } - std::this_thread::sleep_for(std::chrono::milliseconds(100)); + _progress = count * (2 * speed); - if (result.status != RS2_DSC_STATUS_EDGE_TOO_CLOSE) - { - repeat = false; - } - else - { - // Edge to Close means not enough "samples" to identify fit curve - // Slow down to capture more samples next cycle - log("Edge too close... Slowing down"); - speed++; - if (speed > 4) repeat = false; - } + } while (count++ < 200 && !done); + + // If we exit due to counter, report timeout + if (!done) + { + throw std::runtime_error("Operation timed-out!\n" + "Calibration state did not converged in time"); } + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + status = (rs2_dsc_status)result.status; } @@ -543,7 +524,7 @@ namespace rs2 { update_last_used(); - log(to_string() << "Starting calibration at speed " << _speed); + log(to_string() << "Starting calibration at speed " << speed); _in_3d_view = _viewer.is_3d_view; _viewer.is_3d_view = true; @@ -588,6 +569,16 @@ namespace rs2 // Switch into special Auto-Calibration mode start_viewer(256, 144, 90, invoke); + if (speed == 4) // White-wall + { + if (_sub->s->supports(RS2_OPTION_VISUAL_PRESET)) + { + log("Switching into High-Quality preset for White-Wall mode"); + _sub->s->set_option(RS2_OPTION_VISUAL_PRESET, 3.f); + std::this_thread::sleep_for(std::chrono::milliseconds(200)); + } + } + calibrate(); // Get new calibration from the firmware @@ -719,7 +710,8 @@ namespace rs2 if (update_state == RS2_CALIB_STATE_INITIAL_PROMPT) ImGui::Text("%s", "Calibration Health-Check"); else if (update_state == RS2_CALIB_STATE_CALIB_IN_PROCESS || - update_state == RS2_CALIB_STATE_CALIB_COMPLETE) + update_state == RS2_CALIB_STATE_CALIB_COMPLETE || + update_state == RS2_CALIB_STATE_SELF_INPUT) ImGui::Text("%s", "On-Chip Calibration"); else if (update_state == RS2_CALIB_STATE_TARE_INPUT) ImGui::Text("%s", "Tare Calibration"); @@ -839,6 +831,47 @@ namespace rs2 ImGui::SetTooltip("%s", "Begin Tare Calibration"); } } + else if (update_state == RS2_CALIB_STATE_SELF_INPUT) + { + ImGui::SetCursorScreenPos({ float(x + 9), float(y + 33) }); + ImGui::Text("%s", "Speed:"); + + ImGui::SetCursorScreenPos({ float(x + 135), float(y + 30) }); + + std::string id = to_string() << "##speed_" << index; + + std::vector vals{ "Very Fast", "Fast", "Medium", "Slow", "White Wall" }; + std::vector vals_cstr; + for (auto&& s : vals) vals_cstr.push_back(s.c_str()); + + ImGui::PushItemWidth(width - 145); + ImGui::Combo(id.c_str(), &get_manager().speed, vals_cstr.data(), vals.size()); + ImGui::PopItemWidth(); + + auto sat = 1.f + sin(duration_cast(system_clock::now() - created_time).count() / 700.f) * 0.1f; + + ImGui::PushStyleColor(ImGuiCol_Button, saturate(sensor_header_light_blue, sat)); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, saturate(sensor_header_light_blue, 1.5f)); + + std::string button_name = to_string() << "Calibrate" << "##self" << index; + + ImGui::SetCursorScreenPos({ float(x + 5), float(y + height - 25) }); + if (ImGui::Button(button_name.c_str(), { float(bar_width), 20.f })) + { + get_manager().restore_workspace([this](std::function a) { a(); }); + get_manager().reset(); + get_manager().start(shared_from_this()); + update_state = RS2_CALIB_STATE_CALIB_IN_PROCESS; + enable_dismiss = false; + } + + ImGui::PopStyleColor(2); + + if (ImGui::IsItemHovered()) + { + ImGui::SetTooltip("%s", "Begin On-Chip Calibration"); + } + } else if (update_state == RS2_CALIB_STATE_FAILED) { ImGui::Text("%s", _error_message.c_str()); @@ -871,11 +904,11 @@ namespace rs2 { auto health = get_manager().get_health(); - auto recommend_keep = health > 0.1f; + auto recommend_keep = health > 0.15f; ImGui::SetCursorScreenPos({ float(x + 15), float(y + 33) }); - ImGui::Text("Calibration Status: "); + ImGui::Text("Calibration Error: "); std::stringstream ss; ss << std::fixed << std::setprecision(2) << health; auto health_str = ss.str(); @@ -900,7 +933,7 @@ namespace rs2 if (!recommend_keep) { - ImGui::PushStyleColor(ImGuiCol_Text, greenish); + ImGui::PushStyleColor(ImGuiCol_Text, light_blue); ImGui::Text("(Good)"); } else if (health < 0.25f) @@ -914,75 +947,57 @@ namespace rs2 ImGui::Text("(Requires Calibration)"); } ImGui::PopStyleColor(); - - auto old_fr = get_manager().get_metric(false).first; - auto new_fr = get_manager().get_metric(true).first; - - auto old_rms = fabs(get_manager().get_metric(false).second); - auto new_rms = fabs(get_manager().get_metric(true).second); - auto fr_improvement = 100.f * ((new_fr - old_fr) / old_fr); - auto rms_improvement = 100.f * ((old_rms - new_rms) / old_rms); - - std::string old_units = "mm"; - if (old_rms > 10.f) - { - old_rms /= 10.f; - old_units = "cm"; - } - std::string new_units = "mm"; - if (new_rms > 10.f) + if (ImGui::IsItemHovered()) { - new_rms /= 10.f; - new_units = "cm"; + ImGui::SetTooltip("%s", "Calibration error captures how far camera calibration is from the optimal one\n" + "[0, 0.15) - Good\n" + "[0.15, 0.25) - Can be Improved\n" + "[0.25, ) - Requires Calibration"); } - // NOTE: Disabling metrics temporarily - // TODO: Re-enable in future release - if (/* fr_improvement > 1.f || rms_improvement > 1.f */ false) + if (recommend_keep) { - std::string txt = to_string() << " Fill-Rate: " << std::setprecision(1) << std::fixed << new_fr << "%%"; - - if (!use_new_calib) - { - txt = to_string() << " Fill-Rate: " << std::setprecision(1) << std::fixed << old_fr << "%%\n"; - } + + auto old_fr = get_manager().get_metric(false).first; + auto new_fr = get_manager().get_metric(true).first; - ImGui::SetCursorScreenPos({ float(x + 12), float(y + 90) }); - ImGui::PushFont(win.get_large_font()); - ImGui::Text("%s", static_cast(textual_icons::check)); - ImGui::PopFont(); + auto old_rms = fabs(get_manager().get_metric(false).second); + auto new_rms = fabs(get_manager().get_metric(true).second); - ImGui::SetCursorScreenPos({ float(x + 35), float(y + 92) }); - ImGui::Text("%s", txt.c_str()); + auto fr_improvement = 100.f * ((new_fr - old_fr) / old_fr); + auto rms_improvement = 100.f * ((old_rms - new_rms) / old_rms); - if (use_new_calib) + std::string old_units = "mm"; + if (old_rms > 10.f) { - ImGui::SameLine(); - - ImGui::PushStyleColor(ImGuiCol_Text, white); - txt = to_string() << " ( +" << std::fixed << std::setprecision(0) << fr_improvement << "%% )"; - ImGui::Text("%s", txt.c_str()); - ImGui::PopStyleColor(); + old_rms /= 10.f; + old_units = "cm"; + } + std::string new_units = "mm"; + if (new_rms > 10.f) + { + new_rms /= 10.f; + new_units = "cm"; } - if (rms_improvement > 1.f) + // NOTE: Disabling metrics temporarily + // TODO: Re-enable in future release + if (/* fr_improvement > 1.f || rms_improvement > 1.f */ false) { - if (use_new_calib) - { - txt = to_string() << " Noise Estimate: " << std::setprecision(2) << std::fixed << new_rms << new_units; - } - else + std::string txt = to_string() << " Fill-Rate: " << std::setprecision(1) << std::fixed << new_fr << "%%"; + + if (!use_new_calib) { - txt = to_string() << " Noise Estimate: " << std::setprecision(2) << std::fixed << old_rms << old_units; + txt = to_string() << " Fill-Rate: " << std::setprecision(1) << std::fixed << old_fr << "%%\n"; } - ImGui::SetCursorScreenPos({ float(x + 12), float(y + 90 + ImGui::GetTextLineHeight() + 6) }); + ImGui::SetCursorScreenPos({ float(x + 12), float(y + 90) }); ImGui::PushFont(win.get_large_font()); ImGui::Text("%s", static_cast(textual_icons::check)); ImGui::PopFont(); - ImGui::SetCursorScreenPos({ float(x + 35), float(y + 92 + ImGui::GetTextLineHeight() + 6) }); + ImGui::SetCursorScreenPos({ float(x + 35), float(y + 92) }); ImGui::Text("%s", txt.c_str()); if (use_new_calib) @@ -990,37 +1005,65 @@ namespace rs2 ImGui::SameLine(); ImGui::PushStyleColor(ImGuiCol_Text, white); - txt = to_string() << " ( -" << std::setprecision(0) << std::fixed << rms_improvement << "%% )"; + txt = to_string() << " ( +" << std::fixed << std::setprecision(0) << fr_improvement << "%% )"; ImGui::Text("%s", txt.c_str()); ImGui::PopStyleColor(); } + + if (rms_improvement > 1.f) + { + if (use_new_calib) + { + txt = to_string() << " Noise Estimate: " << std::setprecision(2) << std::fixed << new_rms << new_units; + } + else + { + txt = to_string() << " Noise Estimate: " << std::setprecision(2) << std::fixed << old_rms << old_units; + } + + ImGui::SetCursorScreenPos({ float(x + 12), float(y + 90 + ImGui::GetTextLineHeight() + 6) }); + ImGui::PushFont(win.get_large_font()); + ImGui::Text("%s", static_cast(textual_icons::check)); + ImGui::PopFont(); + + ImGui::SetCursorScreenPos({ float(x + 35), float(y + 92 + ImGui::GetTextLineHeight() + 6) }); + ImGui::Text("%s", txt.c_str()); + + if (use_new_calib) + { + ImGui::SameLine(); + + ImGui::PushStyleColor(ImGuiCol_Text, white); + txt = to_string() << " ( -" << std::setprecision(0) << std::fixed << rms_improvement << "%% )"; + ImGui::Text("%s", txt.c_str()); + ImGui::PopStyleColor(); + } + } + } + else + { + ImGui::SetCursorScreenPos({ float(x + 12), float(y + 100) }); + ImGui::Text("%s", "Please compare new vs old calibration\nand decide if to keep or discard the result..."); } - } - else - { - ImGui::SetCursorScreenPos({ float(x + 12), float(y + 100) }); - ImGui::Text("%s", "Please compare new vs old calibration\nand decide if to keep or discard the result..."); - } - ImGui::SetCursorScreenPos({ float(x + 9), float(y + 60) }); + ImGui::SetCursorScreenPos({ float(x + 9), float(y + 60) }); - if (ImGui::RadioButton("New", use_new_calib)) - { - use_new_calib = true; - get_manager().apply_calib(true); - } + if (ImGui::RadioButton("New", use_new_calib)) + { + use_new_calib = true; + get_manager().apply_calib(true); + } - ImGui::SetCursorScreenPos({ float(x + 150), float(y + 60) }); - if (ImGui::RadioButton("Original", !use_new_calib)) - { - use_new_calib = false; - get_manager().apply_calib(false); - } + ImGui::SetCursorScreenPos({ float(x + 150), float(y + 60) }); + if (ImGui::RadioButton("Original", !use_new_calib)) + { + use_new_calib = false; + get_manager().apply_calib(false); + } - auto sat = 1.f + sin(duration_cast(system_clock::now() - created_time).count() / 700.f) * 0.1f; + auto sat = 1.f + sin(duration_cast(system_clock::now() - created_time).count() / 700.f) * 0.1f; - if (recommend_keep) - { + ImGui::PushStyleColor(ImGuiCol_Button, saturate(sensor_header_light_blue, sat)); ImGui::PushStyleColor(ImGuiCol_ButtonHovered, saturate(sensor_header_light_blue, 1.5f)); @@ -1044,11 +1087,11 @@ namespace rs2 } ImGui::PopStyleColor(2); - } - if (ImGui::IsItemHovered()) - { - ImGui::SetTooltip("%s", "New calibration values will be saved in device memory"); + if (ImGui::IsItemHovered()) + { + ImGui::SetTooltip("%s", "New calibration values will be saved in device memory"); + } } } @@ -1226,7 +1269,12 @@ namespace rs2 { if (update_state == RS2_CALIB_STATE_COMPLETE) return 65; else if (update_state == RS2_CALIB_STATE_INITIAL_PROMPT) return 120; - else if (update_state == RS2_CALIB_STATE_CALIB_COMPLETE) return 170; + else if (update_state == RS2_CALIB_STATE_CALIB_COMPLETE) + { + if (get_manager().get_health() > 0.15f) return 170; + else return 80; + } + else if (update_state == RS2_CALIB_STATE_SELF_INPUT) return 85; else if (update_state == RS2_CALIB_STATE_TARE_INPUT) return 160; else return 100; } diff --git a/common/on-chip-calib.h b/common/on-chip-calib.h index 19be61754e..2020ca938b 100644 --- a/common/on-chip-calib.h +++ b/common/on-chip-calib.h @@ -31,10 +31,6 @@ namespace rs2 // Get health number from the calibration summary float get_health() const { return _health; } - // Set calibration speed: 0 - slowest, 4 - fastest - // On-Chip Calib manager will reduce speed if needed - void set_speed(int speed) { _speed = speed; } - // Write new calibration to the device void keep(); @@ -53,6 +49,7 @@ namespace rs2 int average_step_count = 20; int step_count = 20; int accuracy = 2; + int speed = 3; bool tare = false; void calibrate(); @@ -68,7 +65,6 @@ namespace rs2 void process_flow(std::function cleanup, invoker invoke) override; float _health = 0.f; - int _speed = 4; device _dev; bool _was_streaming = false; @@ -101,6 +97,7 @@ namespace rs2 RS2_CALIB_STATE_CALIB_IN_PROCESS,// Calibration in process... Shows progressbar RS2_CALIB_STATE_CALIB_COMPLETE, // Calibration complete, show before/after toggle and metrics RS2_CALIB_STATE_TARE_INPUT, // Collect input parameters for Tare calib + RS2_CALIB_STATE_SELF_INPUT, // Collect input parameters for Self calib }; autocalib_notification_model(std::string name, diff --git a/common/viewer.cpp b/common/viewer.cpp index ec6834a995..cee47a57d1 100644 --- a/common/viewer.cpp +++ b/common/viewer.cpp @@ -1684,11 +1684,7 @@ namespace rs2 ImGui::PushFont(window.get_large_font()); ImGui::PushStyleColor(ImGuiCol_Border, black); - int buttons = window.is_fullscreen() ? 5 : 4; - - ImGui::SetCursorPosX(window.width() - panel_width - panel_y * (buttons - 2)); - not_model.draw_snoozed_button(); - ImGui::SameLine(); + int buttons = window.is_fullscreen() ? 4 : 3; ImGui::SetCursorPosX(window.width() - panel_width - panel_y * (buttons)); ImGui::PushStyleColor(ImGuiCol_Text, is_3d_view ? light_grey : light_blue); @@ -1716,7 +1712,7 @@ namespace rs2 ImGui::PopStyleColor(2); ImGui::SameLine(); - ImGui::SetCursorPosX(window.width() - panel_width - panel_y * (buttons - 3)); + ImGui::SetCursorPosX(window.width() - panel_width - panel_y * (buttons - 2)); static bool settings_open = false; ImGui::PushStyleColor(ImGuiCol_Text, !settings_open ? light_grey : light_blue); From ba2f0071fac694895d9bc47768725e6e7d66d50f Mon Sep 17 00:00:00 2001 From: "Dorodnicov, Sergey" Date: Mon, 16 Sep 2019 05:12:24 -0700 Subject: [PATCH 18/20] Bump version --- include/librealsense2/rs.h | 2 +- package.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/librealsense2/rs.h b/include/librealsense2/rs.h index 461e2120c5..0b172c6949 100644 --- a/include/librealsense2/rs.h +++ b/include/librealsense2/rs.h @@ -24,7 +24,7 @@ extern "C" { #define RS2_API_MAJOR_VERSION 2 #define RS2_API_MINOR_VERSION 28 -#define RS2_API_PATCH_VERSION 0 +#define RS2_API_PATCH_VERSION 1 #define RS2_API_BUILD_VERSION 0 #ifndef STRINGIFY diff --git a/package.xml b/package.xml index 09e2eed6f5..6e42c46b83 100644 --- a/package.xml +++ b/package.xml @@ -7,7 +7,7 @@ librealsense2 - 2.28.0 + 2.28.1 Library for capturing data from the Intel(R) RealSense(TM) SR300, D400 Depth cameras and T2xx Tracking devices. This effort was initiated to better support researchers, creative coders, and app developers in domains such as robotics, virtual reality, and the internet of things. Several often-requested features of RealSense(TM); devices are implemented in this project. From dd95cfe5f94c0f3a690255ead254acae52a49441 Mon Sep 17 00:00:00 2001 From: aangerma Date: Mon, 16 Sep 2019 15:23:29 +0300 Subject: [PATCH 19/20] Added support on distortion on L500 RGB --- src/l500/l500-color.h | 12 ++++++++++++ src/l500/l500-private.h | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/l500/l500-color.h b/src/l500/l500-color.h index 26204309ca..4977d1f5db 100644 --- a/src/l500/l500-color.h +++ b/src/l500/l500-color.h @@ -67,6 +67,18 @@ namespace librealsense intrinsics.fy = model.ipm.focal_length.y; intrinsics.ppx = model.ipm.principal_point.x; intrinsics.ppy = model.ipm.principal_point.y; + + if (model.distort.radial_k1 || model.distort.radial_k2 || model.distort.tangential_p1 || model.distort.tangential_p2 || model.distort.radial_k3) + { + intrinsics.coeffs[0] = model.distort.radial_k1; + intrinsics.coeffs[1] = model.distort.radial_k2; + intrinsics.coeffs[2] = model.distort.tangential_p1; + intrinsics.coeffs[3] = model.distort.tangential_p2; + intrinsics.coeffs[4] = model.distort.radial_k3; + + intrinsics.model = RS2_DISTORTION_INVERSE_BROWN_CONRADY; + } + return intrinsics; } } diff --git a/src/l500/l500-private.h b/src/l500/l500-private.h index 70b7a533b6..f717494e23 100644 --- a/src/l500/l500-private.h +++ b/src/l500/l500-private.h @@ -108,8 +108,8 @@ namespace librealsense float radial_k1; float radial_k2; float tangential_p1; - float radial_k3; float tangential_p2; + float radial_k3; }; struct pinhole_camera_model From ce53f6e9e19e1bb4d349f94ea0424e8f0fde6673 Mon Sep 17 00:00:00 2001 From: "Dorodnicov, Sergey" Date: Mon, 16 Sep 2019 05:31:59 -0700 Subject: [PATCH 20/20] Disable recommended version for the SR300 family --- common/fw-update-helper.cpp | 12 ++++++------ common/fw-update-helper.h | 2 +- common/model-views.cpp | 4 +--- src/ivcam/sr300.cpp | 4 ++-- 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/common/fw-update-helper.cpp b/common/fw-update-helper.cpp index f43a1fb7b2..d13e700c91 100644 --- a/common/fw-update-helper.cpp +++ b/common/fw-update-helper.cpp @@ -38,9 +38,11 @@ namespace rs2 RS2_FWU_STATE_FAILED = 3, }; - bool is_recommended_fw_available() + bool is_recommended_fw_available(std::string id) { - return !(strcmp("", FW_D4XX_FW_IMAGE_VERSION) == 0); + auto pl = parse_product_line(id); + auto fv = get_available_firmware_version(pl); + return !(fv == ""); } int parse_product_line(std::string id) @@ -56,8 +58,6 @@ namespace rs2 if (product_line == RS2_PRODUCT_LINE_D400 && allow_rc_firmware) return FW_D4XX_RC_IMAGE_VERSION; else if (product_line == RS2_PRODUCT_LINE_D400) return FW_D4XX_FW_IMAGE_VERSION; - // NOTE: For now removing recommended firmware version for SR30x series - // TODO: Re-enable in future release //else if (product_line == RS2_PRODUCT_LINE_SR300) return FW_SR3XX_FW_IMAGE_VERSION; else return ""; } @@ -439,7 +439,7 @@ namespace rs2 void fw_update_notification_model::draw_expanded(ux_window& win, std::string& error_message) { - if (update_manager->started() && update_state == RS2_FWU_STATE_INITIAL_PROMPT) + if (update_manager->started() && update_state == RS2_FWU_STATE_INITIAL_PROMPT) update_state = RS2_FWU_STATE_IN_PROGRESS; auto flags = ImGuiWindowFlags_NoResize | @@ -550,4 +550,4 @@ namespace rs2 pinned = true; } -} +} \ No newline at end of file diff --git a/common/fw-update-helper.h b/common/fw-update-helper.h index d5e0b06a60..e71f6c8081 100644 --- a/common/fw-update-helper.h +++ b/common/fw-update-helper.h @@ -12,7 +12,7 @@ namespace rs2 std::map> create_default_fw_table(); std::vector parse_fw_version(const std::string& fw); bool is_upgradeable(const std::string& curr, const std::string& available); - bool is_recommended_fw_available(); + bool is_recommended_fw_available(std::string version); class firmware_update_manager : public process_manager { diff --git a/common/model-views.cpp b/common/model-views.cpp index d42b68962f..71615ccfe3 100644 --- a/common/model-views.cpp +++ b/common/model-views.cpp @@ -4328,9 +4328,7 @@ namespace rs2 if (ImGui::IsItemHovered()) ImGui::SetTooltip("Install official signed firmware from file to the device"); - if (is_recommended_fw_available() && - ((dev.supports(RS2_CAMERA_INFO_PRODUCT_LINE)) || - (dev.query_sensors().size() && dev.query_sensors().front().supports(RS2_CAMERA_INFO_PRODUCT_LINE)))) + if (dev.supports(RS2_CAMERA_INFO_PRODUCT_LINE) && is_recommended_fw_available(dev.get_info(RS2_CAMERA_INFO_PRODUCT_LINE))) { if (ImGui::Selectable("Install Recommended Firmware ")) { diff --git a/src/ivcam/sr300.cpp b/src/ivcam/sr300.cpp index 9a55c09a05..b1f2fddfd5 100644 --- a/src/ivcam/sr300.cpp +++ b/src/ivcam/sr300.cpp @@ -281,7 +281,7 @@ namespace librealsense enable_timestamp(true, true); auto pid_hex_str = hexify(color.pid); - auto recommended_fw_version = firmware_version(SR3XX_RECOMMENDED_FIRMWARE_VERSION); + //auto recommended_fw_version = firmware_version(SR3XX_RECOMMENDED_FIRMWARE_VERSION); register_info(RS2_CAMERA_INFO_NAME, device_name); register_info(RS2_CAMERA_INFO_SERIAL_NUMBER, serial); @@ -292,7 +292,7 @@ namespace librealsense register_info(RS2_CAMERA_INFO_PRODUCT_ID, pid_hex_str); register_info(RS2_CAMERA_INFO_PRODUCT_LINE, "SR300"); register_info(RS2_CAMERA_INFO_CAMERA_LOCKED, _is_locked ? "YES" : "NO"); - register_info(RS2_CAMERA_INFO_RECOMMENDED_FIRMWARE_VERSION, recommended_fw_version); + //register_info(RS2_CAMERA_INFO_RECOMMENDED_FIRMWARE_VERSION, recommended_fw_version); register_autorange_options();