- 创建 arm_control_msgs 包:定义机械臂控制的消息和服务接口 - 消息:JointState, TCPPose - 服务:MoveJoints, MovePose, GetPose, SetGripper - 实现 arm_control 节点:独立的机械臂控制 ROS 节点 - 完整的逆运动学和正运动学 - 关节空间和笛卡尔空间运动控制 - UDP 通信与 ESP32 - 状态发布(10Hz) - 实现 vision_grasp 节点:自动化视觉抓取 - 相机坐标系到基坐标系的完整变换 - 自动抓取流程:释放→移动→抓取→回收 - 自动释放流程:移动→释放→回收 - 多线程执行器支持 - 添加完整文档 - ARM_CONTROL_README.md: 机械臂控制节点使用指南 - VISION_GRASP_README.md: 视觉抓取节点使用指南 - QUICKSTART.md: 快速开始指南 - 文档重命名:docs/craic.md → docs/arm.md
6.5 KiB
6.5 KiB
视觉抓取节点 - 完成总结
✅ 完成的工作
1. 创建了视觉抓取 ROS 节点 (vision_grasp.py)
功能:
- ✅ 抓取功能:输入相机坐标 → 自动转换 → 执行抓取流程
- ✅ 释放功能:输入基坐标 → 移动 → 释放物体
- ✅ 坐标变换:集成
camera_to_base.py的完整变换逻辑 - ✅ 自动化流程:释放夹爪 → 移动 → 抓取 → 回收
2. 抓取流程
输入相机坐标 (x, y, z)
↓
转换: (xc, yc, zc) = (x, -y, z)
↓
变换到基坐标系
↓
1. Release 夹爪 (duration=0)
↓
2. 移动到目标 (duration=3s)
↓
3. Grip 夹爪 (duration=1s)
↓
4. 回收到 (200, 0, 当前z)
3. 释放流程
输入基坐标 (x, y, z)
↓
1. 移动到释放位置
↓
2. Release 夹爪 (duration=0)
↓
3. 回收到 (200, 0, 当前z)
📁 创建的文件
ros2/
├── src/udp_teleop/
│ ├── udp_teleop/
│ │ └── vision_grasp.py ✨ 视觉抓取节点
│ └── config/
│ └── vision_grasp.yaml ✨ 参数配置
├── test_vision_grasp.py ✨ 测试脚本
└── VISION_GRASP_README.md ✨ 完整文档
🚀 快速使用
启动节点
终端 1:arm_control 节点
cd ros2
source install/setup.bash
ros2 run udp_teleop arm_control \
--ros-args --params-file src/udp_teleop/config/arm_control.yaml
终端 2:vision_grasp 节点
cd ros2
source install/setup.bash
ros2 run udp_teleop vision_grasp \
--ros-args --params-file src/udp_teleop/config/vision_grasp.yaml
终端 3:测试
cd ros2
source install/setup.bash
# 测试抓取(相机正前方 300mm)
python test_vision_grasp.py grasp 0 0 300
# 测试抓取(相机右侧 50mm,前方 300mm)
python test_vision_grasp.py grasp 50 0 300
# 测试释放(基坐标)
python test_vision_grasp.py release 100 150 -100
或使用话题发布
# 抓取
ros2 topic pub --once /vision_grasp/grasp_target geometry_msgs/Point \
"{x: 0.0, y: 0.0, z: 300.0}"
# 释放
ros2 topic pub --once /vision_grasp/release_target geometry_msgs/Point \
"{x: 100.0, y: 150.0, z: -100.0}"
🎯 关键特性
1. 自动坐标转换
- 输入:相机坐标系
(x, y, z) - 自动转换:
(xc, yc, zc) = (x, -y, z)(图像坐标修正) - 变换到基坐标系:使用当前 TCP 位姿进行完整变换
2. 参数化配置
vision_grasp:
ros__parameters:
# 相机到 TCP 的变换
cam_tx: 0.0
cam_ty: 0.0
cam_tz: 0.0
# 回收位置
retract_position_x: 200.0
retract_position_y: 0.0
# 运动时长
grasp_duration: 3.0
release_duration: 2.0
3. 完整日志
节点会输出详细的流程日志:
============================================================
开始抓取流程
============================================================
1. 释放夹爪
2. 移动到目标位置: (323.5, 229.6, -108.6)
3. 抓取物体
4. 移动到回收位置: (200.0, 0.0, -108.6)
============================================================
✓ 抓取完成!
============================================================
🔗 集成示例
Python 脚本集成
#!/usr/bin/env python3
import rclpy
from rclpy.node import Node
from geometry_msgs.msg import Point
class MyDetector(Node):
def __init__(self):
super().__init__('my_detector')
self.grasp_pub = self.create_publisher(
Point, 'vision_grasp/grasp_target', 10)
def on_detection(self, camera_x, camera_y, camera_z):
"""检测到物体后触发抓取"""
msg = Point()
msg.x = camera_x
msg.y = camera_y
msg.z = camera_z
self.grasp_pub.publish(msg)
def main():
rclpy.init()
node = MyDetector()
# 模拟检测结果
node.on_detection(10.0, 5.0, 250.0)
rclpy.spin(node)
node.destroy_node()
rclpy.shutdown()
📊 话题接口
| 话题 | 类型 | 说明 |
|---|---|---|
/vision_grasp/grasp_target |
geometry_msgs/Point | 抓取目标(相机坐标) |
/vision_grasp/release_target |
geometry_msgs/Point | 释放目标(基坐标) |
🎓 下一步
1. 集成物体检测
# 订阅相机图像
self.image_sub = self.create_subscription(
Image, '/camera/image_raw', self.on_image, 10)
def on_image(self, msg):
# 检测物体
camera_x, camera_y, camera_z = detect_object(msg)
# 触发抓取
self.publish_grasp_target(camera_x, camera_y, camera_z)
2. 添加深度估计
使用 tools/vision_transform.py 中的相似三角形方法:
from tools.vision_transform import compute_depth_from_size
# 从检测获得像素宽度
pixel_width = 100 # px
real_width = 50 # mm
focal_length = 500 # px
depth = compute_depth_from_size(pixel_width, real_width, focal_length)
3. 多物体抓取
# 创建队列
self.grasp_queue = []
def on_multiple_detections(self, detections):
for det in detections:
self.grasp_queue.append(det)
# 逐个抓取
while self.grasp_queue:
target = self.grasp_queue.pop(0)
self.publish_grasp_target(target.x, target.y, target.z)
# 等待完成...
🐛 故障排查
Q1: 坐标转换不正确
检查:
- TCP 位姿是否正确(
ros2 service call /arm_control/get_pose) - 相机到 TCP 的变换参数(
cam_tx/ty/tz,cam_roll/pitch/yaw) - 坐标系方向理解是否正确
Q2: 抓取位置偏移
解决:
- 校准相机内参
- 验证深度计算准确性
- 调整
cam_pitch(如果相机有俯仰角)
Q3: 服务调用超时
检查:
- arm_control 节点是否运行
- UDP 连接是否正常
- 机械臂是否在合理位置
📚 相关文档
- 完整文档:
VISION_GRASP_README.md - 坐标变换:
tools/camera_to_base.py - 机械臂控制:
ARM_CONTROL_README.md - 视觉变换:
docs/vision_calibration_horizontal.md
🎉 总结
现在你有了一个完整的视觉抓取系统:
- ✅ 独立的机械臂控制节点 -
arm_control - ✅ 自动化抓取节点 -
vision_grasp - ✅ 完整的坐标变换 - 相机 → 基坐标系
- ✅ 参数化配置 - 灵活调整参数
- ✅ 测试工具 - 快速验证功能
- ✅ 完整文档 - 使用指南和示例
只需要:
- 添加物体检测算法
- 连接相机获取图像
- 发布检测结果到
/vision_grasp/grasp_target
系统就会自动完成抓取!