260428
嗯...我想了想,其实还是可以引入动态 SLAM 的。
这样的话我们的旗帜变换位置后,小车就可以自行探索封闭空间,然后找到旗帜并停下了,避免将旗帜作为环境之一。
以及,因为 AI 目前来说还是会参与到我部分的代码编写中,但是对于我正在学习的东西的话,我希望还是尽可能我自己来写代码(参考我之前自行实现神经网络和对应的反向传播)。
这也是我正在考虑的一个点——一种更好的引导方式,避免 AI 直接写代码的同时,又可以让我知道怎么去写这个代码来让我自行去实现。
然后我想了想,其实可以为我们的目标写一个大的 roadmap, 在其下写一个 index.md, 其中每个 item 都对应一个目录。
然后在对应的目录下, 我们创建对应的 roadmap, 在对应的 roadmap item 目录中, 编写详细的 roadmap, 验收条件, 文件组织, 文件应有的功能改动等。
具体到让 AI 进行补全,就差不多是下面这样的了:
这个方式很适合你的目标,而且比“直接开写代码”更利于学习和长期迭代。
我建议把它设计成一个 docs/roadmap 风格的学习型工程路线,而不是普通 TODO。核心思想是:
大目标 roadmap
-> 阶段 index
-> 子阶段 roadmap
-> 任务说明
-> 学习目标
-> 设计约束
-> 验收条件
-> 文件改动计划
-> 调试方法
-> 复盘记录
## 推荐目录结构
可以是这样:
docs/
embodied-ai-roadmap/
index.md
00-system-baseline/
roadmap.md
acceptance.md
file-plan.md
notes.md
01-slam-localization/
roadmap.md
acceptance.md
file-plan.md
notes.md
02-nav2-integration/
roadmap.md
acceptance.md
file-plan.md
notes.md
03-frontier-exploration/
roadmap.md
acceptance.md
file-plan.md
notes.md
04-vision-flag-detection/
roadmap.md
acceptance.md
file-plan.md
notes.md
05-flag-localization/
roadmap.md
acceptance.md
file-plan.md
notes.md
06-mission-state-machine/
roadmap.md
acceptance.md
file-plan.md
notes.md
07-integrated-demo/
roadmap.md
acceptance.md
file-plan.md
notes.md
## index.md 应该承担的职责
index.md 不写太细,主要作为总控视图:
# Embodied AI Roadmap: Autonomous Exploration and Flag Seeking
## Goal
让小车在未知封闭空间中,通过 SLAM、导航、探索和视觉感知,自主探索环境、发现旗帜,并在靠近或发现旗帜后停止。
## Non-goals
- 第一阶段不使用真实机器人。
- 第一阶段不追求复杂语义理解。
- 第一阶段不使用深度学习检测器,除非 HSV / AprilTag / ArUco 无法满足需求。
- 不再直接发布旗帜全局位姿作为任务输入。
## Milestones
| Stage | Name | Purpose | Status |
|---|---|---|---|
| 00 | System Baseline | 梳理当前系统和传感器 | Not Started |
| 01 | SLAM Localization | 建立 map/odom/base_link TF 链路 | Not Started |
| 02 | Nav2 Integration | 支持点到点导航 | Not Started |
| 03 | Frontier Exploration | 自动探索未知区域 | Not Started |
| 04 | Vision Flag Detection | 通过视觉发现旗帜 | Not Started |
| 05 | Flag Localization | 估计旗帜相对或全局位置 | Not Started |
| 06 | Mission State Machine | 探索/追踪/停止状态切换 | Not Started |
| 07 | Integrated Demo | 完整闭环演示 | Not Started |
## 每个子目录建议固定 4 个文件
### 1. roadmap.md
回答“这个阶段要做什么”。
建议格式:
# 04 Vision Flag Detection
## Objective
通过相机图像检测旗帜,并发布结构化检测结果。
## Learning Goals
- 理解 ROS2 图像消息。
- 理解 `cv_bridge`。
- 理解颜色阈值 / 目标检测的基本流程。
- 理解检测结果如何作为任务状态机输入。
## Inputs
- `/camera/image_raw`
- `/camera/camera_info`
## Outputs
- `/flag_detection`
## Proposed Approach
第一版使用 HSV 阈值检测固定颜色旗帜。
## Task Breakdown
- [ ] 确认相机 topic。
- [ ] 定义检测结果消息。
- [ ] 编写检测节点。
- [ ] 在 RViz 或 OpenCV 窗口中验证 bbox。
- [ ] 发布 `/flag_detection`。
### 2. acceptance.md
回答“做到什么程度算完成”。
# Acceptance Criteria
## Functional
- 小车前方出现旗帜时,检测节点能发布 `detected=true`。
- 旗帜离开视野后,检测节点能发布 `detected=false`。
- 检测结果包含 bbox 中心点和尺寸。
- 检测频率不低于 5 Hz。
## Integration
- `mission_manager_node` 可以订阅检测结果。
- 不依赖旗帜的仿真全局位姿。
- 不修改 Gazebo 世界中的旗帜发布逻辑作为感知输入。
## Debugging
- 可以通过日志看到检测状态。
- 可以通过 RViz 或 debug image 看到 bbox。
### 3. file-plan.md
回答“预计要动哪些文件”。
# File Plan
## New Files
- `src/kibot_vision/kibot_vision/flag_detector_node.py`
- `src/kibot_interfaces/msg/FlagDetection.msg`
- `src/kibot_vision/launch/flag_detector.launch.py`
## Modified Files
- `src/kibot_interfaces/CMakeLists.txt`
- `src/kibot_interfaces/package.xml`
- `src/kibot_vision/setup.py`
## File Responsibilities
`flag_detector_node.py`
- 订阅图像。
- 转换为 OpenCV 格式。
- 使用 HSV 阈值检测旗帜区域。
- 发布 `FlagDetection`。
`FlagDetection.msg`
- 表达视觉检测结果。
- 不包含任务决策逻辑。
### 4. notes.md
回答“我学到了什么 / 卡在哪里”。
# Notes
## Decisions
- 第一版先使用 HSV,而不是 YOLO。
- 第一版只做 2D bbox,不估计 3D 位姿。
## Problems
- 光照变化可能导致 HSV 阈值不稳定。
- 如果旗帜太小,bbox 抖动明显。
## Review Notes
- 后续可以加入图像形态学处理。
- 后续可以加入 confidence 平滑。
## 我建议补充两个文件
除了每个阶段的 4 个文件,我建议总目录下再加两个全局文件。
### architecture.md
存总体架构,不随着单个任务频繁变化。
Sensor Layer
RGB Camera
Lidar
Odometry
Perception Layer
Flag Detector
Optional Flag Localizer
Mapping Layer
SLAM Toolbox
Navigation Layer
Nav2
Exploration Layer
Frontier Explorer
Decision Layer
Mission Manager
### glossary.md
存概念表。这个对你学习具身智能很有用。
# Glossary
## SLAM
Simultaneous Localization and Mapping,同时定位与建图。
## TF
ROS 中的坐标系变换系统。
## Frontier
已知自由空间和未知空间的边界,常用于自主探索。
## 每个 roadmap item 可以包含“我能引导你的粒度”
我建议每个阶段都写一个 guidance.md,明确我怎么介入:
# Guidance Contract
## You will implement
- Node structure
- Parameters
- Launch files
- Debugging
## Codex will provide
- Architecture review
- Interface design
- Pseudocode
- Code review
- Debugging hints
## Codex will not do unless explicitly asked
- Write full node implementation
- Modify project files directly
- Refactor working code
这个文件很关键,因为它能防止我后面不小心“越界”直接替你实现。
## 更完整的目录结构
我会建议这样:
docs/
embodied-ai-roadmap/
index.md
architecture.md
glossary.md
guidance-contract.md
00-system-baseline/
roadmap.md
acceptance.md
file-plan.md
notes.md
01-slam-localization/
roadmap.md
acceptance.md
file-plan.md
notes.md
02-nav2-integration/
roadmap.md
acceptance.md
file-plan.md
notes.md
03-frontier-exploration/
roadmap.md
acceptance.md
file-plan.md
notes.md
04-vision-flag-detection/
roadmap.md
acceptance.md
file-plan.md
notes.md
05-flag-localization/
roadmap.md
acceptance.md
06-mission-state-machine/
notes.md
07-integrated-demo/
roadmap.md
acceptance.md
file-plan.md
notes.md
## 我建议的路线顺序
我不建议直接从视觉开始。更稳的顺序是:
1. 00-system-baseline
先确认现有机器人、topic、TF、传感器、Gazebo 世界、已有 package。
2. 01-slam-localization
先让机器人知道自己在哪里。
3. 02-nav2-integration
先能去指定目标点。
4. 03-frontier-exploration
再能自动探索。
5. 04-vision-flag-detection
再通过视觉发现旗帜。
6. 05-flag-localization
再估计旗帜位置。
7. 06-mission-state-machine
最后把探索、发现、靠近、停止串起来。
8. 07-integrated-demo
做完整演示和复盘。
原因是:视觉发现旗帜本身不难,难的是发现之后机器人如何在地图、坐标系、导航行为中正确响应。
## 我建议我们的下一步
先不要写代码。下一步可以只创建 roadmap 文档骨架。
但在创建前,我们最好先决定两个点:
1. 文档放在 docs/embodied-ai-roadmap/,还是项目根目录 roadmap/?
2. 这个 roadmap 是中文为主,还是英文为主?
我的建议:
docs/embodied-ai-roadmap/
中文为主,保留 ROS2 / SLAM / Nav2 / TF 等英文术语
这样最适合学习和后续检索。
就这样,我们就创建了 docs/embodied-ai-roadmap/index.md:
# 路线图:自主探索与旗帜寻找
## 目标结果
KiBotTwo 从“读取外部发布的旗帜位姿”演进为“自主探索未知封闭空间、通过视觉发现旗帜、并完成靠近或停止任务”的系统。
最终系统不应把旗帜位姿当作已知环境信息,而应将旗帜作为运行时感知目标。
## 当前路线状态
当前阶段:`00-系统基线`
| 阶段 | 状态 | 依赖 | 阶段产出 |
| --- | --- | --- | --- |
| 00-系统基线 | 已计划 | 无 | 当前系统能力边界和数据流 |
| 01-SLAM-建图与定位 | 受阻 | 00-系统基线 | 可用的 SLAM 建图与定位链路 |
| 02-Nav2-导航接入 | 受阻 | 01-SLAM-建图与定位 | 可执行点到点导航的 Nav2 系统 |
| 03-边界探索 | 受阻 | 02-Nav2-导航接入 | 可自动选择探索目标的探索模块 |
| 04-视觉旗帜检测 | 受阻 | 00-系统基线 | 不依赖旗帜全局位姿的视觉检测模块 |
| 05-旗帜位置估计 | 受阻 | 04-视觉旗帜检测 | 可用于靠近任务的旗帜位置估计 |
| 06-任务状态机 | 受阻 | 03-边界探索、04-视觉旗帜检测 | 探索、发现、靠近、停止的任务状态机 |
| 07-集成演示 | 受阻 | 06-任务状态机 | 端到端演示与复盘 |
## 路线依赖图
```text
00-系统基线
-> 01-SLAM-建图与定位
-> 02-Nav2-导航接入
-> 03-边界探索
-> 06-任务状态机
-> 07-集成演示
00-系统基线
-> 04-视觉旗帜检测
-> 05-旗帜位置估计
-> 06-任务状态机
阶段 00:系统基线
状态:已计划
阶段目的:
- 明确当前项目已经具备什么能力。
- 找出当前“直接发布旗帜位姿”的数据路径。
- 确认后续 SLAM、Nav2、视觉模块接入的真实工程入口。
进入条件:
- 项目可以正常构建,或至少可以启动当前仿真。
- 能访问当前 package、launch、URDF/Xacro、world、节点代码和接口定义。
阶段产出:
- 当前 ROS2 graph 的概要记录。
- 当前 TF tree 的概要记录。
- 当前传感器列表。
- 当前旗帜位姿发布和消费链路。
- 后续阶段的实现风险清单。
完成条件:
- 能说明当前小车如何移动。
- 能说明当前旗帜信息如何进入任务逻辑。
- 能说明当前是否已有 lidar、camera、odom、imu、TF。
- 能决定
01-SLAM-建图与定位和04-视觉旗帜检测的最小切入点。
后续阶段:
01-SLAM-建图与定位04-视觉旗帜检测
阶段 01:SLAM 建图与定位
状态:受阻
依赖阶段:
00-系统基线
阶段目的:
- 引入或整理 SLAM 链路。
- 建立
map -> odom -> base_link的定位基础。 - 让小车在未知环境中生成可用于导航的地图。
阶段产出:
- SLAM launch / config 方案。
- 可在 RViz 中观察的 map。
- 稳定的 TF 链路。
- 对 lidar / odom 数据质量的判断。
完成条件:
- 小车移动时地图可以持续更新。
map、odom、base_link的 TF 关系清晰且无冲突。- 生成的地图足够支持 Nav2 costmap。
后续阶段:
02-Nav2-导航接入
阶段 02:Nav2 导航接入
状态:受阻
依赖阶段:
01-SLAM-建图与定位
阶段目的:
- 引入 Nav2 点到点导航能力。
- 让小车能够在地图和 costmap 基础上执行目标点导航。
阶段产出:
- Nav2 bringup 方案。
- planner / controller / costmap 的最小配置。
- 可通过 RViz 或 action client 发送目标点。
完成条件:
- 小车能接收
NavigateToPose目标。 - 小车能规划路径并尝试到达目标点。
- 障碍物和未知区域在 costmap 中表现合理。
后续阶段:
03-边界探索
阶段 03:边界探索
状态:受阻
依赖阶段:
02-Nav2-导航接入
阶段目的:
- 让小车从“被动接收目标点”升级为“主动选择探索目标”。
- 使用 frontier 或等价策略驱动未知空间探索。
阶段产出:
- frontier 提取策略。
- frontier 评分和过滤策略。
- 向 Nav2 发送探索目标的模块设计。
- 探索失败和目标不可达处理策略。
完成条件:
- 小车能在没有人工目标点的情况下探索未知空间。
- 探索目标不会明显重复或频繁震荡。
- 遇到不可达目标时能切换到其他目标。
后续阶段:
06-任务状态机
阶段 04:视觉旗帜检测
状态:受阻
依赖阶段:
00-系统基线
阶段目的:
- 通过相机图像发现旗帜。
- 移除任务逻辑对旗帜全局位姿输入的依赖。
阶段产出:
- 旗帜视觉检测方案。
- 检测结果 topic / message 设计。
- 第一版检测节点的输入输出契约。
完成条件:
- 旗帜进入视野时能发布检测结果。
- 旗帜离开视野时能恢复未检测状态。
- 检测结果与任务决策解耦。
后续阶段:
05-旗帜位置估计06-任务状态机
阶段 05:旗帜位置估计
状态:受阻
依赖阶段:
04-视觉旗帜检测
阶段目的:
- 将图像中的旗帜检测转化为机器人可用的空间位置估计。
- 判断第一版任务应采用“发现即停止”还是“发现后靠近”。
阶段产出:
- 旗帜位置估计策略。
- 坐标系转换链路。
- 检测抖动和丢失目标处理策略。
完成条件:
- 能给出旗帜相对
base_link或camera_link的估计。 - 如需要全局导航,能转换到
map坐标系。 - 能明确估计误差对靠近任务的影响。
后续阶段:
06-任务状态机
阶段 06:任务状态机
状态:受阻
依赖阶段:
03-边界探索04-视觉旗帜检测
可选依赖:
05-旗帜位置估计
阶段目的:
- 将探索、视觉发现、靠近旗帜和停止行为组织成明确状态机。
- 避免探索逻辑、视觉逻辑和导航逻辑互相耦合。
阶段产出:
- 任务状态定义。
- 状态切换条件。
- Nav2 goal 发送、取消和切换策略。
- 误检、目标丢失、导航失败、超时的处理规则。
完成条件:
- 小车可从
EXPLORING切换到旗帜相关状态。 - 检测到旗帜后不会继续盲目探索。
- 停止条件明确且可复现。
后续阶段:
07-集成演示
阶段 07:集成演示
状态:受阻
依赖阶段:
06-任务状态机
阶段目的:
- 完成从启动仿真到任务结束的端到端闭环。
- 记录系统能力边界、失败模式和下一轮优化方向。
阶段产出:
- 一套可复现的 demo 流程。
- RViz 可视化配置。
- 运行指令。
- 已知问题列表。
- 下一版路线图候选项。
完成条件:
- 在未知封闭空间中,小车能开始探索。
- 旗帜位置变化后,小车仍能通过视觉发现旗帜。
- 小车能按当前策略靠近或停下。
- 不依赖直接发布的旗帜全局位姿完成任务。
路线图更新规则
- 只有当前阶段可以进入
进行中。 - 阶段完成后,再创建或补全下一阶段的详细 roadmap。
- 如果某阶段发现前置假设错误,应回到依赖阶段更新结论。
- 每个阶段结束时,必须记录新的风险、取舍和下一步入口。
阶段状态说明
已计划 尚未开始,但已进入近期计划
进行中 当前正在推进
受阻 等待依赖阶段完成
已完成 已达到完成条件
暂缓 暂时不做,但不阻塞主线
返工 已完成过,但需要重新调整
在这个的基础上,我们在对应的阶段创建实际的 Roadmap 的详细 item 就可以了。
我们先实现阶段 0 的 item,写入docs/embodied-ai-roadmap/00-系统基线/roadmap.md:
```markdown
# 阶段 00:系统基线调查报告
## 本阶段定位
本阶段由 Codex 负责完成项目梳理,用于承接当前系统,并为后续 SLAM、Nav2、自主探索和视觉旗帜检测提供工程入口。
本阶段不是学习任务清单,也不是功能实现阶段。它的产物应该回答:
```text
当前系统是什么样?
当前能力边界在哪里?
后续阶段应该从哪里接入?
哪些现有逻辑需要保留、替换或隔离?
调查方式
本次基线基于源码静态分析完成,未启动 Gazebo 或 ROS2 graph 做运行时采样。
已阅读范围:
README.mdsrc/kibot_one_control的 package、launch 和 Python 节点src/kibot_one_interface的 msg / srv 接口src/kibot_one_sim的 launch、bridge 配置、world 和 SDF 模型
核心结论
当前系统是一个基于 Gazebo Sim 的移动机器人仿真项目,主要能力是:
- 启动 Gazebo 世界。
- 通过
ros_gz_bridge桥接 Gazebo 和 ROS2。 - 使用
/cmd_vel控制 Gazebo 中的差速机器人模型。 - 使用
/odom、/robot_pose、/flag_pose和/scan做目标跟随。 - 通过模式系统在 STOP、CRUISE、MANUAL、FOLLOW 之间切换。
- FOLLOW 模式下,
follow_controller直接读取机器人全局位姿和旗帜全局位姿,结合激光雷达做局部避障跟随。
当前系统还不具备:
- 相机传感器。
- 深度相机。
- IMU。
- SLAM。
- Nav2。
mapframe。- 标准
base_linkframe。 - 基于视觉的旗帜检测。
- 自主探索。
当前主线数据流
Gazebo world
-> kibot_one_base model
-> DiffDrive plugin
-> /model/kibot_one_base/odometry
-> ros_gz_bridge
-> /odom
Gazebo world
-> follow_flag model
-> PosePublisher plugin
-> /model/follow_flag/pose
-> ros_gz_bridge
-> /flag_pose
Gazebo lidar
-> /scan
-> ros_gz_bridge
-> /scan
/mode
/odom or /robot_pose
/flag_pose
/scan
-> follow_controller
-> /cmd_vel_raw
-> cmd_vel_watchdog
-> /cmd_vel
-> ros_gz_bridge
-> /model/kibot_one_base/cmd_vel
-> Gazebo DiffDrive
当前任务逻辑判断
当前“找旗帜”的任务并不是感知任务,而是位姿跟随任务。
follow_controller 直接订阅 /flag_pose,从消息中读取 x/y 作为目标点;同时订阅 /robot_pose 或 /odom 获取机器人自身位置,再计算到旗帜的方向和距离。当距离小于 stop_distance 时发布零速度停止。
这条链路绕过了:
- 视觉发现。
- 目标识别。
- 从图像估计目标位置。
- 地图构建。
- 全局路径规划。
因此后续目标不是简单替换某个参数,而是要逐步把“已知旗帜位姿输入”改造成“运行时视觉感知输入”。
对后续阶段的直接影响
对阶段 01:SLAM 建图与定位
当前已有 /scan 和 /odom,这是接入 2D SLAM 的基础。
但存在关键风险:
- 当前机器人坐标 frame 是
chassis,不是 Nav2 / SLAM 常见的base_link。 - 激光 frame 是
lidar_link,但 ROS 侧是否存在chassis -> lidar_link的 TF 需要运行时确认。 - 当前没有
mapframe。 - 当前没有
robot_state_publisher,模型是 Gazebo SDF,不是 URDF / Xacro。
阶段 01 的首要任务应该不是直接调 slam_toolbox 参数,而是先补齐或确认 TF 结构。
对阶段 02:Nav2 导航接入
当前控制入口是 /cmd_vel,理论上 Nav2 controller 可以输出到 /cmd_vel。
但当前已有 cmd_vel_watchdog 和多个控制节点会通过 /cmd_vel_raw -> /cmd_vel 链路控制机器人。后续接入 Nav2 时必须避免多个控制源同时发布速度。
阶段 02 需要明确:
- Nav2 是否直接发布
/cmd_vel。 - 是否保留
cmd_vel_watchdog。 - FOLLOW / MANUAL / CRUISE 模式与 Nav2 控制权如何互斥。
对阶段 03:边界探索
当前没有地图,也没有 Nav2,因此不能直接做 frontier exploration。
边界探索必须依赖:
map。- 机器人在
map中的定位。 - 可用的 Nav2 goal 接口。
对阶段 04:视觉旗帜检测
当前没有相机,因此视觉检测阶段必须先给机器人模型增加 RGB camera,并通过 bridge 暴露 ROS2 图像 topic。
当前旗帜模型具备红色旗面,尺寸约为 0.30 x 0.02 x 0.20,适合第一版用颜色阈值做检测。
对阶段 05:旗帜位置估计
当前没有深度相机。若只增加 RGB camera,第一版可以先做“发现即停止”;若要“发现后靠近”,需要至少满足一个条件:
- 增加 depth camera。
- 利用已知旗帜尺寸做单目测距。
- 结合机器人运动和多帧观测做估计。
对阶段 06:任务状态机
当前模式系统已经有 STOP、CRUISE、MANUAL、FOLLOW,但 FOLLOW 逻辑是“直接跟随旗帜位姿”。
后续可以复用模式管理思想,但不建议继续把探索、视觉、导航和停止逻辑塞进现有 follow_controller。
更合理的方向是新增 mission manager,让它管理:
探索中
-> 发现旗帜
-> 取消探索目标
-> 靠近或停止
-> 任务结束
本阶段结论
阶段 00 已经足够解锁两个并行方向:
01-SLAM-建图与定位:基于/scan和/odom,先解决 TF 命名和激光 frame 问题。04-视觉旗帜检测:先给 SDF 机器人模型增加 RGB camera,再桥接图像 topic,最后检测红色旗面。
推荐先推进 01-SLAM-建图与定位,因为自主探索和后续靠近旗帜都依赖地图、定位和导航能力。
目前就是对我们系统的调查情况了,在此基础上我们可以继续后续的 roadmap:01-SLAM-建图与定位。
我觉得这个东西有必要打包为 skill。
最后写了个第一版放到了我的 Skill 仓库里,就叫 guided-engineering-roadmap吧。
对应的仓库地址:https://github.com/JeseKi/jese\_skills/blob/main/guided-engineering-roadmap/SKILL.md