From 9a5d20bdf28bae996d0d2ffb14f46b4f57f560a1 Mon Sep 17 00:00:00 2001 From: Fan-Wu Yang Date: Thu, 31 Aug 2017 17:39:17 +1200 Subject: [PATCH] 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/java/mock/dataInput/PolarParser.java | 1 + .../src/main/java/mock/model/MockRace.java | 32 ++++++------ .../src/main/java/mock/model/Polars.java | 49 +++++++++++++++++-- .../src/main/java/mock/model/RaceServer.java | 4 +- .../src/main/java/mock/model/VMG.java | 4 ++ 5 files changed, 69 insertions(+), 21 deletions(-) diff --git a/racevisionGame/src/main/java/mock/dataInput/PolarParser.java b/racevisionGame/src/main/java/mock/dataInput/PolarParser.java index d33c0ac5..3fa3e6de 100644 --- a/racevisionGame/src/main/java/mock/dataInput/PolarParser.java +++ b/racevisionGame/src/main/java/mock/dataInput/PolarParser.java @@ -89,6 +89,7 @@ public class PolarParser { Bearing angle = Bearing.fromDegrees(angleDegrees); double boatSpeedKnots = Double.parseDouble(row[i + 1]); polarTable.addEstimate(windSpeedKnots, angle, boatSpeedKnots); + polarTable.addPolars(windSpeedKnots, angle, boatSpeedKnots); } catch (NumberFormatException e) { throw new InvalidPolarFileException("Could not convert (Row,Col): (" + rowNumber + "," + i +") = " + row[i] + " to a double.", e); diff --git a/racevisionGame/src/main/java/mock/model/MockRace.java b/racevisionGame/src/main/java/mock/model/MockRace.java index 379123af..2c19ea10 100644 --- a/racevisionGame/src/main/java/mock/model/MockRace.java +++ b/racevisionGame/src/main/java/mock/model/MockRace.java @@ -356,14 +356,15 @@ public class MockRace extends Race { if (boat.getTimeSinceTackChange() > tackPeriod) { //Calculate the new VMG. - VMG newVMG = boat.getPolars().calculateVMG( - this.getWindDirection(), - this.getWindSpeed(), - boat.calculateBearingToNextMarker(), - Bearing.fromDegrees(0d), - Bearing.fromDegrees(359.99999d)); - - +// VMG newVMG = boat.getPolars().calculateVMG( +// this.getWindDirection(), +// this.getWindSpeed(), +// boat.calculateBearingToNextMarker(), +// Bearing.fromDegrees(0d), +// 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 (improvesVelocity(boat, newVMG)) { boat.setVMG(newVMG); @@ -372,12 +373,13 @@ public class MockRace extends Race { } private void setBoatSpeed(MockBoat boat) { - VMG vmg = boat.getPolars().calculateVMG( - this.getWindDirection(), - this.getWindSpeed(), - boat.getBearing(), - Bearing.fromDegrees(boat.getBearing().degrees() - 1), - Bearing.fromDegrees(boat.getBearing().degrees() + 1)); +// VMG vmg = boat.getPolars().calculateVMG( +// this.getWindDirection(), +// this.getWindSpeed(), +// boat.getBearing(), +// 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) { boat.setCurrentSpeed(vmg.getSpeed()); } @@ -527,7 +529,7 @@ public class MockRace extends Race { if (boat.isStarboardSide(roundingMark) && GPSCoordinate.passesLine(roundingMark.getPosition(), roundingChecks.get(0), boat.getPosition(), legBearing) && - gateCheck && + gateCheck && boat.isBetweenGate(roundingMark, Mark.tempMark(roundingChecks.get(0)))) { boat.increaseRoundingStatus(); if (boat.getCurrentLeg().getLegNumber() + 2 >= legs.size()){ diff --git a/racevisionGame/src/main/java/mock/model/Polars.java b/racevisionGame/src/main/java/mock/model/Polars.java index 32ee8842..a18aa627 100644 --- a/racevisionGame/src/main/java/mock/model/Polars.java +++ b/racevisionGame/src/main/java/mock/model/Polars.java @@ -3,10 +3,7 @@ package mock.model; import javafx.util.Pair; import shared.model.Bearing; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; /** * Encapsulates an entire polar table. Has a function to calculate VMG. @@ -25,6 +22,8 @@ public class Polars { */ private HashMap> polarAngles = new HashMap<>(); + //true wind speed, + private HashMap> 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 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. diff --git a/racevisionGame/src/main/java/mock/model/RaceServer.java b/racevisionGame/src/main/java/mock/model/RaceServer.java index cbbe1971..a28f389d 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/mock/model/VMG.java b/racevisionGame/src/main/java/mock/model/VMG.java index 905fadce..370df835 100644 --- a/racevisionGame/src/main/java/mock/model/VMG.java +++ b/racevisionGame/src/main/java/mock/model/VMG.java @@ -45,4 +45,8 @@ public class VMG { return bearing; } + public String toString(){ + return String.format("VMG Object: Speed %f, Bearing %f.", speed, bearing.degrees()); + } + }