Skip to content

Commit 9783092

Browse files
Evgeni Raikhelclaude
andcommitted
Register HKR MinZ Control as a composite option, consolidating off the scalar path
Registers RS2_COMPOSITE_OPTION_HKR_MINZ_CONTROL via composite_xu_option (ds::depth_xu, ds::DS5_HKR_MINZ_CONTROL = 0x14, sizeof(rs2_minz_control)) across every device constructor that used to register the scalar "Improved Close Range Depth" option: D555 (FW-gated), rs5x5_device and rs5x5_dedicated_color_device (unconditional), and left disabled on D585 GMSL for the same pre-existing MIPI/V4L2 backend limitation. Retires close_range_xu_option/d500_close_range_embedded_filter/close_range_filter_feature entirely (POC/demo PR - full consolidation onto the composite-option mechanism rather than keeping two independent accessors on one physical XU control). Known consequence: common/embedded-filter-model.cpp's generic RS2_OPTION_EMBEDDED_FILTER_ENABLED toggle no longer applies to this filter - not fixed, out of scope here. Also corrects rs_hkr_minz_control.h's ctl_id (0x0004 -> 0x0008) and flags (-> 0x01), sourced from the former close_range_xu_option implementation and a real-hardware FW validation tool rather than the Confluence page's stale wire-layout table. Adds examples/composite-option-walkthrough/rs-minz-control-walkthrough.cpp - enumerate/ get_range/get/set/get one at a time against a real connected device. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
1 parent f454c8b commit 9783092

15 files changed

Lines changed: 264 additions & 248 deletions

