[译]机器人操做系统简介:终极机器人应用框架(上)

[译]机器人操做系统简介:终极机器人应用框架

/**
 * 原文出处:https://www.toptal.com/robotics/introduction-to-robot-operating-system
 * @author dogstar.huang <chanzonghuang@gmail.com> 2016-03-05
 */

机器人操做系统(ROS)不是一个真实的操做系统,而是一个框架以及一系列为运行在异质计算机集群的操做系统提供基础功能的工具。 它的用处不局限于机器人,还包括大量关注与外设一块儿工做的工具。html

ROS 分红2000多个包,每一个包提供特定的功能。连续框架的工具数量多是它的最大功率。node

为何我应该用ROS?

ROS提供了硬件抽象,设备驱动,多机器进程间的通讯,测试和可视化的工具等功能。
python

ROS的关键特性是软件运行和沟通的方式,使得你能够设计复杂的软件而不须要知道相关的硬件如何工做。ROS提供了一种利用中央枢纽链接进程(节点)网络的方式。 节点能够运行在众多设备上,而且能够经过各类途径与中央枢纽进行链接。git

建立网络的主要方式有提供可请求的服务,或者定义与其余节点的发布/订阅者链接。这两种方法都是经过指定消息类型来通讯的。 一些类型由核心包提供,而消息类型则可由用户包来定义。github

对于小型问题,开发人员能够经过链接已存在的解决方案来集成一个复杂的系统。这种方式的系统已经实现,它容许咱们:算法

  • 在fly上用熟悉的接口替换组件,以便为各类变化移除中止系统的须要编程

  • 为另外一个组件把众多组件的输出混合成一个输出,以便并行解各种问题ubuntu

  • 只要实现消息系统对应的合适链接器就能够链接各类各样编程语言创造的组件,使得经过链接来自大量开发人员已存在的模块进行软件开发很容易bash

  • 建立基于设备网络的节点,而不用关心代码在哪里运行以及实现进程通讯(IPC)和远程过程调用(RPC)系统网络

  • 根据远程硬件的须要,经过部署前两个要点便可直接链接馈送,而不用编写任何额外的代码

咱们在计划演示经过迭代开发一个简单方案是多么地有用。相比于其余方式,这里有几个关键的好处。ROS有多平台支持以及容许经过隐藏于表面的点对点链接进行多设备的进程链接。 此设计容许支持任何包装了C++通讯类的任何语言,或者手动为语言接口开发类。

ROS由咱们的社区建立,意味着它也回归于社区。多亏于这个系统架构,通过若干年后,这种氛围致使了大量可重用并易于集成的包的涌现。

一些变种如:http://www.mrpt.org/http://carmen.sourceforge.net/intro.htmlhttp://lcm-proj.github.io/http://playerstage.sourceforge.net/https://msdn.microsoft.com/en-us/library/bb648760.aspx 等提供了其中一些特性,但不是所有。 大多数时候,设计的衰落在于语言支持的局限,未优化进程通讯,或者按理说是最难修复的问题 -- 缺乏对大量设备的支持。

咱们准备构建什么?

既然咱们的关注点是框架而不是针对特定问题的具体算法,因此给定的问题是至关简单的。咱们的目标就是为一个车载的计算机构建经过Wi-Fi链接的软件, 从而能够经过使用电脑上的游戏把柄和安装在机器人上的摄像机来远程控制和监控机器人。

首先,为了示范ROS的基本原则,咱们将会建立一个简单的程序来链接一个简单的模拟。咱们会把游戏手柄绑定到电脑上而且尝试为能把游戏手柄输入转换成机器人控制信息而设计一个好的控制方案。

编写ROS代码的只要语言是C++和Python,首选C++是由于它的性能。因为代码中更少的样板和不须要明确的构建,咱们将会经过Python来解释示例。

安装与配置

ROS版本由名称来组成。如如今这个日期,最新的发布版本是_Jade Turtle_,而最新的LTS版本是_Indigo Igloo_。最好是使用LTS版本,由于ROS不保证向前兼容性,因此所有的示例将使用_Indigo_这个版原本编写。

ROS可用于大量的*NIX平台,官方支持的版本运行于Ubuntu。OS X,Arch Linux,Debian,Raapbain 和Android版本则由社区支持。

