Skip to content

Commit

Permalink
Orbit (#261)
Browse files Browse the repository at this point in the history
* Unlocking rtk opmode
* remove deprecated dir
* Move on to Trait implementation
* Prepare for rtk
* Add option to load ref. BASE STATION
  * introduce -z repair
  * add more tests data
  * introduce -o custom reporting
* Improve Satellites reporting
* Improving and updating the orbital state methods
* sp3 and orbital projections
* tutorials/SP3
* Introduce ANISE
* improve orbital proj
* precise orbits
* precise clocks
* plot clock drifts
* clock relativistic correction

---------

Signed-off-by: Guillaume W. Bres <[email protected]>
  • Loading branch information
gwbres authored Aug 5, 2024
1 parent 87ca823 commit 70242aa
Show file tree
Hide file tree
Showing 102 changed files with 2,572 additions and 2,282 deletions.
16 changes: 10 additions & 6 deletions qc-traits/src/processing/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,17 @@ pub trait Preprocessing: Masking + Decimate {
}
}

// pub use filters::{
// Decimate, DecimationFilter, DecimationType, Filter, InterpFilter, InterpMethod, Interpolate,
// Mask, MaskFilter, MaskOperand, Preprocessing, Smooth, SmoothingFilter, SmoothingType,
// };
/// Repair
#[derive(Debug, Copy, Clone)]
pub enum Repair {
/// Repairs all zero values.
Zero,
}

//pub use averaging::Averager;
//pub use derivative::Derivative;
pub trait RepairTrait {
fn repair(&self, r: Repair) -> Self;
fn repair_mut(&mut self, r: Repair);
}

#[derive(Error, Debug)]
pub enum Error {
Expand Down
4 changes: 2 additions & 2 deletions rinex-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@ hifitime = { version = "4.0.0-alpha", features = ["serde", "std"] }

gnss-rs = { version = "2.2.1", features = ["serde"] }

gnss-rtk = { version = "0.5.0", features = ["serde"] }
# gnss-rtk = { version = "0.5.0", 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 = { version = "4.1.5", features = ["serde", "scheduler"], optional = true }
# cggtts = { path = "../../cggtts/cggtts", features = ["serde", "scheduler"], optional = true }
Expand Down
18 changes: 0 additions & 18 deletions rinex-cli/config/rtk/gpst_ppp_kf.json

This file was deleted.

95 changes: 84 additions & 11 deletions rinex-cli/src/cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,12 @@ impl Default for Cli {
pub struct Context {
/// Quiet option
pub quiet: bool,
/// Data context defined by user
/// Data context defined by user.
/// In differential opmode, this is the ROVER.
pub data: QcContext,
/// Secondary dataset defined by user
/// serves as BASE in differential opmodes.
pub station_data: Option<QcContext>,
/// Context name is derived from the primary file loaded in Self,
/// and mostly used in output products generation.
pub name: String,
Expand Down Expand Up @@ -179,6 +183,12 @@ If none are defined, we will then try to create a local directory named \"WORKSP
By default, report synthesis happens once per input set (file combnation and cli options).
Use this option to force report regeneration.
This has no effect on file operations that do not synthesize a report."))
.arg(
Arg::new("report-name")
.short('o')
.action(ArgAction::Set)
.help("Custom report name, otherwise, report is named index.html")
)
.arg(
Arg::new("report-brdc-sky")
.long("brdc-sky")
Expand Down Expand Up @@ -233,6 +243,19 @@ This has no effect on applications compiled without plot and statistical options
.value_delimiter(';')
.action(ArgAction::Append)
.help("Filter designer. Refer to []."))
.next_help_heading("RINEX Repair")
.arg(Arg::new("zero-repair")
.short('z')
.action(ArgAction::SetTrue)
.help("Remove all zero (=null) values. See --help")
.long_help("
Removes all zero (null) values from data records.
Specifically in NAV and OBS RINEX. Null NAV records are forbidden.
Null OBS RINEX are also most likely invalid.
To determine whether some null Observations exist (most likely invalid), simply
generate a first report and study the provided observations.
The `ppp` solver will most likely encounter Physical Non Sense Errors.
Null NAV RINEX content is also invalid by definition."))
.next_help_heading("Receiver Antenna")
.arg(Arg::new("rx-ecef")
.long("rx-ecef")
Expand All @@ -247,30 +270,66 @@ Otherwise it gets automatically picked up."))
.next_help_heading("Exclusive Opmodes: you can only run one at a time.")
.subcommand(filegen::subcommand())
.subcommand(merge::subcommand())
.subcommand(positioning::subcommand())
.subcommand(positioning::ppp_subcommand())
.subcommand(positioning::rtk_subcommand())
.subcommand(split::subcommand())
.subcommand(diff::subcommand())
.subcommand(time_binning::subcommand())
.get_matches()
},
}
}
/// Returns list of input directories
pub fn input_directories(&self) -> Vec<&String> {
if let Some(fp) = self.matches.get_many::<String>("directory") {
fp.collect()
/// Recursive browser depth
pub fn recursive_depth(&self) -> usize {
if let Some(depth) = self.matches.get_one::<u8>("depth") {
*depth as usize
} else {
5
}
}
/// Returns individual input ROVER -d
pub fn rover_directories(&self) -> Vec<&String> {
if let Some(dirs) = self.matches.get_many::<String>("directory") {
dirs.collect()
} else {
Vec::new()
}
}
/// Returns individual input filepaths
pub fn input_files(&self) -> Vec<&String> {
/// Returns individual input ROVER -fp
pub fn rover_files(&self) -> Vec<&String> {
if let Some(fp) = self.matches.get_many::<String>("filepath") {
fp.collect()
} else {
Vec::new()
}
}
/// Returns individual input BASE STATION -d
pub fn base_station_directories(&self) -> Vec<&String> {
match self.matches.subcommand() {
Some(("rtk", submatches)) => {
if let Some(dir) = submatches.get_many::<String>("dir") {
dir.collect()
} else {
Vec::new()
}
},
_ => Vec::new(),
}
}
/// Returns individual input BASE STATION -fp
pub fn base_station_files(&self) -> Vec<&String> {
match self.matches.subcommand() {
Some(("rtk", submatches)) => {
if let Some(fp) = submatches.get_many::<String>("fp") {
fp.collect()
} else {
Vec::new()
}
},
_ => Vec::new(),
}
}
/// Returns preproc ops
pub fn preprocessing(&self) -> Vec<&String> {
if let Some(filters) = self.matches.get_many::<String>("preprocessing") {
filters.collect()
Expand Down Expand Up @@ -302,6 +361,9 @@ Otherwise it gets automatically picked up."))
pub fn irnss_filter(&self) -> bool {
self.matches.get_flag("irnss-filter")
}
pub fn zero_repair(&self) -> bool {
self.matches.get_flag("zero-repair")
}
/*
* faillible 3D coordinates parsing
* it's better to panic if the descriptor is badly format
Expand Down Expand Up @@ -360,12 +422,15 @@ Otherwise it gets automatically picked up."))
pub fn hash(&self) -> u64 {
let mut hasher = DefaultHasher::new();
let mut string = self
.input_directories()
.rover_directories()
.into_iter()
.sorted()
.chain(self.input_files().into_iter().sorted())
.chain(self.rover_files().into_iter().sorted())
.chain(self.preprocessing().into_iter().sorted())
.join(",");
if let Some(custom) = self.custom_report_name() {
string.push_str(custom);
}
if let Some(geo) = self.manual_geodetic() {
string.push_str(&format!("{:?}", geo));
}
Expand All @@ -378,7 +443,11 @@ Otherwise it gets automatically picked up."))
/// Returns QcConfig from command line
pub fn qc_config(&self) -> QcConfig {
QcConfig {
manual_reference: None,
manual_reference: if let Some(manual) = self.manual_position() {
Some(GroundPosition::from_ecef_wgs84(manual))
} else {
None
},
report: if self.matches.get_flag("report-sum") {
QcReportType::Summary
} else {
Expand All @@ -387,4 +456,8 @@ Otherwise it gets automatically picked up."))
force_brdc_skyplot: self.matches.get_flag("report-brdc-sky"),
}
}
/// Report to be generated for this session
pub fn custom_report_name(&self) -> Option<&String> {
self.matches.get_one::<String>("report-name")
}
}
72 changes: 58 additions & 14 deletions rinex-cli/src/cli/positioning.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,8 @@
use clap::{value_parser, Arg, ArgAction, Command};
use rinex::prelude::Duration;

pub fn subcommand() -> Command {
let cmd = Command::new("ppp")
.arg_required_else_help(false)
.about("Post Processed Positioning. Use this mode to deploy the precise position solver.
The solutions are added to the final report as an extra chapter. See --help")
.long_about("Post Processed Positioning (ppp) opmode resolves
PVT solutions from RINEX data sampled by a single receiver (! This is not RTK!).
The solutions are presented in the analysis report (post processed results chapter).
Use --cggtts to convert solutions to CGGTTS special format.")
fn shared_args(cmd: Command) -> Command {
let cmd = cmd
.arg(Arg::new("cfg")
.short('c')
.long("cfg")
Expand All @@ -19,8 +12,8 @@ Use --cggtts to convert solutions to CGGTTS special format.")
.action(ArgAction::Append)
.help("Position Solver configuration file (JSON). See --help.")
.long_help("
Read the [https://github.com/georust/rinex/wiki/Positioning] tutorial.
Use [https://github.com/georust/rinex/config] as a starting point.
Read [https://github.com/georust/rinex/wiki/Positioning]
and refer to the tutorials/ folder shipped with the RINEX repo.
[https://docs.rs/gnss-rtk/latest/gnss_rtk/prelude/struct.Config.html] is the structure to represent in JSON.
"));

Expand Down Expand Up @@ -59,7 +52,7 @@ Use [https://github.com/georust/rinex/config] as a starting point.
let cmd =
cmd.next_help_heading("CGGTTS (special resolution for clock comparison / time transfer)");

if cfg!(not(feature = "cggtts")) {
let cmd = if cfg!(not(feature = "cggtts")) {
cmd.arg(
Arg::new("cggtts")
.long("cggtts")
Expand All @@ -75,7 +68,6 @@ Use [https://github.com/georust/rinex/config] as a starting point.
.long_help("Refer to the [https://github.com/georust/rinex/wiki/CGGTTS] tutorial."))
.arg(Arg::new("tracking")
.long("trk")
.short('t')
.value_parser(value_parser!(Duration))
.action(ArgAction::Set)
.help("CGGTTS custom tracking duration.
Expand All @@ -96,5 +88,57 @@ Use [https://github.com/georust/rinex/config] as a starting point.
.conflicts_with("utck")
.help("If the local clock is not a UTC replica and has a specific name, you
can define it here."))
}
};

cmd
}

pub fn ppp_subcommand() -> Command {
let cmd = Command::new("ppp")
.arg_required_else_help(false)
.about(
"Post Processed Positioning. Use this mode to deploy the precise position solver.
The solutions are added to the final report as an extra chapter. See --help",
)
.long_about(
"Post Processed Positioning (ppp) opmode resolves
PVT solutions from RINEX data sampled by a single receiver (! This is not RTK!).
The solutions are presented in the analysis report (post processed results chapter).
Use --cggtts to convert solutions to CGGTTS special format.",
);
shared_args(cmd)
}

pub fn rtk_subcommand() -> Command {
let cmd = Command::new("rtk")
.arg_required_else_help(true)
.about(
"Post Processed RTK. Use this mode to deploy the precise differential positioning.
The initial context describes the Rover context. rtk accepts `-f` and `-d` once again, to describe the remote Station.
Other positioning flags still apply (like -c). See --help.",
)
.long_about(
"RTK post opmode resolves PVT solutions by (post processed) differential navigation.
The initial context (-f, -d) describes the ROVER.
`rtk` also accepts -f and -d and you need to use those to describe the BASE (mandatory).
Other than that, `rtk` is stricly identical to `ppp` and is presented similarly.
CGGTTS and other options still apply."
)
.arg(
Arg::new("fp")
.long("fp")
.value_name("FILE")
.action(ArgAction::Append)
.required_unless_present("dir")
.help("Pass any RINEX file for remote base station"),
)
.arg(
Arg::new("dir")
.short('d')
.value_name("DIR")
.action(ArgAction::Append)
.required_unless_present("fp")
.help("Pass any directory for remote base station"),
);
shared_args(cmd)
}
6 changes: 3 additions & 3 deletions rinex-cli/src/cli/workspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ impl Workspace {
/// Opens root path with prefered web browser
#[cfg(target_os = "linux")]
pub fn open_with_web_browser(&self) {
let fullpath = self.root.join("index.html").to_string_lossy().to_string();
let fullpath = self.root.to_string_lossy().to_string();
let web_browsers = vec!["firefox", "chromium"];
for browser in web_browsers {
let child = Command::new(browser).arg(fullpath.clone()).spawn();
Expand All @@ -71,7 +71,7 @@ impl Workspace {
/// Opens root path with prefered web browser
#[cfg(target_os = "macos")]
pub fn open_with_web_browser(&self) {
let fullpath = self.root.join("index.html").to_string_lossy().to_string();
let fullpath = self.root.to_string_lossy().to_string();
Command::new("open")
.args(&[fullpath])
.output()
Expand All @@ -80,7 +80,7 @@ impl Workspace {
/// Opens root path with prefered web browser
#[cfg(target_os = "windows")]
pub fn open_with_web_browser(&self) {
let fullpath = self.root.join("index.html").to_string_lossy().to_string();
let fullpath = self.root.to_string_lossy().to_string();
Command::new("cmd")
.arg("/C")
.arg(format!(r#"start {}"#, fullpath))
Expand Down
Loading

0 comments on commit 70242aa

Please sign in to comment.