ros2笔记
5.1 只编译一个包
colcon build --packages-select YOUR_PKG_NAME
5.2 不编译测试单元
colcon build --packages-select YOUR_PKG_NAME --cmake-args -DBUILD_TESTING=0
5.3 运行编译的包的测试
colcon test
5.4 允许通过更改src下的部分文件来改变install(重要)
每次调整 python 脚本时都不必重新build了
colcon build --symlink-install
所以王家村建立指令像下面这样,只不过依赖变成了rclcpp
ros2 pkg create village_wang --build-type ament_cmake --dependencies rclcpp
ros2 pkg create village_wang --build-type ament_python --dependencies rclpy
ros2 run demo_nodes_py listener
3.2.1 ros2 topic list 返回系统中当前活动的所有主题的列表
命令
ros2 topic list
结果
3.2.2 ros2 topic list -t 增加消息类型
命令
ros2 topic list -t
结果
3.2.3 ros2 topic echo 打印实时话题内容
命令
ros2 topic echo /chatter
结果
3.2,4 ros2 topic info 查看主题信息
命令
ros2 topic info /chatter
结果
3.2.5 ros2 interface show 查看消息类型
上面一个指令告诉大家这个消息是std_msgs/msg/String,那String里面有什么呢?不妨来试一试。
命令
ros2 interface show std_msgs/msg/String
结果
3.2.6 ros2 topic pub arg 手动发布命令
关闭发布者,我们受到来发布
命令
ros2 topic pub /chatter std_msgs/msg/String 'data: "123"'
结果
最下面一层string、uint8、uint32
是ROS2中的原始数据类型,原始数据类型有下面几种,ROS2中所有的接口都是由这些原始数据类型组成。
bool
byte
char
float32,float64
int8,uint8
int16,uint16
int32,uint32
int64,uint64
string
3.验证
写好了自定义的消息,我们如何验证呢?
最好的办法肯定是写上一段代码来测试一下,但因为篇幅原因,小鱼把它放在了本章的最后。
所以我们本节可以通过上节课说过的ros2 interface
常用的命令来测试。
source install/setup.bash
ros2 interface package village_interfaces #查看包下所有接口
ros2 interface show village_interfaces/msg/Novel #查看内容
ros2 interface proto village_interfaces/msg/Novel #显示属性
3.1 启动服务端
打开终端,运行下面的命令,这个命令用于运行一个服务节点,这个服务的功能是将两个数字相加,给定a,b两个数,返回sum也就是ab之和。
ros2 run examples_rclpy_minimal_service service
3.2 使用命令查看服务列表
ros2 service list
3.3手动调用服务
再启动一个终端,输入下面的命令(注意a:、b:后的空格)。
ros2 service call /add_two_ints example_interfaces/srv/AddTwoInts "{a: 5,b: 10}"
我们可以看到客户端请求两个数字5+10,服务端返回15。
4.3 查看服务接口类型
ros2 service type /add_two_ints
4.4查找使用某一接口的服务
这个命令看起来和4.3刚好相反。
ros2 service find example_interfaces/srv/AddTwoInts
-----------------------参数
4.1 运行小乌龟模拟器节点和小乌龟控制节点
打开终端
ros2 run turtlesim turtlesim_node
再打开一个终端
ros2 run turtlesim turtle_teleop_key
可以看到下面的蓝蓝的模拟器
4.2 查看节点有哪些参数(设置)
我们可以使用下面的指令来查看所有节点的参数列表,打开一个终端,运行下面的指令
ros2 param list
写代码为什么要做到见名知意?我们看到乌龟模拟器的四个参数,background背景bgr指的是blue、green、red。简而言之就是背景颜色。那这几个参数应该可以控制乌龟模拟器的背景颜色。
最后一个use_sim_time是每个节点都带的,后面小鱼写篇文章稍微讲讲。
如果看不懂,还可以有一个方法详细查看一个参数的信息。
ros2 param describe <node_name> <param_name>
比如:
ros2 param describe /turtlesim background_b
这里就可以详细的看到参数的名字,参数的描述,参数的类型,还有对参数的约束,最大值最小值等。
4.3 查看参数值
参数的组成由名字和值(键值组成),名字可以通过param list
获取,值该使用指令获取呢?
下面这个命令行工具可以帮助我们获取参数的值
ros2 param get /turtlesim background_b
运行一下,你会发现结果是255,蓝色进度条打满,再看看r红色和g绿色。
分别是255,86,69
4.4 设置参数
找到了参数和值,接着我们来改变一下乌龟模拟器的颜色。
打开小鱼精心准备的在线工具:https://fishros.com/tools/pickr
选取一个自己喜欢的颜色,这里小鱼就选绿色,因为乌龟模拟器换成绿色的应该很奇怪。
可以看到当前的这个颜色,r为44,g为156,b为10,接着我们可以使用下面的指令来设置参数的值。
ros2 param set <node_name> <parameter_name> <value>
我们依次修改参数值:
ros2 param set /turtlesim background_r 44
ros2 param set /turtlesim background_g 156
ros2 param set /turtlesim background_b 10
接着你可以看到这样的颜色的乌龟模拟器(绿的令人发慌)
需要留意的是,我们修改的背景数据并没有被存储,只是临时修改。重新启动节点乌龟模拟器依然还是原来的蓝色,不是我们想要的绿色的。
4.5 把参数存起来
把参数存起来其实就相当去把当前的参数值拍一张快照,然后保存下来,后面可以用于恢复参数到当前的数值。
可以使用下面的命令进行操作:
ros2 param dump <node_name>
4.5.1 给乌龟模拟器参数拍照
比如我们要保存乌龟模拟器的节点数据,可以采用下面的指令;
os2 param dump /turtlesim
文件被保存成了yaml格式,用cat指令看一看
cat ./turtlesim.yaml
4.5.2 恢复参数值
我们Ctrl+C
关闭乌龟模拟器,然后再重新运行。
ros2 run turtlesim turtlesim_node
可以看到模拟器又变成了蓝色了,接着通过param的load的方法把参数值恢复成我们之前存储的。
ros2 param load /turtlesim ./turtlesim.yaml
几乎是瞬间,乌龟模拟器又被我们搞绿了
4.5.3 启动节点时加载参数快照
有什么办法一开始就让乌龟模拟器变成绿色?答案有的。
ros2 的run 指令支持下面这种骚操作
。
ros2 run <package_name> <executable_name> --ros-args --params-file <file_name>
关闭我们的乌龟模拟器,使用下面的指令重新运行
ros2 run turtlesim turtlesim_node --ros-args --params-file ./turtlesim.yaml
可以看到一上来就时绿了的模拟器。
roslaunch2
基于 Python 的启动文件
基于 python 的启动文件几乎都遵循相同的结构。
注意,在 Foxy 之前,参数名称、名称空间和可执行文件的前缀:
from launch import LaunchDescription
from launch_ros.actions import Node
def generate_launch_description():
return LaunchDescription([
Node(
name='node_runtime_name',
package='ros2_package_name',
executable='name_of_executable',
parameters=[{'name_of_int_param': 1,
'name_of_str_param': 'value'}],
remappings=[('from', 'to')],
output='screen',
),
# More Nodes!
])
使启动文件成为可执行文件
正常情况下,启动文件的运行方式为:
ros2 launch pkg launch.py
但是,有时你需要一个可执行的启动文件(例如放入一个系统作业)。假设你遵循上面所示的默认模式,则只需添加以下内容:
#!/usr/bin/env python3
import sys
from launch import LaunchService
# define generate_launch_description() as above
if __name__ == '__main__':
desc = generate_launch_description()
service = LaunchService(argv=sys.argv[1:])
service.include_launch_description(desc)
return service.run()
从文件加载参数
有些节点有很多参数,将它们放在 YAML 文件中会更容易:
node_name:
ros__parameters:
some_int_param: 1
some_str_param: "the_value"
要加载此文件,请执行以下操作:
from ament_index_python.packages import get_package_share_directory
# Assuming you have a file called package_name/config/params.yaml
node_params = os.path.join(
get_package_share_directory('package_name'),
'config',
'params.yaml'
)
# Add this to your LaunchDescription
Node(
name='node_runtime_name',
package='ros2_package_name',
executable='name_of_executable',
parameters=[{'another_param': 42.0},
node_params]
)
包括 Python 启动文件
import os
from ament_index_python.packages import get_package_share_directory
from launch.actions import IncludeLaunchDescription
from launch.launch_description_sources import PythonLaunchDescriptionSource
# Assuming you have a file called package_name/launch/my_launch.launch.py
my_launch_file = os.path.join(
get_package_share_directory('package_name'),
'launch',
'my_launch.launch.py'
)
# Add this to your LaunchDescription
IncludeLaunchDescription(
PythonLaunchDescriptionSource([my_launch_file])
),
加载 URDF
大多数机器人需要将其 URDF 加载到 ROBTO_STATE_PUBLISHER 中,也可能需要加载到其他节点中:
import os
from ament_index_python.packages import get_package_share_directory
from launch_ros.actions import Node
# Load the URDF into a parameter
desc_dir = get_package_share_directory('robot_description_pkg')
urdf_path = os.path.join(desc_dir, 'robots', 'my_urdf.urdf')
urdf = open(urdf_path).read()
# Add this to your LaunchDescription
Node(
name='robot_state_publisher',
package='robot_state_publisher',
executable='robot_state_publisher',
parameters=[{'robot_description': urdf}],
)