python3实现网页版raspberry pi(树莓派)小车控制


Posted in Python onFebruary 12, 2020

关于树莓派四驱小车的运动方向控制、摄像头方向控制已经在前面的两篇博文中介绍过。有需要的可以参考。本文也是基于上述两个python文件就绪的情况进行的。

本文主要讲述我是如何实现通过网页实现小车控制的。当前的实现方式比较简陋,只能支持控制网页和树莓派在同一个局域网中的场景。如果以后还有精力,可能会进行一些改进。

1. 基本思路

python3实现网页版raspberry pi(树莓派)小车控制

2. 服务端控制程序server.py

# --coding:utf-8--
from http.server import BaseHTTPRequestHandler, HTTPServer
import time
import socket
import urllib
from car_controler import FourWheelDriveCar
from camera_controler import Camera
 
 
class CarServer(BaseHTTPRequestHandler):
  
  carControler = FourWheelDriveCar()
  cameraControler = Camera()
 
  def get_host_ip(self):
    '''
    This method is used for getting local ip address
    The car server will deploy on this ip
    '''
    try:
      serverSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
      serverSocket.connect(("8.8.8.8", 80))
      localIP = serverSocket.getsockname()[0]
    finally:
      return localIP
 
  def do_GET(self):
    '''
    Define the car control GUI for client
    For the first edition, it will only return direction contol GUI
    '''
    localIP = CarServer.get_host_ip(self)
 
    # When this GET method is called, then should init the car
    self.carControler.reset()
 
    # Read control page html file from control.html
    controlPageFile = open("control.html")
    controlPageGUI = controlPageFile.read()
    controlPageFile.close()
    controlPageGUI = controlPageGUI.replace(
      "requestAddress", "http://" + localIP + ":9090/")
    controlPageGUI = controlPageGUI.replace(
      "cameraAddress", "http://" + localIP + ":8080/")
 
    self.send_response(200)
    self.send_header("Content-type", "text/html")
    self.end_headers()
    self.wfile.write(controlPageGUI.encode())
 
  def do_POST(self):
    length = int(self.headers['Content-Length'])
    qs = self.rfile.read(length)
    direction = qs.decode()
    print(direction)
 
    cameraDirection = ['HR', 'HL', 'VU', 'VD', 'RESET']
    if direction in cameraDirection:
      # This is used to control the camera
      self.cameraControler.cameraRotate(direction)
    else:
      # This is used to control the car
      self.carControler.carMove(direction)
 
    self.send_response(200)
 
 
if __name__ == "__main__":
  raspCarServer = CarServer
  hostIP = raspCarServer.get_host_ip(raspCarServer)
  hostPort = 9090
  myServer = HTTPServer((hostIP, hostPort), raspCarServer)
 
  print(time.asctime(), "Server Starts - %s:%s" % (hostIP, hostPort))
 
  try:
    myServer.serve_forever()
  except KeyboardInterrupt:
    pass

3. 服务端返回的页面control.html 

几点说明:

  • html文件中有两个地址,我是在server.py中做了替换的,所以client请求之后会有实际的地址给到浏览器,最终都是使用的树莓派的ip
  • 有个显示监控视频的区域,可以直接用我给出的示例使用即可,前提是你也用的MJPG-Streamer来获取摄像头监控
  • 小车控制我只给来前后左右运动,没有给后退的转向控制,有需要可以自己添加
  • 比较重要的是点击按钮之后发送请求到服务端,参考文件<script>中的代码
<html>
<script>
  function directionBtnDown(direction) {
    var url = "requestAddress"
    var request = new XMLHttpRequest();
    request.open("POST", url);
 
    request.send(direction)
  }
 
  function directionBtnUp() {
    var url = "requestAddress"
    var request = new XMLHttpRequest();
    request.open("POST", url);
    request.send("S")
  }
</script>
<style type="text/css">
  span.car {
    position: absolute;
    margin-top: 30%;
    height: 480px;  
  }
 
  span.camera {
    position: absolute;
    margin-top: 5%;
    margin-left: 290px;
    height: 480px;
    width: 640px;
    background-color: blue
  }
 
  span.camera_control {
    position: absolute;
    margin-top: 30%;
    margin-left: 950px;
    height: 480px;
    background-color: blue
  }
 
 
  button.top {
    position: absolute;
    height: 50px;
    width: 90px;
    margin-left: 90px
  }
 
  button.left {
    position: absolute;
    height: 50px;
    width: 90px;
    margin-top: 50px;
  }
 
  button.right {
    position: absolute;
    height: 50px;
    width: 90px;
    margin-top: 50px;
    margin-left: 180px
  }
 
  button.bottom {
    position: absolute;
    height: 50px;
    width: 90px;
    margin-top: 100px;
    margin-left: 90px
  }
</style>
 
<head>
  <title>control page</title>
</head>
 
