
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.