Skip to content

Improve/ov model adapter#31

Merged
creeper5820 merged 7 commits intomainfrom
improve/ov-model-adapter
Mar 10, 2026
Merged

Improve/ov model adapter#31
creeper5820 merged 7 commits intomainfrom
improve/ov-model-adapter

Conversation

@creeper5820
Copy link
Copy Markdown
Collaborator

No description provided.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 10, 2026

总体概述

本 PR 实现了从 OpenVinoNet 模型接口到新型 OpenVINO 插件式 ArmorDetection 架构的重大重构,支持多种模型(TongJiYoloV5、ShenZhen0526、ShenZhen0708),替换 ArmorInferResult 为数据驱动的 InferResultAdapter,并重构运行时控制流。

变更列表

文件组 / 文件 变更概要
配置与工具链
.vscode/settings.json, config/config.yaml, tool/CMakeLists.txt, tool/ov_model_status.cpp
移除 vscode 拼写检查配置;扩展模型配置支持多种 ONNX/XML 模型;新增 OpenVINO 工具链依赖和模型状态查询工具。
模型实现移除
src/module/identifier/model.hpp, src/module/identifier/model.cpp
删除整个 OpenVinoNet 实现,包括异步推理、配置编译、预后处理管道等 326 行代码。
新型 OpenVINO 模型定义
src/module/identifier/models/tongji_yolov5.hpp, src/module/identifier/models/shenzhen.hpp, src/module/identifier/models/shenzhen_0526.hpp, src/module/identifier/models/shenzhen_0708.hpp
引入三种新模型实现:TongJiYoloV5、ShenZhenBasic 基类及两个派生类,各含编译方法、结果数据结构(Corners、Color、Genre)与 InferResultAdapter 适配。
装甲检测核心重构
src/module/identifier/armor_detection.cpp
用模板化 ExplainInterface、compile_model_with 动态编译、ROI 分割与推理管道替换旧实现;initialize() 返回 std::expected<void, std::string>;支持按模型类型动态选择推理和后处理逻辑。
通用基础设施
src/utility/model/common_model.hpp, src/utility/string.hpp, src/utility/robot/armor.hpp
添加 OpenVINO 张量布局辅助类(Dimensions、TensorLayout);扩展 StaticString 的 length() 方法;新增 Armor2Ds、Armor3Ds 类型别名。
装甲推理结果适配
src/utility/model/armor_detection.hpp
用通用 InferResultAdapter<data_type> 模板类替换 ArmorInferResult,支持数据驱动的角点/颜色/分类访问,保留 bounding_rect、scale_corners、armor_color() 等方法。
运行时与测试集成
src/runtime.cpp, test/CMakeLists.txt, test/model_infer.cpp, test/solve_pnp.cpp, src/kernel/pose_estimator.cpp
重构运行时控制流引入作用域守卫、标签化节流;更新测试链接为 armor_detection.cpp;重写模型推理测试为多模型泛型测试;更新 PnP 求解器集成使用新 ArmorDetection 接口。

序列图

sequenceDiagram
    participant User
    participant ArmorDetection
    participant ModelCompiler as compile_model_with
    participant OpenVINO as ov::Core
    participant Explainer as ExplainInterface
    participant Result as InferResult

    User->>ArmorDetection: initialize(yaml)
    activate ArmorDetection
    ArmorDetection->>ArmorDetection: parse model_location
    ArmorDetection->>ModelCompiler: compile_model_with(model_type)
    activate ModelCompiler
    ModelCompiler->>OpenVINO: read_model(location)
    OpenVINO-->>ModelCompiler: CompiledModel
    deactivate ModelCompiler
    ModelCompiler-->>ArmorDetection: compiled_model
    ArmorDetection->>ArmorDetection: create ExplainInterface
    deactivate ArmorDetection

    User->>ArmorDetection: sync_detect(image)
    activate ArmorDetection
    ArmorDetection->>ArmorDetection: preprocess (ROI, resize)
    ArmorDetection->>OpenVINO: infer(input_tensor)
    OpenVINO-->>ArmorDetection: raw_output
    ArmorDetection->>Explainer: explain_infer_result(output)
    activate Explainer
    Explainer->>Explainer: parse + sigmoid
    Explainer->>Explainer: apply NMS
    Explainer-->>Result: Armor2D vector
    deactivate Explainer
    ArmorDetection-->>User: Armor2Ds
    deactivate ArmorDetection
Loading

代码审核工作量评估

🎯 4 (复杂) | ⏱️ ~45 分钟

可能相关的 PR

  • PR #16: 同样重构 ArmorDetection 实现与标识符/运行时集成,涉及相同的装甲检测管道层改动。
  • PR #12: 触及识别→PnP 管道(装甲检测/模型层、姿态估计/solve_pnp 类型与相关头文件),与该 PR 的识别层改动有直接关联。
  • PR #10: 修改工程工具链 CMake 配置(HikCamera 与工具目标的添加/移除),影响工具链构建一致性。

建议标签

enhancement

建议审核人

  • qzhhhi

庆祝诗

🐰 模型流水线焕新春,
OpenVINO 织新网;
三种装甲齐飞扬,
插件式推理展风采,
从 Net 到 Adapter 的蜕变!

✨ 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 improve/ov-model-adapter

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.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 6

🧹 Nitpick comments (6)
src/utility/model/common_model.hpp (2)

108-123: noexcept 标记与可能抛出异常的 at() 调用不一致

partial_shape()shape() 方法标记为 noexcept,但内部调用的 dimensions.at() 在接收到无效维度字符时会抛出 std::runtime_error

虽然 TensorLayout 构造时已验证 chars 只包含有效字符(N/C/W/H),实际上不会触发异常,但从防御性编程角度,建议:

  1. 移除 noexcept 标记,或
  2. Dimensions::at() 中使用 assert 替代 throw(因为这是编程错误而非运行时错误)
♻️ 可选:使用 assert 替代 throw
     constexpr auto at(char dimension) const -> Value {
         switch (dimension) {
         case 'N':
             return N;
         case 'C':
             return C;
         case 'W':
             return W;
         case 'H':
             return H;
         default:
-            throw std::runtime_error("Wrong dimension char, valid: N, C, W, H");
+            assert(false && "Wrong dimension char, valid: N, C, W, H");
+            return 0; // unreachable, for compiler satisfaction
         }
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/utility/model/common_model.hpp` around lines 108 - 123, The methods
partial_shape and shape are marked noexcept but call Dimensions::at(), which may
throw; remove the noexcept specifier from both partial_shape(const Dimensions&)
and shape(const Dimensions&) to reflect potential exceptions (or alternatively
change Dimensions::at() to use assert instead of throwing if you prefer treating
invalid chars as programmer errors); ensure references to chars and the
TensorLayout constructor validation remain intact and update any callers/tests
if they relied on noexcept.

76-76: 静态断言消息与检查条件不一致

断言检查 description.length() == 5,但错误消息说"必须恰好 4 个字符"。虽然这在技术上是正确的(StaticStringlength() 包含 null 终止符),但可能造成困惑。

📝 建议:使消息更清晰
-        static_assert(description.length() == 5, "Layout description must be exactly 4 characters");
+        static_assert(description.length() == 5, "Layout description must be exactly 4 characters (length includes null terminator)");
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/utility/model/common_model.hpp` at line 76, The static_assert uses the
condition description.length() == 5 but its message says "must be exactly 4
characters", causing confusion; update the static_assert message to match the
check (e.g., "Layout description must be exactly 5 characters (including null
terminator)") or otherwise clarify the expected length (mentioning the null
terminator) next to the static_assert in common_model.hpp where
description.length() is validated.
src/runtime.cpp (1)

21-21: 使用实验性头文件 <experimental/scope>

<experimental/scope> 是 Library Fundamentals TS v3 的一部分,尚未标准化。不同编译器的支持程度可能不同(GCC 需要 libstdc++ 且可能需要特定版本)。

如果需要更广泛的编译器兼容性,可考虑使用简单的 RAII 包装类或第三方库如 gsl::finally

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

In `@src/runtime.cpp` at line 21, The code currently includes the non-standard
header <experimental/scope>, which is not portable; remove that include and
replace uses of its facilities with a portable alternative—either use the C++23
standard std::scope_exit if your target supports it, or add a small RAII helper
(e.g., a ScopeGuard/Finally class) to perform the same cleanup semantics; update
any code referencing the experimental APIs to use std::scope_exit or your
ScopeGuard class (same function/variable names where applicable) so the project
builds across compilers without relying on <experimental/scope>.
test/model_infer.cpp (1)

44-58: ExpectedCornersArmor2D 命名不一致

ExpectedCorners 使用 lt/lb/rb/rt(left-top/left-bottom/right-bottom/right-top),而 Armor2D 使用 tl/tr/br/bl(top-left/top-right/bottom-right/bottom-left)。这种命名差异可能导致混淆。

assert_sync_infer_with_expected 中(lines 106-109),变量命名已经对齐到 Armor2D 的风格,但 ExpectedCorners 本身的字段和方法仍使用不同的命名。

♻️ 建议:统一命名风格
 struct ExpectedCorners {
-    float lt_x;
-    float lt_y;
-    float lb_x;
-    float lb_y;
-    float rb_x;
-    float rb_y;
-    float rt_x;
-    float rt_y;
-
-    auto lt() const noexcept -> cv::Point2f { return { lt_x, lt_y }; }
-    auto lb() const noexcept -> cv::Point2f { return { lb_x, lb_y }; }
-    auto rb() const noexcept -> cv::Point2f { return { rb_x, rb_y }; }
-    auto rt() const noexcept -> cv::Point2f { return { rt_x, rt_y }; }
+    float tl_x;
+    float tl_y;
+    float bl_x;
+    float bl_y;
+    float br_x;
+    float br_y;
+    float tr_x;
+    float tr_y;
+
+    auto tl() const noexcept -> cv::Point2f { return { tl_x, tl_y }; }
+    auto bl() const noexcept -> cv::Point2f { return { bl_x, bl_y }; }
+    auto br() const noexcept -> cv::Point2f { return { br_x, br_y }; }
+    auto tr() const noexcept -> cv::Point2f { return { tr_x, tr_y }; }
 };
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/model_infer.cpp` around lines 44 - 58, ExpectedCorners uses lt/lb/rb/rt
naming while Armor2D uses tl/tr/br/bl causing inconsistency; rename the struct
fields (lt_x, lt_y, lb_x, lb_y, rb_x, rb_y, rt_x, rt_y) to tl_x, tl_y, bl_x,
bl_y, br_x, br_y, tr_x, tr_y and rename the accessor methods lt(), lb(), rb(),
rt() to tl(), bl(), br(), tr() (preserve signatures like auto tl() const
noexcept -> cv::Point2f), then update all usages (e.g., in
assert_sync_infer_with_expected and test constructions) to the new symbols to
keep naming consistent with Armor2D.
src/utility/model/armor_detection.hpp (2)

52-55: 让这个头文件自包含。

这一版新引入了 std::spanstd::arraystd::ranges::*std::memcpystd::is_trivially_copyable_vstd::size_t,但本头没有显式包含对应标准库头。现在能编译的话也是依赖传递包含,后面只要 include 顺序一变就容易炸。

📦 建议补齐直接依赖
 `#include` "utility/robot/armor.hpp"
+#include <algorithm>
+#include <array>
+#include <cstddef>
+#include <cstring>
+#include <iterator>
+#include <span>
+#include <type_traits>
 `#include` <opencv2/core/types.hpp>

Also applies to: 58-69, 126-135

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

