BOBO · 2022年02月20日

【XR806开发板试用】智能小车的控制系统从0到1

一:首先设计小车的驱动模块

由于设计的小车的运动控制是由控制器控制电机执行,但是控制器的IOS口一般只能提供5MA到10MA的电流,而小车直流电机工作电流一般是200-400MA甚至更大,所以控制器直接驱动电机是驱动不了的,需要使用电机驱动电路来放大电流,并且实现前后转动。家庭智宝采用L298P作为直流电机驱动芯片。L298P由ST公司开发和制造,具有集成高达46V的工作电压,高达3A的瞬时峰值电流和高达25W的额定功率的能力。此外,双通道全桥电动机驱动器芯片可以连接到标准TTL逻辑高电平和低电平,并且可以驱动感性负载。一个L298P可以直接驱动2个直流电动机.由两组L298P驱动电路来驱动循迹避障小车的4个直流电机进行旋转,主控芯片输出电机控制信号给L298P芯片的信号输入脚,进而控制电机的正反转,转动速度等功能。图1-1所示为电机驱动电路设计。

aijishu_xr1.png
图1-1  驱动电机的L298P电机驱动电路图设计

接着使用嘉立创打板。图1-2实物效果

aijishu_xr2.png
图1-2  实物效果

二:WIFI联网

详情参考WiFi联网-全志XR806开发板入门教程
主要就是:hm net sta connect < ssid > < psk >:连接指定热点,在没有进行搜索的情况下默认加密方式为WPA/WPA2,如果连接不上,可以尝试先扫描再连接,开发热点不需要填psk。

三:Python编写代码

Ubuntu自带Python,Python有问题的看看官方解决办法。

一般车辆的状态包括:前进、后退、左转、右转、和速度控制五个状态。智能驾驶电动小车由于是计算机控制,所以还需设置紧急制动动作。底层控制系统接收路径规划层发出的指令,实时控制电动小车的运动状况,而紧急制动动作是由紧急制动命令直接控制,具备最高优先级,而前进、后退、左转、右转和速度控制具有相同的优先级。本次设计的智能电动小车的底层控制是由树莓派来实现,因此规定电动小车的三种状态:前进为1、停车为0、倒车为-1,路径规划层发送的命令,正速度为期望状态1,负速度为期望状态-1,速度为零为期望状态0。小车速度通过PWM控制。具体代码如下:

import RPi.GPIO as GPIO  
import time  
import configparser  
  
LEFT\_FRONT\_1 = 7  
LEFT\_FRONT\_2 = 11  
  
RIGHT\_FRONT\_1 = 13  
RIGHT\_FRONT\_2 = 15  
  
LEFT\_BEHIND\_1 = 31  
LEFT\_BEHIND\_2 = 33  
  
RIGHT\_BEHIND\_1 = 35  
RIGHT\_BEHIND\_2 = 37  
  
class FourWheelDriveCar():  
  
def \_\_init\_\_(self):  
  '''  
  1. Read pin number from configure file  
  2. Init all GPIO configureation  
  '''  
  config = configparser.ConfigParser()  
  config.read("config.ini")  
  self.LEFT\_FRONT\_1 = config.getint("car", "LEFT\_FRONT\_1")  
  self.LEFT\_FRONT\_2 = config.getint("car", "LEFT\_FRONT\_2")  
  
  self.RIGHT\_FRONT\_1 = config.getint("car", "RIGHT\_FRONT\_1")  
  self.RIGHT\_FRONT\_2 = config.getint("car", "RIGHT\_FRONT\_2")  
  
  self.LEFT\_BEHIND\_1 = config.getint("car", "LEFT\_BEHIND\_1")  
  self.LEFT\_BEHIND\_2 = config.getint("car", "LEFT\_BEHIND\_2")  
  
  self.RIGHT\_BEHIND\_1 = config.getint("car", "RIGHT\_BEHIND\_1")  
  self.RIGHT\_BEHIND\_2 = config.getint("car", "RIGHT\_BEHIND\_2")  
  
  GPIO.setmode(GPIO.BOARD)  
  GPIO.setwarnings(False)  
  GPIO.setup(self.LEFT\_FRONT\_1, GPIO.OUT)  
  GPIO.setup(self.LEFT\_FRONT\_2, GPIO.OUT)  
  GPIO.setup(self.RIGHT\_FRONT\_1, GPIO.OUT)  
  GPIO.setup(self.RIGHT\_FRONT\_2, GPIO.OUT)  
  GPIO.setup(self.LEFT\_BEHIND\_1, GPIO.OUT)  
  GPIO.setup(self.LEFT\_BEHIND\_2, GPIO.OUT)  
  GPIO.setup(self.RIGHT\_BEHIND\_1, GPIO.OUT)  
  GPIO.setup(self.RIGHT\_BEHIND\_2, GPIO.OUT)  
  
def reset(self):  
  # Rest all the GPIO as LOW  
  GPIO.output(self.LEFT\_FRONT\_1, GPIO.LOW)  
  GPIO.output(self.LEFT\_FRONT\_2, GPIO.LOW)  
  GPIO.output(self.RIGHT\_FRONT\_1, GPIO.LOW)  
  GPIO.output(self.RIGHT\_FRONT\_2, GPIO.LOW)  
  GPIO.output(self.LEFT\_BEHIND\_1, GPIO.LOW)  
  GPIO.output(self.LEFT\_BEHIND\_2, GPIO.LOW)  
  GPIO.output(self.RIGHT\_BEHIND\_1, GPIO.LOW)  
  GPIO.output(self.RIGHT\_BEHIND\_2, GPIO.LOW)  
  
def \_\_forword(self):  
  self.reset()  
  GPIO.output(self.LEFT\_FRONT\_1, GPIO.HIGH)  
  GPIO.output(self.LEFT\_FRONT\_2, GPIO.LOW)  
  GPIO.output(self.RIGHT\_FRONT\_1, GPIO.HIGH)  
  GPIO.output(self.RIGHT\_FRONT\_2, GPIO.LOW)  
  GPIO.output(self.LEFT\_BEHIND\_1, GPIO.HIGH)  
  GPIO.output(self.LEFT\_BEHIND\_2, GPIO.LOW)  
  GPIO.output(self.RIGHT\_BEHIND\_1, GPIO.HIGH)  
  GPIO.output(self.RIGHT\_BEHIND\_2, GPIO.LOW)  
  
def \_\_backword(self):  
  self.reset()  
  GPIO.output(self.LEFT\_FRONT\_2, GPIO.HIGH)  
  GPIO.output(self.LEFT\_FRONT\_1, GPIO.LOW)  
  GPIO.output(self.RIGHT\_FRONT\_2, GPIO.HIGH)  
  GPIO.output(self.RIGHT\_FRONT\_1, GPIO.LOW)  
  GPIO.output(self.LEFT\_BEHIND\_2, GPIO.HIGH)  
  GPIO.output(self.LEFT\_BEHIND\_1, GPIO.LOW)  
  GPIO.output(self.RIGHT\_BEHIND\_2, GPIO.HIGH)  
  GPIO.output(self.RIGHT\_BEHIND\_1, GPIO.LOW)  
  
def \_\_turnLeft(self):  
  '''  
  To turn left, the LEFT\_FRONT wheel will move backword  
  All other wheels move forword  
  '''  
  self.reset()  
  GPIO.output(self.LEFT\_FRONT\_2, GPIO.HIGH)  
  GPIO.output(self.LEFT\_FRONT\_1, GPIO.LOW)  
  GPIO.output(self.RIGHT\_FRONT\_1, GPIO.HIGH)  
  GPIO.output(self.RIGHT\_FRONT\_2, GPIO.LOW)  
  GPIO.output(self.LEFT\_BEHIND\_1, GPIO.HIGH)  
  GPIO.output(self.LEFT\_BEHIND\_2, GPIO.LOW)  
  GPIO.output(self.RIGHT\_BEHIND\_1, GPIO.HIGH)  
  GPIO.output(self.RIGHT\_BEHIND\_2, GPIO.LOW)  
  
def \_\_turnRight(self):  
  '''  
  To turn right, the RIGHT\_FRONT wheel move backword  
  All other wheels move forword  
  '''  
  self.reset()  
  GPIO.output(self.LEFT\_FRONT\_1, GPIO.HIGH)  
  GPIO.output(self.LEFT\_FRONT\_2, GPIO.LOW)  
  GPIO.output(self.RIGHT\_FRONT\_2, GPIO.HIGH)  
  GPIO.output(self.RIGHT\_FRONT\_1, GPIO.LOW)  
  GPIO.output(self.LEFT\_BEHIND\_1, GPIO.HIGH)  
  GPIO.output(self.LEFT\_BEHIND\_2, GPIO.LOW)  
  GPIO.output(self.RIGHT\_BEHIND\_1, GPIO.HIGH)  
  GPIO.output(self.RIGHT\_BEHIND\_2, GPIO.LOW)  
  
def \_\_backLeft(self):  
  '''  
  To go backword and turn left, the LEFT\_BEHIND wheel move forword  
  All other wheels move backword  
  '''  
  self.reset()  
  GPIO.output(self.LEFT\_FRONT\_2, GPIO.HIGH)  
  GPIO.output(self.LEFT\_FRONT\_1, GPIO.LOW)  
  GPIO.output(self.RIGHT\_FRONT\_2, GPIO.HIGH)  
  GPIO.output(self.RIGHT\_FRONT\_1, GPIO.LOW)  
  GPIO.output(self.LEFT\_BEHIND\_1, GPIO.HIGH)  
  GPIO.output(self.LEFT\_BEHIND\_2, GPIO.LOW)  
  GPIO.output(self.RIGHT\_BEHIND\_2, GPIO.HIGH)  
  GPIO.output(self.RIGHT\_BEHIND\_1, GPIO.LOW)  
  
def \_\_backRight(self):  
  '''  
  To go backword and turn right, the RIGHT\_BEHIND wheel move forword  
  All other wheels move backword  
  '''  
  self.reset()  
  GPIO.output(self.LEFT\_FRONT\_2, GPIO.HIGH)  
  GPIO.output(self.LEFT\_FRONT\_1, GPIO.LOW)  
  GPIO.output(self.RIGHT\_FRONT\_2, GPIO.HIGH)  
  GPIO.output(self.RIGHT\_FRONT\_1, GPIO.LOW)  
  GPIO.output(self.LEFT\_BEHIND\_2, GPIO.HIGH)  
  GPIO.output(self.LEFT\_BEHIND\_1, GPIO.LOW)  
  GPIO.output(self.RIGHT\_BEHIND\_1, GPIO.HIGH)  
  GPIO.output(self.RIGHT\_BEHIND\_2, GPIO.LOW)  
  
def \_\_stop(self):  
  self.reset()  
  
def carMove(self, direction):  
  '''  
  Car move according to the input paramter - direction  
  '''  
  if direction == 'F':  
   self.\_\_forword()  
  elif direction == 'B':  
   self.\_\_backword()  
  elif direction == 'L':  
   self.\_\_turnLeft()  
  elif direction == 'R':  
   self.\_\_turnRight()  
  elif direction == 'BL':  
   self.\_\_backLeft()  
  elif direction == 'BR':  
   self.\_\_backRight()  
  elif direction == 'S':  
   self.\_\_stop()  
  else:  
   print("The input direction is wrong! You can just input: F, B, L, R, BL,BR or S")  
  
  
if \_\_name\_\_ == "\_\_main\_\_":  
raspCar = FourWheelDriveCar()  
while(True):  
  direction = input("Please input direction: ")
推荐阅读
关注数
13820
内容数
140
全志XR806开发板相关的知识介绍以及应用专栏。
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息