Added new polar function, currently it does not distinguish between up wind and downwind and doesn't find it in the correct quadrant #story[1186]

main
Fan-Wu Yang 8 years ago
parent 7086af6057
commit 9a5d20bdf2

@ -89,6 +89,7 @@ public class PolarParser {
Bearing angle = Bearing.fromDegrees(angleDegrees); Bearing angle = Bearing.fromDegrees(angleDegrees);
double boatSpeedKnots = Double.parseDouble(row[i + 1]); double boatSpeedKnots = Double.parseDouble(row[i + 1]);
polarTable.addEstimate(windSpeedKnots, angle, boatSpeedKnots); polarTable.addEstimate(windSpeedKnots, angle, boatSpeedKnots);
polarTable.addPolars(windSpeedKnots, angle, boatSpeedKnots);
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
throw new InvalidPolarFileException("Could not convert (Row,Col): (" + rowNumber + "," + i +") = " + row[i] + " to a double.", e); throw new InvalidPolarFileException("Could not convert (Row,Col): (" + rowNumber + "," + i +") = " + row[i] + " to a double.", e);

@ -356,14 +356,15 @@ public class MockRace extends Race {
if (boat.getTimeSinceTackChange() > tackPeriod) { if (boat.getTimeSinceTackChange() > tackPeriod) {
//Calculate the new VMG. //Calculate the new VMG.
VMG newVMG = boat.getPolars().calculateVMG( // VMG newVMG = boat.getPolars().calculateVMG(
this.getWindDirection(), // this.getWindDirection(),
this.getWindSpeed(), // this.getWindSpeed(),
boat.calculateBearingToNextMarker(), // boat.calculateBearingToNextMarker(),
Bearing.fromDegrees(0d), // Bearing.fromDegrees(0d),
Bearing.fromDegrees(359.99999d)); // Bearing.fromDegrees(359.99999d));
VMG newVMG = boat.getPolars().setBestVMG(this.getWindDirection(), this.getWindSpeed(), boat.getBearing());
System.out.println(newVMG);
//If the new vmg improves velocity, use it. //If the new vmg improves velocity, use it.
if (improvesVelocity(boat, newVMG)) { if (improvesVelocity(boat, newVMG)) {
boat.setVMG(newVMG); boat.setVMG(newVMG);
@ -372,12 +373,13 @@ public class MockRace extends Race {
} }
private void setBoatSpeed(MockBoat boat) { private void setBoatSpeed(MockBoat boat) {
VMG vmg = boat.getPolars().calculateVMG( // VMG vmg = boat.getPolars().calculateVMG(
this.getWindDirection(), // this.getWindDirection(),
this.getWindSpeed(), // this.getWindSpeed(),
boat.getBearing(), // boat.getBearing(),
Bearing.fromDegrees(boat.getBearing().degrees() - 1), // Bearing.fromDegrees(boat.getBearing().degrees() - 1),
Bearing.fromDegrees(boat.getBearing().degrees() + 1)); // Bearing.fromDegrees(boat.getBearing().degrees() + 1));
VMG vmg = boat.getPolars().setBestVMG(this.getWindDirection(), this.getWindSpeed(), boat.getBearing());
if (vmg.getSpeed() > 0) { if (vmg.getSpeed() > 0) {
boat.setCurrentSpeed(vmg.getSpeed()); boat.setCurrentSpeed(vmg.getSpeed());
} }
@ -527,7 +529,7 @@ public class MockRace extends Race {
if (boat.isStarboardSide(roundingMark) && if (boat.isStarboardSide(roundingMark) &&
GPSCoordinate.passesLine(roundingMark.getPosition(), GPSCoordinate.passesLine(roundingMark.getPosition(),
roundingChecks.get(0), boat.getPosition(), legBearing) && roundingChecks.get(0), boat.getPosition(), legBearing) &&
gateCheck && gateCheck &&
boat.isBetweenGate(roundingMark, Mark.tempMark(roundingChecks.get(0)))) { boat.isBetweenGate(roundingMark, Mark.tempMark(roundingChecks.get(0)))) {
boat.increaseRoundingStatus(); boat.increaseRoundingStatus();
if (boat.getCurrentLeg().getLegNumber() + 2 >= legs.size()){ if (boat.getCurrentLeg().getLegNumber() + 2 >= legs.size()){

@ -3,10 +3,7 @@ package mock.model;
import javafx.util.Pair; import javafx.util.Pair;
import shared.model.Bearing; import shared.model.Bearing;
import java.util.ArrayList; import java.util.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/** /**
* Encapsulates an entire polar table. Has a function to calculate VMG. * Encapsulates an entire polar table. Has a function to calculate VMG.
@ -25,6 +22,8 @@ public class Polars {
*/ */
private HashMap<Double, List<Bearing>> polarAngles = new HashMap<>(); private HashMap<Double, List<Bearing>> polarAngles = new HashMap<>();
//true wind speed, <true wind angle, best boat angle>
private HashMap<Double, HashMap<Double, Double>> polars = new HashMap<>();
@ -78,7 +77,49 @@ public class Polars {
} }
public void addPolars(double trueWindSpeed, Bearing trueWindAngle, double boatSpeed){
double tws = trueWindSpeed;
double bs = boatSpeed;
double twa = trueWindAngle.degrees();
if (!polars.containsKey(tws)){
polars.put(tws, new HashMap<>());
}
polars.get(tws).put(twa, bs);
}
public double getClosest(double value, Set<Double> set){
double closestVal = 0;
double smallestDiff = Double.MAX_VALUE;
for (double d: set){
double diff = Math.abs(value - d);
if (diff < smallestDiff){
closestVal = d;
smallestDiff = diff;
}
}
return closestVal;
}
/**
*
* @param trueWindAngle
* @param trueWindSpeed
* @param boatAngle
* @return
*/
public VMG setBestVMG(Bearing trueWindAngle, double trueWindSpeed, Bearing boatAngle){
//speed
double closestSpeed = getClosest(trueWindSpeed, polars.keySet());
//not using true vmg using general concept
double angle = Math.abs(trueWindAngle.degrees() - boatAngle.degrees());
double closestAngle = getClosest(angle, polars.get(closestSpeed).keySet());
Bearing vmgAngle = Bearing.fromDegrees(closestAngle);
double boatSpeed = Math.abs(closestSpeed * Math.cos(vmgAngle.radians())) * 4;
return new VMG(boatSpeed, vmgAngle);
}
/** /**
* Calculates the VMG for a given wind angle, wind speed, and angle to destination. Will only return VMGs that have a true bearing (angle) within a given bound - this is to ensure that you can calculate VMGs without going out of bounds. * Calculates the VMG for a given wind angle, wind speed, and angle to destination. Will only return VMGs that have a true bearing (angle) within a given bound - this is to ensure that you can calculate VMGs without going out of bounds.

@ -151,7 +151,7 @@ public class RaceServer {
List<BoatStatus> boatStatuses = new ArrayList<>(); List<BoatStatus> boatStatuses = new ArrayList<>();
//Add each boat status to the status list. //Add each boat status to the status list.
for (MockBoat boat : race.getBoats()) { /*for (MockBoat boat : race.getBoats()) {
BoatStatus boatStatus = new BoatStatus( BoatStatus boatStatus = new BoatStatus(
boat.getSourceID(), boat.getSourceID(),
@ -160,7 +160,7 @@ public class RaceServer {
boat.getEstimatedTimeAtNextMark().toInstant().toEpochMilli() ); boat.getEstimatedTimeAtNextMark().toInstant().toEpochMilli() );
boatStatuses.add(boatStatus); boatStatuses.add(boatStatus);
} }*/

@ -45,4 +45,8 @@ public class VMG {
return bearing; return bearing;
} }
public String toString(){
return String.format("VMG Object: Speed %f, Bearing %f.", speed, bearing.degrees());
}
} }

Loading…
Cancel
Save