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的另外几种语言实现
Jan 29 Python
python通过yield实现数组全排列的方法
Mar 18 Python
python 筛选数据集中列中value长度大于20的数据集方法
Jun 14 Python
关于python2 csv写入空白行的问题
Jun 22 Python
对pandas中Series的map函数详解
Jul 25 Python
Python常见的pandas用法demo示例
Mar 16 Python
Python Numpy计算各类距离的方法
Jul 05 Python
关于numpy.where()函数 返回值的解释
Dec 06 Python
Python远程开发环境部署与调试过程图解
Dec 09 Python
Python如何生成xml文件
Jun 04 Python
Python实现石头剪刀布游戏
Jan 20 Python
Pytorch 使用tensor特定条件判断索引
Apr 08 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初学者常见问题集合 修正版(21问答)
2010/03/23 PHP
PHP发明人谈MVC和网站设计架构 貌似他不支持php用mvc
2011/06/04 PHP
深入PHP中的HashTable结构详解
2013/06/13 PHP
thinkPHP中钩子的两种配置调用方法详解
2016/11/11 PHP
详解PHP使用Redis存储session时的一个Warning定位
2017/07/05 PHP
jQuery 使用手册(六)
2009/09/23 Javascript
js 分页全选或反选标识实现代码
2011/08/09 Javascript
远离JS灾难css灾难之 js私有函数和css选择器作为容器
2011/12/11 Javascript
使用javascript获取页面名称
2014/12/23 Javascript
jquery实现平滑的二级下拉菜单效果
2015/08/26 Javascript
简介AngularJS中$http服务的用法
2016/02/06 Javascript
jquery获取复选框的值的简单实例
2016/05/26 Javascript
js判断文件格式及大小的简单实例(必看)
2016/10/11 Javascript
js关于getImageData跨域问题的解决方法
2016/10/14 Javascript
自适应布局meta标签中viewport、content、width、initial-scale、minimum-scale、maximum-scale总结
2017/08/18 Javascript
使用Vue.js和Element-UI做一个简单登录页面的实例
2018/02/23 Javascript
vue awesome swiper异步加载数据出现的bug问题
2018/07/03 Javascript
微信小程序用户授权,以及判断登录是否过期的方法
2019/05/10 Javascript
详解mpvue中使用vant时需要注意的onChange事件的坑
2019/05/16 Javascript
js 计数排序的实现示例(升级版)
2020/01/12 Javascript
vue制作toast组件npm包示例代码
2020/10/29 Javascript
vue 数据遍历筛选 过滤 排序的应用操作
2020/11/17 Javascript
[47:46]完美世界DOTA2联赛 Magma vs GXR 第三场 11.07
2020/11/10 DOTA
windows10系统中安装python3.x+scrapy教程
2016/11/08 Python
python图像处理模块Pillow的学习详解
2019/10/09 Python
浅谈pytorch中torch.max和F.softmax函数的维度解释
2020/06/28 Python
python接口自动化框架实战
2020/12/23 Python
AmazeUI的下载配置与Helloworld的实现
2020/08/19 HTML / CSS
shell的种类有哪些
2015/04/15 面试题
求职信内容怎么写
2014/05/26 职场文书
2014年物资管理工作总结
2014/12/02 职场文书
地震捐款简报
2015/07/21 职场文书
幼儿园毕业典礼园长致辞
2015/07/29 职场文书
建国70周年的心得体会(2篇)
2019/09/20 职场文书
《天净沙·秋思》教学反思三篇
2019/11/02 职场文书
canvas绘制折线路径动画实现
2021/05/12 Javascript