Skip to content

Fix/roi offset correction - #33

Merged
creeper5820 merged 4 commits into
mainfrom
fix/roi-offset-correction
Mar 11, 2026
Merged

Fix/roi offset correction#33
creeper5820 merged 4 commits into
mainfrom
fix/roi-offset-correction

Conversation

@heyeuu

@heyeuu heyeuu commented Mar 11, 2026

Copy link
Copy Markdown
Member

ROI偏移校正修复

概述

本PR修复并统一了装甲板检测中的ROI偏移校正机制,用roi_offset替代原先的按角落校正方式;同时对可视化组件与运行时流程进行了重构,并调整了若干配置与测试以支持ROI分段处理。

关键变更

装甲检测逻辑(src/module/identifier/armor_detection.cpp)

  • 移除配置项 use_corner_correction(不再在Config/YAML中暴露)。
  • 新增并暴露 roi_offset(cv::Point2f),默认 {0.f,0.f},在选中ROI时设为ROI左上角偏移。
  • StaticExplainFunctor 构造与说明逻辑更新,接受 roi_offset 并在推理说明时将统一缩放后的四角坐标加上该偏移。
  • 在进行ROI分割前重置 roi_offset;当使用ROI分割时对输入裁剪并保存offset以便恢复坐标到原图空间。

可视化重构(src/kernel/visualization.cpp)

  • 将单一 armor_visualizer 拆分为 solved_pnp_visualizer 与 predicted_visualizer,分别用于可视化PNP解算结果与预测结果。
  • 初始化与 visualize 调用相应分流,帧发送流程保持一致。

运行时重建(src/runtime.cpp)

  • 重新组织并恢复完整运行时流程:构建并初始化 Feishu、Capturer、Identifier、Tracker、PoseEstimator、FireControl、Visualization、ActionThrottler 等组件。
  • 恢复主处理循环(抓帧、识别、PNP 变换、追踪、发射控制与状态传输、可选可视化等)并加入统一的配置读取与错误处理逻辑。
  • 通过model_location拼接/解析Identifier所需模型路径。

配置调整(config/config.yaml)

  • local_video.location: solve_pnp_v2.mp4 → translation.mp4
  • score_threshold: 0.7 → 0.8
  • nms_threshold: 0.3 → 0.45
  • tracker.enemy_color: red → blue
  • 移除了 identifier.use_corner_correction 条目

测试更新(test/model_infer.cpp & test/solve_pnp.cpp)

  • test/model_infer.cpp:
    • 为断言/测试增加 use_roi_segment 参数以支持ROI分段模式。
    • 移除测试内的ROI偏移计算,直接使用装甲坐标。
    • 匹配阈值从4.0提高到8.0。
    • 新增 TEST(model, sync_infer_with_roi_segment) 用例。
    • 调整函数签名以支持 use_roi_segment(默认false)。
  • test/solve_pnp.cpp:移除配置行 use_corner_correction: false

其他小改动

  • src/utility/rclcpp/visual/armor.cpp:删除了对未知设备ID触发panic的分支,改为不抛出异常地继续(可能导致marker scale未设置)。

影响范围

  • 装甲检测的坐标校正与ROI处理(核心改动,可能影响定位精度与下游PNP/追踪流程)。
  • 运行时初始化与主循环(恢复并重构,需关注启动/错误处理路径)。
  • 可视化输出组织(拆分后的可视化器影响调试/展示)。
  • 测试覆盖(新增ROI分段场景,阈值放宽)。

@heyeuu heyeuu self-assigned this Mar 11, 2026
@heyeuu heyeuu added the bug Something isn't working label Mar 11, 2026
@heyeuu heyeuu linked an issue Mar 11, 2026 that may be closed by this pull request
@coderabbitai

coderabbitai Bot commented Mar 11, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ed034b0c-1e22-46b0-91b3-281994ccb9b1

📥 Commits

Reviewing files that changed from the base of the PR and between 7c1daf8 and 451a943.

📒 Files selected for processing (1)
  • src/utility/rclcpp/visual/armor.cpp
💤 Files with no reviewable changes (1)
  • src/utility/rclcpp/visual/armor.cpp

Walkthrough

本PR恢复并重组运行时主循环,拆分装甲可视化为 solved_pnp 与 predicted 两个可视化器,引入并传播 ROI 偏移以修正裁剪坐标,调整配置参数并更新相关单元测试与少量可视化错误处理行为。

Changes

