From 6b3fb021b0d016574cd681f71c5a27dc6641d3e2 Mon Sep 17 00:00:00 2001 From: Daniel Lisunkin Date: Wed, 4 Sep 2019 14:32:19 +0200 Subject: [PATCH] Further refectoring and changes in function signatures of ORCPerformanceCurveImpl to adopt the different ORCPerformanceCurveLegTypes. --- .../orc/ORCCertificateAssignmentEvent.java | 16 ---- .../abstractlog/orc/ORCScratchBoatEvent.java | 2 +- .../ORCCertificateAssignmentEventImpl.java | 50 ------------- .../orc/impl/ORCPerformanceCurveImpl.java | 73 +++++++++---------- 4 files changed, 35 insertions(+), 106 deletions(-) delete mode 100644 java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/orc/ORCCertificateAssignmentEvent.java delete mode 100644 java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/orc/impl/ORCCertificateAssignmentEventImpl.java diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/orc/ORCCertificateAssignmentEvent.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/orc/ORCCertificateAssignmentEvent.java deleted file mode 100644 index a299bbb57c2..00000000000 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/orc/ORCCertificateAssignmentEvent.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.sap.sailing.domain.abstractlog.orc; - -import java.io.Serializable; - -import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEvent; -import com.sap.sailing.domain.common.orc.ORCCertificate; - -// TODO Here is needed a solution/concept to use this kind of events in race and regatta logs. -// Additionally the logic shouldn't be implemented at two different places. -public interface ORCCertificateAssignmentEvent extends RegattaLogEvent { - - public Serializable getCompetitorID(); - - public ORCCertificate getCertificate(); - -} diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/orc/ORCScratchBoatEvent.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/orc/ORCScratchBoatEvent.java index 9886a850a56..c4b291f95bb 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/orc/ORCScratchBoatEvent.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/orc/ORCScratchBoatEvent.java @@ -2,7 +2,7 @@ package com.sap.sailing.domain.abstractlog.orc; import com.sap.sailing.domain.abstractlog.race.RaceLogEvent; -//TODO +//TODO Implementation and decision wether the sratch boat should be set for a whole regatta or per race public interface ORCScratchBoatEvent extends RaceLogEvent { } diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/orc/impl/ORCCertificateAssignmentEventImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/orc/impl/ORCCertificateAssignmentEventImpl.java deleted file mode 100644 index c474c6ee140..00000000000 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/orc/impl/ORCCertificateAssignmentEventImpl.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.sap.sailing.domain.abstractlog.orc.impl; - -import java.io.Serializable; - -import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor; -import com.sap.sailing.domain.abstractlog.impl.AbstractLogEventImpl; -import com.sap.sailing.domain.abstractlog.orc.ORCCertificateAssignmentEvent; -import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEventVisitor; -import com.sap.sailing.domain.base.Competitor; -import com.sap.sailing.domain.base.CompetitorAndBoat; -import com.sap.sailing.domain.common.orc.ORCCertificate; -import com.sap.sse.common.TimePoint; - -public class ORCCertificateAssignmentEventImpl extends AbstractLogEventImpl implements ORCCertificateAssignmentEvent { - - private ORCCertificate certificate; - private Serializable competitorID; - - public ORCCertificateAssignmentEventImpl(TimePoint createdAt, TimePoint logicalTimePoint, - AbstractLogEventAuthor author, Serializable pId, ORCCertificate certificate, Competitor competitor) { - super(createdAt, logicalTimePoint, author, pId); - this.certificate = certificate; - this.competitorID = competitor.getId(); - } - - public ORCCertificateAssignmentEventImpl(TimePoint createdAt, TimePoint logicalTimePoint, - AbstractLogEventAuthor author, Serializable pId, ORCCertificate certificate, Serializable competitorID) { - super(createdAt, logicalTimePoint, author, pId); - this.certificate = certificate; - this.competitorID = competitorID; - } - - private static final long serialVersionUID = -3186019736784868848L; - - @Override - public void accept(RegattaLogEventVisitor visitor) { - visitor.visit(this); - } - - @Override - public ORCCertificate getCertificate() { - return certificate; - } - - @Override - public Serializable getCompetitorID() { - return competitorID; - } - -} diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/orc/impl/ORCPerformanceCurveImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/orc/impl/ORCPerformanceCurveImpl.java index 1b009cf4323..316da535cbb 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/orc/impl/ORCPerformanceCurveImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/orc/impl/ORCPerformanceCurveImpl.java @@ -25,6 +25,7 @@ import com.sap.sailing.domain.common.impl.KnotSpeedImpl; import com.sap.sailing.domain.common.orc.ORCCertificate; import com.sap.sailing.domain.common.orc.ORCPerformanceCurveCourse; import com.sap.sailing.domain.common.orc.ORCPerformanceCurveLeg; +import com.sap.sailing.domain.common.orc.ORCPerformanceCurveLegTypes; import com.sap.sailing.domain.common.orc.impl.ORCCertificateImpl; import com.sap.sailing.domain.orc.ORCPerformanceCurve; import com.sap.sse.common.Bearing; @@ -77,12 +78,9 @@ public class ORCPerformanceCurveImpl implements Serializable, ORCPerformanceCurv * map from the true wind angle (here expressed as an object of type {@link Bearing}) and the {@link Duration} the * boat is assumed to need at that true wind speed/angle for one nautical mile. */ - public ORCPerformanceCurveImpl(ORCCertificate cer, ORCPerformanceCurveCourse course) throws FunctionEvaluationException { + public ORCPerformanceCurveImpl(ORCCertificate certificate, ORCPerformanceCurveCourse course) throws FunctionEvaluationException { this.course = course; - functionImpliedWindInKnotsToAverageSpeedInKnotsForCourse = createPerformanceCurve( - cer.getVelocityPredictionPerTrueWindSpeedAndAngle(), - cer.getBeatAngles(), cer.getBeatVMGPredictions(), cer.getBeatAllowances(), - cer.getRunAngles(), cer.getRunVMGPredictions(), cer.getRunAllowances()); + functionImpliedWindInKnotsToAverageSpeedInKnotsForCourse = createPerformanceCurve(certificate); } /** @@ -101,11 +99,8 @@ public class ORCPerformanceCurveImpl implements Serializable, ORCPerformanceCurv * assumed at 10000kts true wind speed is the same as for the highest wind speed from the original list. *

