Tidied up code
- Removed prints from tests - Added Javadocs in necessary places - Reenabled boat status message to send - Added boat average angle - pulled out modulateAngle function - Commented harder to read loops - Disabled toggled VMG #story[1182]
This commit is contained in:
@@ -343,6 +343,7 @@ public class MockRace extends Race {
|
|||||||
|
|
||||||
if (boat.getAutoVMG()) {
|
if (boat.getAutoVMG()) {
|
||||||
newOptimalVMG(boat);
|
newOptimalVMG(boat);
|
||||||
|
boat.setAutoVMG(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -8,7 +8,8 @@ import java.util.Set;
|
|||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by fwy13 on 4/09/17.
|
* New Polars are the revampe of the old Polars class which interpolates the data after being parsed from the Polar Parser
|
||||||
|
* There can only be one NewPolars instance stored statically however if a boat does happen to have a special case it can be assigned.
|
||||||
*/
|
*/
|
||||||
public class NewPolars {
|
public class NewPolars {
|
||||||
|
|
||||||
@@ -22,6 +23,12 @@ public class NewPolars {
|
|||||||
newPolars = this;
|
newPolars = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add polars from the polar table
|
||||||
|
* @param trueWindSpeed True Wind Speed that the true wind angle and speed corresponds to
|
||||||
|
* @param trueWindAngle True Wind Angle of the race
|
||||||
|
* @param boatSpeed The speed the boat should be going at given the true wind angle
|
||||||
|
*/
|
||||||
public static void addPolars(double trueWindSpeed, Bearing trueWindAngle, double boatSpeed){
|
public static void addPolars(double trueWindSpeed, Bearing trueWindAngle, double boatSpeed){
|
||||||
double tws = trueWindSpeed;
|
double tws = trueWindSpeed;
|
||||||
double bs = boatSpeed;
|
double bs = boatSpeed;
|
||||||
@@ -31,31 +38,33 @@ public class NewPolars {
|
|||||||
}
|
}
|
||||||
polars.get(tws).putIfAbsent(twa, bs);
|
polars.get(tws).putIfAbsent(twa, bs);
|
||||||
polars.get(tws).putIfAbsent(360d - twa, bs);
|
polars.get(tws).putIfAbsent(360d - twa, bs);
|
||||||
//System.out.println(String.format("tws %f, twa %f, bs %f", tws, twa, bs));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Linearly Interpolates this should only be called once per parsing of a polar table
|
||||||
|
*/
|
||||||
public static void linearInterpolatePolars(){
|
public static void linearInterpolatePolars(){
|
||||||
// double maxTWS = 0;
|
|
||||||
// for (double key: polars.keySet()){
|
|
||||||
// if (maxTWS < key){
|
|
||||||
// maxTWS = key;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
/*for (double windSpeed: polars.keySet()){
|
|
||||||
if (!polars.get(windSpeed).containsKey(180d)){
|
|
||||||
polars.get(windSpeed).put(180d, windSpeed);
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
TreeMap<Double, Double> prevTWS = null;
|
TreeMap<Double, Double> prevTWS = null;
|
||||||
TreeMap<Double, TreeMap<Double, Double>> iterablePolars = new TreeMap<>(polars);
|
TreeMap<Double, TreeMap<Double, Double>> iterablePolars = new TreeMap<>(polars);
|
||||||
|
//this loop averages out the speed between tow angles
|
||||||
|
//Example: Pair one: 0 degrees, 0 knots
|
||||||
|
// Pair two: 3 degrees, 6 knots
|
||||||
|
//This loop will add
|
||||||
|
//Pair one: 0 degrees, 0 knots
|
||||||
|
//Pair two: 1 degrees, 2 knots
|
||||||
|
//Pair three: 2 degrees, 4 knots
|
||||||
|
//Pair four: 3 degrees, 6 knots
|
||||||
for (double windSpeed: iterablePolars.keySet()){
|
for (double windSpeed: iterablePolars.keySet()){
|
||||||
TreeMap<Double, Double> tws = iterablePolars.get(windSpeed);
|
TreeMap<Double, Double> tws = iterablePolars.get(windSpeed);
|
||||||
|
|
||||||
if (prevTWS == null){
|
if (prevTWS == null){
|
||||||
prevTWS = tws;
|
prevTWS = tws;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
double previousTWA = -1;
|
double previousTWA = -1;
|
||||||
TreeMap<Double, Double> iterableTWS = new TreeMap<>(tws);
|
TreeMap<Double, Double> iterableTWS = new TreeMap<>(tws);
|
||||||
|
|
||||||
for (double twa: iterableTWS.keySet()){
|
for (double twa: iterableTWS.keySet()){
|
||||||
if (previousTWA == -1){
|
if (previousTWA == -1){
|
||||||
previousTWA = twa;
|
previousTWA = twa;
|
||||||
@@ -65,11 +74,10 @@ public class NewPolars {
|
|||||||
double speedDiff = iterableTWS.get(twa) - iterableTWS.get(previousTWA);
|
double speedDiff = iterableTWS.get(twa) - iterableTWS.get(previousTWA);
|
||||||
double prevSpeed = iterableTWS.get(previousTWA);
|
double prevSpeed = iterableTWS.get(previousTWA);
|
||||||
double diff = speedDiff/twaDiff;
|
double diff = speedDiff/twaDiff;
|
||||||
|
|
||||||
for (double i = previousTWA; i < twa; i ++){
|
for (double i = previousTWA; i < twa; i ++){
|
||||||
double mult = i - previousTWA;
|
double mult = i - previousTWA;
|
||||||
double newSpeed = diff * mult + prevSpeed;
|
double newSpeed = diff * mult + prevSpeed;
|
||||||
//System.out.println(newSpeed);
|
|
||||||
//System.out.println(String.format("tws %f, twa %f, bs %f", windSpeed, i, newSpeed));
|
|
||||||
tws.put(i, newSpeed);
|
tws.put(i, newSpeed);
|
||||||
}
|
}
|
||||||
previousTWA = twa;
|
previousTWA = twa;
|
||||||
@@ -100,17 +108,18 @@ public class NewPolars {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private static int getQuadrant(double degrees){
|
private static int getQuadrant(double degrees){
|
||||||
return ((((int) degrees % 360) + 360) % 360) / 90 + 1;
|
return (int) modulateAngle(degrees) / 90 + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static double getBestSpeedInQuadrant(int quad, Map<Double, Double> set){
|
private static double getBestSpeedInQuadrant(int quad, Map<Double, Double> set){
|
||||||
double min = (quad - 1)* 90;
|
double min = (quad - 1)* 90;
|
||||||
double max = quad * 90;
|
double max = quad * 90;
|
||||||
//System.out.println(quad);
|
|
||||||
//System.out.println(min + " " + max);
|
|
||||||
double maxAngle = 0;
|
double maxAngle = 0;
|
||||||
double maxSpeed = 0;
|
double maxSpeed = 0;
|
||||||
double dupAngle = 0;//index where speed is duplicated
|
double dupAngle = 0;
|
||||||
|
//DupAngle will average the angle between maxAngles that have the same speed
|
||||||
|
//Example: if 150 degrees, 180 degrees, and 210 degrees all go at 10 knots
|
||||||
|
//then the average will be taken as (150 + 210) / 2 and the angle will be returned on that.
|
||||||
for (Double s: set.keySet()){
|
for (Double s: set.keySet()){
|
||||||
if (s >= min && s < max){
|
if (s >= min && s < max){
|
||||||
if (set.get(s) > maxSpeed){
|
if (set.get(s) > maxSpeed){
|
||||||
@@ -121,42 +130,48 @@ public class NewPolars {
|
|||||||
dupAngle = s;
|
dupAngle = s;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}/*
|
}
|
||||||
if (dupAngle != 0 ){
|
if (dupAngle != 0 ){
|
||||||
return getClosest((dupAngle + maxAngle) / 2, set.keySet());
|
return getClosest((dupAngle + maxAngle) / 2, set.keySet());
|
||||||
}*/
|
}
|
||||||
return maxAngle;
|
return maxAngle;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Returns the best VMG that the boat can change to given it's current diagonal heading direction.
|
||||||
* @param trueWindAngle
|
* @param trueWindAngle True wind angle of the race
|
||||||
* @param trueWindSpeed
|
* @param trueWindSpeed True wind speed of the race
|
||||||
* @param boatAngle
|
* @param boatAngle Angle that the boat is currently at
|
||||||
* @return
|
* @return the best vmg that the boat can change to
|
||||||
*/
|
*/
|
||||||
public static VMG setBestVMG(Bearing trueWindAngle, double trueWindSpeed, Bearing boatAngle){
|
public static VMG setBestVMG(Bearing trueWindAngle, double trueWindSpeed, Bearing boatAngle){
|
||||||
//System.out.println("VMG AUTO CALLED");
|
//System.out.println("VMG AUTO CALLED");
|
||||||
//speed
|
//speed
|
||||||
double closestSpeed = getClosest(trueWindSpeed, polars.keySet());
|
double closestSpeed = getClosest(trueWindSpeed, polars.keySet());
|
||||||
|
|
||||||
double angle = ((boatAngle.degrees() - trueWindAngle.degrees()) % 360 + 360) % 360;
|
double angle = modulateAngle(boatAngle.degrees() - trueWindAngle.degrees());
|
||||||
int quad = getQuadrant(angle);
|
int quad = getQuadrant(angle);
|
||||||
double bestAngle = getBestSpeedInQuadrant(quad, polars.get(closestSpeed));
|
double bestAngle = getBestSpeedInQuadrant(quad, polars.get(closestSpeed));
|
||||||
|
|
||||||
Bearing vmgAngle = Bearing.fromDegrees((bestAngle) % 360);
|
|
||||||
double boatSpeed = polars.get(closestSpeed).get(bestAngle);
|
double boatSpeed = polars.get(closestSpeed).get(bestAngle);
|
||||||
|
|
||||||
double newAngle = (bestAngle + trueWindAngle.degrees() % 360 + 360) % 360;
|
double newAngle = modulateAngle(bestAngle + trueWindAngle.degrees());
|
||||||
|
|
||||||
return new VMG(boatSpeed, Bearing.fromDegrees(newAngle));
|
return new VMG(boatSpeed, Bearing.fromDegrees(newAngle));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the speed that a certain angle should be doing
|
||||||
|
* @param trueWindAngle TrueWind Angle of the race
|
||||||
|
* @param trueWindSpeed True Wind Speed of the race
|
||||||
|
* @param boatAngle Angle that the boat is current at
|
||||||
|
* @return the speed that the boat should be traveling at.
|
||||||
|
*/
|
||||||
public static double calculateSpeed(Bearing trueWindAngle, double trueWindSpeed, Bearing boatAngle){
|
public static double calculateSpeed(Bearing trueWindAngle, double trueWindSpeed, Bearing boatAngle){
|
||||||
//speed
|
//speed
|
||||||
double closestSpeed = getClosest(trueWindSpeed, polars.keySet());
|
double closestSpeed = getClosest(trueWindSpeed, polars.keySet());
|
||||||
|
|
||||||
double angleDiff = ((boatAngle.degrees() - trueWindAngle.degrees()) % 360 + 360) % 360;
|
double angleDiff = modulateAngle(boatAngle.degrees() - trueWindAngle.degrees());
|
||||||
double closestAngle = getClosest(angleDiff, polars.get(closestSpeed).keySet());
|
double closestAngle = getClosest(angleDiff, polars.get(closestSpeed).keySet());
|
||||||
|
|
||||||
double boatSpeed = polars.get(closestSpeed).get(closestAngle);
|
double boatSpeed = polars.get(closestSpeed).get(closestAngle);
|
||||||
@@ -166,6 +181,10 @@ public class NewPolars {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static double modulateAngle(double angle){
|
||||||
|
return (angle % 360 + 360) % 360;
|
||||||
|
}
|
||||||
|
|
||||||
private Map<Double, TreeMap<Double, Double>> getPolars(){
|
private Map<Double, TreeMap<Double, Double>> getPolars(){
|
||||||
//this function is just for testing so therefore it is private
|
//this function is just for testing so therefore it is private
|
||||||
return polars;
|
return polars;
|
||||||
@@ -178,7 +197,6 @@ public class NewPolars {
|
|||||||
System.out.println("==================================================");
|
System.out.println("==================================================");
|
||||||
for (double twa: polars.get(tws).keySet()){
|
for (double twa: polars.get(tws).keySet()){
|
||||||
System.out.println("TWA: " + twa + ", Boat Speed: " + polars.get(tws).get(twa));
|
System.out.println("TWA: " + twa + ", Boat Speed: " + polars.get(tws).get(twa));
|
||||||
//System.out.println("--------------------------------------------------");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}*/
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ public class MainController extends Controller {
|
|||||||
* Transitions from the StartController screen (displays pre-race information) to the RaceController (displays the actual race).
|
* Transitions from the StartController screen (displays pre-race information) to the RaceController (displays the actual race).
|
||||||
* @param visualiserRace The object modelling the race.
|
* @param visualiserRace The object modelling the race.
|
||||||
* @param controllerClient Socket Client that manipulates the controller.
|
* @param controllerClient Socket Client that manipulates the controller.
|
||||||
|
* @param isHost whether this window is the host of the race or not.
|
||||||
*/
|
*/
|
||||||
public void beginRace(VisualiserRaceEvent visualiserRace, ControllerClient controllerClient, Boolean isHost) {
|
public void beginRace(VisualiserRaceEvent visualiserRace, ControllerClient controllerClient, Boolean isHost) {
|
||||||
raceController.startRace(visualiserRace, controllerClient, isHost);
|
raceController.startRace(visualiserRace, controllerClient, isHost);
|
||||||
|
|||||||
@@ -26,20 +26,22 @@ public class NewPolarsTest {
|
|||||||
PolarParser.parseNewPolars("mock/polars/acc_polars.csv");
|
PolarParser.parseNewPolars("mock/polars/acc_polars.csv");
|
||||||
NewPolars.linearInterpolatePolars();
|
NewPolars.linearInterpolatePolars();
|
||||||
|
|
||||||
Method getPolars = null;
|
|
||||||
try {
|
// Uncomment if you want to read the linear interpolation in text
|
||||||
getPolars = NewPolars.class.getDeclaredMethod("printOutLinearInterpolated");
|
// Method getPolars = null;
|
||||||
} catch (NoSuchMethodException e) {
|
// try {
|
||||||
e.printStackTrace();
|
// getPolars = NewPolars.class.getDeclaredMethod("printOutLinearInterpolated");
|
||||||
}
|
// } catch (NoSuchMethodException e) {
|
||||||
getPolars.setAccessible(true);
|
// e.printStackTrace();
|
||||||
try {
|
// }
|
||||||
getPolars.invoke(NewPolars.newPolars);
|
// getPolars.setAccessible(true);
|
||||||
} catch (IllegalAccessException e) {
|
// try {
|
||||||
e.printStackTrace();
|
// getPolars.invoke(NewPolars.newPolars);
|
||||||
} catch (InvocationTargetException e) {
|
// } catch (IllegalAccessException e) {
|
||||||
e.printStackTrace();
|
// e.printStackTrace();
|
||||||
}
|
// } catch (InvocationTargetException e) {
|
||||||
|
// e.printStackTrace();
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
Reference in New Issue
Block a user