Índice:

Rpibot - Sobre o aprendizado de robótica: 9 etapas
Rpibot - Sobre o aprendizado de robótica: 9 etapas

Vídeo: Rpibot - Sobre o aprendizado de robótica: 9 etapas

Vídeo: Rpibot - Sobre o aprendizado de robótica: 9 etapas
Vídeo: Robotics 2.0: Combining Artificial Intelligence and RPA 2024, Julho
Anonim
Rpibot - Sobre Aprendizagem de Robótica
Rpibot - Sobre Aprendizagem de Robótica

Sou engenheiro de software embarcado em uma empresa automotiva alemã. Iniciei este projeto como uma plataforma de aprendizagem para sistemas embarcados. O projeto foi cancelado cedo, mas gostei tanto que continuei no meu tempo livre. Este é o resultado …

Eu tinha os seguintes requisitos:

  • Hardware simples (o foco é o software)
  • Hardware barato (cerca de 100 €)
  • Expansível (algumas opções já fazem parte da descrição)
  • Tensão de alimentação para todos os componentes de uma única fonte de 5 V (banco de energia)

Não havia realmente um objetivo além de aprender. A plataforma pode ser usada para aprendizagem, vigilância, concursos de robótica, …

Não é um tutorial para iniciantes. Você precisa de alguns conhecimentos básicos sobre:

  • Programação (Python)
  • Eletrônica básica (para conectar os módulos juntos pela tensão certa)
  • Teoria de controle básico (PID)

Finalmente, você provavelmente enfrentará problemas como eu. Com alguma curiosidade e perseverança, você passará pelo projeto e resolverá os desafios. Meu código é o mais simples possível e as linhas de código críticas são comentadas para dar dicas.

O código-fonte completo e os arquivos estão disponíveis aqui:

Suprimentos:

Mecânica

  • 1x placa de madeira compensada (tamanho A4, 4 mm de espessura)
  • 3x M4 x 80 Parafuso e porca
  • 2x motoredutores com eixo de saída secundário para encoder. Rodas.
  • 1x roda grátis

1x montagem panorâmica e inclinação da câmera (opcional)

Eletrônicos

  • 1x Raspberry Pi Zero com cabeçalho e câmera
  • 1x controle servo PCA 9685
  • 2x roda codificadora ótica e circuito
  • 1x fios de jumper feminino
  • 1x powerbank USB
  • 1 driver de motor duplo DRV8833
  • 2x Micro servos SG90 para panorâmica e inclinação da câmera (opcional)
  • 1x MPU9250 IMU (opcional)
  • 1 sensor de distância ultrassônico HC-SR04 (opcional)
  • 1x placa perfurada e fio de solda, cabeçalhos, …

Etapa 1: construir o chassi

Construir o Chassi
Construir o Chassi
Construir o Chassi
Construir o Chassi
Construir o Chassi
Construir o Chassi

Não sou um bom designer mecânico. Além disso, o objetivo do projeto é não gastar muito tempo no chassi. De qualquer forma, defini os seguintes requisitos:

  • Materiais baratos
  • Montagem e desmontagem rápida
  • Expansível (por exemplo, espaço para sensores adicionados)
  • Materiais leves para economizar energia para a eletrônica

Um chassi fácil e barato pode ser feito de compensado. É fácil de usinar com uma serra e uma furadeira manual. Você pode colar pequenas peças de madeira para criar os suportes para sensores e motores.

Pense na substituição de componentes defeituosos ou na depuração elétrica. As partes principais devem ser fixadas por parafusos para serem substituíveis. Uma pistola de cola quente pode ser simples, mas provavelmente não é a melhor maneira de construir um chassi … Eu precisei de muito tempo para pensar em um conceito fácil de desmontar as peças facilmente. A impressão 3D é uma boa alternativa, mas pode ser muito cara ou demorada.

A roda livre é finalmente muito leve e fácil de montar. As alternativas eram todas pesadas ou cheias de atrito (tentei algumas antes de encontrar a última). Só precisei cortar um espaçador de madeira para nivelar a roda livre da cauda após montar as rodas principais.

Propriedades da roda (para cálculos de software)

Circunferência: 21,5 cmPulsos: 20 pulsos / rev. Resolução: 1,075 cm (finalmente 1 pulso equivale a cerca de 1cm, o que é fácil para cálculos de software)

Etapa 2: Eletrônica e fiação

Eletrônica e fiação
Eletrônica e fiação
Eletrônica e fiação
Eletrônica e fiação
Eletrônica e fiação
Eletrônica e fiação

