下面是小车 

python智能汽车代码 python小车_python智能汽车代码

好丑 对不对 ,不过反正可以蛇皮走位就行。

   蛇皮走位演示视频: https://pan.baidu.com/s/1RHHr8bRHWzSEAkrpwu99aw

 只需要 一个 index.html  和Index.py 就可以实现 简单WiFi 控制小车。

需要准备

  python 

 bottle 库

 bottle 安装

命令: pip install bottle

 

python智能汽车代码 python小车_python智能汽车代码_02

树莓派控制界面(web客户端)

  index.html 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>遥控树莓派</title>
    <link href="http://cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet" media="screen">
    <script src="http://cdn.staticfile.org/jquery/2.2.4/jquery.min.js"></script>
    <style type="text/css">
        #front {
            margin-left: 55px;
            margin-bottom: 3px;
        }
        #rear{
            margin-top: 3px;
            margin-left: 55px;
        }
        .btn{
             background: #62559f;
            }
    </style>
    <script>
        $(function(){
            $("button").click(function(){
                $.post("/cmd",this.id,function(data,status){});
            });
        });

    </script>
</head>
<body>
<div id="container" class="container">
    
    <div>
        <button id="front" class="btn btn-lg btn-primary glyphicon glyphicon-circle-arrow-up"></button>
    </div>
    <div>

        <button id='leftFront' class="btn btn-lg btn-primary glyphicon glyphicon-circle-arrow-left"></button>
        <button id='stop' class="btn btn-lg btn-primary glyphicon glyphicon-stop"></button>
        <button id='rightFront' class="btn btn-lg btn-primary glyphicon glyphicon-circle-arrow-right"></button>
    </div>
    <div>
        <button id='rear' class="btn btn-lg btn-primary glyphicon glyphicon-circle-arrow-down"></button>
    </div>
     <div>
        <button id='leftRear' class="btn btn-lg btn-primary glyphicon">左后转</button>
        <button id='rightRear' class="btn btn-lg btn-primary glyphicon">右后转</button>
    </div>
</div>

<script src="//cdn.bootcss.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
</body>
</html>

  js脚本解释:

<script>
        $(function(){
            $("button").click(function(){
                $.post("/cmd",this.id,function(data,status){});
     //表示 按钮对应的id值 会被传入树莓派服务器中,就如同 你在树莓派的命令行(cmd)中输入 id 的值
            });
        });

</script>

树莓派小车控制程序+we服务端

 Index.py

#!/usr/bin/env python3
# -*- coding:utf-8 -*-
from bottle import get,post,run,request,template

import RPi.GPIO as GPIO
import time
import sys 

 
####  定义Car类
class Car(object):
    def __init__(self):
        self.enab_pin = [5,6,13,19]
####  self.enab_pin是使能端的pin
        self.inx_pin = [21,22,23,24]
####  self.inx_pin是控制端in的pin
        self.RightAhead_pin = self.inx_pin[0]
        self.RightBack_pin = self.inx_pin[1]
        self.LeftAhead_pin = self.inx_pin[2]
        self.LeftBack_pin = self.inx_pin[3]
####  分别是右轮前进,右轮退后,左轮前进,左轮退后的pin
        self.setup()
 
####  setup函数初始化端口
    def setup(self):
        print ("begin setup ena enb pin")
        GPIO.setmode(GPIO.BCM)
        GPIO.setwarnings(False)
        for pin in self.enab_pin: 
            GPIO.setup(pin,GPIO.OUT)
            GPIO.output(pin,GPIO.HIGH)
####  初始化使能端pin,设置成高电平
        pin = None
        for pin in self.inx_pin:
            GPIO.setup(pin,GPIO.OUT)
            GPIO.output(pin,GPIO.LOW)
####  初始化控制端pin,设置成低电平
        print ("setup ena enb pin over")
 
####  fornt函数,小车前进
    def front(self):
        self.setup()
        GPIO.output(self.RightAhead_pin,GPIO.HIGH)
        GPIO.output(self.LeftAhead_pin,GPIO.HIGH)
 
####  leftFront函数,小车左拐弯
    def leftFront(self):
        self.setup()
        GPIO.output(self.RightAhead_pin,GPIO.HIGH)
 
####  rightFront函数,小车右拐弯
    def rightFront(self):
        self.setup()
        GPIO.output(self.LeftAhead_pin,GPIO.HIGH)
 
####  rear函数,小车后退
    def rear(self):
        self.setup()
        GPIO.output(self.RightBack_pin,GPIO.HIGH)
        GPIO.output(self.LeftBack_pin,GPIO.HIGH)
 
####  leftRear函数,小车左退
    def leftRear(self):
        self.setup()
        GPIO.output(self.RightBack_pin,GPIO.HIGH)
 
