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

RTK V0_4_5 #243

Merged
merged 9 commits into from
May 13, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
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
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,10 +103,10 @@ RINEX formats & applications
| Observation (OBS) | :heavy_check_mark:| :heavy_check_mark: | :heavy_check_mark: :chart_with_upwards_trend: | Phase, Pseudo Range, Doppler, SSI | Epoch | GNSS (any) |
| CRINEX (Compressed OBS) | :heavy_check_mark:| RNX2CRX1 :heavy_check_mark: RNX2CRX3 :construction: | :heavy_check_mark: :chart_with_upwards_trend: | Phase, Pseudo Range, Doppler, SSI | Epoch | GNSS (any) |
| Meteorological data (MET) | :heavy_check_mark:| :heavy_check_mark: | :heavy_check_mark: :chart_with_upwards_trend: | Meteo sensors data (Temperature, Moisture..) | Epoch | UTC |
| Clocks (CLK) | :heavy_check_mark:| :construction: | :heavy_check_mark: :chart_with_upwards_trend: | Precise SV and Reference Clock states | Epoch | UTC |
| Clocks (CLK) | :heavy_check_mark:| :construction: | :heavy_check_mark: :chart_with_upwards_trend: | Precise SV and Reference Clock states | Epoch | GNSS (any) |
| Antenna (ATX) | :heavy_check_mark:| :construction: | :construction: | Precise RX/SV Antenna calibration | `antex::Antenna` | :heavy_minus_sign: |
| Ionosphere Maps (IONEX) | :heavy_check_mark:| :construction: | :heavy_check_mark: :chart_with_upwards_trend: | Ionosphere Electron density | Epoch | UTC |
| DORIS RINEX | :heavy_check_mark:| :construction: | :construction: | Temperature, Moisture, Pseudo Range and Phase observations | Epoch | TAI |
| DORIS RINEX | :heavy_check_mark:| :construction: | :heavy_check_mark: | Temperature, Moisture, Pseudo Range and Phase observations | Epoch | TAI |
| SINEX (SNX) | :construction: | :construction: | :heavy_minus_sign: | SINEX are special RINEX, they are managed by a dedicated [core library](sinex/) | Epoch | :question: |
| Troposphere (TRO) | :construction: | :construction: | :question: | Troposphere modeling | Epoch | :question: |
| Bias (BIA) | :heavy_check_mark: | :construction: | :question: | Bias estimates, like DCB.. | Epoch | :question: |
Expand Down
6 changes: 2 additions & 4 deletions rinex-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,14 @@ clap = { version = "4.4.13", features = ["derive", "color"] }
hifitime = { version = "3.9.0", features = ["serde", "std"] }
gnss-rs = { version = "2.1.3" , 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"] }

# plotly
plotly = "0.8.4"
# plotly = { git = "https://github.com/gwbres/plotly", branch = "density-mapbox" }

# solver
gnss-rtk = { version = "0.4.4", 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"] }

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"method": "CodePPP",
"timescale": "GPST",
"interp_order": 13,
"min_sv_elevation": 1.0,
"interp_order": 17,
"min_sv_elevation": 5.0,
"solver": {
"filter": "LSQ",
"gdop_threshold": 10.0
Expand Down
18 changes: 18 additions & 0 deletions rinex-cli/config/rtk/gpst_cpp_kf.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"method": "CodePPP",
"timescale": "GPST",
"interp_order": 17,
"min_sv_elev": 5.0,
"solver": {
"filter": "Kalman",
"gdop_threshold": 10.0
},
"modeling": {
"iono_delay": true,
"tropo_delay": true,
"earth_rotation": true,
"sv_clock_bias": true,
"sv_total_group_delay": true,
"relativistic_clock_bias": true
}
}
2 changes: 1 addition & 1 deletion rinex-cli/config/rtk/gpst_spp_basic.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"method": "SPP",
"timescale": "GPST",
"interp_order": 11,
"min_sv_elevation": 10.0,
"min_sv_elevation": 5.0,
"solver": {
"filter": "LSQ",
"gdop_threshold": 10.0
Expand Down
66 changes: 55 additions & 11 deletions rinex-cli/src/cli/graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,43 +6,77 @@ pub fn subcommand() -> Command {
.long_flag("graph")
.arg_required_else_help(true)
.about(
"RINEX data visualization (signals, orbits..), rendered as HTML or CSV in the workspace.",
"RINEX data analysis and visualization, rendered as HTML or CSV in the workspace.",
)
.long_about("Analysis and plots (in HTML).
When Observations are present, whether they come from Observation RINEX, Meteo or DORIS RINEX,
we can export the results as CSV too. This is particularly useful to export the results of the analysis
to other tools.")
.arg(
Arg::new("csv")
.long("csv")
.action(ArgAction::SetTrue)
.help("Generate CSV files along HTML plots.")
.help("Extract Data as CSV along HTML plots. See --help.")
.long_help("This is particularly helpful if you are interested in
using our toolbox as data parser and preprocessor and inject the results to third party programs.")
)
.next_help_heading(
"RINEX dependent visualizations.
Will only generate graphs if related dataset is present.",
)
.next_help_heading("GNSS observations (requires OBS RINEX)")
.next_help_heading("Observations rendering (OBS, Meteo, DORIS)")
.arg(
Arg::new("obs")
.short('o')
.long("obs")
.action(ArgAction::SetTrue)
.help(
"Plot all observables.
When OBS RINEX is provided, this will plot raw phase, dopplers and SSI.
When METEO RINEX is provided, data from meteo sensors is plotted too.",
),
.help("Plot all observables described in either Observation, Meteo or DORIS RINEX. See --help")
.long_help("Use this option to plot all observations.
OBS RINEX gives GNSS signals observations, but we also support Meteo RINEX and DORIS (special observation) RINEX.

Example (1): render GNSS signals (all of them, whether it be Phase or PR) for GPS.
Use CSV for extract and export as well:

./target/release/rinex-cli \\
-f test_resources/CRNX/V3/ESBC00DNK_R_20201770000_01D_30S_MO.crx.gz \\
-g --obs --csv

Example (2): render meteo sensor observations similary.

./target/release/rinex-cli \\
-f test_resources/MET/V3/POTS00DEU_R_20232540000_01D_05M_MM.rnx.gz \\
-g --obs --csv

Example (3): render DORIS observations similarly.

./target/release/rinex-cli \\
-f test_resources/MET/V3/POTS00DEU_R_20232540000_01D_05M_MM.rnx.gz \\
-g --obs --csv

Example (4): render OBS + Meteo combination at once.
RINEX-Cli allows loading OBS + Meteo in one session.
In graph mode, this means we can render both in a single run.

./target/release/rinex-cli \\
-f test_resources/CRNX/V3/ESBC00DNK_R_20201770000_01D_30S_MO.crx.gz \\
-f test_resources/MET/V3/POTS00DEU_R_20232540000_01D_05M_MM.rnx.gz \\
-g --obs --csv
")

)
.next_help_heading("GNSS signals (requires OBS and/or DORIS RINEX)")
.arg(
Arg::new("dcb")
.long("dcb")
.action(ArgAction::SetTrue)
.help("Plot Differential Code Bias. Requires OBS RINEX."),
.help("Plot Differential Code Bias."),
)
.arg(
Arg::new("mp")
.long("mp")
.action(ArgAction::SetTrue)
.help("Plot Code Multipath. Requires OBS RINEX."),
.help("Plot Code Multipath."),
)
.next_help_heading("GNSS combinations (requires OBS RINEX)")
.arg(
Arg::new("if")
.short('i')
Expand Down Expand Up @@ -149,4 +183,14 @@ It is the temporal equuivalent to |BRDC-SP3| requested with --sp3-residual.")
.action(ArgAction::SetTrue)
.help("Plot ionospheric delay per signal & SV, at latitude and longitude of signal sampling."),
)
.next_help_heading("DORIS (requires at least one DORIS file)").
arg(
Arg::new("acorr")
.short('a')
.long("acorr")
.action(ArgAction::SetTrue)
.help("Compute and render the autocorrelation of (precise) Pseudo Range and Dopplers from the DORIS measurement,
from all contained stations. See --help")
.long_help("TODO")
)
}
17 changes: 10 additions & 7 deletions rinex-cli/src/cli/positioning.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,18 @@ pub fn subcommand() -> Command {
.short_flag('p')
.arg_required_else_help(false)
.about("Precise Positioning opmode.
Use this mode to resolve precise positions and local time from RINEX dataset.
You should provide Observations from a unique receiver.")
Use this mode to resolve Position Velocity and Time (PVT) solutions from one GNSS context.")
.arg(Arg::new("cfg")
.short('c')
.long("cfg")
.value_name("FILE")
.required(false)
.action(ArgAction::Append)
.help("Pass a Position Solver configuration file (JSON).
.help("Pass a Position Solver configuration file (JSON). See --help.")
.long_help("
Use [https://github.com/georust/rinex/rinex-cli/config.rtk] as a starting point.
[https://docs.rs/gnss-rtk/latest/gnss_rtk/prelude/struct.Config.html] is the structure to represent in JSON.
Refer to [https://docs.rs/gnss-rtk/latest/gnss_rtk/prelude/enum.Method.html] for solving strategies.
See [] for meaningful examples."))
Our Wiki pages contains several examples."))
.arg(Arg::new("gpx")
.long("gpx")
.action(ArgAction::SetTrue)
Expand All @@ -31,8 +31,11 @@ See [] for meaningful examples."))
.arg(Arg::new("cggtts")
.long("cggtts")
.action(ArgAction::SetTrue)
.help("Activate CGGTTS special solver.
Wrapps PVT solutions as CGGTTS file(s) for remote clock comparison (time transfer)."))
.help("Activate CGGTTS special solver. See --help.")
.long_help("In CGGTTS opmode, we're only interested in resolving the local offset to the constellation.
Navigation mode is set to [TimeOnly] and we navigate using every single vehicle in sight fitting criteria.
CGGTTS opmode is therefore more demanding as it runs the algorithm many more times than regular PPP.
The PVT solutions are then formatted as a CGGTTS file which is used to compare remote clocks to one another, from a common GNSS constellation."))
.arg(Arg::new("tracking")
.long("trk")
.short('t')
Expand Down
35 changes: 17 additions & 18 deletions rinex-cli/src/graph/record/ionex.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
//use itertools::Itertools;
use crate::graph::PlotContext;
use plotly::color::NamedColor;
use plotly::common::{Marker, MarkerSymbol};
use plotly::layout::MapboxStyle;
//use plotly::DensityMapbox;
use plotly::ScatterMapbox;
use plotly::{
color::NamedColor,
common::{Marker, MarkerSymbol},
layout::MapboxStyle,
{DensityMapbox, ScatterMapbox},
};
use rinex::prelude::Rinex;

pub fn plot_tec_map(data: &Rinex, _borders: ((f64, f64), (f64, f64)), plot_ctx: &mut PlotContext) {
let _cmap = colorous::TURBO;
//TODO
//let hover_text: Vec<String> = ctx.primary_data().epoch().map(|e| e.to_string()).collect();
let hover_text: Vec<String> = data.epoch().map(|e| e.to_string()).collect();
/*
* TEC map visualization
* plotly-rs has no means to animate plots at the moment
Expand Down Expand Up @@ -41,7 +40,7 @@ pub fn plot_tec_map(data: &Rinex, _borders: ((f64, f64), (f64, f64)), plot_ctx:
},
)
.collect();
let _tec: Vec<_> = data
let tec: Vec<_> = data
.tec()
.filter_map(
|(t, _, _, _, tec)| {
Expand Down Expand Up @@ -75,14 +74,14 @@ pub fn plot_tec_map(data: &Rinex, _borders: ((f64, f64), (f64, f64)), plot_ctx:
plot_ctx.add_trace(grid);

//let map = AnimatedDensityMapbox::new(lat.clone(), lon.clone(), z)
//let map = DensityMapbox::new(lat.clone(), lon.clone(), tec.clone())
// //.title("TEST")
// .name(epoch.to_string())
// .opacity(0.66)
// //.hover_text_array(hover_text.clone())
// .zauto(true)
// //.animation_frame("test")
// .zoom(3);
//plot_ctx.add_trace(map);
let map = DensityMapbox::new(lat.clone(), lon.clone(), tec.clone())
//.title("TEST")
.name(epoch.to_string())
.opacity(0.66)
//.hover_text_array(hover_text.clone())
.zauto(true)
//.animation_frame("test")
.zoom(3);
plot_ctx.add_trace(map);
}
}
Loading
Loading