Chariot de camion ROS. Partie 7. Localisation du robot: gmapping, AMCL, points de référence sur le plan de la salle

Messages dans la série:
8. Nous contrôlons à partir du téléphone-ROS Control, GPS-node
7. Localisation du robot: gmapping, AMCL, points de référence sur le plan de la salle
6. Odométrie avec encodeurs de roue, plan de salle, lidar
5. Nous travaillons en rviz et gazebo: xacro, nouveaux capteurs.
4. Créez une simulation de robot à l'aide des éditeurs rviz et gazebo.
3. Accélérez, changez la caméra, corrigez la démarche
2. Logiciel
1. Fer

La dernière fois, après avoir installé le lidar économique RPlidar-A1, nous avons réussi à construire un plan de salle, travailler avec l'odométrie. Cependant, le robot, malgré sa carte et l'ajustement de l'odométrie des capteurs optiques, se sent toujours peu sûr de l'environnement.
Au contraire, il ne la voit pas du tout. Et il parcourt la carte finie au loin, les obstacles ne sont pas pour lui. C'est à la fois agréable et pénible à la fois. D'une part, ne vous inquiétez pas des obstacles et ne voyagez pas où votre cœur le souhaite, d'autre part, il est peu probable qu'il aille dans une autre pièce ou dans la cuisine. Par conséquent, nous parlerons de la localisation du robot dans l'espace en utilisant les algorithmes fournis par ROS, ainsi que l'ensemble de lidar et d'encodeurs de notre gentleman. Mais avant de passer directement à la localisation, parlons d'un autre package ROS, qui vous permet également de créer des cartes 2D de la pièce, et parfois cela fonctionne mieux pour lui que le package ROS du post précédent. Apprenez à connaître le gmapping.

Rm clan gmapping


Nous ne serons pas des originaux et nous utiliserons les développements de l'article Habr déjà existant sur le sujet, mais nous développerons, mettrons à jour et approfondirons les informations qu'il contient. L'article est intitulé Construction d'une carte et localisation d'un robot mobile dans ROS sans odométrie à l'aide de Laser_scan_matcher .

Une partie des manipulations (applications à charge élevée - rviz) seront effectuées sur l'ordinateur (à l'extérieur du robot), le reste (pilote de mouvement, nœud de lancement lidar) - sur le robot.

Tout d'abord, installez le laser_scan_matcher pour ROS-kinetic sur l'ordinateur dans le scénario de l'article ci-dessus (l'article était indigo):

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

Maintenant, cours.

Nod avec un lidar sur le robot:

 roslaunch rplidar_ros rplidar.launch 

Sur un ordinateur:

 roslaunch laser_scan_matcher demo.launch 

* Il n'est pas nécessaire d'exécuter roscore, car le nœud maître démarre à chaque chargement du robot.

Dans le rviz de départ, les contours de la pièce et les ordures seront visibles:

image

nous aurons besoin de laser_scan_matcher pour travailler avec le paquet gmapping ROS. Il n'est pas nécessaire d'installer gmapping lui-même, il est déjà sur la machine virtuelle dans le cadre de ROS Kinetic. Vérifiez le package dans le système:



Créons maintenant un fichier de lancement en utilisant gmapping sur l'ordinateur (pas sur le robot), comme dans l'article ci-dessus:

 roscd roscd rosbots_description/launch nano my_gmapping_launch.launch     

code
 <?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> 


Comme vous pouvez le voir dans le code, l'auteur démarre 3 nœuds: tf, laser_scan_matcher et gmapping.

Lançons à nouveau le lidar sur le robot:

 roslaunch rplidar_ros rplidar.launch 

Sur l'ordinateur, le fichier de lancement nouvellement créé et l'éditeur rviz:

 roslaunch rosbots_description my_gmapping_launch.launch 

 rosrun rviz rviz 

Dans rviz, nous obtenons une image similaire à celle obtenue lors de la construction de la carte dans notre post précédent sur le Robot Cart. Seulement cette fois, le package gmapping fonctionne.

Et je dois admettre que ça ne marche pas mal. Si hector_slam a laissé de nombreux artefacts sur la carte lorsque le lidar a tourné autour de son axe, cette fois il n'y a presque pas d'artefacts:



Après les déplacements dans la pièce, la carte construite est également enregistrée:
rosrun map_server map_saver -f map-1 , oĂą map-1 est le nom de la carte Ă  enregistrer.

Localisation avec amcl


