I am using the FoV Detector to find the time range when a point on earth is visible to the sensor on the spacecraft. However, the pass duration I get as a result is longer than I expect (I expect ~10s but get ~1.5 minutes).
I assume that this is caused by a misconfiguration of the FoV/FoV Detector but I did not figure out what I do wrong.
That’s my FoV declaration (rectangle, 5 degrees):
final double viewAngle = 5.0;
final var fov = new FieldOfView(Vector3D.PLUS_K,
Vector3D.PLUS_I, FastMath.toRadians(viewAngle / 2),
Vector3D.PLUS_J, FastMath.toRadians(viewAngle / 2),
0);
The FoV Detector:
final var tcf = new TopocentricFrame(earth, point, "point");
final var detector = new FieldOfViewDetector(tcf, fov).withMaxCheck(maxCheckingInterval).withHandler(new EventHandler<FieldOfViewDetector>() {
private AbsoluteDate start;
@Override
public Action eventOccurred(SpacecraftState s, FieldOfViewDetector detector,
boolean increasing) throws OrekitException {
if (increasing) {
// Leaving Area
final var end = s.getDate();
System.out.println("Pass duration: " + end.durationFrom(start));
return Action.CONTINUE;
} else {
// Entering Area
start = s.getDate();
return Action.CONTINUE;
}
}});
The propagation:
final var logger = new EventsLogger();
final var propagator = TLEPropagator.selectExtrapolator(...);
final var attitudeProvider = new NadirPointing(propagator.getFrame(), earth);
propagator.setAttitudeProvider(attitudeProvider);
propagator.addEventDetector(logger.monitorDetector(detector));
propagator.propagate(startDate, endDate);
Is there something wrong how I utilize the FoV/FoV Detector?
The way you use this detector is correct. I think you have found a bug in Orekit!
Looking back at the test case for FieldOfViewDetector, the test pass but the way
it is written is wrong, we failed to notice the detector did not work properly since
at least version 7.2
If you could add your own test configuration to the bug report (with your FoV definition, attitude definition,
the TLE data and the search time range), it would help us a lot.
I looked again at the test and improved it, but the library behavior was in fact correct in this
case, so I am not sure anymore there is a bug. We need to have some data to check.
These are the angles in the relevant time frame: angles.dat (18.1 KB)
If I am not mistaken, the boundaries of the FoV are 2.5 degress (~0.0436 rad). When I look through the list of angles, I cannot see that the target crosses the FoV boundary. Does this help?
I have also attached the code snipped with the TLE data to test:
The Snipped
final var tle = new TLE("1 33314U 08040C 18325.13536407 .00000020 00000-0 93127-5 0 9993",
"2 33314 97.7735 35.5590 0025404 105.4992 254.9034 14.79911945552555");
final var startDate = new AbsoluteDate(2018, 11, 20, 3, 0, 0, TimeScalesFactory.getUTC());
final var endDate = new AbsoluteDate(2018, 11, 20, 4, 0, 0, TimeScalesFactory.getUTC());
final var maxCheckingInterval = 5.0;
final var ecef = FramesFactory.getITRF(IERSConventions.IERS_2010, true);
final var earth = new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
Constants.WGS84_EARTH_FLATTENING, ecef);
final double viewAngle = 5.0;
final var fov = new FieldOfView(Vector3D.PLUS_K, Vector3D.PLUS_I,
FastMath.toRadians(viewAngle / 2), Vector3D.PLUS_J, FastMath.toRadians(viewAngle / 2), 0);
final var point = new GeodeticPoint(40.205842983848484, -92.58639608631753, 40.205842983848484);
final var tcf = new TopocentricFrame(earth, point, "point");
final var detector = new FieldOfViewDetector(tcf, fov).withMaxCheck(maxCheckingInterval)
.withHandler(new EventHandler<FieldOfViewDetector>() {
private AbsoluteDate start;
@Override
public Action eventOccurred(SpacecraftState s, FieldOfViewDetector detector,
boolean increasing) throws OrekitException {
if (increasing) {
// Leaving Area
final var end = s.getDate();
final var duration = end.durationFrom(start);
System.out.println("Pass duration: " + duration);
return Action.CONTINUE;
} else {
// Entering Area
start = s.getDate();
return Action.CONTINUE;
}
}
});
final var logger = new EventsLogger();
final var propagator = TLEPropagator.selectExtrapolator(tle);
final var attitudeProvider = new NadirPointing(propagator.getFrame(), earth);
propagator.setAttitudeProvider(attitudeProvider);
propagator.addEventDetector(logger.monitorDetector(detector));
propagator.propagate(startDate, endDate);
It seems like that I detect my point on the Earth from the other side of the Earth. Is there a way to ensure that the spacecraft is not looking through the Earth?
Hi,
You should try to define your geodetic point with values in radians, it seems like you define it from degrees.
With your data taken as radians, the point is really on the other side of the Earth.
thank you for your hint. I have already found this issue and I am now using radians
I am also printing the coordinates of the spacecraft when entering/leaving the FoV. Then I can clearly see, that the long passes occurr when the spacecraft is on the other side of the earth, e.g.: (target point is lat 40.205842983848484 deg, -92.58639608631753 deg
The easiest way is to combine your FieldOfViewDetector with an ElevationDetector thanks to the BooleanDetector. You could try something like:
final FieldOfViewDetector fd = new FieldOfViewDetector(tcf, fov);
final ElevationDetector ed = new ElevationDetector(tcf).withConstantElevation(0.);
final BooleanDetector detector = BooleanDetector.andCombine(ed, BooleanDetector.notCombine(fd)).withMaxCheck(maxCheckingInterval).withHandler(new EventHandler<BooleanDetector>() {
private AbsoluteDate start;
@Override
public Action eventOccurred(SpacecraftState s, BooleanDetector detector, boolean increasing) throws OrekitException {
if (increasing) {
// Entering Area
start = s.getDate();
return Action.CONTINUE;
} else {
// Leaving Area
final double duration = s.getDate().durationFrom(start);
System.out.println("Pass duration: " + duration);
return Action.CONTINUE;
}
}
});
Note that the boolean combination of the detectors requires to change the sign of the g function from the FieldOfViewDetector, which is done through BooleanDetector.notCombine(fd).
With your data, no pass is found, but with a wider timespan, I’ve got the following pass:
Start visibility: 2018-11-23T04:06:39.373
End visibility: 2018-11-23T04:06:47.250
Pass duration: 7.877595829517514
Hi!I have been reading about this post.It’s useful to my work.
But I have a problem,when compute the access of a sensor on a satellite to a sation on the ground.Why do we bind the fov to the station frame rather than the satellite frame?
final var tcf = new TopocentricFrame(earth, point, "point");
final var detector = new FieldOfViewDetector(tcf, fov).withMaxCheck(maxCheckingInterval)
.withHandler(new EventHandler<FieldOfViewDetector>()
Hi! I think the TopocentricFrame is used here only as a provider for the target PVCoordinates. The fov is attached to the spacecraft frame in the evaluation of the detector during the propagation
Hello, I am having a similar issue. I have the same goal, but using that method I get no passes. Could you please see here? Visibility of Location with FOV
In looking through the FieldOfViewDetector API documentation, the switching function is defined as becoming negative when a target enters the FOV, and then back positive again when the target leaves. (So, negative response with FOV inclusion.)
In opposition, the ElevationDetector is worded more cryptically, but appears to switch positive when its target (satellite in this case) is above the elevation threshold.
However, the BooleanDetector.andCombine function expects to AND two positive switching functions (which the FOV detector is not). Therefore, I believe it might be necessary to use the BooleanDetector.notCombine function on the FOV detector before applying it to the elevation combination for correct usage in this case.
Thoughts? Am I correct?
If so, perhaps there might be some examples that may also require this fix.
You are correct about the signs. For elevation detector, the sign of the g function is just satellite elevation minus mask (i.e. profile of the surroundings, like mountains, as seen from the ground station), hence it is positive when satellite is visible.
So you are also correct for the combination: you need to use notCombine on the FOV detector.