O projeto está usando módulos diferentes, conforme mostrado no diagrama.

O Raspberry Pi Zero é o controlador principal. Ele está lendo os sensores e controlando os motores por um sinal PWM. Ele está conectado a um PC remoto por wi-fi.

O DRV8833 é uma ponte H de motor duplo. Ele está fornecendo a corrente suficiente para os motores (o que o Raspberry Pi não pode fazer, pois as saídas podem fornecer apenas alguns mA).

O codificador óptico fornece um sinal quadrado cada vez que a luz passa pelas rodas do codificador. Usaremos as interrupções de HW do Raspberry Pi para obter as informações cada vez que o sinal for alternado.

O pca9695 é uma placa de controle servo. Ele está se comunicando por um barramento serial I2C. Esta placa está fornecendo os sinais PWM e a tensão de alimentação que controlam os servos para panorâmica e inclinação do came.

O MPU9265 é uma aceleração de 3 eixos, velocidade de rotação angular de 3 eixos e sensor de fluxo magnético de 3 eixos. Iremos usá-lo principalmente para obter a direção da bússola.

Os diferentes módulos são todos conectados por um fio de jumper. Uma placa de ensaio atua como um despachante e fornece tensões de alimentação (5 V e 3,3 V) e aterramentos. As conexões são todas descritas na tabela de conexões (ver anexo). Conectar 5 V a uma entrada de 3,3 V provavelmente destruirá seu chip. Tome cuidado e verifique toda a fiação duas vezes antes de fornecer (aqui especialmente o codificador deve ser considerado). Você deve medir as tensões de alimentação principais na placa de despacho com um multímetro antes de conectar todas as placas. Os módulos foram fixados por parafusos de náilon no chassi. Também aqui fiquei feliz por tê-los consertado, mas também removíveis em caso de mau funcionamento.

A única soldagem foi, finalmente, os motores, a placa de ensaio e os conectores. Para ser honesto, eu gosto dos fios de jumper, mas eles podem causar perda de conexão. Em algumas situações, alguns monitoramentos de software podem ajudá-lo a analisar as conexões.

Etapa 3: Infraestrutura de software

Infraestrutura de software
Infraestrutura de software
Infraestrutura de software
Infraestrutura de software

Depois de obter a mecânica, iremos configurar alguma infraestrutura de software para ter condições de desenvolvimento confortáveis.

Git

Este é um sistema de controle de versão de código aberto e gratuito. É usado para gerenciar grandes projetos como Linux, mas também pode ser facilmente usado para pequenos projetos (veja Github e Bitbucket).

As alterações do projeto podem ser rastreadas localmente e também enviadas a um servidor remoto para compartilhar software com a comunidade.

Os principais comandos usados são:

git clone https://github.com/makerobotics/RPIbot.git [Obtenha o código-fonte e a configuração git]

git pull origin master [obter o mais recente do repositório remoto]

git status [obtém o status do repositório local. Algum arquivo foi alterado?] Git log [obter a lista de commits] git add. [adicionar todos os arquivos alterados ao estágio a ser considerado para o próximo commit] git commit -m "comentário para commit" [enviar as alterações para o repositório local] git push origin master [enviar todos os commits para o repositório remoto]

Exploração madeireira

Python está fornecendo algumas funções de registro integradas. A estrutura do software deve definir já toda a estrutura de registro antes de iniciar o desenvolvimento adicional.

O logger pode ser configurado para registrar com um formato definido no terminal ou em um arquivo de registro. Em nosso exemplo, o logger é configurado pela classe webserver, mas também podemos fazer isso por conta própria. Aqui, definimos apenas o nível de registro para DEBUG:

logger = logging.getLogger (_ name_)

logger.setLevel (logging. DEBUG)

Medição e plotagem

Para analisar os sinais ao longo do tempo, o melhor é traçá-los em um gráfico. Como o Raspberry Pi possui apenas um terminal de console, rastrearemos os dados em um arquivo csv separado por ponto-e-vírgula e representá-lo-emos a partir do PC remoto.

O arquivo de rastreamento separado por ponto e vírgula é gerado por nosso código python principal e deve ter cabeçalhos como este:

timestamp; yawCorr; encoderR; I_L; odoDistance; ax; encoderL; I_R; yaw; eSpeedR; eSpeedL; pwmL; speedL; CycleTimeControl; wz; pwmR; speedR; Iyaw; hdg; m_y; m_x; eYaw; tempo de ciclo; m_x; eYaw;