In `@src/utility/model/armor_detection.hpp` around lines 52 - 55, The header is
not self-contained: functions like unsafe_from and types
data_type/precision_type use std::span, std::array, std::ranges utilities,
std::memcpy, std::is_trivially_copyable_v and std::size_t but the header omits
their headers; update the top of src/utility/model/armor_detection.hpp to
explicitly include the direct standard headers (<span> or <cstddef>/<span> as
appropriate), <array>, <ranges> (if ranges algorithms are used), <cstring> for
memcpy, <type_traits> for is_trivially_copyable_v and <cstddef> for size_t so
unsafe_from, related blocks (lines ~58-69 and ~126-135) compile independently of
include order and transitive includes.

7-8: 把模板契约前置,不要让错误散落在各个 accessor 里。

这个类型现在既依赖固定字段名,也依赖 length()/memcpy() 的布局约定,但这些前提都没有在模板入口声明。后面只要有新的 ResultData 字段名或布局稍微变化,错误就会在某个成员函数里以很长的模板回溯形式出现。建议用 concept 或类级 static_assert 把必需成员和布局约束集中起来。

Also applies to: 15-55, 126-128

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

In `@src/utility/model/armor_detection.hpp` around lines 7 - 8, The template
InferResultAdapter currently assumes the template parameter (e.g., ResultData)
exposes specific fields and a contiguous memcpy-able layout, causing cryptic
errors inside accessors; add a template-level contract — either a C++20 concept
(e.g., ResultDataLike) or class-level static_asserts inside InferResultAdapter —
that checks for required members/methods (presence of length() or length member,
required named fields accessed by the accessors), that the type is
std::is_trivially_copyable and sizeof matches expected element size/stride or
that data() returns a contiguous pointer, and fail early with clear messages;
update InferResultAdapter's template declaration to use the concept or include
the static_asserts so violations are reported at instantiation rather than deep
inside member functions (refer to InferResultAdapter and the accessors that rely
on length()/memcpy()).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@config/config.yaml`:
- Around line 39-43: Rename the misspelled YAML key "avaliable_models" to
"available_models" in the config (change the key under the model list), and
search the codebase for any references to "avaliable_models" and update them to
"available_models" (or add a compatibility fallback reading "avaliable_models"
if immediate rename would break runtime). Ensure the config consumer (the code
that reads model_location / available_models) uses the corrected key name.

In `@src/module/identifier/armor_detection.cpp`:
- Around line 278-288: sync_detect is declared noexcept but calls
generate_openvino_request and request.infer() which may throw; either remove
noexcept from sync_detect or wrap the body in a try/catch that catches
std::exception and other throwables and returns std::nullopt on error. Locate
sync_detect and implement one of these fixes referencing
generate_openvino_request, request.infer(), and explain_infer_result so thrown
exceptions won't escape; ensure any caught exception is logged or handled as
appropriate and the function returns std::nullopt.
- Around line 194-248: The function generate_openvino_request is marked noexcept
but calls operations that can throw (ov::Tensor construction and
openvino_model.create_infer_request()); remove the noexcept specifier from
generate_openvino_request or wrap the body in try/catch and convert exceptions
into std::unexpected<string> error results. Specifically, catch std::exception
(and any OpenVINO-specific exceptions) around the ov::Tensor creation and the
call to openvino_model.create_infer_request(), and on any catch return
std::unexpected with a clear error message; keep references to symbols
input_tensor, ov::Tensor, openvino_model.create_infer_request, request and
input_layout/input_dimensions to locate the changes.
- Around line 81-127: The explain(...) function is marked noexcept but performs
operations that may throw (e.g., boxes.push_back, cv::dnn::NMSBoxes,
final_result.reserve/push_back); either remove the noexcept specifier from the
explain method signature (the override of model_type::explain) or wrap the
entire body in a try-catch that catches std::exception (and optionally ...) and
returns an empty Armor2Ds on error; if choosing try-catch, ensure you catch
exceptions before they unwind (catch const std::exception& e and return {} —
optionally log e.what()) and maintain the Armor2Ds return semantics, and if
removing noexcept, update the declaration to drop noexcept so exceptions can
propagate normally.

In `@src/runtime.cpp`:
- Around line 240-249: AutoAimState::target (DeviceId) is left as UNKNOWN
because runtime.cpp creates AutoAimState without setting target and
predictor::Snapshot does not expose the device id; add a public getter (e.g.,
device_id() or getDeviceId()) to predictor::Snapshot (the constructor already
takes DeviceId) so callers can obtain the source DeviceId, update set_identity()
to reset or propagate target where appropriate, and modify the runtime.cpp block
that builds AutoAimState to assign state.target = snapshot.device_id() (or call
the new getter) before committing; reference Snapshot, its constructor, existing
public methods ekf_x()/time_stamp()/predict_at()/predicted_armors(),
set_identity(), and AutoAimState::target when making the changes.

In `@src/utility/model/armor_detection.hpp`:
- Line 13: The member `data` in armor_detection.hpp must be value-initialized to
avoid leaking previous-frame or uninitialized contents when an early return
occurs; change its declaration (in the class that currently has `data_type
data;`) to default-initialize (zero/empty) and ensure any adapter reuse sees a
clean `data`. Also modify `unsafe_from()` to return an explicit status (e.g.,
bool/optional/result) instead of silently returning on failure so callers can
handle errors; update call sites that rely on `bounding_rect()` / `armor_*()` to
check the new status before accessing `data`.

---

Nitpick comments:
In `@src/runtime.cpp`:
- Line 21: The code currently includes the non-standard header
<experimental/scope>, which is not portable; remove that include and replace
uses of its facilities with a portable alternative—either use the C++23 standard
std::scope_exit if your target supports it, or add a small RAII helper (e.g., a
ScopeGuard/Finally class) to perform the same cleanup semantics; update any code
referencing the experimental APIs to use std::scope_exit or your ScopeGuard
class (same function/variable names where applicable) so the project builds
across compilers without relying on <experimental/scope>.

In `@src/utility/model/armor_detection.hpp`:
- Around line 52-55: The header is not self-contained: functions like
unsafe_from and types data_type/precision_type use std::span, std::array,
std::ranges utilities, std::memcpy, std::is_trivially_copyable_v and std::size_t
but the header omits their headers; update the top of
src/utility/model/armor_detection.hpp to explicitly include the direct standard
headers (<span> or <cstddef>/<span> as appropriate), <array>, <ranges> (if
ranges algorithms are used), <cstring> for memcpy, <type_traits> for
is_trivially_copyable_v and <cstddef> for size_t so unsafe_from, related blocks
(lines ~58-69 and ~126-135) compile independently of include order and
transitive includes.
- Around line 7-8: The template InferResultAdapter currently assumes the
template parameter (e.g., ResultData) exposes specific fields and a contiguous
memcpy-able layout, causing cryptic errors inside accessors; add a
template-level contract — either a C++20 concept (e.g., ResultDataLike) or
class-level static_asserts inside InferResultAdapter — that checks for required
members/methods (presence of length() or length member, required named fields
accessed by the accessors), that the type is std::is_trivially_copyable and
sizeof matches expected element size/stride or that data() returns a contiguous
pointer, and fail early with clear messages; update InferResultAdapter's
template declaration to use the concept or include the static_asserts so
violations are reported at instantiation rather than deep inside member
functions (refer to InferResultAdapter and the accessors that rely on
length()/memcpy()).

In `@src/utility/model/common_model.hpp`:
- Around line 108-123: The methods partial_shape and shape are marked noexcept
but call Dimensions::at(), which may throw; remove the noexcept specifier from
both partial_shape(const Dimensions&) and shape(const Dimensions&) to reflect
potential exceptions (or alternatively change Dimensions::at() to use assert
instead of throwing if you prefer treating invalid chars as programmer errors);
ensure references to chars and the TensorLayout constructor validation remain
intact and update any callers/tests if they relied on noexcept.
- Line 76: The static_assert uses the condition description.length() == 5 but
its message says "must be exactly 4 characters", causing confusion; update the
static_assert message to match the check (e.g., "Layout description must be
exactly 5 characters (including null terminator)") or otherwise clarify the
expected length (mentioning the null terminator) next to the static_assert in
common_model.hpp where description.length() is validated.

In `@test/model_infer.cpp`:
- Around line 44-58: ExpectedCorners uses lt/lb/rb/rt naming while Armor2D uses
tl/tr/br/bl causing inconsistency; rename the struct fields (lt_x, lt_y, lb_x,
lb_y, rb_x, rb_y, rt_x, rt_y) to tl_x, tl_y, bl_x, bl_y, br_x, br_y, tr_x, tr_y
and rename the accessor methods lt(), lb(), rb(), rt() to tl(), bl(), br(), tr()
(preserve signatures like auto tl() const noexcept -> cv::Point2f), then update
all usages (e.g., in assert_sync_infer_with_expected and test constructions) to
the new symbols to keep naming consistent with Armor2D.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: eef19187-fe34-4421-9a55-2645f0fb77fe

📥 Commits

Reviewing files that changed from the base of the PR and between 867483f and 876903b.

⛔ Files ignored due to path filters (1)
  • models/tongji-yolov5.bin is excluded by !**/*.bin
📒 Files selected for processing (23)
  • .vscode/settings.json
  • config/config.yaml
  • models/shenzhen-0526.onnx
  • models/shenzhen-0708.onnx
  • models/tongji-yolov5.xml
  • src/kernel/pose_estimator.cpp
  • src/module/identifier/armor_detection.cpp
  • src/module/identifier/model.cpp
  • src/module/identifier/model.hpp
  • src/module/identifier/models/shenzhen.hpp
  • src/module/identifier/models/shenzhen_0526.hpp
  • src/module/identifier/models/shenzhen_0708.hpp
  • src/module/identifier/models/tongji_yolov5.hpp
  • src/runtime.cpp
  • src/utility/model/armor_detection.hpp
  • src/utility/model/common_model.hpp
  • src/utility/robot/armor.hpp
  • src/utility/string.hpp
  • test/CMakeLists.txt
  • test/model_infer.cpp
  • test/solve_pnp.cpp
  • tool/CMakeLists.txt
  • tool/ov_model_status.cpp
💤 Files with no reviewable changes (3)
  • .vscode/settings.json
  • src/module/identifier/model.cpp
  • src/module/identifier/model.hpp

Comment on lines +39 to +43
avaliable_models:
- "tongji-yolov5.xml"
- "shenzhen-0526.onnx"
- "shenzhen-0708.onnx"
model_location: "shenzhen-0526.onnx"
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
# 搜索代码中对此配置键的引用
rg -n "avaliable_models|available_models" --type cpp --type hpp
rg -n "avaliable_models|available_models" -g "*.cpp" -g "*.hpp"

Repository: Alliance-Algorithm/rmcs_auto_aim_v2

Length of output: 106


🏁 Script executed:

#!/bin/bash
# 在所有文件中搜索配置键的引用
rg -i "avaliable_models|available_models" --type-list | head -20

Repository: Alliance-Algorithm/rmcs_auto_aim_v2

Length of output: 468


🏁 Script executed:

#!/bin/bash
# 不限制文件类型,搜索所有引用
rg "avaliable_models|available_models" -n

Repository: Alliance-Algorithm/rmcs_auto_aim_v2

Length of output: 120


🏁 Script executed:

#!/bin/bash
# 搜索YAML配置加载的代码
rg -n "config.yaml|avaliable_models|available_models" -g "*.py" -g "*.cpp" -g "*.cc"

Repository: Alliance-Algorithm/rmcs_auto_aim_v2

Length of output: 204


🏁 Script executed:

#!/bin/bash
# 查看config.yaml的完整内容和相关模型配置的使用
cat config/config.yaml | head -50

Repository: Alliance-Algorithm/rmcs_auto_aim_v2

Length of output: 1115


🏁 Script executed:

#!/bin/bash
# 搜索代码中如何访问YAML配置,特别是模型相关的配置
rg -n "model|Model" config/config.yaml | head -20

Repository: Alliance-Algorithm/rmcs_auto_aim_v2

Length of output: 143


🏁 Script executed:

#!/bin/bash
# 查找config.yaml的加载和使用
rg -A 5 -B 5 "config.yaml" -g "*.cpp" -g "*.cc" -g "*.h" | head -100

Repository: Alliance-Algorithm/rmcs_auto_aim_v2

Length of output: 1282


🏁 Script executed:

#!/bin/bash
# 搜索所有可能的Python配置加载代码
rg -n "avaliable_models|available_models" -g "*.py"

Repository: Alliance-Algorithm/rmcs_auto_aim_v2

Length of output: 61


🏁 Script executed:

#!/bin/bash
# 搜索YAML相关的加载代码
rg -n "YAML\.Load|yaml\.load|config\[" -g "*.cpp" -g "*.py" | head -30

Repository: Alliance-Algorithm/rmcs_auto_aim_v2

Length of output: 260


拼写错误:avaliable_models 应为 available_models

配置键 avaliable_models 存在拼写错误,正确拼写为 available_models。虽然当前代码未引用此键,但应修复此拼写错误以避免未来使用此配置时出现问题。

🐛 修复建议
-  avaliable_models:
+  available_models:
     - "tongji-yolov5.xml"
     - "shenzhen-0526.onnx"
     - "shenzhen-0708.onnx"
📝 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
avaliable_models:
- "tongji-yolov5.xml"
- "shenzhen-0526.onnx"
- "shenzhen-0708.onnx"
model_location: "shenzhen-0526.onnx"
available_models:
- "tongji-yolov5.xml"
- "shenzhen-0526.onnx"
- "shenzhen-0708.onnx"
model_location: "shenzhen-0526.onnx"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@config/config.yaml` around lines 39 - 43, Rename the misspelled YAML key
"avaliable_models" to "available_models" in the config (change the key under the
model list), and search the codebase for any references to "avaliable_models"
and update them to "available_models" (or add a compatibility fallback reading
"avaliable_models" if immediate rename would break runtime). Ensure the config
consumer (the code that reads model_location / available_models) uses the
corrected key name.

Comment on lines +81 to +127
auto explain(ov::InferRequest& finished_request) const noexcept -> Armor2Ds override {
using result_type = typename model_type::Result;
using precision_type = typename result_type::precision_type;

auto tensor = finished_request.get_output_tensor();
auto& shape = tensor.get_shape();

const auto rows = static_cast<std::size_t>(shape.at(1));
const auto cols = static_cast<std::size_t>(shape.at(2));
if (cols != result_type::length()) {
return {};
}

auto parsed_results = std::vector<result_type> {};
auto scores = std::vector<float> {};
auto boxes = std::vector<cv::Rect> {};

const auto* data = tensor.data<precision_type>();
for (std::size_t row = 0; row < rows; row++) {
auto line = result_type {};
line.unsafe_from(std::span { data + row * cols, cols });
line.confidence() = util::sigmoid(line.confidence());

if (line.confidence() > min_confidence) {
parsed_results.push_back(line);
scores.push_back(line.confidence());
boxes.push_back(line.bounding_rect());
}
}

auto kept_points = std::vector<int> {};
cv::dnn::NMSBoxes(boxes, scores, score_threshold, nms_threshold, kept_points);

auto final_result = Armor2Ds {};
final_result.reserve(kept_points.size());

for (auto idx : kept_points) {
auto armor = cast_to_armor_result(parsed_results[idx]);
armor.tl *= 1.f / adapt_scaling;
armor.tr *= 1.f / adapt_scaling;
armor.br *= 1.f / adapt_scaling;
armor.bl *= 1.f / adapt_scaling;
armor.center = (armor.tl + armor.tr + armor.br + armor.bl) * 0.25f;
final_result.push_back(armor);
}
return final_result;
}
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 | 🟠 Major

noexcept 函数中存在可能抛出异常的操作

explain() 函数标记为 noexcept,但以下操作可能抛出异常:

  • Line 107: boxes.push_back() - 内存分配失败
  • Line 112: cv::dnn::NMSBoxes() - OpenCV 函数可能抛出异常
  • Line 115, 124: final_result.reserve() / push_back() - 内存分配

如果异常发生,程序将调用 std::terminate() 而非优雅处理。

🛡️ 建议:移除 noexcept 或添加 try-catch
-        auto explain(ov::InferRequest& finished_request) const noexcept -> Armor2Ds override {
+        auto explain(ov::InferRequest& finished_request) const -> Armor2Ds override {

或者包装异常处理:

         auto explain(ov::InferRequest& finished_request) const noexcept -> Armor2Ds override {
+            try {
             // ... existing code ...
+            } catch (...) {
+                return {};
+            }
         }
📝 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 explain(ov::InferRequest& finished_request) const noexcept -> Armor2Ds override {
using result_type = typename model_type::Result;
using precision_type = typename result_type::precision_type;
auto tensor = finished_request.get_output_tensor();
auto& shape = tensor.get_shape();
const auto rows = static_cast<std::size_t>(shape.at(1));
const auto cols = static_cast<std::size_t>(shape.at(2));
if (cols != result_type::length()) {
return {};
}
auto parsed_results = std::vector<result_type> {};
auto scores = std::vector<float> {};
auto boxes = std::vector<cv::Rect> {};
const auto* data = tensor.data<precision_type>();
for (std::size_t row = 0; row < rows; row++) {
auto line = result_type {};
line.unsafe_from(std::span { data + row * cols, cols });
line.confidence() = util::sigmoid(line.confidence());
if (line.confidence() > min_confidence) {
parsed_results.push_back(line);
scores.push_back(line.confidence());
boxes.push_back(line.bounding_rect());
}
}
auto kept_points = std::vector<int> {};
cv::dnn::NMSBoxes(boxes, scores, score_threshold, nms_threshold, kept_points);
auto final_result = Armor2Ds {};
final_result.reserve(kept_points.size());
for (auto idx : kept_points) {
auto armor = cast_to_armor_result(parsed_results[idx]);
armor.tl *= 1.f / adapt_scaling;
armor.tr *= 1.f / adapt_scaling;
armor.br *= 1.f / adapt_scaling;
armor.bl *= 1.f / adapt_scaling;
armor.center = (armor.tl + armor.tr + armor.br + armor.bl) * 0.25f;
final_result.push_back(armor);
}
return final_result;
}
auto explain(ov::InferRequest& finished_request) const -> Armor2Ds override {
using result_type = typename model_type::Result;
using precision_type = typename result_type::precision_type;
auto tensor = finished_request.get_output_tensor();
auto& shape = tensor.get_shape();
const auto rows = static_cast<std::size_t>(shape.at(1));
const auto cols = static_cast<std::size_t>(shape.at(2));
if (cols != result_type::length()) {
return {};
}
auto parsed_results = std::vector<result_type> {};
auto scores = std::vector<float> {};
auto boxes = std::vector<cv::Rect> {};
const auto* data = tensor.data<precision_type>();
for (std::size_t row = 0; row < rows; row++) {
auto line = result_type {};
line.unsafe_from(std::span { data + row * cols, cols });
line.confidence() = util::sigmoid(line.confidence());
if (line.confidence() > min_confidence) {
parsed_results.push_back(line);
scores.push_back(line.confidence());
boxes.push_back(line.bounding_rect());
}
}
auto kept_points = std::vector<int> {};
cv::dnn::NMSBoxes(boxes, scores, score_threshold, nms_threshold, kept_points);
auto final_result = Armor2Ds {};
final_result.reserve(kept_points.size());
for (auto idx : kept_points) {
auto armor = cast_to_armor_result(parsed_results[idx]);
armor.tl *= 1.f / adapt_scaling;
armor.tr *= 1.f / adapt_scaling;
armor.br *= 1.f / adapt_scaling;
armor.bl *= 1.f / adapt_scaling;
armor.center = (armor.tl + armor.tr + armor.br + armor.bl) * 0.25f;
final_result.push_back(armor);
}
return final_result;
}
🧰 Tools
🪛 Cppcheck (2.20.0)

[error] 110-110: Unhandled exception thrown in function declared not to throw exceptions.

(throwInNoexceptFunction)


[error] 118-118: Unhandled exception thrown in function declared not to throw exceptions.

(throwInNoexceptFunction)

🤖 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 81 - 127, The
explain(...) function is marked noexcept but performs operations that may throw
(e.g., boxes.push_back, cv::dnn::NMSBoxes, final_result.reserve/push_back);
either remove the noexcept specifier from the explain method signature (the
override of model_type::explain) or wrap the entire body in a try-catch that
catches std::exception (and optionally ...) and returns an empty Armor2Ds on
error; if choosing try-catch, ensure you catch exceptions before they unwind
(catch const std::exception& e and return {} — optionally log e.what()) and
maintain the Armor2Ds return semantics, and if removing noexcept, update the
declaration to drop noexcept so exceptions can propagate normally.

Comment on lines +194 to +248
auto generate_openvino_request(const Image& image) noexcept
-> std::expected<ov::InferRequest, std::string> {

const auto& origin_mat = image.details().mat;
if (origin_mat.empty()) [[unlikely]] {
return std::unexpected { "Empty image mat" };
}
const auto& raw_results = result.value();

auto result_armors = std::vector<Armor2D> {};
for (const auto& raw_armor : raw_results) {
auto armor = Armor2D {};
armor.genre = raw_armor.armor_genre();
armor.color = raw_armor.armor_color();
auto segmentation = origin_mat;
if (config.use_roi_segment) {
auto action_success = false;
do {
const auto cols = config.roi_cols;
const auto rows = config.roi_rows;
if (cols > origin_mat.cols) break;
if (rows > origin_mat.rows) break;

armor.tl = raw_armor.tl();
armor.tr = raw_armor.tr();
armor.bl = raw_armor.bl();
armor.br = raw_armor.br();
const auto x = (origin_mat.cols - cols) / 2;
const auto y = (origin_mat.rows - rows) / 2;
const auto rect = cv::Rect2i { x, y, cols, rows };

armor.confidence = raw_armor.confidence;
action_success = true;
segmentation = origin_mat(rect);
} while (false);

if (!action_success) {
return std::unexpected { "Failed to segment image" };
}
}

constexpr auto devices = DeviceIds::kLargeArmor();
armor.shape = devices.contains(armor.genre) ? ArmorShape::LARGE : ArmorShape::SMALL;
const auto rows = static_cast<int>(input_dimensions.H);
const auto cols = static_cast<int>(input_dimensions.W);
auto input_tensor = ov::Tensor {
ov::element::u8,
input_layout.shape(input_dimensions),
};
{
adapt_scaling = std::min(static_cast<float>(1. * cols / segmentation.cols),
static_cast<float>(1. * rows / segmentation.rows));

result_armors.push_back(armor);
const auto scaled_w = static_cast<int>(1. * segmentation.cols * adapt_scaling);
const auto scaled_h = static_cast<int>(1. * segmentation.rows * adapt_scaling);

auto input_mat = cv::Mat { rows, cols, CV_8UC3, input_tensor.data() };
input_mat.setTo(cv::Scalar::all(0));

auto input_roi = cv::Rect2i { 0, 0, scaled_w, scaled_h };
cv::resize(segmentation, input_mat(input_roi), { scaled_w, scaled_h });
}
return result_armors;

auto request = openvino_model.create_infer_request();
request.set_input_tensor(input_tensor);

return request;
}
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 | 🟠 Major

generate_openvino_request 中存在可能抛出异常的操作

此函数标记为 noexcept,但以下操作可能抛出异常:

  • Line 226-229: ov::Tensor 构造函数可能抛出
  • Line 244: openvino_model.create_infer_request() 可能抛出 OpenVINO 异常

建议移除 noexcept 标记或添加异常处理。

🛡️ 建议修复
-    auto generate_openvino_request(const Image& image) noexcept
+    auto generate_openvino_request(const Image& image)
         -> std::expected<ov::InferRequest, std::string> {
🧰 Tools
🪛 Cppcheck (2.20.0)

[error] 228-228: Unhandled exception thrown in function declared not to throw exceptions.

(throwInNoexceptFunction)

🤖 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 194 - 248, The
function generate_openvino_request is marked noexcept but calls operations that
can throw (ov::Tensor construction and openvino_model.create_infer_request());
remove the noexcept specifier from generate_openvino_request or wrap the body in
try/catch and convert exceptions into std::unexpected<string> error results.
Specifically, catch std::exception (and any OpenVINO-specific exceptions) around
the ov::Tensor creation and the call to openvino_model.create_infer_request(),
and on any catch return std::unexpected with a clear error message; keep
references to symbols input_tensor, ov::Tensor,
openvino_model.create_infer_request, request and input_layout/input_dimensions
to locate the changes.

Comment on lines +278 to 288
auto sync_detect(const Image& image) noexcept -> std::optional<Armor2Ds> {
auto result = generate_openvino_request(image);
if (!result.has_value()) {
return std::nullopt;
}

auto request = std::move(result.value());
request.infer();

return explain_infer_result(request);
}
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 | 🟠 Major

sync_detect 中调用可能抛出异常的方法

sync_detect 标记为 noexcept,但调用了 generate_openvino_requestrequest.infer(),这些都可能抛出异常。

🛡️ 建议修复
-    auto sync_detect(const Image& image) noexcept -> std::optional<Armor2Ds> {
+    auto sync_detect(const Image& image) -> std::optional<Armor2Ds> {
+        try {
             auto result = generate_openvino_request(image);
             if (!result.has_value()) {
                 return std::nullopt;
             }

             auto request = std::move(result.value());
             request.infer();

             return explain_infer_result(request);
+        } catch (...) {
+            return std::nullopt;
+        }
     }
📝 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 sync_detect(const Image& image) noexcept -> std::optional<Armor2Ds> {
auto result = generate_openvino_request(image);
if (!result.has_value()) {
return std::nullopt;
}
auto request = std::move(result.value());
request.infer();
return explain_infer_result(request);
}
auto sync_detect(const Image& image) -> std::optional<Armor2Ds> {
try {
auto result = generate_openvino_request(image);
if (!result.has_value()) {
return std::nullopt;
}
auto request = std::move(result.value());
request.infer();
return explain_infer_result(request);
} catch (...) {
return std::nullopt;
}
}
🧰 Tools
🪛 Cppcheck (2.20.0)

[error] 279-279: Unhandled exception thrown in function declared not to throw exceptions.

(throwInNoexceptFunction)

🤖 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 278 - 288,
sync_detect is declared noexcept but calls generate_openvino_request and
request.infer() which may throw; either remove noexcept from sync_detect or wrap
the body in a try/catch that catches std::exception and other throwables and
returns std::nullopt on error. Locate sync_detect and implement one of these
fixes referencing generate_openvino_request, request.infer(), and
explain_infer_result so thrown exceptions won't escape; ensure any caught
exception is logged or handled as appropriate and the function returns
std::nullopt.

Comment on lines +240 to 249
auto state = AutoAimState {};
state.timestamp = Clock::now();
state.gimbal_takeover = true;
state.shoot_permitted = true;
state.yaw = control_cmd->yaw;
state.pitch = control_cmd->pitch;
if (!feishu.commit(state)) {
action_throttler.dispatch(
feishu_commit_label, [&] { rclcpp_node.warn("Commit auto_aim_state failed"); });
}
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 | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# 查找 AutoAimState.target 的使用情况
rg -n "\.target" --type=cpp -C3 | grep -i "auto.*aim.*state\|autoaimstate" -i -A3 -B3

Repository: Alliance-Algorithm/rmcs_auto_aim_v2

Length of output: 61


🏁 Script executed:

#!/bin/bash
# Find AutoAimState definition in the codebase
find . -type f -name "*.hpp" -o -name "*.h" | xargs grep -l "AutoAimState" | head -5

Repository: Alliance-Algorithm/rmcs_auto_aim_v2

Length of output: 135


🏁 Script executed:

#!/bin/bash
# Look at the actual runtime.cpp file around the mentioned lines
cat -n src/runtime.cpp | sed -n '235,255p'

Repository: Alliance-Algorithm/rmcs_auto_aim_v2

Length of output: 990


🏁 Script executed:

#!/bin/bash
# Search for all usages of target field in cpp files
rg "target\s*=" --type=cpp -C2 | head -100

Repository: Alliance-Algorithm/rmcs_auto_aim_v2

Length of output: 1163


🏁 Script executed:

#!/bin/bash
# Read the AutoAimState definition from context.hpp
cat -n src/utility/shared/context.hpp | grep -A 20 "struct AutoAimState"

Repository: Alliance-Algorithm/rmcs_auto_aim_v2

Length of output: 724


🏁 Script executed:

#!/bin/bash
# Search more specifically for AutoAimState.target usage
rg "AutoAimState.*target|\.target.*AutoAim" --type=cpp -C5

Repository: Alliance-Algorithm/rmcs_auto_aim_v2

Length of output: 61


🏁 Script executed:

#!/bin/bash
# Also check what fields are accessed/set on AutoAimState in the codebase
rg "state\." --type=cpp src/runtime.cpp -C2 | head -80

Repository: Alliance-Algorithm/rmcs_auto_aim_v2

Length of output: 1447


🏁 Script executed:

#!/bin/bash
# Check what information the tracker exposes about the current target
rg "class Tracker|struct Tracker" --type=hpp -A 30 | head -100

Repository: Alliance-Algorithm/rmcs_auto_aim_v2

Length of output: 106


🏁 Script executed:

#!/bin/bash
# Look for any public methods on tracker that might give us target info
rg "tracker\." src/runtime.cpp -B 2 -A 2

Repository: Alliance-Algorithm/rmcs_auto_aim_v2

Length of output: 910


🏁 Script executed:

#!/bin/bash
# Check if snapshot has target/armor information
rg "snapshot->" src/runtime.cpp -B 1 -A 1 | head -60

Repository: Alliance-Algorithm/rmcs_auto_aim_v2

Length of output: 229


🏁 Script executed:

#!/bin/bash
# Find Tracker class definition
find . -name "tracker.hpp" -o -name "tracker.h" | xargs cat | head -150

Repository: Alliance-Algorithm/rmcs_auto_aim_v2

Length of output: 727


🏁 Script executed:

#!/bin/bash
# Look for any methods on tracker that return the tracked target
rg "decide|get_target|current_armor|tracked" --type=cpp -C 3 src/kernel/tracker.cpp | head -100

Repository: Alliance-Algorithm/rmcs_auto_aim_v2

Length of output: 843


🏁 Script executed:

#!/bin/bash
# Check if predictor::Snapshot has target information
rg "class Snapshot|struct Snapshot" --type=cpp -A 20 | head -80

Repository: Alliance-Algorithm/rmcs_auto_aim_v2

Length of output: 2806


🏁 Script executed:

#!/bin/bash
# Check if Snapshot has a device() getter method
rg "device()" src/module/predictor/snapshot.hpp -B 2 -A 2

Repository: Alliance-Algorithm/rmcs_auto_aim_v2

Length of output: 263


🏁 Script executed:

#!/bin/bash
# Look at full Snapshot public interface
cat src/module/predictor/snapshot.hpp | grep -A 100 "class Snapshot {" | head -60

Repository: Alliance-Algorithm/rmcs_auto_aim_v2

Length of output: 797


🏁 Script executed:

#!/bin/bash
# Check how the snapshot is used elsewhere - maybe there's a pattern for getting device
rg "snapshot\." src/ --type=cpp -B 1 -A 1 | grep "device\|target" -i

Repository: Alliance-Algorithm/rmcs_auto_aim_v2

Length of output: 482


🏁 Script executed:

#!/bin/bash
# Check if Snapshot::Impl::device is exposed through any public method
rg "pimpl->device|->device\(" src/module/predictor/snapshot.cpp

Repository: Alliance-Algorithm/rmcs_auto_aim_v2

Length of output: 61


🏁 Script executed:

#!/bin/bash
# Verify no other code accesses snapshot device info
rg "device_id|device\|target" src/runtime.cpp -C 2

Repository: Alliance-Algorithm/rmcs_auto_aim_v2

Length of output: 61


🏁 Script executed:

#!/bin/bash
# Check the complete Snapshot header to see all public methods
cat src/module/predictor/snapshot.hpp

Repository: Alliance-Algorithm/rmcs_auto_aim_v2

Length of output: 1037


AutoAimState::target 字段未被设置,且缺乏获取目标信息的接口

AutoAimState 结构体中的 target 字段(DeviceId 类型,定义于 context.hpp:31)在此代码段中保持默认值 DeviceId::UNKNOWN,未被赋值。

更深层的问题是,即使想要填充此字段,也无法从可用的数据源中获取:predictor::Snapshot 虽在构造时接收 DeviceId 参数,但其公共接口中不包含获取该值的方法(仅暴露 ekf_x()time_stamp()predict_at()predicted_armors())。

建议:

  • target 字段是必需的,则需在 Snapshot 中添加公共 getter 方法来暴露设备 ID
  • 同时考虑在 set_identity() 方法中包含对 target 字段的重置逻辑(目前该方法不涉及 target
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/runtime.cpp` around lines 240 - 249, AutoAimState::target (DeviceId) is
left as UNKNOWN because runtime.cpp creates AutoAimState without setting target
and predictor::Snapshot does not expose the device id; add a public getter
(e.g., device_id() or getDeviceId()) to predictor::Snapshot (the constructor
already takes DeviceId) so callers can obtain the source DeviceId, update
set_identity() to reset or propagate target where appropriate, and modify the
runtime.cpp block that builds AutoAimState to assign state.target =
snapshot.device_id() (or call the new getter) before committing; reference
Snapshot, its constructor, existing public methods
ekf_x()/time_stamp()/predict_at()/predicted_armors(), set_identity(), and
AutoAimState::target when making the changes.

auto rt() const noexcept { return Point { rt_x, rt_y }; }
auto lb() const noexcept { return Point { lb_x, lb_y }; }
} corners;
data_type data;
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 | 🟠 Major

不要在短输入上静默保留旧结果。

Line 54 直接返回,但 Line 13 的 data 也没有做值初始化。适配器复用时,这里会把上一帧甚至未初始化的内容继续暴露给 bounding_rect() / armor_*(),而调用方也拿不到失败信号。建议把 data 默认置零,并让 unsafe_from() 返回状态。

🩹 建议修改
-    data_type data;
+    data_type data{};

-    auto unsafe_from(std::span<const precision_type> raw) noexcept -> void {
+    [[nodiscard]] auto unsafe_from(std::span<const precision_type> raw) noexcept -> bool {
         static_assert(std::is_trivially_copyable_v<data_type>);
-        if (raw.size() < length()) return;
+        if (raw.size() < length()) {
+            data = {};
+            return false;
+        }
         std::memcpy(&data, raw.data(), sizeof(data_type));
+        return true;
     }

Also applies to: 52-55

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

In `@src/utility/model/armor_detection.hpp` at line 13, The member `data` in
armor_detection.hpp must be value-initialized to avoid leaking previous-frame or
uninitialized contents when an early return occurs; change its declaration (in
the class that currently has `data_type data;`) to default-initialize
(zero/empty) and ensure any adapter reuse sees a clean `data`. Also modify
`unsafe_from()` to return an explicit status (e.g., bool/optional/result)
instead of silently returning on failure so callers can handle errors; update
call sites that rely on `bounding_rect()` / `armor_*()` to check the new status
before accessing `data`.

@creeper5820 creeper5820 merged commit 6dba086 into main Mar 10, 2026
2 checks passed
@github-project-automation github-project-automation bot moved this from Todo to Done in RMCS Auto Aim V2 Mar 10, 2026
@creeper5820 creeper5820 deleted the improve/ov-model-adapter branch March 10, 2026 14:36
@coderabbitai coderabbitai bot mentioned this pull request Apr 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant