mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-09-28 08:26:44 +00:00
added failing test case for averaging a single wind fix with useSpeed=false
This commit is contained in:
@@ -162,6 +162,22 @@ public class ConfidenceTest {
|
||||
assertEquals(135, average.getObject().getBearing().getDegrees(), 0.00000001);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAveragingOneWindWithUseSpeedFalse() {
|
||||
WindWithConfidence<TimePoint> d1 = new WindWithConfidenceImpl<TimePoint>(new WindImpl(new DegreePosition(1, 0),
|
||||
new MillisecondsTimePoint(20), new KnotSpeedWithBearingImpl(10, new DegreeBearingImpl(180))), /* confidence */
|
||||
0.5, /* relativeTo */new MillisecondsTimePoint(20), /* useSpeed */ false);
|
||||
ConfidenceBasedAverager<ScalableWind, Wind, TimePoint> averager = ConfidenceFactory.INSTANCE
|
||||
.createAverager(ConfidenceFactory.INSTANCE.createHyperbolicTimeDifferenceWeigher(1000));
|
||||
List<WindWithConfidence<TimePoint>> list = Arrays.asList(d1);
|
||||
HasConfidence<ScalableWind, Wind, TimePoint> average = averager.getAverage(list, new MillisecondsTimePoint(20));
|
||||
assertEquals(1.0, average.getObject().getPosition().getLatDeg(), 0.00000001);
|
||||
assertEquals(0.0, average.getObject().getPosition().getLngDeg(), 0.00000001);
|
||||
assertEquals(20, average.getObject().getTimePoint().asMillis());
|
||||
assertEquals(10, average.getObject().getKnots(), 0.00000001);
|
||||
assertEquals(180, average.getObject().getBearing().getDegrees(), 0.00000001);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAveragingWithFourWindsTwoOfWhichHaveUseSpeedFalse() {
|
||||
WindWithConfidence<TimePoint> d1 = new WindWithConfidenceImpl<TimePoint>(new WindImpl(new DegreePosition(1, 0),
|
||||
|
||||
+30
-5
@@ -4,6 +4,7 @@ import com.sap.sailing.domain.base.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.base.impl.ScalablePosition;
|
||||
import com.sap.sailing.domain.base.impl.ScalableSpeedWithBearing;
|
||||
import com.sap.sailing.domain.common.Bearing;
|
||||
import com.sap.sailing.domain.confidence.ScalableValue;
|
||||
import com.sap.sailing.domain.tracking.Wind;
|
||||
|
||||
@@ -19,32 +20,50 @@ public class ScalableWind implements ScalableValue<ScalableWind, Wind> {
|
||||
private final double scaledTimePointSumInMilliseconds;
|
||||
private final ScalableSpeedWithBearing scalableSpeedWithBearing;
|
||||
|
||||
/**
|
||||
* Speeds are combined separately from the other values. A {@link ScalableWind} may use its {@link #useSpeed} flag
|
||||
* to keep its speed value from being considered during addition with other values that do use their speed. For this
|
||||
* case, the confidence sum for the speed needs to be passed along so that during {@link #divide(double)} the speed
|
||||
* can be divided by a different divisor. Must be 0.0 in case {@link #useSpeed} is <code>false</code>.
|
||||
*/
|
||||
private final double speedConfidenceSum;
|
||||
|
||||
/**
|
||||
* if <code>false</code>, the {@link ScalableSpeedWithBearing}'s speed is ignored during an {@link #add(ScalableValue)} operation
|
||||
* with another {@link ScalableWind} object for which {@link #useSpeed} is <code>true</code>.
|
||||
*/
|
||||
private final boolean useSpeed;
|
||||
|
||||
public ScalableWind(Wind wind, boolean useSpeed) {
|
||||
/**
|
||||
* @param speedConfidenceSum must be <code>0.0</code> if <code>useSpeed==false</code>
|
||||
*/
|
||||
public ScalableWind(Wind wind, boolean useSpeed, double speedConfidenceSum) {
|
||||
assert useSpeed || speedConfidenceSum==0.0;
|
||||
this.scalablePosition = wind.getPosition() == null ? null : new ScalablePosition(wind.getPosition());
|
||||
this.scaledTimePointSumInMilliseconds = wind.getTimePoint().asMillis();
|
||||
this.scalableSpeedWithBearing = new ScalableSpeedWithBearing(wind);
|
||||
this.useSpeed = useSpeed;
|
||||
this.speedConfidenceSum = speedConfidenceSum;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param speedConfidenceSum must be <code>0.0</code> if <code>useSpeed==false</code>
|
||||
*/
|
||||
private ScalableWind(ScalablePosition scalablePosition, double scaledTimePointSumInMilliseconds,
|
||||
ScalableSpeedWithBearing scalableSpeedWithBearing, boolean useSpeed) {
|
||||
ScalableSpeedWithBearing scalableSpeedWithBearing, boolean useSpeed, double speedConfidenceSum) {
|
||||
super();
|
||||
assert useSpeed || speedConfidenceSum==0.0;
|
||||
this.scalablePosition = scalablePosition;
|
||||
this.scaledTimePointSumInMilliseconds = scaledTimePointSumInMilliseconds;
|
||||
this.scalableSpeedWithBearing = scalableSpeedWithBearing;
|
||||
this.useSpeed = useSpeed;
|
||||
this.speedConfidenceSum = speedConfidenceSum;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScalableWind multiply(double factor) {
|
||||
return new ScalableWind(scalablePosition == null ? null : scalablePosition.multiply(factor),
|
||||
factor * scaledTimePointSumInMilliseconds, scalableSpeedWithBearing.multiply(factor), useSpeed);
|
||||
factor * scaledTimePointSumInMilliseconds, scalableSpeedWithBearing.multiply(factor), useSpeed, factor*speedConfidenceSum);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -57,6 +76,7 @@ public class ScalableWind implements ScalableValue<ScalableWind, Wind> {
|
||||
public ScalableWind add(ScalableValue<ScalableWind, Wind> t) {
|
||||
ScalableSpeedWithBearing thisSSWB;
|
||||
ScalableSpeedWithBearing tSSWB;
|
||||
double newSpeedConfidenceSum = useSpeed ? speedConfidenceSum : 0.0;
|
||||
if (this.useSpeed || (t instanceof ScalableWind && !((ScalableWind) t).useSpeed)) {
|
||||
thisSSWB = this.scalableSpeedWithBearing;
|
||||
} else {
|
||||
@@ -64,6 +84,7 @@ public class ScalableWind implements ScalableValue<ScalableWind, Wind> {
|
||||
thisSSWB = new ScalableSpeedWithBearing(new KnotSpeedWithBearingImpl(/* wind "is a" speed */ t.getValue().divide(1.0).getKnots(),
|
||||
this.scalableSpeedWithBearing.divide(1.0).getBearing()));
|
||||
}
|
||||
newSpeedConfidenceSum += (t instanceof ScalableWind && ((ScalableWind) t).useSpeed) ? ((ScalableWind) t).speedConfidenceSum : 0.0;
|
||||
if (t instanceof ScalableWind && ((ScalableWind) t).useSpeed || !this.useSpeed) {
|
||||
tSSWB = ((ScalableWind) t).scalableSpeedWithBearing;
|
||||
} else {
|
||||
@@ -73,13 +94,17 @@ public class ScalableWind implements ScalableValue<ScalableWind, Wind> {
|
||||
}
|
||||
return new ScalableWind(scalablePosition == null ? t.getValue().scalablePosition : scalablePosition.add(t.getValue().scalablePosition),
|
||||
scaledTimePointSumInMilliseconds+t.getValue().scaledTimePointSumInMilliseconds,
|
||||
thisSSWB.add(tSSWB), useSpeed || (t instanceof ScalableWind) && ((ScalableWind) t).useSpeed);
|
||||
thisSSWB.add(tSSWB), useSpeed || (t instanceof ScalableWind) && ((ScalableWind) t).useSpeed, newSpeedConfidenceSum);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Wind divide(double divisor) {
|
||||
// TODO this is ugly; if we need to keep the confidence sum for speed in the scalable object, we should also keep the confidence sum for all other values in the scalable value
|
||||
Bearing resultBearing = scalableSpeedWithBearing.divide(divisor).getBearing();
|
||||
double resultSpeedInKnots = scalableSpeedWithBearing.divide(1.0).getKnots() / speedConfidenceSum;
|
||||
return new WindImpl(scalablePosition == null ? null : scalablePosition.divide(divisor), new MillisecondsTimePoint(
|
||||
(long) (scaledTimePointSumInMilliseconds / divisor)), scalableSpeedWithBearing.divide(divisor));
|
||||
(long) (scaledTimePointSumInMilliseconds / divisor)),
|
||||
new KnotSpeedWithBearingImpl(resultSpeedInKnots, resultBearing));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ public class WindWithConfidenceImpl<RelativeTo> extends HasConfidenceImpl<Scalab
|
||||
|
||||
@Override
|
||||
public ScalableWind getScalableValue() {
|
||||
return new ScalableWind(getObject(), useSpeed);
|
||||
return new ScalableWind(getObject(), useSpeed, /* speedConfidenceSum */ useSpeed?1.0:0.0);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
-1
@@ -917,7 +917,6 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
||||
*/
|
||||
protected GPSFixDTO getBoatFix(CompetitorDTO competitorDTO) {
|
||||
return fixes.containsKey(competitorDTO) ? fixes.get(competitorDTO).get(lastShownFix.get(competitorDTO)) : null;
|
||||
return competitorFixes == null ? null : competitorFixes.get(lastShownFix.get(competitorDTO));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user