بناء خريطة وتوطين روبوت متنقل في ROS بدون قياس المسافات باستخدام laser_scan_matcher

قراء مساء الخير! لقد تطرقنا ذات مرة إلى موضوع الأقلمة و SLAM في مقال عن Hector SLAM . نواصل معرفتنا بالخوارزميات لإنشاء خرائط التضاريس والتوطين في ROS. سنحاول اليوم إنشاء خريطة للمنطقة بدون مصدر للقياس ، باستخدام فقط Hokuyo URG-04LX-UG01 lidar وخوارزمية gmapping وتوطين الروبوت على الخريطة التي تم إنشاؤها باستخدام خوارزمية amcl . سيساعدنا Laser_scan_matcher في ذلك . من يهتم ، من فضلك ، تحت القطة.

تثبيت حزمة laser_scan_matcher


لذلك دعونا نبدأ! بالنسبة للتجارب ، سنستخدم ROS Indigo ، ولكن يمكنك استخدام إصدار مختلف من ROS (Jade و Kinetic و Hydro). يجب أن يتم تثبيت الحزم بنفس الطريقة (ربما فقط في ROS Kinetic لن تكون بعض الحزم متاحة عبر apt-get).

تعد حزمة laser_scan_matcher أداة للتسجيل المتزايد لبيانات الليزر ، والتي يتم تنفيذها على أساس طريقة Canonical Scan Matcher ، والتي يمكن قراءتها هنا . يمكنك أن تقرأ عن الحزمة هنا . يمكن استخدام الحزمة بدون بيانات قياس المسافات ؛ فهي تقوم بتقييم قياس المسافات نفسها.

قم بتثبيت الحزمة:

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

لنجرب العرض التوضيحي:

roscore
roslaunch laser_scan_matcher demo.launch

سنرى شيئًا مشابهًا في rviz:



يظهر هنا هو laser_scan_matcher وهو يعمل على بيانات lidar المسجلة في ملف حقيبة. جرب الحزمة مباشرة الآن. حتى لا نضيع الوقت ، سنجربها على الفور باستخدام خوارزمية رسم الخرائط. قم بإنشاء حزمة بالملف my_gmapping_launch_runch لبدء gmapping:

cd ~/catkin_ws/src
catkin_create_pkg my_laser_matcher
cd src/my_laser_matcher
mkdir launch
vim launch/my_gmapping_launch.launch

انسخ الكود التالي إلى ملف my_gmapping_launch_runch:

كود my_gmapping_launch_runch
<?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>


هنا نقوم بتشغيل static_transform_publisher من حزمة tf لنشر التحول بين أنظمة إحداثيات الليزر base_link → و laser_scan_matcher وعقد slam_gmapping. يمكن تنزيل شفرة المصدر للملف من هنا . لاستخدام Hokuyo lidar ، نحتاج إلى تثبيت حزمة hokuyo_node ROS :

sudo apt-get install ros-indigo-hokuyo-node

قم بتشغيل عقدة getID من حزمة hokuyo_node للحصول على معلومات lidar:

rosrun hokuyo_node getID /dev/ttyACM0

قد يحدث خطأ:

Error: Failed to open port. Permission denied.
[ERROR] 1263843357.793873000: Exception thrown while opening Hokuyo.
Failed to open port: /dev/ttyACM0. Permission denied (errno = 13). You probably don't have premission to open the port for reading and writing. (in hokuyo::laser::open) You may find further details at http://www.ros.org/wiki/hokuyo_node/Troubleshooting

في هذه الحالة ، نحتاج إلى إضافة أذونات للمنفذ / dev / ttyACM0:

sudo chmod a+rw /dev/ttyACM0

قم بتشغيل getID من حزمة hokuyo_node مرة أخرى واحصل على ناتج مماثل:

Device at /dev/ttyACM0 has ID H0906078

الآن قم بتشغيل العقدة hokuyo_node:

rosrun hokuyo_node hokuyo_node

أخيرًا ، قم بتشغيل ملف المشغل الخاص بنا my_gmapping_launch.co.unch:

roslaunch my_laser_matcher my_gmapping_launch.launch
rosrun rviz rviz

دعونا نذكر الموضوعات:

rostopic list

من بين المواضيع سنرى ما يلي:

/initialpose
/move_base_simple/goal
/odom
/pose2D
...
/imu/data

وبهذه الطريقة نحصل على قياس المسافات ووضعية الروبوتات بفضل laser_scan_matcher.

أضف إلى عرض شاشة من نوع LaserScan مع موضوع المسح الضوئي كما هو موضح في المقالة . أضف أيضًا عرضًا لخريطة الخريطة ولتحويل TF. قم بتوسيع قسم TF والإطارات بداخله ، ثم لاحظ النقاط: odom ، map ، base_link. دعني أذكرك بأن هذه هي أنظمة عداد المسافات وخريطة الروبوتات على التوالي. تذكر تعيين قيمة / map إلى حقل الإطار الثابت في لوحة العرض اليسرى في قسم الخيارات العامة.

في rviz سنرى صورة مماثلة:

الصورة

بعد ذلك ، فقط قم بتحريك الروبوت في الفضاء لبناء خريطة كاملة للمنطقة. نستخدم الأداة المساعدة map_saver من حزمة map_server لحفظ الخريطة:

rosrun map_server map_saver

التعريب مع amcl


الآن دعنا نحاول أقلمة الروبوت باستخدام خوارزمية amcl. قم بإنشاء الملف my_localize.co.unch داخل الحزمة الخاصة بنا بالمحتويات التالية:

