用户
 找回密码
 立即注册
发表于 2020-7-20 12:09:51
43032
本文来自一位Jetson开发者供稿。文章里,他从项目发起,到项目中遇到的挑战和瓶颈的点点滴滴,都非常详细。这个项目Lady我也一直关注着,当他第一时间把运行的DEMO看的时候,我也是由衷地感到高兴,迫不及待让他写下来分享给大家!


大约是在Aplha Go对战李世石的时候,我看着直播就产生了疑惑:画面上,这明明是两个人在对弈嘛!怎么能说是人机大战呢?后来通过新闻报道了解到,Aplha Go是通过它的研发者黄士杰来执棋的。“不够酷!”——这是我对这场人机大战的评价,虽然机器智能战胜了人类。

“加个机械臂执棋,很难吗?”几年前,和一帮工科大佬朋友吃火锅的时候,我丝毫不屑地夸下海口:“我这个文科生都能做!”估计几位朋友那时看我,就像是现在听“Nobody knows more about xxx than me”这种段子一样的心情吧!

不过,我其实是认真的。决定将一直萦绕在心头的愿望实现,是基于两个原因:第一个原因,家里的小朋友喜欢在手机电脑里找游戏玩,我不想让他总对着屏幕,伤眼睛,而我也不是总有时间陪他下棋,所以如果有一个不带屏幕的下棋机器人陪他下棋,既体验了科技智能,又不伤眼睛,会比较好吧!第二个原因,老爷子是个中国象棋高手,从小我就下不过他,现在我已不惑之年,依然不是他的对手,我想借助“巨人的肩膀”打败他(虽然本质上都是算法,但与机械臂的对战和与电脑屏幕的对战,感受是不同的,请细品)——这也是为啥我做的是中国象棋,而不是围棋或其它。
https://v.qq.com/x/page/j31028lps6r.html
我不想铺垫过多,以免很多读者被大段的文字吓走,这里就放上最终成果的视频,先过个瘾(做好的第一天白天,正好是父亲节,小朋友与机器装置对战,前面其实都玩了两盘了,第一盘输的时候还哭了,这一盘没有打完,孩他妈就河东狮吼地叫他去写作业了~)。

记得是在2018年的冬天,在结束加班给老婆带宵夜炒花甲回家的路上,我和ABCD群里的朋友们第一次聊起了下棋机器人的解决方案,大家纷纷建言献策,帮我逐渐摸到了门。这次聊天,自动下棋装置的idea引起了几位群友的极大兴趣,我也就此立下flag,要将它做出来。此后一段日子,就在网上到处搜索相关的资料,我看到有国外网友做了个国际象棋的下棋装置,也有价格不菲的智能棋盘刚刚开售(不过这个智能棋盘没有机械操控部分,只是用棋盘上的灯标注机器的走步,这样不够酷,我不要学)。逐渐,一套pipeline开始成形,即三个阶段:识别棋盘+棋局智能+机械操控。

说起来就这么几个字,但做起来,我却陆陆续续折腾了快两年。为了不那么萝莉啰嗦,我就以技术实现pipeline为主线顺序,顺便夹带这两年里发生的值得记录的点滴。
整个项目的技术架构图:
1、识别棋盘

2018年底的时候,我已经接触深度学习有两年了,所以当时很明确,通过摄像头拍摄象棋棋盘的图片,然后通过深度学习的方法来识别棋盘的棋子所在位置情况。具体的过程是:

(1)摄像头拍照。为了从顶部拍照,我买了第一组装备:一个摄像头和一个支架。那时的考虑都比较朴素,就地取材,棋盘用的是比较大的(50cm*45cm),支架的高度有限,拍照的位置比较低,所以USB摄像头略贵,带防畸变效果的。

插一句,曾经有一度,我觉得摄像头拍照不够好,而且USB线很烦人,决定用手机作为拍照的摄像头工具,方法就是python通过adb 控制安卓手机拍照,并将照片通过局域网传输到PC端。这东西搞出来的时候,突然觉得好可怕,因为adb可以让手机不动声色的拍照,然后传输。后来,发现USB摄像头拍照之所以不够好,曝光不足,是因为要给摄像头一个预热的时间,软件里加了个小trick之后,就正常了,于是就没有用adb方案。

