Documentation/ GPS Sensor Fusion Toolkit

GPS Sensor Fusion Toolkit

[ DOCUMENTATION ]

Getting started

Requirements

Unity 2021.3 LTS or newer. No other packages required.

Installation

Three ways to add the package to your project:

  • Local UPM package (recommended)Window > Package Manager > + > Add package from disk… and select the package’s package.json.
  • Embedded package — copy the com.kephstudio.gps-sensor-fusion folder into your project’s Packages/ folder.
  • Classic import — copy the Runtime/ scripts into Assets/ (you lose assembly-definition isolation).

Overview

GPS Sensor Fusion fuses GPS (low rate, position + velocity) with an optional AHRS/IMU (high rate, heading + turn rate) into a smooth, high-rate estimate of position, velocity and heading. Two filters are provided: a 6-state linear Kalman filter, and an 8-state Extended Kalman Filter (CTRV) that adds heading and turn rate and ingests AHRS measurements between GPS fixes.

What’s included

KalmanFilter6-state linear filter (constant velocity) — simple and fast, GPS only.
ExtendedKalmanFilter8-state CTRV filter — best quality, fuses GPS + AHRS through turns.
HeadingFilterAdaptive heading smoother (EMA + rate limit + stationary dead-zone).
GPSMovementStateCTRV dead-reckoning predictor between fixes.
NMEAGenerator / NmeaParserStandard NMEA 0183 generation and parsing into a GpsFix.
GeoUtilsGeodesy: haversine, bearing, unit conversions, lat/lon → local ENU.
IGpsSourcePluggable input: NMEA push, Unity LocationService, CSV replay.
SfMatrixZero-allocation dense matrix backing the filters.

Coordinate conventions

All filters operate in Unity world meters: X = East, Y = Up, Z = North. Heading is in radians, 0 = North (+Z), increasing clockwise. Convert GPS latitude/longitude to a local metric frame around an origin before feeding the filter — GeoUtils.GpsCoordTo3D(refLat, refLon, refAlt, lat, lon, alt).

Quick start

using UnityEngine;
using KephStudio.SensorFusion;

public class Example : MonoBehaviour
{
    private ExtendedKalmanFilter _ekf;

    void Start()
    {
        // processNoise, measurementNoise, headingNoise, turnRateNoise
        _ekf = new ExtendedKalmanFilter(1f, 3f, 0.1f, 0.1f);
        _ekf.Reset(transform.position, Vector3.zero, heading: 0f, turnRate: 0f);
    }

    public void OnImu(float headingRad, float turnRate, float dt)   // ~50 Hz
    {
        _ekf.Predict(dt);
        _ekf.UpdateAHRS(headingRad, turnRate, 0.05f, 0.05f);
    }

    public void OnGps(Vector3 worldPos, Vector3 worldVel)           // ~10 Hz
        => _ekf.UpdateGPS(worldPos, worldVel, 1f, 1f);

    void Update()
    {
        transform.position = _ekf.GetPosition();
        transform.rotation = Quaternion.Euler(0f, _ekf.GetHeading() * Mathf.Rad2Deg, 0f);
    }
}

Call Predict once per elapsed dt, then apply whichever measurement arrived — GPS and AHRS updates are independent and run at their own rates.

Tuning

Estimate lags real motionLower measurementNoise, or raise processNoise.
Estimate is jitteryRaise measurementNoise, or lower processNoise.
Overshoots in turns (EKF)Raise turnRateProcessNoise and feed AHRS turn rate.
Poor fixes should count lessPass larger position/velocity uncertainty (e.g. scale by HDOP).

Samples

Import samples from the Package Manager (Samples tab).

  • Synthetic Track Demo — Noisy GPS track → EKF → plots truth / noisy / filtered with LineRenderers. No hardware.

Support & license

Distributed under the Unity Asset Store EULA. Questions, bugs and feature requests are handled directly by the studio — contact@kephstudio.ch.

Still stuck?

Reach the studio directly — we usually reply within a couple of working days.

contact@kephstudio.ch