ROS系统基本功能的使用详解(基本指令/节点/服务/启动文件/动态参数)
一、创建工作空间
1. 新建文件夹
新建一个catkin_ws
的文件夹,并在里面创建src
子目录。
1 | mkdir -p ~/dev/catkin_ws/src |
2. 初始化工作空间
在刚创建的src子目录中,使用如下命令创建工作空间,但此时工作空间中还没有任何功能包,只有CMakeLists.txt。
1 | catkin_init_workspace |
3. 编译工作空间
回到工作空间的顶层目录catkin_ws
文件夹中,使用catkin_make
命令执行编译。编译完成后使用ll
指令可以看到生成了build
和devel
两个文件夹。
1 | cd .. |
4. 完成配置
重新加载setup.bash
文件,完成工作空间创建的最后一步配置
1 | source devel/setup.bash |
其实如果你在~/.bashrc
中加入了此命令行,就可以通过重启终端得到同样的效果,添加命令如下,其中noetic
是我的ros系统的版本号,如果你的版本不同,务必更改。
1 | echo "source /opt/ros/noetic/setup.bash" >> ~/.bashrc |
二、创建与编译ROS功能包
1. 创建功能包
功能包可以通过手动方式创建,但为了方便,通常会使用catkin_create_pkg
命令创建功能包,此命令的格式如下
1 | catkin_create_pkg [package_name] [depend1] [depend2] [depend3] |
其中的depend依赖项包括:
std_msgs
:包含常见的消息类型,表示基本数据类型和其他基本的消息构造。roscpp
:使用C++编写ROS的各种功能。
1 | 例: |
2. 编译功能包
回到catkin_ws
文件夹下执行编译操作,如果没有报错,则说明功能包编译成功。
1 | cd .. |
三、ROS的基本命令
3.1 节点
1. rosnode指令
rosnode工具可以打印ROS节点的相关信息,具体命令如下:
rosnode指令 | 作用 | |
---|---|---|
rosnode ping NODE |
测试节点的连通性 | |
rosnode list |
列出活动节点 | |
rosnode info NODE |
输出此节点的信息 | |
rosnode machine |
打印运行在特定计算机中的节点 | |
rosnode kill NODE |
结束节点进程 | |
rosnode cleanup |
将无法访问的节点的注册信息清除 |
2. 运行节点
首先使用roscore
指令启动ros程序,然后再打开一个新的终端窗口执行接下来的操作。
我们可以使用rosrun
指令运行一个节点
1 | 例: |
节点成功运行后再次使用rosnode list
可以看到正在运行的节点,使用rosnode info /turtlesim
可以查看此节点的详细信息,包括发布(Publications)、订阅(Subscriptions)以及节点具有的服务(Services)等。
3.2 主题
1. rostopic指令
节点可以通过发布主题和订阅主题实现数据的传输,通过主题的消息传输不需要节点直接连接,一个主题可以有多个订阅者和多个发布者。要实现主题与节点之间的交互,可以使用rostopic指令。
rostopic指令 | 作用 |
---|---|
rostopic bw TOPIC |
显示主题所用的带宽 |
rostopic echo TOPIC |
将主题的消息输出到屏幕 |
rostopic find TOPIC |
查找主题 |
rostopic hz TOPIC |
显示主题发布频率 |
rostopic info TOPIC |
输出主题详细信息 |
rostopic list TOPIC |
列出活动主题 |
rostopic pubs TOPIC |
将数据发布到主题 |
rostopic type TOPIC |
输出主题的类型 |
2. 发布主题
可以通过rostopic list
列出当前节点的主题。通过echo参数可以打印节点发出的消息,如:rostopic echo /turtle1/cmd_vel
。
此外,我们也可以直接通过rostopic pub
发布主题,如下:
1 | 例: |
3.3 服务
1. rosservice指令
服务是节点之间相互通信的另一种方法,服务允许节点发送请求和接受响应。可以使用rosservice指令操作服务。
roservice args /service
:输出服务参数rosservice call /service
:根据命令行参数调用服务rosservice find msgtype
:根据服务类型查询服务rosservice info /service
:输出服务信息rosservice list
:列出活动服务清单rosservice type /service
:输出服务类型rosservice uri /service
:输出ROSRPC URI服务
2. 服务的使用
使用rosservice list
可以列出所有的服务,使用rosservice call [service] [args]
可以调用某个服务,例如rosservice call /clear
可以清除海龟图上的线条。
此外,使用rossrv show turtlesim/Spawn
可以查看/spawn服务的详细参数。
通过这些参数就可以调用/spawn服务创建第二只海龟。
1 | rosservice call /spawn 3 3 0.5 "new_turtle" |
3.4 参数服务器
1. rosparam指令
参数服务器存储了所有节点都可以访问的共享数据,可以通过rosparam指令管理参数服务器。
rosparam指令 | 作用 |
---|---|
rosparam set parameter value |
设置参数值 |
rosparam get parameter |
获取参数值 |
rosparam load file |
从文件加载参数 |
rosparam dump file |
将参数保存至文件 |
rosparam delete parameter |
删除参数 |
rosparam list |
列出所有参数名 |
2. 使用参数服务器
以小海龟程序为例,通过rosparam list列出参数列表,可以看到背景background是turtlesim节点的参数,因此我们可以通过get指令获取参数值。
1 | rosparam list |
四、节点的创建与运行
这一部分会以一个具体实验为例,通过创建一个talker和一个listener并实现两者之间的信息交流,进而介绍创建节点的方法。
4.1 创建源文件
首先进入工作空间~/dev/catkin_ws
文件夹中的功能包test_package/src/
文件夹中,在这里创建两个cpp文件,分别作为消息的发送方和接收方。在这里我讲两个源文件分别命名talker.cpp
和listener.cpp
。
1 | //talker.cpp |
1 | //listener.cpp |
4.2 修改CMakeLists.txt
编辑catkin_ws/src/test_package/
中的CMakeLists.txt,在最后加入如下的内容。
1 | #include_directories( |
4.3 编译节点
回到工作空间根目录进行编译:
1 | cd ~/dev/catkin_ws |
如果出现The dependency target does not exist.
的错误,将CMakeLists.txt开头的cmake版本改为2.8.3即可。
编译完成后需要设置环境变量
1 | echo "source ~/ros/tr3_6/devel/setup.bash" >> ~/.bashrc |
4.4 运行节点
然后开始运行节点,首先运行roscore
1 | roscore |
然后再打开两个窗口分别运行
1 | rosrun test_package example1_a |
可以看到消息的接受和发送。
五、服务的创建与使用
本节将创建两个节点,分别作为服务器和客户端,通过服务的调用实现两个节点的数据传输,并实现数字求和的功能。
5.1 创建msg文件
使用服务之前,首先需要创建msg和srv文件,它们用于说明传输的数据类型和数据值。
1. 首先创建msg文件
在test_package
功能包下创建msg
文件夹,并在msg
文件夹中创建一个新的文件test_msg.msg
。在文件中输入以下内容:
1 | int32 num1 |
2. 编辑package.xml文件
在package.xml
文件中找到下面两行,取消这两行的注释<!-- -->
1 | <!-- <build_depend>message_generation</build_depend> --> |
1 | <build_depend>message_generation</build_depend> |
3. 编辑CMakeLists.txt文件
打开功能包目录下的CMakeLists.txt
文件。
找到find_package()
,在其中加入message_generation
如下:
1 | find_package(catkin REQUIRED COMPONENTS |
找到如下的两段,取消注释,并将刚才创建的test_message.msg
消息名称加入其中
1 | ## Generate messages in the 'msg' folder |
1 | ## Generate added messages and services with any dependencies listed here |
4. 编译测试
进行完以上的步骤后,使用下面的命令进行编译:
1 | cd ~/dev/catkin_ws/ |
编译完成后,要检查刚才创建的msg文件是否成功编译,使用rosmsg show
指令:
1 | rosmsg show test_package/test_msg |
如果输出内容与test_msg.msg
文件内的内容一致,说明编译正确。
5.2 创建srv文件
1. 创建srv文件
在test_package
功能包下创建srv
文件夹,并在srv
文件夹中创建一个新的文件test_srv.srv
。在文件中输入以下内容:
1 | int32 num1 |
2. 编辑package.xml文件
在创建msg文件时已经完成了package.xml文件的编辑,这里不需要额外的修改。
3. 编辑CMakeLists.txt
找到catkin_package
,将其注释取消,并加入正确的数据如下:
1 | catkin_package( |
取消add_service_files
的注释,并添加刚创建的服务文件的名字。
1 | ## Generate services in the 'srv' folder |
4. 编译测试
完成上面的文件创建和修改后,使用下面的命令进行编译:
1 | cd ~/dev/catkin_ws |
编译完成后,要检测服务文件编译是否正确,可以使用rossrv show
指令:
1 | rossrv show test_package/test_srv.srv |
如果打印内容与test_srv.srv
文件内的内容一致,说明编译正确。
5.3 创建.cpp源文件
1. 创建源文件
在功能包文件夹中的src目录下catkin_ws/test_package/src
,创建两个.cpp
文件,分别为server.cpp
和client.cpp
,分别作为服务器和客户端。
1 |
|
1 |
|
2. 编辑CMakeLists.txt
1 | add_executable(server src/server.cpp) |
5.4 测试程序
回到catkin_ws
工作空间中,进行编译。
1 | cd ~/dev/catkin_ws |
编译完成后,先打开一个终端,运行roscore
,然后再打开两个新终端窗口,分别运行如下代码
1 | rosrun test_package server |
1 | rosrun test_package client 6 4 2 |
可以看到服务端和客户端实现了消息的通信,完成了三个数字的求和计算。
六、启动文件的配置
在前面,我们已经实现了节点的创建和使用,但是每个节点都需要打开不同的命令行窗口执行,如果节点数目更多,那么启动节点将会是一件非常麻烦的事情。
通过启动文件我们可以在命令行窗口实现启动多个节点,只需要运行后缀名为.launch
的文件即可启动多个节点。
6.1 创建.launch文件
首先在功能包内创建一个名为launch
的文件夹,并在其中创建test.launch
文件。
1 | roscd test_package |
在test.launch
文件内输入如下内容:
1 |
|
6.2 启动节点
上面编写的启动文件可以启动前文实验的talker
和listener
两个节点,启动命令如下:
1 | roslaunch test_package test.launch |
系统会输出以下信息,说明启动成功。
使用rosnode list
可以列出活动的节点,可以看到我们已经成功启动了talker
和listener
两个节点。
如果想看到两个节点传递的信息,可以使用rqt_console
七、动态参数的使用
一般情况下,我们编写一个节点时,只能以数据初始化节点内的变量,如果我们想要改变这些变量值,可以使用主题,服务或参数服务器,但这种方式无法在线动态更新,如果listener不主动查询,我们无法知道参数是否更新。有时我们需要在线动态更新参数,这时就需要使用动态参数。
7.1 创建配置文件
首先在功能包内新建一个名为cfg
的文件夹,并在其内创建一个test.cfg
文件。
1 | roscd test_package |
在test.cfg
内添加如下代码:
1 | # 初始化ROS并导入参数生成器 |
由于test.cfg
是由ROS执行的可执行文件,因此我们需要改变文件权限:
1 | chmod a+x test.cfg |
7.2 修改CMakeLists.txt添加配置文件的编译
打开CMakeLists.txt
,找到find_package
,在最后加入dynamic_reconfigure
如下:
1 | find_package(catkin REQUIRED COMPONENTS |
找到generate_dynamic_reconfigure_options
,取消注释,并将内部的配置文件改为刚创建的配置文件。
1 | ## Generate dynamic reconfigure parameters in the 'cfg' folder |
7.3 创建节点
接下来需要创建一个具有动态配置支持的新节点。
在src
文件夹下创建一个新文件如下:
1 | roscd test_package |
在文件中写入如下代码:
1 |
|
7.4 修改CMakeLists.txt添加节点的编译
1 | add_executable(dynamic_param src/dynamic_param.cpp) |
7.5 运行配置
打开三个终端命令行窗口,分别运行如下的命令:
1 | roscore |
执行完成后,会看到一个rqt_reconfigure
窗口,在这个窗口中就可以动态的配置节点的参数,并且在调整参数时,可以看到命令行打印参数的改变。