转自 https://segmentfault.com/a/1190000022371602 仅供学习使用
1 前言
本案例摘录自胡春旭老师的《ROS机器人开发实践》
本文规定星号代表需要用户自定义
2 解读文件
2.1 定义标头
<?xml version="1.0"?>
<robot name="****" xmlns:xacro="http://www.ros.org/wiki/xacro">
...
</robot>
2.2 定义杆件外观颜色
<!-- Defining the colors used in this robot -->
<material name="Black">
<color rgba="0 0 0 1"/>
</material>
2.3 定义参数(相当于程序里的变量)
<xacro:property name="****" value="****" />
2.4 定义宏(相当于程序里的函数)
<!-- Macro for inertia matrix -->
<xacro:macro name="****" params="**** **** ...">
...
</xacro:macro>
其中macro中的name相当于规定函数名,param即为形参名。
在macro中引用param的方式:${形参名}
;并且支持四则运算。如下所示:
<xacro:macro name="sphere_inertial_matrix" params="m r">
<inertial>
<mass value="${m}" />
<inertia ixx="${2*m*r*r/5}" ixy="0" ixz="0"
iyy="${2*m*r*r/5}" iyz="0"
izz="${2*m*r*r/5}" />
</inertial>
</xacro:macro>
调用自身文件内macro的方式:
<macro名 macro.param=**** />
调用外部文件的macro的方式:
<xacro:include filename="$(find 包名)/urdf/xacro名.xacro" />
<macro名 macro.param=****/>
3 示例xacro文件
具体小车模型如下所示:
示例文件名robot_body.xacro
<?xml version="1.0"?>
<robot name="robot_body" xmlns:xacro="http://www.ros.org/wiki/xacro">
<!-- Defining the colors used in this robot -->
<material name="Black">
<color rgba="0 0 0 1"/>
</material>
<material name="White">
<color rgba="1 1 1 1"/>
</material>
<material name="Blue">
<color rgba="0 0 1 1"/>
</material>
<!-- PROPERTY LIST -->
<!--All units in m-kg-s-radians unit system -->
<xacro:property name="M_PI" value="3.14" />
<!-- Main body length, width, height and mass -->
<xacro:property name="base_mass" value="0.5" />
<xacro:property name="base_link_radius" value="0.13"/>
<xacro:property name="base_link_length" value="0.005"/>
<xacro:property name="motor_x" value="-0.05"/>
<!-- Caster radius and mass -->
<xacro:property name="caster_radius" value="0.016" />
<xacro:property name="caster_mass" value="0.01" />
<xacro:property name="caster_joint_origin_x" value="-0.12" />
<!-- Wheel radius, height and mass -->
<xacro:property name="wheel_radius" value="0.033" />
<xacro:property name="wheel_height" value="0.017" />
<xacro:property name="wheel_mass" value="0.1" />
<!-- Macro for inertia matrix -->
<xacro:macro name="sphere_inertial_matrix" params="m r">
<inertial>
<mass value="${m}" />
<inertia ixx="${2*m*r*r/5}" ixy="0" ixz="0"
iyy="${2*m*r*r/5}" iyz="0"
izz="${2*m*r*r/5}" />
</inertial>
</xacro:macro>
<xacro:macro name="cylinder_inertial_matrix" params="m r h">
<inertial>
<mass value="${m}" />
<inertia ixx="${m*(3*r*r+h*h)/12}" ixy = "0" ixz = "0"
iyy="${m*(3*r*r+h*h)/12}" iyz = "0"
izz="${m*r*r/2}" />
</inertial>
</xacro:macro>
<!-- Macro for wheel joint -->
<xacro:macro name="wheel" params="lr translateY">
<!-- lr: left, right -->
<link name="wheel_${lr}_link">
<visual>
<origin xyz="0 0 0" rpy="${M_PI/2} 0 0 " />
<geometry>
<cylinder length="${wheel_height}" radius="${wheel_radius}" />
</geometry>
<material name="Black" />
</visual>
<collision>
<origin xyz="0 0 0" rpy="${M_PI/2} 0 0 " />
<geometry>
<cylinder length="${wheel_height}" radius="${wheel_radius}" />
</geometry>
</collision>
<cylinder_inertial_matrix m="${wheel_mass}" r="${wheel_radius}" h="${wheel_height}" />
</link>
<joint name="base_to_wheel_${lr}_joint" type="continuous">
<parent link="base_link"/>
<child link="wheel_${lr}_link"/>
<origin xyz="${motor_x} ${translateY * base_link_radius} 0" rpy="0 0 0" />
<axis xyz="0 1 0" rpy="0 0" />
</joint>
</xacro:macro>
<!-- Macro for caster joint -->
<xacro:macro name="caster" params="fb translateX">
<!-- fb: front, back -->
<link name="${fb}_caster_link">
<visual>
<origin xyz="0 0 0 " rpy="0 0 0" />
<geometry>
<sphere radius="${caster_radius}" />
</geometry>
<material name="White" />
</visual>
<collision>
<geometry>
<sphere radius="${caster_radius}" />
</geometry>
<origin xyz="0 0 0 " rpy="0 0 0" />
</collision>
<sphere_inertial_matrix m="${caster_mass}" r="${caster_radius}" />
</link>
<joint name="base_to_${fb}_caster_joint" type="fixed">
<parent link="base_link"/>
<child link="${fb}_caster_link"/>
<origin xyz="${translateX*caster_joint_origin_x} 0 ${-caster_radius}" rpy="0 0 0"/>
</joint>
</xacro:macro>
<!-- BASE-FOOTPRINT -->
<!-- base_footprint is a fictitious link(frame) that is on the ground right below base_link origin -->
<xacro:macro name="robot_body">
<link name="base_footprint">
<visual>
<origin xyz="0 0 0" rpy="0 0 0" />
<geometry>
<box size="0.001 0.001 0.001" />
</geometry>
</visual>
</link>
<joint name="base_footprint_joint" type="fixed">
<origin xyz="0 0 ${wheel_radius}" rpy="0 0 0" />
<parent link="base_footprint"/>
<child link="base_link" />
</joint>
<!-- BASE-LINK -->
<!--Actual body/chassis of the robot-->
<link name="base_link">
<cylinder_inertial_matrix m="${base_mass}" r="${base_link_radius}" h="${base_link_length}" />
<visual>
<origin xyz=" 0 0 0" rpy="0 0 0" />
<geometry>
<cylinder length="${base_link_length}" radius="${base_link_radius}"/>
</geometry>
<material name="Blue" />
</visual>
<collision>
<origin xyz="0 0 0" rpy="0 0 0" />
<geometry>
<cylinder length="${base_link_length}" radius="${base_link_radius}"/>
</geometry>
</collision>
</link>
<!-- Wheel Definitions -->
<wheel lr="right" translateY="1" />
<wheel lr="left" translateY="-1" />
<!-- Casters Definitions -->
<caster fb="front" translateX="-1" />
</xacro:macro>
</robot>
4.调用机器人模型
建立总xacro文件,以调用宏(即macro)robot_body(处于robot_body.xacro文件),总文件名为robot.xacro
<?xml version="1.0"?>
<robot name="robot" xmlns:xacro="http://www.ros.org/wiki/xacro">
<xacro:include filename="$(find 包名)/urdf/robot_body.xacro" />
<robot_body />
</robot>
在ROS中,xacro文件要转化urdf文件来调用,命令如下:
rosrun xacro xacro --inorder xacro名.xacro > ****.urdf
一般我们可以将该命令写入launch文件。因此launch文件,可以写成如下所示:
<?xml version = "1.0"?>
<launch>
<arg name = "model" default = "$(find xacro)/xacro --inorder '$(find pkg名)/urdf/robot.xacro'" />
<arg name = "gui" default = "true" />
<param name = "robot_description" command = "$(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" />
</launch>
以上纯属个人见解~