1603466959.65;0;0;25;0.0;-0.02685546875;0;25;0;25;25;52;0.0;23;0.221252441406;16;0.0;0;252.069366413;-5.19555664062;-16.0563964844;0;6; 1603466959.71;0;0;50;0.0;0.29150390625;0;50;0;25;25;55;0.0;57;-8.53729248047;53;0.0;0;253.562118111;-5.04602050781;-17.1031494141;0;6; 1603466959.76;0;-1;75;0.0;-0.188232421875;1;75;2;25;25;57;0;52;-24.1851806641;55;0;0;251.433794171;-5.64416503906;-16.8040771484;2;7;

A primeira coluna contém o carimbo de data / hora. As seguintes colunas são gratuitas. O script de plotagem é chamado com uma lista de colunas a serem plotadas:

remoto @ pc: ~ / python rpibot_plotter -f trace.csv -p speedL, speedR, pwmL, pwmR

O script do plot está disponível na pasta de ferramentas:

O plotter está usando mathplotlib em Python. Você deve copiá-lo para o seu PC.

Para mais conforto, o script python é chamado por um script bash (plot.sh) que é usado para copiar o arquivo de rastreamento Raspberry Pi para o PC remoto e chamar o plotter com uma seleção de sinal. O script bash "plot.sh" pergunta se o arquivo tiver que ser copiado. Isso foi mais conveniente para mim em vez de copiar manualmente todas as vezes. "sshpass" é usado para copiar o arquivo do Raspberry Pi para o PC remoto via scp. É capaz de copiar um arquivo sem pedir a senha (é passada como parâmetro).

Finalmente, uma janela é aberta com o gráfico conforme mostrado na imagem.

Comunicação remota

A interface de desenvolvimento do Raspberry Pi é SSH. Os arquivos podem ser editados diretamente no destino ou copiados por scp.

Para controlar o robô, um servidor web está rodando no Pi, fornecendo controle via Websockets. Essa interface é descrita na próxima etapa.

Configure o Raspberry Pi

Há um arquivo que descreve a configuração do Raspberry Pi na pasta "doc" do código-fonte (setup_rpi.txt). Não há muitas explicações, mas muitos comandos e links úteis.

Etapa 4: a interface do usuário

A interface do usuário
A interface do usuário

Usamos o leve servidor da web Tornado para hospedar a interface do usuário. É um módulo Python que chamamos quando iniciamos o software de controle do robô.

Arquitetura de software

A interface do usuário é construída pelos seguintes arquivos: gui.html [Descrevendo os controles e layout da página da web] gui.js [Contém o código javascript para manipular os controles e abrir uma conexão de websocket para nosso robô] gui.css [Contém os estilos de os controles html. As posições dos controles são definidas aqui]

A comunicação do websocket

A interface do usuário não é das mais legais, mas está fazendo o trabalho. Concentrei-me aqui em tecnologias que eram novas para mim, como Websockets.

O site está se comunicando com o servidor da web do robô por Websockets. Este é um canal de comunicação bidirecional que permanecerá aberto assim que a conexão for iniciada. Enviamos os comandos do robô via Websocket para o Raspberry Pi e obtemos informações (velocidade, posição, fluxo da câmera) de volta para exibição.

O layout da interface

A interface do usuário possui uma entrada manual para os comandos. Isso foi usado no início para enviar comandos ao robô. Uma caixa de seleção liga e desliga o fluxo da câmera. Os dois controles deslizantes controlam a panorâmica e a inclinação da câmera. A parte superior direita da interface do usuário controla o movimento dos robôs. Você pode controlar a velocidade e a distância do alvo. As informações básicas de telemetria são exibidas no desenho do robô.

Etapa 5: Programando a plataforma do robô

Programando a plataforma do robô
Programando a plataforma do robô
Programando a plataforma do robô
Programando a plataforma do robô
Programando a plataforma do robô
Programando a plataforma do robô

Essa parte era o principal objetivo do projeto. Refatorei muito do software ao apresentar o novo chassi com os motores DC. Usei Python como linguagem de programação por diferentes razões:

  • É o idioma principal do Raspberry Pi
  • É uma linguagem de alto nível com muitos recursos e extensões integrados
  • É orientado a objetos, mas também pode ser usado para programação sequencial
  • Nenhuma compilação ou cadeia de ferramentas necessária. Edite o código e execute-o.

Arquitetura de software principal

O software é orientado a objetos, dividido em alguns objetos. Minha ideia era dividir o código em 3 blocos funcionais:

Sense Think Actuate

Sense.py

