From 06517b7b47a3a267da92fcbe43c3f4ad1dc74d8c Mon Sep 17 00:00:00 2001 From: Fan-Wu Yang Date: Tue, 5 Sep 2017 21:37:33 +1200 Subject: [PATCH] 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] --- .../src/main/java/mock/model/MockRace.java | 1 + .../src/main/java/mock/model/NewPolars.java | 80 ++++++++++++------- .../src/main/java/mock/model/RaceServer.java | 4 +- .../Controllers/MainController.java | 1 + .../test/java/mock/model/NewPolarsTest.java | 30 +++---- 5 files changed, 69 insertions(+), 47 deletions(-) diff --git a/racevisionGame/src/main/java/mock/model/MockRace.java b/racevisionGame/src/main/java/mock/model/MockRace.java index 8ffc2ba2..6a112e93 100644 --- a/racevisionGame/src/main/java/mock/model/MockRace.java +++ b/racevisionGame/src/main/java/mock/model/MockRace.java @@ -343,6 +343,7 @@ public class MockRace extends Race { if (boat.getAutoVMG()) { newOptimalVMG(boat); + boat.setAutoVMG(false); } } else { diff --git a/racevisionGame/src/main/java/mock/model/NewPolars.java b/racevisionGame/src/main/java/mock/model/NewPolars.java index a1fafeeb..c525316c 100644 --- a/racevisionGame/src/main/java/mock/model/NewPolars.java +++ b/racevisionGame/src/main/java/mock/model/NewPolars.java @@ -8,7 +8,8 @@ import java.util.Set; 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 { @@ -22,6 +23,12 @@ public class NewPolars { 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){ double tws = trueWindSpeed; double bs = boatSpeed; @@ -31,31 +38,33 @@ public class NewPolars { } polars.get(tws).putIfAbsent(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(){ -// 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 prevTWS = null; TreeMap> 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()){ TreeMap tws = iterablePolars.get(windSpeed); + if (prevTWS == null){ prevTWS = tws; continue; } + double previousTWA = -1; TreeMap iterableTWS = new TreeMap<>(tws); + for (double twa: iterableTWS.keySet()){ if (previousTWA == -1){ previousTWA = twa; @@ -65,11 +74,10 @@ public class NewPolars { double speedDiff = iterableTWS.get(twa) - iterableTWS.get(previousTWA); double prevSpeed = iterableTWS.get(previousTWA); double diff = speedDiff/twaDiff; + for (double i = previousTWA; i < twa; i ++){ double mult = i - previousTWA; 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); } previousTWA = twa; @@ -100,17 +108,18 @@ public class NewPolars { * @return */ 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 set){ double min = (quad - 1)* 90; double max = quad * 90; - //System.out.println(quad); - //System.out.println(min + " " + max); double maxAngle = 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()){ if (s >= min && s < max){ if (set.get(s) > maxSpeed){ @@ -121,42 +130,48 @@ public class NewPolars { dupAngle = s; } } - }/* + } if (dupAngle != 0 ){ return getClosest((dupAngle + maxAngle) / 2, set.keySet()); - }*/ + } return maxAngle; } /** - * - * @param trueWindAngle - * @param trueWindSpeed - * @param boatAngle - * @return + * Returns the best VMG that the boat can change to given it's current diagonal heading direction. + * @param trueWindAngle True wind angle of the race + * @param trueWindSpeed True wind speed of the race + * @param boatAngle Angle that the boat is currently at + * @return the best vmg that the boat can change to */ public static VMG setBestVMG(Bearing trueWindAngle, double trueWindSpeed, Bearing boatAngle){ //System.out.println("VMG AUTO CALLED"); //speed 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); double bestAngle = getBestSpeedInQuadrant(quad, polars.get(closestSpeed)); - Bearing vmgAngle = Bearing.fromDegrees((bestAngle) % 360); 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)); } + /** + * 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){ //speed 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 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> getPolars(){ //this function is just for testing so therefore it is private return polars; @@ -178,7 +197,6 @@ public class NewPolars { System.out.println("=================================================="); for (double twa: polars.get(tws).keySet()){ System.out.println("TWA: " + twa + ", Boat Speed: " + polars.get(tws).get(twa)); - //System.out.println("--------------------------------------------------"); } } } diff --git a/racevisionGame/src/main/java/mock/model/RaceServer.java b/racevisionGame/src/main/java/mock/model/RaceServer.java index a28f389d..cbbe1971 100644 --- a/racevisionGame/src/main/java/mock/model/RaceServer.java +++ b/racevisionGame/src/main/java/mock/model/RaceServer.java @@ -151,7 +151,7 @@ public class RaceServer { List boatStatuses = new ArrayList<>(); //Add each boat status to the status list. - /*for (MockBoat boat : race.getBoats()) { + for (MockBoat boat : race.getBoats()) { BoatStatus boatStatus = new BoatStatus( boat.getSourceID(), @@ -160,7 +160,7 @@ public class RaceServer { boat.getEstimatedTimeAtNextMark().toInstant().toEpochMilli() ); boatStatuses.add(boatStatus); - }*/ + } diff --git a/racevisionGame/src/main/java/visualiser/Controllers/MainController.java b/racevisionGame/src/main/java/visualiser/Controllers/MainController.java index 57d18830..9e557d38 100644 --- a/racevisionGame/src/main/java/visualiser/Controllers/MainController.java +++ b/racevisionGame/src/main/java/visualiser/Controllers/MainController.java @@ -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). * @param visualiserRace The object modelling the race. * @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) { raceController.startRace(visualiserRace, controllerClient, isHost); diff --git a/racevisionGame/src/test/java/mock/model/NewPolarsTest.java b/racevisionGame/src/test/java/mock/model/NewPolarsTest.java index 24aa0b0f..dcbcc6cc 100644 --- a/racevisionGame/src/test/java/mock/model/NewPolarsTest.java +++ b/racevisionGame/src/test/java/mock/model/NewPolarsTest.java @@ -26,20 +26,22 @@ public class NewPolarsTest { PolarParser.parseNewPolars("mock/polars/acc_polars.csv"); NewPolars.linearInterpolatePolars(); - Method getPolars = null; - try { - getPolars = NewPolars.class.getDeclaredMethod("printOutLinearInterpolated"); - } catch (NoSuchMethodException e) { - e.printStackTrace(); - } - getPolars.setAccessible(true); - try { - getPolars.invoke(NewPolars.newPolars); - } catch (IllegalAccessException e) { - e.printStackTrace(); - } catch (InvocationTargetException e) { - e.printStackTrace(); - } + +// Uncomment if you want to read the linear interpolation in text +// Method getPolars = null; +// try { +// getPolars = NewPolars.class.getDeclaredMethod("printOutLinearInterpolated"); +// } catch (NoSuchMethodException e) { +// e.printStackTrace(); +// } +// getPolars.setAccessible(true); +// try { +// getPolars.invoke(NewPolars.newPolars); +// } catch (IllegalAccessException e) { +// e.printStackTrace(); +// } catch (InvocationTargetException e) { +// e.printStackTrace(); +// } } @Test