1. PID Digital
1.1. Introdução
Equação tradicional de um PID no domínio tempo, formato paralelo:
u(t)=Kpe(t)+Kio∫te(t)dt+Kd∂t∂e(t) [eq. (1)]
A eq. (1) retrata o PID no formato paralelo, conforme mostrado na figura à seguir:
No formato paralelo do PID (eq. (1)), quando variamos certo parâmetro do PID (Kp ou Ki ou Kd), a modificação de um parâmetro não afeta nenhum dos outros não alterados.
Repare porém que o PID pode ser implementado de outras formas, como no tradicional formato "ISA" como é mostrado na próxima figura:
Porém no formato ISA, sua equação assume uma forma ligeiramente diferente:
u(t)=Kc(e(t)+Ti1∫e(t)dt+Td∂t∂e(t))
Neste caso:
Ki=Ti1 e Kd=Td.
Porém, neste caso, quando variamos Kc acabamos gerando um impacto nos outros parâmetros: Ti e Td.
De qualquer modo, estamos interessados na versão digital, ou digitalizada do PID.
Para obter a equação no formato digital do PID poderímos recorrer a sua equação no plano-z, U(z) e usar algum método de transformação bilinear como o "famoso" método de Tustin para obter sua equação no plano-z à partir da sua equação no plano-s e então obter sua equação de diferenças (u[kT]=…), considerando agora o período de amostragem, T que será adotado para sua implementação. O problema destes métodos é que sua precisão varia com o valor do período de amostragem adotado: valores bem baixos (alta taxa de amostragem), conduz a melhores resultados.
Ou podemos partir diretamente para métodos numéricos que aproximam numericamente a ação integrativa e a ação derivativa.
Uma ação de integração numérica pode ser obtida de algumas formas:
- Integração Retangular, ou;
- Integração Trapezoidal, ou;
- Método de Simpson, ou;
- Outros métodos (ver Wikipédia: Integração Numérica).
1.2.1. Integração Retangular
Método mais simples de integração numérica. Acompanhe pela próxima figura:
Suponha que i[0] corresponda ao valor da integral no instante de amostragem zero, k=0. Obviamente este valor é inicialmente nulo. Mas repara como o valor da integral varia conforma aumenta o instante da amostragem:
i[0]i[1]i[2]i[3]i[k]====⋮=0i[0]+e[0]⋅Ti[1]+e[1]⋅Ti[2]+e[2]⋅Ti[k−1]+e[k−1]⋅T
onde: i[k]= integral no instante de tempo atual, amostra atual, k.
Notamos que a integral no instante atual atual, depende do seus valor no instante de amostragem anterior (i[k−1]) e do valor de erro no instante de tempo anterior (e[k−1]). E obviamente neste caso, fácil de acompanhar na figura, estamos realizando sucessivas somas de áreas retangulares.
Podemos realizar uma transformada-z sobre a última eq. genérica:
i[k]I(z)I(z)−z−1I(z)I(z)(1−z−1)I(z)I(z)=↓Z====ou:=i[k−1]+T⋅e[k−1]z−1I(z)+T⋅z−1E(z)T⋅z−1E(z)T⋅z−1E(z)(1−z−1)Tz−1E(z)(z−1)TE(z)
1.2.2. Integração Trapezoidal
Neste caso, vamos realizar sucessivas somas de áreas trapezoidais como mostra a próxima figura:
Lembrando que a área de um trapézio é calculada como:
A=(2B+b)⋅h
onde B= base maior; b= base menor e h= altura do trapézio.
No nosso caso, h será sempre igual à T (período de amostragem adotado).
Levantando as equações, teremos:
i[0]i[1]i[2]i[k]I(z)I(z)I(z)===⋮=↓Z==ou:=0i[0]+T(2e[0]+e[1])i[1]+T(2e[1]+e[2])i[k−1]+T(2e[k−1]+e[k])(1−z−1)Tz−1E(z)2T⋅(1−z−1)(1+z−1)⋅E(z)2T⋅(z−1)(z+1)⋅E(z)
Conclusão:
Note que não importa o método de integração adotado, sempre ocorrerá um pólo em z=1.
Uma derivada numérica pode ser obtida através de:
∂t∂e(t)↓D(z)ouD(z)≅==Te[k]−e[k−1]T(1−z−1)⋅E(z)Tz(z−1)⋅E(z)
1.3.1. O problema da Derivada de um sinal ruidoso
Para entender melhor o impacto da derivada sobre um sinal ruidoso, suponha que num sistema de controle, o sinal do erro seja dado por:
e(t)=sin(ωt)+ansin(nωt)
onde:
- ω= frequência angular do sinal original, cuja amplitude varia entre ±1;
- an= amplitude do ruído, e;
- n= fator-frequencia do ruído, isto é, quantas vezes a frequência do ruído é maior que a frequência do sinal original.
Suponha que a amplitude do ruído seja de apenas 1% da amplitude original do sinal, ou seja, an=0,01.
Suponha que o ruído ocorra numa frequência 100× maior que a frequência original do sinal.
E vamos também supor que ω= 1 rad/s.
Então nosso sinal original (sem passar por derivada) corresponde à:
e(t)=sin(t)+0,01sin(100t)
A derivada deste sinal leva à:
∂t∂e(t)==cos(t)+(0,01⋅100)cos(100t)cos(t)+cos(100t)
ou seja, a amplitude original do ruído foi elevada e igualada (será considerada da mesma forma) que a amplitude do sinal original que queremos derivar, resultando numa onda sinosoidal com amplitude oscilando entre ±2 (note que originalmente estava restrito à ±1,01).
As próximas figuras ressaltam melhor o problema:
Sinal original (com o ruído):
Derivada do sinal anterior (que continha ruído):
Código Matlab usado para gerar figuras anteriores:
>> ezplot('sin(x)+0.01*sin(100*x)',[0 8])
>> grid
>> axis([0 8 -2 2])
>> figure;
>> ezplot('cos(x)+0.01*100*cos(100*x)',[0 8])
>> grid
1.3.2. Ação derivativa filtrada
O problema (inerente à qualquer diferenciação) é que a derivada de um sinal ruidoso ressaltará sobremaneira a presença de ruídos presentes na malha de realimentação. Pior o resultado quanto maior for a frequência do ruído.
Solução?
Acrescentar à solução anterior um filtro derivativo, que pode ser tão simples quanto uma aproximação numérica de um filtro passa-baixa de 1a-ordem (resulta no "filtro exponencial digital de 1a-ordem").
A eq. da ação derivativa incluindo um filtro passa-baixa fica:
D(s)=αTds+1Tds
onde tipicamente α=0,1.
1.3.2.1. Evitando ainda o "derivative kick"
Além disto, como é comum que os valores da referência se alterem de forma abrupta assumindo diferentes valores de constantes ao longo do tempo, realizar a derivada do sinal de erro:
e(t)=r(t)−y(t),
costuma envolver grandes saltos (ou transições abruptas da referência), o que se chama de "derivative kicks", e que resulta numa ação derivativa muito "ruidosa".
Então se sugere fortemente que na eq. final do PID, a parte derivativa (preferencialmente com filtro), seja realizada apenas sobre a saída da planta, ou seja, que se faça algo como:
Nova Aça˜o Derivativa=Td(∂t∂y(t)),
ao invés de:
Aça˜o Derivativa (original)=Td(∂t∂e(t)),
1.3.3. Filtro Derivativo Exponencial de 1a-ordem
Então queremos filtrar o sinal do erro antes de calcular sua derivada e aplicar um ganho sobre o resultado. Ou seja, necessitamos implementar um filtro passa-baixas:
A eq. de um fitro passa-baixas de 1a-ordem pode ser descrita como:
y(t)=x(t)+τf(∂t∂x(t))
ou:
X(s)Y(s)=τfs+11
onde:
- τf corresponde a constante de tempo do filtro;
- x(t)= sinal na entrada do filtro;
- y(t)= sinal na saída do filtro.
Note que:
τf=2πfc1
onde: fc= frequência de corte do filtro (em Hz).
Obs.: recomenda-se fazer: τf<0,1⋅τmax; onde τf corresponde a maior constante de tempo da planta à ser controlada (polo mais lento/dominante), caso contrário, um substancial atraso no tempo será introduzido na malha de controle. Isto corresponde à colocar fc uma década acima da freq. mais lenta da planta.
A primeira eq. (a diferencial) repassada para um formato discreto resulta em:
∂t∂x(t)≅ΔTx[k]−x[k−1]
onde neste caso, Δt corresponde ao período de amostragem T adotado para implementar o filtro. Assim:
y[k]=x[k]+τf(Δtx[k]−x[k−1])
que pode ser reescrita como:
y[k]=(τf+ΔtΔt)x[k]+(τf+Δtτf)y[k−1]
Se neste caso fizermos:
α=(τf+ΔtΔt), então:
(1−α)=1−τf/Δt+11=(τf+Δtτf)
e então, a eq. do filtro resulta numa forma mais simples como:
y[k]=α⋅x[k]+(1−α)⋅y[k−1] [eq. (2)]
onde:
α=2π⋅T⋅fc+12π⋅T⋅fc.
A transformada Z da eq. anterior resulta:
X(z)Y(z)=1−(1−α)z−1α
ou:
X(z)Y(z)=z−(1−α)α⋅z
Note na eq. (2), que:
- Se α=1⇒ não há filtro: simplesmente: y[k]=x[k];
- Se α=0⇒ o sinal original (medição) é ignorado.
Por fim, note que a forma sugerida para o PID "ideal" fica algo como:
A eq. do PID no formato paralelo:
u(t)=Kpe(t)+Kio∫te(t)dt+Kd∂t∂e(t)
pode então ser repassada inicialmente para o formato discreto na forma:
u[k]=Kpe[k]+Kik=0∑ne[k]T+Kd(Te[k]−e[k−1])
equação que também pode ser re-escrita para a forma:
u[k]=Kc[e[k]+τiTk=0∑ne[k]+Tτd(e[k]−e[k−1])]
que corresponde ao formato ISA do PID.
De fato, qualquer uma das implementações anteriores, levam ao formato que se conhece como PID Discreto no formato de posição.
O problema associado com qualquer uma das formas anteriores está relacionado com o termo do somatório.
É fácil prever que este termo pode "saturar", efeito conhecido como de "saturação integral".
Ou seja, suponha um sistema em malha-fechada, onde o erro tarda a baixar. Neste caso, muitas áreas positivas de erro serão acumuladas, até que uma sucessão de áreas negativas (erros negativos) compense o acúmulo de áreas positivas. Neste ínterim, a variável associada com o termo somatório pode eventualmente ultrapassar o escopo da sua própria declaração (se foi declarada como int
) ou pode assumir valores tão elevados (no caso de ter sido declarada como float
) que se repassada como um valor (amplitude) para a ação de controle externa, irá saturar o drive de potência que comanda um motor.
Motivo pelo qual, é comum que o resultado desta implementação na versão digital da ação integral passe por um bloco "saturador", ou resulte num código do tipo:
sum = sum + e*T;
if (sum > 10000.0){
sum = 10000.0;
}
if (sum < -10000.0){
sum = -10000.0;
}
Exitem diferentes formas para contornar esta forma simplista de implementação da ação integral.
Um formato mais interessante de implementação, é conhecido como: PID no formato de velocidade, no qual, o que se computa, não é o valor de u[k], mas sim, que incremento deve ser dado no sinal de controle: Δu[k] em cada instante de amostragem.
Neste formato, o que interesse é calcular:
Δu[k]=u[k]−u[k−1]
ou seja, qual seria a variação, Δu[k], evolvida no sinal de controle u[k].
Tomando a eq. do PID no formato ISA:
u(t)=Kc[e(t)+Ti1∫0te(t)dt+Td∂t∂e(t)]
onde:
∫0te(t)dt≅k=1∑ne[k]⋅T
e:
∂t∂e(t)≅Te[k]−e[k−1].
Teremos então:
Δu[k]Δu[k]==+Kc[e[k]+TiT∑i=1ne[k]+TTd(e[k]−e[k−1])]+−Kc[e[k−1]+TiT∑i=1n−1e[k]+TTd(e[k−1]−e[k−2])]Kc[e[k]−e[k−1]+TiTe[k]+TTd(e[k]−2e[k−1]+e[k−2])]
Como:
u[k]=u[k−1]+Δu[k]
então finalmente obtemos a eq. do PID no formato de velocidade:
u[k]=u[k−1]+Kc[e[k]−e[k−1]+TiTe[k]+TTd(e[k]−2e[k−1]+e[k−2])] [eq. (3)]
Note que:
-
O termo ∑ "desapareceu";
-
Ki=TiT⟵↑Ti⇒↓Ki
-
Kd=TTd⟵↑Td⇒↑Kd
A eq. de Δu[k] do PID, no caso de opção pelo uso de integração trapezoidal, se modifica levemente para:
Δu[k]=Kc[e[k]−e[k−1]+TiT(2e[k]+e[k−1])+TTd(e[k]−2e[k−1]+e[k−2])]
O PID no formato de velocidade, arquitetura paralela fica:
u[k]=u[k−1]+Kp(e[k]−e[k−1])+Kie[k]+Kd(e[k]−2e[k−1]+e[k−2]) [eq. (4)]
onde:
-
Kp=Kc
-
Ki=TiKcT
-
Kd=TKcTd
1.5. Codificação do PID
A próxima figura mostra como ficaria o main()
envolvendo programação de um sistema de controle:
Note na figura anterior, que o algoritmo de controle, a rotina que inclui a eq. do controlador está prevista para ser implementada como uma task() síncrona (ControlTask) em sistemas de tempo-real ou como uma rotina de tratamento de interrupção (ISR) no caso de um sistema embarcado dedicado.
Note que na figura anterior, aparece também uma tarefa associada com a parte de segurança do equipamento (SecurityTask). Este tipo de rotina é responsável por monitorar chaves de fim de curso, botões de emergência, velocidades acima do normal na operação de um sistema, etc. Esta rotina desabilita a rotina de controle caso seja detectado um problema.
A próxima figura detalha o que se faria no bloco "Inicialização de variáveis e objetos":
A próxima figura mostra o bloco em que se realizam os ajustes para funcionamento das tasks de tempo real (síncronas) ou no caso de microcontrolador, o bloco onde são ajustados os registradores para operação e associaçao de temporizadores para operação da interrupção por software causada por overflow de temporizador (ou simplesmente ISR):
A próxima figura ilustra o que faz o bloco de "tratamento do teclado":
A seguinte figura mostra como deve ser programado na task (ou na ISR) associada com o controlador:
A lei de controle apresentada na figura anterior apenas foi mencionada à título de exemplo.
Exemplo: rotinas de controle num robô manipulador.
A próxima figura traz um diagrama mostrando como podem ser implementadas diferentes tasks para controle real de um robô manipulador:
E a próxima figura passa uma idéia de como o tempo de processamento fica distribuído entre as diferentes rotinas que devem ser executadas pelo sistema (o ''tasks time slicing´´):
Fim.
Fernando Passold, em 24/04/2023.