Hi everyone,
I use the ElevationExtremumDetector to calculate the maximum elevation. The key code is as follows.
My question is that when my calculation start time and end time do not include the maximum elevation, there is no event returned. I expect to compute the maximum elevation angle within the time interval. What should I do?
Cheers,
Anjin
public List<MaxElevationResp> calMaxElevation(Coordinate3D location, Long startMillis, Long endMillis) {
GeodeticPoint point = new GeodeticPoint(FastMath.toRadians(location.getLat()), FastMath.toRadians(location.getLng()), location.getAlt());
final TopocentricFrame tcf = new TopocentricFrame(OrekitUtil.EARTH, point, "point");
ElevationExtremumDetector extremumDetector = new ElevationExtremumDetector(tcf)
.withHandler(new RecordAndContinue<>());
propagator.addEventDetector(extremumDetector);
AbsoluteDate start = new AbsoluteDate(new Date(startMillis), TimeScalesFactory.getUTC());
AbsoluteDate end = new AbsoluteDate(new Date(endMillis), TimeScalesFactory.getUTC());
propagator.propagate(start, end);
Iterator<EventDetector> itr = propagator.getEventsDetectors().iterator();
ElevationExtremumDetector respDetector = (ElevationExtremumDetector) itr.next();
RecordAndContinue handler = (RecordAndContinue) respDetector.getHandler();
List<RecordAndContinue.Event> events = handler.getEvents();
List<MaxElevationResp> respList = new ArrayList<>();
for (RecordAndContinue.Event event : events) {
SpacecraftState state = event.getState();
ElevationExtremumDetector detector = (ElevationExtremumDetector) event.getDetector();
double elevationDegrees = FastMath.toDegrees(detector.getElevation(state));
if (elevationDegrees > 0) {
MaxElevationResp maxElevationResp = new MaxElevationResp();
Date date = state.getDate().toDate(TimeScalesFactory.getUTC());
maxElevationResp.setDate(date);
maxElevationResp.setMaxElevation(elevationDegrees);
respList.add(maxElevationResp);
}
}
}
If you’re using Orekit 12.2, you could create your own detector, that would basically wrap ElevationExtremumDetector (possibly with AdapterDetector) and add in the init and finish methods (respectively called at propagation start and end) the computation and storage of the elevation.
Serrof’s approach is probably cleaner, but another approach is that propagators have a method that allows you to get the initial spacecraft state, and the propagate method itself returns the final spacecraft state. One of those two must be the maximum over the interval if there was no sign change in the g function, i.e. no extremum event detected.
Likewise get the final elevation by the spacecraft state that was returned from the propagator by your propagator.propagate(start, end) call and compare the two.
Yeah that’s essentially what you would achieve with the init/finish method. And actually it’s even better to do it at EventHandler level. This way you could collect all local extrema as well, each time eventOccurred is called.