Production-grade GNSS data processor: ingest raw u-blox UBX binary data and produce OPUS-compatible RINEX observation files with normalization, quality control, and validation.
π Try it now β rinexprep.jv.ag
Note
π· Vibe-coded with reckless enthusiasm. This project was conjured into existence through the power of AI-assisted development and an unwavering refusal to ship anything that looks like it belongs on a VT100 terminal. GNSS data processing is arcane enough without the UI making you feel like you're filing taxes in 1987. If you find a bug, it was probably vibing too hard.
β
MVP complete β see docs/PLAN.md for the full design document.
- Web UI β drag-and-drop UBX upload, satellite visibility charts, skyview polar plot, interactive trim sliders, RINEX download
- Auto-trim β detects survey setup/teardown instability and trims to clean 00/30s grid boundaries
- UBX parser β stream-based RXM-RAWX binary decoder, no external tools (no RTKLIB, no convbin)
- RINEX 2.11 + 3.03 β OPUS-grade output with correct L2C mapping (C2, never P2)
- 30s normalization β epoch grid snapping, GPS-only filtering, deduplication
- QC engine β OPUS readiness scoring with satellite visibility and L2 coverage metrics
- OPUS submission β submit directly to NGS OPUS from the web UI
- CLI β
convert,batch, andservecommands for headless/scripted use - Single Docker image β Go backend + embedded React frontend, one container, runs anywhere
RinexPrep matches or exceeds RTKLIB conversion quality for OPUS submissions. Real-world testing shows 97% ambiguity resolution, 0.013m RMS, and millimeter-accurate coordinates β on par with commercial workflows.
Where it differs from RTKLIB:
- Gen9 (F9P) optimized carrier phase filtering β understands u-blox half-cycle and sub-half-cycle flags natively, recovering ~500 more L2 observations that RTKLIB drops
- Zero-gap epoch recovery β intelligent 30s grid decimation snaps observations to the nearest grid point instead of discarding near-misses, producing gapless observation files
- RTKLIB-compatible receiver clock correction β applies TADJ-equivalent clock steering so OPUS sees clean, aligned timestamps
- Complete cycle slip detection β tracks lock time per satellite per frequency with carry-forward across epochs, setting LLI flags where RTKLIB sometimes misses slips
The result is a RINEX file that OPUS processes without warnings and with full L1+L2 dual-frequency coverage.
Visit rinexprep.jv.ag β upload a UBX file, preview satellite visibility, trim, and download OPUS-ready RINEX. No install required.
docker run --rm -p 8080:8080 jakevis/rinexprep:latest
# Open http://localhost:8080# Convert a single UBX file to RINEX 2.11
rinexprep convert --input raw.ubx --output session.obs --format rinex2 --interval 30
# Convert to RINEX 3.03
rinexprep convert --input raw.ubx --output session.rnx --format rinex3
# Convert to both formats at once
rinexprep convert --input raw.ubx --output session --format both
# Batch convert a directory of UBX files
rinexprep batch --input-dir ./ubx_files/ --output-dir ./rinex_out/ --format rinex3
# Print version
rinexprep version# Start with defaults (port 8080, data in ./data/)
rinexprep serve
# Custom port and data directory
rinexprep serve --port 3000 --data-dir /tmp/rinexprep
# Structured JSON logging (for production)
rinexprep serve --port 8080 --data-dir ./data --json-logs# Use the dev container (recommended)
# Open in VS Code β "Reopen in Container"
# Or build locally (requires Go 1.26+ and Node 22+)
make build # β bin/rinexprep
make test # go test -race -coverprofile ./...
make test-short # skip -race flag
make lint # golangci-lint run ./...
make fmt # go fmt + goimports
# Frontend dev (hot reload)
cd web && npm ci && npm run dev
# Run the server locally
go run ./cmd/rinexprep serve --port 8080 --data-dir ./data
# Docker build
make docker-build && make docker-run ββββββββββββββββββββββββββββββββ
β Web UI (React) β
β upload Β· charts Β· trim Β· DL β
ββββββββββββββββ¬ββββββββββββββββ
β REST API
βββββββββββββββΌββββββββββββββββ
β Go Backend β
β β
UBX Binary βββΆ Parser βββΆ Auto-Trim βββΆ Pipeline βββΆ RINEX Writer
β β β β
β βΌ βΌ β
β Instability 30s Grid β
β Detection Snap + Filter β
β β
β QC Engine βββΆ OPUS Score β
ββββββββββββββββββββββββββββββββββββββββ
See docs/PLAN.md for full design documentation.
Contributions are welcome! Please open an issue to discuss proposed changes before submitting a pull request.
- Fork the repository
- Create a feature branch (
git checkout -b feature/my-feature) - Commit your changes
- Push to your branch and open a pull request
This project is licensed under the MIT License β free to use with attribution.