写一个adrc输出值为pwm的C语言代码
时间: 2024-03-24 21:36:18 浏览: 164
以下是一个简单的ADRC输出PWM的C语言代码示例:
```c
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define PI 3.1415926
// ADRC参数
double h = 0.001;
double r = 100;
double beta = 1.5;
double gamma = 1.5;
// 控制器输出限幅
double u_max = 100;
double u_min = -100;
// PWM参数
double T = 0.01; // PWM周期
double dt = 0.001; // PWM时间分辨率
// 反馈控制器
double adrc(double y, double ref)
{
static double x1 = 0, x2 = 0, x3 = 0;
static double last_u = 0, last_e = 0;
double e = ref - y; // 计算误差
// 计算观测量
double z1 = x1 + h * (x2 - r * sign(x3 - e));
double z2 = x2 + h * (r * sign(x3 - e) - beta * x2 + gamma * (ref - last_u));
double z3 = x3 + h * (-r * sign(x3 - e));
// 计算控制器输出
double u = z1 + z2 + z3;
// 限幅
if (u > u_max) {
u = u_max;
} else if (u < u_min) {
u = u_min;
}
// 更新变量
x1 = x1 + h * (x2 - r * sign(x3 - e));
x2 = x2 + h * (r * sign(x3 - e) - beta * x2 + gamma * (ref - u));
x3 = x3 + h * (-r * sign(x3 - e));
last_u = u;
last_e = e;
return u;
}
// PWM函数
double pwm(double u)
{
static double t = 0;
static int k = 0;
double u_pwm;
// 计算PWM输出
if (u > 0) {
u_pwm = u_max;
} else {
u_pwm = u_min;
}
if (fabs(u) > u_max) {
u_pwm = u_pwm;
} else {
t += dt;
if (t >= T) {
t = 0;
k++;
}
if (k % 2 == 1) {
u_pwm = u_pwm;
} else {
u_pwm = -u_pwm;
}
}
return u_pwm;
}
int main()
{
double y = 0, ref = 10; // 初始状态和期望值
double u, u_pwm;
while (1) {
// 计算控制器输出
u = adrc(y, ref);
// PWM输出
u_pwm = pwm(u);
// 计算被控对象状态
y = y + h * (-y + u_pwm);
printf("u = %lf, u_pwm = %lf, y = %lf\n", u, u_pwm, y);
// 延时
usleep(1000);
}
return 0;
}
// 符号函数
double sign(double x)
{
if (x > 0) {
return 1;
} else if (x < 0) {
return -1;
} else {
return 0;
}
}
```
该程序实现了一个简单的ADRC控制器,控制一个被控对象的状态。控制器的输出经过PWM模块进行转换,生成PWM信号控制被控对象。在程序中,使用了符号函数sign(x),该函数返回x的符号,即1、0或-1。
阅读全文