树莓派、机械臂、物品识别与智能小车

自从暑假看到一些人拿单片机DIY的好玩的东西之后一直对于硬件蠢蠢欲动!超级超级激动!

当时只是羡慕,没想到的是这个学期竟然有机会接触,开心的不得了。接下来记录一下这三个和硬件有关的课设中自己的经历。

1 基于树莓派控制机械臂实现特征识别与抓取

这个是数字图像处理课的课设,是小组合作项目,因为大一要补的课太多,以及自己代码能力也不是很强,于是并不是统筹主写代码的那个人,挺遗憾。

所以还是写一点自己实现的小工作吧:

    1.1 设计抓取动作算法

某个在实验室的晚上自己看完了各种文档终于搞懂了树莓派是如何控制机械臂的, 然后很激动……

对于如何实现任意半径范围的抓取,如果三四个舵机都不固定的话,多边形的计算本来就会有很多个解,角度也不好映射,操作起来十分复杂。于是我和朋友讨论出来了一个暴力方法,然后室友又提供了一些新意见,完善讨论出来最终的方法……虽然很蠢但是至少功能实现了而且代码写起来很简单……可行性高就行(自我安慰)

    1.1.1 代码控制机械臂运动的原理

树莓派通过引脚(从集成电路内部电路引出与外围电路的接线)来控制外部设备,而在本次实验中我们要用到的是其中的GPIO(通用输入与输出)口,以此控制舵机的运转。

而在树莓派中,我们可以用python语言调用pigpio库使得其发出PWM波来实现对于GPIO口的控制。pwm波可以操控舵机的位置和速度,从而让机械臂实现我们想要达到的各种动作。

我们在这次实验中使用的树莓派3B+的引脚对应与映射关系如下图。

图片1

图片2

代码实现

在树莓派3B+的各GPIO口中,与抓取有关的分别是GPIO 12,16,3,4,19,13这几个,它们分别对应从上到下的6个舵机(Servo1-Servo6)——最上面的爪子,中间控制角度的4个舵机,以及底盘的转动。

图片3 图片4

    1.1.2 抓取动作的数学模型

机械臂抓取的模型需要解决两个问题,一是如何将摄像头图像中用像素表示的坐标(x,y)映射为物体的实际位置,二是如何将物体的实际位置映射为机械臂各舵机控制的参数。这样我们才能用代码实现对于机械臂的抓取。

因此我们设计的模型,要尽可能使得这两个问题易于解决。

其中,对于摄像头固定的位置,第一种选择是固定在机械臂上跟随机械臂运动,第二种选择是固定在机械臂底端,第三种选择是固定在某一独立于机械臂的位置。前两种选择在工程上更为实用,但是数学模型较为复杂,并且受误差影响较大。因此我们采用了第三种选择,抓取模型如图所示:

截屏2019-10-14上午11.01.07

对于待抓取的二维平面,我们采用极坐标——转动角度(θ)和距离(R)来表示被抓取物体。

转动角度(θ)可以通过底盘的舵机(Servo 6,GPIO 13)来控制。而距离半径R可以通过控制中间4个舵机(Servo 2-Servo 4)的角度来实现。

截屏2019-10-14上午11.01.14

(我直接用word做的图哈哈哈哈,下次应该探索一下好的绘图软件……)

    根据上图,得到转动角度(θ)的计算方法:

图片5

距离R和4个舵机参数的对应关系:一开始我们想通过逆运动学方程求解,但是由于逆运动学方程的解不唯一,且涉及较为复杂的数学原理,因此我们采用了一个较为简单的算法,以R为标准将机械臂的抓取范围分为15个圈,每个圈的4个舵机运动的参数通过手动测定得到。代码示例如下:

图片6

    1.2 设计光照补偿算法

这个工作是和室友一起做的。室友在网上找光照补偿找到了gamma的代码,但是我并不明白其中的原理是什么。而且gamma的值如果固定的话,对于所有像素都是提亮或者变暗,只是程度不一样。因为幂的值限定了,如果>1,所以光线太弱也是所有像素变暗(只是变暗程度不一样);如果<1,光线太强也是所有像素提亮,所以起不到我们想要的效果。

于是我又开始自己瞎想算法,先算出整张照片的像素亮度平均值A,然后A除以某个数x成为幂函数的指数,这样指数可以动态调整,>1是变暗,<1是变亮,x的值由实验得出来。

