LinMao's Blog
学习科研记录与分享!

ROS(Robot Operating System)

ROS介绍

ROS是一个适用于机器人的开源的元操作系统。它不是一个真正的操作系统,但它提供了操作系统应用的服务,包括硬件抽象,底层设备控制,常用函数的实现,进程间消息传递,以及包管理。它也提供用于获取、 编译、编写、和跨计算机运行代码所需的工具和库函数。 它主要采用的是松耦合点对点进程网络。

设计思想

设计思想主要是分布式架构,将机器人的功能和软件,做成一个个节点,然后每个节点通过topic进行沟通,但你这些节点可以部署在同一台机器上,也可以部署在不同机器上,还可以部署在互联网上。

核心概念

1. Nodes(节点)

节点是各自独立的可执行文件,能够通过话题、服务或参数,与服务器或其他进程(节点)通信。ROS通过使用节点的方式将代码和功能解耦,提高了系统容错能力和可维护性,使系统简化。同时,节点允许了ROS系统能够布置在任意多个机器上并同时运行。关于节点需要注意的事项,节点在系统中必须有唯一的名称;节点可以使用不同的库进行编写,如roscpp和rospy,其中roscpp基于C++,rospy基于Python。

2. Messages and Topics(消息与话题)

节点之间通过topic机制进行通信,topic机制是一个一对多的Publish/Subscribe 模式: 同一个话题也可以有很多个订阅者,它的底层传输依靠的是TCP/IP,也可以是UDP。topic具体传输的message,具有一定的类型和数据结构,包括ROS提供的标准类型,和用户自定义类型。

3. Services and Parameters(服务与参数)

除了topic,ROS还提供另一种一对一的机制,也就是Service/Client,当你需要直接与节点通信并获得应答时,将无法通过话题实现,这时需要使用该服务。

4. ROS Master(ROS管理器)

Master向ROS系统中其他节点提供命名和注册服务,跟踪和记录话题的发布者和订阅者,使ROS 节点之间能够相互查找。一旦节点找到了彼此,就能建立一种点对点的通信方式。

5. Stacks and packages(堆栈与功能包)

那么如何组织代码呢?这主要依靠功能包(Package) ,ROS中软件组织的基本形式,用于创建ROS程序。功能包包含源代码和功能包清单(Manifest) 。功能包清单提供关于功能包、许可信息、依赖关系、编译标志等的信息。功能包清单是一个manifests.xml文件,通过这个文件能够实现对功能包的管理。

核心模块

ROS核心模块包括通信结构基础、机器人特性功能以及工具集,通信结构基础包括消息传递、记录和回放消息、远程过程调用、分布式参数系统;机器人特性功能包括标准机器人消息,机器人几何库,机器人描述语言,抢占式远程过程调用,诊断,位资估计、定位与导航;工具集包括命令式工具、可视化工具以及图形化接口。

安装配置ROS环境

  • 安装直接跟着教程走就行,参见官方安装教程
  • 配置环境,就是将source /opt/ros/<distro>/setup.bash添加到~/.bashrc文件中就行。
  • 创建ROS工作空间,有两种方式:catkin和rosbuild。catkin比较新且比较灵活,rosbuild比较旧但是简单。鉴于rosbuild慢慢可能不维护,还是选择用catkin比较好。

    上面生成的devel文件夹中会有几个setup.*sh文件,source这些文件中对应的shell文件,就可以将当前工作区设置在ROS工作环境的最顶层,查看是否将当前工作区设置成最顶层(每次新开终端都source一下):

    至此,工作做环境搭建完成了。

    再来看一看什么是catkin工作区(catkin workspace)?catkin工作区就是一个文件夹,在这个文件夹里面modify,build和install catkin package,下面是catkin workspace的建议也是典型的工作区文件树:

    一个工作区最多可以包括四个不同的子工作区:

    Source Space:用来存放源码;

    Build Space:在Source Space中调用CMake构建catkin包;

    Development (Devel) Space:在安装之前放置已构建的目标;

    Install Space:build完成后可以调用安装到Install Space中,通常使用make install;

    Result space:When ever referring to a folder which can either be a development space or an install space the generic term result space is used,贴上原文,应该用的不多。

