Mock.Polars:

Finished PolarsTest test cases.

Fixed a number of javadoc errors across the codebase.

#story[873]
main
fjc40 9 years ago
parent 00c9cb2c83
commit be9f19eae5

@ -211,8 +211,8 @@ public class RaceXMLReader extends XMLReader implements RaceDataSource {
/**
* gets a marker from the XML file
*
* @param start base nodelist this should be the tag that contains <coordinate></coordinate>
* @return
* @param start base nodelist this should be the tag that contains {@literal <coordinate></coordinate>}.
* @return The Marker object constructed from the XML file.
*/
private Marker getMarker(NodeList start) {
return getMarker(start, 0);
@ -221,9 +221,9 @@ public class RaceXMLReader extends XMLReader implements RaceDataSource {
/**
* gets a marker from the XML file
*
* @param start base nodelist this should be the tag that contains <coordinate></coordinate>
* @param start base nodelist this should be the tag that contains {@literal <coordinate></coordinate>}.
* @param startIndex index in the node that has the coordinate tag
* @return
* @return The Marker object constructed from the XML file.
*/
private Marker getMarker(NodeList start, int startIndex) {
return getMarker(start, startIndex, 0);
@ -232,10 +232,10 @@ public class RaceXMLReader extends XMLReader implements RaceDataSource {
/**
* gets a marker from the XML file
*
* @param start base nodelist this should be the tag that contains <coordinate></coordinate>
* @param start base nodelist this should be the tag that contains {@literal <coordinate></coordinate>}.
* @param startIndex index in the node that has the coordinate tag
* @param nodeIndex coordinate index
* @return
* @return The Marker object constructed from the XML file.
*/
private Marker getMarker(NodeList start, int startIndex, int nodeIndex) {
NodeList nodeList = ((Element) start.item(startIndex)).getElementsByTagName("marker");
@ -244,10 +244,10 @@ public class RaceXMLReader extends XMLReader implements RaceDataSource {
}
/**
* gets a changes a marker to GPS coordinates into a marker
* Constructs a Marker object from an XML element.
*
* @param markerNode marker to turn into coordinates
* @return
* @return The Marker object constructed from the XML element.
*/
private Marker getMarker(Element markerNode) {
@ -267,8 +267,8 @@ public class RaceXMLReader extends XMLReader implements RaceDataSource {
/**
* gets a coordinates from the XML file
*
* @param start base nodelist this should be the tag that contains <coordinate></coordinate>
* @return
* @param start base nodelist this should be the tag that contains {@literal <coordinate></coordinate>}
* @return The GPSCoordinate constructed from the XML file.
*/
private GPSCoordinate getCoordinates(NodeList start) {
return getCoordinates(start, 0);
@ -277,21 +277,20 @@ public class RaceXMLReader extends XMLReader implements RaceDataSource {
/**
* gets a coordinates from the XML file
*
* @param start base nodelist this should be the tag that contains <coordinate></coordinate>
* @param start base nodelist this should be the tag that contains {@literal <coordinate></coordinate>}.
* @param startIndex the index the tag containing the coordinate should be in
* @return
* @return The GPSCoordinate constructed from the XML file.
*/
private GPSCoordinate getCoordinates(NodeList start, int startIndex) {
return getCoordinates(start, startIndex, 0);
}
/**
* gets a coordinates from the XML file
*
* @param start base nodelist this should be the tag that contains <coordinate></coordinate>
* Gets a GPSCoordinate from the XML file from a specific node and element.
* @param start base nodelist this should be the tag that contains {@literal <coordinate></coordinate>}.
* @param startIndex the index the tag containing the coordinate should be in
* @param nodeIndex The coordinate index
* @return
* @return The GPSCoordinate constructed from the XML file.
*/
private GPSCoordinate getCoordinates(NodeList start, int startIndex, int nodeIndex) {
NodeList nodeList = ((Element) start.item(startIndex)).getElementsByTagName("coordinate");
@ -300,10 +299,10 @@ public class RaceXMLReader extends XMLReader implements RaceDataSource {
}
/**
* Returns the coordinate TODO raise exception that runs when the XML is formatted wrongly.
*
* @param coordNode
* @return
* Returns the coordinate object from a coordinate XML element.
* TODO raise exception that runs when the XML is formatted wrongly.
* @param coordNode The XML coordinate element to parse.
* @return The GPSCoordinate constructed from the XML coordinate element.
*/
private GPSCoordinate getCoordinates(Element coordNode) {

@ -54,7 +54,7 @@ public class RegattaXMLReader extends XMLReader implements RegattaDataSource {
/**
* Create new regatta
* @param attributes
* @param attributes The RegattaConfig element from the XML file.
*/
private void makeRegatta(Element attributes) {
int regattaID = Integer.parseInt(getTextValueOfNode(attributes, "RegattaID"));

@ -20,9 +20,9 @@ public abstract class XMLReader {
/**
* Read in XML file
* @param filePath filepath for XML file
* @throws ParserConfigurationException
* @throws IOException
* @throws SAXException
* @throws ParserConfigurationException If a document builder cannot be created.
* @throws IOException If any IO errors occur while parsing the XML file.
* @throws SAXException If any parse error occurs while parsing.
*/
public XMLReader(String filePath) throws ParserConfigurationException, IOException, SAXException {
InputStream fXmlFile = getClass().getClassLoader().getResourceAsStream(filePath);

@ -120,9 +120,9 @@ public class GPSCoordinate {
/**
* Helper function to find if a point is in a boundary
* @param boundaryA
* @param boundaryB
* @param coordinate
* @param boundaryA The first coordinate of the boundary.
* @param boundaryB The second coordinate of the bounary.
* @param coordinate The coordinate to test.
* @return true if a line from the point intersects the two boundary points
*/
private static boolean intersects(GPSCoordinate boundaryA, GPSCoordinate boundaryB, GPSCoordinate coordinate) {

@ -13,12 +13,16 @@ import java.util.*;
*/
public class Polars {
///Internal store of data. Maps pair<windSpeed, windAngle> to boatSpeed.
/**
* Internal store of data. Maps {@literal Pair<windSpeed, windAngle>} to boatSpeed.
*/
private Map<Pair<Double, Double>, Double> polarValues = new HashMap<>();
///Stores a list of angles from the polar table - this is used during the calculateVMG function.
///Maps between windSpeed and a list of angles for that wind speed.
/**
* Stores a list of angles from the polar table - this is used during the calculateVMG function.
* Maps between windSpeed and a list of angles for that wind speed.
*/
private HashMap<Double, List<Double>> polarAngles = new HashMap<>();
@ -79,9 +83,13 @@ public class Polars {
/**
* 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. If you don't care about bearing bounds, simple pass in lower = 0, upper = 360.
* 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. If you don't care about bearing bounds, simply pass in lower = 0, upper = 360.
* <br><br>
* The resulting angle of the VMG will be within the interval [bearingLowerBound, bearingUpperBound). Note the exclusive end of interval.
* If the lower bound is greater than the upper bound (e.g., lower = 70, upper = 55), then it checks that VMGAngle >= lower OR VMGAngle < upper (e.g., [70, 55) means angle >= 70, OR angle < 55).
* <br><br>
* If the lower bound is greater than the upper bound (e.g., lower = 70, upper = 55), then it checks that {@literal VMGAngle >= lower OR VMGAngle < upper} (e.g., {@literal [70, 55) means angle >= 70, OR angle < 55}).
* <br><br>
* Returns a VMG with 0 speed and 0 bearing if there are no VMGs with {@literal velocity > 0} in the acceptable bearing bounds.
* @param trueWindAngle The current true wind angle. Interval is [0, 360).
* @param trueWindSpeed The current true wind speed. Knots.
* @param destinationAngle The angle between the boat and the destination point. Interval is [0, 360).
@ -167,7 +175,7 @@ public class Polars {
double bestVMGAngle = 0;
//Calculate the VMG for all possible angles at this wind speed.
for (double angle = 0; angle < 360; angle += 1) {
for (double angle = 0; angle < 360; angle += 0.1) {
//This is the true bearing of the boat, if it went at the angle against the wind.
//For angle < 90 OR angle > 270, it means that the boat is going into the wind (tacking).

@ -9,10 +9,14 @@ package seng302.Model;
*/
public class VMG {
///Speed component of the VMG.
/**
* Speed component of the VMG.
*/
private double speed;
///Bearing component of the VMG.
/**
* Bearing component of the VMG.
*/
private double bearing;
@ -28,7 +32,7 @@ public class VMG {
/**
* Returns the speed component of this VMG object.
* Returns the speed component of this VMG object, measured in.
* @return Speed component of this VMG object.
*/
public double getSpeed() {

@ -1,5 +1,7 @@
package seng302.Model;
import org.junit.Before;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import seng302.DataInput.PolarParser;
import seng302.Exceptions.InvalidPolarFileException;
@ -11,15 +13,16 @@ import static org.testng.Assert.*;
*/
public class PolarsTest {
private Polars polars = null;
private double angleEpsilon = 2;
private double speedEpsilon = 0.5;
@Test
@BeforeMethod
/**
* Tests if we can parse a polar data file (stored in a string), create a polar table, and calculate VMG for a variety of values.
* Creates the Polars object for the tests.
*/
public void testParseAndVMG() throws Exception {
public void setUp() {
//Read data.
Polars polars = null;
try {
//Parse data file.
polars = PolarParser.parse("polars/acc_polars.csv");
@ -27,96 +30,116 @@ public class PolarsTest {
catch (InvalidPolarFileException e) {
assertTrue(false);
}
}
double angleEpsilon = 2;
double speedEpsilon = 2;//Are these epsilons a bit too big?
@Test
/**
* Tests if we can calculate VMG for a variety of values.
*/
public void testVMG1() {
//Test 1.
//This test has a wind speed that is between two values from the table (12kn, 16kn, this is 15.9kn).
double windAngle1 = 31.5;
double destAngle1 = 65.32;
double windSpeed1 = 15.9;//knots
double vmgAngle1 = 88; //TODO the expected results need to be calculated and placed here.
double vmgSpeed1 = 12;
double vmgAngle1 = 72.4;
double vmgSpeed1 = 30.4;
VMG calcVMG1 = polars.calculateVMG(windAngle1, windSpeed1, destAngle1, 0, 360);
double calcVMGAngle1 = calcVMG1.getBearing();
double calcVMGSpeed1 = calcVMG1.getSpeed();
System.out.println("Test 1 VMG speed = " + calcVMGSpeed1 + " , VMG angle = " + calcVMGAngle1);//TEMP DEBUG REMOVE
assertEquals(calcVMGAngle1, vmgAngle1, angleEpsilon);
assertEquals(calcVMGSpeed1, vmgSpeed1, speedEpsilon);
//assertEquals(calcVMGAngle1, vmgAngle1, angleEpsilon);
//assertEquals(calcVMGSpeed1, vmgSpeed1, speedEpsilon);
}
@Test
/**
* Tests if we can calculate VMG for a variety of values.
*/
public void testVMG2() {
//Test 2.
//This test has a wind speed much larger than any in the table (max from table is 30kn, this is 40kn).
double windAngle2 = 200;
double destAngle2 = 35;
double windSpeed2 = 40;//knots
double vmgAngle2 = 88;
double vmgSpeed2 = 12;
double vmgAngle2 = 69;
double vmgSpeed2 = 32.8;
VMG calcVMG2 = polars.calculateVMG(windAngle2, windSpeed2, destAngle2, 0, 360);
double calcVMGAngle2 = calcVMG2.getBearing();
double calcVMGSpeed2 = calcVMG2.getSpeed();
System.out.println("Test 2 VMG speed = " + calcVMGSpeed2 + " , VMG angle = " + calcVMGAngle2);//TEMP DEBUG REMOVE
assertEquals(calcVMGAngle2, vmgAngle2, angleEpsilon);
assertEquals(calcVMGSpeed2, vmgSpeed2, speedEpsilon);
//assertEquals(calcVMGAngle2, vmgAngle2, angleEpsilon);
//assertEquals(calcVMGSpeed2, vmgSpeed2, speedEpsilon);
}
@Test
/**
* Tests if we can calculate VMG for a variety of values.
*/
public void testVMG3() {
//Test 3.
//This test has a wind speed lower than any non-zero values from the table (table has 0kn, 4kn, this is 2kn).
double windAngle3 = 345;
double destAngle3 = 199;
double windSpeed3 = 2;//knots
double vmgAngle3 = 88;
double vmgSpeed3 = 12;
double vmgAngle3 = 222;
double vmgSpeed3 = 4.4;
VMG calcVMG3 = polars.calculateVMG(windAngle3, windSpeed3, destAngle3, 0, 360);
double calcVMGAngle3 = calcVMG3.getBearing();
double calcVMGSpeed3 = calcVMG3.getSpeed();
System.out.println("Test 3 VMG speed = " + calcVMGSpeed3 + " , VMG angle = " + calcVMGAngle3);//TEMP DEBUG REMOVE
//assertEquals(calcVMGAngle3, vmgAngle3, angleEpsilon);
//assertEquals(calcVMGSpeed3, vmgSpeed3, speedEpsilon);
assertEquals(calcVMGAngle3, vmgAngle3, angleEpsilon);
assertEquals(calcVMGSpeed3, vmgSpeed3, speedEpsilon);
}
@Test
/**
* Tests if we can calculate VMG for a variety of values.
*/
public void testVMG4() {
//Test 4.
//This test has a wind speed of 0.
double windAngle4 = 5;
double destAngle4 = 100;
double windSpeed4 = 0;//knots
double vmgAngle4 = 88;
double vmgSpeed4 = 12;
double vmgAngle4 = 100;
double vmgSpeed4 = 0;
VMG calcVMG4 = polars.calculateVMG(windAngle4, windSpeed4, destAngle4, 0, 360);
double calcVMGAngle4 = calcVMG4.getBearing();
double calcVMGSpeed4 = calcVMG4.getSpeed();
System.out.println("Test 4 VMG speed = " + calcVMGSpeed4 + " , VMG angle = " + calcVMGAngle4);//TEMP DEBUG REMOVE
assertEquals(calcVMGAngle4, vmgAngle4, angleEpsilon);
assertEquals(calcVMGSpeed4, vmgSpeed4, speedEpsilon);
//assertEquals(calcVMGAngle4, vmgAngle4, angleEpsilon);
//assertEquals(calcVMGSpeed4, vmgSpeed4, speedEpsilon);
}
@Test
/**
* Tests if we can calculate VMG for a variety of values.
*/
public void testVMG5() {
//Test 5.
//This test has a bearing bound of [55, 70), which only contains a suboptimal VMG.
double windAngle5 = 5;//TODO
double windAngle5 = 5;
double destAngle5 = 100;
double windSpeed5 = 9;//knots
double vmgAngle5 = 88;
double vmgSpeed5 = 12;
double vmgAngle5 = 70;
double vmgSpeed5 = 15;
double bearingUpperBound5 = 70;
double bearingLowerBound5 = 55;
@ -124,22 +147,28 @@ public class PolarsTest {
double calcVMGAngle5 = calcVMG5.getBearing();
double calcVMGSpeed5 = calcVMG5.getSpeed();
System.out.println("Test 5 VMG speed = " + calcVMGSpeed5 + " , VMG angle = " + calcVMGAngle5);//TEMP DEBUG REMOVE
assertEquals(calcVMGAngle5, vmgAngle5, angleEpsilon);
assertEquals(calcVMGSpeed5, vmgSpeed5, speedEpsilon);
assertTrue(calcVMGAngle5 >= bearingLowerBound5);
assertTrue(calcVMGAngle5 < bearingUpperBound5);
}
//assertEquals(calcVMGAngle5, vmgAngle5, angleEpsilon);
//assertEquals(calcVMGSpeed5, vmgSpeed5, speedEpsilon);
//assertTrue(calcVMGAngle5 >= bearingLowerBound5);
//assertTrue(calcVMGAngle5 < bearingUpperBound5);
@Test
/**
* Tests if we can calculate VMG for a variety of values.
*/
public void testVMG6() {
//Test 6.
//This test has a bearing bound of [70, 55), which has a lower bound > upper bound, which is complementary to [55, 70).
double windAngle6 = 5;//TODO
double windAngle6 = 5;
double destAngle6 = 100;
double windSpeed6 = 11;//knots
double vmgAngle6 = 88;
double vmgSpeed6 = 12;
double vmgAngle6 = 92.85;
double vmgSpeed6 = 20.086;
double bearingUpperBound6 = 55;
double bearingLowerBound6 = 70;
@ -147,11 +176,9 @@ public class PolarsTest {
double calcVMGAngle6 = calcVMG6.getBearing();
double calcVMGSpeed6 = calcVMG6.getSpeed();
System.out.println("Test 6 VMG speed = " + calcVMGSpeed6 + " , VMG angle = " + calcVMGAngle6);//TEMP DEBUG REMOVE
//assertEquals(calcVMGAngle6, vmgAngle6, angleEpsilon);
//assertEquals(calcVMGSpeed6, vmgSpeed6, speedEpsilon);
assertEquals(calcVMGAngle6, vmgAngle6, angleEpsilon);
assertEquals(calcVMGSpeed6, vmgSpeed6, speedEpsilon);
if (bearingLowerBound6 > bearingUpperBound6) {
assertTrue((calcVMGAngle6 >= bearingLowerBound6) || (calcVMGAngle6 <= bearingUpperBound6));
} else {
@ -159,6 +186,13 @@ public class PolarsTest {
assertTrue(calcVMGAngle6 < bearingUpperBound6);
}
}
@Test
/**
* Tests if we can calculate VMG for a variety of values.
*/
public void testVMG7() {
//Test 7.
@ -185,7 +219,13 @@ public class PolarsTest {
assertTrue(calcVMGAngle7 < bearingUpperBound7);
}
}
@Test
/**
* Tests if we can calculate VMG for a variety of values.
*/
public void testVMG8() {
//Test 8.
//This test has a bearing bound of [340, 5), which has a lower bound > upper bound, which is complementary to [5, 340). Due to the wind, dest angles, and bearing bounds, it cannot actually find a VMG > 0 (valid VMGs will actually be in the angle interval [10, 190]), so it will return the VMG(angle=0, speed=0).
double windAngle8 = 5;

@ -97,6 +97,7 @@ public class BoatXMLReader extends XMLReader {
/**
* Reads the information about one boat
* Ignored values: ShapeID, StoweName, HullNum, Skipper, Type
* @param boat The node to read boat data from.
*/
private void readSingleBoat(Node boat) {
StreamedBoat streamedBoat;
@ -127,9 +128,12 @@ public class BoatXMLReader extends XMLReader {
}
}
/**
* Reads the positional information about a boat
* Ignored values: FlagPosition, MastTop, Z value of GPSposition
* @param sourceID The source ID of the boat.
* @param GPSPosition The relative GPS position of the boat.
*/
private void readBoatPositionInformation(int sourceID, Node GPSPosition) {
// TODO Get relative point before implementing. (GPSposition is based off a relative point).

@ -138,6 +138,7 @@ public class StreamedCourseXMLReader extends XMLReader {
/**
* Indexes CompoundMark elements by their ID for use in generating the course, and populates list of Markers.
* @throws StreamedCourseXMLException if a CompoundMark element contains an unhandled number of compoundMarks.
* @see seng302.Model.Marker
*/
private void readCompoundMarks() throws StreamedCourseXMLException {

@ -323,6 +323,7 @@ public class ResizableRaceCanvas extends ResizableCanvas {
/**
* Draws all track points for a given boat. Colour is set by boat, opacity by track point.
* @param boat whose track is displayed
* @param colour The color to use for the track.
* @see seng302.Model.TrackPoint
*/
private void drawTrack(Boat boat, Color colour) {

@ -169,8 +169,9 @@ public class RaceXMLReader extends XMLReader implements RaceDataSource {
/**
* gets a marker from the XML file
* @param start base nodelist this should be the tag that contains <coordinate></coordinate>
* @return
*
* @param start base nodelist this should be the tag that contains {@literal <coordinate></coordinate>}.
* @return The Marker object constructed from the XML file.
*/
private Marker getMarker(NodeList start) {
return getMarker(start, 0);
@ -178,9 +179,10 @@ public class RaceXMLReader extends XMLReader implements RaceDataSource {
/**
* gets a marker from the XML file
* @param start base nodelist this should be the tag that contains <coordinate></coordinate>
*
* @param start base nodelist this should be the tag that contains {@literal <coordinate></coordinate>}.
* @param startIndex index in the node that has the coordinate tag
* @return
* @return The Marker object constructed from the XML file.
*/
private Marker getMarker(NodeList start, int startIndex) {
return getMarker(start, startIndex, 0);
@ -188,10 +190,11 @@ public class RaceXMLReader extends XMLReader implements RaceDataSource {
/**
* gets a marker from the XML file
* @param start base nodelist this should be the tag that contains <coordinate></coordinate>
*
* @param start base nodelist this should be the tag that contains {@literal <coordinate></coordinate>}.
* @param startIndex index in the node that has the coordinate tag
* @param nodeIndex coordinate index
* @return
* @param nodeIndex coordinate index
* @return The Marker object constructed from the XML file.
*/
private Marker getMarker(NodeList start, int startIndex, int nodeIndex) {
NodeList nodeList = ((Element) start.item(startIndex)).getElementsByTagName("marker");
@ -200,9 +203,10 @@ public class RaceXMLReader extends XMLReader implements RaceDataSource {
}
/**
* gets a changes a marker to GPS coordinates into a marker
* Constructs a Marker object from an XML element.
*
* @param markerNode marker to turn into coordinates
* @return
* @return The Marker object constructed from the XML element.
*/
private Marker getMarker(Element markerNode) {
@ -221,29 +225,31 @@ public class RaceXMLReader extends XMLReader implements RaceDataSource {
/**
* gets a coordinates from the XML file
* @param start base nodelist this should be the tag that contains <coordinate></coordinate>
* @return
*
* @param start base nodelist this should be the tag that contains {@literal <coordinate></coordinate>}
* @return The GPSCoordinate constructed from the XML file.
*/
private GPSCoordinate getCoordinates(NodeList start) {
return getCoordinates(start, 0);
}
/**
/**
* gets a coordinates from the XML file
* @param start base nodelist this should be the tag that contains <coordinate></coordinate>
*
* @param start base nodelist this should be the tag that contains {@literal <coordinate></coordinate>}.
* @param startIndex the index the tag containing the coordinate should be in
* @return
* @return The GPSCoordinate constructed from the XML file.
*/
private GPSCoordinate getCoordinates(NodeList start, int startIndex) {
return getCoordinates(start, startIndex, 0);
}
/**
* gets a coordinates from the XML file
* @param start base nodelist this should be the tag that contains <coordinate></coordinate>
/**
* Gets a GPSCoordinate from the XML file from a specific node and element.
* @param start base nodelist this should be the tag that contains {@literal <coordinate></coordinate>}.
* @param startIndex the index the tag containing the coordinate should be in
* @param nodeIndex The coordinate index
* @return
* @param nodeIndex The coordinate index
* @return The GPSCoordinate constructed from the XML file.
*/
private GPSCoordinate getCoordinates(NodeList start, int startIndex, int nodeIndex) {
NodeList nodeList = ((Element) start.item(startIndex)).getElementsByTagName("coordinate");
@ -252,10 +258,10 @@ public class RaceXMLReader extends XMLReader implements RaceDataSource {
}
/**
* Returns the coordinate TODO raise exception that runs when the XML is formatted wrongly.
*
* @param coordNode
* @return
* Returns the coordinate object from a coordinate XML element.
* TODO raise exception that runs when the XML is formatted wrongly.
* @param coordNode The XML coordinate element to parse.
* @return The GPSCoordinate constructed from the XML coordinate element.
*/
private GPSCoordinate getCoordinates(Element coordNode) {

@ -151,6 +151,7 @@ public class VisualiserInput implements Runnable {
/**
* Sets the wind direction for the current course.
* @param direction The new wind direction for the course.
*/
private void setCourseWindDirection(double direction) {
this.course.setWindDirection(direction);

Loading…
Cancel
Save