虽然在自己电脑上这个算法运行起来很快,但是在树莓派上反应就极其慢。后来发现是因为对于所有像素进行浮点数操作需要耗费大量的计算时间。下次有机会要思考一下如何简化,因为速度太慢在工程上肯定不实用。

在编程的过程中我们也想到了同除以255使得像素范围化到0-1之间,这其中还因为整数和浮点数换算出了一个BUG,后来我们发现了问题修改了算法。后来很开心地发现我们俩想的和gamma的思想其实是暗合的,是“归一化,预补偿,反归一化”的思想。于是看懂了网上代码,自己顺带又了解了一下gamma的原理。截屏2019-10-14下午6.46.22

2 模型机实现阶乘

虽然实验指导书上连线图都给我们画好了,但是本人真的超级粗心于是自己把接线检查的工作丢给了合作的妹子……然后代码嘛就只能全权自己负责了。

本来自己真的没指望能写出机器指令的代码,心里默默想我c++都还在学汇编都没学过怎么写机器指令??

老师给我们的只有一个实验指导书里面关于加法的代码,还有一个冒泡排序的代码,周围的同学做的基本上都是选择排序,但是我想做的是阶乘,所以并没有人可以参考。有时候想着自己要不做个简单的算了,但又觉得不能要求这么低。一次我和同学开玩笑说:“要不我做个加法混个合格算了。”同学说:“你这样是在给中国的本科生丢脸。”……嗯,阶乘就阶乘吧。

通过这次课设我真是充分掌握了“机器学习的精髓”(怎么把自己当成一个机器来学习)……

因为这个实验真的是纯逻辑了,光在纸上写非常容易错,自己纸上草稿就打了三四回吧,之后上机调试还是有很多错。好在最后还是成功了,对自己来说算是很大进步吧?

(输出结果:5的阶乘 十六进制表示)

若要了解更多可以看实验报告:

我的辣鸡计算机组成课设

3 树莓派控制智能小车-寻迹避障

这个是工程实训作业。看到树莓派之后我们树莓的同学开心的不得了:哈!!又是它!!而且这次的树莓派还是新的,没有坏哎!!

这次我们用的还是python,不过调用的不是pigpio而是RPi.GPIO库,使其发出PWM波来实现对于GPIO口的控制。

主要功能是循迹,有提供的四路红外模块(并且带指示灯),所要做的就是搞懂原理然后根据原理调参数和改逻辑。因为要实现交叉线直行的功能,于是在设计算法上大家还是做了一番思考。比起上一次机械臂的课设这次自己终于是掌控写代码的那个人(之一)啦!!然后在这次课设中获得了很多debug经验。原来自己可是连print大法都不会的人。

以下是我做的一个流程图,当时偷懒了……

然后就是利用各个模块给智能小车加了一大堆花里胡哨的功能,什么超声波避障啊,倒车入库啊,前舵机啊,蜂鸣器啊,七彩灯啊之类的。至于避障和倒车入库这两个看起来比较高级的功能我们实现的方法还很愚蠢。

本人做的另一个工作是,写了个红绿灯识别的简单算法,大概步骤就是在HSV色彩空间里先设定红绿色的高低阈值,循环读取帧,如果检测到红色/绿色,读取掩膜,并得到轮廓,如果面积大于一定值则认定是红灯或者绿灯。然后又发现了颜色检测的时候不仅检测红还要检测橙这样检测效果会比较好,于是又加入了优化算法修改了阈值,然后又因为发现人脸嘴唇的颜色会干扰识别,于是一直在调各种参数……调参调参调参……树莓派上的OpenCV还是助教装的,感觉自己好垃圾。

因为跟OpenCV的课写的各种实验比起来太简单于是不好意思放代码了……(逃

不过玩的非常开心就是了!!

过程中发生了很多有趣的事情,比如隔壁班有一个组想让树莓派唱一首歌,然后调了一天代码也没调出来,还有的组自己DIY了水晶头,还有个组把树莓派烧掉了(树莓派又做错了什么)。比如某组小车充电到一半突然开始灭火,一同学跑过去,结果被小车风扇割到了手……比如我们班因为做小车太积极导致助教留在实验室不能回家千方百计赶我们回去。比如我们组不小心改错代码导致小车看起来生气了,有人踢了一脚导致小车开始抽搐,把它抓起来之后还乱扭(真的太可爱了哈哈哈),还有各种调戏小车和围观车祸……

可以说是非常快乐的一个短学期啦。

最后的演示剪了一个小视频,下次如果记得的话再放上来……

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注