Python'da Pixhawk irtifası yanlış (Mission Planner doğru)
Python'da Pixhawk irtifası yanlış mı geliyor? GLOBAL_POSITION_INT içindeki alt deniz seviyesini verir; Mission Planner'daki irtifa için relative_alt oku.
Mission Planner drone'u 10 metrede gösteriyor. Raspberry Pi'deki Python kodun aynı anda 510 diyor; bölmeyi unuttuysan 510080. Drone daha yerdeyken bile kodun "10 metreye çıktım" deyip sıradaki adıma geçiyor.
Aynı pakette iki ayrı irtifa var ve kodun, Mission Planner'ın göstermediğini okuyor.
Kod drone yerdeyken kamerayı açıyor
Savaşan İHA görevinde sık kurulan bir koşul düşün: drone kalkışta 10 metreyi geçince kamera kaydı başlasın. Kod konum paketini okur, irtifayı 1000'e bölüp metreye çevirir, sonuç 10'dan büyükse kamerayı açar.
Sahanın rakımı 500 metreyse bu koşul drone yerdeyken de doğrudur, çünkü 500 zaten 10'dan büyük. Pervaneler dönmeden kayıt başlar ve kod kalkışı beklemeden görevin sonraki adımına geçer.
Aynı pakette iki irtifa var
ArduPilot konumu GLOBAL_POSITION_INT paketinde yollar. Paketin iki irtifa alanı var ve ikisi de milimetre:
- alt deniz seviyesinden ölçer. Rakımı 500 metre olan sahada drone yerdeyken 500080 civarı okursun.
- relative_alt kalkış noktasından (home) ölçer. Mission Planner'ın ekranda gösterdiği irtifa budur.
Şekilde üç okun da aynı drone'da bittiğine, ama farklı çizgiden başladığına bak. Kırmızı ok sahanın rakımını da içinde taşır; mavi ok yalnızca kalkıştan bu yana tırmanılan yüksekliği.
Aynı drone, üç sıfır noktası
Kesikli ok üçüncü bir kaynaktır: LOCAL_POSITION_NED paketindeki z. Bu eksen aşağıyı pozitif sayar, bu yüzden drone 10 metre yukarıdayken −9.98 gibi eksi bir değer okursun. VFR_HUD paketindeki irtifa da varsayılan ayarda deniz seviyesinden ölçer.
Sık yapılan hata
alt alanını 1000'e bölmek sorunu çözmez. Birim metreye döner ama sıfır noktası hâlâ deniz seviyesidir; kod 10 yerine sahanın rakımı artı 10'u görür ve 510 okur.
Çözüm: kalkış noktasına göre oku
Koşulu home noktasına göre kur. Aşağıdaki kod iki alanı yan yana basar, böylece hangisinin Mission Planner'la eşleştiğini kendi ekranında görürsün:
from pymavlink import mavutil
# Pixhawk'a hangi adresten bağlanıyorsan onu yaz (seri port, UDP ya da TCP)
baglanti = mavutil.mavlink_connection('tcp:127.0.0.1:5760')
baglanti.wait_heartbeat()
baglanti.mav.request_data_stream_send(baglanti.target_system, baglanti.target_component,
mavutil.mavlink.MAV_DATA_STREAM_POSITION, 5, 1)
for _ in range(3):
m = baglanti.recv_match(type='GLOBAL_POSITION_INT', blocking=True)
deniz = m.alt / 1000 # mm -> m, deniz seviyesine göre
kalkis = m.relative_alt / 1000 # mm -> m, kalkış noktasına (home) göre
print(f"deniz seviyesi: {deniz:.2f} m | kalkış noktasına göre: {kalkis:.2f} m")Gir: kamera koşulunda m.relative_alt / 1000 kullan. Gör: drone yerdeyken sıfıra yakın bir değer, havadayken Mission Planner'daki irtifayla aynı sayı. Değilse: home noktasının nerede yazıldığına bak (aşağıda).
Ne göreceksin
Drone yerdeyken kodu çalıştırırsan şunu görürsün:
deniz seviyesi: 500.08 m | kalkış noktasına göre: 0.01 m
deniz seviyesi: 500.08 m | kalkış noktasına göre: 0.01 m
deniz seviyesi: 500.08 m | kalkış noktasına göre: 0.01 mDrone 10 metreye çıktıktan sonra aynı kodu çalıştırırsan şunu görürsün:
deniz seviyesi: 510.08 m | kalkış noktasına göre: 10.00 m
deniz seviyesi: 510.08 m | kalkış noktasına göre: 10.00 m
deniz seviyesi: 510.08 m | kalkış noktasına göre: 10.00 mÇıktıdaki 500 metre sahanın rakımıdır. Kendi sahanda ilk sütun oranın rakımıyla başlar, ikinci sütun ise her sahada sıfırdan başlar.
Home noktası ARM anında yazılır
relative_alt'ın sıfırı home noktasıdır. ArduCopter home noktası kilitli değilse onu her ARM'da drone'un o anki konumuna yeniden yazar (AP_Arming_Copter.cpp). Bu yüzden ARM'dan önce okuduğun değer sıfırdan kayabilir; kalkış koşulunu ARM'dan sonra okuduğun değere göre kur.
Hata Mesajları ve Anlamları
AttributeError: 'NoneType' object has no attribute 'relative_alt'
recv_match zaman aşımına düştü ve paket yerine None döndü. Konum akışını istemeden okuyorsan paket hiç gelmez; koddaki request_data_stream_send satırının yerinde olduğuna ve dönen değerin None olup olmadığına bak.
Field Elevation Set: 500m
Otopilot sahanın rakımını bu sayıya kurdu. BARO_FIELD_ELV = 0 (varsayılan) iken sayı EKF orijininin yüksekliğidir ve alt alanı bu rakımın üstüne biner. Senin sahanda sayı o sahanın rakımı olur.
PreArm: Baro: GPS alt error
GPS'in verdiği deniz seviyesi irtifası ile barometrenin hesapladığı irtifa arasında BARO_ALTERR_MAX'tan (varsayılan 2000 m) büyük fark var. Mesajın devamında farkın metre cinsinden değeri yazar; ARM izni gelmez.
Python'dan uçuşu adım adım kur
Bağlanma, öznitelik dinleyicileri, GUIDED komutları ve görev yükleme sırasıyla Python ile Sıfırdan İHA Kontrolü eğitiminde. Kurs derslerinde irtifa kaynaklarının hangisinin ne zaman sıfırlandığını ve log'da nasıl ayırt edildiğini de bulursun.
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