Skip to content

Commit

Permalink
Develop (#188)
Browse files Browse the repository at this point in the history
* plot speed vectors
* bump clap to latest
* v0.3.0: lsq-spp
* run linter

---------

Signed-off-by: Guillaume W. Bres <[email protected]>
  • Loading branch information
gwbres authored Nov 30, 2023
1 parent 2be6e55 commit c6f21bd
Show file tree
Hide file tree
Showing 11 changed files with 114 additions and 48 deletions.
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> {
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"] }

0 comments on commit c6f21bd

Please sign in to comment.