L'algorithme utilisé pour déterminer l'emplacement du robot sur la carte est appelé AMCL. AMCL utilise un filtre multi-particules pour suivre la position du robot sur la carte. Dans notre robot, nous utilisons le package ROS (http://wiki.ros.org/amcl) pour implémenter AMCL.

Exécutez AMCL pour notre robot.

Pour ce faire, sur l'ordinateur dans le dossier du projet, créez un autre fichier de lancement.

Appelons-le

amcl-2.launch
 <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> 


Le code est complètement identique à l'article déjà mentionné, à l'exception de:
- exclu le nœud qui lance le hokuyo lidar (il tourne sur le Robot)
- le chemin et le nom du plan de la pièce sont différents (map-3.yaml)
Le code exécute 4 nœuds:
- tf
- map_server
- laser_scan_matcher
- amcl
Le nœud amcl utilise la carte que map_server publie pour la localisation ultérieure du robot.

Exécutez les fichiers de lancement et regardez le résultat.

Mais pour Robot:

 roslaunch rplidar_ros rplidar.launch 

Sur un ordinateur:
1er terminal: roslaunch rosbots_description amcl-2.launch
2ème terminal: roslaunch rosbots_description rviz.launch

Après le démarrage de rviz, les prochaines étapes de cet éditeur seront les suivantes:
- ajouter des affichages Ă  rviz:
• LaserScan
• Carte
• PoseArray


- localiser le robot au stade initial, car au démarrage amcl ne sait pas où le robot a démarré et où il se trouve. Besoin d'une «initialisation initiale».
Pour cela, dans rviz, vous devez sélectionner «Estimation de pose 2D» et utiliser la flèche verte à droite dans la fenêtre où le robot est affiché pour indiquer sa position:



Cette opération doit être effectuée en sélectionnant Frame "map" dans rviz:



Dans le terminal, nous obtenons les coordonnées (pose) du robot:

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

Vous pouvez définir la position du robot sur la carte en utilisant la flèche verte sur la carte à plusieurs reprises.
Il est souhaitable que les données du lidar (bordure rouge) sur la carte coïncident ou soient proches de l'emplacement réel des murs de la pièce:



Dans la fenêtre de visualisation rviz, nous obtenons les flèches rouges caractéristiques autour du robot *:



* en tant que robot, nous avons un axe pour plus de clarté (l'ensemble du modèle rviz peint est toujours caché).
** Si les flèches n'apparaissent pas, vous pouvez essayer de supprimer et revérifier l'affichage PoseArray ajouté à rviz.

Malgré le fait que nous ayons indiqué directement sur la carte où se trouve le robot, le système suppose toujours qu'il peut se trouver aux endroits où les flèches rouges sont dessinées. Il s'agit de l'emplacement probable du robot sur la carte. Un grand nombre de flèches et leur dispersion sur la carte indiquent que le système ne connaît toujours pas l'emplacement exact du robot. Cependant, l'endroit où le tireur est plus dense, le robot est plus probable.

Pour que le système comprenne plus précisément où se trouve le robot, vous devez utiliser une carte avec des nœuds en cours d'exécution qui déterminent l'emplacement du robot. Nous avons de cet ensemble: lidar et encodeurs.
Mais nous nous déplaçons sur la carte uniquement avec le lidar lancé, tout en recherchant s'il est possible de localiser le robot de manière fiable uniquement avec son aide (lidar).
-
conduire un robot sur une carte
Sur le robot:

 rosrun rosbots_driver part2_cmr.py 

Sur un ordinateur:

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


Pendant le voyage, amcl commencera Ă  lire les rubriques / scan, / map, / tf et publiera l'emplacement du robot dans les rubriques / amcl_pose et / particlecloud.

Au fur et à mesure que vous voyagez, vous pouvez observer que le nombre de flèches diminue et qu'elles se condensent de plus en plus en un point avec l'emplacement réel du robot:


L'image montre comment le modèle se déplace (sous la forme d'un arbre de connexions). Et on voit également que le lidar ne fait pas assez précisément face à la localisation aux limites ambiguës de la pièce.

Que signifient les autres paramètres du code de nœud amcl?


Classiquement, ils sont divisés en paramètres de base (général), filtre (filtre), paramètres laser (lidar) (paramètres laser).

Paramètres clés:
  • odom_model_type (par dĂ©faut: "diff"): dĂ©termine le modèle d'odomĂ©trie Ă  utiliser. Nous avons diff, ce qui signifie diffĂ©rentiel. Peut ĂŞtre changĂ© en «omni», «diff-corrigé» ou «omni-corrigé».
  • odom_frame_id (par dĂ©faut: "odom"): dĂ©finit le cadre (lire le sujet) auquel l'odomĂ©trie sera associĂ©e. Il est gĂ©nĂ©ralement publiĂ© dans le sujet odom.
  • base_frame_id (par dĂ©faut: "base_link"): cadre pour la base du robot.
  • global_frame_id (par dĂ©faut: "map"): cadre de la map, en règle gĂ©nĂ©rale, le serveur de carte le publie dans la map du sujet
  • use_map_topic (dĂ©faut: false): dĂ©termine si la carte sera chargĂ©e via le sujet ou en appelant le service (nous nous souvenons qu'en plus des sujets dans ROS, il y a aussi des services et des actions.


Paramètres du filtre
Ces options vous permettent de personnaliser le fonctionnement du filtre Ă  particules.

  • min_particles (par dĂ©faut: 100): dĂ©finit le nombre minimum de particules pour le filtre. Nous en avons 500.
  • max_particles (par dĂ©faut: 5000): dĂ©finit le nombre maximal de particules pour le filtre.
  • kld_err (par dĂ©faut: 0,01): dĂ©finit l'erreur maximale autorisĂ©e entre la distribution rĂ©elle et la distribution calculĂ©e. Nous avons 0,05
  • update_min_d (par dĂ©faut: 0,2): dĂ©finit la distance linĂ©aire (en mètres) que le robot doit parcourir pour mettre Ă  jour le filtre.
  • update_min_a (par dĂ©faut: pi / 6.0): dĂ©finit la distance angulaire (en radians) que le robot doit parcourir pour mettre Ă  jour le filtre. Nous avons 0,5
  • resample_interval (par dĂ©faut: 2): dĂ©finit le nombre de mises Ă  jour du filtre nĂ©cessaires avant la rĂ©cupĂ©ration. Nous en avons 1.
  • transform_tolerance (dĂ©faut: 0.1): Le temps (en secondes) pendant lequel la transformation publiĂ©e doit ĂŞtre datĂ©e pour indiquer que cette transformation est valide Ă  l'avenir.
  • gui_publish_rate (par dĂ©faut: -1,0): vitesse maximale (en Hz) Ă  laquelle les analyses et les chemins sont publiĂ©s pour la visualisation. Si cette valeur est -1,0, cette fonction est dĂ©sactivĂ©e. Nous en avons 10.


Paramètres du laser (lidar) (Paramètres laser)
Ces paramètres vous permettent de configurer la façon dont amcl interagit avec le laser lidar.

  • laser_min_range (par dĂ©faut: -1.0): la plage de balayage minimale Ă  considĂ©rer; -1,0 utilisera la plage minimale spĂ©cifiĂ©e dans le rapport laser.
  • laser_max_range (par dĂ©faut: -1.0): la plage de balayage maximale Ă  considĂ©rer; -1.0 utilisera la portĂ©e laser maximale.
  • laser_max_beams (par dĂ©faut: 30): combien de faisceaux uniformĂ©ment rĂ©partis dans chaque balayage seront utilisĂ©s lors de la mise Ă  jour du filtre.
  • laser_z_hit (par dĂ©faut: 0,95): les poids du composant z_hit du modèle de robot.
  • laser_z_short (par dĂ©faut: 0,1): les poids de la composante z_short du modèle de robot.
  • laser_z_max (par dĂ©faut: 0,05): poids du composant z_max du modèle de robot.
  • laser_z_rand (par dĂ©faut: 0,05): les poids de la composante z_rand du modèle de robot.


Voyons ce que les paramètres min_particles et max_particles affectent. Si vous réduisez leurs valeurs, lorsque vous lancez le fichier de lancement, le nombre de particules dans l'éditeur visuel sera nettement inférieur.

Tous les paramètres portent une charge sémantique, mais il est difficile d'analyser l'effet de la modification de chacun d'eux dans le cadre de l'article.

Points de référence sur le plan de salle


Le nom est accrocheur et implique la position du robot sur la carte Ă  ce moment particulier.

À quoi servent-ils? Afin de comprendre que le robot venait du point A de la pièce au point B de la cuisine.

Les données sur la position (pose) du robot peuvent être obtenues avec le nœud de travail amcl (ce qui a commencé dans l'article ci-dessus).

Et regardez dans le sujet / amcl_pose:

 rostopic echo -n1 /amcl_pose 

* touche n1 - pour "fixer" le flux de messages dans le sujet.



Créons un service qui, lorsqu'il est appelé, donnera la position (coordonnées) du robot afin que chaque fois qu'il ne se penche pas sur le sujet.

1.Créez un nouveau package ros.

 cd catkin_ws/src catkin_create_pkg get_pose rospy cd get_pose/src 

2. Dans le dossier, créez le fichier:

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. 


* N'oubliez pas de le rendre exécutable chmod + x get_pose_service.py
3. Créons le lancement du fichier avec le code du nœud:

 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.N'oubliez pas de reconstruire le chaton:

 cd catkin_ws catkin_make 

Nous allons maintenant tout redémarrer, y compris le nouveau fichier de lancement.

Mais pour Robot:

 roslaunch rplidar_ros rplidar.launch 

Sur un ordinateur:

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

Nous nous tournons vers le nouveau service, qui devrait nous donner la position actuelle du robot sur la carte (nous appellerons le service ROS):

 rosservice call /get_pose_service 

Dans le terminal exécutant le lancement get_pose, nous obtiendrons les coordonnées du robot sur la carte:



Erreurs possibles.

[rviz.launch] n'est ni un fichier de lancement dans le package [rosbots_description] ni [rosbots_description] un nom de fichier de lancement
solution:

 cd catkin_ws source devel/setup.bash 

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


All Articles