Dear all,
I have been a member of this forum for a while, but needed to create a new user due to a change of job, and my previous email doesn’t work anymore
I am trying to create a script with a FieldOfViewDetector and record events whenever a target on the ground is within the spacecraft’s FoV. From other posts of this forum I tried creating it by adding the elevation detector and then a Boolean detector so the FieldOfViewDetector detects the target only when it is visible from the horizon. The problem is that it seems that the results are completely governed by the ElevationDetector, i.e., the events occur as soon as the spacecraft is above the target horizon. Indeed, even drastically decreasing the FoV of the sensor onboard, the results seem to remain practically the same → the impression I get is that the results are using a OR rather than AND, even though I’m using the “BooleanDetector.andCombine”
Could I kindly get a feedback on what I’m doing wrong here? I would be much thankful.
Thank you so much in advance.
Leonardo.
import orekit
vm = orekit.initVM()
from orekit.pyhelpers import setup_orekit_curdir
setup_orekit_curdir()
from org.orekit.orbits import KeplerianOrbit
from org.orekit.orbits import PositionAngle
from org.orekit.propagation.analytical import KeplerianPropagator
from org.orekit.attitudes import NadirPointing
from org.hipparchus.geometry.euclidean.threed import Vector3D
from org.orekit.propagation.events import BooleanDetector
from org.orekit.propagation.events import ElevationDetector
from org.orekit.propagation.events import FieldOfViewDetector
from org.orekit.propagation.events import EventsLogger
from org.orekit.propagation.events.handlers import ContinueOnEvent
from org.orekit.frames import FramesFactory, TopocentricFrame
from org.orekit.bodies import OneAxisEllipsoid, GeodeticPoint
from org.orekit.utils import Constants, IERSConventions
from org.orekit.geometry.fov import DoubleDihedraFieldOfView
from org.orekit.time import TimeScalesFactory, AbsoluteDate
from orekit.pyhelpers import absolutedate_to_datetime
from math import radians
from datetime import datetime
import pandas as pd
utc = TimeScalesFactory.getUTC()
gcrf = FramesFactory.getGCRF()
itrf = FramesFactory.getITRF(IERSConventions.IERS_2010, False)
eci = gcrf # Inertial frame
ecef = itrf # Non-inertial frame
earth = OneAxisEllipsoid(
Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
Constants.WGS84_EARTH_FLATTENING,
ecef)
nadirPointing = NadirPointing(eci, earth)
duration = 20*24*3600.0 # seconds
step = 60.0 # seconds
'''
Spacecraft Definition
'''
mass = 25.0 # [kg]
cross_section = 0.08 # [m2]
cd = 2.2
cr = 1.8
'''
Keplerian Orbit
'''
epoch = datetime(2026, 1, 1, 10, 30, 0)
ra = 375.0 # Apogee
rp = 375.0 # Perigee
i = 15.0#ssoInclination(ra, rp) # inclination
omega = 90.0 # perigee argument
raan = 130.0 # RAAN
lv = 45.0 # True anomaly
sma = (ra*1e3+rp*1e3+2*Constants.WGS84_EARTH_EQUATORIAL_RADIUS)/2.0
ecc = abs((ra*1e3 - rp*1e3)/(ra*1e3 - rp*1e3 + 2*Constants.WGS84_EARTH_EQUATORIAL_RADIUS))
startTime = AbsoluteDate(epoch.year,epoch.month,epoch.day,
epoch.hour,epoch.minute,float(epoch.second),utc)
endTime = startTime.shiftedBy(duration)
initialOrbit = KeplerianOrbit(
sma, ecc,
radians(i), radians(omega),
radians(raan), radians(lv),PositionAngle.TRUE,
eci, startTime, Constants.WGS84_EARTH_MU)
propagator = KeplerianPropagator(
initialOrbit,
nadirPointing,
Constants.WGS84_EARTH_MU,
mass)
'''
Target
'''
targetLatitude = -0.994824
targetLongitude = -52.711238
point = GeodeticPoint(radians(targetLatitude),radians(targetLongitude), 0.0)
target = TopocentricFrame(earth, point, 'target')
'''
Sensor & Detector definition
'''
cameraFOV = 40.0
sensorFOV = DoubleDihedraFieldOfView(
Vector3D.PLUS_K, Vector3D.PLUS_I, radians(cameraFOV),
Vector3D.PLUS_J, radians(cameraFOV), 0.0)
fovDetector = FieldOfViewDetector(target, sensorFOV).withHandler(ContinueOnEvent())
elevationDetector = ElevationDetector(target).withConstantElevation(0.0).withHandler(ContinueOnEvent())
finalDetector = BooleanDetector.andCombine([elevationDetector,fovDetector])
fovLogger = EventsLogger()
logged_detector = fovLogger.monitorDetector(finalDetector)
propagator.addEventDetector(logged_detector)
while(startTime.compareTo(endTime) <= 0.0):
pvECI = propagator.propagate(startTime).getPVCoordinates()
pvPosition = pvECI.getPosition()
pvVelocity = pvECI.getVelocity()
print('{} {} {} {} {} {} {}'.format(
absolutedate_to_datetime(startTime),
pvPosition.getX()/1e3,
pvPosition.getY()/1e3,
pvPosition.getZ()/1e3,
pvVelocity.getX()/1e3,
pvVelocity.getY()/1e3,
pvVelocity.getZ()/1e3))
startTime = startTime.shiftedBy(step)
start_time = None
contacts = pd.DataFrame()
events = fovLogger.getLoggedEvents()
for event in fovLogger.getLoggedEvents():
if event.isIncreasing():
start_time = event.getState().getDate()
elif start_time:
stop_time = event.getState().getDate()
contacts = contacts.append({"Duration (s)": stop_time.durationFrom(start_time),
"Start Time (UTC)": absolutedate_to_datetime(start_time),
"Stop Time (UTC)": absolutedate_to_datetime(stop_time)},
ignore_index=True)
contacts.to_csv('Accesses_FoV_40deg', sep='\t', index=False)
start_time = None
print(contacts)