自20世纪七八十年代以来,在计算机技术、传感器技术、电子技术等新技术发展的推动下,机器人技术进入了迅猛发展的黄金时期。
机器人技术正从传统工业制造领域向家庭服务、医疗看护、教育娱乐、救援探索、军事应用等领域迅速扩展。
如今,随着人工智能的发展,机器人又迎来了全新的发展机遇。机器人与人工智能大潮的喷发,必将像互联网一般,再次为人们的生活带来一次全新的革命。
本文将带大家走入智能机器人的世界,一起掀开ROS的神秘面纱,带领大家认识智能机器人的灵魂。
机器人的发展经历了三个重要时期,如图1所示。
电气时代(2000年前):机器人主要应用于工业生产,俗称工业机器人,由示教器操控,帮助工厂释放劳动力,此时的机器人智能程度不高,只能完全按照人类的命令执行动作。在这个时代,人们更加关注电气层面的驱动器、伺服电机、减速机、控制器等设备。
数字时代(2000—2015年):随着计算机和视觉技术的快速发展,机器人的种类不断丰富,涵盖了如AGV、视觉检测等应用。同时,机器人配备的传感器也更为丰富,然而它们仍然缺乏自主思考的能力,智能化水平有限,仅能感知局部环境。这是机器人大时代的前夜。
智能时代(2015年至今):随着人工智能技术的兴盛,机器人成为AI技术的最佳载体,人形机器人、服务机器人、送餐机器人、四足仿生机器狗、自动驾驶汽车等应用井喷式爆发,智能机器人时代正式拉开序幕。
图1 机器人发展的三个重要时期
硬件是智能机器人的坚实载体,软件则赋予智能机器人灵魂。智能机器人的快速发展,对机器人软件开发提出了更高要求。
为了应对这一挑战,并促进智能时代机器人软件的开发与创新,业界亟须开发一款通用的机器人操作系统作为标准平台,机器人操作系统(Robot Operating System,ROS)在2007年应运而生。
对于运行越来越复杂的智能机器人系统,已经不是一个人或者一个团队可以独立完成的,如何高效开发机器人,是技术层面上非常重要的一个问题。针对这个问题,斯坦福大学的有志青年们尝试给出一个答案,那就是ROS。
2007年,斯坦福大学的有志青年们萌生了一个想法:能否开发一款个人服务机器人,这款机器人能够协助人们完成洗衣、做饭、整理家务等繁琐的任务,也能在人们感到无聊时,陪伴他们聊天解闷、做游戏。最终,他们将这个想法付诸实践,真的研发出了这样的机器人。
当时,他们深知做出这样一款机器人并不容易,机械、电路、软件等都要涉及,横跨很多专业,光靠他们自己肯定做不到——既然自己做不到,那为什么不联合其他人一起干呢?如果设计一个标准的机器人平台,大家都在这个平台上开发应用,那么应用软件都基于同一平台,应用的分享就很容易实现。这就类似于只要有一部苹果手机,就可以使用任何人开发的苹果手机应用。
初期的机器人原型是由实验室可以找到的木头和一些零部件组成的,后期有了充足的资金,才得以实现一款外观精致、性能强悍的机器人——PR2(Personal Robot 2代)。
在他们的不懈努力下,PR2已经可以完成叠毛巾、熨烫衣服、打台球、剪头发等一系列复杂的任务(见图2)。以叠毛巾为例,这在当时是轰动机器人领域的重要成果,因为这是机器人第一次实现对柔性物体的处理,虽然在100分钟内只处理了5条毛巾,但在学术层面,这个成果推动机器人研究向前走了一大步。
图2 PR2的应用功能示例
在这款机器人中,开发者构建了一套相对通用的机器人软件框架,以便上百人的团队分工协作,这就是ROS的原型。ROS因PR2而生,但很快从中独立出来,成为一个更多开发者使用、更多机器人应用的通用软件系统。
PR2个人服务机器人项目很快被商业公司Willow Garage看中(类似于现在流行的风险投资)。Willow Garage投了一大笔钱给这群年轻人,在资本的助推下,PR2小批量上市。
2010年,随着PR2的发布,其中的软件系统名称正式确定,叫作机器人操作系统(Robot Operating System,ROS)。同年,ROS也肩负着让更多人使用的使命,被正式开源,此后,ROS快速发展,如图3所示。
PR2虽好,但是其成本居高不下,几百万元的价格让绝大部分开发者望而却步。2011年,ROS领域的爆款机器人TurtleBot发布,这款机器人采用扫地机器人的底盘,配合Xbox游戏机中的体感传感器Kinect,可以直接使用笔记本电脑控制,同时,它支持ROS中经典的视觉和导航功能,关键是价格便宜。这款机器人的普及大大推动了ROS的应用。
图3 ROS的发展历程
从2012年开始,使用ROS的人越来越多,ROS社区开始举办每年一届的ROS开发者大会(ROS Conference,ROSCon),来自全球的开发者齐聚一堂,分享自己使用ROS开发的机器人应用,其中不乏亚马逊、英特尔、微软等大公司的身影,参与人数也在逐年增多。
经历前几年野蛮而快速的发展,ROS逐渐稳定迭代,2014年起,ROS跟随Ubuntu操作系统,每两年推出一个长期支持版(Long Time Support,LTS),每个版本支持五年,这标志着ROS的成熟,加快了其普及的步伐。
回顾2007年,ROS的创始团队原本只想做一款个人服务机器人,却意外成就了一款被广泛应用的机器人软件系统。
但由于设计的局限性,ROS的问题也逐渐暴露,为了能够设计一款适用于所有机器人的操作系统,全新的ROS——ROS 2在2017年年底正式发布。
又历经多年迭代,终于在2022年5月底,ROS 2迎来了其首个长期支持版——ROS 2 Humble,这标志着ROS 2技术体系已趋成熟,同时宣告了ROS 2时代的开启。2024年5月,ROS 2的第二个长期支持版本 ROS 2 Jazzy发布,这使ROS 2更加稳定、丰满。
如图4所示,从ROS 2发展的时间轴中,大家可以看到ROS 2的生态正在快速迭代发展。
图4 ROS 2的发展历程
ROS的核心目标是提高机器人的软件复用率。围绕这个核心目标,ROS在自身的设计上也尽量做到了模块化,ROS主要由以下四部分组成。
通信机制:为复杂的机器人系统提供高效、安全的数据分发机制。
开发工具:为不同场景下的机器人仿真、可视化、开发调试提供易用性工具。
应用功能:为多种多样的机器人应用提供接口开放、可二次开发的功能包。
生态系统:联合全球机器人开发者,共同建立活跃而繁荣的开源社区与机器人文化。
“减少重复造轮子”的核心理念促使ROS社区快速发展和繁荣,时至今日,ROS已经广泛用于各种机器人的开发,如图5所示,无论是在机械臂、移动机器人、水下机器人,还是在人形机器人、复合机器人应用中,都可以看到ROS的身影,ROS已经成为机器人领域的普遍标准。
图5 ROS社区中多种多样的应用
正如汽车制造公司不会从头开始生产所有汽车零部件,而是采购来自各专业制造商的轮子、引擎和多媒体系统,智能机器人的开发也一样。ROS社区中有丰富的软件模块和工具,开发者可以将这些模块整合,进一步实现机器人创意和应用。这种方式不仅提高了开发效率,还充分利用了社区的集体力量和丰富经验,使项目更加成熟和可靠。
同时,大量开发者将成果分享回社区,这种开源共建的合作模式使每位开发者都能从他人的经验和创新中受益。通过站在巨人的肩膀上,能加速前行,为智能机器人领域的长远进步贡献力量,积累宝贵经验和深厚积淀。
除此之外,ROS还具备以下特点。
全球化的社区:可以集合全人类的智慧来推进机器人的智能化发展,这些智慧的结晶会以应用案例的形式在社区中沉淀下来。
开源开放的生态:ROS自身及众多应用都是完全开源的,公司可以直接使用ROS开发商业化的机器人产品,缩短了产品的上市时间。
跨平台使用:ROS可以跨平台使用,在Linux、Windows、嵌入式系统中都可以运行。
工业应用支持:ROS 2中新增了很多支持工业应用的新特性和新技术,促使ROS在更多领域中被使用。
在学习ROS 2之前,你也许听说或使用过ROS 1,从名称上看,ROS 2不就是第二代ROS吗,变化能有多大?答案是——非常大!
为什么会有ROS 2?
当然是因为ROS 1有一些问题,具体是什么问题呢?
从ROS发展的历程中,大家似乎可以找到答案。
ROS最早的设计目标是开发一款PR 2家庭服务机器人,如图6所示,这款机器人绝大部分时间独立工作,为了让他具备足够的能力,进行了如下设计。
搭载工作站级别的计算平台和各种先进的通信设备,不用担心算力问题,有足够的实力支持各种复杂的实时运算和应用处理。
由于是单兵作战,绝大部分通信任务在内部完成,因此可以使用有线连接,保证了良好的网络连接,没有数据丢失或者黑客入侵的风险。
虽然最终小批量生产,但是由于成本和售价高昂,只能用于学术研究。
图6 PR 2家庭服务机器人
随着ROS的普及,应用ROS的机器人类型已经发生了天翻地覆的变化,绝大部分机器人不具备PR 2这样的条件,原本针对PR 2设计的软件框架就会出现很多问题,例如:
要在资源有限的嵌入式系统中运行。
要在有干扰的地方保证通信的可靠性。
要做成产品走向市场,甚至用在自动驾驶汽车和航天机器人上。
……
类似的需求导致问题不断涌现,因此,更加适合各种机器人应用的新一代ROS,也就是ROS 2,诞生了。
ROS 2肩负变革智能机器人时代的历史使命,在设计之初,就考虑到要满足各种各样机器人应用的需求。
1. 多机器人系统
未来,机器人一定不会是独立的个体,机器人和机器人之间也需要通信和协作,ROS 2为多机器人系统的应用提供了标准方法和通信机制。
2. 跨平台
机器人应用场景不同,使用的控制平台也会有很大差异,例如,人形机器人的算力需求一般比物流机器人高。为了让所有机器人都可以运行,ROS 2可以跨平台运行于Linux、Windows、macOS、RTOS等操作系统,甚至是没有任何系统的微控制器(MCU)上,这样,开发者就不用纠结自己的控制器能不能用ROS平台了。
3. 实时性
机器人运动控制和很多行为策略要求机器人具备实时性,例如,机器人要可靠地在100ms内发现前方的行人,或者稳定地在1ms内完成运动学的解算,ROS 2为类似于这样的实时性需求提供了基本保障。
4. 网络连接
无论在怎样的网络环境下,ROS 2都可以尽量保障机器人大量数据的完整性和安全性,例如,在Wi-Fi信号不好时也要尽力将数据发送过去,在有黑客入侵风险的场景下要对数据进行加密解密等。
5. 产品化
大量机器人已经走向人们的生活,未来还会更加深入,ROS 2不仅可以用于机器人研发,还可以直接搭载在产品中,走向消费市场,这对ROS 2的稳定性、强壮性提出了很高的要求。
6. 项目管理
机器人开发是一项复杂的系统工程,设计、开发、调试、测试、部署等全流程的项目管理工具和机制,也会在ROS 2中体现,方便开发者开发和管理机器人产品。
满足以上需求并不简单。机器人千差万别,开发能够适合尽量多的机器人的系统,远比开发一个标准化的手机系统或者计算机系统复杂。
ROS开发者面对的选择有两个,第一个是在ROS 1的架构之上进行修改和优化,类似于把一个盖好的房子打成毛坯房,再重新装修。这会受制于原有的格局,长远来看并不是最佳选择,于是他们选择了第二个方案,那就是——推倒重来。
所以,ROS 2是一个全新的机器人操作系统,在借鉴ROS 1成功经验的基础上,对系统架构和软件代码进行了重新设计和实现。
重新设计了系统架构。ROS 1中所有节点都需要在节点管理器ROS Master的管理下工作,一旦Master出现问题,系统就面临宕机的风险。而ROS 2实现了真正的分布式,不再有Master这个角色,借助全新的通信框架DDS、Zenoh,为所有节点的通信提供了可靠保障。
重新设计了软件API。ROS 1原有的API已经无法满足需求,ROS 2结合C++最新标准和Python3语言特性,设计了更具通用性的API。这种设计导致原有ROS 1的代码无法直接在ROS 2中运行,但尽量保留了类似的使用方法,同时提供了大量移植说明。
优化升级了编译系统。ROS 1中使用的rosbuild和catkin问题很多,尤其在针对代码较多的大项目及Python编写的项目时,编译、链接经常出错。ROS 2对这些问题进行了优化,优化后的编译系统叫作ament和colcon,它们提供了更稳定、高效的编译和链接过程,减少了出错的可能性,并使整个开发流程更加流畅和可维护。
1. 系统架构
如图7所示,在ROS 1中,应用层(Application Layer)里Master节点管理器的角色至关重要,所有节点都得听它指挥。它类似于公司的CEO,有且只有一个,如果CEO突然消失,公司肯定会乱成一团。为了增强系统的健壮性和可扩展性,ROS 2创新性地摒弃了这一设计,转而采用Discovery自发现机制,允许节点自主寻找并建立稳定的通信连接,从而避免了单点故障的风险。
图7 ROS 2与ROS 1的系统架构对比
中间层(Middleware Layer)是ROS封装好的标准通信接口,大家写程序的时候,会频繁和这些通信接口打交道,例如发布一个图像的数据、接收一个雷达的信息,客户端会调用底层复杂的驱动和通信协议,让开发变得简单明了。
在ROS 1中,ROS通信依赖底层的TCP和UDP,而在ROS 2中,通信协议换成了更加复杂也更完善的数据分发服务(Data Distribution Service,DDS)系统通信机制。
底层是系统层(OS Layer),即可以将ROS安装在哪些操作系统上,ROS 1主要安装在Linux上,ROS 2的可选项很多,Linux、Windows、macOS、RTOS都可以。
2. 通信系统
大家可能会思考,为什么ROS 2要更换成DDS系统通信机制?DDS是什么?
ROS 1是基于TCP/UDP的通信系统,由于自身机制问题,在开发中很容易出现延迟、丢数据、无法加密等问题,所以ROS 2引入了更复杂也更完善的DDS系统通信机制。
DDS是物联网中广泛应用的一种系统通信机制,类似于大家常听说的5G通信,DDS是一个国际标准,能够实现该标准的软件系统并不是唯一的,所以大家可以选择多个厂家提供的DDS系统通信机制,例如OpenSplice、FastRTPS等,每家的性能不同,适用的场景也不同。
这就带来一个问题,每个DDS厂家的软件接口不一样,如果按照某一家的接口写完了程序,想要切换其他厂家的DDS,不是要重新写代码吗?这当然不符合ROS提高软件复用率的目标。
为了解决这个问题,如图8所示,ROS 2中设计了一个ROS Middleware,简称RMW,也就是制定一个标准接口,例如如何发送数据、如何接收数据、数据的各种属性如何配置,等等。如果厂家想接入ROS社区,就需要按照这个标准写一个适配的接口,把自家的DDS移植过来,这样就把问题交给了最熟悉自家DDS的厂商。对于用户来讲,某一个DDS用得“不顺手”,只要安装另一个,然后做简单的配置,不需要更改应用程序,就可以轻松更换底层的通信系统。
图8 ROS 2系统架构概览
总之,DDS的加入,让ROS 2系统更加稳定、更加灵活,也更加复杂。开发者不用再纠结ROS的通信系统是否稳定、该如何优化等问题,可以把更多精力放在如何实现机器人应用功能上。
3. 核心概念
ROS 1应用得非常广泛,全球有几百万名开发者,大家已经熟悉了ROS 1的开发方式以及其中的很多概念。ROS 2保留了如下概念,便于开发者从ROS 1迁移到ROS 2。
工作空间(Workspace):开发过程的大本营,是放置各种开发文件的地方。
功能包(Package):功能源码的聚集地,用于组织某一机器人功能。
节点(Node):机器人的工作细胞,是代码编译生成的一个可执行文件。
话题(Topic):节点间传递数据的桥梁,周期性传递各功能之间的信息。
服务(Service):节点间的“你问我答”,用于某些机器人功能和参数的配置。
通信接口(Interface):数据传递的标准结构,规范了机器人的各种数据形态。
参数(Parameter):机器人系统的全局字典,可定义或查询机器人的配置参数。
动作(Action):完整行为的流程管理,控制机器人完成某些动作。
分布式通信(Distributed Communication):多计算平台的任务分配,实现快速组网。
DDS(Data Distribution Service):机器人的神经网络,完成数据的高效安全传送。
如果大家熟悉ROS 1,那么对以上概念应该不陌生,在ROS 2中,这些概念依然存在,意义也几乎一致。如果大家不熟悉或者没有学习过ROS也没关系,第2章会讲解这些概念的含义和使用方法。
4. 编码方式
再来看看代码的编写方式,ROS 1和ROS 2实现的核心API对比如下。
# 引入Python API接口库
import rclpy # ROS 2
import rospy # ROS 1
# 创建Topic发布者对象
self.pub = self.create_publisher(String, "chatter", 10) # ROS 2
pub = rospy.Publisher('chatter, String, queue_size=10) # ROS 1
# 创建Topic订阅者对象
self.sub = self.create_subscription(String, "chatter", self.listener_callback, 10) # ROS 2
rospy.Subscriber("chatter", String, listener_callback) # ROS 1
# 创建Service服务器对象
self.srv = self.create_service(AddTwoInts, 'add_two_ints', self.adder_callback) # ROS 2
srv = rospy.Service('add_two_ints', AddTwoInts, adder_callback) # ROS 1
# 创建Service客户端对象
self.client = self.create_client(AddTwoInts, 'add_two_ints') # ROS 2
client = rospy.ServiceProxy('add_two_ints', AddTwoInts) # ROS 1
# 输出日志信息
self.get_logger().info('Publishing: "%s" ' % msg.data) # ROS 2
rospy.loginfo("Publishing: "%s" ", msg.data) # ROS 1
ROS 2重新定义了API函数接口,但使用方法与ROS 1相差不大。此外,ROS 2会用到更多面向对象的实现方法和语言特性,从编程语言的角度来讲,难度确实会提高,不过当大家迈过这道坎后,就会发现编写的程序更具备可读性和可移植性,也更接近真实企业中机器人软件开发的过程。
具体如何编码,请大家少安毋躁,不要搬来一本大部头的编程语言教程,一页一页学习,更好的方式是在项目开发的过程中一边用一边学,本书后续章节也会带领大家一步一步操作。
5. 命令行工具
命令行是ROS开发中最为常用的一种工具,如图9所示。
图9 ROS 2命令行工具示例
与ROS 1相比,ROS 2对命令行做了大幅集成,所有命令都集成在一个ROS 2的主命令中,例如,“ros2 run”表示启动某个节点,“ros2 topic”表示话题相关的功能。
来自strongerHuang公众号