标题:
基于MSP430单片机的四旋翼 PID Control种群遗传算法 通过卡尔曼滤波实现自稳
[打印本页]
作者:
郁响
时间:
2018-10-25 13:22
标题:
基于MSP430单片机的四旋翼 PID Control种群遗传算法 通过卡尔曼滤波实现自稳
基于MSP430单片机的四旋翼 仅供大家参考
0.png
(16.69 KB, 下载次数: 86)
下载附件
2018-10-26 02:21 上传
PID Control种群遗传算法:
#include "io430x14x.h"
#include "stdlib.h"
#include "sys.h"
#include "Control.h"
#define col_MAX 50 //群体空间大小
#define var_p 65 //变异概率:65 对应的变异概率约等于0.001,655 为0.01 rand():0-65535
#define epoch_MAX 200 //进化代数
void inherit(void) //遗传进化PID
{
unsigned int colony[col_MAX]={
62267,15148,39769,31849,58411,49944,29915,58375 ,53831
,29144,40332,51900,60411,48378,11552,26588,61306,60089
,26887,58565, 3794,23125,53291, 646, 9102,13288,13023
,39570,17838,13029, 1001,48941,29169,61066,30539,27436
,55457,34416,13280,44049,54926, 1287,44647,24869,54512
,32952,46495,28107,19963,12429
};
unsigned int health[col_MAX]; //对应colony[] ,每个个体的适应值,
unsigned int dad,mum,baby1,baby2;
unsigned int mini_health,mini_id;
unsigned int temp_health;
unsigned char i,epoch; //epoch 遗传代数
mini_health = found(&colony[0],&health[0]); //评估初始个体,并作适应值缩放,找出最小适应值
for(epoch=0; epoch < epoch_MAX; epoch++) //开始进化
{
i = roulette(&health[0]);//轮盘赌转,返回数组下标
dad = colony[i];
i = roulette(&health[0]);//轮盘赌转,返回数组下标
mum = colony[i];
baby1 = dad&0xff;baby1 |= mum&0xff00;
baby2 = mum&0xff;baby2 |= dad&0xff00;
baby1 = variation(baby1); //变异?
baby2 = variation(baby2);
temp_health = evaluating_unit(baby1); //评估个体适应值
if(temp_health > mini_health)
{
mini_id = evaluating(&health[0]); //取得最差适应值的个体id(数组下标)
colony[mini_id] = baby1;
health[mini_id] = temp_health - mini_health;
}
temp_health = evaluating_unit(baby2); //评估个体适应值
if(temp_health > mini_health)
{
mini_id = evaluating(&health[0]); //取得最差个体的适应值,及其id
colony[mini_id] = baby2;
health[mini_id] = temp_health - mini_health;
}
}
while(1); //结束进化
}
#define ev_N 25
#define aim_value 300
uint evaluating_unit(uint unit)//评估个体适应值 顺便PWM输出
{
uint ret=0,temp=0,max=0;
uchar i=0;
int uk=0; //PID增量
redressal(pid, unit); //根据个体,对基因进行解码 修改PID三个参数
while(i<ev_N) //PID调整 ev_N.PID调整次数
{
if(measured > desired)
{
temp = measured - desired;
if(temp > max)
max=temp; //最大超调量
}
else
temp = desired - measured;
ret+=temp;
uk = (int)(PID_Posi(pid, measured, desired)); //PWM输出
M1 = speed[0] - uk; //y轴
M3 = speed[0] + uk; //y轴
i++;
}
}
ret=65535/(ret/ev_N+max);
return ret; //返回适应值
}
void redressal(float* pid,uint colon)
{
pid[0]=(float)((colon&0xFC00)>>10)*5.0/63; //[0:0.079:5]
pid[1]=(float)((colon&0x3E0)>>5)*0.1/31.0; //[0:0.0032:0.1]
pid[2]=(float)(colon&0x1F)/31.0; //[0:0.032:1]
}
uint found(uint colony,uint health) //计算初始群体适应值,并找出最小值
{
uchar i;
uint mini=0xff;
for(i=0;i<col_MAX;i++)
{
*(health+i) = evaluating_unit(*(colony+i)); //评估个体适应值
if(*(health+i)<mini)
mini=*(health+i);
}
for(i=0;i<col_MAX;i++) //适应值缩放
*(health+i)-=mini;
return mini;
}
uchar roulette(uint health)
{
uchar i;
uint temp=0;
i=(uchar)(rand()%col_MAX); //0~(col_MAX-1) 随机选择起点
while(1)
{
if((col_MAX-1)==i) //实现首尾相接
i=0;
temp+=*(health+i); //累加适应值
if (temp>1200)
return i;
i++;
}
}
uchar evaluating(uint health) //取得最小适应值的个体id(数组下标)
{
uchar i,id;
uint mini=0xffff;
for(i=0;i<col_MAX;i++)
{
if(*(health+i)<mini)
{
mini=*(health+i);
id=i;
}
}
return id;
}
uint variation(uint baby) //对基因进行变异
{
uchar i;
for(i=0;i<16;i++)
{
if(rand()<var_p) //rand()0-65535,变异概率:65 对应的变异概率约等于0.001,655 为0.01
{
if(0==(baby&(1<<i)))
baby|=(1<<i);
else
baby &= ~(1<<i);
}
}
return baby;
}
复制代码
单片机源程序如下:
#include "io430x14x.h"
#include "sys.h"
#include "24L01.h"
#include "MPU6050.h"
#include "HMC5883L.h"
#include "EEPROM.h"
#include "Control.h"
#include "math.h"
uchar RxBuf[32]={0};
uchar TxBuf[32]={0};
uchar EEPROMBuffer[SIZE]={0};
int speed[5] = {1300,0,0,0,0};//M0,M1-M4
int desire[4]={0,0,0,0};//HMC_YAW,ROLL,PITCH,YAW
float PID_Roll[6]={0}, PID_Pitch[6]={0}, PID_Yaw[6]={0};
float roll = 0, pitch = 0, yaw = 0;
int gyro[3]={0}, accel[3]={0}, magne[3]={0};
uchar RX = 0, TX = 0, CALC = 0, Fly = 0, EEPROMWR = 0;
uint ms2 = 0, ms10 = 0, ms500 = 0;
/********************************Main*********************************/
void main(void)
{
uchar Flag_TX = 0;
Init_Sys(); //系统功能初始化
_EINT(); //开启中断功能
HMC5883_Init();
MPU6050_Init();
NRF24L01_Init();
while(AT24CXX_Check());//检测不到24c16
AT24CXX_Read(20,EEPROMBuffer,SIZE);
Init_datas(PID_Roll, PID_Pitch, PID_Yaw, desire, speed, EEPROMBuffer);
/********************************Start*********************************/
while(1)
{
if(RX)
{
NRF24L01_RX_Mode();
if(NRF24L01_RxPacket(RxBuf)==RX_OK) //判断是否收到数据
{
if(RxBuf[0]==0xAA)//有数据更新
{
Data_Update(PID_Roll, PID_Pitch, PID_Yaw, desire, speed, RxBuf);
Fly = RxBuf[START_STOP];//Stop?
}
}
}
if(TX)
{
TX = 0;
if(Flag_TX == 0)
{
Flag_TX = 1;
Data_Send_Status(roll, pitch, yaw, desire, speed, TxBuf);
}
else if(Flag_TX == 1)
{
Flag_TX = 0;
// Data_Send_Senser(accel, gyro, magne, TxBuf);
Data_Send_PID(PID_Roll, PID_Pitch, PID_Yaw, TxBuf);
}
NRF24L01_TxPacket(TxBuf);
}
if(CALC)
{
CALC = 0;
MPU6050_Read(accel, gyro);
AHRSupdate(accel, gyro, magne);
yaw = get_angle(magne, roll, pitch);
if(Fly)
{
EEPROMWR = 1;
MotoCtrl(PID_Roll, PID_Pitch, PID_Yaw, desire, speed, roll, pitch, yaw, gyro, 1);
}
else
{
M1=900;M2=900;M3=900;M4=900;
if(EEPROMWR)
{
EEPROMWR = 0;
AT24CXX_BufferWrite(PID_Roll, PID_Pitch, PID_Yaw, desire, speed, EEPROMBuffer);
}
}
}
}
}
//***********************************************************************
//TIMERA中断服务程序
//定时时间:1ms
//***********************************************************************
#pragma vector = TIMERA1_VECTOR
__interrupt void Timer_A1(void)
{
if(TAIV==2)//定时溢出标志位
{
ms2++;
ms10++;
// ms500++;
if(ms2 == 2) {CALC = 1; ms2 = 0;}
if(ms10 == 4) {TX = 1; }
if(ms10 == 8) {TX = 1; }
if(ms10 == 12) {TX = 1; }
if(ms10 == 16) {TX = 1; }
if(ms10 == 20) {RX = 1; ms10 = 0;}
// if(ms500 == 5000)
// {
// ms500 = 0;
// }
}
}
复制代码
所有资料51hei提供下载:
四旋翼飞行器,采用MSP430F149,通过卡尔曼滤波实现自稳。其中包括陀螺仪MPU6505、地.rar
(180.89 KB, 下载次数: 77)
2018-10-25 13:22 上传
点击文件名下载附件
下载积分: 黑币 -5
作者:
becausetyet
时间:
2020-2-19 14:48
非常好
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1