智能车源程序+很详细 增强版Word下载.docx
《智能车源程序+很详细 增强版Word下载.docx》由会员分享,可在线阅读,更多相关《智能车源程序+很详细 增强版Word下载.docx(28页珍藏版)》请在冰豆网上搜索。
为了能使智能车系统能正常工作,就需要对电池电压调节。
其中,单片机系统、车速传感器电路需要5V电压,路径识别的光电传感器和接收器电路电压工作为5V、伺服电机工作电压范围4.8V到6V(或直接由电池提供),直流电机可以使用7.2V2000mAhNi-cd蓄电池直接供电。
考虑到由于驱动电机引起的电压瞬间下降的现象,因此采用低压降的三端稳压器成为必然。
我们在采用lm7805,和lm7806作为稳牙芯片。
经试验电压纹波小,完全可以满足要求。
电池(7.2v)2000mAhNi-cd
5V
6V
7.2V
测速板Encoder
图4.1系统电压调节图
图4.27805电路图
图4.3电源模块示意图
4.2电机驱动电路
电机驱动使用飞思卡尔专用电机驱动芯片MC33886。
驱动电路如图4.4所示。
为了增大驱动能力,减少单片发热量,电路采用两片MC33886并联的方案。
系统使用PWM控制电机转速,充分利用单片机的PWM模块资源。
电机PWM频率设定为8KHz。
MC33886芯片的工作电压为5-40V,导通电阻为140毫欧姆,PWM频率小于10KHz,具有短路保护、欠压保护、过温保护等功能。
电机驱动芯片安装在制作的电机驱动PCB板上,在PCB板设计时,考虑到芯片散热问题,在芯片腹部设计了方型的通孔,实际运行效果表明芯片散热均匀,设计合理。
为了防止电动机突然停止时产生的电磁干扰,在电动机的两端焊接了一个0.1μF滤波电容。
图4.4两片MC33886并联使用
图4.5两片MC33886并联使用的实物图
在图中可以看到,我们使用PWM23和PWM45作为电机驱动PWM信号,两个PWM通道级联可以使其输出更加精确。
在程序中,我们把PWM值直接转换成了以米/秒为单位的绝对速度,这样使智能车的速度更加直观切易于调试。
4.3测速电路
由于考虑到成本需要,我们采用了红外对管和黑白码盘作为测速模块的硬件构成。
其中码盘为32格的黑白相间圆盘,如下图所示:
图4.5码盘
红外传感器安装在正对码盘的前方,虽然这样做精度比编码器要低很多,但是成本低廉制作容易,如果智能车速度较快,可以考虑再减少码盘上黑白色条的数量即可。
当圆盘随着齿轮转动时,光电管接收到的反射光强弱交替变化,由此可以得到一系列高低电脉冲。
设置9S12的ECT模块,同时捕捉光电管输出的电脉冲的上升沿和下降沿。
通过累计一定时间内的脉冲数,或者记录相邻脉冲的间隔时间,可以得到和速度等价的参数值。
测速电路使用自行研制的红外反射式光电测速传感器。
速度测量电路使用红外反射式光电对管RPR220,自行制作的编码盘,比较电路等组成。
图4.6测速电路
速度测量电路图2.8所示。
红外反射式光电对管的光敏三极管信号通过比较器处理后输入单片机的计数器模块,利用单片机的输入捕捉功能,处理智能车速度信息。
自制的编码盘有24道黑色条纹,电机旋转一周将产生24次输入捕捉中断。
单片机记录两次中断的时间间隔T。
两次中断对应于智能车前进的距离S为:
16.5/24cm,即0.6875cm,其中16.5cm为智能车后轮实测周长[7]。
智能车实时速度V(cm/s)的计算公式如下:
4.4红外对管检测电路
由于我们采用了大功率对管,所以红外对管的电路是整个电路中要求最高的,不紧要保证对管正常工作,而且还要考虑整个电路的能耗和发热问题。
经测试我们发现单个对管在通以100mA到170mA电流时可以。
保证抬高20到30厘米的距离。
此时每个对管的管压降为1.2到1.5伏。
为了进一步加大发光量,我们采用了双发射管的办法,即一个接受管对应两个发射管。
为了降低整体的能耗。
我们让同一对的发射管串联,14对发射管再并联。
同时使用了irf540进行开关控制。
控制对管脉冲发光。
开关频率为200HZ。
这样既保证了大前瞻探测的需要,又降低了整体的能耗和对电源的冲击
图4.7先串联再并联的脉冲发光对管电路图。
图4.8对管实物图反面
图4.9对管实物图正面
4.5拨码开关电路
由于在智能车比赛开始后,不能够对智能车硬件及软件进行修改,在保证了硬件有效可靠的同时,软件有可能不能够适应新场地,所以设计拨码开关对智能车有关参数进行设置也是必要的。
拨码开关电路如下图所示:
图4.9拨码开关
这是一个八段的拨码开关,我们把它成成上下连个部分,显然,每个部分都有16种状态,前四个来改变舵机参数,后四个改变直流电机参数,这样对于适应新的场地很有好处。
5.1路径搜索算法
对于本控制系统采用14对光电对管的方案,单排排列在车体头部10cm处。
编号为6、7的光电对管处于正中央位置。
利用14对传感器进行道路识别。
传感器对白色的反射率比黑色的大。
单片机ADC读入值相应也大。
在程序中对传感器信号进行处理,判断传感器是否检测到黑色引导线。
将单个传感器对白色和黑色路面的ADC值之差分为平均的两段,每次处理实时传感器信号时,判断本次采样的ADC值与黑色路面ADC值之差落在两段中的哪一段。
如果在靠近黑色的一段,则判定该传感器检测到黑线,将该传感器对应的变量置为判定值1;
如果在靠近白色的一段,则判定该传感器检测到白线,将该传感器对应的变量置为判定值1;
为了增强判断的准确性,在对ADC值采样时,采用了中值滤波方法,以去除瞬间的干扰。
路径检测完后,将测的的路径值暂时存储,然后将路径信息传递给舵机和电机控制部分,以选择给定合适的转角和速度。
5.2舵机、电机的控制
智能车的舵机和电机都采用了经典的PID控制方法。
但是由于舵机和电机性能的不同要求,分别对其进行了不同的修改。
PID控制器由比例单元(P)、积分单元(I)和微分单元(D)组成。
其输入e(t)与输出u(t)的关系为
式中积分的上下限分别是0和t
因此它的传递函数为:
G(s)=U(s)/E(s)=kp(1+1/(TI*s)+TD*s)
其中kp为比例系数;
TI为积分时间常数;
TD为微分时间常数
比例KP用来控制当前,误差值和一个负常数P(表示比例)相乘,然后和预定的值相加。
P只是在控制器的输出和系统的误差成比例的时候成立,KP能够快速的跟随变化量。
及时的产生与之相关的调节作用。
但是KP是有差调节,无法消除静态误差。
积分KI来控制过去,误差值是过去一段时间的误差和,然后乘以一个负常数I,然后和预定值相加。
I从过去的平均误差值来找到系统的输出结果和预定值的平均误差。
一个简单的比例系统会振荡,会在预定值的附近来回变化,因为系统无法消除多余的纠正。
通过加上一个负的平均误差比例值,平均的系统误差值就会总是减少。
所以,最终这个PID回路系统会在预定值定下来。
微分KD来控制将来,计算误差的一阶导,并和一个负常数D相乘,最后和预定值相加。
这个导数的控制会对系统的改变作出反应。
导数的结果越大,那么控制系统就对输出结果作出更快速的反应。
这个D参数也是PID被成为可预测的控制器的原因。
D参数对减少控制器短期的改变很有帮助。
一些实际中的速度缓慢的系统可以不需要D参数。
舵机PID
由于舵机是一个具有大的延迟的执行机构,所以在PID控制中不能加入积分环节。
否则会导致小车震荡。
所以小车采用PD控制。
同时加入一个一阶惯性环节,构成不完全微分,给小车一个超前的调节。
实际使用中,为了减少计算时间,将位置式PID转化为增量式
增量式PID公式:
电机PID控制
小车行使过程中,随着跑道的不同,需要配合不同的速度值,因此对电机的PID是一个给定值不断变化的PID。
小车的目标速度(Object_Speed)给定规则:
1》小车在直道上,Object_Speed为最大值200。
2》小车在大弯道上,Object_Speed为160。
3》小车在小弯道或S型弯道上,Object_Speed为120
4》小车冲出跑道,Object_Speed为70。
5》小车由直道进入弯道,Object_Speed逐渐减小。
6》小车由弯道进入直道,Object_Speed逐渐加大。
在实验中发现,PID的超调量主要在第一个波形中起作用,也即单速度由很大到很小的时候,或由低速突然加到高速的过程中,会出现很大的超调。
但是这个超调并不是有害的,因为,当速度要求突变的时候,往往是小车由直道入弯道,或者由弯道入直道的过程,这个过程往往需要很快的大加减速,而由于小车的惯性,一般的PID调节难以满足要求,这时使用大的超调量可以使小车有一个加速或刹车的过程,使之更好的达到要求速度。
6.1Codewarrior开发环境
在整个开发调试过程中,使用Metrowerks公司为MC9S12系列专门提供的全套开发工具(FreescaleCodewarriorIDE4.6)。
这是一套用C语言进行编程的集成开发环境——本文智能车定位系统的软件设计部分就是在此开发环境下完成的。
Codewarrior是由Metrowerks公司提供的专门面向Freescale所有MCU与DSP嵌入式应用开发的软件工具。
其中包括集成开发环境IDE、处理器专家、全芯片仿真、可视化参数显示工具、项目工程管理、C交叉编译器、汇编器、链接器以及调试器。
CodeWarriorIDE能够自动地检查代码中的明显错误,它通过一个集成的调试器和编辑器来扫描你的代码,以找到并减少明显的错误,然后编译并链接程序以便计算机能够理解并执行你的程序。
每个应用程序都经过了使用象CodeWorrior这样的开发工具进行编码、编译、编辑、链接和调试的过程。
MetrowerksCodewarriorIDE中的mc9s12dg128.h文件对所有寄存器对应的存储映射地址都
进行了宏定义,开发者在软件开发时直接调用这些宏就可以了。
6.2软件仿真
为了更好的定量分析影响小车行驶的各个因素,而且最大限度的节约时间和成本。
我们采用了软件仿真和实际调试相结合的办法。
仿真软件使用了清华的PLAST2。
通过仿真,我们发现:
1、小车传感器的探测距离对速度有着决定的影响。
所以传感器应该尽量的探测更远。
但是传感器的探测距离不能超过最小转弯的半径。
否则会出现盲区。
2、适度增加舵机的灵敏度,可以使转弯更加灵活。
所以我们在实际调试中,加长了舵机的力臂。
6.2实际调试
实际调试过程中,我们发现小车在直道上会出现左右抖动的现象,通过软件设置死区或其他处理方法,效果都不是很明显,最后发现小车舵机和前轮的间隙是罪魁祸首,通过把前轮设置为内八形,完美的解决了这个问题。
在调试过程中,我们加了液晶显示,还设置了蜂鸣器,这些辅助设备在比赛中为了减轻小车的重量,都是不需要的。
但是在调试过程中,通过这些设备,可以及时的了解小车运行的情况,达到事倍功半的效果。
表7.1模型车技术参数统计:
项目
参数
路径检测方法(赛题组)
光电组
车模几何尺寸(长、宽、高)(毫米)
385*220*60
车模轴距/轮距(毫米)
200/150
车模平均电流(匀速行驶)(毫安)
200
电路电容总量(微法)
430
传感器种类及个数
红外对管15个
新增加伺服电机个数
0
赛道信息检测空间精度(毫米)
9
赛道信息检测频率(次/秒)
200
主要集成电路种类/数量
9s12单片机最小系统/133886电机驱动电路/4
速度检测电路/1
车模重量(带有电池)(千克)
0.9
参考文献
[1]黄开胜、金华民、蒋狄南,韩国智能模型车技术方案分析,北京:
清华大学汽车安全与节能国家重点实验室,2004.3
[2]邵贝贝著,单片机嵌入式应用的在线开发方法,北京:
清华大学出版社,2004.2
[3]‘LM2940datasheet’,July2000,NationalSemiconductor
[4]‘LM7806datasheet’NationalSemiconductor
[5]‘RPR220datasheet’,ROHM
[6]'
SemiconductorTechnicalDataMC33887'
Aug2002MotorolaInc
[7]大赛车模拼装手册
[8]CodeWarriorIDE3.1helpdatasheet
[9]'
MC9S12DG128DeviceUserGuide'
October2002MotorolaInc
[10]'
HCS12COREdatasheet'
Augt2000MotorolaInc
[11]'
S12PWM8B8CV1datasheet'
Mar2002MotorolaInc
[12]'
S12ATD10B8CV2datasheet'
Augt2002MotorolaInc
[13]'
S12ECT16B8V1datasheet'
July2002MotorolaInc
[14]
[15]
[16]
程序
电机PID控制程序
typedefunsignedcharBOOL;
typedefunsignedcharINT8U;
//无符号8位数
typedefsignedcharINT8S;
//有符号8位数
typedefunsignedintINT16U;
//无符号16位数
typedefsignedintINT16S;
//有符号16位数
typedefunsignedlongINT32U;
//无符号32位数
typedefsignedlongINT32S;
//有符号32位数
typedeffloatFP32;
//单精度浮点数
typedefdoubleFP64;
//双精度浮点数
#defineMAX_32(signedlong)0x7fffffffL
#defineMIN_32(signedlong)0x80000000L
#defineMAX_16(signedint)0x7fff
#defineMIN_16(signedint)0x8000
typedefstruct
{
signedintProportionalGain;
signedintProportionalGainScale;
signedintIntegralGain;
signedintIntegralGainScale;
signedintDerivativeGain;
signedintDerivativeGainScale;
signedintPositivePIDLimit;
signedintNegativePIDLimit;
signedintIntegralPortionK_1;
signedintInputErrorK_1;
}sCaiXinBoPID;
sCaiXinBoPIDSpdPID;
externsignedintCaiXinBoPIDController(signedintDesiredValue,signedintMeasuredValue,sCaiXinBoPID*pParams);
staticsignedlongL_sub(registersignedlongsrc_dst,registersignedlongsrc2)
return(src2-src_dst);
}
staticsignedlongL_deposit_l(registersignedintssrc)
return(signedlong)(ssrc);
staticsignedintextract_l(registersignedlonglsrc)
return(signedint)lsrc;
staticsignedlongL_mult(registersignedintsinp1,registersignedintsinp2)
registersignedlonglaccum;
laccum=sinp1;
laccum*=sinp2;
returnlaccum;
staticsignedlongL_add(registersignedlongsrc_dst,registersignedlongsrc2)
return(src_dst+src2);
signedintCaiXinBoPIDController(signedintDesiredValue,signedintMeasuredValue,sCaiXinBoPID*pParams)
signedlongProportionalPortion,IntegralPortion,PIDoutput;
signedintInputError;
/*-------------------------------------------------------------------------------------------------*/
/*Saturationmodemustbeset*/
/*InputError=sub(DesiredValue,MeasuredValue);
*//*inputerror*/
/*inputerrorcalculation-16bitrange,withandwithoutsaturationmode*/
PIDoutput=L_sub(L_deposit_l(DesiredValue),L_deposit_l(MeasuredValue));
/*inputerror-32bitrange*/
if(PIDoutput>
MAX_16)/*inpurerrorisgreaterthan0x00007fff=32767-32bitrange*/
InputError=MAX_16;
/*inputerror=max.positive16bitsignedvalue*/
else
if(PIDoutput<
MIN_16)/*inputerrorislessthan0xffff7fff=-32768-32bitrange*/
InputError=MIN_16;
/*inputerror=min.negative16bitsignedvalue*/
InputError=extract_l(PIDoutput);
/*inputerror-16bitrange*/
/*proportionalportioncalculation*/
ProportionalPortion=L_mult((pParams->
ProportionalGain),InputError)>
>
(pParams->
ProportionalGainScale+1);
/*integralportioncalculation*/
IntegralPortion=L_mult((pParams->
IntegralGain),InputError)>
(pParams->
IntegralGainScale+1);
/*integralportioninstepk+integralportioninstepk-1*/
IntegralPortion=L_add(IntegralPortion,L_deposit_l(pParams->
IntegralPortionK_1));
/*integral