Carro para camiones ROS. Parte 7. Localización del robot: gmapping, AMCL, puntos de referencia en el mapa de la sala.

Publicaciones en la serie:
8. Controlamos desde el control del teléfono ROS, nodo GPS
7. Localización de robots: gmapping, AMCL, puntos de referencia en el mapa de la sala
6. Odometría con codificadores de rueda, mapa de habitación, lidar
5. Trabajamos en rviz y gazebo: xacro, nuevos sensores.
4. Cree una simulación de robot utilizando los editores rviz y gazebo.
3. Acelera, cambia la cámara, arregla la marcha
2. Software
1. hierro

La última vez, después de instalar el presupuesto lidar RPlidar-A1, logramos construir un mapa de habitación, trabajar con odometría. Sin embargo, el robot, a pesar de tener un mapa y ajustar la odometría de los sensores ópticos, todavía se siente inseguro en el entorno.
Más bien, él no la ve en absoluto. Y él recorre el mapa terminado a lo largo y ancho, los obstáculos no son para él. Esto es a la vez agradable y angustiante al mismo tiempo. Por un lado, no te preocupes por los obstáculos y viaja donde tu corazón lo desee; por otro lado, es poco probable que vaya a otra habitación o a la cocina. Por lo tanto, hablaremos sobre la localización del robot en el espacio utilizando los algoritmos que proporciona ROS, así como el conjunto de codificadores y lidar de nuestro caballero. Pero antes de pasar directamente a la localización, hablemos de otro paquete ROS, que también le permite construir mapas 2D de la sala, y a veces funciona mejor para él que el paquete ROS de la publicación anterior. Conozca gmapping.

Rm clan gmapping


No seremos originales y utilizaremos los desarrollos del artículo de Habr ya existente sobre el tema, pero ampliaremos, actualizaremos y profundizaremos la información contenida en él. El artículo se llama Construir un mapa y localizar un robot móvil en ROS sin odometría utilizando Laser_scan_matcher .

Parte de las manipulaciones (aplicaciones altamente cargadas - rviz) se realizarán en la computadora (fuera del robot), el resto (controlador de movimiento, nodo de inicio de LIDAR) - en el robot.

Instale laser_scan_matcher para ROS-kinetic en la computadora de acuerdo con el escenario del artículo anterior (el artículo era índigo):

sudo apt-get install ros-kinetic-laser-scan-matcher 

Ahora corre.

Asiente con un lidar en el robot:

 roslaunch rplidar_ros rplidar.launch 

En una computadora:

 roslaunch laser_scan_matcher demo.launch 

* No es necesario ejecutar roscore, ya que el nodo maestro se inicia cada vez que se carga el robot.

En el rviz de inicio, los contornos de la habitación y la basura en ella serán visibles:

imagen

Necesitaremos laser_scan_matcher para trabajar con el paquete gmapping ROS. No es necesario instalar gmapping, ya está en la máquina virtual como parte de ROS Kinetic. Verifique el paquete en el sistema:



Ahora creemos un archivo de inicio usando gmapping en la computadora (no en el robot), como en el artículo anterior:

 roscd roscd rosbots_description/launch nano my_gmapping_launch.launch     

codigo
 <?xml version="1.0"?> <launch> <node pkg="tf" type="static_transform_publisher" name="base_link_to_laser" args="0.0 0.0 0.0 0.0 0.0 0.0 /base_link /laser 40" /> <node pkg="laser_scan_matcher" type="laser_scan_matcher_node" name="laser_scan_matcher_node" output="screen"> <param name="fixed_frame" value = "odom"/> <param name="use_odom" value="true"/> <param name="publish_odom" value = "true"/> <param name="use_alpha_beta" value="true"/> <param name="max_iterations" value="10"/> </node> <node pkg="gmapping" type="slam_gmapping" name="slam_gmapping" output="screen"> <param name="map_udpate_interval" value="1.0"/> <param name="delta" value="0.02"/> </node> </launch> 


Como puede ver en el código, el autor inicia 3 nodos: tf, laser_scan_matcher y gmapping.

Ejecutemos el lidar en el Robot nuevamente:

 roslaunch rplidar_ros rplidar.launch 

En la computadora, el archivo de inicio recién horneado y el editor rviz:

 roslaunch rosbots_description my_gmapping_launch.launch 

 rosrun rviz rviz 

En rviz obtenemos una imagen similar a la que se obtuvo al construir el mapa en nuestra publicación anterior sobre el Robot Cart. Solo que esta vez funciona el paquete gmapping.

