Capítulo 11

PID: Consertando Tudo

Como eliminamos o desvio residual e paramos a oscilação?

Capítulo 11: PID: Consertando Tudo ↗

O desvio residual que não morre

Theo: Lembra do Capítulo 2? Nosso controlador P deixava o drone parado abaixo de 2 m, e nenhum KpK_p conseguia consertar isso. Hora de descobrir o que consegue.

Para manter o drone no ar, os motores precisam empurrar mg≈4,9mg \approx 4{,}9 N, para sempre. Um controlador P só empurra quando há erro: T=Kp e\eff{T} = K_p\,\err{e}. Então, para empurrar 4,9 N, ele precisa de um erro de e=mg/Kp\err{e} = mg/K_p. Com KpK_p = 20 N/m, isso dá e\err e = 4,9/20 ≈ 24,5 cm, para sempre. O desvio residual não é um defeito da nossa sintonia. É o preço que o P cobra para segurar qualquer coisa no alto.

June: Então precisamos de uma parte do controlador que consiga empurrar 4,9 N com erro zero. Algo com memória.

I: uma pilha de erros passados

A ideia é esta. Mantenha um total acumulado do erro, a área sob a curva do erro, exatamente a "área que se acumula" do Capítulo 3. Empurre proporcionalmente a essa pilha:

TI=Ki∫0te dt\eff{T_I} = K_i \int_0^t \err{e}\,dt

Enquanto o drone estiver abaixo de 2 m, o erro é positivo e a pilha continua crescendo, então o empurrão continua crescendo. A pilha só para de crescer quando o erro é exatamente zero. Nesse ponto ela simplesmente fica, segurando o empuxo que tiver acumulado. É essa a memória que a June queria.

Theo: Ah, isso é manhoso. O drone não consegue se estabilizar em nenhum outro lugar além de 2 m, porque em qualquer outro lugar a pilha ainda estaria mudando.

Capítulo 11: PID: Consertando Tudo ↗

Preveja primeiro! Mika quer que o desvio residual desapareça rápido, então planeja aumentar KiK_i bem alto. O que vai acontecer?

O widget começa com KiK_i = 10 N/(m·s). Observe três coisas: a área sombreada em vermelho (o erro sendo empilhado), a parte integral do empuxo, tracejada em laranja, subindo até a linha roxa da gravidade, e a leitura do desvio residual. Arraste KiK_i até 0 para ter de volta o desvio residual do Capítulo 2 e depois teste valores maiores. KpK_p fica fixo em 20 N/m.

Capítulo 11: PID: Consertando Tudo ↗

Capítulo 11: PID: Consertando Tudo ↗

Mika: Aumenta logo! Ki=50K_i = 50! Acaba com isso de uma vez!

Mika: …por que não para? Os quiques foram crescendo, crescendo, e agora ele fica subindo e descendo meio metro, para sempre!

Theo: Com 50 você passou de algum tipo de limite. Testei alguns valores: abaixo de uns 40 ele se estabiliza, acima não (e o ioiô leva cerca de um segundo por balanço). Já vamos ver por quê. A pilha está sempre um pouco atrasada: continua empurrando para cima depois que o drone já passou de 2 m.

Esse é o erro da Mika, e é muito comum: o integral corrige o desvio residual, mas adiciona atraso, e atraso faz as coisas oscilarem (a manopla do chuveiro nos ensinou isso). Precisamos de algo que reaja contra a velocidade. (Pela matemática, os balanços dela deveriam crescer para sempre. Eles param em cerca de meio metro só porque o empuxo bate em 0 N a cada balanço: hélices não conseguem puxar para baixo, o limite do Capítulo 10.)

D: um amortecedor virtual

June: No Capítulo 7, o amortecedor era o que acalmava a mola. E se o controlador fingisse ser um amortecedor?

Um amortecedor empurra contra a velocidade. Então adicione um termo que empurra contra a rapidez com que o drone está se movendo:

TD=−Kd dhdt\eff{T_D} = -K_d\,\frac{d\out{h}}{dt}

Veja a equação do drone: o arrasto já dá −c h˙-c\,\dot h. O termo D adiciona −Kd h˙-K_d\,\dot h por cima, então o drone se comporta como se seu arrasto fosse c+Kdc + K_d. Estamos adicionando resistência do ar em software.

Capítulo 11: PID: Consertando Tudo ↗

Capítulo 11: PID: Consertando Tudo ↗

Ligue o grande ganho I da Mika e depois adicione amortecimento. Até Kd=0,5K_d = 0{,}5 N·s/m já o traz de volta à estabilidade (empurra o limite para Ki=60K_i = 60): o ioiô sem fim vira um quique que vai morrendo. Mas ele ainda passa do alvo em pelo menos um quarto, por mais D que você coloque. Essa pilha enorme simplesmente lembra demais. Agora desligue o KiK_i da Mika (de volta a 10) e teste Kd≈3K_d \approx 3–5: calmo. I e D se compensam: o D abre espaço para o I, mas não espaço infinito.

June: Se 4 é bom, 10 deve ser melhor. Amortecedor no máximo!

Mika: Ele sobe tããão devagar… e mesmo assim passa de 2 m? Atrasado?

Theo: June, é o seu drone no mel do Capítulo 7 de novo! Acima de Kd≈5,3K_d \approx 5{,}3, o par rápido fica superamortecido. Mas agora também tem uma pilha, e um drone lento dá tempo para a pilha transbordar.

O amortecimento crítico é onde ζ = 1: Kd=2mKp−c≈5,3K_d = 2\sqrt{m K_p} - c \approx 5{,}3 N·s/m com KpK_p = 20. Com KiK_i = 10, ir de KdK_d = 4 para 10 leva o sobressinal de 0 para cerca de 8 %, e o tempo de acomodação de menos de um segundo para cerca de 5 s. Mais D nem sempre é melhor; agora o widget avisa quando você exagera.

Mika: Então D prevê o futuro! Ele vê para onde o drone está indo e chega lá primeiro.

Theo: Não exatamente. Ele só conhece a inclinação agora. É como adivinhar onde uma bola vai cair assumindo que continua em linha reta. Geralmente é um palpite razoável, mas não é mágica. Espere até alimentarmos isso com um sensor instável.

O que cada botão faz com os polos

Hora de usar o mapa do Capítulo 10. Escreva toda a malha, com e=r−h\err{e} = \sp{r} - \out{h}:

mh¨+ch˙=Kp e+Ki ⁣∫ ⁣e dt−Kd h˙⏟T−mgm\ddot{\out h} + c\dot{\out h} = \underbrace{K_p\,\err e + K_i\!\int\!\err e\,dt - K_d\,\dot{\out h}}_{\eff{T}} - \dis{mg}

A integral atrapalha, então tire a inclinação dos dois lados. Inclinação e área se desfazem (Capítulo 3), então a inclinação de ∫e dt\int \err e\,dt é simplesmente e\err e. A gravidade é constante, então sua inclinação é zero: ela simplesmente cai fora. Com um valor de referência fixo, e˙=−h˙\dot{\err e} = -\dot{\out h}. Termo a termo:

ddt(Kp e)=−Kp h˙ddt(Ki ⁣∫ ⁣e dt)=Ki (r−h)ddt(−Kd h˙)=−Kd h¨\begin{aligned} \tfrac{d}{dt}\big(K_p\,\err e\big) &= -K_p\,\dot{\out h} \\ \tfrac{d}{dt}\Big(K_i\!\int\!\err e\,dt\Big) &= K_i\,(\sp r - \out h) \\ \tfrac{d}{dt}\big(-K_d\,\dot{\out h}\big) &= -K_d\,\ddot{\out h} \end{aligned}

Junte tudo de novo e passe tudo o que tem h\out h para a esquerda. Os três pontos em h...\dddot{\out h} significam a inclinação da inclinação da inclinação:

mh...+(c+Kd) h¨+Kp h˙+Ki h=Ki r\begin{aligned} m\dddot{\out h} + (c + K_d)\,\ddot{\out h} &+ K_p\,\dot{\out h} + K_i\,\out h \\ &= K_i\,\sp r \end{aligned}

Theo: A gravidade desapareceu da equação. Esse é o matador do desvio residual na forma algébrica: a altura final não se importa com mgmg de forma alguma. Isto é, desde que ele se acomode. O drone de Ki=50K_i = 50 da Mika nunca se acomodou.

Chute este^{st} de novo. Com o I ativo, a equação é cúbica, então há três polos. Se Ki=0K_i=0, não há integrador: tirar a inclinação acrescentou uma raiz falsa em s=0s = 0, o fator comum ss se cancela, e o drone PD tem dois polos.

ms3+(c+Kd) s2+Kp s+Ki=0m s^3 + (c + K_d)\,s^2 + K_p\,s + K_i = 0

Para uma cúbica com todos os coeficientes positivos a3s3+a2s2+a1s+a0a_3 s^3 + a_2 s^2 + a_1 s + a_0, existe um teste clássico (o critério de Routh–Hurwitz) que diz que os três polos estão no semiplano esquerdo exatamente quando a2a1>a3a0a_2 a_1 > a_3 a_0. Para o nosso drone, essa é a beira do precipício:

(c+Kd) Kp>m Ki⟺Ki<(c+Kd) Kpm(c + K_d)\,K_p > m\,K_i \quad\Longleftrightarrow\quad K_i < \frac{(c+K_d)\,K_p}{m}

Mika: Uma regra com o nome de duas pessoas. A gente tem que simplesmente acreditar?

Theo: Nada disso. A gente mesmo consegue achar o limite.

No instante em que um par oscilante chega ao eixo vertical, sua parte real é zero, então teste s=iωs=i\omega na cúbica. Como i2=−1i^2 = -1 e i3=−ii^3 = -i, as partes reais e as partes laterais têm que somar zero, cada uma:

Ki−(c+Kd) ω2=0,ω (Kp−m ω2)=0K_i - (c+K_d)\,\omega^2 = 0, \qquad \omega\,\big(K_p - m\,\omega^2\big) = 0

A segunda diz que ω2=Kp/m\omega^2 = K_p/m. Coloque isso na primeira:

ω2=Kpm,Ki=(c+Kd)ω2=(c+Kd)Kpm\omega^2=\frac{K_p}{m},\qquad K_i=(c+K_d)\omega^2=\frac{(c+K_d)K_p}{m}

Capítulo 11: PID: Consertando Tudo ↗

Nos valores iniciais (KpK_p = 20, sem D), o limite é 40. Foi exatamente aí que o drone da Mika enlouqueceu, e seu ioiô levava cerca de um segundo por balanço: 6,32 rad/s é o próprio ωn do drone P, do Capítulo 7. Colocar Kd=4K_d = 4 empurra o limite para 200. Não confie na gente: mude os números acima, ou os controles deslizantes abaixo, e observe os polos, o minimapa e a resposta ao degrau.

Capítulo 11: PID: Consertando Tudo ↗

  • O botão do I (KiK_i) traz um terceiro polo para a malha e pode empurrar um par para a direita. Demais, e ele cruza a linha.
  • O botão do D (KdK_d) eleva o limite de estabilidade do ganho I ao adicionar amortecimento. Os caminhos dos polos podem virar: mais D não move todo polo para a esquerda.
  • O botão do P (KpK_p) principalmente espalha o par oscilante para cima e para baixo: mais rápido, mas mais oscilante, a menos que o D acompanhe.

O playground de sintonia

Agora a coisa de verdade: decole do chão até 2 m com motores reais (0–20 N). Conquiste as quatro estrelas. Toda vez que você muda um ganho, o último voo permanece como um fantasma tênue.

Capítulo 11: PID: Consertando Tudo ↗

June: Desliguei o anti-windup, coloquei KpK_p = 30, KiK_i = 60, KdK_d = 2… e o drone disparou até 4 m, direto para fora da sua figura!

Theo: A pilha continuou crescendo o tempo todo em que os motores estavam no máximo. Com o anti-windup ligado, os mesmos ganhos chegam a um pico de 2,8 m. Mesmos botões, memória bem diferente.

Dois avisos sobre D

Aviso 1: o chute derivativo

O drone paira a 1 m. Em t=1t = 1 s, mudamos o valor de referência para 1,5 m. Se o D usa a inclinação do erro, então o erro salta meio metro num instante. Sua inclinação é enorme, e o empurrão também.

Capítulo 11: PID: Consertando Tudo ↗

Capítulo 11: PID: Consertando Tudo ↗

Mika: Sobre o erro, ele pede mais de 200 N? De motores que chegam no máximo a 20?

June: E eles não sabem dizer não com educação. Vão com tudo por um instante, e o drone leva um chute no traseiro.

Usar a inclinação da altura medida em vez disso resolve: o drone não pode se teletransportar, então sua altura não tem saltos. Mesmo amortecimento, sem chute. Quase todo PID real faz isso.

Aviso 2: ruído

Sensores de altura reais oscilam alguns centímetros. Alguns centímetros de oscilação, mil vezes por segundo, têm uma inclinação enorme. D amplifica isso direto para os motores. A solução é suavizar a medição antes de calcular sua inclinação (um filtro com constante de tempo τf\tau_f), ao custo de reagir um pouco mais tarde.

Capítulo 11: PID: Consertando Tudo ↗

Capítulo 11: PID: Consertando Tudo ↗

Mika: Certo, D não prevê o futuro. Ele prevê o que o ruído sentiu um milissegundo atrás.

O que consertamos

O que descobrimos

  • P empurra em proporção ao erro, mas precisa deixar um desvio residual para manter o drone no ar.
  • I empilha o erro passado; o único ponto de repouso é erro zero, então ele elimina o desvio residual, que morre com uma constante de tempo de cerca de Kp/KiK_p/K_i. Ele acrescenta atraso, então demais faz as coisas balançarem.
  • D empurra contra a velocidade: um amortecedor virtual que se soma ao arrasto cc, então ζ=(c+Kd)/(2mKp)\zeta = (c+K_d)/(2\sqrt{mK_p}). Mais D nem sempre é melhor: superamortecido, o drone se arrasta e a pilha transborda.
  • A malha fechada é ms3+(c+Kd)s2+Kps+Kim s^3 + (c + K_d)s^2 + K_p s + K_i; ela é estável exatamente quando (c+Kd)Kp>mKi(c+K_d)K_p > mK_i.
  • Tire o D da medição (sem chute) e filtre-o (menos ruído).

June testou nosso PID estilo drone no chuveiro… e ele oscilou exatamente como fizemos no Capítulo 0. O que há com o atraso?

Capítulo 11: PID: Consertando Tudo ↗