Ground station in view of satellite field of view

Hello there! I am newer to development in general and orekit. I am trying to propagate the ISS and attach a field of view to the ISS and then determine when the satellite sees a specific ground station using python.
I have the propagation done and the field of view done and can plot it on a map. However, I am struggling to implement the FieldOfViewDetector. Any help in how to do this would be greatly appreciated.
I have looked at the python detector example and it shows for eclipse but not a ground station. The ground station elevation part is blank.

Here is my code:
import orekit_jpype as orekit

orekit.initVM()
from orekit_jpype.pyhelpers import setup_orekit_data

setup_orekit_data(“/home/kam/Downloads/orekit-data/”, from_pip_library=False)

from org.orekit.bodies import OneAxisEllipsoid, GeodeticPoint
from org.orekit.frames import FramesFactory, Transform, TopocentricFrame
from org.orekit.utils import IERSConventions, Constants
from org.orekit.orbits import KeplerianOrbit
from org.orekit.attitudes import NadirPointing
from org.orekit.geometry.fov import CircularFieldOfView
from org.orekit.time import AbsoluteDate, TimeScalesFactory
from org.orekit.propagation.analytical.tle import TLE, TLEPropagator
from org.orekit.propagation import SpacecraftState
from org.hipparchus.geometry.euclidean.threed import Vector3D
from math import radians, degrees
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.feature as cfeature
from datetime import datetime

Start/Stop time to propagate and step size

startDate = AbsoluteDate(2024, 12, 23, 1, 5, 0.0, TimeScalesFactory.getUTC())
stopDate = startDate.shiftedBy(300.0 * 2) # seconds
stepSizeSec = 150.0
print('StartTime = ', startDate)
print(‘StopTime = ‘, stopDate)
print(’’)

Define the ground station coordinates (latitude, longitude, altitude)

latitudeGS = radians(0.0) # Latitude in radians
longitudeGS = radians(0.0) # Longitude in radians
altitudeGS = 10.0 # Altitude in meters

file for TLE data expects 3 line format

filename = ‘/home/kam/Documents/ISS.txt’
f = open(filename, “r”)

Read TLE lines if not all there end the loop

line1 = f.readline()
tle_line1 = f.readline()
tle_line2 = f.readline()

Parse the TLE

mytle = TLE(tle_line1, tle_line2)

print(‘Epoch :’, mytle.getDate())

print(mytle)

print(tle_line1)
print(tle_line2)

#setup the FoV of the footprint
fov_angle = 90.0 # Field of view angle in degrees
margin = 0.0 # Margin in degrees
fov = CircularFieldOfView(Vector3D.PLUS_K, radians(fov_angle), radians(margin))

#Setup the earth frame
ITRF_Frame = FramesFactory.getITRF(IERSConventions.IERS_2010, True)
earth = OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
Constants.WGS84_EARTH_FLATTENING, ITRF_Frame)

#Create location on earth from lat/long to do calculations with
station = GeodeticPoint(latitudeGS, longitudeGS, altitudeGS)
station_frame = TopocentricFrame(earth, station, “Esrange”)

#Setup propagator and attitude to be earth pointing
propagator = TLEPropagator.selectExtrapolator(mytle)
attitude_provider = NadirPointing(FramesFactory.getEME2000(), earth)
propagator.setAttitudeProvider(attitude_provider)

Plot the world map and FOV

plt.figure(figsize=(12, 8))
ax = plt.axes(projection=ccrs.PlateCarree())
ax.add_feature(cfeature.LAND)
ax.add_feature(cfeature.COASTLINE)
ax.add_feature(cfeature.BORDERS)

Loop over prop time

while startDate.compareTo(stopDate) <= 0.0:
# prop in J2000 frame
pv = propagator.getPVCoordinates(startDate, FramesFactory.getEME2000())
# Prop to time in ECEF Fixed frame
pvFixed = propagator.getPVCoordinates(startDate, FramesFactory.getITRF(IERSConventions.IERS_2010, True))

# # Create Lat/Lon point of satellite
satelliteGeodeticPoint = earth.transform(pvFixed, ITRF_Frame, startDate)
satLatTemp = satelliteGeodeticPoint.getLatitude().toDegrees().getValue()
satLonTemp = satelliteGeodeticPoint.getLongitude().toDegrees().getValue()
print("Lat=", satLatTemp, "  Lon=", satLonTemp)

# Create orbit or transform
orbit = KeplerianOrbit(pv, FramesFactory.getEME2000(), Constants.EGM96_EARTH_MU)

# Get the spacecraft state at specific time of interest this will include attitude which is needed for transform
state = SpacecraftState(orbit, attitude_provider.getAttitude(orbit, startDate, FramesFactory.getEME2000()))

#Create transforms for the footprint call for FOV
inertToBody = state.getFrame().getTransformTo(earth.getBodyFrame(), state.getDate())
fovToBody = Transform(state.getDate(), state.toTransform().getInverse(), inertToBody)

# Get the footprint of the satellite
footprint = fov.getFootprint(fovToBody, earth, 0.001)

#Save lat/long from footprint
latitude = []
longitude = []
for k in range(0, len(footprint)):
    obj = footprint[k]
    for d in range(0, len(obj)):
        blah = obj[d]
        latitude.append(degrees(blah.getLatitude()))
        longitude.append(degrees(blah.getLongitude()))

# Add to the plot the footprint location
ax.plot(longitude, latitude, transform=ccrs.Geodetic(), color='red', linewidth=2)
# Add to the plot the satellite location
ax.plot(satLonTemp, satLatTemp, color='m', marker='D', markersize=9)

# move the time by the step size
startDate = startDate.shiftedBy(stepSizeSec)

Set plot values

ax.set_global()
plt.title(f"Satellite Field of View from {startDate} to {stopDate}")
plt.show()

Hello @kamblitz,

Thank you for the detailed post. I’m upping this thread.

Cheers,
Vincent

Thank you still looking for some help if anyone has any pointers would be greatly appreciated.

Hello @kamblitz,

Adding a FieldOfViewDetector

You are clearly on the right track, you now only need to create a FieldOfViewDetector (documentation here) and add it to the propagator like so:

fovDetector = FieldOfViewDetector​(stationFrame, fov).withHandler(WHATEVER_HANDLER_YOU_WANT);
...
propagator.addEventDetector(fovDetector);

Note that you should implement your own EventHandler (documentation here) to do something when the station enter/exit the ISS field of view.

Bonus: Replace loop with OrekitFixedStepHandler

Also, you are using some while loop to store your points but i suggest you to use an OrekitFixedStepHandler (documentation here) to store the ISS lat/lon + footprint during propagation.

Orekit jpype documentation

I’m not really used to work with orekit jpype so you should see this to get more information regarding implementation of interfaces in orekit jpype: Orekit / orekit_jpype · GitLab

Hope this helps !

Cheers,
Vincent