咱们将经历在Ubuntu 14.04桌面的安装过程。所有支持的版本和平台的过程均可在官网得到。带ROS的虚拟机也有。

安装是平台依赖性的(大部分平台都有本身提供的包),而工做区间的配置对于所有平台来讲都是同样的。

在Ubuntu上安装

ROS提供了本身的仓库。第一步就是要添加它们。

sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'
sudo apt-key adv --keyserver hkp://pool.sks-keyservers.net --recv-key 0xB01FA116
sudo apt-get update

而后会有针对你的Ubuntu版本的所有ROS的所有托管包。例如,Ubuntu 14.04支持indeigo和jade。

在桌面上安装基本的包能够三选一:

  • 最小化安装:sudo apt-get install ros-indigo-ros-base

  • 带基本额外GUI工具的:sudo apt-get install ros-indigo-desktop

  • 全量安装,即有所有官方特性的,包含了大量模拟器以及导航和知觉类库:sudo apt-get install ros-indigo-desktop-full

为了得到最好的工做体验,推荐全量安装。对于仅仅是用于运行节点的设备安装,基本版本则足够了。不和你选择的是哪一个选项,你均可以安装任何须要的package_name包经过执行:

sudo apt-get install ros-indigo-<package-name>

最终的名字将会把下划线替换成横线,因此stage_ros在这个包里

ros-indigo-stage-ros

下一步是安装rosdep。在ROS的包能够声明他们依赖的包。rosdep容许你编译这些包而不用过多地人工维护依赖处理。为了安装它,调用:

sudo rosdep init
rosdep update

ROS有几个被它的工具使用的环境变量。默认的安装,bash脚本在/opt/ros/indigo/setup.bash初始化他们。在每一个bash的会话中都须要初始化这些变量,因此最好的解决方案是把他们添加到~/.bashrc。

echo "source /opt/ros/indigo/setup.bash" >> ~/.bashrc
source ~/.bashrc

一些包经过rosinstall来安装扩展的依赖,rosinstall可做为一个包来得到并可经过sudo apt-get install python-rosinstall安装。

这里到了在Ubuntu上安装的最后。接下来是安装工做区间的简短介绍。

配置

自从_Groovy Galapagos后_,ROS工做区间经过catkin来管理。咱们须要为所有托管的负定义一个目录。在这个目录里建立一个src目录,并在里面调用catkin_init_workspace。 这将会建立大量的连接到当前ROS版本源的符号。下一步是把这个工做音区也添加到环境变量。

为了演示整个工做区间的配置,选择一个空的目录并执行如下命令:

mkdir src
cd src
catkin_init_workspace
cd ..
catkin_make
echo "source $(pwd)/devel/setup.bash" >> ~/.bashrc
source ~/.bashrc

如今你已经建立了一个能够在里面建立本身ROS包的工做区间。

熟悉工具

立刻建立代码是一个很大的跨越。让咱们先来熟悉一些运行在屏幕后的系统。第一步是运行基本的GUI并看下它生成了什么消息。

为了在ROS中运行一些东西,须要加载一个核心的进程。这一点很简单,只要在一个新的终端窗口并输入:

roscore

在你的整个链接设备网络中,roscore仅须要在为通讯分发托管中央枢纽的设备上加载一次。

roscore的主要角色是告诉节点他们应该链接哪一个节点,以及经过哪一种方式(不论是经过网络端口仍是共享内存)。这样的目的是为了在最小化时间和运行所有通讯所须要的带宽时, 让节点只关心他们想知道的数据,而不是他们想要链接的节点。

rqt

运行roscore后,能够为ROS加载主要的GUI工具:rqt。咱们会看到很通常的东西 -- 一个空白的窗口。rqt托管了很是大量的能够在可视化配置中进行配置的插件 以及任何数量的预约义视图。

为了可以开始,先运行插件_Robot Steering_,能够经过Plugins > Robot Tools > Robot Steering来选择它。咱们会看到有两个滑块,表明着咱们的机器人将会拥有的线性和旋转运动。 在插件的顶部能够看到一个有/cmd_vel的输入框。咱们能够任意进行重命名。它表明了此操舵发布的主题。终端工具是看到在后台运行了什么的最好地方。

终端工具

