0 前言
在 ROS2 中,需要频繁的使用到终端,且可能需要同时开启多个窗口,推荐一款较为好用的终端:Terminator
安装命令:sudo apt install terminator
1 launch
启动一个机器人系统时往往需要启动多个节点,同时根据应用场景和机器人的不同,每个节点还会有不同的配置项
- launch文件允许我们同时启动和配置多个包含 ROS2 节点的可执行文件
- 在ROS2可以使用python代码编写launch文件
- ROS2的launch文件有三种格式,python、xml、yaml
- 官方推荐以python方式编写launch文件
下面我将由简到烦逐步教大家写出一个可以用于运行复杂的ROS2系统的launch file
1.1 编写个简单的launch file
mkdir -p ros2_ws/src
cd ros2_ws/src
ros2 pkg create --build-type ament_cmake my_launch
cd my_launch
mkdir launch
cd launch
touch test.launch.py # 主流方式命名为xxx.launch.py或者xxx_launch.py
可以用任何你喜欢的文本编辑器来打开编辑launch file
在test.launch.py
中加入以下代码:
from launch import LaunchDescription
from launch_ros.actions import Node
# 启动描述
def generate_launch_description():
return LaunchDescription([
# 启动node
Node(
package='turtlesim',
executable='turtlesim_node',
name='sim1'
),
# 启动node
Node(
package='turtlesim',
executable='turtlesim_node',
name='sim2'
)
])
Node中一般需要3个属性,package
、executable
和name
,package为包的名称,executable为包内的可执行文件名,name为节点运行时的节点名。
可能还会用到:
-
namespace: 命名空间。使节点名称前增加命名空间前缀,命名空间不同使系统允许两个相同节点名和主题名不冲突。如果没有唯一的命名空间,当topic消息相同时就无法区分是哪个节点的。
-
respawn: 复位。设为‘true’时,节点停止时自动重启。默认为‘false’
-
output: 输出。设为‘screen’时,将节点的输出打印到中终端屏幕。
-
arguments: 节点需要输入的参数。
-
remappings: 重映射,将默认节点属性(如节点名称、主题名称、服务名称等),重映射为其它名称。
1.2 运行launch file
一般对包进行编译后调用,在package.xml中添加依赖:
<exec_depend>ros2launch</exec_depend>
在CMakeListe.txt中添加:
# Install launch files.
install(DIRECTORY
launch
DESTINATION share/${PROJECT_NAME}/
)
# 回到ros2_ws
colcon build
source install/setup.bash
ros2 launch my_launch test.launch.py
运行结果:
打开键盘控制节点,发现小乌龟在两个终端一模一样地移动
如果要区分两个海龟模拟器的话,就得加入命名空间(namespace)属性,将launch file代码改为:
命名空间
from launch import LaunchDescription
from launch_ros.actions import Node
def generate_launch_description():
return LaunchDescription([
Node(
package='turtlesim',
namespace='turtlesim1',
executable='turtlesim_node',
name='sim1'
),
Node(
package='turtlesim',
namespace='turtlesim2',
executable='turtlesim_node',
name='sim2'
)
])
重映射
增加了命名空间后我们再次运行turtle_teleop_key
,操作一下方向按键,发现海龟动不了了。
虽然话题类型都是geometry_msgs/msg/Twist
,但 turtle_teleop_key
发布的话题是/turtle1/cmd_vel
,而两个turtlesim节点订阅的话题是有带命名空间前缀的,所以并不能兼容
这时候使用重映射,给话题重映射个名字,比如把/turtlesim1/turtle1/cmd_vel
重映射为/turtle1/cmd_vel
,改一下launch file:
from launch import LaunchDescription
from launch_ros.actions import Node
def generate_launch_description():
return LaunchDescription([
Node(
package='turtlesim',
namespace='turtlesim1',
executable='turtlesim_node',
name='sim1',
remappings=[
('/turtlesim1/turtle1/cmd_vel', '/turtle1/cmd_vel'),
]
),
Node(
package='turtlesim',
namespace='turtlesim2',
executable='turtlesim_node',
name='sim2'
)
])
在launch file里调用shell命令
launch file提供了可以在文件里直接调用命令的功能
from launch import LaunchDescription
from launch_ros.actions import Node
from launch.actions import ExecuteProcess
def generate_launch_description():
return LaunchDescription([
Node(
package='turtlesim',
namespace='turtlesim1',
executable='turtlesim_node',
name='sim1',
remappings=[
('/turtlesim1/turtle1/cmd_vel', '/turtle1/cmd_vel'),
]
),
Node(
package='turtlesim',
namespace='turtlesim2',
executable='turtlesim_node',
name='sim2'
),
# 在launch file里调用shell命令
ExecuteProcess(
cmd=[[
'ros2 param set ',
'/turtlesim1/sim1 ',
'background_b ',
'0'
]],
shell=True
)
])
首先需要import一个模块:
from launch.actions import ExecuteProcess
给launch file增加接收参数配置的功能
为了使启动更灵活,比如我们想在启动时改变某个参数,而无需每次去修改launch file,就可以使用参数配置的功能
一般需要用到两个模块:launch.substitutions.LaunchConfiguration
和launch.actions.DeclareLaunchArgument
LaunchConfiguration
用来增加一个启动文件的传递参数,而DeclareLaunchArgument
用于定义可以从上述启动文件或控制台传递的启动参数
from launch import LaunchDescription
from launch_ros.actions import Node
from launch.substitutions import LaunchConfiguration
from launch.actions import ExecuteProcess, DeclareLaunchArgument
def generate_launch_description():
background_blue_arg = LaunchConfiguration('background_blue_arg')
background_blue_launch_arg = DeclareLaunchArgument(
'background_blue_arg',
default_value='255',
description='Configure the blue value of turtlesim1 background color.'
)
return LaunchDescription([
background_blue_launch_arg,
Node(
package='turtlesim',
namespace='turtlesim1',
executable='turtlesim_node',
name='sim1',
remappings=[
('/turtlesim1/turtle1/cmd_vel', '/turtle1/cmd_vel'),
]
),
Node(
package='turtlesim',
namespace='turtlesim2',
executable='turtlesim_node',
name='sim2'
),
ExecuteProcess(
cmd=[[
'ros2 param set ',
'/turtlesim1/sim1 ',
'background_b ',
background_blue_arg
]],
shell=True
)
])
定义了background_blue_arg
,默认值为255
可以用以下命令来查看launch file提供了哪些参数及其默认值:
ros2 launch my_launch test.launch.py --show-args
现在可以将所需的参数传递给启动文件,例如调用以下命令将背景色蓝色值设置为180:
ros2 launch my_launch test.launch.py background_blue_arg:=180
嵌套复用功能IncludeLaunchDescription
launch系统为我们提供给了嵌套复用的功能,直接可以launch file中包含其它launch file,这就使得launch file更灵活,更方便。
另外编写一个launch文件,简单命名为test1.launch.py,复用上面的launch文件
import os
from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch.actions import ExecuteProcess, IncludeLaunchDescription
from launch.launch_description_sources import PythonLaunchDescriptionSource
def generate_launch_description():
two_turtle_sim = IncludeLaunchDescription(
PythonLaunchDescriptionSource([os.path.join(
get_package_share_directory('my_launch'), 'launch'),
'/test.launch.py']),
launch_arguments={'background_blue_arg': '180'}.items()
)
cmd_execute = ExecuteProcess(
cmd=[[
'ros2 topic pub -r 1 /turtle1/cmd_vel geometry_msgs/msg/Twist "{linear: {x: 2.0, y: 0.0, z: 0.0}, angular: {x: 0.0, y: 0.0, z: -1.8}}"'
]],
shell=True
)
return LaunchDescription([
two_turtle_sim,
cmd_execute
])
描述了为大型项目编写启动文件的一些技巧。重点是如何构建启动文件,以便在不同情况下尽可能多地重用它们。可以看到ROS2使用python实现的launch非常实用且灵活。
2 ros2 bag 录包常用命令
记录话题的数据
- 实车调试有时不可避免遇到一些问题,有时候需要录包来确定是定位odom的问题,还是雷达数据其它问题
- 这个工具在我们做一个真实机器人的时候非常有用,比如我们可以录制一段机器人发生问题的话题数据,录制完成后可以多次发布出来进行测试和实验,也可以将话题数据分享给别人用于验证算法等
ros2 bag record /topic_name # 记录topic_name话题的数据
ros2 bag record /topic_name1 /topic_name2 # 记录多个话题的数据
ros2 bag record -a # 记录所有话题
ros2 bag record -o file-name topic-name # -o name 自定义输出文件的名字
ros2 bag play xxx.db3 # 播放话题数据
ros2 bag play rosbag2_2021_10_03-15_31_41_0.db3 -r 10 # 十倍速播放话题
ros2 bag play rosbag2_2021_10_03-15_31_41_0.db3 -l # 循环播放
ros2 bag play rosbag2_2021_10_03-15_31_41_0.db3 --topics /chatter # 播放单个话题
3 RQT工具
RQT是一个GUI框架,通过插件的方式实现了各种各样的界面工具
安装:sudo apt install ros-humble-rqt
启动:rqt
3.1 rqt_tf_tree
安装rqt_tf_tree
sudo apt install ros-humble-rqt-tf-tree
安装完成后报错:
qt_gui_main() found no plugin matching "rqt_tf_tree.tf_tree.RosTfTree"
try passing the option "--force-discover"
[ros2run]: Process exited with failure 1
输入:rm ~/.config/ros.org/rqt_gui.ini
安装完成后,再次打开rqt工具,Plugins->Visualization->TF Tree
利用rqt查看tf树
3.2 rqt_graph
可视化节点,节点之间的联系
命令行打开:rqt_graph
或者先打开rqt,Plugins->Introspection->Node Graph
3.3 rqt_plot
rqt_plot可以直接查看topic的数据曲线,非常方便
录包:ros2 bag record -a
打开rqt_plot
只需要在Toptic一栏输入我们想要监测的话题变量即可
注意输入Topic时中间都用/符号隔开。输入odom、imu话题,enter就会自动把所以变量xyz自动加入
缺陷:不能保存配置文件,功能比较单一,使用体验不如PlotJuggler
3.4 PlotJuggler
PlotJuggler是rqtplot和rqtbag更好的替代品,它提供了更友好的用户界面
安装:sudo apt-get install ros-humble-plotjuggler
安装插件(不安装的话应该打不开.bag文件)
sudo apt-get install ros-humble-plotjuggler-msgs ros-humble-plotjuggler-ros
特征:
- Multiplot(多曲线):将多条曲线添加到绘图中。在行、列、选项卡和/或单独的窗口中排列绘图
- Zoom(缩放):轻松缩放绘图。可以锁定所有绘图的X轴
- Save/Load layouts(保存/加载布局):组织布局后,可以将其保存到文件中以供以后重用
- Complete Undo/Redo(完全撤消/重做):CTRL-Z按您的预期操作
- DataLoad plugins(数据加载插件):轻松加载CSV或rosbags
- DataStreaming plugins(数据流插件):订阅一个或多个ros主题并实时绘制它们的数据
- RosPublisher plugin(RosPublisher 插件):使用交互式跟踪器重新发布原始ROS消息
相关操作如下:
4 Rviz2
机器人开发中常用的数据可视化工具RVIZ2
数据:各种调试机器人时常用的数据,比如:图像数据、三维点云数据、地图数据、TF数据,机器人模型数据等等
可视化:直观的看到数据
不同数据的可视化:已有数据的情况下,把数据显示出来,后面要讲的gazebo仿真软件是通过模拟真实环境产生数据,两者用途并不一样。
启动:rviz2
有一个比较坑的地方就是用相同的网络,发布一样的话题,发现能在不同的主机上运行
打开左下角Add,常用的rviz插件
5 Gazebo
模拟真实环境生产数据的
Gazebo 是一个独立的应用程序,可以独立于 ROS 或 ROS 2 使用。Gazebo可以根据我们所提供的机器人模型文件,传感器配置参数,给机器人创造一个虚拟的环境,虚拟的电机和虚拟的传感器,并通过ROS/ROS2的相关功能包把传感器数据电机数据等发送出来(生产数据)
Gazebo与ROS 版本的集成是通过一组叫做gazebo_ros_pkgs的包 完成的,gazebo_ros_pkgs将Gazebo和ROS2连接起来
安装:sudo apt install gazebo
Gazebo相关全部安装:sudo apt install ros-humble-gazebo-*
以上就是ROS2常用工具的基本介绍