added null-safety to BearingWithConfidenceCluster clients

This commit is contained in:
Axel Uhl committed 2012-02-01 10:34:27 +01:00
1 parent 3e7b09021d
commit bc3742b747
8 files changed
+36 -10

No files matched your search

@@ -6,5 +6,4 @@ import com.sap.sailing.domain.confidence.HasConfidenceAndIsScalable;
public interface BearingWithConfidence<RelativeTo> extends HasConfidenceAndIsScalable<Pair<Double, Double>, Bearing, RelativeTo> {
Bearing getObject();
}
@@ -2,9 +2,15 @@ package com.sap.sailing.domain.confidence;
public interface ConfidenceBasedAverager<ValueType, BaseType, RelativeTo> {
/**
* If a non-<code>null</code> weigher has been set for this averager, <code>at</code> must be a valid
* reference point to which the weigher will determine the difference and from it the confidence for each
* of the <code>values</code>. Otherwise, the <code>at</code> argument is ignored.
* If a non-<code>null</code> weigher has been set for this averager, <code>at</code> must be a valid reference
* point to which the weigher will determine the difference and from it the confidence for each of the
* <code>values</code>. Otherwise, the <code>at</code> argument is ignored.
*
* @return <code>null</code> if <code>values==null</code> or <code>values</code> is empty; otherwise, a non-
* <code>null</code> average with confidence is returned. Note, however, that the
* {@link HasConfidence#getObject() object} in the {@link HasConfidence} result may be <code>null</code>,
* e.g., if the combined confidence went to 0.0 and the averager was unable to determine a reasonable
* average value.
*/
HasConfidence<ValueType, BaseType, RelativeTo> getAverage(
Iterable<? extends HasConfidenceAndIsScalable<ValueType, BaseType, RelativeTo>> values, RelativeTo at);
@@ -12,6 +12,7 @@ public interface ConfidenceFactory {
*/
<ValueType, BaseType, RelativeTo> ConfidenceBasedAverager<ValueType, BaseType, RelativeTo> createAverager(Weigher<RelativeTo> weigher);
<RelativeTo> Weigher<RelativeTo> createConstantWeigher(double constantConfidence);
/**
* Creates a weigher for time points. With increasing time difference the weight/confidence decreases exponentially.
* It is halved every <code>halfConfidenceAfterMilliseconds</code> milliseconds.
@@ -6,6 +6,16 @@ import com.sap.sailing.domain.confidence.ConfidenceFactory;
import com.sap.sailing.domain.confidence.Weigher;
public class ConfidenceBasedAveragerFactoryImpl implements ConfidenceFactory {
@Override
public <RelativeTo> Weigher<RelativeTo> createConstantWeigher(final double constantConfidence) {
return new Weigher<RelativeTo>() {
@Override
public double getConfidence(RelativeTo fix, RelativeTo request) {
return constantConfidence;
}
};
}
@Override
public <ValueType, BaseType, RelativeTo> ConfidenceBasedAverager<ValueType, BaseType, RelativeTo> createAverager(Weigher<RelativeTo> weigher) {
return new ConfidenceBasedAveragerImpl<ValueType, BaseType, RelativeTo>(weigher);
@@ -122,7 +122,9 @@ public class BearingWithConfidenceCluster<RelativeTo> {
/**
* If the cluster contains no bearings, <code>null</code> is returned. Otherwise, the average angle is computed
* by adding up the sin and cos values of the individual bearings, then computing the atan2 of the ratio.
* by adding up the sin and cos values of the individual bearings, then computing the atan2 of the ratio. If the
* combined confidence of the bearings in the cluster is 0.0, the result will contain <code>null</code> as
* {@link BearingWithConfidence#getObject() object}.
*/
public BearingWithConfidence<RelativeTo> getAverage(RelativeTo relativeTo) {
ConfidenceBasedAverager<Pair<Double, Double>, Bearing, RelativeTo> averager = ConfidenceFactory.INSTANCE.createAverager(weigher);
@@ -132,12 +134,13 @@ public class BearingWithConfidenceCluster<RelativeTo> {
/**
* Absolute difference to {@link #getAverage() this cluster's average bearing} in degrees. If there is no bearing stored in
* this cluster yet, 0.0 is returned.
* this cluster yet, or the combined confidence of the values in the cluster is 0.0, 0.0 is returned.
*
* @return a value <code>&gt;=0.0</code>
*/
private double getDifferenceFromAverage(Bearing bearing, RelativeTo relativeTo) {
return bearings.size() == 0 ? 0.0 : Math.abs(getAverage(relativeTo).getObject().getDifferenceTo(bearing).getDegrees());
Bearing averageBearing = getAverage(relativeTo).getObject();
return averageBearing == null ? 0.0 : Math.abs(averageBearing.getDifferenceTo(bearing).getDegrees());
}
protected Iterable<BearingWithConfidence<RelativeTo>> getBearings() {
@@ -5,6 +5,7 @@ import java.util.LinkedList;
import java.util.List;
import java.util.NavigableSet;
import com.sap.sailing.domain.base.BearingWithConfidence;
import com.sap.sailing.domain.base.SpeedWithBearing;
import com.sap.sailing.domain.base.impl.BearingWithConfidenceImpl;
import com.sap.sailing.domain.base.impl.KnotSpeedWithBearingImpl;
@@ -75,7 +76,8 @@ public class DynamicGPSFixMovingTrackImpl<ItemType> extends DynamicTrackImpl<Ite
last = next;
}
}
Bearing bearing = bearingCluster.getAverage(at).getObject();
BearingWithConfidence<TimePoint> average = bearingCluster.getAverage(at);
Bearing bearing = average == null ? null : average.getObject();
SpeedWithBearing avgSpeed = (count == 0 || bearing == null) ? null : new KnotSpeedWithBearingImpl(knotSum / count, bearing);
return avgSpeed;
}
@@ -8,6 +8,7 @@ import java.util.List;
import java.util.NavigableSet;
import java.util.Set;
import com.sap.sailing.domain.base.BearingWithConfidence;
import com.sap.sailing.domain.base.SpeedWithBearing;
import com.sap.sailing.domain.base.impl.BearingWithConfidenceImpl;
import com.sap.sailing.domain.base.impl.KnotSpeedImpl;
@@ -342,7 +343,8 @@ public class GPSFixTrackImpl<ItemType, FixType extends GPSFix> extends TrackImpl
}
}
// TODO bug #169: return SpeedWithBearingWithConfidence to reflect the confidence reduction incurred by the difference of the fix's time point and "at"
Bearing bearing = bearingCluster.getAverage(at).getObject();
BearingWithConfidence<TimePoint> average = bearingCluster.getAverage(at);
Bearing bearing = average == null ? null : average.getObject();
SpeedWithBearing avgSpeed = (count == 0 || bearing == null) ? null : new KnotSpeedWithBearingImpl(knotSum / count, bearing);
return avgSpeed;
}
@@ -7,6 +7,7 @@ import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.sap.sailing.domain.base.BearingWithConfidence;
import com.sap.sailing.domain.base.CourseChange;
import com.sap.sailing.domain.base.SpeedWithBearing;
import com.sap.sailing.domain.base.Timed;
@@ -134,6 +135,7 @@ public class WindTrackImpl extends TrackImpl<Wind> implements WindTrack {
double knotSum = 0;
// TODO bug #169: also measure speed with confidence; return confidence
Weigher<TimePoint> weigher = ConfidenceFactory.INSTANCE.createLinearTimeDifferenceWeigher(millisecondsOverWhichToAverage);
// Weigher<TimePoint> weigher = ConfidenceFactory.INSTANCE.createConstantWeigher(1.0);
BearingWithConfidenceCluster<TimePoint> bearingCluster = new BearingWithConfidenceCluster<TimePoint>(weigher);
int count = 0;
long beforeDistanceToAt = 0;
@@ -189,7 +191,8 @@ public class WindTrackImpl extends TrackImpl<Wind> implements WindTrack {
return null;
} else {
// TODO bug #169: pass on confidence
SpeedWithBearing avgWindSpeed = new KnotSpeedWithBearingImpl(knotSum / count, bearingCluster.getAverage(at).getObject());
BearingWithConfidence<TimePoint> average = bearingCluster.getAverage(at);
SpeedWithBearing avgWindSpeed = new KnotSpeedWithBearingImpl(knotSum / count, average == null ? null : average.getObject());
return new WindImpl(p, at, avgWindSpeed);
}
}