Robô de carrinho 2.0. Parte 1. Navegação autônoma de um robô doméstico baseado em ROS

O projeto foi construído com base em outro projeto bem conhecido em seus círculos - linorobot (linorobot.org), usando componentes disponíveis para um simples leigo. Os objetivos que foram definidos: alcançar o movimento autônomo do robô em casa usando componentes de baixo custo, avaliar o desempenho dos mini-PCs para os fins declarados, configurar a pilha de navegação para se mover nos espaços estreitos do Khrushchev.



Ferro


A lista de componentes nos sólidos é a seguinte:

  • framboesa pi 3b - 2800 r .;
  • lidar rplidar a1 - 7500 p .;
  • pontes de força l298n -2pcs - 400 esfregar;
  • rodado com codificadores do tipo A e B - 2000 r. (210 rpm - link )
  • teenzy 3,2 - 2100 r .;
  • imu 9250 (9150 ou 6050) - 240 p .;
  • banco de potência a 10000mH - 1500 r.
  • 3 baterias 18650 e suporte -600 p.
  • conversor abaixador dc-dc c 5V a 3.3V - 20p.
  • um pedaço de madeira compensada, parquet -? esfregar.

Total: 17160 p.

* O custo pode ser reduzido substituindo teenzy pelo arduino mega 2560 (600 p.), E lidar substituindo o kinect v.1 (1000 p.):



No entanto, deve-se notar que o primeiro kinect tem uma visibilidade mínima (área cega) de 0,5 m, o que pode afetar negativamente a navegação em condições apertadas e é bastante volumoso. O lidar tem uma zona cega de menos de 0,2 m. O Kinect v.2 não se encaixa no raspberry 3b (não possui usb 3.0). O mega do Arduino é inferior ao tamanho teenzy (e algumas características); além disso, você precisará refazer um pouco o código.

Em geral, o "design" se parece com o seguinte:





é claro que não há beleza aqui, mas não é isso.

Além do próprio robô, é altamente desejável ter um PC externo no qual serão projetadas cápsulas gráficas para visualizar as ações do robô (rviz, gazebo).

Montagem do robô


Ele é pintado em detalhes no site do projeto - um link , então vamos nos concentrar nos pontos que causam dificuldades. Primeiro, você precisa considerar que os codificadores no rodado são alimentados por 3,3V e, quando 5V é aplicado, falham perfeitamente.

O script de instalação linorobot foi instalado com sucesso no ubuntu 16.04, ubuntu 18.04. Versões ROS: ROS cinéticas ou ROS melódicas. No raspberry 3b, você deve primeiro criar um arquivo de troca.

O principal código teenzy está no caminho:

roscd linorobot/teensy/firmware/lib/config
nano lino_base_config.h

E derramou nele com o comando:

roscd linorobot/teensy/firmware
platformio run --target upload

Os pacotes de comandos acima serão usados ​​com bastante frequência; portanto, faz sentido adicioná-los aos aliases.

Devido às dificuldades na montagem do robô, a correlação correta de contatos conectados, que vai de l298n a teenzy, pode ser problemática. Apesar do diagrama de conexão extremamente claro, as rodas podem se comportar de maneira diferente e precisam experimentar, escolhendo a atribuição correta de pinos no código.

No meu caso, ficou assim:

/// ENCODER PINS
#define MOTOR1_ENCODER_A 14
#define MOTOR1_ENCODER_B 15 

#define MOTOR2_ENCODER_A 11
#define MOTOR2_ENCODER_B 12 
//MOTOR PINS
#ifdef USE_L298_DRIVER
  #define MOTOR_DRIVER L298

  #define MOTOR1_PWM 21
  #define MOTOR1_IN_A 1
  #define MOTOR1_IN_B 20

  #define MOTOR2_PWM 5
  #define MOTOR2_IN_A 8
  #define MOTOR2_IN_B 6

O segundo ponto é prescrever a especificação das rodas do robô:

