树莓派遇上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
连接,然后通过流
传输数据。
通信协议
定义双方遵循的通信协议,这个似乎没有必要提,毕竟,如果客户端和服务端都无法理解对方发送的指令,那就没有必要再做下去了。
实时判断连接状态
Socket
连接有一个缺陷,就是当连接意外断开的时候客户端和服务端都不会收到任何通知,这样会带来一些安全性问题。
比如在命令机器人前进的过程中脱离了最大控制距离,其和控制端的连接已经断开,但是它既无法收到控制端的停止指令,也无法意识到连接断开,只会执行接到的最后一条命令“前进”。要避免这种情况就需要实时判断连接状态,可以用定时发送心跳包的方式,每5秒发送一次,当一段时间内没有收到心跳就判断连接已经断开,执行一些“停止”“重连”之类的指令。
功能抽象封装
即从最底层的传输字节开始把功能层层封装,对外提供清晰可靠的接口,简化上层程序设计。
比如要实现机器人的“左转”方法turnLeft()
,从底层开始,首先封装左履带的前进和后退方法leftForward()
、leftBack()
,右履带的前进和后退方法rightForward()
、rightBack()
。这样turnLeft()
方法实际上只需要调用leftBack()
和rightForward()
即可,而不必关心更底层的履带转动是如何做的。这被称为“黑箱”思想,上层看到的永远只是功能接口,而非具体实现细节。
图片传输
机器人的摄像头拍摄照片后会立即传输到Android
手机上,为使传输的同时也能正常收发指令,应单独开一个线程
建立新Socket
连接传输图片,完成后关闭连接。
视频传输
视频使用MJPG-Streamer
发送,Android
控制端只需要用WebView
访问指定端口即可接收到视频流。
此外,可以通过控制摄像头云台转动来控制视频拍摄角度。具体实现是WebView
监听触控事件,手指滑动时控制云台指向对应角度,这种指哪看哪的体验是很不错的。
体感控制
这个其实是调用Android
的加速度传感器
判断手机姿态,进而控制机器人动作。
比如手机前倾控制机器人前进,手机左倾控制机器人左转,有一种脱离显性控制器的微妙感觉,挺好玩。