(2)从照片中抽取棋盘部分。因为技术不行,不能适应所有的背景,所以为了将棋盘主体部分从背景中抽离出来,把以前做设计桌游原型剩下的蓝色卡纸垫在棋盘下,作为背景,这样,就可以很方便地从中抽取棋盘主体部分了。这算是“技术不够、装备来凑”的开端,后面你会看到,各种以此理念引导的极端解决方案。

(3)将棋盘照片四点对齐。这个步骤其实是很久以后才加上的,最初的时候拍照,只想着把摄像头支架放在与棋盘相对固定的位置,这样就可以让提取的棋盘很规范了。为了这个“相对固定的位置”,曾经一度尝试放弃了支架,转而用小朋友已经吃灰的乐高积木拼了一个摄像头支架。然而,不仅仅是距离,还有角度,稍微碰一下,整个数值就都不对了,每次又要重新对半天,鲁棒性太差。我不能把这样的产品交给习惯破坏性使用的小朋友,更不能交给机器忙的老人来使用。后来,偶尔看到单位配备的高拍仪,就是用摄像头当扫描仪的装置,发现它除了相对固定的位置,还有四点对齐的矫正功能,啊~只有想象力才是技术的局限,高拍仪能做,我也能做,于是四点对齐就做出来了,再也不怕拍摄的棋盘歪歪扭扭影响识别了。
(4)将棋盘切成9*10的小图片。对齐后的棋盘,就可以切成90张小图,每个小图,或有棋子,或没有棋子。

这里插一句,我是准备用深度学习最简单的Classification来做棋子的分类,每方7种棋子,加上空白棋盘位置,总共15类。

为了做深度学习,我用前面部署的一套环境和流程,生成了四千多张各种棋子在各个位置的图片,有的齐整一些,有的故意摆放歪一点,挪动棋子的时候,也专门旋转一定角度,有的灯光亮一些,有的故意制造一些阴影。切出来的棋子,手工进行分门别类,然后加上旋转、噪点各种处理,制造了几万张的深度学习训练数据。

(5)分别判断每个棋子上的信息。在我做到这里的时候,恰好2019年春天Jetson NANO发售了,于是决定抛弃掉PC机的方案,决定用NANO做,把计算单位做得越小,就会显得越酷!——因为之前用树莓派做过的一些小东西,很多同事都惊叹,这么小的芯片设备能实现这么智能的功能,都很赞叹,这一次,我本来也是想过用树莓派,然后用云端或者同一wifi网络的PC机提供算力的方案,现在有NANO了,就可以在无需联网的情况下单机实现了。几年前在一个私人趴上演示对话机器人,因为没有考虑现场基站的承受能力,导致一百多名嘉宾到场后,手机信号不可用,热点无信号,智能对话结果搞砸了。所以,不联网,对环境也更加鲁棒!

于是我就第一时间找Lady买了NANO,结果拿到设备的第一天,就把插卡的口子搞坏了:我以为它那个tf卡的插口跟树莓派一样,是直插直拔的,在拔的时候,怎么也拔不动,就用钳子硬拔,拔出来之后,再插就插不紧了。哎,我哪知道,它比树莓派的设计更好,拔卡是通过弹簧按压弹出再拔的。(默默回忆起,大学三年级去广东实习的时候,坐高级车,结果粗暴地把人家的电动车门拉坏,类似的情况一再上演,啊,我就是个低端用户。)在我懊恼地准备把NANO仍进垃圾桶的时候,单位的摄影师同事给我想了个办法,用一张便签纸把tf卡牵引进去,然后用纸的厚度卡住,不让tf卡弹出来(所以今天大家看到的NANO后面有一个绿色的便签纸小尾巴,那就是这个作用)。在得到拯救之后,我问摄影师同事:“你是不是也跟我一样,经常把设备搞坏,所以才这么有经验?”对方默不作声,我突然感觉自己嘴好贱。

给NANO刷机、各种安装编译,这些就不表了,反正是一番折腾。终于把深度学习Classification的程序改造好了(其实就是拿初阶教程里花朵识别的cnn模型改的),结果运行效果大失所望,识别率不行,根本达不到训练程序告诉我的97%以上,达不到心中的及格线,要知道,高手过招,一招一式决定胜败,一个棋子都不能遗漏和识别错。我怀疑,识别不准,是不是棋子可以旋转导致的,于是尝试过提取对旋转不敏感的特征来训练,也尝试过vgg、resnet等较为复杂的模型,在PC机上面运行效果还行,但部署到NANO上就遇到了新问题:负载带不动,断电。那时候,NANO才发售没多久,我都不知道可以接DC直流电可以使它供电更稳定,反复尝试之后,可算是从入手到放弃了。

