-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathground_station_actor.py
53 lines (40 loc) · 1.68 KB
/
ground_station_actor.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
from loguru import logger
import pykep as pk
from skyfield.api import load
from paseos.actors.base_actor import BaseActor
class GroundstationActor(BaseActor):
"""This class models a groundstation actor."""
# Ground station latitude / longitude
_skyfield_position = None
# Timescale object to convert from pykep epoch to skyfield time
_skyfield_timescale = load.timescale()
# Minimum angle to communicate with this ground station
_minimum_altitude_angle = None
def __init__(
self,
name: str,
epoch: pk.epoch,
) -> None:
"""Constructor for a groundstation actor.
Args:
name (str): Name of this actor
epoch (pykep.epoch): Epoch at this pos / velocity
"""
logger.trace("Instantiating GroundstationActor.")
super().__init__(name, epoch)
def get_position(self, epoch: pk.epoch):
"""Compute the position of this ground station at a specific time.
Positions are in J2000 geocentric reference frame, same reference frame as
for the spacecraft actors. Since the Earth is rotating, ground stations have
a non-constant position depending on time.
Args:
epoch (pk.epoch): Time as pykep epoch
Returns:
np.array: [x,y,z] in meters
"""
# Converting time to skyfield to use its API
t_skyfield = self._skyfield_timescale.tt_jd(epoch.jd)
# Getting ground station position, skyfield operates in GCRF frame
# which is technically more precise than the J2000 we use but we neglect this here
gcrf_position = self._skyfield_position.at(t_skyfield).position.m
return gcrf_position