【从零开始的ROS四轴机械臂控制】(二) - ROS与Gazebo连接,Gazebo仿真及urdf文件修改

四、urdf文件及gazebo仿真

首先先忽略硬件部分,来看一下gazebo仿真部分。这一个部分的目标是,实现使用arm_mover节点和look_away服务节点来控制gazebo中的机器人。
在这里插入图片描述
本部分完成后如上图所示,使用simple_mover控制机械臂移动。

我找了很多关于urdf资料后发现,很多人讲urdf说的比较模糊,而且没有实际例子来验证。或者介绍的比较模糊,并不是很能理解从Solidworks导出urdf文件后如何进行实际的应用。很多博客都是以导入到rviz中能使用作为结束,但是这样的话对我们这个项目来说是远远不够的。

所以为了能顺利地进行项目,所以重点来研究一下urdf文件和包。 我在改进我的arm0的包的时候主要参考了simple_arm这个示例,如果不想看simple_arm示例可以直接跳到四、2根据simple_arm 示例改进arm0文件夹,其主要详细说明了四轴机械臂项目的arm0包。

1.simple_arm示例

有关于工作区可以参考博客【Udacity机器人软件工程师课程笔记(九)-ROS-Catkin包、工作空间和目录结构
有关simple_arm和gazebo可以参考【Udacity机器人软件工程师课程笔记(十)-ROS-Catkin-包(package)和gazebo

以下是从github仓库克隆的 simple_arm 的包。
在这里插入图片描述
接下来要针对每一个文件来分析其作用。当时我在学习使用simple_arm这个包时,没有很好的研究其文件内容。但是现在要搭建针对于自己项目的gazebo文件,还是很有必要好好的看一下其中文件的结构及内容的。

(1)config文件夹

config文件夹:配置文件
在这里插入图片描述
controllers.yaml

simple_arm:
    #list of controllers
    joint_state_controller:
      type: joint_state_controller/JointStateController
      publish_rate: 50

    joint_1_position_controller:
      type: effort_controllers/JointPositionController
      joint: joint_1
      pid: {p: 100.0, i: 0.01, d: 10.0}
    joint_2_position_controller:
      type: effort_controllers/JointPositionController
      joint: joint_2
      pid: {p: 100.0, i: 0.01, d: 10.0}
(2)launch文件夹

launch:提供更自动化的启动节点的方式
在这里插入图片描述
robot_control.xml:

<launch>
  <!--将关节控制器加载到param服务器-->
  <rosparam file="$(find simple_arm)/config/controllers.yaml" command="load"/>

  <!--Load controllers-->
  <node name="spawner" pkg="controller_manager" type="spawner" respawn="false"
    output="screen" ns="/simple_arm" args="joint_state_controller
    joint_1_position_controller
    joint_2_position_controller"/>
</launch>
```xml
robot_description.xml:
``` robot_spawn.launch ```xml

```
(3)meshes文件夹

在这里插入图片描述
meshes中包含了相机的3d模型文件。

meshes 中文件可以包括meshes(.dae(Collada)或.stl(STereoLithography)格式的CAD文件)。

(4)urdf文件夹

urdf:通用机器人描述文件。
在这里插入图片描述
simple_arm.gazebo.xacro:
定义gazebo中的的模型,其中包括

  • (1)定义gazebo
  • (2)定义link
    • 1)base link
    • 2)link_1
    • 3)link_2
    • 4)camera_link
  • (3)定义摄像头
