近年来, 伴随人工智能技术和传感技术等新型技术的快速发展, 智能机器人技术获得了突飞猛进的进步. 与之对应的是机器人相关体系结构和操作系统迎来了发展的黄金时期, 出现了以ROS为代表的专用于机器人的操作系统[].
鉴于ROS操作系统在架构的模块化与层次化上的良好表现, 国内外很多学者都基于ROS进行了有关研究与技术实现, 如基于ROS实现机器人的各子功能部件的三维建模与开发[]有效降低了工作复杂度、使用ROS作为机器人控制的嵌入式底层避免了对策略核心的重复设计与实现[]、通过ROS提供的各种功能包来进行二次开发[]以期减少成本投入以及使用ROS进行相关仿真实验[]取代实际重复性或长周期的实地实验, 并能保证更高精度的数据获取等. 除此之外, 国外研究大多集中于具体ROS应用的实现, 包括但不限于基于ROS的仿人双臂机器人PR2[]的实现、汽车自动驾驶路径规划与导航[]的实现、家用服务型机器人系统[]的实现、医疗辅助式机器人交互逻辑[]的实现等.
除直接基于ROS操作系统进行机器人方面的工作外, 也有部分开发人员考虑借鉴ROS的逻辑, 为专门化的机器人提供相应的操作系统, 这种操作系统在保留ROS的主要功能和特点的前提下, 都会在某一特定方面做出一定优化, 以期更好地控制与服务于相关机器人. 其中有代表性的是ROCOS操作系统, 主要实现了多台机器人的配合调度.
本文将对ROS和其变种ROCOS做简要介绍, 并详细对比分析两者的架构逻辑, 希望对有关机器人系统研究方面的人员提供一定的参考价值.
ROS (Robot Operating System), 即机器人操作系统, 是用于编写机器人软件程序的一种具有高度灵活性的软件架构, 是一个适用于机器人的开源的元操作系统. 它提供了操作系统应有的服务, 包括硬件抽象, 底层设备控制, 常用函数的实现, 进程间消息传递, 以及包管理. 它也提供用于获取、编译、编写和跨计算机运行代码所需的工具和库函数.
在它诞生之前, 很多专家致力于实现一个能够自我感知、自我导航和自我控制的复杂机器人设计. 过程中, 大家发现很多现有资源难以共享或者直接使用, 所以都认为机器人研究需要一个开放式的协作框架, 用以整合和提高各种资源的利用率. 所以在这样的需求下, 2007年ROS自斯坦福大学诞生, 并在大量研究人员的共同努力下, 逐渐发展和完善. ROS发展历史如图1.
目前, ROS广泛应用于机器人领域, 主要实现机器人的建模、感知、导航和规划, 并能直接和机器人连接通讯, 以实现对其物理实体的控制.
ROCOS是世界杯机器人操作系统(RObotCup Operating System)的英文缩写, 是以ROS操作系统为原型, 剔除不必要的功能分支, 专用于多机器人调度的软件架构.
它源自机器人世界杯RobotCup, 一个为促进人工智能和机器人等相关领域研究的国际项目. 该项目是以足球机器人为主要研究平台, 以推进人工智能和机器人研究的国际比赛, 旨在研究如何在实时性强, 即高动态性和高对抗性的环境中, 调度多台机器人完成指定的工作任务, 和实现多机配合的智能化. 图2是RobotCup赛场实况.
ROCOS最先由卡内基梅隆大学(CMU)在1997年发起构建, 其核心思路是在控制子系统的实现时按照STP (Skill-Tactic-Play)框架进行分层开发, 之后于2012年对其改版, 提出SSPS (Skill-State-Play-Selector)框架,有效提高了各机器人之间的配合度, 在响应机器指令方面也有很大提升.
与此同时, 世界上其他机器人强校如康奈尔大学等也在积极引进ROCOS并投入到对其优化与研发中. 我国浙江大学也在持续跟进, 其控制学院工业控制国家重点实验室于2003年就着手ROCOS的研究, 2020年已形成比较完善的ROCOS版本, 并对ROCOS实效做了相应的测试与研究[10,11]. 表1说明了浙江大学现有ROCOS在世界机器人比赛上的优异表现.
从硬件实现角度, ROS系统可分为3个层次: OS层、中间层和应用层. 其中OS层为底层, 主要使用Linux系统实现(如Ubuntu), 中间层实现ROS核心通信机制以及功能库, 应用层通过运行ROS Master (管理者)来负责系统正常运行.
具体到中间层的实现, 又可将ROS架构细分为计算图层、文件系统层和开源社区层, 如图3.
ROS系统软件的功能模块以节点为单位独立运行, 通过端对端的拓扑结构连接. 所以ROS引进计算图来描述这种拓扑结构, 进而体现程序的运行方式.
计算图的构成方式是: ROS创建一个连接所有进程(节点)的网络, 其中的任何进程(节点)都可以访问此网络, 并通过该网络与其他进程(节点)交互, 获取其他进程(节点)发布的信息, 并将自身数据发布到网络上. 其中, 构成计算图网络的各个节点(node)、主题(topic)、服务(server)等都有唯一的名称做标识.
1)节点: 是主要的计算执行进程, 功能包(在第2.1.2节中详细定义)中创建的每个可执行程序在被启动加载到系统进程中后, 该进程就是一个ROS节点, 如图4中的node1、node2等都是节点. 节点都是各自独立的可执行文件, 能够通过主题(topic)、服务(server)或参数服务器(parameter server)与其他节点通信. ROS通过使用节点将代码和功能解耦, 提高了系统的容错力和可维护性.
2)消息: 节点通过消息(message)完成彼此的沟通. 它是ROS中一个进程(节点)发送到其他进程(节点)的信息. 消息类型是消息的数据结构, ROS系统提供了很多标准类型的消息可以直接使用, 如果要使用非标准类型的消息, 需要进行自定义.
3)主题: 每个消息都必须发布到相应的主题(topic), 通过主题来实现在ROS计算图网络中的路由转发. 节点发送数据被称为该节点正在向主题发布消息. 节点可以通过订阅某个主题, 接收来自其他节点的消息. 通过主题进行消息路由不需要节点之间直接连接, 这意味着发布者节点和订阅者节点之间不需要知道彼此是否存在, 从而保证发布者节点与订阅者节点之间的解耦合.
4)服务: 在一些特殊的场合, 节点间需要点对点的高效率通信并及时获取应答, 此时需要用服务的方式进行交互. 提供服务的节点被称为服务端, 向服务端发起请求并等待响应的节点被称为客户端, 客户端发起一次请求并得到服务端的一次响应就完成了一次服务通信过程. 如图4中node1向node3发起一次请求, 并得到node3返回给node1的响应.
与其他操作系统类似, 一个ROS程序的不同组件需要被放在不同的文件夹下进行管理, 而这些文件夹则根据不同的功能来对文件进行组织, 它们构成了ROS的文件系统.
在文件系统中, 最基本的管理单元就是功能包. 功能包是ROS中软件组织的基本形式, 一个功能包具有用于创建ROS程序的最小结构和最少内容, 它可以包含ROS运行的进程(节点)和配置文件等.
一个功能包可以按照图5的方式分为多个部分, 其中具体到每个子部分如下文.
1)功能包清单: 主要用于记录功能包的信息以及发行者、功能包之间的依赖关系以及编译的相关信息等. 在功能包中扮演管理者的角色.
2)消息类型: 用于描述ROS采用话题通信时消息的类型, 通过该文件可了解这个功能包的相关通信接口.
3)服务类型: 用于描述ROS采用服务通信时服务的类型, 通过该文件也可了解这个功能包的相关通信接口.
4)代码: 节点是通过相应的编程语言进行编写的, 其代码称作源代码, 存放于特定文件夹中.
其中, 由功能包还可以组成更大的功能包, 被称之为元功能包, 用以实现更大、更复杂的功能.
而在元功能包之上, 还有一层文件夹, 被称作工作空间. 工作空间是一个包含功能包、可编译源文件和编译包的文件夹, 当用户想同时编译不同的功能包或保存本地开发包时必须使用这一机制. 用户可根据实际需要创建多个工作空间, 在每个工作空间中开发不同用途的功能包.
如图6所示, 工作空间通常由3种文件夹构成.
1) src源文件空间: 该文件夹放置各个功能包和用于这些功能包的CMake配置文件CMakeLists.txt. 由于ROS中的源码采用catkin工具进行编译, 而catkin工具基于CMake技术, 所以在src源文件空间和各个功能包中都会有CMakeLists.txt, 它起编译配置的作用.
2) build编译空间: 该文件夹放置CMake和catkin编译功能包时产生的缓存、配置、中间文件等.
3) devel开发空间: 该文件夹放置编译好的可执行程序, 这些可执行程序不需要安装就能直接运行. 一旦功能包源码编译和测试通过后, 可以将这些编译好的可执行文件直接导出与其他开发人员分享.
开源社区层是位于ROS架构最外面的层次(注意这里讨论的范围还在中间层, 其实开源社区上还有应用层). 由于ROS的开源让很多人得以共享资源, 这个共享资源的平台称之为ROS的开源社区, 如图7.
ROS的开源社区主要由网站、博客和代码资源构成. 因为ROS有各种功能的功能包, 但ROS安装时只会安装固定的一部分, 所以用户搭建自己的机器人时, 如果需要特定功能的功能包, 可以自己写功能包源码, 也可以从开源社区中寻找, 采用软件源的形式下载别人的功能包来参考使用.
具体的开源社区功能模块构成如下:
1)发行版(Distribution): ROS发行版包括一系列带有版本号、可以直接安装的功能包.
2)软件源(Repository) : ROS依赖于共享网络上的开源代码, 不同的组织机构可以开发或者共享自己的机器人软件.
3)文档社区(Wiki): 记录ROS信息文档的主要论坛.
4)邮件列表(Mailing list): 交流ROS更新的主要渠道, 同时也可以交流ROS开发的各种疑问.
5)问答社区(Answers): 咨询ROS相关问题的网站.
6)博客(Blog): 发布ROS社区中的新闻[12]、图片、视频等内容.
因为ROCOS操作系统是在ROS系统的基础之上做出的单方向(多机调度)的优化. 所以从实现角度看, 其架构与ROS类似, 也可分为3个层次: OS层、中间层和应用层. 其中OS层为底层, 主要使用Linux系统实现(如Ubuntu), 中间层实现ROCOS核心通信机制以及功能库, 应用层主要通过图形界面的模式为用户提供服务.
具体到中间层的实现, ROCOS更加关注具体的机器人仿真与通讯细节, 可将ROS架构细分为后端策略层、前端控制层、文件系统层和开源社区层, 如图8.
后端策略层是ROCOS用于实现机器人操控逻辑、处理I/O信息(如视觉信息、从机器人传回的通讯信息、传感器信息等)和形成指令的控制中心.
在图9中, 机器人的正常运行有赖于多个相互关联系统的信息交互与功能配合. 具体包括: 视觉子系统、决策子系统、通讯子系统、机器人硬件子系统以及场地辅助子系统等. 其中, ROCOS操作系统装载于策略机上, 由其后端策略层处理从其他子系统搜集到的实时信息, 并进行整合、处理与计算, 之后依靠代码逻辑做出相应的决策和命令, 通过通讯机制传输给机器人, 完成逻辑层与物理层之间的配合.
为完成相应功能, 后端策略层需要依赖外置功能包, 并使用合理的框架对功能进行解耦和处理.
涉及到的功能包与运行环境具体包括:
1)开发环境: 为有效组织代码逻辑、合理预留前端控制层需要的接口以及确保应用层较好的可视化效果, 选择具有优良跨平台特性、面向对象的、含丰富API、支持OpenGL的QT作为默认集成开发环境.
2)开发语言: 在ROCOS中, 绝大部分底层逻辑代码采用C++11规范完成开发. 而考虑到多机器人的调度, 使用具有可扩展、简单高效、与平台无关等特性的LUA语言实现相应的功能. (具体实现中需要引入第三方软件包tolua++)
3)相关库: 后端策略层需要对大批量、实时性数据进行处理, 有赖于C++里支持线性代数运算、矩阵和矢量运算、数值分析及其相关的算法的开源模版库Eigen. 另外, 为实现后端策略层和前端控制层、前端控制层和通讯子系统的数据传输, 需要引入与平台和语言无关、可扩展且轻便高效的序列化数据结构协议Protobuf.
具体而言, 后端策略层通过C++和LUA两种计算机语言的有机结合, 用 C++进行各种基础算法、动作任务的编写, LUA进行上层任务的分配, 构建出一个能使机器人从完成一个简单动作到多个机器人进行相互协调配合的框架.
框架结构如图10所示.
1)使用C++完成底层skill动作层的开发: 该层主要完成单台机器人的单个动作, 与硬件实现紧密相关, 如实现到达指定点、转体等.
具体实现框架为:
1. #include “src/utils/PlayerTask.h” ……
2. extern “C”_declspec(dllexport) PlayerTask
player_plan(const WorldModel* model, int robot_id);
3. enum FourQuadrant{LeftUp,……}area;
4. PlayerTask player_plan(const WorldModel* model, int robot_id){
5. PlayerTask task;
6. ……
7. if (ball.y > 0) {
8. if (ball.x > 0) {area = RightUp;}
9. else {area = RightDown;}
10. }
11. else {……}
12. switch (area){
13. case LeftUp:
14. task.orientate = (ball – goal).angle();//dir
15. task.target_pos = point2f(half_x, -half_y);
16. break;
17. case LeftDown:
18. ……}
19. return task;}
2)使用LUA完成task任务层的开发: 该层主要调用多个skill函数, 并将其封装为一个完整的task任务, 用以将该任务分配给单台机器人执行, 如足球机器人执行到达指定点拿球的任务(具体包含到达拿球点skill、控球skill、检测是否拿球skill等).
具体实现框架为:
1. gPlayTable.CreatePlay{
2. firstState = “halt”,
3. switch = function()
4. return “halt”
5. end,
6. [“halt”] = {
7. [“Leader”] = task.stop(),
8. [“Special”] = task.stop(),
9. match = “[LS]”
10. },
11. name = “NormalPlayV1”,
12. applicable = {exp = “a”, a = true},
13. attribute = “attack”,
14. timeout = 99999
15. }
3)使用LUA完成play场景层的开发: 该层主要调用多个task对象, 并将其封装为一个完整的play场景, 用以对多台机器人进行任务分配, 使之并行执行多个任务, 如多台家用机器人处于清扫场景(扫地机器人分配地面清扫任务、擦窗机器人分配玻璃清洁任务等). 其实现框架与task层类似.
如果对策略层做进一步的细化, 可将其分为6个工作层:
1)视觉和传感器的信息处理: 将视觉系统传过来的信息进行分析整合, 过滤重复内容. 另外, 需要对从机器人本体上传感器(如红外传感器)获得的工作信息进行处理, 为后续指令的下达提供依据;
2)运动预测: 通过保留过去若干秒内的图像信息, 将位置信息转化为速度信息, 根据数学计算来预测环境中各实体(包括机器人在内)位置, 该工作也为机器人合理的路径规划打下基础;
3)路径规划: 实现机器人的动态避障, 在完成移动任务的同时确保机器人不与各类静止、运动物体发生严重碰撞;
4)多层决策协作: 实现从一个机器人完成一个动作到多台机器人协同运作的多决策层的有机配合;
5)场景实现: 包括场景动态变换后的任务更新以及动态分配;
6)各种相关的算法: 包括基于硬件提供功能的抽象与二次开发.
前端控制层是ROCOS用于仿真机器人实时场景、提供应用层控制接口以及与通信子系统连接配置等功能的集成.
图11是足球机器人前端控制层在应用层的图形页面, 其构成包括左部的环境仿真与右部的控制面板, 用以实现对机器人控制的可视化处理.
具体使用过程中, 需要在控制面板中设置相关参数、选择研究模式. 如果场地子系统可以提供支持, 可选择实地模式, 并在结合下文的通讯子系统后, 完成实地图像在系统上的二维仿真建模与控制; 如果场地子系统不提供支持, 用户可以脱机进行研究, 在ROCOS中填充自定义的程序实现文件, 系统将解析用户的文件并在环境仿真界面进行仿真运算, 可获得与实地模式同等的研究效果.
图12是ROCOS前端控制层功能的另一方面体现, ROCOS搭载的策略机可直接和信号发射机连接, 通过无线、蓝牙等技术实现与机器人之间的通讯. 其具体实现逻辑仿照无线电系统和无线网络系统的实现模式: 当机器人与策略机连接在同一网段, 或两者频率收发器均设置为相同的频点, 即可实现自主式非人工连接.
为完成相应功能, 前端控制层也需要依赖外置的功能包, 并使用合理的框架对功能进行解耦和处理.
值得注意的是: 由于前端控制层的框架不是特别清晰, 也需要之后随着ROCOS的版本迭代逐步优化, 这里仅对其依赖的功能包做进一步的说明:
1)仿真: 为实现机器人环境与实体的三维建模与实时仿真, 需要引入开源的图形函数库OpenGL进行场景建模, 也需要引入开源的动态引擎库ODE提供相应的支持.
2)驱动: 需要为ROCOS配置相应从其他子系统获取信息和进行I/O管理的软件, 如与信号通讯相关的发射机驱动、加密狗驱动; 与视觉信息捕获相关的显卡驱动等.
ROCOS的文件系统层和ROS没有特别大的差别, 而且在对文件系统管理的文件树结构也大致相同, 均包含基本的文件夹架构:
1) bin: 该文件夹保存可执行的程序和命令, 大多是在ROCOS的终端界面可直接运行的命令行.
2) include: 该文件夹用于放置头文件. 由于ROCOS里面的某一具体的头文件属于某一具体的功能包, 如果一个功能包需要依赖另外的功能包, 自然必须包含另外功能包的头文件, 功能包的头文件在功能包安装的时候被直接存放于该文件夹.
3) lib: 主要存放一些.so结尾的可执行程序.
4) etc: 主要存放ROS和catkin配置文件.
5) share: 放置ROCOS里面已经安装的功能包, 主要包含功能包的各种信息, 包括其接口、配置信息等. 值得注意的是, 如果用户需要真正操作机器人, 并不是直接在该文件夹下进行, 需要额外建立一个文件夹, 即上文提及的工作空间, 然后在工作空间下创建自己的功能包, 进行一系列开发工作.
由于ROCOS相对较为小众, 所以并不像ROS一样提供一个广泛开源的社区, 它主要依托Git实现代码开源与数据共享(Git是目前世界上最先进的分布式版本控制系统).
本文介绍的浙江大学实现的ROCOS, 就在应用Git系统的主流版本管理网站Github上进行了开源[13], 目前有包括笔者在内的多个开发者参与到相关代码的研发与优化中.
为检验ROCOS架构的合理性及其在单一实现方向上所展示出的强针对性, 分别就ROS系统和ROCOS系统进行仿真实验.
由于本文主要针对浙江大学实现的ROCOS做研究, 研究者位处系统的优化人员之列, 所以不能估计本ROCOS的构建成本. 从浙江大学实验室获悉的详细数据是: ROCOS的初始架构时间花费不到半年, 相较ROS系统直接作为成品或工具而言, 其成本偏高. 但注意使用ROS的用户需要花费至少1到2年的时间学习ROS的基本技术, ROCOS仅需1个月或者更短, 所以从总时间成本投入上, ROCOS更胜一筹.
而通常情况下, ROCOS是为专门化领域或专门性需求所构建, 所以与ROS普适性构建相比, 其与机器人的适配性会更好.
基于上述原因, 本次实验以SSL (Small Size League)小型足球机器人(其二维参数如图13)为研究对象, 在一台策略机上运行Ubuntu下ROS系统、一台策略机上运行Ubuntu下ROCOS系统. 为保证实验不受无关因素干扰, 确保两台机器有相同硬件环境配置: Intel core i5-8300, 2.3 GHz, 四核, 内存 8 GB. 并同时接入SSL_Vision对应显卡, 加载相应视觉软件. 相关参数如图14.
从图14可知, 初始条件下, 数据传输率均为0. 在仿真实验中, 该值将指征系统的仿真效果以及稳定性.
使用5台蓝色标识标记的足球机器人进行仿真模拟, 使用LUA脚本指定其分别实现多边形路径规划与队列路径规划, 检验数据传输率、ROCOS计算速度与计算精度以及画面延时情况.
在图15中, 图15(a)是初始场景: 可以看到数据传输率稳定在62 帧/s, 静态仿真效果良好. 图15(b)和图15(c)分别是多机路径规划场景中的多边形路径和队列路径动态仿真, 可以看到数据传输率仍旧维持在62 帧/s, 所以系统稳定性非常好.
使用命令行查看CPU使用情况可以看到(ROCOS没有提供独立任务管理器)如图16.
初始静态仿真时刻CPU占有率为179.5%, 而动态仿真时刻CPU占有率为145.5% (注意这里占有率超过100%属系统问题, 相对占有率为准确值). 可以看出相对占有率不增反降, 主要原因在于静态仿真需要维持机器人仿真二维视图在可视时间内保持静止, 实际仍在进行计算, 所以CPU占用率较高.
为对比ROCOS的显著提升效果, 在ROS上做同组对比实验.
在图17中, 图17(a)是初始场景: 可以看到数据传输率稳定在60 帧/s, 静态仿真效果与ROCOS持平. 图17(b)和图17(c)分别是多机路径规划场景中的多边形路径和队列路径动态仿真, 可以看到数据传输率下降较为严重, 低至30 帧/s左右, 所以系统稳定性不甚理想.
同样使用命令行查看CPU使用情况如图18.
初始静态仿真时刻CPU占有率为0.3%, 而动态仿真时刻CPU占有率为70.9%. 可以看出虽然静态环境下, ROS系统的效率极高, 但转为动态环境后CPU占有率提升70.6%, 与ROCOS不增反降相比, 具有普适性的ROS系统在针对性领域效果不甚理想, 由此可以看出ROCOS系统所具有的强针对性: 在专一领域, 它的功能更加稳定且效果良好.
在机器人领域, 给研究人员带来极大阻碍的就是在程序运行过程中, 无法实时查看相关参数. 此外, 在机器人运行过程中如果出现问题, 一般很难立即定位问题来源, 极大程度上制约了项目推进速度和效率.
ROS系统允许用户根据机器人实际情况, 借助系统提供的功能包自行定义交互式辅助软件. 仍以SSL为例. ROS交互界面如图19.
使用ROS提供的元功能包以及小型足球机器人硬件开发文档提供的相关接口, 实现上述界面, 可执行简单的机器人控制: 包括速度、自身行为、动作触发、多机选择. 但实际使用过程中, 一旦出现程序问题, 只能确定触发源为当前时刻的前一条指令, 无法确定具体原因.
主要原因在于交互界面不灵活, 不能实现用户“所想即所得”, 即实时性动态调整可交互元素. ROCOS可以实现上述需求.
如图20, 使用ROCOS搭建系统交互界面, 可在可视化窗口中有选择地或者全部显示用户需要获取的中间参数, 在控制面板中, 以列表形式提供各参数的设置接口, 并允许用户在使用系统时动态调整列表项. 凡系统可从实体机器人硬件或者仿真后台程序中获取的参数项, 均可在控制面板动态定义.
与此同时, 在本次实验中, ROCOS系统由于主要针对多机调度, 所以从图20中可以看出, 针对每一台机器人都可以获取其独立的参数. 为多机系统的设计与控制提供了极大方便.
通过以上对比, 可见ROCOS在交互方面也获得了较大程度的提升. 与ROS相比, 在强针对性领域, 显示出足够优势.
本文对基于Linux内核(Ubuntu)下的ROS操作系统和ROCOS操作系统分别进行了对比式的介绍和说明, 并对二者具体的系统架构进行了相对详尽的描述, 最后以对比实验的方式论证了ROCOS的系统特性与系统优势. 虽然目前ROS的适用范围仍在不断扩大, 但像ROCOS这样从ROS中发展而来的强针对性操作系统才刚刚起步. 它在保留ROS原有的点对点设计、多语言支持、架构精简、组件化工具包丰富以及免费且开源等特点的基础上, 更强调对某一特定场景的支持(如本文提及的ROCOS就是对多机调度场景的支持), 显然它会比ROS更专一, 功能更稳定, 与特定场景的适配性更好.
截止目前, 由于ROCOS需要的成本投入远低于ROS, 用户不需要学习ROS中大量复杂而多元的概念, 仅需要参照现有ROCOS实现模式, 去实现自己方向的ROCOS系统, 所以其成本更低. 基于ROCOS的显著优势, 随着近年来人工智能等技术的不断推向深入, 像ROCOS这样的操作系统在未来可能会更有市场. 虽然目前看来, 它还有很长的路要走.
原文链接:http://c-s-a.org.cn/html/2021/7/8022.html