一度放弃用NANO之后,我也放弃了用深度学习来做棋盘识别的进路,因为模型始终也没调整到最优。一位一直都说我这个项目是“哥德堡装置”的好朋友给我推荐了NFC方案,我觉得成本太高,而且NFC的大小决定了棋子得比较大,棋盘也得大,这给后期的抓取放置机械装置造成了困难(后面详细说),否决。我也琢磨过类似“智能棋盘”的思路,通过设计电路,用模数转换的方法获取每个棋子的电阻值判断是什么棋子,买了几大包各种电阻和若干“UART通信ADC模块”,结果在测试的过程中,发现电阻值测不准,原因不明(哎,虽然高中是理科生,还曾作为物理奥赛的选手培养,可惜后来的我却为司法考试付出了十年的青春),放弃。后来,我也曾尝试过一些恶心的投机取巧方法,例如在棋子上贴不同颜色、不同的简单图案,但那画面太辣眼睛,让人一眼看出我文科生无能为力的绝望,甚至是直接在棋子上放二维码,这跟考试作弊没啥本质区别,而且是明目张胆的作弊,我不能干这种令自己不齿的事情(至少得隐蔽一点吧!)。

下面试图干的就是隐蔽的作弊(嘿嘿~),一个偶然的想法,把之前的数据传到百度easyDL试了一下,哎,感叹自己还是学艺不精啊,看到百度easyDL用同样的数据,却可以让正确率达到99%以上,而且是在实际运用中确实可以得到这个水平的。我决定可以用这么个云端解决方案了,但始终没有动力做下去,毕竟我是想做离线版啊,用这么个云端解决方案是什么鬼?况且,云端方案的话,树莓派就好了,为啥要用NANO啊?我给自己下台阶,劝慰自己,说这个项目跳票这么久了,无论云端还是离线,先实现全流程再说吧!于是就用easyDL做Classification,然而,在项目运用中,还是出现了问题:调用easyDL的云端API,连续运行30多个就会卡死,工单问过百度,那边答复说是这种现实是为了避免滥用,系统对资源的保护策略,于是我只能人为强制每秒运行几次推理查询,这样,速度就很慢了,体验不好。期间,我也考虑过,不用Classification,而用Object Detection,也曾用很大的耐心标注棋盘数据,但正确率和位置的准确率没有分类好,毕竟,如果不考虑效率和成本,把问题控制在最小可控单元是最明智的,能不依赖深度学习黑箱是最好的。

诶,这个“能不依赖深度学习黑箱是最好的”是我在前面的困局中,试图用openCV来全盘解决问题的一种自我鼓励:切出每一片棋子区域后,我用openCV判断是否有圆形(位置是否有棋子),判断棋子的颜色,这些都做到了,接下来还准备拿openCV来做模板匹配的时候,发现前面判断棋子的圆形和颜色特别容易受到光影的影响,白天做的特别准的测试,到了晚上灯光下又是另一番景象,于是模板匹配暂时停了下来。把openCV与easyDL结合起来,就可以了嘛!前面用openCV判断位置上是否有棋子,如果有,就代入easyDL推理出是什么棋子。这样总算是基本走通识别的流程了,虽然后来发现,这样的速度比本地直接用NANO做各个棋子位置的推理的方案慢了很多。

前面不是说,尝试了NANO上推理,不太好用嘛!除了usb供电不稳定,也有自己写的深度学习模型本身不优的问题。这套装置一度吃灰,所谓“念念不忘,必有回响”,在群里同仁时不时的催促下,自己也一直不甘心。直到今年5月中旬,发现百度居然推出了“EasyDL前端智能计算-软硬一体方案”,可以把之前训练的那一套模型移植到Jetson NANO等设备上离线运行,哦~真是拯救我这类一知半解族的神器,按照大致OK的文档,终于部署上去了,不但离线了,NANO的GPU功能用起来了,而且速度飞快无比啦!

这样,看似很简单,实则一直是瓶颈的棋子识别总算搞定啦!

