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.
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
Ö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
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:
$ 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.
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,0SITL'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ı?
Bu konuyu baştan sona öğrenin
Sezon: altı eğitimin hepsi 9 ay, ayda ₺790. Lise ve üniversite öğrencisine ayda ₺390, üye kodunuzla ilk ay ₺351. İstediğiniz ay bırakırsınız. Sezon'a başlayın · Öğrenciyim