اليوم سنبحث في كيفية اكتشاف كرة حمراء باستخدام كاميرا Raspberry PI ، وكيفية البدء في توجيه الطائرة بدون طيار لدينا.

في المقالات السابقة ، درسنا بالتفصيل إطلاق طائرة استطلاع افتراضية وحقيقية مستقلة. لقد حان الوقت لطائرة بدون طيار لدينا لإيجاد هدف حقيقي.
سيكون الهدف ، كما ذكرنا ، كرة حمراء.
توت العليق
سنكتب برنامجًا للتصفية على إصدار سطح المكتب من Raspbian. منذ تكوين المرشح نذهب في الوقت نفسه إلى تحريف الإعدادات ومعرفة نتيجة الغش لدينا.
على محرك أقراص فلاش منفصل ، سنقوم بتثبيت Raspbian Desktop .
للعمل مع سطح المكتب Raspbian ، تحتاج إلى شاشة منفصلة + لوحة مفاتيح + ماوس متصلة بـ Raspberry ، وهي ليست مريحة للغاية. ولكن يمكنك العمل مع سطح المكتب بدون رأس وعبر الشبكة ، عبر VNC.
للقيام بذلك ، تحتاج إلى:
- تمكين VNC في raspi-config
- تكوين نقطة اتصال واي فاي على التوت. لا يتم التركيز على wpa_supplicant على إصدار سطح المكتب ، هنا تكمن التعليمات الخاصة بإعداد نقاط wifi في Raspberry.
- كعميل ، يمكنك استخدام realvnc .
لتطوير مرشح في بيثون - ضع OpenCV:
sudo apt-get install python-opencv
مرشح HSV لدفق الفيديو
هناك طريقة بسيطة وطريقة سريعة لتسليط الضوء على كائن ملون في صورة ما هي نقل الصورة إلى فراغ لون HSV ، ثم التصفية حسب النطاق المطلوب من الصبغة والتشبع والقيمة باستخدام cv2.inRange. أخذت هذا المثال كأساس.
خصوصية مهمتنا هي أن الكرة لدينا حمراء ، وإذا نظرنا بعناية إلى مقياس النغمة (HUE) ، سنرى أن اللون الأحمر على حوافه:

لذلك ، إذا قمت بتصفية جزء واحد فقط من النطاق ، عندما تتغير الإضاءة ، فقد "تختفي" الكرة من المرشح ، مما يؤثر سلبًا على هدف الطائرة بدون طيار لدينا. لذلك ، بالإضافة إلى المعلمات H و S و V ، سنضيف علامة الانعكاس العكسية إلى الفلتر - حتى نتمكن من تصفية كل شيء ما عدا الكرة ، ثم عكس الفلتر ببساطة.
يظهر رمز برنامج التصفية أدناه: وضع عامل التصفية على الكرة يبدو كالتالي:
حساب موقع الكرة في الفضاء
بعد تلقي المرشح ، يمكننا العثور على الكرة في صورة المرشح باستخدام وظيفة تمييز الكفاف cv2.findContours
.
في برنامجنا ، سنقوم بالتكرار على جميع المعالم الموجودة ، ونختار أكثر من 10x10 نقطة ، ونختار أكبرها - ستكون هذه هي الكرة المرغوبة. إذا ضربت عدة أشياء الكاميرا - للتوجيه ، فإننا نستخدم أقرب واحد ، أي أكبر واحد.
نرسم المعلومات المفيدة للمرشح إلى الصورة الناتجة: ارسم الخطوط العريضة التي تم العثور عليها ودائرة أكبرها ، وحدد مركز الخط (إلى أين تطير) مع الخطوط ، واشتق قطر الكرة عند النقاط وحساب المسافة إليه ، زاوية الانحراف. بالإضافة إلى ذلك ، في وسط الشاشة ، أضفت "نطاق" + أحسب وعرضت معدل الإطار - للتحكم في سرعة مرشحنا.
ويرد النص الكامل لبرنامج التصفية أدناه: ينظر برنامج الصورة من الكاميرا إلى المسافة إلى الكرة وزوايا الانحراف والميل التي تنحرف بها الكرة عن مركز صورة الكاميرا. هذه المعلومات كافية لنا لهدف الطائرة بدون طيار على الكرة. كذلك سوف نشارك في برنامج التوجيه.
كشف الكرة ROS الحزمة
يمكن نقل الوظيفة المطورة إلى نظام التوت بدون رأس مع تثبيت ROS. سنقوم بإنشاء حزمة baloon ROS التي ستؤدي الوظائف التالية:
- إطلاق mavros ، تزويدنا وحدة تحكم الطيران
- تشغيل برنامج الكشف عن الكرة لدينا. في البرنامج ، سنضيف نشر إحداثيات الكرة وتصحيح الصور في موضوعات ROS المقابلة
- قم بتشغيل web_video_server - أحد مكونات ROS التي تسمح لنا بمراقبة مرشحنا من الخارج باستخدام متصفح
قبل إنشاء حزمة ROS ، أضف الوظيفة التالية إلى برنامج تصفية ROS لدينا للعمل في بيئة ROS:
- قراءة إعدادات الكاميرا. يتم تعيين المعلمات في ROS في شكل ملف yaml ، والتي يتم الحصول عليها عادة أثناء معايرة الكاميرا . نحن مهتمون فقط بأحجام الصور (العرض والارتفاع) ، ولكن من أجل اتباع مفهوم ROS ، سنحصل عليها من ملف yaml.
- الحصول على المعلمات مرشح المحدد. سنقوم بتدوين معلمات المرشح المحددة مسبقًا في ملف الإطلاق لحزمة ROS الخاصة بنا.
- نشر إحداثيات الكرة المستلمة في موضوع ROS
/baloon_detector/twist
- نشر صور التصحيح على موضوعات ROS
/baloon_detector/image_filter
و /baloon_detector/image_result
يمكنك تشغيل البرنامج للتنفيذ باستخدام python baloon_pose_cv.py
المعتاد - ولكن هناك أيضًا طريقة أكثر ملاءمة - لحزم الوظائف التي نحتاجها في حزمة ROS وتكوين تشغيله التلقائي عند بدء تشغيل النظام.
هناك الكثير من الدروس حول إنشاء حزم ROS على الشبكة ، لذلك سأقتصر على قائمة الخطوات اللازمة.
دعنا ننشئ دليل مساحة عمل ROS لحزمتنا ، وحزمة ROS نفسها:
mkdir -p ~/baloon_ws/src cd ~/baloon_ws/ catkin_make source devel/setup.bash cd src catkin_create_pkg baloon std_msgs rospy
نضع في الدليل ~ / baloon_ws / src / baloon / src الملفات الضرورية لتشغيل الحزمة الخاصة بنا:
- baloon_pose_cv.py - برنامج الكشف عن الكرة
- baloon_cv.launch - ملف الإطلاق لإطلاق حزمة ROS الخاصة بنا
- fe130_320_01.yaml - ملف تم الحصول عليه نتيجة لمعايرة الكاميرا . نحن مهتمون به فقط في حجم الصورة ، ولكن في المستقبل يمكن استخدام هذا الملف لإجراء تحليل أعمق للصور ، واستعادة المشاهد ثلاثية الأبعاد من صورة ، إلخ.
- baloon.service ، roscore.env - يتم استخدام هذه الملفات للتشغيل التلقائي لحزمة ROS
فيما يلي نصوص كل ملف:
baloon_pose_cv.py - برنامج الكشف الرئيسي عن الكرة baloon_cv.launch - ملف الإطلاق لإطلاق حزمة ROS الخاصة بنا <launch> <include file="$(find mavros)/launch/px4.launch"> <arg name="fcu_url" value="/dev/ttyAMA0:921600"/> <arg name="gcs_url" value="tcp-l://0.0.0.0:5760"/> </include> <node name="baloon_detector" pkg="baloon" type="baloon_pose_cv.py" output="screen"> <param name="invert" value="1"/> <param name="h1" value="7"/> <param name="h2" value="158"/> <param name="s1" value="0"/> <param name="s2" value="255"/> <param name="v1" value="0"/> <param name="v2" value="255"/> <param name="real_ballon_r" value="0.145"/> <param name="camera_info_url" value="$(find baloon)/src/fe130_320_01.yaml"/> <param name="framerate" value="40"/> </node> <node name="web_video_server" pkg="web_video_server" type="web_video_server" required="false" respawn="true" respawn_delay="5"/> </launch>
fe130_320_01.yaml - ملف معايرة الكاميرا image_width: 320 image_height: 240 camera_name: main_camera_optical camera_matrix: rows: 3 cols: 3 data: [251.8636348237197, 0, 161.853506252244, 0, 252.36606604425, 102.0038140308112, 0, 0, 1] distortion_model: plumb_bob distortion_coefficients: rows: 1 cols: 5 data: [-0.4424451138703088, 0.1594038086314775, 0.006694781700363117, 0.00174908936506397, 0] rectification_matrix: rows: 3 cols: 3 data: [1, 0, 0, 0, 1, 0, 0, 0, 1] projection_matrix: rows: 3 cols: 4 data: [174.0442047119141, 0, 163.822732720786, 0, 0, 175.2916412353516, 105.5565883832869, 0, 0, 0, 1, 0]
بعد وضع الملفات في الدليل baloon_ws / src / baloon / src ، تحتاج إلى إضافة السمة "ملف قابل للتنفيذ" (cmod + x) إلى الملفات baloon_pose_cv.py و baloon.service. ثم ، كاختبار أول ، نطلق عقدة ROS الخاصة بنا يدويًا:
roslaunch baloon baloon_cv.launch
بعد بدء العقدة ، يمكننا أن نلاحظ صورة مرشحنا والكرة من خلال متصفح الويب:

وكذلك الحصول على إحداثيات الكرة المكتشفة في الموضوع /baloon_detector/twist
:
pi@raspberry:~ $ rostopic list |grep baloon /baloon_detector/image_filter /baloon_detector/image_result /baloon_detector/twist pi@raspberry:~ $ rostopic echo /baloon_detector/twist header: seq: 1 stamp: secs: 1554730508 nsecs: 603406906 frame_id: "fcu" twist: linear: x: 6.6452559203 y: 0.0 z: 0.0 angular: x: 0.0 y: 0.137081068334 z: -0.165806278939 ---
يبقى لإضافة التشغيل التلقائي للعقدة لدينا في بداية التوت.
للقيام بذلك ، قم بإنشاء ملف وصف خدمة systemd baloon.service ، مع المحتويات التالية:
[Unit] Description=BALOON ROS package Requires=roscore.service After=roscore.service [Service] EnvironmentFile=/home/pi/baloon_ws/src/baloon/src/roscore.env ExecStart=/opt/ros/kinetic/bin/roslaunch baloon baloon_cv.launch --wait Restart=on-abort [Install] WantedBy=multi-user.target
يشير الملف إلى وصف متغير البيئة roscore.env:
ROS_ROOT=/opt/ros/kinetic/share/ros ROS_DISTRO=kinetic ROS_PACKAGE_PATH=/home/pi/baloon_ws/src:/opt/ros/kinetic/share ROS_PORT=11311 ROS_MASTER_URI=http://localhost:11311 CMAKE_PREFIX_PATH=/home/pi/baloon_ws/devel:/opt/ros/kinetic PATH=/opt/ros/kinetic/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin LD_LIBRARY_PATH=/opt/ros/kinetic/lib PYTHONPATH=/home/pi/catkin_ws/devel/lib/python2.7/dist-packages:/opt/ros/kinetic/lib/python2.7/dist-packages ROS_IP=192.168.11.1
يتم توصيل وبدء الخدمة باستخدام الأوامر:
sudo systemctl enable ~/baloon_ws/src/baloon/src/baloon.service sudo systemctl start baloon
الآن يجب أن تبدأ العقدة تلقائيًا عند بدء تشغيل التوت.
يمكنك إيقاف العقدة باستخدام الأمر sudo systemctl stop baloon
، وإلغاء تشغيل تلقائي - sudo systemctl disable balloon
.
نتيجة لإجراءاتنا ، حصلنا على "كاشف كروي تلقائي" يتم إطلاقه عند بدء تشغيل النظام على الكمبيوتر الموجود على متن الطائرة.
في الجزء التالي ، سنشرع في الإطلاق النهائي لطائرة بدون طيار صاروخ موجه.
يتم تحميل شفرة المصدر للبرامج إلى جيثب .