Cherry-picked multiple changes from master

main
cbt24 9 years ago
parent 9ca50aa66c
commit d63641c1e2

@ -24,10 +24,18 @@ public class MockBoat extends Boat implements Collider {
*/
private long timeSinceTackChange = 0;
/**
* This stores the boats current status of rounding a mark
* 0: not started rounding
* 1: passed only first check
* 2: passed first and second check
*/
private Integer roundingStatus = 0;
/**
* Stores whether the boat is on autoVMG or not
*/
private boolean autoVMG = true;
private boolean autoVMG = false;
@ -69,7 +77,15 @@ public class MockBoat extends Boat implements Collider {
//Get the start and end points.
GPSCoordinate currentPosition = this.getCurrentPosition();
GPSCoordinate nextMarkerPosition = this.getCurrentLeg().getEndCompoundMark().getAverageGPSCoordinate();
GPSCoordinate nextMarkerPosition;
// if boat is at the finish
if (this.getCurrentLeg().getEndCompoundMark() == null) {
nextMarkerPosition = currentPosition;
}
else {
nextMarkerPosition = this.getCurrentLeg().getEndCompoundMark().getAverageGPSCoordinate();
}
//Calculate bearing.
Bearing bearing = GPSCoordinate.calculateBearing(currentPosition, nextMarkerPosition);
@ -96,9 +112,7 @@ public class MockBoat extends Boat implements Collider {
//Calculate distance.
double distanceNauticalMiles = GPSCoordinate.calculateDistanceNauticalMiles(startPosition, endMarker);
return distanceNauticalMiles;
return GPSCoordinate.calculateDistanceNauticalMiles(startPosition, endMarker);
}
@ -198,7 +212,91 @@ public class MockBoat extends Boat implements Collider {
return distanceTravelledMeters;
}
public boolean isAutoVMG() {
/**
* Check if a mark is on the port side of the boat
* @param mark mark to be passed
* @return true if mark is on port side
*/
public boolean isPortSide(Mark mark){
Bearing towardsMark = GPSCoordinate.calculateBearing(this.getCurrentPosition(), mark.getPosition());
if (towardsMark.degrees() > 315 || towardsMark.degrees() <= 45){
//south quadrant
return this.getBearing().degrees() <= 180;
} else if(towardsMark.degrees() > 45 && towardsMark.degrees() <= 135){
//west quadrant
return (this.getBearing().degrees() <= 270 && this.getBearing().degrees() >= 90);
}else if(towardsMark.degrees() > 135 && towardsMark.degrees() <= 225){
//north quadrant
return this.getBearing().degrees() >= 180;
}else if(towardsMark.degrees() > 225 && towardsMark.degrees() <= 315){
//east quadrant
return (this.getBearing().degrees() <= 90 || this.getBearing().degrees() >= 270);
}else{
//should not reach here
return false;
}
}
/**
* Check if a mark is on the starboard side of the boat
* @param mark mark to be passed
* @return true if mark is on starboard side
*/
public boolean isStarboardSide(Mark mark){
//if this boat is lower than the mark check which way it is facing
Bearing towardsMark = GPSCoordinate.calculateBearing(this.getCurrentPosition(), mark.getPosition());
if (towardsMark.degrees() > 315 || towardsMark.degrees() <= 45){
//south quadrant
return !(this.getBearing().degrees() <= 180);
} else if(towardsMark.degrees() > 45 && towardsMark.degrees() <= 135){
//west quadrant
return !(this.getBearing().degrees() <= 270 && this.getBearing().degrees() >= 90);
}else if(towardsMark.degrees() > 135 && towardsMark.degrees() <= 225){
//north quadrant
return !(this.getBearing().degrees() >= 180);
}else if(towardsMark.degrees() > 225 && towardsMark.degrees() <= 315){
//east quadrant
return !(this.getBearing().degrees() <= 90 || this.getBearing().degrees() >= 270);
}else{
//should not reach here
return false;
}
}
/**
* Used to check if this boat is between a gate
* @param gate the gate to be checked
* @return true if the boat is between two marks that make up a gate
*/
public boolean isBetweenGate(CompoundMark gate){
return (this.isPortSide(gate.getMark1()) && this.isStarboardSide(gate.getMark2())) ||
(this.isStarboardSide(gate.getMark1()) && this.isPortSide(gate.getMark2()));
}
/**
* Used to check if this boat is between a two marks
* @param mark1 the first mark
* @param mark2 the second mark
* @return true if the boat is between two marks
*/
public boolean isBetweenGate(Mark mark1, Mark mark2){
return (this.isPortSide(mark1) && this.isStarboardSide(mark2)) ||
(this.isStarboardSide(mark1) && this.isPortSide(mark2));
}
public Integer getRoundingStatus() {
return Integer.valueOf(roundingStatus);
}
public void increaseRoundingStatus() {
this.roundingStatus++;
}
public void resetRoundingStatus() {
this.roundingStatus = 0;
}
public boolean getAutoVMG(){
return autoVMG;
}

@ -1,19 +1,15 @@
package mock.model;
import mock.model.collider.ColliderRegistry;
import network.Messages.Enums.BoatStatusEnum;
import network.Messages.Enums.RaceStatusEnum;
import network.Messages.LatestMessages;
import org.opengis.geometry.primitive.*;
import shared.dataInput.BoatDataSource;
import shared.dataInput.RaceDataSource;
import network.Messages.Enums.RaceStatusEnum;
import shared.dataInput.RegattaDataSource;
import shared.model.*;
import shared.model.Bearing;
import java.time.ZonedDateTime;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalUnit;
import java.util.*;
import static java.lang.Math.cos;
@ -53,13 +49,13 @@ public class MockRace extends Race {
* @param boatDataSource Data source for boat related data (yachts and marker boats).
* @param raceDataSource Data source for race related data (participating boats, legs, etc...).
* @param regattaDataSource Data source for race related data (course name, location, timezone, etc...).
* @param latestMessages The LatestMessages to send events to.
* @param polars The polars table to be used for boat simulation.
* @param timeScale The timeScale for the race. See {@link Constants#RaceTimeScale}.
* @param windGenerator The wind generator used for the race.
*/
public MockRace(BoatDataSource boatDataSource, RaceDataSource raceDataSource, RegattaDataSource regattaDataSource, LatestMessages latestMessages, Polars polars, int timeScale) {
public MockRace(BoatDataSource boatDataSource, RaceDataSource raceDataSource, RegattaDataSource regattaDataSource, Polars polars, int timeScale, WindGenerator windGenerator) {
super(boatDataSource, raceDataSource, regattaDataSource, latestMessages);
super(boatDataSource, raceDataSource, regattaDataSource);
this.scaleFactor = timeScale;
@ -67,14 +63,8 @@ public class MockRace extends Race {
this.shrinkBoundary = GPSCoordinate.getShrinkBoundary(this.boundary);
//Set up wind generator. It may be tidier to create this outside the race (with the values sourced from a data file maybe?) and pass it in.
this.windGenerator = new WindGenerator(
Bearing.fromDegrees(225),
Bearing.fromDegrees(215),
Bearing.fromDegrees(235),
12d,
8d,
16d );
this.windGenerator = windGenerator;
//Wind.
this.setWind(windGenerator.generateBaselineWind());
@ -341,7 +331,7 @@ public class MockRace extends Race {
boat.moveForwards(distanceTravelledMeters);
boat.setTimeSinceTackChange(boat.getTimeSinceTackChange() + updatePeriodMilliseconds);
if (boat.isAutoVMG()) {
if (boat.getAutoVMG()) {
newOptimalVMG(boat);
}
@ -351,7 +341,7 @@ public class MockRace extends Race {
}
private void newOptimalVMG(MockBoat boat) {
long tackPeriod = 15000;
long tackPeriod = 1000;
if (boat.getTimeSinceTackChange() > tackPeriod) {
//Calculate the new VMG.
@ -375,8 +365,8 @@ public class MockRace extends Race {
this.getWindDirection(),
this.getWindSpeed(),
boat.getBearing(),
boat.getBearing(),
boat.getBearing());
Bearing.fromDegrees(boat.getBearing().degrees() - 1),
Bearing.fromDegrees(boat.getBearing().degrees() + 1));
if (vmg.getSpeed() > 0) {
boat.setCurrentSpeed(vmg.getSpeed());
}

@ -7,7 +7,6 @@ import javafx.beans.property.SimpleObjectProperty;
import mock.model.collider.ColliderRegistry;
import network.Messages.Enums.RaceStatusEnum;
import network.Messages.Enums.RaceTypeEnum;
import network.Messages.LatestMessages;
import shared.dataInput.BoatDataSource;
import shared.dataInput.RaceDataSource;
import shared.dataInput.RegattaDataSource;
@ -33,11 +32,6 @@ public abstract class Race {
* The source of regatta related data.
*/
protected RegattaDataSource regattaDataSource;
/**
* The collection of latest race messages.
* Can be either read from or written to.
*/
protected LatestMessages latestMessages;
/**
* A list of compound marks in the race.
*/
@ -80,7 +74,7 @@ public abstract class Race {
protected ColliderRegistry colliderRegistry;
/**
* The number of frames per second.
* We essentially track the number of frames generated per second, over a one second period. When {@link #lastFpsResetTime} reaches 1 second, {@link #currentFps} is reset.
* We essentially track the number of frames generated per second, over a one second period. When {@link #lastFpsResetTime} reaches 1 second, currentFps is reset.
*/
private int currentFps = 0;
/**
@ -92,53 +86,38 @@ public abstract class Race {
*/
private long lastFpsResetTime;
/**
* Constructs a race object with a given BoatDataSource, RaceDataSource, and RegattaDataSource.
* @param boatDataSource Data source for boat related data (yachts and marker boats).
* @param raceDataSource Data source for race related data (participating boats, legs, etc...).
* @param regattaDataSource Data source for race related data (course name, location, timezone, etc...).
* @param latestMessages The collection of latest messages, which can be written to, or read from.
*/
public Race(BoatDataSource boatDataSource, RaceDataSource raceDataSource, RegattaDataSource regattaDataSource, LatestMessages latestMessages) {
public Race(BoatDataSource boatDataSource, RaceDataSource raceDataSource, RegattaDataSource regattaDataSource) {
//Keep a reference to data sources.
this.raceDataSource = raceDataSource;
this.boatDataSource = boatDataSource;
this.regattaDataSource = regattaDataSource;
this.latestMessages = latestMessages;
//Marks.
this.compoundMarks = raceDataSource.getCompoundMarks();
//Boundaries.
this.boundary = raceDataSource.getBoundary();
//Legs.
this.useLegsList(raceDataSource.getLegs());
//Race ID.
this.raceId = raceDataSource.getRaceId();
//Regatta name.
this.regattaName = regattaDataSource.getRegattaName();
//Race clock.
this.raceClock = new RaceClock(this.raceDataSource.getStartDateTime());
//Race status.
this.setRaceStatusEnum(RaceStatusEnum.NOT_ACTIVE);
//Race type.
this.raceType = raceDataSource.getRaceType();
//Wind.
this.setWind(Bearing.fromDegrees(0), 0);
// Set up colliders
this.colliderRegistry = new ColliderRegistry();
this.colliderRegistry.addAllColliders(compoundMarks);
}
@ -153,7 +132,6 @@ public abstract class Race {
*/
protected abstract void initialiseBoats();
/**
* Updates the race to use a new list of legs, and adds a dummy "Finish" leg at the end.
* @param legs The new list of legs to use.
@ -185,10 +163,6 @@ public abstract class Race {
return legID == lastLegID;
}
/**
* Returns the current race status.
* @return The current race status.
@ -205,7 +179,6 @@ public abstract class Race {
this.raceStatusEnum = raceStatusEnum;
}
/**
* Returns the type of race this is.
* @return The type of race this is.
@ -222,7 +195,6 @@ public abstract class Race {
return regattaName;
}
/**
* Updates the race to have a specified wind bearing and speed.
* @param windBearing New wind bearing.
@ -241,7 +213,6 @@ public abstract class Race {
this.raceWind.setValue(wind);
}
/**
* Returns the wind bearing.
* @return The wind bearing.
@ -268,7 +239,6 @@ public abstract class Race {
return raceClock;
}
/**
* Returns the RaceDataSource used for the race.
* @return The RaceDataSource used for the race.
@ -286,7 +256,6 @@ public abstract class Race {
return legs.size() - 1;
}
/**
* Returns the race boundary.
* @return The race boundary.
@ -295,12 +264,21 @@ public abstract class Race {
return boundary;
}
/**
* Returns the marks of the race.
* @return Marks of the race.
*/
public List<CompoundMark> getCompoundMarks() {
return compoundMarks;
}
/**
* Returns the number of frames generated per second.
* @return Frames per second.
* Returns the legs of the race.
* @return Legs of the race.
*/
public int getFps() {
return lastFps.getValue();
public List<Leg> getLegs() {
return legs;
}
/**
@ -311,7 +289,6 @@ public abstract class Race {
return lastFps;
}
/**
* Increments the FPS counter, and adds timePeriod milliseconds to our FPS reset timer.
* @param timePeriod Time, in milliseconds, to add to {@link #lastFpsResetTime}.

Loading…
Cancel
Save