Okullar için Robotik ve Mühendislik · anaokulundan liseye

9. ünite / 10

ROS 2 + PX4, SITL ve görüyle hassas iniş

YazılımSimülasyonParça

Bu ünitenin sonunda

  • PX4 ile ROS 2 arasındaki uXRCE-DDS köprüsünü açıklamak
  • PX4 SITL + Gazebo + ROS 2 ortamını kurmak
  • Offboard kipinde konum hedefi gönderen bir ROS 2 düğümü yazmak
  • ArUco işaretçisiyle hassas inişin algılama ve denetim zincirini kurmak

Ders notları

PX4 v1.14'ten bu yana ROS 2'ye uXRCE-DDS ile bağlanır: uçuş kontrolcüsündeki istemci uORB konularını, bilgisayardaki MicroXRCEAgent üzerinden ROS 2 konularına çevirir. Konular /fmu/out/... (PX4'ten çıkan, ör. vehicle_status) ve /fmu/in/... (PX4'e giren, ör. trajectory_setpoint) diye ayrılır; mesaj tanımları px4_msgs paketindedir ve PX4 sürümüyle eşleşmelidir.

SITL: donanımsız tam sistem

Döngüde yazılım (SITL) testinde gerçek PX4 kodu bilgisayarda derlenir, fizik ve sensörler Gazebo'dan gelir. make px4_sitl gz_x500 tek komutla quad'ı başlatır; QGroundControl ve MAVSDK gerçek araçtaki gibi bağlanır. Bu dersin tarayıcı simülasyonları kavramı, SITL ise gerçek yazılımı test eder.

Offboard denetim

  • Offboard kipine geçmeden önce OffboardControlMode ve hedef mesajları en az 2 Hz akmalıdır; akış kesilirse PX4 failsafe'e geçer (COM_OBL_RC_ACT).
  • PX4 yerel çerçevesi NED'dir: x kuzey, y doğu, z aşağı. 5 m yükseklik z = −5 demektir; ROS'un ENU geleneğiyle karıştırma.

Görüyle hassas iniş

Aşağı bakan kamera ArUco işaretçisini bulur, solvePnP ile işaretçinin kameraya göre konumunu hesaplar. İki yol vardır: (1) görev bilgisayarı yatay hız komutu üretir ve hizalanınca alçalır (görsel servo), (2) konum LANDING_TARGET olarak PX4'e verilir ve yerleşik Precision Land kipi gerisini yapar. GPS'le metrelerce olan iniş hatası böylece santimetrelere iner.

Simülasyonlar

Ara nokta görevi ve hassas iniş (3B uçuş + 2B harita)

Kalkış → ara noktalar → iniş pedine iniş. Kontrolcü yalnız kestirilen konumu bilir: GPS hatası yavaşça gezinir. İnişte ArUco kamerası açılınca hata santimetrelere düşer. Haritaya tıklayarak ara nokta ekle (sonuncusu ped), rüzgâr ve GPS hatasını değiştir.

3B sahne yükleniyor…

ROS 2 hesaplama grafiği

Düğümler konulara (topic) mesaj yayınlar, diğer düğümler bunlara abone olur. Bir düğümü durdurmak ya da başlatmak için tıkla ve sistemin hangi kısımlarının sustuğunu gör.

Simülasyon görevi

Görev simülasyonunda iniş kaynağı "ArUco kamerası" iken görevi birkaç kez çalıştır ve iniş hatasını GPS'li 7. ünitedekiyle karşılaştır. Kamera hangi anda devreye giriyor (mavi kestirim)? ESOF 323 ROS 2 grafiği simülasyonunda bir düğümü durdurup hangi konuların sustuğuna bak: offboard düğümün çökerse PX4 ne yapmalı? Linux ya da WSL2 kullanıyorsan kabuk adımlarıyla SITL'i kur ve offboard düğümünü çalıştır.

Kod

