AGV Alta Velocidade

Introdução Arquitetura Hardware Software Resultados Conclusões Referências

Por: Luis Vilaça nº1121405 / Henrique Azevedo nº1090960

Introdução   Inicio

Os Automated Guided Vehicle (AGV), são, como o nome indica, veiculos autómatos, que foram criados com o intuito de realizar tarefas e percursos, sendo orientado através da informação obtida pelo seu sistema de orientação (sensores), tendo como principal objectivo reduzir os custo de mão de obra ao automatizar a tarefa em mãos. No entanto, com a evolução da tecnologia, hoje em dia estes veiculos são o hobby de muitos fãs que participam nas mais variadas competições, sendo uma destas, uma corrida em contra relógio.
Usando sensores de infravermelho como sistema de orientação, os carros tentam percorrer um determinado percurso, que será implementado através de uma linha que poderá ser preta ou branca num piso de contraste. Conforme a pesquisa realizada, existem certas regras [1] que terão que ser cumpridas, entre as quais, o circuito não poderá ter mais de 60 metros de comprimento com intersecções, não podendo existir, nas mesmas, um ângulo de intersecção das linhas maior que 90±5°.
Claramente, o seguidor de linha terá que ser optimizado ao máximo tendo atenção a três vertentes que consideramos essenciais, o controlo variável de velocidade, a capacidade de orientação e correcção, com rapidez, do centro do carro em relação à posição da linha e um algoritmo que gera um erro aproximadamente linear consoante o desvio do veiculo.
Com o objectivo de construir algo semelhante, durante este primeiro semestre desenvolvemos um AGV de "Alta Velocidade" que tem como pontos diferenciadores em relação a um regular, o seu controlador PID e a sua capacidade de captar vários pontos de erro em relação ao nosso eixo.

Figura 1: Competições de seguidores de linha [2]

Arquitetura   Inicio

O nosso trabalho baseia-se num veiculo autónomo implementado num microcontrolador (uC) Atmega88 [7] no qual, em primeiro lugar, lê os valores dos sensores de infravermelho (CNY70) [3], de seguida processa-os e no fim actua nos motores, funcionando em loop.
A leitura dos sensores é realizada através do conversor analógico digital (ADC) do uC que capta os valores de tensão com origem em cada um dos CNY70 tranformando-os num valor entre 0 e 255, sendo que os valores baixos indicam a cor preta e os valores altos a cor branca. Depois do processamento da informação é gerado um sinal de pulse width modulation (PWM) através do Timer Counter 2 e injectado no driver dos motores (L293D) [4], indicando a velocidade a que cada motor vai funcionar, tendo definido o sentido de rotação através de saídas digitais do uC.
Tambem criamos um código de depuração que faz uso da Universal Synchronous Asynchronous Receiver Transmitter (USART) para enviar para um dispositivo que ligado através de Bluetooth recebe os valores lidos por cada CNY, o valor do erro calculado e os valores de duty cycle referentes a cada um dos sinais introduzidos no L293D para controlo de velocidade.
Como é referido nos requisitos minimos do sistema também é usado o Timer Counter 0 para realizar a contagem de 500ms e atuar no led ligado a uma entrada digital, de modo a fazendo-o piscar à frequencia de 1Hz.
Todo este sistema é alimentado por uma bateria LiPo de 11.1V e 1000mAh que carregada debita uma tensão de 12.4V. Esta tensão é a tensão de alimentação dos motores no driver dos motores (Vs) e regulada para 5V, através de um LM7805 [5], de forma a conseguir alimentar o uC e a parte lógica do L293D (Vss) [4].

Figura 2: Arquitetura do sistema

