Enginursday: Precisão de robô de duas rodas dirigindo com feedback do codificador - Notícias

Enginursday: Precisão de robô de duas rodas dirigindo com feedback do codificador – Notícias

cupom com desconto - o melhor site de cupom de desconto cupomcomdesconto.com.br


Usando feedback do codificador para controlar dois motores DC, este robô é autocorretivo!





Favorito



Favorito


0 0

Meu desafio parecia bastante simples: eu queria que um robô de duas rodas conduzisse uma linha reta usando o feedback de um conjunto de codificadores de roda. Mal sabia eu que isso abriria as portas para o vasto mundo do controle de motores PID!

O veículo espacial de duas rodas dirige uma linha reta para fora, depois se vira e retorna

fundo

Antes de iniciar este projeto, minha experiência com robôs de mesa de duas rodas era bastante mínima. Ajudei a dar algumas aulas para os educadores que usavam o SparkFun Redbot – isso envolvia ajudar nossos participantes a configurar e codificar desafios como seguir linhas e conduzir um padrão. Usamos “tentativa e erro” manual para corresponder às velocidades do motor e, em seguida, atrasos para controlar a distância percorrida. Embora seja uma introdução maravilhosa à codificação e à robótica, não é ideal para conduzir um muito linha reta e / ou distância precisa. Ver esses desafios na sala de aula plantou a semente para este projeto. Eu sabia que tinha que haver uma maneira divertida de incorporar alguns codificadores de alta resolução para aumentar o controle de direção!

Hardware e abordagem

Depois de pesquisar muitas opções, finalmente decidi usar o Qwiic Motor Driver, um conjunto de motores DC com engrenagens que incluía codificadores em quadratura e um Raspberry Pi 4 como cérebro principal.

O uso de um Raspberry Pi 4 como controlador teve dois benefícios muito úteis: primeiro, meu programa seria escrito em Python e, segundo, fiquei empolgado por poder ajustar o código e ver dados de streaming em tempo real via Wifi e VNC visualizador.

Leia Também  “Meias inteligentes” incorporadas em sensores ajudam pacientes com neuropatia diabética

A escolha de um método para ler os codificadores foi um pouco mais longa. Minha experiência anterior com codificadores envolveu interfaces de usuário e botões giratórios. Isso envolveu muitas interrupções para manter o controle dos pulsos e, finalmente, uma “posição do zero”. Embora seja possível conectar os codificadores diretamente ao GPIO no Raspberry Pi, eu não estava interessado em atrapalhar meu programa Python com interrupções.

Eu finalmente encontrei o SparkFun Qwiic Twist e decidi fazer algo semelhante. O Twist utiliza um ATTiny84 para lidar com a leitura de um único codificador. Ele controla uma variável de contagem que é facilmente lida no Twist via I2C. Eu escolhi usar esse design e firmware como ponto de partida.

texto alternativo

Tirei o controle de LED e botão e pude utilizar uma segunda interrupção e mais GPIO para ler um segundo codificador. Wahoo! Eu tinha meu leitor de encoder duplo e minhas contagens estariam disponíveis no barramento I2C!

cupom com desconto - o melhor site de cupom de desconto cupomcomdesconto.com.br
texto alternativo

Para modificar o firmware do Twist, eu realmente desenvolvi primeiro um Qwiic do Arduino Redboard (atuando como uma alternativa ao ATTiny84). Isso me permitiu usar a porta UART para depuração enquanto terminava as modificações no firmware (o mais importante, adicionando suporte para um segundo codificador).

Vamos dirigir!

Depois de ligar tudo, simplesmente coloquei os motores na mesma “potência” e observei o que aconteceu. Uau, os motores podem variar muito! Meu robô estava girando bruscamente para a esquerda, o que significa que o motor direito estava realmente superando muito o motor esquerdo. Agora era hora de entrar em algumas contagens de codificadores e ver se poderíamos corrigir essa diferença!

Esta é a parte do meu código que comanda a linha reta:

for i in range(0,300):
    count12_delta = myEncoders.count1 - (-myEncoders.count2)
    error_change = count12_delta - prev_count12_delta
    motor_speed_correction = count12_delta
    motor_speed_correction *= P_gain #proportional adjustment
    motor_speed_correction += (I_gain * error_change) #integral adjustment, looks at the change in error, if it gets smaller, than slow down the correction
    left_motor_speed -= motor_speed_correction
    myMotors.set_drive(L_MTR, L_FWD, (left_motor_speed))
    print("1:%d t2:%d tLS:%d tRS:%d tCD:%d tEr:%d tMC:%d" % 
                  (myEncoders.count1, -myEncoders.count2, left_motor_speed, right_motor_speed, count12_delta, error_change, motor_speed_correction))
    prev_count12_delta = count12_delta

Como você pode ver aqui, estou usando um sistema de controle quazi-PID muito simplificado. Você também pode observar que ainda não estou incorporando uma correção derivada (isso pode ser uma melhoria posterior).

Leia Também  Arduino Blog »Crie seu próprio rastreamento e montagem GoTo para astrofotografia DSLR

Para começar, analiso o delta entre cada contagem e, em seguida, decido se o motor esquerdo deve ser ajustado por uma quantidade específica (velocidade_motor_correção). A correção é realmente definida inicialmente como apenas a diferença nas contagens e, em seguida, meu ganho proporcional é amplificado por um ganho definido (P_gain). O ajuste integral vem da observação da mudança no erro. Se a mudança no erro estiver diminuindo, ela ajustará a quantidade de correção.

A parte do código de retorno fica assim:

for i in range(0,300):
    count12_delta = abs(myEncoders.count1) - (-myEncoders.count2)
    error_change = count12_delta - prev_count12_delta
    motor_speed_correction = count12_delta
    motor_speed_correction *= P_gain #proportional adjustment
    motor_speed_correction += (I_gain * error_change) #integral adjustment, looks at the change in error, if it gets smaller, than slow down the correction
    left_motor_speed -= motor_speed_correction
    myMotors.set_drive(L_MTR, L_BWD, (left_motor_speed))
    print("1:%d t2:%d tLS:%d tRS:%d tCD:%d tEr:%d tMC:%d" % 
                  (myEncoders.count1, -myEncoders.count2, left_motor_speed, right_motor_speed, count12_delta, error_change, motor_speed_correction))
    if(myEncoders.count1 < -575):
        break
    prev_count12_delta = count12_delta

É muito semelhante ao comando de linha reta, no entanto, agora eu inverto a direção do motor esquerdo e peguei o valor absoluto de sua contagem. Também adicionei uma verificação no count1 para interromper esse loop for assim que o curso de rotação desejado fosse atingido. Nesse caso, o valor 575 parecia ter uma curva perfeita de 180 graus.

Indo além

Tenho duas coisas que gostaria de tentar a seguir:

  • Pretendo olhar para a velocidade de cada motor (em vez de apenas olhar para o valor atual da contagem). Isso me permitiria combinar cada velocidade de cada motor individualmente. Eu tentei no código Python, mas eu realmente adoraria transferir os cálculos de velocidade para o ATTiny84, para que isso envolva a modificação do firmware novamente.
  • Eu também gostaria de melhorar meu método PID. Atualmente, na verdade, estou apenas incorporando os ganhos proporcionais e integrais, então gostaria de modificar isso eventualmente para incluir uma correção derivada.
Leia Também  Como os consumidores inteligentes estão impulsionando indústrias inteligentes

Você tem alguma experiência em dirigir rovers semelhantes para computadores? Qualquer idéia para melhorar meu sistema seria muito apreciada. Obrigado e condução feliz!

cupom com desconto - o melhor site de cupom de desconto cupomcomdesconto.com.br