跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
PythonAI算法

OpenClaw 机器人抓取平台搭建全流程详解

综述由AI生成在 Ubuntu 系统下搭建 OpenClaw 机器人抓取仿真平台的完整流程。内容包括环境配置、ROS Noetic 与 Gazebo 安装、Catkin 工作空间创建、URDF 机器人模型设计、控制器配置、Gazebo 仿真环境构建及 Python 抓取控制脚本编写。通过编译运行和调试监控,实现了基础抓取仿真测试,为机器人开发提供实践参考。

魔尊发布于 2026/4/6更新于 2026/5/2232 浏览
OpenClaw 机器人抓取平台搭建全流程详解

前言

OpenClaw 是一个开源的机器人抓取仿真平台,基于 ROS (Robot Operating System) 和 Gazebo 仿真环境。本文将详细讲解如何在 Ubuntu 系统上完整搭建 OpenClaw 开发环境,并进行基础的抓取仿真测试。

一、环境准备与系统配置

1.1 硬件和软件要求

在开始搭建之前,需要确保您的系统满足以下要求:

硬件配置:

  • CPU:Intel i5 或同等性能以上
  • 内存:至少 8GB(推荐 16GB)
  • 硬盘:至少 50GB 可用空间
  • 显卡:支持 OpenGL 3.3+ 的独立显卡(推荐)

软件环境:

  • 操作系统:Ubuntu 20.04 LTS 或 22.04 LTS
  • ROS 版本:ROS Noetic(Ubuntu 20.04)或 ROS2 Humble(Ubuntu 22.04)
1.2 安装 Ubuntu 系统

如果您还没有安装 Ubuntu 系统,请按照以下步骤操作:

# 1. 下载 Ubuntu 20.04 LTS 镜像
# 访问 https://ubuntu.com/download 下载 ISO 文件
# 2. 制作启动 U 盘(在 Windows 下使用 Rufus,在 Linux 下使用)
sudo dd if=ubuntu-20.04.6-desktop-amd64.iso of=/dev/sdb bs=4M status=progress
# 3. 重启电脑,从 U 盘启动,按照图形界面提示完成安装
1.3 系统基础配置

安装完 Ubuntu 后,进行基础配置:

# 更新软件源
sudo apt update
sudo apt upgrade -y
# 安装基础开发工具
sudo apt install -y \
 build-essential \
 cmake \
 git \
 vim \
 curl \
 wget \
 net-tools \
 htop \
 terminator
# 推荐使用 Terminator 作为终端,支持分屏

二、ROS 环境搭建

2.1 ROS Noetic 完整安装
# 步骤 1:设置 sources.list
sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'
# 步骤 2:添加密钥
sudo apt install curl && curl -s https://raw.githubusercontent.com/ros/rosdistro/master/ros.asc | sudo apt-key add -
# 步骤 3:安装 ROS
sudo apt update
 apt install ros-noetic-desktop-full

 rosdep init
rosdep update

  >> ~/.bashrc
 ~/.bashrc

 apt install python3-rosinstall python3-rosinstall-generator python3-wstool
sudo
# 步骤 4:初始化 rosdep
sudo
# 步骤 5:设置环境变量
echo
"source /opt/ros/noetic/setup.bash"
source
# 步骤 6:安装依赖工具
sudo
2.2 验证 ROS 安装
# 测试 ROS 是否安装成功
# 终端 1:启动 ROS 核心
roscore
# 终端 2:运行小海龟仿真
rosrun turtlesim turtlesim_node
# 终端 3:控制小海龟
rosrun turtlesim turtle_teleop_key
# 如果能正常显示和控制小海龟,说明 ROS 安装成功
2.3 安装 Gazebo 仿真环境
# 安装 Gazebo 11(与 ROS Noetic 兼容)
sudo apt install -y \
 gazebo11 \
 libgazebo11-dev \
 ros-noetic-gazebo-ros-pkgs \
 ros-noetic-gazebo-ros-control \
 ros-noetic-gazebo-plugins
# 验证 Gazebo 安装
gazebo --version
# 应显示 Gazebo multi-robot simulator, version 11.x.x

三、创建工作空间

3.1 Catkin 工作空间概念

Catkin 是 ROS 的官方构建系统,工作空间是开发 ROS 项目的目录结构:

openclaw_ws/ # 工作空间根目录
├── src/ # 源代码目录
│   ├── CMakeLists.txt # 顶层 CMake 配置(自动生成)
│   ├── openclaw/ # OpenClaw 主包
│   ├── openclaw_msgs/ # 消息定义包
│   ├── openclaw_description/ # 机器人描述包
│   ├── openclaw_control/ # 控制器包
│   └── openclaw_gazebo/ # Gazebo 仿真包
├── build/ # 编译中间文件(自动生成)
├── devel/ # 开发文件(自动生成)
│   ├── setup.bash # 工作空间环境变量
│   └── lib/ # 编译生成的库文件
└── install/ # 安装文件(可选)
3.2 创建工作空间
# 创建目录结构
mkdir -p ~/openclaw_ws/src
cd ~/openclaw_ws
# 初始化工作空间
catkin_make
# 首次编译后,会自动生成 build 和 devel 目录
ls -la
# 应该看到:build devel src
# 设置工作空间环境变量
echo "source ~/openclaw_ws/devel/setup.bash" >> ~/.bashrc
source ~/.bashrc
# 验证工作空间是否被识别
echo $ROS_PACKAGE_PATH
# 输出应包含:/home/用户名/openclaw_ws/src:/opt/ros/noetic/share

四、获取 OpenClaw 源代码

4.1 创建代码仓库结构

由于 OpenClaw 可能是一个特定的项目,我们需要创建标准的 ROS 包结构:

# 进入源代码目录
cd ~/openclaw_ws/src
# 创建 OpenClaw 相关的功能包
# 1. 创建主功能包
catkin_create_pkg openclaw \
 roscpp \
 rospy \
 std_msgs \
 geometry_msgs \
 sensor_msgs \
 control_msgs \
 trajectory_msgs
# 2. 创建消息定义包
catkin_create_pkg openclaw_msgs \
 std_msgs \
 geometry_msgs \
 message_generation \
 message_runtime
# 3. 创建机器人描述包
catkin_create_pkg openclaw_description \
 urdf \
 xacro \
 robot_state_publisher \
 joint_state_publisher \
 rviz
# 4. 创建控制器包
catkin_create_pkg openclaw_control \
 roscpp \
 controller_manager \
 joint_trajectory_controller \
 position_controllers \
 velocity_controllers \
 effort_controllers
# 5. 创建 Gazebo 仿真包
catkin_create_pkg openclaw_gazebo \
 gazebo_ros \
 gazebo_ros_control \
 gazebo_plugins \
 hector_gazebo_plugins
4.2 如果 OpenClaw 已有代码仓库
# 如果 OpenClaw 有 GitHub 仓库,直接克隆
cd ~/openclaw_ws/src
# 克隆主仓库
git clone https://github.com/yourusername/openclaw.git
# 克隆其他依赖仓库
git clone https://github.com/yourusername/openclaw_msgs.git
git clone https://github.com/yourusername/openclaw_description.git
git clone https://github.com/yourusername/openclaw_control.git
git clone https://github.com/yourusername/openclaw_gazebo.git
git clone https://github.com/yourusername/openclaw_examples.git

五、设计机器人模型

5.1 URDF/XACRO 模型详解

URDF (Unified Robot Description Format) 是 ROS 中描述机器人模型的 XML 格式。我们将创建一个三指夹爪模型:

