mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-08 05:11:04 +00:00
end-to-end support for first-leg-is-upwind identification
This commit is contained in:
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;
|
||||
}
|
||||
|
||||
}
|
||||
+2
@@ -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);
|
||||
|
||||
/**
|
||||
|
||||
+17
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
+8
-21
@@ -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;
|
||||
|
||||
Reference in new issue
Block a user