<?xml version="1.0"?>
<robot>
  <!-- ros_control插件 -->
  <gazebo>
    <plugin name="gazebo_ros_control" filename="libgazebo_ros_control.so">
      <robotNamespace>/simple_arm</robotNamespace>
      <robotSimType>gazebo_ros_control/DefaultRobotHWSim</robotSimType>
    </plugin>
  </gazebo>

  <!--base_link-->
  <gazebo reference="base_link">
    <material>Gazebo/White</material>
  </gazebo>

  <!--link_1-->
  <gazebo reference="link_1">
    <mu1>0.2</mu1>
    <mu2>0.2</mu2>
    <material>Gazebo/Orange</material>
  </gazebo>

  <!--link_2-->
  <gazebo reference="link_2">
    <mu1>0.2</mu1>
    <mu2>0.2</mu2>
    <material>Gazebo/White</material>
  </gazebo>

  <!--camera_link-->
  <gazebo reference="camera_link">
    <material>Gazebo/Grey</material>
  </gazebo>

  <!-- 摄像头-->
  <gazebo reference="camera_link">
    <sensor type="camera" name="rgb_camera">
      <update_rate>30.0</update_rate>
      <camera name="rgb_camera">
        <horizontal_fov>1.4</horizontal_fov>
        <image>
          <width>640</width>
          <height>480</height>
          <format>R8G8B8</format>
        </image>
        <clip>
          <near>0.02</near>
          <far>300</far>
        </clip>
      </camera>
      <plugin name="camera_controller" filename="libgazebo_ros_camera.so">
        <alwaysOn>true</alwaysOn>
        <updateRate>0.0</updateRate>
        <cameraName>rgb_camera</cameraName>
        <imageTopicName>image_raw</imageTopicName>
        <cameraInfoTopicName>camera_info</cameraInfoTopicName>
        <frameName>camera_link</frameName>
        <hackBaseline>0.0</hackBaseline>
        <distortionK1>0.0</distortionK1>
        <distortionK2>0.0</distortionK2>
        <distortionK3>0.0</distortionK3>
        <distortionT1>0.0</distortionT1>
        <distortionT2>0.0</distortionT2>
      </plugin>
    </sensor>
  </gazebo>

</robot>

simple_arm.urdf.xacro:其中...为省略部分:
这个部分定义link、joint和transmission

<?xml version="1.0"?>
<robot name="simple_arm" xmlns:xacro="http://www.ros.org/wiki/xacro">

  <!--Define constants-->
  <xacro:property name="link_type" value="cuboidal" />
  <xacro:property name="PI" value="3.14159"/>
  ...

  <!--Import gazebo elements-->
  <xacro:include filename="$(find simple_arm)/urdf/simple_arm.gazebo.xacro" />

  <!--Links-->
  <link name="world"/>

  <link name="base_link">
    <visual>
      <origin xyz="0 0 ${length1/2}" rpy="0 0 0"/>
      <geometry>
        <cylinder length="${length1}" radius="${radius1}"/>
      </geometry>
      <material name="white">
        <color rgba="1.0 1.0 1.0 1.0"/>
      </material>
    </visual>
    <collision>
      <origin xyz="0 0 ${length1/2}" rpy="0 0 0"/>
      <geometry>
        <cylinder length="${length1}" radius="${radius1}"/>
      </geometry>
    </collision>
    <inertial>
      <origin xyz="0 0 ${length1/2}" rpy="0 0 0"/>
      <mass value="${mass1}"/>
      <inertia
        ixx="${mass1 / 12.0 * (2*radius1*2*radius1 + length1*length1)}" ixy="0.0" ixz="0.0"
        iyy="${mass1 / 12.0 * (length1*length1 + 2*radius1*2*radius1)}" iyz="0.0"
        izz="${mass1 / 12.0 * (2*radius1*2*radius1 + 2*radius1*2*radius1)}"/>
    </inertial>
  </link>
  
  ...
  
  <!--camera_link-->
  <link name="camera_link">
    <collision>
      <origin xyz="0 0 0" rpy="0 0 0"/>
      <geometry>
        <!--mesh filename="package://simple_arm/meshes/camera.dae"/-->
        <sphere radius="${camera_size}"/>
      </geometry>
    </collision>
    <visual>
      <origin xyz="0 0 0" rpy="0 0 0"/>
      <geometry>
        <!--mesh filename="package://simple_arm/meshes/camera.dae"/-->
        <sphere radius="${camera_size}"/>
      </geometry>
      <material name="red">
        <color rgba="1.0 0 0 1.0"/>
      </material>
    </visual>
    <inertial>
      <mass value="1e-5" />
      <origin xyz="0 0 0" rpy="0 0 0"/>
      <inertia ixx="1e-6" ixy="0" ixz="0" iyy="1e-6" iyz="0" izz="1e-6" />
    </inertial>
  </link>

  <!--Joints-->
  <joint name="fixed_base_joint" type="fixed">
    <parent link="world"/>
    <child link="base_link"/>
  </joint>

  ...
  
  <joint name="camera_joint" type="fixed">
    <axis xyz="0 0 1" />
    <origin xyz="0 0 ${length3}" rpy="0 -${PI/2} 0"/>
    <parent link="link_2"/>
    <child link="camera_link"/>
  </joint>

  <!--转换和执行器-->
  <transmission name="tran1">
    <type>transmission_interface/SimpleTransmission</type>
    <joint name="joint_1">
      <hardwareInterface>EffortJointInterface</hardwareInterface>
    </joint>
    <actuator name="motor1">
      <hardwareInterface>EffortJointInterface</hardwareInterface>
      <mechanicalReduction>1</mechanicalReduction>
    </actuator>
  </transmission>

  <transmission name="tran2">
    <type>transmission_interface/SimpleTransmission</type>
    <joint name="joint_2">
      <hardwareInterface>EffortJointInterface</hardwareInterface>
    </joint>
    <actuator name="motor2">
      <hardwareInterface>EffortJointInterface</hardwareInterface>
      <mechanicalReduction>1</mechanicalReduction>
    </actuator>
  </transmission>
