前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >多么孤独的灵魂,才能用Jetson NANO做个象棋机器人

多么孤独的灵魂,才能用Jetson NANO做个象棋机器人

作者头像
GPUS Lady
发布2020-07-01 10:49:42
2.7K1
发布2020-07-01 10:49:42
举报
文章被收录于专栏:GPUS开发者GPUS开发者

本文来自一位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

最后,奉上最终效果视频的另一段,是父亲节当天晚上老爷子与机器装置的对战(由于手机问题,后面部分的拍了,居然不能读取,我想说的是,历时一个多小时,老爷子最终还是赢了机器!姜还是老的辣,哈哈~)

请大家给他点个赞吧!

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-06-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 GPUS开发者 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云直播
云直播(Cloud Streaming Services,CSS)为您提供极速、稳定、专业的云端直播处理服务,根据业务的不同直播场景需求,云直播提供了标准直播、快直播、云导播台三种服务,分别针对大规模实时观看、超低延时直播、便捷云端导播的场景,配合腾讯云视立方·直播 SDK,为您提供一站式的音视频直播解决方案。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档