mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-09-20 04:35:32 +00:00
Merge branch 'master' into bug4652
This commit is contained in:
+5
-1
@@ -46,7 +46,11 @@ public enum MaxPointsReason {
|
||||
/** Time limit Expired */
|
||||
TLE(/* discardable */ true, /* advanceCompetitorsTrackedWorse */ true, /* appliesAtStartOfRace */ false),
|
||||
/** Standard Penalty by Race Committee; gives a certain number of penalty points on top of rank-inferred score */
|
||||
STP(/* discardable */ true, /* advanceCompetitorsTrackedWorse */ false, /* appliesAtStartOfRace */ true);
|
||||
STP(/* discardable */ true, /* advanceCompetitorsTrackedWorse */ false, /* appliesAtStartOfRace */ true),
|
||||
/** Disqualified after causing a tangle in an incident */
|
||||
DCT(/* discardable */ true, /* advanceCompetitorsTrackedWorse */ true, /* appliesAtStartOfRace */ false),
|
||||
/** Retired after causing a tangle */
|
||||
RCT(/* discardable */ true, /* advanceCompetitorsTrackedWorse */ true, /* appliesAtStartOfRace */ false);
|
||||
|
||||
private final boolean discardable;
|
||||
|
||||
|
||||
+4
@@ -16,6 +16,7 @@ import com.sap.sailing.domain.abstractlog.race.SimpleRaceLogIdentifier;
|
||||
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogResolver;
|
||||
import com.sap.sailing.domain.abstractlog.race.impl.RaceLogDependentStartTimeEventImpl;
|
||||
import com.sap.sailing.domain.abstractlog.race.impl.RaceLogImpl;
|
||||
import com.sap.sailing.domain.abstractlog.race.impl.RaceLogPassChangeEventImpl;
|
||||
import com.sap.sailing.domain.abstractlog.race.impl.RaceLogStartTimeEventImpl;
|
||||
import com.sap.sailing.domain.abstractlog.race.impl.SimpleRaceLogIdentifierImpl;
|
||||
import com.sap.sailing.domain.base.CompetitorWithBoat;
|
||||
@@ -73,5 +74,8 @@ public class TrackedRaceStartTimeUpdateForDependentStartTimeTest extends TrackBa
|
||||
assertEquals(r1StartTimeToSet, r1StartTime[0]);
|
||||
assertNotNull(r2StartTime[0]);
|
||||
assertEquals(r1StartTimeToSet.plus(startTimeDiff), r2StartTime[0]);
|
||||
// bug 4708: test that r2's start time is reverted to null after r1 loses its start time
|
||||
r1RaceLog.add(new RaceLogPassChangeEventImpl(MillisecondsTimePoint.now(), author, /* pass */ 1));
|
||||
assertNull(r2StartTime[0]);
|
||||
}
|
||||
}
|
||||
|
||||
+28
-13
@@ -698,8 +698,9 @@ public class ManeuverDetectorImpl extends AbstractManeuverDetectorImpl {
|
||||
} catch (NoWindException e) {
|
||||
tackAfterManeuver = null;
|
||||
}
|
||||
maneuver = new ManeuverWithMainCurveBoundariesImpl(maneuverType, tackAfterManeuver, maneuverPosition, maneuverMainCurveDetails.getTimePoint(),
|
||||
maneuverMainCurveDetails.extractCurveBoundariesOnly(), maneuverUnstableCourseAndSpeedBoundaries,
|
||||
maneuver = new ManeuverWithMainCurveBoundariesImpl(maneuverType, tackAfterManeuver, maneuverPosition,
|
||||
maneuverMainCurveDetails.getTimePoint(), maneuverMainCurveDetails.extractCurveBoundariesOnly(),
|
||||
maneuverUnstableCourseAndSpeedBoundaries,
|
||||
maneuverMainCurveDetails.getMaxTurningRateInDegreesPerSecond(), markPassing, maneuverLoss);
|
||||
}
|
||||
return maneuver;
|
||||
@@ -723,7 +724,8 @@ public class ManeuverDetectorImpl extends AbstractManeuverDetectorImpl {
|
||||
// For upwind/downwind legs, find the mean course between inbound and outbound course and project actual
|
||||
// and
|
||||
// extrapolated positions onto it:
|
||||
Bearing middleManeuverAngle = speedWithBearingWhenSpeedStartedToDrop.getBearing().middle(speedWithBearingAfterManeuver.getBearing());
|
||||
Bearing middleManeuverAngle = speedWithBearingWhenSpeedStartedToDrop.getBearing()
|
||||
.middle(speedWithBearingAfterManeuver.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
|
||||
@@ -731,9 +733,9 @@ public class ManeuverDetectorImpl extends AbstractManeuverDetectorImpl {
|
||||
// maneuver:
|
||||
Position positionWhenSpeedStartedToDrop = track.getEstimatedPosition(timePointWhenSpeedStartedToDrop,
|
||||
/* extrapolate */ false);
|
||||
Position extrapolatedPositionAtTimePointOfMaxSpeedAfterManeuver = speedWithBearingWhenSpeedStartedToDrop.travelTo(
|
||||
positionWhenSpeedStartedToDrop, timePointWhenSpeedStartedToDrop,
|
||||
timePointWhenSpeedLevelledOffAfterManeuver);
|
||||
Position extrapolatedPositionAtTimePointOfMaxSpeedAfterManeuver = speedWithBearingWhenSpeedStartedToDrop
|
||||
.travelTo(positionWhenSpeedStartedToDrop, timePointWhenSpeedStartedToDrop,
|
||||
timePointWhenSpeedLevelledOffAfterManeuver);
|
||||
Position actualPositionAtTimePointOfMaxSpeedAfterManeuver = track
|
||||
.getEstimatedPosition(timePointWhenSpeedLevelledOffAfterManeuver, /* extrapolate */ false);
|
||||
Position projectedExtrapolatedPositionAtTimePointOfMaxSpeedAfterManeuver = extrapolatedPositionAtTimePointOfMaxSpeedAfterManeuver
|
||||
@@ -745,9 +747,8 @@ public class ManeuverDetectorImpl extends AbstractManeuverDetectorImpl {
|
||||
Distance projectedDistanceSailedIfNotManeuvering = positionWhenSpeedStartedToDrop
|
||||
.getDistance(projectedExtrapolatedPositionAtTimePointOfMaxSpeedAfterManeuver);
|
||||
return new ManeuverLoss(projectedDistanceSailed, projectedDistanceSailedIfNotManeuvering,
|
||||
positionWhenSpeedStartedToDrop,
|
||||
actualPositionAtTimePointOfMaxSpeedAfterManeuver, maneuverDuration, speedWithBearingWhenSpeedStartedToDrop,
|
||||
middleManeuverAngle);
|
||||
positionWhenSpeedStartedToDrop, actualPositionAtTimePointOfMaxSpeedAfterManeuver, maneuverDuration,
|
||||
speedWithBearingWhenSpeedStartedToDrop, middleManeuverAngle);
|
||||
}
|
||||
|
||||
protected Duration getDurationForDouglasPeuckerExtensionForMainCurveAnalysis(Duration approximateManeuverDuration) {
|
||||
@@ -938,11 +939,25 @@ public class ManeuverDetectorImpl extends AbstractManeuverDetectorImpl {
|
||||
if (isCourseChangeLimitExceededForCurveExtension(maneuverMainCurveDetails, maneuverStart)) {
|
||||
maneuverStart = null;
|
||||
}
|
||||
// Stable course analysis is considered as not necessary for preparation phase of maneuver because no
|
||||
// oversteering is usually performed before maneuver
|
||||
TimePoint stableBearingAnalysisUntil = maneuverStart == null ? maneuverMainCurveDetails.getTimePointBefore()
|
||||
: maneuverStart.getExtensionTimePoint();
|
||||
Speed lowestSpeed = maneuverStart == null ? null : maneuverStart.getLowestSpeedWithinExtensionArea();
|
||||
double courseChangeSinceManeuverMainCurveInDegrees = maneuverStart == null ? 0
|
||||
: maneuverStart.getCourseChangeInDegreesWithinExtensionArea();
|
||||
stepsToAnalyze = getSpeedWithBearingStepsWithinTimeRange(stepsToAnalyze, earliestTimePointForSpeedTrendAnalysis,
|
||||
stableBearingAnalysisUntil);
|
||||
ManeuverCurveBoundaryExtension stableBearingExtension = findStableBearingWithMaxAbsCourseChangeSpeed(
|
||||
stepsToAnalyze, true, MAX_TURNING_RATE_IN_DEG_PER_SECOND_FOR_STABLE_COURSE_ANALYSIS);
|
||||
if (stableBearingExtension != null
|
||||
&& !isCourseChangeLimitExceededForCurveExtension(maneuverMainCurveDetails, stableBearingExtension)) {
|
||||
maneuverStart = stableBearingExtension;
|
||||
courseChangeSinceManeuverMainCurveInDegrees += stableBearingExtension
|
||||
.getCourseChangeInDegreesWithinExtensionArea();
|
||||
if (lowestSpeed == null
|
||||
|| lowestSpeed.compareTo(stableBearingExtension.getLowestSpeedWithinExtensionArea()) > 0) {
|
||||
lowestSpeed = stableBearingExtension.getLowestSpeedWithinExtensionArea();
|
||||
}
|
||||
}
|
||||
return maneuverStart != null
|
||||
? new ManeuverCurveBoundaryExtension(maneuverStart.getExtensionTimePoint(),
|
||||
maneuverStart.getSpeedWithBearingAtExtensionTimePoint(),
|
||||
@@ -959,8 +974,8 @@ public class ManeuverDetectorImpl extends AbstractManeuverDetectorImpl {
|
||||
if (curveBoundaryExtension == null) {
|
||||
return false;
|
||||
}
|
||||
return Math.abs(curveBoundaryExtension.getCourseChangeInDegreesWithinExtensionArea()) > Math
|
||||
.abs(curveBoundaryExtension.getCourseChangeInDegreesWithinExtensionArea()) / 3.0;
|
||||
return Math.abs(maneuverMainCurveDetails.getDirectionChangeInDegrees()) / 2.0 < Math
|
||||
.abs(curveBoundaryExtension.getCourseChangeInDegreesWithinExtensionArea());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+3
-2
@@ -188,8 +188,9 @@ DynamicTrackedRace, GPSTrackListener<Competitor, GPSFixMoving> {
|
||||
public void onStartTimeChanged(ReadonlyRaceState state) {
|
||||
final TimePoint oldStartTime = getStartOfRace();
|
||||
invalidateStartTime();
|
||||
if (!Util.equalsWithNull(oldStartTime, getStartOfRace())) {
|
||||
onStartTimeChangedByRaceCommittee(getStartOfRace());
|
||||
final TimePoint startTimeFromRaceLog = state.getStartTime();
|
||||
if (!Util.equalsWithNull(oldStartTime, startTimeFromRaceLog)) {
|
||||
onStartTimeChangedByRaceCommittee(startTimeFromRaceLog);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
+11
-15
@@ -23,6 +23,7 @@ import org.apache.http.message.BasicNameValuePair;
|
||||
import org.json.simple.parser.ParseException;
|
||||
|
||||
import com.sap.sailing.domain.base.Regatta;
|
||||
import com.sap.sailing.domain.common.racelog.Flags;
|
||||
import com.sap.sailing.domain.tracking.StartTimeChangedListener;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
@@ -41,10 +42,13 @@ public class StartTimeUpdateHandler extends UpdateHandler implements StartTimeCh
|
||||
* a new start time is received.
|
||||
*/
|
||||
private final Regatta regatta;
|
||||
|
||||
private final RaceAbortedHandler raceAbortedHandler;
|
||||
|
||||
public StartTimeUpdateHandler(URI updateURI, String tracTracUsername, String tracTracPassword,
|
||||
public StartTimeUpdateHandler(URI updateURI, String username, String password,
|
||||
Serializable tracTracEventId, Serializable raceId, Regatta regatta) {
|
||||
super(updateURI, ACTION, tracTracUsername, tracTracPassword, tracTracEventId, raceId);
|
||||
super(updateURI, ACTION, username, password, tracTracEventId, raceId);
|
||||
this.raceAbortedHandler = new RaceAbortedHandler(updateURI, username, password, tracTracEventId, raceId);
|
||||
this.regatta = regatta;
|
||||
}
|
||||
|
||||
@@ -52,20 +56,12 @@ public class StartTimeUpdateHandler extends UpdateHandler implements StartTimeCh
|
||||
public void startTimeChanged(TimePoint newStartTime) throws MalformedURLException, IOException, URISyntaxException {
|
||||
if (isActive()) {
|
||||
if (newStartTime == null) {
|
||||
/*
|
||||
* Do not reset start time based on request by Jorge from TracTrac:
|
||||
*
|
||||
* """
|
||||
* We have detected that when you want to update the race start time your
|
||||
* system sends before a message to reset the race start time. When your
|
||||
* system invokes the first service our system changes the race start time
|
||||
* to null and this value causes some secondary effects in our side.
|
||||
*
|
||||
* Can you just send the update_race_start_time without the
|
||||
* reset_race_start_time? The reset_race_start_time service has to be used
|
||||
* if you want to set the value to null.
|
||||
* """
|
||||
/* notify race status as POSTPONED according to Jorge's comment https://bugzilla.sapsailing.com/bugzilla/show_bug.cgi?id=4708#c5 :
|
||||
* The method that @frank has commented has to work:
|
||||
* http://em.aws.tractrac.com/update_race_status?eventid=5f2f20f0-6cb2-0136-9eca-60a44ce903c3&raceid=81c082a0-7b1f-0136-166e-028f184941da&username=trac%40sapsailing.com&password=sap0912&race_status=POSTPONED
|
||||
* This method changes the race start time to null.
|
||||
*/
|
||||
raceAbortedHandler.raceAborted(Flags.AP); // will send POSTPONED
|
||||
} else {
|
||||
HashMap<String, String> additionalParameters = new HashMap<String, String>();
|
||||
additionalParameters.put(FIELD_RACE_START_TIME, String.valueOf(newStartTime.asMillis()));
|
||||
|
||||
Reference in New Issue
Block a user