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中cPickle用法例子分享
Jan 03 Python
python fabric使用笔记
May 09 Python
CentOS7.3编译安装Python3.6.2的方法
Jan 22 Python
解决每次打开pycharm直接进入项目的问题
Oct 28 Python
Python获取网段内ping通IP的方法
Jan 31 Python
Python3 实现文件批量重命名示例代码
Jun 03 Python
Python 多个图同时在不同窗口显示的实现方法
Jul 07 Python
Pycharm连接远程服务器并实现远程调试的实现
Aug 02 Python
使用Python实现 学生学籍管理系统
Nov 26 Python
python怎么对数字进行过滤
Jul 05 Python
python 解决函数返回return的问题
Dec 05 Python
python三子棋游戏
May 04 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中批量生成静态html(命令行下运行PHP)
2014/04/19 PHP
CodeIgniter控制器之业务逻辑实例分析
2016/01/20 PHP
Laravel中七个非常有用但很少人知道的Carbon方法
2017/09/21 PHP
javascript实现二分查找法实现代码
2007/11/12 Javascript
Jquery + Ajax调用webService实例代码(asp.net)
2010/08/27 Javascript
需要做特殊处理的DOM元素属性的访问
2010/11/05 Javascript
Extjs改变树节点的勾选状态点击按钮将复选框去掉
2013/11/14 Javascript
jQuery判断元素上是否绑定了指定事件的方法
2015/03/17 Javascript
JavaScript实现点击单选按钮改变输入框中文本域内容的方法
2015/08/12 Javascript
Bootstrap文件上传组件之bootstrap fileinput
2016/11/25 Javascript
原生JavaScript来实现对dom元素class的操作方法(推荐)
2017/08/16 Javascript
使用javaScript实现鼠标拖拽事件
2020/04/03 Javascript
详解javascript常用工具类的封装
2018/01/30 Javascript
Vue.js结合bootstrap前端实现分页和排序效果
2018/12/29 Javascript
15分钟深入了解JS继承分类、原理与用法
2019/01/19 Javascript
小程序如何自主实现拦截器的示例代码
2019/11/04 Javascript
nuxt 自定义 auth 中间件实现令牌的持久化操作
2020/11/05 Javascript
[05:45]Ti4观战指南(下)
2014/07/07 DOTA
Python中的字典遍历备忘
2015/01/17 Python
讲解Python中的标识运算符
2015/05/14 Python
Python检测网站链接是否已存在
2016/04/07 Python
python 性能优化方法小结
2017/03/31 Python
利用Python批量压缩png方法实例(支持过滤个别文件与文件夹)
2017/07/30 Python
对python 矩阵转置transpose的实例讲解
2018/04/17 Python
python实现二级登陆菜单及安装过程
2019/06/21 Python
Python如何实现在字符串里嵌入双引号或者单引号
2020/03/02 Python
tensorflow中tf.reduce_mean函数的使用
2020/04/19 Python
英国鞋类及配饰零售商:Kurt Geiger
2017/02/04 全球购物
实验教师岗位职责
2014/02/13 职场文书
销售人员求职的自我评价分享
2014/03/15 职场文书
法律进学校实施方案
2014/03/15 职场文书
2015新年联欢晚会开场白
2014/12/14 职场文书
鸦片战争观后感
2015/06/09 职场文书
基于Java的MathML转图片的方法(示例代码)
2021/06/23 Java/Android
Mysql案例刨析事务隔离级别
2021/09/25 MySQL
js 数组 fill() 填充方法
2021/11/02 Javascript