Merge branch 'master' of /home/trac/git

This commit is contained in:
Generic Wiki User
2018-03-07 21:40:02 +00:00
3 changed files with 47 additions and 56 deletions
@@ -502,10 +502,8 @@ public class ManeuverDetectorImpl implements ManeuverDetector {
refinedPenaltyDetails = computeManeuverDetails(refinedPenaltyMainCurveDetails,
maneuverDetails.getTimePointBefore(), firstPenaltyCircleCompletedAt);
}
if (legBeforeManeuver != null) {
maneuverLoss = legBeforeManeuver.getManeuverLoss(maneuverDetails.getTimePointBefore(),
maneuverDetails.getTimePoint(), firstPenaltyCircleCompletedAt);
}
maneuverLoss = getManeuverLoss(maneuverDetails.getTimePointBefore(),
maneuverDetails.getTimePoint(), firstPenaltyCircleCompletedAt);
Position penaltyPosition = competitorTrack.getEstimatedPosition(refinedPenaltyDetails.getTimePoint(),
/* extrapolate */ false);
final Maneuver maneuver = new ManeuverWithStableSpeedAndCourseBoundariesImpl(maneuverType,
@@ -525,10 +523,8 @@ public class ManeuverDetectorImpl implements ManeuverDetector {
final Maneuver maneuver;
if (numberOfTacks > 0 || numberOfJibes > 0) {
maneuverType = numberOfTacks > 0 ? ManeuverType.TACK : ManeuverType.JIBE;
if (legBeforeManeuver != null) {
maneuverLoss = legBeforeManeuver.getManeuverLoss(maneuverDetails.getTimePointBefore(),
maneuverDetails.getTimePoint(), maneuverDetails.getTimePointAfter());
}
maneuverLoss = getManeuverLoss(maneuverDetails.getTimePointBefore(),
maneuverDetails.getTimePoint(), maneuverDetails.getTimePointAfter());
maneuver = new ManeuverWithStableSpeedAndCourseBoundariesImpl(maneuverType, tackAfterManeuver,
maneuverPosition, maneuverLoss, maneuverDetails.getTimePoint(),
maneuverMainCurveDetails.extractEnteringAndExistingDetailsOnly(),
@@ -553,10 +549,8 @@ public class ManeuverDetectorImpl implements ManeuverDetector {
} else {
// no wind information; marking as UNKNOWN
maneuverType = ManeuverType.UNKNOWN;
if (legBeforeManeuver != null) {
maneuverLoss = legBeforeManeuver.getManeuverLoss(maneuverDetails.getTimePointBefore(),
maneuverDetails.getTimePoint(), maneuverDetails.getTimePointAfter());
}
maneuverLoss = getManeuverLoss(maneuverDetails.getTimePointBefore(),
maneuverDetails.getTimePoint(), maneuverDetails.getTimePointAfter());
maneuver = new ManeuverWithStableSpeedAndCourseBoundariesImpl(maneuverType, tackAfterManeuver, maneuverPosition,
maneuverLoss, maneuverDetails.getTimePoint(),
maneuverMainCurveDetails.extractEnteringAndExistingDetailsOnly(),
@@ -571,6 +565,47 @@ public class ManeuverDetectorImpl implements ManeuverDetector {
wind == null ? null : wind.getBearing()));
}
/**
* Computes the maneuver loss as the distance projected onto the average course between entering and exiting the
* maneuver that the boat lost compared to not having maneuvered. With this distance measure, the competitors speed
* and bearing before the maneuver, as defined by <code>timePointBeforeManeuver</code> is extrapolated until
* <code>timePointAfterManeuver</code>, and the resulting extrapolated position's "windward distance" is compared to
* the competitor's actual position at that time. This distance is returned as the result of this method.
*/
private Distance getManeuverLoss(TimePoint timePointWhenSpeedStartedToDrop, TimePoint maneuverTimePoint,
TimePoint timePointWhenSpeedLevelledOffAfterManeuver) {
assert timePointWhenSpeedStartedToDrop != null;
assert timePointWhenSpeedLevelledOffAfterManeuver != null;
Distance result;
final GPSFixTrack<Competitor, GPSFixMoving> track = trackedRace.getTrack(competitor);
SpeedWithBearing speedWhenSpeedStartedToDrop = track.getEstimatedSpeed(timePointWhenSpeedStartedToDrop);
if (speedWhenSpeedStartedToDrop != null) {
SpeedWithBearing speedAfterManeuver = track.getEstimatedSpeed(timePointWhenSpeedLevelledOffAfterManeuver);
if (speedAfterManeuver != null) {
// For upwind/downwind legs, find the mean course between inbound and outbound course and project actual and
// extrapolated positions onto it:
Bearing middleManeuverAngle = speedWhenSpeedStartedToDrop.getBearing().middle(speedAfterManeuver.getBearing());
// extrapolate maximum speed before maneuver to time point of maximum speed after maneuver and project resulting position
// onto the average maneuver course; compare to the projected position actually reached at the time point of maximum speed after
// maneuver:
Position positionWhenSpeedStartedToDrop = track.getEstimatedPosition(timePointWhenSpeedStartedToDrop, /* extrapolate */ false);
Position extrapolatedPositionAtTimePointOfMaxSpeedAfterManeuver =
speedWhenSpeedStartedToDrop.travelTo(positionWhenSpeedStartedToDrop, timePointWhenSpeedStartedToDrop, timePointWhenSpeedLevelledOffAfterManeuver);
Position actualPositionAtTimePointOfMaxSpeedAfterManeuver = track.getEstimatedPosition(timePointWhenSpeedLevelledOffAfterManeuver, /* extrapolate */ false);
Position projectedExtrapolatedPositionAtTimePointOfMaxSpeedAfterManeuver =
extrapolatedPositionAtTimePointOfMaxSpeedAfterManeuver.projectToLineThrough(positionWhenSpeedStartedToDrop, middleManeuverAngle);
Position projectedActualPositionAtTimePointOfMaxSpeedAfterManeuver =
actualPositionAtTimePointOfMaxSpeedAfterManeuver.projectToLineThrough(positionWhenSpeedStartedToDrop, middleManeuverAngle);
result = projectedActualPositionAtTimePointOfMaxSpeedAfterManeuver.getDistance(projectedExtrapolatedPositionAtTimePointOfMaxSpeedAfterManeuver);
} else {
result = null;
}
} else {
result = null;
}
return result;
}
protected Duration getDurationForDouglasPeuckerExtensionForMainCurveAnalysis(Duration approximateManeuverDuration) {
return approximateManeuverDuration.divide(2);
}
@@ -285,15 +285,6 @@ public interface TrackedLegOfCompetitor extends Serializable {
*/
Distance getAverageSignedCrossTrackError(TimePoint timePoint, boolean waitForLatestAnalysis) throws NoWindException;
/**
* Computes the maneuver loss as the distance projected onto the average course between entering and exiting the
* maneuver that the boat lost compared to not having maneuvered. With this distance measure, the competitors speed
* and bearing before the maneuver, as defined by <code>timePointBeforeManeuver</code> is extrapolated until
* <code>timePointAfterManeuver</code>, and the resulting extrapolated position's "windward distance" is compared to
* the competitor's actual position at that time. This distance is returned as the result of this method.
*/
Distance getManeuverLoss(TimePoint timePointBeforeManeuver, TimePoint maneuverTimePoint, TimePoint timePointAfterManeuver);
TrackedLeg getTrackedLeg();
/**
@@ -780,41 +780,6 @@ public class TrackedLegOfCompetitorImpl implements TrackedLegOfCompetitor {
return result;
}
@Override
public Distance getManeuverLoss(TimePoint timePointWhenSpeedStartedToDrop, TimePoint maneuverTimePoint,
TimePoint timePointWhenSpeedLevelledOffAfterManeuver) {
assert timePointWhenSpeedStartedToDrop != null;
assert timePointWhenSpeedLevelledOffAfterManeuver != null;
Distance result;
final GPSFixTrack<Competitor, GPSFixMoving> track = getTrackedRace().getTrack(getCompetitor());
SpeedWithBearing speedWhenSpeedStartedToDrop = track.getEstimatedSpeed(timePointWhenSpeedStartedToDrop);
if (speedWhenSpeedStartedToDrop != null) {
SpeedWithBearing speedAfterManeuver = track.getEstimatedSpeed(timePointWhenSpeedLevelledOffAfterManeuver);
if (speedAfterManeuver != null) {
// For upwind/downwind legs, find the mean course between inbound and outbound course and project actual and
// extrapolated positions onto it:
Bearing middleManeuverAngle = speedWhenSpeedStartedToDrop.getBearing().middle(speedAfterManeuver.getBearing());
// extrapolate maximum speed before maneuver to time point of maximum speed after maneuver and project resulting position
// onto the average maneuver course; compare to the projected position actually reached at the time point of maximum speed after
// maneuver:
Position positionWhenSpeedStartedToDrop = track.getEstimatedPosition(timePointWhenSpeedStartedToDrop, /* extrapolate */ false);
Position extrapolatedPositionAtTimePointOfMaxSpeedAfterManeuver =
speedWhenSpeedStartedToDrop.travelTo(positionWhenSpeedStartedToDrop, timePointWhenSpeedStartedToDrop, timePointWhenSpeedLevelledOffAfterManeuver);
Position actualPositionAtTimePointOfMaxSpeedAfterManeuver = track.getEstimatedPosition(timePointWhenSpeedLevelledOffAfterManeuver, /* extrapolate */ false);
Position projectedExtrapolatedPositionAtTimePointOfMaxSpeedAfterManeuver =
extrapolatedPositionAtTimePointOfMaxSpeedAfterManeuver.projectToLineThrough(positionWhenSpeedStartedToDrop, middleManeuverAngle);
Position projectedActualPositionAtTimePointOfMaxSpeedAfterManeuver =
actualPositionAtTimePointOfMaxSpeedAfterManeuver.projectToLineThrough(positionWhenSpeedStartedToDrop, middleManeuverAngle);
result = projectedActualPositionAtTimePointOfMaxSpeedAfterManeuver.getDistance(projectedExtrapolatedPositionAtTimePointOfMaxSpeedAfterManeuver);
} else {
result = null;
}
} else {
result = null;
}
return result;
}
@Override
public String toString() {
return "TrackedLegOfCompetitor for "+getCompetitor()+" in leg "+getLeg();