drms (generic function with 1 method)
IEEE/ION PLANS 2023, Monterey, CA
The views expressed in this article are those of the author and do not necessarily reflect the official policy or position of the United States Government, Department of Defense, United States Air Force or Air University.
Distribution A: Authorized for public release. Distribution is unlimited. Case No. 2023-0277.
https://rpubs.com/friendly/test-newcommands https://quarto.org/docs/authoring/markdown-basics.html#equations
https://stackoverflow.com/questions/41362012/how-to-insert-font-awesome-icons-in-mathjax
Font-Awesome will only work for html type output
\[ \newcommand{\dvec}[1]{\dot{\vec{#1}}} \newcommand{\ddvec}[1]{\ddot{\vec{#1}}} \newcommand{\mat}[1]{\mathbf{#1}} \newcommand{\earth}{{\oplus}} \newcommand{\ext}{\text{ext}} \newcommand{\faPlane}{\class{fa fa-plane}{}} \newcommand{\plane}{\class{fa fa-plane}{}} \newcommand{\sensor}{\text{Sensor}} \]
Loads julia configurations and sources needed code.
drms (generic function with 1 method)
Schedule
Tutorial is 90 minutes total:
Outline
Magnetic Anomaly Navigation Overview
Requirements for MagNav
Discuss publicly available MagNav software and dataset
Learn and perform traditional aircraft calibration
- Tolles-Lawson
Evaluate navigation performance
Calibration/noise removal
Navigation performance improvement
Refrigerator magnet
Earth’s core field (compass)
Crustal magnetic anomaly
1 000 000 nT
Range \(\pm\) 500 nT
Resolution \(\sim\) 1 nT https://mrdata.usgs.gov/magnetic/ (Bankey et al. 2002)
Inertial Measurement Unit (IMU)
To get position from accleration, you have to integrate twice
Drifting position estimate needs to be corrected
Features are required to navigate
Magnetic anomaly closely tied to geology
Area and direction of travel make a difference
-The primary sensor used is a scalar magnetometer which measures: \(|\vec{B}|\)
-The field is a vector \(\vec{B}\)
-Interpretation of \(|\vec{B}|\) relies on understanding
\(|\vec{B}_\sensor| = |\vec{B}_\earth + \vec{B}_\text{anomaly}|\)
\(|\vec{B}| = |\vec{B}_\earth + \vec{B}_\text{anomaly} + \vec{B}_\plane|\)
Sensor placement and installation
Degaussing
Algorithms
Collected data and made publicly available:
Created software suite published on GitHub:
https://github.com/MIT-AI-Accelerator/MagNav.jl
https://hub.docker.com/r/jtaylormit/magnav
USGS Magnetic Data
NCEI NOAA Trackline database
Magnetic anomaly maps are usually made at a single altitude.
The process of taking a magnetic map from one altitude to another.
The process of taking a magnetic map from one altitude to another.
\[ \begin{align*} |B_\mathrm{Sensor}| &= |\vec{B}_\ext + \vec{B}_\faPlane|\\ &= \sqrt{ |B_\ext|^2 + |B_\faPlane|^2 + 2 |B_\ext||B_\faPlane|\cos\theta}\\ |B_\text{Sensor}| &= |B_\ext| \sqrt{ 1 + \frac{|B_\faPlane|^2}{|B_\ext|^2} + 2\frac{|B_\faPlane|}{|B_\ext|}\cos\theta} \end{align*} \]
\[
\begin{align*}
|B_\text{Sensor}| &= |\vec{B}_\ext + \vec{B}_\faPlane|\\
&= \sqrt{ |B_\ext|^2 + |B_\faPlane|^2 + 2 |B_\ext||B_\faPlane|\cos\theta}\\
|B_\text{Sensor}| &= |B_\ext| \sqrt{ 1 + 2\frac{|B_\faPlane|}{|B_\ext|}\cos\theta}\\
&\approx |B_\ext| + |B_\faPlane|\cos\theta + \cdots
\end{align*}
\]
Path to Calibration
Measure \(\cos\theta\)
Solve \(|B_\text{sensor}| = |B_\ext| + |B_\plane|\cos\theta\)
Assuming \(|B_\ext|\) is known or constant
Path to Calibration
Measure \(\cos\theta\)
Solve \(|B_\text{sensor}| = |B_\ext| + |B_\faPlane|\cos\theta\)
Assuming \(|B_\ext|\) is known or constant
How to measure \(\cos\theta\)?
Use a vector magnetometer
Rotate aircraft in \(|B_\ext|\)
Compute direction cosines…
In the 2-D example, \(B_z = 0\)
Coordinate system fixed to aircraft
\[\vec{B}_\mathrm{Sensor} = \vec{B}_\ext + \vec{B}_\faPlane\]
\[
\begin{alignat*}{3}
\vec{B}_\ext &= 4.0 \hat{x} && + 0.0 \hat{y} \\
\vec{B}_\faPlane &= 0.5 \hat{x} && +0.0 \hat{y} \\
\vec{B}_\text{Sensor} &= 4.5 \hat{x} && + 0.0 \hat{y} \\
|B_\text{Sensor}| &= 4.5 && \\
\cos X &= \frac{4.5}{4.5} && = 1\\
\cos Y &= \frac{0.0}{4.5} && = 0\\
\end{alignat*}
\]
Coordinate system fixed to aircraft
\[\vec{B}_\text{Sensor} = \vec{B}_\ext + \vec{B}_\faPlane\]
\[
\begin{alignat*}{3}
\vec{B}_\ext &= 0.0 \hat{x} && + 4.0 \hat{y} \\
\vec{B}_\faPlane &= 0.5 \hat{x} && + 0.0 \hat{y} \\
\vec{B}_\text{Sensor} &= 0.5 \hat{x} && + 4.0 \hat{y} \\
|B_\text{Sensor}| &= 4.007 && \\
\cos X &= \frac{0.5}{4.007} && \ne 0 \rightarrow 82.8^\circ\\
\cos Y &= \frac{4.0}{4.007} && \approx 1\\
\end{alignat*}
\]
Coordinate system fixed to aircraft
\[\vec{B}_\text{Sensor} = \vec{B}_\ext + \vec{B}_\faPlane\]
\[
\begin{alignat*}{3}
\vec{B}_\ext &= -4.0 \hat{x} && + 0.0 \hat{y} \\
\vec{B}_\faPlane &= 0.5 \hat{x} && + 0.0 \hat{y} \\
\vec{B}_\text{Sensor} &= -3.5 \hat{x} && + 0.0 \hat{y} \\
|B_\text{Sensor}| &= 3.5 && \\
\cos X &= \frac{-3.5}{3.5} && = -1\\
\cos Y &= \frac{0}{3.5} && = 0\\
\end{alignat*}
\]
Coordinate system fixed to aircraft
\[\vec{B}_\text{Sensor} = \vec{B}_\ext + \vec{B}_\faPlane\]
\[
\begin{alignat*}{3}
\vec{B}_\ext &= 0.0 \hat{x} && + -4.0 \hat{y} \\
\vec{B}_\faPlane &= 0.5 \hat{x} && + 0.0 \hat{y} \\
\vec{B}_\text{Sensor} &= 0.5 \hat{x} && + -4.0 \hat{y} \\
|B_\text{Sensor}| &= 4.007 &&\\
\cos X &= \frac{0.5}{4.007} && \ne 0\\
\cos Y &= \frac{-4.0}{4.007} && \approx -1\\
\end{alignat*}
\]
\[|\vec{B}| = |\vec{B}_\ext + \vec{B}_\faPlane|\]
\[ \begin{array}{ l B c B c B c } \vec{B}_\faPlane & = & \vec{B}_\text{Permanent} & + & \vec{B}_\text{Induced} & + & \vec{B}_\text{Eddy}\\ & = & \vec{P}_\text{constant} {} & + &{} M_{3\times3} \vec{B }_\ext {} & + & {} S_{3\times3} \frac{\partial}{\partial t} \vec{B}_\ext \end{array} \]
\(M_{3\times3}\) is symmetric \(\rightarrow\) 6 independent elements
Total of 18 elements
The direction cosines are computed from the vector magnetometer
\[ \begin{aligned} \cos X = & \frac{B_x}{\sqrt{B_x^2 + B_y^2 + B_z^2}}\\ \cos Y = & \frac{B_y}{\sqrt{B_x^2 + B_y^2 + B_z^2}}\\ \cos Z = & \frac{B_z}{\sqrt{B_x^2 + B_y^2 + B_z^2}} \end{aligned} \]
\[
\begin{aligned}
B_\plane & = & & { c_1 \cos X + c_2 \cos Y + c_3 \cos Z }+ \\
& & B_\ext & {[ c_4 \cos^2 X + c_5 \cos X \cos Y + c_6 \cos X \cos Z +} \\
& & & { c_7 \cos^2 Y + c_8 \cos Y \cos Z + c_9 \cos^2 Z ] + } \\
& & B_\ext & { [ c_{10} \cos X \cos' X + c_{11} \cos X \cos' Y + c_{12} \cos X \cos' Z }+ \\
& & & { c_{13} \cos Y \cos' X + c_{14} \cos Y \cos' Y + c_{15} \cos Y \cos' Z +} \\
& & & { c_{16} \cos Z \cos' X + c_{17} \cos Z \cos' Y + c_{18} \cos Z \cos' Z ] }
\end{aligned}
\]
We need a method to solve for \(c_1 \ldots c_{18}\)
How to sample the range of possible angles?
Fly the aircraft in a series of Roll, Pitch, Yaw maneuvers
High-altitude
Altitude of a known map
Maneuver angle should depend upon the expected aircraft dynamics
Typically at each cardinal heading
Pack your air-sickness bag
(W. E. Tolles and Lawson 1950), (W. E. Tolles 1954), (W. E. Tolles 1955), (Gnadt, Wollaber, and Nielsen 2022)
\[ A = \begin{bmatrix} \cos X_1 & \cdots & \cos X_N\\ \cos Y_1 & \cdots & \cos Y_N \\ \cos Z_1 & \cdots & \cos Z_N\\ B_\ext \cos^2 X_1 & \cdots & B_\ext \cos^2 X_N\\ B_\ext \cos X_1 \cos Y_1 & \cdots & B_\ext \cos X_N \cos Y_N\\ B_\ext \cos X_1 \cos Z_1 & \cdots & B_\ext \cos X_N \cos Z_N \\ B_\ext \cos^2 Y_1 & \cdots & B_\ext \cos^2 Y_N \\ B_\ext \cos Y_1 \cos Z_1 & \cdots & B_\ext \cos Y_N \cos Z_N\\ B_\ext \cos^2 Z_1 & \cdots & B_\ext \cos^2 Z_N\\ B_\ext \cos X_1 \cos' X_1 & \cdots & B_\ext \cos X_N \cos' X_N \\ B_\ext \cos X_1 \cos' Y_1 & \cdots & B_\ext \cos X_N \cos' Y_N\\ B_\ext \cos X_1 \cos' Z_1 & \cdots & B_\ext \cos X_N \cos' Z_N\\ B_\ext \cos Y_1 \cos' X_1 & \cdots & B_\ext \cos Y_N \cos' X_N\\ \vdots & & \vdots \\ B_\ext \cos Z_1 \cos' Z_1 & \cdots & B_\ext \cos Z_N \cos' Z_N \\ \end{bmatrix} \]
\(B_\ext\) is the magnitude of the external field. We assume that \[
B_\ext = \sqrt{B_x^2 + B_y^2 + B_z^2}
\]
Equivalently that the vector mags only see external field. The anomaly signal is below the noise floor.
Map-less calibration
Perform maneuvers at fixed frequency \(f\)
Band-pass filter columns of \(A\), \(B_\text{scalar}\) \[
\begin{aligned}
A_f & = BPF(A)\\
B_{\text{scalar},f} & = BPF(B_{\text{scalar}})
\end{aligned}
\]
Solve for \(c\)
\[
A_f c = B_{\text{scalar},f}
\]
Map-based calibration
Perform maneuvers over known-good map
Solve for \(c\)
\[
A c = B_{\text{sensor}} - B_{\earth} - B_{\text{anomaly}}
\]
In-flight
Compute \(A_i\) for each time-step
Apply \(c\)
\[
B_\text{plane} = A c
\]
\[
B_\text{anomaly} = B_\text{sensor} - B_\earth - B_\faPlane
\]
Load the data which includes the following dataframes:
Dataframe | Description |
---|---|
df_map | Map files for SGL flights |
df_comp | SGL compensation flight lines |
df_flight | SGL flight files |
df_all | All flight lines |
df_nav | All navigation capable flight lines |
df_events | Pilot-recorded flight events |
Dataframe df_comp
has flight times of compensation maneuvers
16×5 DataFrame
Row │ flight line t_start t_end map_name
│ Symbol Float64 Float64 Float64 Symbol?
─────┼─────────────────────────────────────────────────
1 │ Flt1002 1002.02 46390.9 46964.5 missing
2 │ Flt1002 1002.02 47027.1 47546.3 missing
3 │ Flt1002 1002.2 66571.7 67131.8 missing
4 │ Flt1002 1002.2 67276.8 67839.2 missing
5 │ Flt1006 1006.02 47222.0 48213.0 missing
6 │ Flt1006 1006.04 49165.3 49798.5 missing
7 │ Flt1006 1006.04 49940.1 50318.5 missing
8 │ Flt1006 1006.04 50340.7 50804.2 missing
9 │ Flt1006 1006.04 50829.7 51301.7 missing
10 │ Flt1006 1006.04 51377.5 52013.8 missing
11 │ Flt1006 1006.04 52013.8 52372.0 missing
12 │ Flt1006 1006.04 52408.4 52843.1 missing
13 │ Flt1006 1006.04 52861.8 53286.0 missing
14 │ Flt1006 1006.06 53855.0 54510.0 missing
15 │ Flt1006 1006.08 55774.5 56192.0 Eastern_395
16 │ Flt1006 1006.08 56192.0 56609.0 Eastern_395
Select Flight 1006 for analysis:
16×5 DataFrame
Row │ flight line t_start t_end map_name
│ Symbol Float64 Float64 Float64 Symbol?
─────┼─────────────────────────────────────────────────
1 │ Flt1002 1002.02 46390.9 46964.5 missing
2 │ Flt1002 1002.02 47027.1 47546.3 missing
3 │ Flt1002 1002.2 66571.7 67131.8 missing
4 │ Flt1002 1002.2 67276.8 67839.2 missing
5 │ Flt1006 1006.02 47222.0 48213.0 missing
6 │ Flt1006 1006.04 49165.3 49798.5 missing
7 │ Flt1006 1006.04 49940.1 50318.5 missing
8 │ Flt1006 1006.04 50340.7 50804.2 missing
9 │ Flt1006 1006.04 50829.7 51301.7 missing
10 │ Flt1006 1006.04 51377.5 52013.8 missing
11 │ Flt1006 1006.04 52013.8 52372.0 missing
12 │ Flt1006 1006.04 52408.4 52843.1 missing
13 │ Flt1006 1006.04 52861.8 53286.0 missing
14 │ Flt1006 1006.06 53855.0 54510.0 missing
15 │ Flt1006 1006.08 55774.5 56192.0 Eastern_395
16 │ Flt1006 1006.08 56192.0 56609.0 Eastern_395
Applied to the compensation data
Magnetometer 4 300 nT/division
Dataframe df_nav
has all the navigation flight lines
2 rows × 8 columns
flight | line | t_start | t_end | full_line | map_name | map_type | traj_alt | |
---|---|---|---|---|---|---|---|---|
Symbol | Float64 | Float64 | Float64 | Bool | Symbol | Symbol | Int64 | |
1 | Flt1006 | 1006.08 | 55770.0 | 56609.0 | 1 | Eastern_395 | HAE | 397 |
2 | Flt1006 | 1006.09 | 56965.0 | 57480.0 | 0 | Eastern_395 | HAE | 574 |
Select line 1006.08
and get its indices:
Magnetometer 4 300 nT/division
p = plot(
traj_flt.tt[ind],
mag_4_uc,
xlabel="Time [seconds]",
ylabel="Magetic intensity [nT]",
legend=true,
label="Uncomp Mag 4",
linecolor=:green
);
plot!(
traj_flt.tt[ind],
mag_4_c,
label="Comp Mag 4",
linecolor=:black
)
plot!(
traj_flt.tt[ind],
mag_1_sgl,
label="Comp tail Stinger",
linecolor=:red
)
plot!(p; double_pane_defs...)
Magnetometer 5 100 nT/division
p = plot(
traj_flt.tt[ind],
mag_5_uc,
xlabel="Time [seconds]",
ylabel="Magetic intensity [nT]",
legend=true,
label="Uncomp Mag 5",
linecolor=:green
);
plot!(
traj_flt.tt[ind],
mag_5_c,
label="Comp Mag 5",
linecolor=:black
)
plot!(
traj_flt.tt[ind],
mag_1_sgl,
label="Comp tail Stinger",
linecolor=:red
)
plot!(p; double_pane_defs...)
Magnetometer 4
p = plot(
traj_flt.tt[ind],
detrend(mag_4_c-mag_1_sgl;mean_only=true),
xlabel="Time [seconds]",
ylabel="Magnetic intensity [nT]",
legend=true,
linecolor=:black,
label="Comp 4 - Comp Stinger"
)
plot!(
traj_flt.tt[ind],
detrend(mag_4_uc-mag_1_sgl;mean_only=true),
linecolor=:green,
label="Uncomp 4 - Comp Stinger"
)
plot!(p; double_pane_defs...)
Magnetometer 5
p = plot(
traj_flt.tt[ind],
detrend(mag_5_c-mag_1_sgl;mean_only=true),
xlabel="Time [seconds]",
ylabel="Magnetic intensity [nT]",
legend=true,
linecolor=:black,
label="Comp 5 - Comp Stinger"
)
plot!(
traj_flt.tt[ind],
detrend(mag_5_uc-mag_1_sgl;mean_only=true),
linecolor=:green,
label="Uncomp 5 - Comp Stinger"
)
plot!(p; double_pane_defs...)
Magnetometer 4
Magnetometer 5
\[ \vec{x}= \begin{bmatrix} \smash[b]{\underbrace{\begin{matrix} \delta \vec{p} & \delta \vec{v} & \delta \vec{\epsilon} & \vec{b}_a & \vec{b}_g\end{matrix}}_{\text{Pinson 15}}} & \smash[b]{\underbrace{\begin{matrix}\delta h_a & \delta a\end{matrix}}_{\text{Baro}}} & S_\text{fogm} & S_\text{bias} \end{bmatrix} \]
\[ z = h(\vec{x}) + v \] \[ h(\vec{x}) = |B_\mathrm{a}| + |B_\text{earth}| + {\color{gray}|B_\text{Plane}}| + S_\text{fogm} + S_\text{bias} \]
Discrete time dynamics at time index \(k+1\) the state vector \(\vec{x}_{k+1}\) is \[ \vec{x}_{k+1} = {\Phi}_k \vec{x}_k + {B}_k \vec{u}_k + \vec{w}_k \]
A measurement \(\vec{z}\) is \[ \vec{z}_k = {H}_k \vec{x}_k + \vec{v}_k \]
\({H}\) is connection between state \(\vec{x}\) and measurement \(\vec{z}\)
\(\vec{v}\sim\mathcal{N}(0,{R})\) is the noise process of the measurement with covariance \({R}\)
The state \(\vec{x}_{k}\) has a mean \(\hat{\vec{x}}_{k}\) and covariance \({P}_{k}\) which propagates forward in time (with no other information) like: \[ \begin{aligned} \hat{\vec{x}}_{k+1}^- & = {\Phi}_k \hat{\vec{x}}_{k} + \cancelto{0}{{B}\vec{u}_k} \\ {P}_{k+1}^- & = {\Phi}_k {P}_{k} {\Phi}_k^T + {Q}_k \end{aligned} \] When a measurement \(\vec{z}\) is made, we can update the propagated state vector \[ \begin{aligned} \hat{\vec{x}}_{k} &= \hat{\vec{x}}_{k}^- + {K}_k (\vec{z}_k - {H}_k \hat{\vec{x}}_{k}^-)\\ {P}_k &= ({I} -{K}_k {H}_k ) {P}_{k}^- \\ {K}_k &= {P}_{k}^- {H}_k^T( {H}_k {P}_{k}^- {H}_k^T + {R}_k )^{-1} \end{aligned} \]
The map-matching measurement processor is non-linear. Two primary approaches have been used for MagNav:
Generalize the state dynamics and measurement \[ \begin{aligned} \dvec{x} & = \vec{f}(\vec{x}, \vec{u}_d, t) + \vec{u}(t) \\ \vec{z} & = \vec{h}(\vec{x}, t) + \vec{v}(t) \end{aligned} \]
Write the state \(\vec{x}\) in terms of some \(\vec{x}^*(t)\) and a deviation from it \(\Delta\vec{x}(t)\) \[ \vec{x}(t) = \vec{x}^*(t) + \Delta\vec{x}(t) \]
\[ \begin{aligned} \dvec{x}^* + \Delta\dvec{x} & = \vec{f}(\vec{x}^* + \Delta\vec{x}, \vec{u}_d, t) + \vec{u}(t) \\ \vec{z} & = \vec{h}(\vec{x}^* +\Delta\vec{x}, t) + \vec{v}(t) \end{aligned} \]
\(\Delta\vec{x}\) is small and use Taylor series (so many Taylor series) \[ \begin{aligned} \dvec{x}^* + \Delta\dvec{x} & \approx \vec{f}(\vec{x}^*, \vec{u}_d, t) + \left[ \frac{\partial \vec{f}}{\partial \vec{x}}\right]_{\vec{x}=\vec{x}^*} \cdot \Delta\vec{x} + \vec{u}(t) \\ \vec{z} & \approx \vec{h}(\vec{x}^*, t) + \left[ \frac{\partial \vec{h}}{\partial \vec{x}}\right]_{\vec{x}=\vec{x}^*} \cdot \Delta\vec{x} + \vec{v}(t) \end{aligned} \] If \(\vec{x}^*\) is just a single known trajectory, then this is just the Linearized Kalman filter.
If \(\vec{x}^*\) is our trajectory estimate, then this is the Extended Kalman filter.
\[ \begin{aligned} \dvec{x}^* + \Delta\dvec{x} & \approx \vec{f}(\vec{x}^*, \vec{u}_d, t) + \left[ \frac{\partial \vec{f}}{\partial \vec{x}}\right]_{\vec{x}=\vec{x}^*} \cdot \Delta\vec{x} + \vec{u}(t) \\ \vec{z} & \approx \vec{h}(\vec{x}^*, t) + \left[ \frac{\partial \vec{h}}{\partial \vec{x}}\right]_{\vec{x}=\vec{x}^*} \cdot \Delta\vec{x} + \vec{v}(t) \end{aligned} \] Becomes \[ \begin{aligned} \dvec{x}^* + \Delta\dvec{x} & \approx \vec{f}(\vec{x}^*, \vec{u}_d, t) + \mat{F} \cdot \Delta\vec{x} + \vec{u}(t) \\ \vec{z} & \approx \vec{h}(\vec{x}^*, t) + \mat{H} \cdot \Delta\vec{x} + \vec{v}(t) \end{aligned} \] with \[ \mat{F} = \left[ \frac{\partial \vec{f}}{\partial \vec{x}}\right]_{\vec{x}=\vec{x}^*},\ \mat{H} = \left[ \frac{\partial \vec{h}}{\partial \vec{x}}\right]_{\vec{x}=\vec{x}^*} \]
Write the linearized measurement as \[ \vec{z} - \vec{h}(\vec{x}^*) = \mat{H} \Delta \vec{x} + \vec{v} \] The incremental estimate update at time \(t_k\) is \[ \Delta\hat{\vec{x}}_k = \Delta\hat{\vec{x}}_k^- + \mat{K}_k \left[ \vec{z}_k - \vec{h}(\vec{x}^*_k) - \mat{H}_k \Delta\hat{\vec{x}}_k^- \right] \] Write the estimate of what the measurement should be \[ \hat{\vec{z}}^-_k = \vec{h}(\vec{x}^*_k) + \mat{H}_k \Delta\hat{\vec{x}}_k^- \] And then \[ \underbrace{\vec{x}^*_k + \Delta\hat{\vec{x}}_k}_{\textstyle\hat{\vec{x}}_k} = \underbrace{\vec{x}^*_k + \Delta\hat{\vec{x}}_k^-}_{\textstyle\hat{\vec{x}}_k^-} + \mat{K}_k \left[ \vec{z}_k - \hat{\vec{z}}^-_k \right] \]
(Titterton and Weston 2004), (Raquet 2021)
Pinson 9-state model for INS is: \[ \vec{x} = \begin{bmatrix} \delta x_n \\ \delta x_e \\ \delta x_d \\ \delta v_n \\ \delta v_e \\ \delta v_d \\ \delta\epsilon_n \\ \delta\epsilon_e \\ \delta\epsilon_d \\ \end{bmatrix} = \begin{bmatrix} \delta\vec{x} \\ \delta\vec{v} \\ \delta\vec{\epsilon} \\ \end{bmatrix} \]
Where:
and \[ \dvec{x} = \mat{F} \vec{x} \]
\[ \begin{bmatrix} \delta\dvec{x} \\ \delta\dvec{v} \\ \delta\dvec{\epsilon} \end{bmatrix} = \begin{bmatrix} F_{xx} & F_{xv} & F_{x\epsilon} \\ F_{vx} & F_{vv} & F_{v\epsilon} \\ F_{\epsilon x} & F_{\epsilon v} & F_{\epsilon \epsilon} \\ \end{bmatrix} \begin{bmatrix} \delta \vec{x} \\ \delta \vec{v} \\ \delta \vec{\epsilon} \\ \end{bmatrix} \] We are working in geodetic coordinates so the elements of \(\mat{F}\) depend upon Earth specifc parameters to account for Coriolis force.
Variable | Description | Value/Units |
---|---|---|
\(\phi\) | latitude | radian |
\(v_n\) | north velocity | meter/second |
\(v_e\) | east velocity | meter/second |
\(v_d\) | down velocity | meter/second |
\(f_n\) | north specific force | meter/second/second |
\(f_e\) | east specific force | meter/second/second |
\(f_d\) | down specific force | meter/second/second |
\(R_\earth\) | Earth radius | 635300 meter |
\(\Omega_\earth\) | Earth rotation rate | 7.2921151467e-5/second |
\[ F_{xx} = \begin{bmatrix} 0 & 0 & -\frac{v_n}{R_\earth^2}\\ \frac{v_e \tan \phi}{R_\earth\cos \phi} & 0 & \frac{v_e}{R_\earth^2 \cos\phi} \\ 0 & 0 & 0 \\ \end{bmatrix} \]
\[ F_{xv} = \begin{bmatrix} \frac{1}{R_\earth} & 0 & 0\\ 0 & \frac{1}{R_\earth\cos\phi} & 0 \\ 0 & 0 & -1 \\ \end{bmatrix} \]
\[ F_{x\epsilon} = \mat{0}_{3\times 3} \]
\[ F_{vx} = \begin{bmatrix} v_e \left( 2\Omega_\earth\cos\phi + \frac{v_e}{R_\earth\cos^2\phi} \right) & 0 & \frac{v_e^2\tan\phi - v_n v_d}{R_\earth^2}\\ 2\Omega_\earth \left(v_n \cos\phi - v_d \sin\phi\right) + \frac{v_n v_e}{R_\earth \cos^2\phi} & 0 & \frac{-v_e (v_n\tan\phi +v_d)}{R_\earth^2}\\ 2\Omega_\earth v_e \sin \phi & 0 & \frac{v_n^2 + v_e^2}{R_\earth} \\ \end{bmatrix} \]
\[ F_{vv} = \begin{bmatrix} \frac{v_d}{R_\earth} & -2 \left( \Omega_\earth \sin\phi + \frac{v_e\tan\phi}{R_\earth} \right) & \frac{v_n}{R_\earth} \\ 2\Omega_\earth\sin\phi + \frac{v_e\tan\phi}{R_\earth} & \frac{v_n\tan\phi+v_d}{R_\earth} & 2\Omega_\earth \cos\phi + \frac{v_e}{R_\earth} \\ -\frac{2v_n}{R_\earth} & -2 \left( \Omega_\earth \cos\phi + \frac{v_e}{R_\earth} \right) & 0 \\ \end{bmatrix} \]
\[ F_{v\epsilon} = \begin{bmatrix} 0 & -f_d & f_e \\ f_d & 0 & -f_n \\ -f_e & f_n & 0 \end{bmatrix} \]
\[ F_{\epsilon x} = \begin{bmatrix} -\Omega_\earth \sin\phi & 0 & -\frac{v_e}{R_\earth} \\ 0 & 0 & \frac{v_n}{R_\earth^2} \\ -\Omega_\earth \cos\phi - \frac{v_e}{R_\earth \cos^2\phi} & 0 & \frac{v_e\tan\phi}{R_\earth^2} \end{bmatrix} \]
\[ F_{\epsilon v } = \begin{bmatrix} 0 & 1/R_\earth & 0 \\ -1/R_\earth & 0 & 0 \\ 0 & \frac{\tan\phi}{R_\earth} & 0 \\ \end{bmatrix} \]
\[ F_{\epsilon\epsilon} = \begin{bmatrix} 0 & -\Omega_\earth\sin\phi + \frac{v_e}{R_\earth\tan\phi} & v_n/R_\earth \\ \Omega_\earth\sin\phi + \frac{v_e\tan\phi}{R_\earth} & 0 & \Omega_\earth\cos\phi + v_e/R_\earth \\ -v_n/R_\earth & -\Omega\cos\phi -v_e/R_\earth & 0 \\ \end{bmatrix} \]
\[ \vec{x} = \begin{bmatrix} \delta x_n \\ \delta x_e \\ \delta x_d \\ \delta v_n \\ \delta v_e \\ \delta v_d \\ \delta\epsilon_n \\ \delta\epsilon_e \\ \delta\epsilon_d \\ b_{a_x} \\ b_{a_y} \\ b_{a_z} \\ b_{g_x} \\ b_{g_y} \\ b_{g_z} \\ \end{bmatrix} = \begin{bmatrix} \delta\vec{x} \\ \delta\vec{v} \\ \delta\vec{\epsilon} \\ \vec{b_a}\\ \vec{b_g}\\ \end{bmatrix} \]
\[ \begin{bmatrix} \delta\dvec{x} \\ \delta\dvec{v} \\ \delta\dvec{\epsilon} \\ \dvec{b_a}\\ \dvec{b_g}\\ \end{bmatrix} = \begin{bmatrix} F_{xx} & F_{xv} & 0 & 0 & 0\\ F_{vx} & F_{vv} & F_{v\epsilon} & \mat{C}_b^n & 0 \\ F_{\epsilon x} & F_{\epsilon v} & F_{\epsilon \epsilon} & 0 & -\mat{C}_b^n \\ 0 & 0 & 0 & F_{aa} & 0 \\ 0 & 0 & 0 & 0 & F_{gg} \\ \end{bmatrix} \begin{bmatrix} \delta \vec{x} \\ \delta \vec{v} \\ \delta \vec{\epsilon} \\ \vec{b}_a\\ \vec{b}_g\\ \end{bmatrix} \]
\[ F_{aa} = \begin{bmatrix} -1/\tau_a & 0 & 0 \\ 0 & -1/\tau_a & 0 \\ 0 & 0 & -1/\tau_a\\ \end{bmatrix},\ F_{gg} = \begin{bmatrix} -1/\tau_g & 0 & 0 \\ 0 & -1/\tau_g & 0 \\ 0 & 0 & -1/\tau_g\\ \end{bmatrix} \] and \(\mat{C}_b^n\) is the direction cosine matrix that rotates from body to NED frame.
Results in an 18-component state vector \[ \begin{bmatrix} \delta \vec{x} & \delta \vec{v} & \delta \vec{\epsilon} & \vec{b}_a & \vec{b}_g & \delta h_a & \delta a & S \end{bmatrix} \]
\[ \begin{bmatrix} \delta\dvec{x} \\ \delta\dvec{v} \\ \delta\dvec{\epsilon} \\ \dvec{b}_a\\ \dvec{b}_g\\ \dot{h_a}\\ \dot{\delta_a}\\ \dot{S} \end{bmatrix} = \begin{bmatrix} F_{xx} & F_{xv} & 0 & 0 & 0 & F_{xb} & 0 \\ F_{vx} & F_{vv} & F_{v\epsilon} & \mat{C}_b^n & 0 & F_{vb} & 0 \\ F_{\epsilon x} & F_{\epsilon v} & F_{\epsilon \epsilon} & 0 & -\mat{C}_b^n & 0 & 0 \\ 0 & 0 & 0 & F_{aa} & 0 & 0 & 0\\ 0 & 0 & 0 & 0 & F_{gg} &0 & 0 \\ F_{bp} & 0 & 0 & 0 & 0 & F_{bb} & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & F_{ss} \\ \end{bmatrix} \begin{bmatrix} \delta \vec{x} \\ \delta \vec{v} \\ \delta \vec{\epsilon} \\ \vec{b}_a\\ \vec{b}_g\\ \delta h_a \\ \delta a \\ S \end{bmatrix} \]
Barometer aiding: \[ \mat{F}_{xb} = \begin{bmatrix} 0 & 0 \\ 0 & 0 \\ k_1 & 0 \end{bmatrix},\ \mat{F}_{vb} = \begin{bmatrix} 0 & 0 \\ 0 & 0 \\ -k_2 & 1 \\ \end{bmatrix} \]
\[ \mat{F}_{bx} = \begin{bmatrix} 0 & 0 & 0\\ 0 & 0 & k_3 \\ \end{bmatrix},\ \mat{F}_{bb} = \begin{bmatrix} -\frac{1}{\tau_b} & 0 \\ -k_3 & 0 \\ \end{bmatrix} \]
The space weather, diurnal bias is given by: \[ \mat{F}_{ss} = \frac{1}{\tau_s} \]
The scalar sensor measures: \[ |\vec{B}_\text{total}| = |\vec{B}_\ext + \vec{B}_\text{\faPlane} | \] and \[ \vec{B}_\ext = \vec{B}_\earth+ \vec{B}_\text{anomaly} + \vec{B}_\text{disturbance} \]
\[ \begin{aligned} \vec{z} & \approx \vec{h}(\vec{x}^*, t) + \mat{H} \cdot \Delta\vec{x} + \vec{v}(t) \end{aligned} \]
\[ \mat{H} = \left[ \frac{\partial \vec{h}}{\partial \vec{x}}\right]_{\vec{x}=\vec{x}^*} \]
\[ \mat{H}(\vec{x}^*) = \begin{bmatrix} \frac{\partial h(\vec{x}^*)}{\partial x_n} \\ \frac{\partial h(\vec{x}^*)}{\partial x_e} \\ \frac{\partial h(\vec{x}^*)}{\partial x_d} \\ \mat{0}_{1x15} \end{bmatrix} \leftarrow\text{This is the gradient of the map} \] Both the map and 3D gradient of the map are needed in order to make a measurement and incorporate it.
MagNav.jl software does not have it’s own INS mechanization code
2 rows × 8 columns
flight | line | t_start | t_end | full_line | map_name | map_type | traj_alt | |
---|---|---|---|---|---|---|---|---|
Symbol | Float64 | Float64 | Float64 | Bool | Symbol | Symbol | Int64 | |
1 | Flt1006 | 1006.08 | 55770.0 | 56609.0 | 1 | Eastern_395 | HAE | 397 |
2 | Flt1006 | 1006.09 | 56965.0 | 57480.0 | 0 | Eastern_395 | HAE | 574 |
Entire map
Entire map
Zoom on selected flight line
GPS track
INS only
Notice overall shift between tracks
Uncorrected GPS and INS tracks
\(\rightarrow\)
Shifted GPS and INS tracks
Mag 4 DRMS Error = 149.2 meter
Mag 5 DRMS Error = 82.5 meter
INS DRMS Error = 137.5 meter
North position error
tt_min = (traj.tt .- traj.tt[1])./60;
p=error_plot(tt_min,filt_out_4.n_err,filt_out_4.n_std, color=:blue, label="Mag 4, North error",xlabel="Time [minutes]", ylabel="North Error [meters]")
error_plot(p,tt_min,filt_out_5.n_err,filt_out_5.n_std, color=:green,label="Mag 5, North error",xlabel="Time [minutes]", ylabel="North Error [meters]")
plot(p; double_pane_defs...)
East position error
p=error_plot(tt_min,filt_out_4.e_err,filt_out_4.e_std, color=:blue, label="Mag 4, East error",xlabel="Time [minutes]", ylabel="East Error [meters]")
error_plot(p,tt_min,filt_out_5.e_err,filt_out_5.e_std, color=:green, label="Mag 5, East error",xlabel="Time [minutes]", ylabel="East Error [meters]")
plot(p; double_pane_defs...)
You should be familiar with Magnetic Navigation
You should know how to use MagNav.jl to explore navigation
Aaron Nielsen
Air Force Institute of Technology (AFIT) https://www.afit.edu
Autonomy and Navigation Technology Center (ANT Center) https://www.afit.edu/ANT/
Scalar Magnetic Potential \(\Phi_M\)
A procedure to transform magnetic scalar potential \(\Phi_M\) in free space.
From Laplacian we can write (Green’s third identity) \[
\Phi_M(\vec{r}) = \frac{1}{4\pi} \int_S \left( \frac{1}{r} \frac{\partial \Phi_M}{\partial n} -
\Phi_M \frac{\partial}{\partial n} \frac{1}{r} \right) dS
\]
ION/IEEE PLANS MagNav Tutorial 2023