Cohort / File(s) Summary
配置参数调整
config/config.yaml
更改本地视频文件、移除 identifier.use_corner_correction、调整 score_threshold(0.7→0.8)、nms_threshold(0.3→0.45)及 tracker.enemy_color(red→blue)。
可视化重构
src/kernel/visualization.cpp
将单一 armor_visualizer 拆为 solved_pnp_visualizerpredicted_visualizer,分别可视化 PNP 求解与预测结果,相关调用点重定向。
ROI 偏移与装甲检测
src/module/identifier/armor_detection.cpp
移除 use_corner_correction,在 Impl 中新增 roi_offset(cv::Point2f),将其纳入 explain functor 与推理/分割流程以在 ROI 模式下修正坐标回退。
运行时流程重新组织
src/runtime.cpp
重建运行时初始化与主循环(构建各组件:Capturer/Identifier/Tracker/PoseEstimator/FireControl/Visualization/Throttler),恢复图像采集→检测→PNP→跟踪→火控→可视化的端到端流程与错误处理。
可视化容错调整
src/utility/rclcpp/visual/armor.cpp
移除对未知设备 id 的 panic 分支,改为无操作(不再在此处抛错)。
测试调整
test/model_infer.cpp, test/solve_pnp.cpp
为推理断言添加 use_roi_segment 参数并新增 ROI 测试,移除内置 ROI 偏移计算,提高角点匹配阈值(4.0→8.0),并删除测试中对 use_corner_correction 的显式设置。

Sequence Diagram

sequenceDiagram
    participant Capturer
    participant Identifier
    participant PoseEstimator
    participant Tracker
    participant FireControl
    participant Visualization
    participant Throttler

    Capturer->>Identifier: 获取帧
    Identifier->>Identifier: 检测 2D 装甲
    Identifier->>PoseEstimator: 提供 2D 装甲进行 PNP 求解
    PoseEstimator->>Visualization: 可视化 solved_pnp_armors
    Identifier->>Visualization: 可视化 predicted_armors
    Tracker->>Tracker: 应用跟踪逻辑
    Tracker->>Throttler: 请求节流决策
    FireControl->>FireControl: 计算开火命令
    FireControl->>Capturer: 发送/执行开火指令
    Visualization->>Visualization: 更新并发送可视化帧
Loading

Estimated Code Review Effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • creeper5820

"我是一只代码兔,蹦进变更林,
拆解可视化,缝补 ROI 心,
运行时回归热闹非凡,
测试随身验证每一步印,
啪嗒一跳,功能又新鲜 🐇✨"

