반응형
이전 글에서 다룬 Anti-Windup algorithm을 적용한 PID 제어기에 대해서 구현해보았다.
어떤 특성이 있는지 그래프와 함께 볼 수 있다.
실험 코드 및 구현
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <math.h>
using namespace std;
double dt = 0.01;
double Kp = 1.00;
double Ki = 2.00;
double Kd = 0.00;
double y_min = -3.00;
double y_max = 3.00;
double pid_aw(double y, double y_cmd)
{
static double integral = 0;
// Calculate error
double error = y_cmd - y;
// Proportional term
double Pout = Kp * error;
// Integral term
integral += Ki * error * dt;
double Iout = integral;
double out_tmp = Pout + Iout;
// Anti-Windup Algorithm
// Restrict to max/min
if (out_tmp > y_max)
integral = fmax(y_min, fmin(y_max - Pout, y_max));
else if (out_tmp < y_min)
integral = fmax(y_min, fmin(y_min - Pout, y_max));
// Save error to previous error
Iout = integral;
double out = Pout + Iout;
return out;
}
double pid(double y, double y_cmd)
{
static double integral = 0;
// Calculate error
double error = y_cmd - y;
// Proportional term
double Pout = Kp * error;
// Integral term
integral += Ki * error * dt;
double Iout = integral;
// Save error to previous error
Iout = integral;
double out = fmax(y_min, fmin(Pout + Iout, y_max));
return out;
}
int main()
{
FILE* fid = fopen("test.txt", "w");
double TimeEnd = 20.0;
double u = 1;
double x = 0;
double x_prev = 0;
double y = 0.0;
double x1 = 0;
double x1_prev = 0;
double u1_cmd = 0;
double y1 = 0;
double x2 = 0;
double x2_prev = 0;
double u2_cmd = 0;
double y2 = 0;
double alpha = 0.01;
double time = 0;
for (int i = 0; i < (int)(TimeEnd / dt); i++) {
if (time < 4)
u = 1;
else if (time < 6)
u = -1;
else if (time < 8)
u = 2;
else if (time < 12)
u = -2;
else
u = 0;
fprintf(fid, "%10.2f %10.6f %10.6f %10.6f %10.6f %10.6f %10.6f\n", time, u, y, y1, u1_cmd, y2, u2_cmd);
time += dt;
x = (1.00 - alpha) * x_prev + (alpha)*u;
x_prev = x;
y = x * 0.5;
// PID with Anti-windup algorithm
u1_cmd = pid_aw(y1, u);
x1 = (1.00 - alpha) * x1_prev + (alpha)*u1_cmd;
x1_prev = x1;
y1 = x1 * 0.5;
// Pure PID
u2_cmd = pid(y2, u);
x2 = (1.00 - alpha) * x2_prev + (alpha)*u2_cmd;
x2_prev = x2;
y2 = x2 * 0.5;
}
fclose(fid);
}
데이터 비교
시계열에 따른 응답은 그래프와 같다.
y1, u1_cmd는 Anti-windup 알고리즘을 넣은 PID제어기,
y2, u2_cmd는 순수 PID 제어기이다.
0~8초 구간에서는 제어기 응답이 유사하지만,
8~16초 구간을 보면 초록색 선 (u2_cmd)은 적분기 누적을 벗어나는데 시간이 걸려서
노란 선(u1_cmd)보다 느리게 응답이 따라오는 것을 볼 수 있다.
이로 인해 시스템 응답 또한 상대적으로 느린 것을 볼 수 있다.
끝.
** EOF **
728x90
'G.N.C.' 카테고리의 다른 글
이산 선형 칼만 필터 중간 유도 정리 (0) | 2024.04.11 |
---|---|
Van der Pol Oscillator (0) | 2024.03.15 |