关于2018年东南大学Robomaster算法组工作的总结
笔者在写作时,为东南大学机器人俱乐部下Robomaster大赛SUPER NOVA战队算法组的负责人之一(这名字写起来好长)。而SUPER NOVA战队则于2018年5月19日正式结束了中部分区赛,获得了二等奖与总决赛前复活赛的参赛资格,将于两月之后奔赴深圳参赛。本次比赛中我们的工作有种种不如意之处、值得记录与反思。本文是对算法组在迄今位置的开发过程中取得的各种成绩、遇到的各种问题的总结。
项目历程
我加入算法组是在一年前,也就是上个学期开始时开始。由于各种人员变动,现任的组长hby同学是半年前上任的,项目实际上从那时才刚刚起步。那时我们算法组的情况是,整个战队的算法历史很短,是去年的比赛临近比赛时开始工作的,老人们在退出前没有留下什么经验,而已有的代码难以复用。算法组负责的工作主要集中在比赛主办方DJI公司强调的视觉方面。比如非常强力的神符需要短时间内按照数码管的指示依次击打一个九宫格内的手写数字,时间非常有限,只能靠机器完成;又或者今年的比赛中加入了全自动的哨兵机器人、只能通过内置的程序控制运行。
当时我们对项目的规划并不清晰,只是提出要为哨兵开发地方机器人自动识别算法与防御策略、为步兵装载装甲板识别与跟踪,小符的击打等等。当时的人手则是有我和hby还有一个后来退出的三个大三的同学,以及hby带的三个学弟。有感于今年近于从零开始的情景,hby提出来两点,一是要把工作下放到学弟手中练手,确保算法组工作的传承,一是要写一个高度模块化、复用性好的库,后者是他叫我进来的理由。
而算法的难度不在考虑之列,是的,这些视觉算法其实都算不得难,至少在科研界是入门级都够不到的东西。
到后来发生了人员变动、资金短缺等等事情,但我们的算法开发非常顺利,因为算法毕竟都很简单,到比赛前几天,算法基本都到了可用的地步,可以装车了。就在这时,我们项目中的种种问题暴露了出来。在省赛前的最后几天,我们日日熬夜,我与hby通宵四天,最后还是没能让它在车上发挥作用,直到今天,也就是比赛的最后一天,自瞄功能才刚刚上线,已经于事无补了。
发生了什么?
这个项目中发生的事太多,当局者迷,我需要一点一点理清各个导致进度异常的因素。
首先是最后几天发生的事情,也就是在算法开发完成后上车实测的时候发生的事情。
- 上下位机交互没有保证
- 代码移植出现问题
- 新系统上出现问题
第一件事用掉了我一天的时间,我们上下位机之间通过串口通信,按照约定的协议发送信息。我把导致这些事情的原因列举在下面。
硬件不清楚
既然使用串口通信,那么自然是要连接串口线的,不幸的是,我对硬件的连接并不清楚,在调试硬件上的代码前需要确保硬件的连接无误,即使要多花一些时间也是值得的。事实上,我就是因为线在多次调试时时而插反,妙算将电流噪声当做了下位机发来的信息,自然是抓破脑袋都查不出问题来。
底层协议编写出现问题
底层的协议其实是有问题的。由于align的存在,底层在计算一帧长度时少算了一些长度,在我被噪声困扰时,我首先意识到这个问题并且跟电控确认修改了这个问题。为什么协议没有先行测试?因为以前有测试的那一版被更新了,编写者觉得自己没改多少就没测。为什么以前没有出现这个问题?以前的协议是去年的算法组写的,他们知道这个问题。这实际上是联控问题。
开发环境没有统一
代码移植的问题是由开发环境未统一造成的。实际上,hby是坚定的VS拥护者,因为在VS下调试视觉算法有众多方便的插件,而整个组里熟悉Linux环境的人只有我一个。我们的代码最终运行在Linux Arm环境的妙算上,算一算,我们开发时可谓四大皆空——平台、库版本、语言标准、编译器均不相同。
这其实是我的责任,作为唯一熟悉Linux编程的人,应该在最开始就提醒移植代码这件事的困难性。不然、我也应该确保这些东西的一致,给队员做必要的培训,为他们部署使用简单的软件,或者干脆使用模拟器或者交叉编译等技术来解决它。只能说我没有经验,这件事是一个教训、一个警钟。代码必须能够保证运行,而这件事在测试前很难保证,因而实际环境下测试是非常重要的
代码同步有问题
这一点需要和上一点结合来看。我们使用git管理代码并协同工作,并在码云上托管了一个远程仓库。这件事本来是一件好事,然而由于全部人员都不能保证熟悉git,因而在离开图形界面后操作变得非常困难,以至出现了有git却还要手动同步,或者整个团队都停止工作,只为等待一个人代码完成同步成功的情况;同时由于没有意识,大家经常会有忘记同步的情况发生,每次都是一个灾难。这些事情大大地拖慢了项目进度,不管怎样,一晚上什么事都没做只同步了一下实在是不像样。
项目中心化太强
“对这个项目有全面了解的人只有我,这样不行” ----hby
是的,还在成长中的学弟需要hby去带,知道项目已经写到什么情况的人只有hby,知道下一步应该做什么的也只有他一个人。这种情况下他实际上变成了这个本来应该并行的项目中的互斥锁,这样在前期还好,在后期大家聚在一起磨合的时候,这样就会实际上空耗整个团队的人力,俗称全队看着程序员干活无所事事。
新系统上出现问题
这个问题并不是代码的问题,而是系统本身的问题。在妙算的嵌入式linux系统上,会出现很多windows上不会出现的问题。比如,它上面的opencv必须要使用V4L库先做处理才能打开摄像头,直接调用VideoCapture类会出现打不开的问题,而且,调用V4L的opencv程序必须要正常退出,而不能使用Crtl - c 用信号退出,因为系统不能自动回收摄像头资源,多次Crtl-C之后会导致摄像头无法再次打开的问题。另外,C++不保证正常return以外的退出main函数的操作会调用析构函数。
我目前的解决办法是捕获SIGINT信号,让它改变一个全局变量,主函数轮询这个变量之后退出。
另外,出现类似需要解决动态库链接等与系统相关的问题时,开发人员缺少独立解决问题的能力,可能查百度都不能照着解决。
这都能有技术流失
到最后几天终于做出第一版装甲板跟踪后,我们却发现控制性能非常差:飘得很厉害。
诸多调试后,才发现这是很久之前已经解决过的一个问题,但是随着协议的更新,电控那边发生了技术流失,这个问题又重新回来了——很不幸,又浪费了巨多的时间。
更根本的原因呢?
是什么导致了上面这些琐碎的问题发生?肯定有开发人员和管理人员都没有经验的原因,除此之外,还有一些其它的原因。
首先是整个队伍的进度太慢。是的,直到最后几天车只是勉强能动,距离做完差得还远。所以直到最后我们才真正有机会调试,问题因而暴露得太晚。
其次是资金的短缺。hby在一个月前曾经花一个下午的时间把他自己的程序移植到了TX2上,并且做出了已经能用的装甲板跟踪,所以他觉得很多事情都很简单。然而,因为资金的问题,我们最后只能用次一档的妙算。我们忽略了这一点。
最终是项目规划的问题。虽然知道自己该做什么,但整个项目的规划是有问题的,这其实还是管理人员没有经验,对时间的规划是非常重要的。
所以学到的教训是什么?
就我个人而言,教训是在做项目时,需要对目标平台有明确的认识,对所使用到的技术要详细地调查,并且能够熟练地使用,在此之前,需要确定开发的目标平台不要变。
如果让我来重做这个项目,我一定要先确认团队的资金,进而确定最终使用的平台,然后确认使用的库版本以及标准,确保这些东西能够和目标平台兼容。把所有的程序隔三差五就在妙算上跑一遍,最好就要求每个人的代码都要自己在linux上跑。在此之前我需要给队员开linux培训,教给他们make cmake shell脚本 程序的编译链接 动态库静态库等知识。如果时间不够我教,那么我就要给他们提供尽可能便利的环境。
然后跟hby说这个项目的进度需要经过仔细地设计。
然后确保底层接口的稳定性,越底层的东西越需要高质量地尽早完成,而不是相反。