阅读量 次   文章字数 5,453字    阅读时长 18分钟

本篇文章介绍ROS下机器人系统集成的相关经验。

前言

我在大二的时候加入到了西北工业大学舞蹈机器人基地RoboCup@Home项目组,在接近一年半的学习与开发过程中,我与负责其他模块的成员一起在原有晓萌机器人的基础上,对其整个系统架构进行了全面的升级,以便满足实际比赛的需要。同时在这个过程中,我也对新一代晓萌机器人系统有了更深的认识与理解。这里,我把自己对晓萌机器人系统的见解总结下来,一方面算是对我们这一届成员开发成果的总结,另一方面也希望这些经验总结可以留给未来的继任者,能给他们一些开发上的指导和借鉴。

本篇文章重点介绍晓萌机器人的系统架构,其中主要分为硬件层、嵌入式层、驱动层和软件层。除了技术方面的内容之外,我还会介绍其他有关开发的内容。不过由于这些内容都是来源于自己的个人见解,所以有些地方可能会讲得不够准确,欢迎各位成员在留言处进行指正。

技术

xm_system_architecture

如上图所示,晓萌机器人的架构主要分为四层,分别为硬件层、嵌入式层、驱动层和软件层。

硬件层

  • 机械平台

    底盘:
    机械平台分为底盘和机械臂两个部分。根据《自主移动机器人导论》书中的相关内容,底盘采用三角布局的全向轮结构,经过一定的运动学解算,可以实现底盘的全向移动。

    机械臂:
    机械臂由我们上一届学长设计,整个机械结构由复合的同步轮和与之匹配的同步带组成。由于没有采用传统的舵机关节结构,因此该机械臂可以抓取更重的载荷,并且在末端精度上也表现得很出色。

  • 传感器

    音频:
    晓萌机器人安装有话筒和音响两种音频设备。话筒用于接收人所发出的语音信息,不过由于比赛现场声音过于嘈杂,所以人与话筒的距离要保持得比较近才能使语音命令能够被采集到。

    音响主要用来播放晓萌机器人的语音信息。根据比赛规则,晓萌机器人需要在某些比赛项目中通过播放语音的方式来表明机器人已经理解裁判所下达的命令或完成了某个阶段的任务。

    激光:
    晓萌机器人装配有Hokuyo公司的廉价激光传感器,它主要被用于建立未知环境的地图,为机器人的自主导航提供坚实的基础。同时,它也能检测到机器人周围的障碍物,使得机器人能避免与其相撞。

    Kinect:
    Kinect是微软公司推出的一款RGB-D相机,我们将其安装在机械臂的升降台上,主要用于获取点云数据并使用相关图像算法来识别放置在架子上的不同物体。

    Xtion Pro Live:
    Xtion Pro Live是华硕公司推出的一款RGB-D相机,我们将其应用于人脸识别。该相机位于晓萌机器人的顶部云台上,云台则由两个Dynamixel舵机组成。当比赛中需要机器人跟随人一起移动时,晓萌机器人可以通过改变两个舵机的角度来确保人脸始终存在于相机的有效视野内,从而降低跟丢情况的发生。

  • 执行器

    执行器是机器人重要的运动部件,如图所示,晓萌机器人的执行器包含有舵机和电机两个部分。舵机主要用于相机云台的旋转以及机械臂末端手爪的开合,电机则负责底盘和机械臂部分的移动和控制。

  • 反馈器

    反馈器可以实时地获取机器人的运动状态,为实现机器人自主闭环控制提供基本的保障。这里,晓萌机器人采用电机编码器来向上层返回电机的实测数据,以便对原有数据进行一定的修正,减少误差对机器人自主运动或控制的影响。

嵌入式层

  • 底层控制

    嵌入式层的核心是底层控制。我们使用基于ARM Cortex-M3架构的STM32芯片作为下位机的主控,它的主要任务是对通信数据进行解析,并根据一定的解算,将最终的控制命令发送给连接有底盘和机械臂电机的驱动盒进行相应的控制。同样的,通过电机编码器返回的数据可以用来计算底盘的里程和机械臂关节的实时状态,为机器人的上层规划提供基础。

  • 数据通信

    主控与上位机之间采用串口通信,而主控与电机驱动盒之间则使用CAN网络进行连接。经过实测,该机器人通信架构可以满足需求。