<!-- ~/openclaw_ws/src/openclaw_description/urdf/claw.xacro -->
<?xml version="1.0"?>
<robot name="openclaw" xmlns:xacro="http://www.ros.org/wiki/xacro">
    <!-- 定义可配置参数 -->
    <xacro:property name="PI" value="3.1415926535897931"/>
    <xacro:property name="base_width" value="0.1"/>
    <xacro:property name="base_height" value="0.05"/>
    <xacro:property name="finger_length" value="0.15"/>
    <xacro:property name="finger_width" value="0.02"/>
    <!-- 材料定义 -->
    <material name="black">
        <color rgba="0.0 0.0 0.0 1.0"/>
    </material>
    <material name="red">
        <color rgba="1.0 0.0 0.0 1.0"/>
    </material>
    <material name="blue">
        <color rgba="0.0 0.0 1.0 1.0"/>
    </material>
    <!-- 1. 基座链接 -->
    <link name="base_link">
        <visual>
            <geometry>
                <box size="${base_width} ${base_width} ${base_height}"/>
            </geometry>
            <origin rpy="0 0 0" xyz="0 0 0"/>
            <material name="black"/>
        </visual>
        <collision>
            <geometry>
                <box size="${base_width} ${base_width} ${base_height}"/>
            </geometry>
        </collision>
        <inertial>
            <mass value="0.5"/>
            <inertia ixx="0.001" ixy="0" ixz="0" iyy="0.001" iyz="0" izz="0.001"/>
        </inertial>
    </link>
    <!-- 2. 手指链接 - 左指 -->
    <link name="left_finger">
        <visual>
            <geometry>
                <box size="${finger_width} ${finger_length} ${finger_width}"/>
            </geometry>
            <origin rpy="0 0 0" xyz="0 ${finger_length/2} 0"/>
            <material name="red"/>
        </visual>
        <collision>
            <geometry>
                <box size="${finger_width} ${finger_length} ${finger_width}"/>
            </geometry>
        </collision>
        <inertial>
            <mass value="0.1"/>
            <inertia ixx="0.0001" ixy="0" ixz="0" iyy="0.0001" iyz="0" izz="0.0001"/>
        </inertial>
    </link>
    <!-- 3. 手指链接 - 右指 -->
    <link name="right_finger">
        <visual>
            <geometry>
                <box size="${finger_width} ${finger_length} ${finger_width}"/>
            </geometry>
            <origin rpy="0 0 0" xyz="0 ${finger_length/2} 0"/>
            <material name="blue"/>
        </visual>
        <collision>
            <geometry>
                <box size="${finger_width} ${finger_length} ${finger_width}"/>
            </geometry>
        </collision>
        <inertial>
            <mass value="0.1"/>
            <inertia ixx="0.0001" ixy="0" ixz="0" iyy="0.0001" iyz="0" izz="0.0001"/>
        </inertial>
    </link>
    <!-- 4. 定义关节 - 左指关节 -->
    <joint name="left_finger_joint" type="revolute">
        <parent link="base_link"/>
        <child link="left_finger"/>
        <origin xyz="-${base_width/4} ${base_height/2} 0" rpy="0 0 0"/>
        <axis xyz="0 0 1"/>
        <limit effort="10" velocity="1" lower="-0.5" upper="0.5"/>
        <dynamics damping="0.1" friction="0.01"/>
    </joint>
    <!-- 5. 定义关节 - 右指关节 -->
    <joint name="right_finger_joint" type="revolute">
        <parent link="base_link"/>
        <child link="right_finger"/>
        <origin xyz="${base_width/4} ${base_height/2} 0" rpy="0 0 0"/>
        <axis xyz="0 0 1"/>
        <limit effort="10" velocity="1" lower="-0.5" upper="0.5"/>
        <dynamics damping="0.1" friction="0.01"/>
    </joint>
    <!-- 添加传动系统,用于 Gazebo 控制 -->
    <transmission name="left_finger_trans">
        <type>transmission_interface/SimpleTransmission</type>
        <joint name="left_finger_joint">
            <hardwareInterface>hardware_interface/PositionJointInterface</hardwareInterface>
        </joint>
        <actuator name="left_finger_motor">
            <mechanicalReduction>1</mechanicalReduction>
        </actuator>
    </transmission>
    <transmission name="right_finger_trans">
        <type>transmission_interface/SimpleTransmission</type>
        <joint name="right_finger_joint">
            <hardwareInterface>hardware_interface/PositionJointInterface</hardwareInterface>
        </joint>
        <actuator name="right_finger_motor">
            <mechanicalReduction>1</mechanicalReduction>
        </actuator>
    </transmission>
    <!-- 添加 Gazebo 插件,用于仿真 -->
    <gazebo>
        <plugin name="gazebo_ros_control" filename="libgazebo_ros_control.so">
            <robotNamespace>/openclaw</robotNamespace>
        </plugin>
    </gazebo>
</robot>
5.2 创建启动文件
<!-- ~/openclaw_ws/src/openclaw_description/launch/display.launch -->
<?xml version="1.0"?>
<launch>
    <!-- 参数设置 -->
    <arg name="model" default="$(find openclaw_description)/urdf/claw.xacro"/>
    <arg name="gui" default="true"/>
    <arg name="rvizconfig" default="$(find openclaw_description)/rviz/urdf.rviz"/>
    <!-- 解析 URDF 模型 -->
    <param name="robot_description" command="$(find xacro)/xacro '$(arg model)'" />
    <!-- 启动 robot_state_publisher,发布 tf 变换 -->
    <node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher">
        <param name="publish_frequency" value="50.0"/>
    </node>
    <!-- 启动 joint_state_publisher,发布关节状态 -->
    <node name="joint_state_publisher_gui" pkg="joint_state_publisher_gui" type="joint_state_publisher_gui" if="$(arg gui)"/>
    <node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" unless="$(arg gui)"/>
    <!-- 启动 RViz 可视化 -->
    <node name="rviz" pkg="rviz" type="rviz" args="-d $(arg rvizconfig)" required="true"/>
</launch>

六、配置控制器