</robot>
(5)worlds文件夹

在这里插入图片描述
willow_garage.world是用于Gazebo仿真环境的XML文件,如果不定义可以使用空白世界。所以这个文件为可选文件。

(6)文件间联系
/launch/robot_control.xml
/launch/robot_spawn.launch
/launch/robot_description.xml
/config/controllers.yaml
/urdf/simple_arm.urdf.xacro
/urdf/simple_arm.gazebo.xacro
/worlds/willow_garage.world

从框图中我们可以比较清楚的的除了文件的框架结构。所有的文件都指向到robot_spawn.launch文件。要实现搭建自己的包,就要按照框图一步步的修改从solidworks导出的urdf文件。


各文件夹功能如下所示

• script(python可执行文件)
• src(C ++源文件)
• msg(用于自定义消息定义)
• srv(用于服务消息定义)
• include - >作为依赖项所需的头文件/库
• config - >配置文件
• launch - >提供更自动化的启动节点的方式

其他文件夹可能包括
• urdf(通用机器人描述文件)
• meshes(.dae(Collada)或.stl(STereoLithography)格式的CAD文件)
• worlds(用于Gazebo仿真环境的XML文件)


2.根据simple_arm示例改进arm0文件夹

由于某些原因(导出了多次urdf文件),我的文件夹实际名称为arm1,在此特别说明一下,在接下来也会以arm1作为例子。

在这里插入图片描述
以上是arm1包中的所有内容,我已经将它上传至github,其版本号定为Robot arm 0.1.1,功能是通过simple_mover.py实现了最基本机械臂的运动 。

arm1包(arm version 0.1.1)结构如下

arm1
  |-config
  |  |-controllers.yaml
  |-launch
  |  |-gazebo.launch
  |  |-robot_control.xml
  |  |-robot_description.xml
  |-meshes(未更改)
  |  |-base_link.STL
  |  |-link1.STL
  |  |-link2.STL
  |  |-link3.STL
  |  |-link4.STL
  |-scripts
  |  |-simple_mover
  |-urdf
  |  |-arm1.urdf.xacro
  |  |-arm1.gazebo.xacro
  |-worlds
  |  |-willow_garage.world
  |-CMakeLists.txt(未更改)
  |-export.log(未更改)
  |-package.xml(未更改)