🚥 Pre-merge checks | ✅ 2 | ❌ 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 (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR标题'Fix/roi offset correction'清晰指向主要改动:修复ROI偏移校正问题,与大量代码变更(armor_detection.cpp中的roi_offset实现、model_infer.cpp中的ROI分段支持等)直接相关。

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

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/roi-offset-correction

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.

@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

Caution

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

⚠️ Outside diff range comments (1)
src/module/identifier/armor_detection.cpp (1)

117-127: ⚠️ Potential issue | 🟡 Minor

noexcept 函数中存在潜在的异常风险。

静态分析工具指出 explain 函数声明为 noexcept,但 final_result.push_back(armor) 在内存分配失败时可能抛出 std::bad_alloc。虽然在实际运行中发生的概率较低,但这违反了 noexcept 的契约。

♻️ 建议的修复方案

方案一:移除 noexcept 声明(推荐)

-        auto explain(ov::InferRequest& finished_request) const noexcept -> Armor2Ds override {
+        auto explain(ov::InferRequest& finished_request) const -> Armor2Ds override {

方案二:使用 reserve 预分配内存减少异常风险(已存在于 line 115)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/module/identifier/armor_detection.cpp` around lines 117 - 127, The
function explain is declared noexcept but can throw when pushing into
final_result (final_result.push_back(armor)) if allocation fails; remove the
noexcept specifier from the explain function declaration/definition so the
function can propagate std::bad_alloc, or alternatively ensure final_result
cannot allocate (e.g. pre-reserve sufficient capacity before the loop where
kept_points is used), but the preferred fix is to drop noexcept on explain;
locate explain and its signature and update it accordingly (also adjust any
callers or exception-safety contracts if necessary).
🧹 Nitpick comments (2)
src/runtime.cpp (2)

196-203: 条件判断可以简化。

armors_3d 在 187 行已经检查过一次(用于可视化),然后在 196 行再次检查。可以合并逻辑以减少重复判断。

♻️ 建议的简化
-                if (armors_3d) {
-                    auto transform = control_state.odom_to_camera_transform;
-                    pose_estimator.set_odom_to_camera_transform(transform);
-
-                    armors_3d = pose_estimator.odom_to_camera(*armors_3d);
-                } else {
+                if (!armors_3d) {
                     continue;
                 }
+                auto transform = control_state.odom_to_camera_transform;
+                pose_estimator.set_odom_to_camera_transform(transform);
+                armors_3d = pose_estimator.odom_to_camera(*armors_3d);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/runtime.cpp` around lines 196 - 203, The code redundantly checks
armors_3d twice; simplify by merging the logic so the earlier null/empty check
(the one used for visualization) also performs the odom-to-camera transform
step: when armors_3d is valid, grab control_state.odom_to_camera_transform, call
pose_estimator.set_odom_to_camera_transform(transform) and then replace
armors_3d with pose_estimator.odom_to_camera(*armors_3d); otherwise skip both
visualization and transform steps. Update the block around the existing
armors_3d usage to remove the second if/else and ensure only one presence check
controls both visualization and the calls to set_odom_to_camera_transform and
odom_to_camera.

150-155: std::ignore = stream_guard 是多余的。

scope_exit 对象会在作用域结束时自动执行,无需显式使用 std::ignore 来"使用"它。编译器警告(如果有)可以通过 [[maybe_unused]] 属性来抑制。

♻️ 建议的简化
-                auto stream_guard = std::experimental::scope_exit { [&] {
+                [[maybe_unused]] auto stream_guard = std::experimental::scope_exit { [&] {
                     if (visualization.initialized()) {
                         visualization.send_image(*image);
                     }
                 } };
-                std::ignore = stream_guard;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/runtime.cpp` around lines 150 - 155, Remove the redundant "std::ignore =
stream_guard" statement and instead mark the scope_exit variable to avoid
unused-variable warnings; replace "auto stream_guard =
std::experimental::scope_exit { [&] { ... } };" with "[[maybe_unused]] auto
stream_guard = std::experimental::scope_exit { [&] { if
(visualization.initialized()) visualization.send_image(*image); } };" so the
scope guard (stream_guard) still runs at scope exit but does not require the
unnecessary std::ignore assignment.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/utility/rclcpp/visual/armor.cpp`:
- Around line 50-53: marker.scale is left uninitialized when config.device is
not kSmallArmor() or kLargeArmor(), causing unpredictable marker sizes;
initialize a safe default scale and log a warning in that branch. Update the
else branch handling config.device (where marker and config.device are used in
src/utility/rclcpp/visual/armor.cpp) to set marker.scale to a sensible default
(e.g., a fallback size) and emit a warning via the existing logging facility (or
std::cerr) so unknown devices (AERIAL, DART, RADAR, UNKNOWN) produce a
deterministic marker; alternatively initialize marker.scale to the default
before the conditional so all paths are covered.

---

Outside diff comments:
In `@src/module/identifier/armor_detection.cpp`:
- Around line 117-127: The function explain is declared noexcept but can throw
when pushing into final_result (final_result.push_back(armor)) if allocation
fails; remove the noexcept specifier from the explain function
declaration/definition so the function can propagate std::bad_alloc, or
alternatively ensure final_result cannot allocate (e.g. pre-reserve sufficient
capacity before the loop where kept_points is used), but the preferred fix is to
drop noexcept on explain; locate explain and its signature and update it
accordingly (also adjust any callers or exception-safety contracts if
necessary).

---

Nitpick comments:
In `@src/runtime.cpp`:
- Around line 196-203: The code redundantly checks armors_3d twice; simplify by
merging the logic so the earlier null/empty check (the one used for
visualization) also performs the odom-to-camera transform step: when armors_3d
is valid, grab control_state.odom_to_camera_transform, call
pose_estimator.set_odom_to_camera_transform(transform) and then replace
armors_3d with pose_estimator.odom_to_camera(*armors_3d); otherwise skip both
visualization and transform steps. Update the block around the existing
armors_3d usage to remove the second if/else and ensure only one presence check
controls both visualization and the calls to set_odom_to_camera_transform and
odom_to_camera.
- Around line 150-155: Remove the redundant "std::ignore = stream_guard"
statement and instead mark the scope_exit variable to avoid unused-variable
warnings; replace "auto stream_guard = std::experimental::scope_exit { [&] { ...
} };" with "[[maybe_unused]] auto stream_guard = std::experimental::scope_exit {
[&] { if (visualization.initialized()) visualization.send_image(*image); } };"
so the scope guard (stream_guard) still runs at scope exit but does not require
the unnecessary std::ignore assignment.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8963ebf2-db07-4a37-ae40-2e9e36148a62

📥 Commits

Reviewing files that changed from the base of the PR and between 6dba086 and 7c1daf8.

📒 Files selected for processing (7)
  • config/config.yaml
  • src/kernel/visualization.cpp
  • src/module/identifier/armor_detection.cpp
  • src/runtime.cpp
  • src/utility/rclcpp/visual/armor.cpp
  • test/model_infer.cpp
  • test/solve_pnp.cpp
💤 Files with no reviewable changes (1)
  • test/solve_pnp.cpp

Comment thread src/utility/rclcpp/visual/armor.cpp Outdated
@heyeuu
heyeuu requested a review from creeper5820 March 11, 2026 13:57
@creeper5820
creeper5820 merged commit a54e232 into main Mar 11, 2026
2 checks passed
@github-project-automation github-project-automation Bot moved this from Todo to Done in RMCS Auto Aim V2 Mar 11, 2026
@creeper5820
creeper5820 deleted the fix/roi-offset-correction branch March 11, 2026 14:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

fix: ROI offset misalignment in identifier

2 participants