<body>
  <span id="car_control" class="car">
    <button class="top drectionBtn" id="F" οnmοusedοwn="directionBtnDown('F')" οnmοuseup="directionBtnUp()">F</button>
    <button class="left drectionBtn" id="L" οnmοusedοwn="directionBtnDown('L')" οnmοuseup="directionBtnUp()">L</button>
    <button class="right drectionBtn" id="R" οnmοusedοwn="directionBtnDown('R')" οnmοuseup="directionBtnUp()">R</button>
    <button class="bottom drectionBtn" id="B" οnmοusedοwn="directionBtnDown('B')" οnmοuseup="directionBtnUp()">B</button>
  </span>
  <span id="camera_view" class="camera">
    <img id="view" src="cameraAddress?action=stream" />
  </span>
  <span id="camera_control" class="camera_control">
    <button class="top drectionBtn" id="VU" οnmοusedοwn="directionBtnDown('VU')">Up</button>
    <button class="left drectionBtn" id="HL" οnmοusedοwn="directionBtnDown('HL')">Left</button>
    <button class="right drectionBtn" id="HR" οnmοusedοwn="directionBtnDown('HR')">Right</button>
    <button class="bottom drectionBtn" id="VD" οnmοusedοwn="directionBtnDown('VD')">Down</button>
  </span>
 
</body>
 
</html>

4. 使用方式简介

  • 在树莓派上运行MJPG-Streamer
  • 在树莓派上运行服务端控制程序server.py
  • 在相同局域网的pc上打开浏览器,访问server地址,如 http://192.168.1.101:9090。其中,ip地址是树莓派的ip,端口9090是server中设定的端口,可以自己修改

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
使用Python的Treq on Twisted来进行HTTP压力测试
Apr 16 Python
Python基于OpenCV实现视频的人脸检测
Jan 23 Python
django使用xlwt导出excel文件实例代码
Feb 06 Python
windows下安装python的C扩展编译环境(解决Unable to find vcvarsall.bat)
Feb 21 Python
Python入门必须知道的11个知识点
Mar 21 Python
使用python 3实现发送邮件功能
Jun 15 Python
Python中实例化class的执行顺序示例详解
Oct 14 Python
Python3实现的判断回文链表算法示例
Mar 08 Python
在django中使用apscheduler 执行计划任务的实现方法
Feb 11 Python
python 解决tqdm模块不能单行显示的问题
Feb 19 Python
解决pymysql cursor.fetchall() 获取不到数据的问题
May 15 Python
详解Python为什么不用设计模式
Jun 24 Python
解决Pycharm 导入其他文件夹源码的2种方法
Feb 12 #Python
Tensorflow 模型转换 .pb convert to .lite实例
Feb 12 #Python
tensorflow的ckpt及pb模型持久化方式及转化详解
Feb 12 #Python
关于Tensorflow 模型持久化详解
Feb 12 #Python
Python qrcode 生成一个二维码的实例详解
Feb 12 #Python
python标准库sys和OS的函数使用方法与实例详解
Feb 12 #Python
python标准库os库的函数介绍
Feb 12 #Python
You might like
PHP网上调查系统
2006/10/09 PHP
php db类库进行数据库操作
2009/03/19 PHP
PHP加密解密字符串汇总
2015/04/26 PHP
php中让人头疼的浮点数运算分析
2016/10/10 PHP
php实现数组纵向转横向并过滤重复值的方法分析
2017/05/29 PHP
js 如何实现对数据库的增删改查
2012/11/23 Javascript
javascrpt绑定事件之匿名函数无法解除绑定问题
2012/12/06 Javascript
Ext JS 4实现带week(星期)的日期选择控件(实战一)
2013/08/21 Javascript
使用JS CSS去除IE链接虚线框的三种方法
2013/11/14 Javascript
javascript 中__proto__和prototype详解
2014/11/25 Javascript
使用jQuery实现更改默认alert框体
2015/04/13 Javascript
JavaScript检测并限制复选框选中个数的方法
2015/08/12 Javascript
jQuery链式调用与show知识浅析
2016/05/11 Javascript
关于Javascript中defer和async的区别总结
2016/09/20 Javascript
nodejs redis 发布订阅机制封装实现方法及实例代码
2016/12/15 NodeJs
详解nodejs微信jssdk后端接口
2017/05/25 NodeJs
[原创]jQuery实现合并/追加数组并去除重复项的方法
2018/04/11 jQuery
详解.vue文件解析的实现
2018/06/11 Javascript
Vue-router 中hash模式和history模式的区别
2018/07/24 Javascript
element-ui中select组件绑定值改变,触发change事件方法
2018/08/24 Javascript
微信头像地址失效踩坑记附带解决方案
2019/09/23 Javascript
微信小程序本地存储实现每日签到、连续签到功能
2019/10/09 Javascript
Vue父子之间值传递的实例教程
2020/07/02 Javascript
Python基于高斯消元法计算线性方程组示例
2018/01/17 Python
对numpy中的数组条件筛选功能详解
2018/07/02 Python
Python中remove漏删和索引越界问题的解决
2020/03/18 Python
Python tkinter之Bind(绑定事件)的使用示例
2021/02/05 Python
Python中对象的比较操作==和is区别详析
2021/02/12 Python
麦当劳辞职信范文
2014/01/18 职场文书
运动会开幕式主持词
2014/03/28 职场文书
国旗下演讲稿
2014/05/08 职场文书
2015年教师节演讲稿范文
2015/03/19 职场文书
毕业设计工作总结
2015/08/14 职场文书
新娘婚礼答谢词
2015/09/29 职场文书
先进个人主要事迹怎么写
2015/11/04 职场文书
Java十分钟精通进阶适配器模式
2022/04/06 Java/Android