Skip to content

refactor: single process#59

Open
creeper5820 wants to merge 5 commits into
mainfrom
refactor/single-process
Open

refactor: single process#59
creeper5820 wants to merge 5 commits into
mainfrom
refactor/single-process

Conversation

@creeper5820

@creeper5820 creeper5820 commented Jun 10, 2026

Copy link
Copy Markdown
Collaborator

单进程架构重构

概述

本PR将项目架构从原有的进程分离模式(独立的Component和Runtime进程)重构为单进程多线程模式,由AutoAim工作线程与AutoAimComponent主线程协作完成自瞄功能。

核心架构变更

运行时模块移除

  • 删除 src/runtime.cpp 中的完整应用入口和运行时循环逻辑(234行),包括信号处理、图像采集、可视化绘制和Feishu消息通信
  • 移除 launch/launch.py 中的ROS2启动脚本(17行)及 generate_launch_description() 函数
  • CMakeLists.txt 中移除运行时可执行目标 ${PROJECT_NAME}_runtime 的构建和安装配置

新增AutoAim独立处理单元

  • 新增 src/kernel/auto_aim.hpp(42行)定义 AutoAim 类,采用PIMPL设计模式
  • 新增 src/kernel/auto_aim.cpp(210行)实现 AutoAim 的线程化运行逻辑
    • 使用 std::jthread 启动内部运行循环,持续执行图像采集、装甲识别、3D估计、目标选择和发射控制求解
    • 通过互斥锁保护 SystemContextAutoAimState,实现线程安全的数据访问
    • 读取配置初始化各子模块(Capturer、Identifier、Tracker等)
  • 提供三个核心接口:
    • with_context() - 线程安全访问系统上下文
    • with_command() - 线程安全访问自瞄命令状态
    • command_updated() - 原子操作检查未读命令更新

组件深度重构

  • 重写 src/component.cpp(+62/-107)中的 AutoAimComponent
    • 替换 Adapter/RclcppNode/Feishu 为直接的输入输出接口
    • 添加 before_updating() 方法在输入未就绪时绑定默认值
    • 更新 update() 方法:从独立的barrel_direction计算yaw/pitch,填充AutoAim上下文,在命令时间戳有效(100ms内)时应用控制输出
    • 移除原有的Feishu消息系统和heartbeat逻辑

适配器接口移除

  • 删除 src/adapter/adapter.hpp(29行)中的 Adapter 基类
  • 删除 src/adapter/deformable-infantry.hpp(29行)和 src/adapter/sentry.hpp(29行)中的特定机型 Adapter 实现
  • 这些类原本向 rmcs_executor::Component 注册 /tf 输入并提供位姿和方向查询接口

数据结构统一化

  • FireControl::Result::center_position 类型从 Eigen::Vector3d 改为 Point3d
  • Snapshot::Kinematics::center_position 类型从 Eigen::Vector3d 改为 Point3d
  • 各预测器(Outpost、Regular、Empty)中EKF状态向量类型调整:
    • 引入 detail::NormalEKFutil::EKF<11, 4>)和 detail::OutpostEKFutil::EKF<6, 4>)类型别名
    • 更新 make_regular_snapshot()make_outpost_snapshot() 的参数类型

依赖优化

  • 多个模块调整Eigen头文件:将 Eigen/Dense 替换为 Eigen/CoreEigen/Geometry
    • 涉及文件:aim_point_chooser.hpp、shoot_evaluator.hpp、aim_point_sampling.hpp/cpp等
  • 新增对 utility/math/kalman_filter/ekf.hpp 的直接包含
  • 移除 FireControl::Result 中对 Eigen/Core 的直接包含