6.1 控制器配置文件
# ~/openclaw_ws/src/openclaw_control/config/control.yaml
openclaw:
    # 关节控制器配置
    joint_state_controller:
        type: joint_state_controller/JointStateController
        publish_rate: 50
    # 左指位置控制器
    left_finger_position_controller:
        type: position_controllers/JointPositionController
        joint: left_finger_joint
        pid: {p: 100.0, i: 0.01, d: 10.0}
    # 右指位置控制器
    right_finger_position_controller:
        type: position_controllers/JointPositionController
        joint: right_finger_joint
        pid: {p: 100.0, i: 0.01, d: 10.0}
    # 夹爪轨迹控制器(用于同时控制两个手指)
    gripper_controller:
        type: position_controllers/JointTrajectoryController
        joints:
            - left_finger_joint
            - right_finger_joint
        constraints:
            goal_time: 0.5
            stopped_velocity_tolerance: 0.05
            stop_trajectory_duration: 0.5
        state_publish_rate: 25
        action_monitor_rate: 10
6.2 控制器启动文件
<!-- ~/openclaw_ws/src/openclaw_control/launch/control.launch -->
<?xml version="1.0"?>
<launch>
    <!-- 加载控制器配置 -->
    <rosparam file="$(find openclaw_control)/config/control.yaml" command="load"/>
    <!-- 加载机器人描述 -->
    <param name="robot_description" command="$(find xacro)/xacro '$(find openclaw_description)/urdf/claw.xacro'"/>
    <!-- 启动 controller_manager 和控制器 -->
    <node name="controller_spawner" pkg="controller_manager" type="spawner" output="screen" args=" joint_state_controller left_finger_position_controller right_finger_position_controller gripper_controller "/>
    <!-- 启动 robot_state_publisher -->
    <node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher"/>
    <!-- 启动关节状态 GUI(可选) -->
    <node name="joint_state_publisher_gui" pkg="joint_state_publisher_gui" type="joint_state_publisher_gui"/>
</launch>

七、配置 Gazebo 仿真环境

7.1 Gazebo 世界文件
<!-- ~/openclaw_ws/src/openclaw_gazebo/worlds/grasping.world -->
<?xml version="1.0" ?>
<sdf version="1.6">
    <world name="grasping_world">
        <!-- 全局光照 -->
        <include>
            <uri>model://sun</uri>
        </include>
        <!-- 地面 -->
        <include>
            <uri>model://ground_plane</uri>
        </include>
        <!-- 添加桌子 -->
        <model name="table">
            <pose>0 0 0 0 0 0</pose>
            <static>true</static>
            <link name="link">
                <collision name="collision">
                    <geometry>
                        <box>
                            <size>1.0 1.0 0.1</size>
                        </box>
                    </geometry>
                </collision>
                <visual name="visual">
                    <geometry>
                        <box>
                            <size>1.0 1.0 0.1</size>
                        </box>
                    </geometry>
                    <material>
                        <ambient>0.5 0.5 0.5 1</ambient>
                        <diffuse>0.8 0.8 0.8 1</diffuse>
                    </material>
                </visual>
            </link>
        </model>
        <!-- 添加被抓取物体 - 立方体 -->
        <model name="cube">
            <pose>0 0 0.05 0 0 0</pose>
            <link name="link">
                <inertial>
                    <mass>0.1</mass>
                    <inertia>
                        <ixx>0.0001</ixx>
                        <ixy>0</ixy>
                        <ixz>0</ixz>
                        <iyy>0.0001</iyy>
                        <iyz>0</iyz>
                        <izz>0.0001</izz>
                    </inertia>
                </inertial>
                <collision name="collision">
                    <geometry>
                        <box>
                            <size>0.05 0.05 0.05</size>
                        </box>
                    </geometry>
                </collision>
                <visual name="visual">
                    <geometry>
                        <box>
                            <size>0.05 0.05 0.05</size>
                        </box>
                    </geometry>
                    <material>
                        <ambient>1 0 0 1</ambient>
                        <diffuse>1 0 0 1</diffuse>
                    </material>
                </visual>
            </link>
        </model>
        <!-- 添加球体 -->
        <model name="sphere">
            <pose>0.2 0 0.05 0 0 0</pose>
            <link name="link">
                <inertial>
                    <mass>0.1</mass>
                    <inertia>
                        <ixx>0.0001</ixx>
                        <ixy>0</ixy>
                        <ixz>0</ixz>
                        <iyy>0.0001</iyy>
                        <iyz>0</iyz>
                        <izz>0.0001</izz>
                    </inertia>
                </inertial>
                <collision name="collision">
                    <geometry>
                        <sphere>
                            <radius>0.025</radius>
                        </sphere>
                    </geometry>
                </collision>
                <visual name="visual">
                    <geometry>
                        <sphere>
                            <radius>0.025</radius>
                        </sphere>
                    </geometry>
                    <material>
                        <ambient>0 1 0 1</ambient>
                        <diffuse>0 1 0 1</diffuse>
                    </material>
                </visual>
            </link>
        </model>
    </world>
