mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-11-12 05:35:31 +00:00
Refactored and added useful hints after code review with Axel.
This commit is contained in:
1 parent
0feba184ba
commit
07b8b01cdf
5 files changed
+52
-30
No files matched your search
+3
-2
@@ -71,7 +71,7 @@ public class TestORCPerformanceCurve {
|
||||
legs.add(new ORCPerformanceCurveLegImpl(new NauticalMileDistance(1.0), new DegreeBearingImpl(120)));
|
||||
legs.add(new ORCPerformanceCurveLegImpl(new NauticalMileDistance(1.0), new DegreeBearingImpl(180)));
|
||||
ORCPerformanceCurveCourse simpleCourse = new ORCPerformanceCurveCourseImpl(legs);
|
||||
Map<Speed, Duration> allowancesPerCourse = performanceCurve.createAllowancesPerCourse(course);
|
||||
Map<Speed, Duration> allowancesPerCourse = performanceCurve.createAllowancesPerCourse(simpleCourse);
|
||||
|
||||
assertNotNull(course);
|
||||
assertNotNull(performanceCurve);
|
||||
@@ -86,7 +86,8 @@ public class TestORCPerformanceCurve {
|
||||
assertEquals(404.3, allowancesPerCourse.get(new KnotSpeedImpl(20)).asSeconds(), 0.1);
|
||||
}
|
||||
|
||||
//@Test
|
||||
|
||||
@Test
|
||||
public void testComplexConstructedCourse() throws FunctionEvaluationException {
|
||||
ORCCertificate certificate = importer.getCertificate("GER 5549");
|
||||
ORCPerformanceCurveImpl performanceCurve = (ORCPerformanceCurveImpl) certificate.getPerformanceCurve();
|
||||
|
||||
@@ -17,8 +17,13 @@ import com.sap.sse.common.impl.DegreeBearingImpl;
|
||||
* @author Daniel Lisunkin (I505543)
|
||||
*
|
||||
*/
|
||||
|
||||
// TODO Improve public API in regards of semantic connection with real ORC Certificate (paper)
|
||||
// TODO COMMENTS!
|
||||
|
||||
public class ORCCertificate {
|
||||
|
||||
private static final String BEAT = "Beat";
|
||||
private Map<String, String> general;
|
||||
private Map<String, Number> hull;
|
||||
private Map<String, Number> sails;
|
||||
@@ -29,20 +34,31 @@ public class ORCCertificate {
|
||||
private Map<Speed, Bearing> gybeAngles;
|
||||
private ORCPerformanceCurve performanceCurve;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param general
|
||||
* @param hull
|
||||
* @param sails
|
||||
* @param scoring
|
||||
* @param allowancesByTwa
|
||||
* @param predefinedCourses
|
||||
* @param beatAngles
|
||||
* @param gybeAngles
|
||||
*/
|
||||
public ORCCertificate(Map<String, String> general, Map<String, Number> hull, Map<String, Number> sails,
|
||||
Map<String, Number> scoring, Map<String, Map<Speed, Duration>> twaCourses,
|
||||
Map<String, Number> scoring, Map<String, Map<Speed, Duration>> allowancesByTwa,
|
||||
Map<String, Map<Speed, Duration>> predefinedCourses, Map<Speed, Bearing> beatAngles,
|
||||
Map<Speed, Bearing> gybeAngles) {
|
||||
this.general = general;
|
||||
this.hull = hull;
|
||||
this.sails = sails;
|
||||
this.scoring = scoring;
|
||||
this.twaCourses = twaCourses;
|
||||
this.twaCourses = allowancesByTwa;
|
||||
this.predefinedCourses = predefinedCourses;
|
||||
this.beatAngles = beatAngles;
|
||||
this.gybeAngles = gybeAngles;
|
||||
|
||||
if ((String) getValue("C_Type") == "INTL") {
|
||||
if (((String) getValue("C_Type")).equals("INTL")) {
|
||||
initializePerformanceCurve();
|
||||
} else {
|
||||
initializePerformanceCurve();
|
||||
@@ -52,7 +68,7 @@ public class ORCCertificate {
|
||||
|
||||
private void initializePerformanceCurve() {
|
||||
Map<Speed, Map<Bearing, Duration>> map = new HashMap<>();
|
||||
|
||||
// TODO Get Speed Deltas from RMS, create SubBug in Bugzilla, extract Deltas as static final variable
|
||||
map.put(new KnotSpeedImpl( 6), new HashMap<Bearing, Duration>());
|
||||
map.put(new KnotSpeedImpl( 8), new HashMap<Bearing, Duration>());
|
||||
map.put(new KnotSpeedImpl(10), new HashMap<Bearing, Duration>());
|
||||
@@ -60,7 +76,6 @@ public class ORCCertificate {
|
||||
map.put(new KnotSpeedImpl(14), new HashMap<Bearing, Duration>());
|
||||
map.put(new KnotSpeedImpl(16), new HashMap<Bearing, Duration>());
|
||||
map.put(new KnotSpeedImpl(20), new HashMap<Bearing, Duration>());
|
||||
|
||||
for (String keyTWA : twaCourses.keySet()) {
|
||||
int twa = Integer.parseInt(keyTWA.substring(1));
|
||||
|
||||
@@ -68,20 +83,17 @@ public class ORCCertificate {
|
||||
map.get(keyTWS).put(new DegreeBearingImpl(twa), twaCourses.get(keyTWA).get(keyTWS));
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
for (Speed tws : map.keySet()) {
|
||||
map.get(tws).put(beatAngles.get(tws), predefinedCourses.get("Beat").get(tws));
|
||||
// TODO Define constant "Beat"/"Run" as static final literals
|
||||
map.get(tws).put(beatAngles.get(tws), predefinedCourses.get(BEAT).get(tws));
|
||||
map.get(tws).put(gybeAngles.get(tws), predefinedCourses.get("Run").get(tws));
|
||||
}
|
||||
|
||||
performanceCurve = new ORCPerformanceCurveImpl(map, beatAngles, gybeAngles);
|
||||
performanceCurve.hashCode(); // Only to resolve "Warning"
|
||||
}
|
||||
|
||||
public Object getValue(String key) {
|
||||
Object result = null;
|
||||
|
||||
if (general.containsKey(key)) {
|
||||
result = general.get(key);
|
||||
} else if (hull.containsKey(key)) {
|
||||
@@ -95,7 +107,6 @@ public class ORCCertificate {
|
||||
} else if (predefinedCourses.containsKey(key)) {
|
||||
result = predefinedCourses.get(key);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
+7
-6
@@ -10,16 +10,17 @@ import java.util.Map;
|
||||
*
|
||||
**/
|
||||
public interface ORCCertificateImporter {
|
||||
|
||||
|
||||
/**
|
||||
* Returns an ORCCertificate object to a given sail number. If there is no certificate for the given id, the method returns {@link null}.
|
||||
* **/
|
||||
* Returns an ORCCertificate object to a given sail number. If there is no certificate for the given id, the method
|
||||
* returns {@link null}.
|
||||
**/
|
||||
//TODO Better input specification on identification of certificate.
|
||||
ORCCertificate getCertificate(String sailnumber);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns a map of ORCCertificate objects to a given array of sail numbers.
|
||||
* **/
|
||||
**/
|
||||
Map<String, ORCCertificate> getCertificates(String[] sailnumbers);
|
||||
|
||||
}
|
||||
+9
-4
@@ -6,10 +6,15 @@ import com.sap.sse.common.Distance;
|
||||
|
||||
public interface ORCPerformanceCurveCourse {
|
||||
|
||||
ORCPerformanceCurveLeg getLeg(int i);
|
||||
//TODO Return unmodifiable List/Collection something...
|
||||
Iterable<ORCPerformanceCurveLeg> getLegs();
|
||||
|
||||
List<ORCPerformanceCurveLeg> getLegs();
|
||||
|
||||
Distance getTotalLength();
|
||||
default Distance getTotalLength() {
|
||||
Distance result = Distance.NULL;
|
||||
for (ORCPerformanceCurveLeg leg : getLegs()) {
|
||||
result = result.add(leg.getLength());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
+11
-7
@@ -42,7 +42,7 @@ import com.sap.sse.common.impl.MillisecondsDurationImpl;
|
||||
public class ORCPerformanceCurveImpl implements Serializable, ORCPerformanceCurve {
|
||||
private static final long serialVersionUID = 4113356173492168453L;
|
||||
|
||||
public static final Speed[] ALLOWANCES_SPEED_DELTAS = { new KnotSpeedImpl( 6),
|
||||
public static final Speed[] ALLOWANCES_TRUE_WIND_SPEEDS = { new KnotSpeedImpl( 6),
|
||||
new KnotSpeedImpl( 8),
|
||||
new KnotSpeedImpl(10),
|
||||
new KnotSpeedImpl(12),
|
||||
@@ -50,6 +50,7 @@ public class ORCPerformanceCurveImpl implements Serializable, ORCPerformanceCurv
|
||||
new KnotSpeedImpl(16),
|
||||
new KnotSpeedImpl(20) };
|
||||
|
||||
//TODO COMMENT for key
|
||||
private final Map<Speed, Map<Bearing, Duration>> durationPerNauticalMileAtTrueWindAngleAndSpeed;
|
||||
|
||||
/**
|
||||
@@ -117,7 +118,7 @@ public class ORCPerformanceCurveImpl implements Serializable, ORCPerformanceCurv
|
||||
allowancesPerLeg.put(leg, createAllowancePerLeg(leg));
|
||||
}
|
||||
|
||||
for (Speed tws : ALLOWANCES_SPEED_DELTAS) {
|
||||
for (Speed tws : ALLOWANCES_TRUE_WIND_SPEEDS) {
|
||||
Double allowancePerTws = 0.0;
|
||||
|
||||
for (Entry<ORCPerformanceCurveLeg, Map<Speed, Duration>> entry : allowancesPerLeg.entrySet()) {
|
||||
@@ -142,15 +143,18 @@ public class ORCPerformanceCurveImpl implements Serializable, ORCPerformanceCurv
|
||||
// Case switching on TWA (0. TWA = 0; 1. TWA < Beat; 2. Beat < TWA < Gybe; 3. Gybe < TWA)
|
||||
if (twa < beatAngles.get(entry.getKey()).getDegrees()) {
|
||||
// Case 0&1
|
||||
// Need Beat Angle Allowances for different TWS, maybe Constructor and Structure need to be changed, to get direct access? What will be nicer?
|
||||
// Need Beat Angle Allowances for different TWS, maybe Constructor and Structure need to be changed, to
|
||||
// get direct access? What will be nicer?
|
||||
// result will be: beatVMG * distance / cos(TWA)
|
||||
result.put(entry.getKey(), Duration.ONE_SECOND
|
||||
.times(entry.getValue().value(beatAngles.get(entry.getKey()).getDegrees()) * Math.cos(twa)));
|
||||
result.put(entry.getKey(),
|
||||
Duration.ONE_SECOND.times(entry.getValue().value(beatAngles.get(entry.getKey()).getDegrees())
|
||||
* leg.getLength().getNauticalMiles() * Math.cos(Math.toRadians(twa))));
|
||||
} else if (twa > gybeAngles.get(entry.getKey()).getDegrees()) {
|
||||
// Case 3
|
||||
// result will be: runVMG * distance / cos(TWA)
|
||||
result.put(entry.getKey(), Duration.ONE_SECOND
|
||||
.times(entry.getValue().value(gybeAngles.get(entry.getKey()).getDegrees()) * Math.cos(twa)));
|
||||
result.put(entry.getKey(),
|
||||
Duration.ONE_SECOND.times(entry.getValue().value(gybeAngles.get(entry.getKey()).getDegrees())
|
||||
* leg.getLength().getNauticalMiles() * Math.cos(Math.toRadians(twa))));
|
||||
} else {
|
||||
// Case 2
|
||||
// result is given through the laGrange Interpolation, between the Beat and Gybe Angles
|
||||
|
||||
Reference in new issue
Block a user