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; 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 * 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. //Get the start and end points.
GPSCoordinate currentPosition = this.getCurrentPosition(); 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. //Calculate bearing.
Bearing bearing = GPSCoordinate.calculateBearing(currentPosition, nextMarkerPosition); Bearing bearing = GPSCoordinate.calculateBearing(currentPosition, nextMarkerPosition);
@ -96,9 +112,7 @@ public class MockBoat extends Boat implements Collider {
//Calculate distance. //Calculate distance.
double distanceNauticalMiles = GPSCoordinate.calculateDistanceNauticalMiles(startPosition, endMarker); return GPSCoordinate.calculateDistanceNauticalMiles(startPosition, endMarker);
return distanceNauticalMiles;
} }
@ -198,7 +212,91 @@ public class MockBoat extends Boat implements Collider {
return distanceTravelledMeters; 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; return autoVMG;
} }

@ -1,19 +1,15 @@
package mock.model; package mock.model;
import mock.model.collider.ColliderRegistry;
import network.Messages.Enums.BoatStatusEnum; import network.Messages.Enums.BoatStatusEnum;
import network.Messages.Enums.RaceStatusEnum;
import network.Messages.LatestMessages; import network.Messages.LatestMessages;
import org.opengis.geometry.primitive.*;
import shared.dataInput.BoatDataSource; import shared.dataInput.BoatDataSource;
import shared.dataInput.RaceDataSource; import shared.dataInput.RaceDataSource;
import network.Messages.Enums.RaceStatusEnum;
import shared.dataInput.RegattaDataSource; import shared.dataInput.RegattaDataSource;
import shared.model.*; import shared.model.*;
import shared.model.Bearing;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
import java.time.temporal.ChronoUnit; import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalUnit;
import java.util.*; import java.util.*;
import static java.lang.Math.cos; 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 boatDataSource Data source for boat related data (yachts and marker boats).
* @param raceDataSource Data source for race related data (participating boats, legs, etc...). * @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 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 polars The polars table to be used for boat simulation.
* @param timeScale The timeScale for the race. See {@link Constants#RaceTimeScale}. * @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; this.scaleFactor = timeScale;
@ -67,14 +63,8 @@ public class MockRace extends Race {
this.shrinkBoundary = GPSCoordinate.getShrinkBoundary(this.boundary); 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( this.windGenerator = windGenerator;
Bearing.fromDegrees(225),
Bearing.fromDegrees(215),
Bearing.fromDegrees(235),
12d,
8d,
16d );
//Wind. //Wind.
this.setWind(windGenerator.generateBaselineWind()); this.setWind(windGenerator.generateBaselineWind());
@ -341,7 +331,7 @@ public class MockRace extends Race {
boat.moveForwards(distanceTravelledMeters); boat.moveForwards(distanceTravelledMeters);
boat.setTimeSinceTackChange(boat.getTimeSinceTackChange() + updatePeriodMilliseconds); boat.setTimeSinceTackChange(boat.getTimeSinceTackChange() + updatePeriodMilliseconds);
if (boat.isAutoVMG()) { if (boat.getAutoVMG()) {
newOptimalVMG(boat); newOptimalVMG(boat);
} }
@ -351,7 +341,7 @@ public class MockRace extends Race {
} }
private void newOptimalVMG(MockBoat boat) { private void newOptimalVMG(MockBoat boat) {
long tackPeriod = 15000; long tackPeriod = 1000;
if (boat.getTimeSinceTackChange() > tackPeriod) { if (boat.getTimeSinceTackChange() > tackPeriod) {
//Calculate the new VMG. //Calculate the new VMG.
@ -375,8 +365,8 @@ public class MockRace extends Race {
this.getWindDirection(), this.getWindDirection(),
this.getWindSpeed(), this.getWindSpeed(),
boat.getBearing(), boat.getBearing(),
boat.getBearing(), Bearing.fromDegrees(boat.getBearing().degrees() - 1),
boat.getBearing()); Bearing.fromDegrees(boat.getBearing().degrees() + 1));
if (vmg.getSpeed() > 0) { if (vmg.getSpeed() > 0) {
boat.setCurrentSpeed(vmg.getSpeed()); boat.setCurrentSpeed(vmg.getSpeed());
} }

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

Loading…
Cancel
Save