Kabuk: PX4 SITL + Gazebo + ROS 2 kurulumu (Ubuntu 24.04)
# 1) PX4 ve Gazebo Harmonic (Ubuntu 22.04/24.04 ya da WSL2)
git clone https://github.com/PX4/PX4-Autopilot.git --recursive
bash ./PX4-Autopilot/Tools/setup/ubuntu.sh        # bitince oturumu kapatıp aç
cd PX4-Autopilot
make px4_sitl gz_x500                            # x500 quad Gazebo'da; "pxh>" kabuğu açılır
# pxh> commander takeoff     pxh> commander land
# Aşağı bakan kameralı model (hassas iniş): make px4_sitl gz_x500_mono_cam_down

# 2) QGroundControl: AppImage indir, çalıştır; UDP 14550'den kendiliğinden bağlanır

# 3) ROS 2 Jazzy (24.04) ya da Humble (22.04) kurulu olsun; ardından Micro XRCE-DDS Agent
git clone -b v2.4.3 https://github.com/eProsima/Micro-XRCE-DDS-Agent.git   # PX4 belgesindeki etiket (DDS v2)
cd Micro-XRCE-DDS-Agent && mkdir build && cd build && cmake .. && make && sudo make install && sudo ldconfig /usr/local/lib/
MicroXRCEAgent udp4 -p 8888                      # SITL istemcisi buna kendiliğinden bağlanır

# 4) px4_msgs (PX4 sürümünle aynı dal) ve örnekler
mkdir -p ~/px4_ws/src && cd ~/px4_ws/src
git clone https://github.com/PX4/px4_msgs.git
git clone https://github.com/PX4/px4_ros_com.git
cd ~/px4_ws && colcon build && source install/setup.bash
ros2 topic list | grep fmu                       # /fmu/out/vehicle_status (v1.16+: vehicle_status_v1) ...
ROS 2 (rclpy): offboard kipinde 5 m'ye çık ve bekle
# PX4 v1.16+ bazı konu adlarına sürüm eki ekler (ör. vehicle_status_v1): "ros2 topic list" ile kontrol et.
import rclpy
from rclpy.node import Node
from rclpy.qos import QoSProfile, ReliabilityPolicy, DurabilityPolicy, HistoryPolicy
from px4_msgs.msg import OffboardControlMode, TrajectorySetpoint, VehicleCommand

QOS = QoSProfile(reliability=ReliabilityPolicy.BEST_EFFORT, durability=DurabilityPolicy.TRANSIENT_LOCAL,
                 history=HistoryPolicy.KEEP_LAST, depth=1)

class Offboard(Node):
    def __init__(self):
        super().__init__("offboard_demo")
        self.mode = self.create_publisher(OffboardControlMode, "/fmu/in/offboard_control_mode", QOS)
        self.sp = self.create_publisher(TrajectorySetpoint, "/fmu/in/trajectory_setpoint", QOS)
        self.cmd = self.create_publisher(VehicleCommand, "/fmu/in/vehicle_command", QOS)
        self.n = 0
        self.create_timer(0.1, self.tick)              # 10 Hz: offboard en az 2 Hz akış ister

    def us(self):
        return self.get_clock().now().nanoseconds // 1000

    def command(self, command, p1=0.0, p2=0.0):
        m = VehicleCommand(command=command, param1=p1, param2=p2, target_system=1, target_component=1,
                           source_system=1, source_component=1, from_external=True, timestamp=self.us())
        self.cmd.publish(m)

    def tick(self):
        self.mode.publish(OffboardControlMode(position=True, timestamp=self.us()))
        self.sp.publish(TrajectorySetpoint(position=[0.0, 0.0, -5.0], yaw=0.0, timestamp=self.us()))  # NED: z aşağı
        if self.n == 10:                                # 1 s akıştan sonra kip ve ARM
            self.command(VehicleCommand.VEHICLE_CMD_DO_SET_MODE, 1.0, 6.0)   # 6 = OFFBOARD
            self.command(VehicleCommand.VEHICLE_CMD_COMPONENT_ARM_DISARM, 1.0)
        self.n += 1

def main():
    rclpy.init()
    rclpy.spin(Offboard())

if __name__ == "__main__":
    main()
Python + OpenCV: ArUco ile hassas iniş hatası ve hız komutu
# pip install opencv-contrib-python   (OpenCV ≥ 4.7)
import cv2
import numpy as np

