树莓派遇上 Java 06:总结篇
立泉本文时间久远,部分内容可能过时,仅供参考。
之前写过 5 篇文章介绍树莓派的基本特性和对马达、舵机、摄像头的控制方法。
树莓派遇上 Java 01:总述篇
树莓派遇上 Java 02:准备篇
树莓派遇上 Java 03:马达篇
树莓派遇上 Java 04:舵机篇
树莓派遇上 Java 05:摄像头篇
这些内容只是让树莓派具有基本的硬件控制能力,遥控机器人是在基本能力之上配合网络连接和数据传输实现的。
早期没有摄像头云台
后期加装摄像头云台
最终的机器人和 Android 端控制软件
作为参考,简单介绍下实现思路。
建立连接
树莓派和 Android 手机通过 WiFi 建立网络连接。
首先,树莓派开机时自动建立 WiFi 热点,设置自身固定 IP 为 192.168.0.1,服务端软件监听任一可用端口。Android 手机连接这个 WiFi 热点,控制端软件访问树莓派 IP 的指定端口即可建立 Java 原生的Socket
连接通过Stream
流传输数据。
通信协议
定义双方遵循的通信协议,这个似乎不必提,毕竟客户端和服务端互相理解对方发送的指令是“遥控”的基础。
实时判断连接状态
原生Socket
有一个缺陷,当连接意外断开时客户端和服务端不会收到通知,会带来一些安全性问题。
比如在命令机器人前进的过程中脱离最大控制距离,其和控制端的连接已经断开,但它既无法收到控制端的停止指令也无法意识到连接断开,只会执行接到的最后一条命令“前进”。要避免这种情况需实时判断连接状态,可通过定时发送心跳包的方式,每 5 秒发送一次,一段时间内没有收到心跳即判断连接断开,执行一些“停止”“重连”之类的指令。
功能抽象封装
即从底层的传输字节开始把功能层层封装,对外提供清晰可靠的接口,简化上层程序设计。
比如要实现机器人的“左转”方法turnLeft()
,从底层开始首先封装左履带的前进和后退方法leftForward()
、leftBack()
以及右履带的前进和后退方法rightForward()
、rightBack()
。这样turnLeft()
实际上只需调用leftBack()
和rightForward()
,不必关心下层的履带转动是如何做的。这被称为“黑箱”思想,上层看到的只是功能接口而非具体实现细节。
图片传输
机器人拍摄照片后会立即传输到 Android 手机上,为使传输的同时不影响正常收发指令,可单独开一个线程建立新Socket
连接传输图片,完成后关闭连接。
视频流传输
机器人拍摄的视频使用 MJPG-Streamer 发送,Android 控制端用WebView
访问指定端口接收视频流。
此外可通过控制摄像头云台转动调节视频拍摄角度,具体实现是WebView
监听触控事件,手指滑动时控制云台指向对应角度,这种指哪看哪的体验是很不错的。
体感控制
即调用 Android 的加速度传感器判断手机姿态,进而控制机器人动作。
比如手机前倾控制机器人前进,手机左倾控制机器人左转,脱离显性控制器有一种人车合一的微妙感觉,挺好玩。