找回密码
 立即注册
查看: 3847|回复: 5

[参考教程] 树莓派WIFI小车java版(四)android 控制程序

[复制链接]
发表于 2015-7-2 14:22:36 | 显示全部楼层 |阅读模式
前情提要 Previous on 《树莓派WIFI小车java版》

在上一篇,《树莓派WIFI小车java版(三)小车java控制程序》中,我们为小车编写的java版的控制程序,今天是最后一部分,写一个android的程序,来遥控小车。

这是一个标准的android工程,按照标准流程编码即可。
采用FrameLayout布局,下面一层用来显示树莓派摄像头模块拍摄的视频,上面叠加一层控制界面,控制WIFI小车的前进、后退,左转、右转,开灯、关灯等等动作。
layout.jpg
关于android的布局不是今天的重点,有兴趣请自行查看源文件。
遥控客户端有2点需要注意的:
[size=10.5000pt]1. 充分考虑操控性
我们做的是一个遥控app,用于控制WIFI小车,除了要求界面操作要尽量简洁,干脆外,操控性和操控习惯性也非常重要。比如,小车正在直行时需要左转弯,转过一定角度后应该恢复直行的状态,我个人的操控习惯是,按向上的箭头小车前进,松开后不影响小车的运动;按下转弯箭头时,小车开始转弯,当松开按钮后,小车应该恢复直行状态。因此,android app的按钮被分为两组:
左转、右转,以及摄像头的上下左右按钮响应的事件为OnTouch, Action为DOWN和UP都发送指令(上一节的java代码中,转弯和调整摄像头的指令都是开关切换式的,即单数次发送为开始动作,偶数次发送为停止动作)其他按钮响应OnClick
[size=10.5000pt]2. Mjpg-streamer视频解码
命令
mjpg_streamer -i "input_raspicam.so  -fps 15" -o "output_http.so -w /usr/www -p 8002"
将树莓派摄像头模块拍摄到的视频发送的本地的8002端口上,通过HTTP协议即可访问。
(以下一小节为mjpg-streamer源代码中关于HTTP输出视频部分的分析,和java无关,不感兴趣的同学可以放心跳过。这里插播一句,mjpg-streamer是个很优秀的开源视频流服务器,关于他的源码分析网上也很多,这里就不展开了,毕竟我们说的是java)
还记得我们下载的mjpg-streamer的源码吗?看看他是如何通过HTTP发送数据的,我们逆向操作即可解码视频了。看看以上mjpg-streamer的命令,输出部分是output_http.so,那么我们就在源码中找http部分的。OK,找到mjpg-streamer/plugins/output_http/httpd.c,找到函数

  1. void send_stream(int fd, int input_number)
复制代码
mjpg-1.png
嗯嗯,就是这货了,先是输出一个完整的HTTP/1.0的头,内容为multipart/x-mixed-replace;boundary=BOUNDARY
这个BOUNDARY宏在 httpd.h 头文件中,先记住,一会解析时要用,继续往下看:
mjpg-2.png

真正的数据包在这里发送的,只要没结束,就循环发送每一帧的数据,包括包头
现在我们知道数据包的格式了:
  1. HTTP/1.0 200 OK
  2. Access-Control-Allow-Origin: *
  3. ${STD_HEADER}
  4. Content-Type: multipart/x-mixed-replace;boundary=${BOUNDARY}

  5. --${BOUNDARY}
  6. Content-Type: image/jpeg
  7. Content-Length: %d
  8. X-Timestamp: %d.%06d

  9. ${frame-buff}
  10. --${BOUNDARY}
  11. Content-Type: image/jpeg
  12. Content-Length: %d
  13. X-Timestamp: %d.%06d

  14. ${frame-buff}
  15. ......
复制代码
剩下的事就简单了,用java发起一个http请求,解析数据,显示出来就行了。
首先,从android.view.SurfaceView继承一个类出来作为视频的显示控件
android-1.png

每次从一个阻塞式队列中去一帧来显示
android-2.png

若视频未结束,计算fps,且在控件上显示该帧。
另外一个线程则负责从mjpg-streamer服务端获取视频数据并解码
android-3.png

该系列帖子中的所有代码可在https://github.com/seth-yang/remote-car上获取。若在测试过程中发现什么bug,可以直接反馈给我(seth_yang@126.com或在github上发issue),谢谢!
完工后效果
Screenshot_2015-06-30-23-44-43.png
手机连接到树莓派的SSID上
full-view.jpg
手机全景
Screenshot_2015-07-01-00-02-00.png

遥控界面截屏
Screenshot_2015-07-01-00-02-10.png
打开摄像头后的截屏
full-view-1.jpg
full-view-2.jpg
下地后的全景,和我同样心爱的二胡say hi吧。


视频上传到土豆上了,不会贴视频,给个链接自己点吧,抱歉
http://www.tudou.com/programs/view/zOqfks8xfPU/


五、后续
  • 准备给小车加个超声波测距模块,防止小车撞墙。话说,撞墙的危害很大,这个时候,电机处在阻转状态,电流瞬间变很大,都加载在L298N上,有可能烧毁L298N模块,而我们的树莓派和L298N是共地的,这个时候也就很危险了。在第二部分中提到的自制保护板中的1K电阻至关重要,若能串个保险丝应该会安全。
  • 准备给小车安装一个机械臂(自从有了16路的PCA9685,舵机不嫌多了),主要灵感来自某天趴到地上在床底下找东西,这活让小车干应该可行,加装个车前灯是分分钟的事。
  • 准备给小车安装一个无线充电模块(现在科技很科幻啊,淘宝上竟然有距离达到1000mm无线供电的模块出售。。。),当树莓派读到电池电量低于5%时,自己跑到无线充电区域给自己充电
  • 你还有其他天马行空的idea吗?可以和我share,没准能实现呢,谁知道呢。






回复

使用道具 举报

发表于 2015-7-2 17:31:16 | 显示全部楼层
精彩的好帖!
回复 支持 反对

使用道具 举报

发表于 2015-7-24 13:31:32 | 显示全部楼层
无线充电模块想法 超不错好吧
加油  期待
回复 支持 反对

使用道具 举报

发表于 2015-11-15 21:07:16 | 显示全部楼层
真高级,各种羡慕
回复 支持 反对

使用道具 举报

发表于 2017-3-28 20:03:14 | 显示全部楼层
高手,高手,高高手~
回复 支持 反对

使用道具 举报

发表于 2018-9-13 10:26:58 | 显示全部楼层
感谢,感谢,感谢~~
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则