ROS有几个很是有用的工具来检查系统中正在发生什么。第一个咱们将会介绍的工具是rostopic。 它容许咱们检查节点能够评阅和发布的主题。运行```rostopic list···将会产生:

/cmd_vel
/rosout
/rosout_agg

后两个主题一般都会运行而且与中央ROS系统相关。/cmd_vel主题则由咱们的操舵发布。在操舵中重命名这个主题也会在这里重全名。如今,咱们对于在这个主题里面发生的东西感兴趣。 运行rostopic echo /cmd_vel将看不到什么东西(除非你对滑块做了调整)。这个进程会一直执行,直到咱们取消它。让咱们把垂直滑块移到20 m/s。看着输出,咱们会看到如下一次又一次重复的内容:

linear:
  x: 0.2
  y: 0.0
  z: 0.0
angular:
  x: 0.0
  y: 0.0
  z: 0.0

这个消息重复的频率是多少?rostopic hz /cmd_vel说平均频率是10Hz。好吧,经过我很慢的Wi-Fi链接能够运行多少像这样的主题?rostopic bw /cmd_vel代表平均是480B/s。

到目前为止一切运行良好,但咱们将要讨论消息类型。这种数据对于人类是友好的,但应用须要raw格式的数据,而且须要知道消息类型以便它能解析数据。 类型能够经过rostopic type /cmd_vel来决定,告诉咱们这是一个geometry_msgs/Twist。任何ROS终端的工具无参数调用时都会返回一个标准的帮助消息。

ROS的wiki很是赞,在网页搜索这个字符串会找到一系列的解释,从它包括了什么到它的结构是怎样的应有尽有。可是咱们不用依赖于它。rosmsg是针对消息类型的通用工具。 运行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

这个消息包含了两个3D向量,表示在三维空间中的线性和旋转速度。

若是咱们想知道一个节点链接了什么主题,rosnode info <node-name>会给出关于节点的详细数据。rostopic,rosmsg和rosnode是检查raw ROS功能的主要工具。 ROS有大量的GUI和终端工具,但这些已超出了此次简介的范畴。

运行ROS节点的主要工具是rosrun和roslaunch。rosrun经过rosrun <package_name> <node_name>来运行节点,而roslaunch则基于加载 因为是ROS自动化中最为复杂的元素因此咱们知之甚少的文件来运行节点。

咱们能够关闭运行的所有东西以开启咱们最初的代码。在下文中,咱们将省略说明运行任何和ROS相关的东西都须要一个活跃的roscore实例。你遇到的不少问题均可以经过关闭 运行roscore对应的窗口来解决,而且新开一个窗口从新加载。这样的话会更新所有须要从新加载的依赖,包括在bash和在roscore中。

建立游戏柄遥

咱们第一个目标是经过建立一个发布geometry_msgs/Twist数据给基于游戏柄输入的/cmd_vel来模拟Robot Steering的功能。第一步的产出是joy包。

joy包

这个joy包为操纵杆和游戏柄提供了通用的ROS驱动。它没有包含在默认的安装,因此须要这样进行安装:

sudo apt-get install ros-indigo-joy

安装完成后,能够运行rosrun joy joy_node。这会把咱们和默认的操纵杆或者游戏链接起来。运行rostopic list能够看到有一个叫/joy的主题。经过rostopic echo能够 看到如下格式的消息(请注意你须要使用游戏柄或操纵杆解析待发布的消息)。

header:
  seq: 4156
  stamp:
    secs: 1450707466
    nsecs: 204517084
  frame_id: ''
axes: [0.0, 0.0, 0.0, -0.0, 0.0, 0.0, 0.0, 0.0]
buttons: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

如今你能够忽略头部。除此以外,axes和buttons恰到好处地解析了他们表明什么。移动轴和按下在控制器上的按钮会致使这些数字发生变化。使用咱们的工具,能够决定这个消息类型 是sensor_msgs/Joy而且对应的格式是:

std_msgs/Header header
  uint32 seq
  time stamp
  string frame_id
float32[] axes
int32[] buttons

建立咱们的遥

编写代码的第一步是建立一个包。在工做区间的src目录里,运行:

catkin_create_pkg toptal_tutorial rospy joy geometry_msgs sensor_msgs

在这里咱们声明了将要建立的包名,紧跟随后的是所要依赖的包。无须担忧,依赖能够稍候手动更新。

如今咱们有了toptal_tutorial目录。在这个目录里,建立一个将会放置所有Python脚本的scripts目录。

如今来建立一个teleop.py文件,并在里面放置:

#!/usr/bin/env python import rospy from sensor_msgs.msg import Joy def joy_callback(data): print data def main(): rospy.init_node('teleop') rospy.Subscriber('joy', Joy, joy_callback) while not rospy.is_shutdown(): pass if __name__ == '__main__': main()

咱们还须要设置chmod +x teleop.py以便脚本能被执行。在某个终端上运行rosrun joy joy_node并有另外一个终端上运行rosrun toptal_tutorial teleop.py将会致使运行teleop.py的终端被输出的Joy消息填充。

让咱们来检查一下代码作了什么。

首先,导入托管了与ROS框架交互的类库的rospy。每个定义了消息的包都有一个带消息定义的msg子包。咱们导入了Joy以即可以处理输入。 这里不须要导入嵌入式的消息类型(如来自在Joy消息中的std_msgs.msg的Header),除非咱们想明确地说起他们。

第一步是初始化一个指定名字的节点(在这里,咱们把它叫做“teleop”)。而后建立一个订阅者来订阅sensor_msgs.msg.Joy类型的“joy”主题,而且经过 回调joy_callback函数来处理每个消息。回调接收一个参数,即来自消息的数据。访问这个数据的成员很是简单。若是想打印第一个轴的状态,或者想 从新调用这个消息类型,能够调用print data.axes[0],而且是一个浮点类型。在最后的循环会一直循环直到ROS关闭。

下一步是处理未知的数据。咱们会建立一个根据输入而改变的Twist消息,而后会把它发布到cmd_vel主题。

#!/usr/bin/env python import rospy from sensor_msgs.msg import Joy from geometry_msgs.msg import Twist # new from functools import partial # new def joy_callback(pub, data): # modified cmd_vel = Twist() # new cmd_vel.linear.x = data.axes[1] # new cmd_vel.angular.z = data.axes[0] # new pub.publish(cmd_vel) # new def main(): rospy.init_node('teleop') pub = rospy.Publisher('cmd_vel', Twist, queue_size=1000) # new rospy.Subscriber('joy', Joy, partial(joy_callback, pub)) # modified while not rospy.is_shutdown(): pass if __name__ == '__main__': main()

首先,添加Twist消息,而且为经过functools.partial绑定函数参数添加支持。而后建立一个发布者,pub,来把一个Twist消息类型发布给cmd_vel。咱们把这个发布者和回调函数进行绑定,并使它为每个由前两个轴表明的速度的输入都发布一个Twist消息。 这些代码作了咱们指望的它作的事情,并且能够经过rostopic echo /cmd_vel看到结果的输出。

但咱们还有一个问题。joy主题发布的速度会很大。若是监控rostopic hz /cmd_vel并在圆圈中移动模拟遥杆,能够看到超级大量的消息。 这不只仅致使了大量的通讯,还致使了接收这些消息的进程须要一个个地处理他们。其实并不须要如此频繁地发布这些数据,最好是以一个稳定的速率如10Hz来发布。 能够经过如下代码来实现。

#!/usr/bin/env python import rospy from sensor_msgs.msg import Joy from geometry_msgs.msg import Twist from functools import partial def joy_callback(cmd_vel, data): # modified cmd_vel.linear.x = data.axes[1] cmd_vel.angular.z = data.axes[0] # moved pub.publish(cmd_vel) to main loop def main(): rospy.init_node('teleop') cmd_vel = Twist() # new pub = rospy.Publisher('cmd_vel', Twist, queue_size=1000) rospy.Subscriber('joy', Joy, partial(joy_callback, cmd_vel)) # modified rate = rospy.Rate(10) # new while not rospy.is_shutdown(): pub.publish(cmd_vel) # new rate.sleep() # new if __name__ == '__main__': main()

咱们修改了回调函数以便接收可变的Twist对象而且在循环中做了修改。来自rospy.Rate的sleep函数维护了一个稳定的输出频率。

最后的代码将会致使/cmd_vel主题以10Hz来得到速度命令,以模拟_Robot Steering_ ···rqt```插件的输出。


下一篇:[译]机器人操做系统简介:终极机器人应用框架(下)


------------------------    

相关文章
相关标签/搜索