Hari ini kita akan melihat bagaimana mendeteksi bola merah dengan kamera Raspberry PI, dan bagaimana mulai mengarahkan drone kita ke sana.

Pada artikel sebelumnya, kami memeriksa secara rinci peluncuran drone virtual dan otonom nyata . Sudah waktunya bagi drone kami untuk menemukan tujuan nyata.
Tujuannya adalah, seperti yang kami sebutkan, bola merah.
Persiapan Raspberry
Kami akan menulis program untuk filter pada Raspbian versi Desktop. Karena untuk mengonfigurasi filter, kami secara bersamaan memutar pengaturan dan melihat hasil dari cheat kami.
Pada flash drive terpisah, kami akan menginstal Desktop Raspbian .
Untuk bekerja dengan desktop Raspbian, Anda memerlukan monitor + keyboard + mouse terpisah yang terhubung ke Raspberry, yang sangat tidak nyaman. Tetapi Anda dapat bekerja dengan desktop tanpa kepala-Raspberry dan melalui jaringan, melalui VNC.
Untuk melakukan ini, Anda perlu:
- Aktifkan VNC di raspi-config
- Konfigurasikan hotspot Wifi di raspberry. Fokus dengan wpa_supplicant pada versi desktop tidak lulus, instruksi tentang pengaturan titik wifi di Raspberry ada di sini .
- Sebagai klien, Anda dapat menggunakan realvnc .
Untuk mengembangkan filter dengan Python - masukkan OpenCV:
sudo apt-get install python-opencv
Filter HSV untuk aliran video
Cara sederhana dan cara cepat untuk menyorot objek berwarna dalam gambar adalah mentransfer gambar ke ruang warna HSV , dan kemudian memfilter dengan rentang Hue, Saturation, dan nilai yang diinginkan menggunakan cv2.inRange. Saya mengambil contoh ini sebagai dasar.
Keunikan tugas kami adalah bola kami berwarna merah, dan jika kami hati-hati melihat skala Nada (HUE), kami akan melihat bahwa warna merah ada di tepinya:

