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ı:
- İlgili ELF bootloader formatındaki application flash image'a çevrildi.
- Image
0x01800000application flash bölgesine yazıldı. - FPGA SRAM aynı bitstream ile yeniden programlandı.
- Bootloader ELF'i flash'tan DTIM'e kopyaladı; ilk I-cache dolumu ile RAM imajının aynı firmware olması sağlandı.
- İlk konum çözümü acquisition süresinden sonra beklendi.
- 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=0vefde_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 sidi; - ilk epoch: çoğunluk
64634.200, SVID 664634.000; - son epoch: çoğunluk
64933.400, SVID 664933.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:
- Kanal önce LNAV HOW alanından TOW alıyor.
- İlk nav-solve interrupt'ında TOW ownership
HOWkaynağındanNAV_SOLVEkaynağına geçiriliyor. - Bundan sonra kanal TOW'u recursively
tow += event_count * NAV_SOLVE_TIMER * 20 msile artırılıyor. - 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ı:
-
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_sampleve anchor-valid bilgisi. -
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.sviçindekiabsolute_sample_odeğerinin geçerli 20 ms bit sınırında üretildiği vetracking_wrapper.sviçindekiload_sigsyolunun geçerli/pariteli subframe'deABS_SAMPLEileREM_CODE_PHASE'ı birlikte latch ettiği doğrulandı. -
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_PHASEdüzeltmesi iki uçta da hesaba katılmalıdır. 32-bitABS_SAMPLEfarkı signed/wrapped alınmalıdır; anchor 6 saniyede bir yenilendiği için wrap belirsizliği oluşmaz. -
Aynı interrupt'ta hem nav-bits hem nav-solve flag varsa önce HOW anchor güncellenir; nav-solve için
delta_samples=0olur. Eski koddaki koşulsuz+periodoff-by-one riski ortadan kalkar. -
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.
-
gps_tow_sourceownership state'i vegps_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. -
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_SAMPLEwrap; - 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.elfartifacts/firmware_ab/gps_new_how_anchor_fde_off.flash.binlogs/how_anchor_acquisition.csvlogs/how_anchor_fde_off_5min.csvoutput/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.