examples/composite-option-walkthrough/CMakeLists.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,13 @@ set_property(TARGET rs-composite-option-walkthrough PROPERTY CXX_STANDARD 14)
2121
target_link_libraries(rs-composite-option-walkthrough PRIVATE ${LRS_TARGET})
2222
set_target_properties (rs-composite-option-walkthrough PROPERTIES FOLDER Examples)
2323
install(TARGETS rs-composite-option-walkthrough RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
24+
25+
# PROTOTYPE / DEMO: HKR MinZ Control, one call at a time, against a REAL connected device (no
26+
# fake transport) - see rs-minz-control-walkthrough.cpp.
27+
add_executable(rs-minz-control-walkthrough
28+
rs-minz-control-walkthrough.cpp
29+
)
30+
set_property(TARGET rs-minz-control-walkthrough PROPERTY CXX_STANDARD 14)
31+
target_link_libraries(rs-minz-control-walkthrough PRIVATE ${LRS_TARGET})
32+
set_target_properties (rs-minz-control-walkthrough PROPERTIES FOLDER Examples)
33+
install(TARGETS rs-minz-control-walkthrough RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
// License: Apache 2.0. See LICENSE file in root directory.
2+
// Copyright(c) 2026 RealSense, Inc. All Rights Reserved.
3+
4+
// PROTOTYPE / DEMO - HKR MinZ Control, one call at a time, against a real connected device.
5+
// Requires a D555/D5xx with FW >= 7.58.39807.10573 (see minz_filter_feature's registration gate
6+
// in d500-factory.cpp). No fake transport here - this is the real depth sensor's real XU control.
7+
8+
#include <librealsense2/rs.hpp>
9+
10+
#include <algorithm>
11+
#include <cstring>
12+
#include <iostream>
13+
#include <stdexcept>
14+
15+
int main()
16+
try
17+
{
18+
rs2::context ctx;
19+
auto devices = ctx.query_devices();
20+
if( devices.size() == 0 )
21+
throw std::runtime_error( "no RealSense device connected" );
22+
23+
rs2::depth_sensor sensor = devices[0].first< rs2::depth_sensor >();
24+
const auto id = RS2_COMPOSITE_OPTION_HKR_MINZ_CONTROL;
25+
26+
// 1) Enumeration
27+
auto supported = sensor.get_supported_composite_options();
28+
bool has_minz = std::find( supported.begin(), supported.end(), id ) != supported.end();
29+
std::cout << "[1] MinZ control supported: " << ( has_minz ? "yes" : "no" ) << '\n';
30+
if( ! has_minz )
31+
return 0;
32+
33+
// 2) Get range (min/max/step/def), typed
34+
auto range = sensor.get_composite_option_range_as< rs2_minz_control_range >( id );
35+
std::cout << "[2] Range (version=" << range.version << "):\n"
36+
<< " enable: min=" << range.min.enable << " max=" << range.max.enable
37+
<< " step=" << range.step.enable << " def=" << range.def.enable << '\n'
38+
<< " downscale_ratio: min=" << range.min.downscale_ratio << " max=" << range.max.downscale_ratio
39+
<< " step=" << range.step.downscale_ratio << " def=" << range.def.downscale_ratio << '\n'
40+
<< " disparity_shift: min=" << range.min.disparity_shift << " max=" << range.max.disparity_shift
41+
<< " step=" << range.step.disparity_shift << " def=" << range.def.disparity_shift << '\n'
42+
<< " threshold: min=" << range.min.threshold << " max=" << range.max.threshold
43+
<< " step=" << range.step.threshold << " def=" << range.def.threshold << '\n'
44+
<< " threshold_mode: min=" << range.min.threshold_mode << " max=" << range.max.threshold_mode
45+
<< " step=" << range.step.threshold_mode << " def=" << range.def.threshold_mode << '\n';
46+
47+
// 3) Get current value, typed
48+
auto current = sensor.get_composite_option_as< rs2_minz_control >( id );
49+
std::cout << "[3] Current: enable=" << current.enable
50+
<< " downscale_ratio=" << current.downscale_ratio
51+
<< " disparity_shift=" << current.disparity_shift
52+
<< " threshold=" << current.threshold
53+
<< " threshold_mode=" << current.threshold_mode << '\n';
54+
55+
// 4) Set - read-modify-write so the wire header (version/flags/ctl_id/param_count/
56+
// param_type) is preserved exactly as the device reported it, not zero-initialized.
57+
rs2_minz_control cfg = current;
58+
cfg.enable = 1;
59+
cfg.downscale_ratio = 2;
60+
cfg.threshold = 500;
61+
cfg.threshold_mode = 1; // Manual
62+
sensor.set_composite_option_from( id, cfg );
63+
std::cout << "[4] Set: enable=1 downscale_ratio=2 threshold=500 threshold_mode=1 (Manual)\n";
64+
65+
// 5) Get again to confirm
66+
auto after = sensor.get_composite_option_as< rs2_minz_control >( id );
67+
std::cout << "[5] Readback: enable=" << after.enable
68+
<< " downscale_ratio=" << after.downscale_ratio
69+
<< " threshold=" << after.threshold
70+
<< " threshold_mode=" << after.threshold_mode << '\n';
71+
72+
return 0;
73+
}
74+
catch( const rs2::error & e )
75+
{
76+
std::cerr << "FAIL: librealsense error: " << e.what() << std::endl;
77+
return 1;
78+
}
79+
catch( const std::exception & e )
80+
{
81+
std::cerr << "FAIL: " << e.what() << std::endl;
82+
return 1;
83+
}

include/librealsense2/h/rs_hkr_minz_control.h

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,17 @@
1717
* Wire is little-endian; #pragma pack(1) is required because the header's odd 6-byte size would
1818
* otherwise leave the compiler inserting 2 bytes of padding before params[0].
1919
*
20+
* Header field values (version=0x01, flags=0x01, ctl_id=0x0008) were taken from the former
21+
* close_range_xu_option implementation (since removed - see below) and independently confirmed
22+
* against a real-hardware FW validation tool - NOT from the Confluence page's own wire-layout
23+
* table, which states ctl_id=0x0004 and is stale on that point.
24+
*
25+
* This control replaces what used to be exposed as the scalar, enable-only "Improved Close Range
26+
* Depth" option (RS2_OPTION_EMBEDDED_FILTER_ENABLED via close_range_xu_option) - both addressed
27+
* the SAME physical XU control (unit 3, selector 0x14). PROTOTYPE/DEMO PR: that scalar option has
28+
* been removed and consolidated onto this composite option, which exposes full read/write access
29+
* to all 5 fields instead of just enable.
30+
*
2031
* These structs exist purely so callers do not need to hand-roll and keep in sync their own copy
2132
* of the documented wire layout; the SDK does not expose any function named after them - cast the
2233
* raw bytes returned by rs2_get_composite_option/rs2_get_composite_option_range to/from these
@@ -43,7 +54,10 @@ typedef struct rs2_minz_control
4354
/* --- dppc_header: shared by the whole HKR DPP control family, not MinZ-specific --- */
4455
uint8_t version; /**< Wire struct version, per dppc_header. Currently 0x01 */
4556
uint8_t flags; /**< Bitwise control-status mask (active/read-only), per dppc_header */
46-
uint16_t ctl_id; /**< dpp_ctrl_list entry identifying this control. dpp_minz_filter = 0x0004 */
57+
uint16_t ctl_id; /**< dpp_ctrl_list entry identifying this control. dpp_minz_filter = 0x0008 -
58+
* confirmed against the FW validation tool and the existing
59+
* close_range_xu_option implementation; an earlier doc pass on this
60+
* file incorrectly said 0x0004. */
4761

4862
/* --- dppc_ctl parameter block header --- */
4963
uint8_t param_count; /**< Populated param slots below. 5 for MinZ */

src/ds/CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ target_sources(${LRS_TARGET}
4747
"${CMAKE_CURRENT_LIST_DIR}/features/gain-limit-feature.cpp"
4848
"${CMAKE_CURRENT_LIST_DIR}/features/gyro-sensitivity-feature.h"
4949
"${CMAKE_CURRENT_LIST_DIR}/features/gyro-sensitivity-feature.cpp"
50-
"${CMAKE_CURRENT_LIST_DIR}/features/close-range-filter-feature.h"
51-
"${CMAKE_CURRENT_LIST_DIR}/features/close-range-filter-feature.cpp"
5250
"${CMAKE_CURRENT_LIST_DIR}/features/temporal-filter-feature.h"
5351
"${CMAKE_CURRENT_LIST_DIR}/features/temporal-filter-feature.cpp"
52+
"${CMAKE_CURRENT_LIST_DIR}/features/minz-filter-feature.h"
53+
"${CMAKE_CURRENT_LIST_DIR}/features/minz-filter-feature.cpp"
5454
)

src/ds/d500/CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ target_sources(${LRS_TARGET}
1818
"${CMAKE_CURRENT_LIST_DIR}/d500-object-detection.cpp"
1919
"${CMAKE_CURRENT_LIST_DIR}/hw_monitor_extended_buffers.cpp"
2020
"${CMAKE_CURRENT_LIST_DIR}/d500-options.cpp"
21-
"${CMAKE_CURRENT_LIST_DIR}/d500-close-range-embedded-filter.cpp"
2221
"${CMAKE_CURRENT_LIST_DIR}/d500-temporal-embedded-filter.cpp"
22+
"${CMAKE_CURRENT_LIST_DIR}/d500-minz-embedded-filter.cpp"
2323
"${CMAKE_CURRENT_LIST_DIR}/d500-fw-update-device.cpp"
2424
"${CMAKE_CURRENT_LIST_DIR}/d500-auto-calibration.cpp"
2525
"${CMAKE_CURRENT_LIST_DIR}/d500-debug-protocol-calibration-engine.cpp"
@@ -34,8 +34,8 @@ target_sources(${LRS_TARGET}
3434
"${CMAKE_CURRENT_LIST_DIR}/d500-object-detection.h"
3535
"${CMAKE_CURRENT_LIST_DIR}/hw_monitor_extended_buffers.h"
3636
"${CMAKE_CURRENT_LIST_DIR}/d500-options.h"
37-
"${CMAKE_CURRENT_LIST_DIR}/d500-close-range-embedded-filter.h"
3837
"${CMAKE_CURRENT_LIST_DIR}/d500-temporal-embedded-filter.h"
38+
"${CMAKE_CURRENT_LIST_DIR}/d500-minz-embedded-filter.h"
3939
"${CMAKE_CURRENT_LIST_DIR}/d500-info.h"
4040
"${CMAKE_CURRENT_LIST_DIR}/d500-fw-update-device.h"
4141
"${CMAKE_CURRENT_LIST_DIR}/d500-auto-calibration.h"

src/ds/d500/d500-close-range-embedded-filter.cpp

Lines changed: 0 additions & 132 deletions
This file was deleted.

src/ds/d500/d500-close-range-embedded-filter.h

Lines changed: 0 additions & 47 deletions
This file was deleted.

0 commit comments

Comments
 (0)