Files
gps/soc/software/fusion

Stationary GPS / ICM-4268x fusion

Bu klasör Genesys2 kartından UART ile alınan GPS WLS konumlarını ve PMOD SPI üzerindeki ICM-42686/ICM-42688 ölçümlerini Python'da işler. Filtre 15 hata durumlu bir ESKF'dir: ENU konum/hız, quaternion tutum, ivmeölçer biası ve jiroskop biası. Kartın durağan olduğu deneyde zero-velocity update (ZUPT) uygulanır ve GPS innovation değerlerine aykırı-ölçüm kapısı konur.

Çalıştırma

UART kaydı:

python3 serial_capture.py --duration 60 --output logs/gps_60s.csv
python3 serial_capture.py --duration 75 --stop-text 'Complete:' \
  --output logs/imu_60s.csv

Mevcut logları işleme:

python3 fusion_eskf.py

Sabit-kısıtlı ve hareket-kabiliyetli modelleri aynı kayıt üzerinde karşılaştırma:

python3 compare_eskf_models.py \
  --gps logs/gps_live_5min_20260713.csv \
  --imu logs/imu_live_5min_20260713.csv \
  --output output/model_compare_5min

Sabit model her IMU penceresinde zero-velocity ve zero-gyro ölçümü uygular. Hareket-kabiliyetli model bunları sürekli uygulamaz; ivme normu ve gyro normundan üç ardışık durağan pencere algıladığında etkinleştirir. PMOD testinin UART çıktısı 500 ms pencere ortalaması olduğundan bu deney durağan gürültü ve model davranışı karşılaştırmasıdır. Gerçek hareketli kullanım için ham veya yüksek hızlı IMU örnekleri ile GPS ölçümleri aynı CPU sayacıyla firmware içinde zaman damgalanmalıdır.

Linux masaüstü OpenStreetMap oynatıcısını açma:

python3 map_player.py

5 dakikalık sabit/adaptif model karşılaştırmasını doğrudan açma:

python3 map_player.py \
  --comparison output/model_compare_5min_20260713/model_comparison.csv \
  --model adaptive

--model fixed aynı kaydı sürekli-stationary modelle gösterir.

Pencerede oynat/duraklat, sample sürgüsü, 0.5–4x hız, zoom/pan, ham GPS ve ESKF izleri bulunur. Tile'lar output/osm_tile_cache/ altında cache edilir; ilk açılışta harita tabanı için internet bağlantısı gerekir.

Deney sınırı

İstenen akışta GPS ve IMU UART logları peş peşe toplandı. Kart durağan olduğu için iki 0–60 s ekseni offline modellemede üst üste bindirilmiştir. Bu sonuç durağan bias/noise ve konum kararlılığı deneyidir. Hareketli bir sistemde aynı ESKF'nin anlamlı olması için GPS ve ham/decimate edilmiş IMU örnekleri aynı firmware çalışmasında ortak donanım zaman damgasıyla kaydedilmelidir; 500 ms ortalamalar hızlı dinamiği korumaz.

Standalone GPS WLS bütünlük çalışması (2026-07-12)

Bu bölüm, standalone GPS konumundaki 20--30 m ve daha büyük sıçramaları araştırmak için yapılan firmware karşılaştırmasını kaydeder. Karşılaştırılan eski kaynak commit'i 07ddf29 (first draft) idi. Yeni kaynakta residual, chi-square, covariance, validity, leave-one-out FDE, çalışma süresi ve ISR tanıları bulunuyordu.

Karşılaştırma yöntemi

GDB ile çalışan DTIM imajının üzerine başka bir ELF yazıldığında Rocket I-cache'in eski firmware satırlarını yürütmeye devam ettiği gözlendi. Örneğin 0x80002f58 adresi eski ELF'te gps_pps_init, yeni ELF'te ise gps_process_isr_events içindeydi; access-fault anındaki return address yeni ELF anlamına uyuyordu. fence.i stub'ı çalıştırılması da bu kart/akışta güvenilir bir hot-load sağlamadı.

Bu nedenle aşağıdaki A/B ölçümlerinde GDB hot-load kullanılmadı:

  1. İlgili ELF bootloader formatındaki application flash image'a çevrildi.
  2. Image 0x01800000 application flash bölgesine yazıldı.
  3. FPGA SRAM aynı bitstream ile yeniden programlandı.
  4. Bootloader ELF'i flash'tan DTIM'e kopyaladı; ilk I-cache dolumu ile RAM imajının aynı firmware olması sağlandı.
  5. İlk konum çözümü acquisition süresinden sonra beklendi.
  6. Kart ve anten sabitken 300 saniyelik UART kaydı alındı.

Sapmalar surveyed bir koordinata göre değil, her koşunun kendi medyan konumuna göre hesaplandı. Bu nedenle aşağıdaki değerler mutlak doğruluktan çok durağan konum dağılımını/hassasiyetini gösterir. Farklı koşulardaki uydu sayısı ve DOP ayrıca belirtilmiştir.

Kullanılan imajlar ve loglar

  • Exact eski ELF: artifacts/firmware_ab/gps_old.elf
  • FDE açık yeni ELF: artifacts/firmware_ab/gps_new.elf
  • FDE kapalı yeni ELF: artifacts/firmware_ab/gps_new_fde_off.elf
  • Eski log: logs/ab_live_old_5min.csv
  • FDE açık yeni log: logs/ab_live_new_5min.csv
  • FDE kapalı yeni log: logs/ab_live_new_fde_off_5min.csv
  • Uydu/FDE gruplu sonuç: output/firmware_ab_live_5min_by_satellites.csv
  • FDE kapalı karşılaştırma: output/firmware_ab_live_fde_off_5min_by_satellites.csv
  • Analiz programı: compare_firmware_logs.py

FDE kapalı ELF SHA-256:

23e2d5be11ab0bf23213c5253b4213277f11e5785d90484c9d624b4fcae944dc

FDE kapalı 5 dakika log SHA-256:

c2815c0cf3e7f76dd0a19db9526421355d6699c4bc1edc6407fde496e09bafc8

Canlı A/B sonuçları

Firmware/çözüm Kullanılabilir uydu Örnek Yatay ort. Yatay P95 Yatay maks. Düşey mutlak ort. 3B P95 3B maks.
Eski firmware 8 485 6.01 m 11.70 m 20.79 m 9.60 m 25.05 m 38.97 m
Yeni, FDE açık, tümü çoğunlukla 7 300 9.71 m 30.34 m 44.90 m 16.43 m 78.95 m 128.96 m
Yeni, FDE açık ama FDE seçilmeyen epoch 7 231 6.84 m 13.41 m 17.33 m 10.85 m 28.03 m 37.80 m
Yeni, FDE tarafından 7'den 6'ya düşürülen epoch 7 -> 6 68 19.22 m 37.09 m 44.90 m 34.52 m 108.30 m 128.96 m
Yeni, FDE compile-time kapalı 7 300 8.64 m 16.74 m 22.56 m 14.34 m 40.90 m 88.73 m

DOP medyanları aynı değildi:

Koşu HDOP VDOP
Eski, 8 uydu 1.222 1.991
Yeni, FDE açık 1.339 2.102
Yeni, FDE kapalı 1.642 2.852

FDE kapalı koşu daha kötü geometriye rağmen FDE açık toplam sonuçtan daha kararlıydı. Yatay P95 30.34 mden 16.74 mye, yatay maksimum 44.90 mden 22.56 mye ve 3B P95 78.95 mden 40.90 mye düştü.

FDE teşhisi ve alınan karar

FDE açık koşuda 300 epoch'un 68'inde (%22.7) leave-one-out FDE uygulandı. 99% chi-square kapısının nominal false-alarm oranı yaklaşık %1 olmalıydı. Çıkarılan uydu tek bir SVID değildi: SVID 13, 19, 20, 21, 6 ve 29 farklı epoch'larda seçildi. Bu davranış tek ve sürekli arızalı bir uydudan çok, measurement sigma/covariance modelinin gerçek tracking gürültüsü ve multipath'i küçümsemesiyle uyumludur.

FDE açık koşuda exclusion içeren ardışık konum çiftlerinin 3B step ortalaması 47.40 m, FDE içermeyen çiftlerde 18.45 m idi. Bazı kötü FDE seçimleri integrity-valid olarak işaretlendi. Altı uydu için FDE daha önce sentetik testte ayrıca engellenmişti; çünkü 6 -> 5 leave-one-out çözümü yalnız bir residual serbestlik derecesi bırakıp 123 m hatalı bir çözümü geçerli gösterebilmişti.

Ürün firmware'inde otomatik FDE seçimi şu anda compile-time kapalıdır:

#define GPS_NAV_ENABLE_FDE 0u

Full-WLS konumu üretilmeye devam eder. Post-fit residual, chi-square, DOF, threshold, covariance, hAcc/vAcc ve validity hesapları/logları korunur. Chi-square fail eden çözüm konum olarak görülebilir fakat valid=0 olur; PPS ve sonraki WLS seed'i invalid çözümle güncellenmez.

FDE kapalı koşuda:

  • 300/300 epoch'ta fde=0 ve fde_trials=0;
  • 235/300 epoch integrity-valid (%78.3);
  • ISR overflow, PLIC repeat, drain-limit, coalesced event, satellite loss ve period overrun sayaçları sıfır;
  • maksimum foreground süresi 288.74 ms;
  • maksimum WLS süresi 28.11 ms;
  • 1 saniyelik/50 milyon cycle bütçe hiç aşılmadı.

FDE ancak C/N0, tracking variance, URA, elevation ve multipath bileşenlerinden kalibre edilmiş absolute measurement sigma üretildikten; normalized residual, solution separation, exclusion uniqueness ve zaman hysteresis'i eklendikten sonra yeniden açılmalıdır.

Eski firmware'deki kalıcı 0.2 s TOW faz hatası

Ölçüm kanıtı

Eski firmware acquisition logunun ilk çözümü 5 uyduyla yapıldı ve bu ilk epoch'ta bütün TOW değerleri 64620.200 s idi. SVID 6 daha sonra tracking kanalı 7'ye bağlandı. Sekiz uydulu 5 dakika kaydında:

  • 485 epoch'un 485'i TOW-incoherent idi;
  • çoğunluk TOW ile SVID 6 arasındaki fark her epoch'ta tam -0.200 s idi;
  • ilk epoch: çoğunluk 64634.200, SVID 6 64634.000;
  • son epoch: çoğunluk 64933.400, SVID 6 64933.200;
  • sonraki subframe/HOW alımları farkı düzeltmedi.

Dolayısıyla hata geçici değildi. SVID 6 çözümde kaldığı sürece uydu konumu 0.2 saniye yanlış epoch için hesaplandı. Bunun alıcı WLS konumuna etkisi uydu geometrisine bağlıdır; iki firmware medyanı arasındaki 3B fark bu nedenle mutlak doğruluk ölçümü olarak yorumlanamaz.

Yeni 1 saniyelik koşuların her ikisinde de 300/300 epoch TOW-coherent idi; tow_aligned=0 ve tow_rejected=0 kaldı. Bu, eski hatanın her bootta zorunlu olmadığını fakat kanal geç katıldığında kalıcı olabildiğini gösterir.

Kök mekanizma

Mevcut yazılım her tracking kanalı için ayrı TOW state'i yürütüyor:

  1. Kanal önce LNAV HOW alanından TOW alıyor.
  2. İlk nav-solve interrupt'ında TOW ownership HOW kaynağından NAV_SOLVE kaynağına geçiriliyor.
  3. Bundan sonra kanal TOW'u recursively tow += event_count * NAV_SOLVE_TIMER * 20 ms ile artırılıyor.
  4. Ownership geçtikten sonra daha sonraki HOW değerleri TOW'u yeniden anchor etmiyor.

Kanalın enable/ilk interrupt sınırında bir tick off-by-one oluşursa bütün sonraki artışlar doğru miktarda fakat yanlış başlangıçtan yapılır; sabit faz hatası bu yüzden kalıcı olur. Log, SVID 6'nın geç katıldığını ve hatanın tam bir eski nav periodu olduğunu kanıtlıyor. İlk yanlış tick'in enable/flag sıralamasından mı yoksa aynı olayda HOW ve nav-solve işlenmesinden mi geldiği geçiş anı iki UART dosyası arasındaki kısa boşlukta kaldığı için logdan tek başına kesinleştirilemiyor. Ancak recursive kanal-bağımsız TOW mimarisinin hatayı kendi kendine düzeltemediği kesindir.

IS-GPS-200N'e göre HOW içindeki TOW sayacı bir sonraki subframe'in başlangıç zamanını ifade eder. Kodun (HOW >> 13) * 6 dönüşümü bu 6 saniyelik değeri üretir. Kalıcı düzeltme, bu absolute yayın zamanını yalnız ilk başlangıç için değil sürekli time anchor olarak kullanmalıdır. Referans: https://archive.gps.gov/technical/icwg/IS-GPS-200N.pdf, bölüm 3.3.4 ve 20.3.3.2.

Uygulanan kalıcı TOW mimarisi

2026-07-12'de kanal başına recursive TOW artışı kaldırıldı ve aşağıdaki HOW/receiver-sample anchor modeli ürün firmware'ine uygulandı. Snapshot'ta azınlık TOW'unu çoğunluğa kopyalayan geçici recovery yolu da kaldırıldı:

  1. Her geçerli LNAV subframe sonunda kanal için şu anchor saklanır: how_tow, how_week, how_abs_sample_raw, düzeltilmiş how_abs_sample ve anchor-valid bilgisi.

  2. HOW TOW bir sonraki subframe başlangıcını gösterdiği ve nav-bits event'i alınan subframe'in sonuna karşılık geldiği için bu ikisi aynı zaman sınırında anchor edilir. RTL incelemesinde bit_gen.sv içindeki absolute_sample_o değerinin geçerli 20 ms bit sınırında üretildiği ve tracking_wrapper.sv içindeki load_sigs yolunun geçerli/pariteli subframe'de ABS_SAMPLE ile REM_CODE_PHASE'ı birlikte latch ettiği doğrulandı.

  3. Her nav-solve ölçümünün TOW'u önceki nav-solve TOW'una ekleme yapılarak değil, son HOW anchor'ından tekrar hesaplanır:

    delta_samples = signed_wrap(nav_abs_sample - how_abs_sample)
    measurement_tow = normalize(how_tow + delta_samples / 16_368_000)
    

    REM_CODE_PHASE düzeltmesi iki uçta da hesaba katılmalıdır. 32-bit ABS_SAMPLE farkı signed/wrapped alınmalıdır; anchor 6 saniyede bir yenilendiği için wrap belirsizliği oluşmaz.

  4. Aynı interrupt'ta hem nav-bits hem nav-solve flag varsa önce HOW anchor güncellenir; nav-solve için delta_samples=0 olur. Eski koddaki koşulsuz +period off-by-one riski ortadan kalkar.

  5. Anchor yaşı, subframe/parity geçerliliği ve finite/range kontrolleri zorunlu yapıldı. Geçerli anchor olmayan veya 12 saniyeden eski anchor'a sahip kanalın nav-solve ölçümü kabul edilmez.

  6. gps_tow_source ownership state'i ve gps_advance_tow_from_nav_timer() kaldırılır. Interrupt count yalnız event kaybı tanısı için tutulur, absolute GPS zamanının kaynağı olmaz.

  7. Coherent snapshot kontrolü son savunma olarak kalır; fark görülürse epoch veya problemli kanal reject edilir. TOW değeri sessizce başka kanalın değeriyle değiştirilmez.

Üretim kodu header/gps_time_anchor.h ve src/gps_time_anchor.c içindedir. parse_subframe() artık TOW state'ini değiştirmez; yalnız HOW TOW değerini dışarı verir. gps_time_from_sample_anchor() her nav-solve için GPS zamanını son HOW ve iki receiver-sample latch'i arasındaki farktan baştan üretir.

Uygulanan birim testler:

  • HOW ile aynı anda gelen ilk nav-solve (delta=0);
  • 200 ms ve 1 s sonraki nav-solve;
  • geç enable edilen kanal;
  • bir veya birkaç coalesced/missed interrupt;
  • 32-bit ABS_SAMPLE wrap;
  • GPS week rollover;
  • stale HOW anchor;
  • aynı coherent epoch'ta bütün kanalların TOW farkının tolerans içinde olması.

Host testleri normal optimizasyonla ve AddressSanitizer/UndefinedBehaviorSanitizer ile geçti. 50 MHz Rocket ürün build'i de başarılı oldu. Yeni anchor fonksiyonları ELF'te toplam yaklaşık 264 bayt text alanı kullanıyor; 1 Hz'de kanal başına bir kez çalıştığı için WLS yanında CPU etkisi ihmal edilebilir düzeydedir.

Flash-boot donanım doğrulaması

GDB hot-load kullanılmadan yeni ELF application flash bölgesine yazıldı ve FPGA yeniden programlanarak bootloader üzerinden temiz DTIM/I-cache başlangıcı yapıldı. Kullanılan dosyalar:

  • artifacts/firmware_ab/gps_new_how_anchor_fde_off.elf
  • artifacts/firmware_ab/gps_new_how_anchor_fde_off.flash.bin
  • logs/how_anchor_acquisition.csv
  • logs/how_anchor_fde_off_5min.csv
  • output/firmware_ab_how_anchor_fde_off_5min_by_satellites.csv

ELF SHA-256:

fb1de03aafacf46d95bde375f3f744635472e9893a9aff6f3c3db9a16444c5ce

5 dakika log SHA-256:

82b08bd35d4452f92db6af609b2a03db2ff7b8f78443414ca7a0238c3cb603ed

Acquisition sırasında bir kanal diğerlerinden altı nav-solve epoch daha geç katıldı (seq=8, diğer kanallar seq=14). Buna rağmen ortak ölçüm epoch'unda bütün kanallar 67640.000 s TOW üretti; eski yazılımdaki -0.200 s kalıcı faz farkı yeniden oluşmadı.

5 dakikalık sabit anten ölçümü:

Metrik Sonuç
NAV çözümü 300
Kanal zaman ölçümü 2100
TOW yayılımı P95 19 us
TOW yayılımı maksimum 33 us
1 ms üstü TOW epoch'u 0
tow_mismatch / tow_rejected 0 / 0
ISR overflow / PLIC repeat / drain limit 0 / 0 / 0
Coalesced / lost / period overrun 0 / 0 / 0
Integrity-valid 270/300 (%90.0)
FDE uygulanması 0/300
Maksimum foreground / WLS 290.13 ms / 28.34 ms
HDOP / VDOP medyan 1.511 / 2.407
Yatay ortalama / P95 / maksimum 8.34 m / 16.36 m / 24.93 m
3B P95 32.64 m

FDE kapalı önceki yeni-firmware koşusu yatay ortalama/P95 olarak 8.64/16.74 m, HOW-anchor koşusu 8.34/16.36 m verdi. Dolayısıyla FDE kapatılınca full-WLS dağılımı eski firmware'e yakın seviyeye döndü. Eski firmware 8 uydu ve daha iyi geometriyle 6.01/11.70 m, yeni koşu çoğunlukla 7 uyduyla 8.34/16.36 m üretti. Bu farkın tamamı algoritma farkı sayılamaz; koşuların uydu sayıları/DOP'ları farklıdır ve surveyed ground truth yoktur. FDE açık yeni koşunun 9.71/30.34 m toplam sonucu ise belirgin daha kötüydü.

Not: Eski logdaki hata 0.2 ms değil, 0.2 s = 200 ms idi. Yeni ölçümdeki en büyük kanallar arası TOW farkı 33 us, yani 0.033 ms oldu.

Son savunma

Anchor düzeltmesine rağmen TOW farkı görülürse epoch invalid/reject edilir. SVID'e özel +0.2 s eklenmez ve azınlık TOW'u çoğunluğa kopyalanmaz; böylece başka kanal veya başka nav periodundaki gerçek zaman hatası gizlenmez.