Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve surveying and allow BRDC navigation #246

Merged
merged 32 commits into from
May 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
773fd4d
Unlock Navigation without SP3
gwbres May 14, 2024
b8649b9
Simple orbit plot is missing in this condition
gwbres May 15, 2024
865fe9f
upgrade to hifitime v4; radio navigation is faulty due to timing issues
gwbres May 15, 2024
f3cc27d
fix epoch gregorian decomposition
gwbres May 15, 2024
40aff32
upgrade to latest nyx & hifitime
gwbres May 15, 2024
8e0ce51
upgrade to latest nyx & hifitime
gwbres May 15, 2024
e88546c
Add more TOE/Ephemeris tests
gwbres May 16, 2024
595805e
run linter
gwbres May 16, 2024
b0c1a3e
fix timescale
gwbres May 16, 2024
f4ba890
reworking nav interface
gwbres May 17, 2024
ead3a38
improving time and orbit interface
gwbres May 17, 2024
8a74070
working on keplerian nav
gwbres May 17, 2024
0538c25
working on keplerian nav
gwbres May 17, 2024
f9185dc
CPP and Brdc navigation
gwbres May 18, 2024
dc45975
Improve docs
gwbres May 18, 2024
c5806dd
Clock NAV without CLK RINEX but SP3 only
gwbres May 18, 2024
457f806
Clock NAV without CLK RINEX, without SP3
gwbres May 18, 2024
ba64b11
improve PPP presentation
gwbres May 18, 2024
670e62b
update readme
gwbres May 18, 2024
05c210c
asbolute/relative positioning
gwbres May 18, 2024
ab99436
remove toc_i
gwbres May 19, 2024
ccd14b6
BeiDou positioning
gwbres May 19, 2024
63a4683
remove requirement for apriori position
gwbres May 19, 2024
65e84de
fix warnings
gwbres May 19, 2024
67232b9
fix branches
gwbres May 19, 2024
9de1d8c
run linter
gwbres May 20, 2024
6b7e296
Merge branch 'main' into no-sp3
gwbres May 20, 2024
6680d9b
improve readme
gwbres May 20, 2024
973348c
improve Ui and general interface
gwbres May 20, 2024
e9443a5
improve Ui
gwbres May 20, 2024
957fa00
add P2 signal
gwbres May 20, 2024
d5bcd25
rename to time_scale
gwbres May 20, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 10 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,19 @@ You can also open a [Discussion](https://github.com/georust/rinex/discussions) o

- Fast
- Parse and render reports in a few seconds
- Resolve PVT solutions as well
- Perform precise Geodetic surveys in a few seconds
- Open sources
- Read and access all the code
- All examples based on Open data
- Efficient seamless compression / decompression
- Hatanaka (OBS_RINEX) and Gzip are built in
- All modern GNSS constellations, codes and signals
- Surveying with GPS, Galileo, BeiDou and QZSS
- Time scales: GPST, QZSST, BDT, GST, UTC, TAI
- Efficient seamless compression and decompression
- RINEX V4 full support
- All RINEX formats supported (see following table)
- High Precision Clock RINEX products
- High Precision Orbital (SP3) products [SP3](https://docs.rs/sp3/1.0.7/sp3/)
- DORIS (special RINEX) by ESA
- All modern GNSS constellations, codes and signals
- Time scales: GPST, BDT, GST, UTC
- 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)
Expand All @@ -45,11 +45,8 @@ You can also open a [Discussion](https://github.com/georust/rinex/discussions) o

## Disadvantages :warning:

- QZSST is not supported until next release
- PPP is work in progress
- Navigation is only available in Galileo and GPS mode.
QZSST comes next.
BDS and IRNSS will either come at the same time or shortly after.
- 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
- File production might lack some features, mostly because we're currently focused on data processing

Expand Down
12 changes: 6 additions & 6 deletions rinex-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,20 @@ map_3d = "0.1.5"
colorous = "1.0"
horrorshow = "0.8"
clap = { version = "4.4.13", features = ["derive", "color"] }
hifitime = { version = "3.9.0", features = ["serde", "std"] }
gnss-rs = { version = "2.1.3" , features = ["serde"] }
hifitime = { git = "https://github.com/nyx-space/hifitime.git", branch = "master", features = ["serde", "std"] }
gnss-rs = { git = "https://github.com/rtk-rs/gnss", branch = "main", features = ["serde"] }
rinex = { path = "../rinex", version = "=0.16.1", features = ["full"] }
plotly = { git = "https://github.com/plotly/plotly.rs", branch = "main" }
rinex-qc = { path = "../rinex-qc", version = "=0.1.14", features = ["serde"] }
sp3 = { path = "../sp3", version = "=1.0.8", features = ["serde", "flate2"] }
serde = { version = "1.0", default-features = false, features = ["derive"] }


# solver
gnss-rtk = { version = "0.4.5", features = ["serde"] }
# gnss-rtk = { version = "0.4.5", features = ["serde"] }
# gnss-rtk = { path = "../../rtk-rs/gnss-rtk", features = ["serde"] }
# gnss-rtk = { git = "https://github.com/rtk-rs/gnss-rtk", branch = "main", features = ["serde"] }
gnss-rtk = { git = "https://github.com/rtk-rs/gnss-rtk", branch = "main", features = ["serde"] }

# cggtts
cggtts = { version = "4.1.4", features = ["serde", "scheduler"] }
# cggtts = { version = "4.1.4", features = ["serde", "scheduler"] }
# cggtts = { path = "../../cggtts/cggtts", features = ["serde", "scheduler"] }
cggtts = { git = "https://github.com/gwbres/cggtts", branch = "dev", features = ["serde", "scheduler"] }
2 changes: 1 addition & 1 deletion rinex-cli/config/rtk/gpst_cpp_basic.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"method": "CodePPP",
"method": "CPP",
"timescale": "GPST",
"interp_order": 17,
"min_sv_elevation": 5.0,
Expand Down
2 changes: 1 addition & 1 deletion rinex-cli/config/rtk/gpst_cpp_kf.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"method": "CodePPP",
"method": "CPP",
"timescale": "GPST",
"interp_order": 17,
"min_sv_elev": 5.0,
Expand Down
1 change: 1 addition & 0 deletions rinex-cli/src/graph/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,7 @@ fn gnss_combination_plot(matches: &ArgMatches) -> bool {
/* Returns True if Navigation plot is to be generated */
fn navigation_plot(matches: &ArgMatches) -> bool {
matches.get_flag("skyplot")
|| matches.get_flag("orbit")
|| matches.get_flag("orbit-residual")
|| matches.get_flag("sv-clock")
}
Expand Down
51 changes: 21 additions & 30 deletions rinex-cli/src/positioning/cggtts/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,6 @@ use gnss::prelude::{Constellation, SV};

use rinex::{carrier::Carrier, prelude::Observable};

use super::cast_rtk_carrier;
use super::interp::TimeInterpolator;

use rtk::prelude::{
Candidate,
Duration,
Expand All @@ -30,9 +27,16 @@ use cggtts::{
track::{FitData, GlonassChannel, SVTracker, Scheduler},
};

use crate::cli::Context;
use crate::positioning::{
bd_model, kb_model, ng_model, tropo_components, Error as PositioningError,
use crate::{
cli::Context,
positioning::{
bd_model,
cast_rtk_carrier,
kb_model,
ng_model, //tropo_components,
Error as PositioningError,
Time,
},
};

// fn reset_sv_tracker(sv: SV, trackers: &mut HashMap<(SV, Observable), SVTracker>) {
Expand Down Expand Up @@ -61,7 +65,7 @@ use crate::positioning::{
pub fn resolve<I>(
ctx: &Context,
mut solver: Solver<I>,
rx_lat_ddeg: f64,
// rx_lat_ddeg: f64,
matches: &ArgMatches,
) -> Result<Vec<Track>, PositioningError>
where
Expand All @@ -83,26 +87,13 @@ where
// infaillible, at this point
let obs_data = ctx.data.observation().unwrap();
let nav_data = ctx.data.brdc_navigation().unwrap();

let clk_data = ctx.data.clock();
let meteo_data = ctx.data.meteo();

let sp3_has_clock = ctx.data.sp3_has_clock();
if clk_data.is_none() && sp3_has_clock {
if let Some(sp3) = ctx.data.sp3() {
warn!("Using clock states defined in SP3 file - CLK product should be prefered");
if sp3.epoch_interval >= Duration::from_seconds(300.0) {
warn!("Interpolating clock states from low sample rate SP3 will most likely introduce errors");
}
}
}
// let meteo_data = ctx.data.meteo(); //TODO

let dominant_sampling_period = obs_data
.dominant_sample_rate()
.expect("RNX2CGGTTS requires steady GNSS observations");

let mut interp = TimeInterpolator::from_ctx(ctx);
debug!("Clock interpolator created");
let mut time = Time::from_ctx(ctx);

// CGGTTS specifics
let mut tracks = Vec::<Track>::new();
Expand All @@ -120,8 +111,8 @@ where
continue;
}

// Nearest TROPO
let zwd_zdd = tropo_components(meteo_data, *t, rx_lat_ddeg);
// Nearest TROPO: TODO
// let zwd_zdd = tropo_components(meteo_data, *t, rx_lat_ddeg);

for (sv, observations) in vehicles {
let sv_eph = nav_data.sv_ephemeris(*sv, *t);
Expand All @@ -134,7 +125,7 @@ where

// determine TOE
let (_toe, sv_eph) = sv_eph.unwrap();
let clock_corr = match interp.next_at(*t, *sv) {
let clock_corr = match time.next_at(*t, *sv) {
Some(dt) => dt,
None => {
error!("{:?} ({}) - failed to determine clock correction", *t, *sv);
Expand All @@ -150,8 +141,8 @@ where
};

let tropo_bias = TroposphereBias {
total: None, //TODO
zwd_zdd,
total: None, //TODO
zwd_zdd: None, // TODO
};

// tries to form a candidate for each signal
Expand All @@ -177,8 +168,8 @@ where

// attach one phase, if need be
match solver.cfg.method {
Method::SPP => {}, // nothing to do
Method::CodePPP => {}, // nothing to do
Method::SPP => {}, // nothing to do
Method::CPP => {}, // nothing to do
Method::PPP => {
// try to attach phase data
// let to_match =
Expand Down Expand Up @@ -220,7 +211,7 @@ where
// complete if need be
match solver.cfg.method {
Method::SPP => {}, // nothing to do
Method::CodePPP => {
Method::CPP => {
// Attach secondary PR
for (second_obs, second_data) in observations {
let rhs_carrier =
Expand Down
Original file line number Diff line number Diff line change
@@ -1,38 +1,31 @@
mod orbit;
pub use orbit::Interpolator as OrbitInterpolator;

mod time;
pub use time::Interpolator as TimeInterpolator;

use rinex::prelude::{Duration, Epoch};

/// Interpolators internal buffer.
/// Both interpolators, whether it be Temporal or Position, both work on 3D values represented as f64 double precision.
pub trait Buffer {
/// Interpolator buffer Trait.
pub trait Buffer<T> {
/// Memory allocation
fn malloc(size: usize) -> Self;
/// Return current number of symbols
fn len(&self) -> usize;
/// Return symbol by index
fn get(&self, index: usize) -> Option<&(Epoch, (f64, f64, f64))>;
fn get(&self, index: usize) -> Option<&(Epoch, T)>;
/// Clear all symbols
fn clear(&mut self);
/// New new symbol
fn push(&mut self, x_j: (Epoch, (f64, f64, f64)));
fn push(&mut self, x_j: (Epoch, T));
/// Returns internal symbols
fn snapshot(&self) -> &[(Epoch, (f64, f64, f64))];
fn snapshot(&self) -> &[(Epoch, T)];
/// Returns true if an interpolation of this order is feasible @ t
fn feasible(&self, order: usize, t: Epoch) -> bool;
/// Returns direct output in rare cases where Interpolation is not needed.
/// This avoids introduction extra bias in the measurement, due to the interpolation process.
fn direct_output(&self, t: Epoch) -> Option<&(f64, f64, f64)> {
fn direct_output(&self, t: Epoch) -> Option<&T> {
self.snapshot()
.iter()
.filter_map(|(k, v)| if *k == t { Some(v) } else { None })
.reduce(|k, _| k)
}
/// Returns mutable internal symbols
fn snapshot_mut(&mut self) -> &mut [(Epoch, (f64, f64, f64))];
fn snapshot_mut(&mut self) -> &mut [(Epoch, T)];
/// Returns latest interval
fn last_dt(&self) -> Option<(Epoch, Duration)> {
if self.len() > 1 {
Expand All @@ -44,10 +37,9 @@ pub trait Buffer {
}
}
/// Streams data in, in chronological order with gap intolerance.
fn fill(&mut self, x_j: (Epoch, (f64, f64, f64))) {
fn fill(&mut self, x_j: (Epoch, T)) {
if let Some((last, dt)) = self.last_dt() {
if (x_j.0 - last).to_seconds().is_sign_positive() {
// NB Should we make gap tolerance more flexible ?
if (x_j.0 - last) > dt {
warn!("{} - {} gap detected - buffer reset", x_j.0, x_j.0 - last);
self.clear();
Expand Down
Loading
Loading