Planar Entry Dynamics

Also known as canonical entry dynamics!

Overview

The Planar Entry model assumes a spacecraft moving in an exponential atmosphere about a spherical planet. Acceleration due to gravity is ignored. The equations of motion are shown below.

\[\begin{aligned} \dot{\gamma} &= \frac{1}{v} \left( L_m - (1 - \frac{v^2}{v_c^2}) g \cos{\gamma} \right) \\ \dot{v} &= -D_m - g \sin{\gamma} \\ \dot{r} &= v \sin{\gamma} \\ \dot{\theta} &= \frac{v}{r} \cos{\gamma} \\ \end{aligned}\]

Examples

julia> model = PlanarEntrySystem()Model PlanarEntry with 4 equations
Unknowns (4):
  γ(t): flight path angle in degrees
  v(t): airspeed in meters per second
  r(t): polar distance relative to planet center in meters
  θ(t): polar angle relative to planet horizontal in degrees
Parameters (7):
  R: spherical planet radius
  P: atmospheric density at sea level in kilograms per meter cubed
  H: scale factor for exponential atmosphere in meters
  m: entry vehicle mass in kilograms
⋮

Let's compute the Jacobian for these dynamics.

julia> J = calculate_jacobian(PlanarEntrySystem())4×4 Matrix{Num}:
 (sin(γ(t))*((R / r(t))^2)*(1 - ((v(t) / sqrt(μ / r(t)))^2))*μ) / ((R^2)*v(t))  …  0
                                         (-((R / r(t))^2)*cos(γ(t))*μ) / (R^2)     0
                                                                v(t)*cos(γ(t))     0
                                                      (-sin(γ(t))*v(t)) / r(t)     0

Finally, let's construct a Julia function which implements these dynamics!

julia> f = PlanarEntryFunction()(::ODEFunction{true, SciMLBase.FullSpecialize, ModelingToolkit.var"#f#684"{RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0x08264f4d, 0x3a12bc0c, 0x603cc95b, 0x4f8e35ac, 0xb2763e01), Nothing}, RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋out, :ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0xb49cff54, 0xb2c08eb4, 0xe02e83d9, 0x64dcd056, 0xdcf88228), Nothing}}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, ModelingToolkit.var"#_jac#689"{RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0xb742e4c6, 0x8ec6311a, 0x01b3b366, 0xb8f849f6, 0xe20e9a51), Nothing}, RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋out, :ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0x1910ec62, 0xbc68d4da, 0x3fc8e872, 0xe5b9dc7d, 0xfe30f421), Nothing}}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, ModelingToolkit.var"#51211#generated_observed#693"{Bool, ODESystem, Dict{Any, Any}, Vector{SymbolicUtils.BasicSymbolic{Real}}}, Nothing, ODESystem, Nothing, Nothing}) (generic function with 1 method)
julia> let u = abs.(randn(4)), p = abs.(randn(7)), t = 0 f(u, p, t) end4-element Vector{Float64}: 3.0338242573046035 -0.5068883512028585 0.054445579770475636 0.5479331587542847