Merge branch 'master' into story68

-updated port and starboard boat checks
-added gps method to check if on correct side of a line
-updated pos check method to make boats round marks with the new tech

# Conflicts:
#	racevisionGame/src/main/java/mock/app/ConnectionAcceptor.java
#	racevisionGame/src/main/java/mock/app/Event.java
#	racevisionGame/src/main/java/mock/model/commandFactory/TackGybeCommand.java
#	racevisionGame/src/main/java/mock/model/commandFactory/VMGCommand.java
main
hba56 8 years ago
parent 499a409d4f
commit d70a711a3d

@ -211,11 +211,22 @@ public class MockBoat extends Boat {
* @return true if mark is on port side * @return true if mark is on port side
*/ */
public boolean isPortSide(Mark mark){ public boolean isPortSide(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(this.getCurrentPosition().getLongitude() < mark.getPosition().getLongitude()){ if (towardsMark.degrees() > 315 || towardsMark.degrees() <= 45){
//south quadrant
return this.getBearing().degrees() <= 180; 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{ }else{
return this.getBearing().degrees() > 180; //should not reach here
return false;
} }
} }
@ -226,10 +237,22 @@ public class MockBoat extends Boat {
*/ */
public boolean isStarboardSide(Mark mark){ public boolean isStarboardSide(Mark mark){
//if this boat is lower than the mark check which way it is facing //if this boat is lower than the mark check which way it is facing
if(this.getCurrentPosition().getLongitude() < mark.getPosition().getLongitude()){ Bearing towardsMark = GPSCoordinate.calculateBearing(this.getCurrentPosition(), mark.getPosition());
return this.getBearing().degrees() >= 180; 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{ }else{
return this.getBearing().degrees() < 180; //should not reach here
return false;
} }
} }

@ -3,12 +3,10 @@ package mock.model;
import network.Messages.Enums.BoatStatusEnum; import network.Messages.Enums.BoatStatusEnum;
import network.Messages.Enums.RaceStatusEnum; 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 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;
@ -321,6 +319,8 @@ public class MockRace extends Race {
if (!finish && totalElapsedMilliseconds >= updatePeriodMilliseconds) { if (!finish && totalElapsedMilliseconds >= updatePeriodMilliseconds) {
checkPosition(boat, totalElapsedMilliseconds);
if (boat.getCurrentSpeed() == 0) { if (boat.getCurrentSpeed() == 0) {
newOptimalVMG(boat); newOptimalVMG(boat);
boat.setBearing(boat.calculateBearingToNextMarker()); boat.setBearing(boat.calculateBearingToNextMarker());
@ -467,22 +467,22 @@ public class MockRace extends Race {
* @param boat the boat that is rounding a mark * @param boat the boat that is rounding a mark
* @param roundingChecks the checks to run * @param roundingChecks the checks to run
*/ */
private void boatRoundingCheckPort(MockBoat boat, List<GPSCoordinate> roundingChecks){ private void boatRoundingCheckPort(MockBoat boat, List<GPSCoordinate> roundingChecks, Bearing legBearing){
//boats must pass all checks in order to round a mark //boats must pass all checks in order to round a mark
switch (boat.getRoundingStatus()) { switch (boat.getRoundingStatus()) {
case 0://hasn't started rounding case 0://hasn't started rounding
// System.out.println("round 0"); if (boat.isPortSide(boat.getCurrentLeg().getEndCompoundMark().getMarkForRounding(legBearing)) &&
if (boat.isPortSide(boat.getCurrentLeg().getEndCompoundMark().getMark1()) && GPSCoordinate.passesLine(boat.getCurrentLeg().getEndCompoundMark().getMarkForRounding(legBearing).getPosition(),
GPSCoordinate.intersects(boat.getCurrentLeg().getEndCompoundMark().getMark1().getPosition(), roundingChecks.get(0), boat.getCurrentPosition(), legBearing)) {
roundingChecks.get(0), boat.getCurrentPosition())) { System.out.println("true");
boat.increaseRoundingStatus(); boat.increaseRoundingStatus();
} }
break; break;
case 1://has been parallel to the mark case 1://has been parallel to the mark
// System.out.println("round 1"); // System.out.println("round 1");
if (boat.isPortSide(boat.getCurrentLeg().getEndCompoundMark().getMark1()) && if (boat.isPortSide(boat.getCurrentLeg().getEndCompoundMark().getMarkForRounding(legBearing)) &&
GPSCoordinate.intersects(boat.getCurrentLeg().getEndCompoundMark().getMark1().getPosition(), GPSCoordinate.passesLine(boat.getCurrentLeg().getEndCompoundMark().getMarkForRounding(legBearing).getPosition(),
roundingChecks.get(1), boat.getCurrentPosition())) { roundingChecks.get(1), boat.getCurrentPosition(), Bearing.fromDegrees(legBearing.degrees() - 90))) {//negitive 90 from bearing because of port rounding
boat.increaseRoundingStatus(); boat.increaseRoundingStatus();
} }
break; break;
@ -533,7 +533,6 @@ public class MockRace extends Race {
* @param timeElapsed The total time, in milliseconds, that has elapsed since the race started. * @param timeElapsed The total time, in milliseconds, that has elapsed since the race started.
*/ */
protected void checkPosition(MockBoat boat, long timeElapsed) { 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. //The distance, in nautical miles, within which the boat needs to get in order to consider that it has reached the marker.
double epsilonNauticalMiles = 250.0 / Constants.NMToMetersConversion; //250 meters. double epsilonNauticalMiles = 250.0 / Constants.NMToMetersConversion; //250 meters.
@ -541,17 +540,15 @@ public class MockRace extends Race {
//Boat is within an acceptable distance from the mark. //Boat is within an acceptable distance from the mark.
GPSCoordinate startDirectionLinePoint = boat.getCurrentLeg().getStartCompoundMark().getMark1Position(); GPSCoordinate startDirectionLinePoint = boat.getCurrentLeg().getStartCompoundMark().getMark1Position();
//todo will need to change this for gates, so that the end point is the side of the gate needed to be rounded
GPSCoordinate endDirectionLinePoint = boat.getCurrentLeg().getEndCompoundMark().getMark1Position(); GPSCoordinate endDirectionLinePoint = boat.getCurrentLeg().getEndCompoundMark().getMark1Position();
Bearing bearingOfDirectionLine = GPSCoordinate.calculateBearing(startDirectionLinePoint, endDirectionLinePoint); Bearing bearingOfDirectionLine = GPSCoordinate.calculateBearing(startDirectionLinePoint, endDirectionLinePoint);
//use the direction line to create three invisible points that act as crossover lines a boat must cross //use the direction line to create three invisible points that act as crossover lines a boat must cross
//to round a mark //to round a mark
GPSCoordinate roundCheck1 = GPSCoordinate.calculateNewPosition(startDirectionLinePoint, GPSCoordinate roundCheck1 = GPSCoordinate.calculateNewPosition(endDirectionLinePoint,
epsilonNauticalMiles, Azimuth.fromDegrees(bearingOfDirectionLine.degrees() + 90));//adding 90 so the check line is parallel epsilonNauticalMiles, Azimuth.fromDegrees(bearingOfDirectionLine.degrees() + 90));//adding 90 so the check line is parallel
GPSCoordinate roundCheck2 = GPSCoordinate.calculateNewPosition(startDirectionLinePoint, GPSCoordinate roundCheck2 = GPSCoordinate.calculateNewPosition(endDirectionLinePoint,
epsilonNauticalMiles, Azimuth.fromDegrees(bearingOfDirectionLine.degrees())); epsilonNauticalMiles, Azimuth.fromDegrees(bearingOfDirectionLine.degrees()));
List<GPSCoordinate> roundingChecks = new ArrayList<GPSCoordinate>(Arrays.asList(roundCheck1, roundCheck2)); List<GPSCoordinate> roundingChecks = new ArrayList<GPSCoordinate>(Arrays.asList(roundCheck1, roundCheck2));
@ -559,7 +556,7 @@ public class MockRace extends Race {
switch (boat.getCurrentLeg().getEndCompoundMark().getRoundingType()) { switch (boat.getCurrentLeg().getEndCompoundMark().getRoundingType()) {
case SP://Not yet implemented so these gates will be rounded port side case SP://Not yet implemented so these gates will be rounded port side
case Port: case Port:
boatRoundingCheckPort(boat, roundingChecks); boatRoundingCheckPort(boat, roundingChecks, bearingOfDirectionLine);
break; break;
case PS://not yet implemented so these gates will be rounded starboard side case PS://not yet implemented so these gates will be rounded starboard side
case Starboard: case Starboard:

@ -170,6 +170,46 @@ public class GPSCoordinate {
} }
/**
* Checks to see if a point passes or lands on a line
* @param linePointA first point for a line
* @param linePointB second point for a line
* @param point point to check
* @param directionBearing direction of the correct side of line
* @return true if on the correct side
*/
public static boolean passesLine(GPSCoordinate linePointA, GPSCoordinate linePointB, GPSCoordinate point, Bearing directionBearing) {
double d = lineCheck(linePointA, linePointB, point);//this gives a number < 0 for one side and > 0 for an other
//to find if the side is the correct one
//compare with point that is known on the correct side
GPSCoordinate pointForComparison = GPSCoordinate.calculateNewPosition(linePointA,
250, Azimuth.fromDegrees(directionBearing.degrees()));
double d2 = lineCheck(linePointA, linePointB, pointForComparison);
return (d > 0 && d2 > 0) || (d < 0 && d2 < 0) || d == 0;
}
/**
* returns a double that is positive or negative based on which
* side of the line it is on. returns 0 if it is on the line
* @param linePointA first point to make up the line
* @param linePointB second point to make up the line
* @param point the point to check
* @return greater than 0 for one side, less than 0 for another
*/
private static double lineCheck(GPSCoordinate linePointA, GPSCoordinate linePointB, GPSCoordinate point) {
double linePointALat = linePointA.getLatitude();
double linePointALon = linePointA.getLongitude();
double linePointBLat = linePointB.getLatitude();
double linePointBLon = linePointB.getLongitude();
double pointLat = point.getLatitude();
double pointLon = point.getLongitude();
double d1 = (pointLat - linePointALat) * (linePointBLon - linePointALon);
double d2 = (pointLon - linePointALon) * (linePointBLat - linePointALat);
return d1 - d2; //this gives a number < 0 for one side and > 0 for an other
}
/** /**

@ -11,8 +11,6 @@ import visualiser.gameController.Keys.ControlKey;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import java.net.Socket; import java.net.Socket;
import java.net.SocketException;
import java.nio.ByteBuffer;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
@ -62,7 +60,7 @@ public class ControllerClient {
BinaryMessageEncoder binaryMessage = new BinaryMessageEncoder(MessageType.BOATACTION, System.currentTimeMillis(), 0, BinaryMessageEncoder binaryMessage = new BinaryMessageEncoder(MessageType.BOATACTION, System.currentTimeMillis(), 0,
(short) encodedBoatAction.length, encodedBoatAction); (short) encodedBoatAction.length, encodedBoatAction);
System.out.println("Sending out key: " + protocolCode); // System.out.println("Sending out key: " + protocolCode);
outputStream.write(binaryMessage.getFullMessage()); outputStream.write(binaryMessage.getFullMessage());
} catch (InvalidMessageException e) { } catch (InvalidMessageException e) {

@ -1,8 +1,6 @@
package visualiser.gameController; package visualiser.gameController;
import mock.model.RaceLogic; import mock.model.RaceLogic;
import mock.model.commandFactory.Command;
import mock.model.commandFactory.CommandFactory;
import network.BinaryMessageDecoder; import network.BinaryMessageDecoder;
import network.Exceptions.InvalidMessageException; import network.Exceptions.InvalidMessageException;
import network.MessageDecoders.BoatActionDecoder; import network.MessageDecoders.BoatActionDecoder;
@ -12,8 +10,8 @@ import network.Messages.Enums.BoatActionEnum;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.IOException; import java.io.IOException;
import java.net.Socket; import java.net.Socket;
import java.util.logging.Level;
import java.util.Observable; import java.util.Observable;
import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
/** /**

@ -7,8 +7,6 @@ import visualiser.gameController.Keys.KeyFactory;
import java.util.HashMap; import java.util.HashMap;
import static javafx.application.Application.launch;
/** /**
* Class for checking what keys are currently being used * Class for checking what keys are currently being used
*/ */
@ -28,7 +26,7 @@ public class InputChecker {
ControlKey controlKey = keyFactory.getKey(codeString); ControlKey controlKey = keyFactory.getKey(codeString);
if (controlKey != null) { if (controlKey != null) {
controlKey.onAction(); controlKey.onAction();
System.out.println(controlKey.toString() + " is Pressed."); // System.out.println(controlKey.toString() + " is Pressed.");
} }
currentlyActiveKeys.put(codeString, true); currentlyActiveKeys.put(codeString, true);
} }
@ -39,7 +37,7 @@ public class InputChecker {
ControlKey controlKey = keyFactory.getKey(codeString); ControlKey controlKey = keyFactory.getKey(codeString);
if (controlKey != null) { if (controlKey != null) {
controlKey.onRelease(); controlKey.onRelease();
System.out.println(controlKey.toString() + " is Released."); // System.out.println(controlKey.toString() + " is Released.");
} }
currentlyActiveKeys.remove(event.getCode().toString()); currentlyActiveKeys.remove(event.getCode().toString());
}); });
@ -51,7 +49,7 @@ public class InputChecker {
ControlKey controlKey = keyFactory.getKey(key); ControlKey controlKey = keyFactory.getKey(key);
if (controlKey != null){ if (controlKey != null){
controlKey.onHold(); controlKey.onHold();
System.out.println(controlKey.toString() + " is Held."); // System.out.println(controlKey.toString() + " is Held.");
} }
} }
// for (String key : InputKeys.stringKeysMap.keySet()){ // for (String key : InputKeys.stringKeysMap.keySet()){

@ -1,7 +1,6 @@
package visualiser.model; package visualiser.model;
import javafx.scene.image.Image;
import javafx.scene.paint.Color; import javafx.scene.paint.Color;
import javafx.scene.paint.Paint; import javafx.scene.paint.Paint;
import javafx.scene.transform.Rotate; import javafx.scene.transform.Rotate;

Loading…
Cancel
Save