Latitude and Longitude Crossing Detector

Thanks for sharing your solution, which is just right, that’s the great advantage of the EventDetector interface, which makes it easy to build :wink: a specialized detector to suit your needs.

For the record, assuming fromLatitude < toLatitude, the equivalent of your LatitudeRangeCrossingDetector can be obtained by combining 2 LatitudeCrossingDetectors:

LatitudeCrossingDetector fromLatDetector = new LatitudeCrossingDetector(earthShape, fromLatitude);
LatitudeCrossingDetector toLatDetector = new LatitudeCrossingDetector(earthShape, toLatitude);
EventDetector latRangeDetector = BooleanDetector.andCombine(fromLatDetector, BooleanDetector.notCombine(toLatDetector));

Thus, the g function of the combined detector is zero at toLatitude and fromLatitude, positive in the range fromLatitude to toLatitude and negative outside.

But the BooleanDetector is not suitable for the LongitudeCrossingDetector, as its increasing flag is not usable in practice. This is where the EventEnablingPredicateFilter comes in handy :slight_smile: We then need to implement the EnablingPredicate interface to filter out events occurring outside the [fromLongitude, toLongitude] interval, assuming again fromLongitude < toLongitude, as in the following example:

class LongitudeFilter implements EnablingPredicate {
    private OneAxisEllipsoid earth;
    private final double from;
    private final double to;

    public LongitudeFilter(OneAxisEllipsoid eartShape, double fromLongitude, double toLongitude) {
            earth = earthShape;
            from = fromLongitude;
            to = toLongitude;
    }

    @Override
    public boolean eventIsEnabled(SpacecraftState s, EventDetector d, double g) {
        double longitude = earth.transform(s.getPVCoordinates().getPosition(),
                                           s.getFrame(), s.getDate()).getLongitude();
        return from <= longitude && longitude <= to;
    }
}

You can then write the following new detector, which will detect the passage between fromLatitude and toLatitude when the longitude is between fromLongitude and toLongitude:

LongitudeFilter predicate = new LongitudeFilter(eartShape, fromLongitude, toLongitude);
EventDetector LatLonRangeDetector = new EventEnablingPredicateFilter(latRangeDetector, predicate);

The advantage of using an EventPredicate, rather than combining detectors, is that it speeds up detection, but it also has the disadvantage of potentially missing events if the maxCheck parameter isn’t set correctly.

Note: all snippets have been written on the fly, please check before use…