无名飞控姿态解算和控制
来源:互联网 发布:linux漏洞 在哪 编辑:程序博客网 时间:2024/05/22 23:09
回到TIME.c进入Accel_Calibration_Check();//加速度标定检测
定义:
uint8_t flight_direction=6;uint8_t Accel_Calibration_Flag=0;//加速度计校准模式uint8_t Accel_Calibration_Finished[6]={0,0,0,0,0,0};//对应面校准完成标志位uint8_t Accel_Calibration_All_Finished=0;//6面校准全部校准完成标志位uint16_t Accel_Calibration_Makesure_Cnt=0;uint16_t Accel_flight_direction_cnt=0;void Accel_Calibration_Check(void){ uint16_t i=0; if(Throttle_Control==1000&&Yaw_Control>=80&&Roll_Control<=-40&&Pitch_Control>=40) { Accel_Calibration_Makesure_Cnt++; } if(Throttle_Control==1000 &&Yaw_Control>=80 &&Roll_Control<=-40 &&Pitch_Control>=40 &&Accel_Calibration_Makesure_Cnt>=200*3)//持续三秒 { Bling_Mode=1; Accel_Calibration_Flag=1;//加速度校准模式 Cal_Flag=0; Bling_Set(&Light_1,1000,100,0.5,0,GPIOC,GPIO_Pin_4,1); Bling_Set(&Light_2,1000,100,0.5,0,GPIOC,GPIO_Pin_5,1); Bling_Set(&Light_3,1000,100,0.5,0,GPIOC,GPIO_Pin_10,1); flight_direction=6; Accel_Calibration_All_Finished=0;//全部校准完成标志位清零 Accel_Calibration_Makesure_Cnt=0; for(i=0;i<6;i++) { Accel_Calibration_Finished[i]=0;//对应面标志位清零 acce_sample[i].x=0; //清空对应面的加速度计量 acce_sample[i].y=0; //清空对应面的加速度计量 acce_sample[i].z=0; //清空对应面的加速度计量 } Page_Number=10;//OLED加速度计矫正页面 Reset_Mag_Calibartion(1); } if(Accel_Calibration_Flag==1) { if(Throttle_Control==1000&&Yaw_Control<=-80&&Roll_Control==0&&Pitch_Control==0) { Accel_flight_direction_cnt++; if(Accel_flight_direction_cnt>=4*25)//100ms flight_direction=0; } else if(Throttle_Control==1000&&Yaw_Control==0&&Roll_Control>=40&&Pitch_Control==0) { Accel_flight_direction_cnt++; if(Accel_flight_direction_cnt>=4*25)//100ms flight_direction=1; } else if(Throttle_Control==1000&&Yaw_Control==0&&Roll_Control<=-40&&Pitch_Control==0) { Accel_flight_direction_cnt++; if(Accel_flight_direction_cnt>=4*25)//100ms flight_direction=2; } else if(Throttle_Control==1000&&Yaw_Control==0&&Roll_Control==0&&Pitch_Control>=40) { Accel_flight_direction_cnt++; if(Accel_flight_direction_cnt>=4*25)//100ms flight_direction=3; } else if(Throttle_Control==1000&&Yaw_Control==0&&Roll_Control==0&&Pitch_Control<=-40) { Accel_flight_direction_cnt++; if(Accel_flight_direction_cnt>=4*25)//100ms flight_direction=4; } else if(Throttle_Control==1000&&Yaw_Control>80&&Roll_Control==0&&Pitch_Control==0) { Accel_flight_direction_cnt++; if(Accel_flight_direction_cnt>=4*25)//100ms flight_direction=5; } else { Accel_flight_direction_cnt/=2; } if(Accel_flight_direction_cnt>=200) Accel_flight_direction_cnt=0; }}
整个过程可以看做有三个部分组成
第一个if判断用来计数
if(Throttle_Control==1000&&Yaw_Control>=80&&Roll_Control<=-40&&Pitch_Control>=40) { Accel_Calibration_Makesure_Cnt++; }当Accel_Calibration_Makesure_Cnt满足营情况时开始校准(Accel_Calibration_Makesure_Cnt>=250*3)持续三秒 ????
当Accel_Calibration_Makesure_Cnt>=250*3成立时有:
if(Throttle_Control==1000 &&Yaw_Control>=80 &&Roll_Control<=-40 &&Pitch_Control>=40 &&Accel_Calibration_Makesure_Cnt>=250*3)//持续三秒校准赋初值
Bling_Mode=1; Accel_Calibration_Flag=1;//加速度校准模式 Cal_Flag=0; Bling_Set(&Light_1,1000,100,0.5,0,GPIOC,GPIO_Pin_12,1); Bling_Set(&Light_2,1000,100,0.5,0,GPIOC,GPIO_Pin_11,1); Bling_Set(&Light_3,1000,100,0.5,0,GPIOC,GPIO_Pin_10,1); flight_direction=6; Accel_Calibration_All_Finished=0;//全部校准完成标志位清零 Accel_Calibration_Makesure_Cnt=0; for(i=0;i<6;i++) { Accel_Calibration_Finished[i]=0;//对应面标志位清零 acce_sample[i].x=0; //清空对应面的加速度计量 acce_sample[i].y=0; //清空对应面的加速度计量 acce_sample[i].z=0; //清空对应面的加速度计量 } Page_Number=10;//OLED加速度计矫正页面 Reset_Mag_Calibartion(1);其中Bling_Set函数如下:
Bling_Light Light_1,Light_2,Light_3,Light_4;uint16_t Bling_Mode=0;void Bling_Set(Bling_Light *Light, uint32_t Continue_time,//持续时间 uint16_t Period,//周期100ms~1000ms float Percent,//0~100% uint16_t Cnt, GPIO_TypeDef* Port, uint16_t Pin ,uint8_t Flag){ Light->Bling_Contiune_Time=Continue_time/4;//持续时间 Light->Bling_Period=Period;//周期 Light->Bling_Percent=Percent;//占空比 Light->Bling_Cnt=Cnt; Light->Port=Port;//端口 Light->Pin=Pin;//引脚 Light->Endless_Flag=Flag;//无尽模式}Bling_Light结构体定义:
typedef struct{ uint16_t Bling_Contiune_Time;//闪烁持续时间 uint16_t Bling_Period;//闪烁周期 float Bling_Percent;//闪烁占空比 uint16_t Bling_Cnt;//闪烁计数器 GPIO_TypeDef* Port; //端口 uint16_t Pin;//引脚 uint8_t Endless_Flag;//无尽模式}Bling_Light;接着赋值
flight_direction=6; Accel_Calibration_All_Finished=0;//全部校准完成标志位清零 Accel_Calibration_Makesure_Cnt=0; for(i=0;i<6;i++) { Accel_Calibration_Finished[i]=0;//对应面标志位清零 acce_sample[i].x=0; //清空对应面的加速度计量 acce_sample[i].y=0; //清空对应面的加速度计量 acce_sample[i].z=0; //清空对应面的加速度计量 } Page_Number=10;//OLED加速度计矫正页面
其中Acce_Unit acce_sample[6]={0};//三行6列,保存6面待矫正数据
typedef struct{ float x; float y; float z;}Acce_Unit;上面是Acce_Unit定义
接着
Reset_Mag_Calibartion(1);
void Reset_Mag_Calibartion(uint8_t Type){ uint16 i=0; for(i=0;i<12;i++) { Mag_360_Flag[0][i]=0;//清空采集角点 Mag_360_Flag[1][i]=0;//清空采集角点 } Mag_Is_Okay_Flag[0]=0; Mag_Is_Okay_Flag[1]=0; Mag_Calibration_Mode=2; if(Type==1) Mag_Calibration_Flag=0; }加速度计校准开始:
if(Accel_Calibration_Flag==1) { if(Throttle_Control==1000&&Yaw_Control<=-80&&Roll_Control==0&&Pitch_Control==0) { flight_direction=0; } else if(Throttle_Control==1000&&Yaw_Control==0&&Roll_Control>=40&&Pitch_Control==0) { flight_direction=1; } else if(Throttle_Control==1000&&Yaw_Control==0&&Roll_Control<=-40&&Pitch_Control==0) { flight_direction=2; } else if(Throttle_Control==1000&&Yaw_Control==0&&Roll_Control==0&&Pitch_Control>=40) { flight_direction=3; } else if(Throttle_Control==1000&&Yaw_Control==0&&Roll_Control==0&&Pitch_Control<=-40) { flight_direction=4; } else if(Throttle_Control==1000&&Yaw_Control>80&&Roll_Control==0&&Pitch_Control==0) { flight_direction=5; } }回到TIMC.c,进入Mag_Calibration_Check
void Mag_Calibration_Check(void){ uint16_t i=0,j=0; if(Throttle_Control==1000&&Yaw_Control>=80&&Roll_Control>=40&&Pitch_Control>=40) Mag_Calibration_Makesure_Cnt++; if(Throttle_Control==1000 &&Yaw_Control>=80 &&Roll_Control>=40 &&Pitch_Control>=40 &&Mag_Calibration_Makesure_Cnt>250*4//持续4S )//进入磁力计校准模式 { Bling_Mode=2; Mag_Calibration_Flag=1;//磁力计校准模式 Mag_Calibration_Mode=2; Bling_Set(&Light_1,1000,500,0.2,0,GPIOC,GPIO_Pin_12,1); Bling_Set(&Light_2,1000,500,0.5,0,GPIOC,GPIO_Pin_11,1); Bling_Set(&Light_3,1000,500,0.7,0,GPIOC,GPIO_Pin_10,1); Mag_Calibration_Makesure_Cnt=0; Mag_Calibration_All_Finished=0;//全部校准完成标志位清零 for(i=0;i<2;i++) { Mag_Calibration_Finished[i]=0;//对应面标志位清零 for(j=0;j<12;j++) {Mag_360_Flag[i][j]=0;} } Page_Number=11; Reset_Accel_Calibartion(1); } if(Mag_Calibration_Flag==1) { if(Throttle_Control==1000 &&Yaw_Control<=-80 &&Roll_Control==0 &&Pitch_Control==0) //第一面矫正 { Mag_Calibration_Mode=0; Mag_Is_Okay_Flag[1]=0;//单面数据采集完成标志位置0 for(i=0;i<12;i++) Mag_360_Flag[1][i]=0;//清空采集角遍历数据点 } else if(Throttle_Control==1000 &&Yaw_Control>80 &&Roll_Control==0 &&Pitch_Control==0) //第二面矫正 { Mag_Calibration_Mode=1; Mag_Is_Okay_Flag[1]=0;//单面数据采集完成标志位置0 for(i=0;i<12;i++) Mag_360_Flag[1][i]=0;//清空采集角遍历数据点 } } }其中,调用了Reset_Accel_Calibartion
void Reset_Accel_Calibartion(uint8_t Type){ uint16 i=0; for(i=0;i<6;i++) { Accel_Calibration_Finished[i]=0;//对应面标志位清零 acce_sample[i].x=0; //清空对应面的加速度计量 acce_sample[i].y=0; //清空对应面的加速度计量 acce_sample[i].z=0; //清空对应面的加速度计量 } Accel_Calibration_All_Finished=0;//全部校准完成标志位清零 if(Type==1) Accel_Calibration_Flag=0; }uint8_t Mag_360_Flag[2][12]={0};
回到TIME.c,Bling_Working(Bling_Mode),再校准的过程中量不同的灯
void Bling_Working(uint16 bling_mode){ if(bling_mode==0)//全灭 { Bling_Process(&Light_1); Bling_Process(&Light_2); Bling_Process(&Light_3); } else if(bling_mode==1)//加速度计6面校准模式 { if(flight_direction==0)//第一面校准准备 { Bling_Process(&Light_1); GPIO_SetBits(Light_2.Port,Light_2.Pin); GPIO_SetBits(Light_3.Port,Light_3.Pin); } else if(flight_direction==1)//第二面校准准备 { Bling_Process(&Light_2); GPIO_SetBits(Light_1.Port,Light_1.Pin); GPIO_SetBits(Light_3.Port,Light_3.Pin); } else if(flight_direction==2)//第三面校准准备 { Bling_Process(&Light_1); Bling_Process(&Light_2); GPIO_SetBits(Light_3.Port,Light_3.Pin); } else if(flight_direction==3)//第四面校准准备 { Bling_Process(&Light_3); GPIO_SetBits(Light_1.Port,Light_1.Pin); GPIO_SetBits(Light_2.Port,Light_2.Pin); } else if(flight_direction==4)//第五面校准准备 { Bling_Process(&Light_1); Bling_Process(&Light_3); GPIO_SetBits(Light_2.Port,Light_2.Pin); } else if(flight_direction==5)//第六面校准准备 { GPIO_SetBits(Light_1.Port,Light_1.Pin); Bling_Process(&Light_2); Bling_Process(&Light_3); } else { Bling_Process(&Light_1); Bling_Process(&Light_2); Bling_Process(&Light_3); } } else if(bling_mode==2)//磁力计校准模式 { if(Mag_Calibration_Mode==0)//水平面校准 { Bling_Process(&Light_1); Bling_Process(&Light_2); GPIO_SetBits(Light_3.Port,Light_3.Pin); } else if(Mag_Calibration_Mode==1)////竖直平面校准 { GPIO_SetBits(Light_1.Port,Light_1.Pin); Bling_Process(&Light_2); Bling_Process(&Light_3); } else { Bling_Process(&Light_1); Bling_Process(&Light_2); Bling_Process(&Light_3); }}else if(bling_mode==3)//全灭{ GPIO_SetBits(GPIOC,GPIO_Pin_10); GPIO_SetBits(GPIOC,GPIO_Pin_11); GPIO_SetBits(GPIOC,GPIO_Pin_12);} Bling_Process(&Light_4);}
void Bling_Process(Bling_Light *Light)//闪烁运行线程{ if(Light->Bling_Contiune_Time>=1) Light->Bling_Contiune_Time--; else GPIO_SetBits(Light->Port,Light->Pin);//置高,亮 if(Light->Bling_Contiune_Time!=0//总时间未清0 ||Light->Endless_Flag==1)//判断无尽模式是否开启 { Light->Bling_Cnt++; if(4*Light->Bling_Cnt>=Light->Bling_Period) Light->Bling_Cnt=0;//计满清零 if(4*Light->Bling_Cnt<=Light->Bling_Period*Light->Bling_Percent) GPIO_ResetBits(Light->Port,Light->Pin);//置高,亮 else GPIO_SetBits(Light->Port,Light->Pin);//置低,灭 }}
GPIO_SetBits(Light_2.Port,Light_2.Pin);设置指定的数据端口位
GPIOx:x可以是A,B,C,D或者E,来选择GPIO外设
GPIO_Pin:待设置的端口位该参数可以取GPIO_Pin_x(x可以是0-15)的任意组合
Light_1,GPIOC,GPIO_Pin_12
Light_2,GPIOC,GPIO_Pin_11
Light_3,GPIOC,GPIO_Pin_10
进入DMA_Send_StateMachine();//DMA传输
DMA_Vcan_Buff Vcan_Buff;#define DMA_SEND_PERIOD 5//4*5=20ms,周期太小不易于观察波形void DMA_Send_StateMachine(void){ static uint16_t DMA_Send_Cnt=0; DMA_Send_Cnt++; if(DMA_Send_Cnt>=DMA_SEND_PERIOD) { Vcan_Buff.Head=0xfc030000; Vcan_Buff.DataBuf[0]=NamelessQuad.Position[_YAW]; Vcan_Buff.DataBuf[1]=NamelessQuad.Speed[_YAW]; Vcan_Buff.DataBuf[2]=NamelessQuad.Acceleration[_YAW];; Vcan_Buff.DataBuf[3]=Altitude_Estimate; Vcan_Buff.DataBuf[4]=10*Pitch; Vcan_Buff.DataBuf[5]=10*ACCE_X; Vcan_Buff.DataBuf[6]=10*Roll; Vcan_Buff.DataBuf[7]=10*ACCE_Y; Vcan_Buff.End=0x000003fc; Quad_DMA1_USART1_SEND((u32)(&Vcan_Buff),sizeof(Vcan_Buff)); DMA_Send_Cnt=0; }}其中Vcan_Buff是DMA_Vcan_Buff 类型的结构体;
typedef struct{ uint32_t Head; float DataBuf[8]; uint32_t End;}DMA_Vcan_Buff;另外函数Quad_DMA1_USART1_SEND
void Quad_DMA1_USART1_SEND(u32 SendBuff,u16 len)//DMA---USART1传输{Quad_DMA_Config(DMA1_Channel4,(u32)&USART1->DR,(u32)SendBuff,len);//DMA1通道4,外设为串口1,存储器为SendBuff,长度len.USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);Quad_DMA_Enable(DMA1_Channel4);//while(DMA_GetFlagStatus(DMA1_FLAG_TC4) != SET);//DMA_ClearFlag(DMA1_FLAG_TC4);//清除发送完成标志}首先是Quad_DMA_Config
DMA_InitTypeDef DMA_InitStructure;u16 DMA1_MEM_LEN;//保存DMA每次数据传送的长度/*DMA1的各通道配置这里的传输形式是固定的,这点要根据不同的情况来修改从存储器->外设模式/8位数据宽度/存储器增量模式DMA_CHx:DMA通道CHx cpar:外设地址cmar:存储器地址 cndtr:数据传输量*/void Quad_DMA_Config(DMA_Channel_TypeDef* DMA_CHx,u32 cpar,u32 cmar,u16 cndtr){ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);//使能DMA传输 DMA_DeInit(DMA_CHx); //将DMA的通道1寄存器重设为缺省值DMA1_MEM_LEN=cndtr;DMA_InitStructure.DMA_PeripheralBaseAddr = cpar; //DMA外设ADC基地址DMA_InitStructure.DMA_MemoryBaseAddr =cmar;//DMA内存基地址DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; //外设作为数据传输的目的地DMA_InitStructure.DMA_BufferSize = cndtr; //DMA通道的DMA缓存的大小DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址寄存器不变DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址寄存器递增DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //数据宽度为8位DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //数据宽度为8位DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //工作在正常缓存模式DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //DMA通道 x拥有中优先级DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //DMA通道x没有设置为内存到内存传输DMA_Init(DMA_CHx, &DMA_InitStructure); //根据DMA_InitStruct中指定的参数初始化DMA的通道USART1_Tx_DMA_Channel所标识的寄存器}
具体是什么我也不知道,等看了32的资料再接着码吧!
TIME.c的最后一个函数TIM_ClearITPendingBit(TIM4,TIM_FLAG_Update);
清除TIM4的中断待处理位,
TIM_FLAG_Update,待检查的TIM中断待处理位
阅读全文
0 0
- 无名飞控姿态解算和控制
- 无名飞控姿态解算和控制(三)
- 无名飞控的姿态解算和控制(二)
- 无名飞控姿态结算和控制(一)
- crazyflie-firmware之姿态解算和PID控制
- Pixhawk姿态解算流程图&姿态控制流程图
- 磁力计和加速度计初始姿态解算
- 姿态和位置,四旋翼的控制流程
- 无名飞控
- 姿态解算(二),姿态更新
- 四元数AHRS姿态解算和IMU姿态解算分析
- 四元数AHRS姿态解算和IMU姿态解算分析
- [转载]四轴飞行器1.4 姿态解算和Matlab实时姿态显示
- 四轴飞行器1.4 姿态解算和Matlab实时姿态显示
- 姿态解算
- 姿态解算
- 姿态解算
- 姿态解算详解
- Presto-[1]-Concepts
- @Resource 注解失效的一种场景
- 【Mysql】——mysql中的几种索引
- FCPX插件:2K分辨率高清镜头漏光效果Light Leaks V1.0破解版
- 机器学习笔记(十) 应用机器学习的建议
- 无名飞控姿态解算和控制
- 第一个SSH项目总结
- SQL之解决where 1=1 问题及优化多条件查询
- leetcode 551. Student Attendance Record I
- Ubuntu16.04 gedit 中文乱码
- (零) 设计模式开端
- 基于Unity3D的滑动面板的实现
- ECharts官方教程(六)【在图表中加入交互组件】
- ZOJ