驱动层

  • 内核设备驱动

    内核设备驱动是驱动层最基本的组成部分,它们由硬件设备开发商提供,并嵌入在操作系统中,为访问设备提供最基本的保障。

  • 传感器驱动

    传感器驱动则由软件开发者所编写,它们主要负责封装底层细节并向上暴露出特定的数据接口,方便开发者进行使用或二次开发。

  • 控制器驱动

    从图中可以清楚地看到,控制器驱动和传感器驱动处于同一层,所以它们的功能类似,不同点在于控制器驱动服务的对象不是传感器而是舵机和电机。

软件层

  • Windows

    在Windows上,我们主要使用微软自带的Speech库来做语音合成和识别。其实在赛前的开发过程中,我们也曾在Ubuntu下使用过各种语音库,但测试出来的效果都不如Speech库。

  • Ubuntu

    在Ubuntu上,我们全部使用ROS来做各模块的开发和集成工作,其中涉及有负责物体识别和人脸检测的图像模块、负责运动规划和控制的底盘和机械臂模块、以及负责机器人行为决定的策略模块等。

    因为在软件组中,我主要负责机械臂软件部分,所以我对晓萌机械臂模块的开发还是有着比较深的理解和总结的。由于篇幅的缘故,我不在这里展开进行讲解。对于那些想了解如何开发机械臂的初学者来说,我会在下一篇系列博客中对此进行详细地总结。以下是机械臂的软件架构图,各位可以先睹为快:

xm_arm_software_architecture

成果

机械

  • 封装

    底盘的四周用隔板做了简单的封装,并使用束线带对杂乱的线缆进行了整理,从而降低调试过程中因线缆互相缠绕而导致的一些问题(之前由于电机线缆被缠绕在机械臂的底座上,导致机械臂在升起的过程中,出现线缆被扯断的严重问题)。

  • 手爪

    前一代手爪是那种可以对称张开闭合的结构,而现在使用的是平行结构,即两个金属滑块通过在滑轨上完成对称平行的移动来实现抓取操作。除此之外,手爪的内侧还特别加装有塑料海绵,可以保证在不失舵机扭矩的前提下,尽可能地夹紧物体。

电子

  • 机械臂控制

    相比底盘电机的速度闭环控制,机械臂控制使用的是位置闭环。抛开机械上的误差,电子组在控制机械臂的位置精度上做得还是很不错的。

  • 主控制板

    我们也拥有自行设计的基于STM32芯片的控制板,虽然稳定性还需改进,但相比于直接使用战舰等学习板,我们设计的控制板可以最大程度地满足自身嵌入式开发的需要,并精简冗余的部分,提高整个硬件的运行效率。

软件

  • 语音模块

    语音模块的主体虽然还是之前Windows上开发的那一套,但在软件界面和识别精度上都有了很大程度的提高。在2015年的RoboCup贵阳赛中,我们在语音测试环节中识别出了几乎全部的测试用例。虽然有的队全部识别正确,但是对于我们来说能在那样的环境下做到这样已经很不错了。

  • 图像模块

    图像模块的改进主要体现在物体识别上。因为我们之前想用的是和MoveIt!集成在一起的ork,但经过上一届搞图像的学长的研究发现,ork很难配置起来,而且也不是很好用。所以,这一届我的两个队友非常给力地完成了晓萌机器人第一代的物体识别算法,经过测试,识别的效果还是非常不错的。

  • 底盘模块

    底盘模块的成果主要是添加了机器人自主进门以及更加鲁棒的SLAM。当然,对于BSR(Benchmark Service Robot,即服务机器人基准测试)项目来说,基于Kinect定制的视觉SLAM也是不错的成果。

  • 机械臂模块

    机械臂模块的成果是显而易见的,我们做到了晓萌机器人团队自创立以来第一次的机械臂自主抓取。尽管在运动控制以及策略的制订上还存在明显的不足,但可以肯定的是,机械臂是服务机器人不可或缺的重要组成部分,未来我们仍需要不断地努力,让机械臂的控制变得更加精准。

  • 策略模块

    最后是整个晓萌机器人的策略模块。放到最后才讲是因为它的确很重要,它可以说是机器人的大脑,也是整个机器人核心智能的体现(虽然我们还远远没有达到)。策略模块的成果主要是根据所要测试的项目添加了对应的状态机控制,这样就可以通过调用以上不同的模块来让机器人自主完成不同状态下的任务。