Aquisição e processamento do sensor principal. Os dados são armazenados em um dicionário para ser utilizado na etapa seguinte.

Control.py

Uma subclasse de atuação está controlando os motores e servos após alguma abstração. O objeto de controle principal está lidando com os comandos de alto nível e também os algoritmos de controle (PID) para o motor.

rpibot.py

Este objeto principal é gerenciar o servidor web Tornado e instanciar as classes de sentido e controle em threads separados.

Cada módulo pode ser executado sozinho ou como parte de todo o projeto. Você pode detectar apenas e imprimir as informações do sensor para verificar se os sensores estão conectados corretamente e fornecendo as informações corretas.

O controle PID

A primeira tarefa é descobrir o que queremos controlar. Comecei tentando controlar a posição, o que era muito complexo e não ajudava muito.

Por fim, queremos controlar a velocidade de cada roda e também a direção do robô. Para fazer isso, temos que colocar em cascata duas lógicas de controle.

Para aumentar a complexidade passo a passo, o robô deve ser controlado:

circuito aberto (com uma potência constante)

pwm = K

em seguida, adicione o algoritmo de loop fechado

pwm = Kp.speedError + Ki. Integration (speedError)

e, finalmente, adicione o controle de direção como uma última etapa.

Para o controle de velocidade usei um controle "PI" e "P" apenas para o guinada. Eu defino manualmente os parâmetros experimentando. Provavelmente, parâmetros muito melhores poderiam ser usados aqui. Meu alvo era apenas uma linha reta e quase consegui. Criei uma interface no software para escrever algumas variáveis pela interface do usuário. Definir o parâmetro Kp como 1.0 requer o seguinte comando na interface do usuário:

SET; Kp; 1,0

Eu poderia definir o parâmetro P baixo o suficiente para evitar qualquer ultrapassagem. O erro restante é corrigido pelo parâmetro I (erro integrado)

Foi difícil para mim descobrir como colocar os dois controles em cascata. A solução é simples, mas tentei de muitas outras maneiras antes … Então, finalmente, mudei a meta de velocidade das rodas para virar em uma ou outra direção. Alterar a saída do controle de velocidade diretamente foi um erro, pois o controle de velocidade estava tentando remover esta perturbação.

O diagrama de controle usado está anexado. Mostra apenas o lado esquerdo do controle do robô.

Etapa 6: Calibrações do sensor

As Calibrações do Sensor
As Calibrações do Sensor
As Calibrações do Sensor
As Calibrações do Sensor
As Calibrações do Sensor
As Calibrações do Sensor

A primeira coisa a se considerar é que toda a IMU deve funcionar corretamente. Encomendei 3 peças e devolvi-as até ter um sensor totalmente funcional. Cada sensor anterior tinha algumas partes do sensor que não funcionavam corretamente ou não funcionavam. Usei alguns scripts de exemplo para testar o básico antes de montá-lo no robô.

Os sinais do sensor IMU precisam ser calibrados antes de usá-lo. Alguns sinais do sensor dependem do ângulo e da posição de montagem.

As calibrações de velocidade de aceleração e rotação

A calibração mais fácil é para a aceleração longitudinal (A_x). A paralisação deve ser em torno de 0 m / s². Se você girar o sensor corretamente, você pode medir a gravidade (cerca de 9,8 m / s²). Para calibrar a_x, basta montá-lo corretamente e então definir o offset para obter 0 m / s² na paralisação. Agora A_x está calibrado. Você pode obter os deslocamentos para as velocidades de rotação de maneira semelhante na paralisação.

A calibração do magnetômetro para a bússola

Uma calibração mais complexa é necessária para os sensores de campo magnético. Usaremos m_x e m_y para obter o campo magnético no nível horizontal. Ter m_x e m_y nos dará a oportunidade de calcular a direção de uma bússola.

Para o nosso propósito simples, iremos apenas calibrar o desvio do ferro duro. Isso deve ser executado quando o sensor está na posição final, pois depende das perturbações do campo magnético.

Registramos m_x e m_y enquanto giramos o robô em torno do eixo z. Plotamos m_x vs m_y em um gráfico XY. O resultado em reticências, conforme mostrado na imagem. A elipse deve ser centrada na origem. Aqui, consideramos os valores máximo e mínimo de m_x e m_y para obter os deslocamentos em ambas as direções. Por fim, verificamos a calibração e vemos que as reticências agora estão centralizadas.

A calibração do ferro macio significaria que mudamos a imagem de uma elipse para um círculo. Isso pode ser feito adicionando um fator em cada valor secundário.

