第十课 使用Python控制小车

上一节课程我们介绍了怎么连接,以及简单的演示了下怎么控制小车。这节我们将详细介绍python代码,和为什么这样去做。下面是将要用到的代码,首先是robot.py文件:

#!/usr/bin/python
#coding: utf8
import RPIO as GPIO
import time
import sys
import threading
import tornado.ioloop
import tornado.web
import tornado.httpserver
import tornado.options
import json

tornado.options.define("port",default=8000,type=int)

IN1 = 11
IN2 = 12
IN3 = 16
IN4 = 18


stop_status = 0
last_key = ""
last_request_time = 0


def init():
    GPIO.setmode(GPIO.BOARD)
    GPIO.setup(IN1,GPIO.OUT)
    GPIO.setup(IN2,GPIO.OUT)
    GPIO.setup(IN3,GPIO.OUT)
    GPIO.setup(IN4,GPIO.OUT)

# 前进
def forward():
    global stop_status
    GPIO.output(IN1,GPIO.HIGH)
    GPIO.output(IN2,GPIO.LOW)
    GPIO.output(IN3,GPIO.HIGH)
    GPIO.output(IN4,GPIO.LOW)
    # print "forward"
    # time.sleep(0.1)

# 后退
def reverse():
    global stop_status
    GPIO.output(IN1,GPIO.LOW)
    GPIO.output(IN2,GPIO.HIGH)
    GPIO.output(IN3,GPIO.LOW)
    GPIO.output(IN4,GPIO.HIGH)


# 左转弯
def left():
    global stop_status
    GPIO.output(IN1,GPIO.LOW)
    GPIO.output(IN2,GPIO.HIGH)
    GPIO.output(IN3,GPIO.HIGH)
    GPIO.output(IN4,GPIO.LOW)


# 右转弯
def right():
    global stop_status
    GPIO.output(IN1,GPIO.HIGH)
    GPIO.output(IN2,GPIO.LOW)
    GPIO.output(IN3,GPIO.LOW)
    GPIO.output(IN4,GPIO.HIGH)

#停止
def stop_car():
    GPIO.output(IN1,False)
    GPIO.output(IN2,False)
    GPIO.output(IN3,False)
    GPIO.output(IN4,False)
    global stop_status
    stop_status = 1

#关闭GPIO接口
def close_car():
    global stop_status
    stop_status = 1
    GPIO.cleanup()


class IndexHandler(tornado.web.RequestHandler):
    def set_default_headers(self):
        self.set_header('Access-Control-Allow-Origin', '*')
        self.set_header('Access-Control-Allow-Methods', 'POST, GET, OPTIONS')
        self.set_header('Access-Control-Allow-Headers', '*')
    def get(self):
        self.render("index.html")
    def post(self):
        global stop_status
        global last_key
        global last_request_time
        old_request_time = last_request_time
        init()
        sleep_time = 0.1
        try:
            arg = self.get_argument('k')
            new_request_time = self.get_argument('time')
            print 'get last time',new_request_time
        except Exception, e:
            arg = json.loads(self.request.body)['k']
            new_request_time = json.loads(self.request.body)['time']
            print 'json last time', new_request_time

        print "==new time ==", new_request_time
        print "==old time ==", old_request_time
        if(arg=='w' and last_key!='w' and new_request_time >= old_request_time):
            print "forward"
            stop_status = 0
            autoThread = threading.Thread(target = forward)
            autoThread.start()
            last_key = 'w'
        elif(arg=='s' and last_key!='s' and new_request_time >= old_request_time):
            print "reverse"
            stop_status = 0
            autoThread = threading.Thread(target = reverse)
            autoThread.start()
            last_key = 's'
        elif(arg=='a' and last_key!='a' and new_request_time >= old_request_time):
            print "left"
            stop_status = 0
            autoThread = threading.Thread(target = left)
            autoThread.start()
            last_key = 'a'
        elif(arg=='d' and last_key!='d' and new_request_time >= old_request_time):
            print "right"
            stop_status = 0
            autoThread = threading.Thread(target = right)
            autoThread.start()
            last_key = 'd'
        elif(arg=='stop' and new_request_time >= old_request_time):
            print "stop"
            last_key = "stop"
            time.sleep(0.3)
            stop_car()
        else:
            print "error"
        last_request_time = new_request_time
        self.write(arg)
    def options(self):
            pass
if __name__ == '__main__':
    tornado.options.parse_command_line()
    app = tornado.web.Application(handlers=[(r"/",IndexHandler)])
    http_server = tornado.httpserver.HTTPServer(app)
    http_server.listen(tornado.options.options.port)
    tornado.ioloop.IOLoop.instance().start()

然后是index.html文件:

<!DOCTYPE html>
<html>
<head>
        <meta charset="utf-8" />
        <title>WIFI小车客户端</title>
        <script src="http://libs.baidu.com/jquery/1.9.0/jquery.js"></script>
</head>
<body>
<script type="text/javascript">
        function go(k){
                var requestTime= new Date().getTime();
                $.post('/',{k:k,time:requestTime},function(){},"json");
        }
        $(function(){
                var i = null;
                window.document.onkeydown = keyDown;
                function keyDown(env){
                        env = (env) ? env : window.event;
                        if(env.keyCode=='87'){
                                go('w');
                        }
                        if(env.keyCode=='83'){
                                go('s');
                        }
                        if(env.keyCode=='65'){
                                go('a');
                        }
                        if(env.keyCode=='68'){
                                go('d');
                        }
                };
                window.document.onkeyup = keyUp;
                function keyUp(env){
                        env = (env) ? env : window.event;
                        if(env.keyCode=='87'){
                                go('stop');
                        }
                        if(env.keyCode=='83'){
                                go('stop');
                        }
                        if(env.keyCode=='65'){
                                go('stop');
                        }
                        if(env.keyCode=='68'){
                                go('stop');
                        }
                }
                $('.before').mousedown(function(){
                        i = setInterval(function(){
                                go('w');
                        },100);
                });
                $('.left').mousedown(function(){
                        i = setInterval(function(){
                                go('a');
                        },100);
                });
                $('.right').mousedown(function(){
                        i = setInterval(function(){
                                go('d');
                        },100);
                });
                $('.cabk').mousedown(function(){
                        i = setInterval(function(){
                                go('s');
                        },100);
                });
                $('#main span').mouseup(function(){
                        clearInterval(i);
                        go('stop');
                });
        });
</script>
<style type="text/css">
        #main{width: 150px;height: 150px;background: #ccc;}
        #main span{width: 50px;height: 50px;float: left;z-index: 999;}
        #main span.on2{background: #ff00ff;}
</style>
<div id="main">
        <span></span>
        <span class="on2 before"></span>
        <span></span>
        <span class="on2 left"></span>
        <span></span>
        <span class="on2 right"></span>
        <span></span>
        <span class="on2 cabk"></span>
        <span></span>
</div>
</body>
</html>

代码会持续更新在Github上地址,有兴趣的可以watch下,这您将第一时间收到更新通知。