(6)将棋子信息融合成棋盘信息。将90个小片的棋子信息(包含无棋子的情况)按照特定位置融合到特定棋盘的位置,就生成了棋盘信息了。最早的时候,为了debug方便,在命令行生成一组自创的可视化棋盘;之后,觉得命令行不够直观,能够生成图片,图片展示棋局状况;后来,发现象棋有专门的FEN通用规则可以表示棋盘,例如 rnbakabnr/ 9/ 1c5c1/ p1p1p1p1p/ 9/ 9/ P1P1P1P1P/ 1C5C1/ 9/ RNBAKABNR 就是开局,为了用上机器智能的API,也生成了一套FEN格式的棋局;再后来,最终选择了elephantfish作为智能引擎,它需要输入一套它既定的命令行格式,这便是本项目生成的第四组棋局信息格式了。

至此,pipeline的第一步“识别棋盘”终于搞定啦!


2、棋局智能

通过棋盘局面,计算下一步棋如何走,这是本阶段的输入和输出。

最早盯着的,是类似AlphaGo、AlphaZero之类的“高精尖”,陆续试过github上发现的ChineseChess-AlphaZero、cchess-zero、Chinese-Chess-AI、icyChessZero等项目,发现一个共通的情况,就是拿大炮打蚊子,成本消耗太大,功效却没到火候,当然,也有可能是我自己水平太次,反正就是“核武器”用得也不爽。

还是前面说过搞的是“哥德堡装置”的好朋友,一天到晚以黑我、给我泼冷水为乐(当然,毋庸置疑,我们确实是好朋友,忠言逆耳,兼听则明),他说:“搞什么AlphaGo哇,二十年前的算法都足够中国象棋战胜人类了。”于是,我开始找小而精的算法,我又不是参加算法比赛,娱乐第一,只要能把小孩糊住,让老人家没那么容易赢,让一般的下棋者发现这机器还“是那个事”,就达到目的了。

最终,我用的智能引擎是elephantfish。在github上,你可以看到,它也是几个月之前才刚刚开源,之前是没有的,如果两年前有,我早就用它了。

在选定用elephantfish之前,我也曾一度想用在线的API,例如www.chessdb.cn/cloudbook_api.html 。用之前觉得它很强大,充满了期待,真的用起来,才发现它其实好弱鸡,好多棋局都没有现成的棋谱,只能随机出招——绝对昏招。这与之前尝试的那些“核武器”是同样的问题,于是放弃之。更何况,随着第一阶段棋盘识别的问题解决,我坚定了要做完全离线的想法,在线的API当然不再考虑了。

所以说,真的,一切都要选合适的,而不是传闻所谓“最XX”的。


3、机械操控

在夜深人静的时候,我(假装)望着星空会反思,我到底搞这些东西值不值得,没想想到这个,就能不知不觉很快睡去,因为我的内心是笃定的,不念过往,不惧将来,想做就去做吧!所以,现在回想起来,最拿不准的就是机械控制部分,因为之前完全没有做过这方面的创作,一路跌跌撞撞,最终居然给整成了,哈哈!我佩服我自己!

(1)丝杆直线滑台模组方案

还记得最初构思这个项目的时候,因为找到的资料有个视频,是国外一个人做的国际象棋,用的是XYZ丝杆滑台模组,所以我最初的思维也局限在用巨大的丝杆滑台模组。在这之前,我根本就不懂这些,通过请教若干淘宝客服,我逐渐懂了,这属于CNC数控机床的范畴,哈哈,CNN我听到的多,CNC还是新玩意儿。

因为最初准备用的棋盘是50cm*45cm的,所以当时反复选择,决定打造一个80cm*80cm的XYZ丝杆滑台模组,估摸了一下,还有步进电机及配套的控制器,给家里的飘窗定制了一个1m*1.2m的加高层桌板,桌板到货架起来的时候,老妈和老婆都说:“有钱攒着去买房子,不要买没用的东东!”这并不是最关键的,最关键的是,XYZ丝杆滑台模组3个含步进电机及控制器一套配下来要三千多,我差点就付款了,幸好因为桌板的问题在家里闹了不愉快,冷静下来后,确实觉得,本来就是好玩的事情,搞太认真就输了。于是,自此开始,放弃了最早的大棋盘、大棋子,换成小棋盘、小棋子的方案了。有位卖滑台模组的淘宝客服特别贴心,还加了微信,通过视频给我提供解决方案,可惜,最终我还是没有买,主要的原因还是家里房子太小了,哈哈~

