Skip to content

Refactor chassis control for modularity, remove unused components#89

Open
ZGZ713912 wants to merge 24 commits into
deformable-infantryfrom
feat/deformable-infantry
Open

Refactor chassis control for modularity, remove unused components#89
ZGZ713912 wants to merge 24 commits into
deformable-infantryfrom
feat/deformable-infantry

Conversation

@ZGZ713912

@ZGZ713912 ZGZ713912 commented Jul 9, 2026

Copy link
Copy Markdown
Member

本次变更围绕“执行器框架 + 可变形底盘/云台 + 射击链路 + 硬件/配置适配”做了大规模重构与模块化替换,核心包括:

  • 执行器框架层:重构 rmcs_executor::Component/Executor 的接口模型与依赖绑定机制,引入接口类型(Normal/Event)、事件输入/输出与更严格的注册/冲突校验;更新输出配对的类型映射结构,并调整组件生命周期/销毁与事件收尾逻辑。
  • 通用工具与消息类型:新增/替换多种基础类型与工具(板载时钟 BoardClock、IMU 快照/相机原始帧结构、atomic_futexMemoryPoolPooledSharedFactory、环形缓冲可读快照视图/迭代器等),并包含较多格式与常量微调。
  • 可变形底盘控制链路
    • 引入 DeformableChassisModeManager 统一管理底盘模式与姿态目标生成;
    • 新增 DeformableSuspension 作为悬架计算组件(外/内环 PID、激活/参考角、角度限幅、误差/轨迹输出等);
    • DeformableJointController 支持可选的 setpoint_velocity 输入,速度可用时跳过 TD 生成逻辑;
    • 重构可变形全向轮控制器为数组化统一处理;
    • 删除旧实现 DeformableChassisController(旧的可变形轮控制/组件逻辑整体下线)。
  • 云台与自动瞄准
    • 云台解算器增加偏航限幅、根据期望方向设置控制量、并调整 Ctrl/模式切换与锁定逻辑;
    • gimbal_controller/相关控制参数引入重力前馈、移除俯仰融合相关参数;
    • bringup 中同步更新 yaw/pitch 控制与话题绑定。
  • 射击系统
    • 新增 Hero 系列射击控制插件:HeroFrictionWheelControllerHeroHeatControllerPutterController、以及更新/重写的 ShootingRecorder 统计与记录流程;
    • 移除旧“可调摩擦轮工作速度”逻辑与相关参数块,配套 bringup 配置删改。
  • 硬件层重构与新增
    • 新增/接入 FlightSteeringHeroLittle
    • 新增 IMU 融合链路(ImuEkfBmi088EkfBoardClockLifter)并改造 OmniInfantry 的时间基与 EKF 更新流程;
    • 对可变形步兵硬件实现进行大幅重构/下线旧插件(移除 DeformableInfantryV2,并调整步兵/全向硬件链路的板卡生命周期与 TF/状态发布)。
  • bringup/启动与配置
    • 大量 YAML 配置更新:组件映射、串口过滤、悬架/姿态几何与 PID 分组、关节控制器加入 setpoint_velocity、以及控制器参数删改;
    • rmcs.launch.py 移除在 robot 配置 auto.* 时自动包含 rmcs_auto_aim_v2 的逻辑;
    • 新增/替换 flight/steering-hero/steering-hero-little 等配置文件,并删除若干旧配置条目;
    • 更新 .script/template/entrypoint:尝试读取并写入 usbcore/usbfs_memory_mb(带容错 Warning 逻辑),其余启动保持不变。
  • 插件注册清单与 UI
    • 更新 rmcs_core/plugins.xml:新增/替换底盘与射击链路插件注册,移除部分旧组件;
    • 新增 Flight UI,重构 Hero/Deformable UI(输入话题、可见性开关、状态环逻辑等调整)。

ZGZ713912 and others added 20 commits July 3, 2026 16:17
- Consolidated joint input and output registration in deformable_chassis.cpp and deformable_wheel_controller.cpp using loops and arrays to reduce redundancy.
- Removed unused PID control structures and related parameters in deformable_chassis.cpp to simplify the class.
- Updated input and output handling for joint states to utilize arrays, improving scalability for future joint additions.
- Enhanced readability by using fmt library for formatted string outputs in input/output registration.
- Cleaned up unnecessary variables and methods related to IMU calibration and attitude correction in deformable_chassis.cpp.
- Updated the configuration for the deformable infantry steering to correct serial filter values.
- Refactored the chassis control code to remove unnecessary scope motor control logic and related variables.
- Simplified the hardware implementation by removing the IMU board and adjusting the top and bottom board initializations accordingly.
- Enhanced the handling of gimbal pitch and yaw velocity calculations using separate BMI088 instances for better clarity and maintainability.
- Updated CAN communication logic to accommodate the removal of the scope motor and streamline data transmission.
Reset the yaw loops only on ctrl-hold state transitions so yaw hold can keep producing torque while active. Remove stale hard-sync and duplicate BMI088 config paths across deformable infantry variants to match the single IMU pipeline.
…d remove ctrl-hold yaw lock

- Delete standalone ActiveSuspensionController component
- Restore active suspension logic (AttitudePidAxis, IMU calibration, joint I/O) inside DeformableChassis
- Remove ctrl-hold yaw lock from both chassis angular-velocity override and gimbal PID lock
- Gimbal yaw now follows normal solver path during ctrl-hold, pitch remains locked to level
- Simplify configs: remove active_suspension_controller section, restore single-loop PID params
This commit deletes the DeformableChassisController class implementation from the deformable_wheel_controller.cpp file. The removal includes all associated methods, member variables, and dependencies, streamlining the codebase by eliminating unused components.
- Removed the entire deformable infantry steering implementation as it is no longer needed.
- Updated the deformable infantry UI to use a loop for registering wheel velocities and joint physical angles, improving code maintainability.
- Introduced `kWheelName` static array to avoid repetition and enhance clarity in the UI input registration.
- Enhanced the update logic for deformable chassis leg arcs to use a more concise approach for checking readiness of joint angles.
commit 1e99fd9
Author: Zihan Qin <zihanqin2048@gmail.com>
Date:   Fri Jun 12 11:48:28 2026 +0800

    feat: Add event interfaces and board-clocked IMU pipeline (#83)

    This commit lays the groundwork for upcoming IMU-camera hardware synchronization.

    - Add event input/output support to rmcs_executor
    - Add board clock, IMU snapshot, and raw camera frame message types
    - Integrate board-timestamped BMI088 EKF outputs in OmniInfantry
    - Add utility primitives used by the sync pipeline

    Known limitation:
    - OmniInfantry does not preserve the old BMI088 body-to-sensor mapping. This is intentional because that platform is retired and its original mechanical layout no longer exists. It is kept only as the remaining single-board hardware target for sync pipeline testing, so preserving its legacy IMU axis alignment is no longer necessary.

commit c0ab658
Author: Zihan Qin <zihanqin2048@gmail.com>
Date:   Wed Jun 10 18:00:35 2026 +0800

    feat: Fold climbable-infantry into maintained steering-infantry (#82)

    - Convert the active climbable-infantry line into the maintained steering-infantry variant. Remove the stair-climbing control chain and dedicated climber motors, revert the temporary VT13 / merged-remote stack back to pure DR16, and rename the cleaned result back to steering-infantry because the historical steering-infantry is no longer maintained.
    - Update SteeringInfantry to the rmcs-board-lite split top/bottom board path and refresh its bringup config for the current robot. Also restore the original /gimbal/calibrate and /steers/calibrate semantics, remove the temporary yaw watchdog path, make pitch control explicitly use LK velocity commands, and recover accidentally removed mainline content while keeping only the required steering-infantry merge delta.

    Update librmcs from v3.2.0b0 to v3.2.0 for the required board-lite SDK.

    Co-authored-by: Palejoker <2797572751@qq.com>
    Co-authored-by: Fin_Resect <chenchengyue201@126.com>

commit b5ae6cb
Author: Zihan Qin <zihanqin2048@gmail.com>
Date:   Tue Jun 9 22:20:27 2026 +0800

    feat: Integrate steering-hero support (#80)

    Add support for steering-hero and steering-hero-little, including hardware drivers, chassis control, gimbal control, shooting control, Hero UI integration, corresponding bringup configs, and plugin registration.

    Also correct LK motor torque constants:
    - kMG5010Ei10: 0.90909 -> 0.1
    - kMG6012Ei8: 1.09 -> 1.09 / 8.0

    To keep mainline vehicle control output unchanged, also retune:
    - omni-infantry yaw velocity PID parameters
    - sentry bottom yaw velocity PID / viscous FF parameters

    Also remove the unmaintained mecanum-hero config.

    Known issues (not blocking this merge):
    - The Hero UI shooter condition / state_word path is still leftover debug wiring and is not connected to the current active runtime path
    - HeroFrictionWheelController still preserves the historical friction-wheel index convention; for now this is only documented with a TODO and should later be replaced by an explicit first-stage mapping
    - steering-hero-little still has a mismatch between PlayerViewer limit parameters and control logic, which requires follow-up calibration
    - HeroChassisPowerController inherits the existing ChassisPowerController risk of reading uninitialized members / propagating non-finite values; this is a pre-existing shared issue, not newly introduced by this merge
    - steering-hero-little uses different vehicle_radius values in steering_wheel_status and steering_wheel_controller
    - HeroFrictionWheelController does not clear its jam fault counter after recovery, and Ctrl+F currently triggers a double profile toggle
    - PutterController does not reset putter_timeout_count_ during normal stage transitions
    - ChassisClimberController repeatedly resets back_climber_recover_count during auto-climb
    - The Hero UI Ctrl+E bottom-yaw tracking toggle is currently level-triggered, so holding the keys causes repeated flipping

    Co-authored-by: floatpigeon <floatpigeon@proton.me>
    Co-authored-by: dwx5 <1591215786@qq.com>
    Co-authored-by: zhzy-star <2807406212@qq.com>

commit 8407c1d
Author: qzhhhi <zihanqin2048@gmail.com>
Date:   Sat May 30 23:17:41 2026 +0800

    style: Apply clang-format across all C++ source files
commit 2c63c7d
Author: creeper5820 <131014151+creeper5820@users.noreply.github.com>
Date:   Tue Jul 7 00:03:30 2026 +0800

    feat: Integrate flight support (#85)

    - Add flight.yaml parameter config for Flight hardware, gimbal, friction wheels, feeder, referee interaction, auto-aim, and odin_ros_driver.
    - Add rmcs_core::hardware::Flight hardware plugin supporting flight controller, IMU, remote control, CAN/UART comms, TF, and referee serial.
    - Add rmcs_core::referee::app::ui::Flight UI plugin for ammo, friction wheel status, and auto-aim mode display.
    - Replace/add Flight-related hardware, controller, and UI components in plugin registry; remove some legacy chassis/controller registrations.
    - Add auto-aim toggle, yaw limit support, and direction clamping based on current angle to gimbal control.
    - Switch shooting control to /auto_aim/should_shoot input and refine auto/manual shooting logic.
    - Add kMHF7015 motor type support.
    - Add supercap/battery display toggle to StatusRing.
    - Minor CMake, description file, and export formatting/cleanup.

    Co-authored-by: heyeuu <2829004293@qq.com>
    Co-authored-by: zlq040222 <1542498005@qq.com>

commit 1e99fd9
Author: Zihan Qin <zihanqin2048@gmail.com>
Date:   Fri Jun 12 11:48:28 2026 +0800

    feat: Add event interfaces and board-clocked IMU pipeline (#83)

    This commit lays the groundwork for upcoming IMU-camera hardware synchronization.

    - Add event input/output support to rmcs_executor
    - Add board clock, IMU snapshot, and raw camera frame message types
    - Integrate board-timestamped BMI088 EKF outputs in OmniInfantry
    - Add utility primitives used by the sync pipeline

    Known limitation:
    - OmniInfantry does not preserve the old BMI088 body-to-sensor mapping. This is intentional because that platform is retired and its original mechanical layout no longer exists. It is kept only as the remaining single-board hardware target for sync pipeline testing, so preserving its legacy IMU axis alignment is no longer necessary.

commit c0ab658
Author: Zihan Qin <zihanqin2048@gmail.com>
Date:   Wed Jun 10 18:00:35 2026 +0800

    feat: Fold climbable-infantry into maintained steering-infantry (#82)

    - Convert the active climbable-infantry line into the maintained steering-infantry variant. Remove the stair-climbing control chain and dedicated climber motors, revert the temporary VT13 / merged-remote stack back to pure DR16, and rename the cleaned result back to steering-infantry because the historical steering-infantry is no longer maintained.
    - Update SteeringInfantry to the rmcs-board-lite split top/bottom board path and refresh its bringup config for the current robot. Also restore the original /gimbal/calibrate and /steers/calibrate semantics, remove the temporary yaw watchdog path, make pitch control explicitly use LK velocity commands, and recover accidentally removed mainline content while keeping only the required steering-infantry merge delta.

    Update librmcs from v3.2.0b0 to v3.2.0 for the required board-lite SDK.

    Co-authored-by: Palejoker <2797572751@qq.com>
    Co-authored-by: Fin_Resect <chenchengyue201@126.com>

commit b5ae6cb
Author: Zihan Qin <zihanqin2048@gmail.com>
Date:   Tue Jun 9 22:20:27 2026 +0800

    feat: Integrate steering-hero support (#80)

    Add support for steering-hero and steering-hero-little, including hardware drivers, chassis control, gimbal control, shooting control, Hero UI integration, corresponding bringup configs, and plugin registration.

    Also correct LK motor torque constants:
    - kMG5010Ei10: 0.90909 -> 0.1
    - kMG6012Ei8: 1.09 -> 1.09 / 8.0

    To keep mainline vehicle control output unchanged, also retune:
    - omni-infantry yaw velocity PID parameters
    - sentry bottom yaw velocity PID / viscous FF parameters

    Also remove the unmaintained mecanum-hero config.

    Known issues (not blocking this merge):
    - The Hero UI shooter condition / state_word path is still leftover debug wiring and is not connected to the current active runtime path
    - HeroFrictionWheelController still preserves the historical friction-wheel index convention; for now this is only documented with a TODO and should later be replaced by an explicit first-stage mapping
    - steering-hero-little still has a mismatch between PlayerViewer limit parameters and control logic, which requires follow-up calibration
    - HeroChassisPowerController inherits the existing ChassisPowerController risk of reading uninitialized members / propagating non-finite values; this is a pre-existing shared issue, not newly introduced by this merge
    - steering-hero-little uses different vehicle_radius values in steering_wheel_status and steering_wheel_controller
    - HeroFrictionWheelController does not clear its jam fault counter after recovery, and Ctrl+F currently triggers a double profile toggle
    - PutterController does not reset putter_timeout_count_ during normal stage transitions
    - ChassisClimberController repeatedly resets back_climber_recover_count during auto-climb
    - The Hero UI Ctrl+E bottom-yaw tracking toggle is currently level-triggered, so holding the keys causes repeated flipping

    Co-authored-by: floatpigeon <floatpigeon@proton.me>
    Co-authored-by: dwx5 <1591215786@qq.com>
    Co-authored-by: zhzy-star <2807406212@qq.com>

commit 8407c1d
Author: qzhhhi <zihanqin2048@gmail.com>
Date:   Sat May 30 23:17:41 2026 +0800

    style: Apply clang-format across all C++ source files
Co-authored-by: Copilot <copilot@github.com>
commit e95abf7
Author: ZGZ713912 <zgz713912@gmail.com>
Date:   Thu Jul 9 04:10:12 2026 +0800

    refactor(chassis): simplify suspension toggle logic

commit bef3729
Author: ZGZ713912 <zgz713912@gmail.com>
Date:   Thu Jul 9 02:57:18 2026 +0800

    feat(controller): add deformable suspension component

commit 5101024
Author: ZGZ713912 <zgz713912@gmail.com>
Date:   Wed Jul 8 23:12:09 2026 +0800

    feat(chassis): enhance passive suspension parameters

commit 5c483b6
Author: ZGZ713912 <zgz713912@gmail.com>
Date:   Wed Jul 8 22:38:45 2026 +0800

    feat(chassis): add passive suspension parameters
- Output /auto_aim/camera_transform, /auto_aim/barrel_direction,
  /auto_aim/yaw_velocity from hardware layer
- Expose gimbal_yaw_velocity() accessor on TopBoard
- Remove standalone auto-aim launch (now runs as Component in RMCS)
- Bump rmcs_auto_aim_v2 submodule (single-process architecture,
  fire controller & tracker refactor, dynamic yaw limits)
@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4f2f6ae1-8ba5-40ef-85fd-c97aecdc835e

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

本次变更同时更新了启动/配置、执行器接口、IMU 与时钟链路、可变形底盘控制、Hero 系列控制器与 UI、以及消息和工具库定义。还新增并替换了多个插件注册、硬件节点、控制器实现与数据结构。

Changes

启动与配置

Layer / File(s) Summary
启动与配置更新
.script/template/entrypoint, rmcs_ws/src/rmcs_auto_aim_v2, rmcs_ws/src/rmcs_bringup/config/*.yaml, rmcs_ws/src/rmcs_bringup/launch/rmcs.launch.py, rmcs_ws/src/rmcs_core/CMakeLists.txt, rmcs_ws/src/rmcs_core/plugins.xml
新增 USBFS_MEMORY_MB 写入逻辑,更新子模块哈希,重构多份 bringup YAML,移除自动瞄准子 launch,调整 CMake 排版,并更新插件注册清单。

执行器与基础设施

Layer / File(s) Summary
执行器事件机制
rmcs_ws/src/rmcs_executor/include/rmcs_executor/component.hpp, rmcs_ws/src/rmcs_executor/src/executor.hpp, rmcs_ws/src/rmcs_executor/src/component.cpp, rmcs_ws/src/rmcs_executor/src/main.cpp, rmcs_ws/src/rmcs_executor/package.xml
执行器改为按 (name, kind) 解析接口,引入事件输入/输出接口,并调整入口初始化与包依赖。
IMU 与时钟链路
rmcs_ws/src/rmcs_msgs/include/rmcs_msgs/*, rmcs_ws/src/rmcs_core/src/filter/imu_ekf.hpp, rmcs_ws/src/rmcs_core/src/hardware/device/bmi088_ekf.hpp, rmcs_ws/src/rmcs_core/src/hardware/device/board_clock_lifter.hpp, rmcs_ws/src/rmcs_core/src/hardware/omni_infantry.cpp
新增 BoardClock/ImuSnapshot/CameraFrameRaw,补充 EKF 与时钟提升工具,并将 OmniInfantry 切到快照式 IMU 管线。
并发与容器工具
rmcs_ws/src/rmcs_utility/include/rmcs_utility/*
新增 futex 等待、内存池、共享工厂、环形缓冲快照视图与若干辅助工具。

可变形底盘与 Hero 传动链

Layer / File(s) Summary
可变形底盘控制器
rmcs_ws/src/rmcs_core/src/controller/chassis/deformable_*.cpp, deformable_mode.hpp
引入模式管理器、关节速度输入、悬架控制器与轮控数组化实现。
可变形云台与底盘硬件
rmcs_ws/src/rmcs_core/src/controller/gimbal/deformable_infantry_gimbal_controller.cpp, rmcs_ws/src/rmcs_core/src/hardware/deformable-infantry-omni(-b).cpp
云台改为 pitch_lock 语义,硬件层改为 BottomBoard/TopBoard 与数组化关节/TF/CAN 流程。
Hero 系列控制器与硬件
rmcs_ws/src/rmcs_core/src/controller/chassis/hero_*.cpp, rmcs_ws/src/rmcs_core/src/controller/gimbal/*.cpp, rmcs_ws/src/rmcs_core/src/controller/shooting/*.cpp, rmcs_ws/src/rmcs_core/src/hardware/flight.cpp, rmcs_ws/src/rmcs_core/src/hardware/steering-hero-little.cpp
新增并重构 Hero 底盘、舵轮、功率、摩擦轮、热量、推弹、飞控与转向底盘相关实现。

UI、消息与格式化

Layer / File(s) Summary
UI 组件与形状
rmcs_ws/src/rmcs_core/src/referee/app/ui/*, widget/*, shape/*
更新飞行/英雄/可变形底盘 UI、状态环、形状与红黑树/调度器等工具的展示与接口。
消息与工具库
rmcs_ws/src/rmcs_description/include/rmcs_description/*, rmcs_ws/src/rmcs_msgs/include/rmcs_msgs/*, rmcs_ws/src/rmcs_utility/include/rmcs_utility/*
补充消息类型、TF 描述、CRC、原子 futex、内存池、环形缓冲与共享工厂等基础设施。

Estimated code review effort: 5 (Critical) | ~150 minutes

Possibly related PRs

Suggested reviewers: creeper5820, Yukikaze2233, qzhhhi

Poem

兔子跳进代码丛,悬架云台一起动
事件队列轻轻转,IMU 星光亮如虹
Hero 转向风中稳,UI 线条画得工
评审顺顺无烦恼,胡萝卜香满屏中 🥕

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 标题准确概括了核心变更:底盘控制模块化重构并清理了部分未用组件。
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/deformable-infantry

Warning

Review ran into problems

🔥 Problems

Git: Failed to clone repository. Please run the @coderabbitai full review command to re-trigger a full review. If the issue persists, set path_filters to include or exclude specific files.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@ZGZ713912

Copy link
Copy Markdown
Member Author

@coderabbitai summary

@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown
✅ Action performed

Summary regeneration triggered.

@ZGZ713912

Copy link
Copy Markdown
Member Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown
✅ Action performed

Full review finished.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 12

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
rmcs_ws/src/rmcs_core/src/controller/gimbal/player_viewer.cpp (1)

94-96: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

viewer_delta_angle_by_mouse_wheel_ 被连续赋值两次,第一次赋值立即被覆盖。

Line 94 使用灵敏度 0.095 赋值后,Line 96 立即用 0.09 覆盖,第一次赋值是死代码。应删除其中一行,或补充缺失的条件分支。

🐛 建议修复
     *viewer_delta_angle_by_mouse_wheel_ = 0.5 * *mouse_wheel_ * unit_sensitivity(0.095);

-    *viewer_delta_angle_by_mouse_wheel_ = 0.5 * *mouse_wheel_ * unit_sensitivity(0.09);
-
     if (viewer_reset_) {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@rmcs_ws/src/rmcs_core/src/controller/gimbal/player_viewer.cpp` around lines
94 - 96, The viewer mouse-wheel angle value is assigned twice in the same flow,
and the first assignment is immediately overwritten. Update the logic in
player_viewer::... that sets viewer_delta_angle_by_mouse_wheel_ so only the
intended sensitivity is applied, either by removing the redundant assignment or
restoring the missing conditional branch that should make both paths distinct.
🧹 Nitpick comments (12)
rmcs_ws/src/rmcs_core/src/controller/chassis/hero_steering_wheel_controller.cpp (2)

452-453: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

inf_ 常量未被使用。

nan_ 在第 375–376 行有使用,但 inf_ 在整个文件中未被引用,属于死代码。建议移除。

     static constexpr double nan_ = std::numeric_limits<double>::quiet_NaN();
-    static constexpr double inf_ = std::numeric_limits<double>::infinity();
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@rmcs_ws/src/rmcs_core/src/controller/chassis/hero_steering_wheel_controller.cpp`
around lines 452 - 453, The static constexpr inf_ constant in
hero_steering_wheel_controller is unused and should be removed as dead code;
keep the existing nan_ constant since it is referenced elsewhere in the
controller logic, and delete inf_ from the same constants block so the file only
contains actively used symbols.

369-370: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

移除无意义的零乘项。

0 * cos_varphi_[i]0 * sin_varphi_[i] 是死代码,不影响计算结果但会误导读者以为存在某个被置零的系数项。可以简化为:

-                auto x = ax - vehicle_radius_ * (az * sin_varphi_[i] + 0 * cos_varphi_[i]);
-                auto y = ay + vehicle_radius_ * (az * cos_varphi_[i] - 0 * sin_varphi_[i]);
+                auto x = ax - vehicle_radius_ * az * sin_varphi_[i];
+                auto y = ay + vehicle_radius_ * az * cos_varphi_[i];
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@rmcs_ws/src/rmcs_core/src/controller/chassis/hero_steering_wheel_controller.cpp`
around lines 369 - 370, Remove the dead zero-multiply terms in hero steering
wheel kinematics: in the chassis controller’s position calculation, simplify the
expressions in the wheel-coordinate loop so the x and y formulas only use the
meaningful az, sin_varphi_[i], and cos_varphi_[i] terms. Update the logic around
the affected calculations in hero_steering_wheel_controller.cpp to keep the same
result without the misleading 0 * cos_varphi_[i] and 0 * sin_varphi_[i] factors.
rmcs_ws/src/rmcs_utility/include/rmcs_utility/ring_buffer.hpp (2)

486-497: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

pop_front_until 中无符号下溢依赖隐式回绕。

Line 492 pos.origin_ + pos.offset_ - outpos.origin_ < out(视图过期)时会发生无符号下溢,回绕为一个极大值。虽然 Line 493 的 count > in - out 检查能捕获此情况并安全返回 0,但依赖隐式回绕可读性较差。建议添加显式的过期检查。

♻️ 建议改进
     const auto in = in_.load(std::memory_order::acquire);
     const auto out = out_.load(std::memory_order::relaxed);
-    const auto count = pos.origin_ + pos.offset_ - out;
-    if (count > in - out)
+    if (pos.origin_ < out || pos.origin_ + pos.offset_ > in)
         return 0;
+    const auto count = pos.origin_ + pos.offset_ - out;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@rmcs_ws/src/rmcs_utility/include/rmcs_utility/ring_buffer.hpp` around lines
486 - 497, In ring_buffer::pop_front_until, avoid relying on unsigned wraparound
when computing the distance from pos to out_. Add an explicit stale-iterator
check using pos.origin_, pos.offset_, and out before subtracting, so expired
views return 0 directly; keep the existing bounds validation and pop_front_n
call unchanged otherwise.

111-118: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

operator==operator<=> 比较范围不一致。

operator==(Lines 111-114)检查 buffer_origin_offset_ 三个字段,而 operator<=>(Lines 116-118)仅比较 offset_。对于 std::strong_orderinga <=> b == equal 应蕴含 a == b,但来自不同视图的同 offset_ 迭代器会违反这一契约。虽然跨容器比较本身是 UB,但两个比较运算符的语义不一致容易引发误用。

♻️ 建议修复
     friend std::strong_ordering operator<=>(BasicIterator lhs, BasicIterator rhs) {
+        if (lhs.buffer_ != rhs.buffer_)
+            return std::strong_ordering::less;
         return lhs.offset_ <=> rhs.offset_;
     }

或至少添加注释说明 operator<=> 仅适用于同源迭代器。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@rmcs_ws/src/rmcs_utility/include/rmcs_utility/ring_buffer.hpp` around lines
111 - 118, `BasicIterator` 的 `operator==` 和 `operator<=>` 比较语义不一致:前者检查
`buffer_`、`origin_`、`offset_`,后者只比较 `offset_`,会导致相等关系与三路比较契约不匹配。请在
`BasicIterator` 的比较运算符实现中统一比较范围,确保 `operator<=>` 与 `operator==` 对同一组字段给出一致结果;如果
`operator<=>` 仅打算用于同源迭代器,请在该处补充明确注释并避免让它看起来可用于跨视图比较。
rmcs_ws/src/rmcs_msgs/include/rmcs_msgs/camera_frame_raw.hpp (1)

12-26: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

注意 CameraFrameRaw 的体积(~1.5 MB)及拷贝开销。

kFrameSize = 1440 × 1080 = 1,555,200 字节,整个结构体约 1.5 MB。由于结构体是值语义且未禁用拷贝,按值传递或在容器中按值存储会产生大量拷贝开销。建议在文档注释中明确该结构体应通过 std::shared_ptr / std::unique_ptr 传递,或考虑将帧数据改为堆分配的 std::vector<std::byte> 以支持移动语义。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@rmcs_ws/src/rmcs_msgs/include/rmcs_msgs/camera_frame_raw.hpp` around lines 12
- 26, CameraFrameRaw is a large value-type (~1.5 MB) and can be expensive to
copy; update the design guidance around CameraFrameRaw to make its intended
ownership/ փոխանց usage explicit. In camera_frame_raw.hpp, add documentation
near CameraFrameRaw and kFrameSize stating it should not be passed or stored by
value and should use std::shared_ptr/std::unique_ptr instead, or refactor the
data member to a heap-backed std::vector<std::byte> if you want move-friendly
semantics.
rmcs_ws/src/rmcs_executor/src/executor.hpp (1)

197-207: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

output_by_name 冲突检查是冗余代码。

Lines 176-192 的 declaration_kind_map 检查已经会捕获同名不同 kind 的冲突并抛出异常,因此 Lines 197-207 对 output_by_name 的相同检查永远不会触发。可以移除这段死代码以减少维护负担。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@rmcs_ws/src/rmcs_executor/src/executor.hpp` around lines 197 - 207, Remove
the redundant conflict check in the output registration path: the
`output_by_name.find(output.name)` block inside `executor.hpp` duplicates the
earlier `declaration_kind_map` validation and will never be reached for the
same-name different-kind case. Delete this dead branch and keep the existing
`declaration_kind_map` enforcement as the single source of truth for conflicting
interface kinds.
rmcs_ws/src/rmcs_core/src/hardware/steering-hero-little.cpp (1)

39-107: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

CanReceiveRateCounter 是完全未使用的死代码。

CanReceiveRateCounter 类定义(Lines 39-107)以及 TopBoard/BottomBoard 中所有相关的成员变量(Lines 488-491, 828-831)和调用点均已被注释掉。如果该功能暂不需要,建议直接移除这些代码;如果是为将来调试保留,建议通过条件编译宏控制而非注释保留。

Also applies to: 488-491, 828-831

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@rmcs_ws/src/rmcs_core/src/hardware/steering-hero-little.cpp` around lines 39
- 107, Remove the dead `CanReceiveRateCounter` code since it is no longer used:
delete the class definition in `steering-hero-little.cpp`, along with the
commented-out `TopBoard` and `BottomBoard` member declarations and any related
call sites. If this CAN receive-rate logging is meant to stay for debugging,
reintroduce it behind a clear compile-time feature flag instead of leaving the
class and references commented out.
rmcs_ws/src/rmcs_core/src/controller/adrc/eso.hpp (1)

69-69: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

可考虑使用 std::clamp 替代自定义实现。

项目已使用 C++20 特性(如 [[unlikely]]requires),std::clamp(C++17 起)可直接使用,语义与当前实现完全一致。

♻️ 可选重构
-    static double clamp(double x, double lo, double hi) { return std::max(lo, std::min(x, hi)); }
+    static double clamp(double x, double lo, double hi) { return std::clamp(x, lo, hi); }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@rmcs_ws/src/rmcs_core/src/controller/adrc/eso.hpp` at line 69, The custom
clamp helper in `Eso` can be simplified by replacing the local `clamp(double x,
double lo, double hi)` implementation with `std::clamp`, since the project
already targets C++20 and the standard utility matches the current behavior.
Update the `clamp` call site inside the `ESO` header to use the standard
algorithm and keep the same parameter ordering and semantics.
rmcs_ws/src/rmcs_core/src/controller/chassis/deformable_suspension.cpp (1)

105-106: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

configure_active_rate_filters_update() 中的调用是冗余的

before_updating()(第 84 行)已使用 1.0 / update_dt_() 调用过 configure_active_rate_filters_,而 update() 中的 dt 同样来自 update_dt_()。由于 configure_active_rate_filters_ 内部有采样频率变化检查,第二次调用为 no-op,但代码冗余。

♻️ 移除冗余调用
         const auto posture_target_angles_rad = read_posture_target_angles_rad_();
         const auto dt = update_dt_();
-        configure_active_rate_filters_(1.0 / dt);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@rmcs_ws/src/rmcs_core/src/controller/chassis/deformable_suspension.cpp`
around lines 105 - 106, `update()` 中对 `configure_active_rate_filters_`
的调用是重复的,因为 `before_updating()` 已经用 `update_dt_()` 配置过采样频率。请在
`deformable_suspension::update()` 中移除这次基于 `dt` 的重复调用,保留 `before_updating()`
里的那次配置即可,确保 `update_dt_()`, `configure_active_rate_filters_`,
`before_updating()`, 和 `update()` 的职责分离清晰。
rmcs_ws/src/rmcs_core/src/controller/gimbal/two_axis_gimbal_solver.hpp (1)

33-38: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

enable_yaw_limit 缺少参数校验

enable_yaw_limit 未校验 yaw_upper_limit >= yaw_lower_limit。若调用方传入错误顺序的参数,std::clamp(v, lo, hi)lo > hi 时为 C++20 未定义行为。

🛡️ 建议添加校验
     void enable_yaw_limit(
         rmcs_executor::Component& component, double yaw_upper_limit, double yaw_lower_limit) {
+        if (yaw_upper_limit < yaw_lower_limit)
+            std::swap(yaw_upper_limit, yaw_lower_limit);
         yaw_cw_max_ = yaw_upper_limit;
         yaw_cw_min_ = yaw_lower_limit;
         component.register_input("/gimbal/yaw/angle", gimbal_yaw_angle_);
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@rmcs_ws/src/rmcs_core/src/controller/gimbal/two_axis_gimbal_solver.hpp`
around lines 33 - 38, `two_axis_gimbal_solver::enable_yaw_limit` is missing
validation for the yaw bounds before storing them. Add a guard in
`enable_yaw_limit` to verify `yaw_upper_limit >= yaw_lower_limit` before
assigning `yaw_cw_max_` and `yaw_cw_min_`, and reject invalid input with a clear
failure path (for example, throw or otherwise signal an error) so later
`std::clamp` use in the gimbal solver cannot receive an invalid range. Keep the
check close to the existing `enable_yaw_limit` logic in
`two_axis_gimbal_solver`.
rmcs_ws/src/rmcs_executor/include/rmcs_executor/component.hpp (1)

220-247: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

工作线程在回调抛异常后永久退出,后续事件将被静默丢弃。

worker_mainuser_callback_ 抛出异常时记录日志后直接 return,线程结束。此后 enqueue() 仍会继续入队/丢弃,但再也没有消费者,导致该事件通道被静默停用(仅首次丢弃时打一条 WARN)。对于控制系统中的事件流,单次瞬时异常即造成永久性功能失效,风险较高。

请确认这是否为预期设计。若希望具备容错性,可考虑捕获异常后继续循环(丢弃当前事件并 pop_front),而非终止线程。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@rmcs_ws/src/rmcs_executor/include/rmcs_executor/component.hpp` around lines
220 - 247, The worker_main loop in QueuedEventInputInterface currently
terminates the worker thread whenever user_callback_ throws, which permanently
disables the queue consumer. Update the exception handling in worker_main so
that a callback failure only affects the current event: log the error, ensure
the event is removed from queue_ with pop_front, and then continue the loop
instead of returning. Keep the same behavior for the normal success path and
preserve the stop_requested_ and event_count_ wait logic.
rmcs_ws/src/rmcs_core/src/controller/pid/friction_wheel_pid_recorder.cpp (1)

84-106: 🚀 Performance & Scalability | 🔵 Trivial

实时循环内的同步文件 I/O 可能引入抖动。

update() 在执行器循环(配置中 update_rate: 1000.0)上被调用,而这里每个使能周期都直接向 log_stream_ 写入并周期性 flush()。磁盘 write/flush 是阻塞调用,可能在控制线程上造成不可预期的延迟抖动。若该记录器会随实车控制一起运行,建议将序列化后的行推入无锁队列,由独立后台线程负责落盘。若仅用于离线调参台架,可忽略。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@rmcs_ws/src/rmcs_core/src/controller/pid/friction_wheel_pid_recorder.cpp`
around lines 84 - 106, The synchronous file writes in update() can block the
real-time control loop and introduce jitter. Refactor
friction_wheel_pid_recorder::update to avoid direct log_stream_ writes and
flush() calls on the executor thread; instead, serialize each sample into a
queue/buffer and have a separate background worker thread handle disk I/O and
periodic flushing. Keep the existing run_ids_/sample_indices_ bookkeeping in
update(), but move the actual persistence logic out of the control path.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@rmcs_ws/src/rmcs_core/src/controller/chassis/chassis_power_controller.cpp`:
- Around line 95-99: `reset_power_control()` currently clears
`virtual_buffer_energy_`, `boost_mode_`, and `chassis_control_power_limit_`, but
it no longer resets the `supercap_control_enabled_` output, so that signal can
stay enabled in safety/RC-disconnect states. Restore the output reset inside
`reset_power_control()` in `chassis_power_controller.cpp` by setting
`supercap_control_enabled_` to false along with the other power-control outputs,
so the `ChassisPowerController` leaves supercap control disabled whenever this
reset path is taken.

In `@rmcs_ws/src/rmcs_core/src/controller/chassis/deformable_mode.hpp`:
- Around line 176-177: `complex_spin_active_` is never set to true, so the
complex spin path in `deformable_mode.hpp` is unreachable and its timer state
never changes. Either implement the missing activation path by setting
`complex_spin_active_` from the relevant mode transition logic in
`deactivate_complex_spin_()`/the surrounding mode handlers, or remove the dead
`if (complex_spin_active_)` branch, the complex spin elapsed-time updates, and
the `complex_spin_active_`/`complex_spin_elapsed_` state if the feature is not
intended to exist.

In `@rmcs_ws/src/rmcs_core/src/controller/chassis/hero_chassis_controller.cpp`:
- Around line 185-190: The comment and implementation in
hero_chassis_controller::updateChassisBehavior are inconsistent: the AUTO
rear-following scaling is capped at 0.3, so it cannot be “fully enabled at max”
as the comment says. Either update the clamp in the
measured_translational_speed-based angular_velocity scaling to allow a full 1.0
at translational_velocity_max, or revise the nearby comment to match the
intended 30% maximum behavior.

In `@rmcs_ws/src/rmcs_core/src/controller/gimbal/dual_yaw_controller.cpp`:
- Around line 112-118: The wrap_angle() helper in dual_yaw_controller.cpp has a
broken normalization loop that can run forever for positive inputs; update the
first loop condition so it normalizes negative angles into the [0, 2π) range
instead of incrementing positive values indefinitely. Keep the change localized
to wrap_angle(), and verify the logic still returns a wrapped angle consistent
with how bottom_yaw_control_error() handles angle wrapping.

In `@rmcs_ws/src/rmcs_core/src/controller/gimbal/player_viewer.cpp`:
- Around line 30-32: The player_viewer input registration is creating unused
subscriptions: `gimbal_pitch_angle_` and `gimbal_pitch_raw_angle_` are
registered in `player_viewer.cpp` but never referenced, and
`gimbal_pitch_angle_` duplicates the `"/gimbal/player_viewer/angle"` path
already used by `gimbal_player_viewer_angle_`. Update the `PlayerViewer` setup
to remove the redundant `register_input` calls or wire these members into actual
reads where they are intended to be used, and ensure each input path is
registered only once.

In `@rmcs_ws/src/rmcs_core/src/controller/gimbal/two_axis_gimbal_solver.hpp`:
- Around line 208-229: `clamp_yaw_limit` in `TwoAxisGimbalSolver` is clamping an
unnormalized `target_cw`, so equivalent angles outside `[0, 2π)` can be
incorrectly limited. Normalize `target_cw` into the same `[0, 2π)` domain as
`yaw_cw_min_`/`yaw_cw_max_` before calling `std::clamp`, then keep the existing
rotation update logic for `control_direction` unchanged.

In
`@rmcs_ws/src/rmcs_core/src/controller/shooting/hero_friction_wheel_controller.cpp`:
- Around line 71-95: The profile toggle logic in
hero_friction_wheel_controller::update is being triggered twice for the same
ctrl+f press because both the plain f edge check and the ctrl+f edge check can
fire together. Consolidate the handling into a single branch for the intended
shortcut, and ensure active_profile_ ^= 1 runs only once per key transition
while preserving the friction_soft_start_stop_percentage_ recalculation.

In `@rmcs_ws/src/rmcs_core/src/controller/shooting/shooting_recorder.cpp`:
- Around line 56-91: `shooting_recorder`’s update/logging path contains unused
variables, empty log writes, and per-call file I/O that should be cleaned up.
Remove or use the dead assignments (`v`, `timestamp`) in the update flow, build
`log_text` only when `friction_wheel_count_ == 4` and skip both `log_stream_`
and `RCLCPP_INFO` when it is empty, and stop reopening `"shoot_recorder"` on
every update by reusing a persistent stream or buffering writes. Also remove or
wire up the unused `friction_velocities_` and `friction_wheels_velocity_`
members and delete the dead helper methods (`analysis1`, `analysis2`, `GetTime`)
if they are not referenced anywhere.
- Around line 33-36: The shooting recorder setup in shooting_recorder.cpp has
unsafe file handling: the log path built with fmt::format("/robot_shoot/{}.log",
ms) may fail if the directory is missing or unwritable, log_stream_.open(file)
is not validated, and the temporary std::ofstream out_file("shoot_recorder") is
created without being used. Update the recorder initialization around
log_stream_.open and the local out_file creation to use a writable, ensured
path, check the stream state immediately after opening, and either write
meaningful content to out_file or remove it if it is unnecessary.
- Around line 237-242: `analysis3()` can index past the end of `velocities` when
there is only one sample, so add the same minimum-size guard used by
`analysis1()` before computing `range2_`. In `shooting_recorder.cpp`, update the
logic around `analysis3()` to require at least 3 elements before reading
`velocities[1]` and `velocities[size - 2]`, and provide a safe fallback for
smaller inputs. Use the existing `velocities` handling and `range_`/`range2_`
assignments as the place to apply the check.

In `@rmcs_ws/src/rmcs_core/src/referee/app/ui/deformable_infantry_ui.cpp`:
- Around line 152-166: `update_deformable_chassis_leg_arcs()` currently
dereferences `*chassis_angle_` without verifying it is ready, which can cause
undefined behavior on early updates. Update the readiness guard in this function
to include `chassis_angle_.ready()` alongside the existing `std::all_of` check
for `joint_physical_angle_`, and return early or hide
`deformable_chassis_leg_arcs_` when any required input is not ready. Keep the
existing `active_suspension_active_.ready()` handling consistent with the other
inputs before calling `deformable_chassis_leg_arcs_.update()`.

In `@rmcs_ws/src/rmcs_core/src/referee/app/ui/hero.cpp`:
- Around line 287-292: Ctrl+E toggling in update_bottom_yaw_tracking_lines() is
level-triggered and flips bottom_yaw_tracking_enabled_ every frame while held.
Change this logic to edge-triggered by tracking an independent previous-frame
Ctrl+E state (for example a new last_bottom_yaw_ctrl_e_ member) and only
toggling when the key transitions from not pressed to pressed; keep
bottom_yaw_anchor_angle_rad_ updates tied to that single transition.

---

Outside diff comments:
In `@rmcs_ws/src/rmcs_core/src/controller/gimbal/player_viewer.cpp`:
- Around line 94-96: The viewer mouse-wheel angle value is assigned twice in the
same flow, and the first assignment is immediately overwritten. Update the logic
in player_viewer::... that sets viewer_delta_angle_by_mouse_wheel_ so only the
intended sensitivity is applied, either by removing the redundant assignment or
restoring the missing conditional branch that should make both paths distinct.

---

Nitpick comments:
In `@rmcs_ws/src/rmcs_core/src/controller/adrc/eso.hpp`:
- Line 69: The custom clamp helper in `Eso` can be simplified by replacing the
local `clamp(double x, double lo, double hi)` implementation with `std::clamp`,
since the project already targets C++20 and the standard utility matches the
current behavior. Update the `clamp` call site inside the `ESO` header to use
the standard algorithm and keep the same parameter ordering and semantics.

In `@rmcs_ws/src/rmcs_core/src/controller/chassis/deformable_suspension.cpp`:
- Around line 105-106: `update()` 中对 `configure_active_rate_filters_` 的调用是重复的,因为
`before_updating()` 已经用 `update_dt_()` 配置过采样频率。请在
`deformable_suspension::update()` 中移除这次基于 `dt` 的重复调用,保留 `before_updating()`
里的那次配置即可,确保 `update_dt_()`, `configure_active_rate_filters_`,
`before_updating()`, 和 `update()` 的职责分离清晰。

In
`@rmcs_ws/src/rmcs_core/src/controller/chassis/hero_steering_wheel_controller.cpp`:
- Around line 452-453: The static constexpr inf_ constant in
hero_steering_wheel_controller is unused and should be removed as dead code;
keep the existing nan_ constant since it is referenced elsewhere in the
controller logic, and delete inf_ from the same constants block so the file only
contains actively used symbols.
- Around line 369-370: Remove the dead zero-multiply terms in hero steering
wheel kinematics: in the chassis controller’s position calculation, simplify the
expressions in the wheel-coordinate loop so the x and y formulas only use the
meaningful az, sin_varphi_[i], and cos_varphi_[i] terms. Update the logic around
the affected calculations in hero_steering_wheel_controller.cpp to keep the same
result without the misleading 0 * cos_varphi_[i] and 0 * sin_varphi_[i] factors.

In `@rmcs_ws/src/rmcs_core/src/controller/gimbal/two_axis_gimbal_solver.hpp`:
- Around line 33-38: `two_axis_gimbal_solver::enable_yaw_limit` is missing
validation for the yaw bounds before storing them. Add a guard in
`enable_yaw_limit` to verify `yaw_upper_limit >= yaw_lower_limit` before
assigning `yaw_cw_max_` and `yaw_cw_min_`, and reject invalid input with a clear
failure path (for example, throw or otherwise signal an error) so later
`std::clamp` use in the gimbal solver cannot receive an invalid range. Keep the
check close to the existing `enable_yaw_limit` logic in
`two_axis_gimbal_solver`.

In `@rmcs_ws/src/rmcs_core/src/controller/pid/friction_wheel_pid_recorder.cpp`:
- Around line 84-106: The synchronous file writes in update() can block the
real-time control loop and introduce jitter. Refactor
friction_wheel_pid_recorder::update to avoid direct log_stream_ writes and
flush() calls on the executor thread; instead, serialize each sample into a
queue/buffer and have a separate background worker thread handle disk I/O and
periodic flushing. Keep the existing run_ids_/sample_indices_ bookkeeping in
update(), but move the actual persistence logic out of the control path.

In `@rmcs_ws/src/rmcs_core/src/hardware/steering-hero-little.cpp`:
- Around line 39-107: Remove the dead `CanReceiveRateCounter` code since it is
no longer used: delete the class definition in `steering-hero-little.cpp`, along
with the commented-out `TopBoard` and `BottomBoard` member declarations and any
related call sites. If this CAN receive-rate logging is meant to stay for
debugging, reintroduce it behind a clear compile-time feature flag instead of
leaving the class and references commented out.

In `@rmcs_ws/src/rmcs_executor/include/rmcs_executor/component.hpp`:
- Around line 220-247: The worker_main loop in QueuedEventInputInterface
currently terminates the worker thread whenever user_callback_ throws, which
permanently disables the queue consumer. Update the exception handling in
worker_main so that a callback failure only affects the current event: log the
error, ensure the event is removed from queue_ with pop_front, and then continue
the loop instead of returning. Keep the same behavior for the normal success
path and preserve the stop_requested_ and event_count_ wait logic.

In `@rmcs_ws/src/rmcs_executor/src/executor.hpp`:
- Around line 197-207: Remove the redundant conflict check in the output
registration path: the `output_by_name.find(output.name)` block inside
`executor.hpp` duplicates the earlier `declaration_kind_map` validation and will
never be reached for the same-name different-kind case. Delete this dead branch
and keep the existing `declaration_kind_map` enforcement as the single source of
truth for conflicting interface kinds.

In `@rmcs_ws/src/rmcs_msgs/include/rmcs_msgs/camera_frame_raw.hpp`:
- Around line 12-26: CameraFrameRaw is a large value-type (~1.5 MB) and can be
expensive to copy; update the design guidance around CameraFrameRaw to make its
intended ownership/ փոխանց usage explicit. In camera_frame_raw.hpp, add
documentation near CameraFrameRaw and kFrameSize stating it should not be passed
or stored by value and should use std::shared_ptr/std::unique_ptr instead, or
refactor the data member to a heap-backed std::vector<std::byte> if you want
move-friendly semantics.

In `@rmcs_ws/src/rmcs_utility/include/rmcs_utility/ring_buffer.hpp`:
- Around line 486-497: In ring_buffer::pop_front_until, avoid relying on
unsigned wraparound when computing the distance from pos to out_. Add an
explicit stale-iterator check using pos.origin_, pos.offset_, and out before
subtracting, so expired views return 0 directly; keep the existing bounds
validation and pop_front_n call unchanged otherwise.
- Around line 111-118: `BasicIterator` 的 `operator==` 和 `operator<=>`
比较语义不一致:前者检查 `buffer_`、`origin_`、`offset_`,后者只比较 `offset_`,会导致相等关系与三路比较契约不匹配。请在
`BasicIterator` 的比较运算符实现中统一比较范围,确保 `operator<=>` 与 `operator==` 对同一组字段给出一致结果;如果
`operator<=>` 仅打算用于同源迭代器,请在该处补充明确注释并避免让它看起来可用于跨视图比较。
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ad38d6b8-35c6-4d98-89f6-2c89aa96968c

📥 Commits

Reviewing files that changed from the base of the PR and between 610dea3 and 3fb1407.

📒 Files selected for processing (108)
  • .script/template/entrypoint
  • rmcs_ws/src/rmcs_auto_aim_v2
  • rmcs_ws/src/rmcs_bringup/config/deformable-infantry-omni-b.yaml
  • rmcs_ws/src/rmcs_bringup/config/deformable-infantry-omni.yaml
  • rmcs_ws/src/rmcs_bringup/config/deformable-infantry-steering.yaml
  • rmcs_ws/src/rmcs_bringup/config/flight.yaml
  • rmcs_ws/src/rmcs_bringup/config/mecanum-hero.yaml
  • rmcs_ws/src/rmcs_bringup/config/omni-infantry.yaml
  • rmcs_ws/src/rmcs_bringup/config/sentry.yaml
  • rmcs_ws/src/rmcs_bringup/config/steering-hero-little.yaml
  • rmcs_ws/src/rmcs_bringup/config/steering-hero.yaml
  • rmcs_ws/src/rmcs_bringup/config/steering-infantry.yaml
  • rmcs_ws/src/rmcs_bringup/launch/rmcs.launch.py
  • rmcs_ws/src/rmcs_core/CMakeLists.txt
  • rmcs_ws/src/rmcs_core/plugins.xml
  • rmcs_ws/src/rmcs_core/src/broadcaster/tf_broadcaster.cpp
  • rmcs_ws/src/rmcs_core/src/broadcaster/value_broadcaster.cpp
  • rmcs_ws/src/rmcs_core/src/controller/adrc/eso.hpp
  • rmcs_ws/src/rmcs_core/src/controller/adrc/nlesf.hpp
  • rmcs_ws/src/rmcs_core/src/controller/adrc/td.hpp
  • rmcs_ws/src/rmcs_core/src/controller/chassis/chassis_climber_controller.cpp
  • rmcs_ws/src/rmcs_core/src/controller/chassis/chassis_controller.cpp
  • rmcs_ws/src/rmcs_core/src/controller/chassis/chassis_power_controller.cpp
  • rmcs_ws/src/rmcs_core/src/controller/chassis/deformable_chassis.cpp
  • rmcs_ws/src/rmcs_core/src/controller/chassis/deformable_joint_controller.cpp
  • rmcs_ws/src/rmcs_core/src/controller/chassis/deformable_mode.hpp
  • rmcs_ws/src/rmcs_core/src/controller/chassis/deformable_omni_wheel_controller.cpp
  • rmcs_ws/src/rmcs_core/src/controller/chassis/deformable_suspension.cpp
  • rmcs_ws/src/rmcs_core/src/controller/chassis/deformable_wheel_controller.cpp
  • rmcs_ws/src/rmcs_core/src/controller/chassis/hero_chassis_controller.cpp
  • rmcs_ws/src/rmcs_core/src/controller/chassis/hero_chassis_power_controller.cpp
  • rmcs_ws/src/rmcs_core/src/controller/chassis/hero_steering_wheel_controller.cpp
  • rmcs_ws/src/rmcs_core/src/controller/chassis/omni_wheel_controller.cpp
  • rmcs_ws/src/rmcs_core/src/controller/chassis/qcp_solver.hpp
  • rmcs_ws/src/rmcs_core/src/controller/chassis/steering_wheel_status.cpp
  • rmcs_ws/src/rmcs_core/src/controller/gimbal/deformable_infantry_gimbal_controller.cpp
  • rmcs_ws/src/rmcs_core/src/controller/gimbal/dual_yaw_controller.cpp
  • rmcs_ws/src/rmcs_core/src/controller/gimbal/hero_gimbal_controller.cpp
  • rmcs_ws/src/rmcs_core/src/controller/gimbal/player_viewer.cpp
  • rmcs_ws/src/rmcs_core/src/controller/gimbal/precise_two_axis_gimbal_solver.hpp
  • rmcs_ws/src/rmcs_core/src/controller/gimbal/simple_gimbal_controller.cpp
  • rmcs_ws/src/rmcs_core/src/controller/gimbal/two_axis_gimbal_solver.hpp
  • rmcs_ws/src/rmcs_core/src/controller/pid/friction_wheel_pid_recorder.cpp
  • rmcs_ws/src/rmcs_core/src/controller/pid/matrix_pid_calculator.hpp
  • rmcs_ws/src/rmcs_core/src/controller/shooting/bullet_feeder_controller_42mm.cpp
  • rmcs_ws/src/rmcs_core/src/controller/shooting/friction_wheel_controller.cpp
  • rmcs_ws/src/rmcs_core/src/controller/shooting/hero_friction_wheel_controller.cpp
  • rmcs_ws/src/rmcs_core/src/controller/shooting/hero_heat_controller.cpp
  • rmcs_ws/src/rmcs_core/src/controller/shooting/putter_controller.cpp
  • rmcs_ws/src/rmcs_core/src/controller/shooting/shooting_recorder.cpp
  • rmcs_ws/src/rmcs_core/src/filter/alpha_beta_angle_filter.hpp
  • rmcs_ws/src/rmcs_core/src/filter/imu_ekf.hpp
  • rmcs_ws/src/rmcs_core/src/filter/low_pass_filter.hpp
  • rmcs_ws/src/rmcs_core/src/hardware/deformable-infantry-omni-b.cpp
  • rmcs_ws/src/rmcs_core/src/hardware/deformable-infantry-omni.cpp
  • rmcs_ws/src/rmcs_core/src/hardware/deformable-infantry-steering.cpp
  • rmcs_ws/src/rmcs_core/src/hardware/device/benewake.hpp
  • rmcs_ws/src/rmcs_core/src/hardware/device/bmi088.hpp
  • rmcs_ws/src/rmcs_core/src/hardware/device/bmi088_ekf.hpp
  • rmcs_ws/src/rmcs_core/src/hardware/device/board_clock_lifter.hpp
  • rmcs_ws/src/rmcs_core/src/hardware/device/gy614.hpp
  • rmcs_ws/src/rmcs_core/src/hardware/device/lk_motor.hpp
  • rmcs_ws/src/rmcs_core/src/hardware/flight.cpp
  • rmcs_ws/src/rmcs_core/src/hardware/omni_infantry.cpp
  • rmcs_ws/src/rmcs_core/src/hardware/steering-hero-little.cpp
  • rmcs_ws/src/rmcs_core/src/referee/app/ui/deformable_infantry_ui.cpp
  • rmcs_ws/src/rmcs_core/src/referee/app/ui/flight.cpp
  • rmcs_ws/src/rmcs_core/src/referee/app/ui/hero.cpp
  • rmcs_ws/src/rmcs_core/src/referee/app/ui/infantry.cpp
  • rmcs_ws/src/rmcs_core/src/referee/app/ui/shape/cfs_scheduler.hpp
  • rmcs_ws/src/rmcs_core/src/referee/app/ui/shape/red_black_tree.hpp
  • rmcs_ws/src/rmcs_core/src/referee/app/ui/shape/remote_shape.hpp
  • rmcs_ws/src/rmcs_core/src/referee/app/ui/shape/shape.hpp
  • rmcs_ws/src/rmcs_core/src/referee/app/ui/widget/crosshair_circle.hpp
  • rmcs_ws/src/rmcs_core/src/referee/app/ui/widget/deformable_chassis_top_view.hpp
  • rmcs_ws/src/rmcs_core/src/referee/app/ui/widget/rangefinder.hpp
  • rmcs_ws/src/rmcs_core/src/referee/app/ui/widget/status_ring.hpp
  • rmcs_ws/src/rmcs_core/src/referee/command.cpp
  • rmcs_ws/src/rmcs_core/src/referee/command/interaction/ui.cpp
  • rmcs_ws/src/rmcs_core/src/referee/frame.hpp
  • rmcs_ws/src/rmcs_core/src/referee/status.cpp
  • rmcs_ws/src/rmcs_core/src/referee/status/field.hpp
  • rmcs_ws/src/rmcs_description/include/rmcs_description/sentry_description.hpp
  • rmcs_ws/src/rmcs_description/include/rmcs_description/tf_description.hpp
  • rmcs_ws/src/rmcs_executor/include/rmcs_executor/component.hpp
  • rmcs_ws/src/rmcs_executor/package.xml
  • rmcs_ws/src/rmcs_executor/src/component.cpp
  • rmcs_ws/src/rmcs_executor/src/executor.hpp
  • rmcs_ws/src/rmcs_executor/src/main.cpp
  • rmcs_ws/src/rmcs_msgs/include/rmcs_msgs/board_clock.hpp
  • rmcs_ws/src/rmcs_msgs/include/rmcs_msgs/camera_frame_raw.hpp
  • rmcs_ws/src/rmcs_msgs/include/rmcs_msgs/chassis_mode.hpp
  • rmcs_ws/src/rmcs_msgs/include/rmcs_msgs/full_robot_id.hpp
  • rmcs_ws/src/rmcs_msgs/include/rmcs_msgs/game_stage.hpp
  • rmcs_ws/src/rmcs_msgs/include/rmcs_msgs/imu_snapshot.hpp
  • rmcs_ws/src/rmcs_msgs/include/rmcs_msgs/rmcs_msgs.hpp
  • rmcs_ws/src/rmcs_msgs/include/rmcs_msgs/robot_color.hpp
  • rmcs_ws/src/rmcs_msgs/include/rmcs_msgs/robot_id.hpp
  • rmcs_ws/src/rmcs_msgs/include/rmcs_msgs/serial_interface.hpp
  • rmcs_ws/src/rmcs_msgs/include/rmcs_msgs/shoot_condiction.hpp
  • rmcs_ws/src/rmcs_utility/include/rmcs_utility/atomic_futex.hpp
  • rmcs_ws/src/rmcs_utility/include/rmcs_utility/crc/dji_crc.hpp
  • rmcs_ws/src/rmcs_utility/include/rmcs_utility/double_buffer.hpp
  • rmcs_ws/src/rmcs_utility/include/rmcs_utility/fps_counter.hpp
  • rmcs_ws/src/rmcs_utility/include/rmcs_utility/memory_pool.hpp
  • rmcs_ws/src/rmcs_utility/include/rmcs_utility/package_receive.hpp
  • rmcs_ws/src/rmcs_utility/include/rmcs_utility/pooled_shared_factory.hpp
  • rmcs_ws/src/rmcs_utility/include/rmcs_utility/ring_buffer.hpp
💤 Files with no reviewable changes (5)
  • rmcs_ws/src/rmcs_core/src/controller/chassis/deformable_wheel_controller.cpp
  • rmcs_ws/src/rmcs_bringup/config/mecanum-hero.yaml
  • rmcs_ws/src/rmcs_bringup/config/deformable-infantry-steering.yaml
  • rmcs_ws/src/rmcs_core/src/hardware/deformable-infantry-steering.cpp
  • rmcs_ws/src/rmcs_core/src/controller/shooting/friction_wheel_controller.cpp

Comment on lines +176 to +177
if (complex_spin_active_)
next_mode = rmcs_msgs::ChassisMode::SPIN;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

complex_spin_active_ 从未被设为 true,complex spin 功能为死代码。

complex_spin_active_ 在 Line 353 初始化为 falsedeactivate_complex_spin_()(Line 182-185)仅将其设为 false,代码中没有任何位置将其设为 true。因此:

  • Line 176-177 的 if (complex_spin_active_) 永远为 false(死代码)
  • Line 259-267 的 complex spin 计时逻辑永远不会执行
  • complex_spin_elapsed_ 永远为 0

这表明 complex spin 功能尚未实现或被有意禁用但未清理死代码。是否需要我帮助实现激活逻辑,或者应该移除这些死代码?

Also applies to: 259-267, 353-353

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@rmcs_ws/src/rmcs_core/src/controller/chassis/deformable_mode.hpp` around
lines 176 - 177, `complex_spin_active_` is never set to true, so the complex
spin path in `deformable_mode.hpp` is unreachable and its timer state never
changes. Either implement the missing activation path by setting
`complex_spin_active_` from the relevant mode transition logic in
`deactivate_complex_spin_()`/the surrounding mode handlers, or remove the dead
`if (complex_spin_active_)` branch, the complex spin elapsed-time updates, and
the `complex_spin_active_`/`complex_spin_elapsed_` state if the feature is not
intended to exist.

Comment thread rmcs_ws/src/rmcs_core/src/controller/gimbal/dual_yaw_controller.cpp
Comment thread rmcs_ws/src/rmcs_core/src/controller/gimbal/player_viewer.cpp
Comment on lines 33 to +36
auto file = fmt::format("/robot_shoot/{}.log", ms);
log_stream_.open(file);

std::ofstream out_file("shoot_recorder");

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

日志文件路径和错误处理存在问题。

  1. /robot_shoot/{}.log 是绝对路径,若目录不存在或无写权限则打开失败。
  2. log_stream_.open(file) 后未检查是否成功打开,后续写入将静默失败。
  3. Line 36 的 std::ofstream out_file("shoot_recorder") 创建/截断文件但未写入任何内容即销毁。
🛡️ Proposed fix for file open validation
     auto file = fmt::format("/robot_shoot/{}.log", ms);
     log_stream_.open(file);
+    if (!log_stream_.is_open()) {
+        RCLCPP_ERROR(get_logger(), "Failed to open log file: %s", file.c_str());
+    }
-    std::ofstream out_file("shoot_recorder");
     RCLCPP_INFO(get_logger(), "ShootingRecorder initialized, log file: %s", file.c_str());
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
auto file = fmt::format("/robot_shoot/{}.log", ms);
log_stream_.open(file);
std::ofstream out_file("shoot_recorder");
auto file = fmt::format("/robot_shoot/{}.log", ms);
log_stream_.open(file);
if (!log_stream_.is_open()) {
RCLCPP_ERROR(get_logger(), "Failed to open log file: %s", file.c_str());
}
RCLCPP_INFO(get_logger(), "ShootingRecorder initialized, log file: %s", file.c_str());
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@rmcs_ws/src/rmcs_core/src/controller/shooting/shooting_recorder.cpp` around
lines 33 - 36, The shooting recorder setup in shooting_recorder.cpp has unsafe
file handling: the log path built with fmt::format("/robot_shoot/{}.log", ms)
may fail if the directory is missing or unwritable, log_stream_.open(file) is
not validated, and the temporary std::ofstream out_file("shoot_recorder") is
created without being used. Update the recorder initialization around
log_stream_.open and the local out_file creation to use a writable, ensured
path, check the stream state immediately after opening, and either write
meaningful content to out_file or remove it if it is unnecessary.

Comment on lines +56 to 91
v = *shoot_timestamp_;

static constexpr size_t max_velocities_size = 1000;

velocities.push_back(*initial_speed_);
if (velocities.size() > max_velocities_size) {
velocities.erase(velocities.begin());
}

auto log_text = std::string{};
analysis3();

auto log_text = std::string{};
auto timestamp = timestamp_to_string(*shoot_timestamp_);

if (friction_wheel_count_ == 2) {
log_text = fmt::format(
"{},{},{},{},{}", timestamp, *initial_speed_, //
*friction_wheels_velocity_[0], *friction_wheels_velocity_[1],
*fractional_temperature_);
} else if (friction_wheel_count_ == 4) {
if (friction_wheel_count_ == 4) {
log_text = fmt::format(
"{},{},{},{},{},{},{}", timestamp, *initial_speed_, //
*friction_wheels_velocity_[0], *friction_wheels_velocity_[1],
*friction_wheels_velocity_[2], *friction_wheels_velocity_[3],
*fractional_temperature_);
"{},{},{:.3f},{:.3f},{:.3f},{:.3f},{:.3f},{:.3f},{:.3f}", *initial_speed_,
(int)velocities.size(), //
velocity_, excellence_rate_, pass_rate_, range_, range2_, velocity_max,
velocity_min);
}

log_stream_ << log_text << std::endl;
RCLCPP_INFO(get_logger(), "%s", log_text.c_str());
RCLCPP_INFO(
get_logger(), "%s",
log_text.c_str()); // Record each shot's initial speed and statistics.

log_velocity = fmt::format("{:.3f}", *initial_speed_);
std::ofstream out_file("shoot_recorder", std::ios::app);
if (out_file.is_open()) {
out_file << log_velocity << std::endl;
out_file.close();
}

last_shoot_timestamp_ = *shoot_timestamp_;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

存在大量死代码和低效文件操作。

以下问题需要关注:

  1. Line 56: v = *shoot_timestamp_ 赋值后从未使用。
  2. Line 68: timestamp 变量计算后未用于 log_text
  3. Lines 84-88: 每次 update() 都重新打开/关闭文件 "shoot_recorder",效率低下。
  4. Line 70-76: friction_wheel_count_ != 4log_text 为空但仍写入日志。
  5. Lines 95, 101: friction_velocities_friction_wheels_velocity_ 声明后从未注册或使用。
  6. Lines 145-177, 179-214, 245-251: analysis1()analysis2()GetTime() 均为死代码。
  7. Lines 113-127: velocity_excellence_rate_ 等成员变量未初始化。
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@rmcs_ws/src/rmcs_core/src/controller/shooting/shooting_recorder.cpp` around
lines 56 - 91, `shooting_recorder`’s update/logging path contains unused
variables, empty log writes, and per-call file I/O that should be cleaned up.
Remove or use the dead assignments (`v`, `timestamp`) in the update flow, build
`log_text` only when `friction_wheel_count_ == 4` and skip both `log_stream_`
and `RCLCPP_INFO` when it is empty, and stop reopening `"shoot_recorder"` on
every update by reusing a persistent stream or buffering writes. Also remove or
wire up the unused `friction_velocities_` and `friction_wheels_velocity_`
members and delete the dead helper methods (`analysis1`, `analysis2`, `GetTime`)
if they are not referenced anywhere.

Comment on lines +237 to +242
sort(velocities.begin(), velocities.end());
velocity_max = velocities.back();
velocity_min = velocities.front();

range_ = velocities.back() - velocities.front();
range2_ = velocities[int(velocities.size() - 2)] - velocities[1];

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🔴 Critical | ⚡ Quick win

analysis3()velocities.size() == 1 时触发越界访问。

首次射击时,velocities 仅有一个元素。Line 242 执行 velocities[int(velocities.size() - 2)],其中 velocities.size() - 2size_t 无符号下溢变为 SIZE_MAX,转换为 int 后为负值,导致未定义行为。velocities[1] 同样越界。

对比 analysis1() 中的保护逻辑(Lines 156-160 有 size >= 3 检查),analysis3() 缺少相同保护。

🐛 Proposed fix for the out-of-bounds access
     range_ = velocities.back() - velocities.front();
-    range2_ = velocities[int(velocities.size() - 2)] - velocities[1];
+    if (velocities.size() >= 3) {
+        range2_ = velocities[int(velocities.size() - 2)] - velocities[1];
+    } else {
+        range2_ = range_;
+    }
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
sort(velocities.begin(), velocities.end());
velocity_max = velocities.back();
velocity_min = velocities.front();
range_ = velocities.back() - velocities.front();
range2_ = velocities[int(velocities.size() - 2)] - velocities[1];
sort(velocities.begin(), velocities.end());
velocity_max = velocities.back();
velocity_min = velocities.front();
range_ = velocities.back() - velocities.front();
if (velocities.size() >= 3) {
range2_ = velocities[int(velocities.size() - 2)] - velocities[1];
} else {
range2_ = range_;
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@rmcs_ws/src/rmcs_core/src/controller/shooting/shooting_recorder.cpp` around
lines 237 - 242, `analysis3()` can index past the end of `velocities` when there
is only one sample, so add the same minimum-size guard used by `analysis1()`
before computing `range2_`. In `shooting_recorder.cpp`, update the logic around
`analysis3()` to require at least 3 elements before reading `velocities[1]` and
`velocities[size - 2]`, and provide a safe fallback for smaller inputs. Use the
existing `velocities` handling and `range_`/`range2_` assignments as the place
to apply the check.

Comment thread rmcs_ws/src/rmcs_core/src/referee/app/ui/deformable_infantry_ui.cpp
Comment on lines +287 to +292
void update_bottom_yaw_tracking_lines() {
const bool ctrl_e_pressed = keyboard_->ctrl && keyboard_->e;
if (ctrl_e_pressed) {
bottom_yaw_tracking_enabled_ = !bottom_yaw_tracking_enabled_;
bottom_yaw_anchor_angle_rad_ = *bottom_yaw_angle_;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Ctrl+E 采用电平触发切换,会在按住期间每帧反复翻转跟踪状态。

update_bottom_yaw_tracking_lines() 每次 update()(约 1000Hz)都会执行,ctrl_e_pressed 是电平判断。只要 Ctrl+E 持续按住,bottom_yaw_tracking_enabled_ 就会每帧取反、bottom_yaw_anchor_angle_rad_ 每帧被重新锚定,导致开关不可控地抖动、锚点无法稳定。应改为边沿触发(仅在“上一帧未按下→本帧按下”时翻转)。

注意 update_pitch_raw_angle_color() 会在本函数之前更新 last_keyboard_,因此此处需引入独立的上一帧状态用于边沿检测。

🐛 建议的边沿触发修正
-    void update_bottom_yaw_tracking_lines() {
-        const bool ctrl_e_pressed = keyboard_->ctrl && keyboard_->e;
-        if (ctrl_e_pressed) {
-            bottom_yaw_tracking_enabled_ = !bottom_yaw_tracking_enabled_;
-            bottom_yaw_anchor_angle_rad_ = *bottom_yaw_angle_;
-        }
+    void update_bottom_yaw_tracking_lines() {
+        const bool ctrl_e_pressed = keyboard_->ctrl && keyboard_->e;
+        if (ctrl_e_pressed && !last_bottom_yaw_ctrl_e_) {
+            bottom_yaw_tracking_enabled_ = !bottom_yaw_tracking_enabled_;
+            bottom_yaw_anchor_angle_rad_ = *bottom_yaw_angle_;
+        }
+        last_bottom_yaw_ctrl_e_ = ctrl_e_pressed;

同时新增成员 bool last_bottom_yaw_ctrl_e_ = false;

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@rmcs_ws/src/rmcs_core/src/referee/app/ui/hero.cpp` around lines 287 - 292,
Ctrl+E toggling in update_bottom_yaw_tracking_lines() is level-triggered and
flips bottom_yaw_tracking_enabled_ every frame while held. Change this logic to
edge-triggered by tracking an independent previous-frame Ctrl+E state (for
example a new last_bottom_yaw_ctrl_e_ member) and only toggling when the key
transitions from not pressed to pressed; keep bottom_yaw_anchor_angle_rad_
updates tied to that single transition.

@ZGZ713912

Copy link
Copy Markdown
Member Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown
✅ Action performed

Full review finished.


Your plan includes PR reviews subject to rate limits. More reviews will be available in 18 seconds.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Todo

Development

Successfully merging this pull request may close these issues.

3 participants