Skip to content

feat(referee): integrate referee state and sentry commands into decision#17

Closed
gqsdjhh wants to merge 3 commits into
mainfrom
dev/referee
Closed

feat(referee): integrate referee state and sentry commands into decision#17
gqsdjhh wants to merge 3 commits into
mainfrom
dev/referee

Conversation

@gqsdjhh
Copy link
Copy Markdown

@gqsdjhh gqsdjhh commented May 7, 2026

Summary

This PR integrates referee-system state and sentry control commands into the decision layer.

It adds the C++ to Lua data path for referee-related fields, exposes sentry control commands to Lua, and extends the decision blackboard so upper-layer logic can read referee state and issue sentry-related actions.

Changes

  • extend navigation context / component referee bindings in C++
  • sync additional referee fields into the Lua blackboard
  • expose sentry-related Lua actions and API bindings:
    • exchange_17mm_bullet
    • switch_mode
    • confirm_revive
  • add map-command / sentry-related state to decision-side blackboard data

Scope

This PR focuses on communication and decision-layer integration only.

PR 摘要

本 PR 将裁判系统状态与哨兵(sentry)控制命令集成到决策层,建立从 C++ 到 Lua 的裁判相关数据通路,并在决策黑板中暴露哨兵控制命令,供上层 Lua 逻辑读取裁判状态并发出哨兵相关动作。变更范围限定在通信与决策层集成。

主要变更

  • 导航组件集成(src/cxx/component.cc)

    • 在 Navigation::Command 中新增哨兵决策控制输出与定时生命周期逻辑,注册 ROS 输出以启用决策、指定已兑换子弹、选择请求模式、请求复活确认等。
    • 增加三类控制方法:exchange_17mm_bullet(int)、switch_mode(int)、confirm_revive(),对输入进行范围校验/截断,设置对应输出并在约 800ms 后自动清除(由 command.update() 驱动)。
    • 将新的 Lua API 绑定注入:exchange_17mm_bullet、switch_mode、confirm_revive。
    • 重构 lua_sync(),引入 read_context lambda 以安全地读取 Context 输入(避免无条件解引用),并将更多裁判/底盘/射手/地图命令等字段同步到 Lua 黑板。
    • Navigation::update() 每个周期调用 command.update(),以保证决策输出的生命周期管理。
  • 上下文输入扩展(src/cxx/context.cc / src/cxx/context.hh)

    • 在 Context::Impl::init 中注册大量新增输入绑定,覆盖底盘功率/缓冲/输出状态、游戏阶段剩余与同步时间戳、多项裁判事件(能量机制激活、堡垒占领等)、飞镖命中计数、射手冷却/热限与子弹参数、地图命令事件(坐标/键盘/目标/序列)、多盟友机器人血量与位置、哨兵相关能力与兑换/复活/模式/子弹状态、红蓝分数等。
    • Context 公共接口新增多种 InputInterface<> 公共成员以暴露上述字段。
  • 决策黑板扩展(src/lua/blackboard.lua)

    • create_default_blackboard() 初始化更大范围的黑板状态:user(底盘功率、缓冲能量、输出状态、射手冷却/热限、子弹计数等)、game(队伍得分、机器人 id、复活/兑换标志、能量机制状态、飞镖命中计数、各机器人位置与血量、计时器等)、meta(FSM 元数据)、rule(新增阈值与多区域坐标)。
    • 扩展 result.condition 中的判定函数:新增基地危险/前哨存活判定、飞镖首次命中检测、堡垒占领检测、大/小能量机制检测、残局计时判定、复活确认等逻辑。
  • Lua API 与封装(src/lua/action.lua / src/lua/api.lua)

    • 在 action 中新增封装:action:exchange_17mm_bullet(amount)、action:switch_mode(mode)、action:confirm_revive(),其中 exchange 会基于 blackboard.game.exchanged_bullet 做累加调整再调用底层 API。
    • 在 api 注解中声明新增接口:exchange_17mm_bullet、switch_mode、confirm_revive(并调整若干现有注解位置)。
    • 调整 restart_navigation 启动脚本:在启动序列中新增 foxglove_bridge 的 screen 启动步骤并调整 launch 顺序。
  • 并发修复

    • 修复并发问题:在裁判命令更新路径上加入 I/O 互斥(mutex)以保护 referee 命令更新(提交中有一条 commit 专门为此添加锁保护)。

影响范围与兼容性

  • 未更改外部公开 API 签名(对外接口未发生破坏性变更)。
  • 变更局限于决策层内部集成、Context 输入绑定和 C++/Lua 通信路径;不包含底层控制器或更广泛导航逻辑的功能变更。
  • 新增的黑板字段与 Lua 判定/动作为上层决策脚本提供了读取裁判状态与下发哨兵控制命令的能力。

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 7, 2026

Review Change Stack

Warning

Rate limit exceeded

@creeper5820 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 51 minutes and 55 seconds before requesting another review.

To continue reviewing without waiting, purchase usage credits in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a35623ba-3375-432f-9bc9-5f8bf834d008

📥 Commits

Reviewing files that changed from the base of the PR and between 556e561 and b8e70f6.

📒 Files selected for processing (2)
  • src/cxx/component.cc
  • src/lua/blackboard.lua

Walkthrough

该PR在导航模块中添加并注册哨兵决策相关输入与输出,实现在 Command 层的 exchange/switch/confirm 控制与 ~800ms 的自动清除逻辑,重构 lua_sync 为安全读取 Context,扩展 Lua 黑板与 API 并将命令生命周期集成到 Navigation 更新循环。

变更

哨兵决策与游戏状态集成

层级 / 文件 概述
数据类型与输入接口
src/cxx/context.hh
在Context公共接口中添加<cstdint>头文件并扩展InputInterface成员,支持新的阶段计时、能量激活、底盘功率、盟友HP/位置、哨兵能力等字段。
输入绑定注册
src/cxx/context.cc
Context::Impl::init中添加大量新的make_input()调用,注册裁判/底盘/游戏/事件/射手/地图命令/盟友/哨兵相关ROS话题。
哨兵决策命令实现
src/cxx/component.cc
添加标准头文件,在Command类中引入哨兵决策状态与清除时间戳,实现ROS输出注册、exchange_17mm_bullet/switch_mode/confirm_revive方法,以及基于定时器的决策生命周期管理。
上下文数据同步
src/cxx/component.cc
重构lua_sync函数,引入read_context辅助函数实现安全读取,避免未就绪输入的无条件解引用,并同步用户/游戏/地图命令字段。
Lua API接口暴露
src/cxx/component.cc, src/lua/api.lua
在make_api_injection中绑定新的控制方法,在Api注解中声明exchange_17mm_bullet/switch_mode/confirm_revive等字段,并更新restart_navigation脚本以启动foxglove_bridge。
Lua行为包装
src/lua/action.lua
添加action:exchange_17mm_bullet(amount)、action:switch_mode(mode)和action:confirm_revive()方法,manage exchanged_bullet累积计数。
黑板运行时状态扩展
src/lua/blackboard.lua
扩展create_default_blackboard初始化以添加底盘/射手/游戏/规则/条件字段,实现基础危险/飞镖命中/堡垒占据/能量机制激活的谓词函数。
导航组件集成
src/cxx/component.cc
修改Navigation::update()在Lua同步前调用command.update(),完成命令生命周期与主导航循环的集成。

代码审查工作量估计

🎯 3 (中等) | ⏱️ ~25 分钟

🐰 哨兵舞步轻盈起,
决策定时八百毫秒,
交换弹药换模式,
黑板状态齐扩张,
Lua与C++共舞,
导航之心跳动不息。

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 13.64% 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 PR标题准确总结了主要变更:将裁判系统状态和哨兵控制命令集成到决策层,与文件更改中的新referee字段、sentry命令绑定及blackboard扩展完全一致。
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 unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dev/referee

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


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

@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: 2

🧹 Nitpick comments (2)
src/cxx/component.cc (2)

191-193: 💤 Low value

Lambda 风格与同段其他 lambda 不一致。

同一 make_api_injection 中其他 lambda 都未显式书写返回类型,这里的 [this]()-> void { ... } 显式写出 -> void 略显不齐整。统一为隐式返回即可。

♻️ 风格统一
-        api.set_function("confirm_revive", [this]()-> void {
-            command.confirm_revive();
-        });
+        api.set_function("confirm_revive", [this] { command.confirm_revive(); });
🤖 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/cxx/component.cc` around lines 191 - 193, 在 make_api_injection 中的
api.set_function("confirm_revive", [this]()-> void { command.confirm_revive();
}); 与同段其他 lambda 风格不一致:请将该 lambda 的显式返回类型移除,改为与同组一致的隐式返回形式(即使用 [this]() {
command.confirm_revive(); }),以保持代码风格统一并保留对 this 的捕获;定位标识符参考
api.set_function("confirm_revive") 和 command.confirm_revive().

99-106: ⚡ Quick win

switch_mode 对非法 mode 静默返回,建议加日志便于排查。

mode 来自 Lua 调用方,越界时直接 return 不会触发任何反馈,调试时很难定位“为什么没切换”。建议至少 warn 一行,并保持其他决策状态不变(不调用 reset_all_decisions,与现有实现一致)。

♻️ 建议改动
         auto switch_mode(int mode) -> void {
-            if (mode < 1 || mode > 3)
-                return;
+            if (mode < 1 || mode > 3) {
+                // 上层 Lua 传入越界值,记录后忽略,保留既有决策
+                return;
+            }

(如果 Command 能拿到 logger,请把 return 前替换为 warn(...) 调用;否则在调用 api.set_function("switch_mode", ...) 处统一打日志。)

🤖 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/cxx/component.cc` around lines 99 - 106, The switch_mode function
currently returns silently on an out-of-range mode; update it to emit a warning
when mode < 1 || mode > 3 (but keep the current behavior of not calling
reset_all_decisions or changing state) by logging a clear message that includes
the invalid mode value; if the Command class (or the surrounding object that
owns switch_mode) exposes a logger, call its warn(...) before returning from
switch_mode, otherwise add a warning log at the place where
api.set_function("switch_mode", ...) is registered so callers and logs show why
the switch was ignored; keep references to reset_all_decisions, requested_mode
and activate_decision unchanged.
🤖 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/cxx/component.cc`:
- Around line 114-120: Command::update() reads sentry_decision_clear_at which
other Lua API callbacks (e.g., exchange_17mm_bullet, switch_mode,
confirm_revive) modify under io_mutex, so call command.update() while holding
the same io_mutex to prevent data races; specifically, acquire io_mutex before
invoking command.update() (the call site that currently precedes lua_sync() and
lua_tick()) or, alternatively, add a clear comment on the component specifying
it must run in a mutually exclusive callback group / single-threaded executor
(e.g., MultiThreadedExecutor with non-Reentrant callbacks) so maintainers know
the required synchronization.

In `@src/lua/blackboard.lua`:
- Line 9: The local variable last_our_dart_nmber_of_hits is misspelled (nmber)
and the PR also introduced a duplicated field our_dart_nmber_of_hits alongside
the correct our_dart_number_of_hits; rename the local variable
last_our_dart_nmber_of_hits to last_our_dart_number_of_hits and remove the newly
added misspelled field usage in this file, ensuring all references (lines around
initialization and 185-192) use last_our_dart_number_of_hits and
our_dart_number_of_hits; if C++ (component.cc lua_sync) still writes the
misspelled key, keep only the correct key in Lua and optionally add a temporary
alias read-from fallback from our_dart_nmber_of_hits -> our_dart_number_of_hits
(without introducing new persistent misspelled fields) so existing callers
continue to work until they migrate.

---

Nitpick comments:
In `@src/cxx/component.cc`:
- Around line 191-193: 在 make_api_injection 中的
api.set_function("confirm_revive", [this]()-> void { command.confirm_revive();
}); 与同段其他 lambda 风格不一致:请将该 lambda 的显式返回类型移除,改为与同组一致的隐式返回形式(即使用 [this]() {
command.confirm_revive(); }),以保持代码风格统一并保留对 this 的捕获;定位标识符参考
api.set_function("confirm_revive") 和 command.confirm_revive().
- Around line 99-106: The switch_mode function currently returns silently on an
out-of-range mode; update it to emit a warning when mode < 1 || mode > 3 (but
keep the current behavior of not calling reset_all_decisions or changing state)
by logging a clear message that includes the invalid mode value; if the Command
class (or the surrounding object that owns switch_mode) exposes a logger, call
its warn(...) before returning from switch_mode, otherwise add a warning log at
the place where api.set_function("switch_mode", ...) is registered so callers
and logs show why the switch was ignored; keep references to
reset_all_decisions, requested_mode and activate_decision unchanged.
🪄 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: 3fc6475e-0ec3-4adc-bf46-ff22df44d826

📥 Commits

Reviewing files that changed from the base of the PR and between a0bcb9f and 38691ae.

📒 Files selected for processing (6)
  • src/cxx/component.cc
  • src/cxx/context.cc
  • src/cxx/context.hh
  • src/lua/action.lua
  • src/lua/api.lua
  • src/lua/blackboard.lua

Comment thread src/cxx/component.cc
Comment thread src/lua/blackboard.lua Outdated
Copy link
Copy Markdown

@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: 1

🧹 Nitpick comments (3)
src/cxx/component.cc (3)

129-133: 💤 Low value

800ms 魔法数字建议提取为命名常量。

std::chrono::milliseconds{800} 是哨兵决策的自动清除窗口,与裁判系统下行刷新节奏强相关。建议提升为 Commandstatic constexpr 命名常量(如 decision_hold_duration),便于后续调参、统一注释来源,并避免在 update() 中读取 clear_at 与此处写入逻辑分离时产生不一致。

🔧 建议的修复
+        static constexpr auto decision_hold_duration = std::chrono::milliseconds{800};
+
         auto activate_decision() -> void {
             *sentry_decision_enabled = true;
-            sentry_decision_clear_at =
-                std::chrono::steady_clock::now() + std::chrono::milliseconds{800};
+            sentry_decision_clear_at = std::chrono::steady_clock::now() + decision_hold_duration;
         }
🤖 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/cxx/component.cc` around lines 129 - 133, The hard-coded 800ms duration
in activate_decision() (std::chrono::milliseconds{800}) should be extracted to a
named constant on the Command type to centralize tuning and avoid mismatches
with other places that read/write sentry_decision_clear_at; add a static
constexpr std::chrono::milliseconds decision_hold_duration (or similarly named)
to Command and replace std::chrono::milliseconds{800} in activate_decision()
with Command::decision_hold_duration, and update any other places that set or
compare sentry_decision_clear_at to use that constant.

191-193: 💤 Low value

Lambda 风格不一致:多余的尾置返回类型。

第 185、188 行的回调均省略 -> void,而第 191 行的 confirm_revive 显式写出 -> void,建议统一风格。

🔧 建议的修复
-        api.set_function("confirm_revive", [this]()-> void {
+        api.set_function("confirm_revive", [this]() {
             command.confirm_revive();
         });
🤖 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/cxx/component.cc` around lines 191 - 193, 回调 lambda 风格不一致:在
api.set_function("confirm_revive", ...) 的 lambda 中移除多余的尾置返回类型 `-> void`
以与其它回调(例如前面对其他命令的 set_function 回调)保持一致;定位到使用 api.set_function("confirm_revive",
[this]()-> void { command.confirm_revive(); }); 并将其改为省略返回类型的形式(保持捕获和主体不变)。

99-106: ⚡ Quick win

switch_mode 静默忽略非法 mode 值,建议至少打日志。

mode 不在 [1, 3] 范围内时函数直接 return,调用方(Lua 侧)无法感知错误,调试时也难以定位为何决策未生效。建议至少打一条 warn 日志,或返回 bool 让 Lua 侧可判断。

🔧 示例修复
         auto switch_mode(int mode) -> void {
-            if (mode < 1 || mode > 3)
-                return;
+            if (mode < 1 || mode > 3) {
+                // 仅接受 1..3,超出范围视为非法请求
+                return;
+            }

             reset_all_decisions();
             *requested_mode = static_cast<std::uint8_t>(mode);
             activate_decision();
         }

若组件持有日志接口,可改为 warn("switch_mode: invalid mode {}", mode);

🤖 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/cxx/component.cc` around lines 99 - 106, The function switch_mode
currently returns silently for invalid mode values (mode < 1 || mode > 3), which
hides errors from callers; update switch_mode to either log a warning (e.g.,
using the component's logger with a message like "switch_mode: invalid mode {}"
including the mode) before returning, or change its signature to return a bool
indicating success/failure so the Lua side can detect the error; ensure the
modified logic still calls reset_all_decisions(), updates *requested_mode, and
calls activate_decision() only on valid modes, and reference switch_mode,
requested_mode, reset_all_decisions, and activate_decision when making the
change.
🤖 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/cxx/component.cc`:
- Around line 285-286: 修复 game 对象中拼写错误的键:将重复写入的
our_dart_nmber_of_hits(拼写错误)移除,仅保留正确的 our_dart_number_of_hits;如果必须保留旧键做兼容(即保留
our_dart_nmber_of_hits),在该位置添加明确的 TODO: deprecated 注释并记录移除时间表以避免脏 API
长期存在。定位标识符:game、our_dart_number_of_hits、our_dart_nmber_of_hits。

---

Nitpick comments:
In `@src/cxx/component.cc`:
- Around line 129-133: The hard-coded 800ms duration in activate_decision()
(std::chrono::milliseconds{800}) should be extracted to a named constant on the
Command type to centralize tuning and avoid mismatches with other places that
read/write sentry_decision_clear_at; add a static constexpr
std::chrono::milliseconds decision_hold_duration (or similarly named) to Command
and replace std::chrono::milliseconds{800} in activate_decision() with
Command::decision_hold_duration, and update any other places that set or compare
sentry_decision_clear_at to use that constant.
- Around line 191-193: 回调 lambda 风格不一致:在 api.set_function("confirm_revive", ...)
的 lambda 中移除多余的尾置返回类型 `-> void` 以与其它回调(例如前面对其他命令的 set_function 回调)保持一致;定位到使用
api.set_function("confirm_revive", [this]()-> void { command.confirm_revive();
}); 并将其改为省略返回类型的形式(保持捕获和主体不变)。
- Around line 99-106: The function switch_mode currently returns silently for
invalid mode values (mode < 1 || mode > 3), which hides errors from callers;
update switch_mode to either log a warning (e.g., using the component's logger
with a message like "switch_mode: invalid mode {}" including the mode) before
returning, or change its signature to return a bool indicating success/failure
so the Lua side can detect the error; ensure the modified logic still calls
reset_all_decisions(), updates *requested_mode, and calls activate_decision()
only on valid modes, and reference switch_mode, requested_mode,
reset_all_decisions, and activate_decision when making the change.
🪄 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: 0496a083-b2ec-4fa2-8769-aaf15ab924cd

📥 Commits

Reviewing files that changed from the base of the PR and between 38691ae and 556e561.

📒 Files selected for processing (1)
  • src/cxx/component.cc

Comment thread src/cxx/component.cc Outdated
@gqsdjhh gqsdjhh closed this May 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant