Olmayan Bağlantı İçin Tasarlamak: Otonom Bir Survey Filosunda Offline-First Koordinasyon
C.E.O. Bee Mühendislik11 dk okuma
Operatörün hava araçları her görevin kabaca üçte birini yer istasyonuyla bağlantı olmadan geçiriyor — ve kaybedilmemesi gereken olaylar çoğunlukla tam o pencerede oluyor. Bağlantı bozulduğunda çözünürlük düşsün ama güvenlik verisi asla düşmesin diye kurduğumuz CRDT ve gecikmeye toleranslı ağ mimarisi.
1.900 metrede, yüksek gerilim hattı koridorunda dik yamaçlı bir vadinin içinde, operatörün VTOL platformlarından biri ihtiyati iniş kararını tetikleyecek ciddiyette bir hücre dengesizliği arızası kaydetti. Yer istasyonu bunu otuz sekiz dakika sonra, kardeş bir hava aracı sırtı aşıp LTE'yi yeniden yakaladığında öğrendi.
Bu, iyi senaryoydu.
Kötüsü, bizi bu projeye getiren olaydı. Daha önceki bir uçuşta aynı sınıftan bir olay yer istasyonuna hiç ulaşmadı. Olay sabit boyutlu bir replikasyon tamponuna yazılmıştı ve o tampon, sabit boyutlu tamponların yaptığı şeyi yaptı: FIFO sırasıyla tahliye etti, batarya-kritik bir uyarı da yüzlerce megabaytlık tamamen sıradan pozisyon örneğinin arkasında silindi. Kimse hata yazmamıştı. Sistem tam olarak tasarlandığı gibi çalışmıştı ve insanın aklından çıkmayan kısım da bu zaten.
Müşteri dağlık arazide koridor survey uçuşları yapıyor: iletim hatları ve boru hattı güzergâhları. Filoda kırkın biraz üzerinde hava aracı var, tipik olarak on sekiz–yirmi dördü aynı anda ve birbirinden bağımsız görevlerde havada. Görevler 60–90 dakika, koridor bacakları 20–140 km. Ve tipik bir uçuşun kabaca üçte birinde eve doğru kullanılabilir bir link yok: vadilerde arazi gölgelemesi, bacağın sonunda düpedüz mesafe, bir de kontrollü hava sahası yakınında operatörün sözleşme gereği sessize geçtiği koordineli radyo sessizliği pencereleri.
İlk gün beyaz tahtaya tek bir cümle yazdık ve oradan hiç şaşmadık: bu platformda kesintili bağlantı bir arıza modu değil, işletim koşulunun kendisi. "Link var"ı normal, "link yok"u istisna sayan her tasarım, her uçuşun üçte birinde yanlıştır.
Birinci bölüm: saatin yalan söylediği yerde sıralama
Savunulabilir bir "önce" tanımınız yoksa mutabakatın hiçbir anlamı yok, duvar saati de bu tanım değil. Her hava aracı TCXO'sunu GNSS PPS'e disipline ediyor ve bu, GNSS'in kendisi bozulana kadar kusursuz işliyor. Kanyon çokyolluluğu, kötü uydu geometrisi (HDOP > 4'ü güvenilmez sayıyoruz), bilinçli bir denial tatbikatı; bu noktadan sonra araç osilatörle serbest koşuyor. Gerçek bir görevin termal profilinde, yani pistte +31 °C ile irtifada −8 °C arasında, üç saatlik bir serbest koşma diliminde ~90 ms'ye varan birikmiş hata ölçtük.
Doksan milisaniye zararsız duruyor. Şimdi şunu düşünün: iki hava aracı bir çatışma çözüm manevrası sırasında ilişkili olayları 200 ms arayla kaydediyor ve yer istasyonundaki birleşik zaman çizelgesinin bir emniyet incelemesine hangisinin önce olduğunu açıklaması gerekiyor. O incelemelerin birinde oturdum; orada "büyük ihtimalle" diye başlayan bir cümleyi kuran kişi olmak istemezsiniz.
Bu yüzden olay kütüğünü hybrid logical clock'lara taşıdık: 48 bit fiziksel milisaniye artı 16 bit mantıksal sayaç. Lamport nedenselliğini bozmadan koruyor, bir yandan da olay inceleme araçlarında bir insanın okuyabileceği kadar duvar saatine yakın kalıyor. Ama asıl işi yapan kısım sınırın kendisi. HLC varsayılan bir maksimum sapmayla çalışıyor; ε_max'i 2 sn belirledik ve bunu aşan her gelen damgayı sessizce yutmak yerine saat anomalisi olarak karantinaya alıp yüzeye çıkarıyoruz. Osilatörü bozulmuş tek bir araç, bütün filonun mantıksal zamanını peşinden sürükleyebilmemeli. Bunun yanında her replika kompakt bir version vector taşıyor; senkron eşi böylece her şeyi baştan göndermek yerine gerçekte neyi eksik olduğunu hesaplayabiliyor.
İkinci bölüm: yalnızca ekleyebilen birleştirme
Olay kütüğü bir delta-state CRDT: nedensel etiketli, yalnızca büyüyen bir küme. Her olay bir (node_id, seq) "dot"u taşıyor, merge ise nedensel bağlama karşı küme birleşimi. Güvenlik sınıflı olaylar yalnızca burada yaşıyor: batarya ve termal arızalar, çarpışma önleme devreye girmesi, geofence ihlali, GNSS bütünlük kaybı, otonomi fallback geçişleri, görev iptali. İki replikanın bir güvenlik olayı hakkında ayrıştığı ve sonucun birinin lehine çözüldüğü tek bir kod yolu bile yok.
Değişebilir operasyonel durum apayrı bir mesele. Güncel waypoint ataması ve görev fazı gerçekten LWW biçiminde duruyor, yine de LWW kullanmadık: eşzamanlı yazımlar multi-value register içinde bir çakışma kümesi olarak hayatta kalıyor ve operatör konsoluna çıkıyor. LWW yalnızca kozmetik, türetilmiş alanlarda serbest, başka hiçbir yerde değil.
def merge(local, remote):
for e in remote.events:
if e.dot in local.causal_ctx: # görüldü ya da GC edildi
continue
if not hlc_within_skew(e.hlc, local.hlc, EPS_MAX):
local.quarantine(e) # bozuk saat: sakla, sıralama
continue
local.insert(e) # G-Set: sadece ekle, asla değiştirme
local.causal_ctx.add(e.dot)
for key, r in remote.registers.items():
assert r.klass is not EventClass.SAFETY # hem ingest'te hem burada zorunlu
local.registers[key] = mv_register_merge(local.registers[key], r)
local.hlc = hlc_max(local.hlc, remote.hlc)
return local
Anti-entropi turunun saniyelerle ölçülen bir temas penceresine sığması gerekiyor, dolayısıyla kütüğü olduğu gibi göndermek hiçbir zaman masada değildi. (node_id, seq) anahtarlı bir Merkle prefix ağacı üzerinden aralık parmak izleri değiş tokuş edip yalnızca uyuşmayan alt ağaçlara iniyoruz. 90 dakikalık bir ayrışmayı kapatmak tipik olarak üç-dört gidiş-dönüş ve yaklaşık 12 KB tutuyor.
Bir alan merge tarafından üzerine yazılabiliyorsa bir gün üzerine yazılır, üstelik bunun için en kötü anı seçer. O yüzden güvenlik verisine register vermiyoruz. Küme veriyoruz.
Üçüncü bölüm: neyi unutacağına karar vermek
512 MB. Replikasyon kütüğünün sınırı bu ve sınırın depolamayla hiçbir ilgisi yok, araçta fazlasıyla yer var. Mesele taşınabilirlik: kütük, iki araç yan yana geçerken 2,4 GHz mesh link üzerinden tam mutabakat yapılabilecek kadar küçük kalmak zorunda. Gönderemediğiniz bir kütük replike edilmiş bir kütük değil, olsa olsa bir günlüktür.
Yani tahliye kaçınılmaz. Orijinal FIFO halkasının sorunu küçük olması değildi — biçimi yanlıştı. Katmanladık:
Tier 0, güvenlik sınıflı olaylar. Asla tahliye edilmiyor, nokta. Bu garantinin güvenli olabilmesinin tek nedeni tier 0'ın kaynakta olay birleştirmeyle sınırlanması: tekrar eden bir arıza, oluşum sayısıyla ilk/son HLC taşıyan tek bir olaya çöküyor, böylece salınan bir sensör düşürülmesi yasak olan sınıfı taşıramıyor. Kaynak tarafına sınır koymadan "asla tahliye etme" demek, kendi elinizle yazdığınız bir servis dışı bırakma açığıdır.
Tier 1, durum geçişleri, görev tahsis sonuçları ve link olayları. En eskiden başlayarak, üstelik yalnızca tier 2 tükendikten sonra tahliye ediliyor.
Tier 2, rutin poz ve attitude. Bunlar atılmıyor, seyreltiliyor: tampon baskısıyla birlikte yükselen bir hata sınırıyla Ramer–Douglas–Peucker yörünge sadeleştirmesi, %50 baskıda 2 m çapraz hatadan %90 baskıda 15 m'ye kadar. Uçuşun geometrisi ayakta kalıyor, çözünürlüğü yumuşakça düşüyor. Çapa pencereleri bunun dışında: her tier-0 olayının ±10 sn çevresindeki tam hızlı telemetri baskıdan bağımsız korunuyor. Bir çarpışma önleme tetiklemesinden önceki beş saniye araçtaki en değerli veri ve onu kimse seyreltemez.
on_pressure(p): # 5 sn EWMA, p ∈ [0,1]
if p < 0.5: return
eps = lerp(2.0, 15.0, (p - 0.5) / 0.4) # metre, çapraz hata
for seg in tier2.segments_outside(anchors(tier0, window=10s)):
seg.simplify(rdp, eps) # kayıplı, biçim koruyan
if pressure() > 0.9:
tier1.evict_oldest_until(0.85)
invariant(tier0.retained == tier0.ingested) # runtime + CI assertion
Dördüncü bölüm: taşıyıcı olarak başka bir hava aracı
Mesh radyo bunca zamandır araçların üzerindeydi. Kimse onu bir veri düzlemi olarak kullanmayı akıl etmemişti. Mevcut 2,4 GHz radyo üzerinde özel bir convergence layer ile Bundle Protocol v7 semantiğinde bir store-carry-forward katmanı kurduk, sonra da bir temasın gerçekte neye benzediğini ölçmeye gittik: iki hava aracı ~900 m görüş hattı içinden geçerken medyan 26 sn kullanılabilir link, efektif ~5 Mbps.
Asıl haddimizi bildiren yer yönlendirme oldu. Epidemic flooding hem en bariz ilk deneme hem de, şimdi yazınca, başkasının tasarım incelemesinde dört saniyede yakalayacağınız cinsten bir hataydı: filo genelindeki tampon şişmesi, operatörün korumamızı istediği tier-2 geçmişini tam olarak dışarı itti. Biz bunu sahada öğrendik, ki daha pahalı bir sınıftır. Karar kıldığımız şema şöyle: tier-0 bundle'ları için L = 4 kopyalı binary spray-and-wait, geri kalan her şey için tek kopyalı doğrudan teslim. Üstüne bir contact-graph sezgiseli koyduk; her aracın planlı koridor bacaklarını zaten bildiğimiz için bir bundle, kalan planı bilinen bir kapsama hücresiyle en erken kesişen taşıyıcıyı tercih ediyor.
BPv7 custody transfer'ı bilinçli olarak kaldırdığı için onaylı devri uygulama katmanında biz yazdık. Bir taşıyıcı custody'yi kabul ettiğinde kaynak araç kendi kopyasını tier 0'dan tier 1'e düşürüyor: hâlâ saklı, ama artık tahliye edilebilir. Üçüncü ve dördüncü bölümlerin birbirine borcunu ödediği yer tam olarak burası. Yer istasyonunun teslim makbuzları da mesh üzerinden minik anti-entropi ipuçları hâlinde geri yayılıyor, bayat kopyalar böylece toplanıyor.
Beşinci bölüm: nicelenmiş güven
Buraya kadarki her şey veriyi taşımakla ilgiliydi. Bu bölüm ise aracın kendi başına karar vermesiyle ilgili ve bu konuda rahat olmak çok daha zor.
Koridor survey'inin gerçekten kötü bir algı problemi var: iletkenler, koruma telleri ve gergi telleri ince, dokusuz ve menzilde stereo için neredeyse görünmez. Gömülü yığın; stereo derinliği, monoküler derinlik önselini ve ince yapı segmentasyon başlığını 16 GB'lık bir Orin NX üzerinde, survey faydalı yüküyle paylaşılan 15 W'lık bir platform bütçesi içinde, 20 Hz'de uçtan uca 25 ms'de koşuyor.
Oraya varmanın bedeli 1,2 mAP oldu: kanal başına ölçekli INT8 post-training kuantizasyon, derinlik başlığında QAT, daha ağır bir öğretmenden distilasyon. Buna razıydık, bütçesini ayırmıştık. Bütçesini ayırmadığımız ve saha verisi olmadan asla yakalayamayacağımız şey şuydu: kalibrasyon, doğruluktan dört kat daha kötü bozuldu. Expected calibration error 0,021'den 0,088'e çıktı, üstelik asimetrik biçimde bozuldu; en kötüsü arkadan aydınlatmalı puslu havada ve düşük ışıkta, yani güven skorunun dürüst olmasına en çok ihtiyaç duyduğunuz koşullarda. Saha sayılarını laboratuvar sayılarının yanına ilk koyduğumuzda birinin koşuları karıştırdığını düşünmüştüm. Karıştıran yoktu. Laboratuvarda ayarlanmış bir eşik basitçe anlamsızdı.
Kuantizasyondan sonra temperature scaling'i, aydınlatma ve arazi sınıfına göre katmanlanmış saha verisiyle yeniden fit ettik ve min(kalibre_güven, ood_skoru) üzerinden kapı koyduk; OOD terimi, sınıf başına kovaryanslara karşı öznitelik uzayında Mahalanobis mesafesi. Yaklaşık 0,4 ms, yani her karede koşacak kadar ucuz.
Eşiğin altında araç tahmin yürütmeye devam etmiyor. Küçük ve enine boyuna test edilmiş bir durum makinesini yürüyor: NOMINAL → CAUTION (hız 4 m/s ile sınırlı, engel şişirmesi genişletilmiş) → HOLD (pozisyon tut, 3 sn'de bir yeniden değerlendir) → CLIMB (bilinen koridor yapısının üstünde, taranmış temiz irtifaya) → RTL. Bir geçişe girmek k/n mutabakatı istiyor, 10 karede 7, yani 350 ms; çıkmak ise 2 sn bekleme. Çünkü otonomi modları arasında zıplamak başlı başına bir tehlike.
O eşiği ayarlamak bir hiperparametre taraması değildi, müzakereydi. İlk ayarımız yaklaşık her dokuz görevde bir gereksiz RTL üretti ve operatör bunu haklı olarak reddetti: yeniden uçulan bir koridor bacağı bir ekip-saati ve bir batarya çevrimi demek, üstelik bu insanlar bu işten ekmek yiyor. Gerçek uçuşlardan 6.400 etiketli bozulma klibi çıkardık, ROC'u kurduk ve maliyet asimetrisini yazılı olarak masaya koyduk: kaçırılan bir ince tel tespiti, hatalı bir RTL'e karşı yaklaşık 400:1 fiyatlandı ve bu oranı müşterinin emniyet ekibi onayladı. Sonuçta ~60 görevde bir gereksiz RTL'e indik ve değerlendirme döneminde hiç kaçırılmış tespit vakası olmadı.
Güven eşiği dediğiniz şey, üzerine bir sayı iliştirilmiş bir maliyet oranıdır. Emniyet sorumlunuz o oranı görmediyse, onun kararını siz vermişsiniz ve kendisine söylememişsiniz demektir.
Altıncı bölüm: düşen şey merkezin kendisi olduğunda
Bir dönem filodaki en sinir bozucu arızanın radyolarla hiçbir ilgisi yoktu. Planlayıcı merkezîydi. Bacak ortasında bağlantısını kaybeden bir araç, atanmış waypoint'lerini bitirip bekliyordu; artık dolduramadığı bir görev kuyruğu uğruna menzilini yakarak. Kopan bağlantı dronun hedefe olan bağlantısı değildi, filonun planlayıcıya olan bağlantısıydı ve tamamen sağlıklı araçları yerinde çiviliyordu.
Yerine, her aracın o an erişebildiği komşularla yürüttüğü, CBBA tarzı mutabakatla genişletilmiş bir contract-net açık artırması koyduk. Teklifler mesafeyle değil, tamamlamak için gereken watt-saatle fiyatlanıyor; EKF'in kestirdiği rüzgâr durumları ve sıcaklığa göre derate edilmiş paket enerjisiyle beslenen enerji modelinden geliyorlar. 20 km'lik bir bacağı rüzgâra karşı uçmakla rüzgâr arkadan uçmak aynı görev değil. Bundle kurulumu azalan marjinal fayda koşulunu zorluyor; yakınsama garantisini satın alan şey de bu. Erişilebilir komşular arasında yeniden ihale 2 saniyenin altında oturuyor.
Atamalar bir lease taşıyor: epoch artı sona erme. Bölünmüş kalıp lease'ini yenileyemeyen araç talebini bırakıyor, erişebildiği komşular da işi yeniden ihaleye çıkarıyor. Bölünme birleştiğinde mükerrer kapsama çıkabiliyor ve bunu bilerek göze aldık. Bir koridorun %3'ünü iki kez taramak israftır; çoğunluğa ulaşamadığı için uçmayı bırakan bölünmüş bir filo ise kesintidir. Bu alanda idempotent mükerrerlik, bloklayan mutabakatı her seferinde yener.
Manuel yeniden görevlendirme gerektiren takılı kalmış görevler %6,1'den %1,0'a düştü — yani %83'lük bir azalma. Kalan %1 de artık koordinasyondan değil, gerçek donanım sorunlarından kaynaklanıyor.
Yedinci bölüm: arızayı tekrarlanabilir kılmak
Yukarıdakilerin hiçbiri daha çok uçarak test edilemez. Bir GNSS denial olayını takvime koyamazsınız, doğru çokyolluluk geometrisinin ortaya çıkmasını da oturup bekleyemezsiniz.
O yüzden bir hardware-in-the-loop tezgâhı kurduk: gerçek uçuş kontrolcüsü ve gerçek Orin üzerinde üretim yazılımı, çokyolluluk / bozuk HDOP / tam denial enjekte eden bir RF takımyıldız simülatörü, 2,4 GHz mesh bandına girişim basan bir SDR ve 10 m DEM üzerinden Longley-Rice modeliyle yol kaybı hesaplayan bir link emülatörü. Son madde kulağa geldiğinden çok daha önemli. Rastgele paket kaybı, bu sistemleri asıl kıran korelasyonlu, geometriye bağlı kesintileri üretmiyor. Gerçek gölgeleme, araç bir sırtın arkasına alçalırken linki dört dakika boyunca komple düşürüyor; üstelik aynı anda hem yer linkini hem de mesh komşularının yarısını götürüyor, çünkü hepsi aynı kayanın yanlış tarafında kalıyor.
Her şey deterministik: sabit adımlı simülasyon saati, tohumlanmış RNG, kayıtlı sensör izleri. Dört tezgâhta gecelik 214 senaryo yaklaşık 46 dakikada koşuyor; senkron ya da otonomiye dokunan her PR, 38 senaryoluk emniyet alt kümesini dokuz dakikada geçiriyor. Assertion'lar çıktı değil invaryant: alınan tier-0 sayısı = teslim edilen veya custody'de olan tier-0 sayısı, hiçbir replikada nedensel sıra ihlali yok, fallback FSM'inde tanımsız kenar yok.
Bu tezgâhın benim için neden önemli olduğunu açıkça söyleyeyim. Tezgâh yokken, "güvenlik sınıfının asla düşmediğinden emin misiniz?" sorusunun dürüst cevabı "öyle olduğunu düşünüyoruz, üzerine uzun uzun çalıştık" idi. Bu aynı cümle değil ve bir hava aracında bu fark akademik bir ayrıntı değil. Tezgâh maliyetini daha ilk ayında çıkardı. Üç saatlik bir serbest koşma senaryosu, yalnızca olay birleştirme fırtınalarında ortaya çıkan bir 16 bit mantıksal sayaç taşmasını yüzeye çıkardı; başka bir koşu ise custody'yi üstlenmiş bir taşıyıcının inip bir daha link yakalayamaması durumunda oluşan spray-and-wait kopya sızıntısını buldu, onu da custody süre aşımı ve yer istasyonunun yeniden yayınlamasıyla çözdük. İkisi de uçarak bulunamazdı. İkisi de bir olay raporuyla bulunurdu.
Asıl önemli olan sayı
Dokuz aylık operasyonda, güvenlik sınıflı 2,31 milyon olayın %99,98'i yer istasyonuna ulaştı. Bu olaylarda yere ulaşma süresinin medyanı 41 dakikadan 6,5 dakikaya, p99 ise 2s07'den 22 dakikaya indi. Teslim edemediğimiz %0,02, fiziksel olarak kaybedilen iki hava aracının üzerinde kaldı. Hiçbir olay tampon, merge ya da röle tarafından düşürülmedi — zaten bütün mesele buydu.
Operatörün satın aldığı şey uptime değildi. Uptime zaten hiçbir zaman masada değildi, arazi pazarlık etmiyor. Satın aldıkları şey, bir hava aracı sırtın arkasında karanlığa gömüldüğünde sorulan tek anlamlı sorunun sınırları çizilmiş, açıkça ifade edilmiş bir cevabıydı: orada bir şey olduysa, haberimiz oluyor mu ve ne kadar hızlı?
Araçtaki diğer her şeyin bozulma hakkı var. O cevabın yok.