ROBOCON 2026「武林探秘」R1/R2 两机协作通信项目。
通信方案:AprilTag 定位 + LED 二进制光码。 R1 通过 LED 光码板发出状态信号,R2 通过摄像头 + AprilTag 检测解码。
📌 当前状态(2026-06-22):
- ✅ 软件协议与状态机已完成 (634 tests passed)
- ✅ STM32F103 + 三灯串口闭环已实机验证通过,ACK 正常
- ✅ STM32 六灯全部可点亮 (PA0-PA5)
- ✅ M3-1:Hikrobot 三灯识别已工程化
- ✅ M3-2:AprilTag 检测 + 透视矫正 + LED ROI 自动采样(软件)
- ✅ M3-3:R2 FSM HOLD/ERROR 安全门控
- ✅ M3-5:六灯 ROI 识别 + PatternMapper + 实时工具(软件)
- ✅ Round FSM-A:R1/R2 Mission FSM safety hardening
- R2 FSM: confidence / staleness / local_estop guards
- R1 FSM: ABORT 状态 + local_estop
- BeaconEvent 中间层 + ActionIntent 输出枚举
- RETRY_RESET 恢复支持
- FSM 安全仿真 demo (26 场景)
- 🔬 Round 4A:Hikrobot 真实相机六灯面包板 bitmask smoke test 进行中
⚠️ 面包板测试,非最终灯板结构⚠️ 当前不接 FSM 真实动作,只验证 LED bitmask 识别⚠️ 当前不宣称 M3 完成或实机链路最终通过 纯软件闭环可以直接跑,真实硬件替换上层接口不变。仓库包含两部分:
- 🐍 Python 上位机 — R1/R2 状态机、协议编解码、操作手输入、虚拟信标、benchmark
- 🔌 STM32F103 C 固件 — LED 光码板 MCU 裸寄存器固件(USART1 串口帧 → LED + ACK)
| 部分 | 位置 | 说明 |
|---|---|---|
| Python 控制端 | robocon_coop_comm/ tools/ |
R1 逻辑、状态机、协议、串口帧发送 |
| STM32 固件 | firmware/stm32f103_beacon_baremetal/ |
LED Beacon MCU 裸寄存器 C 固件 |
| Arduino 固件骨架 | firmware/led_beacon_mcu/ |
Arduino 参考实现 |
# 1. 烧录固件到 STM32F103(用 STM32CubeProgrammer 或 OpenOCD)
# 固件路径: firmware/stm32f103_beacon_baremetal/main.c
# 2. 激活 Python 环境
source .venv/bin/activate
# 3. 发一帧验证
python tools/r1_beacon_control.py --port /dev/ttyACM0 --command insert
# 期望: ack=CC 04 01, STM32 上 D2 LED 亮- ❌ R1/R2 之间不使用 Wi-Fi、蓝牙、Zigbee、UWB、LoRa、ESP-NOW 等无线射频通信。
- ❌ 武馆组装阶段不使用 R1/R2 直接接触式通信。
- ✅ 遥控器只向 R1 状态机发出"状态请求",不直接控制 R2,也不直接点亮某颗 LED。
- ✅ R2 将 R1 光码视为"队友状态",必须结合自身状态机和传感器判断后才执行动作。
- ✅ 所有危险事件(如
INSERT_ALLOWED)必须由 R1 本地传感器条件守卫。
git clone https://github.com/JFCY2718/robocon_coop_comm.git
cd robocon_coop_commpython3 -m venv .venv
source .venv/bin/activate
pip install -U pip
pip install -e ".[dev,vision]"./tools/test.sh
# 期望:188+ passed# 命令行闭环演示(不需要硬件)
python -m robocon_coop_comm.demo_cli
# FSM 安全仿真演示(26 安全场景)
python -m robocon_coop_comm.demo_fsm_safety
# OpenCV 虚拟信标窗口(需要图形界面)
python -m robocon_coop_comm.demo_cv# 需要先接好 ST-LINK 和 STM32,安装 pyserial
pip install pyserial
# dry-run 先验证帧格式
python tools/r1_beacon_control.py --dry-run --command insert
# 实机发送
python tools/r1_beacon_control.py --port /dev/ttyACM0 --command insert
# 期望看到: ack=CC 04 01| 硬件 | 用途 |
|---|---|
| STM32F103C8T6 (Blue Pill) | LED 光码 MCU,接收 USART1 串口帧 |
| ST-LINK/V2.1 | 烧录器 + USB 虚拟串口 (VCP),系统枚举为 /dev/ttyACM0 |
| 3× 高亮 LED + 限流电阻 | D0/D1/D2 三灯信标(✅ 已实机验证) |
| 3× LED(REF/SEQ/PAR) | 六灯模式下一阶段扩展(引脚 PA3/PA4/PA5 已预留) |
| Hikrobot 相机 | 三灯识别 ✅ 已工程化(HikrobotFrameProvider + ThreeLedRoiDecoder) |
三灯:
| STM32 GPIO | 连接 |
|---|---|
| PA0 | → 电阻 → D0 LED 长脚,短脚 → GND |
| PA1 | → 电阻 → D1 LED 长脚,短脚 → GND |
| PA2 | → 电阻 → D2 LED 长脚,短脚 → GND |
| PA3 | REF,预留 |
| PA4 | SEQ,预留 |
| PA5 | PAR,预留 |
串口(ST-LINK ↔ STM32):
| ST-LINK | STM32 |
|---|---|
| TX | PA10 / USART1_RX |
| RX | PA9 / USART1_TX |
| GND | GND |
串口参数: 115200 baud / 8N1 / 无流控
AA 55 msg_id seq brightness checksum
| 字节 | 字段 | 说明 |
|---|---|---|
| 0-1 | Header | 固定 AA 55 |
| 2 | msg_id | 0~31,对应 protocol.MsgID |
| 3 | seq | 0 或 1,事件切换时翻转 |
| 4 | brightness | 0~255 LED 亮度 |
| 5 | checksum | msg_id ^ seq ^ brightness |
ACK 格式: CC msg_id seq(3 字节)
| 命令 | msg_id | 帧 | ACK |
|---|---|---|---|
hold |
1 | AA 55 01 00 C8 C9 |
CC 01 00 |
rod |
2 | AA 55 02 01 C8 CB |
CC 02 01 |
insert |
4 | AA 55 04 01 C8 CD |
CC 04 01 |
mf |
7 | AA 55 07 00 C8 CF |
CC 07 00 |
robocon_coop_comm/
├── robocon_coop_comm/ # Python 包(核心代码)
│ ├── protocol.py # msg_id 定义、LED 编码/解码、校验
│ ├── r1_fsm.py # R1 任务状态机
│ ├── r2_fsm.py # R2 任务状态机
│ ├── serial_frame.py # MCU 串口帧编解码 (AA 55 ...)
│ ├── serial_transport.py # 串口传输抽象(内存假串口 / pyserial)
│ ├── led_mcu_client.py # LED MCU 高层客户端
│ ├── led_mcu_simulator.py # MCU 固件模拟器(无硬件时使用)
│ ├── beacon_image.py # 虚拟 LED 信标图像生成/解码
│ ├── beacon_decoder.py # 信标图像解码
│ ├── beacon_stabilizer.py # 解码结果稳定化
│ ├── beacon_frame_provider.py # 帧提供器抽象
│ ├── beacon_types.py # 信标类型定义
│ ├── hikrobot_frame_provider.py # ✅ Hikrobot 真实相机帧提供器 + 3-LED 解码器
│ ├── fake_frame_provider.py # ✅ 测试用假帧提供器(无 SDK)
│ ├── frame_logger.py # ✅ CSV/JSONL 帧调试日志
│ ├── operator_command.py # 操作手命令抽象层
│ ├── operator_session.py # 操作手会话管理
│ ├── keyboard_operator.py # 键盘操作手输入
│ ├── trace_events.py # 链路追踪事件
│ ├── trace_export.py # Chrome Trace 导出
│ ├── dojo_end_to_end.py # 武馆端到端 pipeline
│ ├── pipeline_benchmark.py # 性能 benchmark
│ ├── demo_cli.py # 命令行闭环演示
│ ├── demo_cv.py # OpenCV 虚拟信标窗口
│ ├── demo_mcu_pipeline.py # MCU pipeline 模拟
│ ├── demo_operator_pipeline.py # 操作手 pipeline
│ ├── demo_r2_vision_pipeline.py # R2 视觉 pipeline
│ ├── demo_dojo_end_to_end.py # 武馆端到端演示
│ ├── demo_benchmark.py # benchmark 入口
│ └── ros_nodes/ # ROS2 Humble 可选节点
├── firmware/
│ ├── stm32f103_beacon_baremetal/ # ✅ STM32F103 裸寄存器 C 固件(已实机验证)
│ │ ├── main.c # 固件源码
│ │ ├── README.md # 烧录/接线说明
│ │ └── PROTOCOL.md # 串口协议文档
│ └── led_beacon_mcu/ # Arduino MCU 固件骨架(参考实现)
├── test/ # pytest 单元测试 (215+)
├── docs/ # 协议、架构、硬件文档
├── tools/ # 开发/调试辅助脚本
├── .github/workflows/ # GitHub Actions CI
├── pyproject.toml # Python 项目配置
└── Makefile # 常用命令快捷方式
./tools/test.sh # 全部单元测试
make test-all # test + demo-cli-check + demo-mcu-check
make lint # ruff 代码检查python -m robocon_coop_comm.demo_cli # 命令行闭环
python -m robocon_coop_comm.demo_cv # OpenCV 虚拟信标窗口
python -m robocon_coop_comm.demo_mcu_pipeline # MCU pipeline 模拟
python -m robocon_coop_comm.demo_operator_pipeline # 操作手 pipeline
python -m robocon_coop_comm.demo_r2_vision_pipeline # R2 视觉 pipeline
python -m robocon_coop_comm.demo_dojo_end_to_end # 武馆端到端
python -m robocon_coop_comm.demo_benchmark # 性能 benchmark# R1 Beacon 交互控制台
python tools/r1_beacon_control.py --port /dev/ttyACM0
# R1 Beacon 单次发送
python tools/r1_beacon_control.py --port /dev/ttyACM0 --command insert
python tools/r1_beacon_control.py --dry-run --command insert # 只打印不发送
# 低层串口帧发送
python tools/send_3led_msg.py --port /dev/ttyACM0 --msg-id 4 --seq 1 --brightness 200
# 仅生成帧 hex(不开串口)
python tools/send_led_frame.py --msg-id 4 --seq 1 --brightness 200
# 关闭 LED
python tools/send_3led_msg.py --port /dev/ttyACM0 --msg-id 0 --seq 0 --brightness 0
# Round 4B:六灯自动化 expected-vs-observed 验证 🆕
python tools/sixled_serial_sequence.py \
--port /dev/ttyACM0 --values 0,63,1,2,4,8,16,32 \
--hold-sec 5 --log data/sixled/logs/round4b_expected.csv
python tools/sixled_expected_observed_check.py \
--expected data/sixled/logs/round4b_expected.csv \
--observed data/sixled/logs/round4b_t40_e12000.csv
# Hikrobot 三灯实时解码(需相机 + SDK)
python tools/hikrobot_3led_live.py
python tools/hikrobot_3led_live.py --threshold 100 --log /tmp/beacon.csv> hold # 发送 HOLD (msg_id=1)
> rod # 发送 R1_ROD_CLAMPED (msg_id=2)
> pose # 发送 R1_AT_ASSEMBLY_POSE (msg_id=3)
> insert # 发送 INSERT_ALLOWED (msg_id=4)
> locked # 发送 WEAPON_LOCKED (msg_id=5)
> clear # 发送 R1_CLEAR_MC (msg_id=6)
> mf # 发送 R1_IN_MF (msg_id=7)
> status # 查看当前状态
> help # 帮助
> q # 退出
python -m robocon_coop_comm.demo_benchmark --iterations 100 --warmup-iterations 1
python -m robocon_coop_comm.demo_benchmark --iterations 20 --trace-out /tmp/trace.json
make benchmark
make benchmark-check- 保持
./tools/test.sh通过 — 修改代码后先跑测试。 - 修改协议时同步更新
docs/PROTOCOL.md和测试。 - 新增硬件模块不要破坏纯软件 demo — 硬件和软件解耦。
- 每个状态机新增状态都要有单元测试。
操作手输入 (keyboard/F710/ROS2 joy)
→ OperatorSession / OperatorCommand
→ R1MissionFSM (r1_fsm.py)
→ LedMcuClient (led_mcu_client.py)
→ serial_frame.encode_frame()
→ PySerialTransport / MemorySerialTransport
→ STM32 USART1
→ LED 光码板 (PA0/PA1/PA2)
→ R2 摄像头 + AprilTag
→ BeaconDecoder → R2MissionFSM
- 在
protocol.py的MsgID枚举中添加。 - 在
r1_fsm.py中添加对应的状态转换。 - 在
tools/r1_beacon_control.py的COMMAND_MAP中添加命令映射。 - 更新
docs/PROTOCOL.md。 - 添加对应单元测试。
编辑 tools/r1_beacon_control.py 中的 COMMAND_MAP:
COMMAND_MAP: dict[str, MsgID] = {
# ... 现有命令 ...
"new_cmd": MsgID.SOME_NEW_MSG,
}| Pipeline | 入口 | 说明 |
|---|---|---|
| CLI Demo | demo_cli.py |
键盘 → R1 FSM → 直接解码 → R2 FSM,最简单闭环 |
| CV Demo | demo_cv.py |
同上 + OpenCV 虚拟信标图像窗口 |
| Operator Pipeline | demo_operator_pipeline.py |
操作手输入抽象层完整链路 |
| MCU Pipeline | demo_mcu_pipeline.py |
R1 FSM → LED MCU Client → 模拟器 |
| R2 Vision | demo_r2_vision_pipeline.py |
信标图像 → 解码 → 稳定化 → R2 FSM |
| Dojo E2E | demo_dojo_end_to_end.py |
武馆完整闭环(操作手 → R1 → LED → 视觉 → R2) |
| Benchmark | demo_benchmark.py |
端到端延迟测量 + Chrome Trace 导出 |
详细文档见 docs/ 目录。
| 文档 | 内容 |
|---|---|
| PROTOCOL.md | 光码协议完整定义 |
| ARCHITECTURE.md | 系统架构与模块边界 |
| SERIAL_FRAME.md | MCU 串口帧协议 |
| LED_MCU_LINK.md | LED MCU 链路与硬件接线 ✅ |
| OPERATOR_INPUT.md | 操作手输入抽象层 |
| R2_VISION_PIPELINE.md | R2 视觉解码 pipeline |
| HIKROBOT_REAL_CAMERA.md | Hikrobot 真实相机调试 ✅ |
| DOJO_END_TO_END.md | 武馆端到端 pipeline |
| MCU_PIPELINE_SIM.md | MCU pipeline 模拟 |
| PERFORMANCE_BENCHMARK.md | 性能 benchmark |
| FSM_SAFETY_DESIGN.md | FSM 安全设计文档 🆕 |
| R1_R2_MISSION_FSM.md | R1/R2 FSM 详细文档 🆕 |
| HANDOFF_TO_NEXT_CC_SESSION.md | CC 交接文档 🆕 |
| ROADMAP.md | 项目路线图 |
| LOCAL_DEV_UBUNTU22.md | Ubuntu 22.04 开发环境配置 |
source /opt/ros/humble/setup.bash
colcon build --symlink-install
source install/setup.bash
ros2 run robocon_coop_comm r1_fsm_nodeGitHub Actions 自动运行:
./tools/test.sh— 全部单元测试make demo-cli-check— CLI demo 回归make demo-mcu-check— MCU pipeline 回归make benchmark-check— 性能基准
ROBOCON 2026 战队 · 通信组