因为放弃了大棋子方案,之前买的一套步进电机及控制器及琢磨的控制代码也都废弃了。还有个准备用来夹棋子的大夹子和舵机,在此之前,我都没整过这些玩意儿,当时把GPIO接错了,然后把一个测试用的树莓派Zero给烧了,那一瞬间的糊味,至今难忘。

(2)机械臂方案

这次放弃直线滑台模组方案之后,我觉得可以考虑机械臂,毕竟机械臂比直线滑台模组更像人,也更酷。也有可能是《复仇者联盟4》火了,然后回过头去看了《钢铁侠》的缘故,对机械臂开始情有独钟。反复权衡,500多RMB在淘宝上买了“傻二哥模型工厂店”的机械臂,前面有泵机吸盘,非常适合我构思的新的小棋子方案——新的小象棋棋盘和小棋子是淘宝上可以买到的最小的了,也就是我最终用的这款(当然,后来我丧心病狂的把这套象棋一口气买了6套,至于为什么,看到后面会讲)。

刚拿到机械臂时,我是迷茫的,还是那句话,之前根本没碰过。后来七摸索八摸索,终于能用python的pyfirmata库来控制自如了。其实也不难,就是三个舵机控制三个自由度,一个左右方向划圆圈,两个纵向的轴(就像人的手臂一样,一个主动轴,一个次动轴),设定特定的值,数字舵机就会挪动到特定位置,机械臂三轴就组成指向特定坐标的点。然后上面的气泵吸盘也很有意思,我原本以为就是个吸气装置,它还有个电磁阀,当我弄懂这一套的原理,就像回到高中的物理课堂一样的爽。气泵吸盘也是用pyfirmata库来控制。用Arduino UNO来输出PWM信号,当舵机的控制器。

这个机械臂也有缺点,不过可以克服。缺点就是,它的纵向只有两个轴,而棋子很小,如果要切到平面,其实是容易碰到旁边临近的棋子的,不过我有办法,用增加路径的方式弥补,在临近棋盘的地方多折一些小的往返,就可以躲过临近的棋子。
https://v.qq.com/x/page/n3102kgqold.html
机械臂比直线滑台模组酷多了,我原本我要与它厮守终身了,看这个视频,就是我曾经发的一个朋友圈,其实只是一个概念演示,当时却获赞无数啊!哪知道,有一天,情况急转直下,那天它的臂轴工作了几下,有个螺丝居然掉了,别的几个螺丝也都松了,我拿螺丝刀把它上紧后,发现之前的数据都不准了。螺丝松紧与机械臂的坐标密切相关,简直就是差之毫厘、谬以千里,但问题是,它的臂轴动几下,整个松紧度就不一样了,根本没法复现测定好的数据,也就是说,随着机械臂工作,误差完全是一个没法预测。原本还想学学机械臂的空间坐标系,通过计算来定位90个点的,结果发现这一茬,那叫一个没法用啊!于是找淘宝掌柜求助,掌柜立刻严正提醒:“这只是一个玩具,不是工业品,不对精确性负责。”意思就是,像演示视频那样,抓抓苹果可以,精准到毫米级,还请买高精度(价格贵)的机械臂吧!

很久以后,我在B站上面看到,有个学生的毕业设计,用同款机械臂做了8*8格子的五子棋,我于是加了他微信,向他请教。他说,不妨试试“闭环式控制”,我于是问:“啥叫闭环式控制?”人家一直没回话,我不敢再发信息了,估计已经在被拉黑的边缘了。

我似乎怀疑,机械臂是在一开始固定到板子上的时候就搞坏了吧?为啥人家可以用同款做8*8的五子棋,我9*10的中国象棋也只是略复杂了一点。我给机械臂找的固定板,其实是一个奖牌的反面,为了把机械臂固定在这个奖牌板的边缘,我上班前,委托老爸带到外面去上螺丝,估计是那个时候被粗暴对待了,导致了后面掉螺丝和不精准的情况吧!如果真的是这样,那么恭喜他,成功推迟了被机器人打败的时间。(习惯性不找自身的原因,坏习惯!批!)

(3)SCARA机械臂

