飞思卡尔智能车课设.docx
《飞思卡尔智能车课设.docx》由会员分享,可在线阅读,更多相关《飞思卡尔智能车课设.docx(10页珍藏版)》请在冰豆网上搜索。
![飞思卡尔智能车课设.docx](https://file1.bdocx.com/fileroot1/2022-10/11/3ff807f8-d1f3-483e-b34a-1e1d9fe5ed9a/3ff807f8-d1f3-483e-b34a-1e1d9fe5ed9a1.gif)
飞思卡尔智能车课设
意义及任务
两轮自平衡机器人的研究领域,美国、日本和瑞士等国家研究得较多,而且己经达到了一个很高的水平,国内的研究相对还比较少。
我国在两轮自平衡机器人方面的研究也取得了一定的成就:
西安电子科技大学研究出了自平衡两轮机器人,它是一种两轮式左右并行布置结构的自平衡系统。
它利用伺服放大器ADS作为控制器,选择两个Maxson电机作为执行元件,采用自适应神经模糊控制器对小车这一非线性对象进行大范围控制,从而实现系统的自平衡。
哈尔滨工业大学也有类似的双轮直立自平衡机器人,该系统采用DSP作为控制核心。
车体倾斜角度检测采用加速度传感器和陀螺仪。
利用PWM技术动态控制两台直流电机的转速。
基于这些完备而可靠的硬件设计,使用了一套独特的软件算法,实现了该系统的平衡控制。
受教育部高等教育司委托,高等学校自动化专业教学指导委员会负责主办全国大学生智能车竞赛。
该项比赛已列入教育部主办的全国五大竞赛之一。
首届“飞思卡尔”杯全国大学生智能车邀请赛于2006年在清华大学成功举办。
此项赛事,在韩国已举办过多届,其专业知识涉及控制、模式识别、传感技术、汽车电子、电气、计算机、机械等诸多学科,对学生的知识融合和动手能力的培养,对高等学校控制及汽车电子学科学术水平的提高,具有良好的推动作用。
飞思卡尔智能车比赛从第七届开始使用自平衡智能车,第七届在电磁组用直立车模,第八届开始在光电组使用直立车模。
需求分析
本项目要实现的功能有:
1.车模保持平稳直立,并且能够向前和向后运动
分析:
用陀螺仪和加速度传感器所得到的信号相互融合即可获取小车的倾角状态值;用编码器获取车轮的转速信号;将这些数据相互融合,运用控制工程的原理对小车进行控制。
2.蓝牙控制
分析:
使用蓝牙串口模块发射指令对小车的转向和速度进行控制。
软件部分
开发软件主要任务包括:
(1)建立软件工程,配置K60单片机资源,初步编写程序的主框架;
(2)编写上位机监控软件,建立软件编译、下载、调试的环境;
(3)编写实现各个子模块,并测试各个子模块的功能正确性;
(4)通过程序初步调试,验证控制电路板的正确性。
软件的主要功能包括有:
(1)各传感器信号的采集、处理;
(2)电机PWM输出;
(3)车模运行控制:
直立控制、速度控制、方向控制;
(4)车模运行流程控制:
程序初始化、车模启动与结束、车模状态监控;
(5)车模信息显示与参数设定:
状态显示、上位机监控、参数设定等。
程序框图
控制方案框图
重点程序段代码的分析
1.角度控制
voidangle(void)
{
Adc0_Result=adc_get_ave(ADC0,16,30); //取得ADC0_SE16引脚AD值——陀螺仪角速度
Adc1_Result=adc_get_ave(ADC1,16,60); //取得ADC1_SE16引脚AD值——加速度计角度
data1=Normalized_U8(Adc0_Result);
data2=Normalized_U8(Adc1_Result);
k=0.008; //角度调整时间3秒 5毫秒中断
w=(3.3*(data1-w_0)/255.0)/0.67; //将角速度AD值转化为角速度deg/s
//a=(3.3*data2/255.0-1.65)/0.8; //将加速度AD值转化为g
angle_g=1.5*(data2-angle_mid); //将Z轴方向的加速度转化为角度
derta=k*(angle_g-angle_get); //将实际角度与积分角度做差
angle_get+=-w*4+derta; //积分角度
/*
data3=(int8)(angle+100); //data3用于把积分角度反映到上位机
data4=(int8)(value/10+120); //data4用于把飘移偏差反映到上位机
data5=(int8)(angle_g+100); //data5用于把重力角度反映到上位机
*/
p=100; //比例因子 p=80&d=1.0
d=1.5; //微分因子
value_ang=(angle_set-angle_get)*p-(w_set-w*1000)*d;
if(value_ang>1000)
value_ang=1000;
if(value_ang<-1000)
value_ang=-1000;
}
2.速度控制
voidspeed()
{
if(sp_cnt==0)
{
Speed_set=60;
Speed_get=k_spd*(GetFreq1+GetFreq2)/2; //得到平均脉冲值,转换为速度
if(Pulse_dir==1) //前进
{dif_spd=Speed_get-Speed_set; //求速度偏差,以逼近设定值
LPLD_GPIO_Set_b(PTA,6,OUTPUT_L);
if(dif_spd<-20)
{dif_spd=dif_spd/5;}
else
dif_spd=dif_spd/1.2;
}
else //后退
{dif_spd=-Speed_get-Speed_set;
LPLD_GPIO_Set_b(PTA,6,OUTPUT_H);
if(dif_spd<-20)
{dif_spd=dif_spd/5;}
else
dif_spd=dif_spd/1.2;
}
dif_P=dif_spd*P_spd; //比例项
dif_I=dif_spd*I_spd; //微分项
Speed_I+=dif_I;
{if(Speed_I>600)
Speed_I=600;
if(Speed_I<-600)
Speed_I=-600;}
Speed_old=Speed_new;
Speed_new=dif_P+Speed_I; //比例微分后的速度值
fValue=Speed_new-Speed_old; //速度控制平滑要些
}
elseif(sp_cnt==1)
{
//temp1=GetFreq1;
//GetFreq1=(LPLD_LPTMR_GetPulseAcc()+temp1)/2;
GetFreq1=LPLD_LPTMR_GetPulseAcc();
LPLD_LPTMR_Reset();
LPLD_LPTMR_Init(MODE_PLACC,0,LPTMR_ALT2,IRQ_DISABLE,NULL);
}
elseif(sp_cnt==2)
{
//LPLD_GPIO_Set_b(PTA,4,OUTPUT_L); //空闲状态
Pulse_dir=LPLD_GPIO_Get_b(PTC,2);
}
else
{
//temp2=GetFreq2;
//GetFreq2=(LPLD_LPTMR_GetPulseAcc()+temp2)/2;
GetFreq2=LPLD_LPTMR_GetPulseAcc();
LPLD_LPTMR_Reset();
LPLD_LPTMR_Init(MODE_PLACC,0,LPTMR_ALT1,IRQ_DISABLE,NULL);
}
value_spd=fValue*(sp_cnt+1)/4+Speed_old;//把速度均分到4个5ms脉冲周期内
if(value_spd>1000)
value_spd=1000;
if(value_spd<-1000)
value_spd=-1000;
sp_cnt++;
if(sp_cnt>=4)
sp_cnt=0;
}
3.方向控制
voiddirection(void)
{
if(dir_cnt==0) //进行方向控制
{
w_data=Normalized_U8(adc_get_ave(ADC1,23,30));
w_dir=(3.3*(w_d0-w_data)/255.0)/0.67;
Dir_old=Dir_new;
total=-total_l-total_r;
//Speed_set=20+16*total/64;
//Speed_set=20-0.01*abs((int)(total));
//Speed_set=40;
//{if(max_tsh//Speed_set=-20;}
Dir_new=P_dir*total+D_dir*w_dir;
dValue=Dir_new-Dir_old;
}
elseif(dir_cnt==1) //进行偏差计算:
动态阈值+二值化算法
{
Data_tsh=max_tsh=min_tsh=pixel[0];
for(inti=0;i<128;++i)
{
{
if(max_tshmax_tsh=pixel[i];
if(pixel[i]min_tsh=pixel[i];
}
if(pixel[i]>threshold)
{
pix[i]=1;
}
else
{
pix[i]=0;
}
Data_tsh=(Data_tsh+pixel[i])/2;
}
}
elseif(dir_cnt==2) //进行总偏差计算,同时进行余弦化滤波处理
{
total_l=0;
for(inti=0;i<64;++i)
{
//total_l+=pix[i]*(cos[i]/2+0.5);
total_l+=pix[i];
}
}
elseif(dir_cnt==3)
{
total_r=0;
for(inti=64;i<128;++i)
{
//total_r+=-pix[i]*(cos[i]/2+0.5);
total_r+=-pix[i];
}
}
elseif(dir_cnt==4)
{
if(put_char==0)
{
LPLD_UART_PutChar(UART5,0xFF);
for(inti=0;i<64;++i)
{
if(pixel[i]==0xFF) pixel[i]=0xFE; LPLD_UART_PutChar(UART5,