其中 CMakeLists.txt、export.log、package.xml和meshes文件夹中内容为solidworks转出的自带内容,其它文件都进行了更改。

(1)urdf文件夹

这部分使用Xacro(XML宏)。

Xacro是一种XML宏语言。使用xacro,可以使用扩展较大的XML表达式的宏来构造更短,更易读的XML文件。

有关xacro的更多信息可以参考ROS Wiki

①arm1.gazebo.xacro

arm1.gazebo.xacro的主要功能是,添加gazebo_ros_control插件,将ros和gazebo连接起来。

<?xml version="1.0"?>

<robot>

  <!-- ros_control plugin -->

  <gazebo>

    <plugin name="gazebo_ros_control" filename="libgazebo_ros_control.so">

      <robotNamespace>/arm1</robotNamespace>

      <robotSimType>gazebo_ros_control/DefaultRobotHWSim</robotSimType>

    </plugin>

  </gazebo>



  <!--base_link-->

  <gazebo reference="base_link">

    <material>Gazebo/White</material>

  </gazebo>



  <!--link_1-->

  <gazebo reference="link1">

    <mu1>0.2</mu1>

    <mu2>0.2</mu2>

    <material>Gazebo/Orange</material>

  </gazebo>



  <!--link_2-->

  <gazebo reference="link2">

    <mu1>0.2</mu1>

    <mu2>0.2</mu2>

    <material>Gazebo/White</material>

  </gazebo>



  <!--link_3-->

  <gazebo reference="link3">

    <mu1>0.2</mu1>

    <mu2>0.2</mu2>

    <material>Gazebo/Orange</material>

  </gazebo> 

 <!--link_4-->

  <gazebo reference="link4">

    <mu1>0.2</mu1>

    <mu2>0.2</mu2>

    <material>Gazebo/White</material>

  </gazebo>

</robot>
②arm1.urdf.xacro

为了方便阅读,我在其中删除了一部分的内容,完整部分可以查看github

这个文件主要定义了arm的urdf文件。其中包括link,joint和Transmission。link和joint 在solidworks转换出来的文件中已经给出了,在这里不在赘述。

主要注意的有三个地方。

一、我们在urdf文件中,需要对joint打上gazebo使用的transmission标签,transmission把TF(ros)的连接关系与仿真平台上的驱动设备(gazebo)联系在了一起,有了执行器,gazebo就可以在物理层面上对模型进行驱动了。

更多关于transmission标签可以参考此处

二、我们需要定义world link,然后再将base link 和world link连接起来,这样模型才能在gazebo世界中固定。

三、需要导入arm1.gazebo.xacro文件。

<?xml version="1.0" encoding="utf-8"?>

<!-- This URDF was automatically created by SolidWorks to URDF Exporter! Originally created by Stephen Brawner (brawner@gmail.com) 

     Commit Version: 1.5.1-0-g916b5db  Build Version: 1.5.7152.31018

     For more information, please see http://wiki.ros.org/sw_urdf_exporter -->

