added a failing test case for order-dependent extreme bearings bug

This commit is contained in:
Axel Uhl
2012-03-13 18:04:56 +01:00
parent 11163863d7
commit 05bac12203
6 changed files with 86 additions and 7 deletions
@@ -16,5 +16,5 @@
<stringAttribute key="org.eclipse.jdt.junit.TEST_KIND" value="org.eclipse.jdt.junit.loader.junit4"/>
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value=""/>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.sap.sailing.domain.test"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Dhttp.proxyHost=proxy -Dhttp.proxyPort=8080 -XX:+UseParallelGC -Dtractrac.tunnel=true -Dtractrac.tunnel.host=10.18.206.73 -ea"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Dhttp.proxyHost=proxy -Dhttp.proxyPort=8080 -XX:+UseParallelGC -Dtractrac.tunnel=true -Dtractrac.tunnel.host=10.18.206.73 -ea -Djava.util.logging.config.file=${project_loc:com.sap.sailing.server}/../target/configuration/logging_debug.properties"/>
</launchConfiguration>
@@ -11,7 +11,9 @@ import java.util.Set;
import org.junit.Test;
import com.sap.sailing.domain.base.BearingWithConfidence;
import com.sap.sailing.domain.base.PositionWithConfidence;
import com.sap.sailing.domain.base.impl.BearingWithConfidenceImpl;
import com.sap.sailing.domain.base.impl.KnotSpeedWithBearingImpl;
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
import com.sap.sailing.domain.base.impl.PositionWithConfidenceImpl;
@@ -32,6 +34,7 @@ import com.sap.sailing.domain.confidence.Weigher;
import com.sap.sailing.domain.confidence.impl.ScalableDoubleWithConfidence;
import com.sap.sailing.domain.tracking.Wind;
import com.sap.sailing.domain.tracking.WindWithConfidence;
import com.sap.sailing.domain.tracking.impl.BearingWithConfidenceCluster;
import com.sap.sailing.domain.tracking.impl.ScalableWind;
import com.sap.sailing.domain.tracking.impl.WindImpl;
import com.sap.sailing.domain.tracking.impl.WindWithConfidenceImpl;
@@ -115,6 +118,64 @@ public class ConfidenceTest {
}
}
@Test
public void testBearingClusterSplittingWithDifferentBearingsOrdering() {
TimePoint timePoint = new MillisecondsTimePoint(1308839544250l);
BearingWithConfidenceCluster<TimePoint> clusterA = new BearingWithConfidenceCluster<TimePoint>(ConfidenceFactory.INSTANCE.createExponentialTimeDifferenceWeigher(
// use a minimum confidence to avoid the bearing to flip to 270deg in case all is zero
/* milliseconds over which to average */ 30000l, /* minimum confidence */ 0.0000000001));
for (String a : new String[] {
"87.0@0.3561978879735175",
"286.8716453147824@0.7507926558478147",
"282.55627120464703@0.7643492902545556",
"286.8605698949788@0.7483842322506868",
"291.5836361697427@0.7491852169449421",
"297.0631828865192@0.7488453128197485",
"283.6400613098378@0.7488453128197485",
"279.95201024864554@0.7298408190555351",
"279.77216720379766@0.7283443881177472",
"283.75770067567913@0.7491852169449421",
"284.30394138063696@0.7488453128197485",
"285.5253164529858@0.7491852169449421"
}) {
BearingWithConfidence<TimePoint> bearingWithConfidence = parseBearingWithConfidence(a);
clusterA.add(bearingWithConfidence);
}
BearingWithConfidenceCluster<TimePoint>[] splitResultA = clusterA.splitInTwo(45.0, timePoint);
BearingWithConfidenceCluster<TimePoint> clusterB = new BearingWithConfidenceCluster<TimePoint>(ConfidenceFactory.INSTANCE.createExponentialTimeDifferenceWeigher(
// use a minimum confidence to avoid the bearing to flip to 270deg in case all is zero
/* milliseconds over which to average */ 30000l, /* minimum confidence */ 0.0000000001));
for (String b : new String[] {
"282.55627120464703@0.7643492902545556",
"286.8716453147824@0.7507926558478147",
"286.8605698949788@0.7483842322506868",
"285.5253164529858@0.7491852169449421",
"283.75770067567913@0.7491852169449421",
"283.6400613098378@0.7488453128197485",
"279.95201024864554@0.7298408190555351",
"291.5836361697427@0.7491852169449421",
"297.0631828865192@0.7488453128197485",
"279.77216720379766@0.7283443881177472",
"284.30394138063696@0.7488453128197485",
"87.0@0.3561978879735175"
}) {
BearingWithConfidence<TimePoint> bearingWithConfidence = parseBearingWithConfidence(b);
clusterB.add(bearingWithConfidence);
}
BearingWithConfidenceCluster<TimePoint>[] splitResultB = clusterB.splitInTwo(45.0, timePoint);
assertEquals(11, splitResultA[0].size());
assertEquals(1, splitResultA[1].size());
assertEquals(11, splitResultB[0].size());
assertEquals(1, splitResultB[1].size());
}
private BearingWithConfidence<TimePoint> parseBearingWithConfidence(String a) {
String[] bearingAndConfidence = a.split("@");
double degBearing = Double.valueOf(bearingAndConfidence[0]);
double confidence = Double.valueOf(bearingAndConfidence[1]);
return new BearingWithConfidenceImpl<TimePoint>(new DegreeBearingImpl(degBearing), confidence, new MillisecondsTimePoint(1308839544250l));
}
@Test
public void testLinearWeigherHalfTime() {
Weigher<TimePoint> w = ConfidenceFactory.INSTANCE.createHyperbolicTimeDifferenceWeigher(1000);
@@ -1,5 +1,7 @@
package com.sap.sailing.domain.confidence.impl;
import java.util.logging.Logger;
import com.sap.sailing.domain.base.impl.HasConfidenceImpl;
import com.sap.sailing.domain.common.impl.Util;
import com.sap.sailing.domain.confidence.ConfidenceBasedAverager;
@@ -32,6 +34,8 @@ import com.sap.sailing.domain.confidence.Weigher;
* @author Axel Uhl (d043530)
*/
public class ConfidenceBasedAveragerImpl<ValueType, BaseType, RelativeTo> implements ConfidenceBasedAverager<ValueType, BaseType, RelativeTo> {
private static final Logger logger = Logger.getLogger(ConfidenceBasedAverager.class.getName());
private final Weigher<RelativeTo> weigher;
/**
@@ -47,6 +51,9 @@ public class ConfidenceBasedAveragerImpl<ValueType, BaseType, RelativeTo> implem
public HasConfidence<ValueType, BaseType, RelativeTo> getAverage(
Iterable<? extends HasConfidenceAndIsScalable<ValueType, BaseType, RelativeTo>> values, RelativeTo at) {
if (values == null || Util.isEmpty(values)) {
logger.finest("empty collection to average: "+values);
// FIXME remove again when debugging is done
new RuntimeException("empty collection to average: "+values).printStackTrace();
return null;
} else {
ScalableValue<ValueType, BaseType> numerator = null;
@@ -3,6 +3,7 @@ package com.sap.sailing.domain.tracking.impl;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.logging.Logger;
import com.sap.sailing.domain.base.BearingWithConfidence;
import com.sap.sailing.domain.base.impl.BearingWithConfidenceImpl;
@@ -27,6 +28,7 @@ import com.sap.sailing.domain.confidence.Weigher;
*
*/
public class BearingWithConfidenceCluster<RelativeTo> {
private final static Logger logger = Logger.getLogger(BearingWithConfidenceCluster.class.getName());
private final List<BearingWithConfidence<RelativeTo>> bearings;
private final Weigher<RelativeTo> weigher;
@@ -80,6 +82,9 @@ public class BearingWithConfidenceCluster<RelativeTo> {
}
}
}
// FIXME remove once debugging is done
logger.finest("extremeBearings: "+extremeBearings);
logger.finest("result[0]: "+result[0]+", result[1]: "+result[1]);
} else if (!bearings.isEmpty()) {
// add the only bearing to the first of the two resulting clusters
result[0].add(bearings.get(0));
@@ -792,7 +792,7 @@ public abstract class TrackedRaceImpl implements TrackedRace, CourseListener {
DummyMarkPassingWithTimePointOnly dummyMarkPassingForNow = new DummyMarkPassingWithTimePointOnly(timePoint);
Weigher<TimePoint> weigher = ConfidenceFactory.INSTANCE.createExponentialTimeDifferenceWeigher(
// use a minimum confidence to avoid the bearing to flip to 270deg in case all is zero
getMillisecondsOverWhichToAverageSpeed());
getMillisecondsOverWhichToAverageSpeed(), /* minimum confidence */ 0.0000000001);
Map<LegType, BearingWithConfidenceCluster<TimePoint>> bearings = clusterBearingsByLegType(timePoint, position,
dummyMarkPassingForNow, weigher);
// use the minimum confidence of the four "quadrants" as the result's confidence
@@ -802,8 +802,10 @@ public abstract class TrackedRaceImpl implements TrackedRace, CourseListener {
int numberOfBoatsRelevantForEstimate = 0;
BearingWithConfidence<TimePoint> resultBearing = null;
if (bearings != null) {
logger.finest("UPWIND cluster size: "+bearings.get(LegType.UPWIND).size());
BearingWithConfidenceCluster<TimePoint>[] bearingClustersUpwind = bearings.get(LegType.UPWIND).splitInTwo(
getMinimumAngleBetweenDifferentTacksUpwind(), timePoint);
logger.finest("UPWIND cluster split result sizes: "+bearingClustersUpwind[0].size()+"/"+bearingClustersUpwind[1].size());
if (!bearingClustersUpwind[0].isEmpty() && !bearingClustersUpwind[1].isEmpty()) {
BearingWithConfidence<TimePoint> average0 = bearingClustersUpwind[0].getAverage(timePoint);
BearingWithConfidence<TimePoint> average1 = bearingClustersUpwind[1].getAverage(timePoint);
@@ -816,8 +818,10 @@ public abstract class TrackedRaceImpl implements TrackedRace, CourseListener {
}
BearingWithConfidenceImpl<TimePoint> downwindAverage = null;
int downwindNumberOfRelevantBoats = 0;
logger.finest("DOWNWIND cluster size: "+bearings.get(LegType.DOWNWIND).size());
BearingWithConfidenceCluster<TimePoint>[] bearingClustersDownwind = bearings.get(LegType.DOWNWIND)
.splitInTwo(getMinimumAngleBetweenDifferentTacksDownwind(), timePoint);
logger.finest("DOWNWIND cluster split result sizes: "+bearingClustersDownwind[0].size()+"/"+bearingClustersDownwind[1].size());
if (!bearingClustersDownwind[0].isEmpty() && !bearingClustersDownwind[1].isEmpty()) {
BearingWithConfidence<TimePoint> average0 = bearingClustersDownwind[0].getAverage(timePoint);
BearingWithConfidence<TimePoint> average1 = bearingClustersDownwind[1].getAverage(timePoint);
@@ -840,6 +844,9 @@ public abstract class TrackedRaceImpl implements TrackedRace, CourseListener {
resultCluster.add(downwindAverage);
}
resultBearing = resultCluster.getAverage(timePoint);
if (resultBearing == null) {
logger.finer("resultBearing == null");
}
}
return resultBearing == null ? null : new WindImpl(null, timePoint, new KnotSpeedWithBearingImpl(
/* speedInKnots */numberOfBoatsRelevantForEstimate, resultBearing.getObject()));
@@ -235,18 +235,17 @@ public class WindTrackImpl extends TrackImpl<Wind> implements WindTrack {
return null;
} else {
BearingWithConfidence<TimePoint> average = bearingCluster.getAverage(at);
Position resultPosition;
if(p == null) {
if (p == null) {
HasConfidence<ScalablePosition, Position, TimePoint> averagePos = positionAverager.getAverage(positionsToAverage, at);
if(averagePos != null)
if (averagePos != null) {
resultPosition = averagePos.getObject();
else
} else {
resultPosition = null;
}
} else {
resultPosition = p;
}
// Position resultPosition = p == null ? positionAverager.getAverage(positionsToAverage, at).getObject() : p;
SpeedWithBearing avgWindSpeed = new KnotSpeedWithBearingImpl(knotSum / count, average == null ? null : average.getObject());
return new WindWithConfidenceImpl<Pair<Position,TimePoint>>(new WindImpl(resultPosition, at, avgWindSpeed), average.getConfidence(),
new Pair<Position, TimePoint>(p, at), useSpeed);