# 方框检测与自动抓取节点 基于 YOLO 模型检测方框,并自动调用视觉抓取节点完成抓取。 ## 功能特性 - ✅ 实时 YOLO 方框检测 - ✅ 自动/手动模式切换 - ✅ 检测成功后自动停止识别 - ✅ 自动发布抓取目标到 `/vision_grasp/grasp_target` - ✅ 3D 坐标估计(基于方框尺寸) ## 快速开始 ### 1. 启动必要的节点 ```bash # 终端 1: 启动 arm_control 节点 ros2 run udp_teleop arm_control \ --ros-args --params-file src/udp_teleop/config/arm_control.yaml # 终端 2: 启动 vision_grasp 节点 ros2 run udp_teleop vision_grasp \ --ros-args --params-file src/udp_teleop/config/vision_grasp.yaml ``` ### 2. 启动方框检测节点 #### 自动模式(检测到方框后自动抓取) ```bash ros2 run udp_teleop box_detection_grasp \ --ros-args --params-file src/udp_teleop/config/box_detection_grasp.yaml \ -p auto_grasp:=true ``` #### 手动模式(仅检测,不自动抓取) ```bash ros2 run udp_teleop box_detection_grasp \ --ros-args --params-file src/udp_teleop/config/box_detection_grasp.yaml \ -p auto_grasp:=false ``` ## 工作流程 ### 自动模式 (auto_grasp=true) 1. 节点启动后立即开始实时检测 2. 检测到方框后: - 停止检测(避免重复) - 计算 3D 坐标(相机坐标系,单位:mm) - 发布到 `/vision_grasp/grasp_target` - vision_grasp 节点接收并执行抓取 3. 等待 10 秒后完成(可自定义) 4. 节点保持运行但不再检测 ### 手动模式 (auto_grasp=false) - 节点启动后不检测 - 通过服务触发检测: ```bash # 启动检测 ros2 service call /box_detection/start std_srvs/srv/Trigger # 停止检测 ros2 service call /box_detection/stop std_srvs/srv/Trigger ``` ## 服务接口 ### `/box_detection/start` 启动方框检测。 **类型**:`std_srvs/srv/Trigger` **示例**: ```bash ros2 service call /box_detection/start std_srvs/srv/Trigger ``` **响应**: - `success: true` - 检测已启动 - `success: false` - 检测已在运行或抓取进行中 ### `/box_detection/stop` 停止方框检测。 **类型**:`std_srvs/srv/Trigger` **示例**: ```bash ros2 service call /box_detection/stop std_srvs/srv/Trigger ``` **响应**: - `success: true` - 检测已停止 - `success: false` - 检测未运行 ## 使用场景 ### 场景 1:自动抓取流水线 ```bash # 启动自动模式 ros2 run udp_teleop box_detection_grasp \ --ros-args --params-file src/udp_teleop/config/box_detection_grasp.yaml \ -p auto_grasp:=true # 节点自动检测并抓取,无需人工干预 ``` ### 场景 2:手动触发抓取 ```bash # 终端 1: 启动手动模式 ros2 run udp_teleop box_detection_grasp \ --ros-args --params-file src/udp_teleop/config/box_detection_grasp.yaml \ -p auto_grasp:=false # 终端 2: 需要抓取时手动触发 ros2 service call /box_detection/start std_srvs/srv/Trigger # 检测到方框后自动抓取,完成后停止 # 需要再次抓取时,再次调用 start 服务 ros2 service call /box_detection/start std_srvs/srv/Trigger ``` ### 场景 3:紧急停止 ```bash # 在检测过程中紧急停止 ros2 service call /box_detection/stop std_srvs/srv/Trigger ``` ## 配置参数 编辑 `config/box_detection_grasp.yaml`: ```yaml box_detection_grasp: ros__parameters: # 相机流 stream_url: "http://192.168.4.1/stream" # 模型路径 model_path: "/path/to/model.pt" # 检测参数 confidence: 0.35 # 置信度阈值 imgsz: 768 # YOLO 输入尺寸 device: "" # "cpu", "cuda", 或 "" (自动) detection_rate: 10.0 # 检测频率 (Hz) # 方框尺寸(用于深度估计) box_size_m: 0.03 # 方框边长 (米) # 相机参数 horizontal_fov_deg: 66.0 # 水平视场角 # 调试 show_debug_window: false # 显示检测窗口 # 控制 auto_grasp: false # 自动抓取开关 ``` ## 调试 ### 显示检测窗口 ```bash ros2 run udp_teleop box_detection_grasp \ --ros-args --params-file src/udp_teleop/config/box_detection_grasp.yaml \ -p auto_grasp:=true \ -p show_debug_window:=true ``` ### 监控话题 ```bash # 查看抓取目标 ros2 topic echo /vision_grasp/grasp_target # 查看日志 ros2 node list ros2 node info /box_detection_grasp ``` ## 坐标系说明 - **输入**:YOLO 检测框(图像像素坐标) - **输出**:相机坐标系 3D 坐标(单位:mm) - X: 向右 - Y: 向下 - Z: 向前(深度) - **传递**:vision_grasp 节点自动转换到基坐标系 ## 深度估计原理 使用透视投影原理: ``` Z = (实际尺寸 × 焦距) / 像素尺寸 X = (u - cx) × Z / fx Y = (v - cy) × Z / fy ``` 其中: - `box_size_m` = 方框实际边长(米) - `horizontal_fov_deg` = 相机水平视场角 ## 故障排除 ### 问题:无法连接到 ESP32 相机 **解决**: 1. 检查 ESP32 IP 地址:`ping 192.168.4.1` 2. 浏览器访问:`http://192.168.4.1` 3. 修改配置:`-p stream_url:=http:///stream` ### 问题:检测不到方框 **解决**: 1. 降低置信度:`-p confidence:=0.25` 2. 检查模型路径:`ls -lh src/udp_teleop/models/box_detection.pt` 3. 启用调试窗口:`-p show_debug_window:=true` ### 问题:深度估计不准确 **解决**: 1. 校准方框尺寸:`-p box_size_m:=0.03` 2. 校准相机 FOV:`-p horizontal_fov_deg:=66.0` ## 依赖 - ROS 2 Humble - Python 3.8+ - OpenCV (`pip install opencv-python`) - NumPy (`pip install numpy`) - Ultralytics YOLO (`pip install ultralytics`) ## 示例:完整启动脚本 ```bash #!/bin/bash # 启动完整的方框检测与抓取系统 # 确保在 ros2 目录 cd ~/Dev/craic/ros2 source install/setup.bash # 启动 arm_control gnome-terminal -- bash -c " source install/setup.bash ros2 run udp_teleop arm_control \ --ros-args --params-file src/udp_teleop/config/arm_control.yaml exec bash" sleep 2 # 启动 vision_grasp gnome-terminal -- bash -c " source install/setup.bash ros2 run udp_teleop vision_grasp \ --ros-args --params-file src/udp_teleop/config/vision_grasp.yaml exec bash" sleep 2 # 启动方框检测(自动抓取模式) gnome-terminal -- bash -c " source install/setup.bash ros2 run udp_teleop box_detection_grasp \ --ros-args --params-file src/udp_teleop/config/box_detection_grasp.yaml \ -p auto_grasp:=true \ -p show_debug_window:=true exec bash" echo "所有节点已启动!" ``` 保存为 `launch_box_grasp.sh` 并运行: ```bash chmod +x launch_box_grasp.sh ./launch_box_grasp.sh ```