Files
ROS2_learn/doc/99-embodied-ai.md
T

18 KiB

99 · 入门具身智能:从 ROS2 到 VLA / 机器人(完全学习路线)

目标:为"想用本仓库入门具身智能"的开发者,画一张清晰、可执行、有时间估算的学习路线图。 读完这篇,你就知道"接下来该装什么、写什么、跑什么"。


目录


0. 你现在的位置

已掌握 (本仓库覆盖)

  • ROS2 通信:Topic / Service / Action / Parameter
  • TF2 坐标变换 + URDF 描述
  • sensor_msgs/Image + cv_bridge
  • JointState 发布(模拟)
  • launch 文件 + 测试金字塔
  • Docker 容器化开发
  • 跨包跨语言互通

还没掌握 (缺口)

  • ros2_control 硬件驱动抽象层
  • MoveIt2 运动规划(IK / path / collision)
  • Gazebo / ros_gz 物理仿真
  • 真实机械臂 URDF(6-7 DoF)+ Gripper
  • 手眼标定(eye-in-hand / eye-to-hand)
  • Cartesion path planning
  • 力控 / Force-Torque sensor
  • 真实电机驱动(Bus Servo / EtherCAT)
  • GraspNet / 6-DoF 抓取
  • VLA 模型接入(OpenVLA / Pi0)
  • 移动底盘(Nav2 / SLAM)
  • 多机协调 / ROS2 多机器人

1. ROS2 全栈知识点地图

                                ROS2 全栈
                                    │
        ┌───────────────────────────┼───────────────────────────┐
        │                           │                           │
    通信层(本仓库)            机器人层                    应用层
        │                           │                           │
  ┌─────┼─────┐             ┌───────┼───────┐           ┌───────┼───────┐
  │     │     │             │       │       │           │       │       │
Topic  Srv  Action      URDF  ros2_ctrl MoveIt2       Nav2  VLA  Gazebo
  │     │     │             │       │       │           │       │       │
  └─────┴─────┘             └───────┴───────┘           └───────┴───────┘
        │                           │                           │
     7 包已覆盖              需要继续补              需要仿真/真机

2. 5 个学习阶段(完全路线)

本仓库 ──── 阶段 1 (本仓库) ──── 阶段 2 (仿真机械臂) ──── 阶段 3 (Gazebo)
   │                                                                 │
   │                                                                 ▼
   │                                                  阶段 4 (视觉抓取)
   │                                                                 │
   │                                                                 ▼
   └─────────────────────────────────────────────────── 阶段 5 (真机+VLA)
阶段 主题 工作量 学习产出
1. 通信 + TF + 视觉 本仓库 已完成 ROS2 全栈基础
2. 仿真机械臂 ros2_control + MoveIt2 + 6-DoF URDF 2-3 周 能用 MoveIt2 算关节轨迹
3. 物理仿真 Gazebo + ros_gz 1-2 周 离线测试机械臂 / 视觉
4. 视觉 + 抓取 GraspNet / 6-DoF + 手眼标定 3-4 周 "看到 → 抓" 端到端
5. 真机 + VLA OpenVLA / Pi0 + ros2_control + 真电机 4-8 周 具身智能 MVP

总计: 3-5 个月全职工作量(取决于每周投入时间)。


3. 阶段 1: 通信 + TF + 视觉(本仓库已完)

验证清单

  • Topic pub/sub 跨语言互通(听 cpp 收 py / 听 py 收 cpp)
  • Service 同步 req/resp(12+30=42 验证)
  • Action 三件套(Fibonacci 验证)
  • TF 坐标变换(gripper 在 base_link 下位置)
  • Image + cv_bridge(图像流验证)
  • 10/10 测试 100% 通过

你应该已经能

  • 写 Topic pub/sub 节点(单语言)
  • 写 launch 文件
  • 用 ros2 CLI 调试
  • 理解 DDS 自动发现
  • 跑 colcon build + test

4. 阶段 2: 仿真机械臂(ros2_control + MoveIt2)

4.1 安装清单

# PC 上(本机)
sudo apt install -y \
  ros-humble-ros2-control \
  ros-humble-ros2-controllers \
  ros-humble-moveit \
  ros-humble-moveit-resources \
  ros-humble-moveit-servo \
  ros-humble-moveit-ros-planners

预计下载 ~1GB。

4.2 写 6-DoF 机械臂 URDF

本仓库的 cpp_robot_tf2/urdf/simple_arm.urdf 是 3 关节玩具臂。

升级步骤:

  1. 找一款开源 6-DoF 机械臂 URDF(推荐):
  2. 把它拷到 src/<新包>/urdf/
  3. <transmission> 标签(ros2_control 需要)
  4. <gazebo> 标签(后续 Gazebo 用,可选)
  5. check_urdf <urdf> 校验

