moveit2_servo 怎么接收相机调节指令(视觉伺服)

一、核心原理(一句话懂)

moveit2_servo 不吃 "轨迹",只吃 "速度增量指令" 相机 → 算出目标偏移 → 转成 TwistStamped(速度) → 发给 /servo_demo_node/delta_twist_cmds → moveit2_servo 自动 IK + 避障 → 输出 /arm_controller/joint_trajectory

和你键盘控制完全同一路线,只是把键盘换成相机。


二、moveit2_servo 固定输入话题(必须记住)

ROS2 Humble + moveit2_servo 默认输入:

  • 笛卡尔(末端)指令: /servo_demo_node/delta_twist_cmds消息:geometry_msgs/TwistStamped

  • 关节指令: /servo_demo_node/delta_joint_cmds消息:moveit_msgs/JointJog

相机必须发 TwistStamped 到上面这个 topic!


三、相机 → moveit2_servo 完整流程(4 步)

1)相机输出:目标在相机坐标系的 3D 位姿

相机节点输出:

  • TF:camera_link → target
  • 或者话题:/target_pose(PoseStamped)

2)手眼标定(关键!)

必须知道:

  • base_link ↔ camera_link 的 TF(固定)
  • end_effector ↔ camera_link(眼在手上)

没有标定,坐标乱飘。

3)视觉 PID(把偏移 → 速度指令)

相机算出:

plaintext

复制代码
error_x, error_y, error_z (m)
error_rx, error_ry, error_rz (rad)

用简单 PID 转成 TwistStamped(速度):

plaintext

复制代码
linear.x  = Kp * error_x
linear.y  = Kp * error_y
linear.z  = Kp * error_z
angular.x = Kp * error_rx
...

4)发给 moveit2_servo(和你键盘完全一样)

ROS2 发布到:

plaintext

复制代码
/servo_demo_node/delta_twist_cmds

moveit2_servo 收到后:

  • 内部 IK
  • 碰撞检测
  • 限速
  • 输出:/arm_controller/joint_trajectory

四、直接可用的 ROS2 相机→servo 代码(极简)

python

运行

复制代码
#!/usr/bin/env python3
import rclpy
from rclpy.node import Node
from geometry_msgs.msg import TwistStamped, PoseStamped
from tf2_ros import TransformListener, Buffer
import math

class CameraToServo(Node):
    def __init__(self):
        super().__init__('camera_to_servo')
        # 发布给 servo
        self.pub = self.create_publisher(TwistStamped, '/servo_demo_node/delta_twist_cmds', 10)
        # 订阅相机目标位姿
        self.create_subscription(PoseStamped, '/target_pose', self.pose_cb, 10)

        self.tf_buffer = Buffer()
        self.tf_listener = TransformListener(self.tf_buffer, self)

        self.Kp = 0.5  # 速度增益,调这个

    def pose_cb(self, msg):
        try:
            # 把目标转到 base_link
            tf = self.tf_buffer.lookup_transform(
                'base_link', msg.header.frame_id, rclpy.time.Time()
            )
        except:
            return

        # 简化:直接拿误差做速度(PID你再加)
        err_x = msg.pose.position.x - tf.transform.translation.x
        err_y = msg.pose.position.y - tf.transform.translation.y
        err_z = msg.pose.position.z - tf.transform.translation.z

        twist = TwistStamped()
        twist.header.stamp = self.get_clock().now().to_msg()
        twist.header.frame_id = 'base_link'

        twist.twist.linear.x  = self.Kp * err_x
        twist.twist.linear.y  = self.Kp * err_y
        twist.twist.linear.z  = self.Kp * err_z
        # 旋转同理,这里省略

        self.pub.publish(twist)

def main():
    rclpy.init()
    Node = CameraToServo()
    rclpy.spin(Node)
    Node.destroy_node()
    rclpy.shutdown()

if __name__ == '__main__':
    main()

五、servo 参数必须开对(非常关键)

servo_params.yaml 确保:

yaml

复制代码
moveit_servo:
  ros__parameters:
    command_in_type: "twist_units"   # 接收Twist
    robot_link_command_frame: "base_link"  # 和相机统一
    scale:
      linear: 0.2   # 最大速度 m/s

六、最终数据流(你一眼看懂)

plaintext

复制代码
相机 → 目标位姿 → 视觉PID → TwistStamped
   ↓
/servo_demo_node/delta_twist_cmds
   ↓
moveit2_servo(IK+避障+限速)
   ↓
/arm_controller/joint_trajectory
   ↓
机械臂动
相关推荐
JIAOZHANZHISHIKU5 小时前
机器人外壳粘接性价比怎么选?3M VHB 胶带与结构胶解决方案
经验分享·机器人·工业胶粘剂·3m胶粘剂
Easy_API6 小时前
2.8万亿参数,编程反超GPT-6 Astra:Kimi K3.1 Pro把开源模型推到了哪一步
大数据·人工智能·gpt·深度学习
GlobalInfo6 小时前
2026年机器人多指灵巧手市场分析报告——涵盖行业调查、趋势分析与发展前景
大数据·人工智能·microsoft·微服务·机器人
紧跟先前的步伐7 小时前
Go AI Agent 实战 24|工具系统工程化收尾与阶段验收
人工智能·ai·golang·1024程序员节
释厄6237 小时前
AI学习层更新与跨体转移律——人类社会同构·不缺理解缺 U
人工智能·学习
老金带你玩AI8 小时前
集万家所长,一键复制的Agent.md!
人工智能
ZhuoAIStage8 小时前
舞台工艺多专业审图提速:用 AI 智能体编排 A+B+C+G 四段读图流水线
人工智能·自动化·工作流编排·舞台工艺·审图智能体
小奶包他干奶奶8 小时前
AI学习——1、机器学习概念
人工智能·机器学习
展讯快报8 小时前
悬浮提词器免费App评估报告:说得AI的免费策略与可用性分析
人工智能
Yuzhiyuxia9 小时前
【AI Agent面试系列】AI Agent记忆机制知识点1
人工智能·面试·职场和发展