MARKER = 0.30                                    # işaretçi kenarı, m
K = np.array([[410.0, 0, 320], [0, 410.0, 240], [0, 0, 1]])   # kamera matrisi (kalibrasyondan)
DIST = np.zeros(5)
OBJ = np.array([[-1, 1, 0], [1, 1, 0], [1, -1, 0], [-1, -1, 0]], dtype=np.float32) * MARKER / 2
det = cv2.aruco.ArucoDetector(cv2.aruco.getPredefinedDictionary(cv2.aruco.DICT_4X4_50), cv2.aruco.DetectorParameters())

def landing_command(gray, k=0.6, v_max=1.0):
    """Aşağı bakan kamera görüntüsü → (vx, vy, vz) gövde hızı, m/s; işaretçi yoksa None"""
    corners, ids, _ = det.detectMarkers(gray)
    if ids is None:
        return None                              # ARAMA durumuna dön
    ok, rvec, tvec = cv2.solvePnP(OBJ, corners[0][0].astype(np.float32), K, DIST, flags=cv2.SOLVEPNP_IPPE_SQUARE)
    ex, ey, h = tvec.ravel()                     # kamera çerçevesinde işaretçi: x sağ, y aşağı (görüntüde), z ileri = yükseklik
    # Kamera aşağı bakıyor: görüntü yukarısı = gövde ileri (montaja göre işaretleri doğrula)
    vx, vy = np.clip(-k * ey, -v_max, v_max), np.clip(k * ex, -v_max, v_max)
    vz = 0.5 if np.hypot(ex, ey) < 0.15 else 0.0  # hizalıysa alçal (NED: + aşağı)
    return float(vx), float(vy), float(vz)
# Alternatif: konumu LANDING_TARGET (#149) olarak gönder, PX4 Precision Land kipi gerisini yapar.

Sık yapılan hatalar

  • px4_msgs dalını PX4 sürümüyle eşleştirmemek: mesajlar uyuşmaz, konular boş görünür.
  • Offboard'a akış başlamadan geçmeye çalışmak: PX4 reddeder.
  • NED ile ENU'yu karıştırmak: drone yükselmek yerine yere iner.
  • Kamera kalibrasyonu yapmadan solvePnP kullanmak: mesafe ve konum hatalı çıkar.

Yazılım mühendisliği bağlantısı

SITL, sürekli entegrasyonun parçası olabilir: her değişiklikte başsız (headless) Gazebo'da görev çalıştırılır.

  • HEADLESS=1 make px4_sitl gz_x500 ile görüntüsüz başlat, betikle görevi uçur, ULog'dan kabul ölçütlerini ölç.
  • Senaryoları kod olarak tut (rüzgâr, GPS kaybı, bağlantı kesilmesi); her biri bir test olsun.

Kendini sına

  1. PX4 (v1.14+) ile ROS 2 arasında hangi köprü kullanılır?

  2. Offboard kipine geçmeden önce ne gerekir?

  3. PX4 yerel çerçevesinde 5 m yükseklik hangi z değerine karşılık gelir?

  4. ArUco işaretçisinin kameraya göre konumunu bulmak için hangi OpenCV fonksiyonu kullanılır?

Bu üniteden sonra bitirme projesinde

  • Hassas iniş: ArUco algılama düğümü ve görsel servo; iniş hatası 5 denemede ölçüldü (G2).

Bu ünitenin parçaları

3B modelli gerçek Hyvex parçaları:

Esc
  • PanelAna sayfaSayfa
  • ModüllerTüm modüllerSayfa
  • ParçalarParça ansiklopedisiSayfa
  • Mühendislik yoluBüyükler için robotik: 128 parça, 7 seviyeSayfa
  • Robotik dersi (ESOF 323)Üniversite robotik dersi, 14 haftaSayfa
  • Drone dersiBüyükler için: parça, simülasyon, yazılım; 10 üniteSayfa
  • Blok atölyesiSerbest blok programlamaAraç
  • Devre laboratuvarıSanal Arduino ve devreAraç
  • Robot arenasıSanal robot sürüşüAraç
  • OyunlarBloklarla 8 öğretici oyunAraç
  • Mikro Kart atölyesiSanal LED kartı bloklarla programlaAraç
  • Robot atölyesiMikro Kart'ı robota tak, bloklarla görev yapAraç