<robot

  name="arm1" 

  xmlns:xacro="http://www.ros.org/wiki/xacro">



  <!--Import gazebo elements-->

  <xacro:include filename="$(find arm1)/urdf/arm1.gazebo.xacro" />



  <!--Links and joints-->

  <link name="world"/>


  <link name="base_link">

    <inertial>

      <origin

        xyz="0.000877732518704125 -6.1202787414609E-05 0.0136416983965608"

        rpy="0 0 0" />

      <mass

        value="0.0149906128541691" />

      <inertia

        ixx="9.0485354260676E-07"

        ixy="9.67790693248534E-12"

        ixz="-1.26661641226237E-08"

        iyy="1.3035966603116E-06"

        iyz="-4.46725888473771E-12"

        izz="1.62723345073819E-06" />

    </inertial>

    <visual>

      <origin

        xyz="0 0 0"

        rpy="0 0 0" />

      <geometry>

        <mesh

          filename="package://arm1/meshes/base_link.STL" />

      </geometry>

      <material

        name="">

        <color

          rgba="1 1 1 1" />

      </material>

    </visual>

    <collision>

      <origin

        xyz="0 0 0"

        rpy="0 0 0" />

      <geometry>

        <mesh

          filename="package://arm1/meshes/base_link.STL" />

      </geometry>

    </collision>

  </link>

  <!--this joint used to fix model-->
  <joint name="fixed_base_joint" type="fixed">
    <parent link="world"/>
    <child link="base_link"/>
  </joint>

  ...(省略部分)

  <!--Transmission and actuators-->
  <transmission name="tran1">
  ...(省略部分)
  </transmission>

</robot>
(2)config文件夹

为每个joint添加控制器controller,保存为controllers.yaml文件。

arm1:
    #list of controllers
    joint_state_controller:
      type: joint_state_controller/JointStateController
      publish_rate: 50

    joint1_position_controller:
      type: effort_controllers/JointPositionController
      joint: joint1
      pid: {p: 1, i: 0.001, d: 0.002}
    joint2_position_controller:
      type: effort_controllers/JointPositionController
      joint: joint2
      pid: {p: 1, i: 0.001, d: 0.002}
    joint3_position_controller:
      type: effort_controllers/JointPositionController
      joint: joint3
      pid: {p: 1, i: 0.001, d: 0.002}
    joint4_position_controller:
      type: effort_controllers/JointPositionController
      joint: joint4
      pid: {p: 1, i: 0.001, d: 0.002}
(3)launch文件夹
①robot_control.xml

该xml文件负责加载控制器。

<launch>
  <!--Load the joint controllers to param server-->
  <rosparam file="$(find arm1)/config/controllers.yaml" command="load"/>

  <!--Load controllers-->
  <node name="spawner" pkg="controller_manager" type="spawner" respawn="false"
    output="screen" ns="/arm1" args="joint_state_controller
    joint1_position_controller
    joint2_position_controller
    joint3_position_controller
    joint4_position_controller"/>
</launch>
②robot_description.xml

机器人描述文件,其每个部分的功能见注释。

<launch>
  <!--Load urdf to param server-->
  <param name="robot_description" command="$(find xacro)/xacro --inorder '$(find arm1)/urdf/arm1.urdf.xacro'"/>

  <!--GUI used to send fake joint values-->
  <node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher">
    <param name="use_gui" value="false"/>
  </node>

  <!--Publish robot state to TF-->
  <node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher">
    <remap from="/joint_states" to="/arm1/joint_states" />
  </node>
</launch>
③gazebo.launch

最终的运行文件,加载gazebo和相关节点。

<launch>
  <include file="$(find arm1)/launch/robot_description.xml"/>
  <include file="$(find arm1)/launch/robot_control.xml"/>

  <!--Launch a gazebo world-->
  <include file="$(find gazebo_ros)/launch/empty_world.launch"/>
    <arg name="world_name" value="$(find arm1)/worlds/willow_garage.world"/>
    <arg name="paused" value="false"/>
    <arg name="use_sim_time" value="true"/>
    <arg name="gui" value="true"/>
    <arg name="headless" value="false"/>
    <arg name="debug" value="false"/>

  <node 
     name="urdf_spawner" 
     pkg="gazebo_ros" 
     type="spawn_model" 
     respawn="false" output="screen"
     args="-urdf -param robot_description -x 0 -y 0 -z 0 -R 0 -P 0 -Y 0 -model arm1"/>

</launch>

打开一个新的终端

source ~/catkin_ws/devel/setup.bash
roslaunch arm1 gazebo.launch

