xacro模型
为每个link、joint加上命名空间前缀:
- 添加xacro属性:
<xacro:property name="ns" value="$(arg ns)/" />
,其中$(arg ns)
由launch文件传入,在下文会讲如何传入。 - 为每个link添加命名空间前缀:
<link name = "${ns}<用户指定link名字>">
- 为每个joint添加命名空间前缀:
<joint name="${ns}<用户指定joint名字>" type="<用户指定类型>">
launch文件
对于每个命名为<命名空间>的机器人模型,在launch文件中添加如下代码。
<group ns="命名空间">
<param name="robot_description"
command="$(find xacro)/xacro.py
$(find battlebot)/urdf/$(arg model) ns:=<命名空间>"
/>
<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="urdf_spawner" pkg="gazebo_ros" type="spawn_model" respawn="false" output="screen"
args="-urdf -model <命名空间> -param robot_description -z 0.30"/>
</group>
各部分代码解释
<group ns="命名空间">
...
</group>
被group包围的节点,发布的parameters、topics、services均会被加上[<命名空间>/]前缀。
<param name="robot_description"
command="$(find xacro)/xacro.py
$(find battlebot)/urdf/$(arg model) ns:=<命名空间>"
/>
调用xacro.py解析xacro文件,并且传入ns参数,在xacro文件中可以通过$(arg ns)
来获取传入的参数,将解析出来的urdf模型设置给[<命名空间>/robot_description]参数。
<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" />
[<命名空间>/joint_state_publisher]通过解析[<命名空间>/robot_description]参数(urdf模型),获取所有非固定关节,然后将关节的状态通过[<命名空间>/joint_states]话题发布出去。
[<命名空间>/robot_state_publisher]通过解析[<命名空间>/robot_description]参数(urdf模型),和订阅[<命名空间>/joint_states],计算当前机器人各个坐标系的当前坐标,发布给tf。
<node name="urdf_spawner" pkg="gazebo_ros" type="spawn_model" respawn="false" output="screen"
args="-urdf -model <命名空间> -param robot_description -z 0.30"/>
调用一个python命令,通过解析[<命名空间>/robot_description]参数(urdf模型),往gazebo添加一个名字为[<命名空间>]的机器人模型。如果不需要用到gazebo,可删除。
例子
<?xml version="1.0"?>
<launch>
<arg name="paused" default="false"/>
<arg name="use_sim_time" default="true"/>
<arg name="gui" default="true"/>
<arg name="headless" default="false"/>
<arg name="debug" default="false"/>
<include file="$(find gazebo_ros)/launch/empty_world.launch">
<arg name="world_name" value="$(find battlebot)/worlds/robot.world"/>
<arg name="debug" value="$(arg debug)" />
<arg name="gui" value="$(arg gui)" />
<arg name="paused" value="$(arg paused)"/>
<arg name="use_sim_time" value="$(arg use_sim_time)"/>
<arg name="headless" value="$(arg headless)"/>
</include>
<group ns="robot1">
<param name="robot_description"
command="$(find xacro)/xacro.py
$(find battlebot)/urdf/battlebot.xacro ns:=robot1"/>
<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="urdf_spawner" pkg="gazebo_ros" type="spawn_model" respawn="false" output="screen"
args="-urdf -model robot1 -param robot_description -z 1"/>
</group>
<group ns="robot2">
<param name="robot_description"
command="$(find xacro)/xacro.py
$(find battlebot)/urdf/battlebot.xacro ns:=robot2"/>
<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="urdf_spawner" pkg="gazebo_ros" type="spawn_model" respawn="false" output="screen"
args="-urdf -model robot2 -param robot_description -z 0.30"/>
</group>
</launch>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
为什么不使用<param name="tf_prefix" value="<命名空间>" />
的方式?
有两种方式给坐标系名字加上[<命名空间>/]前缀:
1. 如上文描述的,给xacro传递参数的方式。
2. 在<group></group>
之间加上<param name="tf_prefix" value="<命名空间>" />
的方式。
不采用方式2的原因是,rviz图形化Robot Model类型时,会根据urdf模型的命名在tf中寻找对应的坐标系,它在寻找的时候不会自动加上命名空间,因此会导致Robot Model显示失败。
方式1直接改变了urdf模型的命名,因此rviz能寻找到正确的坐标系。
参考