xacro

本文完全照搬https://blog.csdn.net/sunbibei/article/details/52297524

Xacro (XML Macros) Xacro is an XML macro language.

XACRO文件和URDF实质上是等价的. XACRO格式提供了一些更高级的方式来组织编辑机器人描述. 主要提供了三种方式来使得整个描述文件变得简单. 借用在教程中一句话来形容xacro的优势: “Fortunately, you can use the xacro package to make your life simpler”.

3.1 Constants

Usage: <xacro:property name="WIDTH" value="2.0"/>

类似于C语言中的宏定义, 在头部定义, 如<xacro:property name="WIDTH" value="2.0"/>, 以${WIDTH}的方式进行使用. 经常会看到的一个常量定义, <property name="PI" value="3.14159265" />. 还有定义一个前缀, 这样后面关节名都可以方便的进行修改. 比如<property name="prefix" value="my_"/>, 后面关节名字就可以类似的进行更新. <joint name="${prefix}joint1" type="revolute"/>.

在有了上面的常量定义之后, 类似于宏定义, 完成字符串替换, 同时还可以进行一些简单的数学运算.

Usage: ${1/2}, ${PI*(WIDTH*0.5)}

3.2 Macros

这个才是xacro文件中最重要的部分. 就像宏函数一样, 完成一些最小模块的定义, 方便重用, 以及可以使用参数来标识不同的部分.

3.2.1 Simple Macro

Usage:

<xacro:macro name="default_origin">
    <origin xyz="0 0 0" rpy="0 0 0"/>
</xacro:macro>
<xacro:default_origin />

前面三行对宏进行定义, 第四行是使用.

3.2.2 Parameterized Macro

Usage:

<xacro:macro name="default_link" params="prefix">
    <link name="${prefix}_link1" />
</xacro:macro>
<xacro:default_link prefix="my" />

类似, 前三行定义, 第四行是进行使用. 当然, 不单由这样简单的参数, 还可以使用块参数.
Usage:

<xacro:macro name="default_link" params="prefix *origin">
    <link name="${prefix}_link1" >
        <xacro:insert_block name="prigin" />
    </link>
</xacro:macro>
<xacro:default_link prefix="my">
    <origin xyz="0 0 0" rpy="0 0 0" />
</xacro:default_link>

一般情况下, 很多已有的机器人模型, 都是以xacro格式提供描述, 而在xacro文件中, 整个机器人定义为一个很大的宏. 例如, barrett hand, 想进一步了解的朋友可以点击前面的链接, 查看以下barrett hand是如何进行描述的.

3.2.3 Include

很多模型都是已宏的形式进行定义, 并以最小集团分成很多个文件. 而最终的机器人描述就变得非常简单了. 下面摘录一个ur5的描述文件. 从中可以看出来xacro的强大优势. 在最后的示例中我们还能够看到, urdf文件也是能够直接导入进来的.

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

  <!-- common stuff -->
  <xacro:include filename="$(find ur_description)/urdf/ur5/common.gazebo.xacro" />

  <!-- ur5 -->
  <xacro:include filename="$(find ur_description)/urdf/ur5/ur5.urdf.xacro" />

  <!-- arm -->
  <xacro:ur5_robot prefix="" joint_limited="false"/>

  <link name="world" />

  <joint name="world_joint" type="fixed">
    <parent link="world" />
    <child link = "base_link" />
    <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" />
  </joint>

</robot>

当然, 此时的简单是建立在之前的复杂的基础上的. 从上述内容中可以看到, 首先是在ur_description包中找到另外几个xacro文件, 将其包含进来. 当然应该注意到, include类似于C语言中的include, 先将该文件扩展到包含的位置. 但包含进来的文件很有可能只是一个参数宏的定义. 并没有被调用. 所以, 示例中调用了一个宏(<xacro:ur5_robot prefix="" joint_limited="false"/>), 产生一个ur5机器人.

3.3 可视化

urdf_tutorial包也是可以查看xacro文件的. 使用roslaunch urdf_tutorial xacrodisplay.launch model:=path/to/your/xxx.urdf.xacro.

4. 关于urdf_tutorial

前面提到的可视化都是使用urdf_tutorial包进行的. 分别调用了两个launch文件. 在上面的示例中我们还看到了不但会使用rviz进行可视化, 还会发起一些话题等. 其实这些我们能够从他的launch文件中一窥究竟.

打开命令行, 输入: rosed urdf_tutorial dispaly.launch. 会使用vim打开该文件. 可以看到下述内容.

<launch>
  <arg name="model" />
  <arg name="gui" default="False" />
  <param name="robot_description" textfile="$(arg model)" />
  <param name="use_gui" value="$(arg gui)"/>
  <node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" />
  <node name="robot_state_publisher" pkg="robot_state_publisher" type="state_publisher" />
  <node name="rviz" pkg="rviz" type="rviz" args="-d $(find urdf_tutorial)/urdf.rviz" required="true" />
</launch>

由上可以看到, 参数model是没有默认值的, 所以调用该launch文件必须指定model参数. 其他都比较易懂, 主要解释以下robot_description, 可以看到, 其前面是param. 这个是指定ros 参数服务器中的参数值. 而打开rviz之后, rviz就是直接从参数服务器中读取机器人描述文件, 也就是这个参数. 然后进行显示. use_gui也是如此对显示产生的影响. 另外, 还发起了两个发布者节点, 分别发布joint_states和robot_state. 这也就是会由joint_states话题的原因. xacrodispaly.launch文件和上面类似, 但在处理文件时, 使用的是: <param name="robot_description" command="$(find xacro)/xacro.py $(arg model)" />. 在launch中将xacro文件解析为urdf.

至于其中启动的两个节点, joint_state_publisher 和 robot_state_publisher, 可以查看ROS Answer上相关的解释. 另外, 在robot_state_publisher概述中提到, robot_state_publisher从/joint_states话题中获取机器人joint角度作为输入, 使用机器人的运动学树模型计算出机器人link的3D姿态, 然后将其发布到话题/tf和 /tf_staticjoint_state_publisher从ROS参数服务器中读取robot_description参数, 找到所有non-fixed joint, 发布他们的JointState消息到/joint_states话题.

Leave a Comment