Merge branch 'story36' into 'sprint4_master'

Story36



See merge request !9
main
Hamish Ball 9 years ago
commit adbb8f0a64

@ -31,6 +31,7 @@ public class BoatXMLReader extends XMLReader implements BoatDataSource {
* Constructor for Boat XML * Constructor for Boat XML
* *
* @param filePath Name/path of file to read. Read as a resource. * @param filePath Name/path of file to read. Read as a resource.
* @param boatPolars polars used by the boats
* @throws IOException error * @throws IOException error
* @throws SAXException error * @throws SAXException error
* @throws ParserConfigurationException error * @throws ParserConfigurationException error

@ -38,6 +38,7 @@ public class RaceXMLReader extends XMLReader implements RaceDataSource {
/** /**
* Constructor for Streamed Race XML * Constructor for Streamed Race XML
* @param filePath path of the file * @param filePath path of the file
* @param boatData data for boats in race
* @throws IOException error * @throws IOException error
* @throws SAXException error * @throws SAXException error
* @throws ParserConfigurationException error * @throws ParserConfigurationException error
@ -53,6 +54,7 @@ public class RaceXMLReader extends XMLReader implements RaceDataSource {
/** /**
* Constructor for Streamed Race XML * Constructor for Streamed Race XML
* @param filePath file path to read * @param filePath file path to read
* @param boatData data of the boats in race
* @param read whether or not to read and store the files straight away. * @param read whether or not to read and store the files straight away.
* @throws IOException error * @throws IOException error
* @throws SAXException error * @throws SAXException error

@ -54,6 +54,9 @@ public class Angle implements Comparable<Angle> {
return this.degrees; return this.degrees;
} }
public void setDegrees(double degrees) {
this.degrees = degrees;
}
/** /**
* Returns the value of this Angle object, in radians. * Returns the value of this Angle object, in radians.

@ -3,7 +3,6 @@ package seng302.Model;
import javafx.animation.AnimationTimer; import javafx.animation.AnimationTimer;
import javafx.collections.FXCollections; import javafx.collections.FXCollections;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;
import seng302.Constants; import seng302.Constants;
import seng302.DataInput.RaceDataSource; import seng302.DataInput.RaceDataSource;
import seng302.MockOutput; import seng302.MockOutput;
@ -14,8 +13,6 @@ import seng302.Networking.Messages.Enums.RaceStatusEnum;
import seng302.Networking.Messages.Enums.RaceTypeEnum; import seng302.Networking.Messages.Enums.RaceTypeEnum;
import seng302.Networking.Messages.RaceStatus; import seng302.Networking.Messages.RaceStatus;
import java.io.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
@ -592,9 +589,21 @@ public class Race implements Runnable {
VMG newVMG = this.calculateVMG(boat, bearingBounds); VMG newVMG = this.calculateVMG(boat, bearingBounds);
Azimuth azimuth = Azimuth.fromBearing(boat.getBearing());
GPSCoordinate testBounds = GPSCoordinate.calculateNewPosition(boat.getCurrentPosition(),
(100.0 / Constants.NMToMetersConversion), azimuth);
//If the new vmg improves velocity, use it. //If the new vmg improves velocity, use it.
if (improvesVelocity(boat, newVMG)) { if (improvesVelocity(boat, newVMG)) {
boat.setVMG(newVMG); boat.setVMG(newVMG);
}else if (!GPSCoordinate.isInsideBoundary(testBounds, boundary)){
//checks to see if the new vmg sends the boat out of bounds and if so mirrors its direction in the wind
double currDegrees = newVMG.getBearing().degrees();
double windDirectionDegrees = this.windDirection.degrees();
double tempHeading = (currDegrees - windDirectionDegrees +90)%360;
newVMG.getBearing().setDegrees(tempHeading);
boat.setVMG(newVMG);
} }

@ -33,6 +33,8 @@ public class PolarsTest {
} }
/** /**
* Tests if we can calculate VMG for a variety of values. * Tests if we can calculate VMG for a variety of values.
*/ */

@ -7,23 +7,17 @@ import javafx.fxml.FXML;
import javafx.scene.chart.LineChart; import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis; import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart; import javafx.scene.chart.XYChart;
import javafx.geometry.Pos;
import javafx.scene.control.*; import javafx.scene.control.*;
import javafx.scene.layout.GridPane; import javafx.scene.layout.GridPane;
import javafx.scene.paint.Color;
import javafx.scene.layout.Pane; import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane; import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color; import javafx.scene.paint.Color;
import javafx.scene.paint.Paint;
import seng302.Mock.StreamedRace; import seng302.Mock.StreamedRace;
import seng302.Model.*; import seng302.Model.*;
import seng302.VisualiserInput; import seng302.VisualiserInput;
import java.net.URL; import java.net.URL;
import java.util.*; import java.util.*;
import java.util.ArrayList;
import java.util.Locale;
import java.util.ResourceBundle;
/** /**
* Created by fwy13 on 15/03/2017. * Created by fwy13 on 15/03/2017.
@ -40,6 +34,7 @@ public class RaceController extends Controller {
private ArrayList<String> colours; private ArrayList<String> colours;
private Map<Integer, String> boatColours = new HashMap<>(); private Map<Integer, String> boatColours = new HashMap<>();
private int legNum; private int legNum;
private RaceClock raceClock;
@FXML Pane arrow; @FXML Pane arrow;
@FXML SplitPane race; @FXML SplitPane race;
@FXML StackPane arrowPane; @FXML StackPane arrowPane;
@ -52,6 +47,7 @@ public class RaceController extends Controller {
@FXML CheckBox showName; @FXML CheckBox showName;
@FXML CheckBox showAbbrev; @FXML CheckBox showAbbrev;
@FXML CheckBox showSpeed; @FXML CheckBox showSpeed;
@FXML CheckBox showTime;
@FXML Button saveAnno; @FXML Button saveAnno;
@FXML Button showSetAnno; @FXML Button showSetAnno;
@FXML TableView<Boat> boatInfoTable; @FXML TableView<Boat> boatInfoTable;
@ -138,8 +134,8 @@ public class RaceController extends Controller {
xAxis.setTickMarkVisible(false); xAxis.setTickMarkVisible(false);
xAxis.setTickLabelsVisible(false); xAxis.setTickLabelsVisible(false);
xAxis.setMinorTickVisible(false); xAxis.setMinorTickVisible(false);
xAxis.setUpperBound(startBoats.size()*legNum); xAxis.setUpperBound((startBoats.size()+1)*legNum);
xAxis.setTickUnit(startBoats.size()*legNum); xAxis.setTickUnit((startBoats.size()+1)*legNum);
// set y axis details // set y axis details
@ -173,7 +169,7 @@ public class RaceController extends Controller {
* @param raceClock The RaceClock to use for the race's countdown/elapsed duration + timezone. * @param raceClock The RaceClock to use for the race's countdown/elapsed duration + timezone.
*/ */
public void startRace(VisualiserInput visualiserInput, RaceClock raceClock) { public void startRace(VisualiserInput visualiserInput, RaceClock raceClock) {
StreamedRace newRace = new StreamedRace(visualiserInput, this);
//newRace.initialiseBoats(); //newRace.initialiseBoats();
legNum = visualiserInput.getCourse().getLegs().size()-1; legNum = visualiserInput.getCourse().getLegs().size()-1;
@ -211,6 +207,10 @@ public class RaceController extends Controller {
}); });
}); });
this.raceClock = raceClock;
raceMap.setRaceClock(raceClock);
StreamedRace newRace = new StreamedRace(visualiserInput, this);
initializeFPS(); initializeFPS();
initializeAnnotations(); initializeAnnotations();
@ -357,6 +357,10 @@ public class RaceController extends Controller {
raceMap.toggleAnnoSpeed(); raceMap.toggleAnnoSpeed();
raceMap.update(); raceMap.update();
}); });
showTime.selectedProperty().addListener((ov, old_val, new_val) -> {
raceMap.toggleAnnoTime();
raceMap.update();
});
//listener to save currently selected annotation //listener to save currently selected annotation
saveAnno.setOnAction(event -> { saveAnno.setOnAction(event -> {
presetAnno.clear(); presetAnno.clear();
@ -364,6 +368,7 @@ public class RaceController extends Controller {
presetAnno.add(showAbbrev.isSelected()); presetAnno.add(showAbbrev.isSelected());
presetAnno.add(showSpeed.isSelected()); presetAnno.add(showSpeed.isSelected());
presetAnno.add(showBoatPath.isSelected()); presetAnno.add(showBoatPath.isSelected());
presetAnno.add(showTime.isSelected());
}); });
//listener to show saved annotation //listener to show saved annotation
showSetAnno.setOnAction(event -> { showSetAnno.setOnAction(event -> {
@ -372,6 +377,7 @@ public class RaceController extends Controller {
showAbbrev.setSelected(presetAnno.get(1)); showAbbrev.setSelected(presetAnno.get(1));
showSpeed.setSelected(presetAnno.get(2)); showSpeed.setSelected(presetAnno.get(2));
showBoatPath.setSelected(presetAnno.get(3)); showBoatPath.setSelected(presetAnno.get(3));
showTime.setSelected(presetAnno.get(4));
raceMap.update(); raceMap.update();
} }
}); });
@ -387,4 +393,8 @@ public class RaceController extends Controller {
private void makeArrow() { private void makeArrow() {
arrowPane.getChildren().add(arrow); arrowPane.getChildren().add(arrow);
} }
public RaceClock getRaceClock() {
return raceClock;
}
} }

