Finished MarkRoundingSequence class. Added MarkRoundingData class.
RaceState has a MarkRoundingSequenceMember. The temporary rounding line drawing in canvas uses MarkRoundingSequence. MockRace now uses MarkRoundingSequence. #story[1185]
This commit is contained in:
@@ -1,19 +1,13 @@
|
||||
package mock.model;
|
||||
|
||||
import mock.model.wind.WindGenerator;
|
||||
import javafx.animation.AnimationTimer;
|
||||
import mock.model.collider.ColliderRegistry;
|
||||
import mock.xml.*;
|
||||
import network.Messages.BoatLocation;
|
||||
import network.Messages.BoatStatus;
|
||||
import network.Messages.Enums.BoatStatusEnum;
|
||||
import network.Messages.Enums.RaceStatusEnum;
|
||||
import network.Utils.AC35UnitConverter;
|
||||
import shared.dataInput.BoatDataSource;
|
||||
import shared.dataInput.RaceDataSource;
|
||||
import shared.dataInput.RegattaDataSource;
|
||||
import shared.exceptions.BoatNotFoundException;
|
||||
import shared.enums.RoundingType;
|
||||
import shared.model.*;
|
||||
import shared.model.Bearing;
|
||||
|
||||
@@ -358,8 +352,6 @@ public class MockRace extends RaceState {
|
||||
|
||||
if (!finish && totalElapsedMilliseconds >= updatePeriodMilliseconds && boat.isSailsOut()) {
|
||||
|
||||
checkPosition(boat, totalElapsedMilliseconds);
|
||||
|
||||
if (boat.getCurrentSpeed() == 0) {
|
||||
newOptimalVMG(boat);
|
||||
boat.setBearing(boat.calculateBearingToNextMarker());
|
||||
@@ -373,6 +365,7 @@ public class MockRace extends RaceState {
|
||||
//Scale it.
|
||||
distanceTravelledMeters = distanceTravelledMeters * this.scaleFactor;
|
||||
|
||||
checkPosition(boat, totalElapsedMilliseconds);
|
||||
|
||||
//Move the boat forwards that many meters, and advances its time counters by enough milliseconds.
|
||||
boat.moveForwards(distanceTravelledMeters);
|
||||
@@ -515,32 +508,28 @@ public class MockRace extends RaceState {
|
||||
/**
|
||||
* Checks to be run on boats rounding marks on the port side
|
||||
* @param boat the boat that is rounding a mark
|
||||
* @param roundingChecks the checks to run
|
||||
* @param legBearing the direction of the leg
|
||||
* @param roundingData The data for the current leg's rounding.
|
||||
*/
|
||||
private void boatRoundingCheckPort(MockBoat boat, List<GPSCoordinate> roundingChecks, Bearing legBearing) {
|
||||
private void boatRoundingCheckPort(MockBoat boat, MarkRoundingData roundingData) {
|
||||
//boats must pass all checks in order to round a mark
|
||||
|
||||
//boolean for if boat has to/needs to pass through a gate
|
||||
boolean gateCheck = boat.getCurrentLeg().getEndCompoundMark().getMark2() == null || boat.isBetweenGate(boat.getCurrentLeg().getEndCompoundMark());
|
||||
Mark roundingMark = boat.getCurrentLeg().getEndCompoundMark().getMarkForRounding(legBearing);
|
||||
|
||||
System.out.println("boat rounding state: " + boat.getRoundingStatus());//TEMP REMOVE
|
||||
|
||||
|
||||
switch (boat.getRoundingStatus()) {
|
||||
case 0://hasn't started rounding
|
||||
System.out.println("portside? " + boat.isPortSide(roundingMark));//TEMP REMOVE
|
||||
System.out.println("passes line? " + GPSCoordinate.passesLine(roundingMark.getPosition(), roundingChecks.get(0), boat.getPosition(), legBearing));//TEMP REMOVE
|
||||
System.out.println("gatecheck? " + gateCheck);//TEMP REMOVE
|
||||
System.out.println("between gates? " + boat.isBetweenGate(roundingMark, Mark.tempMark(roundingChecks.get(0))));//TEMP REMOVE
|
||||
if (boat.isPortSide(roundingMark) &&
|
||||
if (boat.isPortSide(roundingData.getMarkToRound()) &&
|
||||
GPSCoordinate.passesLine(
|
||||
roundingMark.getPosition(),
|
||||
roundingChecks.get(0),
|
||||
roundingData.getMarkToRound().getPosition(),
|
||||
roundingData.getRoundCheck1(),
|
||||
boat.getPosition(),
|
||||
legBearing) &&
|
||||
roundingData.getLegBearing()) &&
|
||||
gateCheck &&
|
||||
boat.isBetweenGate(roundingMark, Mark.tempMark(roundingChecks.get(0)))) {
|
||||
boat.isBetweenGate(
|
||||
roundingData.getMarkToRound(),
|
||||
Mark.tempMark(roundingData.getRoundCheck1())) ) {
|
||||
boat.increaseRoundingStatus();
|
||||
if (boat.getCurrentLeg().getLegNumber() + 2 >= getLegs().size()){
|
||||
//boat has finished race
|
||||
@@ -549,13 +538,18 @@ public class MockRace extends RaceState {
|
||||
}
|
||||
break;
|
||||
case 1://has been parallel to the mark;
|
||||
if (boat.isPortSide(roundingMark) &&
|
||||
if (boat.isPortSide(roundingData.getMarkToRound()) &&
|
||||
GPSCoordinate.passesLine(
|
||||
roundingMark.getPosition(),
|
||||
roundingChecks.get(1),
|
||||
roundingData.getMarkToRound().getPosition(),
|
||||
roundingData.getRoundCheck2(),
|
||||
boat.getPosition(),
|
||||
Bearing.fromDegrees(legBearing.degrees() - 90)) &&//negative 90 from bearing because of port rounding
|
||||
boat.isBetweenGate(roundingMark, Mark.tempMark(roundingChecks.get(1)))) {
|
||||
Bearing.fromDegrees(
|
||||
GPSCoordinate.calculateBearing(
|
||||
roundingData.getMarkToRound().getPosition(),
|
||||
roundingData.getRoundCheck2()).degrees() - 90)) &&//negative 90 from bearing because of port rounding
|
||||
boat.isBetweenGate(
|
||||
roundingData.getMarkToRound(),
|
||||
Mark.tempMark(roundingData.getRoundCheck2()))) {
|
||||
boat.increaseRoundingStatus();
|
||||
}
|
||||
break;
|
||||
@@ -571,25 +565,27 @@ public class MockRace extends RaceState {
|
||||
/**
|
||||
* Checks to be run on boats rounding marks on the starboard side
|
||||
* @param boat the boat that is rounding a mark
|
||||
* @param roundingChecks the checks to run
|
||||
* @param legBearing the direction of the leg
|
||||
* @param roundingData The data for the current leg's rounding.
|
||||
*/
|
||||
private void boatRoundingCheckStarboard(MockBoat boat, List<GPSCoordinate> roundingChecks, Bearing legBearing){
|
||||
private void boatRoundingCheckStarboard(MockBoat boat, MarkRoundingData roundingData){
|
||||
//boats must pass all checks in order to round a mark
|
||||
|
||||
//boolean for if boat has to/needs to pass through a gate
|
||||
boolean gateCheck = boat.getCurrentLeg().getEndCompoundMark().getMark2() == null || boat.isBetweenGate(boat.getCurrentLeg().getEndCompoundMark());
|
||||
Mark roundingMark = boat.getCurrentLeg().getEndCompoundMark().getMarkForRounding(legBearing);
|
||||
|
||||
System.out.println("boat rounding state: " + boat.getRoundingStatus());//TEMP REMOVE
|
||||
|
||||
switch (boat.getRoundingStatus()) {
|
||||
case 0://hasn't started rounding
|
||||
if (boat.isStarboardSide(roundingMark) &&
|
||||
GPSCoordinate.passesLine(roundingMark.getPosition(),
|
||||
roundingChecks.get(0), boat.getPosition(), legBearing) &&
|
||||
if (boat.isStarboardSide(roundingData.getMarkToRound()) &&
|
||||
GPSCoordinate.passesLine(
|
||||
roundingData.getMarkToRound().getPosition(),
|
||||
roundingData.getRoundCheck1(),
|
||||
boat.getPosition(),
|
||||
roundingData.getLegBearing()) &&
|
||||
gateCheck &&
|
||||
boat.isBetweenGate(roundingMark, Mark.tempMark(roundingChecks.get(0)))) {
|
||||
boat.isBetweenGate(
|
||||
roundingData.getMarkToRound(),
|
||||
Mark.tempMark(roundingData.getRoundCheck1()))) {
|
||||
boat.increaseRoundingStatus();
|
||||
if (boat.getCurrentLeg().getLegNumber() + 2 >= getLegs().size()){
|
||||
//boat has finished race
|
||||
@@ -598,10 +594,18 @@ public class MockRace extends RaceState {
|
||||
}
|
||||
break;
|
||||
case 1://has been parallel to the mark
|
||||
if (boat.isStarboardSide(roundingMark) &&
|
||||
GPSCoordinate.passesLine(roundingMark.getPosition(),
|
||||
roundingChecks.get(1), boat.getPosition(), Bearing.fromDegrees(legBearing.degrees() + 90)) && //positive 90 from bearing because of starboard rounding
|
||||
boat.isBetweenGate(roundingMark, Mark.tempMark(roundingChecks.get(1)))) {
|
||||
if (boat.isStarboardSide(roundingData.getMarkToRound()) &&
|
||||
GPSCoordinate.passesLine(
|
||||
roundingData.getMarkToRound().getPosition(),
|
||||
roundingData.getRoundCheck2(),
|
||||
boat.getPosition(),
|
||||
Bearing.fromDegrees(
|
||||
GPSCoordinate.calculateBearing(
|
||||
roundingData.getMarkToRound().getPosition(),
|
||||
roundingData.getRoundCheck2() ).degrees() + 90)) && //positive 90 from bearing because of starboard rounding
|
||||
boat.isBetweenGate(
|
||||
roundingData.getMarkToRound(),
|
||||
Mark.tempMark(roundingData.getRoundCheck2())) ) {
|
||||
boat.increaseRoundingStatus();
|
||||
}
|
||||
break;
|
||||
@@ -620,84 +624,29 @@ public class MockRace extends RaceState {
|
||||
* @param timeElapsed The total time, in milliseconds, that has elapsed since the race started.
|
||||
*/
|
||||
protected void checkPosition(MockBoat boat, long timeElapsed) {
|
||||
//The distance, in nautical miles, within which the boat needs to get in order to consider that it has reached the marker.
|
||||
double epsilonMeters = boat.getCurrentLeg().getEndCompoundMark().getRoundingDistance(); //250 meters.
|
||||
//System.out.println("epsilon dist meters: " + epsilonMeters);//TEMP REMOVE
|
||||
|
||||
//System.out.println("boat dist to next point NM: " + boat.calculateDistanceToNextMarker());//TEMP REMOVE
|
||||
|
||||
double epsilonNM = epsilonMeters / Constants.NMToMetersConversion;
|
||||
|
||||
//System.out.println("epsilon NM: " + epsilonNM);//TEMP REMOVE
|
||||
|
||||
if (boat.calculateDistanceToNextMarker() < epsilonNM) {
|
||||
//Boat is within an acceptable distance from the mark.
|
||||
|
||||
GPSCoordinate startDirectionLinePoint = boat.getCurrentLeg().getStartCompoundMark().getAverageGPSCoordinate();
|
||||
GPSCoordinate endDirectionLinePoint = boat.getCurrentLeg().getEndCompoundMark().getAverageGPSCoordinate();
|
||||
Bearing bearingOfDirectionLine = GPSCoordinate.calculateBearing(startDirectionLinePoint, endDirectionLinePoint);
|
||||
|
||||
//use the direction line to create three invisible points that act as crossover lines a boat must cross
|
||||
//to round a mark
|
||||
|
||||
double bearingToAdd;
|
||||
//System.out.println("leg: " + boat.getCurrentLeg().getName() + " has bearing DL of: " + bearingOfDirectionLine.degrees());//TEMP REMOVE
|
||||
if (boat.getCurrentLeg().getEndCompoundMark().getRoundingType() == RoundingType.Port ||
|
||||
boat.getCurrentLeg().getEndCompoundMark().getRoundingType() == RoundingType.SP){
|
||||
bearingToAdd = 90;
|
||||
}else{
|
||||
bearingToAdd = -90;
|
||||
}
|
||||
|
||||
//System.out.println("so new bearing is " + (bearingToAdd + bearingOfDirectionLine.degrees()));//TEMP REMOVE
|
||||
|
||||
GPSCoordinate roundCheck1 = GPSCoordinate.calculateNewPosition(
|
||||
endDirectionLinePoint,
|
||||
epsilonMeters,
|
||||
Azimuth.fromDegrees(bearingOfDirectionLine.degrees() + bearingToAdd) );
|
||||
//System.out.println("this has a rounding coordinate of (" + roundCheck1.getLongitude() + ", " + roundCheck1.getLatitude() + ")");//TEMP REMOVE
|
||||
|
||||
GPSCoordinate roundCheck2;
|
||||
try{
|
||||
Leg nextLeg = getLegs().get(getLegs().indexOf(boat.getCurrentLeg()) + 1);
|
||||
|
||||
GPSCoordinate startNextDirectionLinePoint = nextLeg.getStartCompoundMark().getAverageGPSCoordinate();
|
||||
GPSCoordinate endNextDirectionLinePoint = nextLeg.getEndCompoundMark().getAverageGPSCoordinate();
|
||||
Bearing bearingOfNextDirectionLine = GPSCoordinate.calculateBearing(startNextDirectionLinePoint, endNextDirectionLinePoint);
|
||||
|
||||
roundCheck2 = GPSCoordinate.calculateNewPosition(
|
||||
endDirectionLinePoint,
|
||||
epsilonMeters,
|
||||
Azimuth.fromDegrees(bearingOfNextDirectionLine.degrees() + bearingToAdd) );
|
||||
}catch(NullPointerException e){
|
||||
//this is caused by the last leg not being having a leg after it
|
||||
roundCheck2 = roundCheck1;
|
||||
}
|
||||
|
||||
List<GPSCoordinate> roundingChecks = new ArrayList<>(Arrays.asList(roundCheck1, roundCheck2));
|
||||
|
||||
switch (boat.getCurrentLeg().getEndCompoundMark().getRoundingType()) {
|
||||
case SP://Not yet implemented so these gates will be rounded port side
|
||||
case Port:
|
||||
boatRoundingCheckPort(boat, roundingChecks, bearingOfDirectionLine);
|
||||
break;
|
||||
case PS://not yet implemented so these gates will be rounded starboard side
|
||||
case Starboard:
|
||||
boatRoundingCheckStarboard(boat, roundingChecks, bearingOfDirectionLine);
|
||||
break;
|
||||
}
|
||||
|
||||
System.out.println("resultant boat rounding state: " + boat.getRoundingStatus());//TEMP REMOVE
|
||||
switch (boat.getCurrentLeg().getEndCompoundMark().getRoundingType()) {
|
||||
case SP://Not yet implemented so these gates will be rounded port side
|
||||
case Port:
|
||||
boatRoundingCheckPort(
|
||||
boat,
|
||||
getMarkRoundingSequence().getRoundingData(boat.getCurrentLeg()) );
|
||||
break;
|
||||
case PS://not yet implemented so these gates will be rounded starboard side
|
||||
case Starboard:
|
||||
boatRoundingCheckStarboard(
|
||||
boat,
|
||||
getMarkRoundingSequence().getRoundingData(boat.getCurrentLeg()) );
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
//Check if the boat has finished or stopped racing.
|
||||
if (this.isLastLeg(boat.getCurrentLeg())) {
|
||||
//Boat has finished.
|
||||
boat.setTimeFinished(timeElapsed);
|
||||
boat.setCurrentSpeed(0);
|
||||
boat.setStatus(BoatStatusEnum.FINISHED);
|
||||
|
||||
}
|
||||
//Check if the boat has finished or stopped racing.
|
||||
if (this.isLastLeg(boat.getCurrentLeg())) {
|
||||
//Boat has finished.
|
||||
boat.setTimeFinished(timeElapsed);
|
||||
boat.setCurrentSpeed(0);
|
||||
boat.setStatus(BoatStatusEnum.FINISHED);
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user