Restricted Two-body Dynamics
Also known as R2BP dynamics!
Overview
The Restricted Two-body Problem (R2BP) assumes a massless spacecraft which moves due to the gravity of one celestial body: one star, or one planet, or one moon, or one asteroid. The equations of motion for R2BP dynamics are shown below.
\[\begin{aligned} \frac{dx(t)}{dt} =& ẋ\left( t \right) \\ \frac{dy(t)}{dt} =& ẏ\left( t \right) \\ \frac{dz(t)}{dt} =& ż\left( t \right) \\ \frac{dẋ(t)}{dt} =& \frac{ - \mu x\left( t \right)}{\left( \sqrt{x^2\left(t\right) + y^2\left(t\right) + z^2\left(t\right)} \right)^{3}} \\ \frac{dẏ(t)}{dt} =& \frac{ - \mu y\left( t \right)}{\left( \sqrt{x^2\left(t\right) + y^2\left(t\right) + z^2\left(t\right)} \right)^{3}} \\ \frac{dż(t)}{dt} =& \frac{ - \mu z\left( t \right)}{\left( \sqrt{x^2\left(t\right) + y^2\left(t\right) + z^2\left(t\right)} \right)^{3}} \end{aligned}\]
Examples
julia> model = R2BSystem()
Model R2B with 6 equations Unknowns (6): x(t) y(t) z(t) ẋ(t) ⋮ Parameters (1): μ
Every model also offers optional state transition matrix dynamics. Use stm=true
to append the state transition matrix dynamics to your model's equations of motion. State transition dynamics can also be thought of the model's local linearization.
The state transition dynamics for R2BSystem
are not nearly as useful as the state transition dynamics within CR3BP
models. Within CR3BP dynamics, a spacecraft's local linearization offers stability characteristics for periodic orbits, and provides stable and unstable directions (in state-space) for invariant manifolds about periodic orbits and Lagrange points.
julia> model = R2BSystem(; stm=true)
Model R2BWithSTM with 42 equations Unknowns (42): x(t) y(t) z(t) ẋ(t) ⋮ Parameters (1): μ
Let's compute the Jacobian for these dynamics.
julia> J = calculate_jacobian(R2BSystem())
6×6 Matrix{Num}: 0 … 1 0 0 0 0 1 0 0 0 0 1 (-μ) / (sqrt(abs2(y(t)) + abs2(x(t)) + abs2(z(t)))^3) - 3x(t)*((-x(t)*μ) / (sqrt(abs2(y(t)) + abs2(x(t)) + abs2(z(t)))^6))*sqrt(abs2(y(t)) + abs2(x(t)) + abs2(z(t))) 0 0 0 -3((-y(t)*μ) / (sqrt(abs2(y(t)) + abs2(x(t)) + abs2(z(t)))^6))*x(t)*sqrt(abs2(y(t)) + abs2(x(t)) + abs2(z(t))) 0 0 0 -3x(t)*((-z(t)*μ) / (sqrt(abs2(y(t)) + abs2(x(t)) + abs2(z(t)))^6))*sqrt(abs2(y(t)) + abs2(x(t)) + abs2(z(t))) … 0 0 0
Finally, let's construct a Julia function which implements these dynamics!
julia> f = R2BFunction()
(::ODEFunction{true, SciMLBase.FullSpecialize, ModelingToolkit.var"#f#684"{RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0x85184888, 0xb17a535f, 0x82fddb8f, 0x46fde24e, 0xe0ba6752), Nothing}, RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋out, :ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0x4feca1d2, 0xcfce7c7e, 0x9e2fea20, 0xdcc4aa6a, 0xca1fa926), Nothing}}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, ModelingToolkit.var"#_jac#689"{RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0x67420626, 0x1a4595aa, 0x37e5bbe7, 0xf10f7fc6, 0xf0e5b87a), Nothing}, RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋out, :ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0x0923dfa2, 0x8c524e4a, 0x4b8fb075, 0x723709b6, 0xf6c592f1), 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 = randn(6), p = [3e6], t = 0 f(u, p, t) end
6-element Vector{Float64}: -1.3861836496864846 0.5450243502117527 0.4389799758921788 154547.75853430055 2.2552757355901767e6 -754110.155828129