Softivation

Pixhawk Python'dan hedef gönderince neden yere iniyor

Python'dan hedef gönderince drone yere iniyorsa ilk bakılacak yer irtifa çerçevesidir. 20 metreyi deniz seviyesine göre yollarsan Pixhawk zemine iner.

Furkan IŞIKAY 6 dk okuma

Drone GUIDED modda havada bekliyor. Raspberry Pi'deki Python kodun 50 metre ileriye, 20 metre yüksekliğe bir hedef gönderiyor. Drone ileri gitmek yerine yavaşça alçalıyor ve hedefe varmadan yere konuyor.

Koddaki 20 doğru. Sorun, otopilotun o 20'yi neye göre okuduğunda.

Drone neden alçalıyor

Konum hedefindeki irtifa tek başına gitmez, yanında bir çerçeve numarası taşır. Çerçeve 6 eve göre demektir: 20, kalkış noktasının 20 metre üstüdür. Çerçeve 5 deniz seviyesine göre demektir: 20, deniz seviyesinden 20 metredir.

Saha deniz seviyesinden 500 metre yüksekteyse çerçeve 5 ile gönderilen 20 metrelik hedef zeminin 480 metre altında kalır. ArduPilot bu hedefi itiraz etmeden kabul eder ve drone'u oraya doğru düz bir çizgide götürmeye başlar.

Aynı 20, iki farklı çerçeve

Aynı 20, iki farklı çerçeve
Nereye bak: kırmızı çizginin zemine değdiği nokta. 50 metrelik yolun yalnızca 2 metresi gidilmiş.

Şekilde kırmızı çizginin zemine değdiği noktaya bak. Hedef 50 metre ileride ama 480 metre aşağıda olduğu için yolun neredeyse tamamı dikeydir. Drone iniş hızı sınırıyla, saniyede 1,5 metreyle alçalır, yatayda yalnızca 2 metre ilerler ve yere değer.

Teknofest sürü görevinden bir örnek: lider drone'un konumunu okuyup takipçiye hedef olarak yollayan bir kod düşün. Kod yüksekliği eve göre olan alandan (20 m) alıp çerçeve 5 ile gönderirse takipçi yere iner. Aynı sayıyı çerçeve 6 ile gönderirse takipçi liderle aynı yükseklikte kalır.

Otopilot neden uyarmıyor

Bu konum mesajının onayı yoktur. ArduPilot hedefi kabul ettiğinde de, GUIDED dışındaki bir modda yok saydığında da yer istasyonuna tek satır yazmaz.

Elinde kalan tek geri bildirim, otopilotun yayınladığı hedef mesajıdır. O mesaj irtifayı her zaman deniz seviyesine göre verir. Kodun bu sayıdan ev yüksekliğini çıkarırsa hedefin eve göre nerede durduğunu görürsün.


En sık hata, drone'un konum mesajındaki iki yüksekliği karıştırmaktır. GLOBAL_POSITION_INT içindeki alt alanı deniz seviyesine göre, relative_alt alanı eve göredir. Sayıyı hangi alandan aldıysan çerçeveyi ona göre seç: alt için 5, relative_alt için 6.

Çözüm: çerçeveyi seç, hedefi geri oku

Aşağıdaki kod hedefi 6 numaralı çerçeveyle, yani eve göre gönderir. Ardından otopilotun kabul ettiği hedefi okur ve eve göre kaç metreye denk geldiğini yazar.

Python · hedef_kontrol.py
import time
from pymavlink import mavutil

BAGLANTI = "tcp:127.0.0.1:5762"   # Raspberry Pi'de: "/dev/serial0"
IRTIFA_M = 20                      # kalkış noktasına (eve) göre metre
KUZEY_M = 50                       # hedef, şu anki konumun kaç metre kuzeyinde

baglanti = mavutil.mavlink_connection(BAGLANTI, baud=57600)
baglanti.wait_heartbeat()
baglanti.mav.request_data_stream_send(
    baglanti.target_system, baglanti.target_component,
    mavutil.mavlink.MAV_DATA_STREAM_ALL, 4, 1)

konum = baglanti.recv_match(type="GLOBAL_POSITION_INT", blocking=True)
ev_amsl = (konum.alt - konum.relative_alt) / 1000.0   # evin deniz seviyesine göre yüksekliği
hedef_lat = konum.lat / 1e7 + KUZEY_M / 111111.0
hedef_lon = konum.lon / 1e7