ROS文件系统介绍

两个文件系统的概念:

  • Packages: 软件包,是ROS应用程序代码的组织单元,每个软件包都可以包含程序库、可执行文件、脚本或者其它手动创建的东西。
  • Manifest (package.xml): 清单,是对于’软件包’相关信息的描述,用于定义软件包相关元信息之间的依赖关系,这些信息包括版本、维护者和许可协议等。

几个文件系统的工具:rosbash

  • rospack命令:rospack可以用来获取包的相关信息。这里只用到了rospackfind参数选项,该选项可以返回软件包的路径信息。
  • roscd命令:roscdrosbash命令集中的一部分,它允许你直接切换工作目录到某个软件包或者软件包集当中。这个命令就像ubuntu中的cd命令,但是后面接的命令是包名。就像ROS中的其它工具一样,roscd只能切换到那些路径已经包含在ROS_PACKAGE_PATH环境变量中的软件包。
  • rosls命令:rosls是rosbash命令集中的一部分,它允许你直接按软件包的名称而不是绝对路径执行ls命令(罗列目录)。用法和注意问题和roscd一样。

创建ROS程序包

一个catkin程序包由以下组成:

  • 该程序包必须包含catkin compliant package.xml文件,这个package.xml文件提供有关程序包的元信息。
  • 程序包必须包含一个catkin 版本的CMakeLists.txt文件,而Catkin metapackages中必须包含一个对CMakeList.txt文件的引用。
  • 每个目录下只能有一个程序包,也就是说在同一个目录下不能有嵌套的或者多个程序包存在。

最简单的程序包看起来像下面这样:

在catkin工作空间中的程序包可能看着想下面这样:

如何创建catkin程序包?

程序包之间的依赖

  • 一级依赖,使用上面命令创建程序包时候指定的依赖都保存在package.xml中;可以使用rospack命令工具来查看程序包的一级依赖。
  • 间接依赖包,一个程序包可能依赖的包又依赖其他的包,可以用rospack命令递归的检测出所有依赖的包。

自定义程序包

  • 自定义生成的package.xml,弄清楚几个标签的含义。
  • 自定义CMakeLists.txt

编译ROS程序包

用catkin make编译ROS程序包

传统CMake标准工作流程:

而在ROS中多个catkin项目放在一个工作区中一起编译流程:

编译完成以后像上面创建工作区一样在目录下有三个文件夹:build,devel和src。build 目录是build space的默认所在位置,同时cmake 和 make也是在这里被调用来配置并编译你的程序包。devel 目录是devel space的默认所在位置, 同时也是在你安装程序包之前存放可执行文件和库文件的地方。

理解ROS节点

图概念概述:

  • Nodes:节点,一个节点即为一个可执行文件,它可以通过ROS与其它节点进行通信。
  • Messages:消息,消息是一种ROS数据类型,用于订阅或发布到一个话题。
  • Topics:话Topics题,节点可以发布消息到话题,也可以订阅话题以接收消息。
  • Master:节点管理器,ROS名称服务 (比如帮助节点找到彼此)。
  • rosout: ROS中相当于stdout/stderr。
  • roscore: 主机+ rosout + 参数服务器 (参数服务器会在后面介绍)。

主要介绍了3个命令:

roscore命令:roscore是运行所有ROS程序之前首先要运行的命令。

执行完看到下面的输出started core service表示启动了roscore,如果没有正常启动,可能是网络配置问题。

如果提示权限问题,可能是~/.ros文件夹是root用户的,将归属关系改成当前用户就行。

必须先正确启动roscore再运行其他的ros程序,并且运行roscore以后,让终端一直后台运行着。

rosnode命令:节点相关的命令

rosrun命令:允许你使用包名直接运行一个包内的节点(而不需要知道这个包的路径).

ROS话题

先来一个用键盘移动小乌龟的例子:

turtlesim_node节点和turtle_teleop_key节点之间是通过一个ROS话题来互相通信的。turtle_teleop_key在一个话题上发布按键输入消息,而turtlesim则订阅该话题以接收该消息。