其他

  • 版本控制

    我们基于GitHub搭建了晓萌机器人团队的代码管理系统,并根据开发角色和分配任务的不同,将代码仓库的管理权限分配给各自需要进行维护的成员,这提高了团队协作开发的效率,也减少了因代码版本不同而导致的问题。

  • 开发指南

    我们编写了一套比较完整的软件开发指南,其中包含常用编程语言以及代码版本管理方面的内容,这些指南主要被用于统一各团队成员的编码风格,使得各成员所编写的模块可以无缝地对接,提高开发效率并降低代码出错的可能。

  • 团队建设

    我们设计了自己团队的标志、海报和队服,我们以此希望未来的成员能以自己是晓萌机器人团队的一份子而感到自豪,并努力地为晓萌机器人的发展贡献自己的力量!

问题

机械

  • 机械臂

    现在,机械臂每次初始化都需要在断电的情况下由人手动地将沉重的机械臂掰成水平,然后才能上电复位。虽然这比于之前使用的限位开关要精准的多,但使用起来依然不是很方便。造成这个问题的原因是我们的机械臂构造比较特殊,由同步轮和同步带组成的关节很难保证在限位开关被触发的时候能够及时停下,所以希望新成员能找到方法来解决这个问题。

  • 机械手爪

    现在,控制手爪舵机的方法是由软件组直接通过串口发送舵机旋转所需要的角度,而角度的计算则是根据物体的宽度通过解算得到的。虽然我们可以对误差进行一定的修正,以使得舵机能多次做到抓紧物体而又不会过载,但是本身这种方式就不是很科学。因为,我们不能绝对保证手爪每次都能到达物体的相同高度,对于那些是等宽圆柱体的物体来说,我们现在使用的这种纯通过计算的方式没有问题,但对于不等宽的圆柱体来说,这么做很有可能会导致手爪要么太松,抓不住。要么手爪抓得太紧,舵机过载失去扭矩。我认为解决的最好办法就是在手爪上装个压力传感器,并预先根据舵机可以承受的最大过载设定一个安全的压力阈值,这样每当抓一个物体的时候,不管它是什么形状,手爪都能根据压力的变化来尽可能地抓紧物体。

电子

  • 封装

    主要是有太多裸露的电线,这样既不美观,也很影响机器人的调试工作。之前,我们在调试机械臂的时候就曾出现过升降电机的线被底盘缠住,在升降复位上升的过程中直接将其扯断的悲惨经历。希望之后的电子组成员可以在布线这个问题上多考虑考虑,多参考其他队伍是如何把线布的既方便使用又能简洁美观的。

  • 机械臂

    机械臂关节移动的正方向比较混乱,希望电子组之后统一方向为:向上为正、向右为正。即软件组发送关节数据为正时,机械臂关节要向上或向右动才行。

软件

  • 串口

    在启动底盘和机械臂的robot_hardware,并打开串口给下位机发送数据的时候,串口总是会出现莫名其妙的崩溃问题。当时我和负责底盘的队友商量之后,决定写一个ROS Service来切换底盘和机械臂的模式,这样做虽然可以保证每次只有底盘或机械臂在给串口发数据,暂时地解决了问题,但它并不是一个很好的解决方案,因为它使得底盘和机械臂无法同时工作。

    我个人认为问题的原因应该和串口发送接收队列有关。RS-485串口的波特率已经达到了我们所能使用的极限了,所以要修改的话,应该在软件组代码中对发送或接收队列进行适当的延迟,以抵消大量的数据对数据线路的冲击。

  • MoveIt!

    我之前在研究机械臂控制的时候,发现在调用MoveIt!做机械臂逆解时,总会出现解算不成功的问题。后来我们简化了机械臂的控制,并没有在机械臂中用到MoveIt!。希望新成员能够解决这个问题,使晓萌的机械臂控制更上一层楼。

规划

机械