配置与部署调整

  • CMakeLists.txt
    • 移除运行时可执行目标的安装(18行减少)
    • 调整 install(DIRECTORY config/...) 新增 models/ 目录到 share/${PROJECT_NAME}/ 的安装
  • config/config.yaml
    • 移除 localhost_develop 顶层配置项
    • 启用摄像头录制(capturer.record_enablefalse 改为 true
    • 调整哨兵装甲厚度(outpost_armor_thickness0.02 改为 0.022

文档更新

  • README.md(+43/-29):
    • 架构部分由"进程分离"改为"单进程多线程"
    • 部署步骤移除了启动运行时的命令
    • 新增自瞄组件的输入/输出接口说明表
    • 补充 fast_tf 获取输入示例代码
  • doc/streaming.md(+1/-2):
    • 更新模块接口使用示例中关于依赖检查的注释,移除针对rmcs-runtime的特殊处理说明

@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

该PR重构RMCS自瞄系统的运行时架构:移除独立的runtime可执行目标与launch配置,创建新的线程化AutoAim内核在worker线程中执行自瞄算法,同时重写AutoAimComponent以直接驱动该内核并处理ROS接口。删除中间的Adapter抽象层,统一项目中的Vector3d→Point3d类型转换,并整理Eigen头文件依赖。

Changes

AutoAim架构重构与运行时迁移

Layer / File(s) Summary
移除独立运行时基础设施
CMakeLists.txt, launch/launch.py, doc/streaming.md
CMakeLists.txt删除${PROJECT_NAME}_runtime可执行目标与对应安装规则,调整models目录到share路径;移除launch/launch.py中的ROS2 launch描述生成函数;更新doc/streaming.md的依赖检查说明。
AutoAim线程化内核实现
src/kernel/auto_aim.hpp, src/kernel/auto_aim.cpp
新增AutoAim类使用PIMPL与两个互斥锁分别保护SystemContext和AutoAimState,通过with_context/with_command模板方法提供线程安全访问;Impl在std::jthread中执行图像捕获→装甲识别→2D/3D估计→目标跟踪→火控求解→可视化的完整流水线,支持模块初始化、信号处理与帧率统计。
AutoAimComponent驱动逻辑重构
src/component.cpp
移除Adapter/RclcppNode/Feishu依赖,直接使用AutoAim成员;新增before_updating()为未就绪输入绑定默认值;update()从枪口方向计算yaw/pitch,填充AutoAim上下文,条件下应用100ms内的有效命令输出。
删除旧Adapter中间层
src/adapter/adapter.hpp, src/adapter/deformable-infantry.hpp, src/adapter/sentry.hpp
删除Adapter类及其ready()、camera_transform()、barrel_direction()方法,移除TF输入注册的中间层抽象。
类型标准化与Eigen头文件整理
src/kernel/fire_control.hpp, src/kernel/fire_control.cpp, src/module/fire_control/*/, src/module/predictor/*/*, src/utility/math/solve_armors.cpp
跨多文件统一Snapshot::Kinematics与FireControl::Result中Vector3d→Point3d的类型,调整Point3d初始化与转换方式;系统整理Eigen头文件从Eigen/Dense简化为Eigen/Core或Eigen/Geometry,引入EKF别名并调整相关参数类型从Snapshot::XVec→detail::XVec。
文档与配置更新
config/config.yaml, README.md
启用capturer.record_enable、调整outpost_armor_thickness参数;重写README部署步骤与项目架构说明为单进程多线程模型,新增输入/输出接口说明表与fast_tf查询示例。

Sequence Diagram

sequenceDiagram
  participant Component as AutoAimComponent<br/>(RMCS main thread)
  participant AutoAim as AutoAim kernel<br/>(worker thread)
  participant Modules as Capturer/Identifier/<br/>Tracker/PoseEstimator/FireControl
  Component->>AutoAim: with_context(SystemContext)
  Note over AutoAim: Set camera transform,<br/>barrel direction, timestamp
  AutoAim->>Modules: run pipeline loop
  Modules-->>AutoAim: Image → Armors → 3D Poses → Target → AutoAimState
  AutoAim->>AutoAim: mutex: current_command = state<br/>atomic: unread_command = true
  Component->>AutoAim: command_updated()
  alt command ready and timestamp valid
    Component->>AutoAim: with_command(read state)
    AutoAim-->>Component: AutoAimState
    Component->>Component: apply yaw/pitch/shoot outputs
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Possibly related PRs

  • Alliance-Algorithm/rmcs_auto_aim_v2#44: 该PR与主PR都直接修改src/component.cpp的AutoAimComponent驱动与命令处理,但44号PR引入了Adapter而主PR则完全移除并替换为新的AutoAim线程驱动方式。
  • Alliance-Algorithm/rmcs_auto_aim_v2#42: 主PR进一步重构src/component.cpp并删除42号PR引入的Adapter抽象,用新的AutoAim线程与命令驱动替换旧的adapter+Feishu管道。
  • Alliance-Algorithm/rmcs_auto_aim_v2#56: 两份PR都大幅修改src/runtime.cpp与相关的标识符/可视化流水线,包括运行时初始化、配置读取与模块集成,存在直接的代码级重叠关系。

Suggested labels

enhancement

Suggested reviewers

  • heyeuu

Poem

🐰 从独立进程到线程共舞,AutoAim内核启承雏,
组件同步通过互斥锁,流水线高效无比喜,
类型统一Eigen整装去,架构清晰未来无虑!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 6.45% 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 标题'refactor: single process'准确概括了该PR的主要变更——从多进程(Component + Runtime)架构重构为单进程多线程架构。
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/single-process

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 Infer (1.2.0)
src/component.cpp

In file included from src/component.cpp:1:
src/kernel/auto_aim.hpp:3:10: fatal error: 'utility/pimpl.hpp' file not found
3 | #include "utility/pimpl.hpp"
| ^~~~~~~~~~~~~~~~~~~
1 error generated.
Error: the following clang command did not run successfully:
/opt/infer-linux-x86_64-v1.2.0/lib/infer/facebook-clang-plugins/clang/install/bin/clang-18
@/tmp/coderabbit-infer/860d01b67c22f5a1a9f7e6b2762bf308693eaa61-be72817c5bbcbe6a/tmp/clang_command_.tmp.a90627.txt
++Contents of '/tmp/coderabbit-infer/860d01b67c22f5a1a9f7e6b2762bf308693eaa61-be72817c5bbcbe6a/tmp/clang_command_.tmp.a90627.txt':
"-cc1" "-load"
"/opt/infer-linux-x86_64-v1.2.0/lib/infer/infer/bin/../../facebook-clang-plugins/libtooling/build/FacebookClangPlugin.dylib"
"-add-plugin" "BiniouASTExporter" "-plugin-arg-BiniouASTExporter" "-"
"-plugin-arg-BiniouASTExporter" "PREPEND_CURRENT_DIR=1"
"-plugin-arg-BiniouASTExporter" "MAX_STRING_SIZE=65535" "-cc1" "-triple"
"x86_64-unknown

... [truncated 1109 characters] ...

ins/clang/install/lib/clang/18/include"
"-internal-isystem" "/usr/local/include" "-internal-isystem"
"/usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/include"
"-internal-externc-isystem" "/usr/include/x86_64-linux-gnu"
"-internal-externc-isystem" "/include" "-internal-externc-isystem"
"/usr/include" "-Wno-ignored-optimization-argument" "-Wno-everything"
"-fdeprecated-macro" "-ferror-limit" "19" "-fgnuc-version=4.2.1"
"-fskip-odr-check-in-gmf" "-fcxx-exceptions" "-fexceptions"
"-D__GCC_HAVE_DWARF2_CFI_ASM=1" "-o"
"/tmp/coderabbit-infer/be72817c5bbcbe6a/file.o" "-x" "c++"
"src/component.cpp" "-O0" "-fno-builtin" "-include"
"/opt/infer-linux-x86_64-v1.2.0/lib/infer/infer/bin/../lib/clang_wrappers/global_defines.h"
"-Wno-everything"

src/kernel/auto_aim.cpp

In file included from src/kernel/auto_aim.cpp:1:
src/kernel/auto_aim.hpp:3:10: fatal error: 'utility/pimpl.hpp' file not found
3 | #include "utility/pimpl.hpp"
| ^~~~~~~~~~~~~~~~~~~
1 error generated.
Error: the following clang command did not run successfully:
/opt/infer-linux-x86_64-v1.2.0/lib/infer/facebook-clang-plugins/clang/install/bin/clang-18
@/tmp/coderabbit-infer/860d01b67c22f5a1a9f7e6b2762bf308693eaa61-a02f5f9dad849261/tmp/clang_command_.tmp.96599b.txt
++Contents of '/tmp/coderabbit-infer/860d01b67c22f5a1a9f7e6b2762bf308693eaa61-a02f5f9dad849261/tmp/clang_command_.tmp.96599b.txt':
"-cc1" "-load"
"/opt/infer-linux-x86_64-v1.2.0/lib/infer/infer/bin/../../facebook-clang-plugins/libtooling/build/FacebookClangPlugin.dylib"
"-add-plugin" "BiniouASTExporter" "-plugin-arg-BiniouASTExporter" "-"
"-plugin-arg-BiniouASTExporter" "PREPEND_CURRENT_DIR=1"
"-plugin-arg-BiniouASTExporter" "MAX_STRING_SIZE=65535" "-cc1" "-triple"
"x86_64-u

... [truncated 1120 characters] ...

ang/install/lib/clang/18/include"
"-internal-isystem" "/usr/local/include" "-internal-isystem"
"/usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/include"
"-internal-externc-isystem" "/usr/include/x86_64-linux-gnu"
"-internal-externc-isystem" "/include" "-internal-externc-isystem"
"/usr/include" "-Wno-ignored-optimization-argument" "-Wno-everything"
"-fdeprecated-macro" "-ferror-limit" "19" "-fgnuc-version=4.2.1"
"-fskip-odr-check-in-gmf" "-fcxx-exceptions" "-fexceptions"
"-D__GCC_HAVE_DWARF2_CFI_ASM=1" "-o"
"/tmp/coderabbit-infer/a02f5f9dad849261/file.o" "-x" "c++"
"src/kernel/auto_aim.cpp" "-O0" "-fno-builtin" "-include"
"/opt/infer-linux-x86_64-v1.2.0/lib/infer/infer/bin/../lib/clang_wrappers/global_defines.h"
"-Wno-everything"

src/kernel/fire_control.cpp

In file included from src/kernel/fire_control.cpp:1:
src/kernel/fire_control.hpp:4:10: fatal error: 'yaml-cpp/yaml.h' file not found
4 | #include <yaml-cpp/yaml.h>
| ^~~~~~~~~~~~~~~~~
1 error generated.
Error: the following clang command did not run successfully:
/opt/infer-linux-x86_64-v1.2.0/lib/infer/facebook-clang-plugins/clang/install/bin/clang-18
@/tmp/coderabbit-infer/860d01b67c22f5a1a9f7e6b2762bf308693eaa61-76a2d0b06e8be3a5/tmp/clang_command_.tmp.813f6f.txt
++Contents of '/tmp/coderabbit-infer/860d01b67c22f5a1a9f7e6b2762bf308693eaa61-76a2d0b06e8be3a5/tmp/clang_command_.tmp.813f6f.txt':
"-cc1" "-load"
"/opt/infer-linux-x86_64-v1.2.0/lib/infer/infer/bin/../../facebook-clang-plugins/libtooling/build/FacebookClangPlugin.dylib"
"-add-plugin" "BiniouASTExporter" "-plugin-arg-BiniouASTExporter" "-"
"-plugin-arg-BiniouASTExporter" "PREPEND_CURRENT_DIR=1"
"-plugin-arg-BiniouASTExporter" "MAX_STRING_SIZE=65535" "-cc1" "-triple"
"x86_64

... [truncated 1130 characters] ...

install/lib/clang/18/include"
"-internal-isystem" "/usr/local/include" "-internal-isystem"
"/usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/include"
"-internal-externc-isystem" "/usr/include/x86_64-linux-gnu"
"-internal-externc-isystem" "/include" "-internal-externc-isystem"
"/usr/include" "-Wno-ignored-optimization-argument" "-Wno-everything"
"-fdeprecated-macro" "-ferror-limit" "19" "-fgnuc-version=4.2.1"
"-fskip-odr-check-in-gmf" "-fcxx-exceptions" "-fexceptions"
"-D__GCC_HAVE_DWARF2_CFI_ASM=1" "-o"
"/tmp/coderabbit-infer/76a2d0b06e8be3a5/file.o" "-x" "c++"
"src/kernel/fire_control.cpp" "-O0" "-fno-builtin" "-include"
"/opt/infer-linux-x86_64-v1.2.0/lib/infer/infer/bin/../lib/clang_wrappers/global_defines.h"
"-Wno-everything"

  • 6 others

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 and usage tips.

@creeper5820 creeper5820 requested a review from heyeuu June 10, 2026 00:06

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (4)
src/component.cpp (1)

73-73: 💤 Low value

可选:记录过时指令的丢弃情况

当指令时间戳超过 100ms 时会被静默丢弃。如果指令频繁过时,可能表明性能瓶颈。建议添加周期性日志或计数器以便诊断:

if (Clock::now() - cmd.timestamp > 100ms) {
    // 可选:添加速率限制的警告日志
    // static auto last_warn = Clock::now();
    // if (Clock::now() - last_warn > 5s) {
    //     logger.warn("Discarding stale command (age: {}ms)", ...);
    //     last_warn = Clock::now();
    // }
    return;
}

这有助于在调试时发现组件更新频率不匹配的问题。

🤖 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 `@src/component.cpp` at line 73, Currently stale commands are silently dropped
when Clock::now() - cmd.timestamp > 100ms; add a rate-limited diagnostic to
surface frequent drops by incrementing a counter or emitting a periodic warning.
Locate the check using Clock::now() and cmd.timestamp in the handler (the if
that returns on >100ms) and implement either a static timestamp (e.g.,
last_warn) or a counter with a time window to call logger.warn("Discarding stale
command (age: {}ms)", age) only every few seconds (or when a threshold count is
reached), or increment a metrics counter so operators can detect frequent
stale-command drops.
src/kernel/auto_aim.cpp (1)

159-159: ⚡ Quick win

建议显式转换信号处理函数

当前使用无捕获 lambda 作为信号处理器,可以隐式转换为函数指针。为提高可读性和明确意图,建议使用一元 + 运算符显式转换:

-std::signal(SIGINT, [](int) { util::set_running(false); });
+std::signal(SIGINT, +[](int) { util::set_running(false); });

或者使用 extern "C" 函数以确保 C 链接:

extern "C" void sigint_handler(int) {
    util::set_running(false);
}
std::signal(SIGINT, sigint_handler);
🤖 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 `@src/kernel/auto_aim.cpp` at line 159, The current call std::signal(SIGINT,
[](int){ util::set_running(false); }) relies on implicit conversion of a
no-capture lambda to a function pointer; change it to an explicit conversion or
a C-linkage handler to make intent clear and safe: either use the unary +
operator to convert the lambda to a function pointer when passing to
std::signal, or replace the lambda with an extern "C" function (e.g.,
sigint_handler) that calls util::set_running(false) and pass that to
std::signal; update the signal registration accordingly to reference
std::signal, SIGINT, the converted lambda or sigint_handler.
src/kernel/auto_aim.hpp (1)

15-27: 💤 Low value

可选:考虑允许回调返回值

当前 with_contextwith_command 的返回类型为 auto(推导为 void),回调函数的返回值被丢弃。如果希望支持从回调中提取数据的用例,可以改为返回回调的结果:

template <typename WithFunc>
    requires std::invocable<WithFunc, SystemContext&>
auto with_context(WithFunc&& func) -> decltype(auto) {
    std::lock_guard lock(context_mutex);
    return func(current_context);
}

template <typename WithFunc>
    requires std::invocable<WithFunc, const AutoAimState&>
auto with_command(WithFunc&& func) -> decltype(auto) {
    std::lock_guard lock(command_mutex);
    return func(current_command);
}

这样调用方可以选择返回值或仅执行副作用。当前设计仅用于副作用也是合理的,此建议为可选改进。

🤖 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 `@src/kernel/auto_aim.hpp` around lines 15 - 27, with_context and with_command
currently discard the callback return value (they deduce to void); change both
to return the callback result by using a trailing return type -> decltype(auto)
and returning func(...) while still holding the lock (for with_context: use
decltype(auto) return, lock context_mutex, return func(current_context); for
with_command: use decltype(auto) return, lock command_mutex, return
func(current_command)); keep the existing requires constraints
(std::invocable<WithFunc, SystemContext&> and std::invocable<WithFunc, const
AutoAimState&>) and the same mutex/variable names to locate the change.
src/module/fire_control/aim_point_chooser.hpp (1)

3-13: ⚡ Quick win

多个头文件存在同一根因:include 分组顺序不符合仓库约定。

以上位置都应统一为“本地头文件 → 标准库 → 第三方库”,并用空行分组;这是同一规范问题,建议一次性批量修正,避免后续冲突和风格漂移。

As per coding guidelines, “Header files should follow the order: local headers, standard library, third-party libraries, with blank lines separating these groups”。

🤖 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 `@src/module/fire_control/aim_point_chooser.hpp` around lines 3 - 13, The
include order in aim_point_chooser.hpp violates the project's grouping
convention; reorder the `#include` lines so local headers (e.g.
"utility/pimpl.hpp", "utility/robot/armor.hpp") come first, then C++ standard
library headers (e.g. <expected>, <optional>, <span>, <string>), and finally
third‑party/externals (e.g. <eigen3/Eigen/Core>, <yaml-cpp/yaml.h>), with a
blank line between each group; apply the same grouped ordering consistently to
any other files that use these headers to avoid style drift.

Source: Coding guidelines

🤖 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 `@src/component.cpp`:
- Around line 59-60: The pitch sign is inconsistent between visualization and
control: ensure you document or align the convention by either removing the
negation in visual.update_aiming_direction(-cmd.pitch) or explicitly explaining
the reason for the flip; add a clear comment in src/component.cpp around
ctx.pitch and where ctx.yaw is passed to fire.solve describing the chosen
Z-axis/pitch sign convention, and add matching comments in
trajectory_solution.cpp (where pitch = std::atan2(target_h, target_d) produces
result->pitch) and in src/kernel/auto_aim.cpp
(visual.update_aiming_direction(cmd.yaw, -cmd.pitch)) that state how
/auto_aim/barrel_direction and aim_point/target_position.z define positive Z and
why visualization negates pitch, so future readers know whether to flip or not
and avoid semantic mismatches.

---

Nitpick comments:
In `@src/component.cpp`:
- Line 73: Currently stale commands are silently dropped when Clock::now() -
cmd.timestamp > 100ms; add a rate-limited diagnostic to surface frequent drops
by incrementing a counter or emitting a periodic warning. Locate the check using
Clock::now() and cmd.timestamp in the handler (the if that returns on >100ms)
and implement either a static timestamp (e.g., last_warn) or a counter with a
time window to call logger.warn("Discarding stale command (age: {}ms)", age)
only every few seconds (or when a threshold count is reached), or increment a
metrics counter so operators can detect frequent stale-command drops.

In `@src/kernel/auto_aim.cpp`:
- Line 159: The current call std::signal(SIGINT, [](int){
util::set_running(false); }) relies on implicit conversion of a no-capture
lambda to a function pointer; change it to an explicit conversion or a C-linkage
handler to make intent clear and safe: either use the unary + operator to
convert the lambda to a function pointer when passing to std::signal, or replace
the lambda with an extern "C" function (e.g., sigint_handler) that calls
util::set_running(false) and pass that to std::signal; update the signal
registration accordingly to reference std::signal, SIGINT, the converted lambda
or sigint_handler.

In `@src/kernel/auto_aim.hpp`:
- Around line 15-27: with_context and with_command currently discard the
callback return value (they deduce to void); change both to return the callback
result by using a trailing return type -> decltype(auto) and returning func(...)
while still holding the lock (for with_context: use decltype(auto) return, lock
context_mutex, return func(current_context); for with_command: use
decltype(auto) return, lock command_mutex, return func(current_command)); keep
the existing requires constraints (std::invocable<WithFunc, SystemContext&> and
std::invocable<WithFunc, const AutoAimState&>) and the same mutex/variable names
to locate the change.

In `@src/module/fire_control/aim_point_chooser.hpp`:
- Around line 3-13: The include order in aim_point_chooser.hpp violates the
project's grouping convention; reorder the `#include` lines so local headers (e.g.
"utility/pimpl.hpp", "utility/robot/armor.hpp") come first, then C++ standard
library headers (e.g. <expected>, <optional>, <span>, <string>), and finally
third‑party/externals (e.g. <eigen3/Eigen/Core>, <yaml-cpp/yaml.h>), with a
blank line between each group; apply the same grouped ordering consistently to
any other files that use these headers to avoid style drift.
🪄 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: 295d6e36-cdf2-4618-aca9-c902c2065afe

📥 Commits

Reviewing files that changed from the base of the PR and between 933504c and 860d01b.

📒 Files selected for processing (28)
  • CMakeLists.txt
  • README.md
  • config/config.yaml
  • doc/streaming.md
  • launch/launch.py
  • src/adapter/adapter.hpp
  • src/adapter/deformable-infantry.hpp
  • src/adapter/sentry.hpp
  • src/component.cpp
  • src/kernel/auto_aim.cpp
  • src/kernel/auto_aim.hpp
  • src/kernel/fire_control.cpp
  • src/kernel/fire_control.hpp
  • src/module/fire_control/aim_point_chooser.hpp
  • src/module/fire_control/shoot_evaluator.hpp
  • src/module/fire_control/solver/aim_point_sampling.cpp
  • src/module/fire_control/solver/aim_point_sampling.hpp
  • src/module/fire_control/solver/target_solution_solver.cpp
  • src/module/fire_control/solver/target_solution_solver.hpp
  • src/module/fire_control/trajectory_solution.hpp
  • src/module/predictor/outpost/snapshot.cpp
  • src/module/predictor/outpost/snapshot.hpp
  • src/module/predictor/regular/snapshot.cpp
  • src/module/predictor/regular/snapshot.hpp
  • src/module/predictor/snapshot.cpp
  • src/module/predictor/snapshot.hpp
  • src/runtime.cpp
  • src/utility/math/solve_armors.cpp
💤 Files with no reviewable changes (6)
  • src/adapter/sentry.hpp
  • launch/launch.py
  • src/runtime.cpp
  • src/adapter/deformable-infantry.hpp
  • src/adapter/adapter.hpp
  • CMakeLists.txt

Comment thread src/component.cpp
Comment on lines +59 to +60
ctx.yaw = std::atan2(dir.y(), dir.x());
ctx.pitch = std::atan2(-dir.z(), std::hypot(dir.x(), dir.y()));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# 查找 pitch 计算、赋值和使用的位置,检查符号一致性
rg -n -C3 'pitch\s*=' --type=cpp
rg -n -C3 'atan2.*dir\.z\(\)' --type=cpp  
rg -n -C3 'sin\(.*pitch\)' --type=cpp

Repository: Alliance-Algorithm/rmcs_auto_aim_v2

Length of output: 15695


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# 1) 定位可视化阶段是否存在 -cmd.pitch
rg -n --type=cpp 'update_aiming_direction\(([^)]*)\)' src/kernel/auto_aim.cpp
rg -n --type=cpp '\b-\s*cmd\.pitch\b' src/kernel/auto_aim.cpp

# 2) 精确定位从 yaw/pitch 重建方向向量处是否有 std::sin(pitch) 以及是否额外取反
rg -n --type=cpp 'std::sin\(\s*pitch\s*\)' src/component.cpp
rg -n --type=cpp 'target_direction\s*\=\s*Eigen::Vector3d' -S src/component.cpp
sed -n '70,120p' src/component.cpp

# 3) 在 component.cpp 中核对 ctx.pitch 的符号约定是否还有其他地方会再取反/归一化
rg -n --type=cpp 'ctx\.pitch\s*=' src/component.cpp
rg -n --type=cpp '\bcmd\.pitch\b' src/component.cpp

Repository: Alliance-Algorithm/rmcs_auto_aim_v2

Length of output: 156


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Find all pitch reconstruction / sign usage in component.cpp
rg -n --type=cpp '\bcmd\.pitch\b' src/kernel/auto_aim.cpp src/component.cpp
rg -n --type=cpp 'update_aiming_direction\(' src/kernel/auto_aim.cpp
rg -n --type=cpp 'std::sin\(\s*pitch\s*\)' src/component.cpp src/utility/math/conversion.hpp src/module/fire_control/trajectory_solution.cpp

# Show the exact target_direction reconstruction block in component.cpp
rg -n --type=cpp -C3 'target_direction\s*\=\s*Eigen::Vector3d' src/component.cpp
sed -n '40,120p' src/component.cpp

# Show where ctx.pitch is later used
rg -n --type=cpp '\bctx\.pitch\b' src/component.cpp

Repository: Alliance-Algorithm/rmcs_auto_aim_v2

Length of output: 906


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Show full relevant blocks in src/component.cpp
sed -n '40,115p' src/component.cpp
sed -n '115,190p' src/component.cpp

# Show visual update block in src/kernel/auto_aim.cpp
sed -n '110,175p' src/kernel/auto_aim.cpp

# Also capture any conversion helpers that relate pitch<->z sign
rg -n --type=cpp 'atan2\(\s*-\s*.*z' src/utility/math src/component.cpp src/kernel src/module
rg -n --type=cpp 'atan2\(\s*.*z\s*,' src/utility/math src/component.cpp src/kernel src/module

Repository: Alliance-Algorithm/rmcs_auto_aim_v2

Length of output: 5707


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# 1) Find implementation of update_aiming_direction
rg -n --type=cpp 'update_aiming_direction\s*\(' src

# 2) Trace target_direction usage (where the reconstructed vector is consumed)
rg -n --type=cpp '\btarget_direction\b' src/component.cpp src/kernel src/module src/utility

# 3) Inspect AutoAimState.pitch usage in solver path
rg -n --type=cpp '\bresult->pitch\b' src/kernel src/module src/utility
rg -n --type=cpp '\bcmd\.pitch\b' src/kernel/auto_aim.cpp src/component.cpp src/module

Repository: Alliance-Algorithm/rmcs_auto_aim_v2

Length of output: 1329


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect visualization pitch usage
sed -n '150,260p' src/kernel/visualization.cpp
sed -n '1,120p' src/kernel/visualization.hpp

# Trace where the output `/auto_aim/control_direction` is consumed
rg -n --type=cpp 'control_direction' src
rg -n --type=cpp '\btarget_direction\b' src

# Also inspect component.cpp near registration and full computation block
sed -n '1,120p' src/component.cpp
sed -n '120,220p' src/component.cpp

Repository: Alliance-Algorithm/rmcs_auto_aim_v2

Length of output: 9504


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Topic/path consumers of the control direction output
rg -n --type=cpp '"/auto_aim/control_direction"' src
rg -n --type=cpp 'control_direction' src

# Find how Euler pitch is interpreted when converting to quaternion
rg -n --type=cpp 'euler_to_quaternion\(' src/kernel/visualization.cpp src/kernel/visualization.hpp src/kernel

# Show the relevant helper implementation near euler_to_quaternion
rg -n --type=cpp 'euler_to_quaternion' src/kernel/visualization.cpp
sed -n '1,140p' src/kernel/visualization.cpp

Repository: Alliance-Algorithm/rmcs_auto_aim_v2

Length of output: 5405


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# 1) Find euler_to_quaternion definition/implementation
rg -n --type=cpp 'euler_to_quaternion\s*\(' src/utility src/kernel

# 2) Inspect mpc plan visualizer pitch handling
rg -n --type=cpp 'publish_planned_pitch|planned_pitch|mpc_plan' src/module src/kernel
sed -n '1,240p' src/module/debug/visualization/mpc_plan_visualizer.hpp
sed -n '1,260p' src/module/debug/visualization/mpc_plan_visualizer.cpp 2>/dev/null || true
# if cpp doesn't exist, list by name
ls -la src/module/debug/visualization || true

# 3) Trace how result->pitch is computed
# Look for struct fields named pitch in fire_control solver outputs
rg -n --type=cpp '\.pitch\s*=' src/module/fire_control src/kernel src/component.cpp
rg -n --type=cpp 'Result\s*\{[^}]*pitch|pitch\s*=' src/module/fire_control src/kernel

# 4) Inspect the immediate pitch computation helper used by trajectory solution
sed -n '1,120p' src/module/fire_control/trajectory_solution.cpp

Repository: Alliance-Algorithm/rmcs_auto_aim_v2

Length of output: 10657


🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n --type=cpp '\bcontext\.pitch\b' src/kernel
rg -n --type=cpp '\bctx\.pitch\b' src/kernel
rg -n --type=cpp '\bSystemContext\b' src/kernel
rg -n --type=cpp '\.pitch\s*\+' src/kernel

Repository: Alliance-Algorithm/rmcs_auto_aim_v2

Length of output: 61


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# 1) Show euler_to_quaternion implementation (pitch sign)
sed -n '120,220p' src/utility/math/conversion.hpp

# 2) Look for any documentation/comments about barrel_direction / coordinate frame
rg -n --type=cpp 'barrel_direction|control_direction|aiming_direction|dir\.z\(|pitch.*z|Z.*axis' src/component.cpp src/kernel src/utility | head -n 200

# 3) Confirm target_direction consumers (if none, we can’t fully conclude runtime impact)
rg -n --type=cpp '/auto_aim/control_direction' src || true

Repository: Alliance-Algorithm/rmcs_auto_aim_v2

Length of output: 4420


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Search how SystemContext is used in auto_aim / fire_control
rg -n --type=cpp 'context\.pitch|context\.yaw|SystemContext' src/kernel/auto_aim.cpp src/kernel/fire_control.cpp src/kernel/pose_estimator.cpp

# Search if control_direction output is consumed in this repo
rg -n --type=cpp 'control_direction' src

# Inspect fire_control.cpp signature/logic around solve
sed -n '1,220p' src/kernel/fire_control.cpp

Repository: Alliance-Algorithm/rmcs_auto_aim_v2

Length of output: 7014


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Find producers/other uses of barrel_direction topic
rg -n --type=cpp '(/auto_aim/barrel_direction)' src

# Track where target_position comes from (coordinate frame / z definition)
rg -n --type=cpp '\btarget_position\b' src/kernel src/module src/utility

# Also check for comments/transform definitions around z-axis conventions
rg -n --type=cpp 'Z.*axis|z.*axis|dir\.z\(|target_h|impact_pitch' src | head -n 200

Repository: Alliance-Algorithm/rmcs_auto_aim_v2

Length of output: 2347


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect where pitch sign enters in aim_point_sampling and target_solution_solver
sed -n '1,220p' src/module/fire_control/solver/aim_point_sampling.cpp
sed -n '1,220p' src/module/fire_control/solver/target_solution_solver.cpp
sed -n '1,240p' src/module/fire_control/solver/target_solution_solver.hpp
sed -n '1,260p' src/module/fire_control/solver/aim_point_sampling.hpp 2>/dev/null || true

# Inspect AimAttitude / pitch reconstruction types
rg -n --type=cpp 'struct AimAttitude|AimAttitude' src/module/fire_control -S
rg -n --type=cpp 'pitch\s*\{' src/module/fire_control/solver src/module/fire_control/planner src/module/fire_control/shoot_evaluator -S

# Inspect how target_position.z is defined via aim_point
sed -n '1,240p' src/module/fire_control/solver/aim_point_sampling.cpp

Repository: Alliance-Algorithm/rmcs_auto_aim_v2

Length of output: 8845


澄清:pitch 符号不一致风险主要出在“可视化”,控制/target_direction 没有再次取反

  • src/component.cpp 里虽然计算了 ctx.pitch = std::atan2(-dir.z(), std::hypot(dir.x(), dir.y())),但下游控制只使用 context.yaw 传给 fire.solvectx.pitch 不参与控制计算链路。
  • 俯仰角控制链路中未再对 pitch 取反:trajectory_solution.cpppitch = std::atan2(target_h, target_d)target_h = target_position.z())得到 result->pitch,随后 src/component.cpp 重建 target_direction.z = std::sin(pitch)
  • 仅“可视化箭头”做了额外符号翻转:src/kernel/auto_aim.cpp 调用 visual.update_aiming_direction(cmd.yaw, -cmd.pitch)。这意味着可视化坐标系/俯仰角正方向与控制/target_direction 的约定存在差异。