总之,普通的机械臂方案是被否了,我也曾看过精准度较高的机械臂,曾经想过狠心地几千元整一个,然而去年考上了梦寐以求的法理学博士,是在职读书,学费嗨贵,还要养家糊口,实在是没钱买高精度的机械臂了。

所以,看到有SCARA机械臂,结构很奇特(大家可自行搜索,设计很奇特),感觉精准度也有保障,但始终没忍心买一台尝试。

(4)皮带滑台模组

无论如何,下棋机器人的项目要继续,我的目光又回到了直线滑台模组,不过,实在是不喜欢丝杆滑台那种庞大又冰冷的感觉,皮带滑台模组很酷,看它用途也很广泛:键盘机器人(似乎是用来玩DNF游戏的),用皮带滑台的写字机器人也有。关键的,它个头比较小,噪音也相对小,维护也相对容易。

我准备买一台皮带滑台模组的写字机器人来改造,从尺寸来看,也能够胜任目前的棋盘大小,而且写字机器人连字都能写,精度一定不成问题。也是经济比较紧张的原因,我没有买新的写字机器人,而是在闲鱼上面500块买的一个二手写字机器人。不过,实在是不能图便宜,后续发生了一些插曲,还是花了冤枉钱。

首当其冲,X轴上的笔架是断的,这个似乎是3D打印的一个配件,感觉应该是设计不合适,3D打印的材料韧性似乎不足以支撑那么重的一个步进电机在上面吧!无论如何,坏了就修吧,是二手的,又不是商家,人家卖家也没办法,说多了双方都不愉快,与其那么麻烦,不妨就自己想办法解决问题吧!断了嘛,就拿502胶粘嘛,两边用乐高积木的长条固定住,老爸看我用502粘得不是很好,拿出在拼多多上用来粘渔具的“焊接剂”,好家伙,确实比502粘得更牢固。还有陆陆续续一些小毛病,由于缺少专业工具,我都用很山寨的方法修复好了。

其中最麻烦的一个问题,是滑块的钢珠好多都掉了,也不知道是它本来就掉了好多,还是在运输过程中包装不善才掉的,总之是不能正常使用了,于是我就去淘宝买新的滑块。咨询的时候,淘宝客服不屑地丢给我一个网址,让我自己看图纸,我居然自己会看图纸了,型号是LWL9B,然后客服又丢给我一个对照表,LWL9B应该是进口的型号,与之对应的国产型号叫MGN9C,于是我自信满满地说,这个给我来3个吧!

几天后,我收到了3个滑块,又过了几天,又收到了3个滑块,而且都是MGN9C,一组是从上海发来的,一组是从浙江发来的,怀疑是商家把货发重了,一问,果然是发货发重了,问店家怎么办,店家说:那就把多的给我寄回来吧!前几天因为工作很忙,也没来得及试,我想着肯定是能用的嘛,于是我就说,算了,寄回来麻烦,干脆我再拍3个,算是照顾你生意了。印象中,店家没有说谢谢,我心里略有点不爽。结果回到家,开始试的时候,发生了更不爽的事情,型号虽然一样,但里面的钢珠不一样,新买的这批钢珠明显是比原装的要大很多的,自然就卡不进去了,店家居然还说:“使劲,你姿势不对!”

在确认是钢珠大了之后,我退一步,原装滑块不就是钢珠掉了嘛,我干嘛要重新买滑块呢,我买钢珠还不行嘛!于是就找了一个卖钢珠的店家,我就拿小朋友做作业的直尺量,大约1mm,卖钢珠的店家劝我买个游标卡尺量,我说,不用了,没钱买游标卡尺,保险起见,1mm的、1.2mm的、1.3mm的,一样来一袋好了,总有一款适合咱,跑不掉的。估计店家被我的傻缺精神吓到了,给我免了邮费。几天后,花了21元的3袋钢珠到了,发现三款都小了。哎~21元可以买一个游标卡尺了。

不想折腾钢珠了,只得又回去找那个卖滑块的店家,干脆又找他订制了滑轨。算了,我是中国好买家,不计前嫌,多多积德,为了象棋机器人项目早日成功!最后,收到的滑块终于算是配套上了。皮带滑台模组的硬件搞定啦!

(5)CoreXY结构的皮带滑台的控制

