预计完成时间:7 分钟
要创建一个新的机器人模型,你需要按照特定的目录结构来组织机器人的定义文件和文件夹。
除了机器人的定义文件,也就是 URDF 文件之外,你还需要使用 launch 文件来调试机器人的创建过程。
创建一个功能包,并在其中新建以下文件夹:
在 Web Shell 1 中执行
cd /workspace/src
ros2 pkg create robot_description --build-type ament_python --dependencies rclpy urdf xacro
mkdir -p robot_description/urdf
touch robot_description/urdf/robot.urdf
URDF 文件夹将用于存放机器人的描述文件。
将下面的内容粘贴到 robot.urdf 文件中:
robot.urdf
<?xml version="1.0"?>
<robot name="robot">
<!-- Link - chassis -->
<link name="link_chassis">
<inertial>
<mass value="10" />
<origin xyz="0 0 0.3" rpy="0 0 0" />
<inertia ixx="1.5417" ixy="0" ixz="0" iyy="3.467" iyz="0" izz="4.742" />
</inertial>
<collision>
<geometry>
<box size="2 1.3 0.4" />
</geometry>
</collision>
<visual>
<geometry>
<box size="2 1.3 0.4" />
</geometry>
<material name="Red">
<color rgba="1 0 0 1" />
</material>
</visual>
</link>
</robot>
使用下面的命令在该功能包中创建一个新的 launch 文件:
在 Web Shell 1 中执行
cd /workspace/src
mkdir -p robot_description/launch
touch robot_description/launch/rviz.launch.py
launch 文件夹将用于存放使用 RVIZ2 调试该机器人模型所需的 launch 文件。
复制并粘贴以下内容:
rviz.launch.py
import os
from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch.substitutions import Command
from launch_ros.actions import Node
# ROS2 Launch System will look for this function definition #
def generate_launch_description():
# Get Package Description and Directory #
package_description = "robot_description"
package_directory = get_package_share_directory(package_description)
# Load URDF File #
urdf_file = 'robot.urdf'
robot_desc_path = os.path.join(package_directory, "urdf", urdf_file)
print("URDF Loaded !")
# Robot State Publisher (RSP) #
robot_state_publisher_node = Node(
package='robot_state_publisher',
executable='robot_state_publisher',
name='robot_state_publisher_node',
output="screen",
emulate_tty=True,
parameters=[{'use_sim_time': True,
'robot_description': Command(['xacro ', robot_desc_path])}]
)
# RViz2 Launch Configuration (RViz) #
rviz_node = Node(
package='rviz2',
executable='rviz2',
name='rviz2_node',
output='screen',
emulate_tty=True,
parameters=[{'use_sim_time': True}],
)
# Create and Return the Launch Description Object #
return LaunchDescription(
[
robot_state_publisher_node,
rviz_node,
]
)
修改 setup.py 文件,确保 ROS2 Launch 系统能够检测并执行你在上面步骤中创建的 launch 文件。
将下面的内容复制到 setup.py 文件中,直接替换原有内容。
setup.py
import os
from glob import glob
from setuptools import setup
package_name = 'robot_description'
setup(
name=package_name,
version='0.0.0',
packages=[package_name],
data_files=[
('share/ament_index/resource_index/packages',
['resource/' + package_name]),
('share/' + package_name, ['package.xml']),
(os.path.join('share', package_name, 'urdf'), glob('urdf/*.urdf')),
(os.path.join('share', package_name, 'launch'), glob('launch/*.launch.*')),
],
install_requires=['setuptools'],
zip_safe=True,
maintainer='user',
maintainer_email='user@todo.todo',
description='TODO: Package description',
license='TODO: License declaration',
tests_require=['pytest'],
entry_points={
'console_scripts': [
],
},
)
新旧文件之间真正不同的只有下面这几行:
# imports
import os
from glob import glob
...
# paths to urdf and launch files that must be copied to 'share' folder
(os.path.join('share', package_name, 'urdf'), glob('urdf/*.urdf')),
(os.path.join('share', package_name, 'launch'), glob('launch/*.launch.*')),
按照下面的命令来启动你刚刚创建的文件:
在 Web Shell 1 中执行
cd /workspace
colcon build --packages-select robot_description && source install/setup.bash
ros2 launch robot_description rviz.launch.py
启动该文件后,等待图形化工具打开。你应该会看到下图所示的结果。然后,在显示面板中添加 RobotModel,并将 /robot_description 设为描述主题。接着,把 RVIZ2 中的固定坐标系改为 link_chassis。这样就会把机器人的底盘连杆设为 RVIZ2 模型可视化的参考坐标系。把这个配置保存在你的工作区中,这样下次启动 RVIZ2 时,机器人模型就会被正确显示。
将当前的 RVIZ2 配置保存为 config.rviz,并放到你的 ROS2 robot_description 功能包中新建的 rviz 目录里。

把 rviz 文件夹添加到 setup.py 中,这样下次编译时就能检测到 config.rviz。
此时你的 setup.py 文件应该包含下面这三行:
(os.path.join('share', package_name, 'urdf'), glob('urdf/*.urdf')),
(os.path.join('share', package_name, 'rviz'), glob('rviz/*.rviz')),
(os.path.join('share', package_name, 'launch'), glob('launch/*.launch.*')),
最后,把 config.rviz 文件作为参数传给 launch 文件中的 RVIZ 节点。
# Load RViz Configuration File #
rviz_config_file = "config.rviz"
rviz_config_path = os.path.join(package_directory, "rviz", rviz_config_file)
print("RViz Config Loaded !")
# Rviz2 Launch Configuration (RViz)#
rviz_node = Node(
package='rviz2',
executable='rviz2',
name='rviz2_node',
output='screen',
emulate_tty=True,
parameters=[{'use_sim_time': True}],
arguments=['-d', rviz_config_path],
)
现在你的 launch 文件应该如下所示:
rviz.launch.py
import os
from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch.substitutions import Command
from launch_ros.actions import Node
# ROS2 Launch System will look for this function definition #
def generate_launch_description():
# Get Package Description and Directory #
package_description = "robot_description"
package_directory = get_package_share_directory(package_description)
# Load URDF File #
urdf_file = 'robot.urdf'
robot_desc_path = os.path.join(package_directory, "urdf", urdf_file)
print("URDF Loaded !")
# Robot State Publisher (RSP) #
robot_state_publisher_node = Node(
package='robot_state_publisher',
executable='robot_state_publisher',
name='robot_state_publisher_node',
output="screen",
emulate_tty=True,
parameters=[{'use_sim_time': True,
'robot_description': Command(['xacro ', robot_desc_path])}]
)
# Load RViz Configuration File #
rviz_config_file = "config.rviz"
rviz_config_path = os.path.join(package_directory, "rviz", rviz_config_file)
print("RViz Config Loaded !")
# Rviz2 Launch Configuration (RViz)#
rviz_node = Node(
package='rviz2',
executable='rviz2',
name='rviz2_node',
output='screen',
emulate_tty=True,
parameters=[{'use_sim_time': True}],
arguments=['-d', rviz_config_path],
)
# Create and Return the Launch Description Object #
return LaunchDescription(
[
robot_state_publisher_node,
rviz_node,
]
)
