|
|
|
@ -35,7 +35,6 @@ public class Polars {
|
|
|
|
polarValues.put(newKey, boatSpeed);
|
|
|
|
polarValues.put(newKey, boatSpeed);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//TODO calculate VMG from (windAngle, destAngle, windSpeed).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* Calculates the VMG for a given wind angle, wind speed, and angle to destination.
|
|
|
|
* Calculates the VMG for a given wind angle, wind speed, and angle to destination.
|
|
|
|
@ -65,27 +64,37 @@ public class Polars {
|
|
|
|
ArrayList<Double> windAngles = new ArrayList<>();
|
|
|
|
ArrayList<Double> windAngles = new ArrayList<>();
|
|
|
|
for (Pair<Double, Double> key : this.polarValues.keySet()) {
|
|
|
|
for (Pair<Double, Double> key : this.polarValues.keySet()) {
|
|
|
|
|
|
|
|
|
|
|
|
windAngles.add(key.getValue());
|
|
|
|
//Don't add angles multiple times.
|
|
|
|
|
|
|
|
double angle = key.getValue();
|
|
|
|
|
|
|
|
if (!windAngles.contains(angle)) {
|
|
|
|
|
|
|
|
windAngles.add(angle);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//Find the angle with the best VMG.
|
|
|
|
//Find the angle with the best VMG.
|
|
|
|
|
|
|
|
//TODO need to differentiate between windward and leeward.
|
|
|
|
double bestVMGAngle = 0;
|
|
|
|
double bestVMGAngle = 0;
|
|
|
|
double bestVMGVelocity = 0;
|
|
|
|
double bestVMGVelocity = 0;
|
|
|
|
for (double tackAngle : windAngles) {
|
|
|
|
for (double tackAngle : windAngles) {
|
|
|
|
//This is the velocity from the polar table at this wind speed/angle.
|
|
|
|
Pair<Double,Double> key = new Pair<Double,Double>(polarWindSpeed, tackAngle);
|
|
|
|
double estVelocity = this.polarValues.get(new Pair<Double,Double>(polarWindSpeed, tackAngle));
|
|
|
|
if (this.polarValues.containsKey(key)) {
|
|
|
|
double angleBetweenDestAndTack = tackAngle - destinationAngle;
|
|
|
|
//This is the velocity from the polar table at this wind speed/angle.
|
|
|
|
//This is the estimated velocity towards the target (e.g., angling away from the target reduces velocity).
|
|
|
|
double estVelocity = this.polarValues.get(key);
|
|
|
|
double vmgTemp = Math.cos(angleBetweenDestAndTack) * estVelocity;
|
|
|
|
double angleBetweenDestAndTack = tackAngle - destinationAngle;
|
|
|
|
|
|
|
|
//This is the estimated velocity towards the target (e.g., angling away from the target reduces velocity).
|
|
|
|
//Check that the velocity is better.
|
|
|
|
double vmgTemp = Math.cos(angleBetweenDestAndTack) * estVelocity;
|
|
|
|
if (vmgTemp > bestVMGVelocity) {
|
|
|
|
|
|
|
|
bestVMGVelocity = vmgTemp;
|
|
|
|
//Check that the velocity is better.
|
|
|
|
bestVMGAngle = tackAngle;
|
|
|
|
if (vmgTemp > bestVMGVelocity) {
|
|
|
|
|
|
|
|
bestVMGVelocity = vmgTemp;
|
|
|
|
|
|
|
|
bestVMGAngle = tackAngle;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
System.out.println("VMG speed = " + bestVMGVelocity + " , VMG angle = " + bestVMGAngle);//TEMP DEBUG REMOVE
|
|
|
|
|
|
|
|
|
|
|
|
//Create the VMG object and return it.
|
|
|
|
//Create the VMG object and return it.
|
|
|
|
return new VMG(bestVMGVelocity, bestVMGAngle);
|
|
|
|
return new VMG(bestVMGVelocity, bestVMGAngle);
|
|
|
|
|