Fixed XML Loading error, used VMG to calculate boat velocity

- XML read from stream instead of file
- Started implementing VMG to calculate boat velocity dynamically

Tags: #pair[wmu16, mra106] #story[986]
This commit is contained in:
Michael Rausch
2017-07-25 20:14:50 +12:00
parent 4f2dca7ecf
commit c8a96dcce9
7 changed files with 45 additions and 57 deletions
@@ -52,7 +52,7 @@ public class ClientPacketParser {
private static Map<Integer, Yacht> clientStateBoats = new ConcurrentHashMap<>();
//CONVERSION CONSTANTS
private static final Double MS_TO_KNOTS = 1.94384;
public static final Double MS_TO_KNOTS = 1.94384;
/**
* Used to initialise the thread name and stream parser object so a thread can be executed
@@ -21,7 +21,7 @@ public class MainServerThread extends Observable implements Runnable, PacketBuff
private static final int PORT = 4942;
private static final Integer MAX_NUM_PLAYERS = 3;
private static final Integer UPDATES_PER_SECOND = 5;
private static final Integer UPDATES_PER_SECOND = 2;
private static final int LOG_LEVEL = 1;
private Thread thread;
+32 -14
View File
@@ -4,6 +4,7 @@ import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.HashMap;
@@ -126,7 +127,7 @@ public final class PolarTable {
*/
public static HashMap<Double, Double> getOptimalUpwindVMG(Double thisWindSpeed) {
Double polarWindSpeed = getClosestMatch(thisWindSpeed);
Double polarWindSpeed = getClosestWindSpeedInPolar(thisWindSpeed);
return upwindOptimal.get(polarWindSpeed);
}
@@ -138,30 +139,47 @@ public final class PolarTable {
*/
public static HashMap<Double, Double> getOptimalDownwindVMG(Double thisWindSpeed) {
Double polarWindSpeed = getClosestMatch(thisWindSpeed);
Double polarWindSpeed = getClosestWindSpeedInPolar(thisWindSpeed);
return downwindOptimal.get(polarWindSpeed);
}
public static Double getClosestMatch(Double thisWindSpeed) {
public static Double getBoatSpeed(Double thisWindSpeed, Double thisHeading) {
ArrayList<Double> windValues = new ArrayList<>(polarTable.keySet());
Double polarWindSpeed = getClosestWindSpeedInPolar(thisWindSpeed);
Double polarAngle = getClosestAngleInPolar(polarTable.get(polarWindSpeed), thisHeading);
Double lowerVal = windValues.get(0);
Double upperVal = windValues.get(1);
return polarTable.get(polarWindSpeed).get(polarAngle);
}
for(int i = 0; i < windValues.size() - 1; i++) {
lowerVal = windValues.get(i);
upperVal = windValues.get(i+1);
if (thisWindSpeed <= upperVal) {
break;
public static Double getClosestWindSpeedInPolar(Double thisWindSpeed) {
Double smallestDif = Double.POSITIVE_INFINITY;
Double closestWind = 0d;
for (Double polarWindSpeed : polarTable.keySet()) {
Double difference = Math.abs(polarWindSpeed - thisWindSpeed);
if (difference < smallestDif) {
smallestDif = difference;
closestWind = polarWindSpeed;
}
}
return closestWind;
}
Double lowerDiff = Math.abs(lowerVal - thisWindSpeed);
Double upperDiff = Math.abs(upperVal - thisWindSpeed);
return (lowerDiff <= upperDiff) ? lowerVal : upperVal;
public static Double getClosestAngleInPolar(HashMap<Double, Double> thisWindSpeedPolar, Double thisHeading) {
Double smallestDif = Double.POSITIVE_INFINITY;
Double closestAngle = 0d;
for (Double polarAngle : thisWindSpeedPolar.keySet()) {
Double difference = Math.abs(polarAngle - thisHeading);
if (difference < smallestDif) {
smallestDif = difference;
closestAngle = polarAngle;
}
}
return closestAngle;
}
}
+8 -26
View File
@@ -4,8 +4,9 @@ import static seng302.utilities.GeoUtility.getGeoCoordinate;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Map;
import javafx.scene.paint.Color;
import seng302.client.ClientPacketParser;
import seng302.controllers.RaceViewController;
import seng302.gameServer.GameState;
import seng302.models.mark.Mark;
@@ -19,7 +20,7 @@ import seng302.utilities.GeoPoint;
*/
public class Yacht {
private final Double TURN_STEP = 2.0;
private final Double TURN_STEP = 5.0;
private Double lastHeading;
private Boolean sailIn;
@@ -119,35 +120,16 @@ public class Yacht {
public void update(Long timeInterval) {
if (sailIn) {
Double secondsElapsed = timeInterval / 1000000.0;
Double thisHeading = ((double) Math.floorMod(heading.longValue(), 360L));
Double windSpeedKnots = 0d;
Double boatSpeedInKnots = PolarTable.getBoatSpeed(windSpeedKnots, thisHeading);
velocity = boatSpeedInKnots / ClientPacketParser.MS_TO_KNOTS * 3000;
//System.out.println("velocity = " + velocity);
Double metersCovered = velocity * secondsElapsed;
location = getGeoCoordinate(location, heading, metersCovered);
}
}
/**
* Adjusts the yachts velocity based on the wind direction and speed from the polar table.
*
* @param windDir current wind Direction TODO: 20/07/17 ajm412: (TWA or AWA, not 100% sure?)
* @param windSpd current wind Speed
*/
public void updateYachtVelocity(Double windDir, Double windSpd) {
Double closestSpd = PolarTable.getClosestMatch(windSpd);
Map<Double, Double> polarsFromClosestSpd = PolarTable.getPolarTable().get(closestSpd);
Double closest = 0d;
Double closest_key = 0d;
for (Double key : polarsFromClosestSpd.keySet()) {
Double difference = Math.abs(key - windDir);
if (difference <= closest) {
closest = difference;
closest_key = key;
}
}
// System.out.println("Closest angle " + closest_key);
// System.out.println("WindDir " + windDir);
velocity = polarsFromClosestSpd.get(closest_key);
}
public Double getHeading() {
return heading;
@@ -3,6 +3,7 @@ package seng302.models.xml;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.apache.commons.io.IOUtils;
import seng302.server.messages.XMLMessageSubType;
import java.io.*;
@@ -27,11 +28,7 @@ public class XMLGenerator {
configuration = new Configuration(Configuration.VERSION_2_3_26);
try {
configuration.setDirectoryForTemplateLoading(new File(getClass().getResource(XML_TEMPLATE_DIR).toURI()));
} catch (IOException e){
System.out.println("[FATAL] Server could not read XML templates");
} catch (URISyntaxException e) {
System.out.println("[FATAL] Xml template directory URI is invalid");
configuration.setClassForTemplateLoading(getClass(), XML_TEMPLATE_DIR);
} catch (NullPointerException e){
System.out.println("[FATAL] Server could not load XML Template directory, ensure this directory isn't empty");
}
+1 -1
View File
@@ -8,4 +8,4 @@
<?import javafx.scene.layout.*?>
<AnchorPane fx:id="contentPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" onKeyPressed="#keyPressed" onKeyReleased="#keyReleased" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="seng302.controllers.Controller" />
<AnchorPane fx:id="contentPane" cache="true" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" onKeyPressed="#keyPressed" onKeyReleased="#keyReleased" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="seng302.controllers.Controller" />