baglanti.mav.set_position_target_global_int_send(
    0, baglanti.target_system, baglanti.target_component,
    mavutil.mavlink.MAV_FRAME_GLOBAL_RELATIVE_ALT_INT,   # irtifa EVE göre
    0b0000111111111000,                                  # yalnızca konum
    int(hedef_lat * 1e7), int(hedef_lon * 1e7), IRTIFA_M,
    0, 0, 0, 0, 0, 0, 0, 0)

# Otopilotun kabul ettiği hedefi geri oku. Bu mesaj hep deniz seviyesine göre gelir.
hedef = None
bitis = time.time() + 5
while time.time() < bitis:
    m = baglanti.recv_match(type="POSITION_TARGET_GLOBAL_INT", blocking=True, timeout=1)
    if m and abs(m.lat_int / 1e7 - hedef_lat) < 1e-5:
        hedef = m
        break

if hedef is None:
    print("Hedef geri gelmedi: araç GUIDED modunda mı?")
else:
    eve_gore = hedef.alt - ev_amsl
    print(f"Ev (deniz seviyesi): {ev_amsl:.1f} m")
    print(f"Hedef (deniz seviyesi): {hedef.alt:.1f} m -> eve göre {eve_gore:.1f} m")
    if eve_gore < 2:
        print("DİKKAT: hedef yerde ya da yerin altında, irtifa çerçevesini kontrol et")

Raspberry Pi'de BAGLANTI satırını "/dev/serial0" yap ve baud değerini Pixhawk'ta Pi'nin bağlı olduğu portun hızıyla eşle. Kodu çalıştırmadan önce drone GUIDED modda olmalı; başka bir modda otopilot hedefi hiç işlemez.

Ne göreceksin

Kodu olduğu gibi, çerçeve 6 ile çalıştırırsan hedef evin 20 metre üstüne düşer ve drone 50 metre kuzeye o yükseklikte gider:

Kod
Ev (deniz seviyesi): 500.1 m
Hedef (deniz seviyesi): 520.1 m -> eve göre 20.0 m

Aynı satırda MAV_FRAME_GLOBAL_RELATIVE_ALT_INT yerine MAV_FRAME_GLOBAL_INT yazarsan hedef zeminin altına düşer, kod uyarır ve drone alçalmaya başlar:

Kod
Ev (deniz seviyesi): 500.1 m
Hedef (deniz seviyesi): 20.0 m -> eve göre -480.1 m
DİKKAT: hedef yerde ya da yerin altında, irtifa çerçevesini kontrol et

Ev satırındaki sayı senin sahanın yüksekliğidir; 500 yerine kendi rakamını görürsün. Önemli olan ikinci satırdaki eve göre değerinin istediğin yükseklikle aynı olması.

Hata Mesajları

ArduPilot yanlış çerçeve için bir uyarı basmaz. Aşağıdakiler aynı sorunun çevresinde karşına çıkabilecek gerçek mesajlar.

Mode change to GUIDED failed: requires position

Otopilotun konum tahmini yok, araç GUIDED'e geçmedi. Bu durumda gönderdiğin hedef hiç işlenmez ve kod "Hedef geri gelmedi" yazar. Önce GPS'in 3D fix almasını bekle.

SET_POSITION_TARGET_GLOBAL_INT invalid coordinate frame 0

Bu satırı PX4 basar. PX4 bu mesajda yalnızca 5, 6 ve 11 numaralı çerçeveleri kabul eder; 0, 3 ve 10 numaralıları reddeder. ArduPilot ikisini de kabul eder.

Expecting location to be LocationGlobal or LocationGlobalRelative.

DroneKit'in simple_goto fonksiyonu bu iki sınıftan başka bir şey alırsa bu hatayı verir. LocationGlobal verirsen kütüphane ev yüksekliğini çıkarıp eve göre gönderir; LocationGlobal(enlem, boylam, 20) yazarsan hedef yine yerin altına düşer.

Kodu kursta tamamla

Hedefi göndermeden önce yerin altına düşüp düşmediğini hesaplayan, otopilotun cevabıyla karşılaştırıp uyuşmazsa drone'u LOITER'a alan tam kod ve ArduPilot'un bu mesajı işlerken izlediği karar sırası Python ile Sıfırdan İHA Kontrolü eğitiminde.

Bu yazı işinize yaradı mı?

Ücretsiz kaynakTEKNOFEST İHA yazılım hazırlık kontrol listesiTakımınızın yazılım hazırlığını aşama aşama işaretleyin; yazdırılabilir liste.