Skip to content

timliudev/FusionGNSS

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

FusionGNSS

GNSS + IMU fusion (UKF) for Android, outputting high-rate NMEA 0183 over TCP — built for feeding RaceChrono with 1–25 Hz position data on track (cars and motorcycles).

How it works

GNSS (FusedLocationProvider, ~1 Hz from HAL)  ──┐
                                                ├─► 6-state UKF [pos NED, vel NED]
IMU linear accel @ 100–200 Hz ── rotated to ───┘        │
NED via ROTATION_VECTOR or FSensor orientation          ▼
                                            output ticker @ 1–25 Hz
                                                │
                                    NMEA GGA + RMC (+VTG/GSA)
                                                │
                                  TCP server (default 127.0.0.1:5555)
                                  + optional file logging
  • The phone's GNSS HAL only delivers ~1 Hz. The extra rate is IMU dead-reckoning between fixes via the UKF predict step, not interpolation — so latency is low and positions move with real vehicle dynamics (important for lap timing).
  • Runs as a foreground service (location type, partial wakelock); the notification shows the output rate and current position.
  • Mount auto-calibration: gravity low-pass gives the phone's "down"; correlating device acceleration with GNSS speed changes during one firm brake/accel gives "forward". After that the app reports vehicle-frame long/lat G and motorcycle lean angle regardless of how the phone is mounted. The UKF itself is mount-independent (accel is rotated to NED with the orientation sensor).
  • FSensor option: toggle to use KalebKE/FSensor Kalman-fused orientation instead of Android's ROTATION_VECTOR.

RaceChrono setup

  1. Start FusionGNSS, press Start, wait for fix.
  2. RaceChrono → Settings → GPS/receiver → NMEA over TCP/IP → host 127.0.0.1, port 5555 (default; both configurable in the app).
  3. Keep "Localhost only" on when RaceChrono runs on the same phone (lowest latency, nothing exposed on the network). Turn it off to serve another device over Wi-Fi.

Settings

Setting Default Notes
Output rate 10 Hz 1–25 Hz slider
TCP port 5555
Localhost only on off = bind 0.0.0.0
Log NMEA to file off Android/data/com.fusiongnss/files/logs/
FSensor orientation off uses KalebKE/FSensor Kalman fusion
Raw GPS provider off LocationManager.GPS_PROVIDER instead of Fused (no smoothing, lowest GNSS latency)
VTG / GSA off GGA + RMC are always sent

Build

Open in Android Studio (Ladybug+) and run. minSdk 30 (Android 11), Kotlin + Jetpack Compose Material 3, Play Services Location. FSensor comes from JitPack — if the v2.2 tag fails to resolve, check the latest tag on JitPack and adjust app/build.gradle.kts.

Notes / known limitations

  • NMEA timestamps are GNSS UTC (from Location.time), extrapolated between fixes with the monotonic clock — independent of the phone's wall clock.
  • NMEA lat/lon uses 4 decimal minute digits (~0.2 m). RaceChrono accepts this fine.
  • HDOP in GGA is synthesized from UKF position covariance, not true DOP.
  • Disable battery optimization for the app for long sessions.
  • IMU-only drift between 1 Hz fixes is bounded (<1 s horizon) so accuracy stays close to GNSS accuracy while adding real inter-fix dynamics.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages