عربة شاحنة ROS. الجزء 4. إنشاء محاكاة الروبوت باستخدام محرري rviz و gazebo

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

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



المشاركات السابقة في السلسلة:

1. الجزء 3
2. الجزء 2
3. الجزء 1

إنشاء ملفات urdf الأساسية

بشكل عام ، تتكون عملية إنشاء روبوت بطريقة مبسطة عادة من المراحل التالية:

1. إنشاء نموذج الروبوت.
2. اختبار النموذج في محاكاة.
3. إنشاء نموذج روبوت حقيقي.
4. اختبار نموذج حقيقي.

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

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

إنشاء قوات الدفاع الشعبي


من أجل التمتع الكامل بالمحاكاة في Gazebo واختبار الروبوت ، يجب أولاً إنشاء ملف URDF للروبوت.

ملف URDF هو نوع من هيكل عظمي في مجال التصور.
ببساطة ، ملف URDF هو ملف يصف الروبوت.

كما ذكرنا سابقًا ، سيتم تنفيذ العمل باستخدام صورة VMWARE Workstation التي تم بالفعل تثبيت ROS (Ubuntu 16.04 ، ROS-Kinetic) والمحررين المرئيين عليها. لذلك ، جميع الإجراءات قابلة للتكرار في هذا النظام.

قم بإنشاء حزمة ROS تسمى rosbots_description.

للقيام بذلك ، تحتاج إلى إدخال المجلد باستخدام catkin_ws / src وتنفيذ الأمر لإنشاء الحزمة في ROS:

roscd; cd ..; cd src; catkin_create_pkg rosbots_description rospy 

* إذا عند تنفيذ الأمر roscd ؛ مؤتمر نزع السلاح .. مؤتمر نزع السلاح src؛ إذا لم تحصل على catkin_ws ، فربما لديك العديد من البيئات من هذا النوع. لتفعيل ما يلزم ، انتقل إلى مجلد catkin_ws وقم بتشغيل الأمر: source devel / setup.bash. لكي لا تضيع ، إذا كنت تعمل مع الصورة ، يمكنك الوصول إلى هذا المجلد من الجذر: cd ~؛ catkin_ws مؤتمر نزع السلاح.

إذا سارت الأمور على ما يرام ، فسيتم إنشاء مجلد rosbots_description.

لماذا يكون إنشاء مجلد في catkin_ws / src يدويًا أمرًا صعبًا وليس أسهل؟ وأي نوع من الروبي هو؟

يمكنك إنشاء مجلد يدويًا ، ولكن سيتعين عليك أيضًا كتابة ملفين آخرين يعملان مع ROS: CMakeLists.txt و package.xml.

كانت موجودة في المجلد بعد الإنشاء:



ROS بهم يخلق من تلقاء نفسها. في حين أننا لن نتطرق إلى محتوياتها.
rospy في نهاية الأمر يعني خلق التبعيات ، ودعم الثعبان.

المضي قدما.

داخل حزمة rosbots_description التي تم إنشاؤها حديثًا ، قم بإنشاء مجلد urdf ، وفيه ملف rosbots.xacro.

 roscd rosbots_description mkdir urdf; cd urdf; touch rosbots.xacro chmod +x rosbots.xacro 

إن جمال نظام ROS هو أنه في أي مجلد من مجلدات النظام لن تكون موجودًا فيه ، يمكنك الوصول إلى الهدف على الفور بمجرد كتابة اسمه بأمر roscd في بداية السطر.

الآن ضع الكود التالي في الملف المنشأ حديثًا:

rosbots.xacro
 <?xml version="1.0" encoding="utf-8"?> <robot name="rosbots" xmlns:xacro="http://www.ros.org/wiki/xacro"> <link name="base_footprint"/> <joint name="base_joint" type="fixed"> <origin xyz="0 0 0.05" rpy="0 0 0" /> <parent link="base_footprint"/> <child link="base_link" /> </joint> <link name="base_link"> <visual> <geometry> <mesh filename="package://rosbots_description/meshes/base.dae"/> </geometry> <origin xyz="-0.52 -0.4 0.43" rpy="0 0 0"/> </visual> <collision> <geometry> <mesh filename="package://rosbots_description/meshes/base.dae"/> </geometry> <origin xyz="-0.52 -0.4 0.43" rpy="0 0 0"/> </collision> <inertial> <origin xyz="0.0 0 0."/> <mass value="0.5"/> <inertia ixx="0.01" ixy="0.0" ixz="0.0" iyy="0.01" iyz="0.0" izz="0.03" /> </inertial> </link> <joint name="second_level_joint" type="fixed"> <origin xyz="0 0 0.68" rpy="0 0 0" /> <parent link="base_link"/> <child link="base_second_link" /> </joint> <link name="base_second_link"> <visual> <geometry> <mesh filename="package://rosbots_description/meshes/base.dae"/> </geometry> <origin xyz="-0.52 -0.4 0.0" rpy="0 0 0"/> </visual> <collision> <geometry> <mesh filename="package://rosbots_description/meshes/base.dae"/> </geometry> <origin xyz="-0.52 -0.4 0.0" rpy="0 0 0"/> </collision> <!--inertial> <origin xyz="0.01 0 0.7"/> <mass value="1.0"/> <inertia ixx="0.01" ixy="0.0" ixz="0.0" iyy="0.01" iyz="0.0" izz="0.03" /> </inertial--> </link> <joint name="mcu_joint" type="fixed"> <origin xyz="0.02 0.12 0.73" rpy="0 0 0" /> <parent link="base_link"/> <child link="mcu_link" /> </joint> <link name="mcu_link"> <visual> <geometry> <mesh filename="package://rosbots_description/meshes/rasp.dae" scale="0.14 0.14 0.14"/> </geometry> <origin xyz="0.9 -1.25 0" rpy="0 0 1.57"/> </visual> <collision> <geometry> <mesh filename="package://rosbots_description/meshes/rasp.dae" scale="0.14 0.14 0.14"/> </geometry> <origin xyz="0.9 -1.25 0" rpy="0 0 1.57"/> </collision> <!-- inertial> <origin xyz="0.01 0 0"/> <mass value="1.0"/> <inertia ixx="0.019995" ixy="0.0" ixz="0.0" iyy="0.019995" iyz="0.0" izz="0.03675" /> </inertial--> </link> <joint name="mcu_joint_1" type="fixed"> <origin xyz="0.02 0.12 0.83" rpy="0 0 0" /> <parent link="base_link"/> <child link="mcu_link_1" /> </joint> <link name="mcu_link_1"> <visual> <geometry> <mesh filename="package://rosbots_description/meshes/rasp.dae" scale="0.14 0.14 0.14"/> </geometry> <origin xyz="0.9 -1.25 0" rpy="0 0 1.57"/> </visual> <collision> <geometry> <mesh filename="package://rosbots_description/meshes/rasp.dae" scale="0.14 0.14 0.14"/> </geometry> <origin xyz="0.9 -1.25 0" rpy="0 0 1.57"/> </collision> <!-- inertial> <origin xyz="0.01 0 0"/> <mass value="1.0"/> <inertia ixx="0.019995" ixy="0.0" ixz="0.0" iyy="0.019995" iyz="0.0" izz="0.03675" /> </inertial--> </link> <joint name="stand_mcu1_joint" type="fixed"> <origin xyz="0.02 0.25 0.78" rpy="0 0 1.57" /> <parent link="base_link"/> <child link="stand_mcu1_link" /> </joint> <link name="stand_mcu1_link"> <visual> <geometry> <cylinder length="0.1" radius="0.01"/> </geometry> <origin rpy="0.0 0 0" xyz="0 0 0.0"/> </visual> <collision> <geometry> <cylinder length="0.1" radius="0.01"/> </geometry> <origin rpy="0.0 0 0" xyz="0 0 0.0"/> </collision> </link> <joint name="stand_mcu2_joint" type="fixed"> <origin xyz="0.02 -0.1125 0.78" rpy="0 0 1.57" /> <parent link="base_link"/> <child link="stand_mcu2_link" /> </joint> <link name="stand_mcu2_link"> <visual> <geometry> <cylinder length="0.1" radius="0.01"/> </geometry> <origin rpy="0.0 0 0" xyz="0 0 0.0"/> </visual> <collision> <geometry> <cylinder length="0.1" radius="0.01"/> </geometry> <origin rpy="0.0 0 0" xyz="0 0 0.0"/> </collision> </link> <joint name="stand_mcu3_joint" type="fixed"> <origin xyz="0.25 0.25 0.78" rpy="0 0 1.57" /> <parent link="base_link"/> <child link="stand_mcu3_link" /> </joint> <link name="stand_mcu3_link"> <visual> <geometry> <cylinder length="0.1" radius="0.01"/> </geometry> <origin rpy="0.0 0 0" xyz="0 0 0.0"/> </visual> <collision> <geometry> <cylinder length="0.1" radius="0.01"/> </geometry> <origin rpy="0.0 0 0" xyz="0 0 0.0"/> </collision> </link> <joint name="stand_mcu4_joint" type="fixed"> <origin xyz="0.25 -0.1125 0.78" rpy="0 0 1.57" /> <parent link="base_link"/> <child link="stand_mcu4_link" /> </joint> <link name="stand_mcu4_link"> <visual> <geometry> <cylinder length="0.1" radius="0.01"/> </geometry> <origin rpy="0.0 0 0" xyz="0 0 0.0"/> </visual> <collision> <geometry> <cylinder length="0.1" radius="0.01"/> </geometry> <origin rpy="0.0 0 0" xyz="0 0 0.0"/> </collision> </link> <joint name="batery_joint" type="fixed"> <origin xyz="1.2 0.2 0.43" rpy="0 0 1.57" /> <parent link="base_link"/> <child link="batery_link" /> </joint> <link name="batery_link"> <visual> <geometry> <mesh filename="package://rosbots_description/meshes/battery.dae" scale="13.0 6.0 6.0"/> </geometry> <origin xyz="0 4.5 0.05" rpy="1.57 0 1.57"/> </visual> <collision> <geometry> <mesh filename="package://rosbots_description/meshes/battery.dae" scale="13.0 6.0 6.0"/> </geometry> <origin xyz="0 4.5 0.05" rpy="1.57 0 1.57"/> </collision> <!-- inertial> <origin xyz="0.01 0 0"/> <mass value="1.0"/> <inertia ixx="0.01" ixy="0.0" ixz="0.0" iyy="0.01" iyz="0.0" izz="0.03" /> </inertial--> </link> <joint name="stand_1_joint" type="fixed"> <origin xyz="0.5 0.4125 0.58" rpy="0 0 1.57" /> <parent link="base_link"/> <child link="stand_1_link" /> </joint> <link name="stand_1_link"> <visual> <geometry> <cylinder length="0.20" radius="0.03"/> </geometry> <origin rpy="0.0 0 0" xyz="0 0 0.0"/> </visual> <collision> <geometry> <cylinder length="0.20" radius="0.03"/> </geometry> <origin rpy="0.0 0 0" xyz="0 0 0.0"/> </collision> <!--inertial> <origin xyz="0.0 0 0"/> <mass value="1.0"/> <inertia ixx="0.019995" ixy="0.0" ixz="0.0" iyy="0.019995" iyz="0.0" izz="0.03675" /> </inertial--> </link> <joint name="stand_2_joint" type="fixed"> <origin xyz="0.5 -0.2625 0.58" rpy="0 0 1.57" /> <parent link="base_link"/> <child link="stand_2_link" /> </joint> <link name="stand_2_link"> <visual> <geometry> <cylinder length="0.20" radius="0.03"/> </geometry> <origin rpy="0.0 0 0" xyz="0 0 0.0"/> </visual> <collision> <geometry> <cylinder length="0.20" radius="0.03"/> </geometry> <origin rpy="0.0 0 0" xyz="0 0 0.0"/> </collision> <!--inertial> <origin xyz="0.0 0 0"/> <mass value="1.0"/> <inertia ixx="0.019995" ixy="0.0" ixz="0.0" iyy="0.019995" iyz="0.0" izz="0.03675" /> </inertial--> </link> <joint name="wheel_left_joint" type="continuous"> <parent link="base_link"/> <child link="wheel_left_link"/> <origin xyz="0.15 0.4125 0.30" rpy="-1.57 0 0"/> <axis xyz="0 0 1"/> </joint> <link name="wheel_left_link"> <collision> <geometry> <cylinder length="0.20" radius="0.23"/> </geometry> <origin rpy="0.0 0.0 0" xyz="0 0 0.1"/> </collision> <visual name="visual"> <geometry> <!-- cylinder length="0.0206" radius="0.0550"/--> <!--cylinder length="0.20" radius="0.26"/--> <mesh filename="package://rosbots_description/meshes/wheel.dae" scale="8.0 8.0 8.0"/> </geometry> <origin rpy="0.0 0 0" xyz="0 0 0"/> </visual> <inertial> <mass value="0.4" /> <origin xyz="0 0 0" /> <inertia ixx="0.001" ixy="0.0" ixz="0.0" iyy="0.001" iyz="0.0" izz="0.001" /> </inertial> </link> <joint name="wheel_right_joint" type="continuous"> <parent link="base_link"/> <child link="wheel_right_link"/> <origin xyz="0.15 -0.5625 0.30" rpy="-1.57 0 0"/> <axis xyz="0 0 1"/> </joint> <link name="wheel_right_link"> <collision> <geometry> <cylinder length="0.20" radius="0.23"/> </geometry> <origin rpy="0.0 0 0" xyz="0 0 0.195"/> </collision> <visual name="visual"> <geometry> <!--cylinder length="0.20" radius="0.26"/--> <mesh filename="package://rosbots_description/meshes/wheel.dae" scale="8.0 8.0 8.0"/> </geometry> <origin rpy="0.0 0 0" xyz="0 0 0"/> </visual> <inertial> <mass value="0.4" /> <origin xyz="0 0.0 0.3" /> <inertia ixx="0.001" ixy="0.0" ixz="0.0" iyy="0.001" iyz="0.0" izz="0.001" /> </inertial> </link> <joint name="caster_back_joint" type="fixed"> <parent link="base_link"/> <child link="caster_back_link"/> <origin xyz="-0.4 0.1 0.26" rpy="0 0 0"/> </joint> <link name="caster_back_link"> <collision> <geometry> <!-- cylinder length="0.05" radius="0.19"/--> <sphere radius="0.19"/> </geometry> <origin rpy="0 0 0" xyz="0 0 0"/> </collision> <visual> <geometry> <!--cylinder length="0.05" radius="0.19"/--> <sphere radius="0.19"/> </geometry> <origin rpy="0 0 0" xyz="0 0 0"/> </visual> <inertial> <mass value="0.1" /> <origin xyz="0 0 0" /> <inertia ixx="0.001023539" ixy="0.0" ixz="0.0" iyy="0.001023539" iyz="0.0" izz="0.001023539" /> </inertial> </link> <joint name="stand_3_joint" type="fixed"> <origin xyz="-0.4 0.4125 0.58" rpy="0 0 1.57" /> <parent link="base_link"/> <child link="stand_3_link" /> </joint> <link name="stand_3_link"> <visual> <geometry> <cylinder length="0.20" radius="0.03"/> </geometry> <origin rpy="0.0 0 0" xyz="0 0 0.0"/> </visual> <collision> <geometry> <cylinder length="0.20" radius="0.03"/> </geometry> <origin rpy="0.0 0 0" xyz="0 0 0.0"/> </collision> </link> <joint name="stand_4_joint" type="fixed"> <origin xyz="-0.4 -0.2625 0.58" rpy="0 0 1.57" /> <parent link="base_link"/> <child link="stand_4_link" /> </joint> <link name="stand_4_link"> <visual> <geometry> <cylinder length="0.20" radius="0.03"/> </geometry> <origin rpy="0.0 0 0" xyz="0 0 0.0"/> </visual> <collision> <geometry> <cylinder length="0.20" radius="0.03"/> </geometry> <origin rpy="0.0 0 0" xyz="0 0 0.0"/> </collision> </link> </robot> 


في حالة عدم ظهور الرمز ، يمكن تنزيل جميع الملفات في نهاية المنشور.

للحصول على الكود أعلاه ، نحتاج أيضًا إلى خلايا (meches) ، والتي سيتم تحميلها أثناء إطلاق الحزمة.

يمكن أن تؤخذ Meches هنا
ووضع مجلد meches unpacked في rosbots_description.

إذا نظرت إلى الكود بالتفصيل ، يمكنك معرفة أن هذا ملف xml قياسي يتكون من كتل:
- البصرية
- تصادم
- بالقصور الذاتي

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

أصل xyz هو الموقع الأولي للكائن على طول محاور س ، ص ، ض.

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

الكود أعلاه هو أساسا نموذج الروبوت.

العمل في rviz


دعونا نرى ما حدث.

للقيام بذلك ، قم بإنشاء ملف بدء تشغيل يقوم بتشغيل حزمة ROS.

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

قم بإنشاء مجلد تشغيل في rosbots_description باستخدام ملف rviz.launch:

 roscd rosbots_description mkdir launch; cd launch; touch rviz.launch 

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

املأ الملف بالمحتويات -
rviz.launch
  <?xml version="1.0"?> <launch> <param name="robot_description" command="cat '$(find rosbots_description)/urdf/rosbots.xacro'"/> <!-- send fake joint values --> <node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher"> <param name="use_gui" value="False"/> </node> <!-- Combine joint values --> <node name="robot_state_publisher" pkg="robot_state_publisher" type="state_publisher"/> <!-- Show in Rviz --> <node name="rviz" pkg="rviz" type="rviz" /> </launch> 


