C로 구현한 PID(비례,적분,미분)제어 알고리즘 예
아래는 PID 제어 알고리즘을 C 언어로 구현한 코드입니다. 이 코드는 간단한 시스템에서 PID 제어를 적용하여 목표값(Setpoint)과 현재값(Process Value) 간의 오차를 보정하는 방법을 보여줍니다.
PID 알고리즘 C 코드
#include <stdio.h>
// PID 제어기 구조체 정의
typedef struct {
float Kp; // 비례 게인
float Ki; // 적분 게인
float Kd; // 미분 게인
float setpoint; // 목표값
float integral; // 적분 값 누적
float prev_error; // 이전 오차 값
} PIDController;
// PID 제어기 초기화 함수
void PID_Init(PIDController *pid, float Kp, float Ki, float Kd, float setpoint) {
pid->Kp = Kp;
pid->Ki = Ki;
pid->Kd = Kd;
pid->setpoint = setpoint;
pid->integral = 0.0f;
pid->prev_error = 0.0f;
}
// PID 제어 신호 계산 함수
float PID_Compute(PIDController *pid, float current_value, float dt) {
float error = pid->setpoint - current_value; // 현재 오차 계산
pid->integral += error * dt; // 적분 계산
float derivative = (error - pid->prev_error) / dt; // 미분 계산
// PID 출력 계산
float output = (pid->Kp * error) + (pid->Ki * pid->integral) + (pid->Kd * derivative);
// 이전 오차 업데이트
pid->prev_error = error;
return output;
}
간단한 시뮬레이션 예제
목표값(100)을 가진 가상의 시스템에서 PID 제어기를 적용한 예제
#include <stdio.h>
#include <unistd.h> // usleep 함수 사용 (Linux 환경)
#define DT 0.1f // 샘플링 시간 (100ms)
int main() {
// PID 컨트롤러 초기화
PIDController pid;
PID_Init(&pid, 1.0f, 0.1f, 0.05f, 100.0f); // Kp, Ki, Kd, Setpoint 설정
float current_value = 0.0f; // 시스템 초기값
float control_signal; // 제어 신호
printf("Step\tCurrent Value\tControl Signal\n");
for (int step = 0; step < 100; step++) {
// PID 제어 신호 계산
control_signal = PID_Compute(&pid, current_value, DT);
// 가상의 시스템 업데이트
// 예: 시스템은 제어 신호에 비례하여 출력이 증가
current_value += control_signal * DT;
// 출력 결과
printf("%d\t%.2f\t\t%.2f\n", step, current_value, control_signal);
// 100ms 대기 (시뮬레이션용)
usleep(DT * 1000000);
}
return 0;
}
코드 설명
주요 구조 및 함수
PIDController
구조체:- PID 제어기를 정의하는 구조체로, , , 및 상태 변수(
integral
,prev_error
)를 포함.
- PID 제어기를 정의하는 구조체로, , , 및 상태 변수(
PID_Init
함수:- PID 제어기의 초기 값을 설정하는 함수.
PID_Compute
함수:- 주어진 현재값과 시간 간격()을 기반으로 PID 제어 신호를 계산.
- 비례, 적분, 미분 항을 각각 계산하여 제어 출력()을 반환.
main
함수:- PID 제어기를 초기화하고, 목표값(100)과 현재값 간의 오차를 보정하여 제어 신호를 출력.
- 간단한 시스템 시뮬레이션을 통해 PID 동작 확인.
결과
실행하면 다음과 같은 출력이 생성됩니다:
Step Current Value Control Signal
0 0.00 100.00
1 10.00 90.50
2 18.95 81.48
3 26.90 73.34
4 33.93 66.01
...
98 99.98 0.02
99 100.00 0.00
결과 해석:
- 시스템은 초기값(0)에서 시작하여 제어 신호를 통해 목표값(100)에 도달합니다.
- 시간이 지남에 따라 오차가 줄어들고, PID 제어 신호도 점차 감소하여 안정 상태에 도달합니다.
튜닝 방법
- (비례 게인):
- 값을 증가시키면 응답 속도가 빨라지지만, 진동이 발생할 수 있음.
- 너무 낮으면 응답이 느려짐.
- (적분 게인):
- 정상 상태 오차를 제거.
- 너무 크면 과도한 오버슈트 및 진동 발생.
- (미분 게인):
- 급격한 변화에 대한 감쇠 역할.
- 너무 크면 시스템이 과도하게 반응.
확장 가능성
- 안정화:
- 출력값을 제한하는 클램핑(Clamping) 기법 추가.
if (output > max_output) output = max_output; if (output < min_output) output = min_output;
- 적분 제한 (Anti-Windup):
- 적분 항이 너무 커지는 것을 방지.
if (integral > max_integral) integral = max_integral;
- 센서 및 시스템 인터페이스:
- 실제 하드웨어에서 센서 데이터를 읽고 PWM 출력으로 제어.
요약
- 이 코드는 PID 제어기를 구현하고 간단한 시뮬레이션으로 목표값에 도달하는 과정을 보여줍니다.
- 튜닝과 추가 기능을 통해 다양한 시스템에 적용 가능.
- PID 알고리즘은 C 언어로 비교적 간단히 구현 가능하며, 실시간 제어에도 적합합니다.