URDF 关键改造:

<!-- 关节加 transmission -->
<joint name="joint1" type="revolute">
  <parent link="base_link"/>
  <child  link="link1"/>
  <origin xyz="0 0 0.05" rpy="0 0 0"/>
  <axis   xyz="0 0 1"/>
  <limit  lower="-3.14" upper="3.14" effort="100" velocity="1.0"/>
  <!-- ros2_control 需要 -->
  <transmission name="trans_joint1">
    <type>transmission_interface/SimpleTransmission</type>
    <joint name="joint1">
      <hardwareInterface>hardware_interface/PositionJointInterface</hardwareInterface>
    </joint>
    <actuator name="motor_joint1">
      <hardwareInterface>hardware_interface/PositionJointInterface</hardwareInterface>
      <mechanicalReduction>1</mechanicalReduction>
    </actuator>
  </transmission>
</joint>

4.3 ros2_control 配置

src/my_arm_controller/config/my_controllers.yaml:

controller_manager:
  ros__parameters:
    update_rate: 100
    joint_state_broadcaster:
      type: joint_state_broadcaster/JointStateController
    arm_controller:
      type: position_controllers/JointGroupPositionController

arm_controller:
  ros__parameters:
    joints:
      - joint1
      - joint2
      - joint3
      - joint4
      - joint5
      - joint6

4.4 ros2_control launch

src/my_arm_controller/launch/arm_control.launch.py:

from launch import LaunchDescription
from launch_ros.actions import Node
from ament_index_python.packages import get_package_share_directory
import os

def generate_launch_description():
    pkg_share = get_package_share_directory('my_arm_controller')
    config = os.path.join(pkg_share, 'config', 'my_controllers.yaml')
    urdf = os.path.join(pkg_share, 'urdf', 'arm.urdf')
    with open(urdf, 'r') as f: urdf_content = f.read()

    return LaunchDescription([
        Node(package='controller_manager', executable='ros2_control_node',
             parameters=[{'robot_description': urdf_content, 'update_rate': 100}],
             output='screen'),
        Node(package='controller_manager', executable='spawner',
             arguments=['joint_state_broadcaster', '-c', '/controller_manager'],
             output='screen'),
        Node(package='controller_manager', executable='spawner',
             arguments=['arm_controller', '-c', '/controller_manager'],
             output='screen'),
    ])

4.5 MoveIt2 SRDF(从 URDF 生成)

ros2 launch moveit_setup_assistant setup_assistant.launch.py

在 MoveIt Setup Assistant 里:

  1. Load URDF
  2. Add Virtual Joint(base_link → world)
  3. Add Planning Group("arm" 包含 6 个 joint)
  4. Add Poses(home / ready / extended)
  5. Add End Effector(gripper)
  6. Add Passive Joints
  7. Generate SRDF + MoveIt 配置

4.6 MoveIt2 编程

# PC 上: MoveIt2 客户端 → /joint_trajectory → ros2_control → 电机
from moveit.planning import MoveItPy
from moveit.core import PlanningComponent

moveit = MoveItPy(node=your_node)
arm = moveit.get_planning_component("arm")
arm.set_start_state_to_current_state()
arm.set_goal_state_from_pose_stamped(goal_pose)
plan_result = arm.plan()

if plan_result:
    arm.execute(plan_result.trajectory, blocking=True)

预期效果: 在 RViz 点目标位姿 → MoveIt2 算关节轨迹 → ros2_control 执行 → 真实机械臂(或仿真臂)运动。

4.7 阶段 2 验证清单

  • ros2_control 6 关节都能 set position
  • MoveIt2 RViz 里 plan + execute 能看到机械臂动
  • 写 Python 节点调用 MoveIt2 API,能指定目标 pose 让臂到达
  • 加 UnitTest 验证 motion plan 正确性

预计 2-3 周。完成后你能:"告诉末端去哪个 pose,MoveIt2 算出关节轨迹,ros2_control 执行"。


5. 阶段 3: 物理仿真(Gazebo / ros_gz)

5.1 安装

sudo apt install -y ros-humble-ros-gz

5.2 把 URDF 改成 Gazebo 模型

<gazebo> 标签 + <transmission>(已在阶段 2 加)→ gazebo_ros2_control 自动识别。

5.3 Gazebo Sim 启动

ros2 launch ros_gz_sim gz_sim.launch.py gz_args:="-r empty.sdf"
# 加载机械臂
ros2 run ros_gz_sim create -world default \
  -file ~/ros2_ws/src/my_arm/urdf/arm.urdf \
  -name my_arm \
  -x 0 -y 0 -z 1

5.4 ros_gz_bridge

把 Gazebo 的 Topic 桥到 ROS2:

  • /clock ←→ /clock(仿真时间)
  • /world/default/model/my_arm/joint_state/joint_states
  • /cmd_vel → Gazebo twist controller

5.5 仿真 + MoveIt2

# 终端 1: Gazebo
ros2 launch my_arm gazebo.launch.py

# 终端 2: ros2_control spawner
ros2 launch my_arm ros2_control.launch.py

# 终端 3: MoveIt2
ros2 launch my_arm moveit.launch.py

# 终端 4: 写 Python 脚本,MoveIt2 算轨迹 → 发到 Gazebo → 看可视化

预计 1-2 周。完成后你能"在仿真里训练 / 验证 / 演示"。


6. 阶段 4: 视觉 + 抓取(GraspNet / 6-DoF)

6.1 硬件升级

  • 加 RGB-D 相机(RealSense D435 / Azure Kinect)
  • 加力矩传感器(可选)

6.2 相机驱动

sudo apt install -y ros-humble-realsense2-camera
# 或:
sudo apt install -y ros-humble-azure-kinect

发布 /camera/color/image_raw + /camera/depth/image_rect_raw + /camera/depth/color/points

6.3 6-DoF GraspNet 集成

# grasp_detector 节点
import rospy
from sensor_msgs.msg import Image, PointCloud2
from geometry_msgs.msg import PoseStamped

class GraspNetNode:
    def __init__(self):
        self.image_sub = rospy.Subscriber('/camera/color/image_raw', Image, self.image_cb)
        self.cloud_sub = rospy.Subscriber('/camera/depth/color/points', PointCloud2, self.cloud_cb)
        self.grasp_pub = rospy.Publisher('/grasp_pose', PoseStamped, queue_size=10)

    def image_cb(self, msg):
        # 1) 用 GraspNet 模型推理
        # 2) 输出 6-DoF grasp pose
        # 3) publish /grasp_pose
        pass

6.4 手眼标定(eye-in-hand)

sudo apt install -y ros-humble-easy-handeye

# 标定流程:
# 1) 启动相机 + 标定板 + MoveIt2
# 2) 移动机械臂到多个 pose
# 3) easy_handeye 离线计算 camera_link → gripper 静态 TF
# 4) 把 TF 写进 URDF

6.5 端到端抓取

vision_node (YOLO/GraspNet)
    ↓ /grasp_pose
grasp_planner (MoveIt2 算轨迹)
    ↓ /joint_trajectory
ros2_control (PID 闭环)
    ↓
电机 → 真实 / 仿真机械臂 → 抓取

6.6 阶段 4 验证

  • 摄像头能 publish 图像 + 点云
  • GraspNet 能输出 6-DoF grasp pose
  • MoveIt2 根据 grasp pose 算出无碰撞轨迹
  • 仿真里端到端跑通"看到物体 → grasp → 抓取"

预计 3-4 周。完成后你能做"6-DoF 抓取 demo"。


7. 阶段 5: 真机 + VLA(OpenVLA / Pi0)

7.1 VLA 是什么

VLA = Vision-Language-Action,即"看图 + 听指令 → 输出动作"的端到端模型:

  • OpenVLA(7B 参数)
  • RT-2(Google)
  • Pi0(Physical Intelligence)
  • Octo

7.2 VLA 在 ROS2 里的角色

RGB Image + "Pick up the apple" → VLA Model
                                     ↓
                          7-DoF Joint Trajectory
                                     ↓
                            ros2_control
                                     ↓
                               真电机

7.3 集成示例

# vla_inference_node
import torch
from vla_model import OpenVLA   # 或 Pi0
from sensor_msgs.msg import Image
from trajectory_msgs.msg import JointTrajectory

class VLANode:
    def __init__(self):
        self.model = OpenVLA.from_pretrained("openvla-7b")
        self.image_sub = rospy.Subscriber('/camera/color/image_raw', Image, self.cb)
        self.cmd_pub = rospy.Publisher('/joint_trajectory', JointTrajectory, queue_size=10)

    def cb(self, msg):
        image = self.bridge.imgmsg_to_cv2(msg, 'rgb8')
        instruction = rospy.get_param('~instruction', 'pick up the apple')
        action = self.model.predict(image, instruction)
        self.cmd_pub.publish(self.action_to_trajectory(action))

7.4 真机部署清单

推荐
6-DoF 机械臂 Ufactory xArm 6 / Franka Panda(二手) / 国产 6-DoF
相机 Intel RealSense D435i(深度 + RGB)
控制器 ROS2 + ros2_control(已学)
主机 PC / RDK X5(NPU 加速 VLA)
网络 千兆 LAN(DDS + 视觉流)

7.5 阶段 5 验证

  • VLA 模型加载到 PC / RDK X5
  • 输入图像 + 指令 → 输出关节轨迹
  • 真实机械臂(或者 Gazebo)执行轨迹
  • 抓取成功率 > 50%(MVP)

预计 4-8 周


8. 3 个实战项目模板(从本仓库出发)

项目 A:桌面级 6-DoF 机械臂抓取

目标: 给定桌面物体的 6-DoF 位姿,机械臂抓起来放到指定位置。

栈:
  - 本仓库(通信 + TF + 视觉)
  + 6-DoF URDF + ros2_control
  + MoveIt2 规划
  + GraspNet(可选,先用固定位姿也行)
  + Gazebo 仿真

改造点:

  • src/cpp_robot_tf2/urdf/simple_arm.urdf → 替换为 6-DoF URDF
  • 新增 src/<your_arm>/config/controllers.yaml
  • 新增 src/<your_arm>/launch/<arm>_bringup.launch.py
  • pick_and_place Python 节点

项目 B:差速底盘 + OpenVLA 抓桌面物体

目标: 移动底盘 + 机械臂 + VLA,自主导航到目标 + 抓取。

栈:
  - 本仓库
  + ros2_control (底盘 diff_drive_controller + 机械臂 controller)
  + Nav2 (底盘导航)
  + MoveIt2 (机械臂)
  + OpenVLA / Pi0 (高层策略)

改造点: 在项目 A 基础上 + 底盘 URDF + Nav2 配置 + VLA 模型集成。

项目 C:ALOHA 双臂遥操 + Pi0 学习

目标: 双机械臂 ALOHA 配置 + 遥操 + Pi0 fine-tune + 部署。

栈:
  - 本仓库
  + 双手臂 6+6 DoF
  + Gazebo + ALOHA 模型
  + Pi0 训练数据收集(bag 录制遥操)
  + Pi0 fine-tune + 部署

改造点: 在项目 A + 镜像配置 + 双臂 URDF + 数据收集脚本。


9. 学习资源 + 时间表

9.1 官方文档

9.2 中文社区

9.3 开源项目

9.4 VLA / 具身智能

9.5 总时间表

阶段 工作 时间(全职)
1 本仓库 已完
2 ros2_control + MoveIt2 + 6-DoF 2-3 周
3 Gazebo 1-2 周
4 视觉 + GraspNet 3-4 周
5 真机 + VLA 4-8 周
总计 3-5 月

10. FAQ

Q1: 我可以跳阶段吗?

可以,但不推荐:

  • 跳过阶段 2 直接搞 VLA: VLA 输出关节轨迹,你不理解轨迹,debug 不了
  • 跳过阶段 3 直接真机: 真机调试成本高(电机可能撞机)

Q2: 必须做 Gazebo 仿真吗?

不一定,但强烈建议:

  • 没有仿真 = 直接真机,出错成本高
  • Gazebo = 离线验证,出问题不伤人

Q3: VLA 模型有多大?

OpenVLA 7B 约 15GB,需要 GPU(NVIDIA RTX 3090+)。 轻量方案: OpenVLA-OFT,Pi0-Lite,LLaRA 等。

Q4: 我只有 1 个 RK3506,够吗?

可以做,但建议至少:

  • 1 个 RK3506: 电机控制
  • 1 个 RDK X5: VLA 推理(NPU)
  • 1 个 PC: 决策 + 可视化

Q5: 真机能直接用本仓库的代码吗?

部分可以:

  • Topic / Service / Action / TF 通信: 直接用
  • JointState 发布(cpp_robot_tf2): 是模拟的,要改读编码器
  • MoveIt2 / ros2_control: 本仓库没,需要补

下一步

按你当前状态选:

你现在的状态 推荐
学完本仓库,想做机器人 → 阶段 2(ros2_control + MoveIt2)
想做 VLA → 阶段 2(先把硬件层打通)→ 阶段 5
只想做软件/规划算法 → 阶段 2 + 3(全程仿真,不上硬件)
想做移动底盘 → 阶段 2(底盘) + 阶段 5(Nav2)

每阶段做完后,回到本仓库做一次 colcon test 验证 ROS2 通信基础仍然稳

加油,具身智能之旅! 🚀



📖 阅读路径导航

💡 这是仓库 doc/ 下所有文档的推荐阅读顺序。返回 README 总导航

本文预计阅读时间: 60 分钟 📍 当前位置: 第 22 / 24 篇