هنا يمكنك أن ترى أنه عند بدء التشغيل سوف يبحث النظام عن وصف للنموذج في rosbots.xacro.

بعد ذلك ، سيتم إطلاق العقد الثلاثة: joint_state_publisher من حزمة joint_state_publisher ، robot_state_publisher من robot_state_publisher ، rviz من rviz. type هو نوع العقدة ، وعادة ما يتوافق مع ملف Python أو C الذي يحمل نفس الاسم ، ولكن يتم تحديده دون امتداد.

تشغيل:

في المحطة الأولى ، قم بتشغيل برنامج ROS الرئيسي:

 roscore 

في الثاني:

 roslaunch rosbots_description rviz.launch 

* إذا حدث خطأ
ROS_MASTER_URI [http: //192.168.1 ....: 11311] لم يتم تعيين المضيف على هذا الجهاز
، فأنت بحاجة إلى التحقق من bashrc - الذي يعمل عليه ip ROS:

 nano ~/.bashrc 

حدد ip للجهاز الظاهري في ملف bashrc نفسه (على سبيل المثال ، هذا واحد):

 export ROS_MASTER_URI=http://192.168.1.114:11311 

أعد قراءة bashrc مرة أخرى:

source ~/.bashrc أو إعادة التشغيل.
**
إذا لم يبدأ roslaunch ، فيمكنك محاولة الانتقال إلى مجلد catkin_ws وتشغيله: source devel / setup.bash

الغوص في رفيز


بعد تنفيذ الأمر ، يبدأ محرر Rviz ويفتح الغلاف الرسومي.
قد يختلف العرض التقديمي المرئي ، ولكن بشكل عام سيكون العرض تقريبًا كما يلي:



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

يتم تنفيذ معظم الأعمال في المحرر في أول عمودين: يعرض والتمثيل المرئي للروبوت.

دعنا نعمل مع نظرة الروبوت


دعنا نختار "الإطار الثابت" - "الرابط الأساسي" في السطر:



وإضافة Robot Description إلى عرض:

انقر فوق "إضافة" وحدد "RobotModel" في القائمة:

"

الآن في نافذة المحاكاة ، يمكنك مراقبة الروبوت الذي تم استنساخه من طراز rviz.xacro:

"

ممتاز. مع تمثيل مرئي ، كل شيء واضح. أنت الآن بحاجة إلى فهم كيفية تشغيل المحاكاة ، لأن rviz هو مجرد تصور للمحاكاة ، ولكن ليس المحاكاة نفسها.
وهذا هو ، والفيزياء لا تعمل هنا.

تعيش المحاكاة نفسها في محرر يسمى Gazebo.

أكشاك


لوضع النموذج الذي تم إنشاؤه في Gazebo ، قم بإنشاء ملف تشغيل آخر - spawn.launch في مجلد إطلاق المشروع. الآن لدينا 2 إطلاق الملفات!

spawn.launch
 <?xml version="1.0" encoding="UTF-8"?> <launch> <param name="robot_description" command="cat '$(find rosbots_description)/urdf/rosbots.xacro'" /> <arg name="x" default="0"/> <arg name="y" default="0"/> <arg name="z" default="0.5"/> <node name="mybot_spawn" pkg="gazebo_ros" type="spawn_model" output="screen" args="-urdf -param robot_description -model rosbots -x $(arg x) -y $(arg y) -z $(arg z)" /> </launch> 


هنا نقرأ أيضًا النموذج ، ثم من خلال الوسائط نجعل موقعه في الفضاء على طول المحاور x و y و z. بعد ذلك ، قم بتشغيل عقدة واحدة فقط - mybot_spawn من حزمة gazebo_ros.
* ليست هناك حاجة لإعادة تثبيت الحزم المذكورة أعلاه. إذا كنت ترغب في ذلك ، يمكنك إلقاء نظرة على هذه الحزم بنفس الأمر: roscd. على سبيل المثال roscd gazebo_ros.

الآن توقف روس ماستر في المحطة 1:

 CTRL+C 

وتشغيل محرر أكشاك:

 roslaunch gazebo_ros empty_world.launch 

في المحطة 2 ، قم بتشغيل الملف المنشأ حديثًا:

 roslaunch rosbots_description spawn.launch 

الآن نرى روبوتنا في محاكاة محرر Gazebo:



* إذا كان لديك خطأ: في Waiting for service /gazebo/spawn_urdf_model
هذا يعني أنك أطلقت النموذج دون بدء تشغيل Gazebo أولاً ، منتهكًا ترتيب الإطلاق.

دعنا نذهب إلى محاكاة شرفة.


أضف الآن الكود التالي إلى rosbots.xacro قبل علامة الإغلاق:

قانون
 <gazebo> <plugin name="differential_drive_controller" filename="libgazebo_ros_diff_drive.so"> <legacyMode>false</legacyMode> <alwaysOn>true</alwaysOn> <publishWheelTF>true</publishWheelTF> <publishTf>1</publishTf> <publishWheelJointState>true</publishWheelJointState> <updateRate>100.0</updateRate> <leftJoint>wheel_left_joint</leftJoint> <rightJoint>wheel_right_joint</rightJoint> <wheelSeparation>1.1</wheelSeparation> <wheelDiameter>0.52</wheelDiameter> <wheelAcceleration>1.0</wheelAcceleration> <torque>20</torque> <commandTopic>/part2_cmr/cmd_vel</commandTopic> <odometryTopic>odom</odometryTopic> <odometryFrame>odom</odometryFrame> <robotBaseFrame>base_link</robotBaseFrame> </plugin> </gazebo> 


لا يمكن إغلاق محاكي أكشاك عند التحرير.

الآن احذف النموذج من محرر Gazebo:

 rosservice call /gazebo/delete_model "model_name: 'rosbots'" 

أو فقط أعد تشغيل المحرر.

* Gazebo غريب الأطوار في جهاز افتراضي ، لذلك حتى بعد إغلاقه يغفر أحيانًا CTRL + C بشكل إضافي في الجهاز.

أعد وضع النموذج في Gazebo بعد التحرير:

 roslaunch rosbots_description spawn.launch 

إذا نظرت الآن إلى قائمة موضوعات ROS ، يمكنك أن ترى أن هناك من بينها

 /part2_cmr/cmd_vel 



الآن دعونا نحاول التحكم في الروبوت في المحاكاة عن طريق تشغيل التحكم في محطة منفصلة:

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

من خلال كونك في النافذة مع تشغيل عنصر التحكم والضغط على المفاتيح "i" و "l" و "j" و "k" و "و" في النافذة الطرفية ، يمكنك مراقبة حركة الروبوت في محاكاة محرر Gazebo:



رمز - تحميل .

أن تستمر.

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


All Articles