عربة الروبوت 2.0. الجزء 1. التنقل المستقل للروبوت المنزلي على أساس ROS

تم بناء المشروع على أساس مشروع آخر معروف جيدًا في دوائره - linorobot (linorobot.org) ، باستخدام المكونات المتاحة للشخص العادي البسيط. الأهداف التي تم تحديدها: لتحقيق حركة مستقلة للروبوت في المنزل باستخدام مكونات منخفضة التكلفة ، وتقييم أداء أجهزة الكمبيوتر المصغرة للأغراض المذكورة ، لتكوين حزمة التنقل للتحرك في المساحات الضيقة من خروتشوف.



حديد


قائمة المكونات في المواد الصلبة هي كما يلي:

  • التوت بي 3B - 2800 ص.
  • lidar rplidar a1 - 7500 ص ؛
  • جسور الطاقة l298n -2pcs - 400 rub.
  • العجلات مع التشفير من النوع A و B - 2000 ص. (210 دورة في الدقيقة - رابط )
  • teenzy 3.2 - 2100 ص ؛
  • imu 9250 (إما 9150 أو 6050) - 240 ص ؛
  • بنك الطاقة في 10000mH - 1500 ص.
  • عدد 3 بطاريات 18650 وحامل -600 ص.
  • تنحى محول DC-DC ج 5V إلى 3.3V - 20P.
  • قطعة من الخشب الرقائقي ، الباركيه -؟ فرك.

المجموع: ١٧١٦٠ ص.

* يمكن تخفيض التكلفة عن طريق استبدال teenzy بـ arduino mega 2560 (600 ص.) ، والليدار عن طريق استبدال kinect v.1 (1000 ص):



ومع ذلك ، تجدر الإشارة إلى أن kinect الأول لديه الحد الأدنى من الرؤية (المنطقة العمياء) 0.5 م ، والتي يمكن أن تؤثر سلبًا على الملاحة في ظروف ضيقة وهي كبيرة الحجم إلى حد ما. يحتوي الليدار على منطقة عمياء أقل من 0.2 م.لن يتناسب Kinect v.2 مع التوت 3 ب (لا يحتوي على USB 3.0). Arduino mega أدنى من المراهق في الحجم (وبعض الخصائص) ، بالإضافة إلى ذلك ، سيكون عليك إعادة صياغة الرمز قليلاً.

بشكل عام ، يبدو "التصميم" كالتالي:





ليس هناك جمال هنا ، بالطبع ، لكن هذا ليس حوله.

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

تجميع الروبوت


تم رسمه بالتفصيل على موقع المشروع - رابط ، لذلك دعونا نتحدث عن النقاط التي تسبب صعوبات. أولاً ، يجب أن تضع في اعتبارك أن الترميز الموجود على العجلات يتم تشغيله بجهد 3.3 فولت ، وعندما يتم تطبيق 5V ، يفشل تمامًا.

تم تثبيت البرنامج النصي لتثبيت linorobot بنجاح على أوبونتو 16.04 ، أوبونتو 18.04. إصدارات ROS: ROS الحركية أو ROS لحني. في raspberry 3b ، يجب عليك أولاً إنشاء ملف مبادلة.

رمز المراهق الرئيسي هو على طول الطريق:

roscd linorobot/teensy/firmware/lib/config
nano lino_base_config.h

وسكب عليها الأمر:

roscd linorobot/teensy/firmware
platformio run --target upload

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

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

في حالتي ، اتضح مثل هذا:

/// ENCODER PINS
#define MOTOR1_ENCODER_A 14
#define MOTOR1_ENCODER_B 15 

#define MOTOR2_ENCODER_A 11
#define MOTOR2_ENCODER_B 12 
//MOTOR PINS
#ifdef USE_L298_DRIVER
  #define MOTOR_DRIVER L298

  #define MOTOR1_PWM 21
  #define MOTOR1_IN_A 1
  #define MOTOR1_IN_B 20

  #define MOTOR2_PWM 5
  #define MOTOR2_IN_A 8
  #define MOTOR2_IN_B 6

النقطة الثانية هي وصف مواصفات عجلات الروبوت:

//define your robot' specs here
#define MAX_RPM 210               // motor's maximum RPM
#define COUNTS_PER_REV 1365       // wheel encoder's no of ticks per rev
#define WHEEL_DIAMETER 0.065       // wheel's diameter in meters
#define PWM_BITS 8                // PWM Resolution of the microcontroller
#define LR_WHEELS_DISTANCE 0.235  // distance between left and right wheels
#define FR_WHEELS_DISTANCE 0.30   // distance between front and rear wheels. Ignore this if you're on 2WD/ACKERMANN
#define MAX_STEERING_ANGLE 0.415  // max steering angle. This only applies to Ackermann st

