树莓派入门到入土:ROS 2 视觉机器人项目复盘
本文目录
这不是把“树莓派 + ROS”概念拼在一起的通用入门文,而是基于现存学习笔记和项目资料整理的技术复盘。本地 ROS/Python 学习笔记目前是 Python 基础练习;另一份机器人项目文档快照标注于 2026-07-22,记录了 Raspberry Pi 5、Debian 13、Docker 中的 ROS 2 Humble、视觉检测和轨迹跟踪方案,并注明摄像头实测尚未完成。那份 ROS 方案目录没有可供复验的 ROS 2 源码工作区,因此其中的节点接口、容器状态和算法描述仍代表文档记录,不等于当前代码或真机验收结果。
如果目标是从头学习 ROS 2,而不是阅读这份视觉机器人项目复盘,可先看独立的 树莓派 ROS 2 入门:从 Python 小练习到机器人节点;该文是学习路线,不能替代项目源码审计或真实设备验收。
另外,在相关资料目录中发现一份独立的 Python 羽毛球视频分析代码。它的 README 指向公开上游 yo-WASSUP/Good-Badminton,所以本文只把它作为外部参考实现做有限静态审阅,不把代码、模型或功能归为站长原创;它也不是前述 ROS 2 方案的源码。
系统分层
| 层 | 项目记录 | 需要守住的边界 |
|---|---|---|
| 硬件宿主 | Raspberry Pi 5 8GB、Debian 13、ARM64 | 负责设备、电源、网络和硬件访问;不要为了装 ROS 擅自重装系统 |
| ROS 环境 | Docker 中运行 ROS 2 Humble,容器使用 Python 3.10 | Humble 的主要二进制目标是 Ubuntu 22.04;容器隔离用户空间,不等于硬件或网络隔离 |
| 节点链路 | 摄像头图像 → ONNX/HSV 视觉检测 → 2D 卡尔曼跟踪 | 代码记录不等于摄像头已到货或现场帧率已达标 |
| 未来控制 | PCA9685、机械臂/底盘、统一 bringup | 项目记录里仍是规划项;接真实电机前要有急停、限位和台架验证 |
ROS 2 Humble 的目标平台表以 Ubuntu Jammy 为主,官方时间表列出支持至 2027 年 5 月。该项目保留 Debian 宿主,把 ROS 放进 Ubuntu 用户空间容器,是为了减少宿主依赖冲突;这是项目约束下的工程选择,不是任何 Pi 项目都必须照抄的唯一方案。升级 ROS 发行版前先核对 REP-2000、镜像架构和相机/推理依赖。
2026 年平台组合复核
截至 2026-10-16,ROS 2 Lyrical Luth 已发布。官方发布信息将 Ubuntu 26.04 的 amd64/arm64 列为 Tier 1,把 Ubuntu 24.04、Debian Trixie 和 macOS 列为 Tier 3;Canonical 也已提供 Raspberry Pi 5 的 Ubuntu 26.04 LTS 镜像。因此,如果要新建一套 Pi 5 学习环境,优先评估 Ubuntu Server 26.04 ARM64 + ROS 2 Lyrical;但 Tier 1 仅说明平台目标支持,不代表当前摄像头、ONNX Runtime、特定推理硬件或本项目节点已经兼容。
| 目标 | 建议基线 | 需要验证 |
|---|---|---|
| 复现 2026-07 的项目快照 | Debian 13 宿主 + Ubuntu 22.04/Humble 容器 | 镜像 digest、ARM64 架构、设备映射、DDS 网络和实际帧率 |
| 新建 ROS 2 LTS 学习环境 | Pi 5 + Ubuntu 26.04 ARM64 + Lyrical | 相机驱动、ONNX/系统库、I2C/串口权限、工作区依赖 |
| Debian Trixie 原生运行 Lyrical | 可作为实验支线,不作为同等保证的默认方案 | 官方平台等级为 Tier 3,包兼容性和升级路径需自行验收 |
不要在当前 Debian/Humble 设备上直接跨发行版升级。先保留已知可启动的容器快照,另建独立工作区和 Lyrical 测试镜像;逐项核对 /etc/os-release、uname -m、ROS_DISTRO、RMW 实现、摄像头节点、模型推理和消息 QoS。只有在固定测试数据上通过节点启动、topic 收发、rosbag 回放和设备访问后,再决定是否迁移。这里是基于官方支持矩阵提出的后续测试方案,不是站长已经完成的设备迁移或实测。
数据流与节点职责
USB camera
│ sensor_msgs/msg/Image
▼
vision node: ONNX inference, with HSV emergency fallback
│ 2D detection: pixel x/y/r + capture time
▼
tracker node: outlier gate + constant-velocity Kalman filter
├── filtered pixel position and pixel/frame velocity
├── bounded recent image-space trajectory
└── short-horizon image-space extrapolation
│
└── controller is a future stage, not a verified actuator path
项目笔记记录了两个主要 Python 包:视觉节点订阅 sensor_msgs/msg/Image,使用羽毛球专用 YOLOv11 ONNX 模型,ONNX Runtime 不可用时可退回 HSV 颜色分割,并发布像素位置和可选标注图;跟踪节点使用匀速 2D 卡尔曼状态 [x, y, vx, vy],另做跳变门限、短时丢帧容忍、轨迹缓存和有限步数的外推。这些接口与算法细节尚未通过当前源码独立验证。若继续实现,模型推理、相机驱动和后续执行器应分节点,便于单独测延迟和故障。
外部参考代码:离线视频分析管线
这份独立代码提供 CLI 和 Gradio 两种入口,共用同一个逐帧分析系统。WebUI 先自动检测球场;失败时允许用户按顺序点击四个角点。代码随后把模板角点按视频帧尺寸缩放,用四点透视变换把图像平面映射到约 6.1 × 13.4 米的球场平面,再以球场范围生成姿态检测 ROI。自动检测由线段候选、交点组合和球场几何评分组成,手工标注仍是恢复路径。
羽毛球检测并非“模型输出即轨迹”:实现先按置信度、候选框面积和预测位置挑选候选,再做 ROI 与跳变/短期预测门限;缺帧一段时间后会放宽连续轨迹门限。这里的预测是图像像素上的简化外推,不是带空气阻力、球拍碰撞、深度和相机标定的飞行物理模型。球员位置经过球场映射后输出轨迹、速度/距离等统计,管线还可生成标注视频、JSON 元数据、JSONL 检测记录以及热力图/散点图。
WebUI 源码把单个输入视频限制为 2 GiB、模板图限制为 50 MiB,并把默认队列并发设为 1;结果目录只保留最近 10 份,超出的旧目录会被清理且清理异常被静默忽略。launch 调用没有显式传入账号认证或监听地址,因此不能仅凭“有浏览器界面”就把它当成可直接公网部署的服务;公开运行前必须明确网络绑定、访问认证、磁盘配额、任务隔离、取消和输出下载授权。大文件上限也不等于安全的内存/磁盘预算。
以上是对本地外部参考快照的静态阅读,不代表重新运行了 WebUI、GPU 推理、模型权重、精度基准或 Pi 设备。README 中的速度数字是上游记录,不是本次复测;外部仓库只作为参考来源,不等于站长个人作品。
先修数据契约,再接控制器
当前项目记录用 Float32MultiArray 的位置约定传 [x, y, r, timestamp],跟踪输出也把多个字段塞进数组。它上手快,但字段顺序、单位和版本都只能靠文档约定,改一端就可能静默读错。适合原型,不适合把未经检查的值直接送到机械控制。
建议下一版定义带语义的消息:
- 图像时间使用 ROS Header 的时间戳和
frame_id,不要用一个浮点数混装时钟语义。 - 检测消息明确
center_x_px、center_y_px、半径/框、置信度、图像宽高和有效标志。 - 跟踪消息明确坐标系、单位、速度单位、观测时间、跟踪状态和丢失原因。
- 控制器只接受有效、足够新、置信度达标且在安全工作区内的目标;过期/NaN/越界时必须停止或进入安全状态。
2D 像素坐标经过单目相机的卡尔曼滤波,只能得到图像平面轨迹。恒速向前推 10 帧不是羽毛球真实落点预测:它没有球场标定、深度、重力、阻力和相机运动模型。需要先标定镜头/球场并建立世界坐标,再用实测轨迹验证物理模型;不要把二维外推直接换算成机械臂指令。
容器和 ARM64 检查
树莓派 5 是 ARM64。ROS 官方 library 的 Humble Jammy base 镜像列有 arm64v8,而 OSRF 的桌面叠加镜像架构不应被默认视为 ARM64。选镜像时同时核对 tag、基础 Ubuntu 版本和 manifest 架构;不需要在 Pi 上显示 RViz 时,优先从较小的 ros:humble-ros-base-jammy 构建专用开发镜像,再按需安装相机/视觉依赖。构建产物应记录镜像 tag 或 digest,避免依赖漂移。
容器运行权限要按设备最小化:显式映射实际需要的 /dev/video*、I2C 或串口设备,给容器非 root UID,并只挂载工作区。--privileged、挂载整个 /dev、宿主 SSH 私钥和 host 网络虽然省事,但会扩大容器对宿主的访问面;只有明确需要且理解风险时才启用。host network 能简化 DDS 发现,同时也意味着容器共享宿主网络边界。
容器环境常用操作如下。容器名、工作区和包名应按自己的 compose 配置替换:
docker image inspect ros2-badminton:dev --format "{{.Os}}/{{.Architecture}}"
docker exec -it ros2-dev bash
source /opt/ros/humble/setup.bash
cd /ros2_ws
rosdep install --from-paths src --ignore-src -r -y
colcon build --symlink-install --packages-up-to badminton_vision
source install/setup.bash
ros2 node list
ros2 topic list
若 docker image inspect 结果不是 linux/arm64,不要尝试靠改 --platform 把 x86 镜像当成本机原生部署;应选有 ARM64 manifest 的基础镜像或明确进行有性能代价的模拟。Docker 官方 ROS 镜像标签和架构会随时间变化,更新前先在测试环境拉取验证。
分层验证清单
- 硬件/宿主:确认电源、存储余量、散热、内核识别和摄像头设备节点;先用只读命令观察,不要在 SD 卡唯一副本上反复断电。
- 容器:检查镜像架构、ROS 发行版、挂载目录、运行 UID 和设备权限;确认容器内 Python/ONNX Runtime 与 wheel ABI 对得上。macOS arm64 wheel 不能装进 Linux aarch64 容器。
- 相机驱动:先看设备列表和实际图像,再检查编码、分辨率、时间戳与帧率;发布 60fps 参数并不证明 Pi 已经稳定处理 60fps。
- 视觉节点:用固定图像或离线录包验证检测框、置信度和漏检;记录推理耗时、CPU、内存、掉帧和 HSV 回退次数。
- 跟踪节点:先用合成的移动点、停留点、跳变点和连续丢失帧覆盖初始化、门限、滤波和重置;再用录制数据回放。
- 分布式调试:用
ros2 topic info <topic> --verbose核对 QoS,用ros2 topic hz <topic>看实际发布频率;跨设备订阅还要检查 ROS_DOMAIN_ID、DDS 实现、网段发现和防火墙。 - 机械控制:先在断开执行器或限流台架上验证状态机、超时和急停;绝不把未经标定的像素坐标直接映射为高速舵机/底盘动作。
对于实时图像流,ROS 2 的 sensor-data QoS 往往优先新鲜数据而不是可靠重传;它不是所有节点的固定答案。订阅和发布端的 QoS 必须兼容,结合丢帧容忍度与网络质量实测。
常见故障定位
| 现象 | 优先检查 |
|---|---|
找不到 ros2 | 当前 shell 是否 source /opt/ros/humble/setup.bash 和工作区 install/setup.bash |
| 容器里看不到摄像头 | 主机是否识别设备、compose 是否映射设备、用户是否有 video 权限 |
| 节点存在但 topic 收不到 | ROS_DOMAIN_ID、发布/订阅 QoS、ROS graph、namespace/remapping |
| 只能在 Pi 本机发现节点 | 检查 DDS discovery、网络接口、防火墙和是否误用了 host/container 两套不同网络配置 |
onnxruntime 导入失败 | Linux ARM64、Python ABI、manylinux 标签和依赖是否与容器一致;不要混装 macOS wheel |
| 帧率低或温度升高 | 分别计量相机、预处理、推理、发布耗时;先降分辨率或减少可视化,不要凭感觉调模型 |
| 轨迹预测跳动 | 检查真实帧间隔、时间戳、噪声参数、检测离群点和重置条件;固定 dt 仅适用于帧率稳定的简化原型 |
本机 Python 练习:已验证与未完成
2026-10-14 对本机 Python 学习目录做了源码检查,并用 Python 3.9.6 实际运行 lesson5.py 与 lesson6.py。lesson5.py 完成字典字段增改删、键值遍历和成员检查;lesson6.py 对示例传感器读数统计得到 4 个大于 3.0 的值,按顺序找到的首个大于 5.0 的值是 5.1,并输出传感器错误和车轮警告。
lesson7.py 目前只有函数、默认参数、类型标注和 lambda 的练习说明,没有可执行答案;不能据此认定函数课程已完成。检查到的这组文件也没有 rclpy 导入、ROS 2 节点、Publisher 或 Subscriber 实现。它们证明的是 Python 基础练习可运行,不是 ROS 2 工作区、机器人视觉管线或真机链路已验收。
推荐学习顺序
本地学习笔记展示了 Python 字典、条件/循环到函数的基础练习,尚不能代表 ROS 2 课程已经完成。下一步不要急着碰机械臂,按“Linux 与容器 → ROS node/topic → 参数与 launch → sensor_msgs/QoS → rosbag 回放 → 相机检测 → 2D 跟踪 → 标定和世界坐标 → 控制”逐层学习。每层都留下可重复的命令、输入样本和验收结果。
项目记录提到参考过 Good-Badminton。资料将其定位为视频后处理/分析项目,适合参考检测和离群点处理思路,不应把依赖 GPU 的整套离线 pipeline 直接移到 Pi 做实时控制;引用其实现时需回到上游检查当前许可和依赖。
官方资料
- ROS REP-2000:目标平台与发行版时间表:核对发行版、操作系统和架构支持;表格会更新。
- ROS 2 Lyrical Luth 发布说明:核对 Lyrical 当前公布的平台支持层级。
- ROS 2 Lyrical Ubuntu 安装指南:以官方说明配置 apt 源、安装组件并验证环境。
- Ubuntu on Raspberry Pi:核对当前可用镜像与设备支持,不以旧教程中的版本号代替设备页面。
- Raspberry Pi 无屏安装与远程访问:使用 Imager 预配置网络和 SSH,并先准备可恢复的启动介质。
- ROS 2 Humble 文档:节点、Topic、Service、Action、参数、launch 和调试命令。
- 官方 ROS Docker 镜像标签:查看 Jammy base、tag 与 arm64v8 架构清单。
- OSRF Docker Images:区分 Official Library 基础镜像与 OSRF 桌面叠加镜像的用途和架构。
- ROS 2 QoS 设计:理解可靠性、历史深度和 sensor-data profile 的取舍。
硬件型号、系统镜像、摄像头、ROS 发行版和模型都会变化。下一次更新应先重新确认真实设备和代码状态,尤其是摄像头实测、ROS 节点接口与控制器进度;不要把几个月前的项目快照写成当前生产状态。
Live Notes
留言提交后会先进入审核,审核通过后对其他读者公开。