rqt_graph节点:创建一个显示当前系统运行情况的动态图形,rqt_graph是rqt程序包中的一部分,执行如下命令安装(早期的版本,rqt可能不可用,使用rxgraph代替):

在终端中运行rqt_graph命令查看当前节点通信图:

然后会看到节点通信图:

上图表示turtlesim_node和turtle_teleop_key节点正通过一个名为 /turtle1/command_velocity的话题来互相通信。

ROS Topic

rostopic命令:这个命令工具可以获取ROS话题有关的信息。

上面常用的几个命令:

ROS Messages

话题中间的通信是通过节点之间的ROS消息实现的。对于发布器(turtle_teleop_key)和订阅器(turtulesim_node)之间的通信,发布器和订阅器之间必须发送和接收相同类型的消息。这意味着话题的类型是由发布在它上面的消息类型决定的。使用rostopic type命令可以查看发布在某个话题上的消息类型。

rostopic type命令:用来显示所发布的话题的消息类型

rostopic pub命令:可以把数据发布到当前某个正在广播的话题上

-1:这个参数选项使rostopic发布一条消息后马上退出

/turtle1/cmd_vel:这是消息所发布到的话题名称

geometry_msgs/Twist:这是所发布消息的类型

--:告诉命令选项解析器接下来的参数部分都不是命令选项

rostopic hz命令:用来查看数据发布的频率

rqt_plot节点:可以实时显示一个发布到某个话题上的数据变化图形。

理解ROS服务和参数

ROS Services

服务(services)是节点之间通讯的另一种方式。服务允许节点发送请求(request) 并获得一个响应(response).

rosservice命令:rosservice提供了很多可以在topic上使用的命

rosservice list命令:

list 命令显示turtlesim节点提供了9个服务:重置(reset)清除(clear)再生(spawn)终止(kill)turtle1/set_pen/turtle1/teleport_absolute/turtle1/teleport_relativeturtlesim/get_loggers, and turtlesim/set_logger_level. 同时还有另外两个rosout节点提供的服务: /rosout/get_loggers and /rosout/set_logger_level.

rosservice type命令:

rosservice call命令:

ROS Param

rosparam使得我们能够存储并操作ROS 参数服务器(Parameter Server)上的数据。参数服务器能够存储整型、浮点、布尔、字符串、字典和列表等数据类型。rosparam使用YAML标记语言的语法。一般而言,YAML的表述很自然:1 是整型, 1.0是浮点型, one是字符串, true是布尔, [1, 2, 3]是整型列表, {a: b, c: d}是字典。如下所示:

rosparam list命令:

rosparam setrosparam get命令:

rosparam dumprosparam load命令:存储这些参数服务器信息以备今后重新读取

使用rqt_console和roslaunch

rqt_consolerqt_logger_level工具:这两个工具可以用来进行调试。

rqt_console属于ROS日志框架(logging framework)的一部分,用来显示节点的输出信息。

rqt_logger_level允许我们修改节点运行时输出信息的日志等级(logger levels)(包括 DEBUG、WARN、INFO和ERROR)。

上面的调试工具,没有必要深究,先用起来再来弹调试,直接看下面的roslaunch命令。

roslaunch命令

roslaunch可以用来启动定义在launch文件中的多个节点

创建Launch文件

创建一个名为turtlemimic.launch的launch文件并写入一下内容:

现在分析一下上面的Launch文件

上面<launch>标签表示这是一个launch文件

上面表示这里创建了两个节点分组并以’命名空间(namespace)’标签来区分,其中一个名为turtulesim1,另一个名为turtlesim2,两个组里面都使用相同的turtlesim节点并命名为’sim’。这样可以让我们同时启动两个turtlesim模拟器而不会产生命名冲突。

在这里启动模仿节点,并将所有话题的输入和输出分别重命名为turtlesim1和turtlesim2,这样就会使turtlesim2模仿turtlesim1。

roslaunching:现在开始用roslaunch命令来启动launch文件

使用rosed编辑ROS中的文件

