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

Develop #188

Merged
merged 14 commits into from
Nov 30, 2023
2 changes: 1 addition & 1 deletion crx2rnx/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ edition = "2021"
readme = "README.md"

[dependencies]
clap = { version = "4.4.8", features = ["derive", "color"] }
clap = { version = "4.4.10", features = ["derive", "color"] }
rinex = { path = "../rinex", version = "=0.15.1", features = ["serde"] }
4 changes: 2 additions & 2 deletions rinex-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ map_3d = "0.1.5"
# ndarray = "0.15"
colorous = "1.0"
horrorshow = "0.8"
clap = { version = "4.4.8", features = ["derive", "color"] }
clap = { version = "4.4.10", features = ["derive", "color"] }
hifitime = { version = "3.8.4", features = ["serde", "std"] }
gnss-rs = { version = "2.1.2" , features = ["serde"] }
rinex = { path = "../rinex", version = "=0.15.1", features = ["full"] }
Expand All @@ -41,6 +41,6 @@ plotly = "0.8.4"
# plotly = { git = "https://github.com/gwbres/plotly", branch = "density-mapbox" }

# solver
gnss-rtk = { version = "0.2.2", features = ["serde"] }
gnss-rtk = { version = "0.3.0", features = ["serde"] }
# gnss-rtk = { git = "https://github.com/rtk-rs/gnss-rtk", branch = "develop", features = ["serde"] }
# gnss-rtk = { path = "../../rtk-rs/gnss-rtk", features = ["serde"] }
37 changes: 30 additions & 7 deletions rinex-cli/src/cli.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
use clap::{Arg, ArgAction, ArgMatches, ColorChoice, Command};
use gnss_rtk::prelude::Config;
use log::{error, info};
use rinex::prelude::*;
use rinex_qc::QcOpts;

use std::path::Path;
use std::str::FromStr;

use rinex::prelude::*;
use rinex_qc::QcOpts;

use gnss_rtk::prelude::{Config, Mode as SolverMode};

