반응형
PID 제어란
비례 / 적분 / 미분 제어로서 P I D 의미를 갖는다.
자동제어로 센서로부터 I/O 신호를 읽고 목표치와 비교하며, 운전 등 조작량을 제어하므로써
목표 값에 근사하게 유지하는 방식이다.
즉, 조작량을 비례 한 크기로 제어하는 방식이다.
PID 제어를 증명하려면 사실 어렵긴하지만, 이 글에서는 PD제어에 대하여 설명 할 것이다.
PD 제어
PD 제어는 Proportional Derivative 제어 (비례 미분 제어) 로서, 아래의 수식을 갖는다.
별칭으로는 폭주하는 제어를 잠재우기 위한 미분제 라고도 하며,
실제로 모터 사용 시 아래와 같이 모듈레이션이 좋지 않은걸 스코프로 측정 할 수 있다.
이러한 경우 모터 구동 시 RPM 이 일정하지 않으며, 소음 등이 정상 제어가 되지 않는다.
이럴때 바로, PID 제어 중 PD 제어가 필요한 것이다.
PID 제어로 PID 및 Target 값은 상수로 사용된다.
MotorOutput.RPM.->En0 = (60/(((float)MotorOutput.RPM->TargetRPM)*0x000004)) - (60/(((float)MotorOutput.RPM->CurrentRPM)*0x000004));
MotorOutput.RPM.->En0 = MotorOutput.RPM.->En0>>4;
if(SpeedControl == SPDCTL_ON)
xQ = PAR_PID_END;
else
xQ = PAR_PID_AN;
MotorOutput.RPM.->OffsetDuty = ((float)((((xQ * MotorOutput.RPM.->En0 - MotorOutput.RPM.->En1 + MotorOutput.RPM.->En2)/8)*16)/183 * 128) - 0x4000);
if(MotorOutput.RPM.->En0 >= 250){
MotorOutput.RPM.->En0 = 250;
}else if(MotorOutput.RPM.->En0 =< -250){
MotorOutput.RPM.->En0 = -250;
}
//---------------------------------------------------------------------
// 이전 에러량 비교
//---------------------------------------------------------------------
MotorOutput.RPM.->En2 = MotorOutput.RPM.->En1;
MotorOutput.RPM.->En1 = MotorOutput.RPM.->En0;
//---------------------------------------------------------------------
// 현재 에러량 계산
//---------------------------------------------------------------------
MotorOutput.RPM.->En0 = (float)((float)MotorOutput.RPM->CurrentRPM - (float)MotorOutput.RPM->TargetRPM);
//---------------------------------------------------------------------
// p 계산
//---------------------------------------------------------------------
fTerm_p = Kp * MotorOutput.RPM->En0;
if(fTerm_p <= -1024){
fTerm_p = -1024;
}else if(fTerm_p >= 1024){
fTerm_p = 1024;
}
//---------------------------------------------------------------------
// i 계산
//---------------------------------------------------------------------
fTerm_i = Ki * ((MotorOutput.RPM->En0 + MotorOutput.RPM->En1 + MotorOutput.RPM->En2)/3);
if(fTerm_i <= -512){
fTerm_i = -512;
}else if(fTerm_i >= 512){
fTerm_i = 512;
}
//---------------------------------------------------------------------
// d 계산
//---------------------------------------------------------------------
fTerm_d = ((MotorOutput.RPM->En0 - MotorOutput.RPM->En1 - (MotorOutput.RPM->En1 - MotorOutput.RPM->En2));
fTerm_d = Kd * fTerm_d;
if(fTerm_d <= -512){
fTerm_d = -512;
}else if(fTerm_d >= 512){
fTerm_d = 512;
}
//---------------------------------------------------------------------
// PID 계산
//---------------------------------------------------------------------
if(Kp != 0))
{
MotorOutput.RPM.->OffsetDuty = (float)MotorOutput.RPM.->OffsetDuty + (fTerm_p + fTerm_i + fTerm_d);
}
tempDuty = 0x4000;
tempDuty = tempDuty + MotorOutput.RPM->OffsetDuty;
if(tempDuty >= 0x8000){
tempDuty = 0x8000;
}else if(tempDuty <= 0){
tempDuty = 0;
}
PWM_Set_Duty((int)tempDuty);
목표 값 : 3000 rpm
아래는 위의 코드를 통해 실제 펌웨어에 적용하였을때의 측정 결과이다.
3000 RPM 으로 목표 값에 거의 수렴하는 것을 볼 수 있다.
이로서 원하는 RPM 제어를 하기 위해 PD 제어 하는 것을 볼 수 있었다.
실제 모터를 구동하는 펌웨어에서 자주 사용되며, 모터에 따라 사양도 다르고
많은 테스트를 거쳐야 한다.
이것으로 PD 제어 방식을 마치겠다.
반응형