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编程之字符串模板(Template)用法实例分析
Jul 22 Python
Python操作Sql Server 2008数据库的方法详解
May 17 Python
Python PyQt5 Pycharm 环境搭建及配置详解(图文教程)
Jul 16 Python
django Admin文档生成器使用详解
Jul 22 Python
python二进制读写及特殊码同步实现详解
Oct 11 Python
Python函数式编程实例详解
Jan 17 Python
Python中的 ansible 动态Inventory 脚本
Jan 19 Python
详解python itertools功能
Feb 07 Python
动态设置django的model field的默认值操作步骤
Mar 30 Python
Python使用jupyter notebook查看ipynb文件过程解析
Jun 02 Python
Python内置函数property()如何使用
Sep 01 Python
Python Matplotlib绘制两个Y轴图像
Apr 13 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 中提示undefined index如何解决(多种方法)
2016/03/16 PHP
Symfony的安装和配置方法
2016/03/17 PHP
详解Yii2 之 生成 URL 的方法
2017/06/16 PHP
PHP从尾到头打印链表实例讲解
2018/09/27 PHP
为你的网站增加亮点的9款jQuery插件推荐
2011/05/03 Javascript
jquery通过visible来判断标签是否显示或隐藏
2014/05/08 Javascript
Node.js 异步编程之 Callback介绍(一)
2015/03/30 Javascript
JavaScript入门基础
2015/08/12 Javascript
JS实现自动切换文字的导航效果代码
2015/08/27 Javascript
javascript发送短信验证码实现代码
2015/11/12 Javascript
JS之相等操作符详解
2016/09/13 Javascript
JS正则匹配中文的方法示例
2017/01/06 Javascript
bootstrap timepicker在angular中取值并转化为时间戳
2017/06/13 Javascript
JSON在Javascript中的使用(eval和JSON.parse的区别)详细解析
2017/09/05 Javascript
Vue.js 十五分钟入门图文教程
2018/09/12 Javascript
微信小程序日历效果
2018/12/29 Javascript
VuePress 快速踩坑小结
2019/02/14 Javascript
Vue组件之高德地图地址选择功能的实例代码
2019/06/21 Javascript
layer.open提交子页面的form和layedit文本编辑内容的方法
2019/09/27 Javascript
ES2020系列之空值合并运算符 '??'
2020/07/22 Javascript
python局部赋值的规则
2013/03/07 Python
python爬虫的工作原理
2017/03/05 Python
python调用xlsxwriter创建xlsx的方法
2018/05/03 Python
Python编程深度学习计算库之numpy
2018/12/28 Python
python 在指定范围内随机生成不重复的n个数实例
2019/01/28 Python
Python爬取腾讯视频评论的思路详解
2019/12/19 Python
如何使用pycharm连接Databricks的步骤详解
2020/09/23 Python
实习护理工作自我评价
2013/09/25 职场文书
市场专员岗位职责
2014/02/14 职场文书
党的群众路线教育实践活动总结材料
2014/10/30 职场文书
教师个人发展总结
2015/02/11 职场文书
法定代表人身份证明书
2015/06/18 职场文书
导游词之贵州织金洞
2019/10/12 职场文书
Python实现学生管理系统(面向对象版)
2021/06/24 Python
Python Pygame实战之塔防游戏的实现
2022/03/17 Python
Python实现为PDF去除水印的示例代码
2022/04/03 Python