Title: | Analyze the Impact of Sensor Error Modelling on Navigation Performance |
---|---|
Description: | Implements the framework presented in Cucci, D. A., Voirol, L., Khaghani, M. and Guerrier, S. (2023) <doi:10.1109/TIM.2023.3267360> which allows to analyze the impact of sensor error modeling on the performance of integrated navigation (sensor fusion) based on inertial measurement unit (IMU), Global Positioning System (GPS), and barometer data. The framework relies on Monte Carlo simulations in which a Vanilla Extended Kalman filter is coupled with realistic and user-configurable noise generation mechanisms to recover a reference trajectory from noisy measurements. The evaluation of several statistical metrics of the solution, aggregated over hundreds of simulated realizations, provides reasonable estimates of the expected performances of the system in real-world conditions. |
Authors: | Davide A. Cucci [aut], Lionel Voirol [aut, cre], Mehran Khaghani [aut], Stéphane Guerrier [aut] |
Maintainer: | Lionel Voirol <[email protected]> |
License: | AGPL-3 |
Version: | 0.0.1 |
Built: | 2024-11-07 03:28:10 UTC |
Source: | https://github.com/smac-group/navigation |
Compute Empirical Coverage
compute_coverage( sols, alpha = 0.95, step = 100, idx = 1:6, progressbar = FALSE )
compute_coverage( sols, alpha = 0.95, step = 100, idx = 1:6, progressbar = FALSE )
sols |
The set of solutions returned by the |
alpha |
size of the confidence interval |
step |
Step |
idx |
Components of the states to be considered (default: position and orientation) |
progressbar |
A |
Return a coverage.stat
object which contains the empirical coverage of the navigation solutions.
Davide Cucci, Lionel Voirol, Mehran Khaghani, Stéphane Guerrier
# load data data("lemniscate_traj_ned") head(lemniscate_traj_ned) traj <- make_trajectory(data = lemniscate_traj_ned, system = "ned") timing <- make_timing( nav.start = 0, # time at which to begin filtering nav.end = 20, freq.imu = 100, # frequency of the IMU, can be slower wrt trajectory frequency freq.gps = 1, # GNSS frequency freq.baro = 1, # barometer frequency (to disable, put it very low, e.g. 1e-5) gps.out.start = 10, # to simulate a GNSS outage, set a time before nav.end gps.out.end = 15 ) # create sensor for noise data generation snsr.mdl <- list() # this uses a model for noise data generation acc.mdl <- WN(sigma2 = 5.989778e-05) + AR1(phi = 9.982454e-01, sigma2 = 1.848297e-10) + AR1(phi = 9.999121e-01, sigma2 = 2.435414e-11) + AR1(phi = 9.999998e-01, sigma2 = 1.026718e-12) gyr.mdl <- WN(sigma2 = 1.503793e-06) + AR1(phi = 9.968999e-01, sigma2 = 2.428980e-11) + AR1(phi = 9.999001e-01, sigma2 = 1.238142e-12) snsr.mdl$imu <- make_sensor( name = "imu", frequency = timing$freq.imu, error_model1 = acc.mdl, error_model2 = gyr.mdl ) # RTK-like GNSS gps.mdl.pos.hor <- WN(sigma2 = 0.025^2) gps.mdl.pos.ver <- WN(sigma2 = 0.05^2) gps.mdl.vel.hor <- WN(sigma2 = 0.01^2) gps.mdl.vel.ver <- WN(sigma2 = 0.02^2) snsr.mdl$gps <- make_sensor( name = "gps", frequency = timing$freq.gps, error_model1 = gps.mdl.pos.hor, error_model2 = gps.mdl.pos.ver, error_model3 = gps.mdl.vel.hor, error_model4 = gps.mdl.vel.ver ) # Barometer baro.mdl <- WN(sigma2 = 0.5^2) snsr.mdl$baro <- make_sensor( name = "baro", frequency = timing$freq.baro, error_model1 = baro.mdl ) # define sensor for Kalmna filter KF.mdl <- list() # make IMU sensor KF.mdl$imu <- make_sensor( name = "imu", frequency = timing$freq.imu, error_model1 = acc.mdl, error_model2 = gyr.mdl ) KF.mdl$gps <- snsr.mdl$gps KF.mdl$baro <- snsr.mdl$baro # perform navigation simulation num.runs <- 5 # number of Monte-Carlo simulations res <- navigation( traj.ref = traj, timing = timing, snsr.mdl = snsr.mdl, KF.mdl = KF.mdl, num.runs = num.runs, noProgressBar = TRUE, PhiQ_method = "1", # order of the Taylor expansion of the matrix exponential # used to compute Phi and Q matrices compute_PhiQ_each_n = 20, # compute new Phi and Q matrices # every n IMU steps (execution time optimization) parallel.ncores = 1, P_subsampling = timing$freq.imu ) # keep one covariance every second coverage <- compute_coverage(res, alpha = 0.7, step = 100, idx = 1:6) plot(coverage)
# load data data("lemniscate_traj_ned") head(lemniscate_traj_ned) traj <- make_trajectory(data = lemniscate_traj_ned, system = "ned") timing <- make_timing( nav.start = 0, # time at which to begin filtering nav.end = 20, freq.imu = 100, # frequency of the IMU, can be slower wrt trajectory frequency freq.gps = 1, # GNSS frequency freq.baro = 1, # barometer frequency (to disable, put it very low, e.g. 1e-5) gps.out.start = 10, # to simulate a GNSS outage, set a time before nav.end gps.out.end = 15 ) # create sensor for noise data generation snsr.mdl <- list() # this uses a model for noise data generation acc.mdl <- WN(sigma2 = 5.989778e-05) + AR1(phi = 9.982454e-01, sigma2 = 1.848297e-10) + AR1(phi = 9.999121e-01, sigma2 = 2.435414e-11) + AR1(phi = 9.999998e-01, sigma2 = 1.026718e-12) gyr.mdl <- WN(sigma2 = 1.503793e-06) + AR1(phi = 9.968999e-01, sigma2 = 2.428980e-11) + AR1(phi = 9.999001e-01, sigma2 = 1.238142e-12) snsr.mdl$imu <- make_sensor( name = "imu", frequency = timing$freq.imu, error_model1 = acc.mdl, error_model2 = gyr.mdl ) # RTK-like GNSS gps.mdl.pos.hor <- WN(sigma2 = 0.025^2) gps.mdl.pos.ver <- WN(sigma2 = 0.05^2) gps.mdl.vel.hor <- WN(sigma2 = 0.01^2) gps.mdl.vel.ver <- WN(sigma2 = 0.02^2) snsr.mdl$gps <- make_sensor( name = "gps", frequency = timing$freq.gps, error_model1 = gps.mdl.pos.hor, error_model2 = gps.mdl.pos.ver, error_model3 = gps.mdl.vel.hor, error_model4 = gps.mdl.vel.ver ) # Barometer baro.mdl <- WN(sigma2 = 0.5^2) snsr.mdl$baro <- make_sensor( name = "baro", frequency = timing$freq.baro, error_model1 = baro.mdl ) # define sensor for Kalmna filter KF.mdl <- list() # make IMU sensor KF.mdl$imu <- make_sensor( name = "imu", frequency = timing$freq.imu, error_model1 = acc.mdl, error_model2 = gyr.mdl ) KF.mdl$gps <- snsr.mdl$gps KF.mdl$baro <- snsr.mdl$baro # perform navigation simulation num.runs <- 5 # number of Monte-Carlo simulations res <- navigation( traj.ref = traj, timing = timing, snsr.mdl = snsr.mdl, KF.mdl = KF.mdl, num.runs = num.runs, noProgressBar = TRUE, PhiQ_method = "1", # order of the Taylor expansion of the matrix exponential # used to compute Phi and Q matrices compute_PhiQ_each_n = 20, # compute new Phi and Q matrices # every n IMU steps (execution time optimization) parallel.ncores = 1, P_subsampling = timing$freq.imu ) # keep one covariance every second coverage <- compute_coverage(res, alpha = 0.7, step = 100, idx = 1:6) plot(coverage)
Compute the mean orientation error (|| log(A^T * B) ||)
compute_mean_orientation_err(sols, step = 1, t0 = NULL, tend = NULL)
compute_mean_orientation_err(sols, step = 1, t0 = NULL, tend = NULL)
sols |
The set of solutions returned by the |
step |
do it for one sample out of |
t0 |
Start time for RMS calculation (default: beginning) |
tend |
Start time for RMS calculation (default: end) |
Return a navigation.stat
object which contains the mean orientation error over the fused trajectories.
Davide Cucci, Lionel Voirol, Mehran Khaghani, Stéphane Guerrier
# load data data("lemniscate_traj_ned") head(lemniscate_traj_ned) traj <- make_trajectory(data = lemniscate_traj_ned, system = "ned") timing <- make_timing( nav.start = 0, # time at which to begin filtering nav.end = 20, freq.imu = 100, # frequency of the IMU, can be slower wrt trajectory frequency freq.gps = 1, # GNSS frequency freq.baro = 1, # barometer frequency (to disable, put it very low, e.g. 1e-5) gps.out.start = 10, # to simulate a GNSS outage, set a time before nav.end gps.out.end = 15 ) # create sensor for noise data generation snsr.mdl <- list() # this uses a model for noise data generation acc.mdl <- WN(sigma2 = 5.989778e-05) + AR1(phi = 9.982454e-01, sigma2 = 1.848297e-10) + AR1(phi = 9.999121e-01, sigma2 = 2.435414e-11) + AR1(phi = 9.999998e-01, sigma2 = 1.026718e-12) gyr.mdl <- WN(sigma2 = 1.503793e-06) + AR1(phi = 9.968999e-01, sigma2 = 2.428980e-11) + AR1(phi = 9.999001e-01, sigma2 = 1.238142e-12) snsr.mdl$imu <- make_sensor( name = "imu", frequency = timing$freq.imu, error_model1 = acc.mdl, error_model2 = gyr.mdl ) # RTK-like GNSS gps.mdl.pos.hor <- WN(sigma2 = 0.025^2) gps.mdl.pos.ver <- WN(sigma2 = 0.05^2) gps.mdl.vel.hor <- WN(sigma2 = 0.01^2) gps.mdl.vel.ver <- WN(sigma2 = 0.02^2) snsr.mdl$gps <- make_sensor( name = "gps", frequency = timing$freq.gps, error_model1 = gps.mdl.pos.hor, error_model2 = gps.mdl.pos.ver, error_model3 = gps.mdl.vel.hor, error_model4 = gps.mdl.vel.ver ) # Barometer baro.mdl <- WN(sigma2 = 0.5^2) snsr.mdl$baro <- make_sensor( name = "baro", frequency = timing$freq.baro, error_model1 = baro.mdl ) # define sensor for Kalman filter KF.mdl <- list() # make IMU sensor KF.mdl$imu <- make_sensor( name = "imu", frequency = timing$freq.imu, error_model1 = acc.mdl, error_model2 = gyr.mdl ) KF.mdl$gps <- snsr.mdl$gps KF.mdl$baro <- snsr.mdl$baro # perform navigation simulation num.runs <- 5 # number of Monte-Carlo simulations res <- navigation( traj.ref = traj, timing = timing, snsr.mdl = snsr.mdl, KF.mdl = KF.mdl, num.runs = num.runs, noProgressBar = TRUE, PhiQ_method = "1", # order of the Taylor expansion of the matrix exponential # used to compute Phi and Q matrices compute_PhiQ_each_n = 10, # compute new Phi and Q matrices every n IMU steps (execution time optimization) parallel.ncores = 1, P_subsampling = timing$freq.imu ) # keep one covariance every second oe <- compute_mean_orientation_err(res, step = 25) plot(oe)
# load data data("lemniscate_traj_ned") head(lemniscate_traj_ned) traj <- make_trajectory(data = lemniscate_traj_ned, system = "ned") timing <- make_timing( nav.start = 0, # time at which to begin filtering nav.end = 20, freq.imu = 100, # frequency of the IMU, can be slower wrt trajectory frequency freq.gps = 1, # GNSS frequency freq.baro = 1, # barometer frequency (to disable, put it very low, e.g. 1e-5) gps.out.start = 10, # to simulate a GNSS outage, set a time before nav.end gps.out.end = 15 ) # create sensor for noise data generation snsr.mdl <- list() # this uses a model for noise data generation acc.mdl <- WN(sigma2 = 5.989778e-05) + AR1(phi = 9.982454e-01, sigma2 = 1.848297e-10) + AR1(phi = 9.999121e-01, sigma2 = 2.435414e-11) + AR1(phi = 9.999998e-01, sigma2 = 1.026718e-12) gyr.mdl <- WN(sigma2 = 1.503793e-06) + AR1(phi = 9.968999e-01, sigma2 = 2.428980e-11) + AR1(phi = 9.999001e-01, sigma2 = 1.238142e-12) snsr.mdl$imu <- make_sensor( name = "imu", frequency = timing$freq.imu, error_model1 = acc.mdl, error_model2 = gyr.mdl ) # RTK-like GNSS gps.mdl.pos.hor <- WN(sigma2 = 0.025^2) gps.mdl.pos.ver <- WN(sigma2 = 0.05^2) gps.mdl.vel.hor <- WN(sigma2 = 0.01^2) gps.mdl.vel.ver <- WN(sigma2 = 0.02^2) snsr.mdl$gps <- make_sensor( name = "gps", frequency = timing$freq.gps, error_model1 = gps.mdl.pos.hor, error_model2 = gps.mdl.pos.ver, error_model3 = gps.mdl.vel.hor, error_model4 = gps.mdl.vel.ver ) # Barometer baro.mdl <- WN(sigma2 = 0.5^2) snsr.mdl$baro <- make_sensor( name = "baro", frequency = timing$freq.baro, error_model1 = baro.mdl ) # define sensor for Kalman filter KF.mdl <- list() # make IMU sensor KF.mdl$imu <- make_sensor( name = "imu", frequency = timing$freq.imu, error_model1 = acc.mdl, error_model2 = gyr.mdl ) KF.mdl$gps <- snsr.mdl$gps KF.mdl$baro <- snsr.mdl$baro # perform navigation simulation num.runs <- 5 # number of Monte-Carlo simulations res <- navigation( traj.ref = traj, timing = timing, snsr.mdl = snsr.mdl, KF.mdl = KF.mdl, num.runs = num.runs, noProgressBar = TRUE, PhiQ_method = "1", # order of the Taylor expansion of the matrix exponential # used to compute Phi and Q matrices compute_PhiQ_each_n = 10, # compute new Phi and Q matrices every n IMU steps (execution time optimization) parallel.ncores = 1, P_subsampling = timing$freq.imu ) # keep one covariance every second oe <- compute_mean_orientation_err(res, step = 25) plot(oe)
Compute the mean position error (norm of 3D NED error)
compute_mean_position_err(sols, step = 1, t0 = NULL, tend = NULL)
compute_mean_position_err(sols, step = 1, t0 = NULL, tend = NULL)
sols |
The set of solutions returned by the |
step |
do it for one sample out of |
t0 |
Start time for RMS calculation (default: beginning) |
tend |
Start time for RMS calculation (default: end) |
Return a navigation.stat
object which contains the mean position error over the fused trajectories.
Davide Cucci, Lionel Voirol, Mehran Khaghani, Stéphane Guerrier
# load data data("lemniscate_traj_ned") head(lemniscate_traj_ned) traj <- make_trajectory(data = lemniscate_traj_ned, system = "ned") timing <- make_timing( nav.start = 0, # time at which to begin filtering nav.end = 20, freq.imu = 100, # frequency of the IMU, can be slower wrt trajectory frequency freq.gps = 1, # GNSS frequency freq.baro = 1, # barometer frequency (to disable, put it very low, e.g. 1e-5) gps.out.start = 10, # to simulate a GNSS outage, set a time before nav.end gps.out.end = 15 ) # create sensor for noise data generation snsr.mdl <- list() # this uses a model for noise data generation acc.mdl <- WN(sigma2 = 5.989778e-05) + AR1(phi = 9.982454e-01, sigma2 = 1.848297e-10) + AR1(phi = 9.999121e-01, sigma2 = 2.435414e-11) + AR1(phi = 9.999998e-01, sigma2 = 1.026718e-12) gyr.mdl <- WN(sigma2 = 1.503793e-06) + AR1(phi = 9.968999e-01, sigma2 = 2.428980e-11) + AR1(phi = 9.999001e-01, sigma2 = 1.238142e-12) snsr.mdl$imu <- make_sensor( name = "imu", frequency = timing$freq.imu, error_model1 = acc.mdl, error_model2 = gyr.mdl ) # RTK-like GNSS gps.mdl.pos.hor <- WN(sigma2 = 0.025^2) gps.mdl.pos.ver <- WN(sigma2 = 0.05^2) gps.mdl.vel.hor <- WN(sigma2 = 0.01^2) gps.mdl.vel.ver <- WN(sigma2 = 0.02^2) snsr.mdl$gps <- make_sensor( name = "gps", frequency = timing$freq.gps, error_model1 = gps.mdl.pos.hor, error_model2 = gps.mdl.pos.ver, error_model3 = gps.mdl.vel.hor, error_model4 = gps.mdl.vel.ver ) # Barometer baro.mdl <- WN(sigma2 = 0.5^2) snsr.mdl$baro <- make_sensor( name = "baro", frequency = timing$freq.baro, error_model1 = baro.mdl ) # define sensor for Kalmna filter KF.mdl <- list() # make IMU sensor KF.mdl$imu <- make_sensor( name = "imu", frequency = timing$freq.imu, error_model1 = acc.mdl, error_model2 = gyr.mdl ) KF.mdl$gps <- snsr.mdl$gps KF.mdl$baro <- snsr.mdl$baro # perform navigation simulation num.runs <- 5 # number of Monte-Carlo simulations res <- navigation( traj.ref = traj, timing = timing, snsr.mdl = snsr.mdl, KF.mdl = KF.mdl, num.runs = num.runs, noProgressBar = TRUE, PhiQ_method = "2", # order of the Taylor expansion of the matrix exponential # used to compute Phi and Q matrices compute_PhiQ_each_n = 10, # compute new Phi and Q matrices every n IMU steps # (execution time optimization) parallel.ncores = 1, P_subsampling = timing$freq.imu ) # keep one covariance every second pe <- compute_mean_position_err(res, step = 25) plot(pe)
# load data data("lemniscate_traj_ned") head(lemniscate_traj_ned) traj <- make_trajectory(data = lemniscate_traj_ned, system = "ned") timing <- make_timing( nav.start = 0, # time at which to begin filtering nav.end = 20, freq.imu = 100, # frequency of the IMU, can be slower wrt trajectory frequency freq.gps = 1, # GNSS frequency freq.baro = 1, # barometer frequency (to disable, put it very low, e.g. 1e-5) gps.out.start = 10, # to simulate a GNSS outage, set a time before nav.end gps.out.end = 15 ) # create sensor for noise data generation snsr.mdl <- list() # this uses a model for noise data generation acc.mdl <- WN(sigma2 = 5.989778e-05) + AR1(phi = 9.982454e-01, sigma2 = 1.848297e-10) + AR1(phi = 9.999121e-01, sigma2 = 2.435414e-11) + AR1(phi = 9.999998e-01, sigma2 = 1.026718e-12) gyr.mdl <- WN(sigma2 = 1.503793e-06) + AR1(phi = 9.968999e-01, sigma2 = 2.428980e-11) + AR1(phi = 9.999001e-01, sigma2 = 1.238142e-12) snsr.mdl$imu <- make_sensor( name = "imu", frequency = timing$freq.imu, error_model1 = acc.mdl, error_model2 = gyr.mdl ) # RTK-like GNSS gps.mdl.pos.hor <- WN(sigma2 = 0.025^2) gps.mdl.pos.ver <- WN(sigma2 = 0.05^2) gps.mdl.vel.hor <- WN(sigma2 = 0.01^2) gps.mdl.vel.ver <- WN(sigma2 = 0.02^2) snsr.mdl$gps <- make_sensor( name = "gps", frequency = timing$freq.gps, error_model1 = gps.mdl.pos.hor, error_model2 = gps.mdl.pos.ver, error_model3 = gps.mdl.vel.hor, error_model4 = gps.mdl.vel.ver ) # Barometer baro.mdl <- WN(sigma2 = 0.5^2) snsr.mdl$baro <- make_sensor( name = "baro", frequency = timing$freq.baro, error_model1 = baro.mdl ) # define sensor for Kalmna filter KF.mdl <- list() # make IMU sensor KF.mdl$imu <- make_sensor( name = "imu", frequency = timing$freq.imu, error_model1 = acc.mdl, error_model2 = gyr.mdl ) KF.mdl$gps <- snsr.mdl$gps KF.mdl$baro <- snsr.mdl$baro # perform navigation simulation num.runs <- 5 # number of Monte-Carlo simulations res <- navigation( traj.ref = traj, timing = timing, snsr.mdl = snsr.mdl, KF.mdl = KF.mdl, num.runs = num.runs, noProgressBar = TRUE, PhiQ_method = "2", # order of the Taylor expansion of the matrix exponential # used to compute Phi and Q matrices compute_PhiQ_each_n = 10, # compute new Phi and Q matrices every n IMU steps # (execution time optimization) parallel.ncores = 1, P_subsampling = timing$freq.imu ) # keep one covariance every second pe <- compute_mean_position_err(res, step = 25) plot(pe)
Compute Normalized Estimation Errror Squared (NEES)
compute_nees(sols, step = 50, idx = 1:6, progressbar = FALSE)
compute_nees(sols, step = 50, idx = 1:6, progressbar = FALSE)
sols |
The set of solutions returned by the |
step |
do it for one sample out of |
idx |
Components of the states to be considered (default: position and orientation) |
progressbar |
A |
Return a nees.stat
object which contains the Normalized Estimation Error Squared.
Davide Cucci, Lionel Voirol, Mehran Khaghani, Stéphane Guerrier
# load data data("lemniscate_traj_ned") head(lemniscate_traj_ned) traj <- make_trajectory(data = lemniscate_traj_ned, system = "ned") timing <- make_timing( nav.start = 0, # time at which to begin filtering nav.end = 30, freq.imu = 100, # frequency of the IMU, can be slower wrt trajectory frequency freq.gps = 1, # GNSS frequency freq.baro = 1, # barometer frequency # (to disable, put it very low, e.g. 1e-5) gps.out.start = 20, # to simulate a GNSS outage, set a time before nav.end gps.out.end = 25 ) # create sensor for noise data generation snsr.mdl <- list() # this uses a model for noise data generation acc.mdl <- WN(sigma2 = 5.989778e-05) + AR1(phi = 9.982454e-01, sigma2 = 1.848297e-10) + AR1(phi = 9.999121e-01, sigma2 = 2.435414e-11) + AR1(phi = 9.999998e-01, sigma2 = 1.026718e-12) gyr.mdl <- WN(sigma2 = 1.503793e-06) + AR1(phi = 9.968999e-01, sigma2 = 2.428980e-11) + AR1(phi = 9.999001e-01, sigma2 = 1.238142e-12) snsr.mdl$imu <- make_sensor(name = "imu", frequency = timing$freq.imu, error_model1 = acc.mdl, error_model2 = gyr.mdl) # RTK-like GNSS gps.mdl.pos.hor <- WN(sigma2 = 0.025^2) gps.mdl.pos.ver <- WN(sigma2 = 0.05^2) gps.mdl.vel.hor <- WN(sigma2 = 0.01^2) gps.mdl.vel.ver <- WN(sigma2 = 0.02^2) snsr.mdl$gps <- make_sensor( name = "gps", frequency = timing$freq.gps, error_model1 = gps.mdl.pos.hor, error_model2 = gps.mdl.pos.ver, error_model3 = gps.mdl.vel.hor, error_model4 = gps.mdl.vel.ver ) # Barometer baro.mdl <- WN(sigma2 = 0.5^2) snsr.mdl$baro <- make_sensor( name = "baro", frequency = timing$freq.baro, error_model1 = baro.mdl ) # define sensor for Kalmna filter KF.mdl <- list() # make IMU sensor KF.mdl$imu <- make_sensor( name = "imu", frequency = timing$freq.imu, error_model1 = acc.mdl, error_model2 = gyr.mdl ) KF.mdl$gps <- snsr.mdl$gps KF.mdl$baro <- snsr.mdl$baro # perform navigation simulation num.runs <- 5 # number of Monte-Carlo simulations res <- navigation( traj.ref = traj, timing = timing, snsr.mdl = snsr.mdl, KF.mdl = KF.mdl, num.runs = num.runs, noProgressBar = TRUE, PhiQ_method = "4", # order of the Taylor expansion of the matrix exponential # used to compute Phi and Q matrices compute_PhiQ_each_n = 10, # compute new Phi and Q matrices every n IMU steps # (execution time optimization) parallel.ncores = 1, P_subsampling = timing$freq.imu ) # keep one covariance every second nees <- compute_nees(res, idx = 1:6, step = 100) plot(nees)
# load data data("lemniscate_traj_ned") head(lemniscate_traj_ned) traj <- make_trajectory(data = lemniscate_traj_ned, system = "ned") timing <- make_timing( nav.start = 0, # time at which to begin filtering nav.end = 30, freq.imu = 100, # frequency of the IMU, can be slower wrt trajectory frequency freq.gps = 1, # GNSS frequency freq.baro = 1, # barometer frequency # (to disable, put it very low, e.g. 1e-5) gps.out.start = 20, # to simulate a GNSS outage, set a time before nav.end gps.out.end = 25 ) # create sensor for noise data generation snsr.mdl <- list() # this uses a model for noise data generation acc.mdl <- WN(sigma2 = 5.989778e-05) + AR1(phi = 9.982454e-01, sigma2 = 1.848297e-10) + AR1(phi = 9.999121e-01, sigma2 = 2.435414e-11) + AR1(phi = 9.999998e-01, sigma2 = 1.026718e-12) gyr.mdl <- WN(sigma2 = 1.503793e-06) + AR1(phi = 9.968999e-01, sigma2 = 2.428980e-11) + AR1(phi = 9.999001e-01, sigma2 = 1.238142e-12) snsr.mdl$imu <- make_sensor(name = "imu", frequency = timing$freq.imu, error_model1 = acc.mdl, error_model2 = gyr.mdl) # RTK-like GNSS gps.mdl.pos.hor <- WN(sigma2 = 0.025^2) gps.mdl.pos.ver <- WN(sigma2 = 0.05^2) gps.mdl.vel.hor <- WN(sigma2 = 0.01^2) gps.mdl.vel.ver <- WN(sigma2 = 0.02^2) snsr.mdl$gps <- make_sensor( name = "gps", frequency = timing$freq.gps, error_model1 = gps.mdl.pos.hor, error_model2 = gps.mdl.pos.ver, error_model3 = gps.mdl.vel.hor, error_model4 = gps.mdl.vel.ver ) # Barometer baro.mdl <- WN(sigma2 = 0.5^2) snsr.mdl$baro <- make_sensor( name = "baro", frequency = timing$freq.baro, error_model1 = baro.mdl ) # define sensor for Kalmna filter KF.mdl <- list() # make IMU sensor KF.mdl$imu <- make_sensor( name = "imu", frequency = timing$freq.imu, error_model1 = acc.mdl, error_model2 = gyr.mdl ) KF.mdl$gps <- snsr.mdl$gps KF.mdl$baro <- snsr.mdl$baro # perform navigation simulation num.runs <- 5 # number of Monte-Carlo simulations res <- navigation( traj.ref = traj, timing = timing, snsr.mdl = snsr.mdl, KF.mdl = KF.mdl, num.runs = num.runs, noProgressBar = TRUE, PhiQ_method = "4", # order of the Taylor expansion of the matrix exponential # used to compute Phi and Q matrices compute_PhiQ_each_n = 10, # compute new Phi and Q matrices every n IMU steps # (execution time optimization) parallel.ncores = 1, P_subsampling = timing$freq.imu ) # keep one covariance every second nees <- compute_nees(res, idx = 1:6, step = 100) plot(nees)
Example trajectory 1 in ellipsoidal coordinates.
example_1_traj_ellipsoidal
example_1_traj_ellipsoidal
An object of class matrix
(inherits from array
) with 6000 rows and 7 columns.
Example trajectory 1 in NED coordinates.
example_1_traj_ned
example_1_traj_ned
An object of class matrix
(inherits from array
) with 6000 rows and 7 columns.
Example trajectory 2 in ellipsoidal coordinates.
example_2_traj_ellipsoidal
example_2_traj_ellipsoidal
An object of class matrix
(inherits from array
) with 12001 rows and 7 columns.
Example trajectory 2 in NED coordinates.
example_2_traj_ned
example_2_traj_ned
An object of class matrix
(inherits from array
) with 12001 rows and 7 columns.
Lemniscate trajectory in NED coordinates.
lemniscate_traj_ned
lemniscate_traj_ned
An object of class matrix
(inherits from array
) with 60001 rows and 7 columns.
sensor
objectConstruct a sensor
object for IMU, GPS, and Baro from error model of class ts.model
make_sensor( name, frequency = 1, error_model1 = NULL, error_model2 = NULL, error_model3 = NULL, error_model4 = NULL, error_data1 = NULL )
make_sensor( name, frequency = 1, error_model1 = NULL, error_model2 = NULL, error_model3 = NULL, error_model4 = NULL, error_data1 = NULL )
name |
Name of the sensor |
frequency |
Frequency associated with the error model |
error_model1 |
Error model of class |
error_model2 |
Error model of class |
error_model3 |
Error model of class |
error_model4 |
Error model of class |
error_data1 |
Vector of error observations. |
An object of class sensor
containing sensor name and its additive error model along with the frequency associated to that model
Davide Cucci, Lionel Voirol, Mehran Khaghani, Stéphane Guerrier
# IMU: imu.freq <- 250 acc.mdl <- WN(sigma2 = 1.535466e-04) + RW(gamma2 = 1.619511e-10) gyr.mdl <- WN(sigma2 = 1.711080e-03) + RW(gamma2 = 1.532765e-13) imu.mdl <- make_sensor( name = "imu", frequency = imu.freq, error_model1 = acc.mdl, error_model2 = gyr.mdl ) # GPS: gps.freq <- 1 gps.mdl.pos.hor <- WN(sigma2 = 2^2) gps.mdl.pos.ver <- WN(sigma2 = 4^2) gps.mdl.vel.hor <- WN(sigma2 = 0.04^2) gps.mdl.vel.ver <- WN(sigma2 = 0.06^2) gps.mdl <- make_sensor( name = "gps", frequency = gps.freq, error_model1 = gps.mdl.pos.hor, error_model2 = gps.mdl.pos.ver, error_model3 = gps.mdl.vel.hor, error_model4 = gps.mdl.vel.ver ) # Baro: baro.freq <- 1 baro.mdl <- WN(sigma2 = 0.5^2) baro.mdl <- make_sensor( name = "baro", frequency = baro.freq, error_model1 = baro.mdl )
# IMU: imu.freq <- 250 acc.mdl <- WN(sigma2 = 1.535466e-04) + RW(gamma2 = 1.619511e-10) gyr.mdl <- WN(sigma2 = 1.711080e-03) + RW(gamma2 = 1.532765e-13) imu.mdl <- make_sensor( name = "imu", frequency = imu.freq, error_model1 = acc.mdl, error_model2 = gyr.mdl ) # GPS: gps.freq <- 1 gps.mdl.pos.hor <- WN(sigma2 = 2^2) gps.mdl.pos.ver <- WN(sigma2 = 4^2) gps.mdl.vel.hor <- WN(sigma2 = 0.04^2) gps.mdl.vel.ver <- WN(sigma2 = 0.06^2) gps.mdl <- make_sensor( name = "gps", frequency = gps.freq, error_model1 = gps.mdl.pos.hor, error_model2 = gps.mdl.pos.ver, error_model3 = gps.mdl.vel.hor, error_model4 = gps.mdl.vel.ver ) # Baro: baro.freq <- 1 baro.mdl <- WN(sigma2 = 0.5^2) baro.mdl <- make_sensor( name = "baro", frequency = baro.freq, error_model1 = baro.mdl )
timing
objectConstruct a timing
object controlling the timing and frequencies for navigation, making sure about the consistency and feasibility of provided information.
make_timing( nav.start = NULL, nav.end = NULL, freq.imu = NULL, freq.gps = NULL, freq.baro = NULL, gps.out.start = NULL, gps.out.end = NULL )
make_timing( nav.start = NULL, nav.end = NULL, freq.imu = NULL, freq.gps = NULL, freq.baro = NULL, gps.out.start = NULL, gps.out.end = NULL )
nav.start |
Time at which navigation starts |
nav.end |
Time at which navigation ends |
freq.imu |
Frequency of generated IMU data (and hence that of navigation) |
freq.gps |
Frequency of generated GPS data |
freq.baro |
Frequency of generated Baro data |
gps.out.start |
Time at which GPS outage starts |
gps.out.end |
Time at which GPS outage ends |
An object of class timing
containing sensor name and its additive error model along with the frequency associated to that model
Davide Cucci, Lionel Voirol, Mehran Khaghani, Stéphane Guerrier
timing <- make_timing( nav.start = 0, nav.end = 50, freq.imu = 10, freq.gps = 1, freq.baro = 1e-5, gps.out.start = 25.1, gps.out.end = 45 )
timing <- make_timing( nav.start = 0, nav.end = 50, freq.imu = 10, freq.gps = 1, freq.baro = 1e-5, gps.out.start = 25.1, gps.out.end = 45 )
trajectory
objectCreate a trajectory
object from simple matrix input.
make_trajectory( data, system = "ellipsoidal", start_time = NULL, name = NULL, ... )
make_trajectory( data, system = "ellipsoidal", start_time = NULL, name = NULL, ... )
data |
A multiple-column |
system |
A |
start_time |
A |
name |
A |
... |
Additional arguments. |
An object of class trajectory
.
Davide Cucci, Lionel Voirol, Mehran Khaghani, Stéphane Guerrier
n <- 100 dat <- cbind( seq(from = 0, to = 60 * 60, length.out = n), 46.204391 * pi / 180 + cumsum(rnorm(n)) / 10^5, 6.143158 * pi / 180 + cumsum(rnorm(n)) / 10^5, 375 + cumsum(rnorm(n)) ) traj <- make_trajectory(data = dat, name = "My cool data") traj plot(traj)
n <- 100 dat <- cbind( seq(from = 0, to = 60 * 60, length.out = n), 46.204391 * pi / 180 + cumsum(rnorm(n)) / 10^5, 6.143158 * pi / 180 + cumsum(rnorm(n)) / 10^5, 375 + cumsum(rnorm(n)) ) traj <- make_trajectory(data = dat, name = "My cool data") traj plot(traj)
this function plots the estimated IMU errors with covariance of a solution computed with the navigation
function
plot_imu_err_with_cov(sol, idx = 1, error = TRUE, step = 10)
plot_imu_err_with_cov(sol, idx = 1, error = TRUE, step = 10)
sol |
The set of solutions returned by the |
idx |
Which Monte-Carlo solution to plot |
error |
Whether to plot the error with respect to the reference or the estimated values |
step |
Plot one time out of |
A plot of the estimated IMU errors with covariance.
Davide Cucci, Lionel Voirol, Mehran Khaghani, Stéphane Guerrier
data("lemniscate_traj_ned") head(lemniscate_traj_ned) traj <- make_trajectory(data = lemniscate_traj_ned, system = "ned") plot(traj) timing <- make_timing( nav.start = 0, # time at which to begin filtering nav.end = 20, freq.imu = 100, # frequency of the IMU, can be slower wrt trajectory frequency freq.gps = 1, # GNSS frequency freq.baro = 1, # barometer frequency (to disable, put it very low, e.g. 1e-5) gps.out.start = 10, # to simulate a GNSS outage, set a time before nav.end gps.out.end =15 ) # create sensor for noise data generation snsr.mdl <- list() # this uses a model for noise data generation acc.mdl <- WN(sigma2 = 5.989778e-05) + AR1(phi = 9.982454e-01, sigma2 = 1.848297e-10) + AR1(phi = 9.999121e-01, sigma2 = 2.435414e-11) + AR1(phi = 9.999998e-01, sigma2 = 1.026718e-12) gyr.mdl <- WN(sigma2 = 1.503793e-06) + AR1(phi = 9.968999e-01, sigma2 = 2.428980e-11) + AR1(phi = 9.999001e-01, sigma2 = 1.238142e-12) snsr.mdl$imu <- make_sensor( name = "imu", frequency = timing$freq.imu, error_model1 = acc.mdl, error_model2 = gyr.mdl ) # RTK-like GNSS gps.mdl.pos.hor <- WN(sigma2 = 0.025^2) gps.mdl.pos.ver <- WN(sigma2 = 0.05^2) gps.mdl.vel.hor <- WN(sigma2 = 0.01^2) gps.mdl.vel.ver <- WN(sigma2 = 0.02^2) snsr.mdl$gps <- make_sensor( name = "gps", frequency = timing$freq.gps, error_model1 = gps.mdl.pos.hor, error_model2 = gps.mdl.pos.ver, error_model3 = gps.mdl.vel.hor, error_model4 = gps.mdl.vel.ver ) # Barometer baro.mdl <- WN(sigma2 = 0.5^2) snsr.mdl$baro <- make_sensor( name = "baro", frequency = timing$freq.baro, error_model1 = baro.mdl ) # define sensor for Kalmna filter KF.mdl <- list() # make IMU sensor KF.mdl$imu <- make_sensor( name = "imu", frequency = timing$freq.imu, error_model1 = acc.mdl, error_model2 = gyr.mdl ) KF.mdl$gps <- snsr.mdl$gps KF.mdl$baro <- snsr.mdl$baro # perform navigation simulation num.runs <- 5 # number of Monte-Carlo simulations res <- navigation( traj.ref = traj, timing = timing, snsr.mdl = snsr.mdl, KF.mdl = KF.mdl, num.runs = num.runs, noProgressBar = TRUE, PhiQ_method = "2", # order of the Taylor expansion of the matrix exponential used to compute Phi and Q matrices compute_PhiQ_each_n = 10, # compute new Phi and Q matrices every n IMU steps (execution time optimization) parallel.ncores = 1, P_subsampling = timing$freq.imu ) plot_imu_err_with_cov(res, error=FALSE)
data("lemniscate_traj_ned") head(lemniscate_traj_ned) traj <- make_trajectory(data = lemniscate_traj_ned, system = "ned") plot(traj) timing <- make_timing( nav.start = 0, # time at which to begin filtering nav.end = 20, freq.imu = 100, # frequency of the IMU, can be slower wrt trajectory frequency freq.gps = 1, # GNSS frequency freq.baro = 1, # barometer frequency (to disable, put it very low, e.g. 1e-5) gps.out.start = 10, # to simulate a GNSS outage, set a time before nav.end gps.out.end =15 ) # create sensor for noise data generation snsr.mdl <- list() # this uses a model for noise data generation acc.mdl <- WN(sigma2 = 5.989778e-05) + AR1(phi = 9.982454e-01, sigma2 = 1.848297e-10) + AR1(phi = 9.999121e-01, sigma2 = 2.435414e-11) + AR1(phi = 9.999998e-01, sigma2 = 1.026718e-12) gyr.mdl <- WN(sigma2 = 1.503793e-06) + AR1(phi = 9.968999e-01, sigma2 = 2.428980e-11) + AR1(phi = 9.999001e-01, sigma2 = 1.238142e-12) snsr.mdl$imu <- make_sensor( name = "imu", frequency = timing$freq.imu, error_model1 = acc.mdl, error_model2 = gyr.mdl ) # RTK-like GNSS gps.mdl.pos.hor <- WN(sigma2 = 0.025^2) gps.mdl.pos.ver <- WN(sigma2 = 0.05^2) gps.mdl.vel.hor <- WN(sigma2 = 0.01^2) gps.mdl.vel.ver <- WN(sigma2 = 0.02^2) snsr.mdl$gps <- make_sensor( name = "gps", frequency = timing$freq.gps, error_model1 = gps.mdl.pos.hor, error_model2 = gps.mdl.pos.ver, error_model3 = gps.mdl.vel.hor, error_model4 = gps.mdl.vel.ver ) # Barometer baro.mdl <- WN(sigma2 = 0.5^2) snsr.mdl$baro <- make_sensor( name = "baro", frequency = timing$freq.baro, error_model1 = baro.mdl ) # define sensor for Kalmna filter KF.mdl <- list() # make IMU sensor KF.mdl$imu <- make_sensor( name = "imu", frequency = timing$freq.imu, error_model1 = acc.mdl, error_model2 = gyr.mdl ) KF.mdl$gps <- snsr.mdl$gps KF.mdl$baro <- snsr.mdl$baro # perform navigation simulation num.runs <- 5 # number of Monte-Carlo simulations res <- navigation( traj.ref = traj, timing = timing, snsr.mdl = snsr.mdl, KF.mdl = KF.mdl, num.runs = num.runs, noProgressBar = TRUE, PhiQ_method = "2", # order of the Taylor expansion of the matrix exponential used to compute Phi and Q matrices compute_PhiQ_each_n = 10, # compute new Phi and Q matrices every n IMU steps (execution time optimization) parallel.ncores = 1, P_subsampling = timing$freq.imu ) plot_imu_err_with_cov(res, error=FALSE)
coverage.stat
objectsplot multiple coverages alltogether
## S3 method for class 'coverage.stat' plot(..., legend = NA, title = NA)
## S3 method for class 'coverage.stat' plot(..., legend = NA, title = NA)
... |
coverage, e.g., computed with |
legend |
Legend of the plot. |
title |
Title of the plot. |
a plot of the empirical coverage.
Davide Cucci, Lionel Voirol, Mehran Khaghani, Stéphane Guerrier
data("lemniscate_traj_ned") head(lemniscate_traj_ned) traj <- make_trajectory(data = lemniscate_traj_ned, system = "ned") plot(traj) timing <- make_timing( nav.start = 0, # time at which to begin filtering nav.end = 30, freq.imu = 100, # frequency of the IMU, can be slower wrt trajectory frequency freq.gps = 1, # GNSS frequency freq.baro = 1, # barometer frequency (to disable, put it very low, e.g. 1e-5) gps.out.start = 20, # to simulate a GNSS outage, set a time before nav.end gps.out.end = 25 ) # create sensor for noise data generation snsr.mdl <- list() # this uses a model for noise data generation acc.mdl <- WN(sigma2 = 5.989778e-05) + AR1(phi = 9.982454e-01, sigma2 = 1.848297e-10) + AR1(phi = 9.999121e-01, sigma2 = 2.435414e-11) + AR1(phi = 9.999998e-01, sigma2 = 1.026718e-12) gyr.mdl <- WN(sigma2 = 1.503793e-06) + AR1(phi = 9.968999e-01, sigma2 = 2.428980e-11) + AR1(phi = 9.999001e-01, sigma2 = 1.238142e-12) snsr.mdl$imu <- make_sensor( name = "imu", frequency = timing$freq.imu, error_model1 = acc.mdl, error_model2 = gyr.mdl ) # RTK-like GNSS gps.mdl.pos.hor <- WN(sigma2 = 0.025^2) gps.mdl.pos.ver <- WN(sigma2 = 0.05^2) gps.mdl.vel.hor <- WN(sigma2 = 0.01^2) gps.mdl.vel.ver <- WN(sigma2 = 0.02^2) snsr.mdl$gps <- make_sensor( name = "gps", frequency = timing$freq.gps, error_model1 = gps.mdl.pos.hor, error_model2 = gps.mdl.pos.ver, error_model3 = gps.mdl.vel.hor, error_model4 = gps.mdl.vel.ver ) # Barometer baro.mdl <- WN(sigma2 = 0.5^2) snsr.mdl$baro <- make_sensor( name = "baro", frequency = timing$freq.baro, error_model1 = baro.mdl ) # define sensor for Kalmna filter KF.mdl <- list() # make IMU sensor KF.mdl$imu <- make_sensor( name = "imu", frequency = timing$freq.imu, error_model1 = acc.mdl, error_model2 = gyr.mdl ) KF.mdl$gps <- snsr.mdl$gps KF.mdl$baro <- snsr.mdl$baro # perform navigation simulation num.runs <- 5 # number of Monte-Carlo simulations res <- navigation( traj.ref = traj, timing = timing, snsr.mdl = snsr.mdl, KF.mdl = KF.mdl, num.runs = num.runs, noProgressBar = TRUE, PhiQ_method = "2", # order of the Taylor expansion of the matrix exponential used to compute Phi and Q matrices compute_PhiQ_each_n = 10, # compute new Phi and Q matrices every n IMU steps (execution time optimization) parallel.ncores = 1, P_subsampling = timing$freq.imu ) # Empirical coverage coverage <- compute_coverage(res, alpha = 0.7, step = 100, idx = 1:6) plot(coverage)
data("lemniscate_traj_ned") head(lemniscate_traj_ned) traj <- make_trajectory(data = lemniscate_traj_ned, system = "ned") plot(traj) timing <- make_timing( nav.start = 0, # time at which to begin filtering nav.end = 30, freq.imu = 100, # frequency of the IMU, can be slower wrt trajectory frequency freq.gps = 1, # GNSS frequency freq.baro = 1, # barometer frequency (to disable, put it very low, e.g. 1e-5) gps.out.start = 20, # to simulate a GNSS outage, set a time before nav.end gps.out.end = 25 ) # create sensor for noise data generation snsr.mdl <- list() # this uses a model for noise data generation acc.mdl <- WN(sigma2 = 5.989778e-05) + AR1(phi = 9.982454e-01, sigma2 = 1.848297e-10) + AR1(phi = 9.999121e-01, sigma2 = 2.435414e-11) + AR1(phi = 9.999998e-01, sigma2 = 1.026718e-12) gyr.mdl <- WN(sigma2 = 1.503793e-06) + AR1(phi = 9.968999e-01, sigma2 = 2.428980e-11) + AR1(phi = 9.999001e-01, sigma2 = 1.238142e-12) snsr.mdl$imu <- make_sensor( name = "imu", frequency = timing$freq.imu, error_model1 = acc.mdl, error_model2 = gyr.mdl ) # RTK-like GNSS gps.mdl.pos.hor <- WN(sigma2 = 0.025^2) gps.mdl.pos.ver <- WN(sigma2 = 0.05^2) gps.mdl.vel.hor <- WN(sigma2 = 0.01^2) gps.mdl.vel.ver <- WN(sigma2 = 0.02^2) snsr.mdl$gps <- make_sensor( name = "gps", frequency = timing$freq.gps, error_model1 = gps.mdl.pos.hor, error_model2 = gps.mdl.pos.ver, error_model3 = gps.mdl.vel.hor, error_model4 = gps.mdl.vel.ver ) # Barometer baro.mdl <- WN(sigma2 = 0.5^2) snsr.mdl$baro <- make_sensor( name = "baro", frequency = timing$freq.baro, error_model1 = baro.mdl ) # define sensor for Kalmna filter KF.mdl <- list() # make IMU sensor KF.mdl$imu <- make_sensor( name = "imu", frequency = timing$freq.imu, error_model1 = acc.mdl, error_model2 = gyr.mdl ) KF.mdl$gps <- snsr.mdl$gps KF.mdl$baro <- snsr.mdl$baro # perform navigation simulation num.runs <- 5 # number of Monte-Carlo simulations res <- navigation( traj.ref = traj, timing = timing, snsr.mdl = snsr.mdl, KF.mdl = KF.mdl, num.runs = num.runs, noProgressBar = TRUE, PhiQ_method = "2", # order of the Taylor expansion of the matrix exponential used to compute Phi and Q matrices compute_PhiQ_each_n = 10, # compute new Phi and Q matrices every n IMU steps (execution time optimization) parallel.ncores = 1, P_subsampling = timing$freq.imu ) # Empirical coverage coverage <- compute_coverage(res, alpha = 0.7, step = 100, idx = 1:6) plot(coverage)
nees.stat
objectsplot multiple nees.stat
objects alltogether
## S3 method for class 'nees.stat' plot(..., alpha = 0.95, legend = NA, title = NA)
## S3 method for class 'nees.stat' plot(..., alpha = 0.95, legend = NA, title = NA)
... |
NEES, e.g., computed with |
alpha |
for the confidence interval plot |
legend |
legend of the plot. |
title |
title of the plot. |
Produce a plot of the Normalized Estimation Error Squared (NEES) for the nees.stat
object provided.
Davide Cucci, Lionel Voirol, Mehran Khaghani, Stéphane Guerrier
data("lemniscate_traj_ned") head(lemniscate_traj_ned) traj <- make_trajectory(data = lemniscate_traj_ned, system = "ned") plot(traj) timing <- make_timing( nav.start = 0, # time at which to begin filtering nav.end = 30, freq.imu = 100, # frequency of the IMU, can be slower wrt trajectory frequency freq.gps = 1, # GNSS frequency freq.baro = 1, # barometer frequency (to disable, put it very low, e.g. 1e-5) gps.out.start = 20, # to simulate a GNSS outage, set a time before nav.end gps.out.end = 25 ) # create sensor for noise data generation snsr.mdl <- list() # this uses a model for noise data generation acc.mdl <- WN(sigma2 = 5.989778e-05) + AR1(phi = 9.982454e-01, sigma2 = 1.848297e-10) + AR1(phi = 9.999121e-01, sigma2 = 2.435414e-11) + AR1(phi = 9.999998e-01, sigma2 = 1.026718e-12) gyr.mdl <- WN(sigma2 = 1.503793e-06) + AR1(phi = 9.968999e-01, sigma2 = 2.428980e-11) + AR1(phi = 9.999001e-01, sigma2 = 1.238142e-12) snsr.mdl$imu <- make_sensor( name = "imu", frequency = timing$freq.imu, error_model1 = acc.mdl, error_model2 = gyr.mdl ) # RTK-like GNSS gps.mdl.pos.hor <- WN(sigma2 = 0.025^2) gps.mdl.pos.ver <- WN(sigma2 = 0.05^2) gps.mdl.vel.hor <- WN(sigma2 = 0.01^2) gps.mdl.vel.ver <- WN(sigma2 = 0.02^2) snsr.mdl$gps <- make_sensor( name = "gps", frequency = timing$freq.gps, error_model1 = gps.mdl.pos.hor, error_model2 = gps.mdl.pos.ver, error_model3 = gps.mdl.vel.hor, error_model4 = gps.mdl.vel.ver ) # Barometer baro.mdl <- WN(sigma2 = 0.5^2) snsr.mdl$baro <- make_sensor( name = "baro", frequency = timing$freq.baro, error_model1 = baro.mdl ) # define sensor for Kalmna filter KF.mdl <- list() # make IMU sensor KF.mdl$imu <- make_sensor( name = "imu", frequency = timing$freq.imu, error_model1 = acc.mdl, error_model2 = gyr.mdl ) KF.mdl$gps <- snsr.mdl$gps KF.mdl$baro <- snsr.mdl$baro # perform navigation simulation num.runs <- 2 # number of Monte-Carlo simulations res <- navigation( traj.ref = traj, timing = timing, snsr.mdl = snsr.mdl, KF.mdl = KF.mdl, num.runs = num.runs, noProgressBar = TRUE, PhiQ_method = "1", # order of the Taylor expansion of the matrix exponential used to compute Phi and Q matrices compute_PhiQ_each_n = 10, # compute new Phi and Q matrices every n IMU steps (execution time optimization) parallel.ncores = 1, P_subsampling = timing$freq.imu ) nees <- compute_nees(res, idx = 1:6, step = 100) plot(nees)
data("lemniscate_traj_ned") head(lemniscate_traj_ned) traj <- make_trajectory(data = lemniscate_traj_ned, system = "ned") plot(traj) timing <- make_timing( nav.start = 0, # time at which to begin filtering nav.end = 30, freq.imu = 100, # frequency of the IMU, can be slower wrt trajectory frequency freq.gps = 1, # GNSS frequency freq.baro = 1, # barometer frequency (to disable, put it very low, e.g. 1e-5) gps.out.start = 20, # to simulate a GNSS outage, set a time before nav.end gps.out.end = 25 ) # create sensor for noise data generation snsr.mdl <- list() # this uses a model for noise data generation acc.mdl <- WN(sigma2 = 5.989778e-05) + AR1(phi = 9.982454e-01, sigma2 = 1.848297e-10) + AR1(phi = 9.999121e-01, sigma2 = 2.435414e-11) + AR1(phi = 9.999998e-01, sigma2 = 1.026718e-12) gyr.mdl <- WN(sigma2 = 1.503793e-06) + AR1(phi = 9.968999e-01, sigma2 = 2.428980e-11) + AR1(phi = 9.999001e-01, sigma2 = 1.238142e-12) snsr.mdl$imu <- make_sensor( name = "imu", frequency = timing$freq.imu, error_model1 = acc.mdl, error_model2 = gyr.mdl ) # RTK-like GNSS gps.mdl.pos.hor <- WN(sigma2 = 0.025^2) gps.mdl.pos.ver <- WN(sigma2 = 0.05^2) gps.mdl.vel.hor <- WN(sigma2 = 0.01^2) gps.mdl.vel.ver <- WN(sigma2 = 0.02^2) snsr.mdl$gps <- make_sensor( name = "gps", frequency = timing$freq.gps, error_model1 = gps.mdl.pos.hor, error_model2 = gps.mdl.pos.ver, error_model3 = gps.mdl.vel.hor, error_model4 = gps.mdl.vel.ver ) # Barometer baro.mdl <- WN(sigma2 = 0.5^2) snsr.mdl$baro <- make_sensor( name = "baro", frequency = timing$freq.baro, error_model1 = baro.mdl ) # define sensor for Kalmna filter KF.mdl <- list() # make IMU sensor KF.mdl$imu <- make_sensor( name = "imu", frequency = timing$freq.imu, error_model1 = acc.mdl, error_model2 = gyr.mdl ) KF.mdl$gps <- snsr.mdl$gps KF.mdl$baro <- snsr.mdl$baro # perform navigation simulation num.runs <- 2 # number of Monte-Carlo simulations res <- navigation( traj.ref = traj, timing = timing, snsr.mdl = snsr.mdl, KF.mdl = KF.mdl, num.runs = num.runs, noProgressBar = TRUE, PhiQ_method = "1", # order of the Taylor expansion of the matrix exponential used to compute Phi and Q matrices compute_PhiQ_each_n = 10, # compute new Phi and Q matrices every n IMU steps (execution time optimization) parallel.ncores = 1, P_subsampling = timing$freq.imu ) nees <- compute_nees(res, idx = 1:6, step = 100) plot(nees)
trajectory
objectPlot a trajectory
object in 2D or 3D.
## S3 method for class 'trajectory' plot( x, threeD = FALSE, col = "#2980b9", col_start = "#e67e22", col_end = "#e67e22", pch_points_start = 15, pch_points_end = 16, cex_points = 1.5, add_altitude = TRUE, n_split = 6, plot_end_points = TRUE, add_title = TRUE, threeD_line_width = 4, threeD_line_color = "#008080", threeD_col_grad = FALSE, threeD_grad_start = "#008080", threeD_grad_end = "#ab53cf", ... )
## S3 method for class 'trajectory' plot( x, threeD = FALSE, col = "#2980b9", col_start = "#e67e22", col_end = "#e67e22", pch_points_start = 15, pch_points_end = 16, cex_points = 1.5, add_altitude = TRUE, n_split = 6, plot_end_points = TRUE, add_title = TRUE, threeD_line_width = 4, threeD_line_color = "#008080", threeD_col_grad = FALSE, threeD_grad_start = "#008080", threeD_grad_end = "#ab53cf", ... )
x |
A |
threeD |
A |
col |
A |
col_start |
A |
col_end |
A |
pch_points_start |
A |
pch_points_end |
A |
cex_points |
A |
add_altitude |
A |
n_split |
A |
plot_end_points |
A |
add_title |
A |
threeD_line_width |
A |
threeD_line_color |
A |
threeD_col_grad |
A |
threeD_grad_start |
A |
threeD_grad_end |
A |
... |
Additional arguments affecting the plot produced. |
A trajectory plot.
Davide Cucci, Lionel Voirol, Mehran Khaghani, Stéphane Guerrier
n <- 100 set.seed(123) dat <- cbind( seq(from = 0, to = 60 * 60, length.out = n), 46.204391 * pi / 180 + cumsum(rnorm(n)) / 10^5, 6.143158 * pi / 180 + cumsum(rnorm(n)) / 10^5, 375 + cumsum(rnorm(n)) ) traj <- make_trajectory(data = dat, name = "My cool data") plot(traj) plot(traj, threeD = TRUE) plot(traj, threeD = TRUE, threeD_line_width = 8, threeD_line_color = "#e74c3c" ) plot(traj, threeD = TRUE, threeD_col_grad = TRUE ) plot(traj, threeD = TRUE, threeD_col_grad = TRUE, threeD_grad_start = "#e74c3c", threeD_grad_end = "#d68910" ) traj <- make_trajectory(data = dat, name = "My cool data", system = "ned") plot(traj) plot(traj, col = "orange2", col_start = "pink", col_end = "purple") plot(traj, pch_points_start = 15, cex_points = 3) plot(traj, plot_end_points = FALSE) plot(traj, plot_end_points = FALSE, add_title = FALSE)
n <- 100 set.seed(123) dat <- cbind( seq(from = 0, to = 60 * 60, length.out = n), 46.204391 * pi / 180 + cumsum(rnorm(n)) / 10^5, 6.143158 * pi / 180 + cumsum(rnorm(n)) / 10^5, 375 + cumsum(rnorm(n)) ) traj <- make_trajectory(data = dat, name = "My cool data") plot(traj) plot(traj, threeD = TRUE) plot(traj, threeD = TRUE, threeD_line_width = 8, threeD_line_color = "#e74c3c" ) plot(traj, threeD = TRUE, threeD_col_grad = TRUE ) plot(traj, threeD = TRUE, threeD_col_grad = TRUE, threeD_grad_start = "#e74c3c", threeD_grad_end = "#d68910" ) traj <- make_trajectory(data = dat, name = "My cool data", system = "ned") plot(traj) plot(traj, col = "orange2", col_start = "pink", col_end = "purple") plot(traj, pch_points_start = 15, cex_points = 3) plot(traj, plot_end_points = FALSE) plot(traj, plot_end_points = FALSE, add_title = FALSE)
sensor
object parameters (name, frequency and error model)Print method for a sensor
object
## S3 method for class 'sensor' print(x, ...)
## S3 method for class 'sensor' print(x, ...)
x |
A |
... |
Further arguments passed to or from other methods. |
Print the sensor
object name and specifications in the console.
Davide Cucci, Lionel Voirol, Mehran Khaghani, Stéphane Guerrier
# IMU: imu.freq <- 250 acc.mdl <- WN(sigma2 = 1.535466e-04) + RW(gamma2 = 1.619511e-10) gyr.mdl <- WN(sigma2 = 1.711080e-03) + RW(gamma2 = 1.532765e-13) imu.mdl <- make_sensor( name = "imu", frequency = imu.freq, error_model1 = acc.mdl, error_model2 = gyr.mdl ) print(imu.mdl)
# IMU: imu.freq <- 250 acc.mdl <- WN(sigma2 = 1.535466e-04) + RW(gamma2 = 1.619511e-10) gyr.mdl <- WN(sigma2 = 1.711080e-03) + RW(gamma2 = 1.532765e-13) imu.mdl <- make_sensor( name = "imu", frequency = imu.freq, error_model1 = acc.mdl, error_model2 = gyr.mdl ) print(imu.mdl)
Transform position from ellipsoidal coordinates to a fixed Cartesian NED frame
X_ellips2ned(x, x_o = NULL)
X_ellips2ned(x, x_o = NULL)
x |
An object of class |
x_o |
Origin of the fixed Cartesian NED frame expressed in ellipsoidal coordinates |
An object of class trajectory
in "NED" system or a matrix of position data with x_N, x_E, and x_D, according to the type of input x
Davide Cucci, Lionel Voirol, Mehran Khaghani, Stéphane Guerrier
library(navigation) data("example_1_traj_ellipsoidal") traj_ellips <- make_trajectory(example_1_traj_ellipsoidal, system = "ellipsoidal") plot(traj_ellips) plot(traj_ellips, threeD = TRUE) traj_ned <- X_ellips2ned(traj_ellips, x_o = example_1_traj_ellipsoidal[1, -1]) plot(traj_ned)
library(navigation) data("example_1_traj_ellipsoidal") traj_ellips <- make_trajectory(example_1_traj_ellipsoidal, system = "ellipsoidal") plot(traj_ellips) plot(traj_ellips, threeD = TRUE) traj_ned <- X_ellips2ned(traj_ellips, x_o = example_1_traj_ellipsoidal[1, -1]) plot(traj_ned)
Transform position from a fixed Cartesian NED frame to ellipsoidal coordinates
X_ned2ellips(x, x_o = NULL)
X_ned2ellips(x, x_o = NULL)
x |
An object of class |
x_o |
Origin of the fixed Cartesian NED frame expressed in ellipsoidal coordinates |
An object of class trajectory
in "ellipsoidal" system or a matrix of position data with latitude, longitude, and altitude, according to the type of input x
Davide Cucci, Lionel Voirol, Mehran Khaghani, Stéphane Guerrier
data("example_1_traj_ned") traj_ned <- make_trajectory(example_1_traj_ned, system = "ned") plot(traj_ned) traj_ellips <- X_ned2ellips(traj_ned, x_o = example_1_traj_ellipsoidal[1, -1]) plot(traj_ellips, threeD = FALSE) plot(traj_ellips, threeD = TRUE)
data("example_1_traj_ned") traj_ned <- make_trajectory(example_1_traj_ned, system = "ned") plot(traj_ned) traj_ellips <- X_ned2ellips(traj_ned, x_o = example_1_traj_ellipsoidal[1, -1]) plot(traj_ellips, threeD = FALSE) plot(traj_ellips, threeD = TRUE)