电子设计大赛四旋翼设计报告最终版
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
四旋翼飞行器〔A 题〕
参赛队号:20140057号
四旋翼飞行器
设计摘要:
四旋翼作为一种具有构造特殊的旋转翼无人飞行器,与固定翼无人机相比,它具有体积小,垂直起降,具有很强的机动性,负载能力强,能快速、灵活的在各个方向进展机动,构造简单,易于控制,且能执行各种特殊、危险任务等特点。
因此在军用和民用领域具有广泛的应用前景如低空侦察、灾害现场监视与救援等。
多旋翼无人机飞行原理上比拟简单,但涉及的科技领域比拟广,从机体的优化设计、传感器算法、软件及控制系统的设计都需要高科技的支持。
四旋翼无人机的飞行控制技术是无人机研究的重点之一。
它使用直接力矩,实现六自由度〔位置与姿态〕控制,具有多变量、非线性、强耦合和干扰敏感的特性。
此外,由于飞行过程中,微型飞行器同时受到多种物理效应的作用,还很容易受到气流等外部环境的干扰,模型准确性和传感器精度也将对控制器性能产生影响,这些都使得飞行控制系统的设计变得非常困难。
因此,研究既能准确控制飞行姿态,又具有较强抗干扰和环境自适应能力的姿态控制器是微小型四旋翼飞行器飞行控制系统研究的当务之急。
一、引言:
1.1 题目理解:四旋翼飞行器,顾名思义,其四只旋转的翅膀为飞行的动力来源。
四只旋转翼是无刷电机,因此对于无刷电机的控制调速系统对飞行器的飞行性能起着决定性的作用。
在本次大赛中,需要利用四旋翼飞行器平台,实现四旋翼的起飞,悬停,姿态控制,以及四旋翼和地面之间的测距等功能。
以往做的核心板较大,所需的电路较多,考虑到四轴飞行器的轻便,故而不太是一个很理想的选择。
方案二:主控板使用STM32。
STM32板子的I/O口很多,自带定时器和多路PWM,可以实现的功能较多,符合实验要求。
Stm32迷你板在体积和重量上也不是很大,对飞机的载重量要求不是很高。
综上所述,我们一致决定使用STM32 MMC10作为此次大学生电子竞赛的主控板。
2.2 飞行姿态的方案论证:
方案一:十字飞行方式。
四轴的四个电机以十字的方式排列,*轴和y轴成直角,调整俯仰角和翻滚角的时候分开调整,角度融合简单,适合初学者,能明确头尾,飞行时机体动作精准,飞控起来也容易。
方案二: *行飞行方式。
四轴的四个电机以*字的方式排列,灵活性和可调性较高,调整的时候应该相邻两个融合调节,融合复杂。
*型飞行方式非常自由灵活,旋转方式多样,可以把戏飞行,也可以做出很多高难度动作,但是控制上相比照拟困难。
综合以上两种方案鉴于我们是初次尝试,所以选择了方案一。
2.3 角度测量模块方案论证
方案一:光纤陀螺仪。
光纤陀螺仪是以光导纤维线圈为根底的敏感元件,由激光二极管发射出的光线朝两个方向沿光导纤维传播。
光传播路径的变化,决定了敏感元件的角位移。
光纤陀螺仪寿命长,动态围大,瞬时启动,构造简单,尺寸小,重量轻,但是本钱较高,鉴于我们这是初次尝试,需要屡次实验,破坏较大。
方案二: MPU6050三轴陀螺仪。
MPU6050三轴陀螺仪就是可以在同一时间测量三个不同方向的加速度、角速度、角度。
单轴的话,就只可以测定一个方向的量,则一个三轴陀螺就可以代替三个单轴陀螺。
它现在已经成为激光陀螺的开展趋向,具有可靠性很好、构造简单不复杂、重量很轻和体积很小等等特点,但是其输出数据需要大量的浮点预算才能保证较高的精度,这样会影响主控板对最终的姿态控制的响应速率。
综合以上两种方案,我们选择了方案二
2.4 飞行器距地距离显示的方案论证:
方案一:选用LCD液晶显示:LCD液晶显示在显示效果上较丰富,可以显示字母,数字等等需求,但在我们实际编写的时候发现驱动代码稍显复杂,显示效果在实际光线较亮的时候外界不容易清晰的看到LCD显示的容,尤其是当四轴飞行器在实际飞行的过程中,显示效果并不理想。
方案二:选用LED数码管显示:实际的观察中,发现数码管的显示比拟单一,但显示容清晰可识别,实际使用中对系统的占用资源也比拟少。
考虑比赛要求只要求看到实际的显示效果,因而我们决定使用数码管来显示四轴飞行器距离地面的距离。
2.5 确定方案之后,针对题目要求,最终编写出适宜算法,进展控制。
程序流程图如下〔图2.1〕:
图2.1
2.6 程序局部核心代码见附录二
三、设计实现:
3.1 超声波测距模块:
由于竞赛要求需要四轴飞行器悬停在一个距离,因而在我们做的过程中,选用超声波传感器用于测量四轴飞行器距离地面的距离,测量误差实际保证在1cm一下,根本做到准确测量,在写超声波模块的
驱动时,开场我们只想通过在程序中写一个无限循环的延时程序来测量超声波往返的时间,这种方法在开场单步调试测距的时候表现正常,可以读到正确数据,但在单片机中参加中断优先级的程序时这种方法就不能胜任了。
最后经我们小组讨论决定利用单片机的pit中断实现超声波模块的测量往返时延,测量准确。
实验效果较好。
3.2 显示报告飞行高度:
在我们的方案设计中小队决定使用数码管来显示四轴飞行器距离地面的高度,在我们做的过程中首先要解决的问题就是选用静态显示还是动态显示的问题,开场因为想的比拟简单就想单纯的用I/O口置高与置低电平来控制LED数码管的亮暗,发现如果4位数码管显示的话所用到的I/O口就需要4*8=32个IO口,这对单片机有限的引脚来说是一个巨大的负担,在查找资料与请教教师后我们找到一种动态显示数码管的方法很好的解决了这个问题,所需引脚仅仅用11个,实际测试中,显示效果很好。
四、测试:
4.1 硬件测试:将四旋翼模型拆解,然后用物理法测量中心,使其重心维持在四轴飞行器的中心。
然后按顺序将电池,主控板,陀螺仪等机械硬件使其结实的装在模型飞机上。
硬件测试使用了万能角度尺、示波器、万用表、压线钳、电量测量仪等。
4.2 软件测试:为了保证PWM波输出的正确性,每次改动程序初始化之
后用示波器测试波形的输出,保证其占空比和周期的正确性。
在正式算法程序之前,又用串口显示每个电机PWM输入,观察电机在各个PWM占空比的电机转速。
确保软件反响硬件是规律一致的。
软件测试最关键的是PID的参数调试,其中,p参数是调整整个四旋翼飞行器的反响速度和力度的,调节p参数以当整个模块反响迅速并且四旋翼振动频率四边偏差不大的时候即可完成,d参数在这之中的目的是一个抑制作用,当振荡幅度过大的时候能从任意角度一次直接返回平衡位置。
I参数是一个积分项,当哪一边反响过小时可以加一个i参数,这样就成了一个完整的PID参数调试了。
4.3 硬件软件联合测试:此步主要通过在STM32平台下进展编程,进展一系列的算法设计与调校,确认四旋翼飞行器是否能够飞行,通过大量的测试与实践,找出能刚刚使飞行器的电机占空比〔PWM〕值,当然,这一步可以通过联合超声波距离传感器设计一个动态PID调节,具体的调节方法依据能反响姿态的传感器联合作用。
五、完成情况:
在本小组所有队员这几天的努力调试下,本次完成情况如下,飞行器能够垂直起飞,起飞后能在50cm出悬停5s以上,然后飞行器可以继续垂直上升至100cm出,能悬停5s以上,在平稳回到原地的过程中,因为没有其他的传感器给飞行器提供路径的识别,所以回到原地的过程中,一切只能依靠软件与经历来模拟,故实际使用中发现做到这一步误差存在,在飞行器起飞至50~100cm 的高度上,悬停5s以后,然后水平飞行200cm,这一步也是由于没有具体的识别方法,依靠软件实际测试得出的规律来确定200cm的大致飞行时间与速度,因而依然存在误差。
由于我们把数码管和超声波做好,因而显示飞行器距地距离
很顺利。
总体比赛容大致完成。
六、总结:
本次参加电子设计大赛,我们将以往的一些经历杂糅成新,深刻认识到软硬件结合的重要性。
四旋翼的完成,硬件是根底,只有在能灵活熟练地使用硬件,才能更加方便的编写质量好的软件。
另外一个不可无视的问题便是方案的选取。
一个工程的完成可能会有很多种方案,而且不同方案在实现之前不可预知其好坏以及是否适合本工程的完成,这就衍生出更多的实践测试,工程的完成不可一蹴而就,认真对待,在摸爬滚打中可积累更多的经历。
另外,基于软硬件的工程,其机械性能也会有不可小觑的影响。
起初我队在搭建机械的时候无视了四旋翼的重心,认为机械重心的廉价可通过算法的自我调控来调节,事实证明,这种想法是错误的,好的机械性能更有利于算法的实现,机械搭建的好,便更容易调试软件。
在完成的过程中,我队深刻意识到在嵌入式的开发过程中,对软件质量的要求很高,所以在实际的编写过程中,优异的代码与思想或许尤为重要,而我们在这方面还多有缺乏,在此过程中,我们因为传感器的缺乏,有些想法不能做,但也正是缺少直接的东西,让我们可以很好的发现其他的解决方法,以后还需努力。
附录一:
附录二:〔局部核心代码〕
/******************超声波模块**************************************/
int csb(void){
int d=0;
PTT_PTT5 = 1;
delayus(10);
PTT_PTT5 = 0;
while(PTIT_PTIT3!=1);
count=0;
while(PTIT_PTIT3==1);
d=count*17/10;
return d;
}
/******************数码管显示模块**************************************/ void show123(*){
if(*==0){
PORTA_PA1 = up;
PORTA_PA2 = up;
PORTA_PA3 = up;
PORTA_PA4 = up;
PORTA_PA5 = up;
PORTA_PA6 = up;
PORTA_PA7 = down;
}else if(*==1){
PORTA_PA1 = down;
PORTA_PA2 = up;
PORTA_PA3 = up;
PORTA_PA4 = down; PORTA_PA5 = down; PORTA_PA6 = down; PORTA_PA7 = down; }
else if(*==2){
PORTA_PA1 = up; PORTA_PA2 = up; PORTA_PA3 = down; PORTA_PA4 = up; PORTA_PA5 = up; PORTA_PA6 = down; PORTA_PA7 = up; }
else if(*==3){
PORTA_PA1 = up; PORTA_PA2 = up; PORTA_PA3 = up; PORTA_PA4 = up; PORTA_PA5 = down; PORTA_PA6 = down; PORTA_PA7 = up;
}
else if(*==4){
PORTA_PA1 = down; PORTA_PA2 = up; PORTA_PA3 = up; PORTA_PA4 = down; PORTA_PA5 = down; PORTA_PA6 = up; PORTA_PA7 = up; }
else if(*==5){
PORTA_PA1 = up; PORTA_PA2 = down; PORTA_PA3 = up; PORTA_PA4 = up; PORTA_PA5 = down; PORTA_PA6 = up; PORTA_PA7 = up; }
else if(*==6){
PORTA_PA1 = up; PORTA_PA2 = down;
PORTA_PA3 = up; PORTA_PA4 = up; PORTA_PA5 = up; PORTA_PA6 = up; PORTA_PA7 = up; }
else if(*==7){
PORTA_PA1 = up; PORTA_PA2 = up; PORTA_PA3 = up; PORTA_PA4 = down; PORTA_PA5 = down; PORTA_PA6 = down; PORTA_PA7 = down; }
else if(*==8){
PORTA_PA1 = up; PORTA_PA2 = up; PORTA_PA3 = up; PORTA_PA4 = up; PORTA_PA5 = up; PORTA_PA6 = up;
PORTA_PA7 = up; }
else if(*==9){
PORTA_PA1 = up; PORTA_PA2 = up; PORTA_PA3 = up; PORTA_PA4 = up; PORTA_PA5 = down; PORTA_PA6 = up; PORTA_PA7 = up; } else if(*==10){ PORTA_PA1 = down; PORTA_PA2 = down; PORTA_PA3 = down; PORTA_PA4 = down; PORTA_PA5 = down; PORTA_PA6 = down; PORTA_PA7 = down; } else{
PORTA_PA1 = down; PORTA_PA2 = up; PORTA_PA3 = up;
PORTA_PA4 = up;
PORTA_PA5 = up;
PORTA_PA6 = up;
PORTA_PA7 = down;
}
}
/******************起飞模块**************************************/ void startfly(void){
PWMDTY2=25;
show_*t=10;
show_a=show_b=10;
show_c=0;
delayms(2000);
PWMDTY0=1185>>8;
PWMDTY1=1185;
PWMDTY3=19;
PWMDTY2=19;
}
void main(void)
{
int i=0;
int P=12,I=0,D=150;
PLL_Init();
PWM_Init();
DDRT_DDRT3 = 0;
DDRT_DDRT5 = 1;
DDRA=0*FF;
DDRT_DDRT2 = 1;
DDRT_DDRT4 = 1;
DDRT_DDRT6 = 1;
PIT_Init();
EnableInterrupts;
delayms(4000);
startfly();
delayms(2000);
/* GetDIPSwitch();
if(DIPSwitch_DIPS8==0){
bmkg =100;
} */
while(s<=14){
if(s>=11)
want=350;
if(s>=12)
want=350;
if(s>=14)
want=150;
delayms(40);
test=csb();
now_high=want-test;
PI+=I*now_high;
PWM3_ls=P*now_high+PI+D*(now_high-last_high); PWM3=1160+PWM3_ls/100;
llst_high=last_high;
last_high=now_high;
if(PWM3>1230)
PWM3=1230;
else if(PWM3<1100)
PWM3=1100;
PWMDTY4=PWM3>>8;
PWMDTY5=PWM3;
test=test/10;
if(csb_count>3000) {
csb_count=0;
if(test<10){
show_a=10;
show_b=10;
show_c=test;
}else if(test<100){
show_a=10;
show_b=test/10;
show_c=test%10;
} else{
show_a=test/100;
show_b=test/10%10;
show_c=test%10;
}
}
}
PWMDTY4=800>>8;
PWMDTY5=800;
for(;;)
{
_FEED_COP();
}
}
/******************中断效劳函数**************************************/ #pragma CODE_SEG __NEAR_SEG NON_BANKED
void interrupt 66 PIT0_ISR(void)
{
PITTF_PTF0=1;//清中断标志位
if(count<10000)
count++;
us++;
csb_count++;
if(us>100) {
us=0;
ms++;
if(ms>1000) {
ms=0;
s++;
show_*t=s%10;
}
}
if(s>15){
PWMDTY4=800>>8;
PWMDTY5=800;
}
if(us==0){
if(*sq_count==1) {
PORTA_PA0 = 0;
show123(show_*t);
PTT_PTT2 = 1;
}else if(*sq_count==2){
PTT_PTT2 = 0;
show123(show_a);
PTT_PTT6 = 1;
} else if(*sq_count==3){
PTT_PTT6 = 0;
show123(show_b);
PTT_PTT4 = 1;
}else if(*sq_count==4){
PTT_PTT4 = 0;
show123(show_c);
PORTA_PA0 = 1;
*sq_count=0;
}
*sq_count++;
}
}。