Y debo admitir que no funciona mal. Si hector_slam dejó numerosos artefactos en el mapa cuando el lidar giró alrededor de su eje, esta vez casi no hay artefactos:



Después de los recorridos por la habitación, el mapa construido también se guarda:
rosrun map_server map_saver -f map-1 , donde map-1 es el nombre del mapa a guardar.

Localización con amcl


El algoritmo que se usa para determinar la ubicación del robot en el mapa se llama AMCL. AMCL utiliza un filtro de partículas múltiples para rastrear la posición del robot en el mapa. En nuestro robot, utilizamos el paquete ROS (http://wiki.ros.org/amcl) para implementar AMCL.

Ejecute AMCL para nuestro robot.

Para hacer esto, en la computadora en la carpeta del proyecto, cree otro archivo de inicio.

Vamos a llamarlo

lanzamiento de amcl-2.
 <launch> <param name="/use_sim_time" value="false"/> <node pkg="tf" type="static_transform_publisher" name="base_link_to_laser" args="0.0 0.0 0.0 0.0 0.0 0.0 /base_link /laser 40" /> <node pkg="laser_scan_matcher" type="laser_scan_matcher_node" name="laser_scan_matcher_node" output="screen"> <param name="fixed_frame" value = "odom"/> <param name="use_alpha_beta" value="true"/> <param name="max_iterations" value="10"/> </node> <node name="map_server" pkg="map_server" type="map_server" args="/home/pi/catkin_ws/src/rosbots_description/maps/map-3.yaml"/> <node pkg="amcl" type="amcl" name="amcl" output="screen" > <!-- Publish scans from best pose at a max of 10 Hz --> <param name="odom_model_type" value="diff"/> <param name="odom_alpha5" value="0.1"/> <param name="transform_tolerance" value="0.2" /> <param name="gui_publish_rate" value="10.0"/> <param name="laser_max_beams" value="30"/> <param name="min_particles" value="500"/> <param name="max_particles" value="5000"/> <param name="kld_err" value="0.05"/> <param name="kld_z" value="0.99"/> <param name="odom_alpha1" value="0.2"/> <param name="odom_alpha2" value="0.2"/> <!-- laser, translation std dev, m --> <param name="laser_min_range" value="-1"/> <param name="laser_max_range" value="-1"/> <param name="odom_alpha3" value="0.8"/> <param name="odom_alpha4" value="0.2"/> <param name="laser_z_hit" value="0.5"/> <param name="laser_z_short" value="0.05"/> <param name="laser_z_max" value="0.05"/> <param name="laser_z_rand" value="0.5"/> <param name="laser_sigma_hit" value="0.2"/> <param name="laser_lambda_short" value="0.1"/> <param name="laser_lambda_short" value="0.1"/> <param name="laser_model_type" value="likelihood_field"/> <!-- <param name="laser_model_type" value="beam"/> --> <param name="laser_likelihood_max_dist" value="2.0"/> <param name="update_min_d" value="0.2"/> <param name="update_min_a" value="0.5"/> <param name="odom_frame_id" value="odom"/> <param name="base_frame_id" type="str" value="base_link" /> <param name="global_frame_id" type="str" value="map" /> <param name="resample_interval" value="1"/> <param name="transform_tolerance" value="0.1"/> <param name="recovery_alpha_slow" value="0.0"/> <param name="recovery_alpha_fast" value="0.0"/> <param name="use_map_topic" value="true" /> <param name="first_map_only" value="true" /> </node> </launch> 


El código es completamente idéntico al artículo ya mencionado, con la excepción de:
- excluyó el nodo que inicia el hidaryo lidar (se ejecuta en el Robot)
- la ruta y el nombre del mapa de la habitación es diferente (map-3.yaml)
El código ejecuta 4 nodos:
- tf
- map_server
- laser_scan_matcher
- amcl
El nodo amcl usa el mapa que map_server publica para la posterior localización del robot.

Ejecute los archivos de inicio y mire el resultado.

Pero para robot:

 roslaunch rplidar_ros rplidar.launch 

En una computadora:
1er terminal: roslaunch rosbots_description amcl-2.launch
2do terminal: roslaunch rosbots_description rviz.launch

Después de que comience rviz, los siguientes pasos en este editor serán los siguientes:
- Agregar pantallas a rviz:
• LaserScan
• Mapa
• PoseArray


- localizar el robot en la etapa inicial, ya que al iniciar amcl no sabe dónde comenzó el robot y dónde está. Necesita "inicialización inicial".
Para esto, en rviz debe seleccionar "Estimación de pose 2D" y usar la flecha verde hacia la derecha en la ventana donde se muestra el robot para indicar su posición:



Esta operación se debe hacer seleccionando Frame "map" en rviz:



En la terminal obtenemos las coordenadas (pose) del robot:

 [ INFO] [1572374324.454855505]: Setting pose (1572374324.454806): -0.014 -0.012 0.655 

Puede establecer la posición del robot en el mapa utilizando la flecha verde en el mapa repetidamente.
Es deseable que los datos del lidar (borde rojo) en el mapa coincidan o estén cerca de la ubicación real de las paredes de la habitación:



En la ventana de visualización de rviz, obtenemos las flechas rojas características alrededor del robot *:



* como robot, tenemos un eje para la claridad (todo el modelo rviz pintado todavía está oculto).
** Si las flechas no aparecieron, puede intentar eliminar y volver a verificar la pantalla PoseArray agregada a rviz.

A pesar del hecho de que indicamos directamente en el mapa dónde está ubicado el robot, el sistema aún asume que puede estar en aquellos lugares donde se dibujan las flechas rojas. Esta es la ubicación probable del robot en el mapa. Una gran cantidad de flechas y su dispersión en el mapa indican que el sistema aún no conoce la ubicación exacta del robot. Sin embargo, el lugar donde el tirador es más denso, el robot es más probable.

Para que el sistema entienda con mayor precisión exactamente dónde está el robot, debe viajar en un mapa con nodos en ejecución que determinan la ubicación del robot. Tenemos de este conjunto: lidar y codificadores.
Pero viajamos en el mapa solo con el LIDAR lanzado, al mismo tiempo que descubrimos si es posible localizar de manera confiable el robot solo con su ayuda (LIDAR).
-
montar un robot en un mapa
En el robot:

 rosrun rosbots_driver part2_cmr.py 

En una computadora:

 rosrun teleop_twist_keyboard teleop_twist_keyboard.py /cmd_vel:=/part2_cmr/cmd_vel 


Durante el viaje, amcl comenzará a leer los temas / scan, / map, / tf y publicará la ubicación del robot en topics / amcl_pose y / particlecloud.

A medida que viaja, puede observar que el número de flechas disminuye y se condensan cada vez más en un punto con la ubicación real del robot:


La imagen muestra cómo viaja el modelo (en forma de árbol de conexiones). Y también se ve que el lidar no hace frente con suficiente precisión a la localización en los límites ambiguos de la habitación.

¿Qué significan los otros parámetros en el código del nodo amcl?


Convencionalmente, se dividen en básicos (General), parámetros de filtro (Filtro), Parámetros láser (lidar) (Parámetros láser).

Parámetros clave:
  • odom_model_type (predeterminado: "diff"): determina qué modelo de odometría usar. Tenemos diff, que significa diferencial. Se puede cambiar a "omni", "corregido por diferencias" u "omni corregido".
  • odom_frame_id (predeterminado: "odom"): define el marco (leer el tema) con el que se asociará la odometría. Generalmente se publica en el tema odom.
  • base_frame_id (predeterminado: "base_link"): marco para la base del robot.
  • global_frame_id (predeterminado: "mapa"): marco del mapa, como regla del servidor de mapas lo publica en el mapa de temas
  • use_map_topic (predeterminado: falso): determina si el mapa se cargará a través del tema o llamando al servicio (recordamos que además de los temas en ROS, también hay servicios y acciones.


Parámetros de filtro
Estas opciones le permiten personalizar cómo funciona el filtro de partículas.

  • min_particles (predeterminado: 100): establece el número mínimo de partículas para el filtro. Tenemos 500.
  • max_particles (predeterminado: 5000): establece el número máximo de partículas para el filtro.
  • kld_err (predeterminado: 0.01): establece el error máximo permitido entre la distribución verdadera y la distribución calculada. Tenemos 0.05
  • update_min_d (predeterminado: 0.2): establece la distancia lineal (en metros) que debe recorrer el robot para actualizar el filtro.
  • update_min_a (predeterminado: pi / 6.0): establece la distancia angular (en radianes) que el robot debe mover para actualizar el filtro. Tenemos 0.5
  • resample_interval (predeterminado: 2): establece el número de actualizaciones de filtro necesarias antes de volver a buscar. Tenemos 1.
  • transform_tolerance (predeterminado: 0.1): El tiempo (en segundos) durante el cual la transformación publicada debe tener fecha para indicar que esta transformación es válida en el futuro.
  • gui_publish_rate (predeterminado: -1.0): la velocidad máxima (en Hz) a la que se publican los escaneos y las rutas para su visualización. Si este valor es -1.0, esta función está deshabilitada. Tenemos 10.


Parámetros del láser (lidar) (Parámetros láser)
Estos parámetros le permiten configurar cómo interactúa amcl con el láser lidar.

  • laser_min_range (predeterminado: -1.0): el rango de exploración mínimo a considerar; -1.0 utilizará el rango mínimo especificado en el informe del láser.
  • laser_max_range (predeterminado: -1.0): el rango máximo de exploración a tener en cuenta; -1.0 usará el rango máximo de láser.
  • laser_max_beams (predeterminado: 30): cuántos haces distribuidos uniformemente en cada escaneo se utilizarán al actualizar el filtro.
  • laser_z_hit (predeterminado: 0.95): los pesos del componente z_hit del modelo de robot.
  • laser_z_short (predeterminado: 0.1): los pesos del componente z_short del modelo de robot.
  • laser_z_max (predeterminado: 0.05): El peso del componente z_max del modelo de robot.
  • laser_z_rand (predeterminado: 0.05): los pesos del componente z_rand del modelo de robot.


Veamos qué afectan los parámetros min_particles y max_particles. Si reduce sus valores, cuando inicie el archivo de inicio, la cantidad de partículas en el editor visual será claramente menor.

Todos los parámetros llevan una carga semántica, pero es difícil analizar el efecto de cambiar cada uno de ellos dentro del marco del artículo.

Puntos de referencia en el mapa de la habitación.


El nombre es pegadizo e implica la posición del robot en el mapa en este momento en particular.

¿Para que son? Para entender que el robot vino del punto A en la habitación al punto B en la cocina.

Los datos sobre la posición (pose) del robot se pueden obtener con el nodo de trabajo amcl (lo que comenzó en el artículo anterior).

Y mira en el tema / amcl_pose:

 rostopic echo -n1 /amcl_pose 

* clave n1: para "arreglar" el flujo de mensajes en el tema.



Creemos un servicio que, cuando se llame, regale la posición (coordenadas) del robot para que cada vez que no se vea el tema.

1.Cree un nuevo paquete ros.

 cd catkin_ws/src catkin_create_pkg get_pose rospy cd get_pose/src 

2. En la carpeta, cree el archivo:

get_pose_service.py
 #! /usr/bin/env python import rospy from std_srvs.srv import Empty, EmptyResponse # Import the service message python classes generated from Empty.srv. from geometry_msgs.msg import PoseWithCovarianceStamped, Pose robot_pose = Pose() def service_callback(request): print "Robot Pose:" print robot_pose return EmptyResponse() # the service Response class, in this case EmptyResponse def sub_callback(msg): global robot_pose robot_pose = msg.pose.pose rospy.init_node('service_server') my_service = rospy.Service('/get_pose_service', Empty , service_callback) # create the Service called get_pose_service with the defined callback sub_pose = rospy.Subscriber('/amcl_pose', PoseWithCovarianceStamped, sub_callback) rospy.spin() # mantain the service open. 


* No olvide hacer que sea ejecutable chmod + x get_pose_service.py
3. Creemos el inicio del archivo con el código de nodo:

 cd .. mkdir launch && cd launch 

nano

get_pose_service.launch
 <launch> <node pkg="get_pose" type="get_pose_service.py" name="service_server" output="screen"> </node> </launch> 


4.No olvides reconstruir amentos:

 cd catkin_ws catkin_make 

Ahora reiniciaremos todo, incluido el nuevo archivo de inicio.

Pero para robot:

 roslaunch rplidar_ros rplidar.launch 

En una computadora:

 1- : roslaunch rosbots_description amcl-2.launch 2- : roslaunch rosbots_description rviz.launch 3- : roslaunch get_pose get_pose_service.launch 

Pasamos al nuevo servicio, que debería darnos la posición actual del robot en el mapa (llamaremos al servicio ROS):

 rosservice call /get_pose_service 

En el terminal que ejecuta el lanzamiento get_pose, obtendremos las coordenadas del robot en el mapa:



Posibles errores.

[rviz.launch] no es un archivo de inicio en el paquete [rosbots_description] ni [rosbots_description] es un nombre de archivo de inicio
solución:

 cd catkin_ws source devel/setup.bash 

Source: https://habr.com/ru/post/472984/


All Articles