Trolley Robot 2.0. Parte 1. Navegación autónoma de un robot doméstico basado en ROS

El proyecto fue construido sobre la base de otro proyecto bien conocido en sus círculos: linorobot (linorobot.org), utilizando componentes disponibles para un simple laico. Los objetivos que se establecieron: lograr el movimiento autónomo del robot en casa utilizando componentes de bajo costo, evaluar el rendimiento de las mini PC para los fines establecidos, configurar la pila de navegación para moverse en los espacios estrechos del Khrushchev.



Hierro


La lista de componentes en los sólidos es la siguiente:

  • frambuesa pi 3b - 2800 r .;
  • lidar rplidar a1 - 7500 p .;
  • puentes de energía l298n -2pcs - 400 rub.;
  • juego de ruedas con codificadores de tipo A y B - 2000 r. (210 rpm - enlace )
  • teenzy 3.2 - 2100 r.;
  • imu 9250 (9150 o 6050) - 240 p .;
  • banco de potencia a 10000mH - 1500 r.
  • 3 baterías 18650 y soporte -600 p.
  • convertidor reductor dc-dc c 5V a 3.3V - 20p.
  • una pieza de madera contrachapada, parquet -? frotar.

Total: 17160 p.

* El costo puede reducirse reemplazando teenzy con arduino mega 2560 (600 p.), Y lidar reemplazando kinect v.1 (1000 p.):



Sin embargo, debe tenerse en cuenta que el primer kinect tiene una visibilidad mínima (área ciega) de 0.5 m, que puede afectar negativamente la navegación en condiciones de hacinamiento y es bastante voluminoso. El lidar tiene una zona ciega de menos de 0.2 m. Kinect v.2 no se ajusta a raspberry 3b (no tiene usb 3.0). Arduino mega es inferior al tamaño de teenzy (y algunas características), además, tendrá que modificar ligeramente el código.

En general, el "diseño" se ve así:





no hay belleza aquí, por supuesto, pero no se trata de eso.

Además del robot en sí, es altamente deseable tener una PC externa en la cual se lanzarán proyectiles gráficos para visualizar las acciones del robot (rviz, gazebo).

Ensamblaje de robot


Está pintado en detalle en el sitio web del proyecto, un enlace , así que analicemos los puntos que causan dificultades. Primero, debe tener en cuenta que los codificadores del juego de ruedas funcionan con 3.3V y, cuando se aplica 5V, fallan perfectamente.

El script de instalación de linorobot se instaló con éxito en ubuntu 16.04, ubuntu 18.04. Versiones ROS: ROS cinéticas o ROS melódicas. En raspberry 3b, primero debe crear un archivo de intercambio.

El código principal de teenzy está en el camino:

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

Y vierte en él con el comando:

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

Los paquetes de comandos anteriores se usarán con bastante frecuencia, por lo que tiene sentido agregarlos a los alias.

Debido a las dificultades para ensamblar el robot, la correlación correcta de los contactos conectados que van de l298n a teenzy puede ser problemática. A pesar del diagrama de conexión extremadamente claro, las ruedas pueden comportarse de manera diferente y tener que experimentar, eligiendo la asignación de pin correcta en el código.

En mi caso, resultó así:

/// 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

El segundo punto es prescribir la especificación de las ruedas del robot:

//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

Las RPM se pueden encontrar en la especificación de la rueda, pero el valor calculado es CPR (COUNTS_PER_REV).
CPR = PPR x 4. PPR de nuestras ruedas 341.

* PPR se puede ver en la especificación o ejecutar el código en el robot roslaunch linorobot minimal.launch y girar la rueda 360 grados. PPR será igual al valor numérico que se mostrará en la pantalla después de la rotación de la rueda:



* PPR = abs (RECENT_COUNT - INITIAL_COUNT).

Entonces CPR = 1364. También necesita establecer WHEEL_DIAMETER y LR_WHEELS_DISTANCE en metros. Además, LR_WHEELS_DISTANCE es la distancia entre los ejes centrales de las ruedas, y no de borde a borde. Se pueden ignorar otros indicadores si el robot es de dos ruedas, diferencial (no omnidireccional).

El tercer punto que puede causar dificultades: la calibración de la IMU. Para hacer esto, siguiendo las instrucciones, es necesario fijar el robot en ciertas posiciones. Las sugerencias estarán en el código cuando se ejecute el script rosrun imu_calib do_calib : una



vez completado, se generará imu_calib.yaml con la configuración.

Es mejor realizar la calibración, a pesar del hecho de que hay un archivo predeterminado con la configuración de imu.
* Además, resultó que la calibración de imu puede afectar la dirección del movimiento del robot a través de teleop (izquierda en lugar de derecha y viceversa, mientras que el movimiento de ida y vuelta fue correcto). La situación no se resolvió mediante la reorganización de los pines en el código. Imu en sí fue reparado y calibrado con soportes invertidos, como fijado en la parte posterior de la base del robot. Su (imu) cambio adicional sin recalibración resolvió el problema.

Cuarto punto: calibración pid.

En el sitio web del proyecto, el procedimiento sobre cómo implementar el ajuste se describe en detalle: enlace .

