1 参考链接
Chenglin Li:自抗扰控制理论(十七)使用C++实现LADRC封装类
2 相关程序
#include<stdio.h>
#include<stdlib.h>
//#include<math.h>
//ODE参数数量声明
#define ODE_NUM 2
//静态全局变量的声明
static double _h;// 步长
static double _t1; //初始和末尾时刻
//LESO和控制器参数
static double _ref;
static double _y;
static double _u;
static double _Wo;//LESO带宽
static double _Wc;//控制带宽
static double _b;//控制输入系数
static double beta_Wo[ODE_NUM + 1];//LESO系数
static double beta_Wc[ODE_NUM];//控制器系数
//static double *_z[ODE_NUM + 1] = { 0 }; //表示LESO返回值
static double *_z=NULL;
static double _x[ODE_NUM + 1] = { 0 };////表示RK计算的当前节点值
static double _t;
static double _s[ODE_NUM + 1] = { 0 };
static double *y1 = NULL, *y2 = NULL, *y3 = NULL, *y4 = NULL;
//子函数声明
void calcCoefficient();
double powj(double Wo, int n);
double comb(int n, int m);
double jiecheng(int n);
double* LESO(double t, double x[]);
void calc();
void Lx();
void Controller();
double Output();
//主函数
int main()
{
//参数初始化
_u = 0;
_Wo = 10;
_Wc = 10;
_b = 1;
_y = 0.2;
_h = 0.02;
_ref = 1;
Controller();//计算函数
_u = Output();
printf("u=%.3f\n", _u);
return 0;
}
//控制量输出
double Output()
{
return _u;
}
//控制器计算函数
//vector<double> fx(double t, double x[]);
void Controller()
{
int i;
calcCoefficient();
calc();
_u = _z[ODE_NUM]+beta_Wc[0]*(_z[0]-_ref);//取z3
for (i = 1; i < ODE_NUM; i++)
{
_u = _u + beta_Wc[i] * _z[i];
}
_u = -_u / _b;
}
//迭代计算函数
void calc()
{
int j;
//vector<double> s(ODE_NUM+1,0);
Lx();
//vector<double> _s(ODE_NUM + 1, 0);
for (j = 0; j<ODE_NUM + 1; j++)
_x[j] = _x[j] + _s[j];//更新当前ODE计算的值
_t = _t + _h;// 更新时间节点
_z = _x;//返回当前节点解算的LESO
}
//RungeKutta计算所需项
//vector<double> LADRC::Lx(double _t, vector<double> _x)
void Lx()
{
int j;
//vector<double> x1(ODE_NUM + 1, 0), x2(ODE_NUM + 1, 0), x3(ODE_NUM + 1, 0);
//vector<double> y1(ODE_NUM + 1, 0), y2(ODE_NUM + 1, 0), y3(ODE_NUM + 1, 0), y4(ODE_NUM + 1, 0);// 使用vector数据类型,子函数可返回数组
//N = ODE_NUM + 1;
//vector<double> _s(ODE_NUM + 1, 0);//
double x1[ODE_NUM + 1] = { 0 }, x2[ODE_NUM + 1] = { 0 }, x3[ODE_NUM + 1] = { 0 };
y1 = LESO(_t, _x);
for (j = 0; j<ODE_NUM + 1; j++)
x1[j] = _x[j] + _h / 2 * y1[j];
y2 = LESO(_t + _h / 2, x1);
for (j = 0; j<ODE_NUM + 1; j++)
x2[j] = _x[j] + _h / 2 * y2[j];
y3 = LESO(_t + _h / 2, x2);
for (j = 0; j<ODE_NUM + 1; j++)
x3[j] = _x[j] + _h*y3[j];
y4 = LESO(_t + _h, x3);
for (j = 0; j<ODE_NUM + 1; j++)
_s[j] = _s[j] + y1[j];
for (j = 0; j<ODE_NUM + 1; j++)
_s[j] = _s[j] + 2 * y2[j];
for (j = 0; j<ODE_NUM + 1; j++)
_s[j] = _s[j] + 2 * y3[j];
for (j = 0; j<ODE_NUM + 1; j++)
_s[j] = _s[j] + y4[j];
for (j = 0; j < ODE_NUM + 1; j++)
_s[j] = _s[j] * _h / 6;
}
//计算观测器和控制器系数
void calcCoefficient()
{
int i;
//生成LESO系数
for (i = 0; i < ODE_NUM + 1; i++)
{
beta_Wo[i] = powj(_Wo, i + 1)*comb(ODE_NUM + 1, i + 1);
}
//生成LESO系数
for (i = 0; i < ODE_NUM + 1; i++)
{
beta_Wo[i] = powj(_Wc, i + 1)*comb(ODE_NUM + 1, i + 1);
}
//控制律系数
for (i = 0; i < ODE_NUM; i++)
{
beta_Wc[i] = powj(_Wc, ODE_NUM - i)*comb(ODE_NUM, ODE_NUM - i);
}
for (i = 0; i < ODE_NUM; i++)
printf("beta_Wc[%d]=%.3f\n",i,beta_Wc[i]);
for (i = 0; i < ODE_NUM + 1; i++)
printf("beta_Wo[%d]=%.3f\n", i,beta_Wo[i]);
}
// 计算幂函数
double powj(double Wo, int n)
{
int i;
double z = 1;
if (n == 0)
return 1;
else
{
for (i = n; i >= 1; i--)
{
z = z*Wo;
}
}
return z;
}
//组合数计算公式
double comb(int n, int m)
{
if (n < 0 || n < 0)
return 0;
else
return jiecheng(n) / jiecheng(m) / jiecheng(n - m);
}
//计算阶乘子函数
double jiecheng(int n)
{
if (n < 0)
return 0;
else if (n == 0 || n == 1)
return 1.0;
else
return n*jiecheng(n - 1);
}
//LESO微分方程组定义
double* LESO(double t, double x[])
{
int i;
double e;
double dx[ODE_NUM + 1] = { 0 };//
e = _y - _x[0];
for (i = 0; i < ODE_NUM - 1; i++)
{
dx[i] = beta_Wo[i] * e + x[i + 1];
}
dx[ODE_NUM - 1] = beta_Wo[ODE_NUM - 1] * e + _b*_u;
dx[ODE_NUM] = beta_Wo[ODE_NUM] * e;
return dx;
}
评论(0)
您还未登录,请登录后发表或查看评论