建议补充注释说明为什么可视化对 pitch 要取反(或直接对齐:移除 -cmd.pitch),并在注释中写清 /auto_aim/barrel_direction 与预测 aim_point/target_position.z 的坐标系(尤其 Z 轴正方向)约定,避免模块间语义误读。

🤖 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 `@src/component.cpp` around lines 59 - 60, The pitch sign is inconsistent
between visualization and control: ensure you document or align the convention
by either removing the negation in visual.update_aiming_direction(-cmd.pitch) or
explicitly explaining the reason for the flip; add a clear comment in
src/component.cpp around ctx.pitch and where ctx.yaw is passed to fire.solve
describing the chosen Z-axis/pitch sign convention, and add matching comments in
trajectory_solution.cpp (where pitch = std::atan2(target_h, target_d) produces
result->pitch) and in src/kernel/auto_aim.cpp
(visual.update_aiming_direction(cmd.yaw, -cmd.pitch)) that state how
/auto_aim/barrel_direction and aim_point/target_position.z define positive Z and
why visualization negates pitch, so future readers know whether to flip or not
and avoid semantic mismatches.

Comment thread src/component.cpp
register_output("/auto_aim/should_control", should_control, false);
register_output("/auto_aim/control_direction", target_direction, Eigen::Vector3d::Zero());
register_output("/auto_aim/robot_center", robot_center, kVectorNaN);
register_output("/auto_aim/robot_center", robot_center, Eigen::Vector3d::Zero());

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

还是用 NaN 来做默认值吧

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.

2 participants