希望机械上可以减轻机械臂升降台的重量,因为负责底盘的队友曾经抱怨沉重的升降使得他的底盘在导航的时候跑得不稳定。还有就是对于BSR项目底盘的设计,希望可以向中科大和上交学习,尝试地使用两轮驱动,因为两轮驱动的话,底盘过门槛是没有问题的,而且底盘电机可以承受的重量也要在设计的时候好好考虑,毕竟负重越重,得分所乘的权值越大。

软件

希望软件组各个模块的负责人可以在已有学长学姐的技术积累之上,让模块本身做得足够稳定。我知道虽然我在这里讲的很容易,但真要实现起来,对于我们本科生来说,确实也不容易。但我们不相信自己还能相信谁呢?就像之前我们的学长告诉我们的那样:如果各位不做,西工大就再也没有人去做了。时代把任务交给你们,你们就必须肩负起这个使命。所以为了晓萌机器人项目的发展,希望每届项目组的成员都要做出自己应有的贡献。

其他

最后,我的个人愿望就是希望我能在大四本科毕业之前,看到晓萌机器人能自主完成GPSR项目,或者至少可以去大学生超市秀一把机械臂的自主抓取。虽然愿望很美好,但到底能不能完成,还要看未来的新成员给不给力了。

文档

我知道有很多人喜欢编程,不喜欢花时间来写文档(首先阐明一下,这里的文档指的是广义上的文档,即包括图片、视频、文字、架构图等)。但我不得不说,文档对于一个项目的发展是至关重要的。在我们2015年贵阳赛比完之后,我们组的ROS大牛学长就曾告诉过我:只要晓萌的技术方向没有问题,经过一段时间的发展,我们超越除中科大之外的其他队是没有问题的。我想,相比于代码来说,整个晓萌团队的技术架构、需求设计才最为重要。而往往新架构的设计要花费很多时间,而且还可能需要组内各个模块负责人之间要相互讨论和统一意见。

总之,我真的很不希望看到在若干年之后:我们拿不出曾经调试或比赛的照片来告诉新成员过去几代的晓萌机器人长什么样子;我们拿不出合适的视频资料来证明我们曾经在调试或比赛的时候也完成过某项测试;我们拿不出曾经设计严谨的架构图或技术文档来指导学弟学妹未来晓萌该如何前进和发展。所以为了下一代的发展,我觉得我们应该把我们已有的技术、经验、成果、和对未来的规划以纸质文档、照片、视频等方式永久地记录下来,这样在过了几代发展之后,晓萌机器人才能以一种增量式开发的成果展现在人们的面前。

总结

首先我很幸运自己能有机会在本科阶段就加入到这样一支强大的团队中来,而且还能做我自己喜欢做的东西。当然,我觉得最重要的是我体会到了什么才叫真正的团队。回顾以往的开发经历,我们也曾遇到过人员流失等种种困难,但团结一心使我们最终坚持到了现在。多少个周末、寒暑假,别人在放松休息的时候,我们在埋头为晓萌团队的发展贡献自己的力量。我也记不清赛前我们到底熬了多少个昼夜,为比赛项目测试了多少次,但有一点是值得肯定的,我们能够彼此不懈努力并为此拼命的最大动力只来源于学长曾经教导过我们的一句话:绝对不能坑自己的队友。

其实有很多人都不理解我们,说我们比赛名次不是很好,拿的奖也不是国际奖,为什么还要牺牲那么多的时间或者有时还要冒着挂科的巨大风险来去做这些东西。其实我想说的是,奖这个东西往往不代表能力,或者说奖不能完全体现出我们的真实水平。就像学长曾说过的,奖只能证明你曾经经历过,只有你自己知道你配得上还是配不上这个奖。总之,在经历过三次比赛之后,我开始慢慢意识到也许奖真的不那么重要,重要的是我们可以用我们的能力来陪伴并见证晓萌的不断成长。有收获,就不遗憾了。

未来,我觉得有必要多花一些时间来研究理论,因为如果你只会调别人的API,你是很难有非常大的进步的。只有掌握了最核心、最基础的理论知识,才可能在未来创造出令别人刮目相看的东西。

最后,我想说的是:做你最想做的事情,并且为之奋斗下去,永不后悔!

本博客所有文章除特别声明外,均采用CC BY-NC-SA 3.0许可协议。获得许可后,要求转载时注明文章出处和网站链接,谢谢!

留言