كود my_localize.co.unch
<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 name="hokuyo" pkg="hokuyo_node" type="hokuyo_node" respawn="false" output="screen">
    <param name="calibrate_time" type="bool" value="false"/> 
    <param name="port" type="string" value="/dev/ttyACM0"/> 
    <param name="intensity" type="bool" value="false"/>
  </node>

  <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/vladimir/catkin_ws/map.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"/>
  <!-- translation std dev, m -->
  <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>


هنا ، نحن ، على غرار المشغل الخاص بـ gmapping ، ننشر التحويل / الليزر → / base_link باستخدام عقدة static_transform_publisher ، hoduyo_node و laser_scan_matcher. ثم نقوم بتشغيل map_server لنشر خريطتنا التي تم إنشاؤها ، حيث في القوس نمر المسار إلى الخريطة في ملف yaml. أخيرًا ، ابدأ العقدة amcl بالمعلمات. يمكنك القراءة عن معلمات amcl في صفحة الخوارزمية الرسمية .

يمكن أيضًا تنزيل رمز ملف المشغل من مستودع github . قم بتشغيل ملف المشغل الخاص بنا:

roslaunch my_laser_matcher my_localize.launch

الآن دعنا ننتقل إلى رفيز. قم بتعيين قيمة الخريطة للإطار الثابت في قسم الخيارات العامة. دعونا نذكر الموضوعات:

rostopic list

ستظهر مواضيع جديدة في القائمة:

...
/amcl/parameter_descriptions
/amcl/parameter_updates
/amcl_pose
...
/map
/map_metadata
/map_updates
...
/particlecloud

يتوافق موضوع amcl_pose مع موضع الروبوت المنشور بواسطة amcl.
دعنا نرى المنشورات في الموضوع:

rostopic echo /amcl_pose

احصل على البيانات عن موقع الروبوت:

header: 
  seq: 15
  stamp: 
    secs: 1482430591
    nsecs:  39625000
  frame_id: map
pose: 
  pose: 
    position: 
      x: 0.781399671581
      y: 0.273353260585
      z: 0.0
    orientation: 
      x: 0.0
      y: 0.0
      z: -0.636073020536
      w: 0.771628869694
  covariance: [0.2187289446708912, -0.010178711317316846, 0.0, 0.0, 0.0, 0.0, -0.010178711317316819, 0.23720047371620548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.07106236846890918]
---

في rviz نحصل على الصورة التالية:

الصورة

كما ترى ، تتطابق نقاط المسح من اللدار جزئيًا مع الجدران على الخريطة. إليك ما يبدو عليه إعدادي حقًا:

الصورة

فلنحاول تحريك الروبوت. يجب أن يتغير موضع الروبوت ووجهة نظر الخريطة في وقت واحد في نافذة rviz. بعد تحريك الروبوت ، قد لا يتم تحديد موضع الروبوت بدقة من خلال خوارزمية amcl. نحتاج إلى تعديل موضع الروبوت باستخدام أداة تقدير 2D Pose. للقيام بذلك ، انقر على زر تقدير 2D Pose في شريط الأدوات العلوي في rviz ، وانقر على النقطة التقريبية لمركز نظام إحداثيات الروبوت على الخريطة في rviz (نظام إحداثيات base_link) واضغط باستمرار على زر الماوس. يظهر سهم أخضر ينبعث من مركز الروبوت:

الصورة

اسحب السهم يغير اتجاهه ويحاول دمج نقاط المسح من الليدار مع الحواف السوداء (الجدران) على الخريطة. بعد الحصول على أفضل ترك ترك زر الماوس.

الصورة

سوف نتلقى مثل هذه الرسائل في الوحدة الطرفية حيث يتم تشغيل my_localize.co.unch:

[ INFO] [1482431993.717411186]: Setting pose (1482431993.717383): -0.413 -0.071 0.057

على مقطع فيديو قصير ، يمكنك مشاهدة كل شيء عمليًا:



يقدم الموضوع / particlecloud بيانات حول عدم اليقين لموضع الروبوت في شكل مواضع موجهة (Pose) أو ما يسمى سحابة الجسيمات. نوع الرسالة هو geometry_msgs / PoseArray.

أضف عرضًا مسمىًا موضوعًا / particlecloud :

الصورة

في rviz ، ستظهر سحابة من الجسيمات على شكل مجموعة سميكة من الأسهم الحمراء:

الصورة

كلما كانت كتلة الجسيمات أكثر سمكًا ، زاد احتمال موضع الروبوت في هذا الموضع. يمكنك أن تقرأ عن أداة تقدير 2D Pose ، وسحابة الجسيمات ، والمفاهيم الأخرى في amcl في البرنامج التعليمي على ros.org.

هذا كل شيء! جميع الخوارزميات المدروسة (gmapping و amcl) هي جزء من حزمة التنقل الكبيرة في ROS ، يمكنك العثور على الكثير من المعلومات حولها على الإنترنت. جربنا اليوم أداة laser_scan_matcher ، وخوارزميات gmapping ، و amcl قيد التنفيذ. الآن يمكنك بسهولة البدء في العمل على توطين الروبوت المتنقل والتنقل فيه وإنشاء روبوت مستقل تمامًا يمكنه التنقل في الفضاء دون الحاجة إلى التحكم اليدوي.
اشترك في مجموعتنا على ROS Vkontakte وابقَ على اطلاع دائم بمظهر المقالات والأخبار الجديدة حول منصة ROS. أتمنى لكم كل التوفيق في التجارب ونراكم قريبا!

PS: كل ذلك مع 2017 القادمة!

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


All Articles