عربة شاحنة ROS. الجزء 7. توطين الروبوت: gmapping ، AMCL ، والنقاط المرجعية على خريطة الغرفة

المشاركات في السلسلة:
8. نحن نتحكم من الهاتف ROS Control ، GPS العقدة
7. توطين الروبوت: gmapping ، AMCL ، النقاط المرجعية على خريطة الغرفة
6. المسافات مع ترميز عجلة ، خريطة الغرفة ، ليدار
5. نحن نعمل في rviz وشرفة المراقبة: xacro ، أجهزة استشعار جديدة.
4. قم بإنشاء محاكاة روبوت باستخدام محرري rviz و gazebo.
3. تسريع ، تغيير الكاميرا ، إصلاح المشية
2. البرمجيات
1. الحديد

آخر مرة ، بعد تثبيت ميزانية lidar RPlidar-A1 ، تمكنا من بناء خريطة غرفة ، والعمل مع قياس المسافات. ومع ذلك ، فإن الروبوت ، على الرغم من امتلاكه بطاقة وضبط قياس المسافات من أجهزة الاستشعار البصرية ، لا يزال يشعر بعدم الأمان في البيئة.
بدلا من ذلك ، فهو لا يراها على الإطلاق. وهو يركب على طول الخريطة النهائية البعيدة ، والعقبات ليست بالنسبة له. هذا هو السرور والمحزن على حد سواء في نفس الوقت. من ناحية ، لا تقلق بشأن العقبات والسفر أينما كان قلبك ، من ناحية أخرى ، من غير المحتمل أن تذهب إلى غرفة أخرى أو إلى المطبخ. لذلك ، سنتحدث عن توطين الروبوت في الفضاء باستخدام الخوارزميات التي توفرها ROS ، فضلاً عن مجموعة رجلنا من Lidar وأجهزة التشفير. ولكن قبل أن نذهب مباشرة إلى التعريب ، دعنا نتحدث عن حزمة ROS أخرى ، والتي تتيح لك أيضًا إنشاء خرائط ثنائية الأبعاد للغرفة ، وفي بعض الأحيان تعمل بشكل أفضل له من حزمة ROS من المشاركة السابقة. تعرف على gmapping.

جمهورية مقدونيا gmapping


لن نكون أصليين وسنستخدم التطورات من مقالة هبر الموجودة بالفعل حول هذا الموضوع ، لكننا سنقوم بتوسيع وتحديث وتعميق المعلومات الواردة فيه. يُطلق على المقال إنشاء خريطة وتعريب روبوت متنقل في ROS دون قياس المسافات باستخدام Laser_scan_matcher .

سيتم تنفيذ جزء من العمليات (التطبيقات عالية التحميل - rviz) على الكمبيوتر (خارج الروبوت) ، والباقي (برنامج تشغيل الحركة ، عقدة إطلاق lidar) - على الروبوت.

أولاً ، قم بتثبيت laser_scan_matcher لـ ROS-kinetic على الكمبيوتر وفقًا لسيناريو المقال أعلاه (كانت المقالة نيلي):

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

ركض الآن.

إيماءة مع غطاء على الروبوت:

 roslaunch rplidar_ros rplidar.launch 

على الكمبيوتر:

 roslaunch laser_scan_matcher demo.launch 

* ليست هناك حاجة لتشغيل roscore ، لأن العقدة الرئيسية تبدأ في كل مرة يتم فيها تحميل Robot.

في بداية rviz ، ستكون ملامح الغرفة والقمامة الموجودة بها مرئية:

صورة

سنحتاج إلى laser_scan_matcher للعمل مع حزمة gOS لـ ROS. ليست هناك حاجة لتثبيت gmapping نفسه ، فهو موجود بالفعل على الجهاز الظاهري كجزء من ROS Kinetic. تحقق الحزمة في النظام:



الآن لنقم بإنشاء ملف تشغيل باستخدام gmapping على الكمبيوتر (وليس على Robot) ، كما في المقالة أعلاه ،:

 roscd roscd rosbots_description/launch nano my_gmapping_launch.launch     

قانون
 <?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> 