</sdf>
7.2 Gazebo 启动文件
<!-- ~/openclaw_ws/src/openclaw_gazebo/launch/gazebo.launch -->
<?xml version="1.0"?>
<launch>
    <!-- 参数设置 -->
    <arg name="paused" default="false"/>
    <arg name="use_sim_time" default="true"/>
    <arg name="gui" default="true"/>
    <arg name="headless" default="false"/>
    <arg name="debug" default="false"/>
    <arg name="world" default="$(find openclaw_gazebo)/worlds/grasping.world"/>
    <!-- 加载机器人描述 -->
    <param name="robot_description" command="$(find xacro)/xacro '$(find openclaw_description)/urdf/claw.xacro'"/>
    <!-- 启动 Gazebo 服务器 -->
    <include file="$(find gazebo_ros)/launch/empty_world.launch">
        <arg name="world_name" value="$(arg world)"/>
        <arg name="paused" value="$(arg paused)"/>
        <arg name="use_sim_time" value="$(arg use_sim_time)"/>
        <arg name="gui" value="$(arg gui)"/>
        <arg name="headless" value="$(arg headless)"/>
        <arg name="debug" value="$(arg debug)"/>
    </include>
    <!-- 在 Gazebo 中生成机器人 -->
    <node name="spawn_urdf" pkg="gazebo_ros" type="spawn_model" args="-param robot_description -urdf -model openclaw -x 0 -y 0 -z 0.1"/>
    <!-- 启动控制器 -->
    <include file="$(find openclaw_control)/launch/control.launch"/>
</launch>

八、编写抓取控制程序

8.1 Python 控制脚本
#!/usr/bin/env python3
# ~/openclaw_ws/src/openclaw_examples/scripts/grasp_object.py
import rospy
import actionlib
from control_msgs.msg import FollowJointTrajectoryAction, FollowJointTrajectoryGoal
from trajectory_msgs.msg import JointTrajectoryPoint
from std_msgs.msg import Float64
import sys
import time

