1.建立工作空间
cd /home/fishbot_ws/src
ros2 pkg create fishbot_description --build-type ament_python
2.创建并编写URDF文件
cd /home/fishbot_ws/src/fishbot_description
mkdir urdf
cd urdf
touch fishbot_base.urdf
完成后的src中的文件结构
├── fishbot_description
│ ├── __init__.py
├── package.xml
├── setup.cfg
├── setup.py
└── urdf
└── fishbot_base.urdf
编辑fishbot_base.urdf
<?xml version="1.0"?>
<robot name="fishbot">
<!-- base link -->
<link name="base_link">
<visual>
<origin xyz="0 0 0.0" rpy="0 0 0"/>
<geometry>
<cylinder length="0.12" radius="0.10"/>
</geometry>
</visual>
</link>
<!-- laser link -->
<link name="laser_link">
<visual>
<origin xyz="0 0 0" rpy="0 0 0"/>
<geometry>
<cylinder length="0.02" radius="0.02"/>
</geometry>
<material name="black">
<color rgba="0.0 0.0 0.0 0.8" />
</material>
</visual>
</link>
<!-- laser joint -->
<joint name="laser_joint" type="fixed">
<parent link="base_link" />
<child link="laser_link" />
<origin xyz="0 0 0.075" />
</joint>
</robot>
3.创建并编写launch文件
cd /home/fishbot_ws/src/fishbot_description
mkdir launch
cd launch
touch display_rviz2.launch.py
完成后的目录结构
├── fishbot_description
│ ├── __init__.py
├── launch
│ └── display_rviz2.launch.py
├── package.xml
├── setup.cfg
├── setup.py
└── urdf
└── fishbot_base.urdf
编辑launch文件
import os
from launch import LaunchDescription
from launch.substitutions import LaunchConfiguration
from launch_ros.actions import Node
from launch_ros.substitutions import FindPackageShare
def generate_launch_description():
package_name = 'fishbot_description'
urdf_name = "fishbot_base.urdf"
ld = LaunchDescription()
pkg_share = FindPackageShare(package=package_name).find(package_name)
urdf_model_path = os.path.join(pkg_share, f'urdf/{urdf_name}')
robot_state_publisher_node = Node(
package='robot_state_publisher',
executable='robot_state_publisher',
arguments=[urdf_model_path]
)
joint_state_publisher_node = Node(
package='joint_state_publisher_gui',
executable='joint_state_publisher_gui',
name='joint_state_publisher_gui',
arguments=[urdf_model_path]
)
rviz2_node = Node(
package='rviz2',
executable='rviz2',
name='rviz2',
output='screen',
)
ld.add_action(robot_state_publisher_node)
ld.add_action(joint_state_publisher_node)
ld.add_action(rviz2_node)
return ld
generate_launch_description()
函数是入口点,用于生成LaunchDescription
对象,描述了启动的节点及其参数。FindPackageShare
类用于查找指定包的共享目录,以便获取该包中的资源文件。在这里,它用于获取机器人描述包(fishbot_description
)的共享目录路径。
-LaunchDescription
对象用于存储要启动的节点及其参数。
其中涉及三个节点:
joint_state_publisher_gui
负责发布机器人关节数据信息,通过joint_states
话题发布robot_state_publisher_node
负责发布机器人模型信息robot_description
,并将joint_states
数据转换tf信息发布- r
viz2_node
负责显示机器人的信息
最终,通过调用 ld.add_action() 将这些节点添加到 LaunchDescription
对象中,并将其返回,以便由 ROS 2 的启动系统加载并执行。
joint_state_publisher_gui,还有一个兄弟叫做joint_state_publisher
两者区别在于joint_state_publisher_gui运行起来会跳出一个界面,通过界面可以操作URDF中能动的关节
4.修改setup.py
from glob import glob
import os
完整setup.py
from setuptools import setup
from glob import glob
import os
package_name = 'fishbot_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, 'launch'), glob('launch/*.launch.py')),
(os.path.join('share', package_name, 'urdf'), glob('urdf/**')),
],
install_requires=['setuptools'],
zip_safe=True,
maintainer='root',
maintainer_email='root@todo.todo',
description='TODO: Package description',
license='TODO: License declaration',
tests_require=['pytest'],
entry_points={
'console_scripts': [
],
},
)
5.编译测试
回到工作空间(fishbot_ws),编译
cd /home/fishbot_ws
colcon build
运行测试
source install/setup.bash
ros2 launch fishbot_description display_rviz2.launch.py