كما ترى من الكود ، يبدأ المؤلف بثلاث عقد: tf و laser_scan_matcher و gmapping.

دعنا نركض على الروبوت مرة أخرى:

 roslaunch rplidar_ros rplidar.launch 

على الكمبيوتر ، ملف الإطلاق المخبأ حديثًا ومحرر rviz:

 roslaunch rosbots_description my_gmapping_launch.launch 

 rosrun rviz rviz 

في rviz ، نحصل على صورة مشابهة للصورة التي تم الحصول عليها عند إنشاء الخريطة في منشورنا السابق حول Robot Cart. فقط هذه المرة تعمل حزمة gmapping.

ويجب أن أعترف ، أنها لا تعمل بشكل سيء. إذا ترك hector_slam العديد من القطع الأثرية على الخريطة عندما تدور الغطاء حول محوره ، فلا توجد تقريبًا هذه المرة:



بعد الرحلات في جميع أنحاء الغرفة ، يتم أيضًا حفظ الخريطة المبنية:
rosrun map_server map_saver -f map-1 ، حيث map-1 هو اسم الخريطة المراد حفظها.

التعريب مع amcl


الخوارزمية المستخدمة لتحديد موقع الروبوت على الخريطة تسمى AMCL. يستخدم AMCL مرشح متعدد الجسيمات لتتبع موقع الروبوت على الخريطة. في روبوتنا ، نستخدم حزمة ROS (http://wiki.ros.org/amcl) لتنفيذ AMCL.

تشغيل AMCL للروبوت لدينا.

للقيام بذلك ، قم بإنشاء ملف تشغيل آخر على الكمبيوتر في مجلد المشروع.

دعنا ندعوه

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> 


الكود مطابق تمامًا للمقال المذكور سابقًا ، باستثناء:
- استبعد العقدة التي تطلق lokar hokuyo (يتم تشغيله على Robot)
- مسار واسم غرفة الخريطة مختلفان (map-3.yaml)
يعمل الكود 4 عقد:
- TF
- map_server
- laser_scan_matcher
- amcl
تستخدم العقدة amcl الخريطة التي ينشرها map_server لترجمة الروبوت اللاحقة.

قم بتشغيل ملفات الإطلاق وانظر إلى النتيجة.

لكن للروبوت:

 roslaunch rplidar_ros rplidar.launch 

على الكمبيوتر:
1st محطة: roslaunch rosbots_description amcl-2.launch
2nd محطة: roslaunch rosbots_description rviz.launch

بعد بدء تشغيل rviz ، ستكون الخطوات التالية في هذا المحرر هي:
- إضافة عروض إلى rviz:
• LaserScan
• خريطة
• PoseArray


- توطين الروبوت في المرحلة الأولية ، لأنه عند بدء تشغيل amcl لا يعرف من أين بدأ الروبوت ومكانه. تحتاج إلى "التهيئة الأولية".
لهذا الغرض ، في rviz ، تحتاج إلى تحديد "2D Pose Estimate" واستخدام السهم الأخضر في النافذة التي يظهر فيها الروبوت للإشارة إلى موضعه:



يجب أن تتم هذه العملية من خلال تحديد Frame "map" في rviz:



في المحطة نحصل على إحداثيات (تشكل) من الروبوت:

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

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



في نافذة التصور rviz ، نحصل على السهام الحمراء المميزة حول الروبوت *:



* كإنسان آلي ، لدينا محور للوضوح (لا يزال نموذج rviz بأكمله مطبقًا).
** إذا لم تظهر الأسهم ، فيمكنك محاولة إزالة شاشة PoseArray وإضافتها إلى rviz وإعادة التحقق منها.

على الرغم من أننا أشرنا مباشرة على الخريطة حيث يوجد الروبوت ، لا يزال النظام يفترض أنه يمكن أن يكون في تلك الأماكن حيث يتم رسم الأسهم الحمراء. هذا هو الموقع المحتمل للروبوت على الخريطة. يشير عدد كبير من الأسهم ومبعثراتها على الخريطة إلى أن النظام لا يزال لا يعرف الموقع الدقيق للروبوت. ومع ذلك ، فإن المكان الذي يكون فيه مطلق النار أكثر كثافة ، يكون الروبوت أكثر احتمالًا.

حتى يتمكن النظام من فهم مكان الروبوت بدقة أكبر ، يجب عليك الركوب على خريطة مع عقد تشغيل تحدد موقع الروبوت. لدينا من هذه المجموعة: lidar والتشفير.
لكننا لا نسافر على الخريطة إلا باستخدام ليدار الذي تم إطلاقه ، وفي نفس الوقت نتعرف على ما إذا كان من الممكن توطين الروبوت بطريقة موثوقة فقط بمساعدة (ليدار).
-
ركوب الروبوت على الخريطة
على الروبوت:

 rosrun rosbots_driver part2_cmr.py 

على الكمبيوتر:

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


أثناء الرحلة ، سيبدأ amcl في قراءة المواضيع / المسح الضوئي / / map / / tf ونشر موقع الروبوت في المواضيع / amcl_pose و / particlecloud.

أثناء سفرك ، يمكنك ملاحظة أن عدد الأسهم يتناقص ويتزايد تكثيفها عند نقطة ما مع الموقع الفعلي للروبوت:


توضح الصورة كيفية انتقال النموذج (في شكل شجرة اتصالات). ويتبين أيضًا أن الغطاء لا يتناسب بدقة مع التوطين عند الحدود الغامضة للغرفة.

ماذا المعلمات الأخرى في رمز العقدة amcl يعني؟


تقليديًا ، يتم تقسيمها إلى معلمات أساسية (عامة) ، عوامل تصفية (تصفية) ، معلمات ليزر (ليدار) (معلمات الليزر).

المعلمات الرئيسية:
  • odom_model_type (افتراضي: "فرق"): يحدد أي نموذج لقياس المسافات يتم استخدامه. لدينا فرق ، وهو ما يعني الفرق. يمكن تغييره إلى "omni" أو "diff-corrected" أو "omni-corrected".
  • odom_frame_id (افتراضي: "odom"): يحدد الإطار (اقرأ الموضوع) الذي سيتم ربط قياس المسافات به. وعادة ما يتم نشرها في موضوع odom.
  • base_frame_id (افتراضي: "base_link"): إطار لقاعدة الروبوت.
  • global_frame_id (افتراضي: "map"): إطار الخريطة ، حيث يقوم خادم خريطة القاعدة بنشرها في خريطة الموضوع
  • use_map_topic (افتراضي: خطأ): يحدد ما إذا كان سيتم تحميل الخريطة من خلال الموضوع أو عن طريق الاتصال بالخدمة (نذكر أنه بالإضافة إلى الموضوعات الموجودة في ROS ، هناك أيضًا خدمات وإجراءات.


تصفية المعلمات
تتيح لك هذه الخيارات تخصيص كيفية عمل مرشح الجسيمات.

  • min_particles (افتراضي: 100): تعيين الحد الأدنى لعدد الجزيئات للمرشح. لدينا 500.
  • max_particles (افتراضي: 5000): ضبط الحد الأقصى لعدد الجزيئات للمرشح.
  • kld_err (الافتراضي: 0.01): يعين الحد الأقصى للخطأ المسموح به بين التوزيع الحقيقي والتوزيع المحسوب. لدينا 0.05
  • update_min_d (الافتراضي: 0.2): ضبط المسافة الخطية (بالأمتار) التي يجب أن يسافرها الروبوت لتحديث الفلتر.
  • update_min_a (افتراضي: pi / 6.0): ضبط المسافة الزاوية (بالراديان) التي يجب أن يتحركها الروبوت لتحديث الفلتر. لدينا 0.5
  • resample_interval (افتراضي: 2): يضبط عدد تحديثات المرشح اللازمة قبل إعادة الجلب. لدينا 1.
  • transform_tolerance (افتراضي: 0.1): الوقت (بالثواني) الذي يجب أن يكون مؤرخًا فيه التحويل المنشور للإشارة إلى أن هذا التحول صالح في المستقبل.
  • gui_publish_rate (افتراضي: -1.0): السرعة القصوى (بالهرتز هرتز) التي يتم فيها إجراء عمليات المسح والمسارات للنشر. إذا كانت هذه القيمة هي -1.0 ، فسيتم تعطيل هذه الوظيفة. لدينا 10.


معلمات الليزر (ليدار) (معلمات الليزر)
تسمح لك هذه المعلمات بتكوين كيفية تفاعل amcl مع ليزر lidar.

  • laser_min_range (افتراضي: -1.0): الحد الأدنى لنطاق المسح الذي يجب مراعاته ؛ -1.0 سيستخدم الحد الأدنى للنطاق المحدد في تقرير الليزر.
  • laser_max_range (افتراضي: -1.0): الحد الأقصى لنطاق المسح الذي يجب مراعاته ؛ -1.0 سيستخدم نطاق الليزر الأقصى.
  • laser_max_beams (افتراضي: 30): كم عدد الحزم الموزعة بالتساوي في كل عملية مسح سيتم استخدامها عند تحديث الفلتر.
  • laser_z_hit (افتراضي: 0.95): أوزان مكون z_hit في نموذج الروبوت.
  • laser_z_short (افتراضي: 0.1): أوزان المكون z_short في نموذج الروبوت.
  • laser_z_max (افتراضي: 0.05): وزن مكون z_max في نموذج الروبوت.
  • laser_z_rand (افتراضي: 0.05): أوزان المكون z_rand في نموذج الروبوت.


دعونا نرى ما تؤثر على معلمات min_particles و max_particles. إذا قمت بتقليل قيمها ، فعند بدء تشغيل ملف الإطلاق ، سيكون عدد الجزيئات في المحرر المرئي أقل بشكل واضح.

جميع المعلمات تحمل عبء دلالي ، ولكن من الصعب تحليل تأثير تغيير كل منها داخل المقالة.

النقاط المرجعية على خريطة الغرفة


الاسم جذاب ويشير إلى وضع الروبوت على الخريطة في هذه اللحظة بالذات.

لماذا هم ل؟ من أجل فهم أن الروبوت جاء من النقطة أ في الغرفة إلى النقطة ب في المطبخ.

يمكن الحصول على البيانات المتعلقة بموضع (تشكل) الروبوت باستخدام عقدة amcl العاملة (ما بدأ في المقالة أعلاه).

وابحث في الموضوع / amcl_pose:

 rostopic echo -n1 /amcl_pose 

* المفتاح n1 - من أجل "إصلاح" تدفق الرسائل في الموضوع.



لنقم بإنشاء خدمة ، عندما يتم الاتصال بها ، ستتخلى عن موضع (إحداثيات) الروبوت بحيث لا يبحث في كل مرة في الموضوع.

1. إنشاء حزمة جديدة روس.

 cd catkin_ws/src catkin_create_pkg get_pose rospy cd get_pose/src 

2. في المجلد ، قم بإنشاء الملف:

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. 


* لا تنسَ أن تجعله قابلاً للتنفيذ chmod + x get_pose_service.py
3. دعنا ننشئ تشغيل للملف برمز العقدة:

 cd .. mkdir launch && cd launch 

نانو

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


4. لا تنس أن إعادة بناء catkin:

 cd catkin_ws catkin_make 

الآن سنقوم بإعادة تشغيل كل شيء ، بما في ذلك ملف التشغيل الجديد.

لكن للروبوت:

 roslaunch rplidar_ros rplidar.launch 

على الكمبيوتر:

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

ننتقل إلى الخدمة الجديدة ، والتي ينبغي أن تعطينا الموضع الحالي للروبوت على الخريطة (سوف ندعو خدمة ROS):

 rosservice call /get_pose_service 

في محطة التشغيل get get ، سنحصل على إحداثيات الروبوت على الخريطة:



الأخطاء المحتملة.

[rviz.launch] ليس ملف تشغيل في الحزمة [rosbots_description] ولا يعد [rosbots_description] اسمًا لملف التشغيل
الحل:

 cd catkin_ws source devel/setup.bash 

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


All Articles