基于 ROS2 + YOLO 的视觉分拣系统
基于 Mech-Eye 3D 相机、YOLOv11 实例分割、ROS2 Humble 通信框架、AUBO i10H 协作机械臂和数字 IO 夹爪的视觉引导分拣系统。项目地址:https://github.com/Jees996/ros2-yolo-robot-sorting。
系统架构
系统由 4 个核心 ROS2 node 组成,通过 topic 和 service 松耦合:
Mech-Eye 相机采集 (2D + 深度)
│
▼
yolo_coordinate_publisher ← YOLOv11-seg 实例分割 → /vision/detections
│
▼
vision_coordinate_transformer ← 手眼标定矩阵 → camera → base 坐标 → /vision/targets_base
│
▼
sorting_decision ← 分拣状态机 → 目标选择、稳定性判断、抓取/放置序列
│
▼
arm_executor + gripper_controller ← AUBO TCP 位姿执行 + 数字 IO 夹爪
每个节点独立运行,可单独编译、测试和替换。
ROS2 包结构
项目包含 12 个 ROS2 package,按功能分组:
核心链路(4 个):
| 包 | 功能 |
|---|---|
yolo_coordinate_publisher |
Mech-Eye 采集、YOLO 分割推理、3D 检测结果发布 |
vision_coordinate_transformer |
camera_link → base_link 齐次变换,发布 TargetBase |
sorting_decision |
有限状态机:IDLE → SELECT → APPROACH → GRASP → LIFT → PLACE → RETRACT |
arm_executor |
AUBO TCP 位姿执行服务,支持 dry / sim / real 三种模式 |
辅助与接口(5 个):
| 包 | 功能 |
|---|---|
gripper_controller |
数字 IO 夹爪控制(开/关/断电),可配置 pin 和有效电平 |
sorting_executor |
关节状态发布、夹爪后端封装 |
vision_coordinate_bringup |
系统级 launch 入口,编排全部节点和参数 |
vision_interfaces |
自定义消息:Detection3D / TargetBase 及其数组 |
sorting_interfaces |
自定义服务:MoveTcpPose / MoveAbove / SetGripper |
AUBO 驱动(3 个,按需启用):
| 包 | 功能 |
|---|---|
aubo_ros2_driver |
AUBO C++ 硬件接口 + ros2_control |
aubo_description |
URDF / mesh / RViz 可视化资源 |
aubo_msgs / aubo_dashboard_msgs |
机器人状态、IO、JSON-RPC 接口消息和服务定义 |
相机与视觉
使用梅卡曼德 Mech-Eye PRO S 相机,通过 Mech-Eye SDK 获取 2D 彩色图和深度图。相机模块(camera/)提供:
- 在线采集 —
camera_controller.py封装 SDK,输出 RGB + 深度图 + 点云 - 离线标定板检测 —
detect_board_pose.py基于 OpenCV blob detector + PnP 求解标定板位姿 - 内参获取 —
get_intrinsics.py从 SDK 读取相机内参矩阵和畸变系数 - 参数配置 —
camera_config.json集中管理 IP、型号、曝光、输出路径和内参
YOLO 模块(yolo/)基于 Ultralytics YOLOv11-seg:
- 训练脚本
train_model.py,数据集配置brake_dataset_seg.yaml - 推理管道
mecheye_yolo_pipeline.py:读取相机输出 → YOLO 分割 → 提取 mask 中心点 → 查深度图得 3D 坐标 - 训练结果包含 F1/PR 曲线、混淆矩阵、训练批次可视化,权重文件随仓库分发
坐标转换
手眼标定采用 eye-in-hand 方案(相机固定于机械臂末端),使用 Tsai-Lenz 方法求解。
- 标定采集
eye_in_hand_capture.py:移动机械臂到多个位姿,记录 TCP 位姿 + 标定板检测结果 - 求解
solve_eye_in_hand_from_config.py:Tsai-Lenz 闭式解 → 手眼矩阵 - 结果输出到
handeye_result.json,包含旋转矩阵和平移向量 - 运行时
vision_coordinate_transformer读取手眼矩阵,对每个 Detection3D 做T_base_camera = T_base_tcp × T_tcp_camera变换,发布 TargetBase
分拣状态机
sorting_decision node 实现 7 状态 FSM:
IDLE ──[收到目标]──▶ SELECT ──[目标有效]──▶ APPROACH ──[到达]──▶ GRASP
│
┌─────────────────────────────────────────┘
▼
LIFT ──▶ PLACE ──▶ RETRACT ──▶ IDLE
- 稳定性判断:连续 N 帧检测到同一类别且 mask 中心偏移小于阈值才确认目标有效
- 抓取区域约束:通过
sorting_task.yaml配置有效作业空间的 x/y/z 范围 - 放置位姿:每个类别独立配置放置位(TCP 位姿),支持多放置位循环
安全模式
arm_executor 支持三种执行模式:
| 模式 | 行为 |
|---|---|
dry(默认) |
完整 ROS2 链路 + 视觉推理,但不驱动机械臂,仅 log 位姿 |
sim |
驱动 AUBO 仿真环境或 RViz 可视化 |
real |
实机执行,需先确认设备参数和安全条件 |
首次部署必须先跑 dry 模式,验证视觉检测、坐标转换、状态机逻辑和 topic/service 通信正常后再切 real。
关键配置文件
| 文件 | 内容 |
|---|---|
camera/camera_config.json |
相机 IP、型号、曝光、内参、YOLO 推理参数 |
aubo/control/aubo_config.json |
机械臂 IP、端口、账号密码、运动参数 |
eye_in_hand/output/handeye_result.json |
手眼标定矩阵(旋转 + 平移) |
sorting_decision/config/sorting_task.yaml |
目标类别、抓取区域、放置位、稳定性阈值 |
gripper_controller/config/gripper_config.yaml |
夹爪 IO pin、有效电平、断电策略 |
迁移到新设备时必须按 HARDWARE_CONFIGURATION_LOCATIONS.md 逐项修改上述配置,不可直接复用。
快速启动
# 构建
cd ros2_ws && colcon build --symlink-install && source install/setup.bash
# 默认 dry 模式启动
ros2 launch vision_coordinate_bringup system.launch.py
# 单次分拣
ros2 service call /sorting/start_once std_srvs/srv/Trigger "{}"
# 循环分拣
ros2 service call /sorting/start_loop std_srvs/srv/Trigger "{}"
# 停止
ros2 service call /sorting/stop std_srvs/srv/Trigger "{}"
# 实机模式(需先确认设备参数和安全)
ros2 launch vision_coordinate_bringup system.launch.py \
arm_mode:=real camera_preview:=off \
config_path:=camera/camera_config.json \
model_path:=yolo/model/yolo11s-seg.pt \
executor_config_path:=aubo/control/aubo_config.json \
decision_config:=sorting_decision/config/sorting_task.yaml
依赖
- ROS2 Humble + colcon
- Python 3.10+,PyTorch 2.x,Ultralytics,OpenCV
- Mech-Eye SDK(相机)
- AUBO Python/C++ SDK(机械臂)
- 硬件:Mech-Eye PRO S、AUBO i10H、数字 IO 夹爪
详见 requirements.txt 和各模块目录下的 README。
仓库地址:https://github.com/Jees996/ros2-yolo-robot-sorting
— 本文由 AI 助手代笔