@ -55,7 +55,8 @@ public class StreamedRace implements Runnable {
if (boat != null) { if (boat != null) {
Leg startLeg = new Leg(name, 0); Leg startLeg = new Leg(name, 0);
startLeg.setEndMarker(endCompoundMark); startLeg.setEndMarker(endCompoundMark);
boat.setCurrentLeg(startLeg); boat.setCurrentLeg(startLeg, controller.getRaceClock());
boat.setTimeSinceLastMark(controller.getRaceClock().getTime());
} }
} }
} }
@ -87,7 +88,7 @@ public class StreamedRace implements Runnable {
if (legNumber >= 1 && legNumber < legs.size()) { if (legNumber >= 1 && legNumber < legs.size()) {
if (boat.getCurrentLeg() != legs.get(legNumber)){ if (boat.getCurrentLeg() != legs.get(legNumber)){
boat.setCurrentLeg(legs.get(legNumber)); boat.setCurrentLeg(legs.get(legNumber), controller.getRaceClock());
legChanged = true; legChanged = true;
} }
} }

@ -6,6 +6,7 @@ import org.geotools.referencing.GeodeticCalculator;
import seng302.GPSCoordinate; import seng302.GPSCoordinate;
import java.awt.geom.Point2D; import java.awt.geom.Point2D;
import java.time.ZonedDateTime;
import java.util.Queue; import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ConcurrentLinkedQueue;
@ -31,6 +32,8 @@ public class Boat {
private final Queue<TrackPoint> track = new ConcurrentLinkedQueue<>(); private final Queue<TrackPoint> track = new ConcurrentLinkedQueue<>();
private long nextValidTime = 0; private long nextValidTime = 0;
private ZonedDateTime timeSinceLastMark;
/** /**
* Boat initializer which keeps all of the information of the boat. * Boat initializer which keeps all of the information of the boat.
* *
@ -181,9 +184,10 @@ public class Boat {
return currentLeg; return currentLeg;
} }
public void setCurrentLeg(Leg currentLeg) { public void setCurrentLeg(Leg currentLeg, RaceClock raceClock) {
this.currentLeg = currentLeg; this.currentLeg = currentLeg;
this.currentLegName.setValue(currentLeg.getName()); this.currentLegName.setValue(currentLeg.getName());
this.setTimeSinceLastMark(raceClock.getTime());
} }
public boolean isFinished() { public boolean isFinished() {
@ -236,4 +240,12 @@ public class Boat {
public void setDnf(boolean dnf) { public void setDnf(boolean dnf) {
this.dnf = dnf; this.dnf = dnf;
} }
public ZonedDateTime getTimeSinceLastMark() {
return timeSinceLastMark;
}
public void setTimeSinceLastMark(ZonedDateTime timeSinceLastMark) {
this.timeSinceLastMark = timeSinceLastMark;
}
} }

@ -12,6 +12,10 @@ import seng302.Mock.StreamedCourse;
import seng302.RaceDataSource; import seng302.RaceDataSource;
import seng302.RaceMap; import seng302.RaceMap;
import java.time.Duration;
import java.time.ZonedDateTime;
import java.time.temporal.ChronoUnit;
import java.util.*; import java.util.*;
/** /**
@ -28,12 +32,15 @@ public class ResizableRaceCanvas extends ResizableCanvas {
private boolean annoAbbrev = true; private boolean annoAbbrev = true;
private boolean annoSpeed = true; private boolean annoSpeed = true;
private boolean annoPath = true; private boolean annoPath = true;
private boolean annoTimeSinceLastMark = true;
private List<Color> colours; private List<Color> colours;
private final List<Marker> markers; private final List<Marker> markers;
private final RaceDataSource raceData; private final RaceDataSource raceData;
private Map<Integer, Color> boatColours = new HashMap<>(); private Map<Integer, Color> boatColours = new HashMap<>();
private Node arrow; private Node arrow;
private RaceClock raceClock;
public ResizableRaceCanvas(RaceDataSource raceData) { public ResizableRaceCanvas(RaceDataSource raceData) {
super(); super();
@ -169,8 +176,9 @@ public class ResizableRaceCanvas extends ResizableCanvas {
* @param abbrev abbreviation of the boat name * @param abbrev abbreviation of the boat name
* @param speed speed of the boat * @param speed speed of the boat
* @param coordinate coordinate the text appears * @param coordinate coordinate the text appears
* @param timeSinceLastMark time since the last mark was passed
*/ */
private void displayText(String name, String abbrev, double speed, GraphCoordinate coordinate) { private void displayText(String name, String abbrev, double speed, GraphCoordinate coordinate, ZonedDateTime timeSinceLastMark) {
String text = ""; String text = "";
//Check name toggle value //Check name toggle value
if (annoName){ if (annoName){
@ -182,7 +190,12 @@ public class ResizableRaceCanvas extends ResizableCanvas {
} }
//Check speed toggle value //Check speed toggle value
if (annoSpeed){ if (annoSpeed){
text += String.format("%.2fkn", speed); text += String.format("%.2fkn ", speed);
}
//Check time since last mark toggle value
if(annoTimeSinceLastMark){
Duration timeSince = Duration.between(timeSinceLastMark, raceClock.getTime());
text += String.format("%d", timeSince.getSeconds());
} }
//String text = String.format("%s, %2$.2fkn", name, speed); //String text = String.format("%s, %2$.2fkn", name, speed);
long xCoord = coordinate.getX() + 20; long xCoord = coordinate.getX() + 20;
@ -264,10 +277,18 @@ public class ResizableRaceCanvas extends ResizableCanvas {
annoName = !annoName; annoName = !annoName;
} }
/**
* Toggle boat path display in annotation
*/
public void toggleBoatPath() { public void toggleBoatPath() {
annoPath = !annoPath; annoPath = !annoPath;
} }
/**
* Toggle boat time display in annotation
*/
public void toggleAnnoTime() { annoTimeSinceLastMark = !annoTimeSinceLastMark;}
/** /**
* Toggle abbreviation display in annotation * Toggle abbreviation display in annotation
*/ */
@ -303,13 +324,17 @@ public class ResizableRaceCanvas extends ResizableCanvas {
displayBoat(boat, 0, boatColours.get(sourceID)); displayBoat(boat, 0, boatColours.get(sourceID));
} }
if (raceAnno) if (raceAnno) {
displayText(boat.toString(), boat.getAbbrev(), boat.getVelocity(), this.map.convertGPS(boat.getCurrentPosition())); if (Duration.between(boat.getTimeSinceLastMark(), raceClock.getTime()).getSeconds() < 0) {
boat.setTimeSinceLastMark(raceClock.getTime());
}
displayText(boat.toString(), boat.getAbbrev(), boat.getVelocity(), this.map.convertGPS(boat.getCurrentPosition()), boat.getTimeSinceLastMark());
//TODO this needs to be fixed. //TODO this needs to be fixed.
drawTrack(boat, boatColours.get(sourceID)); drawTrack(boat, boatColours.get(sourceID));
} }
} }
} }
}
/** /**
* Draws all track points for a given boat. Colour is set by boat, opacity by track point. * Draws all track points for a given boat. Colour is set by boat, opacity by track point.
@ -345,6 +370,10 @@ public class ResizableRaceCanvas extends ResizableCanvas {
this.arrow = arrow; this.arrow = arrow;
} }
public void setRaceClock(RaceClock raceClock) {
this.raceClock = raceClock;
}
private void mapBoatColours() { private void mapBoatColours() {
int currentColour = 0; int currentColour = 0;
for (Boat boat : boats) { for (Boat boat : boats) {

@ -33,8 +33,9 @@
<CheckBox fx:id="showName" layoutY="39.0" mnemonicParsing="false" selected="true" text="Show Boat Name" AnchorPane.leftAnchor="0.0" AnchorPane.topAnchor="26.0" /> <CheckBox fx:id="showName" layoutY="39.0" mnemonicParsing="false" selected="true" text="Show Boat Name" AnchorPane.leftAnchor="0.0" AnchorPane.topAnchor="26.0" />
<CheckBox fx:id="showAbbrev" layoutY="61.0" mnemonicParsing="false" selected="true" text="Show Boat Abbreviation" AnchorPane.leftAnchor="0.0" AnchorPane.topAnchor="52.0" /> <CheckBox fx:id="showAbbrev" layoutY="61.0" mnemonicParsing="false" selected="true" text="Show Boat Abbreviation" AnchorPane.leftAnchor="0.0" AnchorPane.topAnchor="52.0" />
<CheckBox fx:id="showSpeed" layoutY="90.0" mnemonicParsing="false" selected="true" text="Show Boat Speed" AnchorPane.leftAnchor="0.0" AnchorPane.topAnchor="78.0" /> <CheckBox fx:id="showSpeed" layoutY="90.0" mnemonicParsing="false" selected="true" text="Show Boat Speed" AnchorPane.leftAnchor="0.0" AnchorPane.topAnchor="78.0" />
<Button fx:id="saveAnno" layoutX="11.0" layoutY="106.0" maxWidth="154.0" mnemonicParsing="false" prefWidth="154.0" text="Save Annotation" AnchorPane.topAnchor="130.0" /> <CheckBox fx:id="showTime" mnemonicParsing="false" selected="true" text="Show Boat Leg Time" AnchorPane.leftAnchor="0.0" AnchorPane.topAnchor="130.0" />
<Button fx:id="showSetAnno" layoutX="11.0" layoutY="139.0" mnemonicParsing="false" text="Show Set Annotation" AnchorPane.topAnchor="160.0" /> <Button fx:id="saveAnno" layoutX="11.0" layoutY="106.0" maxWidth="154.0" mnemonicParsing="false" prefWidth="154.0" text="Save Annotation" AnchorPane.topAnchor="160.0" />
<Button fx:id="showSetAnno" layoutX="11.0" layoutY="139.0" mnemonicParsing="false" text="Show Set Annotation" AnchorPane.topAnchor="190.0" />
</children> </children>
</AnchorPane> </AnchorPane>
</content> </content>

Loading…
Cancel
Save