Skip to content

Commit

Permalink
BINEX (#274)
Browse files Browse the repository at this point in the history
* BINEX

    * introducing BINEX parser

---------

Signed-off-by: Guillaume W. Bres <[email protected]>
  • Loading branch information
gwbres authored Oct 13, 2024
1 parent 7f8b1c6 commit c317d8a
Show file tree
Hide file tree
Showing 40 changed files with 4,609 additions and 13 deletions.
38 changes: 38 additions & 0 deletions .github/workflows/benchmarks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: Benchmarks

on:
push:
branches:
- main
tags:
- "*"
pull_request:
branches:
- main

env:
RUST_BACKTRACE: 1
CARGO_TERM_COLOR: always

jobs:
benchmark:
name: Benchmarking
runs-on: ubuntu-latest
strategy:
fail-fast: true
matrix:
include:
- name: BINEX Benchmark
folder: "binex"
steps:
- name: Checkout sources
uses: actions/checkout@v4
- name: Install stable toolchain
uses: dtolnay/rust-toolchain@master
with:
toolchain: stable
- name: ${{ matrix.name }}
run: cargo bench -p ${{ matrix.folder }} > benchmark.txt

- name: Parse and publish summary
run: python tools/parse_crit_benchmark.py < benchmark.txt >> $GITHUB_STEP_SUMMARY
3 changes: 3 additions & 0 deletions .github/workflows/daily.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ jobs:
- name: RINEX All-features
folder: rinex
opts: --all-features
- name: BINEX
folder: binex
opts: --all-features
- name: SP3 default
folder: sp3
opts: -r
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ jobs:
- crate: rinex
- crate: sp3
- crate: sinex
- crate: binex
- crate: rinex-qc
- crate: ublox-rnx
- crate: rnx2crx
Expand Down
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
resolver = "2"

members = [
"binex",
"crx2rnx",
"qc-traits",
"rinex",
Expand Down
23 changes: 10 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,10 @@ You can also open a [Discussion](https://github.com/georust/rinex/discussions) o
## Advantages :rocket:

- Fast
- Parse and render reports in a few seconds
- Perform precise Geodetic surveys in a few seconds
- Open sources
- Read and access all the code
- All examples based on Open data
- Render High level Geodetic survey reports
- Resolve PPP solutions in a few seconds
- Open sources: read and access all the code!
- Self sustained examples and tutorials: data hosted within this repo
- All modern GNSS constellations, codes and signals
- Surveying with GPS, Galileo, BeiDou and QZSS
- Time scales: GPST, QZSST, BDT, GST, UTC, TAI
Expand All @@ -34,21 +33,18 @@ You can also open a [Discussion](https://github.com/georust/rinex/discussions) o
- High Precision Clock RINEX products (for PPP)
- High Precision Orbital [SP3 for PPP](https://docs.rs/sp3/1.0.7/sp3/)
- DORIS (special RINEX)
- Several pre-processing algorithms:
- [File merging](https://github.com/georust/rinex/wiki/file-merging)
- [Time binning](https://github.com/georust/rinex/wiki/time-binning)
- [Filtering](https://github.com/georust/rinex/wiki/Preprocessing)
- Several post-processing operations
- [File Operations](https://github.com/georust/rinex/wiki/fops)
- Many pre-processing algorithms including Filter Designer
- Several file operations: merging, splitting, time binning (batch)
- Post processing:
- [Position solver](https://github.com/georust/rinex/wiki/Positioning)
- [CGGTTS solver](https://github.com/georust/rinex/wiki/CGGTTS)
- [Graphical QC](https://github.com/georust/rinex/wiki/Graph-Mode)

## Disadvantages :warning:

- BINEX support is currently work in progress
- Navigation is currently not feasible with Glonass and IRNSS
- Differential navigation (SBAS, DGNSS or RTK) is not support yet
- Our applications do not accept BINEX or other proprietary formats
- Our applications do not accept proprietary formats like Septentrio for example
- File production might lack some features, mostly because we're currently focused on data processing

## Repository
Expand All @@ -62,6 +58,7 @@ The application is auto-generated for a few architectures, you can directly
* [`tutorials`](tutorials/) is a superset of scripts (Linux/MacOS compatible)
to get started quickly. The examples span pretty much everything our applications allow.
* [`sp3`](sp3/) High Precision Orbits (by IGS)
* [`binex`](binex/) BINEX Encoding and Decoding library
* [`rnx2crx`](rnx2crx/) is a RINEX compressor (RINEX to Compact RINEX)
* [`crx2rnx`](crx2rnx/) is a CRINEX decompresor (Compact RINEX to RINEX)
* [`rinex-qc`](rinex-qc/) is a library dedicated to RINEX files analysis
Expand Down
36 changes: 36 additions & 0 deletions binex/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
[package]
name = "binex"
version = "0.2.0"
license = "MIT OR Apache-2.0"
authors = ["Guillaume W. Bres <[email protected]>"]
description = "BINEX Binary RINEX encoder and decoder"
homepage = "https://github.com/georust/rinex"
repository = "https://github.com/georust/rinex"
keywords = ["rinex", "timing", "gps", "glonass", "galileo"]
categories = ["science", "science::geo", "parsing"]
edition = "2021"
rust-version = "1.64"

[features]
default = ["flate2"]

[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docrs", "--generate-link-to-definition"]

[dependencies]
log = "0.4"
thiserror = "1"
flate2 = { version = "1.0.34", optional = true }
hifitime = { version = "4.0.0-alpha", features = ["serde", "std"] }

[dev-dependencies]
criterion = "0.5.1"

[[bench]]
name = "encoding"
harness = false

[[bench]]
name = "decoding"
harness = false
43 changes: 43 additions & 0 deletions binex/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# BINEX

[![Rust](https://github.com/georust/rinex/actions/workflows/rust.yml/badge.svg)](https://github.com/georust/rinex/actions/workflows/rust.yml)
[![Rust](https://github.com/georust/rinex/actions/workflows/daily.yml/badge.svg)](https://github.com/georust/rinex/actions/workflows/daily.yml)
[![crates.io](https://img.shields.io/crates/v/binex.svg)](https://crates.io/crates/binex)
[![crates.io](https://docs.rs/binex/badge.svg)](https://docs.rs/binex/badge.svg)

BINEX is a simple library to decode and encode BINEX messages.
BINEX stands for BINary EXchange and is the "real time" stream oriented
version of the RINEX format.

RINEX is a readable text format which is based on line termination and allows describing
from the minimum requirement for GNSS navigation up to very precise navigation and
other side GNSS applications.

BINEX is a binary stream (non readable) conversion to that, dedicated to GNSS receivers and hardware interfacing.
Like RINEX, it is an open source format, the specifications are described by
[UNAVCO here](https://www.unavco.org/data/gps-gnss/data-formats/binex).

This library allows easy message encoding and decoding, and aims at providing seamless
convertion from RINEX back and forth.

## Message Decoding

Use the BINEX `Decoder` to decode messages from a `Readable` interface:

```rust
```

## Message forging

The BINEX library allows easy message forging. Each message can be easily encoded and then
streamed into a `Writable` interface:

```rust
```

## Licensing

Licensed under either of:

* Apache Version 2.0 ([LICENSE-APACHE](http://www.apache.org/licenses/LICENSE-2.0))
* MIT ([LICENSE-MIT](http://opensource.org/licenses/MIT)
55 changes: 55 additions & 0 deletions binex/benches/decoding.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
use binex::prelude::{
EphemerisFrame, Epoch, Message, MonumentGeoMetadata, MonumentGeoRecord, Record, TimeResolution,
};
use criterion::{black_box, criterion_group, criterion_main, Criterion};

#[allow(unused_must_use)]
pub fn criterion_benchmark(c: &mut Criterion) {
let t0 = Epoch::from_gpst_seconds(10.0);
let meta = MonumentGeoMetadata::RNX2BIN;

let record = MonumentGeoRecord::new(t0, meta)
.with_comment("This is a test")
.with_climatic_info("basic info")
.with_geophysical_info("another field")
.with_user_id("Test");

let record = Record::new_monument_geo(record);
let msg = Message::new(true, TimeResolution::QuarterSecond, false, false, record);

let mut buf = [0; 256];
msg.encode(&mut buf).unwrap();

c.bench_function("decoding-00", |b| {
b.iter(|| {
black_box(Message::decode(&buf).unwrap());
})
});

let record = Record::new_ephemeris_frame(EphemerisFrame::GPSRaw(Default::default()));
let msg = Message::new(true, TimeResolution::QuarterSecond, false, false, record);

let mut buf = [0; 256];
msg.encode(&mut buf).unwrap();

c.bench_function("decoding-01-00", |b| {
b.iter(|| {
black_box(Message::decode(&buf).unwrap());
})
});

let record = Record::new_ephemeris_frame(EphemerisFrame::GPS(Default::default()));
let msg = Message::new(true, TimeResolution::QuarterSecond, false, false, record);

let mut buf = [0; 256];
msg.encode(&mut buf).unwrap();

c.bench_function("decoding-01-01", |b| {
b.iter(|| {
black_box(Message::decode(&buf).unwrap());
})
});
}

criterion_group!(benches, criterion_benchmark);
criterion_main!(benches);
47 changes: 47 additions & 0 deletions binex/benches/encoding.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
use binex::prelude::{
EphemerisFrame, Epoch, Message, MonumentGeoMetadata, MonumentGeoRecord, Record, TimeResolution,
};
use criterion::{black_box, criterion_group, criterion_main, Criterion};

#[allow(unused_must_use)]
pub fn criterion_benchmark(c: &mut Criterion) {
let mut buf = [0; 256];
let t0 = Epoch::from_gpst_seconds(10.0);
let meta = MonumentGeoMetadata::RNX2BIN;

let record = MonumentGeoRecord::new(t0, meta)
.with_comment("This is a test")
.with_climatic_info("basic info")
.with_geophysical_info("another field")
.with_user_id("Test");

let record = Record::new_monument_geo(record);
let msg = Message::new(true, TimeResolution::QuarterSecond, false, false, record);

c.bench_function("encoding-00", |b| {
b.iter(|| {
black_box(msg.encode(&mut buf).unwrap());
})
});

let record = Record::new_ephemeris_frame(EphemerisFrame::GPSRaw(Default::default()));
let msg = Message::new(true, TimeResolution::QuarterSecond, false, false, record);

c.bench_function("encoding-01-00", |b| {
b.iter(|| {
black_box(msg.encode(&mut buf).unwrap());
})
});

let record = Record::new_ephemeris_frame(EphemerisFrame::GPS(Default::default()));
let msg = Message::new(true, TimeResolution::QuarterSecond, false, false, record);

c.bench_function("encoding-01-01", |b| {
b.iter(|| {
black_box(msg.encode(&mut buf).unwrap());
})
});
}

criterion_group!(benches, criterion_benchmark);
criterion_main!(benches);
35 changes: 35 additions & 0 deletions binex/src/constants.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
pub struct Constants {}

impl Constants {
/// Forward Little Endian stream with standard CRC
pub const FWDSYNC_LE_STANDARD_CRC: u8 = 0xC2;

/// Forward Big Endian stream with standard CRC
pub const FWDSYNC_BE_STANDARD_CRC: u8 = 0xE2;

/// Forward Little Endian stream with enhanced CRC
pub const FWDSYNC_LE_ENHANCED_CRC: u8 = 0xC8;

/// Forward Big Endian stream with enhanced CRC
pub const FWDSYNC_BE_ENHANCED_CRC: u8 = 0xE8;

/// Rerversed Little Endian stream with standard CRC
pub const REVSYNC_LE_STANDARD_CRC: u8 = 0xD2;

/// Rerversed Big Endian stream with standard CRC
pub const REVSYNC_BE_STANDARD_CRC: u8 = 0xF2;

/// Rerversed Little Endian stream with enhanced CRC
pub const REVSYNC_LE_ENHANCED_CRC: u8 = 0xD8;

/// Rerversed Big Endian stream with enhanced CRC
pub const REVSYNC_BE_ENHANCED_CRC: u8 = 0xF8;

/// Keep going byte mask in the BNXI algorithm,
/// as per [https://www.unavco.org/data/gps-gnss/data-formats/binex/conventions.html/#ubnxi_details]
pub const BNXI_KEEP_GOING_MASK: u8 = 0x80;

/// Data byte mask in the BNXI algorithm,
/// as per [https://www.unavco.org/data/gps-gnss/data-formats/binex/conventions.html/#ubnxi_details]
pub const BNXI_BYTE_MASK: u8 = 0x7f;
}
Loading

0 comments on commit c317d8a

Please sign in to comment.