Messages dans la série:
8. Nous contrôlons à partir du téléphone-ROS Control, GPS-node7. Localisation du robot: gmapping, AMCL, points de référence sur le plan de la salle6. Odométrie avec encodeurs de roue, plan de salle, lidar5. 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émarche2. Logiciel1. FerLa 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:

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" > <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"/> <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_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 carteSur 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 filtreCes 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:
* 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