class OpenClawGraspController:
    """OpenClaw 抓取控制器"""
    def __init__(self):
        # 初始化 ROS 节点
        rospy.init_node('openclaw_grasp_controller', anonymous=True)
        # 定义关节名称
        self.left_finger_joint = 'left_finger_joint'
        self.right_finger_joint = 'right_finger_joint'
        # 创建发布者(用于直接控制单个关节)
        self.left_finger_pub = rospy.Publisher(
            '/openclaw/left_finger_position_controller/command', Float64, queue_size=10)
        self.right_finger_pub = rospy.Publisher(
            '/openclaw/right_finger_position_controller/command', Float64, queue_size=10)
        # 创建动作客户端(用于轨迹控制)
        self.client = actionlib.SimpleActionClient(
            '/openclaw/gripper_controller/follow_joint_trajectory', FollowJointTrajectoryAction)
        # 等待服务器启动
        rospy.loginfo("等待控制器服务器...")
        self.client.wait_for_server()
        rospy.loginfo("控制器服务器已连接")
        # 等待一段时间确保所有组件就绪
        rospy.sleep(1.0)

    def open_gripper(self):
        """打开夹爪"""
        rospy.loginfo("打开夹爪")
        # 方法 1:使用单个关节发布器
        self.left_finger_pub.publish(-0.5) # 左指向外打开
        self.right_finger_pub.publish(0.5) # 右指向外打开
        # 等待动作完成
        rospy.sleep(2.0)

    def close_gripper(self):
        """闭合夹爪"""
        rospy.loginfo("闭合夹爪")
        # 方法 1:使用单个关节发布器
        self.left_finger_pub.publish(0.5) # 左指向内闭合
        self.right_finger_pub.publish(-0.5) # 右指向内闭合
        # 等待动作完成
        rospy.sleep(2.0)

    def grasp_object(self, force=0.3):
        """抓取物体(带力控制)"""
        rospy.loginfo("开始抓取物体,力度:%.2f", force)
        # 逐步闭合夹爪
        steps = 10
        for i in range(steps):
            # 计算当前角度(从打开到闭合)
            left_angle = -0.5 + (i / steps) * 1.0 # -0.5 到 0.5
            right_angle = 0.5 - (i / steps) * 1.0 # 0.5 到 -0.5
            # 发布关节角度
            self.left_finger_pub.publish(left_angle)
            self.right_finger_pub.publish(right_angle)
            # 等待一小段时间
            rospy.sleep(0.1)
        rospy.loginfo("抓取完成")

    def release_object(self):
        """释放物体"""
        rospy.loginfo("释放物体")
        self.open_gripper()

    def trajectory_grasp(self):
        """使用轨迹控制进行抓取(更平滑的运动)"""
        rospy.loginfo("使用轨迹控制进行抓取")
        # 创建目标
        goal = FollowJointTrajectoryGoal()
        goal.trajectory.joint_names = [
            self.left_finger_joint,
            self.right_finger_joint]
        # 定义轨迹点
        # 点 1:打开位置
        point1 = JointTrajectoryPoint()
        point1.positions = [-0.5, 0.5] # [左指,右指]
        point1.time_from_start = rospy.Duration(1.0)
        # 点 2:闭合位置
        point2 = JointTrajectoryPoint()
        point2.positions = [0.5, -0.5]
        point2.time_from_start = rospy.Duration(3.0)
        # 添加点到轨迹
        goal.trajectory.points.append(point1)
        goal.trajectory.points.append(point2)
        # 发送目标
        self.client.send_goal(goal)
        # 等待结果
        self.client.wait_for_result()
        # 获取结果
        result = self.client.get_result()
        rospy.loginfo("轨迹执行结果:%s", result)

    def multi_stage_grasp(self):
        """多阶段抓取策略"""
        rospy.loginfo("执行多阶段抓取")
        # 阶段 1:预抓取位置(稍微打开)
        rospy.loginfo("阶段 1:预抓取位置")
        self.left_finger_pub.publish(-0.3)
        self.right_finger_pub.publish(0.3)
        rospy.sleep(1.0)
        # 阶段 2:缓慢接近
        rospy.loginfo("阶段 2:接近物体")
        for angle in [-0.4, -0.2, 0.0, 0.2]:
            self.left_finger_pub.publish(angle)
            self.right_finger_pub.publish(-angle)
            rospy.sleep(0.5)
        # 阶段 3:施加抓取力
        rospy.loginfo("阶段 3:施加抓取力")
        self.left_finger_pub.publish(0.4)
        self.right_finger_pub.publish(-0.4)
        rospy.sleep(1.0)
        # 阶段 4:保持抓取
        rospy.loginfo("阶段 4:保持抓取")
        rospy.sleep(2.0)
        # 阶段 5:释放
        rospy.loginfo("阶段 5:释放")
        self.open_gripper()

def main():
    """主函数"""
    try:
        # 创建控制器实例
        controller = OpenClawGraspController()
        # 获取命令行参数
        if len(sys.argv) > 1:
            mode = sys.argv[1]
        else:
            mode = "simple"
        rospy.loginfo("执行模式:%s", mode)
        # 根据不同模式执行抓取
        if mode == "simple":
            # 简单抓取
            controller.open_gripper()
            rospy.sleep(1.0)
            controller.close_gripper()
            rospy.sleep(1.0)
            controller.open_gripper()
        elif mode == "grasp":
            # 抓取物体
            controller.open_gripper()
            rospy.sleep(1.0)
            controller.grasp_object(force=0.5)
            rospy.sleep(2.0)
            controller.release_object()
        elif mode == "trajectory":
            # 轨迹抓取
            controller.trajectory_grasp()
        elif mode == "multistage":
            # 多阶段抓取
            controller.multi_stage_grasp()
        else:
            rospy.loginfo("未知模式,使用默认模式")
            controller.open_gripper()
            rospy.sleep(1.0)
            controller.close_gripper()
        rospy.loginfo("抓取演示完成")
    except rospy.ROSInterruptException:
        rospy.loginfo("程序被中断")
    except Exception as e:
        rospy.logerr("发生错误:%s", str(e))

if __name__ == '__main__':
    main()
8.2 创建启动文件
<!-- ~/openclaw_ws/src/openclaw_examples/launch/demo.launch -->
<?xml version="1.0"?>
<launch>
    <!-- 启动 Gazebo 仿真 -->
    <include file="$(find openclaw_gazebo)/launch/gazebo.launch"/>
    <!-- 启动抓取演示节点 -->
    <node name="grasp_demo" pkg="openclaw_examples" type="grasp_object.py" output="screen" required="true">
        <!-- 可以传递参数 -->
        <param name="grasp_force" value="0.5"/>
        <param name="grasp_speed" value="0.1"/>
    </node>
    <!-- 可选:启动 RViz 可视化 -->
    <node name="rviz" pkg="rviz" type="rviz" args="-d $(find openclaw_description)/rviz/openclaw.rviz"/>
