Softivation

Telemetri gelmiyor, önce mesaj aralığına bak

pymavlink ile bağlandın ama konum verisi gelmiyor. ArduPilot sen istemeden çoğu mesajı yayınlamaz. Mesaj aralığını isteyip hızı doğru ölçmeyi anlatıyoruz.

Furkan IŞIKAY 6 dk okuma

Python ile drone'a bağlanıyorsun, bağlantı sinyali geliyor, konum mesajını bekleyen satır ise sonsuza kadar bekliyor. Kabloyu değiştiriyorsun, baud'u kurcalıyorsun, firmware'i yeniden yüklüyorsun.

Hiçbiri sorunu çözmüyor, çünkü sorun orada değil: ArduPilot, sen açıkça istemeden çoğu MAVLink mesajını yayınlamaz.

Savaşan İHA'da bunun bedeli ağır. 20 m/s uçan bir rakibi 1 Hz konum verisiyle takip edemezsin: iki örnek arasında 20 metre yol gider, kilitlenme algoritman havayı kovalar.

Konum verisi yavaş değil, hiç akmıyor

İstemediğin mesaj sıfır hızla akar, yani hiç gelmez. Hangi mesajı hangi hızla istediğini otopilota bir komutla söylersin, otopilot da kabul ettiğini bir cevapla bildirir.

Kabul cevabı mesajın istediğin hızda aktığı anlamına gelmez, yalnızca komutun kabul edildiğini söyler. Hızı kendin ölçmen gerekir.

İstediğin hız mikrosaniye olarak yazılır

MAV_CMD_SET_MESSAGE_INTERVAL komutunun param2 alanı aralık, yani mikrosaniyedir. 10 Hz istiyorsan 1000000/10 = 100000 yazmalısın. Buraya 10 yazarsan 10 mikrosaniyelik aralık, yani 100.000 Hz istemiş olursun. Özel değerler: 0 varsayılana döner, -1 mesajı tamamen kapatır.

Ölçümün sana yanlış sayı verebilir

İstekle ölçüm arasına time.sleep(1) koyup kuyruğu boşaltmadan sayarsan, 10 Hz istediğin hâlde 12.2 Hz okursun. Bekleme boyunca soket kuyruğunda yaklaşık 10 mesaj birikir.

Ölçüm penceresi açılır açılmaz bu birikmiş yığın anında sayılır ve 5 saniyede 50 yerine 60 mesaj çıkar. Şekilde ortadaki şeridin başındaki kırmızı yığına bak.

İstekten sonra ölçüm penceresinde ne sayılıyor

İstek öncesi mesaj akmıyor; istekten sonra araç 10 Hz yollar. sleep(1) sırasında biriken yaklaşık 10 mesaj kuyruk boşaltılmazsa ölçüm penceresinin başında tek seferde sayılır ve 5 saniyede 60 mesaj, 12.2 Hz görünür; kuyruk boşaltılınca 50 mesaj, 10.0 Hz okunur.
Nereye bak: ortadaki şeridin başındaki kırmızı yığın. sleep(1) sırasında birikenler pencere açılır açılmaz sayılıyor; alttaki şeritte boşaltma onları pencereden önce atıyor.

Ölçmeden önce kuyruğu boşaltmazsan aldığın sayı gerçek frekans değildir. Aşağıdaki koddaki kuyrugu_bosalt() fonksiyonu bu işi yapar.

Mesajı açan ve hızını ölçen kod

Python
import time
from pymavlink import mavutil

arac = mavutil.mavlink_connection('tcp:127.0.0.1:5760')
arac.wait_heartbeat()

MSG_ID = mavutil.mavlink.MAVLINK_MSG_ID_GLOBAL_POSITION_INT

def kuyrugu_bosalt(arac, sure=0.5):
    """Olcumden ONCE cagir. Birikmis mesajlar frekansi sisirir."""
    bitis = time.time() + sure
    while time.time() < bitis:
        arac.recv_match(blocking=False)

def olc(arac, ad, sure=5.0):
    bitis = time.time() + sure
    n = 0
    while time.time() < bitis:
        if arac.recv_match(type=ad, blocking=True, timeout=0.5):
            n += 1
    return n / sure

# 1) Istemeden once: bu mesaj varsayilan olarak AKMIYOR
kuyrugu_bosalt(arac)
print(f"Once : {olc(arac, 'GLOBAL_POSITION_INT'):.1f} Hz")

# 2) 10 Hz iste - aralik MIKROSANIYE
arac.mav.command_long_send(
    arac.target_system, arac.target_component,
    mavutil.mavlink.MAV_CMD_SET_MESSAGE_INTERVAL,
    0, MSG_ID, int(1_000_000 / 10), 0, 0, 0, 0, 0)

ack = arac.recv_match(type='COMMAND_ACK', blocking=True, timeout=3)
print(f"ACK  : result={ack.result}  (0 = ACCEPTED)")

# 3) ACK'e degil olcume guven - ve olcmeden once kuyrugu bosalt
time.sleep(1)
kuyrugu_bosalt(arac)
print(f"Sonra: {olc(arac, 'GLOBAL_POSITION_INT'):.1f} Hz")

Kodu ArduCopter V4.7.0'a karşı çalıştırırsan şu çıktıyı alırsın:

Kod
$ python3 telemetri_hizi.py
Once : 0.0 Hz
ACK  : result=0  (0 = ACCEPTED)
Sonra: 10.0 Hz

İlk satıra dikkat: 0.0 Hz. Mesaj yavaşlamış değil, hiç akmıyor. İstekten sonra hız hedefe oturuyor.

Örnek: Savaşan İHA'da rakibi takip eden kodun hedefe kilitlenemiyorsa, kabloyu ve baud'u kurcalamadan önce takip kodunu kapat ve otopilotu yeniden başlatmadan bu kodu aynı hattan çalıştır. Once satırında 0.0 Hz görürsen takip kodun konum mesajını hiç istememiş demektir; Sonra satırında 10.0 Hz görüyorsan hat ve otopilot ayarı yerindedir, sorunu takip kodunun kendi içinde ararsın.

Elinde kart yoksa SITL'de dene

Kodu kart olmadan denemek istersen SITL'i birkaç komutla kurabilirsin.

Bash
mkdir -p ~/sitl && cd ~/sitl
curl -sL -o arducopter \
  https://firmware.ardupilot.org/Copter/stable/SITL_x86_64_linux_gnu/arducopter
chmod +x arducopter
curl -sL -o copter.parm \
  https://raw.githubusercontent.com/ArduPilot/ardupilot/master/Tools/autotest/default_params/copter.parm
pip install pymavlink

# --speedup 1 sart: hizlandirilmis simulasyonda olctugun Hz sim-zamani olur
./arducopter -S -I0 --model + --speedup 1 --defaults copter.parm \
  --sysid 1 --home 37.1591,38.7969,500,0

SITL'i --speedup 5 ile çalıştırırsan aralık simülasyon zamanına göre işler; 10 Hz isteyip duvar saatinde 60 Hz ölçersin. Frekans ölçerken --speedup 1 kullan.

Hata Mesajları ve Anlamları

Bu sorun bir hata satırı basmaz; konum mesajını bekleyen recv_match sessizce bekler. Kodun çıktısındaki iki satır ise ilk bakışta yanlış okunur.

Once : 0.0 Hz satırı, istek yollanmadan önceki ölçümdür. GLOBAL_POSITION_INT varsayılan olarak akmadığı için sayaç sıfır kalır.

ACK : result=0 satırı otopilotun komutu kabul ettiğini söyler, mesajın istediğin hızda aktığını değil. Hızı kuyruğu boşalttıktan sonra kendin ölç.

AttributeError: 'NoneType' object has no attribute 'result'

Komuttan sonra 3 saniye içinde COMMAND_ACK gelmedi; recv_match None döndürdü ve kod onun result alanını okumaya çalıştı. Komut otopilota ulaşmamış ya da cevabı gelmemiş demektir; bağlantıyı kontrol edip yeniden dene.

Yarışma kodunda eksik kalanlar

Bu yazıdaki kod tek bir mesajı açar ve ölçer. Yarışma gününde eksik kalan kısımlar şunlar:

  • Hangi mesajı hangi frekansta isteyeceğine karar vermek. SiK telemetri 57600 baud'da 50 Hz'i taşımaz, link doyar ve komutların gitmez.
  • Pixhawk, Cube Orange ve Matek kartlarında UART ve DMA farkları.
  • ACK'in DENIED veya FAILED döndüğü durumların teşhisi.
  • ArduPilot ayarı kanal bazında tuttuğu için kod yeniden başladığında eski hızın devam etmesi.

Bunların tam çözümü, kart bazlı pinout tablosu ve yarışma seviyesi kod ile İHA Haberleşme Teknolojileri eğitiminde işleniyor.

Yapay Zeka ve İHA Simülasyon Sanal Makinesi: ArduPilot SITL, ROS Noetic ve Gazebo 11 kurulu gelir; simülasyonu kurulumla uğraşmadan başlat.

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.