####  rightRear函数,小车右退
    def rightRear(self):
        self.setup()
        GPIO.output(self.LeftBack_pin,GPIO.HIGH)
 
####  定义main主函数
def main(status):
    
    car = Car()

    if status == "front":
        car.front()
    elif status == "leftFront":
        car.leftFront()
    elif status == "rightFront":
        car.rightFront()
    elif status == "rear":
        car.rear()
    elif status == "leftRear":
        car.leftRear()
    elif status == "rightRear":
        car.rightRear()
    elif status == "stop":
        car.setup()      
             



@get("/")
def index():
    return template("index")
@post("/cmd")
def cmd():
    adss=request.body.read().decode()
    print("按下了按钮:"+adss)
    main(adss)
    return "OK"
run(host="0.0.0.0")

web服务端 实际就这点代码, 主要是 bottle 库的强大,(实际控制的小车的代码 根据自己的需求改就行了)

from bottle import get,post,run,request,template


@get("/")
def index():
    return template("index") 
#### 这个是 客户端请求 服务端就发给一个 index.html 控制界面给客户端
@post("/cmd")
def cmd():
    adss=request.body.read().decode()#### 接收到 客户端 发过来的数据
    print("按下了按钮:"+adss)
    main(adss)  #### 传值到主函数 实现对应功能
    return "OK"
run(host="0.0.0.0")  #### 开启服务端

运行 index.py 开启服务器:

python智能汽车代码 python小车_python智能汽车代码_03

然后打开浏览器(手机浏览器也可以但必须在同一个局域网内) 输入 树莓派的ip 我的是 192.168.191.4:8080

有可能 打开比较慢  10分钟内吧 哈哈哈(我第一次打开 就用了好久 都以为没有成功)

python智能汽车代码 python小车_python智能汽车代码_04

手机端输入ip

python智能汽车代码 python小车_树莓派_05

登录成功!!!

python智能汽车代码 python小车_python智能汽车代码_06

输入之后  服务器会给你抛出一个 index.html 控制文件。

然后就可以点击按键 控制小车了  下面是 服务端中反馈

python智能汽车代码 python小车_树莓派_07

框架搭好后,根据自己需求更改 。

补充说明一下啊 因为我改过系统的语言和编码设置 (支持utf-8)

  详情 :  树莓派 设置系统中文 并安装中文输入法

当很多人遇到

UnicodeDecodeError: 'ascii' codec can't decode byte 0xe6 in position

1. 开头添加

                          import sys

                           reload(sys)

                           sys.setdefaultencoding('utf8') 

2.暴力一点,把所有中文字符 汉字什么的 包括注释了的 都统统删掉 也可以解决

 还有遇到 bottle 下载安装后 ,运行说 没有 安装 bottle  可能是 你把 bottle 安装到 python 2.7 环境下,而在python3 环境下找不到。

解决办法:

1 在命令行中 用对应pythonX  环境下运行

2.在执行脚本代码前 手动引包(得找到bottle 安装路径)


如果你想了解更多树莓派相关知识或则其他控制小车的手段

(如 自写网页,数据库,语音控制等)


先运行服务端代码 car.py,然后再 运行 car.html

  car.py 代码

#coding=utf8

import struct, socket, sys
import hashlib
import threading, random
import time
from base64 import b64encode, b64decode
import RPi.GPIO as GPIO
import sys 

GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(17,GPIO.OUT)
p=GPIO.PWM(17,600)
p_pin =35
p.start(p_pin)
####  定义Car类
class Car(object):
    def __init__(self):

        self.inx_pin = [19,26,5,6]
####  self.inx_pin是控制端in的pin
        self.RightAhead_pin = self.inx_pin[0]
        self.LeftAhead_pin = self.inx_pin[1]
        self.RightBack_pin = self.inx_pin[2]
        self.LeftBack_pin = self.inx_pin[3]
####  分别是右轮前进,左轮前进,右轮退后,左轮退后的pin
        self.RightP_pin=17
        self.LeftP_pin =27 
        self.setup()
       
 
####  setup函数初始化端口
    def setup(self):
        GPIO.setmode(GPIO.BCM)
        GPIO.setwarnings(False)
####  初始化使能端pin,设置成高电平
        pin = None
        for pin in self.inx_pin:
            GPIO.setup(pin,GPIO.OUT)
            GPIO.output(pin,GPIO.LOW)
####  初始化控制端pin,设置成低电平
        print ("setup ena enb pin over")
          
 
####  fornt函数,小车前进
    def front(self):
        self.setup()
        GPIO.output(self.RightAhead_pin,GPIO.HIGH)
        GPIO.output(self.LeftAhead_pin,GPIO.HIGH)
 
####  leftFront函数,小车左拐弯
    def leftFront(self):
        self.setup()
        GPIO.output(self.RightAhead_pin,GPIO.HIGH)
 
####  rightFront函数,小车右拐弯
    def rightFront(self):
        self.setup()
        GPIO.output(self.LeftAhead_pin,GPIO.HIGH)
 
####  rear函数,小车后退
    def rear(self):
        self.setup()
        GPIO.output(self.RightBack_pin,GPIO.HIGH)
        GPIO.output(self.LeftBack_pin,GPIO.HIGH)
 
####  leftRear函数,小车左退
    def leftRear(self):
        self.setup()
        GPIO.output(self.RightBack_pin,GPIO.HIGH)
 
####  rightRear函数,小车右退
    def rightRear(self):
        self.setup()
        GPIO.output(self.LeftBack_pin,GPIO.HIGH)

       
        
####  定义main主函数
def main(status):
    
    car = Car()

    if status == "front":
        car.front()
    elif status == "leftFront":
        car.leftFront()
    elif status == "rightFront":
        car.rightFront()
    elif status == "rear":
        car.rear()
    elif status == "leftRear":
        car.leftRear()
    elif status == "rightRear":
        car.rightRear()
    elif status == "stop":
        car.setup()      
        #p.stop()
    elif status == "q1":
        p.ChangeDutyCycle(35)
    elif status == "q2":
        p.ChangeDutyCycle(50)
    elif status == "q3":
        p.ChangeDutyCycle(75)
    elif status == "q4":
        p.ChangeDutyCycle(90)
    elif status == "q5":
        p.ChangeDutyCycle(100)



##socket
connectionlist = {}

def decode(data):
    if not len(data):
        return False

    # 用数据包的第二个字节,与127作与位运算,拿到前七位。
    length = data[1] & 127

    # 这七位在数据头部分成为payload,如果payload等于126,就要再扩展2个字节。
    # 如果等于127,就要再扩展8个字节。
    # 如果小于等于125,那它就占这一个字节。
    if length == 126:
        extend_payload_len = data[2:4]
        mask = data[4:8]
        decoded = data[8:]
    elif length == 127:
        extend_payload_len = data[2:10]
        mask = data[10:14]
        decoded = data[14:]
    else:
        extend_payload_len = None
        mask = data[2:6]
        decoded = data[6:]
    
    byte_list = bytearray()

    print(mask)
    print(decoded)

    # 当payload确定之后,再往后数4个字节,这4个字节成为masking key,再之后的内容就是接收到的数据部分。
    # 数据部分的每一字节都要和masking key作异或位运算,得出来的结果就是真实的数据内容。
    for i in range(len(decoded)):
        chunk = decoded[i] ^ mask[i % 4]
        byte_list.append(chunk)
    
    new_str = str(byte_list, encoding="utf-8")
    print(new_str)
    return new_str

def encode(data):  
    data=str.encode(data)
    head = b'\x81'

    if len(data) < 126:
        head += struct.pack('B', len(data))
    elif len(data) <= 0xFFFF:
        head += struct.pack('!BH', 126, len(data))
    else:
        head += struct.pack('!BQ', 127, len(data))
    return head+data
                
def sendMessage(message):
    global connectionlist
    for connection in connectionlist.values():
        connection.send(encode(message))
 
def deleteconnection(item):
    global connectionlist
    del connectionlist['connection'+item]

class WebSocket(threading.Thread):

    GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"

    def __init__(self,conn,index,name,remote, path="/"):
        threading.Thread.__init__(self)
        self.conn = conn
        self.index = index
        self.name = name
        self.remote = remote
        self.path = path
        self.buffer = ""     
    def run(self):
        print('Socket%s Start!' % self.index)
        headers = {}
        self.handshaken = False

        while True:
          try: 
            if self.handshaken == False:
                print ('Socket%s Start Handshaken with %s!' % (self.index,self.remote))
                self.buffer += bytes.decode(self.conn.recv(1024))

                if self.buffer.find('\r\n\r\n') != -1:
                    header, data = self.buffer.split('\r\n\r\n', 1)
                    for line in header.split("\r\n")[1:]:
                        key, value = line.split(": ", 1)
                        headers[key] = value

                    headers["Location"] = ("ws://%s%s" %(headers["Host"], self.path))
                    key = headers['Sec-WebSocket-Key']
                    token = b64encode(hashlib.sha1(str.encode(str(key + self.GUID))).digest())

                    handshake="HTTP/1.1 101 Switching Protocols\r\n"\
                        "Upgrade: websocket\r\n"\
                        "Connection: Upgrade\r\n"\
                        "Sec-WebSocket-Accept: "+bytes.decode(token)+"\r\n"\
                        "WebSocket-Origin: "+str(headers["Origin"])+"\r\n"\
                        "WebSocket-Location: "+str(headers["Location"])+"\r\n\r\n"
                    
                    self.conn.send(str.encode(str(handshake)))
                    self.handshaken = True  
                    print('Socket%s Handshaken with %s success!' %(self.index, self.remote))
                    sendMessage('Welcome, ' + self.name + ' !')

            else:
                msg = decode(self.conn.recv(1024))
                main(msg)
                if msg == 'quit':
                    print ('Socket%s Logout!' % (self.index))
                    nowTime = time.strftime('%H:%M:%S',time.localtime(time.time()))
                    sendMessage('%s %s say: %s' % (nowTime, self.remote, self.name+' Logout'))                  
                    deleteconnection(str(self.index))
                    self.conn.close()
                    break
                else:
                    #print('Socket%s Got msg:%s from %s!' % (self.index, msg, self.remote))
                    nowTime = time.strftime('%H:%M:%S',time.localtime(time.time()))
                    sendMessage('%s %s say: %s' % (nowTime, self.remote, msg))       
                
            self.buffer = ""
          except Exception as e:
            self.conn.close()

