1620 字

如何设计一个扫地机器人程序?

首先先搞清楚扫地机器人运行的抽象版,就是一个2D不随机行走,走过的地方要标记为干净,干净到一定程度停止。从设计角度要考虑面向对象编程,设定初始值与运行停止条件。也就是说我们要定义一个2D棋盘并将其网格化,然后定义一个棋子在上面游走。两者的基本联系是坐标,所以从继承的角度先定义坐标类型。围绕坐标标记或替换写出棋盘与棋子的类型,到时候调用就ok了。初始值与停止条件是解决实际问题必须考虑的,不能没法初始化运行,更不能完全停不下来。寻址算法效率什么的倒可以暂时放到后面去考虑或不考虑,让高级语言编译器代工。

坐标的属性很简单,给出x与y即可。同时可以给坐标的移动写一个函数,下一步的坐标要通过现有速度与角度进行更新来得到新坐标。因为棋盘与棋子的行为不同,我们最好用不同的类型来区分并针对特殊的类型进行编程,例如平面就需要有标记是否被清洁的属性而棋子则要有移动属性。这两个类型中都要继承来自坐标的属性。

先看平面类型,我们要对平面类型预定义长与宽,这样就可以按照单位长宽设计网格了。之后要进行初始化,预设全部都是脏的,那么所有网格都有个脏的属性。反映到编程上就是做一个列表,先存储所有的坐标点,这个列表要可更新。这只是初始状态,然后设计一个函数,当给出一个坐标后去检查是否在脏的列表之中:如果在,从列表中删掉;不在,继续。针对这个类型设计一个函数来返回干净坐标的比例,这个比例用来判定是否停止工作。同时,我们还面对一个大的初始化问题,那就是平面要可以给出一个随机点让棋子开始游走。有了平面坐标,脏净判断并初始化后,还要抽象一个边界,当随机行走坐标跑到预定义之外要返回一个逻辑判断,让棋子自行决定如何进行下一步。

然后就是棋子类型了,棋子要做的就是继承一个棋盘类型并定义一个速度,初始的速度直接用棋盘里的随机点函数生成,这样可以保证不会一出生就跑到棋盘外的坐标上去。然后初始方向直接随机,接下来就是如何行走了。很简单,棋子所在点在单位时间已经干净了,直接调用坐标类型的移动函数进行移动,将初始化中的方向与速度放进去即可。但需要注意的是要调用前面棋盘类型中的函数对下一个点进行判断,看是否撞墙了,撞了墙就改方向,直到不撞墙为止。然后就是停止条件,直接通过棋盘类型中是否干净的比例进行判断,如果达到一定比例就别干活了。

然后我们就可以写一个仿真程序来看看结果了,输入的参数包括房间大小、速度、行走方式及停止条件,程序可以返回一个估计时间来进行调试。对于行走方式而言,常见的一般就是撞墙变方向,也有比较疯狂的每一步都变方向。当然这都是基于算法的,如果基于其他传感信号,也可以写出更有针对性的算法例如脏的地方降低速度等来提高效果。这样通过程序我们已经可以模拟一个棋子连续遍历棋盘的过程了。也就是说这时候我们把这个程序跟参数输给扫地机器人,它就可以打扫空房间了。

真实状态的房间除了墙还有桌子腿什么的,不过用上面的算法也可以跑,就是慢点。一般会通过传感器感应房间大小,要是没有也无所谓,第一天跑时间长点,把房型撞出来也不难。先预设一个1000平的大房间,然后跑,撞墙就在坐标上做标记,跑时间长点就可以记住房型了。然后我们可以设计内置一个优化算法,对已经撞出来的房型路线进行路线优化,得到时间最短的那个。如果再高级点,可以对平时打扫需要较长时间的地方(此时要依赖传感器了)进行坐标标记,关键位置提高功率。然后软件可以放到树莓派这种东西上跑,外接上一个压力传感器得到墙的信号,一个电机跟电池保障能动能扫地,最好有个判断干净与否的光学传感器就够了。作为搞分析化学的,我建议搞个拉曼顺道定性测下污染物是什么,小型化质谱也应该可以,现在不流行原位电离吗,上一个就得了。这样不但采集了室内灰尘,顺道连污染物一并测完了,然后断面研究或队列研究随便搞,发点健康类文章问题应该不会太大。咦,好像写跑偏了。

不过鉴于宿舍里只有扫帚,我也不会真的去设计这玩意,只是完成了一次课程作业后的遐想。