mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-13 15:50:59 +00:00
fix for bug 1587: when a fix-provided speed is greater than the maximum for smoothing (50kts by default), the fix-provided speed is ignored
This commit is contained in:
1 parent
1139fcaa3b
commit
a64a191992
2 files changed
+74
-18
No files matched your search
@@ -305,6 +305,53 @@ public class TrackTest {
|
||||
assertEquals(0, average.getBearing().getDegrees(), 0.00001);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFixValidEvenIfFixProvidedSpeedIsOutrageous() {
|
||||
DynamicGPSFixTrack<Object, GPSFixMoving> track = new DynamicGPSFixMovingTrackImpl<Object>(null, /* millisecondsOverWhichToAverage */ 5000l);
|
||||
TimePoint t1 = new MillisecondsTimePoint(1000);
|
||||
TimePoint t2 = new MillisecondsTimePoint(2000);
|
||||
TimePoint t3 = new MillisecondsTimePoint(3000);
|
||||
GPSFixMoving f1 = new GPSFixMovingImpl(new DegreePosition(1./3600.*1./60., 0), t1, new KnotSpeedWithBearingImpl(1, new DegreeBearingImpl(0)));
|
||||
GPSFixMoving f2 = new GPSFixMovingImpl(new DegreePosition(2./3600.*1./60., 0), t2, new KnotSpeedWithBearingImpl(150, new DegreeBearingImpl(0))); // outrageous speed; to be ignored by getEstimatedSpeed
|
||||
GPSFixMoving f3 = new GPSFixMovingImpl(new DegreePosition(3./3600.*1./60., 0), t3, new KnotSpeedWithBearingImpl(1, new DegreeBearingImpl(0)));
|
||||
track.addGPSFix(f1);
|
||||
track.addGPSFix(f2);
|
||||
track.addGPSFix(f3);
|
||||
assertEquals(f2, track.getFirstFixAtOrAfter(f2.getTimePoint())); // expect the fix to still be valid, but only its provided speed shall be ignored
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFixInvalidEvenIfPositionInferredSpeedIsOutrageous() {
|
||||
DynamicGPSFixTrack<Object, GPSFixMoving> track = new DynamicGPSFixMovingTrackImpl<Object>(null, /* millisecondsOverWhichToAverage */ 5000l);
|
||||
TimePoint t1 = new MillisecondsTimePoint(1000);
|
||||
TimePoint t2 = new MillisecondsTimePoint(2000);
|
||||
TimePoint t3 = new MillisecondsTimePoint(3000);
|
||||
GPSFixMoving f1 = new GPSFixMovingImpl(new DegreePosition(1./3600.*1./60., 0), t1, new KnotSpeedWithBearingImpl(1, new DegreeBearingImpl(0)));
|
||||
GPSFixMoving f2 = new GPSFixMovingImpl(new DegreePosition(150./3600.*1./60., 0), t2, new KnotSpeedWithBearingImpl(150, new DegreeBearingImpl(0))); // outrageous speed; to be ignored by getEstimatedSpeed
|
||||
GPSFixMoving f3 = new GPSFixMovingImpl(new DegreePosition(3./3600.*1./60., 0), t3, new KnotSpeedWithBearingImpl(1, new DegreeBearingImpl(0)));
|
||||
track.addGPSFix(f1);
|
||||
track.addGPSFix(f2);
|
||||
track.addGPSFix(f3);
|
||||
assertEquals(f3, track.getFirstFixAtOrAfter(f2.getTimePoint())); // expect the f2 fix to be invalid
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIgnoringFixProvidedSpeedIfItIsOutrageous() {
|
||||
DynamicGPSFixTrack<Object, GPSFixMoving> track = new DynamicGPSFixMovingTrackImpl<Object>(null, /* millisecondsOverWhichToAverage */ 5000l);
|
||||
TimePoint t1 = new MillisecondsTimePoint(1000);
|
||||
TimePoint t2 = new MillisecondsTimePoint(2000);
|
||||
TimePoint t3 = new MillisecondsTimePoint(3000);
|
||||
GPSFixMoving f1 = new GPSFixMovingImpl(new DegreePosition(1./3600.*1./60., 0), t1, new KnotSpeedWithBearingImpl(1, new DegreeBearingImpl(0)));
|
||||
GPSFixMoving f2 = new GPSFixMovingImpl(new DegreePosition(2./3600.*1./60., 0), t2, new KnotSpeedWithBearingImpl(150, new DegreeBearingImpl(0))); // outrageous speed; to be ignored by getEstimatedSpeed
|
||||
GPSFixMoving f3 = new GPSFixMovingImpl(new DegreePosition(3./3600.*1./60., 0), t3, new KnotSpeedWithBearingImpl(1, new DegreeBearingImpl(0)));
|
||||
track.addGPSFix(f1);
|
||||
track.addGPSFix(f2);
|
||||
track.addGPSFix(f3);
|
||||
assertEquals(f2, track.getFirstFixAtOrAfter(f2.getTimePoint())); // expect the fix to still be valid, but only its provided speed shall be ignored
|
||||
SpeedWithBearing average = track.getEstimatedSpeed(t2);
|
||||
assertEquals(1, average.getKnots(), 0.001);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBearingAveragingAcrossZeroDegreesWithGPSFixMoving() {
|
||||
DynamicGPSFixMovingTrackImpl<Object> track = new DynamicGPSFixMovingTrackImpl<Object>(null, /* millisecondsOverWhichToAverage */ 5000);
|
||||
@@ -352,7 +399,7 @@ public class TrackTest {
|
||||
}
|
||||
|
||||
private TimePoint addMillisToTimepoint(TimePoint p, long millis) {
|
||||
return new MillisecondsTimePoint(p.asMillis() + millis);
|
||||
return p.plus(millis);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+26
-17
@@ -56,23 +56,30 @@ public class DynamicGPSFixMovingTrackImpl<ItemType> extends DynamicTrackImpl<Ite
|
||||
if (!relevantFixes.isEmpty()) {
|
||||
int i=0;
|
||||
GPSFixMoving last = relevantFixes.get(i);
|
||||
// add fix's own speed/bearing; this also works if only one "relevant" fix is found
|
||||
SpeedWithConfidenceImpl<TimePoint> speedWithConfidence = new SpeedWithConfidenceImpl<TimePoint>(
|
||||
last.getSpeed(),
|
||||
/* original confidence */0.9, last.getTimePoint());
|
||||
speeds.add(speedWithConfidence);
|
||||
bearingCluster.add(new BearingWithConfidenceImpl<TimePoint>(last.getSpeed().getBearing(), /* confidence */
|
||||
0.9, last.getTimePoint()));
|
||||
// if speed is within reasonable bounds, add fix's own speed/bearing; this also works if only one
|
||||
// "relevant" fix is found
|
||||
if (maxSpeedForSmoothing == null || last.getSpeed().compareTo(maxSpeedForSmoothing) <= 0) {
|
||||
SpeedWithConfidenceImpl<TimePoint> speedWithConfidence = new SpeedWithConfidenceImpl<TimePoint>(
|
||||
last.getSpeed(),
|
||||
/* original confidence */0.9, last.getTimePoint());
|
||||
speeds.add(speedWithConfidence);
|
||||
bearingCluster.add(new BearingWithConfidenceImpl<TimePoint>(last.getSpeed().getBearing(), /* confidence */
|
||||
0.9, last.getTimePoint()));
|
||||
}
|
||||
while (i<relevantFixes.size()-1) {
|
||||
// add to average the position and time difference
|
||||
GPSFixMoving next = relevantFixes.get(++i);
|
||||
aggregateSpeedAndBearingFromLastToNext(speeds, bearingCluster, last, next);
|
||||
// add to average the speed and bearing provided by the GPSFixMoving
|
||||
SpeedWithConfidenceImpl<TimePoint> computedSpeedWithConfidence = new SpeedWithConfidenceImpl<TimePoint>(
|
||||
next.getSpeed(), /* original confidence */0.9, next.getTimePoint());
|
||||
speeds.add(computedSpeedWithConfidence);
|
||||
bearingCluster.add(new BearingWithConfidenceImpl<TimePoint>(next.getSpeed().getBearing(), /* confidence */
|
||||
0.9, next.getTimePoint()));
|
||||
// if speed is within reasonable bounds, add fix's own speed/bearing; this also works if only one
|
||||
// "relevant" fix is found
|
||||
if (maxSpeedForSmoothing == null || next.getSpeed().compareTo(maxSpeedForSmoothing) <= 0) {
|
||||
SpeedWithConfidenceImpl<TimePoint> computedSpeedWithConfidence = new SpeedWithConfidenceImpl<TimePoint>(
|
||||
next.getSpeed(), /* original confidence */0.9, next.getTimePoint());
|
||||
speeds.add(computedSpeedWithConfidence);
|
||||
bearingCluster.add(new BearingWithConfidenceImpl<TimePoint>(next.getSpeed().getBearing(), /* confidence */
|
||||
0.9, next.getTimePoint()));
|
||||
}
|
||||
last = next;
|
||||
}
|
||||
}
|
||||
@@ -96,10 +103,11 @@ public class DynamicGPSFixMovingTrackImpl<ItemType> extends DynamicTrackImpl<Ite
|
||||
|
||||
/**
|
||||
* In addition to the base class implementation, we may have the speed and bearing as measured by the device (the
|
||||
* special speed/bearing combination 0.0/0.0 is simply ignored). If the adjacent fixes are within the averaging
|
||||
* interval defined by {@link GPSFixTrackImpl#getMillisecondsOverWhichToAverageSpeed()}, we use the device-measured
|
||||
* speed and compare it with the speed computed based on the time stamp and distance between previous and next fix.
|
||||
* If the ratio between the higher and the lower of the two speeds exceeds
|
||||
* special speed/bearing combination 0.0/0.0 is simply ignored, as are fix-provided speed values that exceed
|
||||
* {@link #maxSpeedForSmoothing}). If the adjacent fixes are within the averaging interval defined by
|
||||
* {@link GPSFixTrackImpl#getMillisecondsOverWhichToAverageSpeed()}, we use the device-measured speed and compare it
|
||||
* with the speed computed based on the time stamp and distance between previous and next fix. If the ratio between
|
||||
* the higher and the lower of the two speeds exceeds
|
||||
* {@link #MAX_SPEED_FACTOR_COMPARED_TO_MEASURED_SPEED_FOR_FILTERING}, the fix is considered invalid.
|
||||
*/
|
||||
@Override
|
||||
@@ -109,7 +117,8 @@ public class DynamicGPSFixMovingTrackImpl<ItemType> extends DynamicTrackImpl<Ite
|
||||
if (e.isValidityCached()) {
|
||||
isValid = e.isValid();
|
||||
} else {
|
||||
boolean fixHasValidSogAndCog = (e.getSpeed().getMetersPerSecond() != 0.0 && e.getSpeed().getBearing().getDegrees() != 0.0);
|
||||
boolean fixHasValidSogAndCog = (e.getSpeed().getMetersPerSecond() != 0.0 && e.getSpeed().getBearing().getDegrees() != 0.0 &&
|
||||
(maxSpeedForSmoothing == null || e.getSpeed().compareTo(maxSpeedForSmoothing) <= 0));
|
||||
|
||||
GPSFixMoving previous = rawFixes.lower(e);
|
||||
final boolean atLeastOnePreviousFixInRange = previous != null && e.getTimePoint().asMillis() - previous.getTimePoint().asMillis() <= getMillisecondsOverWhichToAverageSpeed();
|
||||
|
||||
Reference in new issue
Block a user