Karena itu, jika Anda memfilter hanya satu bagian dari rentang, ketika pencahayaan berubah, bola mungkin "menghilang" dari filter, yang akan secara negatif mempengaruhi tujuan dari drone kami. Oleh karena itu, selain parameter H, S dan V, kami akan menambahkan bendera inversi terbalik ke filter kami - untuk dapat memfilter semua kecuali bola, dan kemudian cukup membalikkan filter.
Kode untuk program filter ditunjukkan di bawah ini: Mengatur filter pada bola terlihat seperti ini:
Perhitungan posisi bola di ruang angkasa
Setelah menerima filter, kita dapat menemukan bola di gambar filter menggunakan fungsi penyorotan kontur cv2.findContours
.
Dalam program kami, kami akan mengulangi semua kontur yang ditemukan, pilih yang lebih dari 10x10 poin, dan pilih yang terbesar - ini akan menjadi bola yang diinginkan. Jika beberapa objek menabrak kamera - untuk panduan kami menggunakan yang terdekat, mis. yang terbesar.
Kami menarik informasi yang berguna dari filter ke dalam gambar yang dihasilkan: menggambar garis yang ditemukan dan melingkari yang terbesar dari mereka, pilih pusat garis (di mana untuk terbang) dengan garis-garis, dapatkan diameter bola pada titik-titik dan menghitung jarak ke sana, sudut menguap. Selain itu, di tengah layar, saya menambahkan "cakupan" + dihitung dan ditampilkan frame rate - untuk mengontrol kecepatan filter kami.
Teks lengkap program filter diberikan di bawah ini: Program dari gambar kamera mempertimbangkan jarak ke bola dan sudut yaw dan pitch di mana bola menyimpang dari pusat gambar kamera. Informasi ini cukup bagi kami untuk mengarahkan pesawat tanpa awak pada bola. Selanjutnya kita akan terlibat dalam program bimbingan.
Paket Deteksi Bola
Fungsi yang dikembangkan dapat ditransfer ke sistem Raspberry tanpa kepala dengan ROS diinstal. Kami akan membuat paket ROS baloon yang akan melakukan fungsi-fungsi berikut:
- Luncurkan mavro, memberi kami pengontrol penerbangan
- Jalankan program deteksi bola kami. Dalam program ini kami akan menambahkan publikasi koordinat bola dan men-debug gambar dalam topik ROS yang sesuai
- Jalankan web_video_server - komponen ROS yang memungkinkan kami memantau filter kami dari luar menggunakan browser
Sebelum membuat paket ROS, tambahkan fungsionalitas berikut ke program filter ROS kami untuk bekerja di lingkungan ROS:
- Membaca pengaturan kamera. Parameter dalam ROS diatur dalam bentuk file yaml, yang biasanya diperoleh selama kalibrasi kamera . Kami hanya tertarik pada ukuran gambar (lebar dan tinggi), tetapi untuk mengikuti konsep ROS, kami mendapatkannya dari file yaml.
- Mendapatkan parameter filter yang ditentukan. Kami akan menuliskan parameter filter yang dipilih sebelumnya di file peluncuran paket ROS kami.
- Publikasi koordinat bola yang diterima dalam topik ROS
/baloon_detector/twist
- Menerbitkan debug gambar ke topik ROS
/baloon_detector/image_filter
dan /baloon_detector/image_result
Anda dapat menjalankan program untuk dieksekusi menggunakan python baloon_pose_cv.py
biasa - tetapi ada juga cara yang lebih nyaman - untuk mengemas fungsionalitas yang kita butuhkan ke dalam paket ROS dan mengkonfigurasi autorun-nya saat startup sistem.
Ada banyak pelajaran tentang cara membuat paket ROS di jaringan , jadi saya akan membatasi diri pada daftar langkah-langkah yang diperlukan.
Mari kita buat direktori ruang kerja ROS untuk paket kami, dan paket ROS itu sendiri:
mkdir -p ~/baloon_ws/src cd ~/baloon_ws/ catkin_make source devel/setup.bash cd src catkin_create_pkg baloon std_msgs rospy
Kami memasukkan direktori ~ / baloon_ws / src / baloon / src file yang diperlukan untuk menjalankan paket kami:
- baloon_pose_cv.py - program deteksi bola
- baloon_cv.launch - luncurkan file untuk meluncurkan paket ROS kami
- fe130_320_01.yaml - file diperoleh sebagai hasil kalibrasi kamera . Kami tertarik hanya pada ukuran gambar, tetapi di masa depan file ini dapat digunakan untuk analisis gambar yang lebih dalam, pemulihan adegan 3D dari gambar, dll.
- baloon.service, roscore.env - file-file ini digunakan untuk autorun dari paket ROS
Di bawah ini adalah teks dari masing-masing file:
baloon_pose_cv.py - program pendeteksi bola utama baloon_cv.launch - luncurkan file untuk meluncurkan paket ROS kami <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 - file kalibrasi kamera 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]
Setelah menempatkan file di direktori baloon_ws / src / baloon / src, Anda perlu menambahkan atribut "file yang dapat dieksekusi" (cmod + x) ke file baloon_pose_cv.py dan baloon.service. Kemudian, sebagai tes pertama, kami meluncurkan simpul ROS kami secara manual:
roslaunch baloon baloon_cv.launch
Setelah memulai node, kita dapat mengamati gambar filter dan bola kami melalui browser web:

Dan juga dapatkan koordinat bola yang terdeteksi dalam topik /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 ---
Masih menambahkan autostart dari simpul kami di awal Raspberry.
Untuk melakukan ini, buat file deskripsi layanan systemd baloon.service, dengan konten berikut:
[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
File merujuk ke deskripsi variabel lingkungan 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
Menghubungkan dan memulai layanan dilakukan menggunakan perintah:
sudo systemctl enable ~/baloon_ws/src/baloon/src/baloon.service sudo systemctl start baloon
Sekarang simpul harus mulai secara otomatis ketika Raspberry dimulai.
Anda dapat menghentikan node dengan perintah sudo systemctl stop baloon
, batalkan autostart - sudo systemctl disable balloon
.
Sebagai hasil dari tindakan kami, kami mendapat "detektor bola otomatis" yang diluncurkan ketika sistem dimulai pada komputer yang terpasang.
Di bagian selanjutnya, kita akan melanjutkan ke peluncuran akhir dari pesawat pengintai.
Kode sumber untuk program diunggah ke Github .