Uma rotina de teste agora pode ser codificada para recalibrar ou pelo menos para verificar se os sensores ainda estão calibrados.

O título da bússola

Os dados do magnetômetro agora serão usados para calcular a direção da bússola. Para isso, temos que converter os sinais m_x e m_y em um ângulo. Python está fornecendo diretamente a função math.atan2 que tem esse objetivo. O cálculo completo é definido no arquivo mpu9250_i2c.py ("calcHeading (mx, my, mz)").

Etapa 7: designs alternativos

Projetos Alternativos
Projetos Alternativos
Projetos Alternativos
Projetos Alternativos
Projetos Alternativos
Projetos Alternativos

O projeto demorou muito porque o design era totalmente aberto. Para cada componente fiz algumas implementações de protótipos e experimentei os limites do sistema.

O tópico mais complexo era o codificador de roda. Testei 3 opções diferentes antes de encontrar o codificador óptico usado atualmente. Eu acho que as soluções abortadas também são muito interessantes em tal projeto. Diz respeito às partes onde mais aprendi.

Servo de rotação contínua conectado ao pca 9695

Para evitar uma ponte H adicional para um motor DC, comecei com servos de rotação contínua. Estes foram acionados pelo já presente servo driver pca 9695. Toda a mecânica de propulsão e a eletrônica correspondente eram muito mais simples. Este projeto tinha duas desvantagens:

  • O alcance de controle pobre dos servos.
  • A localização de retenção do codificador ausente

Os servos começam a se mover com 50% pwm e têm velocidade total em cerca de 55%. Esta é uma faixa de controle muito pobre.

Sem um codificador, era muito difícil encontrar um codificador pronto para usar. Testei 3 codificadores de refletância diferentes que foram montados no chassi. Eu colei uma roda codificadora feita por mim mesmo na parte externa da roda com seções em preto e branco. Usei os sensores QTR-1RC, que precisam de muito processamento de sinal para obter o sinal correto. O Raspberry Pi não era capaz de realizar esse tipo de processamento em tempo real. Então decidi adicionar um NodeMCU D1 mini como um controlador em tempo real para o robô. Ele foi conectado ao raspberry Pi pelo UART serial para fornecer os dados processados do sensor. O NodeMCU também gerenciava o sensor HC-SR04. A mecânica era difícil e não muito robusta, a linha serial estava recebendo ruído da linha I2C e dos motores, então finalmente construí a segunda versão do chassi com motores DC de engrenagem simples acionados por uma ponte H. Esses motores possuem um eixo de saída secundário para colocar um codificador óptico.

Etapa 8: Processamento de imagem

Processamento de imagem
Processamento de imagem
Processamento de imagem
Processamento de imagem
Processamento de imagem
Processamento de imagem
Processamento de imagem
Processamento de imagem

Para melhorar a condução autônoma, podemos fazer algum processamento de imagem.

A biblioteca opencv é uma referência para isso. Ele pode ser usado pelo Python para implementar rapidamente a detecção de obstáculos.

Capturamos uma imagem e aplicamos algumas tarefas de processamento de imagem:

Os primeiros testes foram feitos com transformações de Canny e Sobel. Canny pode ser um bom candidato, mas não é sensato o suficiente. Sobel é muito sensível (muitos objetos detectados).

Finalmente fiz meu próprio filtro para misturar todos os gradientes horizontais e verticais (detectar móveis):

  • Transforme a imagem colorida em uma imagem em nível de cinza
  • Desfoque a imagem para remover pequenos ruídos
  • Limite a imagem para uma imagem em preto e branco
  • Agora detectamos gradientes horizontais e verticais para detectar objetos como paredes e móveis
  • Filtramos apenas os grandes contornos restantes (veja os contornos coloridos na imagem)

Agora podemos usar essas novas informações para detectar obstáculos …

Etapa 9: Próximas etapas …

Próximos passos…
Próximos passos…
Próximos passos…
Próximos passos…

Agora, temos uma plataforma de robô simples com sensores, atuadores e uma câmera. Meu objetivo é me mover de forma autônoma e voltar para a estação sem adicionar mais sensores. Para isso, vou precisar dos seguintes passos:

  • Fusão de sensor de sinais de orientação magnética e guinada
  • Processamento de imagem da câmera (apenas baixa CPU disponível para isso)
  • Detecção de colisão (distância ultrassônica e câmera)
  • Construção ou orientação do mapa

Agora vá e crie seus próprios desafios ou metas …

Recomendado: