智能车总结.docx
- 文档编号:5401160
- 上传时间:2022-12-15
- 格式:DOCX
- 页数:13
- 大小:48.14KB
智能车总结.docx
《智能车总结.docx》由会员分享,可在线阅读,更多相关《智能车总结.docx(13页珍藏版)》请在冰豆网上搜索。
智能车总结
智能车电磁组总结
专业:
信息安全(保密方向)
班级:
09091401
*****
学号:
**********
暑期我在智能车基地进行了自己的暑期生产实习,和队友在之前搭建的智能车基础上进行完善和改进,参加了恩智浦杯智能汽车竞赛。
我想本次的实习报告从智能车原理和算法设计上进行叙述。
电磁类智能车概述
智能车顾名思义便是可以按照预先设定的模式在特定的环境中自由的运动而不受人为的干预的小车,除了可以自动循迹(沿着特定的轨道跑),他还可以实时显示自己的各种运动状态,如:
速度,里程,实时轮胎打角状况等。
要实现它的自动化,小车便由三部分组成的——传感器部分、控制部分和执行部分。
首先传感器部分便是智能车的眼睛,它用来收集智能车所在环境中的有用信号,将收集到的模拟信号转化为数字信号以此为依据进行相应的控制,我们组所做的是电磁类的智能车,传感器便是电感,通过测量电感所产生的电压来判断小车在赛道的位置,由于电压大小与和导线的距离有关,所以这种方式可以实现位置检测。
测量具体原理如下,有毕奥-萨伐尔定律可知,通有稳恒电流I、长度为L的直导线周围会产生磁场,距离导线距离为r处的磁感应强度为:
对于无线长直导线先来说,上式中
等于
,
等于0,
为真空磁导率,则:
位于磁场中的电感线圈的感应电动势近似为:
其中
为水平方向上的感应电动势分量(我们将电感卧式放置),x为距离导线的水平距离,h为高,故感应电动势的大小正比于电流的变化率K,反比于距离
,由于K是定值,故可通过测量E获得水平距离r值。
接着是控制部分,这部分主要是接受传感器部分测量的信号进行计算分析,根据预先编进程序的策略传送出控制信号给各部分执行单位,控制部分主要是单片机,我们所用的是K60,他通过ADC模块接收传感器模块传进来的电压信号并进行模数转化,并经过一系列的数据处理得到电压值,通过电压的计算得出小车在赛道中的位置值,以此为依据进行相应的控制,当然还接受其他部分传进的信心以便更精细的控制,如编码器等。
一是转向控制,当计算出的位置值比较大时,说明小车已经偏离赛道中央或者正在弯道中,这时小车应该向赛道中央拐,控制部分通过FTM定时模块输出PWM波到执行部分中的舵机中,使舵机进行相应方向的打角让小车回到赛道中央,为了在不同的车速下确保小车能够及时回到赛道中央,多级的转角大小应该对应小车位置的大小,PWM波的占空比决定舵机(步进电机)转动的角度,具体PWM波的计算在后面会给出。
二是速度控制,对于竞速型的智能车,速度是小车的关键,小车要能够在保证不冲出赛道的情况下尽量提高速度,这就需要小车具有非常灵敏的加减速功能,除去小车轮胎摩擦力和倾角外等一些硬件方面的因素外,加减速功能主要是通过控制部分的相应功能实现,单片机可通过输出PWM波到驱动模块使电机转动,当然可以改变占空比来控制电机转动的快慢,从而控制速度的大小,加减速控制的时机和速度的大小可以通过相应的算法进行判断。
最后是执行部分,一是舵机模块,这部分不需要驱动电路,只需将单片机的PWM波输入到舵机相应的引脚就可以,舵机内部有自己的基准波形,他和输入的PWM波的占空比等相比较从而决定正转还是反转以及转动的角度。
电机模块有电机的驱动电路和电机本身,一般电机只要通电就可以转动起来,但要控制其转动的快慢就需要驱动电路实现电机转速的控制,同时驱动电路还可以提供相应的电压。
程序设计
一、位置获取方式
由电感采集的感应电动势信号通过信号板输入单片机的ADC模数转换模块的各个端口,单片机将其转化为数字信号后,可将其作为此刻的电动势值,每个传感器每次采集100次数据,然后计算这100次采集的数据中最大值和最小值之差,作为电压值。
由于各个电感固定的位置不同,所测量到的电压范围也会有所不同,这些数据便不能直接进行比较或计算,为了能够很好地处理数据,我们通过归一化将各个电感的数据统一到同一个范围之内,这样便可以进行比较计算了,同时归一化还可以消除因赛道电流变化产生的误差,实时地反映赛道的真实状况,因为归一化采用的是相对值,不易受绝对数据变动而产生的影响。
归一化的公式为:
这部分的程序为:
voidsignal_collecting(void)//传感器信号采集函数
{
uint8i;
for(i=0;i<100;i++)//每个传感器采集100次数据
{
sensor[0][i]=LPLD_ADC_Get(ADC1,AD10);
sensor[1][i]=LPLD_ADC_Get(ADC1,AD8);
sensor[2][i]=LPLD_ADC_Get(ADC1,AD9);
sensor[3][i]=LPLD_ADC_Get(ADC0,AD12);
sensor[4][i]=LPLD_ADC_Get(ADC0,AD13);
sensor[5][i]=LPLD_ADC_Get(ADC1,AD11);
sensor[6][i]=LPLD_ADC_Get(ADC1,AD12);
sensor[7][i]=LPLD_ADC_Get(ADC1,AD13);
sensor[8][i]=LPLD_ADC_Get(ADC0,AD14);
sensor[9][i]=LPLD_ADC_Get(ADC0,AD15);
}
for(i=0;i<10;i++)
{
peak[i]=CalcMaxToMin(sensor[i]);//传感器信号采集峰值计算
unity[i]=300*peak[i]/max[i];//归一化公式
}
}
uint16CalcMaxToMin(uint16data[100])//峰值计算函数
{
uint16Max=0;
uint16Min=0;
uint16i=0;
Max=data[0];
Min=data[0];
for(i=0;i<100;i++)
{
if(data[i]>Max)Max=data[i];//选取数组中最大值
if(data[i] } returnMax-Min; } 获得了电压值后我们便可以进行小车中心轴距离导线位置的计算,首先我们通过实际测量得出当小车中心轴上的电感刚好在导线垂直上方的高度h,而此时的电压值刚好是最大值,由前面的计算可知,电压值反比于距离r的平方,应此刚好可以列出等式计算出距离r,又高度h已知,则可得到水平距离x,这是的x还是正值,不能够用来进行舵机转向的控制,因此还需进行正负辨别将其转化为矢量,这样小车的位置测定基本上就完成了。 这部分的代码如下: float32Biot_Savart_Law1(uint16unity)//毕奥萨伐尔定律函数 { float32distance;//定义变量 float32dis; float32k; k=300*ave_peak_init[2]/max[2]; distance=(H*H*k)/unity-H*H; if(distance>0) dis=sqrt(distance); else dis=0; returndis; } float32Dis_Get1(void)//提线函数1 { float32dis_error; if(unity[3]>unity[1])//由[1][3]两个电感值的大小来判断小车的方向 dis_error=Distance[2];//偏左,返回正值 else dis_error=(-1)*Distance[2];//偏右,返回负值 returndis_error; } 二、舵机控制PD算法 得到了位置信息之后,我们便可以通过它来进行舵机的控制,我们对于舵机的控制采取位置式PD算法,即: P为比例系数,它所起的作用便是以最快速度(一次性)减小与目标PWM占空比之间的差距,只要有偏差它便起作用,当偏差为0时它便失去作用,系统保持在平衡状态,但它很容易产生超调,调节得太过了,这样下一次又会往回调,来来回回就容易产生振荡,不易在短时间内达到目标值,此时就需要D来解决,D为微分系数,与他相乘的便是位置量变化的微分,微分反映位置变化的速率,所以D控制具有一定得预见性,使得在产生偏差之前就消除了偏差,从而一定程度上避免了系统产生超调,至于另外一个积分调节,他是用来消除静态误差的,但由于他积累了每次调节所产生的误差,使得系统变化比较大,不易使用。 为了防止舵机打角超过一定范围会因为轮胎卡住而损坏舵机,我们应该限定舵机打角的范围,另外还有一种异常情况是当电感偏离赛道太远时,所收集到的电磁信号变得非常小,以至于判断方向的两个电感采集的值大小相等,从而舵机不打角甚至向相反的方向打角,使得小车乱跑,这是小车丢线了,为了防止丢线,我们应该在小车失去判别方向能力的前一时刻防止小车大范围打角,即保持之前的打角状况,我们来检测小车是否丢线的方法便是判断与前一次位置矢量之差是否大于一个阈值,或者直接判断位置矢量是否超过一个范围,若是则采取相应的防丢线措施。 这部分的程序如下: voidrudder_control(void) { If(Dis_Error>60||Dis_Error<-60) Dis_Error=preDis_Error; preDis_Error=Dis_Error; rp.rudder_PWM=RUDDER_MID-rudder_P*error[9]-rudder_D*(error[9]-error[5]); if(rp.rudder_PWM>5370)rp.rudder_PWM=5370; if(rp.rudder_PWM<4570)rp.rudder_PWM=4570; LPLD_FTM_PWM_ChangeDuty(FTM3,//使用FTM3 FTM_Ch1,//使用Ch1通道 rp.rudder_PWM);//舵机占空比赋值 } 三、电机控制算法 1、目标速度设定 我们在这部分控制中进行速度的设定与控制,首先在速度的设定中我们以位置变化速率为依据,选一个速度设定依赖值trend(初始值为0),根据trend的值的范围选定不同的速度,当位置变化率比较小时,说明小车此时跑的赛道弯度不是很大或者在当前速度下小车跑的姿态很好,能跟得上轨迹的变化,此时小车可以尝试再加一点速度,则令trend++,而当位置变化率比较大并且超过了设置的阈值,说明小车此时遇到了大角度弯道或者小车自身速度太快了,已经不能随着轨迹的快速变化调整自己的位置,此时需要的是快速降速以便小车能够及时调整自己的位置,这时我们令trend=/2,这种增加降除的策略能够很好的适应加速平滑减速迅速的需要。 最后实时目标速度的设定可以根据现有的trend值得范围来确定,trend越大,设置的目标速度就越高。 接着我们还考虑到小车跑时的姿态问题,如果小车过弯时在弯道中间或靠近弯道外侧时,同样的速度下在同一时间内肯定没有切内弯跑得远,而且太靠近弯道外侧速度不容易提高,因为按照之前位置确定的计算方式下,当电感离中心线太远时,所采集到的电压值每变化1~2个单位,位置值则跳变10~20,这样按照我们目标速度设定方法,目标速度就不易提高,但若小车是切内道跑的,可以避免这个问题并且明显减少跑完一圈所用的时间。 要想切内道跑我们所采取的策略是在设置的目标速度上减去与小车位置有关的变量,小车离中心导线越远,在原来目标速度的基础上减的就越多,小车就能及时跟得上轨迹变化并且还能靠近弯的内道,当小车在弯内跑平稳了还可以加速。 目标速度设定的程序如下: voidtargetspeed(void)//目标速度设置函数 { standderror=ABS(error[9])-ABS(error[7]);//求位置变化率 if(standderror<=0.8&&trend<=50) trend++; elseif(standderror>1) { trend/=2; } if(trend>55)mp.targetspeed=1800-ABS(rp.rudder_PWM-RUDDER_MID)/40; elseif(trend>45)mp.targetspeed=1700-ABS(rp.rudder_PWM-RUDDER_MID)/50; elseif(trend>30)mp.targetspeed=1600-ABS(rp.rudder_PWM-RUDDER_MID)/60; elseif(trend>20)mp.targetspeed=1500-ABS(rp.rudder_PWM-RUDDER_MID)/70; elseif(trend>10)mp.targetspeed=1400-ABS(rp.rudder_PWM-RUDDER_MID)/80; elsemp.targetspeed=1400-ABS(rp.rudder_PWM-RUDDER_MID)/90; if(mp.targetspeed>1800)mp.targetspeed=1800; if(mp.targetspeed<1300)mp.targetspeed=1300; } 2、速度控制算法(增量式PD) 目标速度设置好后,还需要速度控制策略保证小车按照目标速度跑,由于车模自身有重量(惯性大)再加上摩擦力的影响,让小车严格按照目标速度跑肯定是做不到的,我们只能尽量控制让小车接近目标速度跑,将偏差限定的可接受范围内,速度控制算法还是采用PID控制,和之前舵机控制不一样,要想对速度进行相对及时且精准的控制,我们还需要测量小车的实时速度,与目标速度进行比较利用差值进行控制,形成闭环反馈控制。 这次我们采取增量式PD算法,增量式PD是由两个位置式PD相减的结果,它的结果只与上一次的结果有关,当小车速度有非正常跳变时,采用增量式可以降低这突变产生的影响。 增量式PID的表达式为: 由于小车要想跑得快且稳就需要有非常及时的加减速能力,要能在该减速的时候迅速降低速度,而且还不能减得太猛,使得小车有较大的停顿,减下来后要及时将速度加上去,因此应该有很好的加减速策略,在速度控制PD算法中已经拥有加减速的功能,但当反馈速度和目标速度相差太多时,减速不见得那么得心应手,总觉得减速的力度不够大,不能及时将速度减下来,为了克服这一弊端,我们在原来PD控制算法的基础上有添加了额外的控制算法,即bang-bang控制算法,我对bang-bang算法的理解是它是一个开关控制,每次走的都是两个极端,在速度偏差比较大时,我们输出更大的控制力度以求能够在短时间内达到目标速度,这种做法我的理解是虽然可能错失了最有效的控制时机,但通过大幅度的控制力度弥补了错过控制时机的缺陷,但是由于bang-bang算法控制粗糙,不容易实现较为精准的控制,在加上我们使用的B车模本身惯性比较大,若采用bang-bang算法虽然可以及时让小车减下速来,但是很容易让小车有停顿,最后我们果断放弃bang-bang控制算法,仍采用抓住控制时机的控制策略,增量式PD算法由于有微分控制,所以能够较为准确地抓住控制时机,缺点是控制力度不强,我们就在原来的表达式中加了一个权值,使其控制力度能够有效增加,最后我们有对这个权值进行变量化,让它和速度变化速率紧密相关,这样又进一步降低了小车停顿的可能性。 小车速度控制程序如下: voidPID(void) { if(mp.spdfeedback<5) mp.motorPWMlast=700; mp.speed_error=mp.targetspeed-mp.spdfeedback;//当前的速度差值=目标速度-当//前速度返回值 mp.motorPWM=mp.motorPWMlast+motor_P*(mp.speed_error-mp.speed_eerror)+\motor_I*mp.speed_error+motor_D*(mp.speed_error-2*mp.speed_eerror+\mp.speed_eeerror); if(mp.speed_error<0&&mp.speed_eerror<0) { if((mp.speed_error-mp.speed_eerror)>0&&trend1<=51) trend1++; elseif((mp.speed_error-mp.speed_eerror)<0) trend1/=2; } else trend1=0; if(trend1>=50)slow=0; elseif(trend1>=40)slow=0.11; elseif(trend1>=30)slow=0.13; elseif(trend1>=20)slow=0.15; elseif(trend1>=10)slow=0.17; elseslow=0.2; if(mp.motorPWM<0)mp.motorPWM=(1+slow)*mp.motorPWM; if(mp.motorPWM>10000)mp.motorPWM=10000; if(mp.motorPWM<-8000)mp.motorPWM=-8000; mp.speed_eeerror=mp.speed_eerror; mp.speed_eerror=mp.speed_error; mp.motorPWMlast=mp.motorPWM; } 三、坡道检测策略 以上算法基本上可以是小车能够在赛道上正常循迹行驶,但是为了提高难度,竞赛时的赛道并不是只有弯道和直道那么简单,还设置了坡道和环岛来提高难度,首先介绍一下坡道,设置坡道的目的就是考察我们的提线算法有没有普适性,事实证明我们的提线算法在坡道面前会有很大的影响,因为我们是靠电感感应到的磁感应强度来进行位置判断,当小车刚上坡道的时候,前瞻电感会离导线很近,这样电磁感应强度会变得很大,所计算到的水平距离会变小,此时车在赛道中央,水平距离本来就是零,没有影响,关键是上坡过程中电感会离导线很远,这样所感应到的磁感应强度会很小,这样计算出来的水平距离会很大,即使小车此时是在赛道中间,因此产生误判,导致小车大幅度拐弯,从坡道上翻下来,在坡道上时也有此现象。 要想在不改变原来提线方法的情况下解决这个问题,就只有识别坡道,当小车识别到坡道时,我们就限制他大幅度拐弯就行,所以解决坡道问题就变成识别坡道的问题了。 要想识别坡道,我们就得先分析坡道和普通赛道之间的明显区别,将这些区别因素加入判断坡道的依据,首先很容易可以想到当小车接近坡道的时候,所采集到的peak值会变得非常大,超出了在普通赛道采集到的peak范围,所以我们完全可以以此为依据进行坡道的识别,认为当小车电感采集到非常大的peak值时进入坡道,采取相应的防止大幅度拐弯的策略,但是小车过坡道是一个过程,在小车过坡道过程中peak值在接近坡道时变大,在上坡过程中减小,在坡道上行驶时peak值又非常小,到下坡过程中又是先增大后减小到正常值,所以下车在坡道行驶过程中peak值得曲线是有两个峰值的双抛物线,如果仅仅以peak值增大的某个瞬间为识别坡道的条件,则小车在整个过坡过程中会多次识别到坡道,致使我们的防拐弯策略失效,因此坡道检测应该贯穿于小车过坡的整个过程,也就是说坡道检测应分为上坡检测和下坡检测,检测方法也应该是通过peak之瞬间变化趋势和大小来分别判断上坡或者下坡,检测到上坡和下坡之间的时间内都认为在坡道上,首先当首次检测到peak值大于某个较大的值并且peak值处于上升阶段时认为是在上坡,随后当peak值小于某个值并且处于下降状态时,并不是小车下坡,而是小车接近坡顶,当再次出现peak值大于某个值并且上升,是小车刚开始下坡,最后当peak值下降并且小于某个值时才是小车下坡的标志,将这四个过程分别标记出来,只有过程一和过程四之间的时间是小车处于坡道上的时间,在这段时间内采取相应的坡道策略即可。 相应坡道识别和坡道策略的程序如下: voidsloped(void)//斜坡处理函数,分别将4个上升下降阶段用nn标记出来 { if(nn==0&&unity[2]>320&&unity[2]>pre_unity2) { nn=1; slope=1; } If(nn==1&&unity[2]<320&&unity[2] if(nn==2&&unity[2]>320&&unity[2]>pre_unity2)nn=3; if(nn==3&&unity[2]<320&&unity[2] if(nn==4) { slope=0; nn=0; } If(slope==1) { If(Dis_Error>20||Dis_Error<-20) Dis_Error=0; } } 四、环岛识别和处理 环岛是今年新增的一个赛道元素,本身是一个环形赛道,与普通赛道不一样的还有环岛内导线的电流大小是普通赛道的一半,环岛本身是一个有难度的弯道,而且环岛口和直赛道相接处又几乎是个直角弯,这很容易造成小车入环岛的时候减速不及时而冲出赛道,而且环岛内电流小弯度大,增加了环岛内行驶的困难,而且这样一来小车在环岛内基本上不能以较高的速度行驶。 如果我们对环岛不进行任何处理,很容易发生以下两种情况,一是进环岛时减速不及时而冲出环岛,二是环岛内提线不稳定而冲出赛道,因为环岛内电流比较小,导致计算出的水平距离变大,速度稍微一高提线就不连续,导致小车在环岛内左右晃动比较明显。 因此必须采取策略进行环岛处理。 我们环岛处理主要涉及两个方面,一是能识别环岛,以便于采用更强力的减速输出及时减下速来,二是在原来提线的基础上再做改进,将新提线用在环岛内以便适应电流小的情况。 首先是环岛识别,同样的道理,识别环岛便是找环岛和普通赛道之间的区别,主要区别有两个,一是形状是环形,二是电流小。 从形状入手,我们知道环岛口的赛道呈T型,我们设置的前排电感在环岛口检测到的磁感应强度是非常小的,这不是因为导线中的电流较小,而是方向问题,我们前排的电感是水平且横向放置的,这样当电感在环岛口上方时,穿过线圈的磁感线几乎为零,所以磁感应强度非常小,这是一个非常重要的依据,但是小车在过弯时也可能会出现这种状况,仅仅依靠这一不同点是不能完全区别出环岛,还应该加入其他依据共同区别,为此我们特意加入两个额外的电感,这两个电感水平放置在前瞻杆两端,但纵向放置,这样一来小车在直道行驶时这两个电感采集的磁感应强度会很小(原因同上),但在环岛口会变得很大,因为此时穿过线圈的磁感线非常多,这样一来我
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 智能 总结