</launch>

九、编译和运行

9.1 编译工作空间
# 返回工作空间根目录
cd ~/openclaw_ws
# 安装依赖
rosdep install --from-paths src --ignore-src -r -y
# 编译(使用 4 个线程)
catkin_make -j4
# 如果编译出错,可以尝试单线程编译以便查看详细错误
catkin_make -j1
# 编译特定包
catkin_make --only-pkg-with-deps openclaw_control
# 清理并重新编译
catkin_make clean
catkin_make
9.2 运行仿真
# 终端 1:启动 Gazebo 仿真
source ~/openclaw_ws/devel/setup.bash
roslaunch openclaw_gazebo gazebo.launch
# 终端 2:运行抓取演示
source ~/openclaw_ws/devel/setup.bash
rosrun openclaw_examples grasp_object.py simple
# 或者使用不同模式
rosrun openclaw_examples grasp_object.py grasp
rosrun openclaw_examples grasp_object.py trajectory
rosrun openclaw_examples grasp_object.py multistage
9.3 使用 RViz 可视化
# 终端:启动 RViz
source ~/openclaw_ws/devel/setup.bash
rosrun rviz rviz
# 在 RViz 中配置:
# 1. 添加 RobotModel 显示机器人模型
# 2. 添加 TF 显示坐标变换
# 3. 添加 Image 显示摄像头图像(如果有)

十、调试和监控

10.1 查看 ROS 信息
# 查看所有节点
rosnode list
# 查看所有话题
rostopic list
# 查看所有服务
rosservice list
# 查看所有参数
rosparam list
# 查看特定话题内容
rostopic echo /openclaw/joint_states
# 查看特定话题发布频率
rostopic hz /openclaw/joint_states
# 查看话题带宽
rostopic bw /openclaw/joint_states
10.2 使用 rqt 工具
# 启动 rqt 图形界面
rqt
# 常用插件:
# - rqt_graph:查看节点间关系
# - rqt_plot:实时绘制数据
# - rqt_console:查看日志
# - rqt_tf_tree:查看 TF 树
# 单独启动特定工具
rqt_graph
rqt_plot /openclaw/joint_states/position[0]
10.3 记录和回放数据
# 记录所有话题到 bag 文件
rosbag record -a -o grasp_demo.bag
# 记录特定话题
rosbag record /openclaw/joint_states /openclaw/gripper_controller/state
# 查看 bag 信息
rosbag info grasp_demo.bag
# 回放 bag 文件
rosbag play grasp_demo.bag

