Ground Facility Gaps
We can compute the gaps between the accesses of a satellite to a set of ground facilities using the function ground_facility_gaps (see also Ground Facility Accesses):
SatelliteAnalysis.ground_facility_gaps — Function
ground_facility_gaps(orbp, args...; duration::Number = 86400, initial_time::Number = 0, kwargs...) -> DataFrameCompute the gaps between the accesses of ground facilities. The arguments and keywords are the same as the ones used in the function ground_facility_accesses.
Notice that the gap analysis starts in the orbit propagator epoch plus initial_time and lasts for duration [s].
Returns
DataFrame: The function returns aDataFramewith three columns:gap_beginning: Time of the gap beginning [UTC] encoded usingDateTime.gap_end: Time of the gap end [UTC] encoded usingDateTime.duration: Duration of the gap [time_unit].
DataFrameusing metadata.
Extended Help
Throws
ArgumentError: Ifstepis not positive, ifdurationis negative, or iftime_unitis not:s,:min, or:h.
Examples
julia> using SatelliteAnalysis
julia> jd₀ = date_to_jd(2024, 1, 1);
julia> orb = KeplerianElements(
jd₀,
7130.982e3,
0.001111,
98.405 |> deg2rad,
ltdn_to_raan(10.5, jd₀),
π / 2,
0
);
julia> orbp = Propagators.init(Val(:J2), orb);
julia> ground_facility_gaps(orbp, (0, 0, 0))
3×3 DataFrame
Row │ gap_beginning gap_end duration
│ DateTime DateTime Float64
─────┼────────────────────────────────────────────────────────────
1 │ 2024-01-01T00:00:00 2024-01-01T10:20:03.136 37203.1
2 │ 2024-01-01T10:30:02.971 2024-01-01T22:49:55.910 44392.9
3 │ 2024-01-01T22:59:23.470 2024-01-02T00:00:00 3636.53
julia> ground_facility_gaps(orbp, (0, 0, 0); time_unit = :min)
3×3 DataFrame
Row │ gap_beginning gap_end duration
│ DateTime DateTime Float64
─────┼────────────────────────────────────────────────────────────
1 │ 2024-01-01T00:00:00 2024-01-01T10:20:03.136 620.052
2 │ 2024-01-01T10:30:02.971 2024-01-01T22:49:55.910 739.882
3 │ 2024-01-01T22:59:23.470 2024-01-02T00:00:00 60.6088Examples
Let's compute the gaps of the Amazonia-1 satellite to the INPE's ground station at Cuiabá, MT, Brazil.
First, we need to define an orbit propagator. In this case, we will use the TLE obtained from CelesTrak when this documentation was written:
julia> tle_amz1 = tle""" AMAZONIA 1 1 47699U 21015A 24008.13079366 .00000299 00000+0 10693-3 0 9994 2 47699 98.4120 87.2350 0001570 92.1147 268.0222 14.40836963150331 """TLE: AMAZONIA 1 (Epoch = 2024-01-08T03:08:20.572): ├─ Line 1 │ Satellite Number : 47699 │ Classification : U │ International Designator : 21015A │ Epoch Year : 24 │ Epoch Day : 8.13079366 │ ṅ/2 : 2.99e-6 rev/day² │ n̈/6 : 0.0 rev/day³ │ B* : 0.00010693 1/ER │ Ephemeris Type : 0 │ Element Set Number : 999 └─ Line 2 Inclination : 98.412° RA of the Ascending Node : 87.235° Eccentricity : 0.000157 Arg. of Perigee : 92.1147° Mean Anomaly : 268.0222° Mean Motion : 14.40836963 rev/day Revolution Number : 15033julia> orbp = Propagators.init(Val(:SGP4), tle_amz1)OrbitPropagatorSgp4{Float64, Float64} (SGP4 Orbit Propagator): ├─ Mean Elements │ Epoch : 2.46032e6 (2024-01-08T03:08:20.572) │ Semi-Major Axis : 7133.871818 km │ Mean Motion : 14.40836963 rev/day │ Eccentricity : 0.000157 │ Inclination : 98.412° │ RA of Asc. Node : 87.235° │ Arg. of Periapsis : 92.1147° │ Mean Anomaly : 268.0222° │ B* : 0.00010693 1/ER ├─ Constants │ R₀ : 6378.137 km │ XKE : 0.07436685317 er^(3/2)/min │ J₂ : 0.001082629989 │ J₃ : -2.53215306e-6 │ J₄ : -1.61098761e-6 └─ Propagation Last Instant : 0.0 min
Now, we can compute the gaps during one day considering the INPE's station at Cuiabá:
julia> ground_facility_gaps( orbp, [(-(15 + 33 / 60) |> deg2rad, -(56 + 04 / 60) |> deg2rad, 0)]; duration = 1 * 86400, minimum_elevation = 5 |> deg2rad, time_unit = :min )4×3 DataFrame Row │ gap_beginning gap_end duration │ DateTime DateTime Float64 ─────┼──────────────────────────────────────────────────────────── 1 │ 2024-01-08T03:09:16.311 2024-01-08T13:56:48.099 647.53 2 │ 2024-01-08T14:08:50.888 2024-01-08T15:39:28.281 90.6232 3 │ 2024-01-08T15:43:47.366 2024-01-09T02:18:02.879 634.259 4 │ 2024-01-09T02:30:08.933 2024-01-09T03:08:20.572 38.194
If we want to change the reference frames used in the analysis, we must provide a function f_eci_to_ecef(r_i, jd) that converts the vector r_i to the desired ECEF frame at the instant jd [Julian Day]. For example, let's use the more precise ITRF instead of the PEF (default):
julia> const eop = fetch_iers_eop(Val(:IAU1980));julia> function f_eci_to_ecef(r_teme, jd) D_itrf_teme = r_eci_to_ecef(TEME(), ITRF(), jd, eop) r_itrf = D_itrf_teme * r_teme return r_itrf endf_eci_to_ecef (generic function with 1 method)julia> ground_facility_gaps( orbp, [(-(15 + 33 / 60) |> deg2rad, -(56 + 04 / 60) |> deg2rad, 0)]; duration = 1 * 86400, f_eci_to_ecef = f_eci_to_ecef, minimum_elevation = 5 |> deg2rad, time_unit = :min )4×3 DataFrame Row │ gap_beginning gap_end duration │ DateTime DateTime Float64 ─────┼──────────────────────────────────────────────────────────── 1 │ 2024-01-08T03:09:16.312 2024-01-08T13:56:48.098 647.53 2 │ 2024-01-08T14:08:50.887 2024-01-08T15:39:28.281 90.6232 3 │ 2024-01-08T15:43:47.364 2024-01-09T02:18:02.879 634.259 4 │ 2024-01-09T02:30:08.935 2024-01-09T03:08:20.572 38.194
We can also perform analyses using multiple ground facilities. For example, let's find the accumulated gap if we consider the INPE's stations at Cuiabá, MT, Brazil, and Alcântara, MA, Brazil:
julia> ground_facility_gaps( orbp, [ (-(15 + 33 / 60) |> deg2rad, -(56 + 04 / 60) |> deg2rad, 0) (-( 2 + 20 / 60) |> deg2rad, -(44 + 24 / 60) |> deg2rad, 0) ]; duration = 1 * 86400, minimum_elevation = 5 |> deg2rad, time_unit = :min )6×3 DataFrame Row │ gap_beginning gap_end duration │ DateTime DateTime Float64 ─────┼──────────────────────────────────────────────────────────── 1 │ 2024-01-08T03:09:16.311 2024-01-08T12:16:55.777 547.658 2 │ 2024-01-08T12:23:20.782 2024-01-08T13:52:44.135 89.3892 3 │ 2024-01-08T14:08:50.888 2024-01-08T15:39:28.281 90.6232 4 │ 2024-01-08T15:43:47.366 2024-01-09T00:43:23.473 539.602 5 │ 2024-01-09T00:53:25.918 2024-01-09T02:18:02.879 84.616 6 │ 2024-01-09T02:32:05.994 2024-01-09T03:08:20.572 36.243
By default, the algorithm computes the accumulated gap, i.e., it considers the gap active if neither station has visibility to the satellite. We can change this logic by overloading the function in the keyword parameter reduction. For example, let's compute the gap when the satellite does not have visibility to both ground stations at the same time:
julia> ground_facility_gaps( orbp, [ (-(15 + 33 / 60) |> deg2rad, -(56 + 04 / 60) |> deg2rad, 0) (-( 2 + 20 / 60) |> deg2rad, -(44 + 24 / 60) |> deg2rad, 0) ]; duration = 1 * 86400, minimum_elevation = 5 |> deg2rad, reduction = v -> (&)(v...), time_unit = :min )3×3 DataFrame Row │ gap_beginning gap_end duration │ DateTime DateTime Float64 ─────┼──────────────────────────────────────────────────────────── 1 │ 2024-01-08T03:08:20.572 2024-01-08T13:56:48.099 648.459 2 │ 2024-01-08T14:04:29.601 2024-01-09T02:21:47.636 737.301 3 │ 2024-01-09T02:30:08.933 2024-01-09T03:08:20.572 38.194