找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3708|回复: 1
收起左侧

基于MSP430单片机的四旋翼 PID Control种群遗传算法 通过卡尔曼滤波实现自稳

[复制链接]
ID:415178 发表于 2018-10-25 13:22 | 显示全部楼层 |阅读模式
基于MSP430单片机的四旋翼 仅供大家参考
0.png

PID Control种群遗传算法:
  1. #include "io430x14x.h"
  2. #include "stdlib.h"
  3. #include "sys.h"
  4. #include "Control.h"


  5. #define col_MAX 50                //群体空间大小
  6. #define var_p 65                //变异概率:65 对应的变异概率约等于0.001,655 为0.01   rand():0-65535
  7. #define epoch_MAX 200        //进化代数
  8. void inherit(void)                //遗传进化PID
  9. {
  10.         unsigned int colony[col_MAX]={
  11.         62267,15148,39769,31849,58411,49944,29915,58375 ,53831
  12.         ,29144,40332,51900,60411,48378,11552,26588,61306,60089
  13.         ,26887,58565, 3794,23125,53291,  646, 9102,13288,13023
  14.         ,39570,17838,13029, 1001,48941,29169,61066,30539,27436
  15.         ,55457,34416,13280,44049,54926, 1287,44647,24869,54512
  16.         ,32952,46495,28107,19963,12429
  17.         };
  18.         unsigned int health[col_MAX];        //对应colony[] ,每个个体的适应值,
  19.         unsigned int dad,mum,baby1,baby2;
  20.         unsigned int mini_health,mini_id;
  21.         unsigned int temp_health;
  22.         unsigned char i,epoch;        //epoch 遗传代数
  23.         mini_health = found(&colony[0],&health[0]);        //评估初始个体,并作适应值缩放,找出最小适应值
  24.         for(epoch=0; epoch < epoch_MAX; epoch++) //开始进化
  25.         {
  26.                 i = roulette(&health[0]);//轮盘赌转,返回数组下标
  27.                 dad = colony[i];
  28.                 i = roulette(&health[0]);//轮盘赌转,返回数组下标
  29.                 mum = colony[i];
  30.                 baby1 = dad&0xff;baby1 |= mum&0xff00;
  31.                 baby2 = mum&0xff;baby2 |= dad&0xff00;
  32.                 baby1 = variation(baby1);        //变异?
  33.                 baby2 = variation(baby2);
  34.                 temp_health = evaluating_unit(baby1);        //评估个体适应值
  35.                 if(temp_health > mini_health)
  36.                 {
  37.                         mini_id = evaluating(&health[0]);        //取得最差适应值的个体id(数组下标)
  38.                         colony[mini_id] = baby1;
  39.                         health[mini_id] = temp_health - mini_health;
  40.                 }
  41.                 temp_health = evaluating_unit(baby2);        //评估个体适应值
  42.                 if(temp_health > mini_health)
  43.                 {
  44.                         mini_id = evaluating(&health[0]);        //取得最差个体的适应值,及其id
  45.                         colony[mini_id] = baby2;
  46.                         health[mini_id] = temp_health - mini_health;
  47.                 }
  48.         }
  49.         while(1); //结束进化
  50. }

  51. #define ev_N 25
  52. #define aim_value 300
  53. uint evaluating_unit(uint unit)//评估个体适应值  顺便PWM输出
  54. {
  55.         uint ret=0,temp=0,max=0;
  56.         uchar i=0;
  57.         int uk=0;                                //PID增量
  58.         redressal(pid, unit);        //根据个体,对基因进行解码  修改PID三个参数
  59.         while(i<ev_N)        //PID调整 ev_N.PID调整次数
  60.         {
  61.                         if(measured > desired)
  62.                         {
  63.                                 temp = measured - desired;
  64.                                 if(temp > max)
  65.                                         max=temp;        //最大超调量
  66.                         }
  67.                         else
  68.                                 temp = desired - measured;
  69.                        
  70.                         ret+=temp;
  71.                         uk = (int)(PID_Posi(pid, measured, desired));        //PWM输出
  72.                         M1 = speed[0] - uk;        //y轴
  73.                         M3 = speed[0] + uk;        //y轴

  74.                         i++;
  75.                 }
  76.         }
  77.         ret=65535/(ret/ev_N+max);
  78.         return ret;        //返回适应值
  79. }

  80. void redressal(float* pid,uint colon)
  81. {
  82.         pid[0]=(float)((colon&0xFC00)>>10)*5.0/63;        //[0:0.079:5]
  83.         pid[1]=(float)((colon&0x3E0)>>5)*0.1/31.0;        //[0:0.0032:0.1]
  84.         pid[2]=(float)(colon&0x1F)/31.0;                        //[0:0.032:1]
  85. }

  86. uint found(uint colony,uint health)        //计算初始群体适应值,并找出最小值
  87. {
  88.         uchar i;
  89.         uint mini=0xff;
  90.         for(i=0;i<col_MAX;i++)
  91.         {
  92.                 *(health+i) = evaluating_unit(*(colony+i));        //评估个体适应值
  93.                 if(*(health+i)<mini)
  94.                         mini=*(health+i);
  95.         }
  96.         for(i=0;i<col_MAX;i++) //适应值缩放
  97.                 *(health+i)-=mini;
  98.         return mini;
  99. }

  100. uchar roulette(uint health)
  101. {
  102.         uchar i;
  103.         uint temp=0;
  104.         i=(uchar)(rand()%col_MAX); //0~(col_MAX-1) 随机选择起点
  105.         while(1)
  106.         {
  107.                 if((col_MAX-1)==i) //实现首尾相接
  108.                         i=0;
  109.                
  110.                 temp+=*(health+i); //累加适应值
  111.                 if (temp>1200)
  112.                         return i;
  113.                 i++;
  114.         }
  115. }

  116. uchar evaluating(uint health)        //取得最小适应值的个体id(数组下标)
  117. {
  118.         uchar i,id;
  119.         uint mini=0xffff;
  120.         for(i=0;i<col_MAX;i++)
  121.         {
  122.                 if(*(health+i)<mini)
  123.                 {
  124.                         mini=*(health+i);
  125.                         id=i;
  126.                 }
  127.         }
  128.         return id;
  129. }

  130. uint variation(uint baby)        //对基因进行变异
  131. {
  132.         uchar i;
  133.         for(i=0;i<16;i++)
  134.         {
  135.                 if(rand()<var_p)        //rand()0-65535,变异概率:65 对应的变异概率约等于0.001,655 为0.01
  136.                 {
  137.                         if(0==(baby&(1<<i)))
  138.                                 baby|=(1<<i);
  139.                         else
  140.                                 baby &= ~(1<<i);
  141.                 }
  142.         }
  143.         return baby;
  144. }
复制代码


单片机源程序如下:
  1. #include "io430x14x.h"
  2. #include "sys.h"
  3. #include "24L01.h"
  4. #include "MPU6050.h"
  5. #include "HMC5883L.h"
  6. #include "EEPROM.h"
  7. #include "Control.h"
  8. #include "math.h"

  9. uchar RxBuf[32]={0};
  10. uchar TxBuf[32]={0};
  11. uchar EEPROMBuffer[SIZE]={0};

  12. int speed[5] = {1300,0,0,0,0};//M0,M1-M4
  13. int desire[4]={0,0,0,0};//HMC_YAW,ROLL,PITCH,YAW
  14. float PID_Roll[6]={0}, PID_Pitch[6]={0}, PID_Yaw[6]={0};
  15. float roll = 0, pitch = 0, yaw = 0;
  16. int gyro[3]={0}, accel[3]={0}, magne[3]={0};

  17. uchar RX = 0, TX = 0, CALC = 0, Fly = 0, EEPROMWR = 0;
  18. uint ms2 = 0, ms10 = 0, ms500 = 0;

  19. /********************************Main*********************************/
  20. void main(void)
  21. {
  22.         uchar Flag_TX = 0;
  23.         Init_Sys(); //系统功能初始化
  24.         _EINT();    //开启中断功能
  25.        
  26.         HMC5883_Init();
  27.         MPU6050_Init();
  28.         NRF24L01_Init();
  29.         while(AT24CXX_Check());//检测不到24c16
  30.        
  31.         AT24CXX_Read(20,EEPROMBuffer,SIZE);
  32.         Init_datas(PID_Roll, PID_Pitch, PID_Yaw, desire, speed, EEPROMBuffer);
  33.        
  34. /********************************Start*********************************/
  35.         while(1)
  36.         {
  37.                 if(RX)
  38.                 {
  39.                         NRF24L01_RX_Mode();
  40.                         if(NRF24L01_RxPacket(RxBuf)==RX_OK)   //判断是否收到数据
  41.                         {
  42.                                 if(RxBuf[0]==0xAA)//有数据更新
  43.                                 {
  44.                                         Data_Update(PID_Roll, PID_Pitch, PID_Yaw, desire, speed, RxBuf);
  45.                                         Fly = RxBuf[START_STOP];//Stop?
  46.                                 }
  47.                         }
  48.                 }
  49.                 if(TX)
  50.                 {
  51.                         TX = 0;
  52.                         if(Flag_TX == 0)
  53.                         {
  54.                                 Flag_TX = 1;
  55.                                 Data_Send_Status(roll, pitch, yaw, desire, speed, TxBuf);
  56.                         }
  57.                         else if(Flag_TX == 1)
  58.                         {
  59.                                 Flag_TX = 0;
  60. //                                Data_Send_Senser(accel, gyro, magne, TxBuf);
  61.                                 Data_Send_PID(PID_Roll, PID_Pitch, PID_Yaw, TxBuf);
  62.                         }
  63.                         NRF24L01_TxPacket(TxBuf);
  64.                 }
  65.                 if(CALC)
  66.                 {
  67.                         CALC = 0;
  68.                         MPU6050_Read(accel, gyro);
  69.                         AHRSupdate(accel, gyro, magne);
  70.                         yaw = get_angle(magne, roll, pitch);
  71.                         if(Fly)
  72.                         {
  73.                                 EEPROMWR = 1;
  74.                                 MotoCtrl(PID_Roll, PID_Pitch, PID_Yaw, desire, speed, roll, pitch, yaw, gyro, 1);
  75.                         }
  76.                         else
  77.                         {
  78.                                 M1=900;M2=900;M3=900;M4=900;
  79.                                 if(EEPROMWR)
  80.                                 {
  81.                                         EEPROMWR = 0;
  82.                                         AT24CXX_BufferWrite(PID_Roll, PID_Pitch, PID_Yaw, desire, speed, EEPROMBuffer);
  83.                                 }
  84.                         }
  85.                 }
  86.         }
  87. }

  88. //***********************************************************************
  89. //TIMERA中断服务程序
  90. //定时时间:1ms
  91. //***********************************************************************
  92. #pragma vector = TIMERA1_VECTOR
  93. __interrupt void Timer_A1(void)
  94. {
  95.         if(TAIV==2)//定时溢出标志位
  96.         {
  97.                 ms2++;
  98.                 ms10++;
  99. //                ms500++;
  100.                
  101.                 if(ms2 == 2)        {CALC = 1;                        ms2  = 0;}
  102.                
  103.                 if(ms10 == 4)        {TX = 1;                                         }
  104.                 if(ms10 == 8)        {TX = 1;                                         }
  105.                 if(ms10 == 12)        {TX = 1;                                         }
  106.                 if(ms10 == 16)        {TX = 1;                                         }
  107.                 if(ms10 == 20)        {RX = 1;                        ms10 = 0;}
  108.                
  109. //                if(ms500 == 5000)
  110. //                {
  111. //                        ms500 = 0;
  112. //                }
  113.                
  114.         }
  115. }
复制代码

所有资料51hei提供下载:
四旋翼飞行器,采用MSP430F149,通过卡尔曼滤波实现自稳。其中包括陀螺仪MPU6505、地.rar (180.89 KB, 下载次数: 75)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:497177 发表于 2020-2-19 14:48 | 显示全部楼层
非常好
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表