【机器人】树莓派+Arduino+TensorFlow:搭建图像识别小车 - 知乎

标签: | 发表时间:2019-01-04 12:35 | 作者:
出处:https://zhuanlan.zhihu.com

从买第一个Arduino套装开始,我接触机器人有好几年了,但直到最近才开始做完整的课题。期间有两项技能为我打开了新世界的大门:Python和Linux。他们背后,是强大的开源社区。掌握了这两样工具的工具(元工具),你感觉网上遍地是趁手的兵器。上周在公司内部编程培训时,有一句话深得我心:我们是软件工程师,不是程序员。我们的工作不是写程序,而是合理使用工具解决问题。在Google,如果你觉得自己不得不从零开始写某项功能,只是你还没有找到相应的工具罢了。在开源社区更是如此。

这是一个遥控小车,通过红外遥控或无线键盘可以控制小车的行动和摄像头的角度。TensorFlow实时监测摄像头拍摄到的画面,语音读出它识别出的物体。所有代码都放在我的 GitHub上。

这个想法不是我的原创,来自Lukas Biewald去年九月写的 这篇博客。核心部分,TensorFlow识别摄像头图像并语音输出,是我司人工智能工程师Pete Warden的 开源工作。和原博客不同的是,制作过程中我加入了Arduino作为机械总控,也了解了Arduino和树莓派对话的方法(串口通信)。期间用到了许多有用的技能和工具,在这里整理一下,欢迎同好们留言交流!

整个课题在命令行环境完成,没有图形界面。如果你不懂Linux系统,可能有些吃力。但是,你都开始玩机器人了,怎么能不学Linux呢?我是通过《 鸟叔的Linux私房菜》自学Linux的,后来又尝试 从源代码搭建Linux,终于克服在Windows系统环境长大产生的对命令行的抗拒心理。相信我,克服这个障碍,你将打开新世界的大门。何况,用命令行工作才显得更酷更极客,不是吗?除了Linux,你还要懂C++和Python来完成这个课题。

另外,这篇文章主要介绍电子部分,不讲机械和美工。如你看到的,这个小车丑破了我的审美底线,我没花心思在外观上。我希望以后做一些兼具美学和功能的电子课题,或许会和设计师朋友们合作!

一、树莓派

首先,你需要一个最新款的 Raspberry Pi,安装好定制的Linux系统,连上无线网。你还需要一个 官配摄像头,并在树莓派中 设置为可用。你可以将树莓派通过HDMI连接到显示器,但更方便的做法是ssh远程登录,这样你就不用在调试过程中反复地把树莓派从小车上拔线、取下、连屏幕、然后安装回小车了,你可以实时远程修改小车的内核。甚至,我的Arduino程序也是通过树莓派编写、上传、通信的,于是也免去了电脑连接Arduino的步骤,让一切更流畅无缝。

树莓派的Linux系统支持图形桌面,你可以使用RealVNC(用于Windows)或TightVNC(用于Mac)远程登录图形桌面。(这个课题里不需要)

二、TensorFlow

这是课题的核心部分,反而操作起来最简单,因为一切都在 这里写清楚了,按部就班就行。运行代码在 这里

注意:这里用了训练好的模型,即TensorFlow中预先给定了训练好的参数集,训练图片库是 ImageNet。也就是说,小车识别出的物体只能是图片库里包含的labels,也没有“学习”的过程。

三、小车

小车套件(robot chassis)很多,选你喜欢的一款。标准的套件包括一个基座,两组马达+轮子,一个万向轮,一个电池盒。这个课题不需要四驱,而且之后要用到的马达控制器可能只支持两个马达。我用的是张尧姐送给我的第一个DIY套件:一个戳了很多洞的木板和3D打印出来的轮子和连接部件。这个恐怕是 萝卜太辣最早的套件,来自硅谷的创客空间。现在,萝卜太辣已经是国内机器人教育的领军公司,他们正式出品的“起源”套件已非常精致完善,线上也有成熟的教学资源。这个课题里用到的舵机和金属连接部件都来自尧姐送给我的第二个套件——“起源”套件。但从感情上来讲,那套粗糙的木板套件让我更亲近,符合“用最简单的材料实现原型”的理念。

电源:树莓派需要5V、2A电源,放在小车上的话需要一个电流足够大的充电宝。连接树莓派和Arduino的连接线同时也为Arduino供电。但是,马达我用了外部电源(电池盒)。你会发现即使没有外部电源,充电宝依然可以带动马达(尽管很慢)。但是,好的习惯是机械部分独立供电;逻辑电路部分由充电宝提供。

下一步,操控小车。这里有两个方案,第一个不需要Arduino。我使用的是第二个。

3.1:树莓派作为机械总控

我认为单片机的精髓,不是尺寸小,而是丰富的GPIO(General Purpose Input-Output),它们是程序与外部世界对话的窗口。你看到的各种电子部件、探头、焊接、面包板,都是在和GPIO打交道。你需要了解基本的电路知识,也需要知道它们在单片机上的 排布。树莓派有一个非常好用的GPIO Python库: gpiozero,使用方法一目了然。

