官网ROS教程: https://wiki.ros.org/cn/ROS/Tutorials
中国大学MOOC---《机器人操作系统入门》课程讲义 https://sychaichangkun.gitbooks.io/ros-tutorial-icourse163/content/
autolabor: http://www.autolabor.com.cn/book/ROSTutorials/
视频教程: https://www.bilibili.com/video/BV1zt411G7Vn/?p=1
使用printenv | grep ROS
查看环境变量,必须有ROS_ROOT、ROS_PACKAGE_PATH。如下:
bash展开代码# printenv | grep ROS
ROS_VERSION=1
ROS_PYTHON_VERSION=3
ROS_PACKAGE_PATH=/opt/ros/noetic/share
ROSLISP_PACKAGE_DIRECTORIES=
ROS_ETC_DIR=/opt/ros/noetic/etc/ros
ROS_MASTER_URI=http://localhost:11311
ROS_ROOT=/opt/ros/noetic/share/ros
ROS_DISTRO=noetic
开始创建和构建一个catkin工作空间:
bash展开代码mkdir -p catkin_ws/src
cd catkin_ws
catkin_make
如下图,catkin_ws下面就有对应文件了。整个catkin_ws文件夹就作为一个工程,包含了ros的必备文件。
这是通过 catkin_make
或 catkin build
编译ROS工作空间后自动生成的目录。
build
:存放编译过程中的中间文件(如CMake缓存)。devel
:包含编译生成的最终文件(如可执行程序、库、环境配置脚本)。文件位置:在 devel
文件夹内,通常有多个 setup.*sh
文件(如 setup.bash
、setup.zsh
),对应不同的Shell类型。
功能:
执行 source devel/setup.bash
会:
ROS_PACKAGE_PATH
环境变量中。rosrun
、roslaunch
)识别。命令:echo $ROS_PACKAGE_PATH
预期输出:
应包含你的工作空间路径(如 /home/<username>/catkin_ws/src
)和系统ROS路径(如 /opt/ros/<distro>/share
)。
:
分隔,左侧路径优先级更高。bash展开代码source devel/setup.bash # 根据你的Shell选择对应的文件(bash/zsh)
bash展开代码echo $ROS_PACKAGE_PATH
确认输出中包含你的工作空间路径(如 /home/yourname/catkin_ws/src
)。
使用rospack查看包。
bash展开代码rospack find roscpp
使用roscd切到包路径。
bash展开代码roscd [locationname[/subdir]]
在ws空间里,src下面可以有多个包:
我使用 catkin_create_pkg beginner_tutorials std_msgs rospy roscpp 在src里创建了一个软件包。
bash展开代码root@550f2bb73c66:~/xiedong/learning-ros/catkin_ws# cd src/
root@550f2bb73c66:~/xiedong/learning-ros/catkin_ws/src# catkin_create_pkg beginner_tutorials std_msgs rospy roscpp
Created file beginner_tutorials/package.xml
Created file beginner_tutorials/CMakeLists.txt
Created folder beginner_tutorials/include/beginner_tutorials
Created folder beginner_tutorials/src
Successfully created files in /root/xiedong/learning-ros/catkin_ws/src/beginner_tutorials. Please adjust the values in package.xml.
可以看到beginner_tutorials下面有了软件包该有的文件:
bash展开代码root@550f2bb73c66:~/xiedong/learning-ros/catkin_ws/src# tree -L 2
.
|-- CMakeLists.txt -> /opt/ros/noetic/share/catkin/cmake/toplevel.cmake
`-- beginner_tutorials
|-- CMakeLists.txt
|-- include
|-- package.xml
`-- src
3 directories, 3 files
再回到ws里执行 catkin_make ,可以看到识别到了软件包:
要将这个工作空间添加到ROS环境中,你需要source一下生成的配置文件:
bash展开代码. devel/setup.bash
使用rospack命令工具来查看这些一级依赖包。
bash展开代码root@550f2bb73c66:~/xiedong/learning-ros/catkin_ws# rospack depends1 beginner_tutorials
roscpp
rospy
std_msgs
package.xml 里面有这个软件包的很多资料信息》》
bash展开代码root@550f2bb73c66:~/xiedong/learning-ros/catkin_ws/src/beginner_tutorials# cat package.xml
这是一个ROS包的package.xml
文件,它遵循ROS的package.xml格式版本2。下面是对这个文件的详细解析:
xml展开代码<name>beginner_tutorials</name>
<version>0.0.0</version>
<description>The beginner_tutorials package</description>
beginner_tutorials
0.0.0
(初始版本)xml展开代码<maintainer email="root@todo.todo">root</maintainer>
xml展开代码<license>TODO</license>
这是最重要的部分,定义了包的各种依赖:
xml展开代码<buildtool_depend>catkin</buildtool_depend>
xml展开代码<build_depend>roscpp</build_depend>
<build_depend>rospy</build_depend>
<build_depend>std_msgs</build_depend>
xml展开代码<build_export_depend>roscpp</build_export_depend>
<build_export_depend>rospy</build_export_depend>
<build_export_depend>std_msgs</build_export_depend>
xml展开代码<exec_depend>roscpp</exec_depend>
<exec_depend>rospy</exec_depend>
<exec_depend>std_msgs</exec_depend>
catkin_make 等价于cmake和make合体。
在ws下面执行允许 catkin_make 就是构建ws里所有软件包和ws。上一节演示过了。
ROS客户端库可以让用不同编程语言编写的节点进行相互通信:
rospy = Python客户端库
roscpp = C++客户端库
roscore是你在运行所有ROS程序前首先要运行的命令。
roscore 启动了一个节点:
这段命令显示了当前 ROS 系统中的节点信息:执行 rosnode list 后只看到 /rosout 这一个核心日志节点,进一步用 rosnode info /rosout 查看该节点详情,可见它负责聚合(/rosout_agg)和记录所有 ROS 节点的日志消息(类型为 rosgraph_msgs/Log),同时提供日志级别设置服务(如 /rosout/set_logger_level),该节点运行在进程 ID 13247 上并通过 HTTP 端口 45809 通信,当前系统中除了这个默认的核心日志节点外尚未运行其他功能节点。
bash展开代码root@550f2bb73c66:/# rosnode list
/rosout
root@550f2bb73c66:/# rosnode info /rosout
--------------------------------------------------------------------------------
Node [/rosout]
Publications:
* /rosout_agg [rosgraph_msgs/Log]
Subscriptions:
* /rosout [unknown type]
Services:
* /rosout/get_loggers
* /rosout/set_logger_level
contacting node http://550f2bb73c66:45809/ ...
Pid: 13247
rosrun可以让你用包名直接运行软件包内的节点(而不需要知道包的路径)。
安装turtlesim包:
bash展开代码apt-get install ros-noetic-turtlesim -y
这样可以看到可视化界面:
bash展开代码rosrun turtlesim turtlesim_node
roscore 运行着别动。
rosrun turtlesim turtlesim_node 运行着别动。
开新的终端,运行这个:
bash展开代码rosrun turtlesim turtle_teleop_key
按键盘的方向键控制乌龟:
turtlesim_node节点和turtle_teleop_key节点之间是通过一个ROS话题来相互通信的。turtle_teleop_key在话题上发布键盘按下的消息,turtlesim则订阅该话题以接收消息。让我们使用rqt_graph来显示当前运行的节点和话题。
注意:如果你使用的是ROS electric或早期版本,那么rqt是不可用的,请使用rxgraph代替。
如果你发现没有安装,请:
bash展开代码$ sudo apt-get install ros-<distro>-rqt $ sudo apt-get install ros-<distro>-rqt-common-plugins
在新的终端执行:
bash展开代码$ rosrun rqt_graph rqt_graph
如果把鼠标放在/turtle1/command_velocity上方,相应的ROS节点(这里是蓝色和绿色)和话题(这里是红色)就会高亮显示。可以看到,turtlesim_node和turtle_teleop_key节点正通过一个名为/turtle1/command_velocity的话题来相互通信。
bash展开代码root@euler-MS-7D30:/# rostopic --help
rostopic is a command-line tool for printing information about ROS Topics.
Commands:
rostopic bw display bandwidth used by topic
rostopic delay display delay of topic from timestamp in header
rostopic echo print messages to screen
rostopic find find topics by type
rostopic hz display publishing rate of topic
rostopic info print information about active topic
rostopic list list active topics
rostopic pub publish data to topic
rostopic type print topic or field type
Type rostopic <command> -h for more detailed usage, e.g. 'rostopic echo -h'
bash展开代码root@euler-MS-7D30:/# rostopic list
/rosout
/rosout_agg
/statistics
/turtle1/cmd_vel
/turtle1/color_sensor
/turtle1/pose
bash展开代码rostopic echo /turtle1/cmd_vel
查看消息类型:
bash展开代码root@euler-MS-7D30:/# rostopic type /turtle1/cmd_vel
geometry_msgs/Twist
使用rosmsg查看消息的详细信息:
bash展开代码root@euler-MS-7D30:/# rosmsg show geometry_msgs/Twist
geometry_msgs/Vector3 linear
float64 x
float64 y
float64 z
geometry_msgs/Vector3 angular
float64 x
float64 y
float64 z
手动发布消息前的乌龟:
手动发布消息:
bash展开代码rostopic pub -1 /turtle1/cmd_vel geometry_msgs/Twist -- '[2.0, 0.0, 0.0]' '[0.0, 0.0, 1.8]'
可见乌龟移动,消息是成功发布了的:
手动发消息的时候也可以看这个更新,左上角刷新:
rostopic hz 查看发布速率。
服务(Services)是节点之间通讯的另一种方式。服务允许节点发送一个请求(request)并获得一个响应(response)。
bash展开代码rosservice list #输出活跃服务的信息
rosservice call #用给定的参数调用服务
rosservice type #输出服务的类型
rosservice find #按服务的类型查找服务
rosservice uri #输出服务的ROSRPC uri
确保这个在运行:
bash展开代码roscore # 总线
rosrun turtlesim turtlesim_node # 乌龟
rosrun turtlesim turtle_teleop_key # 键盘
rosservice list 输出活跃服务的信息
bash展开代码root@euler-MS-7D30:/# rosservice list
/clear
/kill
/reset
/rosout/get_loggers
/rosout/set_logger_level
/spawn
/teleop_turtle/get_loggers
/teleop_turtle/set_logger_level
/turtle1/set_pen
/turtle1/teleport_absolute
/turtle1/teleport_relative
/turtlesim/get_loggers
/turtlesim/set_logger_level
rosservice call /clear 清除了乌龟的行动轨迹
bash展开代码
root@euler-MS-7D30:/# rosservice type /spawn | rossrv show
float32 x
float32 y
float32 theta
string name
---
string name
产生新的乌龟:
bash展开代码rosservice call /spawn 2 2 0.2 "haha"
rosparam能让我们在ROS参数服务器(Parameter Server)上存储和操作数据。参数服务器能够存储整型(integer)、浮点(float)、布尔(boolean)、字典(dictionaries)和列表(list)等数据类型。rosparam使用YAML标记语言的语法。一般而言,YAML的表述很自然:1是整型,1.0是浮点型,one是字符串,true是布尔型,[1, 2, 3]是整型组成的列表,{a: b, c: d}是字典。rosparam有很多命令可以用来操作参数,如下所示:
bash展开代码rosparam set 设置参数
rosparam get 获取参数
rosparam load 从文件中加载参数
rosparam dump 向文件中转储参数
rosparam delete 删除参数
rosparam list 列出参数名
可以看到turtlesim节点在参数服务器上有3个参数用于设定背景颜色:
bash展开代码
root@euler-MS-7D30:/# rosparam list
/rosdistro
/roslaunch/uris/host_euler_ms_7d30__37897
/rosversion
/run_id
/turtlesim/background_b
/turtlesim/background_g
/turtlesim/background_r
现在我们修改背景颜色的红色通道值:
bash展开代码rosparam set /turtlesim/background_r 150
上述指令修改了参数的值,现在我们需要调用clear服务使得参数的修改能生效:
bash展开代码rosservice call /clear
然后我们来查看参数服务器上其他参数的值。获取背景的绿色通道的值:
bash展开代码root@euler-MS-7D30:/# rosparam get /turtlesim/background_g
86
也可以用rosparam get /来显示参数服务器上的所有内容:
bash展开代码root@euler-MS-7D30:/# rosparam get /
rosdistro: 'noetic
'
roslaunch:
uris:
host_euler_ms_7d30__37897: http://euler-MS-7D30:37897/
rosversion: '1.15.14
'
run_id: 64467cf2-78ee-11f0-9273-d8bbc18a2881
turtlesim:
background_b: 255
background_g: 86
background_r: 150
在这里,我们将所有的参数写入params.yaml文件:
bash展开代码root@euler-MS-7D30:/# rosparam dump params.yaml
root@euler-MS-7D30:/# cat params.yaml
rosdistro: 'noetic
'
roslaunch:
uris:
host_euler_ms_7d30__37897: http://euler-MS-7D30:37897/
rosversion: '1.15.14
'
run_id: 64467cf2-78ee-11f0-9273-d8bbc18a2881
turtlesim:
background_b: 255
background_g: 86
background_r: 150
你甚至可以将yaml文件重载入新的命名空间,例如copy_turtle:
bash展开代码rosparam load params.yaml copy_turtle rosparam get /copy_turtle/turtlesim/background_b
本教程会用到rqt和turtlesim这两个软件包。如果你发现没有安装,请先:
bash展开代码apt-get install ros-noetic-rqt ros-noetic-rqt-common-plugins ros-noetic-turtlesim -y
rqt_console连接到了ROS的日志框架,以显示节点的输出信息。rqt_logger_level允许我们在节点运行时改变输出信息的详细级别,包括Debug、Info、Warn和Error。
现在让我们来看一下turtlesim在rqt_console中输出的信息,同时在使用turtlesim时切换rqt_logger_level中的日志级别。在启动turtlesim之前先在两个新终端中运行rqt_console和rqt_logger_level:
bash展开代码rosrun rqt_console rqt_console
bash展开代码rosrun rqt_logger_level rqt_logger_level
bash展开代码Fatal (致命) Error (错误) Warn (警告) Info (信息) Debug (调试)
roslaunch可以用来启动定义在launch(启动)文件中的节点。
bash展开代码roslaunch [package] [filename.launch]
先切换到我们之前创建和构建的beginner_tutorials软件包目录下:
roscd 直接就切换到软件包里去了:
bash展开代码root@euler-MS-7D30:~/xiedong/learning-ros/catkin_ws# . devel/setup.bash
root@euler-MS-7D30:~/xiedong/learning-ros/catkin_ws# cd ~
root@euler-MS-7D30:~# roscd beginner_tutorials
root@euler-MS-7D30:~/xiedong/learning-ros/catkin_ws/src/beginner_tutorials#
然后创建一个launch目录:
bash展开代码$ mkdir launch
$ cd launch
存放launch文件的目录不一定非要命名为launch,事实上都不用非得放在目录中,roslaunch命令会自动查找经过的包并检测可用的启动文件。然而,这种推荐的标准做法被认为是“最佳实践”。
现在一起创建一个名为 turtlemimic.launch 的launch文件并复制粘贴以下内容进去:
这段ROS launch文件定义了一个包含两个独立命名空间(turtlesim1和turtlesim2)的仿真系统,每个命名空间下都运行一个turtlesim_node节点作为海龟仿真器;同时启动了一个名为"mimic"的模仿节点,通过重映射机制将turtlesim1中turtle1的运动指令作为输入,转发给turtlesim2的turtle1作为输出,从而实现第二个海龟完全复制第一个海龟所有动作的功能。
bash展开代码<launch>
<group ns="turtlesim1">
<node pkg="turtlesim" name="sim" type="turtlesim_node"/>
</group>
<group ns="turtlesim2">
<node pkg="turtlesim" name="sim" type="turtlesim_node"/>
</group>
<node pkg="turtlesim" name="mimic" type="mimic">
<remap from="input" to="turtlesim1/turtle1"/>
<remap from="output" to="turtlesim2/turtle1"/>
</node>
</launch>
现在让我们通过roslaunch命令来运行launch文件:
bash展开代码$ roslaunch beginner_tutorials turtlemimic.launch
现在将会有两个turtlesim被启动,然后我们在一个新终端中使用rostopic命令发送:
bash展开代码$ rostopic pub /turtlesim1/turtle1/cmd_vel geometry_msgs/Twist -r 1 -- '[2.0, 0.0, 0.0]' '[0.0, 0.0, -1.8]'
我们还可以用rqt_graph来更好地理解launch文件所做的事情。运行rqt并在主窗口中选择Plugins > Introspection > Node Graph:
bash展开代码rqt_graph
rosed是rosbash套件的一部分。利用它可以直接通过软件包名编辑包中的文件,而无需键入完整路径。
bash展开代码$ rosed [package_name] [filename]
这个例子演示了如何编辑roscpp软件包中的Logger.msg文件。
如果该实例没有运行成功,可能是因为你没有安装vim编辑器。请参考编辑器部分进行设置。
如果你不知道怎么退出vim,请尝试按下键盘上的Esc,然后分别按下
!。如果文件名在包中不是唯一的,则菜单将提示你选择要编辑哪个文件。
bash展开代码$ rosed roscpp Logger.msg
Tab补全
使用这个方法,在不知道准确文件名的情况下,你也可以轻松地查看和编辑包中的所有文件。
bash展开代码$ rosed roscpp <tab><tab>
rosed默认的编辑器是vim。其实Ubuntu默认还有一个初学者更友好的编辑器nano,你可以把下面这行加到~/.bashrc文件中来更改默认编辑器:
bash展开代码export EDITOR='nano -w'
msg(消息):msg文件就是文本文件,用于描述ROS消息的字段。它们用于为不同编程语言编写的消息生成源代码。
srv(服务):一个srv文件描述一个服务。它由两部分组成:请求(request)和响应(response)。
msg文件存放在软件包的msg目录下,srv文件则存放在srv目录下。
msg文件就是简单的文本文件,每行都有一个字段类型和字段名称。可以使用的类型为:
下面是一个使用了Header、字符串原语和其他两个消息的示例: 下面是一个msg文件的样例,它使用了Header,string,和其他另外两个消息的类型:
bash展开代码Header header string child_frame_id geometry_msgs/PoseWithCovariance pose geometry_msgs/TwistWithCovariance twist
srv文件和msg文件一样,只是它们包含两个部分:请求和响应。这两部分用一条---线隔开。下面是一个srv文件的示例:
bash展开代码int64 A int64 B --- int64 Sum
ROS里的msg和srv:
bash展开代码1. msg文件(消息说明书)
- 就像快递包裹的清单,写明包裹里有什么类型的东西
- 比如:string name 表示有个字符串类型的名字
- int32 age 表示有个整数类型的年龄
- 支持的类型有整数、小数、字符串、时间等
- 还能嵌套使用其他消息类型
- 例子:就像快递单写着:
[发件人]张三
[物品]手机1部+充电器2个
2. srv文件(服务合同书)
- 分前后两部分的约定书,中间用"---"隔开
- 前半部分是你要给服务提供者的参数
- 后半部分是服务提供者返回给你的结果
- 例子:就像去银行办业务:
[你要提交] 存折+100元钱
---
[银行给你] 盖章后的回执单
使用msg
创建msg
下面,我们将在之前创建的软件包里定义一个新的消息。
bash展开代码cd ~/xiedong/learning-ros/catkin_ws/src/beginner_tutorials
mkdir msg
echo "int64 num" > msg/Num.msg
上面是最简单的示例,.msg文件只有一行。当然,你可以通过添加更多元素(每行一个)来创建一个更复杂的文件,如下所示:
bash展开代码string first_name string last_name uint8 age uint32 score
不过还有关键的一步:我们要确保msg文件能被转换为C++、Python和其他语言的源代码。
打开package.xml, 确保它包含以下两行且没有被注释。如果没有,添加进去:
bash展开代码<build_depend>message_generation</build_depend> <exec_depend>message_runtime</exec_depend>
注意,在构建时,其实只需要message_generation,而在运行时,我们只需要message_runtime。
在你喜欢的文本编辑器中打开CMakeLists.txt文件(rosed是一个不错的选择)。
在CMakeLists.txt文件中,为已经存在里面的find_package调用添加message_generation依赖项,这样就能生成消息了。直接将message_generation添加到COMPONENTS列表中即可,如下所示:
你可能注意到了,有时即使没有使用全部依赖项调用find_package,项目也可以构建。这是因为catkin把你所有的项目整合在了一起,因此如果之前的项目调用了find_package,你的依赖关系也被配置成了一样的值。但是,忘记调用意味着你的项目在单独构建时很容易崩溃。
还要确保导出消息的运行时依赖关系:
还需要在最后面加上:
bash展开代码add_message_files( FILES Num.msg )
手动添加.msg文件后,我们要确保CMake知道何时需要重新配置项目。
现在必须确保generate_messages()函数被调用:
在ROS Hydro及更新版本中,你需要取消下面几行的注释:
现在,你可以从msg文件定义中生成源代码文件了。如果现在就想这样做,请直接跳到msg和srv的一般步骤。
以上就是创建消息的所有步骤。让我们通过rosmsg show命令看看ROS能否识别它。
bash展开代码root@euler-MS-7D30:~/xiedong/learning-ros/catkin_ws/src/beginner_tutorials# rosmsg show beginner_tutorials/Num
int64 num
string first_name
string last_name
uint8 age
uint32 score
让我们使用之前创建的包再来创建服务:
bash展开代码roscd beginner_tutorials
mkdir srv
我们将从另一个包复制现有的srv定义,而不是手动创建新的srv。roscp是一个实用的命令行工具,用于将文件从一个包复制到另一个包。
bash展开代码sudo apt-get install ros-noetic-rospy-tutorials
bash展开代码roscp rospy_tutorials AddTwoInts.srv srv/AddTwoInts.srv
以下是关于ROS消息(msg)和服务(srv)创建教程的整理说明:
消息(msg):文本文件,定义ROS消息的字段类型,用于生成多语言代码。
package/msg/
。int8/16/32/64
、float32/64
、string
、time
、duration
、其他msg、数组等。Header
(包含时间戳和坐标帧信息)。msg展开代码Header header string child_frame_id geometry_msgs/PoseWithCovariance pose
服务(srv):描述服务请求(request)和响应(response)。
package/srv/
。---
分隔请求和响应。srv展开代码int64 A int64 B --- int64 Sum
步骤:
创建msg
目录并定义.msg
文件:
bash展开代码roscd beginner_tutorials
mkdir msg
echo "int64 num" > msg/Num.msg
修改package.xml
,确保包含:
xml展开代码<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>
修改CMakeLists.txt
:
message_generation
依赖:
cmake展开代码find_package(catkin REQUIRED COMPONENTS roscpp rospy std_msgs message_generation)
cmake展开代码add_message_files(FILES Num.msg)
cmake展开代码generate_messages(DEPENDENCIES std_msgs)
编译:
bash展开代码catkin_make
验证工具:
bash展开代码rosmsg show beginner_tutorials/Num # 显示消息定义
步骤:
创建srv
目录并复制示例:
bash展开代码roscd beginner_tutorials
mkdir srv
roscp rospy_tutorials AddTwoInts.srv srv/AddTwoInts.srv
修改package.xml
(同msg,需message_generation
和message_runtime
)。
修改CMakeLists.txt
:
cmake展开代码add_service_files(FILES AddTwoInts.srv)
编译:
bash展开代码catkin_make
验证工具:
bash展开代码rossrv show beginner_tutorials/AddTwoInts # 显示服务定义
本文作者:Dong
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC。本作品采用《知识共享署名-非商业性使用 4.0 国际许可协议》进行许可。您可以在非商业用途下自由转载和修改,但必须注明出处并提供原作者链接。 许可协议。转载请注明出处!