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

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

moveit2_servo 不吃 "轨迹",只吃 "速度增量指令" 相机 → 算出目标偏移 → 转成 TwistStamped(速度) → 发给 /servo_demo_node/delta_twist_cmdsmoveit2_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
   ↓
机械臂动
相关推荐
xieliyu.2 小时前
Java算法精讲:双指针(三)
java·开发语言·算法
我没胡说八道2 小时前
高校论文AI检测优化工具对比研究与实测分析(2026)
人工智能·深度学习·机器学习·计算机视觉·aigc·论文
秦亚伟2 小时前
AI浪潮重塑融资租赁行业新格局
人工智能
love530love2 小时前
LiveTalking 数字人项目 Windows 部署完全指南(EPGF 架构)
人工智能·windows·python·架构·livetalking·epgf
元启数宇2 小时前
喷淋AI布点实战:8小时人工布点→20分钟自动出图
人工智能
哈哈,柳暗花明2 小时前
人工智能专业术语详解(H)
人工智能·专业术语
圣殿骑士-Khtangc2 小时前
AI 编程工具 2026 实战横评:Cursor 3 vs Claude Code vs Copilot,开发者选型完全指南
人工智能·copilot
云器科技2 小时前
云器Lakehouse 2026年5月版本发布:拥抱 AI Agent,重塑数据智能开发新范式
人工智能
小鹰-上海鹰谷-电子实验记录本2 小时前
第六届党建引领科创生态座谈会 | 邓光辉博士出席分享AI赋能创新药科研新范式
人工智能·ai·电子实验记录本·药企合规
极客老王说Agent2 小时前
2026电信IDC机房巡检深度报告:人工巡检频次和深度够吗?实在Agent重塑智慧运维新范式
人工智能·ai·chatgpt