end-to-end support for first-leg-is-upwind identification

This commit is contained in:
Axel Uhl committed 2011-12-20 17:23:56 +01:00
1 parent 82077866ce
commit be6c9eb6b7
15 files changed
+109 -54

No files matched your search

@@ -19,11 +19,11 @@ public class BoatClassImpl extends NamedImpl implements BoatClass {
private final long approximateManeuverDurationInMilliseconds;
private final boolean alwaysStartsUpwind;
private final boolean typicallyStartsUpwind;
public BoatClassImpl(String name, boolean alwaysStartsUpwind) {
public BoatClassImpl(String name, boolean typicallyStartsUpwind) {
super(name);
this.alwaysStartsUpwind = alwaysStartsUpwind;
this.typicallyStartsUpwind = typicallyStartsUpwind;
approximateManeuverDurationInMilliseconds = 8000; // as discussed with Dennis Gehrlein
}
@@ -54,7 +54,7 @@ public class BoatClassImpl extends NamedImpl implements BoatClass {
@Override
public boolean typicallyStartsUpwind() {
return alwaysStartsUpwind;
return typicallyStartsUpwind;
}
}
@@ -46,6 +46,8 @@ public interface DynamicTrackedRace extends TrackedRace {
DynamicTrackedEvent getTrackedEvent();
void setWindSource(WindSource windSource);
/**
* If and only if <code>raceIsKnownToStartUpwind</code> is <code>true</code>, this tracked race is allowed to use
* the start leg's direction as a fallback for estimating the wind direction.
@@ -155,8 +155,6 @@ public interface TrackedRace {
*/
Wind getWind(Position p, TimePoint at);
void setWindSource(WindSource windSource);
WindSource getWindSource();
WindTrack getWindTrack(WindSource windSource);
@@ -208,6 +206,17 @@ public interface TrackedRace {
TrackedEvent getTrackedEvent();
/**
* Computes a default wind direction based on the direction of the first leg at time <code>at</code>, with a default
* speed of one knot. Note that this wind direction can only be used if {@link #raceIsKnownToStartUpwind()} returns
* <code>true</code>.
*
* @param at
* usually the {@link #getStart() start time} should be used; if no valid start time is provided, the
* current time point may serve as a default
* @return <code>null</code> in case the first leg's direction cannot be determined, e.g., because the necessary
* mark positions are not known (yet)
*/
Wind getDirectionFromStartToNextMark(TimePoint at);
/**
@@ -37,6 +37,12 @@ public class DynamicTrackedRaceImpl extends TrackedRaceImpl implements
private boolean raceIsKnownToStartUpwind;
/**
* The wind source to be used for all computations based on wind. Used as key into
* {@link #windTracks}. The default value is {@link WindSource#EXPEDITION}.
*/
private WindSource currentWindSource;
public DynamicTrackedRaceImpl(TrackedEvent trackedEvent, RaceDefinition race,
WindStore windStore, long millisecondsOverWhichToAverageWind, long millisecondsOverWhichToAverageSpeed) {
super(trackedEvent, race, windStore, millisecondsOverWhichToAverageWind, millisecondsOverWhichToAverageSpeed);
@@ -48,6 +54,7 @@ public class DynamicTrackedRaceImpl extends TrackedRaceImpl implements
for (WindSource windSource : WindSource.values()) {
getWindTrack(windSource).addListener(this);
}
currentWindSource = WindSource.EXPEDITION;
}
@Override
@@ -294,4 +301,14 @@ public class DynamicTrackedRaceImpl extends TrackedRaceImpl implements
return raceIsKnownToStartUpwind;
}
@Override
public WindSource getWindSource() {
return this.currentWindSource;
}
@Override
public void setWindSource(WindSource windSource) {
this.currentWindSource = windSource;
}
}
@@ -97,12 +97,6 @@ public abstract class TrackedRaceImpl implements TrackedRace, CourseListener {
*/
private final Map<WindSource, WindTrack> windTracks;
/**
* The wind source to be used for all computations based on wind. Used as key into
* {@link #windTracks}. The default value is {@link WindSource#EXPEDITION}.
*/
private WindSource currentWindSource;
private final Map<Buoy, GPSFixTrack<Buoy, GPSFix>> buoyTracks;
private final long millisecondsOverWhichToAverageSpeed;
@@ -147,7 +141,6 @@ public abstract class TrackedRaceImpl implements TrackedRace, CourseListener {
windTracks.put(windSource, windStore.getWindTrack(trackedEvent, this, windSource, millisecondsOverWhichToAverageWind));
}
this.trackedEvent = trackedEvent;
currentWindSource = WindSource.EXPEDITION;
competitorRankings = new HashMap<TimePoint, List<Competitor>>();
}
@@ -399,15 +392,15 @@ public abstract class TrackedRaceImpl implements TrackedRace, CourseListener {
@Override
public Wind getWind(Position p, TimePoint at) {
Wind result = getWindTrack(currentWindSource).getEstimatedWind(p, at);
Wind result = getWindTrack(getWindSource()).getEstimatedWind(p, at);
if (result == null) {
if (!warnedOfNoWindFromSelectedSource) {
logger.warning("Couldn't find any wind information for race "+getRace()+" from currently selected source "+currentWindSource+
logger.warning("Couldn't find any wind information for race "+getRace()+" from currently selected source "+getWindSource()+
". Future warnings of this type will be suppressed for this race.");
warnedOfNoWindFromSelectedSource = true;
}
for (WindSource alternativeWindSource : WindSource.values()) {
if (alternativeWindSource != currentWindSource) {
if (alternativeWindSource != getWindSource()) {
result = getWindTrack(alternativeWindSource).getEstimatedWind(p, at);
if (result != null) {
if (!warnedOfUsingWindFromAlternativeWindSource) {
@@ -438,20 +431,14 @@ public abstract class TrackedRaceImpl implements TrackedRace, CourseListener {
Leg firstLeg = getRace().getCourse().getLegs().iterator().next();
Position firstLegEnd = getApproximatePosition(firstLeg.getTo(), at);
Position firstLegStart = getApproximatePosition(firstLeg.getFrom(), at);
result = new WindImpl(firstLegStart, at, new KnotSpeedWithBearingImpl(1.0, firstLegEnd.getBearingGreatCircle(firstLegStart)));
if (firstLegStart != null && firstLegEnd != null) {
result = new WindImpl(firstLegStart, at, new KnotSpeedWithBearingImpl(1.0, firstLegEnd.getBearingGreatCircle(firstLegStart)));
} else {
result = null;
}
return result;
}
@Override
public WindSource getWindSource() {
return this.currentWindSource;
}
@Override
public void setWindSource(WindSource windSource) {
this.currentWindSource = windSource;
}
@Override
public TimePoint getTimePointOfNewestEvent() {
return timePointOfNewestEvent;