4. 多机器人URDF集成
任务目标
在ROS2中加载多个机器人URDF模型,并在RViz中同时显示。本案例以两个简单两轮机器人为例,通过robot_state_publisher分别发布各机器人的TF与关节状态,最终在RViz中看到两个独立且可区分的机器人模型。
环境依赖
- Ubuntu 22.04 + ROS2 Humble(或其他ROS2发行版)
- 安装包:
urdf_tutorial、joint_state_publisher、rviz2、xacro
sudo apt install ros-${ROS_DISTRO}-urdf-tutorial ros-${ROS_DISTRO}-joint-state-publisher ros-${ROS_DISTRO}-rviz2 ros-${ROS_DISTRO}-xacro
实现方案
核心思路:为每个机器人创建独立的URDF文件(或xacro),每个URDF中通过ros2_control标签或直接设置frame_prefix参数来区分TF命名空间。启动时分别运行两个robot_state_publisher节点,各自加载对应URDF并设置不同的frame_prefix,从而避免TF树冲突。
关键完整代码
创建multi_robot_demo包,目录结构如下:
multi_robot_demo/
├── urdf/
│ ├── robot1.urdf
│ └── robot2.urdf
├── launch/
│ └── display_multi_robot.launch.py
├── CMakeLists.txt
└── package.xml
robot1.urdf(robot2.urdf仅颜色不同,结构相同):
<robot name="robot1">
<link name="base_link">
<visual>
<geometry><box size="0.4 0.2 0.1"/></geometry>
<material name="blue"/>
</visual>
</link>
<link name="left_wheel">
<visual>
<geometry><cylinder radius="0.05" length="0.03"/></geometry>
<material name="dark"/>
</visual>
</link>
<link name="right_wheel">
<visual>
<geometry><cylinder radius="0.05" length="0.03"/></geometry>
<material name="dark"/>
</visual>
</link>
<joint name="base_to_left_wheel" type="continuous">
<parent link="base_link"/>
<child link="left_wheel"/>
<origin xyz="0 -0.12 0" rpy="1.5708 0 0"/>
<axis xyz="0 0 1"/>
</joint>
<joint name="base_to_right_wheel" type="continuous">
<parent link="base_link"/>
<child link="right_wheel"/>
<origin xyz="0 0.12 0" rpy="1.5708 0 0"/>
<axis xyz="0 0 1"/>
</joint>
<material name="blue"><color rgba="0.2 0.3 0.9 1.0"/></material>
<material name="dark"><color rgba="0.1 0.1 0.1 1.0"/></material>
</robot>
display_multi_robot.launch.py:
import os
from launch import LaunchDescription
from launch_ros.actions import Node
from ament_index_python.packages import get_package_share_directory
def generate_launch_description():
pkg_dir = get_package_share_directory('multi_robot_demo')
# 机器人1:TF前缀为robot1_
robot1_state_publisher = Node(
package='robot_state_publisher',
executable='robot_state_publisher',
name='robot1_state_publisher',
parameters=[{
'robot_description': open(os.path.join(pkg_dir, 'urdf', 'robot1.urdf')).read(),
'frame_prefix': 'robot1_'
}]
)
# 机器人2:TF前缀为robot2_
robot2_state_publisher = Node(
package='robot_state_publisher',
executable='robot_state_publisher',
name='robot2_state_publisher',
parameters=[{
'robot_description': open(os.path.join(pkg_dir, 'urdf', 'robot2.urdf')).read(),
'frame_prefix': 'robot2_'
}]
)
# 关节状态发布(两个机器人共用,通过前缀区分)
joint_state_publisher = Node(
package='joint_state_publisher',
executable='joint_state_publisher',
name='joint_state_publisher',
parameters=[{'source_list': ['robot1/joint_states', 'robot2/joint_states']}]
)
rviz2 = Node(
package='rviz2',
executable='rviz2',
name='rviz2',
arguments=['-d', os.path.join(pkg_dir, 'config', 'multi_robot.rviz')]
)
return LaunchDescription([
robot1_state_publisher,
robot2_state_publisher,
joint_state_publisher,
rviz2
])
CMakeLists.txt关键部分:
install(DIRECTORY urdf launch config
DESTINATION share/${PROJECT_NAME}
)
运行与验证
# 构建并source
colcon build --packages-select multi_robot_demo
source install/setup.bash
# 启动
ros2 launch multi_robot_demo display_multi_robot.launch.py
RViz启动后,在左侧Displays面板点击Add,选择RobotModel,将Description Topic分别设为/robot1/robot_description和/robot2/robot_description(需添加两个RobotModel显示)。同时添加TF显示,勾选robot1_和robot2_前缀的TF树。
通过条件:
- RViz中同时出现两个不同颜色的机器人模型(蓝色为robot1,绿色为robot2);
- TF树中两个机器人的坐标系互不干扰,各自以
robot1_base_link和robot2_base_link为根; - 运行
ros2 topic list可看到/robot1/joint_states和/robot2/joint_states两个独立话题。
常见问题:若RViz中模型不显示,检查
robot_description参数是否被正确加载(ros2 param get /robot1_state_publisher robot_description);若TF前缀未生效,确认frame_prefix参数名正确(ROS2 Humble中为frame_prefix,旧版本为tf_prefix)。