يمكن العثور على العائد لكل ألف ظهور في مواصفات العجلة ، ولكن CPR (COUNTS_PER_REV) هي القيمة المحسوبة.
CPR = PPR × 4. طاعون المجترات الصغيرة من عجلاتنا 341.

* يمكن عرض PPR في المواصفات أو تشغيل الكود على roslaunch linorobot Mineal_runch robot وتدور العجلة 360 درجة. سيكون PPR مساويًا للقيمة العددية التي سيتم عرضها على الشاشة بعد تدوير العجلة:



* PPR = القيمة المطلقة (RECENT_COUNT - INITIAL_COUNT).

لذا CPR = 1364. تحتاج أيضًا إلى تعيين WHEEL_DIAMETER و LR_WHEELS_DISTANCE بالأمتار. علاوة على ذلك ، LR_WHEELS_DISTANCE هي المسافة بين المحاور المركزية للعجلات ، وليس من حافة إلى أخرى. يمكن تجاهل المؤشرات الأخرى إذا كان الروبوت ذو عجلتين وتفاضلي (وليس كليًا).

النقطة الثالثة التي يمكن أن تسبب صعوبات - معايرة imu. للقيام بذلك ، باتباع التعليمات ، من الضروري إصلاح الروبوت في مواقف معينة. ستكون التلميحات في التعليمات البرمجية عند تنفيذ البرنامج النصي rosrun imu_calib do_calib :



بعد الانتهاء من إنشاء imu_calib.yaml مع الإعدادات.

من الأفضل إجراء المعايرة ، على الرغم من وجود ملف افتراضي بإعدادات imu.
* بالإضافة إلى ذلك ، تبين أن المعايرة imu يمكن أن تؤثر على اتجاه حركة الروبوت من خلال teleop (اليسار بدلاً من اليمين والعكس صحيح ، بينما كانت الحركة ذهابًا وإيابًا صحيحة). لم يتم حل الموقف بإعادة ترتيب المسامير في الكود. تم إصلاح ومعايرة Imu نفسها بأقواس مقلوبة ، مثل ثابتة على الجزء الخلفي من قاعدة الروبوت. له (imu) المزيد من الوجه دون إعادة المعايرة حل المشكلة.

النقطة الرابعة - معايرة pid.

على موقع المشروع ، يتم وصف إجراء تنفيذ التعديل بالتفصيل - رابط .

ومع ذلك ، سيكون من الصعب على المبتدئ معرفة ما هو وكيفية العمل معه. بشكل عام ، هناك حاجة إلى تنظيم pid لضمان تحرك الروبوت بشكل موحد ، دون الرجيج / الكبح المفاجئ. المعلمات الثلاث هي المسؤولة عن هذا: ص ، ط ، د. يتم تضمين قيمهم في الرمز الرئيسي الذي تم تحميله إلى teenzy:

#define K_P 2.0 // P constant angle
#define K_I 0.3 // I constant
#define K_D 0.1 // D constant

يمكنك تجربتها عن طريق التشغيل على الروبوت:

roslaunch linorobot minimal.launch

علاوة على الكمبيوتر الخارجي في ثلاث محطات مختلفة:

rosrun lino_pid pid_configure
rosrun teleop_twist_keyboard teleop_twist_keyboard.py
rqt

من خلال تحريك منزلقات p ، d ، i في محطة rqt ، ومن ثم التحكم في الروبوت في محطة teleop_twist_keyboard ، يمكنك تحقيق النتائج الضرورية دون الحاجة إلى تنزيل الكود بمعلمات pid الجديدة في كل مرة في سن المراهقة:



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

يوصون بالبدء بتحديد القيم p = 1.0 ، d = 0.1 ، i = 0.1. في حالتنا ، تكون القيم على النحو التالي (تم الحصول عليها تجريبيًا) p = 2.0 ، i = 0.3 ، d = 0.1.

بعد ذلك ، يجب تعيين هذه القيم في التعليمات البرمجية وملؤها في سن المراهقة.

أيضًا ، لا تنس تعيين الرمز (DEBUG 0 بدلاً من DEBUG 1):

#define DEBUG 0

قياس المسافات


لتوجيه الروبوت والملاحة اللاحقة ، يتم استخدام بيانات lidar وبيانات imu و encoder. إذا تم إجراء معايرة imu بشكل صحيح ، يتم تثبيت الليدار بشكل صحيح ، وتكون قيم التشفير صحيحة ، فيجب ألا تكون هناك مشاكل في قياس المسافات.

للتحقق من صحة odometry ، تحتاج إلى الركوب قليلاً على الروبوت عبر teleop ورؤية القيم في موضوع odom ، وهذا مكتوب على صفحة المشروع - رابط .

وانظر أيضًا في الغلاف البصري لـ rviz:



خلية واحدة في rviz هي 1 متر ، لذا فمن المستحسن أن يقوم الروبوت بتمرير هذا العداد في المحرر المرئي والعيني أيضًا.

بالإضافة إلى ذلك ، يتم عرض المسافة المقطوعة في المؤشر ث:



يجب أن تميل أيضًا إلى 1 م.

وينطبق الشيء نفسه على زوايا دوران الروبوت:



* في rviz والعيش ، يجب أن يدور الروبوت في نفس الزوايا.

يتم تحديد قياس المسافات من ليدار بطريقة مماثلة - ارتباط. يجب أن تتطابق المسافة من ليدار إلى أقرب جدار مباشر وفي رفيز.

TF


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

في المشروع ، تم تكوين جميع اتصالات tf بالفعل بالنسبة لبعضها البعض وتحتاج فقط إلى ضبط المؤشرات ، على سبيل المثال ، الإشارة إلى كيفية وجود lidar. يعد ذلك ضروريًا لفهم الروبوت أن العائق لم يبرز مباشرة أمامه ، ولكن أمام الليدار ، الذي يتم فصله عن مركز الروبوت على مسافة معينة.

دعنا نذهب إلى الدليل المناسب:

roscd linorobot/launch
nano bringup.launch

تقع القاعدة نفسها على مسافة 0.065 م من الأرضية:

<node pkg="tf_ros" type="static_transform_publisher" name="base_footprint_to_base_link" args="0 0 0.065 0 0 0  /base_footprint /base_link "/>

في laser_runch ، تحتاج إلى تعيين موقع الليدار بالنسبة لمركز قاعدة الروبوت:

roscd linorobot/launch/include
nano laser.launch

في حالتي ، يتم تحريك الليدار على طول المحور x: -0.08 ، y: 0.04 و "الارتفاعات" فوق القاعدة (المحور z): 0.08 م:

<node pkg="tf2_ros" type="static_transform_publisher" name="base_link_to_laser"
args="-0.08 0.04 0.08 0 0 0  /base_link /laser "/>

في rviz ، يمكن ملاحظة هذا الموقع بصريًا: في



حين أنه ليس بعيدًا عن الليدار ، قم بتعديل تردده بحيث يعطي المزيد من النقاط (بشكل افتراضي يعطي 4k) ، سيساعد ذلك في بناء الخريطة:

cd linorobot/launch/include/lidar
nano rplidar.launch

إضافة معلمة:

<param name="scan_mode"  type="string" value="Boost"/>

والتغيير

<param name="angle_compensate"    type="bool"   value="false"/>

الآن 8k تحت تصرفنا:



الموقع المادي لليدار على الروبوت مهم أيضًا:



بناء خريطة غرفة ثنائية الأبعاد


يقترح على موقع المشروع إنشاء خريطة غرفة من خلال الإطلاق في محطتين:

roslaunch linorobot bringup.launch
roslaunch linorobot slam.launch

ومع ذلك ، فقد أظهرت الممارسة أن slam ، الذي يأتي مع المشروع بشكل افتراضي ، يرفض العمل عندما يكون وضع lidar هو 8k:



بينما في وضع 4K ، لا تكون البطاقات ناجحة للغاية ، فهي صاخبة للغاية.

لذلك ، من الأفضل استخدام ضربة سلام أخرى - hector-slam.

يشار إلى كيفية تثبيته هنا .

بعد التثبيت ، سيكون إجراء بناء الخريطة هو نفسه ، ولكن بدلاً من roslaunch linorobot slam.co.unch ، قم بتشغيل roslaunch my_hector_mapping my_launch_runch.

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



لا تنسى حفظ خريطة الغرفة:

rosrun map_server map_saver -f my-map

* يتم الحصول على الخرائط بشكل أفضل في الشفق اللطيف ، وهذا سيضغط إلى أقصى حد من ميزانية الميزانية.

يتبع.

All Articles