|
1 | | -# rmcs-navigation (Ai Generated, 不保真) |
| 1 | +# RMCS NAVIGATION |
2 | 2 |
|
3 | | -`rmcs-navigation` 是一个由 `rmcs_executor` 加载的导航决策组件,和一个 Nav2 启动包。 |
| 3 | +## 0. 基本架构 |
4 | 4 |
|
5 | | -它的核心结构是: |
| 5 | +`RMCS-NAVIGATION` 是一个 RoboMaster 哨兵机器人自主导航决策系统,采用 C++ 和 Lua 开发主要逻辑,该程序以 [RMCS 控制系统插件](https://github.com/Alliance-Algorithm/RMCS) 的形式运行,由 RMCS 提供运行时与上下文,由 ROS Navigation 提供导航能力,Lua 开发决策 |
6 | 6 |
|
7 | | -- C++ 组件 `rmcs::navigation::Navigation` |
8 | | -- Lua 决策入口 `main.lua` |
9 | | -- Lua 黑板 `blackboard.lua` |
10 | | -- Lua 原生接口表 `api.lua` |
| 7 | +- `Component`:获取机器人状态,裁判系统等信息,提供运动控制接口,以及为 Lua 侧提供运行时 |
| 8 | +- `ROS Navigation`:Nav2 堆栈的纯配置与启动文件,负责路径规划及其他导航相关能力 |
| 9 | +- `Lua Decision`:在 `component` 的 update 中自旋,其热重载特性和原生协程支持有利于决策的快速迭代开发 |
11 | 10 |
|
12 | | -组件负责把裁判系统/遥控器上下文同步进 Lua,并执行每帧决策逻辑;Lua 负责行为组织、切换条件与导航相关业务策略。 |
| 11 | +## 1. 快速入门 |
13 | 12 |
|
14 | | -## 目录结构 |
| 13 | +### 信息流与调用链总览 |
15 | 14 |
|
16 | | -- `src/cxx/component.cc`:`rmcs_executor` 组件主实现。 |
17 | | -- `src/cxx/util/logger_mixin.hh`:组件日志封装。 |
18 | | -- `src/lua/main.lua`:Lua 决策入口,要求定义 `on_init()` 和 `on_tick()`。 |
19 | | -- `src/lua/blackboard.lua`:Lua 黑板单例与默认字段。 |
20 | | -- `src/lua/api.lua`:Lua 侧可调用的原生接口表。 |
21 | | -- `config/rmul.yaml`、`config/rmuc.yaml`:决策配置。 |
22 | | -- `launch/*.launch.py`:Nav2/在线导航/自定义模式等启动入口。 |
23 | | - |
24 | | -## 组件运行模型 |
25 | | - |
26 | | -`Navigation` 组件在构造阶段完成以下工作: |
27 | | - |
28 | | -- 读取参数,例如 `command_vel_name`、`mock_context` |
29 | | -- 初始化上下文输入接口 |
30 | | -- 初始化输出接口 |
31 | | -- 创建 `Twist` 订阅 |
32 | | -- 初始化 Lua VM,并加载 `main.lua` / `blackboard.lua` / `api.lua` |
33 | | -- 调用 Lua `on_init()` |
34 | | - |
35 | | -运行阶段每次 `update()` 会执行: |
36 | | - |
37 | | -- 将当前上下文同步到 Lua blackboard |
38 | | -- 调用 Lua `on_tick()` |
39 | | - |
40 | | -当前实现采用 fail-fast 策略: |
41 | | - |
42 | | -- Lua 初始化失败会在构造阶段直接抛异常 |
43 | | -- Lua 运行期异常会在 `update()` 中直接抛异常 |
44 | | -- 不再使用静默熔断或失败后跳过更新的策略 |
45 | | - |
46 | | -## 输入输出接口 |
47 | | - |
48 | | -### 输入 |
49 | | - |
50 | | -组件当前声明的输入包括: |
51 | | - |
52 | | -- `/referee/id` |
53 | | -- `/remote/switch/right` |
54 | | -- `/remote/switch/left` |
55 | | -- `/referee/game/stage` |
56 | | -- `/referee/current_hp` |
57 | | -- `/referee/shooter/bullet_allowance` |
58 | | -- `/referee/game/red_score` |
59 | | -- `/referee/game/blue_score` |
60 | | - |
61 | | -另外还会额外订阅速度输入: |
62 | | - |
63 | | -- `command_vel_name` 参数指定的话题,默认常见值为 `/cmd_vel_smoothed` |
64 | | - |
65 | | -### 输出 |
66 | | - |
67 | | -组件当前导出的输出接口包括: |
68 | | - |
69 | | -- `/rmcs_navigation/chassis_velocity` |
70 | | -- `/rmcs_navigation/nod_count` |
71 | | -- `/rmcs_navigation/rotate_chassis` |
72 | | -- `/rmcs_navigation/detect_targets` |
73 | | -- `/rmcs_navigation/start_autoaim` |
74 | | - |
75 | | -其中: |
76 | | - |
77 | | -- `/rmcs_navigation/chassis_velocity` 由外部 `Twist` 订阅直接写入 |
78 | | -- 其他输出通常由 Lua 逻辑间接控制 |
79 | | - |
80 | | -## Lua 决策接口 |
81 | | - |
82 | | -### 必要入口 |
83 | | - |
84 | | -`src/lua/main.lua` 必须定义: |
85 | | - |
86 | | -- `on_init()` |
87 | | -- `on_tick()` |
88 | | - |
89 | | -组件初始化时会调用 `on_init()`,之后每帧调用 `on_tick()`。 |
90 | | - |
91 | | -### Blackboard 结构 |
92 | | - |
93 | | -Lua 黑板当前默认包含以下字段: |
94 | | - |
95 | | -- `user.health` |
96 | | -- `user.bullet` |
97 | | -- `game.stage` |
98 | | -- `play.rswitch` |
99 | | -- `play.lswitch` |
100 | | -- `rule.decision` |
101 | | -- `rule.health_limit` |
102 | | -- `rule.health_ready` |
103 | | -- `rule.bullet_limit` |
104 | | -- `rule.bullet_ready` |
105 | | -- `rule.home` |
106 | | -- `meta.timestamp` |
107 | | - |
108 | | -其中由 C++ 每帧同步的主要字段为: |
109 | | - |
110 | | -- `user.health` |
111 | | -- `user.bullet` |
112 | | -- `game.stage` |
113 | | -- `play.rswitch` |
114 | | -- `play.lswitch` |
115 | | -- `meta.timestamp` |
116 | | - |
117 | | -### Api 注入 |
118 | | - |
119 | | -`api.lua` 中的 `api` 表会在 C++ 侧被进一步注入原生函数。 |
120 | | - |
121 | | -当前额外注入了: |
122 | | - |
123 | | -- `api.info(message: string)` |
124 | | -- `api.warn(message: string)` |
125 | | - |
126 | | -这两个函数由 C++ 直接挂到 `api` 表上,可在 Lua 中直接使用: |
127 | | - |
128 | | -```lua |
129 | | -local api = require("api") |
130 | | - |
131 | | -api.info("navigation init") |
132 | | -api.warn("health is low") |
133 | | -``` |
134 | | - |
135 | | -## Mock Context |
136 | | - |
137 | | -当参数 `mock_context: true` 时,组件不会从真实输出链路读取上下文,而是将输入接口本地 direct bind,并额外监听一个 mock topic。 |
138 | | - |
139 | | -### Mock Topic |
140 | | - |
141 | | -- topic: `/rmcs_navigation/context/mock` |
142 | | -- type: `std_msgs/msg/String` |
143 | | - |
144 | | -### Payload 形式 |
145 | | - |
146 | | -负载内容是裸 YAML 文本,要求根节点是 map。例如: |
147 | | - |
148 | | -```yaml |
149 | | -game_stage: 4 |
150 | | -robot_health: 350 |
151 | | -``` |
152 | | -
|
153 | | -当前 mock 同步逻辑允许只更新部分字段,不要求一次性提供完整上下文。 |
154 | | -
|
155 | | -### 当前支持的 mock 字段 |
156 | | -
|
157 | | -当前 `Context::from()` 实际支持: |
158 | | - |
159 | | -- `game_stage` |
160 | | -- `robot_health` |
161 | | -- `robot_bullet` |
162 | | -- `red_score` |
163 | | -- `blue_score` |
164 | | - |
165 | | -当前这几项按数值解析: |
166 | | - |
167 | | -- `game_stage` 接受底层整数值 |
168 | | -- 其余字段接受整数 |
169 | | - |
170 | | -注意:虽然组件内部也声明了 `robot_id`、`switch_right`、`switch_left` 输入,但当前 mock YAML 同步逻辑没有覆盖这些字段。 |
171 | | - |
172 | | -## 远程脚手架 |
173 | | - |
174 | | -项目根目录提供了脚手架: |
175 | | - |
176 | | -- `/workspaces/RMCS/.script/remote-context` |
177 | | - |
178 | | -它会向远端发布 `std_msgs/msg/String` 到: |
179 | | - |
180 | | -- `/rmcs_navigation/context/mock` |
181 | | - |
182 | | -常用示例: |
183 | | - |
184 | | -```bash |
185 | | -remote-context game_stage started |
186 | | -remote-context game_stage 4 |
187 | | -remote-context robot_health 350 |
188 | | -remote-context red_score 3 |
189 | | -``` |
190 | | - |
191 | | -其中脚手架会把: |
192 | | - |
193 | | -- `started` 转成 `4` |
194 | | -- `preparation` 转成 `1` |
195 | | -- `unknown` 转成 `255` |
196 | | - |
197 | | -因此可以直接用较友好的文本形式发 `game_stage`。 |
198 | | - |
199 | | -## 参数 |
200 | | - |
201 | | -常用参数包括: |
202 | | - |
203 | | -- `command_vel_name`:速度输入订阅话题 |
204 | | -- `mock_context`:是否启用本地 mock context 模式 |
205 | | - |
206 | | -一个最小示例见: |
207 | | - |
208 | | -- `rmcs_bringup/config/navigation.yaml` |
209 | | - |
210 | | -当前安装配置示例为: |
211 | | - |
212 | | -```yaml |
213 | | -rmcs_navigation: |
214 | | - ros__parameters: |
215 | | - command_vel_name: "/cmd_vel_smoothed" |
216 | | - mock_context: true |
217 | | -``` |
218 | | - |
219 | | -## 构建 |
220 | | - |
221 | | -在 RMCS 开发环境(zsh)中: |
222 | | - |
223 | | -```bash |
224 | | -build-rmcs --packages-select rmcs-navigation |
225 | | -``` |
226 | | - |
227 | | -如果还要联动构建定位与地图链路: |
228 | | - |
229 | | -```bash |
230 | | -build-rmcs --packages-select point_lio rmcs_local_map rmcs-navigation |
231 | | -``` |
232 | | - |
233 | | -## 调试 |
234 | | - |
235 | | -### 1) 组件初始化失败 |
236 | | - |
237 | | -优先检查: |
238 | | - |
239 | | -- `main.lua` 是否正确定义 `on_init()` / `on_tick()` |
240 | | -- `api.lua`、`blackboard.lua` 是否能被 `require(...)` 到 |
241 | | -- 包内 share 目录中的 Lua 文件是否已正确安装 |
242 | | - |
243 | | -### 2) mock 模式不生效 |
244 | | - |
245 | | -优先检查: |
246 | | - |
247 | | -- `mock_context` 是否为 `true` |
248 | | -- 是否向 `/rmcs_navigation/context/mock` 发了消息 |
249 | | -- 消息负载是否是根节点为 map 的 YAML 文本 |
250 | | - |
251 | | -### 3) Lua 侧验证 |
252 | | - |
253 | | -可以在 Lua 中直接调用: |
254 | | - |
255 | | -```lua |
256 | | -local api = require("api") |
257 | | -api.info("lua tick reached") |
258 | | -``` |
259 | | - |
260 | | -用于确认 `api` 注入与决策执行链路是否正常。 |
261 | | - |
262 | | -## Launch 相关 |
263 | | - |
264 | | -本包仍然保留 Nav2 与在线导航相关 launch 文件,例如: |
265 | | - |
266 | | -- `launch/nav2.launch.py` |
267 | | -- `launch/online.launch.py` |
268 | | -- `launch/custom.launch.py` |
269 | | -- `launch/follow_waypoints.launch.py` |
| 15 | + |
0 commit comments