Hardware   Inicio

  1. Regulador de Tensão LM7805 [5]
  2. De modo a conseguir regular a tensão à saida da bateria para alimentar o uC e a parte lógica do L293D, foi usado um 7805 que regula a tensão de entrada para a tensão admissivel na alimentação de ambos os integrados e nos restantes componentes eléctricos, adicionando, também, uma protecção contra curto-circuitos ao sistema.



    Figura 3: LM7805

  3. Módulo Bluetooth Hc-06 [6]
  4. De modo a conseguir visualizar os dados processados pelos sensores e o erro processado pelo uC foi utilizado o Hc-06. Este módulo permite a comunicação entre dois dispositivos atraves de bluetooth tendo esta um alcançe máximo de 10 metros. A recepção no HC-06 é realizada num nivel logico de 3.3v que foi implementado com um divisor de tensão ligado ao pino de transmissão de comunicação serie (TX) do microcontrolador. Actualmente no mercado, existem 2 tipos destes dispositivos que diferem apenas no facto de um ser um módulo Master e o outro Slave, tendo sido este ultimo o que foi usado.
    Foi escolhido o HC-06 pois o sistema apenas irá receber ligações de outros dispositivos Bluetooth.




    Figura 4: Hc-06

  5. Motores com caixa de engrenagem "Kinmore FF-N20VA/TA" [8]
  6. Para atingir as velocidades observadas nos videos de competições são necessarios motores com velocidades nominais altas e que aguentassem as mudanças rápidas de velocidade.
    Após uma breve pesquisa concluimos que teriamos que utilizar motores com uma caixa de engrenagens devido ao binário necessário e com uma velocidade nominal de, no minimo, 400 rotações por minuto (RPM). Depois de definir um peso máximo para o veiculo, verificamos que estes motores com uma taxa de redução de 1/20 e uma velocidade nominal à volta de 600rpm são os ideais.
    Os motores usados são motores que operam entre os 3V e os 6V com uma velocidade nominal de 12240 rotações por minuto (RPM), devido à taxa de redução da caixa de engrenagens esta velocidade passa para 612 RPM com um torque de 3 g/cm³.





    Figura 5: Motores DC

    Figura 6: Caracteristicas dos motores usados

  7. Ponte H - Driver de Motores L293D [4]
  8. Para controlar os motores foi necessario um integrado de potência que recebe um sinal com uma baixa corrente e que gera um sinal com uma corrente maior, terá que conseguir definir o sentido de orientação do movimento e proceder à inversão do mesmo. Visto que teriamos que controlar dois motores em simultâneo daí originou a escolha do L293D.
    Os sinais PW são injectados nos pinos 1 e 9 do integrado que controlam a corrente que flui por cada um dos motores ligados aos pinos com a label MOT (pinos: 3,6,11,14) enquanto que os pinos indicados com a label INT controlam o sentido de rotação e a travagem do motor. Este integrado consegue controlar correntes até um máximo de 600mA por motor e com tensões entre os 4.5V e os 36V.



    Figura 7: L293D

    Figura 8: Esquemático L293D

  9. Sensor infravermelho CNY70 [3]
  10. Como sistema de orientação para o veiculo, optou-se pelos sensores CNY70 devido ao seu encapsulamento que confere ao componente robustez e durabilidade. É composto por um led infravermelho (emissor) e um fototransistor (receptor) que funcionam num comprimento de onda de 950nm. Este sensor para uma superficie pouco ou não refletora devolve ao uC um valor de tensão "baixo" na ordem dos mV e para as superficies refletoras um valor de tensão "alto", perto do seu máximo de alimentação, 5V.
    A distância ideal de sensibilidade é de 0.3mm, não tendo sido respeitado pois iremos precisar que os sensores detetem a cor "cinzenta" (valor intermedio de tensão) como iremos explicar mais à frente.




    Figura 9: CNY70

    Figura 10: Esquemático de cada Cny70

  11. Atmega88 [7]
  12. Após a realização de uma lista com todos os periféricos a usar, verificamos que o microcontrolador utilizado para as avaliações anteriores da unidade curricular reunia as condições necessarias para ser a base do nosso sistema. Com uma velocidade de relógio que poderá chegar a 20 Mhz (externo), 6 entradas no ADC, 3 Timer Counters, 1 USART e os suficientes pinos I/O para acoplar os componentes utilizados.
    De seguida, apresentamos o esquemático do sistema usado.




    Figura 11: Atmega88

    Figura 12: Esquemático Sistema

  13. Printed Circuit Board - PCB
  14. Conforme foi pedido, aqui apresentamos o desenho da Printed Circuit Board (PCB) do nosso sistema.

    Figura 12: PCB - Placa de circuito impresso

    NOTA: O cristal oscilador presente no esquemático, PCB e no próprio carro apesar de não estar a ser utilizado por Software pode vir a ser utilizado numa versão posterior.

Software   Inicio

A figura seguinte identifica e explica as configurações dos periféricos usados no projeto.
Figura 13: Configurações dos periféricos"
Como dito anteriormente, este programa baseia-se na execução de 3 passos, a leitura, o processamento de informação e a atuação. O ponto diferenciador este projeto é o método de leitura utilizado. Normalmente, o que um AGV faz é usar os sensores infravermelhos de modo a obter, ou através de Hardware ou Software, uma comparação gerando estados lógicos.
Descobriu-se que usando os valores obtidos diretamente do ADC em conjunto com uma média ponderada, se conseguia obter valores mais precisos para a posição relativa do carro face à posição da linha. Por exemplo, se o carro estiver com erro máximo à esquerda terá um valor de -255, 0 se estiver no centro e 255 á direita.
Foi implementada comunicação Bluetooth com o computador para fazer a depuração das leituras de cada sensor de linha e as saídas de cada função de processamento de dados.
De forma conseguir variar o valor da velocidade do carro durante o funcionamento, fez-se um "mapeamento" da pista, dividindo-a em segmentos em cada um assume um estado dos seguintes apresentados:
  1. Init;
  2. Curva rápida;
  3. Curva média;
  4. Travagem.
Figura 14: Mapeamento
Cada estado tem atribuidos valores próprios e diferentes do outros estados para a velocidade, constante proporcional e constante derivativa do controlo PD. A mudança de estado é feita pelo sensor lateral através do qual, ao passar pelas linhas lateriais, actualiza um contador que serve de indice para um vetor que contém o mapeamento da pista.
De modo a executar as leituras dos sensores é usada a interrupção do Conversor Analógico/Digital que irá gerar um valor de 8 bits consoante o valor de tensão lido no emissor do receptor de cada sensor CNY70. Através da função "read_analog()" é primeiramente selecionado o canal ADC a ler através da reconfiguração do registo ADMUX usando os valores preestabelecidos no vetor admux_vec, de seguida ativada a conversão que quando terminada, copia o valor convertido para um registo temporário chamado med_temp. A variável flag_adc apenas funciona como uma condição de teste para detetar o final da conversão.
Este valor é testado sempre que é efectuada uma leitura de modo a encontrar os valores máximos e mínimos de cada sensor que mais à frente são usados no processamento de dados. É tambem testado o valor lido do sensor auxiliar, que deteta mudanças de estado, sendo que a mudança de estado apenas acontece quando existe uma passagem de uma leitura que deteta a cor branca para uma leitura que deteta a cor preta.
O seguinte fluxograma exemplifica os passos tomados na leitura dos sensores.

Figura 14: Read_Analog e Interrupção ADC


O processamento de dados é implementado através de 3 funções, a escala, a media e o control_pd. Sendo que cada uma corresponde respectivamente à "auto-calibração progressiva", ao cálculo da média ponderada e ao Controlador Proporcional Diferencial.
Como cada sensor não lê o mesmo valor minimo numa superficie pouco refletora e o mesmo valor máximo numa superficie refletora (máximos e mínimos), surgiu a necessidade de normalizar os sensores fazendo com que cada um adotasse o mesmo minimo e o mesmo máximo, deixando assim de existir discrepâncias nos valores de erro calculados. Este processo é implementado pela função "escala()" que através de uma regra de 3 simples são passados os valores lidos de cada CNY70 que têm uma escala de [valor mínimo - valor máximo] para uma escala de [0-255] e novamente guardado no vetor "leitura_cny[]" na posição onde estava anteriormente localizado. É apresentado a seguir o fluxograma referente á função "escala()".

Figura 15: Escala

Para obtermos uma variavel de erro que será usada no nosso controlador foi implementado o cálculo de uma média ponderada, na qual a cada sensor é atribuido um peso, localizados no vetor "peso[]", estes valores foram definidos com valores crescentes da esquerda para a direita e com espaçamento igual pois, após o cálculo, obtem-se um valor que nos indica a posição da linha num intervalo de [0-100]. A fórmula usada no cálculo é a apresentada na figura seguinte.

Figura 16: Fórmula Média Ponderada

Figura 17: Eixo que contém as posições da linha possiveis

Através da função "media()" é implementado este cálculo mas é necessário proceder a uma inversão de valores pois o trajeto na pista é definido com uma fita preta e os valores de superficie pouco refletora lidos são valores baixos. O valor referente ao numerador é guardado na variável "med" e o referente ao denominador é guardado na variável "som". Após o cálculo é adicionado um offset que é equivalente a metade da escala (- 50) de modo a conseguir uma referência que define se a linha esta para a esquerda ou para a direita em relação ao centro do carro. Por fim este valor é para uma escala de [0-255]. Estes valores podem ser conferidos com um código em anexo, Modo Depuração, que utiliza a UART para enviar os valores calculados via bluetooth.

Figura 18: Média

Como num veiculo que participa numa corrida em contra-relógio é necessario que o carro tenha o máximo de eficiência a percorrer o trajecto concluiu-se que seria preciso um algoritmo que controlasse o modo como o programa atua nos motores. Sendo assim, foi implementado um algoritmo de um controlador em malha fechada que une a acção proporcional à derivativa, respondendo às nossas necessides no momento, este algoritmo situa-se na função "control_pd()".
O controlo proporcional varia o controlo proporcionalmente com o valor de erro gerado anteriormente, enquanto que o controlo derivativo varia o controlo de acordo com a variação do erro, dependendo assim do ultimo erro calculado (erro atual - erro anterior). Para calcular o valor de controlo são somadas as partes referentes a cada acção, sendo que cada uma delas é multiplicada pela constante definida para cada uma consoante o estado atual (KP[estado] e KD[estado]). De seguida, está apresentado o fluxograma referente ao calculo do erro gerado pela função "media()" e o valor do controlador pela função "control_pd()".

Figura 19: Controlador P.D.

A actuação nos motores foi implementada na função "mov_motor()", na qual em primeiro lugar é definido o sentido inicial dos motor e de seguida é testado o valor de erro gerado que define o motor que terá uma redução de velocidade em relação ao seu valor base. Se o erro for negativo é a velocidade do motor da esquerda que será menor em relação ao motor da direita corrigindo assim a posição do carro para o centro. O inverso acontece se o erro for positivo.
Como o controlador poderá fazer com que o carro tome uma correcção maior que o valor base da velocidade invertemos o sentido do motor do lado para qual a correcção é tomada fazendo com que o carro possa realizar curvas com uma amplitude maior. De seguida os valores de atuação em cada motor são limitados ao valor máximo definido no inicio do código.
Na figura seguinte está demonstrada a ordem de execução na função "mov_motor()".

Figura 20: Mov_Motor

Resultados   Inicio

Figura 21: Vídeo do projeto

Figura 22: Vídeo da Depuração do valor de erro


Figura 23: Protótipo Construido

Conclusões   Inicio

Face aos AGVs desenvolvidos anteriormente nesta unidade curricular (UC), optou-se por evoluir o que já foi feito. Depois observar alguns videos de AGVs de alta-velocidade, decidiu-se criar um veiculo que seguisse o mesmo principio, ie, que conseguisse circular a uma velocidade superior e sem grandes zigue-zagues.
Começou-se por testar o veiculo com leituras digitais, cada sensor lê branco ou preto, e ver como o carro se comportava. Neste modo, o carro andava aos zigue-zagues como esperado, mas não era o que pretendiamos. Para evitar esse comportamento, percebeu-se que precisava de obter uma leitura do erro mais precisa e um controlo PID para suavizar o movimento do carro.
Desenvolveu-se uma função de leitura dos sensores analógica e feita uma média ponderada, que aliada a um controlo PD, resultou num controlo preciso do veiculo a uma velocidade alta.
Relativamente à média ponderada, descobriu-se ao longo das semanas que havia uma não-linearidade entre a distância do eixo ao centro e o erro calculado, a variação do erro é parcialmente linear pois as zonas que variam linearmente são intercaladas por patamares de valor constante, mas para os efeitos pretendidos o carro comporta-se dentro do esperado. No entanto, acreditamos que um estudo mais profundo da relação da distancia entre sensores e a largura da linha a seguir poderá aumentar a precisão do erro e por conseguinte melhorar ainda mais o movimento do carro. Foi acrescentado em anexo um código correspondente a um modo depuração usado para verificar que os valores lidos pelos sensores correspondem aos valores teóricos que pretendiamos obter.
O controlo PID, na realidade PD, foi desenvolvido empiricamente. Inicialmente, tentamos seguir o método de malha fechada Ziegler-Nichols, no entanto os valores obtidos para as constantes proporcionais e derivativas não surtiam o efeito desejado. Seguimos o método apenas para a abtenção da constante proporcional e obtivemos o periodo de oscilação, passamos então a um método de observação para a constante derivativa. Não usamos o efeito integrativo pois, sendo que o nosso erro já é relativo a um centro, no nosso caso não é necessário um ajuste do erro estacionário com um offset.
No cálculo final do valor para actuação nos motores, existirão momentos em que a constante derivativa não estará presente devido aos patamares falados mais acima (pois não há variação do erro) o que se traduz num movimento não tão suave como o pretendido.

Depois de terminado este projecto, verificamos que este deveria ser melhorado nos seguinte aspectos:
  1. Peso do carro: deve ser reduzido ao máximo, pois quanto mais baixo for o peso menos inercia haverá, logo haverá mais facilidade de manobrar o carro;
  2. Rodas do carro: para haver maior contacto com o chão deveríamos ter umas rodas mais largas e tipo "slick";
  3. Centro de gravidade: baixar o mais possível para melhorar o controlo nas curvas;
  4. CNY70: verificamos que com este sensores a leitura do erro é algo imprecisa e com uma camera e openCV, talvez se possa melhorar bastante o sistema de orientação, no entanto não poderá ser feito com este microprocessador;
  5. Alimentação: Usar uma bateria de 14.8 V e um LM7812 na alimentação dos motores, para evitar flutuações de tensão;