pub struct Cli {
/// Arguments passed by user
matches: ArgMatches,
Expand Down Expand Up @@ -238,13 +241,23 @@ The summary report by default is integrated to the global HTML report."))
.arg(Arg::new("spp")
.long("spp")
.conflicts_with("ppp")
.conflicts_with("lsqspp")
.action(ArgAction::SetTrue)
.help("Enable Single Point Positioning.
Use with ${RUST_LOG} env logger for more information.
Refer to the positioning documentation."))
.arg(Arg::new("lsqspp")
.long("lsqspp")
.conflicts_with("ppp")
.conflicts_with("spp")
.action(ArgAction::SetTrue)
.help("Recursive Weighted Least Square SPP strategy.
Use with ${RUST_LOG} env logger for more information.
Refer to the positioning documentation."))
.arg(Arg::new("ppp")
.long("ppp")
.conflicts_with("spp")
.conflicts_with("lsqspp")
.action(ArgAction::SetTrue)
.help("Enable Precise Point Positioning.
Use with ${RUST_LOG} env logger for more information.
Expand Down Expand Up @@ -440,12 +453,22 @@ Primary RINEX was either loaded with `-f`, or is Observation RINEX loaded with `
pub fn quiet(&self) -> bool {
self.matches.get_flag("quiet")
}
/// Returns true if SPP position solver is enabled
pub fn spp(&self) -> bool {
self.matches.get_flag("spp")
/* returns RTK solver mode to implement */
pub fn solver_mode(&self) -> Option<SolverMode> {
lnicola marked this conversation as resolved.
Show resolved Hide resolved
if self.matches.get_flag("spp") {
Some(SolverMode::SPP)
} else if self.matches.get_flag("lsqspp") {
Some(SolverMode::LSQSPP)
} else if self.matches.get_flag("ppp") {
Some(SolverMode::PPP)
} else {
None
}
}
pub fn ppp(&self) -> bool {
pub fn positioning(&self) -> bool {
self.matches.get_flag("spp")
|| self.matches.get_flag("lsqspp")
|| self.matches.get_flag("ppp")
}
pub fn positioning_only(&self) -> bool {
self.matches.get_flag("pos-only")
Expand Down
2 changes: 1 addition & 1 deletion rinex-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ pub fn main() -> Result<(), Error> {
let qc = cli.quality_check() || qc_only;

let positioning_only = cli.positioning_only();
let positioning = cli.spp() || cli.ppp() || positioning_only;
let positioning = cli.positioning() || positioning_only;

if !positioning {
warn!("position solver currently turned off");
Expand Down
46 changes: 38 additions & 8 deletions rinex-cli/src/positioning/post_process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ pub fn post_process(
true, // show legend
MapboxStyle::OpenStreetMap,
(lat_ddeg, lon_ddeg), //center
15, // zoom in!!
18, // zoom in!!
);

let ref_scatter = ScatterMapbox::new(vec![lat_ddeg], vec![lon_ddeg])
Expand Down Expand Up @@ -128,20 +128,47 @@ pub fn post_process(
);
plot_ctx.add_trace(trace);

plot_ctx.add_cartesian2d_2y_plot("Velocity (X & Y)", "Speed [m/s]", "Speed [m/s]");
let trace = build_chart_epoch_axis(
"velocity (x)",
Mode::Markers,
epochs.clone(),
results.values().map(|p| p.v.x).collect::<Vec<f64>>(),
);
plot_ctx.add_trace(trace);

let trace = build_chart_epoch_axis(
"velocity (y)",
Mode::Markers,
epochs.clone(),
results.values().map(|p| p.v.y).collect::<Vec<f64>>(),
)
.y_axis("y2");
plot_ctx.add_trace(trace);

plot_ctx.add_cartesian2d_plot("Velocity (Z)", "Speed [m/s]");
let trace = build_chart_epoch_axis(
"velocity (z)",
Mode::Markers,
epochs.clone(),
results.values().map(|p| p.v.z).collect::<Vec<f64>>(),
);
plot_ctx.add_trace(trace);

plot_ctx.add_cartesian2d_2y_plot("HDOP, VDOP", "HDOP [m]", "VDOP [m]");
let trace = build_chart_epoch_axis(
"hdop",
Mode::Markers,
epochs.clone(),
results.values().map(|e| e.hdop).collect::<Vec<f64>>(),
results.values().map(|e| e.hdop()).collect::<Vec<f64>>(),
);
plot_ctx.add_trace(trace);

let trace = build_chart_epoch_axis(
"vdop",
Mode::Markers,
epochs.clone(),
results.values().map(|e| e.vdop).collect::<Vec<f64>>(),
results.values().map(|e| e.vdop()).collect::<Vec<f64>>(),
)
.y_axis("y2");
plot_ctx.add_trace(trace);
Expand All @@ -159,7 +186,7 @@ pub fn post_process(
"tdop",
Mode::Markers,
epochs.clone(),
results.values().map(|e| e.tdop).collect::<Vec<f64>>(),
results.values().map(|e| e.tdop()).collect::<Vec<f64>>(),
)
.y_axis("y2");
plot_ctx.add_trace(trace);
Expand All @@ -185,23 +212,26 @@ pub fn post_process(

writeln!(
fd,
"Epoch, dx, dy, dz, x_ecef, y_ecef, z_ecef, hdop, vdop, rcvr_clock_bias, tdop"
"Epoch, dx, dy, dz, x_ecef, y_ecef, z_ecef, speed_x, speed_y, speed_z, hdop, vdop, rcvr_clock_bias, tdop"
)?;

for (epoch, solution) in results {
let (px, py, pz) = (x + solution.p.x, y + solution.p.y, z + solution.p.z);
let (lat, lon, alt) = map_3d::ecef2geodetic(px, py, pz, map_3d::Ellipsoid::WGS84);
let (hdop, vdop, tdop) = (solution.hdop, solution.vdop, solution.tdop);
let (hdop, vdop, tdop) = (solution.hdop(), solution.vdop(), solution.tdop());
writeln!(
fd,
"{:?}, {:.6E}, {:.6E}, {:.6E}, {:.6E}, {:.6E}, {:.6E}, {:.6E}, {:.6E}, {:.6E}, {:.6E}",
"{:?}, {:.6E}, {:.6E}, {:.6E}, {:.6E}, {:.6E}, {:.6E}, {:.6E}, {:.6E}, {:.6E}, {:.6E}, {:.6E}, {:.6E}, {:.6E}",
epoch,
solution.p.x,
solution.p.y,
solution.p.z,
px,
py,
pz,
solution.v.x,
solution.v.y,
solution.v.z,
hdop,
vdop,
solution.dt,
Expand Down Expand Up @@ -240,7 +270,7 @@ pub fn post_process(
attrs: HashMap::new(),
}))
},
attrs: [(String::from("TDOP"), format!("{:.6E}", solution.tdop))]
attrs: [(String::from("TDOP"), format!("{:.6E}", solution.tdop()))]
.into_iter()
.collect(),
children: vec![],
Expand Down
20 changes: 8 additions & 12 deletions rinex-cli/src/positioning/solver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,22 +143,18 @@ fn ng_model(nav: &Rinex, t: Epoch) -> Option<NgModel> {

pub fn solver(ctx: &mut RnxContext, cli: &Cli) -> Result<BTreeMap<Epoch, PVTSolution>, Error> {
// custom strategy
let rtk_mode = match cli.spp() {
true => {
info!("single point positioning opmode");
Mode::SPP
},
false => {
info!("precise point positioning opmode");
//TODO: verify feasiblity here, otherwise panic
Mode::PPP
},
let mode = cli.solver_mode().unwrap(); // infaillible

match mode {
Mode::SPP => info!("single point positioning"),
Mode::LSQSPP => info!("recursive lsq single point positioning"),
Mode::PPP => info!("precise point positioning"),
};

// parse custom config, if any
let cfg = match cli.config() {
Some(cfg) => cfg,
None => Config::default(rtk_mode),
None => Config::default(mode),
};

let pos = match cli.manual_position() {
Expand Down Expand Up @@ -195,7 +191,7 @@ pub fn solver(ctx: &mut RnxContext, cli: &Cli) -> Result<BTreeMap<Epoch, PVTSolu
let meteo_data = ctx.meteo_data();

let mut solver = Solver::new(
rtk_mode,
mode,
apriori,
&cfg,
/* state vector interpolator */
Expand Down
4 changes: 2 additions & 2 deletions rnx2cggtts/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ serde_json = "1"
map_3d = "0.1.5"
env_logger = "0.10"
gnss-rs = { version = "2.1.2" , features = ["serde"] }
clap = { version = "4.4.8", features = ["derive", "color"] }
clap = { version = "4.4.10", features = ["derive", "color"] }
serde = { version = "1.0", default-features = false, features = ["derive"] }
rinex = { path = "../rinex", version = "=0.15.1", features = ["full"] }

Expand All @@ -31,6 +31,6 @@ cggtts = { version = "4.0.1", features = ["serde", "scheduler"] }
# cggtts = { path = "../../cggtts/cggtts", features = ["serde", "scheduler"] }

# solver
gnss-rtk = { version = "0.2.2", features = ["serde"] }
gnss-rtk = { version = "0.3.0", features = ["serde"] }
# gnss-rtk = { git = "https://github.com/rtk-rs/gnss-rtk", branch = "develop", features = ["serde"] }
# gnss-rtk = { path = "../../rtk-rs/gnss-rtk", features = ["serde"] }
24 changes: 21 additions & 3 deletions rnx2cggtts/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ pub struct Cli {
}

use cggtts::{prelude::ReferenceTime, track::Scheduler};
use gnss_rtk::prelude::{Config, Mode as SolverMode};
use rinex::prelude::*;
use rtk::prelude::Config;

impl Cli {
/// Build new command line interface
Expand Down Expand Up @@ -108,8 +108,14 @@ This is the delay induced by the cable on the external ref clock. Specify it in
.help("Pass Positioning configuration, refer to README."))
.arg(Arg::new("spp")
.long("spp")
.conflicts_with("ppp")
.action(ArgAction::SetTrue)
.help("Force solving strategy to SPP."))
.help("Force solving strategy to SPP (default is LSQSPP)."))
.arg(Arg::new("ppp")
.long("ppp")
.conflicts_with("spp")
.action(ArgAction::SetTrue)
.help("Force solving strategy to PPP (default is LSQSPP)."))
.next_help_heading("Preprocessing")
.arg(Arg::new("gps-filter")
.short('G')
Expand Down Expand Up @@ -196,8 +202,20 @@ Refer to rinex-cli Preprocessor documentation for more information"))
fn get_flag(&self, flag: &str) -> bool {
self.matches.get_flag(flag)
}
pub fn spp(&self) -> bool {
/* returns RTK solver mode to implement */
pub fn solver_mode(&self) -> SolverMode {
if self.matches.get_flag("spp") {
SolverMode::SPP
} else if self.matches.get_flag("ppp") {
SolverMode::PPP
} else {
SolverMode::LSQSPP
}
}
pub fn positioning(&self) -> bool {
self.matches.get_flag("spp")
|| self.matches.get_flag("lsqspp")
|| self.matches.get_flag("ppp")
}
/// Returns the manualy defined RFDLY (in nanoseconds!)
pub fn rf_delay(&self) -> Option<HashMap<Observable, f64>> {
Expand Down
15 changes: 7 additions & 8 deletions rnx2cggtts/src/solver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,18 +186,17 @@ pub fn resolve(ctx: &mut RnxContext, cli: &Cli) -> Result<Vec<Track>, Error> {
info!("tracking duration set to {}", trk_duration);

// custom strategy
let rtk_mode = match cli.spp() {
true => {
info!("spp position solver");
Mode::SPP
},
false => Mode::SPP, //TODO
let mode = cli.solver_mode();
match mode {
Mode::SPP => info!("single point positioning"),
Mode::LSQSPP => info!("recursive lsq single point positioning"),
Mode::PPP => info!("precise point positioning"),
};

// parse custom config, if any
let cfg = match cli.config() {
Some(cfg) => cfg,
None => Config::default(rtk_mode),
None => Config::default(mode),
};

let pos = match cli.manual_apc() {
Expand Down Expand Up @@ -238,7 +237,7 @@ pub fn resolve(ctx: &mut RnxContext, cli: &Cli) -> Result<Vec<Track>, Error> {
let meteo_data = ctx.meteo_data();

let mut solver = Solver::new(
rtk_mode,
mode,
apriori,
&cfg,
/* state vector interpolator */
Expand Down
4 changes: 2 additions & 2 deletions rnx2crx/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "rnx2crx"
version = "1.1.1"
version = "1.1.2"
license = "MIT OR Apache-2.0"
authors = ["Guillaume W. Bres <[email protected]>"]
description = "RINEX data compressor"
Expand All @@ -14,5 +14,5 @@ readme = "README.md"
[dependencies]
chrono = "0.4"
thiserror = "1"
clap = { version = "4.4.8", features = ["derive", "color"] }
clap = { version = "4.4.10", features = ["derive", "color"] }
rinex = { path = "../rinex", version = "=0.15.1", features = ["serde"] }
4 changes: 2 additions & 2 deletions ublox-rnx/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ublox-rnx"
version = "0.1.2"
version = "0.1.3"
license = "MIT OR Apache-2.0"
authors = ["Guillaume W. Bres <[email protected]>"]
description = "Efficient RINEX production from a Ublox GNSS receiver"
Expand All @@ -12,7 +12,6 @@ edition = "2021"
readme = "README.md"

[dependencies]
clap = "4"
log = "0.4"
pretty_env_logger = "0.5"
chrono = "0.4.30"
Expand All @@ -21,5 +20,6 @@ thiserror = "1"
serde_json = "1.0"
serialport = "4.2.0"
ublox = "0.4.4"
clap = { version = "4.4.10", features = ["derive", "color"] }
gnss-rs = { version = "2.1.2", features = ["serde"] }
rinex = { path = "../rinex", version = "=0.15.1", features = ["serde", "nav", "obs"] }
Loading