Using the MagNav Package with Simulated Data
This file is best viewed in a Pluto notebook. To run it this way, from the MagNav.jl directory, do:
julia> using Pluto
julia> Pluto.run() # select & open notebook
This is a reactive notebook, so feel free to change any parameters of interest.
Import packages and DataFrames
The DataFrames listed below provide useful information about the flight data collected by Sander Geophysics Ltd. (SGL) & magnetic anomaly maps.
Dataframe | Description |
---|---|
df_map | map files relevant for SGL flights |
df_cal | SGL calibration flight lines |
df_flight | SGL flight files |
df_all | all flight lines |
df_nav | all navigation-capable flight lines |
df_event | pilot-recorded in-flight events |
begin
cd(@__DIR__)
# uncomment line below to use local MagNav.jl (downloaded folder)
# using Pkg; Pkg.activate("../"); Pkg.instantiate()
using MagNav
using CSV, DataFrames
using Plots: plot, plot!
using Random: seed!
using Statistics: mean, median, std
seed!(33); # for reproducibility
include("dataframes_setup.jl"); # setup DataFrames
end;
Load map data and create flight data
The built-in NAMAD map is used to create flight data.
begin
seed!(33) # ensure create_XYZ0() reproducibility
t = 600 # flight time [s]
mapS = get_map(MagNav.namad) # load map data
xyz = create_XYZ0(mapS;alt=mapS.alt,t=t) # create flight data
traj = xyz.traj # trajectory (GPS) struct
ins = xyz.ins # INS struct
mapS = map_trim(mapS,traj;pad=10) # trim map for given trajectory (with padding)
itp_mapS = map_interpolate(mapS) # map interpolation function
end;
The xyz
flight data struct is of type MagNav.XYZ0
(for the minimum dataset required for MagNav), which is a subtype of MagNav.XYZ
(the abstract type for any flight data in MagNav.jl). There are 7 fields, which can be accessed using dot notation. These fields are described in the docs, which are easily accessed by searching MagNav.XYZ0
in the Live Docs in the lower right within Pluto.
typeof(xyz)
MagNav.XYZ0{Int64, Float64}
fieldnames(MagNav.XYZ0)
(:info, :traj, :ins, :flux_a, :flight, :line, :year, :doy, :diurnal, :igrf, :mag_1_c, :mag_1_uc)
Navigation
Create a navigation filter model.
(P0,Qd,R) = create_model(traj.dt,traj.lat[1]);
Run the navigation filter (EKF), determine the Cramér–Rao lower bound (CRLB), & extract output data.
begin
mag_use = xyz.mag_1_c # selected magnetometer (using compensated mag)
(crlb_out,ins_out,filt_out) = run_filt(traj,ins,mag_use,itp_mapS,:ekf;P0,Qd,R)
end;
Plotting setup.
begin
t0 = traj.tt[1]/60 # [min]
tt = traj.tt/60 .- t0 # [min]
end;
Position (lat & lot) for trajectory (GPS), INS (after zeroing), & navigation filter.
begin
p1 = plot_map(mapS;map_color=:gray); # map background
plot_filt!(p1,traj,ins,filt_out;show_plot=false) # overlay GPS, INS, & filter
plot!(p1,legend=:topleft) # move as needed
end
Northing & easting INS error (after zeroing).
begin
p2 = plot(xlab="time [min]",ylab="error [m]",legend=:topright,dpi=200)
plot!(p2,tt,ins_out.n_err,lab="northing")
plot!(p2,tt,ins_out.e_err,lab="easting")
end
(p3,p4) = plot_filt_err(traj,filt_out,crlb_out;show_plot=false);
Northing navigation filter residuals.
p3
Easting navigation filter residuals.
p4
Display the map or flight paths in Google Earth by uncommenting below to generate a KMZ file (mapS
) or KML files (traj
, ins
, filt_out
), then open in Google Earth.
begin
# map2kmz(mapS,"pluto_sim_map")
# path2kml(traj,"pluto_sim_gps")
# path2kml(ins,"pluto_sim_ins")
# path2kml(filt_out,"pluto_sim_filt")
end;