3. 倾转机构PID控制器设计
任务定义
倾转机构在eVTOL过渡飞行中承担旋翼从垂直升力位到水平巡航位的连续偏转,其角度跟踪品质直接影响过渡走廊的安全性。本案例要求设计一个位置式PID控制器,使倾转角度在阶跃指令下实现快速跟踪且无超调,并给出可执行的调参路径与验证方法。
被控对象模型
倾转机构简化为带惯量与阻尼的二阶系统,传递函数为:
G(s) = ωn² / (s² + 2ζωn·s + ωn²)
其中ωn=8 rad/s(机构固有频率),ζ=0.35(欠阻尼),电机驱动饱和限幅为±12 rad/s²。控制周期Ts=1ms,采用零阶保持器离散化。
控制器设计
采用位置式PID,控制律为:
u(k) = Kp·e(k) + Ki·Σe(i)·Ts + Kd·(e(k)-e(k-1))/Ts
其中e(k)=θ_ref(k)-θ(k)。为避免微分冲击,对角度指令侧不施加微分,仅对反馈角度求导(即微分先行结构)。积分项设置抗饱和限幅,当输出达到执行器边界时冻结积分累加。
代码实现
#include <stdio.h>
#include <math.h>
#define Ts 0.001f
#define SAT_UPPER 12.0f
#define SAT_LOWER -12.0f
typedef struct {
float Kp, Ki, Kd;
float integral;
float prev_error;
float prev_theta;
float out;
} PID_t;
void PID_Init(PID_t *pid, float kp, float ki, float kd) {
pid->Kp = kp; pid->Ki = ki; pid->Kd = kd;
pid->integral = 0.0f;
pid->prev_error = 0.0f;
pid->prev_theta = 0.0f;
pid->out = 0.0f;
}
float PID_Update(PID_t *pid, float theta_ref, float theta) {
float error = theta_ref - theta;
float d_theta = (theta - pid->prev_theta) / Ts; // 微分先行
float P = pid->Kp * error;
float I = pid->Ki * pid->integral;
float D = -pid->Kd * d_theta;
float u = P + I + D;
// 抗饱和:输出限幅时冻结积分
if (u > SAT_UPPER || u < SAT_LOWER) {
// 积分不累加
} else {
pid->integral += error * Ts;
}
// 输出限幅
if (u > SAT_UPPER) u = SAT_UPPER;
if (u < SAT_LOWER) u = SAT_LOWER;
pid->prev_error = error;
pid->prev_theta = theta;
pid->out = u;
return u;
}
// 被控对象离散化模拟(双线性变换)
float Plant_Step(float theta, float theta_dot, float u, float *theta_dot_new) {
float omega_n = 8.0f;
float zeta = 0.35f;
float theta_ddot = omega_n*omega_n*u - 2*zeta*omega_n*theta_dot - omega_n*omega_n*theta;
*theta_dot_new = theta_dot + theta_ddot * Ts;
return theta + (*theta_dot_new) * Ts;
}
int main() {
PID_t pid;
// 初始调参:Kp=2.0, Ki=0.5, Kd=0.15
PID_Init(&pid, 2.0f, 0.5f, 0.15f);
float theta = 0.0f;
float theta_dot = 0.0f;
float theta_ref = 1.0f; // 阶跃目标:1 rad
float u = 0.0f;
float theta_dot_new;
printf("time,theta,u\n");
for (int i = 0; i < 3000; i++) { // 仿真3秒
u = PID_Update(&pid, theta_ref, theta);
theta = Plant_Step(theta, theta_dot, u, &theta_dot_new);
theta_dot = theta_dot_new;
if (i % 50 == 0) {
printf("%.3f,%.4f,%.4f\n", i*Ts, theta, u);
}
}
return 0;
}
调参方法与判定标准
调参目标为:上升时间tr<0.4s,超调量σ=0%,稳态误差ess<0.01 rad。采用先比例、后积分、再微分的顺序:
- 置Ki=Kd=0,逐步增大Kp至系统临界振荡(约Kp=4.5),记录振荡周期Tcr≈0.78s;
- 按Ziegler-Nichols经验公式取Kp=0.6×4.5=2.7,Ki=Kp/(0.5×Tcr)≈6.9,Kd=Kp×0.125×Tcr≈0.26;
- 因目标要求无超调,将Kp降至2.0,Ki降至0.5,Kd设为0.15作为初始值,再微调:增大Kd抑制超调,减小Ki避免积分过冲。
经上述初始参数仿真,θ在约0.35s到达0.98 rad,无超调,稳态误差小于0.005 rad,满足指标。若实际机构存在非线性摩擦,需在仿真中增加库仑摩擦项并重新整定。
验证方法
编译运行以上代码:gcc tilt_pid.c -o tilt_pid -lm && ./tilt_pid。观察输出数据:θ列在0.4s内单调趋近1.0且不越过1.0,即判定无超调;稳态时θ与1.0的差值小于0.01即满足精度。将输出导入Excel或Python绘制θ-t曲线,可直观确认跟踪品质。
落地与验证
将代码保存为tilt_pid.c,编译运行后观察终端输出的三列数据。判定通过条件:θ列最大值不超过1.0(无超调),θ首次到达0.98 rad的时间小于0.4s,最后500个采样点的θ与1.0之差的值均小于0.01。若超调不为零,降低Kp或增大Kd;若上升过慢,增大Kp或适当增大Ki但需监控超调趋势。