orbitalgym.groundstations¶
Ground-station network and contact-schedule primitives.
Network types¶
orbitalgym.groundstations.network.GroundStation ¶
A single ground station — Earth-fixed lat/lon/alt + elevation mask.
name is a Python-level string (not a traced array) so it stays usable
by visualization and logging without escaping the JAX trace.
orbitalgym.groundstations.network.ContactSchedule ¶
Precomputed contact windows for one side over the episode horizon.
windows is a fixed-shape padded array so in_contact_now runs in JIT
without Python control flow. Sentinel rows have t_end <= t_start and
are guarded by the per-row idx < n_valid mask.
orbitalgym.groundstations.network.GroundStationNetwork ¶
A side's network — static-tuple stations + their precomputed schedule.
schedule is filled by precompute_contact_schedule (in contacts.py)
at scenario construction. Construction without a schedule is allowed for
tests that don't exercise contacts; production code goes through the
builder.
Contact computation¶
The runtime predicate in_contact_now is pure JAX and JIT-stable; the
brahe-backed builder precompute_contact_schedule runs once at
scenario construction.
orbitalgym.groundstations.contacts.precompute_contact_schedule ¶
precompute_contact_schedule(
stations: tuple[GroundStation, ...],
reference_orbit: ReferenceOrbitState,
epoch_mjd_utc: float,
horizon_s: float,
*,
pad_to: int = 256,
) -> ContactSchedule
Build a ContactSchedule from per-station brahe queries.
Calls brahe once per station, concatenates the per-station window lists, sorts ascending by start time, pads to pad_to rows with sentinels.
Raises ValueError if the total window count exceeds pad_to.
orbitalgym.groundstations.contacts.in_contact_now ¶
Scalar bool: is t inside any valid contact window?
Open-closed semantics: t_start <= t < t_end. Pure JAX — single
jnp.any over the padded (N_max, 2) array, gated by an
idx < n_valid mask so sentinel rows never match.