rosed 是 rosbash的一部分。利用它可以直接通过package名来获取到待编辑的文件而无需指定该文件的存储路径。

设置编辑器,rosed默认的编辑器是vim,更改默认编辑器需要修改你的 ~/.bashrc 文件:

创建ROS消息和ROS服务

  • 消息(msg): msg文件就是一个描述ROS中所使用消息类型的简单文本。它们会被用来生成不同语言的源代码。
  • 服务(srv): 一个srv文件描述一项服务。它包含两个部分:请求和响应。

msg文件存放在package的msg目录下,srv文件则存放在srv目录下。

 

msg文件实际上就是每行声明一个数据类型和变量名。可以使用的数据类型如下:

  • int8, int16, int32, int64 (plus uint*)
  • float32, float64
  • string
  • time, duration
  • other msg files
  • variable-length array[] and fixed-length array[C]

在ROS中有一个特殊的数据类型:Header,它含有时间戳和坐标系信息。在msg文件的第一行经常可以看到Header header的声明.

srv文件分为请求和响应两部分,由’—‘分隔。下面是srv的一个样例:

使用msg

  • 创建一个msg

    接下来,还有关键的一步:我们要确保msg文件被转换成为C++,Python和其他语言的源代码:

    用编辑器打开 CMakeLists.txt文件,在 CMakeLists.txt文件中,利用find_packag函数,在find_packag函数中增加对message_generation的依赖,这样就可以生成消息了.

    同样,需要在 CMakeLists.txt文件中设置运行依赖:

    去掉注释符号#,用你的.msg文件替代Message*.msg,就像下边这样:

    添加.msg文件后,要确保CMake知道在什么时候重新配置project,保添加了如下函数(取消注释):
  • 使用rosmsg验证创建的msg上面的步骤完成后,使用rosmsg show命令检查ROS是否能够识别消息

使用srv

  • 创建一个srv

    这里不手动创建服务,而是使用roscp命令从其他package中复制一个服务。

    同样还有很关键的一步:我们要确保srv文件被转换成C++,Python和其他语言的源代码

    和上面一样,先在CMakeLists.txt文件中增加对message_generation的依赖:

    可以发现,message_generation 对msgsrv都起作用。

    用你自己的srv文件名替换掉那些Service*.srv文件:

  • rossrv命令验证生成的service

msg和srv都需要的步骤

打开CMakeLists.txt文件,找到如下部分并去掉注释,并附加上所有消息文件所依赖的那些含有.msg文件的package(上面这个例子是依赖std_msgs,不要添加roscpp,rospy)

由于增加了新的消息,所以我们需要重新编译我们的package:

至此,所有在msg路径下的.msg文件都将转换为ROS所支持语言的源代码:

生成的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/ 路径下。

编写简单的消息发布器和订阅器 (C++)

项目想用python来写,C++这部分不看了。

编写简单的消息发布器和订阅器 (Python)

编写发布器节点

节点(Node) 是指 ROS 网络中可执行文件。接下来,创建一个发布器节点(“talker”),它将不断的在 ROS 网络中广播消息。

代码解释

可以使用rosed beginner_tutorials talker.py命令或者其他编辑器查看源码如下:

现在逐行解释上面代码:

指定python脚本解释器,一般可执行文件的方式执行python时,在代码中指定python脚本解释器

用python来编写节点首先要import rospy;然后import std_msgs.msg中的String消息类型用来发布消息

这部分定义了这个消息发布器的接口。第一句表明节点使用消息类型String发布到chatter话题;这里的String实际上是类std_msgs.msg.String;queue_size指定当接收器来不及接受消息,在发送队列中存放消息的最大数量,旧的ROS发行版中没有这个参数。

这句很重要,它告诉rospy将要创建的节点名称,只有rospy直到这个消息以后节点才可以和ROS Master通信。这里表示向rospy说明将要创建的节点名称为:talker;anonymous=True表示通过添加一个随机的数给节点来唯一标示节点名。

创建rate对象来控制循环速率(通过sleep()方法实现),在这里表示每秒循环10次(只要每次处理时间不超过1/10秒)。

