URDF 是最初也是比较简单的机器人描述文件,它的结构简单明了,容易理解。但是这也导致当机器人模型变得复杂时,urdf的结构描述就变得冗长,无法简洁有效的描述机器人部件;
Xacro 的出现在一定程度上有效地解决这种问题。在本质上,Xacro与URDF是等价的,但Xacro格式提供了一些更高级的方式来组织和编辑机器人描述。
在学习UR机器人的时候,官方包都是使用Xacro文件来描述机器人的模型参数和一些动力学参数,包括Gazebo的插件,而原本我们比较熟悉的URDF缺没有找到,而且乍一看,Xacro文件比起URDF又复杂很多,各种参数,各种数据,看的简直头大.促使我去理解Xacro文件的原因是因为通过SolidWorks生成的URDF包,无法通过里面的gazebo.launch启动Gazebo来仿真机械臂.但是UR提供的Gazebo包缺可以成功启动仿真,而他们之间的不同点就在于前者启动的是URDF文件,后者启动的是Xacro文件,虽然知道这两者可能没有什么必然关系,但是后续的力控制程序使用的都是Xacro文件,不得已+顺势而为了解了一下.
对于如下URDF的结构: 包含了Link :redwall_arm_base_link 和 redwall_shoulder_link以及他们之间的joint :redwall_arm_shoulder_pan_joint, 中间的只是一些外观,颜色,质量,极限等参数,比较简单也比较直观,但是这样的内容只能通过RViz启动description展示,想要通过Gazebo启动还需要加一些Gazebo的插件,详细见:https://blog.csdn.net/qq_34935373/article/details/95886151
<?xml version="1.0" encoding="utf-8"?>
<robot name="redwall_arm_description">
<link name="redwall_arm_base_link">
<visual>
<origin
xyz="0 0 0"
rpy="0 0 0" />
<geometry>
<mesh filename="package://redwall_arm_description/meshes/redwall_arm_base_link.STL" />
</geometry>
<material
name="">
<color rgba="0.776470588235294 0.756862745098039 0.737254901960784 1" />
</material>
</visual>
<collision>
<origin
xyz="0 0 0"
rpy="0 0 0" />
<geometry>
<mesh filename="package://redwall_arm_description/meshes/redwall_arm_base_link.STL" />
</geometry>
</collision>
</link>
<link name="redwall_arm_shoulder_link">
<inertial>
<origin
xyz="-0.00683747788351393 0.0126830913447122 0.103283560952032"
rpy="0 0 0" />
<mass
value="1.44474247247484" />
<inertia
ixx="0.00137468883201446"
ixy="-9.63035810976166E-06"
ixz="-2.22705760746311E-05"
iyy="0.00336510121555168"
iyz="-4.41374668694778E-06"
izz="0.00350020775935878" />
</inertial>
<visual>
<origin
xyz="0 0 0"
rpy="0 0 0" />
<geometry>
<mesh
filename="package://redwall_arm_description/meshes/redwall_arm_shoulder_link.STL" />
</geometry>
<material
name="">
<color
rgba="0.435294117647059 0.329411764705882 0 1" />
</material>
</visual>
<collision>
<origin
xyz="0 0 0"
rpy="0 0 0" />
<geometry>
<mesh
filename="package://redwall_arm_description/meshes/redwall_arm_shoulder_link.STL" />
</geometry>
</collision>
</link>
<joint name="redwall_arm_shoulder_pan_joint"
type="revolute">
<origin
xyz="0 0 0"
rpy="0 0 1.5707963267949" />
<parent link="redwall_arm_base_link" />
<child link="redwall_arm_shoulder_link" />
<axis xyz="0 0 1" />
<limit lower="-3.14" upper="3.14" effort="150" velocity="3.15" />
</joint>
</robot>
对于Xacro文件:先看一个比较短的,这种相当于写代码时候的main程序,他会调用一些子程序,通过<xarco:include filename>的方式,调用所指目录的子程序xarco文件,而第二部分的spawn arm是传递参数的方式,类似与代码的实参,举例来说 <xacro:redwall_arm_transmission prefix="redwall_arm_" hw_interface="hardware_interface/PositionJointInterface"/>表示上述子程序xarco文件中的一个函数<xacro:redwall_arm_transmission>需要两个参数,第一个和第二个参数的实参分别为prefix="redwall_arm_" 和hw_interface="hardware_interface/PositionJointInterface".接下来的就link和joint就是URDF里面一模一样的东西
<?xml version="1.0"?>
<robot name="redwall_arm_description" xmlns:xacro="http://ros.org/wiki/xacro">
<xacro:include filename="$(find redwall_arm_description)/urdf/redwall_arm_description.urdf.xacro" />
<!-- Spawn arm -->
<xacro:redwall_arm_robot prefix="redwall_arm_" />
<xacro:redwall_arm_gazebo prefix="redwall_arm_" />
<xacro:redwall_arm_transmission prefix="redwall_arm_" hw_interface="hardware_interface/PositionJointInterface"/>
<link name="base_link"/>
<!-- Join arm -->
<joint name="redwall_arm_base_joint" type="fixed">
<parent link="base_link" />
<child link="redwall_arm_base_link" />
<origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0" />
</joint>
</robot>
看了xacro的主程序,接下来看看被调用的子xacro:一共三个函数,和主xarco文件是一致的,参数个数和名称也是一致的,对于第一个函数: <xacro:macro name="redwall_arm_robot" params="prefix">里面的link 和 joint 同URDF完全一致,直接复制过来即可(这里UR的文件有所不同,通常会使用所传递的参数$prefix作为命名的一部分).
第二个函数则是gazebo的插件,照葫芦画瓢即可
第三个是减速比和点击的参数,同理
最后保险期间,加上gazebo的插件.
<?xml version="1.0"?>
<robot xmlns:xacro="http://wiki.ros.org/xacro">
<xacro:macro name="redwall_arm_robot" params="prefix">
<link name="redwall_arm_base_link">
<visual>
<origin
xyz="0 0 0"
rpy="0 0 0" />
<geometry>
<mesh
filename="package://redwall_arm_description/meshes/redwall_arm_base_link.STL" />
</geometry>
<material
name="">
<color rgba="0.776470588235294 0.756862745098039 0.737254901960784 1" />
</material>
</visual>
<collision>
<origin
xyz="0 0 0"
rpy="0 0 0" />
<geometry>
<mesh filename="package://redwall_arm_description/meshes/redwall_arm_base_link.STL" />
</geometry>
</collision>
</link>
<link name="redwall_arm_shoulder_link">
<inertial>
<origin
xyz="-0.00683747788351393 0.0126830913447122 0.103283560952032"
rpy="0 0 0" />
<mass
value="1.44474247247484" />
<inertia
ixx="0.00137468883201446"
ixy="-9.63035810976166E-06"
ixz="-2.22705760746311E-05"
iyy="0.00336510121555168"
iyz="-4.41374668694778E-06"
izz="0.00350020775935878" />
</inertial>
<visual>
<origin
xyz="0 0 0"
rpy="0 0 0" />
<geometry>
<mesh
filename="package://redwall_arm_description/meshes/redwall_arm_shoulder_link.STL" />
</geometry>
<material
name="">
<color rgba="0.435294117647059 0.329411764705882 0 1" />
</material>
</visual>
<collision>
<origin
xyz="0 0 0"
rpy="0 0 0" />
<geometry>
<mesh filename="package://redwall_arm_description/meshes/redwall_arm_shoulder_link.STL" />
</geometry>
</collision>
</link>
<joint name="redwall_arm_shoulder_pan_joint"
type="revolute">
<origin
xyz="0 0 0"
rpy="0 0 1.5707963267949" />
<parent
link="redwall_arm_base_link" />
<child
link="redwall_arm_shoulder_link" />
<axis
xyz="0 0 1" />
<limit
lower="-3.14"
upper="3.14"
effort="150"
velocity="3.15" />
</joint>
</xacro:macro>
<xacro:macro name="redwall_arm_gazebo" params="prefix">
<gazebo reference="${prefix}shoulder_link">
<selfCollide>true</selfCollide>
</gazebo>
</xacro:macro>
<xacro:macro name="redwall_arm_transmission" params="prefix hw_interface">
<transmission name="${prefix}shoulder_pan_trans">
<type>transmission_interface/SimpleTransmission</type>
<joint name="${prefix}shoulder_pan_joint">
<hardwareInterface>${hw_interface}</hardwareInterface>
</joint>
<actuator name="${prefix}shoulder_pan_motor">
<mechanicalReduction>1</mechanicalReduction>
</actuator>
</transmission>
</xacro:macro>
<gazebo>
<plugin name="gazebo_ros_control" filename="libgazebo_ros_control.so">
<robotNamespace>/</robotNamespace>
<legacyModeNS>true</legacyModeNS>
</plugin>
<plugin name="joint_state_publisher" filename="libgazebo_ros_joint_state_publisher.so">
<jointName>redwall_arm_shoulder_pan_joint</jointName>
</plugin>
</gazebo>
</robot>
接下通过launch文件启动模型,URDF和Xacro也有所区别,这也是改UR包比较纠结的一个地方:区别如下
<node
name="spawn_model"
pkg="gazebo_ros"
type="spawn_model"
args="-file $(find redwall_arm_description)/urdf/redwall_arm_description.urdf -urdf -model redwall_arm_description"
output="screen" />
<node
<param name="robot_description" command="$(find xacro)/xacro --inorder '$(find redwall_arm_description)/urdf/redwall_arm.urdf.xacro'" />
每次启动Gazebo的时候,会提示PID参数的报错,加上即可:
gazebo_ros_control:
pid_gains:
# these gains are used by the gazebo_ros_control plugin
redwall_arm_elbow_joint:
p: 500
i: 0.0
d: 0.0
i_clamp: 1
antiwindup: false
publish_state: true