通常用四个端口控制马达,分别连接两个马达的正负级,通过每个马达的正向/逆向旋转来实现小车的前进/后退/转向。实现双向电流的标准电路模型是 H桥接。你可以选购一款最基本的H-bridge模块。

因为我手头没有H桥接,所以这个方案我没有实现。

3.2:Arduino作为机械总控

我没有H桥接,但有一个用于Arduino的Motor stacking shield,即Arduino上的H桥接。于是我干脆用Arduino负责机械(马达+舵机),相当于身体;树莓派只负责图像识别,相当于大脑。

Arduino不是Linux系统,不能直接ssh进去写程序,需要在外写好后编译上传。我用数据线连接了树莓派和Arduino,在树莓派上写好程序后上传。我发现一个非常好用的命令行IDE:PlatformIO(也有很棒的图形界面编辑器)。Linux上的 安装过程基于Python 2.7。你需要一些初始化,如果像我一样是Arduino Uno主板,输入以下命令即可:

pio init -b uno

Arduino的C++源代码在 这里。进入 这个文件夹后,输入以下命令即可上传:

pio run –target upload

后来我发现PlatformIO对于Arduino主板好像不支持C++11,如果你有这个需要,可以考虑 inotool

四,无线遥控

同样有两个方案:无线键盘,红外遥控。两个方案我都实现了。

4.1:无线键盘

如果你在上一步用了3.1,无线键盘操控模块就可以直接嵌入到机械操控代码中(我没有实现)。如果你在上一步用了3.2,那么需要在树莓派上将按键操作转为机械控制信号(文本形式),通过串口通信(Serial Port)操控Arduino。python代码在 这里,用到了我 自己写的库,用来检测键盘按键。这个库将单次按键匹配到前进/后退/转/停止等行为;但我希望实现的是长按键前进/后退/转,不按键时停止。但我始终没有找到现成的库(Update:据说在PyGame里有)。后来我试着通过背景线程(threading)和系统延时的方法 写了一个库,但效果不太理想,系统延时和程序运行时间带来的误差总是匹配不好,就放弃了。现在代码里用的是单次按键行动/停止的方案。如果读者有好的库,请推荐!

有一点要注意,使用串口通信前需要disable login(既然你已经ssh远程登录了), 这篇解释比较清楚。

4.2:红外遥控

老婆催我看电影,红外遥控的原理就不介绍了。红外的长按返回的是一个单独的值(REPEAT),这点就可以让我很容易实现“长按-车动,不按-车停”。此外,红外遥控的代码直接写在Arduino的C++代码里,不需要通过树莓派和串口通信,更符合Arduino作为机械总控的设计原则。

PlatformIO不自带红外的库,我用的是 这个。PlatformIO使用第三方库实在太简单了,不需要下载安装,直接在配置里加上GitHub链接即可,参考我的 配置文件

还有一点,每一个红外遥控都不一样。家里的电视机、音响、空调遥控都可以用,你只需要在使用前匹配好按键和对应的码。我在 代码里define的一堆KEY只适用于我的遥控器。你可以用 这个代码来获得键码。注意:红外遥控有几种模式,我的遥控用的是最常见的NEC模式,如果你匹配出来一堆乱码,可以考虑库里的其他几个模式。

对了,如果你用红外遥控,你还需要在车上装一个IR Receiver。我装在Arduino上,用8号端口。

如果你用了方案3.1,你也可以直接将IR Receiver装在树莓派的GPIO上。

五,其他

这些已经够你开车上路了。我在车上装了舵机(Servo),控制摄像头的上下转动。操作很直观,看代码就能理解。我没有装超声探头,这个可以帮助你检测障碍,在撞墙前强行停止。

如果你想远程看摄像头的实时画面,VNC不能胜任。可以考虑 这个方案。但这样的话TensorFlow就不能再用摄像头了。应该有一个共用的方案,我没有探究。

差不多就这些了,我的代码没有太多注释,等有空往上加。如果你有疑问,可以留言问我。

福利: 这里有一个延时摄影的简单程序,我在crontab里设置为每隔一分钟拍一张照,然后每天半夜将当天拍的照转成录像。下周打算带到公司里,找个风景好的位置,放几天,拍纽约的24小时风景。

相关 [机器人 树莓派 arduino] 推荐:

【机器人】树莓派+Arduino+TensorFlow:搭建图像识别小车 - 知乎

- -
从买第一个Arduino套装开始,我接触机器人有好几年了,但直到最近才开始做完整的课题. 期间有两项技能为我打开了新世界的大门:Python和Linux. 掌握了这两样工具的工具(元工具),你感觉网上遍地是趁手的兵器. 上周在公司内部编程培训时,有一句话深得我心:我们是软件工程师,不是程序员. 我们的工作不是写程序,而是合理使用工具解决问题.