搞定了硬件,软件的时候傻了,我总是很傻很天真,以为天下所有的滑台都是直线滑台那种XY笛卡尔坐标系的,XYZ轴分别每个轴一个步进电机控制,结果眼前的这个皮带滑台模组的写字机器人,它的XY轴是一体的,一根皮带联动两个轴,两个电机同时向前则X轴向前移动,同时向后则X轴向后移动,左前右后则Y轴向右移动,左后右前则Y轴向左移动,我的天呐,这怎么控制啊?之前机械臂那样的Firmate库的python解决方法有吗?一番摸索之后,发现答案是有的!

这套写字机的3个步进电机也是通过arduino UNO来输出PWM作为控制器的。在网上找此类写字机的资料,似乎可以用Xloader来烧录Corexy__servo_0.9.hex ,不过这个方法不能达到我用python来控制滑台的目的。于是还是继续找python控制arduino的CoreXY方案:烧录GRBL,具体的步骤是:在官方Arduino软件中,依次选择“项目-加载库-添加ZIP文件或文件夹”,选择GRBL里面的gbrl文件夹(GRBL从github下载),加载后,选择“文件-示例-第三方-brl-gbrlUpload-烧录”,之后,就可以用python的serial库来控制CoreXY结构的皮带滑台了,可以控制其XYZ三个轴。不要问我为什么会,我也是从别地方学来的,不记得是CSDN还是B站了,反正我就是学会了。所以说,世界上没有多么难的事情,关键是你想不想钻研,而钻研的前提,是你有没有兴趣,有没有坚持。

这个当中有个插曲,我之前是一直用MacBook在做这个项目的开发,到了这一步,serial库不能正常工作,在Windows电脑上却可以,查原因是说:MAC上面USB-serial Controller已经不能用了,据说是生产厂家问题。不深究,果断换Windows,试了一下NANO,没问题,NANO没问题就行。

在Windows电脑上也遇到点小插曲,一开始这个UNO插上USB口,打开官方的烧录程序不识别,我疑惑问前面提到过几次的好朋友,他说:系统不识别,似乎是因为这个二手写字机所用的arduino UNO是个国货,请安装CH340或CH341驱动,同时,要想通过USB串口与其通讯还得装PL2303芯片驱动。哦哦!按照他说的,果然搞定啦!

在Windows电脑上,也顺便用绿色版的“奎享雕刻”软件(不能用新版本,新版本需要购买才能用,这个是旧版本,绿色版,挺好的~)试了一把装置的本来功能——写字。用这个软件的调试功能,彻底搞明白了CoreXY的精巧结构。

前面说了,用python的serial库实现控制,本质上是向控制器arduino发去gcode数据,写字机也是执行后缀名为gcode的文件内容,通过“奎享雕刻”进行了理解,然后就会写了。我们的需求也比较简单,就是定位象棋棋盘的90个点。

(6)小补丁

不得不吐槽,这个写字机器人实在是太“二手”了,虽然我极力想调整好它,但它依然有问题。最大的一个问题是,从近处的棋子挪到远处没问题,但是,把远处的棋子挪回近处,涉及到X轴的换向问题时,它这个一体结构的缺点就暴露了,X轴有个很明显的偏移误差。不过,幸好这个偏移误差是个固定值,我只需要在程序中加个补丁,判断是否是这种换向折返的情况,如果是,加上这个固定值就行了。谢天谢地这个便宜误差是个固定值,如果像之前的机械臂那样是个不确定值,我这次又崩溃了。

(7)技术不够,装备来凑

从数字世界到物理世界,滑台依然是存在误差的,人类就是用手去移动棋子,也有可能摆的棋子不一定在正位置。一定的误差固然没什么,但对于棋盘来说,如果棋子不在正位置,就有可能识别错误。这就是工程上经常说的,流程中三个90%的准确率会导致整个系统的准确率只有70%多点儿。为了尽量弥补误差,也就是想尽量地把棋子摆正,无论是在机械装置移动后,还是在人手棋子移动后,那就是:把每个棋子的正位下面都放一个磁铁棋子(前面忘了说了,这个棋子就是带磁铁的),我画了一个纸棋盘,弃用了它自带的铁质棋盘,这样,棋子如果没搁在正位,它就会被最接近的一个位置上的磁铁棋子吸到正位上,从而确保了在操作环节的误差尽量小。当然,你难保被错误的位置吸走的,但那是极少数情况,一般情况下,这套设计能发挥良好的作用。

