Astrodynamical Models
This tutorial will briefly introduce propagating and plotting orbits in the astrodynamical models provided by OrbitalTrajectories.jl
Here, we will reproduce Figure 3 from the OrbitalTrajectories.jl paper[Padilha2021], which shows example trajectories in the Earth-Moon(-Sun) system.
Load packages
First, we load all necessary packages:
using OrbitalTrajectories
using DifferentialEquations # To propagate trajectories
using Plots # To plot trajectories
using Unitful # Units (u"km", u"d" (days)) and unit conversion
Build astrodynamical models
We build a set of astrodynamical models (systems
) in the Earth-Moon(-Sun) system. This includes:
- Circular Restricted 3-Body Problem (
CR3BP
) for Earth-Moon - Elliptic Restricted 3-Body Problem (
ER3BP
) for Earth-Moon - Bi-Circular Restricted 4-Body Problem (
BC4BP
) for Earth-Moon-Sun - Ephemeris Restricted N-Body Problem (
EphemerisNBP
) for Earth-Moon-Sun
a, b, c = (:Earth, :Moon, :Sun)
# The EphemerisNBP model requires a timespan in seconds, rather than radians.
tspan = (0.88π, 2.83π)
tspan_epoch = ustrip.(u"s", tspan .* R3BPSystemProperties(a, b).T)
# Define the systems to test.
# xoffset/yoffset are used to offset the model labels in the resulting plot.
systems = Dict(
CR3BP(a, b) => (color=:blue, tspan=(0.88π, 2.88π), xoffset=-0.06, yoffset=-0.04),
ER3BP(a, b) => (color=:red, tspan=(0.88π, 3.00π), xoffset=-0.06, yoffset=-0.04),
BC4BP(a, b, c) => (color=:green, tspan=(0.88π, 2.85π), xoffset=-0.05, yoffset=-0.06),
EphemerisNBP(a, b, c) => (color=:orange, tspan=tspan_epoch, xoffset=-0.20, yoffset=-0.02)
)
Initial state and reference frame
We specify an initial state simply as a vector of $[x_0, y_0, z_0, \dot{x}_0, \dot{y}_0, \dot{z}_0]$. The state we provide is defined in a normalised synodic rotating frame, so we specify the initial frame as SynodicFrame()
.
u0 = [0.76710535, 0., 0., 0., 0.47262724, 0.]
u0_frame = SynodicFrame()
Simple propagation and plotting
We can propagate a trajectory by creating an initial state object State
, providing the desired astrodynamical model (sys
), initial state vector (u0
), initial state reference frame (u0_frame
), and propagation timespan (tspan
).
To propagate, we simply call solve(state)
.
For example, to plot in the Circular Restricted 3-Body Problem (CR3BP
):
# Create the initial state
state = State(CR3BP(:Earth, :Moon), u0_frame, u0, tspan)
# Propagate the state to compute a trajectory
trajectory = solve(state)
# Plot the trajectory
plot(trajectory; legend=:bottomright)
Propagate and plot in all the models
Here we propagate and plot trajectories in all of the aforementioned models.
First, set up some plotting options as follows.
plot_attrs = (thickness_scaling=0.75, legendfontsize=9, tickfontsize=9, guidefontsize=10,
titlefontsize=10, bg_color_legend=RGBA(1, 1, 1, 0.8), fg_color_legend=nothing,
legend=:bottomright)
p = plot();
# Keep track of the maximum x and y limits
xlim = (Inf, -Inf)
ylim = (Inf, -Inf)
To plot in the original reference frame (i.e. normalised synodic rotating frame), we simply call plot(trajectory, u0_frame)
.
for (i, (sys, opts)) in enumerate(systems)
# Create the initial state
state = State(sys, u0_frame, u0, opts.tspan)
# Propagate it to compute the trajectory
trajectory = solve(state)
# Plot the trajectory
plot!(p, trajectory, u0_frame; label="", color=opts.color, nolabels=(i!=1))
# Add a label for the model name
traj_converted = convert_to_frame(trajectory, u0_frame)
annotate!(p, [(traj_converted.sol[end][1] + opts.xoffset,
traj_converted.sol[end][2] - opts.yoffset,
Plots.text("$(nameof(typeof(sys)))" *
((isa(sys, EphemerisNBP) || isa(sys, BC4BP)) ? "\n(+ $(String(c)))" : ""),
opts.color, :left, 9, 0.))]);
# Add a label for barycenter
(i == 1) && hline!(p, [0.]; linecolor=:black, linestyle=:solid,
label="$(titlecase(String(a)))-$(titlecase(String(b))) Barycenter")
# Expand the plot limits to the biggest size
global xlim, ylim # we want to override the global variables outside this scope
xlim = (min(xlim[1], xlims()[1]), max(xlim[2], xlims()[2]))
ylim = (min(ylim[1], ylims()[1]), max(ylim[2], ylims()[2]))
plot!(p; xlims=xlim, ylims=ylim, plot_attrs...)
end
p # Display the final plot
- Padilha2021Dan Padilha, Diogene A. Dei Tos, Nicola Baresi, Junichiro Kawaguchi, "Modern Numerical Programming with Julia for Astrodynamic Trajectory Design", 31st AAS/AIAA Space Flight Mechanics Meeting, 2021.