Arduino 与树莓派 Raspberry Pi 相比各自有什么优缺点? - 知乎

- -
因为近两年内有家装的需求,考察了市面上的智能家居方案,要么不靠谱看不上眼,要么价格高得离谱. 想着自己原来也搞过一段时间单片机,Linux 靠着 Google 和 StackOverflow 也能解决一些问题. 于是开始尝试 Arduino 和 RPi 在家居控制方面的各种实践. RPi 和 Arduino 两个完全不同运算水平的平台.

极客DIY:利用Arduino 制作一个小机器人

- - FreeBuf.COM | 关注黑客与极客
Arduino是一款开源电子原型平台,包含硬件(各种型号的Arduino板)和软件(Arduino IDE). arduino的一些特点,开源架构. 我们也可以很低的价格从网上购买到现成的控制板;统一接口的传感器,应有尽有的传感器组件. 通过统一的插口,很方便就能连接不同扩展设备. 作者提供了一些参考( 点击我).

如何利用树莓派打造一款机器人 | 新知 · 科技

- -
本文来自作者:刘端阳在 GitChat 上的分享「如何利用树莓派打造一款机器人」. 树莓派是为学习计算机编程教育而设计,只有信用卡大小的微型电脑,最早的系统基于Linux,随着Win10 IOT的发布,现在树莓派也可以运行Windows. 树莓派虽然只有信用卡大小,但是内心却非常的强大,视频,音频等功能都是有的,现在树莓派3版本有1G内存,1.2GHZ频率,拥有操作系统的树莓派预留了40个可以驱动各种传感器和驱动器的 I/O 接口,所以我们使用树莓派作为机器人的控制器,将控制软件写入树莓派的TF卡中,然后这个软件通过 GPIO 接口就能控制驱动和传感器了.

新玩具:Arduino Uno

- Zheng - 大智若鱼
没生在一个好的年代,不能跟Wozniak一样拿电烙铁亲手做点什么东西. 中学的时候,一腔热情都被我喷到了集成度更高的电脑上. 到了大学,又阴差阳错地选择了文科,彻底与电子产品无缘了. 但这并不能阻止我对电子产品的热爱,比如我家还有一块万用表和烙铁(虽然用的极少),比如我对拆解电子产品有浓厚的兴趣. 前些日子看 thetwo.cc 的文章,发现两篇介绍NXT的文章.

树莓派初级折腾

- - 极客范 - GeekFan.net
前些天在网上买了一个二手的树莓派 裸板子190包邮 (新品套装280 360什么的太贵了啊岂可修). 到手目测没有问题 主IC还有一个铜质散热片 不错. 电源就用买移动电源送的充电器(标称5v 1000mA输出 )和数据线. SD卡么… 把很久没玩的PSP掏出来 把马甲卡中的东西倒到记忆棒里 记忆棒插回PSP TF卡装到转接卡上 (话说还是个class10的呢).

安装树莓派 Raspberry PI

- - CSDN博客综合推荐文章
树莓派终于到货了,是这个样子的. 上面有一行日期是 Raspberry PI (c) 2011.12. 选择这个镜像: RASPBIAN Debian 2014-01-07. 780M的压缩包,很大的样子. 似乎还有个NOOBS的安装方式,完全无感. 顺便展示一下SD卡,通过查阅可用SD卡列表,似乎是支持个别的64G Class10的卡的,就像这个,编号是 Transcend SDXC 64G Class10 TS64GSDXC10.

树莓派 1602A显示屏

- - 编程语言 - ITeye博客
树莓派 1602A显示屏. 下面代码本人测试过没有问题,开始运行完屏幕上什么也没有显示出来,后来调整了下电位器可以了,所以大家如果按着下面的做出来之后运行什么也没有显示的话,记得调整下电位器. VO,液晶对比度调节,接电位器中间的引脚,电位器两边的引脚分别接5V和接地. RS,寄存器选择,接GPIO14.

自制 Arduino NFC 实验

- Nickcheng - Engadget 中国版
Google 大神刚刚发布了非接触式钱包挑战金流,不过这种金钱游戏离市井小民总是有一段距离,况且不是每个 Android 手机都有NFC 功能. 不过自己玩玩总可以:Joe Desbonnet 用 Arduino 开发板,作了个 NFC 的小小实验:. 一台有电子罗盘的 Android 行动装置(如图中使用的 HTC desire).

在树莓派上用python控制LED

- - 极客范 - GeekFan.net
初步学习RPi.GPIO模块的过程中写了一个控制8个LED的模块,基本上只是一个对RPi.GPIO的一个封装. 一个已经安装配置好了的树莓派. 连接控制树莓派所用的其他必须设备. 按照电路图所示,在面包板上进行连接. 首先得确定RPi.GPIO已安装. 最新的系统已经自带了,如果没有的可以使用命令.