This feature will be very easy to implement! I will do this!
Hi @minetest2048 !
Can you please test the main
branch of SatelliteToolboxPropagators.jl? Now, you can do this:
julia> using SatelliteToolboxPropagators
julia> f = create_tle_fetcher(CelestrakTleFetcher)
CelestrakTleFetcher("https://celestrak.org/NORAD/elements/gp.php")
julia> tles = fetch_tles(f; satellite_name = "ISS (ZARYA)")
[ Info: Fetch TLEs from Celestrak using satellite name: "ISS (ZARYA)" ...
1-element Vector{TLE}:
TLE: ISS (ZARYA) (Epoch = 2024-12-27T11:52:08.200)
julia> iss_tle = tles[1]
TLE:
Name : ISS (ZARYA)
Satellite number : 25544
International designator : 98067A
Epoch (Year / Day) : 24 / 362.49453935 (2024-12-27T11:52:08.200)
Element set number : 999
Eccentricity : 0.00057970
Inclination : 51.63830000 deg
RAAN : 77.61300000 deg
Argument of perigee : 11.65550000 deg
Mean anomaly : 348.45670000 deg
Mean motion (n) : 15.50310083 revs / day
Revolution number : 48853
B* : 0.00045083 1 / er
ṅ / 2 : 0.00025652 rev / day²
n̈ / 6 : 0 rev / day³
julia> orbp = Propagators.init(Val(:SGP4), iss_tle)
OrbitPropagatorSgp4{Float64, Float64}:
Propagator name : SGP4 Orbit Propagator
Propagator epoch : 2024-12-27T11:52:08.200
Last propagation : 2024-12-27T11:52:08.200
julia> sv_teme = Propagators.propagate!(orbp, 0, OrbitStateVector)
OrbitStateVector{Float64, Float64}:
epoch : 2.46067e6 (2024-12-27T11:52:08.200)
r : [1456.71, 6632.76, 0.0224472] km
v : [-4.647, 1.0129, 6.01325] km/s
The last argument in Propagators.propagate!
is now a “sink” option and it can be Tuple
(default) to obtain the old behavior or OrbitStateVector
to obtain the state vector as you wanted.
I only need to add the documentation and test cases before tagging the new version.
Now with OrbitStateVector
with epochs, its easy to convert ECI to ECEF without magic numbers
julia> using SatelliteToolbox
julia> f = create_tle_fetcher(CelestrakTleFetcher)
CelestrakTleFetcher("https://celestrak.org/NORAD/elements/gp.php")
julia> tles = fetch_tles(f; satellite_name = "ISS (ZARYA)")
[ Info: Fetch TLEs from Celestrak using satellite name: "ISS (ZARYA)" ...
1-element Vector{TLE}:
TLE: ISS (ZARYA) (Epoch = 2024-12-29T04:05:28.309)
julia> iss_tle = tles[1]
TLE:
Name : ISS (ZARYA)
Satellite number : 25544
International designator : 98067A
Epoch (Year / Day) : 24 / 364.17046654 (2024-12-29T04:05:28.309)
Element set number : 999
Eccentricity : 0.00059130
Inclination : 51.63830000 deg
RAAN : 69.30530000 deg
Argument of perigee : 18.67410000 deg
Mean anomaly : 341.44630000 deg
Mean motion (n) : 15.50400391 revs / day
Revolution number : 48879
B* : 0.00043786 1 / er
ṅ / 2 : 0.0002498 rev / day²
n̈ / 6 : 0 rev / day³
julia> orbp = Propagators.init(Val(:SGP4), iss_tle)
OrbitPropagatorSgp4{Float64, Float64}:
Propagator name : SGP4 Orbit Propagator
Propagator epoch : 2024-12-29T04:05:28.309
Last propagation : 2024-12-29T04:05:28.309
julia> sv_temes = Propagators.propagate!(orbp, 0:10, OrbitStateVector)
11-element Vector{OrbitStateVector{Float64, Float64}}:
OrbitStateVector{Float64, Float64}: Epoch = 2.46067e6 (2024-12-29T04:05:28.309)
OrbitStateVector{Float64, Float64}: Epoch = 2.46067e6 (2024-12-29T04:05:29.309)
OrbitStateVector{Float64, Float64}: Epoch = 2.46067e6 (2024-12-29T04:05:30.309)
OrbitStateVector{Float64, Float64}: Epoch = 2.46067e6 (2024-12-29T04:05:31.309)
OrbitStateVector{Float64, Float64}: Epoch = 2.46067e6 (2024-12-29T04:05:32.309)
OrbitStateVector{Float64, Float64}: Epoch = 2.46067e6 (2024-12-29T04:05:33.309)
OrbitStateVector{Float64, Float64}: Epoch = 2.46067e6 (2024-12-29T04:05:34.309)
OrbitStateVector{Float64, Float64}: Epoch = 2.46067e6 (2024-12-29T04:05:35.309)
OrbitStateVector{Float64, Float64}: Epoch = 2.46067e6 (2024-12-29T04:05:36.309)
OrbitStateVector{Float64, Float64}: Epoch = 2.46067e6 (2024-12-29T04:05:37.309)
OrbitStateVector{Float64, Float64}: Epoch = 2.46067e6 (2024-12-29T04:05:38.309)
julia> sv_eci_to_ecef.(sv_temes, TEME(), PEF(), getfield.(sv_temes,:t))
11-element Vector{OrbitStateVector{Float64, Float64}}:
OrbitStateVector{Float64, Float64}: Epoch = 2.46067e6 (2024-12-29T04:05:28.309)
OrbitStateVector{Float64, Float64}: Epoch = 2.46067e6 (2024-12-29T04:05:29.309)
OrbitStateVector{Float64, Float64}: Epoch = 2.46067e6 (2024-12-29T04:05:30.309)
OrbitStateVector{Float64, Float64}: Epoch = 2.46067e6 (2024-12-29T04:05:31.309)
OrbitStateVector{Float64, Float64}: Epoch = 2.46067e6 (2024-12-29T04:05:32.309)
OrbitStateVector{Float64, Float64}: Epoch = 2.46067e6 (2024-12-29T04:05:33.309)
OrbitStateVector{Float64, Float64}: Epoch = 2.46067e6 (2024-12-29T04:05:34.309)
OrbitStateVector{Float64, Float64}: Epoch = 2.46067e6 (2024-12-29T04:05:35.309)
OrbitStateVector{Float64, Float64}: Epoch = 2.46067e6 (2024-12-29T04:05:36.309)
OrbitStateVector{Float64, Float64}: Epoch = 2.46067e6 (2024-12-29T04:05:37.309)
OrbitStateVector{Float64, Float64}: Epoch = 2.46067e6 (2024-12-29T04:05:38.309)
Awesome! I will implement one new feature that, if you omit the time in sv_
functions, it will automatically use the epoch in the state vector.
Hi @minetest2048 !
With the v1.0 of SatelliteToolbox.jl, you can now suppress the time argument:
julia> using SatelliteToolbox
julia> f = create_tle_fetcher(CelestrakTleFetcher)
CelestrakTleFetcher("https://celestrak.org/NORAD/elements/gp.php")
julia> tles = fetch_tles(f; satellite_name = "ISS (ZARYA)")
[ Info: Fetch TLEs from Celestrak using satellite name: "ISS (ZARYA)" ...
1-element Vector{TLE}:
TLE: ISS (ZARYA) (Epoch = 2025-01-06T13:47:09.406)
julia> iss_tle = tles[1]
TLE:
Name : ISS (ZARYA)
Satellite number : 25544
International designator : 98067A
Epoch (Year / Day) : 25 / 6.57441442 (2025-01-06T13:47:09.406)
Element set number : 999
Eccentricity : 0.00063540
Inclination : 51.63990000 deg
RAAN : 27.62390000 deg
Argument of perigee : 52.73050000 deg
Mean anomaly : 91.48470000 deg
Mean motion (n) : 15.50836984 revs / day
Revolution number : 49009
B* : 0.00038488 1 / er
ṅ / 2 : 0.00022243 rev / day²
n̈ / 6 : 0 rev / day³
julia> orbp = Propagators.init(Val(:SGP4), iss_tle)
OrbitPropagatorSgp4{Float64, Float64}:
Propagator name : SGP4 Orbit Propagator
Propagator epoch : 2025-01-06T13:47:09.406
Last propagation : 2025-01-06T13:47:09.406
julia> sv_temes = Propagators.propagate!(orbp, 0:10, OrbitStateVector)
11-element Vector{OrbitStateVector{Float64, Float64}}:
OrbitStateVector{Float64, Float64}: Epoch = 2.46068e6 (2025-01-06T13:47:09.406)
OrbitStateVector{Float64, Float64}: Epoch = 2.46068e6 (2025-01-06T13:47:10.406)
OrbitStateVector{Float64, Float64}: Epoch = 2.46068e6 (2025-01-06T13:47:11.406)
OrbitStateVector{Float64, Float64}: Epoch = 2.46068e6 (2025-01-06T13:47:12.406)
OrbitStateVector{Float64, Float64}: Epoch = 2.46068e6 (2025-01-06T13:47:13.406)
OrbitStateVector{Float64, Float64}: Epoch = 2.46068e6 (2025-01-06T13:47:14.406)
OrbitStateVector{Float64, Float64}: Epoch = 2.46068e6 (2025-01-06T13:47:15.406)
OrbitStateVector{Float64, Float64}: Epoch = 2.46068e6 (2025-01-06T13:47:16.406)
OrbitStateVector{Float64, Float64}: Epoch = 2.46068e6 (2025-01-06T13:47:17.406)
OrbitStateVector{Float64, Float64}: Epoch = 2.46068e6 (2025-01-06T13:47:18.406)
OrbitStateVector{Float64, Float64}: Epoch = 2.46068e6 (2025-01-06T13:47:19.406)
julia> sv_eci_to_ecef.(sv_temes, TEME(), PEF())
11-element Vector{OrbitStateVector{Float64, Float64}}:
OrbitStateVector{Float64, Float64}: Epoch = 2.46068e6 (2025-01-06T13:47:09.406)
OrbitStateVector{Float64, Float64}: Epoch = 2.46068e6 (2025-01-06T13:47:10.406)
OrbitStateVector{Float64, Float64}: Epoch = 2.46068e6 (2025-01-06T13:47:11.406)
OrbitStateVector{Float64, Float64}: Epoch = 2.46068e6 (2025-01-06T13:47:12.406)
OrbitStateVector{Float64, Float64}: Epoch = 2.46068e6 (2025-01-06T13:47:13.406)
OrbitStateVector{Float64, Float64}: Epoch = 2.46068e6 (2025-01-06T13:47:14.406)
OrbitStateVector{Float64, Float64}: Epoch = 2.46068e6 (2025-01-06T13:47:15.406)
OrbitStateVector{Float64, Float64}: Epoch = 2.46068e6 (2025-01-06T13:47:16.406)
OrbitStateVector{Float64, Float64}: Epoch = 2.46068e6 (2025-01-06T13:47:17.406)
OrbitStateVector{Float64, Float64}: Epoch = 2.46068e6 (2025-01-06T13:47:18.406)
OrbitStateVector{Float64, Float64}: Epoch = 2.46068e6 (2025-01-06T13:47:19.406)
In this case, it will use the epoch of the state vector.