package seng302.Model; import seng302.Constants; import seng302.Networking.Messages.Enums.BoatStatusEnum; /** * This class represents a boat during a race. */ public class Boat { /** * The name of the boat/team. */ private String name; /** * The current speed of the boat, in knots. * TODO knots */ private double currentSpeed; /** * The current bearing/heading of the boat. */ private Bearing bearing; /** * The current position of the boat. */ private GPSCoordinate currentPosition; /** * The country or team abbreviation of the boat. */ private String country; /** * The source ID of the boat. * This uniquely identifies an entity during a race. */ private int sourceID; /** * The leg of the race that the boat is currently on. */ private Leg currentLeg; /** * The distance, in meters, that the boat has travelled in the current leg. * TODO meters */ private double distanceTravelledInLeg; /** * The time, in milliseconds, that has elapsed during the current leg. * TODO milliseconds */ private long timeElapsedInCurrentLeg; /** * The timestamp, in milliseconds, of when the boat finished the race. * Is -1 if it hasn't finished. * TODO milliseconds */ private long timeFinished = -1; /** * The current status of the boat. */ private BoatStatusEnum status; /** * This stores a boat's polars table. * Can be used to calculate VMG. */ private Polars polars; /** * This stores the milliseconds since the boat has changed its tack, to allow for only updating the tack every X milliseconds. * TODO milliseconds */ private long timeSinceTackChange = 0; /** * Constructs a boat object with a given sourceID, name, country/team abbreviation, and polars table. * * @param sourceID The id of the boat * @param name The name of the Boat. * @param country The abbreviation or country code for the boat. * @param polars The polars table to use for this boat. */ public Boat(int sourceID, String name, String country, Polars polars) { this.country = country; this.name = name; this.sourceID = sourceID; this.polars = polars; this.bearing = Bearing.fromDegrees(0d); this.status = BoatStatusEnum.UNDEFINED; } /** * Calculate the bearing of the boat to its next marker. * @return The bearing to the next marker. */ public Bearing calculateBearingToNextMarker() { //Get the start and end points. GPSCoordinate currentPosition = this.getCurrentPosition(); GPSCoordinate nextMarkerPosition = this.getCurrentLeg().getEndCompoundMark().getAverageGPSCoordinate(); //Calculate bearing. Bearing bearing = GPSCoordinate.calculateBearing(currentPosition, nextMarkerPosition); return bearing; } /** * Calculates the distance between the boat and its target marker in nautical miles. * @return The distance (in nautical miles) between the boat and its target marker. */ public double calculateDistanceToNextMarker() { //Get start and end markers. GPSCoordinate startPosition = this.getCurrentPosition(); //When boats finish, their "current leg" doesn't have an end marker. if (this.getCurrentLeg().getEndCompoundMark() == null) { return 0d; } GPSCoordinate endMarker = this.getCurrentLeg().getEndCompoundMark().getAverageGPSCoordinate(); //Calculate distance. double distanceNauticalMiles = GPSCoordinate.calculateDistanceNauticalMiles(startPosition, endMarker); return distanceNauticalMiles; } /** * Returns the name of the boat/team. * @return Name of the boat/team. */ public String getName() { return name; } /** * Sets the name of the boat/team. * @param name Name of the boat/team. */ public void setName(String name) { this.name = name; } /** * Returns the current speed of the boat, in knots. * @return The current speed of the boat, in knots. */ public double getCurrentSpeed() { return currentSpeed; } /** * Sets the speed of the boat, in knots. * @param currentSpeed The new speed of the boat, in knots. */ public void setCurrentSpeed(double currentSpeed) { this.currentSpeed = currentSpeed; } /** * Gets the country/team abbreviation of the boat. * @return The country/team abbreviation of the boat. */ public String getCountry() { return country; } /** * Sets the country/team abbreviation of the boat. * @param country The new country/team abbreviation for the boat. */ public void setCountry(String country) { this.country = country; } /** * Returns the source ID of the boat. * @return The source ID of the boat. */ public int getSourceID() { return sourceID; } /** * Sets the source ID of the boat. * @param sourceID The new source ID for the boat. */ public void setSourceID(int sourceID) { this.sourceID = sourceID; } /** * Returns the current leg of the race the boat is in. * @return The current leg of the race the boat is in. */ public Leg getCurrentLeg() { return currentLeg; } /** * Sets the current leg of the race the boat is in. * Clears time elapsed in current leg and distance travelled in current leg. * @param currentLeg The new leg of the race the boat is in. */ public void setCurrentLeg(Leg currentLeg) { this.currentLeg = currentLeg; this.setTimeElapsedInCurrentLeg(0); this.setDistanceTravelledInLeg(0); } /** * Returns the distance, in meters, the boat has travelled in the current leg. * @return The distance, in meters, the boat has travelled in the current leg. */ public double getDistanceTravelledInLeg() { return distanceTravelledInLeg; } /** * Sets the distance, in meters, the boat has travelled in the current leg. * @param distanceTravelledInLeg The distance, in meters, the boat has travelled in the current leg. */ public void setDistanceTravelledInLeg(double distanceTravelledInLeg) { this.distanceTravelledInLeg = distanceTravelledInLeg; } /** * Returns the current position of the boat. * @return The current position of the boat. */ public GPSCoordinate getCurrentPosition() { return currentPosition; } /** * Sets the current position of the boat. * @param currentPosition The new position for the boat. */ public void setCurrentPosition(GPSCoordinate currentPosition) { this.currentPosition = currentPosition; } /** * Gets the timestamp, in milliseconds, at which the boat finished the race. * @return The timestamp, in milliseconds, at which the boat finished the race. */ public long getTimeFinished() { return timeFinished; } /** * Sets the timestamp, in milliseconds, at which the boat finished the race. * @param timeFinished The timestamp, in milliseconds, at which the boat finished the race. */ public void setTimeFinished(long timeFinished) { this.timeFinished = timeFinished; } /** * Returns the current bearing of the boat. * @return The current bearing of the boat. */ public Bearing getBearing() { return bearing; } /** * Sets the current bearing of the boat. * @param bearing The new bearing of the boat. */ public void setBearing(Bearing bearing) { this.bearing = bearing; } /** * Returns the polars table for this boat. * @return The polars table for this boat. */ public Polars getPolars() { return polars; } /** * Sets the polars table for this boat. * @param polars The new polars table for this boat. */ public void setPolars(Polars polars) { this.polars = polars; } /** * Returns the time since the boat changed its tack, in milliseconds. * @return Time since the boat changed its tack, in milliseconds. */ public long getTimeSinceTackChange() { return timeSinceTackChange; } /** * Sets the time since the boat changed it's tack, in milliseconds. * @param timeSinceTackChange Time since the boat changed its tack, in milliseconds. */ public void setTimeSinceTackChange(long timeSinceTackChange) { this.timeSinceTackChange = timeSinceTackChange; } /** * Returns the time, in milliseconds, that has elapsed since the boat started the current leg. * @return The time, in milliseconds, that has elapsed since the boat started the current leg. */ public long getTimeElapsedInCurrentLeg() { return timeElapsedInCurrentLeg; } /** * Sets the time, in milliseconds, that has elapsed since the boat started the current leg. * @param timeElapsedInCurrentLeg The new time, in milliseconds, that has elapsed since the boat started the current leg. */ public void setTimeElapsedInCurrentLeg(long timeElapsedInCurrentLeg) { this.timeElapsedInCurrentLeg = timeElapsedInCurrentLeg; } /** * Returns the status of the boat. * @return The sttus of the boat. */ public BoatStatusEnum getStatus() { return status; } /** * Sets the status of the boat. * @param status The new status of the boat. */ public void setStatus(BoatStatusEnum status) { this.status = status; } /** * Moves the boat meters forward in the direction that it is facing * @param meters The number of meters to move forward. * @param milliseconds The number of milliseconds to advance the boat's timers by. */ public void moveForwards(double meters, long milliseconds) { //Update the boat's time since last tack. this.setTimeSinceTackChange(this.getTimeSinceTackChange() + milliseconds); //Update the time into the current leg. this.setTimeElapsedInCurrentLeg(this.getTimeElapsedInCurrentLeg() + milliseconds); //Update the distance into the current leg. this.setDistanceTravelledInLeg(this.getDistanceTravelledInLeg() + meters); //Updates the current position of the boat. GPSCoordinate newPosition = GPSCoordinate.calculateNewPosition(this.getCurrentPosition(), meters, Azimuth.fromBearing(this.getBearing())); this.setCurrentPosition(newPosition); } /** * Sets the boats speed and bearing to those in the given VMG. * @param newVMG The new VMG to use for the boat - contains speed and bearing. */ public void setVMG(VMG newVMG) { this.setBearing(newVMG.getBearing()); this.setCurrentSpeed(newVMG.getSpeed()); this.setTimeSinceTackChange(0); } /** * Calculates the number of nautical miles the boat will travel in a given time slice. * E.g., in 53 milliseconds a boat may travel 0.0002 nautical miles. * @param timeSlice The timeslice to use. * @return The distance travelled, in nautical miles, over the given timeslice. */ public double calculateNauticalMilesTravelled(long timeSlice) { //The proportion of one hour the current timeslice is. //This will be a low fractional number, so we need to go from long -> double. double hourProportion = ((double) timeSlice) / Constants.OneHourMilliseconds; //Calculates the distance travelled, in nautical miles, in the current timeslice. //distanceTravelledNM = speed (nm p hr) * time taken to update loop double distanceTravelledNM = this.getCurrentSpeed() * hourProportion; return distanceTravelledNM; } /** * Calculates the number of meters the boat will travel in a given time slice. * E.g., in 53 milliseconds a boat may travel 0.02 meters. * @param timeSlice The timeslice to use. * @return The distance travelled, in meters, over the given timeslice. */ public double calculateMetersTravelled(long timeSlice) { //Calculate the distance travelled, in nautical miles. double distanceTravelledNM = this.calculateNauticalMilesTravelled(timeSlice); //Convert to meters. double distanceTravelledMeters = distanceTravelledNM * Constants.NMToMetersConversion; return distanceTravelledMeters; } }