Sin embargo, será difícil para un principiante descubrir qué es y cómo trabajar con él. En general, se necesita una regulación pid para garantizar que el robot se mueva uniformemente, sin sacudidas / frenado repentino. Tres parámetros son responsables de esto: p, i, d. Sus valores están contenidos en el código principal cargado a teenzy:

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

Puedes experimentar con ellos corriendo en el robot:

roslaunch linorobot minimal.launch

Además en la PC externa en tres terminales diferentes:

rosrun lino_pid pid_configure
rosrun teleop_twist_keyboard teleop_twist_keyboard.py
rqt

Al mover los controles deslizantes p, d, i en el terminal rqt y luego controlar el robot en el terminal teleop_twist_keyboard, puede lograr los resultados necesarios sin tener que descargar el código con los nuevos parámetros pid cada vez en teenzy:



es decir, todo sucede sobre la marcha y en ese momento en el firmware Teenzy puede tener significados completamente diferentes. * No puedes concentrarte en los gráficos, porque visualmente, y así se entenderá CÓMO viaja el robot.

Recomiendan comenzar con la configuración de los valores p = 1.0, d = 0.1, i = 0.1. En nuestro caso, los valores son los siguientes (obtenidos experimentalmente) p = 2.0, i = 0.3, d = 0.1.

A continuación, estos valores deben establecerse en el código y completarse teenzy.

Además, no olvide establecer el código (DEBUG 0 en lugar de DEBUG 1):

#define DEBUG 0

Odometria


Para la orientación del robot y la navegación posterior, se utilizan datos LIDAR, IMU y datos del codificador de rueda. Si la calibración de imu se realiza correctamente, el lidar está instalado correctamente y los valores del codificador son correctos, entonces no debería haber problemas con la odometría.

Para verificar que la odometría sea correcta, debe montar un poco en el robot a través de teleop y ver los valores en el tema principal, esto está escrito en la página del proyecto: enlace .

Y también mire en el caparazón visual de rviz:



una celda en rviz es 1 m, por lo que es aconsejable que el robot pase este medidor tanto en el editor visual como en especie.

Además, la distancia recorrida se muestra en el indicador w:



también debe tender a 1 m.

Lo mismo se aplica a los ángulos de rotación del robot:



* En rviz y live, el robot debe girar en los mismos ángulos.

La odometría de un lidar se define de manera similar: un enlace: la distancia del lidar al muro más cercano, tanto en vivo como en rviz, debe coincidir.

TF


En ROS, se presta especial atención a las transformaciones - tf. En términos generales, este concepto describe la correlación de los objetos entre sí en el espacio. Para que los objetos no cuelguen en el aire y el programa comprenda cómo se presentan uno con respecto al otro, es necesario prestar atención a la configuración de tf.

En el proyecto, todas las conexiones tf ya están configuradas entre sí y solo necesita ajustar los indicadores, por ejemplo, indican cómo está ubicado el LIDAR. Esto es necesario para que el robot entienda que el obstáculo no surgió directamente frente a él, sino frente al lidar, que está separado del centro del robot a cierta distancia.

Vayamos al directorio apropiado:

roscd linorobot/launch
nano bringup.launch

La base en sí se encuentra a una distancia de 0.065 m del 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 "/>

En laser.launch, debe establecer la ubicación del lidar en relación con el centro de la base del robot:

roscd linorobot/launch/include
nano laser.launch

En mi caso, el lidar se desplaza a lo largo del eje x: -0.08, y: 0.04 y "sube" por encima de la base (eje 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 "/>

En rviz, esta ubicación se puede observar visualmente:



aunque no está lejos del lidar, ajustaremos su frecuencia para que otorgue más puntos (de forma predeterminada, da 4k), esto ayudará a construir el mapa:

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

Añadir parámetro:

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

y cambio

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

Ahora 8k está a nuestra disposición:



la ubicación física del LIDAR en el robot también importa:



Construyendo un mapa de habitación 2D


En el sitio web del proyecto, se propone construir un mapa de la sala mediante el lanzamiento en dos terminales:

roslaunch linorobot bringup.launch
roslaunch linorobot slam.launch

Sin embargo, la práctica ha demostrado que slam, que viene con el proyecto por defecto, se niega a funcionar cuando el modo lidar es 8k:



mientras que en el modo 4k, las tarjetas no tienen mucho éxito, son muy ruidosas.

Por lo tanto, es mejor usar otro golpe: hector-slam.

Cómo instalarlo se indica aquí .

Después de la instalación, el procedimiento para crear un mapa será el mismo, pero en lugar de roslaunch linorobot slam.launch, ejecute roslaunch my_hector_mapping my_launch.launch Los

mapas son más limpios, pero luego es mejor modificarlos en un editor gráfico, eliminando los innecesarios, especialmente si el lidar colisionó con los espejos al construir el mapa :



No olvide guardar el mapa de la habitación:

rosrun map_server map_saver -f my-map

* Los mapas se obtienen mejor en un agradable crepúsculo, esto exprimirá al máximo el presupuesto de LIDAR.

Continuará.

All Articles