mirror of
https://github.com/michaelrausch/Party-Parrots-At-Sea.git
synced 2026-05-09 06:18:44 +00:00
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:
@@ -52,7 +52,7 @@ public class ClientPacketParser {
|
|||||||
private static Map<Integer, Yacht> clientStateBoats = new ConcurrentHashMap<>();
|
private static Map<Integer, Yacht> clientStateBoats = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
//CONVERSION CONSTANTS
|
//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
|
* 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 int PORT = 4942;
|
||||||
private static final Integer MAX_NUM_PLAYERS = 3;
|
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 static final int LOG_LEVEL = 1;
|
||||||
|
|
||||||
private Thread thread;
|
private Thread thread;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import java.io.BufferedReader;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
|
import java.lang.reflect.Array;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
@@ -126,7 +127,7 @@ public final class PolarTable {
|
|||||||
*/
|
*/
|
||||||
public static HashMap<Double, Double> getOptimalUpwindVMG(Double thisWindSpeed) {
|
public static HashMap<Double, Double> getOptimalUpwindVMG(Double thisWindSpeed) {
|
||||||
|
|
||||||
Double polarWindSpeed = getClosestMatch(thisWindSpeed);
|
Double polarWindSpeed = getClosestWindSpeedInPolar(thisWindSpeed);
|
||||||
return upwindOptimal.get(polarWindSpeed);
|
return upwindOptimal.get(polarWindSpeed);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,30 +139,47 @@ public final class PolarTable {
|
|||||||
*/
|
*/
|
||||||
public static HashMap<Double, Double> getOptimalDownwindVMG(Double thisWindSpeed) {
|
public static HashMap<Double, Double> getOptimalDownwindVMG(Double thisWindSpeed) {
|
||||||
|
|
||||||
Double polarWindSpeed = getClosestMatch(thisWindSpeed);
|
Double polarWindSpeed = getClosestWindSpeedInPolar(thisWindSpeed);
|
||||||
return downwindOptimal.get(polarWindSpeed);
|
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);
|
return polarTable.get(polarWindSpeed).get(polarAngle);
|
||||||
Double upperVal = windValues.get(1);
|
|
||||||
|
|
||||||
for(int i = 0; i < windValues.size() - 1; i++) {
|
|
||||||
lowerVal = windValues.get(i);
|
|
||||||
upperVal = windValues.get(i+1);
|
|
||||||
if (thisWindSpeed <= upperVal) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Double lowerDiff = Math.abs(lowerVal - thisWindSpeed);
|
|
||||||
Double upperDiff = Math.abs(upperVal - thisWindSpeed);
|
|
||||||
|
|
||||||
return (lowerDiff <= upperDiff) ? lowerVal : upperVal;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -4,8 +4,9 @@ import static seng302.utilities.GeoUtility.getGeoCoordinate;
|
|||||||
|
|
||||||
import java.text.DateFormat;
|
import java.text.DateFormat;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Map;
|
|
||||||
import javafx.scene.paint.Color;
|
import javafx.scene.paint.Color;
|
||||||
|
import seng302.client.ClientPacketParser;
|
||||||
import seng302.controllers.RaceViewController;
|
import seng302.controllers.RaceViewController;
|
||||||
import seng302.gameServer.GameState;
|
import seng302.gameServer.GameState;
|
||||||
import seng302.models.mark.Mark;
|
import seng302.models.mark.Mark;
|
||||||
@@ -19,7 +20,7 @@ import seng302.utilities.GeoPoint;
|
|||||||
*/
|
*/
|
||||||
public class Yacht {
|
public class Yacht {
|
||||||
|
|
||||||
private final Double TURN_STEP = 2.0;
|
private final Double TURN_STEP = 5.0;
|
||||||
|
|
||||||
private Double lastHeading;
|
private Double lastHeading;
|
||||||
private Boolean sailIn;
|
private Boolean sailIn;
|
||||||
@@ -119,35 +120,16 @@ public class Yacht {
|
|||||||
public void update(Long timeInterval) {
|
public void update(Long timeInterval) {
|
||||||
if (sailIn) {
|
if (sailIn) {
|
||||||
Double secondsElapsed = timeInterval / 1000000.0;
|
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;
|
Double metersCovered = velocity * secondsElapsed;
|
||||||
location = getGeoCoordinate(location, heading, metersCovered);
|
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() {
|
public Double getHeading() {
|
||||||
return heading;
|
return heading;
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package seng302.models.xml;
|
|||||||
import freemarker.template.Configuration;
|
import freemarker.template.Configuration;
|
||||||
import freemarker.template.Template;
|
import freemarker.template.Template;
|
||||||
import freemarker.template.TemplateException;
|
import freemarker.template.TemplateException;
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
import seng302.server.messages.XMLMessageSubType;
|
import seng302.server.messages.XMLMessageSubType;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
@@ -27,11 +28,7 @@ public class XMLGenerator {
|
|||||||
configuration = new Configuration(Configuration.VERSION_2_3_26);
|
configuration = new Configuration(Configuration.VERSION_2_3_26);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
configuration.setDirectoryForTemplateLoading(new File(getClass().getResource(XML_TEMPLATE_DIR).toURI()));
|
configuration.setClassForTemplateLoading(getClass(), XML_TEMPLATE_DIR);
|
||||||
} 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");
|
|
||||||
} catch (NullPointerException e){
|
} catch (NullPointerException e){
|
||||||
System.out.println("[FATAL] Server could not load XML Template directory, ensure this directory isn't empty");
|
System.out.println("[FATAL] Server could not load XML Template directory, ensure this directory isn't empty");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,4 +8,4 @@
|
|||||||
<?import javafx.scene.layout.*?>
|
<?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" />
|
||||||
|
|||||||
@@ -24,13 +24,4 @@ public class YachtTest {
|
|||||||
yachts.add(new Yacht("Yacht 3", "Y3", new GeoPoint(-35.0, -15.5), 20.0));
|
yachts.add(new Yacht("Yacht 3", "Y3", new GeoPoint(-35.0, -15.5), 20.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testVelocityUpdate() {
|
|
||||||
for (Yacht yacht : yachts) {
|
|
||||||
yacht.updateYachtVelocity(windDir, windSpd);
|
|
||||||
System.out.println(yacht.getVelocity());
|
|
||||||
// TODO: 20/07/17 ajm412: add assertions.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user