Removed some unneccessary code and comments from PolarParser.parse(...).

Fixed a bug where the polar parser would attempt to insert (wind speed, windspeed, windangle) instead of (windspeed, windangle, boatspeed).
Removed some unused constructors from RaceXMLReader, and fixed a bug where it wouldn't actually use the polar table correctly.
Boat's constructor now expects a Polars table.
Added some comments to the Polars class, and specified the HashMap's template parameters
Added PolarsTest - which needs to be implemented properly when the VMG calculations have been added.

#story[900]
main
fjc40 9 years ago
parent 4f8d6b14d4
commit 693da8a82a

@ -5,6 +5,7 @@ import javafx.application.Application;
import javafx.stage.Stage;
import org.xml.sax.SAXException;
import seng302.DataInput.*;
import seng302.Exceptions.InvalidPolarFileException;
import seng302.Model.Event;
import seng302.Model.Polars;
@ -37,6 +38,8 @@ public class App extends Application {
e.printStackTrace();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (InvalidPolarFileException e) {
e.printStackTrace();
}
}
}

@ -50,18 +50,13 @@ public class PolarParser {
//Angles are expected to be in degrees, and velocities in knots.
//We read the heading and data rows, and split them into arrays of elements.
String[] headings;
//We read data rows, and split them into arrays of elements.
ArrayList<String[]> dataRows = new ArrayList<>(7);
try {
//Heading.
//Read heading row.
//Heading row.
//We skip the heading row by reading it.
String headingRow = inputStream.readLine();
//Split it into individual headings.
headings = headingRow.split(",");
//Data rows.
while (inputStream.ready()) {
//Read line.
@ -83,13 +78,13 @@ public class PolarParser {
//For each row...
int rowNumber = 0;
for (String[] row : dataRows) {
//Create Polar row object.
//For each column...
for (int i = 0; i < row.length / 2; i += 2) {
//For each pair of columns (the pair is angle, speed).
//We start at column 1 since column 0 is the wind speed column.
// (row.length - 1) / 2 means the number of pairs of angle+speed.
for (int i = 1; i < (row.length - 1) / 2; i += 2) {
//Convert value to a double.
Double value;
//Add angle+speed=velocity estimate to polar table.
try {
//Add the polar value to the polar table
polarTable.addEstimate( Double.parseDouble(row[0]), Double.parseDouble(row[i]), Double.parseDouble(row[i + 1]));
@ -104,7 +99,6 @@ public class PolarParser {
}
return polarTable;
}

@ -25,48 +25,35 @@ public class RaceXMLReader extends XMLReader implements RaceDataSource {
private GPSCoordinate mapTopLeft, mapBottomRight;
private List<GPSCoordinate> boundary = new ArrayList<>();
private List<Marker> markers = new ArrayList<>();
///Filename to read data from.
private String filePath;
///The polar table object to assign to each boat.
private Polars boatPolars;
/**
* Constractor for Race XML
*
* @param filePath path of the file
* @throws IOException error
* @throws SAXException error
* @throws ParserConfigurationException error
*/
public RaceXMLReader(String filePath) throws IOException, SAXException, ParserConfigurationException {
this(filePath, true);
}
/**
* Constractor for Race XML
*
* @param filePath path of the file
* @param filePath The path to the file to read data from.
* @param boatPolars The polar table to assign to each boat.
* @throws IOException error
* @throws SAXException error
* @throws ParserConfigurationException error
*/
public RaceXMLReader(String filePath, Polars boatPolars) throws IOException, SAXException, ParserConfigurationException {
this(filePath, true);
this.boatPolars = boatPolars;
}
/**
* COnstructor for Race XML
*
* @param filePath file path to read
* @param read whether or not to read and store the files straight away.
* @throws IOException error
* @throws SAXException error
* @throws ParserConfigurationException error
*/
public RaceXMLReader(String filePath, boolean read) throws IOException, SAXException, ParserConfigurationException {
super(filePath);
if (read) {
this.filePath = filePath;
this.boatPolars = boatPolars;
read();
}
}
/**
* Read the files
@ -100,8 +87,9 @@ public class RaceXMLReader extends XMLReader implements RaceDataSource {
String abbrev = getTextValueOfNode((Element) nBoats.item(i), "abbr");
double velo = Double.parseDouble(getTextValueOfNode((Element) nBoats.item(i), "speed"));
int sourceID = Integer.parseInt(getTextValueOfNode((Element) nBoats.item(i), "sourceID"));
Boat boat = new Boat(name, velo, abbrev, sourceID);
boat.setPolars(boatPolars);
Boat boat = new Boat(name, velo, abbrev, sourceID, this.boatPolars);
boat.setCurrentPosition(startPt1);
if (legs.size() > 0) {
boat.setCurrentLeg(legs.get(0));

@ -29,12 +29,14 @@ public class Boat {
* @param velocity Speed in m/s that the boat travels at.
* @param abbrev nam abbreviation
* @param sourceID id of boat
* @param polars The polars table to use for this boat.
*/
public Boat(String name, double velocity, String abbrev, int sourceID) {
public Boat(String name, double velocity, String abbrev, int sourceID, Polars polars) {
this.velocity = velocity;
this.abbrev = abbrev;
this.name = name;
this.sourceID = sourceID;
this.polars = polars;
}
/**

@ -7,19 +7,40 @@ import java.util.HashMap;
/**
* Created by hba56 on 10/05/17.
*/
/**
* Encapsulates an entire polar table. Has a function to calculate VMG.
*/
public class Polars {
private HashMap polarValues;
///Internal store of data. Maps pair<windSpeed, windAngle> to boatSpeed.
private HashMap<Pair<Double, Double>, Double> polarValues = new HashMap<>();
/**
* Ctor.
*/
public Polars() {
polarValues = new HashMap();
}
/**
* Adds an estimated velocity to the polar table object, for a given (windSpeed, windAngle) pair. That is, stores a mapping from (windSpeed, windAngle) to (boatVelocity).
* @param trueWindSpeed The true wind speed of the estimate.
* @param trueWindAngle The true wind angle of the estimate.
* @param boatSpeed The boat speed of the estimate.
*/
public void addEstimate(double trueWindSpeed, double trueWindAngle, double boatSpeed){
Pair newKey = new Pair(trueWindSpeed, trueWindAngle);
polarValues.put(newKey, boatSpeed);
}
public HashMap getPolarValues() {
//TODO calculate VMG from (windAngle, destAngle, windSpeed).
/**
* Returns the hashmap used to store polar data.
* @return A hashmap containing estimated boat speeds for a given (windSpeed, windAngle) pair.
*/
public HashMap<Pair<Double, Double>, Double> getPolarValues() {
return polarValues;
}
}

@ -6,6 +6,7 @@ import org.junit.Test;
import org.xml.sax.SAXException;
import seng302.DataInput.RaceDataSource;
import seng302.DataInput.RaceXMLReader;
import seng302.Model.Polars;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
@ -33,7 +34,7 @@ public class BoatDataTest {
@Before
public void initReader() {
try {
raceDataSource = new RaceXMLReader("raceXML/bermuda_AC35.xml");
raceDataSource = new RaceXMLReader("raceXML/bermuda_AC35.xml", new Polars());
BoatData boatData = new BoatData(raceDataSource.getBoats());
result = boatData.createXML();

@ -5,6 +5,7 @@ import org.junit.Test;
import org.xml.sax.SAXException;
import seng302.DataInput.RaceDataSource;
import seng302.DataInput.RaceXMLReader;
import seng302.Model.Polars;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
@ -27,7 +28,7 @@ public class RaceDataTest {
@Before
public void initReader() {
try {
raceDataSource = new RaceXMLReader("raceXML/bermuda_AC35.xml");
raceDataSource = new RaceXMLReader("raceXML/bermuda_AC35.xml", new Polars());
RaceData raceData = new RaceData(raceDataSource);
result = raceData.createXML();

@ -1,6 +1,9 @@
package seng302.DataInput;
import org.testng.annotations.Test;
import seng302.Exceptions.InvalidPolarFileException;
import seng302.Model.Polars;
import java.io.File;
@ -17,10 +20,19 @@ public class PolarParserTest {
*/
public void testParse() throws Exception {
try {
//Parse data file.
Polars polars = PolarParser.parse("polars/acc_polars.csv");
//Polars = PolarParser.parse("polars/acc_polars.csv");
//If the parse function didn't through, it worked.
assertTrue(true);
}
catch (InvalidPolarFileException e) {
assertTrue(false);
}
}
}

@ -13,7 +13,7 @@ public class BoatTest {
private GPSCoordinate ORIGIN_COORDS = new GPSCoordinate(0, 0);
private Boat TEST_BOAT = new Boat("Test", 1, "tt", 1);
private Boat TEST_BOAT = new Boat("Test", 1, "tt", 1, new Polars());
@Test
public void calculateDueNorthAzimuthReturns0() {

@ -0,0 +1,47 @@
package seng302.Model;
import org.testng.annotations.Test;
import seng302.DataInput.PolarParser;
import seng302.Exceptions.InvalidPolarFileException;
import static org.testng.Assert.*;
/**
* Created by f123 on 10-May-17.
*/
public class PolarsTest {
@Test
/**
* 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.
*/
public void testParseAndVMG() throws Exception {
//Read data.
Polars polars;
try {
//Parse data file.
polars = PolarParser.parse("polars/acc_polars.csv");
}
catch (InvalidPolarFileException e) {
assertTrue(false);
}
//Test 1.
//TODO make these tests actually do something when the calculateVMG function is added.
double windAngle1 = 31.5;
double destAngle1 = 65.32;
double windSpeed1 = 15;//knots
//double vmgAngle1 = TODO;
//double vmgSpeed1 = TODO;
//VMG calcVMG1 = Polars.calculateVMG(windAngle1, destAngle1, windSpeed1);
//double calcVMGAngle1 = calcVMG1.getKey();
//double calcVMGSpeed1 = calcVMG1.getValue();
//assertEquals(vmgAngle1, calcVMGAngle1, 0.1);
//assertEquals(vmgSpeed1, calcVMGSpeed1, 0.1);
}
}

@ -17,7 +17,7 @@ public class RaceXMLTest {
@Test
public void canFindFile() {
try {
RaceXMLReader raceXMLReader = new RaceXMLReader("raceXML/bermuda_AC35.xml", false);
RaceXMLReader raceXMLReader = new RaceXMLReader("raceXML/bermuda_AC35.xml", new Polars());
} catch (Exception e) {
fail("Cannot find raceXML/bermuda_AC35.xml in the resources folder");
}
@ -27,7 +27,7 @@ public class RaceXMLTest {
@Test
public void canReadBoats() {
try {
RaceXMLReader raceXMLReader = new RaceXMLReader("raceXML/bermuda_AC35.xml", false);
RaceXMLReader raceXMLReader = new RaceXMLReader("raceXML/bermuda_AC35.xml", new Polars());
raceXMLReader.readBoats();
List<Boat> boats = raceXMLReader.getBoats();
assertTrue(boats.size() == 6);
@ -62,7 +62,7 @@ public class RaceXMLTest {
@Test
public void canReadLegs() {
try {
RaceXMLReader raceXMLReader = new RaceXMLReader("raceXML/bermuda_AC35.xml", false);
RaceXMLReader raceXMLReader = new RaceXMLReader("raceXML/bermuda_AC35.xml", new Polars());
raceXMLReader.readLegs();
assertTrue(raceXMLReader.getLegs().size() == 5);
} catch (Exception e) {
@ -73,7 +73,7 @@ public class RaceXMLTest {
@Test
public void canReadCourse() {
try {
RaceXMLReader raceXMLReader = new RaceXMLReader("raceXML/bermuda_AC35.xml", false);
RaceXMLReader raceXMLReader = new RaceXMLReader("raceXML/bermuda_AC35.xml", new Polars());
raceXMLReader.readCourse();
assertTrue(raceXMLReader.getMapTopLeft() != null);
assertTrue(raceXMLReader.getMapBottomRight() != null);

@ -0,0 +1,8 @@
Tws,Twa0,Bsp0,Twa1,Bsp1,UpTwa,UpBsp,Twa2,Bsp2,Twa3,Bsp3,Twa4,Bsp4,Twa5,Bsp5,Twa6,Bsp6,DnTwa,DnBsp,Twa7,Bsp7
4,0,0,30,4,45,8,60,9,75,10,90,10,115,10,145,10,155,10,175,4
8,0,0,30,7,43,10,60,11,75,11,90,11,115,12,145,12,153,12,175,10
12,0,0,30,11,43,14.4,60,16,75,20,90,23,115,24,145,23,153,21.6,175,14
16,0,0,30,12,42,19.2,60,25,75,27,90,31,115,32,145,30,153,28.8,175,20
20,0,0,30,13,41,24,60,29,75,37,90,39,115,40,145,38,153,36,175,24
25,0,0,30,15,40,30,60,38,75,44,90,49,115,50,145,49,151,47,175,30
30,0,0,30,15,42,30,60,37,75,42,90,48,115,49,145,48,150,46,175,32
1 Tws Twa0 Bsp0 Twa1 Bsp1 UpTwa UpBsp Twa2 Bsp2 Twa3 Bsp3 Twa4 Bsp4 Twa5 Bsp5 Twa6 Bsp6 DnTwa DnBsp Twa7 Bsp7
2 4 0 0 30 4 45 8 60 9 75 10 90 10 115 10 145 10 155 10 175 4
3 8 0 0 30 7 43 10 60 11 75 11 90 11 115 12 145 12 153 12 175 10
4 12 0 0 30 11 43 14.4 60 16 75 20 90 23 115 24 145 23 153 21.6 175 14
5 16 0 0 30 12 42 19.2 60 25 75 27 90 31 115 32 145 30 153 28.8 175 20
6 20 0 0 30 13 41 24 60 29 75 37 90 39 115 40 145 38 153 36 175 24
7 25 0 0 30 15 40 30 60 38 75 44 90 49 115 50 145 49 151 47 175 30
8 30 0 0 30 15 42 30 60 37 75 42 90 48 115 49 145 48 150 46 175 32

@ -62,7 +62,7 @@ public class StartController extends Controller implements Observer {
*/
private void startRaceNoScaling() {
//startRace(1);
while(visualiserInput.getRaceStatus() == null);//TODO probably remove this.
//while(visualiserInput.getRaceStatus() == null);//TODO probably remove this.
countdownTimer();
}

@ -219,7 +219,7 @@ public class VisualiserInput implements Runnable {
//If no heartbeat has been received in more the heartbeat period
//then the connection will need to be restarted.
System.out.println("time since last heartbeat: " + timeSinceHeartbeat());//TEMP REMOVE
//System.out.println("time since last heartbeat: " + timeSinceHeartbeat());//TEMP REMOVE
long heartBeatPeriod = 10 * 1000;
if (timeSinceHeartbeat() > heartBeatPeriod) {
System.out.println("Connection has stopped, trying to reconnect.");

Loading…
Cancel
Save