Existem dois tipos principais de sistemas de controle: os de malha aberta e malha fechada. Em um sistema de malha aberta, a ação de controle do controlador independe da variável do processo. O que isso significa? Vamos explicar com um exemplo:
Uma torradeira é um sistema de malha aberta. Podemos tomar duas variáveis, a título de exemplo: tempo e cor do pão. Um sistema de malha aberta funciona exatamente como uma função direta da cor do pão ao longo do tempo. Se você quiser dizer uma leve torrada preta, precisará inserir, por exemplo, 2 minutos. Mas você pode não saber qual é o momento em que isso acontece, precisará, portanto, criar um modelo em sua mente através da experiência.
É necessário entendermos que tipo de malha é a mais adequada para o nosso projeto, pois não saber pode nos proporcionar uma série de erros – ou mesmo danos irreversíveis aos nossos equipamentos. Uma situação possível é que a torradeira poderia estar quebrada e liberar muito menos calor do que o normal. Desta vez, se você colocar por 2 minutos, poderá não atingir o seu objetivo (o chamaremos de setpoint).
Já em um sistema de controle malha fechada, a ação de controle do controlador dependerá da variável do processo real e o valor desejado (setpoint). O que isso significa? Vamos pensar em uma situação. Você decide correr 25 voltas na praça do seu bairro. Para atingir este objetivo, você precisará controlar, por exemplo, a sua velocidade. Sendo um corredor novato e não tendo experiência, poderá pensar que correr o mais rápido possível para chegar ao objetivo final será o mais adequado. Eventualmente, depois de algumas voltas, você vê que está ficando cansado e teme que, com sua resistência, você não conseguirá alcançar as 25 voltas.
Para resolver este problema, você começa a desacelerar até atingir a velocidade que sua resistência permite durante todas as 25 voltas. Então, aqui, você recebe feedback do seu corpo, indicando que sua resistência está baixa, respirando rapidamente e suando profusamente, agindo para reduzir a tensão que faria com que você não terminasse as 25 voltas. Usamos malhas de feedback o tempo todo em nossa vida. Veja o diagrama a seguir para que você possa entender melhor como eles funcionam.

O controle PD é uma variação do sistema de controle PID. O sistema de controle é usado para obter a saída desejada de um sistema de circuito fechado (gerando o devido sinal de correção). Um sistema de circuito fechado leva em consideração a saída desejada (setpoint) e a saída medida, gerando um sinal de correção para que o atuador torne a saída medida o mais próximo possível da saída desejada. Agora, sabemos que precisamos de um sistema que tenha algum tipo de feedback sobre sua posição atual e que, de alguma maneira, corrija os erros.
PID é um acrônimo para proporcional – integral – derivado. Você pode pensar nelas como ferramentas matemáticas para corrigir erros. A primeira coisa que você deve saber é o que é um controle proporcional.

Proporcional
Imagine que você tem uma corrida leve todos os dias pela manhã e que seu objetivo é percorrer 10 km em 2 horas. Antes de começar a correr, leva alguns segundos para calcular qual a velocidade média que você precisará manter durante a corrida e chega à conclusão de que é necessário correr 5 km/h.
Você começa a corrida e tudo está indo bem, até que você é atingido por uma dor de facão. Talvez você não devesse ter bebido tanta água antes de correr! Correr com dores não é uma boa ideia, então você decide parar por um tempo. Depois de mais ou menos 20 minutos, você olha para o relógio e percebe que uma hora inteira se passou e você ainda está no terceiro quilômetro, assim, pensa que precisará correr mais rápido para compensar o tempo perdido enquanto você aguardou a dor diminuir. Então você corre cada vez mais rápido, até atingir uma velocidade que permita alcançar seu objetivo no tempo desejado de 2 horas, nessa situação a velocidade desejada é 7 km/h.
Quando você atinge essa velocidade, pode perceber que não há necessidade de acelerar mais e vai chegar ao seu destino a tempo. Aqui a mudança de velocidade deve ser proporcional ao erro. Caso você estivesse atrasado apenas 1km na sua corrida, você aceleraria proporcionalmente menos do que o que aconteceu no primeiro exemplo. Portanto, concluímos que quanto maior o erro, maior a mudança na variável e é por isso que chamamos de controle de ganho proporcional.
Derivada
Agora você pode estar pensando: “O que significa o D do controle PD?” Como afirmado antes, o “D” significa derivativo. Uma derivada é uma ferramenta matemática que mede a taxa de mudança. Em uma função de primeiro grau – como y = 2x – a derivada seria igual a 2. Isso significa que y muda no ritmo de 2 unidades em comparação com x, que muda no ritmo de 1 unidade. Se você deseja se aprofundar no cálculo, existem muitos recursos disponíveis na internet!
Como podemos usar este conceito para ajudar a controlar nosso robô? Vamos passar por outra analogia. Desta vez, vamos usar um carro.
Digamos que você esteja viajando e precise parar em uma loja de conveniência para reabastecer alguns alimentos e bebidas não alcoólicas. Digamos que a sua posição inicial é 0 e a posição da loja de conveniência está a 80 metro à sua frente, ou seja, o erro é de 80 metros.
Este erro é alto e, se você estiver usando apenas controle de ganho proporcional, acelerará apenas de forma proporcional ao erro. O problema é que quando você se aproxima da loja e o erro diminui e a sua velocidade já não é a mesma, pois você está apenas ficando proporcionalmente mais devagar para compensar o novo erro. Imaginando que você esteja de aproximando, o que poderia acontecer? Você passaria direto pela loja e teria de voltar, já que o erro agora seria negativo.
Você da ré para chegar à loja e corrigir o erro, mas ainda sim erra o setpoint e continua oscilando na frente da loja como um pêndulo e, se isso continuar, a polícia poderá ser chamada para dar conta de uma pessoa causando problemas Ao tráfico! Precisamos, portanto, de algo melhor.
Vamos mudar esse sistema para que ele saiba quando precisa parar ou possa perceber quando o erro está ficando cada vez menor, assim sabendo com que rapidez o erro muda e, para isso, usaremos a derivada. Vamos passar pela mesma situação, mas agora com o termo derivativo na estrutura de controle.
Para atingirmos o nosso objetivo, é essencial que os valores constantes de multiplicação – Kp e Kd – estejam sintonizados corretamente.
É assim que um sistema de PD funciona. Nosso sistema precisará apenas das partes Proporcional e Derivativa do sistema, portanto, se você quiser saber mais sobre controle e sistema PID e entender o ganho Integrativo, pode consultar o seguinte link.
Agora que já sabemos como funciona o Controle PD (proporcional-derivativo) de forma teórica, vamos implementar ele em nosso código?
Criaremos, a seguir, as variáveis que utilizaremos nesta parte:
int setP=2500, erro=0; // declara o setpoint e a variável para lidar com o erro
int P=0, D=0; // variáveis para a equação PD
float valPid=0; // valor de correção
float kp=0.102, kd=0.32; // constantes de ganho proporcional e derivativo
int ultErro=0; // variável para guardar o erro anterior lido
Criaremos, também, a função pid():
void pid() {
}
O erro será dado pela diferença entre o setpoint (valor desejado de posição) e o valor de posição lido, logo:
erro = setP - pos;
Como sabemos, o valor de correção proporcional será resultado da multiplicação do erro pela constante (definida em código), Criando uma variável chamada “valPid” para guardar o valor de PID, teremos:
valPid = (kp*erro)
Muito bacana, né? Agora vamos adicionar o ganho derivativo, responsável por dar o ganho necessário de correção nas curvas.
Como foi explicado anteriormente, o ganho derivativo será resultado da multiplicação de uma constante pela diferença entre o erro atual e o erro anterior. Como podemos fazer isso? Vamos aproveitar da forma como o nosso código é interpretado (comando por comando, de cima para baixo) e adicionar o nosso erro lido a uma outra variável. Assim, ao termos um novo valor de erro lido, o valor antigo permanecerá estocado nesta outra variável.
Em termos práticos, teremos:
valPid = (kp*erro) + (kd*(erro-ultErro));
ultErro = erro;
Agora, precisamos informar os estados para a ponte H girar os motores no sentido horário ou anti-horário. Nosso robô utilizará a inversão de motores neste projeto para realizar curvas mais acentuadas sem sair do percurso.
Indique os estados iniciais para que o robô ande para a frente:
digitalWrite(motorEsq, LOW);
digitalWrite(motorDir, HIGH);
Agora, vamos criar uma condição para que valores de correção acima de um limite – definido de forma empírica – possam alternar os estados dos nossos motores. Assim, teremos:
if((valPid > 110)||(valPid < -110)){
// aqui colocaremos as condições para os valores de correção altos
} else {
digitalWrite(motorEsq, LOW);
digitalWrite(motorDir, HIGH);
}
Utilizamos o seguinte valor por representar cerca de 43% do sinal de correção total.
Como você pode notar, temos duas possibilidades para essa condição ser verdadeira: ou o sinal de correção é superior a 110 ou o sinal de correção é inferior a 110. Assim, precisaremos definir as condições de forma isolada para cada caso.
Caso o valor seja superior a zero, vamos inverter a rotação do motor direito do sentido horário para o anti-horário:
if(valPid > 0){
digitalWrite(motorEsq, LOW);
digitalWrite(motorDir, LOW);
}
E caso o valor seja inferior a zero, vamos inverter inverter a rotação do motor esquerdo do sentido horário para o anti-horário:
else if(valPid < 0){
digitalWrite(motorEsq, HIGH);
digitalWrite(motorDir, HIGH);
}
Assim, ficamos com as seguintes estruturas:
if((valPid > 110)||(valPid < -110)){
if(valPid > 0){
digitalWrite(motorEsq, LOW);
digitalWrite(motorDir, LOW);
}
else if(valPid < 0){
digitalWrite(motorEsq, HIGH);
digitalWrite(motorDir, HIGH);
}
} else{
digitalWrite(motorEsq, LOW);
digitalWrite(motorDir, HIGH);
}
Vamos dar uma olhada em como ficou nossa função pid():
void pid() {
erro = setP - pos;
valPid = (kp*erro) + (kd*(erro-ultErro)) + (ki*(I += erro));
ultErro = erro;
digitalWrite(motorEsq, LOW);
digitalWrite(motorDir, HIGH);
if((valPid > 110)||(valPid < -110)){
if(valPid > 0){
digitalWrite(motorEsq, LOW);
digitalWrite(motorDir, LOW);
}
else if(valPid < 0){
digitalWrite(motorEsq, HIGH);
digitalWrite(motorDir, HIGH);
}
} else{
digitalWrite(motorEsq, LOW);
digitalWrite(motorDir, HIGH);
}
}
Estamos quase finalizando nosso projeto, nos vemos na finalização do robô!
Um comentário em “Controle PD”