这个循环是一个标准的rospy结构:先检查rospy.is_shutdown( )标志然后执行下面的工作,rospy.is_shutdown( )标志用来检查程序是否退出。ospy.loginfo(str)有三个作用:消息被打印到屏幕,消息被写入Node的日志文件以及被写入rosout。rosout对于调试非常方便:可以使用rqt_console来提取消息,而不必使用Node的输出找到控制台窗口。pub.publish(hello_str)向chatter话题广播一个字符串。rate.sleep()用来调节时间以确保以上面设置的频率向话题发送消息,通用也可以使用rospy.sleep( )来达到相同的目的。

std_msgs.msg.String 是一个非常简单的消息类型,也可以构造更复杂的消息类型。一般经验是构造函数args的顺序与.msg文件中的顺序相同。

当按下Ctrl-C或您的节点关闭时,可以通过rospy.sleep()和rospy.Rate.sleep()方法抛出rospy.ROSInterruptException异常。

编写订阅器节点

现在,创建一个订阅器节点(“listener”),用来接收发布器节点(“talker”)广播的消息。

代码解释

下载的代码如下:

下面逐行解释代码:

ROS中要求每个节点拥有唯一的名字,如果新建的节点名字和之前的重复,那么将会覆盖之前的节点,这个特性可以很容易的去除故障节点。第一句是创建’listener’节点,该节点像上面一样使用了anonymous=True参数,表示生成唯一名称,以便轻松的运行多个’listener’节点。

第二句声明创建的节点订阅了std_msgs.msgs.String类型的chatter话题,收到新消息时,将调用回调,并将消息作为第一个参数。

最后一句,rospy.spin()是为了直到节点关闭才退出。与roscpp不同,rospy.spin()不会影响订阅者回调函数,因为它们有自己的线程。

编译节点

测试消息发布器和订阅器

启动发布器

启动订阅器

编写简单的服务器和客户端 (C++)

项目想用python来写,C++这部分不看了。

编写简单的Service和Client (Python)

编写Service节点

这里将创建一个简单的service节点(“add_two_ints_server”),该节点将接收到两个整形数字,并返回它们的和。

创建 scripts/add_two_ints_server.py文件,并粘贴下面的代码然后赋予可执行权限:

代码解释

上面这句代码表示使用AddTwoInts服务类型声明一个名为add_two_ints的新服务,handle_add_two_ints使用AddTwoIntsRequest的实例调用,并返回AddTwoIntsResponse的实例。

编写Client节点

创建scripts/add_two_ints_client.py文件,并粘贴下面的代码然后赋予可执行权限:

代码解释

调用服务的客户端代码也很简单,对于客户端,您不必调用init_node()。我们先调用

这可以block一直到add_two_ints服务可用,接下来,我们创建一个用于调用服务的句柄:

可以像普通函数一样使用这个句柄并调用它:

因为已经将服务的类型声明为AddTwoInts,所以它会生成AddTwoIntsRequest对象(不用自己传递)。返回值是AddTwoIntsResponse对象,如果调用失败,可能会抛出rospy.ServiceException。

编译节点

测试简单的Service和Client

录制与回放数据

将ROS系统运行过程中的数据录制到一个.bag文件中,然后通过回放数据来重现相似的运行过程。

这部分和项目没有太大关系,粗略看一下。

roswtf入门

roswtf,名字怪怪的。。是一个用来检查ROS系统并尝试发现问题的工具。

现在也用不太招,粗略看一下。

探索ROS维基

说明怎么使用ROS维基网站,并在并在上面找问题。

教程注明已过时,不看了。

接下来做什么?

这个介绍了一些机器人模拟器和一些程序包,现在用不着,扫了一眼。至此,20个初级教程看完了。

 

 

Reference:

核心 ROS 教程

机器人程序设计之如何正确入门ROS | 硬创公开课

 

 

 

 

 

 

 

赞(0) 打赏
转载请注明出处:LinMao's Blog(林茂的博客) » ROS(Robot Operating System)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

LinMao's Blog(林茂的博客)

了解更多联系我们

觉得文章有用就打赏一下作者吧~

支付宝扫一扫打赏

微信扫一扫打赏