|
|
|
@ -19,6 +19,10 @@ import java.util.ArrayList;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.Random;
|
|
|
|
import java.util.Random;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import static java.lang.Math.cos;
|
|
|
|
|
|
|
|
import static java.lang.Math.max;
|
|
|
|
|
|
|
|
import static java.lang.Math.min;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* Parent class for races
|
|
|
|
* Parent class for races
|
|
|
|
@ -41,6 +45,7 @@ public class Race implements Runnable {
|
|
|
|
private MockOutput mockOutput;
|
|
|
|
private MockOutput mockOutput;
|
|
|
|
private static int boatOffset = 0;
|
|
|
|
private static int boatOffset = 0;
|
|
|
|
private int finished = 0;
|
|
|
|
private int finished = 0;
|
|
|
|
|
|
|
|
private List<GPSCoordinate> boundary;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
@ -50,7 +55,7 @@ public class Race implements Runnable {
|
|
|
|
* @param legs Number of marks in order that the boats pass in order to complete the race.
|
|
|
|
* @param legs Number of marks in order that the boats pass in order to complete the race.
|
|
|
|
* @param scaleFactor for race
|
|
|
|
* @param scaleFactor for race
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public Race(List<Boat> boats, List<Leg> legs, int raceID, int scaleFactor, MockOutput mockOutput) {
|
|
|
|
public Race(List<Boat> boats, List<Leg> legs, int raceID, int scaleFactor, MockOutput mockOutput, List<GPSCoordinate> boundary) {
|
|
|
|
|
|
|
|
|
|
|
|
this.startingBoats = FXCollections.observableArrayList(boats);
|
|
|
|
this.startingBoats = FXCollections.observableArrayList(boats);
|
|
|
|
this.legs = legs;
|
|
|
|
this.legs = legs;
|
|
|
|
@ -58,6 +63,7 @@ public class Race implements Runnable {
|
|
|
|
this.raceId = raceID;
|
|
|
|
this.raceId = raceID;
|
|
|
|
this.scaleFactor = scaleFactor;
|
|
|
|
this.scaleFactor = scaleFactor;
|
|
|
|
this.mockOutput = mockOutput;
|
|
|
|
this.mockOutput = mockOutput;
|
|
|
|
|
|
|
|
this.boundary = boundary;
|
|
|
|
|
|
|
|
|
|
|
|
//TODO refactor
|
|
|
|
//TODO refactor
|
|
|
|
this.startTime = System.currentTimeMillis() + (this.PRERACE_TIME / this.scaleFactor);
|
|
|
|
this.startTime = System.currentTimeMillis() + (this.PRERACE_TIME / this.scaleFactor);
|
|
|
|
@ -69,7 +75,7 @@ public class Race implements Runnable {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public Race(RaceDataSource raceData, int scaleFactor, MockOutput mockOutput) {
|
|
|
|
public Race(RaceDataSource raceData, int scaleFactor, MockOutput mockOutput) {
|
|
|
|
this(raceData.getBoats(), raceData.getLegs(), raceData.getRaceId(), scaleFactor, mockOutput);
|
|
|
|
this(raceData.getBoats(), raceData.getLegs(), raceData.getRaceId(), scaleFactor, mockOutput, raceData.getBoundary());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
@ -298,16 +304,57 @@ public class Race implements Runnable {
|
|
|
|
|
|
|
|
|
|
|
|
boolean finish = boat.getCurrentLeg().getName().equals("Finish");
|
|
|
|
boolean finish = boat.getCurrentLeg().getName().equals("Finish");
|
|
|
|
if (!finish) {
|
|
|
|
if (!finish) {
|
|
|
|
|
|
|
|
int windAngle = 360;//todo - get the wind speed from somewhere, using 360 for now
|
|
|
|
|
|
|
|
if(boat.getCurrentLeg().getName().endsWith("to Windward Gate")){//todo something is broken in this if statement, not sure what
|
|
|
|
|
|
|
|
double totalDistanceTravelledInTack = distanceTravelled + boat.getDistanceTravelledInTack();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
double bound1 = (boat.calculateBearingToDestination()-90)%360;
|
|
|
|
|
|
|
|
double bound2 = (boat.calculateBearingToDestination()+90)%360;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
VMG newHeading = boat.getPolars().calculateVMG(windAngle, 30,
|
|
|
|
|
|
|
|
boat.calculateBearingToDestination(), min(bound1, bound2), max(bound1,bound2));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
double azimuth = newHeading.bearing;
|
|
|
|
|
|
|
|
if (newHeading.bearing > 180){
|
|
|
|
|
|
|
|
azimuth = newHeading.bearing -360;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// if (!GPSCoordinate.isInsideBoundary(calculatePosition(boat.getCurrentPosition(),
|
|
|
|
|
|
|
|
// 1, azimuth), boundary)){
|
|
|
|
|
|
|
|
// System.out.println("LDFSGSDFG");
|
|
|
|
|
|
|
|
// double tempHeading = (newHeading.bearing+90)%360;
|
|
|
|
|
|
|
|
// newHeading.bearing = tempHeading;
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
boat.setHeading(newHeading.bearing);
|
|
|
|
|
|
|
|
boat.setVelocity(newHeading.speed);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//calc the distance travelled in a straight line to windward
|
|
|
|
|
|
|
|
double angleBetweenDestAndHeading = newHeading.bearing - boat.calculateBearingToDestination();
|
|
|
|
|
|
|
|
totalDistanceTravelled = cos(angleBetweenDestAndHeading)*totalDistanceTravelledInTack;
|
|
|
|
|
|
|
|
boat.setDistanceTravelledInLeg(totalDistanceTravelled);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//Calculate boat's new position by adding the distance travelled onto the start point of the leg
|
|
|
|
|
|
|
|
boat.setCurrentPosition(calculatePosition(boat.getCurrentPosition(),
|
|
|
|
|
|
|
|
totalDistanceTravelledInTack, azimuth));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}else{
|
|
|
|
boat.setHeading(boat.calculateHeading());
|
|
|
|
boat.setHeading(boat.calculateHeading());
|
|
|
|
//update boat's distance travelled
|
|
|
|
//update boat's distance travelled
|
|
|
|
boat.setDistanceTravelledInLeg(totalDistanceTravelled);
|
|
|
|
boat.setDistanceTravelledInLeg(totalDistanceTravelled);
|
|
|
|
//Calculate boat's new position by adding the distance travelled onto the start point of the leg
|
|
|
|
//Calculate boat's new position by adding the distance travelled onto the start point of the leg
|
|
|
|
boat.setCurrentPosition(calculatePosition(boat.getCurrentLeg().getStartMarker().getAverageGPSCoordinate(),
|
|
|
|
boat.setCurrentPosition(calculatePosition(boat.getCurrentLeg().getStartMarker().getAverageGPSCoordinate(),
|
|
|
|
totalDistanceTravelled, boat.calculateAzimuth()));
|
|
|
|
totalDistanceTravelled, boat.calculateAzimuth(boat.getCurrentLeg().getStartMarker().getAverageGPSCoordinate(),
|
|
|
|
|
|
|
|
boat.getCurrentLeg().getEndMarker().getAverageGPSCoordinate())));
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
protected void checkPosition(Boat boat, long timeElapsed) {
|
|
|
|
protected void checkPosition(Boat boat, long timeElapsed) {
|
|
|
|
|
|
|
|
System.out.println(boat.getDistanceTravelledInLeg());
|
|
|
|
|
|
|
|
System.out.println(boat.getCurrentLeg().getDistance());
|
|
|
|
|
|
|
|
System.out.println(" ");
|
|
|
|
if (boat.getDistanceTravelledInLeg() > boat.getCurrentLeg().getDistance()) {
|
|
|
|
if (boat.getDistanceTravelledInLeg() > boat.getCurrentLeg().getDistance()) {
|
|
|
|
//boat has passed onto new leg
|
|
|
|
//boat has passed onto new leg
|
|
|
|
if (boat.getCurrentLeg().getName().equals("Finish")) {
|
|
|
|
if (boat.getCurrentLeg().getName().equals("Finish")) {
|
|
|
|
|