C# yer kontrol istasyonunda parametre eksik geliyor

C# ile yazdığın yer kontrol istasyonu ArduPilot'a bağlanıyor, telemetri akıyor ama parametre listesi her seferinde eksik geliyor. Bazen 1200 parametre bekliyorsun, ekrana 1150 civarı düşüyor ve hangi 50 tanesinin gitmediğini bilmiyorsun.
Bu, ArduPilot'un parametreleri gönderme biçiminden kaynaklanıyor: liste bir kere akıtılıyor, kaybolan otomatik olarak tekrar gelmiyor.
Neden oluyor
GCS bağlandığında PARAM_REQUEST_LIST mesajını gönderir. ArduPilot buna karşılık, elindeki her parametreyi index 0'dan başlayarak tek tek PARAM_VALUE mesajı olarak yollar. Her mesajda parametrenin kendi index'i ve toplam parametre sayısı (param_count) taşınır.
Bu akış, hattın tahmini bant genişliğine göre kısılır. Bağlantıda donanımsal akış kontrolü (RTS/CTS) yoksa ArduPilot bir turda en fazla 5 PARAM_VALUE gönderir. Kaynak koddaki yorum satırı gerekçeyi açıklıyor: akış kontrolü olmadan daha hızlı gönderim hattı tıkıyor. Bu davranış resmi dokümanda geçmiyor; yalnızca kaynak kodda var.
Resmi ArduPilot dokümanı da MAVLink'in teslimat garantisi vermediğini, bu yüzden GCS'in eksik parametreleri kendisinin fark edip yeniden istemesi gerektiğini söylüyor. Ama akışı neyin yavaşlattığını ve tur başına kaç mesaj gittiğini yalnızca kaynak kodda görebiliyorsun.
Bağlantı tipi neden fark yaratıyor
Pixhawk'ı bilgisayara USB ile bağladığında ArduPilot, o kanalda akış kontrolünü var sayar (hal.gpio->usb_connected() true dönünce). Bu yüzden USB üzerinden indirilen parametre listesi pratikte tek seferde ve hızlı tamamlanır.
Raspberry Pi ya da başka bir yardımcı bilgisayarı TELEM portuna sade bir UART (yalnızca TX, RX, GND) ile bağladığında akış kontrolü yok sayılır. Düşük baud hızında, uzun parametre listesinde bu, gerçek paket kaybı ihtimalini artırır. SITL üzerinden TCP ile test edersen bu farkı göremezsin, çünkü TCP zaten güvenilir teslimat yapar.
En sık yapılan hata: GCS'in 'akış durdu' anını 'liste tamamlandı' sanması. Kısa bir sessizlik penceresinden sonra dinlemeyi kesen bir okuyucu, gerçekte kaybolmuş parametreleri hiç fark etmez.
Çözüm
Gelen her PARAM_VALUE'nun index'ini bir kümede topla. Akış durduğunda, 0 ile param_count-1 arasında kümede olmayan index'leri çıkar ve yalnızca onlar için PARAM_REQUEST_READ gönder. ArduPilot tek bir index istendiğinde yalnızca o parametreyi geri döndürür.
public class ParamListTracker
{
private readonly HashSet<ushort> _received = new();
private ushort _paramCount;
public void OnParamValue(ushort paramIndex, ushort paramCount)
{
_paramCount = paramCount;
_received.Add(paramIndex);
}
public IReadOnlyList<ushort> FindMissingIndexes()
{
var missing = new List<ushort>();
for (ushort i = 0; i < _paramCount; i++)
{
if (!_received.Contains(i)) missing.Add(i);
}
return missing;
}
public bool IsComplete() => _paramCount > 0 && _received.Count == _paramCount;
}
Doğrulama
Bu kodu, 4 parametrenin (37, 812, 813, 1200) kasıtlı olarak düşürüldüğü 1369 parametrelik simüle bir akışla bugün çalıştırdık. Aşağıdaki çıktı gerçek çalıştırma sonucudur, uydurulmuş sayı yoktur.
received=1365 / paramCount=1369
complete=False
missingCount=4
missingIndexes=37,812,813,1200
-> PARAM_REQUEST_READ gonderiliyor: param_index=37
-> PARAM_REQUEST_READ gonderiliyor: param_index=812
-> PARAM_REQUEST_READ gonderiliyor: param_index=813
-> PARAM_REQUEST_READ gonderiliyor: param_index=1200
tamamlandiktan sonra complete=True
Bu konuyu daha derinden görmek istersen
Kaynak kodun karar sırasını, gerçek parametre varsayılanlarını, kart bazlı farkları ve hızlı teşhis kartını Sıfırdan İleri Seviyeye C# eğitiminin ilgili dersinde bulabilirsin.
İNDİRİM KUPONU
Kupon kodu: SOFTIVATION15
Eğitimi alırken ödeme ekranındaki "Kupon kodu" kutusuna bu kodu yaz, %15 iner.




Yorumlar