크고 예측할 수없는 이상 현상이있는 PID 제어 루프


10

짧은 질문
달리 균일 한 제어 영역 내에서 매우 큰 이상 (크기 차수)을 처리하는 일반적인 방법이 있습니까?

배경
저는 일반적으로 균일 한 제어 영역에서 모터를 구동하는 제어 알고리즘을 연구하고 있습니다. 로드가 적거나 최소 인 PID 제어는 훌륭하게 작동합니다 (빠른 응답, 오버 슈트가 거의 없음). 내가 겪고있는 문제는 일반적으로 하나 이상의 높은로드 위치가 있다는 것입니다. 위치는 설치하는 동안 사용자에 의해 결정되므로 언제 / 어디서 기대하는지 알 수있는 합리적인 방법이 없습니다.

높은 부하 위치를 처리하도록 PID를 조정하면로드되지 않은 영역에서 큰 오버 슈트가 발생합니다 (완전히 예상 됨). 이동 중에 오버 슈트 해도 괜찮지 만 인클로저에는 기계적인 하드 스톱이 없습니다. 하드 스톱이 없다는 것은 심각한 오버 슈트가 발생하면 제어 암이 모터에서 분리 될 수 있음을 의미합니다.

내가 프로토 타이핑하는 것

  • 중첩 된 PID (목표에서 멀리 떨어져있을 때는 매우 공격적이며 가까이있을 때는 보수적 임)
  • 멀리 있으면 고정 게인, 닫으면 PID
  • 보수적 PID (무부하 작동) + PID가 목표를 달성하거나 빠른 변화율이 감지 될 때까지 (즉, 높은 부하 영역을 떠날 때까지) 추가 에너지를 적용 할 수있는 외부 제어 장치

한계

  • 전체 여행 정의
  • 하드 스톱을 추가 할 수 없습니다 (현재 시점)
  • 오류는 절대 0으로되지 않을 것입니다
  • 10 % 미만의 이동으로 높은 하중을 얻을 수있었습니다 ( "실행 시작"이 없음).

답변:


2

미분 항으로 작업 할 때 오차 계산에 오차가 누적되지 않는 것 같으며 미분 항만 공정의 빠른 변화에 반응 할 수 있으므로이 값을 수정해야 할 수 있습니다.

내가 당신의 코드를 올바르게 찾으면

// Determine the error delta
dE = abs(last_error - new_error);
last_error = new_error;

PID를 구현하는 전통적인 방식 인 항상 현재 오류를 기준으로 제어 항을 계산합니다. 어쨌든 I 용어가 누적 오류를 처리해야하기 때문에 괜찮습니다.

그러나 시도해 볼 수있는 다음 아이디어를 생각해 낸 고객이 있습니다. 보다 적극적인 변경이 필요한 프로세스 곡선 부분이 있으므로 D 부분 오류도 누적되도록 할 수 있습니다.

if(TD)                                                 // Calculate D term
{  
   Last_C += (Error - Last_C) / TD;                    // D term simulates
   Dterm = (Error - Last_C) * KD;                      // capacitor discharging
}
else    
   Dterm = 0;                                          // D term is OFF (TD is 0)

여기서 주목해야 할 두 가지 흥미로운 점이 있습니다.

  • TD 값은 미분 게인 (KD)이 아니라 미분 시간, 오차가 누적되는 시간을 제어하는 ​​사용자 상수입니다. 0으로 설정하면 KD 게인 값 설정을 무시하고 PID의 D 부분이 비활성화됩니다.

  • 현재 오류를 사용하여 Last_C 값을 D 부품 계산으로 인계하기 전에 '충전'하는 방법에 유의하십시오. Last_C 변수는 커패시터처럼 작동하며 오차가 큰 동안 누적되어 파생 부품이 최근 오류의 '역사'를 기반으로 작동하고 그 후에 (오류가 작을 때)이 '역사' '는 커패시터처럼 방전됩니다.

물론 전체 출력을 이미 수행했던 방식 (와인드업 리셋, 범프없는 자동-수동 전송 및 기타 일반적인 작업)으로 제한해야합니다.

유용한 경우 PID 알고리즘의 다른 용어에 대한 자세한 내용을 게시 할 수 있지만이 방법을 시도하여 어떤 일이 발생하는지 확인할 수 있습니다. 그것은 수년간 내 고객에게 잘 봉사했습니다.


입력 주셔서 감사합니다. 이것을 시도해야합니다. 한눈에 이해가되는 것 같습니다.
Adam Lewis

알다시피, 당신은 '주요'PID 내에 스톨 감지가 계산에 가져 오는 모든 것을 포함하는 D 항 기여를 가지고 있습니다.
Drazen Cika

1
맞습니다. PID의 Dterm은 튜닝 중에 매우 공격적이지는 않지만 사용됩니다. 이 문제를 더욱 어렵게 만드는 것은로드가 매우 짧은 시간 내에 끊어 질 수 있다는 것 입니다. IE 연결이 해제되었습니다. 이러한 힘의 갑작스런 제거는 스톨 힘에 스무딩 기능 (서밍)이 적용될 때 큰 오버 슈트를 유발합니다.
Adam Lewis

사악한 문제, 일부 퍼지 논리 알고리즘이이를 얼마나 잘 처리하는지 알면 흥미로울 것입니다. 최소한 표준 솔루션 내에 갇혀있는 대신 문제 관련 경험을 알고리즘에 더 많이 구축 할 수 있습니다. 어쨌든, 행운을 빕니다 :-)
Drazen Cika

1

초기 솔루션

stalled_pwm_output = PWM / | ΔE |

PWM = 최대 PWM 값
ΔE = last_error-new_error

초기 관계 는 모터 의 변화 부족에 따라 PWM 출력을 성공적으로 증가시킵니다 . 샘플 출력은 아래 그래프를 참조하십시오.

이 접근 방식은 공격적이지 않은 PID가 정지 된 상황에서 발생합니다. 그러나 공격적이지 않은 PID가 설정 포인트를 달성 할 수 있고 속도를 늦출 때 stalled_pwm_output이 증가한다는 불행한 (그리고 명백한) 문제가 있습니다. 이 상승은 비 적재 위치로 이동할 때 큰 오버 슈트를 유발합니다.

1 / ΔE 대 ΔE

현재 솔루션

이론

stalled_pwm_output = (kE * PID_PWM) / | ΔE |

kE = 스케일링 상수
PID_PWM = 공격적이지 않은 PID의 현재 PWM 요청
ΔE = last_error-new_error

내 현재 관계는 여전히 1 / ΔE 개념을 사용하지만 비 공격적 PID PWM 출력을 사용하여 stall_pwm_output을 결정합니다. 이를 통해 PID가 목표 설정 점에 가까워 질 때 stall_pwm_output을 스로틀 백할 수 있지만 정지시 100 % PWM 출력을 허용합니다. PWM이 포화 점 (아래 그래프에서 10,000 이상)에 도달하도록하려면 스케일링 상수 kE가 필요합니다.

의사 코드

cal_stall_pwm의 결과는 현재 제어 로직의 PID PWM 출력에 추가 됩니다.

int calc_stall_pwm(int pid_pwm, int new_error)
{
    int ret = 0;
    int dE = 0;
    static int last_error = 0;
    const int kE = 1;

    // Allow the stall_control until the setpoint is achived
    if( FALSE == motor_has_reached_target())
    {
        // Determine the error delta
        dE = abs(last_error - new_error);
        last_error = new_error;

        // Protect from divide by zeros
        dE = (dE == 0) ? 1 : dE;

        // Determine the stall_pwm_output
        ret = (kE * pid_pwm) / dE;
    }

    return ret;
}

출력 데이터

정지 된 PWM 출력 정지 된 PWM 출력

정지 된 PWM 출력 그래프에서 ~ 3400의 갑작스러운 PWM 드롭은 모터가 지정된 시간 내에 위치에 도달 할 수 없기 때문에 활성화 된 내장 안전 기능입니다.

비 부하 PWM 출력 무부하 PWM 출력


1

당신은 당신이 무엇을 제어하고 있는지 말하지 않습니다 ... 모터 속도? 위치? 그것이 무엇이든간에 첫 번째 단계는 수용 가능한 오류가 무엇인지 정의하는 것입니다. 예를 들어 제어가 속도를위한 경우 목표의 1 % 이내의 최대 오류를 설정할 수 있습니다. 허용 가능한 오류를 정의하지 않으면 ADC 또는 PWM 카운트에 필요한 해상도를 결정할 수 없습니다. 그렇지 않으면 PID 보상은 완벽 할 수 있지만 여전히 한계주기 진동이 발생합니다.

그런 다음 개방형 루프 시스템의 역학을 알아야합니다. 그렇지 않으면 루프의 비례 (P), 적분 (I) 및 미분 (D) 부분에 필요한 게인을 알 수 없습니다. 입력 단계 (드라이브 레벨 또는 PWM의 단계 변경) 또는 부하의 단계 변경 (이것이 귀하에게 관련이있는 것으로 나타남)으로 동적을 측정 할 수 있습니다.

제어 알고리즘의 분모에서 사이클 간 오류 변경을 사용하여 PWM 값을 수정하면 루프가 안정되지 않습니다. 이를 통해 컨트롤에서 제한 사이클 진동이 보장됩니다. 대부분의 고객은 그것을 참지 않을 것입니다.

루프의 P 부분은 즉각적인 오류를 처리합니다 (오류에 즉시 대응). 그러나 유한 이득을 가지므로 약간의 오차가 남습니다. 루프의 I 부분은 시간이 지남에 따라 천천히 반응하여 무한 게인 (무한 게인의 경우 무한 시간)을 적용하여 P 부분에서 남은 오류를 수정합니다.

I 부분이 느리기 때문에 올바른 게인이 설정되어 있어도 오류를 최소화하는 데 필요한 수정으로 단계를 벗어날 수 있습니다. 따라서 상처를 입히고 회복하는 데 오랜 시간이 걸립니다. 또는 P 부분과 반대쪽에 있습니다.

와인드업을 처리하는 가장 좋은 방법은 적분기의 최대 저장된 값을 최악의 경우 비례 오류를 수정하는 데 필요한 것보다 조금만 제한하는 것입니다. 적분기가 위상을 벗어나 P와 반대되는 경우 적분기 값을 0으로 설정하는 것이 가장 좋습니다. algo는이를 감지하고 필요할 때 적분기를 재설정하도록 설계 될 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.