494c464a8848e4b2f19b0279fb44ab29f9af8ccc
java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/CourseChangeBasedTrackApproximation.java
| ... | ... | @@ -85,13 +85,15 @@ public class CourseChangeBasedTrackApproximation implements Serializable, GPSTra |
| 85 | 85 | * We need to remember the speed / bearing as we saw them when we inserted the fixes into the {@link #window} |
| 86 | 86 | * collection. Based on more fixes getting added to the track, things may change. In particular, fixes that may have |
| 87 | 87 | * had a valid speed when inserted may later have their cached speed/bearing invalidated, and computing it again |
| 88 | - * from the track may then yield {@code null}. |
|
| 88 | + * from the track may then yield {@code null}.<p> |
|
| 89 | + * |
|
| 90 | + * TODO bug6209: the above observation regarding changes when later fixes get added is exactly what is causing the bug6209 issues! |
|
| 89 | 91 | */ |
| 90 | 92 | private final LinkedList<SpeedWithBearing> speedForFixesInWindow; |
| 91 | 93 | |
| 92 | 94 | /** |
| 93 | 95 | * one shorter than "window"; {@link #totalCourseChangeFromBeginningOfWindow}{@code [i]} is from |
| 94 | - * {@link #window}{@code [i]} to {@link #window}{@code [i+1]} |
|
| 96 | + * {@link #window}{@code [0]} to {@link #window}{@code [i+1]} |
|
| 95 | 97 | */ |
| 96 | 98 | private final List<Double> totalCourseChangeFromBeginningOfWindow; |
| 97 | 99 | |
| ... | ... | @@ -154,8 +156,9 @@ public class CourseChangeBasedTrackApproximation implements Serializable, GPSTra |
| 154 | 156 | GPSFixMoving add(GPSFixMoving next) { |
| 155 | 157 | assert window.isEmpty() || !next.getTimePoint().before(window.peekFirst().getTimePoint()); |
| 156 | 158 | final GPSFixMoving result; |
| 157 | - final SpeedWithBearing nextSpeed = next.isEstimatedSpeedCached() ? next.getCachedEstimatedSpeed() : track.getEstimatedSpeed(next.getTimePoint()); |
|
| 158 | - if (nextSpeed != null) { |
|
| 159 | + final SpeedWithBearing nextSpeed = /* TODO this was the original code that can depend on fixes newer than next: next.isEstimatedSpeedCached() ? next.getCachedEstimatedSpeed() : track.getEstimatedSpeed(next.getTimePoint()) */ |
|
| 160 | + next.getSpeed(); int TODO; // TODO bug6209: try without dependency on newer fixes and see if it helps produce equal results for early/late initialization |
|
| 161 | + if (nextSpeed != null) { // TODO bug6209: this gets messy... if we drop a fix because no estimated speed can be determined for it, and later fix additions may change this, where would we get this fix from again? |
|
| 159 | 162 | numberOfFixesAdded++; |
| 160 | 163 | int insertPosition = window.size(); |
| 161 | 164 | GPSFixMoving previous; |
| ... | ... | @@ -179,18 +182,20 @@ public class CourseChangeBasedTrackApproximation implements Serializable, GPSTra |
| 179 | 182 | // rather expensive ceil/floor search on the track; resort to track.getEstimatedSpeed if not cached |
| 180 | 183 | assert previousSpeed != null; // we wouldn't have added the fix in the previous run if it hadn't had a valid speed |
| 181 | 184 | final double courseChangeBetweenPreviousAndNextInDegrees = previousSpeed.getBearing().getDifferenceTo(nextSpeed.getBearing()).getDegrees(); |
| 182 | - windowDuration = windowDuration.plus(previous.getTimePoint().until(next.getTimePoint())); |
|
| 185 | + if (insertPosition == window.size()-1) { // if not appended to the end, the window duration won't change |
|
| 186 | + windowDuration = windowDuration.plus(previous.getTimePoint().until(next.getTimePoint())); |
|
| 187 | + } |
|
| 183 | 188 | if (totalCourseChangeFromBeginningOfWindow.isEmpty()) { |
| 184 | 189 | totalCourseChangeFromBeginningOfWindow.add(courseChangeBetweenPreviousAndNextInDegrees); |
| 185 | 190 | absoluteMaximumTotalCourseChangeFromBeginningOfWindowInDegrees = Math.abs(courseChangeBetweenPreviousAndNextInDegrees); |
| 186 | 191 | indexOfMaximumTotalCourseChange = 0; |
| 187 | 192 | } else { |
| 188 | - final double totalCourseChangeFromBeginningOfWindowForCurrentFix = totalCourseChangeFromBeginningOfWindow.get(totalCourseChangeFromBeginningOfWindow.size()-1) |
|
| 193 | + final double totalCourseChangeFromBeginningOfWindowForCurrentFix = totalCourseChangeFromBeginningOfWindow.get(insertPosition-2) |
|
| 189 | 194 | + courseChangeBetweenPreviousAndNextInDegrees; |
| 190 | - totalCourseChangeFromBeginningOfWindow.add(totalCourseChangeFromBeginningOfWindowForCurrentFix); |
|
| 195 | + totalCourseChangeFromBeginningOfWindow.add(insertPosition-1, totalCourseChangeFromBeginningOfWindowForCurrentFix); |
|
| 191 | 196 | if (Math.abs(totalCourseChangeFromBeginningOfWindowForCurrentFix) > absoluteMaximumTotalCourseChangeFromBeginningOfWindowInDegrees) { |
| 192 | 197 | absoluteMaximumTotalCourseChangeFromBeginningOfWindowInDegrees = Math.abs(totalCourseChangeFromBeginningOfWindowForCurrentFix); |
| 193 | - indexOfMaximumTotalCourseChange = totalCourseChangeFromBeginningOfWindow.size()-1; |
|
| 198 | + indexOfMaximumTotalCourseChange = insertPosition-1; |
|
| 194 | 199 | } |
| 195 | 200 | } |
| 196 | 201 | if (windowDuration.compareTo(getMaximumWindowLength()) > 0) { |
java/com.sap.sailing.windestimation.test/src/com/sap/sailing/windestimation/integration/IncrementalMstHmmWindEstimationForTrackedRaceTest.java
| ... | ... | @@ -124,19 +124,23 @@ public class IncrementalMstHmmWindEstimationForTrackedRaceTest extends OnlineTra |
| 124 | 124 | new URL("file:///" + new File("resources/event_20110609_KielerWoch-505_Race_2.txt").getCanonicalPath()), |
| 125 | 125 | /* liveUri */ null, /* storedUri */ storedUri, |
| 126 | 126 | new ReceiverType[] { ReceiverType.MARKPASSINGS, ReceiverType.RACECOURSE, ReceiverType.RAWPOSITIONS, ReceiverType.MARKPOSITIONS }); |
| 127 | - final MillisecondsTimePoint timePointForFixes = new MillisecondsTimePoint(new GregorianCalendar(2011, 05, 23, 10, 00).getTime()); |
|
| 127 | + final GregorianCalendar cal = new GregorianCalendar(2011, 05, 23, 13, 40); |
|
| 128 | + cal.setTimeZone(TimeZone.getTimeZone("UTC")); |
|
| 129 | + final MillisecondsTimePoint timePointForFixes = new MillisecondsTimePoint(cal.getTime()); |
|
| 128 | 130 | final WindSourceWithAdditionalID testWindSource = new WindSourceWithAdditionalID(WindSourceType.EXPEDITION, "Test"); |
| 129 | 131 | getTrackedRace().getOrCreateWindTrack(testWindSource).add( |
| 130 | 132 | new WindImpl(new DegreePosition(54.48448470246412, 10.185846456327479), |
| 131 | - timePointForFixes, new KnotSpeedWithBearingImpl(12.5, /* to */ new DegreeBearingImpl(60)))); |
|
| 132 | - final MillisecondsTimePoint timePointForFixes2 = new MillisecondsTimePoint(new GregorianCalendar(2011, 05, 23, 10, 30).getTime()); |
|
| 133 | + timePointForFixes, new KnotSpeedWithBearingImpl(9, /* to */ new DegreeBearingImpl(51)))); |
|
| 134 | + cal.set(2011, 05, 23, 14, 6); |
|
| 135 | + final MillisecondsTimePoint timePointForFixes2 = new MillisecondsTimePoint(cal.getTime()); |
|
| 133 | 136 | getTrackedRace().getOrCreateWindTrack(testWindSource).add( |
| 134 | 137 | new WindImpl(new DegreePosition(54.48448470246412, 10.185846456327479), |
| 135 | - timePointForFixes2, new KnotSpeedWithBearingImpl(11.5, /* to */ new DegreeBearingImpl(58)))); |
|
| 136 | - final MillisecondsTimePoint timePointForFixes3 = new MillisecondsTimePoint(new GregorianCalendar(2011, 05, 23, 10, 45).getTime()); |
|
| 138 | + timePointForFixes2, new KnotSpeedWithBearingImpl(11, /* to */ new DegreeBearingImpl(60)))); |
|
| 139 | + cal.set(2011, 05, 23, 14, 35); |
|
| 140 | + final MillisecondsTimePoint timePointForFixes3 = new MillisecondsTimePoint(cal.getTime()); |
|
| 137 | 141 | getTrackedRace().getOrCreateWindTrack(testWindSource).add( |
| 138 | 142 | new WindImpl(new DegreePosition(54.4844847, 10.1858464), |
| 139 | - timePointForFixes3, new KnotSpeedWithBearingImpl(12.1, /* to */ new DegreeBearingImpl(59)))); |
|
| 143 | + timePointForFixes3, new KnotSpeedWithBearingImpl(14, /* to */ new DegreeBearingImpl(58)))); |
|
| 140 | 144 | final PolarDataServiceImpl polarDataService = new PolarDataServiceImpl(); |
| 141 | 145 | getTrackedRace().setPolarDataService(polarDataService); |
| 142 | 146 | polarDataService.insertExistingFixes(getTrackedRace()); |