总则
学完urdf文件编写后又去学了xacro文件编写,还是比较顺利的,现在记录以下过程
效果图:
文件内容及注释
下面展示我的代码文件
myrobot.xacro文件,该文件和C语言的头文件差不多,后面myrobot_all.xacro文件引入这个文件后,就可以使用该文件定义的组件:
<?xml version="1.0"?>
<robot name="myrobot" xmlns:xacro="http://www.ros.org/wiki/xacro"> <!--xacro文件标注的一行,urdf文件没有这行-->
<xacro:property name="M_PI" value="3.1415926536"/>
<xacro:property name="wheel_length" value="0.1"/>
<xacro:property name="wheel_radius" value="0.1"/>
<xacro:property name="base_link_length" value="1.0"/> <!--参数宏定义,和C语言的define差不多-->
<xacro:property name="base_link_width" value="0.5"/>
<xacro:property name="base_link_heigth" value="0.25"/>
<material name="micai">
<texture filename="package://mbot_description/meshes/muzhi.jpeg" /> <!--定义一个木质材料-->
</material>
<material name="black">
<color rgba="0 0 0 1"/>
</material>
<xacro:macro name="wheel" params="prefix reflect_r reflect_t"> <!--定义一个轮胎,和C语言的函数差不多,params后面是参数列表-->
<link name="${prefix}_wheel_link"> <!--用${}引用参数值,中括号里可以计算-->
<inertial>
<origin xyz="0 0 0" rpy="0 0 0"/>
<mass value="30"/>
<inertia ixx="3.125" ixy="0" ixz="0" iyy="10.625" iyz="0" izz="12.5" />
</inertial>
<visual>
<origin xyz="0 0 0" rpy="0 0 0" />
<geometry>
<cylinder length="${wheel_length}" radius="${wheel_radius}" />
</geometry>
<material name="black">
<color rgba="0 0 0 1"/>
</material>
</visual>
<collision>
<origin xyz="0 0 0" rpy="0 0 0" />
<geometry>
<cylinder length="${wheel_length}" radius="${wheel_radius}" />
</geometry>
</collision>
</link>
<joint name="${prefix}_wheel_joint" type="continuous">
<axis xyz="0 0 1"/>
<parent link="base_link"/>
<child link="${prefix}_wheel_link"/>
<origin rpy="${M_PI/2} 0 0" xyz="${base_link_length/4*reflect_r} ${base_link_width/2*reflect_t} ${wheel_radius}"/>
<limit effort="100" velocity="100"/>
<joint_properties damping="0.0" friction="0.0"/>
</joint>
</xacro:macro>
<xacro:macro name="base" params="sensor_name height length offset parent_link z_value">
<joint name="${sensor_name}_base_joint" type="fixed">
<parent link="${parent_link}"/>
<child link="${sensor_name}_base"/>
<origin rpy="0 0 0" xyz="${offset} 0 ${z_value}"/>
</joint>
<link name="${sensor_name}_base">
<inertial>
<origin xyz="0 0 0" rpy="0 0 0"/>
<mass value="30"/>
<inertia ixx="1" ixy="0" ixz="0" iyy="1" iyz="0" izz="1" />
</inertial>
<visual>
<origin xyz="0 0 0" rpy="0 0 0" />
<geometry>
<box size="${length} ${base_link_width} ${height}" />
</geometry>
<material name="micai"/>
</visual>
<collision>
<origin xyz="0 0 0" rpy="0 0 0" />
<geometry>
<box size="${length} ${base_link_width} ${height}" />
</geometry>
</collision>
</link>
</xacro:macro>
<xacro:macro name="base_car">
<link name="base_link">
<inertial>
<origin xyz="0 0 ${wheel_radius+base_link_heigth/2}" rpy="0 0 0" />
<mass value="30"/>
<inertia ixx="3.125" ixy="0" ixz="0" iyy="10.625" iyz="0" izz="12.5" />
</inertial>
<visual>
<origin xyz="0 0 ${wheel_radius+base_link_heigth/2}" rpy="0 0 0" />
<geometry>
<box size="${base_link_length} ${base_link_width} ${base_link_heigth}" />
</geometry>
<material name="micai"/>
</visual>
<collision>
<origin xyz="0 0 ${wheel_radius+base_link_heigth/2}" rpy="0 0 0" />
<geometry>
<box size="${base_link_length} ${base_link_width} ${base_link_heigth}" />
</geometry>
</collision>
</link>
<wheel prefix="right_front" reflect_r="1" reflect_t="-1" /> <!--相当于C语言函数调用,调用上面的wheel板块并给参数赋值-->
<wheel prefix="right_back" reflect_r="-1" reflect_t="-1" />
<wheel prefix="left_front" reflect_r="1" reflect_t="1" />
<wheel prefix="left_back" reflect_r="-1" reflect_t="1" />
<base sensor_name="kinect" height="0.05" length="0.9" offset="-0.05" parent_link="base_link" z_value="0.375"/>
<base sensor_name="laser" height="0.06" length="0.8" offset="-0.05" parent_link="kinect_base" z_value="0.055"/>
<link name="dummy">
</link> <!--这个link和下面的joint作用是的作用是解决base_link inertial属性警告的问题-->
<joint name="dummy_joint" type="fixed">
<parent link="dummy"/>
<child link="base_link"/>
</joint>
</xacro:macro>
</robot>
myrobot_all.xacro:
<?xml version="1.0"?>
<robot name="my_robot" xmlns:xacro="http://www.ros.org/wiki/xacro">
<xacro:include filename="$(find mbot_description)/urdf/xacro/sensors/myrobot.xacro" /> <!--这个是引入文件的语法,find后面跟的是功能包-->
<base_car/>
</robot>
myrobot_xacro.launch:
<launch>
<arg name="model" default="$(find xacro)/xacro --inorder '$(find mbot_description)/urdf/xacro/sensors/myrobot_all.xacro'"/> <!--这行命令主要的作用是调用/opt/ros/melodic/lib/xacro路径下的xacro解释器解析xacro文件-->
<arg name="gui" default="true" />
<param name="robot_description" command="$(arg model)" /> <!--command标签是指命令行参数的意思,后面跟的是命令行参数,即xacro文件,这个地方的command标签和urdf文件的launch文件不太一样,urdf的launch文件中的是textfile-->
<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="robot_state_publisher" />
<node name="rviz" pkg="rviz" type="rviz" args="-d $(find mbot_description)/rviz/myrobot.rviz" />
</launch>
注意,以上注释部分只是为了更好的理解语法,实际复制上面内容时中文部分要删掉,文件不能出现中文,不然会有问题。
参考
链接: Xacro_语法详解.