Skip to content

Commit

Permalink
✨ DateTime support in propagate_to_epoch
Browse files Browse the repository at this point in the history
  • Loading branch information
ronisbr committed Jul 1, 2024
1 parent c9e01cb commit 4dc45ad
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 5 deletions.
31 changes: 26 additions & 5 deletions src/api/Propagators.jl
Original file line number Diff line number Diff line change
Expand Up @@ -255,10 +255,12 @@ end

"""
propagate_to_epoch(::Val{:propagator}, jd::Number, args...; kwargs...)
propagate_to_epoch(::Val{:propagator}, dt::DateTime, args...; kwargs...)
Initialize the orbit `propagator` and propagate the orbit until the epoch `jd` [s] from the
initial orbit epoch. The initialization arguments `args...` and `kwargs...` are the same as
in the initialization function [`Propagators.init`](@ref).
Initialize the orbit `propagator` and propagate the orbit until the epoch defined by either
the Julian Day `jd` [UTC] or by a `DateTime` object `dt` [UTC] from the initial orbit epoch.
The initialization arguments `args...` and `kwargs...` are the same as in the initialization
function [`Propagators.init`](@ref).
# Returns
Expand All @@ -268,6 +270,11 @@ in the initialization function [`Propagators.init`](@ref).
instant.
- [`OrbitPropagator`](@ref): Structure with the initialized parameters.
"""
function propagate_to_epoch(T::Val, dt::DateTime, args...; kwargs...)
jd = datetime2julian(dt)
return propagate_to_epoch(T, jd, args...; kwargs...)
end

function propagate_to_epoch(T::Val, jd::Number, args...; kwargs...)
orbp = init(T, args...; kwargs...)
r_i, v_i = propagate_to_epoch!(orbp, jd)
Expand All @@ -276,8 +283,10 @@ end

"""
propagate_to_epoch!(orbp::OrbitPropagator{Tepoch, T}, jd::Number) where {Tepoch, T} -> SVector{3, T}, SVector{3, T}
propagate_to_epoch!(orbp::OrbitPropagator{Tepoch, T}, dt::DateTime) where {Tepoch, T} -> SVector{3, T}, SVector{3, T}
Propagate the orbit using `orbp` until the epoch `jd` [Julian Day].
Propagate the orbit using `orbp` until the epoch defined either by the Julian Day `jd`
[UTC] or by the `DateTime` object `dt` [UTC].
# Returns
Expand All @@ -286,14 +295,21 @@ Propagate the orbit using `orbp` until the epoch `jd` [Julian Day].
- `SVector{3, T}`: Velocity vector [m / s] represented in the inertial frame at propagation
instant.
"""
function propagate_to_epoch!(orbp::OrbitPropagator, dt::DateTime)
jd = datetime2julian(dt)
return propagate_to_epoch!(orbp, jd)
end

function propagate_to_epoch!(orbp::OrbitPropagator, jd::Number)
return propagate!(orbp, 86400 * (jd - epoch(orbp)))
end

"""
propagate_to_epoch!(orbp::OrbitPropagator{Tepoch, T}, vjd::AbstractVector; kwargs...) where {Tepoch, T} -> SVector{3, T}, SVector{3, T}
propagate_to_epoch!(orbp::OrbitPropagator{Tepoch, T}, vdt::AbstractVector{DateTime}; kwargs...) where {Tepoch, T} -> SVector{3, T}, SVector{3, T}
Propagate the orbit using `orbp` for every epoch defined in `jd` [Julian Day].
Propagate the orbit using `orbp` for every epoch defined in the vector of Julian Days `vjd`
[UTC] or in the vector of `DateTime` objects `vdt` [UTC].
# Keywords
Expand All @@ -308,6 +324,11 @@ Propagate the orbit using `orbp` for every epoch defined in `jd` [Julian Day].
- `Vector{SVector{3, T}}`: Array with the velocity vectors [m / s] in the inertial frame at
each propagation instant defined in `vt`.
"""
function propagate_to_epoch!(orbp::OrbitPropagator, vdt::AbstractVector{T}) where T<:DateTime
vjd = datetime2julian.(vdt)
return propagate_to_epoch!(orbp, vjd)
end

function propagate_to_epoch!(orbp::OrbitPropagator, vjd::AbstractVector)
return propagate!(orbp, 86400 .* (vjd .- epoch(orbp)))
end
Expand Down
67 changes: 67 additions & 0 deletions test/api.jl
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,56 @@ struct DummyPropagator{Tepoch, T} <: OrbitPropagator{Tepoch, T} end
end
end

@testset "DateTime Support" verbose = true begin
jd₀ = date_to_jd(2023, 1, 1, 0, 0, 0)

for (T, j2c) in ((Float64, j2c_egm2008), (Float32, j2c_egm2008_f32))
orb = KeplerianElements(
jd₀,
T(8000e3),
T(0.015),
T(28.5) |> deg2rad,
T(100) |> deg2rad,
T(200) |> deg2rad,
T(45) |> deg2rad
)

orbp_ref = Propagators.init(Val(:J2), orb; j2c = j2c)

# == propagate_to_epoch ============================================================

r, v, orbp = Propagators.propagate_to_epoch(
Val(:J2),
DateTime("2024-01-01"),
orb;
j2c = j2c
)

r_ref, v_ref = Propagators.propagate_to_epoch!(orbp_ref, date_to_jd(2024, 1, 1))

@test orbp isa typeof(orbp_ref)
@test r isa SVector{3, T}
@test v isa SVector{3, T}
@test r r_ref
@test v v_ref
@test Propagators.last_instant(orbp) == Propagators.last_instant(orbp_ref)

# == propagate_to_epoch! ===========================================================

orbp = Propagators.init(Val(:J2), orb; j2c = j2c)

r, v = Propagators.propagate_to_epoch!(orbp, DateTime("2024-01-01"))

r_ref, v_ref = Propagators.propagate_to_epoch!(orbp_ref, date_to_jd(2024, 1, 1))

@test r isa SVector{3, T}
@test v isa SVector{3, T}
@test r r_ref
@test v v_ref
@test Propagators.last_instant(orbp) == Propagators.last_instant(orbp_ref)
end
end

@testset "Multi-thread Propagation" verbose = true begin
for (T, j2c) in ((Float64, j2c_egm2008), (Float32, j2c_egm2008_f32))
@testset "$T" begin
Expand Down Expand Up @@ -118,6 +168,23 @@ end
@test ret[k][2] == v[k]
end

# -- DateTime Support ----------------------------------------------------------

vdt = [DateTime(2024, 1, i) for i in 1:30]
ret = Propagators.propagate_to_epoch!.(orbp, vdt)
r, v = Propagators.propagate_to_epoch!(orbp, vdt)

@test length(r) == 30
@test length(v) == 30
@test r isa Vector{SVector{3, T}}
@test v isa Vector{SVector{3, T}}
@test Propagators.last_instant(orbp) == 3.40416e7

for k in 1:30
@test ret[k][1] == r[k]
@test ret[k][2] == v[k]
end

# == Simultaneous Initialization and Propagation ===============================

ret = Propagators.propagate!.(orbp, 1:1:100)
Expand Down

0 comments on commit 4dc45ad

Please sign in to comment.