最近有许多网友在问,关于用单片机操控的自平衡小车制造的问题,其实这在飞思卡尔智能车竞赛的时分,清华的卓晴教师的那篇文档里边说的很清楚,许多没参与竞赛的人不知道或许不注重这个文档,我用自己的了解来写一个总结期望对咱们有协助,大神勿拍砖。
首要确认一下咱们的方针是什么?咱们得让车站起来,小车整个身体只要电机能够操控轮子,天然对小车的操控就落在了对单片机程序对电机的操控上。许多参与竞赛的朋友由于车模是组委会发的,没去想过什么样的电机是适宜的? 天然发动会快,反映越快的直流电机最适宜。关于直流电机的操控调速,咱们都知道最常用的是脉宽调制即PWM方法,这时分就得选好电机驱动芯片了,跟你的电机匹配,电流要扛的住。再一个,把小车想成一个骑独轮车的杂技演员,保持平衡,你的保证能前后转吧,所以驱动得做成H桥型的,其电路图能够在http://www.51hei.com找到,总结一下咱们第一个方针便是做好驱动电路,能够完成对电机的正反两个方向的大约调速操控(留意是大约,无反应调理,假设想试试PID也能够先做一下速度反应调理)。
第二个问题,略微有点操控思维的就应该理解,小车是自平衡,天然是自己在操控,那它操控的依据是什么?依据什么去操控?关于两轮小车当它倒下去的时分,只要一个维度的两个量,那便是和直立方位的视点值和在倒下去的时分的快慢值(角速度),其实他俩是一个量,由于对角速度积分便是视点值。角速度仅仅反映了倒下去的快慢。即改变量。比如你拿一根筷子直立在手指上,你看见它要倒下去的时分必定手会跟着移动,你一方面看到的是筷子倒下去的视点,另一个是筷子倒的时分的快慢,视点大速度快你天然移动的快,起伏也大,视点小速度慢,你天然移动的慢起伏也小。以上纯脑袋想的,从科学的严谨性来说,仍是去看卓老迈的文档,从树立数学模型,到自控原理的核算剖析终究得出来。所以第二个方针出来了,咱们要去实时测出小车违背直立方位的视点,这个其实是自平衡小车的第一个难点。
咱们说测视点一般运用加速度计就能够了,加速度计是分为模仿的和数字的两种,都是能够用的,仅仅在实践情况中,加速度计丈量的视点是不精确的,由于在小车运动进程中存在轰动加速度,这会使输出值不精确,不能实在反映小车的偏转视点。这是器材自身的问题,有些人说用简略的数字滤波(中值、均值等),这些滤波是滤除的搅扰信号,这自身的过错信号怎样虑出?再来考虑另一个器材 陀螺仪,咱们知道陀螺仪是丈量角速度的,可是角速度转化为视点是需求一个积分进程,假设在输入时有一个极小的差错,那么跟着积分这个差错将会越来越大,终究得出的视点天然也是不精确的。(器材的运用是最基本的,期望咱们能把这两个传感器的运用先搞理解,理解视点详细是怎样核算出来的?)这个时分才有咱们常说的卡尔曼滤波、互补滤波的上台,许多人在制造进程中总是觉得卡尔曼或许互补滤波很高端的东西,视野全被它们遮盖了,实践上它们终究的意图任然是得到最精确的视点违背值。关于这一方针,传感器的功能、电路设计同样是很重要的。至于卡尔曼滤波和互补滤波的好坏不在这评论,咱们只说说用的较多的卡尔曼滤波,卡尔曼的宿世此生咱们在网上搜一下,千人一面,没一个说到点上了的。其实作为运用咱们只需知道卡尔曼输入的两个量,一个是丈量值,一个是猜测值,程序都是成型的,要点仍是在参数的调试上。整个算法中影响输出的便是Kg的值,能够简略的了解为一种加权行为,信任谁更多一点罢了。
代码如下:阐明:简化版卡尔曼滤波单片机c言语程序
volatile float QingJiao = 0; //终究精确视点输出变量界说
volatile float Gyro_Data = 0; //陀螺仪
float Q =1,R =3900; //调整卡尔曼的滞后 3900
static float RealData = 0,RealData_P =10000;
float NowData = 0,NowData_P =0 ;
float Kg = 0,gyroscope_rate = 0,gyroscope_rat = 0,accelerometer_angle;
volatile float gyroscope_angle=0 ; //用卡尔曼滤波时不必此变量
int Gyro1_zero=0;
void kalman_update(void)
{
if(zeroflag>1000) //与开机自检有关,没用到的能够删去
{ zeroflag=1001; //保证zeroflag不会溢出
//——————————————————————————————————————————-
Acc_z = Acc_z – 28850; //加速度计收集的AD值减去直立时的输出值
Gyro1_zero=zerosub/1000; //陀螺仪开机自检累加1000次后取均值 得到陀螺仪零偏值
Gyro1 = Gyro1 – Gyro1_zero; //陀螺仪AD收集值减去陀螺仪零偏值
Gyro_Data = Gyro1;
accelerometer_angle= Acc_z*180/(47915.71-12843.7); //加速度计核算出的视点 归一化到-90 到+90
gyroscope_rate = Gyro1*0.0235*0.005; //0.0235 是转化视点的份额值 0.005是操控周期
gyroscope_rat =gyroscope_rat -Gyro1*0.0235*0.005; //积分角速度得到视点
//卡尔曼五个公式的算法完成
NowData = RealData -gyroscope_rate;
NowData_P = Q+RealData_P;
Kg = NowData_P/(NowData_P+R);
RealData = NowData + Kg*(accelerometer_angle – NowData);
RealData_P = (1-Kg)*NowData_P;
QingJiao = RealData; //将精确视点成果给QingJiao
}
}
整个调试进程有三个参数需求调整,Q R 及那个0.0235 。详细的调试这个真是说不清楚,往往算法的调试都是经历,测验多了就有规则了。个人感觉做到这,就得用去三分之二时刻。
好了,假设你现已得到精确视点,天然是开端以此作为操控量,那咱们要操控成啥样?想一想也知道是要把这个视点值操控成0度(我自己将直立时界说为0度),那么天然运用常用的PID算法,误差天然便是QingJiao-0=QingJiao,当然你能够反过来,这其实依据你自己对方向的界说。咱们来个最简略的方位式PD算法:
fValue = (float) P *QingJiao -(float) D*Gyro_Data;
P便是PID的P参数 D便是PID的D参数,QingJiao反映起伏,Gyro_Data反映快慢。这也是需求不断调试出来的。再把fvalue值给PWM输出就能够了。实践在做的时分,往往没那么简略,所以一定要一步一步做好之后再做后边的,假设你第二部没做好,在第三部时你怎样也直立不起来,你不知道到底是PD参数不对,仍是卡尔曼出来的视点自身禁绝。所以个人感觉,得到精确视点是整个进程至关重要的一步。小车的直立是一直是一个动态进程,即便最好的状况一动不动,也是在动态操控中,仅仅看不出罢了。
以上只针对直立操控,即最基本的自平衡。