Linux教程:机器人操作系统ROS学习教程
描述:这篇文章主要介绍ROS(机器人操作系统,Robot Operating System)的用途及安装方式;
1.1 ROS的主要用途
ROS(机器人操作系统,Robot Operating System),是专为机器人软件开发所设计出来的一套电脑操作系统架构。它是一个开源的元级操作系统(后操作系统),提供类似于操作系统的服务,包括硬件抽象描述、底层驱动程序管理、共用功能的执行、程序间消息传递、程序发行包管理,它也提供一些工具和库用于获取、建立、编写和执行多机融合的程序。
ROS的运行架构是一种使用ROS通信模块实现模块间P2P的松耦合的网络连接的处理架构,它执行若干种类型的通讯,包括基于服务的同步RPC(远程过程调用)通讯、基于Topic的异步数据流通讯,还有参数服务器上的数据存储。
1.2 ROS安装方式
ROS可以安装到多种平台上,目前支持最全的是Ubuntu操作系统平台,推荐在Windows平台下采用虚拟机的方式进行安装,方便下一步的学习实验;
官方提供的最新版(ROS Groovy Galapagos)安装镜像地址如下:http://nootrix.com/downloads/#RosVM
虚拟机下载网站为:https://www.virtualbox.org/
安装完Oracle VM VirtualBox后,点击菜单“管理”->“导入虚拟电脑”->“打开虚拟电脑”
选择下载的“rosGroovyGalapagos.ova”文件;
在虚拟电脑导入配置选项中,建议调整一下虚拟硬盘的位置到空间比较大的硬盘区,如时飞安装的位置为“D:\VirtualOS\VirtualBox”,如下图所示:
安装完毕后启动虚拟机,默认用户名及密码都是“viki”,运行后如下所示:
我们试着在命令终端“Terminal”中输入ROS指令“roscore”,会出现如下信息:
现在,虚拟机安装完毕了,以后我们可以利用这个虚拟机进一步学习有关ROS的相关内容了。
1.1 ROS文件系统中的相关概念
功能包(Packages):功能包是ROS中比较基础的软件组织方式,每个功能包可包含依赖库,可执行文件,脚本文件及其它的相关文件;
Manifest(package.xml):Manifest是功能包的描述文件,它主要定义功能包与其他功能包之间的依赖关系,并提供关于功能包的版本信息,维护者信息和许可信息等。
1.2 文件系统工具集
由于ROS代码分布在许多功能包中,如果采用ls和cd等命令将会非常繁琐,因此ROS提供一些自定义的工具集辅助操作;
1.2.1 rospack使用介绍
rospack用于获取功能包的相关信息,在这篇文章中,我们只涉及其中的find参数,它返回功能包的路径信息;
用法:
# rospack find [package_name]
示例:
$ rospack find roscpp
执行结果如下:
YOUR_INSTALL_PATH/share/roscpp
如果你的ROS是从apt安装到Ubuntu系统中的,将会显示如下结果:
/opt/ros/groovy/share/roscpp
1.2.2 roscd使用介绍
roscd 是rosbash套件中的一部分,利用它可以改变路径到指定的功能包或功能包集中;
用法:
# roscd [locationname[/subdir]]
示例:
$ roscd roscpp
为了验证是否改变到roscpp功能包的路径下,可采用Uinx的命令pwd打印出当前的路径信息;
$ pwd
得到如下执行结果:
YOUR_INSTALL_PATH/share/roscpp
这个路径和上一个示例中rospack find roscpp查找出的路径是一致的;
注意,roscd和其他ROS命令工具一样,只会查找ROS_PACKAGE_PATH变量中包含的packages,通过下面的命令可以查看ROS_PACKAGE_PATH包含的信息:
$ echo $ROS_PACKAGE_PATH
ROS_PACKAGE_PATH变量包含一系列被冒号“:”隔开的路径,通常情况下,ROS_PACKAGE_PATH变量值如下所示:
/opt/ros/groovy/base/install/share:/opt/ros/groovy/base/install/stacks
与其他环境变量的用法一致,可以添加路径到ROS_PACKAGE_PATH中,路径间必须用冒号隔开;
子目录
roscd也可以改变到一个功能包或者功能包集的子目录中;
试用如下命令:
$ roscd roscpp/cmake
$ pwd
执行结果如下所示:
YOUR_INSTALL_PATH/share/roscpp/cmake
1.2.3 roscd log
roscd log 将会把你引导到ROS日志所在的目录下;需要注意的是,如果你没有运行任何ROS程序,它将显示日志目录不存在的错误信息;
如果你已经运行过ROS程序,可以尝试如下命令:
$ roscd log
1.2.4 rosls使用介绍
rosls是rosbash套件的一部分,它可以通过功能包的名称列出其下面包含的文件,而不必使用绝对路径;
用法:
# rosls [locationname[/subdir]]
示例:
$ rosls roscpp_tutorials
执行结果如下:
cmake package.xml srv
1.2.5 使用Tab键
有时拼写出整个功能包的名称会比较繁琐,在上一个示例中, roscpp_tutorials是一个相当长的名称,幸运的是大部分ROS的命令工具支持TAB键操作;
按照如下所示操作:
# roscd roscpp_tut<<< 此处按下TAB键 >>>
按下TAB键后,命令行会自动填充完余下的字符,如下所示:
$ roscd roscpp_tutorials/
1.2.6 ROS命令工具的风格
经过上面的一些示例可以总结出关于ROS命令的命名风格:
rospack = ros + pack(age)
roscd = ros + cd
rosls = ros + ls
在ROS系统中,大部分的命令工具均采用这样的命名方式;
描述:这篇文章介绍如何用roscreate-pkg或catkin创建一个新的功能包,并用rospack列出功能包的依赖关系。
1、catkin功能包的组成
要组成一个catkin功能包,必须满足如下相关条件:
• 功能包必须包含一个catkin兼容的注释文件package.xml。
o package.xml文件提供有关功能包的元信息;
• 功能包必须包含采用catkin的CmakeLists.txt文件
o 例外情况是metapackages不必包含CmakeLists.txt
• 在一个文件夹中不允许出现多个功能包
o 这意味着多个功能包不能共享一个路径,也不允许功能包之间相互嵌套包;
最简单的功能包组成如下所示:
• my_package/
• CMakeLists.txt
• package.xml
2、catkin Workspace里的功能包
推荐在catkin workspace下生成并编译catkin 功能包,当然,catkin功能包也可单独编译。catkin workspace的文件组织形式如下所示:
• workspace_folder/ -- WORKSPACE
• src/ -- SOURCE SPACE
• CMakeLists.txt -- 'Toplevel' CMake file, provided by catkin
• package_1/
• CMakeLists.txt -- CMakeLists.txt file for package_1
• package.xml -- Package manifest for package_1
• ...
• package_n/
• CMakeLists.txt -- CMakeLists.txt file for package_n
• package.xml -- Package manifest for package_n
在创建catkin功能包之前,我们先创建一个空的catkin workspace,命名为catkin_ws,接下来的练习都在这个catkin_ws下进行;
3、创建catkin功能包
接下来将会阐述如何利用catkin_create_pkg命令工具生成一个新的catkin功能包,并介绍catkin功能包的用途;
首先,改变路径到catkin workspace的src目录内;
# You should have created this in the Creating a Workspace Tutorial
$cd~/catkin_ws/src
现在使用catkin_create_pkg命令创建名字为beginner_tutorials的功能包,并设置这个新功能包依赖于std_msg,roscpp和rospy;
?1 $ catkin_create_pkg beginner_tutorials std_msgs rospy roscpp
这将会创建一个beginner_tutorials的文件夹,这个文件夹内会自动生成package.xml文件和CmakeLists.txt文件,这个两个文件会依据你对catin_create_pkg命令的设置参数填写一些信息;
Catkin_create_pkg后面的参数需包含功能包的名字及所创建功能包的一些依赖选项:
# This is an example, do not try to run this
# catkin_create_pkg
4、功能包依赖关系
4.1 直接(一级)依赖关系
在使用catkin_create_pkg时,一些依赖的功能包需要提供出来,这些直接(一级)依赖关系可以通过命令工具rospack查看;
?1 $ rospack depends1 beginner_tutorials
• std_msgs
• rospy
• roscpp
就像看到的一样,rospack列出了用catkin_create_pkg创建时设置的依赖功能包。这些依赖功能包信息被保存在package.xml文件内;
$ roscd beginner_tutorials
$catpackage.xml
•
• ...
•
•
•
•
• ...
•
4.2 间接依赖关系
在很多情况下,依赖功能包本身也需要自己的依赖功能包,例如,rospy就会需要一些依赖功能包;
$ rospack depends1 rospy
• genpy
• rosgraph
• rosgraph_msgs
• roslib
• std_msgs
一个功能包会需要很多间接的依赖功能包,幸运的是,rospack可以次序检测到所有嵌套的依赖功能包;
$ rospack depends beginner_tutorials
cpp_common
rostime
roscpp_traits
roscpp_serialization
genmsg
genpy
message_runtime
rosconsole
std_msgs
rosgraph_msgs
xmlrpcpp
roscpp
rosgraph
catkin
rospack
roslib
rospy
5、 设置生成的功能包
这一部分将会逐行查看catkin_create_pkg自动生成的各个文件,并根据需要修正它们;
5.1 设置文件package.xml
在你新创建的功能包内会产生一个package.xml文件,现在我们查看一下文件package.xml,看哪些元素是我们尤其要关注的;
5.1.1 描述标签
首先需要更新的是描述标签:
根据你的需要,改变这些描述信息,顺便提示一下,最好采用一句话描述这个功能包的用途信息;
5.1.2 维护者标签
接下来我们可以看到维护者标签:
这在package.xml文件里是一个非常重要的标签,它可以让其它人知道维护这个功能包的联系人信息。至少提供一个维护者信息,当然,如果需要,你可以添加任何一个维护者的信息。维护者的标签处于body的位置,属性里面的email信息也需要填写完整:
5.1.3 许可标签
接下来是许可标签,这个标签也是必要的:
可以选择一种license填写到里面。常用的license信息为BSD,MIT,Boost Software License,GPLv2,GPLv3,LGPLv2.1和LGPLv3等,针对这篇文章,我们使用BSD许可。
5.1.4 依赖功能包标签
接下一组标签是描述这个功能包的依赖关系的。这些依赖关系被 build_depend,buildtool_depend,run_depend,test_depend等分隔开,有关这些标签的更详细的描述可以查看catkin dependencies。因为我们设置了catkin_create_pkg命令的std_msg,roscpp,rospy参数,因此可以看到下面的依赖项:
在catkin功能包里,除了默认的buildtool_dependon,所有列出的依赖包被作为build_depend添加进来。我们希望在编译和运行时均指定相关的依赖包,因此我们为每一个依赖包添加一下run_depend标签:
5.1.5 最终的package.xml
去除注解及没有用到的标签,最终的package.xml文件如下所示,看起来更简洁,
6、设置生成的CMakeLists.txt文件
既然包含元信息的package.xml已经根据需要做了修改,你已经做好了练习的准备了吧。Catkin_create_pkg产生的文件CMakeLists.txt将在以后编译功能包时进行修正完善;
描述:这篇教程主要介绍编译功能包的工具链;
1、编译功能包
只要功能包的依赖项都已经安装完毕,我们就可以编译新的功能包了;
在开始之前,务必通过source指令设置运行的环境,在Ubuntu系统中可以执行如下指令;
$source/opt/ros/groovy/setup.bash
1.1 使用catkin_make
catkin_make是一个命令行工具,这个工具集成了一些标准catkin的工作流程;可以认为catkin_make在Cmake执行中联合调用了cmake和make;
用法:
# In a catkin workspace
$ catkin_make [make_targets] [-DCMAKE_VARIABLES=...]
对于不很熟悉Cmake标准工作流程的朋友,可以参考如下所示,下面的代码只是演示CMake的标准流程,不可执行;
# In a CMake project
$mkdirbuild
$cdbuild
$ cmake ..
$make
$makeinstall # (optionally)
每一个CMake工程是单独编译的,而在一个workspace里的catkin工程是可以一起编译,一起编译时可以参考如下流程进行:
# In a catkin workspace
$ catkin_make
$ catkin_make install # (optionally)
上面的命令会编译在src文件夹里的任何一个catkin工程,如果你的代码在别的位置,比如my_src,则应当如下调用catkin_make命令(因为示例的my_src可能不存在,下面的指令不一定能编译成功):
# In a catkin workspace
$ catkin_make --sourcemy_src
$ catkin_make install--sourcemy_src # (optionally)
2、 编译你自己的功能包
我们已经创建了一个catkin workspace和一个名字为beginner_tutorials的catkin功能包,改变路径到catkin workspace中查看一下src文件夹:
$cd~/catkin_ws/
$lssrc
• beginner_tutorials/ CMakeLists.txt@
你应当看到一个名字为beginner_tutorials的文件夹,现在我们利用catkin_make编译这个功能包:
$ catkin_make
你应当看到源自cmake及make的输出信息,大致如下所示:
• Base path: /home/user/catkin_ws
• Source space: /home/user/catkin_ws/src
• Build space: /home/user/catkin_ws/build
• Devel space: /home/user/catkin_ws/devel
• Install space: /home/user/catkin_ws/install
• ####
• #### Running command: "cmake /home/user/catkin_ws/src
• -DCATKIN_DEVEL_PREFIX=/home/user/catkin_ws/devel
• -DCMAKE_INSTALL_PREFIX=/home/user/catkin_ws/install" in "/home/user/catkin_ws/build"
• ####
• -- The C compiler identification is GNU 4.2.1
• -- The CXX compiler identification is Clang 4.0.0
• -- Checking whether C compiler has -isysroot
• -- Checking whether C compiler has -isysroot - yes
• -- Checking whether C compiler supports OSX deployment target flag
• -- Checking whether C compiler supports OSX deployment target flag - yes
• -- Check for working C compiler: /usr/bin/gcc
• -- Check for working C compiler: /usr/bin/gcc -- works
• -- Detecting C compiler ABI info
• -- Detecting C compiler ABI info - done
• -- Check for working CXX compiler: /usr/bin/c++
• -- Check for working CXX compiler: /usr/bin/c++ -- works
• -- Detecting CXX compiler ABI info
• -- Detecting CXX compiler ABI info - done
• -- Using CATKIN_DEVEL_PREFIX: /tmp/catkin_ws/devel
• -- Using CMAKE_PREFIX_PATH: /opt/ros/groovy
• -- This workspace overlays: /opt/ros/groovy
• -- Found PythonInterp: /usr/bin/python (found version "2.7.1")
• -- Found PY_em: /usr/lib/python2.7/dist-packages/em.pyc
• -- Found gtest: gtests will be built
• -- catkin 0.5.51
• -- BUILD_SHARED_LIBS is on
• -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
• -- ~~ traversing packages in topological order:
• -- ~~ - beginner_tutorials
• -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
• -- +++ add_subdirectory(beginner_tutorials)
• -- Configuring done
• -- Generating done
• -- Build files have been written to: /home/user/catkin_ws/build
• ####
• #### Running command: "make -j4" in "/home/user/catkin_ws/build"
• ####
注意catkin_make首先显示出每个‘space’使用的路径,因为采用的默认参数,编译后会产生几个文件夹,可以通过ls查看:
$ls
• build
• devel
• src
build文件夹是编译时的默认位置,这里保存有cmake和make配置及编译信息的相关文件,devel文件夹是编译后保存编译结果的,编译后的可执行文件及依赖库保存在这个位置;
描述:这篇教程主要介绍ROS图的概念及命令行工具roscore,rosnode和rosrun等;
1、必备条件
在这篇教程里,我们会使用一个轻量级的模拟器,可以通过下面的命令安装:
$ sudo apt-get install ros-
替换命令中
2、浏览图的概念
• 节点:节点是一个可执行文件,可以与其它ROS节点进行通信;
• 消息:ROS中的一种数据类型,用于订阅或者发布一个主题;
• 话题:节点发布的一个话题,同时也可以接收一个话题;
• Master:ROS系统中的名称管理器,方便节点之间的查找;
• rosout:在ROS系统中相当于标准的stdout/stderr;
• roscore:Master+rosout+parameter server(parameter server会稍后介绍)
3、Nodes节点
节点只不过是ROS功能包中的一个可执行文件,ROS节点采用ROS客户端库与其它节点进行通信,节点可以发布或订阅一个话题,也可以提供或使用一个服务。
4、客户端库
ROS客户端库允许节点以不同的编程语言实现,通信方式也可以采用不同的语言实现:
• rospy 为 python 语言实现的客户端库
• roscpp 为 c++ 语言实现的客户端库
5、roscore
使用ROS时,roscore 是第一个需要运行的指令;
指令如下:
$ roscore
运行后将看到类似如下的相关信息:
• ... logging to ~/.ros/log/9cf88ce4-b14d-11df-8a75-00251148e8cf/roslaunch-machine_name-13039.log
• Checking log directory for disk usage. This may take awhile.
• Press Ctrl-C to interrupt
• Done checking log file disk usage. Usage is <1GB.
•
• started roslaunch server http://machine_name:33919/
• ros_comm version 1.4.7
•
• SUMMARY
• ========
•
• PARAMETERS
• * /rosversion
• * /rosdistro
•
• NODES
•
• auto-starting new master
• process[master]: started with pid [13054]
• ROS_MASTER_URI=http://machine_name:11311/
•
• setting /run_id to 9cf88ce4-b14d-11df-8a75-00251148e8cf
• process[rosout-1]: started with pid [13067]
• started core service [/rosout]
如果roscore没有成功初始化,有可能是网络配置的问题;
6、rosnode的使用
打开一个新的命令终端,利用rosnode查看一下正在运行的roscore在做什么
rosnode可以显示正在运行的ROS节点信息;
rosnode list列出了正在活动的节点:
$ rosnode list
将会看到如下执行结果
• /rosout
这表明只有一个节点正在运行,就是rosout,这是一个始终都在运行的节点,它用来收集节点的调试输出信息等;
rosnode info命令显示指定的节点的信息:
$ rosnode info /rosout
这将显示出节点rosout更多的信息,比如它将发布/rosout_agg等;
• ------------------------------------------------------------------------
• Node [/rosout]
• Publications:
• * /rosout_agg [rosgraph_msgs/Log]
•
• Subscriptions:
• * /rosout [unknown type]
•
• Services:
• * /rosout/set_logger_level
• * /rosout/get_loggers
•
• contacting node http://machine_name:54614/ ...
• Pid: 5092
现在,我们查看其他的节点;这次采用rosrun的方式激活节点;
7、rosrun的使用
采用rosrun指令,可以通过功能包的名字直接运行一个节点,而不必知道这个功能包的具体路径;
用法:
$ rosrun [package_name] [node_name]
让我们来运行一下turtlesim功能包里的节点turtlesim_node;
在一个新的命令终端输入如下指令:
$ rosrun turtlesim turtlesim_node
可以看到一个turtlesim窗口:
注意:turtlesim窗口中的小乌龟可能不一样,不用担心,ROS里有多种类型的小乌龟,你的是一个惊喜哦!
在一个新的命令终端输入:
$ rosnode list
可以看到如下信息:
• /rosout
• /turtlesim
ROS中一个比较强大的功能是你可以通过命令行重新指定名称;
关闭turtlesim窗口停止这个节点,或者返回rosrun turtlesim命令终端,按下crtl+C键盘。我们重新运行它,不过这次我们通过映射参数(Remapping Argument)来改变节点的名字:
$ rosrun turtlesim turtlesim_node __name:=my_turtle
现在我们依然采用rosnode list:
$ rosnode list
• 将会得到如下输出信息:
• /rosout
• /my_turtle
我们查看这个新的my_turtle节点,这次采用另外一个rosnode参数ping,如下所示:
$ rosnode ping my_turtle
• rosnode: node is [/my_turtle]
• pinging /my_turtle with a timeout of 3.0s
• xmlrpc reply from http://aqy:42235/ time=1.152992ms
• xmlrpc reply from http://aqy:42235/ time=1.120090ms
• xmlrpc reply from http://aqy:42235/ time=1.700878ms
• xmlrpc reply from http://aqy:42235/ time=1.127958ms
8、Review回顾
这一节我们讲解了如下一些指令:
roscor = ros+core:master(在ROS中提供名字的服务)+rosout(stdout/stderr)+parameter server(参数服务);
rosnode = ros+node:用于获取节点信息的ROS 工具;
rosrun = ros+run:从指定的功能包中运行一个节点;
描述:这篇教程主要讲解ROS系统中的话题及rostopic和rqt_plot等命令工具;
1. Setup安装
1.1 roscore
首先确保roscore已经启动运行,打开一个新的命令终端,输入如下指令:
$ roscore
如果此时你仍然运行着上一篇教程中的roscore,将会看到如下错误信息:
• roscore cannot run as another roscore/master is already running.
• Please kill other roscore/master processes before relaunching
这是没有什么问题的,因为只能有一个roscore运行;
1.2 turtlesim
在这篇教程,我们仍然使用turtlesim功能包,打开一个新的命令终端,输入如下指令:
$ rosrun turtlesim turtlesim_node
1.3 键盘遥控乌龟
我们需要采取一些措施来操纵乌龟,请在新的命令终端输入如下指令:
$ rosrun turtlesim turtle_teleop_key
• [ INFO] 1254264546.878445000: Started node [/teleop_turtle], pid [5528], bound on [aqy], xmlrpc port [43918], tcpros port [55936], logging to [~/ros/ros/log/teleop_turtle_5528.log], using [real] time
• Reading from keyboard
• ---------------------------
• Use arrow keys to move the turtle.
这样就可以使用键盘上的方向键来操控乌龟运动了,如果乌龟不动弹,则需要选中turtle_teleop_key窗口,确保按下的键被窗口采集到;
•
现在可以操作乌龟运行了,我们看看这里面究竟发生了什么事!
2. ROS系统中的话题
Turtlesim_node节点和turtle_teleop_key节点之间通过ROS系统的话题进行通信,turtle_teleop_key节点发布键盘的动作到话题,同时turtlesim订阅同样的话题来接收键盘动作。我们可以通过 rqt_graph查看当前运行的节点和话题。
注意:如果采用electric或更早期的版本,是不支持rqt的,可以通过rxgraph来替代;
2.1 rqt_graph的用法
rqt_graph会产生一个关于系统正在运行的元素(注节点及话题等)的动态图表,它是rqt功能包的一部分,如果你还没有安装,可以通过如下方式安装:
• $ sudo apt-get install ros-
替换指令中的
新打开一个命令终端,输入如下指令:
$ rosrun rqt_graph rqt_graph
可以看到如下类似的图像:
如果把鼠标放置到/turtle1/command_velocity上,ROS节点(蓝色和绿色显示的)及话题(红色显示的)会出现高亮, 如图所示,turtlesim_node和turtle_teleop_key节点通过名字为/turtle1/command_velocity的话题进行通信;
2.2 rostopic介绍
通过rostopic工具可以获取有关ROS话题的信息;
可以通过help参数获取有关rostopic的次级命令选项用法;
$ rostopic -h
• rostopic bw display bandwidth used by topic
• rostopic echo print messages to screen
• rostopic hz display publishing rate of topic
• rostopic list print information about active topics
• rostopic pub publish data to topic
• rostopic type print topic type
下面我们使用这些次级命令来检测一下turtlesim节点;
2.3 rostopic echo的用法
Rostopic echo 列示出发布给话题的数据信息;
用法:
rostopic echo [topic]
我们在一个新的命令终端下查看节点turtle_teleop_key发布给/turtle1/command_velocity话题的数据:
$ rostopic echo /turtle1/command_velocity
你也许什么都看不到,因为节点没有正在发布数据给话题,还需要通过按方向键让turtle_teleop_key发布数据,需要注意的是,如果乌龟没有动弹,需要重新选中turtle_teleop_key的命令终端;
如果你按下向上的方向键,你可以看到如下的相关信息:
• ---
• linear: 2.0
• angular: 0.0
• ---
• linear: 2.0
• angular: 0.0
• ---
• linear: 2.0
• angular: 0.0
• ---
• linear: 2.0
• angular: 0.0
• ---
• linear: 2.0
• angular: 0.0
现在再次查看一下rqt_graph(需要刷新一下),可以看到rostopic echo节点(红颜色所示)也在订阅trutle1/command_velocity话题了;
2.4 rostopic list的用法
rostopic list 会列示出当前提供订阅和发布的所有话题信息;
我们猜想一下list的次级命令是什么,在一个新的命令终端,输入如下指令:
$ rostopic list -h
• Usage: rostopic list [/topic]
•
• Options:
• -h, --help show this help message and exit
• -b BAGFILE, --bag=BAGFILE
• list topics in .bag file
• -v, --verbose list full details about each topic
• -p list only publishers
• -s list only subscribers
我们使用rostopic list的 verbose选项:
[plain] view plaincopyprint?$ rostopic list -v
$ rostopic list -v
这将会展示一个有关发布者及订阅者的详细列表及他们的类型。
• Published topics:
• * /turtle1/color_sensor [turtlesim/Color] 1 publisher
• * /turtle1/command_velocity [turtlesim/Velocity] 1 publisher
• * /rosout [roslib/Log] 2 publishers
• * /rosout_agg [roslib/Log] 1 publisher
• * /turtle1/pose [turtlesim/Pose] 1 publisher
•
• Subscribed topics:
• * /turtle1/command_velocity [turtlesim/Velocity] 1 subscriber
• * /rosout [roslib/Log] 1 subscriber
3. ROS消息
节点通过话题通信时是采用ROS消息的方式进行的,对于发布者turtle_teleop_key和订阅者turtlesim_node之间的通信,发布者和订阅者必须采用类型一致的消息。亦即话题通信类型是由发布方发送的消息类型决定的。发送给话题的消息类型可以通过rostopic type检测到;
3.1 rostopic type的用法
rostopic type返回话题发布的任何一个消息的类型。
用法:
rostopic type [topic]
试着输入:
$ rostopic type /turtle1/command_velocity
• You should get:
• 得到如下结果:
turtlesim/Velocity
可以通过rosmsg查看更详细的信息;
$ rosmsg show turtlesim/Velocity
• float32 linear
• float32 angular
现在我们知道了turtlesim需要什么类型的数据了,因此我们可以对小乌龟发布命令了;
4. rostopic补充讲解
我们知道了ROS消息,现在我们使用rostopic操作消息;
4.1 pub rostopic pub的用法
rostopic pub 发布数据给当前存在的话题;
用法:
rostopic pub [topic] [msg_type] [args]
示例:
$ rostopic pub -1 /turtle1/command_velocity turtlesim/Velocity -- 2.0 1.8
在指令中,发送一条消息给turtlesim,通知他采用2.0的线性速度及1.8的角速度运行;
•
这是一个比较奥复杂的指令,我们相信看一下每一个参数;
• rostopic pub
表示发布消息到指定的话题;
• -1
-1选项表示只发送一次消息,然后就停发;
• /turtle1/command_velocity
指定要发送的话题;
• turtlesim/Velocity
指定发送给话题的消息类型
• --
“--”告诉解析器后面的参数不是选项了(而是消息的具体数值),当数值为负数时是非常有必要的;
• 2.0 1.8
如前面提到的,turtlesim/Velocity命令有两个浮点型的数据:线性速度和角速度,这是2.0表示线性速度,1.8表示角速度的数值,这些参数表示形式符合YAML语法,具体可以查看有关YAML的介绍;
你会注意到小乌龟已经停止运动了,因为它需要靠1Hz的数据流不断驱动,我们可以使用rostopic pub –r指令不断发送数据流:
$ rostopic pub /turtle1/command_velocity turtlesim/Velocity -r 1 -- 2.0 -1.8
这条指令以1Hz的频率不断发布速度数据到速度话题;
•
我们可以通过rqt_graph查看什么正在运行,rostopic pub节点(红色所示)正和rostopic echo节点(绿色所示)不断通信;
这样,小乌龟不断的做圆周运行。打开一个新的命令终端,我们使用rostopic echo可以查看由tertlesim发布的数据信息;
4.1 rostopic hz的用法
rostopic hz会报告出数据发布的频率;
用法:
rostopic hz [topic]
我们查看一下turtlesim_node发布的/turtle1/pose有多快:
$ rostopic hz /turtle1/pose
可以看到如下执行结果:
• subscribed to [/turtle1/pose]
• average rate: 59.354
• min: 0.005s max: 0.027s std dev: 0.00284s window: 58
• average rate: 59.459
• min: 0.005s max: 0.027s std dev: 0.00271s window: 118
• average rate: 59.539
• min: 0.004s max: 0.030s std dev: 0.00339s window: 177
• average rate: 59.492
• min: 0.004s max: 0.030s std dev: 0.00380s window: 237
• average rate: 59.463
• min: 0.004s max: 0.030s std dev: 0.00380s window: 290
现在我们可以看出turtlesim正以60Hz的频率发布数据给小乌龟,我们也可以通过rostopic type与rosmsg show 联合在一起的方式输出有关话题的更详细信息;
$ rostopic type /turtle1/command_velocity | rosmsg show
现在我们已经可以通过rostopit来检查话题了,我们还需要使用其他工具查看一下turtlesim发布的数据;
5. rqt_plot用法
注意:如果使用electric或者更早期的版本,rqt是不支持的,用rxplot替代;
rqt_plot展示出了有关数据随着时间输出的曲线。这里我们使用rqt_plot画出发布给/turtle1/pose的数据:
$ rosrun rqt_plot rqt_plot /turtle1/pose/x:y
$ rosrun rqt_plot rqt_plot /turtle1/pose/theta
下面第一副图展示了x-y的位置随时间的关系,第二幅图展示了海龟的theta(方向角?)数值随时间的关系;
描述:这篇教程借助于rosservice和rosparam命令工具介绍ROS系统中的服务及参数。
假设你上一个教程中练习的turtlesim_node还在运行,我们看一下turtlesim节点都提供有哪些服务。
1. ROS服务
服务是节点之间通信的另一种方式,通过服务节点可以发送请求并接收反馈;
2. rosservice的用法
rosservice可以很容易的依附到ROS客户端/服务端的框架中,rosservice具有很多参数用于话题,如下:
用法:
rosservice list print information about active services
rosservice call call the service with the provided args
rosservice type print service type
rosservice find find services by service type
rosservice uri print service ROSRPC uri
2.1 rosservice list
$ rosservice list
这个list指令展示出turtlesim节点提供9个服务:reset, clear, spawn, kill,turtle1/set_pen, /turtle1/teleport_absolute, /turtle1/teleport_relative, turtlesim/get_loggers, 和turtlesim/set_logger_level.还有两个与rosout节点相关的服务:/rosout/get_loggers and /rosout/set_logger_level.
• /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 type查看一下clear这个服务:
2.2 rosservice type
用法:
rosservice type [service]
我们查明clear服务是什么类型的:
$ rosservice type clear
• std_srvs/Empty
这个服务是空的,意味着调用这个服务时不用任何参数(亦即,发送请求或接收反馈时不用借助于任何参数),我们用rosservice call来调用这个服务:
2.3 rosservice call
用法:
rosservice call [service] [args]
这里我们调用时没带任何参数,因为这个服务为空类型的:
$ rosservice call clear
正如我们所料,它清空了turtlesim_node节点的背景。
•
我们查看一下带参数的服务spawn:
$ rosservice type spawn| rossrv show
• float32 x
• float32 y
• float32 theta
• string name
• ---
• string name
这个服务让我们在指定的位置生成一个新的海龟。name区域是可选的(可以不设置),我们不用指定名字产生一个海龟;
$ rosservice call spawn 2 2 0.2 ""
这个调用会返回新产生的海龟的名字:
• name: turtle2
执行结果会如下图所示:
•
3. rosparam的用法
rosparam 允许我们操作并保存ROS系统中参数服务中的数据。参数服务可以存储integer,float,boolean,dictionaries及 lists。rosparam采用YAML标记语言,简单的讲,YAML看起来非常自然:1 is an integer, 1.0 is a float, one is a string, true is a boolean, [1, 2, 3] is a list of integers, and {a: b, c: d} is a dictionary. rosparam具有很多命令用于操作参数,如下所示:
用法:
rosparam set set parameter
rosparam get get parameter
rosparam load load parameters from file
rosparam dump dump parameters to file
rosparam delete delete parameter
rosparam list list parameter names
我们查看一下当前参数服务中都有什么参数:
3.1 rosparam list
$ rosparam list
我们看到turtlesim节点有三个有关背景色的参数保存在参数服务中:
• /background_b
• /background_g
• /background_r
• /roslaunch/uris/aqy:51932
• /run_id
我们用rosparam set改变其中一个参数:
3.2 rosparam set and rosparam get
用法:
rosparam set [param_name]
rosparam get [param_name]
这里我们改变背景色的红色部分:
$ rosparam set background_r 150
上述命令改变了参数的值,我们必须调用clear服务才能使改变的参数生效:
$ rosservice call clear
执行结果如下所示:
•
我们查看参数服务中的其它参数值,看一下背景色中的绿色部分数值:
$ rosparam get background_g
• 86
我们也可以通过rosparam get/ 命令获取参数服务中所有参数的数值:
$ rosparam get /
• background_b: 255
• background_g: 86
• background_r: 150
• roslaunch:
• uris: {'aqy:51932': 'http://aqy:51932/'}
• run_id: e07ea71e-98df-11de-8875-001b21201aa8
你也许想把参数保存到文件中,以便下一次可以调用。采用rosparam命令是非常方便的:
3.3 rosparam dump and rosparam load
用法:
rosparam dump [file_name]
rosparam load [file_name] [namespace]
我们保存所有参数到一个名字为params.yaml的文件中:
$ rosparam dump params.yaml
你可以加载这些yaml文件到新的命名空间,比如copy:
$ rosparam load params.yaml copy
$ rosparam get copy/background_b
• 255
描述:这篇教程介绍ROS系统中rqt_console和rqt_logger_level的调试方式,利用roslaunch一次启动多个节点;如果采用早期的版本(fuerte及以前的版本),rqt也许并不能用,可以采用基于rx的相关工具。
1. rqt的前期准备和turtlesim功能包
这篇教程同时用到了rqt和turtlesim功能包。为了完成这部教程,请安装这两个功能包,可以通过如下命令安装:
$ sudo apt-get install ros-
替换命令中的
注意:你也许已经在前面的教程中编译过rqt和turtlesim了,如果你不确定,可以重新安装一下,不会有任何影响。
2. rqt_console和rqt_logger_level的用法
rqt_console依附于ROS系统的日志框架,用于显示节点的输出信息。通过rqt_logger_level可以调整当前运行节点输出信息的显示级别(DEBUG,WARN,INFO和ERROR);
现在我们利用rqt_console查看一下turtlesim的输出信息,同时用rqt_logger_level调整一下日志级别。在启动turtlesim前,重新打开两个命令终端,分别启动rqt_console和rqt_logger_level:
$ rosrun rqt_console rqt_console
$ rosrun rqt_logger_level rqt_logger_level
这时会弹出两个窗口信息:
这时我们在新的命令终端启动turtlesim:
$ rosrun turtlesim turtlesim_node
因为默认的logger级别为INFO,我们可以看到turtlesim启动时发布出的任何信息,输出信息会如下所示:
我们在rqt_logger_level窗口调整一下日志级别到Warn级别,如下所示,选择Warn:
此时我运行小乌龟,让它碰到墙壁(注:窗口边缘),查看一下rqt_console里的输出信息:
rostopic pub /turtle1/command_velocity turtlesim/Velocity -r 1 -- 2.0 0.0
2.1 Quick Note about logger levels
日志级别的优先级顺序如下所示:
Fatal
Error
Warn
Info
Debug
Fatal优先级最高级别,Debug优先级最低。通过设置日志级别,你可以得到同级及更高级的所有输出信息,如果设置级别为Warn,你将会得到Warn,Error及Fatal级别的日志输出信息;
输入Crtl+C结束turtlesim,通过roslaunch产生多个turtlesim节点,并让其中的一个节点模仿另一个节点运行:
3 Using roslaunch
Roslaunch会按照启动文件描述的方式启动节点:
用法:
$ roslaunch [package] [filename.launch]
首先进入beginner_tutorials功能包:
$ roscd beginner_tutorials
如果roscd失败,可以在命令终端设置ROS_PACKAGE_PATH的变量,命令如下所示:
$ export ROS_PACKAGE_PATH=~/
$ roscd beginner_tutorials
如果仍然无法找到beginner_tutorials,则需要按照前面的课程重新创建这个功能包了。
然后我们需要创建一个启动目录:
$ mkdir launch
$ cd launch
3.1 The Launch File
现在我们创建名字为turtlemimic.launch的启动文件,并在里面粘贴如下内容:
3.2 The Launch File Explained
现在我们分开介绍一下launch的内容:
启动配置文件利用launch作为开始标签,这样这个文件就被标识为启动文件。
这里配置两个组,分别命名为turtlesim1和turtlesim2,这两个组,功能源于同样的功能包turtlesim,同样的名字sim及同样的类型turtlesim_node,这样启动两个模拟器可以避免名字方面的冲突。
接着我们启动模拟节点,并把输入话题及输出话题分别命名为turtlesim1和turtlesim2,重命名之后,将会让turtlesim2模仿turtlesim1运行。
这个xml标签作为启动文件配置的结束。
3.3 roslaunching
现在通过roslaunch启动launch文件:
$ roslaunch beginner_tutorials turtlemimic.launch
两个turtlesims已经启动了,在新的命令终端发送rostopic命令如下:
$ rostopic pub /turtlesim1/turtle1/command_velocity turtlesim/Velocity -r 1 -- 2.0 -1.8
可以看到,即使命令发给了turtlesim1,但两个乌龟均开始运动,
我们可以借助于rqt_graph来更好的理解launch文件做了什么,启动rqt的主窗口然后选择rqt_graph:
$ rqt
或者简单的输入:
$ rqt_graph
我们成功的采用rqt_console和roslaunch,下一步我们了解一下ROS系统中的编辑选项。现在可以通过Ctrl-C终止所有的turtlesims了,下一个教程中我们并不需要他们了。
描述:这篇教程主要讲述如何使用rosed,以使编辑文件更加方便。
1. Using rosed
rosed 是rosbash套件之一,借助它,我们可以使用名字直接编辑功能包中的文件,而不必知道功能包的路径。
用法:
$ rosed [package_name] [filename]
示例:
$ rosed roscpp Logger.msg
这个例子展示了如何编辑功能包roscpp中的文件Logger.msg,如果这个例子没有起作用,有可能是因为你的vim编辑工具没有安装,请参考Editor部分进行安装。
如果名字在这个功能包中并不是唯一的,则会弹出一个菜单供你选择,以确定那个文件是你要编辑的。
2. Using rosed with tab completion
采用tab键的方式,可以很方便的编辑功能包中的所有文件,而不必知道具体的文件名。
用法:
$ rosed [package_name]
3. Editor
默认的rosed编辑器为vim,如果需要设置为其他的默认编辑器,则需要编辑文件~/.bashrc,包含如下信息:
exportEDITOR='emacs -nw'
这个例子采用emacs作为默认编辑器。
注意:改变.bashrc文件将会在新启动的命令终端生效,已经启动的命令终端不会再检测环境变量。
打开新的命令终端,查看EDITOR是否定义了:
$ echo $EDITOR
• emacs -nw
现在已经成功的配置并使用了rosed,下面我们创建一个Msg和Svr。
描述:这篇教程涵盖了如何生成并编译msg和srv文件,及rosmsg,rossrv和roscp等命令工具的用法。
1. msg和srv介绍
•msg:msg文件是简单的文本文件,用于描述ROS中消息(消息的各个参数项)。用于为不同的编程语言生成有关消息的源代码。
•srv:描述服务的文件,由两部分组成:请求和反馈;
msg文件放置在功能包的msg目录下,srv文件放置在srv目录下。
msgs只是一些每行带有类型和名字的文本文件,可以使用的类型如下:
• int8, int16, int32, int64 (plus uint*)
• float32, float64
• string
• time, duration
• other msg files
• variable-length array[] and fixed-length array[C]
ROS中有一个比较特殊的类型:Header,它包含ROS系统中常用的时间戳和坐标信息。一般在msg文件的第一行会指定为Header header。
下面为msg的例子,这个例子使用了Header,string字符串及两个其他类型的msgs。
Header header
string child_frame_id
geometry_msgs/PoseWithCovariance pose
geometry_msgs/TwistWithCovariance twist
srv文件非常类似于msg文件,他们包含两个部分,请求和反馈,这两个部分被“---”分隔开,下面为srv的一个例子。
int64 A
int64 B
---
int64 Sum
在上面的例子中,A和B是用于请求的变量,而Sum是反馈的结果变量。
2. Using msg
2.1 Creating a msg
我们在前面课程中创建的功能包里定义一个新的msg。
$ cd ~/catkin_ws/src/beginner_tutorials
$ mkdir msg
$ echo "int64 num" > msg/Num.msg
在上面例子中,*.msg文件只是简单的包含一行(定义信息)。如果必要,可以如下所示添加多个元素来生成一个复杂的文件:
string first_name
string last_name
uint8 age
uint32 score
还有一点需要确认的是,msg文件需要转换为C++,Python和其他编程语言的源代码。
打开package.xml文件,确保文件中存在下面两行定义:
注意,在编译时,需要依赖“message_generation”,而在运行时,只需要依赖“message_runtime”。
利用你喜欢的文本编辑器(前面课程学习的rosed是一个不错的选择)打开CMakeLists.txt文件。
在CMakeLists.txt文件中添加message_generation到功能包查找项,以便于(节点)调用它们生成消息。只需简单的添加message_generation到COMPONENTS列表中即可,如下所示:
# Do not just add this line to your CMakeLists.txt, modify the existing line
find_package(catkin REQUIRED COMPONENTS roscpp rospy std_msgs message_generation)
你也许注意到即使没有调用find_package中全部的依赖项,你的工程也可以正常编译。这是因为catkin集成了所有的工程,也许前期别的工程调用了find_package,而你的工程使用了同样的配置。但是如果单独编译时忘记添加,则将导致编译失败。
同样,需要确保运行时的依赖项添加进来:
catkin_package(
...
CATKIN_DEPENDS message_runtime ...
...)
查找如下的代码区:
# add_message_files(
# FILES
# Message1.msg
# Message2.msg
# )
去掉每行前面的注释符号“#”,并用你自己的.msg替换Message*.msg文件,替换后如下所示:
add_message_files(
FILES
Num.msg
)
通过手动添加.msg文件,确保了CMake在重新配置时知道这些新添加的.msg文件。
2.2 Using rosmsg
上面的介绍就可以产生一个msg文件了。借助于rosmsg show命令可以判断ROS是否能检测到它:
用法:
$ rosmsg show [message type]
示例:
[html] view plaincopyprint?$ rosmsg show beginner_tutorials/Num
$ rosmsg show beginner_tutorials/Num
得到执行结果:
• int64 num
在前面的示例中,指令参数包含如下两个部分:
• beginner_tutorials -- the package where the message is defined
• Num -- The name of the msg Num.
如果你记不起msg文件存在于哪个功能包内,可以空缺功能包的名字:
$ rosmsg show Num
执行结果如下所示:
• [beginner_tutorials/Num]:
• int64 num
3. Using srv
3.1 Creating a srv
我们在刚刚创建的功能包中生成一个srv:
$ roscd beginner_tutorials
$mkdirsrv
我们从另一个功能包中复制出一个srv,不必亲自手动创建了。roscp是一个非常有用的命令行工具,用于从一个功能包拷贝文件到另一个功能包中。
用法:
$ roscp [package_name] [file_to_copy_path] [copy_path]
现在我们拷贝rospy_tutorials功能包的服务
$ roscp rospy_tutorials AddTwoInts.srv srv/AddTwoInts.srv
还有一步需要确认的是,我们必须确保srv文件可以为C++,Python或其他语言转换为源代码。
如果你在前面还没有添加message_generation到CMakeLists.txt文件中,这里请确保把message_generation添加进去,以便能够生成消息:
# Do not just add this line to your CMakeLists.txt, modify the existing line
find_package(catkin REQUIRED COMPONENTS roscpp rospy std_msgs message_generation)
(没错,message_generation同时为msg和srv工作)
同样你也需要为消息和服务改变package.xml文件,查看上面附加的依赖项。
去掉如下行前面的注释符“#”
# add_service_files(
# FILES
# Service1.srv
# Service2.srv
# )
把Service*.srv文件替换为自己的服务文件,替换后如下所示:
add_service_files(
FILES
AddTwoInts.srv
)
3.2 Using rossrv
上面的介绍就可以产生一个srv文件了。借助于rossrv show命令可以判断ROS是否能检测到它。
用法:
$ rossrv show
示例:
$ rossrv show beginner_tutorials/AddTwoInts
将看到如下执行结果:
• int64 a
• int64 b
• ---
• int64 sum
与rosmsg类似,如下所示可以不指定功能包的名字来查找服务文件:
$ rossrv show AddTwoInts
[rospy_tutorials/AddTwoInts]:
int64 a
int64 b
---
int64 sum
4. Common step for msg and srv
接下来在CMakeLists.txt中找到如下部分:
# generate_messages(
# DEPENDENCIES
# # std_msgs # Or other packages containing msgs
# )
去掉注释并添加 .msg文件在生成消息时的所有依赖项(功能包),这里需要的是std_msg,添加后如下所示:
generate_messages(
DEPENDENCIES
std_msgs
)
既然我们创建了一些新的消息,我们需要用make命令重新编译这些功能包:
# In your catkin workspace
$ cd ../..
$ catkin_make
$ cd -
在msg目录下的所有.msg文件将会为我们支持的编程语言生成代码。C++类型消息的头文件会生成到~/catkin_ws/devel /include/beginner_tutorials/文件夹中;Python脚本文件将生成到~/catkin_ws/devel/lib /python2.7/dist-packages/beginner_tutorials/msg的文件夹中;Lisp语言文件生成到路径~ /catkin_ws/devel/share/common-lisp/ros/beginner_tutorials/msg/内。
The full specification for the message format is available at the Message Description Language page.
5. Getting Help
我们已经看到不少ROS命令工具了,如果记住每一个命令的参数将是非常困难的,幸运的是,大部分ROS命令工具提供了帮助信息:
如下所示:
$ rosmsg -h
• You should see a list of different rosmsg subcommands.
• 可以看到rosmsg中的各种二级命令(命令参数):
• Commands:
• rosmsg show Show message description
• rosmsg users Find files that use message
• rosmsg md5 Display message md5sum
• rosmsg package List messages in a package
rosmsg packages List packages that contain messages
也可以查看二级命令(命令参数)的帮助信息:
$ rosmsg show -h
• This shows the arguments that are needed for rosmsg show:
• 下面显示了rosmsg show所需的参数信息:
• Usage: rosmsg show [options]
•
• Options:
• -h, --help show this help message and exit
-r, --raw show raw message text, including comments
6. Review
我们列举出至今为止我们用到的命令工具:
• rospack = ros+pack(age) : provides information related to ROS packages
• rosstack = ros+stack : provides information related to ROS stacks
• roscd = ros+cd : changes directory to a ROS package or stack
• rosls = ros+ls : lists files in a ROS package
• roscp = ros+cp : copies files from/to a ROS package
• rosmsg = ros+msg : provides information related to ROS message definitions
• rossrv = ros+srv : provides information related to ROS service definitions
• rosmake = ros+make : makes (compiles) a ROS package
7.Next Tutorial
现在我们创建了一个新的msg和srv,下面我们简单的编写一个发布者及订阅者(python及C++)。