//define your robot' specs here
#define MAX_RPM 210               // motor's maximum RPM
#define COUNTS_PER_REV 1365       // wheel encoder's no of ticks per rev
#define WHEEL_DIAMETER 0.065       // wheel's diameter in meters
#define PWM_BITS 8                // PWM Resolution of the microcontroller
#define LR_WHEELS_DISTANCE 0.235  // distance between left and right wheels
#define FR_WHEELS_DISTANCE 0.30   // distance between front and rear wheels. Ignore this if you're on 2WD/ACKERMANN
#define MAX_STEERING_ANGLE 0.415  // max steering angle. This only applies to Ackermann st

A RPM pode ser encontrada na especificação da roda, mas CPR (COUNTS_PER_REV) é o valor calculado.
CPR = PPR x 4. O PPR de nossas rodas 341.

* O PPR pode ser visualizado na especificação ou executar o código no robô roslaunch linorobot minimal.launch e girar a roda em 360 graus. PPR será igual ao valor numérico que será exibido na tela após a rotação da roda:



* PPR = abs (RECENT_COUNT - INITIAL_COUNT).

Portanto, CPR = 1364. Você também precisa definir WHEEL_DIAMETER e LR_WHEELS_DISTANCE em metros. Além disso, LR_WHEELS_DISTANCE é a distância entre os eixos centrais das rodas, e não de ponta a ponta. Outros indicadores podem ser ignorados se o robô for de duas rodas, diferencial (não omni).

O terceiro ponto que pode causar dificuldades - imu calibração. Para fazer isso, seguindo as instruções, é necessário fixar o robô em determinadas posições. As dicas estarão no código ao executar o script rosrun imu_calib do_calib :



após a conclusão, imu_calib.yaml com as configurações será gerado.

É melhor executar a calibração, apesar do fato de haver um arquivo padrão com configurações de imu.
* Além disso, a calibração imu pode afetar a direção do movimento do robô pelo teleop (esquerda em vez de direita e vice-versa, enquanto o movimento para frente e para trás estava correto). A situação não foi resolvida pelo rearranjo de pinos no código. O próprio Imu foi fixado e calibrado com suportes de cabeça para baixo, fixado na parte traseira da base do robô. Sua (imu) virada sem recalibração resolveu o problema.

Quarto ponto - calibração pid.

No site do projeto, o procedimento para implementar o ajuste é descrito em detalhes - link .

No entanto, será difícil para um iniciante descobrir o que é e como trabalhar com ele. Em geral, a regulação pid é necessária para garantir que o robô se mova de maneira uniforme, sem solavancos / frenagens bruscas. Três parâmetros são responsáveis ​​por isso: p, i, d. Seus valores estão contidos no código principal enviado ao teenzy:

#define K_P 2.0 // P constant angle
#define K_I 0.3 // I constant
#define K_D 0.1 // D constant

Você pode experimentar com eles executando o robô:

roslaunch linorobot minimal.launch

Mais adiante no PC externo em três terminais diferentes:

rosrun lino_pid pid_configure
rosrun teleop_twist_keyboard teleop_twist_keyboard.py
rqt

Movendo os controles deslizantes p, d, i no terminal rqt e controlando o robô no terminal teleop_twist_keyboard, você pode obter os resultados necessários sem precisar fazer o download do código com os novos parâmetros pid a cada vez no teenzy:



isto é, tudo acontece instantaneamente e no firmware teenzy pode ter significados completamente diferentes. * Você não pode se concentrar em gráficos, porque visualmente, e assim será entendido como o robô está viajando.

Eles recomendam começar com a configuração dos valores p = 1,0, d = 0,1, i = 0,1. No nosso caso, os valores são os seguintes (obtidos experimentalmente) p = 2,0, i = 0,3, d = 0,1.

Em seguida, esses valores devem ser definidos no código e preenchidos em pequenos detalhes.

Além disso, não esqueça de definir o código (DEBUG 0 em vez de DEBUG 1):

#define DEBUG 0

Odometria


Para orientação do robô e navegação subseqüente, são usados ​​dados do lidar, dados do imu e do codificador da roda. Se a calibração da imu for realizada corretamente, o lidar está instalado corretamente e os valores do codificador estão corretos, então não deve haver problemas com a odometria.

Para verificar se a odometria está correta, você precisa montar um pouco no robô via teleop e ver os valores no tópico odom, isso está escrito na página do projeto - link .

E também observe a concha visual do rviz:



uma célula no rviz é de 1 m; portanto, é recomendável que o robô passe esse medidor no editor visual e também em espécie.

Além disso, a distância percorrida é exibida no indicador w:



também deve tender a 1 m.

O mesmo se aplica aos ângulos de rotação do robô:



* No rviz e no live, o robô deve girar nos mesmos ângulos.

Odometria de um LIDAR é definido de uma forma similar - uma ligação A. Distância do radar de laser para a parede mais próxima ao vivo e em rviz deve corresponder.

TF


Em ROS, atenção especial é dada às transformações - tf. Em termos gerais, esse conceito descreve a correlação de objetos em relação um ao outro no espaço. Para que os objetos não fiquem no ar e o programa entenda como eles são apresentados em relação um ao outro, é preciso prestar atenção às configurações tf.

No projeto, todas as conexões tf já estão configuradas uma em relação à outra e você só precisa ajustar os indicadores, por exemplo, indicar como o lidar está localizado. Isso é necessário para o robô entender que o obstáculo não surgiu diretamente na frente dele, mas na frente do lidar, que é separado do centro do robô a uma certa distância.

Vamos para o diretório apropriado:

roscd linorobot/launch
nano bringup.launch

A base em si está localizada a uma distância de 0,065 m do piso:

<node pkg="tf_ros" type="static_transform_publisher" name="base_footprint_to_base_link" args="0 0 0.065 0 0 0  /base_footprint /base_link "/>

No laser.launch, você precisa definir a localização do lidar em relação ao centro da base do robô:

roscd linorobot/launch/include
nano laser.launch

No meu caso, o lidar é deslocado ao longo do eixo x: -0,08, y: 0,04 e "sobe" acima da base (eixo z): 0,08m:

<node pkg="tf2_ros" type="static_transform_publisher" name="base_link_to_laser"
args="-0.08 0.04 0.08 0 0 0  /base_link /laser "/>

No rviz, esse local pode ser observado visualmente:



embora não esteja longe do lidar, ajustaremos sua frequência para que ele dê mais pontos (por padrão, ele fornece 4k), isso ajudará na construção do mapa:

cd linorobot/launch/include/lidar
nano rplidar.launch

Adicionar parâmetro:

<param name="scan_mode"  type="string" value="Boost"/>

e mudar

<param name="angle_compensate"    type="bool"   value="false"/>

Agora, 8k estão à nossa disposição:



a localização física do lidar no robô também importa:



Construindo um mapa da sala 2d


No site do projeto, propõe-se construir um mapa da sala lançando em dois terminais:

roslaunch linorobot bringup.launch
roslaunch linorobot slam.launch

No entanto, a prática mostrou que o slam, que vem por padrão com o projeto, se recusa a trabalhar quando o modo lidar é 8k:



enquanto no modo 4k, os cartões não são muito bem-sucedidos, são muito barulhentos.

Portanto, é melhor usar outro slam - hector-slam.

Como instalá-lo é indicado aqui .

Após a instalação, o procedimento para criar um mapa será o mesmo, mas em vez de roslaunch linorobot slam.launch, execute roslaunch my_hector_mapping my_launch.launch Os

mapas são mais limpos, mas é melhor modificá- los em um editor gráfico, removendo os desnecessários, especialmente se o lidar colidir com espelhos ao criar o mapa :



Não esqueça de salvar o mapa do quarto:

rosrun map_server map_saver -f my-map

* Os mapas são melhor obtidos em um crepúsculo agradável, o que tirará o máximo proveito do orçamento.

Continua.

All Articles