5.6.3 舵机控制算法
在小车行驶途中,由于在直道和过弯时,摄像头所采集到的图像的有效行数是会变化的,在过弯时,采集到的图像行数会减少,同时黑线的偏差值也会相应的变化,这样便可利用有效行的大小来分段给定舵机的Kp值,再结合偏差细化Kp值。经过测试和调试得出以下分段控制:
按照有效行进行分段确定比例系数:
Effect_row≤12; Kp=7;
12<Effect_row≤18; Kp=6;
18<Effect_row≤25; Kp=6;
Effect_row>25&&左边丢线数B_LZ>20||右边丢线数B_LR>20; Kp=6;
Effect_row>25&&B_LZ≤20&&B_LR≤20; KP=5;
经过实际调试测量控制后,小车的转向控制是非常准确。
5.6.2 电机控制算法
小车行驶途中,在不同的路况时,摄像头所采集到的图像的有效行数和偏差值是会变化的。在过弯时,采集到的图像行数会减少,偏差会增大,这样便可利用有效行和偏差的大小来控制速度。
控制的主要思想:将一幅图像划分成三段,计算每一段图像中两条黑线的累积偏差。对于直道来说累积偏差较小,有效行较多,对于弯道来说累积偏差较大,有效行较少。若前面两段的累积偏差大,后一段的累积偏差小,即可判定是直道入弯,此时电机减速;若前面两段的累积偏差较小,后一段的累积偏差较大,即可判定是开始由弯道进入直道,此时电机加速。在直道和弯道中主要通过弯道计数器和直道计数器来完成对电机的控制。若正在处理的一行如上一行的偏差大于一个设定的值(通过测试得到),弯道计数器加一,否则直道计数器加一,通过一幅图像的中弯道计数器与直道计数器的值的相应大小即可判定是直道还是弯道,并设定相应的速度。
这种算法的优点是对于小S弯,计算的累积偏差不大,即可判定为直道,此时可以以最优的路径冲过小S弯。
5.5.4 转角控制 根据赛道的偏差来控制舵机的转角,采用如下: - voidduoji(void){
- if(duandianflag==0){
-
-
- if(error>0)
- duty=DUOJICENTER+error*kp;
- else
-
- duty=DUOJICENTER+error*kp;
- error1=error;
-
- }else if(duandianflag==1){
- duty= DUOJICENTER+ZHUANMAX;
- }else if(duandianflag==2)
- duty= DUOJICENTER-ZHUANMAX;
- if(duty>DUOJICENTER+ZHUANMAX)
-
- duty=DUOJICENTER+ZHUANMAX;
- if(duty<DUOJICENTER-ZHUANMAX)
- duty=DUOJICENTER-ZHUANMAX;
-
-
- PWMDTY01=duty;
- }
- ////////////////////////////////////////////////////////////////////
复制代码
斜率控制
判断赛道类型,给出速度基准
5.3 舵机控制从采集回来的图像中提取控制量来控制舵机的转向,实现智能车的自动循迹。本系统采用虚拟黑线的偏移量e_steer和虚拟黑线的某段斜率K_buf对舵机进行控制,可称为PD控制器。
其控制形式如下式所表示:
e_steer=(POINT/2-(int)mid_image[1])*KD2_2;
K_buf=((int)(mid_image[1])-(int)(mid_image[hang_en]))*(KS2-2)/hang_en;
式中的POINT为摄像头采集的列数,mid_imag数组时根据两条黑线虚拟出来的中间线,KD2_2和KS2_2是结合小车行驶的情况整定的参数。
由于车模是个随动系统,我们的小车的前瞻是70cm,而真正用到的只用我们指定的17行。在摄像头70cm前瞻内覆盖的黑线超过17行,特别是前方的弯特别急的时候,在摄像头前瞻视角范围内覆盖的黑线会特别少。根据这个特点,可设置一个有效前瞻量hang_en作为对前方的弯的平缓程度的反应。
这样,从一场的黑线位置数据中,系统提取了有效行hang_en、e_steer、K_buf 3个量来对舵机进行控制。在实际情况中,K_buf可以很灵活,因为前方黑线的斜率可以取不同段得到,可以根据实际要求得到不同段的斜率值.如速度快时可以适当的取距车较远处的黑线斜率,以实现超前控制。在智能车调试参数的时候.对这3个量的理解很是重要,具体来说,hang_en表征车模的有效前瞻, 即看得有多远,对于智能车在道路上行驶,看得远说明黑线都在前方,看不远说明智能车前方的黑线已经偏左或者偏右,而这个量的大小正好可以表征弯的平缓与急切。另外,看得远则摄像头采集的黑线多,系统信息量大,那么怎么处理这些大量的信息为我们所用就变得很关键,如看得70cm都能看见.说明小车必然在长直道上,不然也是小S弯,稍作处理就可以过滤掉小S弯了,让小车像都是在直道上跑;看得很近说明弯已经很急,这时候,只要能够判断出弯往那边拐就可以给舵机一个极值急拐。e_steer表征在某一个特定视野下.小车与黑线偏离的程度,这个量可以让智能车在某个特定视野下决定给舵机多大的转角。K_buf则在有效前瞻远的时候尤为关键,因为它可以预判前方的弯,从而超前的转弯。 5.4 速度控制 电机控制方面我们才用的是增量式PID。行驶过程中给定的速度主要要六种,这六个速度值对应舵机赛道的不同半径的弯道,也就是说在半径小的圆弯,速度不能太大,因此赋予小的速度值,而半径大的圆弯则要赋予较高的速度值。这样在小车行驶过程中既保证了小车的稳定性,也提高了速度。具体实现程序如下所示: - if(Steer_PWM>1125) //右弯
- {
- if(Steer_PWM>1215)
- {speed_goal=speed_strategy.very_slow;}
- else if(Steer_PWM>1185)
- {speed_goal=speed_strategy.slow;}
- else if(Steer_PWM>1155)
- {speed_goal=speed_strategy.medium;}
- else
- {speed_goal=speed_strategy.high;}
- }
- else if(Steer_PWM<1095) //左弯
- {
- if(Steer_PWM<1005)
- { speed_goal=speed_strategy.very_slow;}
- else if(Steer_PWM<1035)
- { speed_goal=speed_strategy.slow;}
- else if(Steer_PWM<1065)
- { speed_goal=speed_strategy.medium;}
- else
- {speed_goal=speed_strategy.high;}
- }
- else{if(Judgment_straight(hang_en))speed_goal=speed_strategy.very_high;}
复制代码 其中的速度值可由拨码开关控制其大小。我们采用的是四位拨码开关,理论上可以设定十六种速度值,但是为了控制的方便,我们只使用了八个值,其中两个设置为开环,防止比赛时测速突然失灵。其它六中则为对应的速度结构体,具体对应的不同半径的速度值存放在一个结构体变量speed_strategy中,速度的选取可视赛场的情况而定。为了加快系统的响应,使用PID控制器来提高响应速度.具体的实现如下代码: ek=(int)speed_goal-(int)speed; out=(int)(ek*Kp)-(ek_1*Ki)+(ek_2*Kd); 其中ek为当前速度与期望值的偏差,ek_1为上一次的偏差,而ek_2为更早一次的偏差,Kp为比例系数,Ki为积分环节系数,Kd为微分环节系数,这三个参数经过大量的调试得来
////////////////////////////////////////
5.3.2 舵机转向控制算法
经过上面的图像处理方法,得到本场第一个有效行为istart,最后一个有效行iend。为了使智能车的路径更优化,需要把赛道分类。针对不同赛道选用不同的走线策略。由(istart,cent[istart])和(iend,cent[iend])两点确定一直线y=a*i+b记为L。当有效行大于3行时,从istart+1开始到iend-1结束进行逐行处理。每行计算cent[ i]-a*i+b[ i]。如果扫描中发现有的行导航线在L左侧,有的在L右侧,因为只有S弯才会看到此现象,所以此时赛道为S弯,再根据bulb(bulb为一场中最大的cent[ i]-a*i+b[ i])的大小可确定是大S弯还是小S弯。如不是S弯,再根据iend的大小来判断。iend大说明看到的图像长,那转弯处必定较远,记为远弯。相应的iend小则为近弯。如果有效行小于3行,再看istart是否为第0行。是则说明比较信息比较可靠,且弯很急记为急弯,否则信息不可靠记为不可靠信号。因为直道上不管以哪一行控制差别都不大,所以直到也可归为远弯。
得到了路径识别的结果,再确定不同路径的控制行。先按在直线上以每行作为控制行分别得到的转角相等为标准,确定每行的转角系数。这样同样大小的cent[ i]所对应的转角随着i增大而减小。如果路径为小S弯,就以iend为控制行,以达到直走的效果。如果是大S弯,根据S玩的大小,分别以iend和ibulb控制行算得的转角按一定权值求平均值作为最终转角。如果是远弯,如果以iend行的黑线中值来控制舵机会使智能车过弯太提前,容易从弯内侧冲出赛道,为此要沿线走较合理,而ibulb正好是相当于直线与拐弯交界处,所以以ibulb为控制行。如果是近弯,以iend控制,会走内线,既不易冲出赛道又缩短路径。
如果是急弯,以iend控制转的最大。如果是不可靠信号,就以近处某一固定行控制,以达到循线走的效果。
为了更好的解决转向的问题,我们采用分段转角系数控制舵机。根据不同的路况信息来设定不同的转角系数。因为在直道或小S上转角系数太大,往往会导致舵机的抖动使得小车在直线上左右摇摆,所以如果小车行驶在直线上那么舵机的转角系数应该比较小;如果小车舵机行驶湾道上,那么转角系数应该同时变大否则很可能不能及时地过弯道。
5.3.3 直流电机的控制算法
根据路径识别的情况,如果当前路径为直道,则需要加速;若是弯道,则需要降速,而且根据不同的弯道速度也是有所区别,这个区别体现在速度设定上。我们根据iend、舵机转角、bulb等多个变量的大小来确定速度设定的策略。
当iend等于最远行时,说明弯道离得很远,速度可以设为很高的值。这时需要根据bulb来确定远处是弯道还是直道,bulb越大速度应该越小,bulb为0时速度为最高档。当iend不等于最远行时,速度需要降一个档,再根据iend越大速度越高,舵机转角越大,速度越低的原则,对速度做进一步微调。当iend小于4时,说明有冲出赛道的危险,速度再降一档,再根据iend越大速度越高,舵机转角越大,速度越低的原则,对速度做进一步微调。由于速度太低时,电机动力不足难以推动智能车前进。因此速度设定应该有个最低限幅值。当运算得到的速度设定小于该限幅值时,速度直接赋值为最低值。速度设定中用到的各参数都可用拨码开关来改变,这在实际比赛中有较大的实际意义。
以上只是速度设定的算法,实际的车速还需要闭环控制,用PID算法来实现稳定、准确、快速地跟随速度设定。下面介绍速度的控制算法。
系统利用测速模块反馈的当前速度值,和设定速度值来选择不同的P参数来进行调节,从而控制直流电机对当前路径进行快速反应,利用I的作用使得消除静差,加入D使得速度更加稳定。
本系统采用的是数字PID 控制,通过每一控制周期读入脉冲数来间接测得小车当前转速vi_FeedBack,将vi_ FeedBack与模糊推理得到的小车期望速度vi_Ref比较,既而算得速度偏差error,再通过调用PID函数来获得速度的控制。 考虑到CMOS方案的控制周期较长,假设按2.5m/s的平均速度计算,则一个控制周期小车大概可以跑过5cm,如果按这种周期用上述PID调节速度,则会导致加速减速均过长的后果,严重的影响小车的快速性和稳定性。为了解决这个问题,可以在PID调速控制中适当加入Bang-Bang控制:根据error的大小,如果正大,则正转给全额占空比;如果负大,则自由停车或给一个反转的PWM,否则就采用PID来计算所需的占空比。
|