Softivation

Drone kendiliğinden DISARM oluyor (Python ARM etmişti)

Python ile ARM ettikten sonra drone kendiliğinden DISARM oluyorsa DISARM_DELAY sayacı dolmuştur. Sayacın işleyişi ve kodu nasıl sıralayacağın bu yazıda.

Furkan IŞIKAY 5 dk okuma

Python kodunu çalıştırıyorsun, ekranda ARM satırını görüyorsun, sonra hiçbir şey olmuyor. Motorlar birkaç saniye rölantide dönüyor ve kendiliğinden susuyor.

Kalkış komutunu gönderdiğinde araç yerde duruyor. İlk bakışta kod hatası gibi görünür ve aynı kodu ikinci kez çalıştırdığında da aynı yerde durursun. Kodun ARM'ı doğru yapmıştır; onu geri alan başka bir şey vardır.

Otopilotun içinde işleyen bir sayaç var

ArduPilot, araç ARM'lı hâlde beklerken bir sayaç işletir. Araç yere temaslı ve gaz kolu düşükken bu sayaç dolarsa otopilot motorları kendisi DISARM eder.

Varsayılan süre 10 saniyedir. Şekildeki kırmızı çizgi ARM'dan sonra GPS beklemeye oturan bir kodun başına geleni gösteriyor: sayaç sınıra varıyor ve DISARM geliyor. Mavi çizgide kalkış komutu hemen gittiği için sayaç sıfırlanıyor.

ARM'dan sonra otopilotun sayacı nasıl dolar

Sayaç ARM anından itibaren saniye saniye dolar; araç yerde, gaz düşükken 10 saniyeye ulaşınca DISARM gelir; kalkış komutu sayacı sıfırlar
Nereye bak: kırmızı çizginin kesikli sınıra değdiği nokta. Mavi çizgide kalkış komutu sayacı sınıra varmadan sıfırlar. Şematik çizim.

Sayaç ne zaman sıfırlanıyor

Karar sırası her döngüde baştan işler. Aşağıdakilerden biri geçerliyse sayaç sıfırlanır ve DISARM gelmez.

  • Motorlar zaten DISARM ise ya da süre parametresi sıfır yazılmışsa
  • Kalkış isteniyorsa, yani motorların hedef durumu rölantinin üstündeyse
  • Gaz kolu düşük değilse ya da araç yere temaslı sayılmıyorsa
  • Uçuş modu THROW ise

Interlock kapalıysa ya da acil durdurma etkinse süre yarıya iner.

Python koduyla uçarken ARM'dan sonra bunların hiçbiri gerçekleşmez. ARM edip GPS beklemeye ya da rota hesaplamaya oturursan araç yerde, gaz kolu sıfırda kalır ve sayaç sonuna kadar işler.

Varsayılan ayarda bu durumda ARM'dan 10 saniye sonra telemetriye Disarming motors satırı düşer. Ardından gönderdiğin kalkış komutu aracı yerden kaldırmaz.

Ne yapman gerekiyor

Çözüm sırayı düzeltmek: hazırlığın tamamı ARM'dan önce biter. ARM ile kalkış komutu arasına hiçbir bekleme girmez.

Python
import time
from pymavlink import mavutil

arac = mavutil.mavlink_connection("tcp:127.0.0.1:5760", source_system=255)
arac.wait_heartbeat(timeout=30)
arac.mav.request_data_stream_send(arac.target_system, arac.target_component,
                                  mavutil.mavlink.MAV_DATA_STREAM_ALL, 10, 1)

# Hazirlik ARM'dan ONCE biter. GPS beklemek ARM'dan sonra yapilirsa sayac isler.
bitis = time.time() + 120
while time.time() < bitis:
    g = arac.recv_match(type="GPS_RAW_INT", blocking=True, timeout=3)
    if g and g.fix_type >= 3 and g.satellites_visible >= 6:
        break
else:
    raise SystemExit("GPS hazir degil")

arac.set_mode_apm("GUIDED")
time.sleep(2)

for deneme in range(5):
    arac.mav.command_long_send(arac.target_system, arac.target_component,
                               mavutil.mavlink.MAV_CMD_COMPONENT_ARM_DISARM,
                               0, 1, 0, 0, 0, 0, 0, 0)
    son = time.time() + 8
    while time.time() < son:
        hb = arac.recv_match(type="HEARTBEAT", blocking=True, timeout=2)
        if hb and (hb.base_mode & mavutil.mavlink.MAV_MODE_FLAG_SAFETY_ARMED):
            break
    else:
        continue
    break
else:
    raise SystemExit("ARM olmadi")

# ARM ile kalkis komutu arasina hicbir is girmez.
arac.mav.command_long_send(arac.target_system, arac.target_component,
                           mavutil.mavlink.MAV_CMD_NAV_TAKEOFF,
                           0, 0, 0, 0, 0, 0, 0, 8.0)

# COMMAND_ACK sonucu teyit etmez; irtifayi izle.
bitis = time.time() + 60
while time.time() < bitis:
    m = arac.recv_match(type=["GLOBAL_POSITION_INT", "HEARTBEAT"],
                        blocking=True, timeout=3)
    if m is None:
        continue
    if m.get_type() == "HEARTBEAT":
        if not (m.base_mode & mavutil.mavlink.MAV_MODE_FLAG_SAFETY_ARMED):
            raise SystemExit("DISARM oldu, kalkis gerceklesmedi")
    elif m.relative_alt / 1000.0 >= 7.6:
        print("irtifa: %.2f m" % (m.relative_alt / 1000.0))
        break

Sayacın süresi DISARM_DELAY parametresinde tutulur, birimi saniyedir. Kaynak koddaki varsayılan değeri 10'dur; kendi kartında başka bir değer yazıyor olabilir, okumadan varsayma.

Uzun bir hazırlık kaçınılmazsa DISARM_DELAY'i büyütebilirsin. Bunun bedeli var: yerde unutulan bir araç daha uzun süre ARM'lı kalır. Süreyi büyütmeden önce hazırlığı öne almayı dene.

Örnek: Kodun önce ARM ediyor, sonra yük bırakma noktasının koordinatını yer istasyonundan girmeni bekliyor. Sen koordinatı yazana kadar araç yerde gaz sıfırda duruyor, 10 saniye dolunca telemetriye Disarming motors düşüyor ve ardından gelen kalkış komutu boşa gidiyor. Koordinat girişini ARM'dan önceye alırsan kalkış komutu ARM'ın hemen ardından gider ve sayaç hiç dolmaz.

Hata Mesajları ve Anlamları

Disarming motors

Otopilot DISARM ettiğinde bastığı satır. Tek başına arıza anlamına gelmez. ARM'dan sonra sen istemeden geldiyse sayacın dolduğunu gösterir.

PreArm: Motor Interlock Enabled

Bu başka bir durum. Araç henüz ARM olmamıştır, interlock kanalı açık konumdayken otopilot ARM izni vermez. Sayaçla ilgisi yoktur.

PreArm: Safety Switch

Kart üstündeki güvenlik butonuna basılmamış. Yine ARM öncesi bir engeldir; bu mesajı görüyorsan araç zaten hiç ARM olmamıştır.

Sahada ne değişir

Sayacın kendisi firmware içindedir. Kumandan bağlıysa gaz kolunun konumu sayacı sıfırlayabilir ve arıza hiç görünmeyebilir. Kumandasız otonom kurulumlarda böyle bir kurtarıcı yoktur.

Devamını nerede bulursun

Karar zincirinin firmware içindeki tam sırası, log imzaları ve gövde tipine göre değişen davranış Python ile Sıfırdan İHA Kontrolü eğitimi içinde işleniyor.

Bu yazı işinize yaradı mı?

Ücretsiz kaynakPixhawk ve ArduPilot hata mesajları sözlüğüBu yazıdaki 2 mesaj ve benzerleri sözlükte: ne demek, neden çıkar, ilk neye bakılır.