@ -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 (
rounding Mark. getPosition ( ) ,
rounding Checks. 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 ( rounding Mark) & &
if ( boat . isPortSide ( rounding Data. get MarkToRound( ) ) & &
GPSCoordinate . passesLine (
rounding Mark. getPosition ( ) ,
rounding Checks. get ( 1 ) ,
rounding Data. get MarkToRound( ) . getPosition ( ) ,
rounding Data. 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,75 +624,22 @@ 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 ) ;
boatRoundingCheckPort (
boat ,
getMarkRoundingSequence ( ) . getRoundingData ( boat . getCurrentLeg ( ) ) ) ;
break ;
case PS : //not yet implemented so these gates will be rounded starboard side
case Starboard :
boatRoundingCheckStarboard ( boat , roundingChecks , bearingOfDirectionLine ) ;
boatRoundingCheckStarboard (
boat ,
getMarkRoundingSequence ( ) . getRoundingData ( boat . getCurrentLeg ( ) ) ) ;
break ;
}
System . out . println ( "resultant boat rounding state: " + boat . getRoundingStatus ( ) ) ; //TEMP REMOVE
//Check if the boat has finished or stopped racing.
if ( this . isLastLeg ( boat . getCurrentLeg ( ) ) ) {
@ -701,8 +652,6 @@ public class MockRace extends RaceState {
}
}