目录

  1. 前言
  2. 一、环境准备与系统配置
  3. 1.1 硬件和软件要求
  4. 1.2 安装 Ubuntu 系统
  5. 1. 下载 Ubuntu 20.04 LTS 镜像
  6. 访问 https://ubuntu.com/download 下载 ISO 文件
  7. 2. 制作启动 U 盘(在 Windows 下使用 Rufus,在 Linux 下使用)
  8. 3. 重启电脑,从 U 盘启动,按照图形界面提示完成安装
  9. 1.3 系统基础配置
  10. 更新软件源
  11. 安装基础开发工具
  12. 推荐使用 Terminator 作为终端,支持分屏
  13. 二、ROS 环境搭建
  14. 2.1 ROS Noetic 完整安装
  15. 步骤 1:设置 sources.list
  16. 步骤 2:添加密钥
  17. 步骤 3:安装 ROS
  18. 步骤 4:初始化 rosdep
  19. 步骤 5:设置环境变量
  20. 步骤 6:安装依赖工具
  21. 2.2 验证 ROS 安装
  22. 测试 ROS 是否安装成功
  23. 终端 1:启动 ROS 核心
  24. 终端 2:运行小海龟仿真
  25. 终端 3:控制小海龟
  26. 如果能正常显示和控制小海龟,说明 ROS 安装成功
  27. 2.3 安装 Gazebo 仿真环境
  28. 安装 Gazebo 11(与 ROS Noetic 兼容)
  29. 验证 Gazebo 安装
  30. 应显示 Gazebo multi-robot simulator, version 11.x.x
  31. 三、创建工作空间
  32. 3.1 Catkin 工作空间概念
  33. 3.2 创建工作空间
  34. 创建目录结构
  35. 初始化工作空间
  36. 首次编译后,会自动生成 build 和 devel 目录
  37. 应该看到:build devel src
  38. 设置工作空间环境变量
  39. 验证工作空间是否被识别
  40. 输出应包含:/home/用户名/openclaw_ws/src:/opt/ros/noetic/share
  41. 四、获取 OpenClaw 源代码
  42. 4.1 创建代码仓库结构
  43. 进入源代码目录
  44. 创建 OpenClaw 相关的功能包
  45. 1. 创建主功能包
  46. 2. 创建消息定义包
  47. 3. 创建机器人描述包
  48. 4. 创建控制器包
  49. 5. 创建 Gazebo 仿真包
  50. 4.2 如果 OpenClaw 已有代码仓库
  51. 如果 OpenClaw 有 GitHub 仓库,直接克隆
  52. 克隆主仓库
  53. 克隆其他依赖仓库
  54. 五、设计机器人模型
  55. 5.1 URDF/XACRO 模型详解
  56. 5.2 创建启动文件
  57. 六、配置控制器
  58. 6.1 控制器配置文件
  59. ~/openclawws/src/openclawcontrol/config/control.yaml
  60. 6.2 控制器启动文件
  61. 七、配置 Gazebo 仿真环境
  62. 7.1 Gazebo 世界文件
  63. 7.2 Gazebo 启动文件
  64. 八、编写抓取控制程序
  65. 8.1 Python 控制脚本
  66. ~/openclawws/src/openclawexamples/scripts/grasp_object.py
  67. 8.2 创建启动文件
  68. 九、编译和运行
  69. 9.1 编译工作空间
  70. 返回工作空间根目录
  71. 安装依赖
  72. 编译(使用 4 个线程)
  73. 如果编译出错,可以尝试单线程编译以便查看详细错误
  74. 编译特定包
  75. 清理并重新编译
  76. 9.2 运行仿真
  77. 终端 1:启动 Gazebo 仿真
  78. 终端 2:运行抓取演示
  79. 或者使用不同模式
  80. 9.3 使用 RViz 可视化
  81. 终端:启动 RViz
  82. 在 RViz 中配置:
  83. 1. 添加 RobotModel 显示机器人模型
  84. 2. 添加 TF 显示坐标变换
  85. 3. 添加 Image 显示摄像头图像(如果有)
  86. 十、调试和监控
  87. 10.1 查看 ROS 信息
  88. 查看所有节点
  89. 查看所有话题
  90. 查看所有服务
  91. 查看所有参数
  92. 查看特定话题内容
  93. 查看特定话题发布频率
  94. 查看话题带宽
  95. 10.2 使用 rqt 工具
  96. 启动 rqt 图形界面
  97. 常用插件:
  98. - rqt_graph:查看节点间关系
  99. - rqt_plot:实时绘制数据
  100. - rqt_console:查看日志
  101. - rqttftree:查看 TF 树
  102. 单独启动特定工具
  103. 10.3 记录和回放数据
  104. 记录所有话题到 bag 文件
  105. 记录特定话题
  106. 查看 bag 信息
  107. 回放 bag 文件
  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • 基于 Bright Data MCP Server 构建实时数据驱动的 AI 情报系统实战
  • OpenClaw 漏洞预警:为 AI 代理构建可追溯的日志审计方案
  • Buzz 离线语音转文字工具安装与使用指南
  • Python 人工智能常用库整理与介绍
  • LocalAI 本地部署及 CPolar 远程访问实战
  • 基于 RAG 的智能知识问答探索企业知识边界
  • 大模型检索增强生成(RAG)技术综述
  • Python 第三方库实战:键盘监听鼓励器与学生管理系统
  • 纯 Java 手写 TopoJSON 生成器:零依赖实战教程
  • 大模型训练原理深度解析:以 GPT-1 为例
  • HunyuanOCR 接入 RPA 机器人:UiPath 与影刀兼容性测试
  • Python Web 开发:Flask 框架核心概念与实战
  • Python 核心语法详解:变量、流程控制与函数实战
  • RabbitMQ 通配符模式详解
  • 大模型应用开发中的高级 RAG 技术详解
  • Web-Rooter:基于 IR + Lint 模式的 AI Agent 联网工具
  • OpenAI Whisper 语音识别技术解析与企业级部署实践
  • ops-nn 自定义算子开发全流程:注册与测试
  • oicq 快速入门:从零搭建你的第一个 QQ 机器人
  • core-js 包结构与配置策略:Polyfill 解决前端兼容性问题

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • RSA密钥对生成器

    生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online

  • Mermaid 预览与可视化编辑

    基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online

  • 随机西班牙地址生成器

    随机生成西班牙地址(支持马德里、加泰罗尼亚、安达卢西亚、瓦伦西亚筛选),支持数量快捷选择、显示全部与下载。 在线工具,随机西班牙地址生成器在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • curl 转代码

    解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online