所以,现在知道为啥我前面用又买了6套象棋了吗?因为要填充90个位置。这虽然是一个暴殄天物的方法,但达到效果就好。也较好地贯彻了我一直奉行的“技术不够、装备来凑”的山寨理念。这只是一个原型demo,如果将来有机会量产,很多东西不会这么花钱和浪费的。

(8)气泵吸盘

由于滑台的XYZ轴是用serial库来控制,由一个烧录了gbrl的arduino来控制,所以气泵吸盘就只能用机械臂时的老办法pyfirmata库了,这是另一个arduino。前一个arduino接口不够,加了个扩展板,还需要额外的电源支持,后面这个不用扩展板和额外电力支持,从NANO的USB口供电,经测试没问题。

我把气泵架在写字机原本的笔架子上,尺寸距离都刚刚够用,好不惬意。


4、整体移植到NANO上

移植到NANO上,这就是近几天的事情了。

首先是百度easyDL的离线SDK只适用于JetPack 4.2.2版本,这个不是最新版本,下载速度很慢,于是求助Lady,她请工程师帮忙,下载下来后,帮我传到百度网盘了,网络的接力使我能够很快投入正式的战斗。

再就是,终于我要换DC电源了,依然是求助Lady,她慷慨地顺丰给我寄了一个过来,在等待电源的几天里,就像要到人生巅峰的感觉,充满了期待。果然拿到电源之后,一切都非常顺利,如果一切都能像这几天这么顺利,就不会前面叽里呱啦写一万多字了。

唯一就是发现,前面矫正图像畸变(四点对齐)的过程比较慢,大约足有两分钟,应该是默认的openCV用的不是GPU的缘故,于是按照JetsonHacksNano的buildOpenCV方案,略微修改了下shell脚本,就编译带CUDA加速的openCV成功啦!然后矫正图像畸变的过程就比较快了(大约10秒,可以忍受的范围,知足了)。

将Windows上python代码移植到NANO上,其实没什么难度,对本项目来说,唯一需要修改的,就是接arduino的USB口的名称要改,Windows电脑上叫COM3,到了NANO的ubuntu系统里,可能就叫ttyACM0或ttyUSB0了。

目前,项目已经可以顺畅地跑起来了。我们家的老老小小已经与机器鏖战过几盘了。接下来,加上一些循环和逻辑,设置成开机启动,然后接上GPIO的按钮(每次人类下完一步之后,就按按钮,然后机器就开始识别-思考-执行),这些应该都没难度了,都是很久以前都搞定的代码了。

我做这个下象棋机器人的心路历程与技术原理大致就是这些,真的特别的高兴!终于对一众朋友夸下的海口,没有食言,你不管我的方法有多少山寨的成份,至少我做出来了,至少跑起来效果还算不错,至少能给下棋体验的人带来一些欢声笑语和惊奇!而且,最关键的是,我是用NANO做出来的,而且是充分发挥了NANO的性能和效用的,你不得不说,人生就是这么神奇,虽然我一度都绝望了,但机缘巧合,最终又绕回来了,而且OK啦!

我始终相信,人生不经意间留下的伏笔,总会在哪里惊艳登场。需要插一句的是,几年前长辈送我surface book的时候,问我要不要扩展坞,我随口说了一句要,后来发现这扩展坞一千多块钱,好贵的,但就功能来说,一直没啥用,吃灰吃得我一直耿耿于怀。直到这次的项目接近尾声,必须用Windows电脑开发,而且需要3个USB口(一个摄像头,两个arduino),再加上鼠标,才发现,真心需要这个扩展坞。这真就是,你今天做的一切,哪怕是一件小事,都有可能是未来一个重要节点的伏笔,所以,好好珍惜眼下,一切的经历都是财富!
https://v.qq.com/x/page/g3102o40cu7.html
最后,奉上最终效果视频的另一段,是父亲节当天晚上老爷子与机器装置的对战(由于手机问题,后面部分的拍了,居然不能读取,我想说的是,历时一个多小时,老爷子最终还是赢了机器!姜还是老的辣,哈哈~)

请大家给他点个赞吧!



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
使用道具 举报 回复
发表于 2021-1-6 11:20:48
给你点个赞
使用道具 举报 回复 支持 反对
发表于 2021-1-15 17:59:49
点个赞,厉害厉害
使用道具 举报 回复 支持 反对
发新帖
您需要登录后才可以回帖 登录 | 立即注册