然后我们就可以看到gazebo成功打开了,模型成功加载如下。

在这里插入图片描述
若gazebo中模型出现抖动,则考虑controllers.yaml中的pid参数的设置。我当时按照pid默认值来运行gazebo模型,结果造成了非常严重的模型抖动。猜测可能是因为模型尺寸和simple_arm的尺寸相差较大而导致的。

确定了只是因为pid参数的问题之后,那就需要调参了。调参可是门艺术啊。我调整完的参数已经在controllers.yaml中给出了,其效果比默认值好上很多了,但是还是有抖动。

每次调参数,需要重新开启新的终端加载gazebo。如果有必要,可以输入以下命令,来关闭所有的gazevo服务。

$ killall gzserver
(4)scripts文件夹

scripts文件夹中存放python的可执行文件,我们需要把我们的simple_mover放到这里边。
若不存在scripts文件夹,则首先创建它

$ cd ~/catkin_ws/src/arm1/
$ mkdir scripts
$ cd ~/catkin_ws/src/arm1/scripts 

创建simple_mover 文件

$ sudo touch simple_mover 

使文件可执行

$ sudo chmod 777 simple_mover 

编写simple_mover文件,也可以直接打开文件进行编辑。

nano simple_mover

以下内容可以参考博客【Udacity机器人软件工程师课程笔记(十一)-ROS-编写ROS节点

#!/usr/bin/env python

import math
import rospy
from std_msgs.msg import Float64

def mover():
    pub_j1 = rospy.Publisher('/arm1/joint1_position_controller/command',
                             Float64, queue_size=10)
    pub_j2 = rospy.Publisher('/arm1/joint2_position_controller/command',
                             Float64, queue_size=10)
    pub_j3 = rospy.Publisher('/arm1/joint3_position_controller/command',
                             Float64, queue_size=10)
    pub_j4 = rospy.Publisher('/arm1/joint4_position_controller/command',
                             Float64, queue_size=10)
    rospy.init_node('arm_mover')
    rate = rospy.Rate(10)
    start_time = 0

    while not start_time:
        start_time = rospy.Time.now().to_sec()

    while not rospy.is_shutdown():
        elapsed = rospy.Time.now().to_sec() - start_time
        pub_j1.publish(math.sin(2*math.pi*0.1*elapsed)*(math.pi/2))
        pub_j2.publish(math.sin(2*math.pi*0.1*elapsed)*(math.pi/2))
		pub_j3.publish(math.sin(2*math.pi*0.1*elapsed)*(math.pi/2))
		pub_j4.publish(math.sin(2*math.pi*0.1*elapsed)*(math.pi/2))
        rate.sleep()

if __name__ == '__main__':
    try:
        mover()
    except rospy.ROSInterruptException:
	pass

在gazebo运行的条件下,新建一个终端。

source ~/catkin_ws/devel/setup.bash
rosrun arm1 simple_mover

运行如下:
在这里插入图片描述

  • 22
    点赞
  • 75
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 46
    评论
1. URDF文件 以下是一个简单的六自由度机械臂的URDF文件示例: ``` <?xml version="1.0"?> <robot name="six_dof_arm" xmlns:xacro="http://www.ros.org/wiki/xacro"> <link name="base_link"> <visual> <geometry> <cylinder length="0.2" radius="0.05"/> </geometry> </visual> <inertial> <mass value="1.0"/> <inertia ixx="0.1" iyy="0.1" izz="0.1" ixy="0.0" ixz="0.0" iyz="0.0"/> </inertial> </link> <joint name="shoulder_pan_joint" type="revolute"> <parent link="base_link"/> <child link="shoulder_link"/> <origin rpy="0 0 0" xyz="0 0 0.1"/> <axis xyz="0 0 1"/> <limit effort="100" lower="-3.14" upper="3.14" velocity="1.0"/> </joint> <link name="shoulder_link"> <visual> <geometry> <cylinder length="0.3" radius="0.05"/> </geometry> </visual> <inertial> <mass value="1.0"/> <inertia ixx="0.1" iyy="0.1" izz="0.1" ixy="0.0" ixz="0.0" iyz="0.0"/> </inertial> </link> <joint name="shoulder_lift_joint" type="revolute"> <parent link="shoulder_link"/> <child link="upper_arm_link"/> <origin rpy="-1.57 0 0" xyz="0 0 0.3"/> <axis xyz="0 1 0"/> <limit effort="100" lower="-3.14" upper="3.14" velocity="1.0"/> </joint> <link name="upper_arm_link"> <visual> <geometry> <cylinder length="0.4" radius="0.05"/> </geometry> </visual> <inertial> <mass value="1.0"/> <inertia ixx="0.1" iyy="0.1" izz="0.1" ixy="0.0" ixz="0.0" iyz="0.0"/> </inertial> </link> <joint name="elbow_joint" type="revolute"> <parent link="upper_arm_link"/> <child link="forearm_link"/> <origin rpy="1.57 0 0" xyz="0 0 0.4"/> <axis xyz="0 1 0"/> <limit effort="100" lower="-3.14" upper="3.14" velocity="1.0"/> </joint> <link name="forearm_link"> <visual> <geometry> <cylinder length="0.2" radius="0.05"/> </geometry> </visual> <inertial> <mass value="1.0"/> <inertia ixx="0.1" iyy="0.1" izz="0.1" ixy="0.0" ixz="0.0" iyz="0.0"/> </inertial> </link> <joint name="wrist_joint" type="revolute"> <parent link="forearm_link"/> <child link="wrist_link"/> <origin rpy="-1.57 0 0" xyz="0 0 0.2"/> <axis xyz="0 1 0"/> <limit effort="100" lower="-3.14" upper="3.14" velocity="1.0"/> </joint> <link name="wrist_link"> <visual> <geometry> <cylinder length="0.1" radius="0.05"/> </geometry> </visual> <inertial> <mass value="1.0"/> <inertia ixx="0.1" iyy="0.1" izz="0.1" ixy="0.0" ixz="0.0" iyz="0.0"/> </inertial> </link> <joint name="gripper_joint" type="revolute"> <parent link="wrist_link"/> <child link="gripper_link"/> <origin rpy="-1.57 0 0" xyz="0 0 0.1"/> <axis xyz="0 1 0"/> <limit effort="100" lower="-3.14" upper="3.14" velocity="1.0"/> </joint> <link name="gripper_link"> <visual> <geometry> <box size="0.05 0.05 0.1"/> </geometry> </visual> <inertial> <mass value="0.1"/> <inertia ixx="0.0001" iyy="0.0001" izz="0.0001" ixy="0.0" ixz="0.0" iyz="0.0"/> </inertial> </link> </robot> ``` 2. Launch文件 以下是一个简单的六自由度机械臂Gazebo2仿真的launch文件示例: ``` <launch> <!-- Load URDF into parameter server --> <param name="robot_description" textfile="$(find six_dof_arm)/urdf/six_dof_arm.urdf" /> <!-- Launch Gazebo with robot model --> <node name="gazebo" pkg="gazebo_ros" type="gazebo" args="$(find six_dof_arm)/worlds/six_dof_arm.world"/> <!-- Spawn robot model in Gazebo --> <node name="spawn_urdf" pkg="gazebo_ros" type="spawn_model" args="-urdf -model my_robot -param robot_description"/> <!-- Start joint_state_publisher --> <node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher"> <rosparam param="source_list">[/shoulder_pan_joint, /shoulder_lift_joint, /elbow_joint, /wrist_joint, /gripper_joint]</rosparam> </node> <!-- Start robot_state_publisher --> <node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" /> </launch> ``` 注意,上述示例中的文件路径和文件名需要根据实际情况进行修改
评论 46
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Stan Fu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值