一个简单的机器人
这是一个用来制造结婚十周年惊喜的机器人,它的原型是 Kiwibot 送货机器人,我使用了一些简单的技术来复刻它,目的是想让我的爱人感受到她程序员老公的一点点浪漫。
我的计划是在让它在那个重要的日子帮我去投递一份我准备好的礼物,我在家里通过远程操控它前往某个目的地,然后在我爱人面前打开仓盖。远程操控的距离必须足够远且不能被轻易干扰,同时那些可爱的表情也要保留。
设计
基于以上需求我至少需要一个可以显示表情的屏幕,一个可以获取机器人周围映像的摄像头,一个可以和服务端通讯的网络模块以及一个遥控车地盘,刚好我手头就有一个集成了前面三种功能于一身的设备——手机,对于软件工程师来说,基于手机开发应用那是再熟悉不过的事情了,所以最简单的实现方式是,通过 WebRTC 推送视频流到远端,在 Web 页面显示表情,而 MCU 则可以通过手机共享的网络接收远端的指令。
制作
机体结构
由于我没有使用过 CAD 软件,也没有 3D 打印机,好在学过一点点 Blender,所以我的想法是用 Blender 建好模型后,再用 Pepakura Designer 将模型展开,展开后将图纸打印出来,然后再裁切组装。
为了验证自己的想法先画了个简单模型,展开后等比例缩小到一张 A4 大小,然后打印出来折成改有的形状。看着效果还不错。
测试方案可行后开始制作更精细的模型,因为手机要放在前方显示表情,所以模型的尺寸是根据手机的尺寸而设置的。
模型制作好后用将起展开,调整好位置后再打印出来,因为 A4 纸的硬度不够,所以需要将 A4 纸贴到雪弗板上,按图纸形状将雪弗板裁下来,最终的机体结构就是由裁下来的大大小小部件拼接而成的。
运动控制
机器人使用了一个从遥控车上拆卸下来的底盘,这个底盘自带三个电机,两个控制前进后退,一个控制转弯,原本的控制电路比较简单,没有多余的 IO 口用来连接增加的舵机,而且非常容易受到干扰,所以为了更好的扩展,我使用了 NodeMCU 来接收和处理指令。
NodeMCU 的 Wi-Fi 功能可以用来连接手机的共享网络与服务器通讯,服务器使用 Socket.IO 部署,Socket.IO 是构建于 WebSocket 之上,支持客户端与服务器低延迟、双向和基于事件通讯的框架,后续此服务器还会作为 WebRTC 信令服务器。NodeMCU 支持 Arduino 编程语言,可以像 Arduino 一样编写硬件代码,可以使用 Arduino 的扩展库,通过扩展库可以快速地开发出基于 Socket.IO 客户端程序。
底盘使用的是普通的 130 电机,电机的突然启停会感应出很大的电动势,这很容易烧毁电路中的元器件,所以需要接入驱动电路,为了快速开发,我使用了是现成的 L298N 电机驱动板,它能控制两路电机的正反转,还支持 PWM 调速,可以很方便地通过 NodeMCU 来控制机器人的形式速度。
舱盖使用 SG90 舵机控制,通过 Arduino 官方的 Servo 库就可以很容易地控制舵机的旋转,进而实现仓库的开启和关闭。
远程操控
原本的计划是在家里操控机器人,后来担心机器人一进电梯就会被熊孩子肢解,所以上位机软件还是要做到了平板上,带着平板在远处操控,通过肉眼来弥补手机前摄有限视界带来的不安全感。对于我自己来说做界面最拿手的还是 Web 技术,我在 Dribbble 上找了几个 Neumorphism 风格的 UI,照猫画虎地就把控制界面做好了。
机器人的表情是用 Canvas 画的,画了 微笑、爱心、酷三种表情,通过增加一些简单的动画来让这几个表情变得更生动,微笑的眯眯眼和酷的墨镜会上下跳动,爱心则会放大缩小。画表情的过程比较枯燥,需要一步步绘制路径和填充,当然也可能是我没有找到合适的工具。
使用 Web 技术的另一个主要原因是视频通讯需要用到 WebRTC 技术,WebRTC 是一个支持网页浏览器进行实时语音对话或视频对话的 API,所以可以将获取视频流的代码藏在机器人表情的网页里,这样既可以正常通过手机前摄获取到视频流,还可以通过网页来显示表情,一举两得。
其它
尝试了使用 ml5.js 机器学习库开发语音控制的功能,现成的 SpeechCommands18w 模型就可以识别 0-9 英文数字以及“up”,“down”,“left”,“right”,“go”,“stop”,“yes”,“no” 这几个单词,我在这个项目中使用“go”和“stop”来控制前进和停止,用“left”和“right”来控制左转和右转,在安静的环境识别准确度还是比较高,最重要的是用 ml5.js 开发原型非常快。
小结
因为增加的东西越来越多,底盘的承受的重量也越来越大,130 电机的转速很高,但是力量非常小,原本的传动结构又非常简单,所以现在机器人转向变得非常吃力,转弯角度变得很小,我计划用 MG946R 舵机替换,但是对原来的机械结构需要做一些改造。原来设计的外壳是没有设计成可拆卸式的,所以每次组装测试都像组装火箭一样麻烦,需要从内部一个个部件从底往上安装,如果可以从外部安装会方便很多。还有散热问题之前也没有考虑到,使用 WebRTC 通讯时手机发热严重,所以还需要制作散热装置对手机进行散热。这些问题都会在下次迭代的时候解决。