ds: split fw_cmd per family + add AE_ACCEL_PARAMS = 0x95 opcode#15382
ds: split fw_cmd per family + add AE_ACCEL_PARAMS = 0x95 opcode#15382remibettan wants to merge 14 commits into
Conversation
sysrsbuild-gh-agentic
left a comment
There was a problem hiding this comment.
Auto-generated review by rs-agentic bot
Overall the enum-split design is clean and the rationale is well-documented. The C++ refactor looks correct. Unscoped enums in namespace ds mean existing call sites (ds::GLD, ds::SAFETY_PRESET_WRITE, etc.) continue to resolve without changes. A few bugs and enhancement notes are called out inline below.
Summary of findings:
- BUG (critical):
device.as_debug_protocol()can returnNone- no null-check before use. - BUG:
send_and_receive_raw_dataexceptions are unhandled inget_params/set_params. - Concern:
CALIBRESTOREEPROM = 0xA8left in sharedds::fw_cmdneeds confirmation it is genuinely dual-family. - Enhancement:
uint8_topcode erasure inemitter_always_on_option. - Enhancement: Missing FW-version guard and D415/product-line validation in Python utility.
- Enhancement:
d400_fw_cmd2str/d500_fw_cmd2strappear unused. - Tests: No unit or integration tests added for the enum split or the new AE_ACCEL_PARAMS command.
8c1556e to
e7c7cf1
Compare
ae8cfc5 to
81e078d
Compare
The shared enum in ds-private.h had grown to include opcodes only ever used by one family (SAFETY_PRESET_*, HKR_*, APM_STROBE_*, RGB_TNR, GET_FW_LOGS, SET/GET_CALIB_MODE/STATUS on d500; GLD, GET/SETINTCAL*, CALIBRECALC, ASIC_TEMP_MIPI, GET/SETAELIMITS on d400), and the two families are starting to compete for opcode numbers. Move d400-only opcodes to ds::d400_fw_cmd in d400-private.h and d500-only opcodes to ds::d500_fw_cmd in d500-private.h. Keep genuinely-shared opcodes in ds::fw_cmd. Because these are unscoped enums all living in the ds namespace, existing `ds::GLD`, `ds::SAFETY_PRESET_WRITE`, etc. references resolve unchanged; only a handful of type-qualified `fw_cmd::X` call sites needed updating. emitter_always_on_option was taking ds::fw_cmd, but its call sites now pass opcodes from either the shared or the d500 enum. Switched its ctor + fields to uint8_t (the actual HWM byte), which composes with any of the three enums via implicit underlying-type conversion. Frees opcode 0x95 on the d400 side (currently d500's SAFETY_PRESET_WRITE), which is the prerequisite for AE_ACCEL_PARAMS = 0x95 in a follow-up commit. Tracked by: RSDSO-21571 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Register the AE_ACCEL_PARAMS opcode from RSDSO-21571 in ds::d400_fw_cmd so terminal HWM commands can address it. The FW-side handler (get/set of the 7 float tuning parameters, per-SKU defaults, setpoint/deadband clamping, stream-guard NACK, IEEE-754 encoding) lives in RSDSO-21570 and is not part of this change. No SDK-visible RS2_OPTION is added: the tuning parameters are intended for terminal + engineering use only, and must not appear in the viewer UI. Tracked by: RSDSO-21571 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Two follow-ups to the previous enum split commit:
- d500-options.cpp used ds::RGB_TNR and ds::HKR_THERMAL_COMPENSATION but
only included d500-options.h, which didn't transitively include the new
d500-private.h where those enumerators now live. Added the include.
- d400-auto-calibration.cpp had a local `fw_cmd cmd{}` that then gets
assigned SETINTCAL / SETINTCALNEW — both are now d400_fw_cmd, and
unscoped enum types don't cross-convert. Retyped the local as
d400_fw_cmd; it composes with `command(cmd, ...)` unchanged since the
command constructor takes uint8_t.
Tracked by: RSDSO-21571
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Terminal-only GET/SET helper for AE_ACCEL_PARAMS (opcode 0x95). Handles the 7-float IEEE-754 payload documented in RSDSO-21571 and the writable- vs-read-only field distinction (5 R/W + 2 R-only). Ranges from the ticket table are validated client-side before dispatch. The GET/SET wire protocol (param1=0 for GET, param1=1 with 5-float body for SET) is inferred from the ticket and needs confirmation once FW-side RSDSO-21570 lands. The script prints raw response bytes on failure so mismatches surface quickly. Tracked by: RSDSO-21571 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Two follow-ups from PR review: - CALIBRESTOREEPROM (0xA8, "HKR Store EEPROM Calibration") was left in the shared enum but has no call sites and its name is HKR/d500-specific. Moving it to d500_fw_cmd completes the split cleanly. - The uint8_t retype on emitter_always_on_option's opcode fields loses compile-time enum typing. Added a comment explaining why it's necessary: the class is instantiated with opcodes from more than one family enum (ds::LASERONCONST vs d500_fw_cmd::APM_STROBE_*), and unscoped enums don't cross-convert. Raw byte is what the HWM actually stores. Tracked by: RSDSO-21571 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…nd errors Addresses PR review comments: - D400 product-line guard: on D500 opcode 0x95 is SAFETY_PRESET_WRITE, so running this against a D500 could be destructive. Refuse to proceed unless product_line == "D400". - FW-version guard: bail out below 5.17.3.20 with a clear message pointing at RSDSO-21358 instead of letting the FW NACK. - as_debug_protocol() null-check: prints a human-readable message instead of AttributeError. - GET/SET try/except: convert raw C++ tracebacks into a single sys.exit line. SET's failure path now short-circuits before the re-GET so the "After SET" table can no longer echo the pre-SET values on a NACK. Tracked by: RSDSO-21571 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Live-device test covering the RSDSO-21571 acceptance criteria: - GET returns 7 IEEE-754 floats, each within the ticket-documented range. - SET applies the 5 writable fields and leaves score_low_th / score_high_th recomputed by FW as setpoint +/- deadband/2. - Setpoint / deadband clamping (ported from D457) keeps score_low_th >= 0.08 and score_high_th <= 0.45 even when the input would push them out. - SET while depth is streaming is NACK'd and values do not move. - Sanity check that no RS2_OPTION_* was accidentally registered (this is a terminal-only HWM per the ticket, no viewer UI). Marked pytest.mark.skip until RSDSO-21570 FW ships, following the pattern already used by pytest-depth-ae-toggle.py / pytest-depth-ae-metadata.py. D415 family is skipped in-fixture since Accelerated AE is unsupported there. Tracked by: RSDSO-21571 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…ofile Follow-up to PR review: the streaming test grabbed the first depth-stream profile via a bare `next(...)` generator, which raises StopIteration (surfaced by pytest as ERROR rather than SKIP) on any D400* variant whose first depth sensor exposes only IR or confidence streams. Use `next(..., None)` with a `pytest.skip(...)` fallback so unusual sensor configurations get a clean skip instead of a red-error. Tracked by: RSDSO-21571 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Ticket IDs belong in commit messages and PR descriptions, not in inline source comments (they rot as tickets get closed or the codebase evolves). Removed the ticket markers from three files touched by this PR: - src/ds/d400/d400-private.h (AE_ACCEL_PARAMS enum comment) - wrappers/python/examples/ae_accel_params.py (header + FW-gate message + argparse description) - unit-tests/live/d400/pytest-ae-accel-params.py (header + MIN_FW comment + skip reason) Tracked by: RSDSO-21571 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
81e078d to
ffe5b2c
Compare
| register_info(RS2_CAMERA_INFO_FIRMWARE_VERSION, _fw_version); | ||
| register_info(RS2_CAMERA_INFO_PHYSICAL_PORT, group.uvc_devices.front().device_path); | ||
| register_info(RS2_CAMERA_INFO_DEBUG_OP_CODE, std::to_string(static_cast<int>(fw_cmd::GLD))); | ||
| register_info(RS2_CAMERA_INFO_DEBUG_OP_CODE, std::to_string(static_cast<int>(ds::GLD))); |
There was a problem hiding this comment.
What is DEBUG_OP_CODE and why we want to change the enum to a global one?
There was a problem hiding this comment.
DEBUG_OP_CODE is the HWM opcode we report via RS2_CAMERA_INFO_DEBUG_OP_CODE so external tools (rs-terminal / rs-fw-logger) can pull FW flash logs from the device. On D400 that means GLD (0x0f) - legacy flash-logs command. On D500 the equivalent is GET_FW_LOGS (0xB4).
The enum was not made global - the opposite: GLD moved into the new per-family d400_fw_cmd enum (D400-only opcode). I've now scoped the reference explicitly as d400_fw_cmd::GLD instead of the bare ds::GLD in c7a4b58, matching your other comments in this PR.
| register_info(RS2_CAMERA_INFO_FIRMWARE_VERSION, gvd_parsed_fields.fw_version); | ||
| register_info(RS2_CAMERA_INFO_PHYSICAL_PORT, group.uvc_devices.front().device_path); | ||
| register_info(RS2_CAMERA_INFO_DEBUG_OP_CODE, std::to_string(static_cast<int>(fw_cmd::GET_FW_LOGS))); | ||
| register_info(RS2_CAMERA_INFO_DEBUG_OP_CODE, std::to_string(static_cast<int>(ds::GET_FW_LOGS))); |
There was a problem hiding this comment.
lets try to scope it under a dedicated common enum and not right after ds
| switch( cmd.cmd) | ||
| { | ||
| case ds::fw_cmd::GET_HKR_CONFIG_TABLE: | ||
| case ds::GET_HKR_CONFIG_TABLE: |
There was a problem hiding this comment.
same all over, lets scope it
| @@ -0,0 +1,169 @@ | |||
| # License: Apache 2.0. See LICENSE file in root directory. | |||
There was a problem hiding this comment.
lets place example and test in the Jira ticket for Algo to run and remove from the PR
| @@ -0,0 +1,177 @@ | |||
| # License: Apache 2.0. See LICENSE file in root directory. | |||
sysrsbuild-gh-agentic
left a comment
There was a problem hiding this comment.
Auto-generated review by rs-agentic bot — commit c7a4b58d14e
Reviewed the new push: "ds: scope HWM opcode call sites under their per-family enum" (18 lines, 5 files).
This commit adds explicit per-family enum scoping to all HWM opcode call sites in response to @Nir-Az's review:
| File | Change |
|---|---|
d400-device.cpp |
fw_cmd::GLD → d400_fw_cmd::GLD ✅ |
d500-active.cpp |
APM_STROBE_GET/SET → d500_fw_cmd::APM_STROBE_GET/SET, LASERONCONST → fw_cmd::LASERONCONST ✅ |
d500-device.cpp |
fw_cmd::GET_FW_LOGS → d500_fw_cmd::GET_FW_LOGS ✅ |
d500-options.cpp |
ds::fw_cmd::HKR_THERMAL_COMPENSATION → ds::d500_fw_cmd::HKR_THERMAL_COMPENSATION ✅ |
hw_monitor_extended_buffers.cpp |
ds::fw_cmd::GET_HKR_CONFIG_TABLE/SET_HKR_CONFIG_TABLE → ds::d500_fw_cmd::* ✅ |
No bugs found in the new commit. The scoping changes are consistent and correct across all affected call sites. All previously flagged issues from prior reviews remain resolved.
⚠️ Note: @Nir-Az's open request to move the Python example (ae_accel_params.py) and pytest file to the Jira ticket and remove them from this PR is still unaddressed.
Tracked by: RSDSO-21571
Overview
Part 2 of RSDSO-21571 (part 1: #15381 for the viewer-side Depth AE mode toggle). This PR sets up the LibRS-side plumbing for the new
AE_ACCEL_PARAMS = 0x95Hardware-Monitor command described in the ticket, so the FW-side implementation (RSDSO-21570) can be exercised end-to-end from terminal/Python. No new RS2_OPTION is added — the tuning parameters are engineering-only and must not appear in the viewer UI.Why the enum split
Ticket calls for
AE_ACCEL_PARAMS = 0x95. That opcode was alreadySAFETY_PRESET_WRITEin the sharedds::fw_cmdenum (src/ds/ds-private.h). Since the two families are diverging and the shared enum was already accumulating single-family opcodes, this PR does the split cleanly rather than picking a workaround opcode number.ds::fw_cmd(ds/ds-private.h) — shrunk to genuinely-shared opcodes (flash ops, GVD, DFU/HWRST, GTEMP, advanced-mode, ROI, cam-sync, pwm, subpreset, LASERONCONST, AUTO_CALIB, MMER, RECPARAMSGET, CAL_RESTORE_DFLT).ds::d400_fw_cmd(ds/d400/d400-private.h) — d400-only:GLD,GETINTCAL,SETINTCAL,CALIBRECALC,SETINTCALNEW,ASIC_TEMP_MIPI,GETAELIMITS,SETAELIMITS, plus the newAE_ACCEL_PARAMS = 0x95.ds::d500_fw_cmd(ds/d500/d500-private.h) — d500-only:HKR_THERMAL_COMPENSATION,SAFETY_PRESET_READ,SAFETY_PRESET_WRITE,APM_STROBE_SET/GET,SET/GET_HKR_CONFIG_TABLE,RGB_TNR,GET_FW_LOGS,SET_CALIB_MODE,GET_CALIB_STATUS.Because all three enums live in
namespace dsand are unscoped, existingds::GLD/ds::SAFETY_PRESET_WRITE/ etc. call sites resolve unchanged. Only a handful of type-qualifiedfw_cmd::Xreferences needed updating (d400-device.cpp,d500-device.cpp,d500-options.cpp,hw_monitor_extended_buffers.cpp).emitter_always_on_optionwas retyped fromds::fw_cmdtouint8_t— its callers now pass a mix of shared-family and d500-family opcodes, and enum-to-enum doesn't cross-convert;uint8_tmatches whatcommand::cmdactually stores anyway.Commits
9e526154f— split enum329f1d60c— addAE_ACCEL_PARAMS = 0x95e880ec261— build fix (missing include + one local-var retype)58de51839—wrappers/python/examples/ae_accel_params.pyGET/SET utilityPython utility
wrappers/python/examples/ae_accel_params.py— terminal-only helper that callsdebug_protocol.build_command+send_and_receive_raw_datafor the 7 float fields. Ranges from the ticket table are validated client-side.Wire convention assumed (per ticket, needs RSDSO-21570 confirmation):
param1 = 0, no payload → response has 7 IEEE-754 floats after the 4-byte opcode echo.param1 = 1, payload = 5 IEEE-754 floats (score_setpoint,score_deadband,saturation_weight,saturation_value,stability_factor).score_low_th/score_high_thare recomputed by FW.Test plan
realsense2andpyrealsense2compile clean (done locally on Win/x64/Release).ae_accel_params.pyon D405/D435 to GET+SET.