*/ - private UnivariateDifferentiableFunction createPerformanceCurve(Map> twaAllowances, - Map beatAngles, Map beatVMGPredictionPerTrueWindSpeed, Map beatAllowancePerTrueWindSpeed, - Map runAngles, Map runVMGPredictionPerTrueWindSpeed, Map runAllowancePerTrueWindSpeed) throws FunctionEvaluationException { - final Map allowancesForCoursePerTrueWindSpeed = createAllowancesPerCourse(twaAllowances, beatAngles, - beatVMGPredictionPerTrueWindSpeed, beatAllowancePerTrueWindSpeed, runAngles, runVMGPredictionPerTrueWindSpeed, runAllowancePerTrueWindSpeed); + private UnivariateDifferentiableFunction createPerformanceCurve(ORCCertificate certificate) throws FunctionEvaluationException { + final Map allowancesForCoursePerTrueWindSpeed = createAllowancesPerCourse(certificate); double[] xs = new double[ORCCertificateImpl.ALLOWANCES_TRUE_WIND_SPEEDS.length+2]; double[] ys = new double[ORCCertificateImpl.ALLOWANCES_TRUE_WIND_SPEEDS.length+2]; int i = 0; @@ -142,15 +137,13 @@ public class ORCPerformanceCurveImpl implements Serializable, ORCPerformanceCurv * {@link #course}, keyed by the different true wind speeds. The resulting {@link LinkedHashMap}'s iteration * order is guaranteed to deliver the true wind speed keys in the order of ascending wind speeds. */ - public LinkedHashMap createAllowancesPerCourse(Map> velocityPredictionPerTrueWindSpeedAndAngle, - Map beatAngles, Map beatVMGPredictionPerTrueWindSpeed, Map beatAllowancePerTrueWindSpeed, - Map runAngles, Map runVMGPredictionPerTrueWindSpeed, Map runAllowancePerTrueWindSpeed) - throws FunctionEvaluationException { + public LinkedHashMap createAllowancesPerCourse(ORCCertificate certificate) throws FunctionEvaluationException { + + final LinkedHashMap result = new LinkedHashMap<>(); final Map> allowancesPerLeg = new HashMap<>(); for (final ORCPerformanceCurveLeg leg : course.getLegs()) { - allowancesPerLeg.put(leg, createAllowancePerLeg(leg, velocityPredictionPerTrueWindSpeedAndAngle, beatAngles, - beatVMGPredictionPerTrueWindSpeed, beatAllowancePerTrueWindSpeed, runAngles, runVMGPredictionPerTrueWindSpeed, runAllowancePerTrueWindSpeed)); + allowancesPerLeg.put(leg, createAllowancePerLeg(leg, certificate)); } for (final Speed tws : ORCCertificateImpl.ALLOWANCES_TRUE_WIND_SPEEDS) { double allowancePerTws = 0.0; @@ -166,30 +159,32 @@ public class ORCPerformanceCurveImpl implements Serializable, ORCPerformanceCurv * Computes the durations the boat to which this performance curve belongs is expected to sail to complete the {@code leg}, * considering the leg's {@link ORCPerformanceCurveLeg#getLength() length}. */ - private Map createAllowancePerLeg(ORCPerformanceCurveLeg leg, - Map> twaAllowances, Map beatAngles, - Map beatVMGPredictionPerTrueWindSpeed, Map beatAllowancePerTrueWindSpeed, Map runAngles, - Map runVMGPredictionPerTrueWindSpeed, Map runAllowancePerTrueWindSpeed) throws FunctionEvaluationException { + private Map createAllowancePerLeg(ORCPerformanceCurveLeg leg, ORCCertificate certificate) throws FunctionEvaluationException { + Map> twaAllowances = certificate.getVelocityPredictionPerTrueWindSpeedAndAngle(); + Map beatAngles = certificate.getBeatAngles(); + Map beatVMGPredictionPerTrueWindSpeed = certificate.getBeatVMGPredictions(); + Map beatAllowancePerTrueWindSpeed = certificate.getBeatAllowances(); + Map runAngles = certificate.getRunAngles(); + Map runVMGPredictionPerTrueWindSpeed = certificate.getRunVMGPredictions(); + Map runAllowancePerTrueWindSpeed = certificate.getRunAllowances(); final Map result = new HashMap<>(); - for (final Speed tws : ORCCertificateImpl.ALLOWANCES_TRUE_WIND_SPEEDS) { - // Case switching on TWA (0. TWA == 0; 1. TWA < Beat; 2. Beat < TWA < Gybe; 3. Gybe < TWA; 4. TWA == 180) - if (leg.getTwa().compareTo(beatAngles.get(tws)) <= 0) { - // Case 0 & 1 - result = beatVMG * distance * cos(TWA) - // TODO Test if it is necessary to provide the allowances for the accuracy (so the interfaces stay so large) or if calculating back from the velocity is accurate enough - //result.put(tws, beatVMGPredictionPerTrueWindSpeed.get(tws).getDuration( - // /* rhumb line distance of upwind leg projected to wind */ leg.getLength().scale(Math.cos(leg.getTwa().getRadians())))); - result.put(tws, beatAllowancePerTrueWindSpeed.get(tws).times(leg.getLength().getNauticalMiles()).times(Math.cos(leg.getTwa().getRadians()))); - } else if (leg.getTwa().compareTo(runAngles.get(tws)) >= 0) { - // Case 3 & 4 - result = runVMG * distance * cos(TWA) - //result.put(tws, runVMGPredictionPerTrueWindSpeed.get(tws).getDuration( - // /* rhumb line distance of downwind leg projected to wind */ leg.getLength().scale(Math.cos(Math.PI-leg.getTwa().getRadians())))); - result.put(tws, runAllowancePerTrueWindSpeed.get(tws).times(leg.getLength().getNauticalMiles()).times(Math.cos(Math.PI - leg.getTwa().getRadians()))); - } else { - // Case 2 - result is given through the laGrange Interpolation, between the Beat and Gybe Angles - result.put(tws, - getLagrangeSpeedPredictionForTrueWindSpeedAndAngle(twaAllowances, beatAngles, - beatVMGPredictionPerTrueWindSpeed, runAngles, runVMGPredictionPerTrueWindSpeed, tws, - leg.getTwa()).getDuration(leg.getLength())); + + if(leg.getType().equals(ORCPerformanceCurveLegTypes.TWA)) { + for (final Speed tws : ORCCertificateImpl.ALLOWANCES_TRUE_WIND_SPEEDS) { + // Case switching on TWA (0. TWA == 0; 1. TWA < Beat; 2. Beat < TWA < Gybe; 3. Gybe < TWA; 4. TWA == 180) + if (leg.getTwa().compareTo(beatAngles.get(tws)) <= 0) { + // Case 0 & 1 - result = beatVMG * distance * cos(TWA) + result.put(tws, beatAllowancePerTrueWindSpeed.get(tws).times(leg.getLength().getNauticalMiles()).times(Math.cos(leg.getTwa().getRadians()))); + } else if (leg.getTwa().compareTo(runAngles.get(tws)) >= 0) { + // Case 3 & 4 - result = runVMG * distance * cos(TWA) + result.put(tws, runAllowancePerTrueWindSpeed.get(tws).times(leg.getLength().getNauticalMiles()).times(Math.cos(Math.PI - leg.getTwa().getRadians()))); + } else { + // Case 2 - result is given through the laGrange Interpolation, between the Beat and Gybe Angles + result.put(tws, + getLagrangeSpeedPredictionForTrueWindSpeedAndAngle(twaAllowances, beatAngles, + beatVMGPredictionPerTrueWindSpeed, runAngles, runVMGPredictionPerTrueWindSpeed, tws, + leg.getTwa()).getDuration(leg.getLength())); + } } } return result;