Skip to content

Repository files navigation

coldstart

GPS NMEA sentence simulator. Fetches real satellite ephemeris from u-blox AssistNow, propagates orbits using Keplerian mechanics (IS-GPS-200), and outputs realistic NMEA sentences over serial or stdout.

u-center showing simulated receiver (left) alongside a real u-blox GNSS receiver (right) with matching skyviews and signal strength Left: coldstart feeding u-center via TCP. Right: real u-blox receiver on COM33. Skyviews and SNR bars match.

What it does

Given a position (lat/lon/alt) and a u-blox API key, coldstart:

  1. Fetches current GPS broadcast ephemeris from u-blox AssistNow Online
  2. Propagates satellite orbits using Keplerian mechanics with IS-GPS-200 harmonic corrections (Cuc/Cus/Crc/Crs/Cic/Cis)
  3. Computes per-satellite azimuth, elevation, and simulated SNR for the observer position
  4. Generates a full set of NMEA 0183 sentences at 1 Hz, synchronized to UTC second boundaries
  5. Outputs over serial port, stdout, or anything you can pipe to

This is useful for testing GPS receivers, NMEA parsers, and navigation systems without real GPS signals or expensive RF simulators.

Building

With Nix (recommended)

nix develop       # enter dev shell with Rust toolchain
cargo build       # build the binary
cargo test        # run the test suite (44 tests)

Without Nix

Requires Rust 1.75+, pkg-config, openssl, and libudev dev headers.

cargo build

Usage

# CLI args (recommended)
coldstart --lat 53.3498 --lon -6.2603 --api-key YOUR_KEY

# Or via environment variables
export LATITUDE=53.3498
export LONGITUDE=-6.2603
export UBLOX_API_KEY=your-api-key-here
coldstart

Options

Flag Env var Default Description
--lat LATITUDE required Decimal degrees (-90 to 90)
--lon LONGITUDE required Decimal degrees (-180 to 180)
--alt ALTITUDE 0 Altitude in metres
--api-key UBLOX_API_KEY required u-blox AssistNow API key
--api-host UBLOX_API_HOST online-live1.services.u-blox.com AssistNow host
-p, --port /dev/ttyUSB0 Serial port device
-b, --baud 9600 Serial baud rate
--stdout Output to stdout instead of serial
--once Emit one burst and exit
-v, --verbose Verbose logging (-v info, -vv debug)

Examples

# Serial output at custom baud rate
coldstart --lat 53.35 --lon -6.26 --api-key KEY -p /dev/ttyACM0 -b 115200

# Test without hardware — single burst to stdout
coldstart --lat 53.35 --lon -6.26 --api-key KEY --stdout --once

# Continuous stdout — pipe to socat, netcat, u-center via TCP, etc.
coldstart --lat 53.35 --lon -6.26 --api-key KEY --stdout

# Feed u-center over TCP (as shown in screenshot)
coldstart --lat 53.35 --lon -6.26 --api-key KEY --stdout | socat - TCP-LISTEN:7878,reuseaddr

The simulator syncs to the top of each UTC second and outputs NMEA sentences at 1 Hz. Satellite positions are recomputed every tick.

Architecture

src/
├── main.rs        — CLI (clap), orchestration, serial/stdout output loop
├── nmea.rs        — NMEA 0183 sentence generation with checksum
├── orbit.rs       — IS-GPS-200 Keplerian propagation, WGS-84 geodesy, ECEF/ENU/AzEl
├── ubx.rs         — u-blox UBX protocol parsing, ephemeris struct scaling
└── assist_now.rs  — u-blox AssistNow Online API client

Data flow

AssistNow API → UBX MGA-GPS-EPH → ephemeris scaling → Keplerian propagation
    → satellite ECEF → observer-relative azimuth/elevation
    → NMEA sentence generation → serial port / stdout

NMEA sentences generated

Sentence Description
GGA Fix data — position, fix quality, satellite count, HDOP
GLL Geographic position — lat/lon with validity status
GSA DOP and active satellites (up to 12)
RMC Recommended minimum — position, velocity, time
VTG Course and speed over ground
GSV Satellites in view — azimuth, elevation, SNR (multi-message)
ZDA UTC date/time with timezone offset

Orbital model

Satellite positions are computed from broadcast ephemeris using the IS-GPS-200 algorithm (§ 20.3.3.4.3):

  • Keplerian orbit propagation with eccentric anomaly solved via Newton-Raphson
  • Second harmonic corrections: Cuc/Cus (argument of latitude), Crc/Crs (radius), Cic/Cis (inclination)
  • WGS-84 geodetic-to-ECEF conversion for observer position
  • ECEF-to-ENU rotation for azimuth/elevation computation
  • SNR model: 25 dB-Hz at horizon, 50 dB-Hz at zenith (linear with elevation)

License

MIT

About

GPS NMEA receiver simulator with real orbital mechanics

Resources

Stars

0 stars

Watchers

1 watching

Forks

Contributors

Languages