İHA AUTO modda ilk waypoint'e gitmiyor
Mission Planner'dan görev yüklendi görünüyor ama İHA AUTO modda ilk waypoint'e gitmiyor. Yüklemenin neden sessizce boşta kaldığını ve çözümünü anlatıyoruz.
Görevi Python koduyla yükledin. Otopilot onay verdi, kod hatasız bitti.
Sonra AUTO'ya alıyorsun ve araç hiçbir yere gitmiyor. Ya da daha kötüsü: bir önceki uçuşun görevini uçuruyor.
Çoğu zaman sebep, kodun yanlış onaya güvenmesidir. Görev yükleme el sıkışmasını adım adım kuralım ve bu tuzağı nasıl yakalayacağını görelim.
Gelen onay hangi komuta ait
Çoğu örnek kodda akış şöyledir: eski görevi sil, otopilota kaç öğe geleceğini söyle, sonra gelen ilk onayı yakala.
Eski görevi silme komutunun da kendi onayı vardır. Onu okumazsan döngün, otopilot daha tek bir waypoint istemeden o onayı görür, "kabul edildi" okur ve "yüklendi" diye çıkar.
Şekildeki sarı şeride bak: ilk onay silme komutuna aittir. Yüklemenin onayı ancak otopilot her öğeyi tek tek istedikten sonra gelir. Yüklemenin kanıtı da bu isteklerdir; hiç istek gelmeden düşen onay bir önceki komuta aittir.
Görev yüklemede iki ayrı onay gelir
Kodu önce SITL'de dene
Kodu karta bağlamadan önce bilgisayarında SITL ile deneyebilirsin. Aşağıdaki komutlar ArduCopter SITL'i indirip Şanlıurfa koordinatlarında başlatır.
Ayrı bir terminalde açık bırak; Python kodu buna TCP 5760'tan bağlanacak.
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
./arducopter -S -I0 --model + --speedup 5 --defaults copter.parm --sysid 1 --home 37.1591,38.7969,500,0Doğru kod
Aşağıdaki kod üç şeyi doğru yapar: CLEAR_ALL'in ACK'ini tüketir, MISSION_REQUEST ve MISSION_REQUEST_INT'in ikisini de dinler, sonunda istenen seq sayısını kontrol eder.
import time
from pymavlink import mavutil
WPS = [(37.1600, 38.7969, 20.0), (37.1600, 38.7980, 20.0), (37.1591, 38.7980, 20.0)]
m = mavutil.mavlink_connection('tcp:127.0.0.1:5760')
m.wait_heartbeat()
m.mav.request_data_stream_send(m.target_system, m.target_component,
mavutil.mavlink.MAV_DATA_STREAM_ALL, 4, 1)
# Eski gorevi sil VE CLEAR_ALL'in kendi ACK'ini tuket.
m.mav.mission_clear_all_send(m.target_system, m.target_component)
m.recv_match(type='MISSION_ACK', blocking=True, timeout=5)
def item(seq):
lat, lon, alt = (WPS[0][0], WPS[0][1], 0.0) if seq == 0 else WPS[seq - 1]
return m.mav.mission_item_int_encode(
m.target_system, m.target_component, seq,
mavutil.mavlink.MAV_FRAME_GLOBAL_RELATIVE_ALT,
mavutil.mavlink.MAV_CMD_NAV_WAYPOINT,
0, 1, 0, 3, 0, 0,
int(lat * 1e7), int(lon * 1e7), alt, 0)
# seq 0 HOME'dur: len(WPS) + 1 gonderilir.
m.mav.mission_count_send(m.target_system, m.target_component, len(WPS) + 1, 0)
ack, served = None, []
t0 = time.time()
while time.time() - t0 < 40:
msg = m.recv_match(type=['MISSION_REQUEST', 'MISSION_REQUEST_INT', 'MISSION_ACK'],
blocking=True, timeout=5)
if msg is None:
continue
if msg.get_type() == 'MISSION_ACK':
ack = msg
break
served.append(msg.seq)
m.mav.send(item(msg.seq))
print("Istenen seq listesi :", served)
print("MISSION_ACK type :", ack.type if ack else None)
assert ack is not None and ack.type == 0, "ACK gelmedi ya da reddedildi"
assert len(served) == len(WPS) + 1, "Otopilot her item'i istemedi -> gorev eksik!"
print("SONUC: gorev yuklendi ve el sikismasi teyit edildi.")Doğru çalışınca ne görürsün
Kodu çalıştırdığında şunu görürsün:
Istenen seq listesi : [0, 1, 2, 3]
MISSION_ACK type : 0
SONUC: gorev yuklendi ve el sikismasi teyit edildi.3 waypoint göndermene rağmen istenen seq listesi 4 eleman, çünkü seq 0 HOME'dur ve sayıma dahildir. Bunu atlarsan son waypoint'in sessizce kaybolur.
Silme onayını okumazsan ne görürsün
CLEAR_ALL'in onayını tüketmeyen, ilk MISSION_ACK'i yakalayıp çıkan bir kod şuna benzer bir çıktı verir:
HEARTBEAT sys=1 comp=0
GPS OK fix=6 sat=10
ACK: MISSION_ACK {target_system : 255, target_component : 0, type : 0, mission_type : 0}
UPLOAD OK, servis edilen seq: []
Traceback (most recent call last):
File "mission_test.py", line 78, in <module>
print("READBACK count =", cnt.count)
AttributeError: 'NoneType' object has no attribute 'count'Servis edilen seq listesi BOŞ. Otopilot hiçbir item istemedi, ama ekranda type=0 bir ACK var. Kod "başarılı" dedi, araçta görev yok.
Yani MISSION_ACK tek başına yüklemenin kanıtı değildir. Kanıt, otopilotun her seq için MISSION_REQUEST göndermiş olmasıdır.
Örnek: Yük bırakma görevinde bırakma noktasını son dakikada değiştirip yeni rotayı sahada yüklüyorsun. Kod ilk onayı görüp "yüklendi" derse, AUTO'ya aldığında drone yerinden kıpırdamaz, çünkü araçta görev yoktur. Kodun ekrana bastığı istenen seq listesine bakmak bunu daha AUTO'ya geçmeden yakalar: liste boşsa yeni görev araçta değildir.
Yarışma koşullarında bu kod yetmez
Savaşan İHA sahasında bu minimal kodun açıkta bıraktığı noktalar var:
- Geri okuma yok: Otopilot ACK verdi diye koordinatlar doğru yazıldı demek değil. MISSION_REQUEST_LIST ile geri okuyup metre cinsinden karşılaştırmak gerekir.
- AUTO'da varış teyidi yok: Görev yüklenmesi ile görevin uçulması ayrı şeyler. MISSION_ITEM_REACHED dinlenmeden "waypoint'e gitti" denemez.
- Telemetri kaybı senaryosu yok: Gerçek linkte MISSION_REQUEST paketi düşerse otopilot tekrar ister; kodun bunu yeniden gönderecek şekilde kurgulanmış olmalı.
- Kart bazlı seri port farkları: Pixhawk TELEM2, Cube ve Matek kartlarında SERIALx_PROTOCOL ve baud ayarları farklıdır; yanlış ayarda hiç MISSION_REQUEST gelmez.
Hata Mesajları
İlk iki satır doğru koddaki kontrollerden, üçüncüsü tuzağa düşen kodun çıktısından gelir. Hangisini gördüğün, yüklemenin nerede kaldığını söyler.
AssertionError: Otopilot her item'i istemedi -> gorev eksik!
Doğru koddaki ikinci kontrol tuttu: onay geldi ama istenen seq sayısı waypoint sayısı + 1 değil. Görev araçta eksik ya da hiç yok; istenen seq listesine bak.
AssertionError: ACK gelmedi ya da reddedildi
Doğru koddaki ilk kontrol tuttu: 40 saniye içinde onay gelmedi ya da onayın type değeri 0 değil. Bağlantıyı ve gönderilen öğeleri kontrol et.
AttributeError: 'NoneType' object has no attribute 'count'
Tuzağa düşen kodun çıktısında boş seq listesinin hemen ardından gelir. Geri okuma isteğine yanıt gelmedi ve kod boş yanıtın count alanını okumaya çalıştı; araçta görev yok.
Bu yazıyı okuyanlara
Görev yükleme, geri okuma, AUTO'da varış teyidi ve kart bazlı seri port ayarlarının tamamı Python ile Sıfırdan İHA Kontrolü Eğitimi içinde adım adım 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