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.

Note

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) end6-element Vector{Float64}: -1.3861836496864846 0.5450243502117527 0.4389799758921788 154547.75853430055 2.2552757355901767e6 -754110.155828129