TD非线性跟踪微分器的C代码实现

一、何为跟踪微分器

TD即time delay,具有时间延迟作用,跟踪微分器会提供两个信号:一个是过渡信号,另一个是过渡信号的微分信号。

过渡信号:即起过渡作用的信号。这里的过渡是连续的,显示在图像上的则是一条光滑曲线。

二、使用跟踪微分器的原因

本人用PID好长一段时间了,由于噪音对系统的影响,我对单独的PID控制效果不满意,考虑ADRC,但是ADRC需要的参数也太多,而调ADRC的参并不容易,一个系统调好了,另一个系统也要换个参数调,TD是内嵌于ADRC算法的一项,且调参简单,因此我采用了ADRC中的TD。

三、在STM32上的C代码实现

1、.c文件


/*跟踪微分信号器,简称TD(time delay)算法*/
//对信号起到过渡作用//
/*使用步骤*/
/*
定义
TD_conctrol ABCD[4];

初始化
for(uint i=0;i<4;i++)
create_TD(&ABCD[i],parameter);

进行输入和计算
TD_Run(&ABCD[i],given_value);

获取输出结果
x=TD_get_R1(&ABCD[i]);
xx=TD_get_R2(&ABCD[i]);
单环PID采用ABCD[i].R1作为输入,双环PID采用R1为外环输入,R2为内环输入

参数整定
只需改变parameter,    parameter越大,收敛速度越快,反之亦然
*/

#include "td.h"
#include "struct_typedef.h"

float fst(float x1, float x2, float r, float h)//期望  跟踪速度  最大跟踪速度  控制的时间间隔
{

float y, d, a0, a1, a, sy, sa, result;
	y = x1 + h * x2;
	d = r * h*h;
	d = (d==0) ? 0.000001f : d;
	a0 = sqrtf(d*(d + 8.f * fabsf(y)));
	a1 = 0.5f *(a0 - d)* sign(y) + h * x2;
	sy = 0.5f *(sign(y+d)- sign(y-d));
	a = (h * x2 + y - a1)* sy + a1;
	sa = 0.5f *(sign(a+d)- sign(a-d));
	result = -r *((a / d - sign(a))* sa + sign(a));

	return result;
}



static void TD_cal(TD_conctrol * TD)   //计算得出预估的跟踪速度 预估的跟踪加速度 当前跟踪值 当前跟踪速度  
{
	TD->td.V1 = TD->td.R2;
	TD->td.V2 = fst(TD->td.R1-TD->Target, TD->td.R2, TD->td.R, TD->Time.Dtime);
	TD->td.R1 += TD->Time.Dtime * TD->td.V1;
	TD->td.R2 += TD->Time.Dtime * TD->td.V2;
}


static void getTimeStamp(TD_conctrol * TD)  
{
	TD->Time.Time_p = TD->Time.Time_n;
	TD->Time.Time_n = HAL_GetTick();
	TD->Time.Dtime = (TD->Time.Time_n - TD->Time.Time_p)/ timeradio;
}

static void TD_param_init(TD_conctrol * TD, float R)
{
	memset(TD, 0, sizeof(TD_conctrol));
	TD->td.R = R;
}

static void TD_inputStatus(TD_conctrol * TD, float target)
{
	TD->Lastnot0_target = TD->Target==0 ? TD->Lastnot0_target : TD->Target;
	TD->Target = target;
	getTimeStamp(TD);
}

void TD_Run(TD_conctrol * TD, float target)
{
	TD_inputStatus(TD, target);
	TD_cal(TD);

}

static void reset_TD(TD_conctrol * TD, float R)
{
	TD->td.R = R;
}

void create_TD(TD_conctrol* TD,float R)
{
	reset_TD(TD,R);
	TD_param_init(TD,R);

}

float TD_get_R1(TD_conctrol * TD)
{
	return TD->td.R1;
}

float TD_get_R2(TD_conctrol * TD)
{
	return TD->td.R2;
}

2、.h文件


#include <math.h>
#include <string.h>
#include <stdint.h>
#include "stm32f4xx_hal.h"

#define timeradio 1000.f
#define sign(x) ((x)>0?1:((x)<0?-1:1))
/*****************************/
typedef struct 
{
	float Target; //目标值
	float Lastnot0_target;  // 最后一次非零的目标值

	struct 
	{
		float R1;  // 跟踪微分器当前跟踪值
		float R2;  // 跟踪微分器当前跟踪速度
		float V1;  // 跟踪微分器预估的跟踪速度
		float V2;  // 跟踪微分器预估的跟踪加速度
		float R;   // *跟踪微分器最大跟踪速度
	}td;  // 跟踪微分器子结构

   struct 
	{
		uint32_t Time_p;  // 上次控制的时刻
		uint32_t Time_n;  // 本次控制的时刻
		float Dtime;      // 两次控制之间的时间
	}Time;


}TD_conctrol;

	
static void getTimeStamp(TD_conctrol * TD); // 记录当前的时间戳
static void TD_cal(TD_conctrol * TD);  // 计算跟踪微分器部分
static void TD_inputStatus(TD_conctrol * TD, float target);  // 输入当前状态
void TD_Run(TD_conctrol * TD, float target);  //输入目标值运行
static void reset_TD(TD_conctrol * TD, float new_R);      	// 重设跟踪微分器参数
static void TD_param_init(TD_conctrol * TD, float R);
float TD_get_R1(TD_conctrol * TD);
float TD_get_R2(TD_conctrol * TD);
void create_TD(TD_conctrol* TD,float R);

#endif

四、参考文献

跟踪微分器icon-default.png?t=N7T8http://t.csdnimg.cn/zBU4X

【ADRC】跟踪微分器icon-default.png?t=N7T8http://t.csdnimg.cn/NzMTdADRC的C代码开源icon-default.png?t=N7T8https://github.com/zzqzzqzzq2002/ThisisADRC

  • 7
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
下面是一个使用MATLAB编写的具有跟踪微分、扩张状态观测非线性组合的二自抗扰PID控制的示例代码: ```matlab % 系统模型 num = [1]; % 系统传递函数的分子多项式系数 den = [1, 1, 1]; % 系统传递函数的分母多项式系数 G = tf(num, den); % 创建传递函数模型 % 设计控制参数 Kp = 1; % 比例增益 Ki = 1; % 积分增益 Kd = 1; % 微分增益 beta = 1; % 抗扰性增益 % 跟踪微分参数 Td = 0.1; % 微分时间常数 % 扩张状态观测参数 L = 1; % 观测增益 % 创建跟踪微分 D = tf([Td, 1], [Td, 0]); % 创建扩张状态观测 A = [-2, 0; 0, -3]; % 系统的矩阵A B = [1; 1]; % 系统的矩阵B C = [1, 0]; % 系统的矩阵C Dx = [0; 0]; % 系统的矩阵Dx E = [1, 0]; % 扩张状态观测的矩阵E Gx = ss(A, [B, E], C, [Dx, zeros(size(E))]); % 创建扩张状态观测模型 % 创建非线性组合二阶自抗扰PID控制 C = nl2syss(pidstd(Kp, Ki, Kd, beta)) * D * Gx; % 将控制和系统模型连接起来 T = feedback(G*C, 1); % 绘制阶跃响应曲线 t = 0:0.01:10; % 时间向量 step(T, t); ``` 在这个示例中,我们首先定义了一个二阶系统模型,并设定了系统的传递函数分子多项式系数和分母多项式系数。然后,我们选择了合适的比例增益(Kp)、积分增益(Ki)、微分增益(Kd)和抗扰性增益(beta)来设计非线性组合的二阶自抗扰PID控制。 在控制设计中,我们引入了跟踪微分(D)和扩张状态观测(Gx)。跟踪微分用于改善系统的稳态误差和抗高频干扰能力。扩张状态观测用于估计系统的未测量状态,提供更好的控制性能。 最后,将控制和系统模型连接在一起,并绘制了控制系统的阶跃响应曲线。 请注意,这只是一个简单的示例,具体的控制参数设计需要根据实际系统的需求进行调整。另外,非线性组合二阶自抗扰PID控制的设计可能需要更复杂的方法和工具。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值