gnss-rtk 0.8.0

GNSS position solver
Documentation
use hifitime::Unit;
use log::{debug, info};
use rstest::*;

use rand::{prelude::*, rngs::SmallRng, SeedableRng};

use std::str::FromStr;

use crate::{
    navigation::apriori::Apriori,
    prelude::{
        Almanac, Config, Duration, Epoch, Error, Frame, Method, Orbit, Solver, TimeScale,
        UserParameters,
    },
    tests::{
        bias::TestBias, ephemeris::NullEph, init_logger, time::NullTime, CandidatesBuilder,
        OrbitsData, TestNumber,
    },
};

#[fixture]
fn build_almanac() -> Almanac {
    use crate::tests::almanac;
    almanac()
}

#[fixture]
fn build_earth_frame() -> Frame {
    use crate::tests::earth_frame;
    earth_frame()
}

#[fixture]
fn build_initial_apriori() -> Apriori {
    use crate::tests::reference_apriori_at_ref_epoch;
    reference_apriori_at_ref_epoch()
}

mod epochs;
mod orbits;
mod settings;
mod number;

use epochs::*;
use orbits::*;

pub struct FuzzTest {
    t0: Epoch,
    name: String,
    cfg: Config,
    frame: Frame,
    almanac: Almanac,
    num_epochs: usize,
    num_sv: TestNumber<usize>,
    apriori: Option<Apriori>,
    sampling_period_nanos: TestNumber<i128>,
}

impl FuzzTest {
    const NB_REFERENCE_ORBITS: usize = 4;

    const REFERENCE_ORBITS_KM: [(f64, f64, f64); Self::NB_REFERENCE_ORBITS] = [
        (-11562.163582, 14053.114306, 23345.128269),
        (4577.136069, -22995.974895, 18062.640686),
        (16577.017768, -4619.539763, 24092.494804),
        (18846.610510, 16144.830741, 16159.863309),
    ];

    const REFERENCE_PR_M: [(f64, f64); Self::NB_REFERENCE_ORBITS] = [
        (27616185.992, 27616184.819),
        (27055946.391, 27055945.532),
        (23730317.923, 23730316.788),
        (22756243.562, 22756242.295),
    ];

    const REFERENCE_CP_M: [(f64, f64); Self::NB_REFERENCE_ORBITS] = [
        (145124050.106, 108371872.760),
        (142179967.778, 106173364.686),
        (124703702.220, 93122915.921),
        (119584910.611, 89300442.791),
    ];

    fn generate_orbits(&self, rng: &mut SmallRng, frame: Frame) -> FuzzTestOrbits {
        let mut t = self.t0;

        let mut orbits = Vec::new();

        for i in 0..self.num_epochs {
            let num_sv = self.num_sv.value();

            for j in 0..num_sv {
                let sv_index = j % Self::NB_REFERENCE_ORBITS;

                let (x_km, y_km, z_km) = Self::REFERENCE_ORBITS_KM[sv_index];

                let orbit = Orbit::from_position(x_km, y_km, z_km, t, frame);

                orbits.push(orbit);
            }

            t = t + Duration::from_nanoseconds(self.sampling_period_nanos.value() as f64);
        }

        FuzzTestOrbits { database: orbits }
    }

    fn generate_epochs(&self, rng: &mut SmallRng) -> Vec<FuzzTestEpoch> {
        let mut t = self.t0;
        let mut epochs = Vec::new();

        for i in 0..self.num_epochs {}

        epochs
    }

    pub fn run(&mut self) {
        init_logger();

        let default_params = UserParameters::default();

        let bias = TestBias {};
        let null_time = NullTime {};
        let null_eph = NullEph {};

        let mut generator = rand::rng();
        let mut rng = SmallRng::from_rng(&mut generator);

        let orbits = self.generate_orbits(&mut rng, self.frame);

        let apriori = if let Some(apriori) = self.apriori {
            Some(apriori.pos_m)
        } else {
            None
        };

        let mut solver = Solver::new(
            self.almanac.clone(),
            self.frame,
            self.cfg.clone(),
            null_eph.into(),
            orbits.into(),
            null_time,
            bias,
            apriori,
        );

        let epochs = self.generate_epochs(&mut rng);

        for (nth_epoch, epochs) in epochs.iter().enumerate() {
            match solver.ppp_solving(epochs.time, default_params, &epochs.candidates) {
                Err(e) => {
                    panic!("Solver failed with {}", e);
                },
                Ok(pvt) => {
                    info!(
                        "fuzz-test {} - nth {} - position Fix {:#?}",
                        self.name, nth_epoch, pvt
                    );
                },
            }
        }
    }
}