ADRC例程

ADRC例程ADRC优化fhan《自抗扰控制入门》自抗扰死忠粉ADRC.H#ifndef_ADRC_H_#define_ADRC_H_typedefstruct{/*****安排过度过程*******/floatx1;//跟踪微分期状态量floatx2;//跟踪微分期状态量微分项floatr;//时间尺度floath;//ADRC系统积分时间uint16N0;/…

大家好,又见面了,我是你们的朋友全栈君。

ADRC

优化fhan
《自抗扰控制入门》
自抗扰死忠粉
在这里插入图片描述

ADRC.H

#ifndef _ADRC_H_
#define _ADRC_H_

typedef struct
{ 
   
/*****安排过度过程*******/
float x1;//跟踪微分期状态量
float x2;//跟踪微分期状态量微分项
float r;//时间尺度
float h;//ADRC系统积分时间
uint16 N0;//跟踪微分器解决速度超调h0=N*h

float h0;
float fh;//最速微分加速度跟踪量
float fst;//最速微分加速度跟踪量

/*****扩张状态观测器*******/
/******已系统输出y和输入u来跟踪估计系统状态和扰动*****/
float z1;
float z2;
float z3;//根据控制对象输入与输出,提取的扰动信息
float e;//系统状态误差
float y;//系统输出量
float fe;
float fe1;
float beta_01;
float beta_02;
float beta_03;
float b;


/**********系统状态误差反馈率*********/
float e0;//状态误差积分项
float e1;//状态偏差
float e2;//状态量微分项
float u0;//非线性组合系统输出
float u;//带扰动补偿后的输出
float b0;//扰动补偿

/*********第一种组合形式*********/
float beta_0;//线性
float beta_1;//非线性组合参数
float beta_2;//u0=beta_1*e1+beta_2*e2+(beta_0*e0);
/*********第二种组合形式*********/
float alpha1;//u0=beta_1*fal(e1,alpha1,zeta)+beta_2*fal(e2,alpha2,zeta)
float alpha2;//0<alpha1<1<alpha2
float zeta;//线性段的区间长度
/*********第三种组合形式*********/
float h1;//u0=-fhan(e1,e2,r,h1);
uint16 N1;//跟踪微分器解决速度超调h0=N*h
/*********第四种组合形式*********/
float c;//u0=-fhan(e1,c*e2*e2,r,h1);


}Fhan_Data;



void ADRC_Init(Fhan_Data *fhan_Input1,Fhan_Data *fhan_Input2);
void Fhan_ADRC(Fhan_Data *fhan_Input,float expect_ADRC);
void ADRC_Control(Fhan_Data *fhan_Input,float expect_ADRC,float feedback);

extern Fhan_Data ADRC_Pitch_Controller,ADRC_Roll_Controller;
#endif

ADRC.C

//#include "Headfile.h"
#include "ADRC.h"

Fhan_Data ADRC_Pitch_Controller;
Fhan_Data ADRC_Roll_Controller;
const float ADRC_Unit[3][16]=
{ 
   
/*TD跟踪微分器 改进最速TD,h0=N*h 扩张状态观测器ESO 扰动补偿 非线性组合*/
/* r h N beta_01 beta_02 beta_03 b0 beta_0 beta_1 beta_2 N1 C alpha1 alpha2 zeta b*/
 { 
   300000 ,0.005 , 3,               300,      4000,      10000,     0.001,    0.002,   2.0,      0.0010,    5,    5,    0.8,   1.5,    50,    0},
 { 
   300000 ,0.005 , 3,               300,      4000,      10000,     0.001,    0.002,   2.0,      0.0010,    5,    5,    0.8,   1.5,    50,    0},
 { 
   300000 ,0.005 , 3,               300,      4000,      10000,     0.001,    0.002,   1.2,      0.0005,    5,    5,    0.8,   1.5,    50,    0},
};

float Constrain_Float(float amt, float low, float high){ 
   
  return ((amt)<(low)?(low):((amt)>(high)?(high):(amt)));
}

int16_t Sign_ADRC(float Input)
{ 
   
    int16_t output=0;
    if(Input>1E-6) output=1;
    else if(Input<-1E-6) output=-1;
    else output=0;
    return output;
}

int16_t Fsg_ADRC(float x,float d)
{ 
   
  int16_t output=0;
  output=(Sign_ADRC(x+d)-Sign_ADRC(x-d))/2;
  return output;
}

void ADRC_Init(Fhan_Data *fhan_Input1,Fhan_Data *fhan_Input2)
{ 
   
  fhan_Input1->r=ADRC_Unit[0][0];
  fhan_Input1->h=ADRC_Unit[0][1];
  fhan_Input1->N0=(uint16)(ADRC_Unit[0][2]);
  fhan_Input1->beta_01=ADRC_Unit[0][3];
  fhan_Input1->beta_02=ADRC_Unit[0][4];
  fhan_Input1->beta_03=ADRC_Unit[0][5];
  fhan_Input1->b0=ADRC_Unit[0][6];
  fhan_Input1->beta_0=ADRC_Unit[0][7];
  fhan_Input1->beta_1=ADRC_Unit[0][8];
  fhan_Input1->beta_2=ADRC_Unit[0][9];
  fhan_Input1->N1=(uint16)(ADRC_Unit[0][10]);
  fhan_Input1->c=ADRC_Unit[0][11];

  fhan_Input1->alpha1=ADRC_Unit[0][12];
  fhan_Input1->alpha2=ADRC_Unit[0][13];
  fhan_Input1->zeta=ADRC_Unit[0][14];
  fhan_Input1->b=ADRC_Unit[0][15];

  fhan_Input2->r=ADRC_Unit[1][0];
  fhan_Input2->h=ADRC_Unit[1][1];
  fhan_Input2->N0=(uint16)(ADRC_Unit[1][2]);
  fhan_Input2->beta_01=ADRC_Unit[1][3];
  fhan_Input2->beta_02=ADRC_Unit[1][4];
  fhan_Input2->beta_03=ADRC_Unit[1][5];
  fhan_Input2->b0=ADRC_Unit[1][6];
  fhan_Input2->beta_0=ADRC_Unit[1][7];
  fhan_Input2->beta_1=ADRC_Unit[1][8];
  fhan_Input2->beta_2=ADRC_Unit[1][9];
  fhan_Input2->N1=(uint16)(ADRC_Unit[1][10]);
  fhan_Input2->c=ADRC_Unit[1][11];

  fhan_Input2->alpha1=ADRC_Unit[1][12];
  fhan_Input2->alpha2=ADRC_Unit[1][13];
  fhan_Input2->zeta=ADRC_Unit[1][14];
  fhan_Input2->b=ADRC_Unit[1][15];
}

//ADRC最速跟踪微分器TD,改进的算法fhan
void Fhan_ADRC(Fhan_Data *fhan_Input,float expect_ADRC)//安排ADRC过度过程
{ 
   
  float d=0,a0=0,y=0,a1=0,a2=0,a=0;
  float x1_delta=0;//ADRC状态跟踪误差项
  x1_delta=fhan_Input->x1-expect_ADRC;//用x1-v(k)替代x1得到离散更新公式
  fhan_Input->h0=fhan_Input->N0*fhan_Input->h;//用h0替代h,解决最速跟踪微分器速度超调问题
  d=fhan_Input->r*fhan_Input->h0*fhan_Input->h0;//d=rh^2;
  a0=fhan_Input->h0*fhan_Input->x2;//a0=h*x2
  y=x1_delta+a0;//y=x1+a0
  a1=sqrt(d*(d+8*ABS(y)));//a1=sqrt(d*(d+8*ABS(y))])
  a2=a0+Sign_ADRC(y)*(a1-d)/2;//a2=a0+sign(y)*(a1-d)/2;
  a=(a0+y)*Fsg_ADRC(y,d)+a2*(1-Fsg_ADRC(y,d));
  fhan_Input->fh=-fhan_Input->r*(a/d)*Fsg_ADRC(a,d)
                  -fhan_Input->r*Sign_ADRC(a)*(1-Fsg_ADRC(a,d));//得到最速微分加速度跟踪量
  fhan_Input->x1+=fhan_Input->h*fhan_Input->x2;//跟新最速跟踪状态量x1
  fhan_Input->x2+=fhan_Input->h*fhan_Input->fh;//跟新最速跟踪状态量微分x2
}

//原点附近有连线性段的连续幂次函数
float Fal_ADRC(float e,float alpha,float zeta)
{ 
   
    int16 s=0;
    float fal_output=0;
    s=(Sign_ADRC(e+zeta)-Sign_ADRC(e-zeta))/2;
    fal_output=e*s/(powf(zeta,1-alpha))+powf(ABS(e),alpha)*Sign_ADRC(e)*(1-s);
    return fal_output;
}




/************扩张状态观测器********************/
//状态观测器参数beta01=1/h beta02=1/(3*h^2) beta03=2/(8^2*h^3) ...
void ESO_ADRC(Fhan_Data *fhan_Input)
{ 
   
  fhan_Input->e=fhan_Input->z1-fhan_Input->y;//状态误差

  fhan_Input->fe=Fal_ADRC(fhan_Input->e,0.5,fhan_Input->h);//非线性函数,提取跟踪状态与当前状态误差
  fhan_Input->fe1=Fal_ADRC(fhan_Input->e,0.25,fhan_Input->h);

  /*************扩展状态量更新**********/
  fhan_Input->z1+=fhan_Input->h*(fhan_Input->z2-fhan_Input->beta_01*fhan_Input->e);
  fhan_Input->z2+=fhan_Input->h*(fhan_Input->z3
                                 -fhan_Input->beta_02*fhan_Input->fe
                                   +fhan_Input->b*fhan_Input->u);
 //ESO估计状态加速度信号,进行扰动补偿,传统MEMS陀螺仪漂移较大,估计会产生漂移
  fhan_Input->z3+=fhan_Input->h*(-fhan_Input->beta_03*fhan_Input->fe1);
}

void Nolinear_Conbination_ADRC(Fhan_Data *fhan_Input)
{ 
   
  float temp_e2=0;
  temp_e2=Constrain_Float(fhan_Input->e2,-3000,3000);
  fhan_Input->u0=fhan_Input->beta_1*Fal_ADRC(fhan_Input->e1,fhan_Input->alpha1,fhan_Input->zeta)
                +fhan_Input->beta_2*Fal_ADRC(temp_e2,fhan_Input->alpha2,fhan_Input->zeta);

}


void ADRC_Control(Fhan_Data *fhan_Input,float expect_ADRC,float feedback_ADRC)
{ 
   
    /*自抗扰控制器第1步*/
    /******** ** ** ** ** ** ********/
      /***** 安排过度过程,输入为期望给定, 由TD跟踪微分器得到: 过度期望信号x1,过度期望微分信号x2 ******/
      Fhan_ADRC(fhan_Input,expect_ADRC);

    /*自抗扰控制器第2步*/
    /******** * * **** * * ********/
      /************系统输出值为反馈量,状态反馈,ESO扩张状态观测器的输入*********/
      fhan_Input->y=feedback_ADRC;
      /***** 扩张状态观测器,得到反馈信号的扩张状态: 1、状态信号z1; 2、状态速度信号z2; 3、状态加速度信号z3。 其中z1、z2用于作为状态反馈与TD微分跟踪器得到的x1,x2做差后, 经过非线性函数映射,乘以beta系数后, 组合得到未加入状态加速度估计扰动补偿的原始控制量u *********/
      ESO_ADRC(fhan_Input);//低成本MEMS会产生漂移,扩展出来的z3此项会漂移,目前暂时未想到办法解决,未用到z3
    /*自抗扰控制器第3步*/
    /******** ** ** ** ** ** ********/
      /********状态误差反馈率***/
      fhan_Input->e0+=fhan_Input->e1*fhan_Input->h;//状态积分项
      fhan_Input->e1=fhan_Input->x1-fhan_Input->z1;//状态偏差项
      fhan_Input->e2=fhan_Input->x2-fhan_Input->z2;//状态微分项,
      /********线性组合*******/
     /* fhan_Input->u0=//fhan_Input->beta_0*fhan_Input->e0 +fhan_Input->beta_1*fhan_Input->e1 +fhan_Input->beta_2*fhan_Input->e2; */
      Nolinear_Conbination_ADRC(fhan_Input);
      /**********扰动补偿*******/
      //fhan_Input->u=fhan_Input->u0
      // -fhan_Input->z3/fhan_Input->b0;
      //由于MEMS传感器漂移比较严重,当beta_03取值比较大时,长时间z3漂移比较大,目前不加入扰动补偿控制量
      fhan_Input->u=Constrain_Float(fhan_Input->u0,-200,200);
}


版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/144311.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • phpstorm2021 通过 github 激活破解方法

    phpstorm2021 通过 github 激活破解方法,https://javaforall.net/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

    2022年3月15日
    101
  • rabbitmq集群部署详解_搭建hadoop集群的步骤

    rabbitmq集群部署详解_搭建hadoop集群的步骤集群搭建参考文档RabbitMQ集群搭建了解原理参考文档RabbitMQ集群原理(非常简洁优秀的总结)1.保证各个节点erlang版本一致。RabbitMQ基于erlang语言,必须保证各个节点erlang版本完全一致。2.可以跨操作系统建立集群。因RabbitMQ基于erlang运行,因此只要erlang版本一致即可,与操作系统无关。3.如果节点加入集群失败,请根据给出的错误原因对症解决。一般有以下几点:a.连接磁盘节点失败。…

    2025年10月23日
    5
  • navicatfor激活码(注册激活)

    (navicatfor激活码)2021最新分享一个能用的的激活码出来,希望能帮到需要激活的朋友。目前这个是能用的,但是用的人多了之后也会失效,会不定时更新的,大家持续关注此网站~https://javaforall.net/100143.htmlIntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,上面是详细链接哦~2K…

    2022年4月1日
    865
  • html段落空格怎么写,html怎么写空格

    html段落空格怎么写,html怎么写空格html写空格的方法:1、通过键入“空格”键在html网页中输入一个空格;2、通过空格字符代码“”在html中输入多个空格即可。本文操作环境:windows7系统、HTML5版、DellG3电脑。HTML中如何键入空格?一个空格的键入在html网页中一个空格,我们可以键入“空格”键即可实现。多个html空格字符如果在html中想实现多个空格间隙,如果是键入多个“空格”键,但最终也只…

    2022年6月17日
    34
  • 如果没人挖矿比特币会变成什么样[通俗易懂]

    如果没人挖矿比特币会变成什么样[通俗易懂]如果没人挖矿,比特币网络就无法出块,也无法转账,比特币网络将不复存在。当然这种情况并不会存在,因为出块意味着获得比特币奖励。只要比特币有价格就有人会投入成本来挖矿,并卖出挖到的比特币。有人使用比特币,从而进一步加强比特币的价值,且使用量越来越大。比特币网络就将一直存在。那么比特币网络有可能被摧毁吗。我们知道区块链是比特币的底层技术,而区块链具有不可篡改,数据可查的属性。那么摧毁比特币网络就只…

    2022年5月8日
    186
  • python偏函数理解_python进阶路线图

    python偏函数理解_python进阶路线图什么是偏函数partialpython中提供一种对于函数固定属性的函数偏函数的作用把一个函数的某些参数给固定住(也就是设置默认值),返回一个新的函数偏函数的语法使用偏函数必须先导入from

    2022年7月28日
    4

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号