java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/CourseChangeBasedTrackApproximationWithTracTracDataTest.java
... ...
@@ -46,9 +46,9 @@ public class CourseChangeBasedTrackApproximationWithTracTracDataTest extends Onl
46 46
do {
47 47
competitors = getTrackedRace().getRace().getCompetitors();
48 48
// To pick a single competitor, e.g., for debugging, use the following line:
49
- sampleCompetitor = (CompetitorWithBoat) Util.first(Util.filter(competitors, c->c.getName().equals("Dasenbrook")));
49
+// sampleCompetitor = (CompetitorWithBoat) Util.first(Util.filter(competitors, c->c.getName().equals("Dasenbrook")));
50 50
// To pick a random competitor, use the following line:
51
-// sampleCompetitor = (CompetitorWithBoat) Util.get(competitors, new Random().nextInt(Util.size(competitors)));
51
+ sampleCompetitor = (CompetitorWithBoat) Util.get(competitors, new Random().nextInt(Util.size(competitors)));
52 52
sampleTrack = getTrackedRace().getTrack(sampleCompetitor);
53 53
} while (sampleTrack.isEmpty());
54 54
}
... ...
@@ -72,7 +72,8 @@ public class CourseChangeBasedTrackApproximationWithTracTracDataTest extends Onl
72 72
final DynamicGPSFixTrack<Competitor, GPSFixMoving> trackCopy = new DynamicGPSFixMovingTrackImpl<Competitor>(
73 73
sampleCompetitor,
74 74
/* millisecondsOverWhichToAverage */ boatClass.getApproximateManeuverDurationInMilliseconds());
75
- final CourseChangeBasedTrackApproximation earlyInitApproximation = new CourseChangeBasedTrackApproximation(trackCopy, sampleCompetitor.getBoat().getBoatClass(), /* logFixes */ true);
75
+ final CourseChangeBasedTrackApproximation earlyInitApproximation = new CourseChangeBasedTrackApproximation(
76
+ trackCopy, sampleCompetitor.getBoat().getBoatClass(), /* logFixes for debugging */ false);
76 77
final TimePoint from = sampleTrack.getFirstRawFix().getTimePoint();
77 78
final TimePoint to = sampleTrack.getLastRawFix().getTimePoint();
78 79
sampleTrack.lockForRead();
... ...
@@ -83,7 +84,8 @@ public class CourseChangeBasedTrackApproximationWithTracTracDataTest extends Onl
83 84
} finally {
84 85
sampleTrack.unlockAfterRead();
85 86
}
86
- final CourseChangeBasedTrackApproximation lateInitApproximation = new CourseChangeBasedTrackApproximation(trackCopy, sampleCompetitor.getBoat().getBoatClass(), /* logFixes */ true);
87
+ final CourseChangeBasedTrackApproximation lateInitApproximation = new CourseChangeBasedTrackApproximation(
88
+ trackCopy, sampleCompetitor.getBoat().getBoatClass(), /* logFixes for debugging */ false);
87 89
assertEquals(earlyInitApproximation.getNumberOfFixesAdded(), lateInitApproximation.getNumberOfFixesAdded(), "Number of fixes added to approximators differs");
88 90
final Iterable<GPSFixMoving> earlyInitResult = earlyInitApproximation.approximate(from, to);
89 91
final Iterable<GPSFixMoving> lateInitResult = lateInitApproximation.approximate(from, to);
java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/ManeuverLossOnPenaltyCircleTest.java
... ...
@@ -54,7 +54,7 @@ public class ManeuverLossOnPenaltyCircleTest extends OnlineTracTracBasedTest {
54 54
Competitor canottieri = getCompetitorByName("Club Canottieri Roggero di Lauria");
55 55
final Iterable<Maneuver> maneuversCanottieri = getTrackedRace().getManeuvers(canottieri, getTrackedRace().getStartOfRace(), getTrackedRace().getEndOfRace(), /* waitForLatest */ true);
56 56
final Optional<Maneuver> penaltyCircleCanottieri = StreamSupport.stream(maneuversCanottieri.spliterator(), /* parallel */ false).filter(m->m.getType()==ManeuverType.PENALTY_CIRCLE).findAny();
57
- assertThat("Maneuver loss of "+penaltyCircleCanottieri.get()+" too small", penaltyCircleCanottieri.get().getManeuverLoss().getProjectedDistanceLost(), greaterThan(new MeterDistance(30)));
58
- logger.info("Maneuver loss of "+penaltyCircleCanottieri.get()+" was greater than 30m. Good.");
57
+ assertThat("Maneuver loss of "+penaltyCircleCanottieri.get()+" too small", penaltyCircleCanottieri.get().getManeuverLoss().getProjectedDistanceLost(), greaterThan(new MeterDistance(12)));
58
+ logger.info("Maneuver loss of "+penaltyCircleCanottieri.get()+" was greater than 12m. Good.");
59 59
}
60 60
}
java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/CourseChangeBasedTrackApproximation.java
... ...
@@ -188,7 +188,8 @@ public class CourseChangeBasedTrackApproximation implements Serializable, GPSTra
188 188
GPSFixMoving add(GPSFixMoving next) {
189 189
insertIntoQueueSortedByTime(next);
190 190
final GPSFixMoving first = queueOfNewFixes.getFirst();
191
- final GPSFixMoving result = first.getTimePoint().until(next.getTimePoint()).asMillis() > track.getMillisecondsOverWhichToAverageSpeed()/2
191
+ // getMillisecondsOverWhichToAverageSpeed() is the duration in both directions that fixes are considered for validity / outlier decisions.
192
+ final GPSFixMoving result = first.getTimePoint().until(next.getTimePoint()).asMillis() > track.getMillisecondsOverWhichToAverageSpeed()
192 193
? addOldEnoughFix(queueOfNewFixes.removeFirst())
193 194
: null;
194 195
return result;
... ...
@@ -244,10 +245,20 @@ public class CourseChangeBasedTrackApproximation implements Serializable, GPSTra
244 245
private GPSFixMoving addOldEnoughFix(GPSFixMoving next) {
245 246
assert window.isEmpty() || !next.getTimePoint().before(window.peekFirst().getTimePoint());
246 247
final GPSFixMoving result;
247
- final boolean validityCached = next.isValidityCached();
248
- final boolean validity = validityCached ? next.isValidCached() : track.isValid(next);
249 248
final SpeedWithBearing nextSpeed = next.isEstimatedSpeedCached() ? next.getCachedEstimatedSpeed() : track.getEstimatedSpeed(next.getTimePoint());
250 249
if (logFixes) {
250
+ final boolean validityCached = next.isValidityCached();
251
+ final boolean validity;
252
+ if (validityCached) {
253
+ validity = next.isValidCached();
254
+ } else {
255
+ track.lockForRead();
256
+ try {
257
+ validity = track.isValid(next);
258
+ } finally {
259
+ track.unlockAfterRead();
260
+ }
261
+ }
251 262
// CSV logging: approxId, fixIndex, fixTimeMillis, validityCached, speedCached, COG, SOG
252 263
System.out.println(System.identityHashCode(this) + "," + next.getTimePoint().asMillis() + ","
253 264
+ next.isValidityCached() + "," + next.isEstimatedSpeedCached() + ","
java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/GPSFixTrackImpl.java
... ...
@@ -619,7 +619,7 @@ public abstract class GPSFixTrackImpl<ItemType, FixType extends GPSFix> extends
619 619
@Override
620 620
public SpeedWithBearing getEstimatedSpeed(TimePoint at) {
621 621
lockForRead();
622
- FixType ceil = getInternalFixes().ceiling(createDummyGPSFix(at));
622
+ FixType ceil = getInternalFixes().ceiling(createDummyGPSFix(at)); // TODO bug6209: if "at" is the time point of an outlier, ceil would be the first valid fix *after* the outlier! We shouldn't be updating the fix at "at" but some later valid fix which, if asked at its timepoint, may have computed a different estimation altogether
623 623
try {
624 624
final SpeedWithBearing result;
625 625
if (ceil != null && ceil.getTimePoint().equals(at) && ceil.isEstimatedSpeedCached()) {