class WebSocketServer(object):
    def __init__(self):
        self.socket = None
    def begin(self):
        print( 'WebSocketServer Start!')
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.socket.bind(("172.19.8.102", 8081))
        self.socket.listen(50)

        global connectionlist

        i = 0
        while True:
            connection, address = self.socket.accept()

            username=address[0]     
            newSocket = WebSocket(connection,i,username,address)
            newSocket.start()
            connectionlist['connection'+str(i)]=connection
            i = i + 1

if __name__ == "__main__":
    server = WebSocketServer()
    server.begin()

 car.html  代码:

<!DOCTYPE html>
<html lang="zh-cn">
<head>
   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>遥控树莓派</title>
    <link href="http://cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet" media="screen">
    <script src="http://cdn.staticfile.org/jquery/2.2.4/jquery.min.js"></script>
    <style type="text/css">
        #front {
            margin-left: 55px;
            margin-bottom: 3px;
        }
        #rear{
            margin-top: 3px;
            margin-left: 55px;
        }
        .btn{
             background: #62559f;
            }
    </style>
    <script>
  var socket;
        function init() {
            var host = "ws://192.168.1.111:8081/";
            try {
                socket = new WebSocket(host);
                socket.onopen = function () {
                 
                };
                socket.onmessage = function () {
                    
                };
                socket.onclose = function () {
                    
                };
            }
            catch (ex) {
                
            }
           
        }
        function send(msg) {
            try {
                socket.send(msg);
            } catch (ex) {
                
            }
        }
        window.onbeforeunload = function () {
            try {
                socket.send('quit');
                socket.close();
                socket = null;
            }
            catch (ex) {
                
            }
        };
     
       
 
 
    </script>
</head>
<body onload="init()">
<div id="container" class="container">
    
    <div>
        <button id="front" class="btn btn-lg btn-primary glyphicon glyphicon-circle-arrow-up" onclick="send('front')"></button>
    </div>
    <div>
 
        <button id='leftFront' class="btn btn-lg btn-primary glyphicon glyphicon-circle-arrow-left" onclick="send('leftFront')"></button>
        <button id='stop' class="btn btn-lg btn-primary glyphicon glyphicon-stop" onclick="send('stop')"></button>
        <button id='rightFront' class="btn btn-lg btn-primary glyphicon glyphicon-circle-arrow-right" onclick="send('rightFront')"></button>
    </div>
    <div  style="height:50px;">
        <button id='rear' class="btn btn-lg btn-primary glyphicon glyphicon-circle-arrow-down" onclick="send('rear')"></button>
    </div>
    <div style="height:20px;"></div>
     <div style="height:50px;">
        <button id='leftRear' class="btn btn-lg btn-primary glyphicon" onclick="send('leftRear')">左后转</button>
        <button id='rightRear' class="btn btn-lg btn-primary glyphicon" onclick="send('rightRear')">右后转</button>
    </div>
     <div style="height:20px;"></div>
    <div  style="height:50px;">
        <button id='q1' class="btn btn-lg btn-primary glyphicon" onclick="send('q1')">P1</button>
        <button id='q2' class="btn btn-lg btn-primary glyphicon" onclick="send('q2')">P2</button>
        <button id='q3' class="btn btn-lg btn-primary glyphicon" onclick="send('q3')">P3</button>
        <div style="height:20px;"></div>
        <button id='q4' class="btn btn-lg btn-primary glyphicon" onclick="send('q4')">P4</button>
        <button id='q5' class="btn btn-lg btn-primary glyphicon" onclick="send('q5')">P5</button>
    </div>
</div>
 
<script src="//cdn.bootcss.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
</body>
</html>

注意: host 端口号要匹配哦