用树莓派制作智能小车

2019-07-14 03:13发布

用树莓派制作智能小车

DarkBull's Blog 2014-06-02 4164 阅读   树莓派智能小车     难得周末有空,折腾了一下智能不车。     道具:树莓派,usb无线网卡,L298N电机驱动板,usb移动电源一个,两块手机电板(串联组成7.2v的电源供小车驱动),智能小车底盘,杜邦线若干,橡皮筋若干,电脑一台     原理:通过树莓派的gpio接口,控制电机驱动及速度,实现小车的前进后退,变向。         电机通过L298N驱动,其中电路图为:
    小车的电机驱动需要外接电源,不可从树莓派的gpio口取电,gpio口只提供5v的电压,驱动电机够吃力的,轻者造成树莓派死机,重者直接把树莓派烧掉~~ 手头上刚好有几前买过的一只山寨机的两块电板,刚好拿来,串联成一个7.2v的电源。     车轮的速度可以通过pmw控制,随便找两个gpio口,连接到驱动电板的ena、enb,控制,非常方便。     小车的控制,我走的是http,在树莓派上运行一个tornado进程,在手机上通过触控控制。如果左轮的速度>右轮,则右转,反之左转。web界面很简单,如下图,点到哪里,得到一个相对于圆心的点,根据点到圆心的x,y轴距离,算出小车左右轮的速度,从而通过pwm控制小车。界面使用了html5的canvas。本来在小车上装了个摄像头,通过mjpg-stream把图像实时显示在网页上,无奈摄像头太差,就不加了。下次要买个nb点的摄像头。
     越来越赖了,直接贴源码,作个标记,下次继续完善:加个机械臂,装一大堆传感器。 前台代码: xmlns="http://www.w3.org/1999/xhtml"> http-equiv="Content-Type" content="text/html; charset=UTF-8" /> </span><span class="pln">智能小车控制平台</span><span class="tag" style="color:rgb(128,0,0);"> type="text/javascript" src=""/static/jquery.min.js"> id="cav_dir" width="400" height="400" style="background-color: #eeeeee"> 您的浏览器不支持。 id="spn">hello src="http://192.168.1.20:8090/?action=stream" /> type="text/javascript"> $(function() { var c=document.getElementById("cav_dir"); var cxt=c.getContext("2d"); var r = 200 cxt.beginPath(); cxt.fillStyle="rgba(0, 255, 0, 0.5)"; cxt.arc(r, r, r, 0, Math.PI*2, false); cxt.closePath(); cxt.lineWidth = 2 cxt.strokeStyle = "'rgba(255,0,0,0.5)'; cxt.moveTo(0, r - 1) cxt.lineTo(2 * r, r - 1) cxt.moveTo(r - 1, 0) cxt.lineTo(r - 1, 2 * r) cxt.stroke() cxt.fill(); function run(event) { event = event || window.event event.preventDefault() var x = event.touches[0].clientX - r var y = event.touches[0].clientY - r var oInp = document.getElementById("spn"); oInp.innerHTML = '(' + x + ',' + y + ')' if (x * x + y * y < r * r) { $.post('/?x=' + x + '&y=' + y + '&r=' + r) } } function stop(event) { event = event || window.event event.preventDefault() $.post('?x=0&y=0&r=' + r) } c.addEventListener('touchstart',run, false); c.addEventListener('touchmove',run, false); c.addEventListener('touchend',stop, false); }) 后台代码: #!/usr/bin/env python # -*- coding: utf-8 -*- # @Author: darkbull # @Date: 2014-05-31 10:02:21 # @Last Modified by: darkbull # @Last Modified time: 2014-06-02 15:29:20 """Web控制树莓派小车 """ import tornado.web import tornado.ioloop import codecs import RPi.GPIO as GPIO import time import atexit import math atexit.register(GPIO.cleanup) GPIO.setmode(GPIO.BCM) IN1 = 17 IN2 = 22 IN3 = 23 IN4 = 24 # 左边轮速度控制 PWM_L = 8 PWM_R = 7 GPIO.setup(IN1, GPIO.OUT, initial=False) GPIO.setup(IN2, GPIO.OUT, initial=False) GPIO.setup(IN3, GPIO.OUT, initial=False) GPIO.setup(IN4, GPIO.OUT, initial=False) GPIO.setup(PWM_L, GPIO.OUT, initial=False) GPIO.setup(PWM_R, GPIO.OUT, initial=False) pwm_l = GPIO.PWM(PWM_L, 50) pwm_l.start(0) pwm_r = GPIO.PWM(PWM_R, 50) pwm_r.start(0) def front(): GPIO.output(IN1, True) GPIO.output(IN2, False) GPIO.output(IN3, True) GPIO.output(IN4, False) def back(): GPIO.output(IN1, False) GPIO.output(IN2, True) GPIO.output(IN3, False) GPIO.output(IN4, True) # def left(): # # GPIO.output(IN1, False) # # GPIO.output(IN2, True) # GPIO.output(IN1, False) # GPIO.output(IN2, False) # GPIO.output(IN3, True) # GPIO.output(IN4, False) # def right(): # # GPIO.output(IN1, True) # # GPIO.output(IN2, False) # GPIO.output(IN1, False) # GPIO.output(IN2, False) # GPIO.output(IN3, False) # GPIO.output(IN4, True) def stop(): GPIO.output(IN1, False) GPIO.output(IN2, False) GPIO.output(IN3, False) GPIO.output(IN4, False) def run(x, y, r): """小车运行 """ if x * x + y * y > r * r: return speed_min = 15 speed_max = 100 speed_delta = speed_max - speed_min # y轴为小车的运行方向,速度以y轴的值为基准 if y < 0: back() elif y > 0: front() else: stop() return t = abs(y) * 100.0 / r if t < 20: # 电压太小,驱动不起来 t = 20 d = math.atan2(x, y) * 180 / math.pi if x < 0: # 往左边偏, 右轮的速度比左轮快 t2 = t * (abs(90 + d) / 90) pwm_r.ChangeDutyCycle(t) pwm_l.ChangeDutyCycle(t2) elif x > 0: # 往右边偏, 左边的速度比右轮快 t2 = t * (abs(90 - d) / 90) pwm_l.ChangeDutyCycle(t) pwm_r.ChangeDutyCycle(t2) print x, y, t, t2 class CarController(tornado.web.RequestHandler): def get(self): with codecs.open('webcar.html', 'r', encoding='utf-8') as fp: self.write(fp.read()) def post(self): r = int(self.get_argument('r')) x = int(self.get_argument('x')) y = int(self.get_argument('y')) run(x, y, r) self.write('ok') if __name__ == '__main__': app = tornado.web.Application([('/', CarController)], static_path='static', debug=True) app.listen(18080) tornado.ioloop.IOLoop.instance().start()