Race.simulateRace() function now generates a BoatLocationMessage after updating the position of each boat. Currently we just print the message to stdout.
Added functions to convert knots (as a double) to mm/sec (as an int) to BoatLocationMessage class. Added toString function to BoatLocationMessage class. Added a sequence number member to the BoatInRace class. Added Knots to meters per second conversion factor to Contants class. #story[788]
This commit is contained in:
@@ -11,6 +11,9 @@ public class Constants {
|
||||
|
||||
public static final int NMToMetersConversion = 1852; // 1 nautical mile = 1852 meters
|
||||
|
||||
//Knots x this = meters per second.
|
||||
public static final double KnotsToMetersPerSecondConversionFactor = 0.514444;
|
||||
|
||||
public static final GPSCoordinate startLineMarker1 = new GPSCoordinate(32.296577, -64.854304);
|
||||
public static final GPSCoordinate startLineMarker2 = new GPSCoordinate(32.293771, -64.855242);
|
||||
public static final GPSCoordinate mark1 = new GPSCoordinate(32.293039, -64.843983);
|
||||
|
||||
@@ -29,6 +29,9 @@ public class BoatInRace extends Boat {
|
||||
private StringProperty position;
|
||||
private double heading;
|
||||
|
||||
///While generating BoatLocationMessages, each one needs a sequence number relating to each boat.
|
||||
private long sequenceNumber = 0;
|
||||
|
||||
private boolean trackVisible = true;
|
||||
|
||||
/**
|
||||
@@ -263,4 +266,18 @@ public class BoatInRace extends Boat {
|
||||
this.position.set(position);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the current sequence number, and increments the internal value, such that that next call will return a value 1 larger than the current call.
|
||||
* @return Current sequence number.
|
||||
*/
|
||||
public long getNextSequenceNumber(){
|
||||
//Make a copy of current value.
|
||||
long oldNumber = this.sequenceNumber;
|
||||
//Increment.
|
||||
this.sequenceNumber += 1;
|
||||
//Return the previous value.
|
||||
return oldNumber;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import org.geotools.referencing.GeodeticCalculator;
|
||||
import seng302.Constants;
|
||||
import seng302.GPSCoordinate;
|
||||
import seng302.RaceDataSource;
|
||||
import seng302.RaceEventMessages.BoatLocationMessage;
|
||||
|
||||
|
||||
import java.awt.geom.Point2D;
|
||||
@@ -158,20 +159,61 @@ public class Race implements Runnable {
|
||||
}
|
||||
|
||||
new AnimationTimer() {
|
||||
|
||||
long timeRaceStarted = System.currentTimeMillis(); //start time of loop
|
||||
//Start time of loop.
|
||||
long timeRaceStarted = System.currentTimeMillis();
|
||||
|
||||
@Override
|
||||
public void handle(long arg0) {
|
||||
if (boatsFinished < startingBoats.size()) {
|
||||
totalTimeElapsed = System.currentTimeMillis() - timeRaceStarted;
|
||||
//Get the current time.
|
||||
long currentTime = System.currentTimeMillis();
|
||||
//Update the total elapsed time.
|
||||
totalTimeElapsed = currentTime - timeRaceStarted;
|
||||
|
||||
//For each boat, we update it's position, and generate a BoatLocationMessage.
|
||||
for (BoatInRace boat : startingBoats) {
|
||||
if (boat != null && !boat.isFinished()) {
|
||||
//Update position.
|
||||
updatePosition(boat, Math.round(1000 / lastFPS) > 20 ? 15 : Math.round(1000 / lastFPS));
|
||||
checkPosition(boat, totalTimeElapsed);
|
||||
|
||||
|
||||
//Generate a boat location message for the updated boat.
|
||||
BoatLocationMessage boatLocationMessage = new BoatLocationMessage();
|
||||
boatLocationMessage.setTime(currentTime);
|
||||
boatLocationMessage.setSourceID(boat.getSourceID());
|
||||
boatLocationMessage.setSequenceNumber(boat.getNextSequenceNumber());
|
||||
boatLocationMessage.setDeviceType(BoatLocationMessage.RacingYacht);
|
||||
|
||||
boatLocationMessage.setLatitude(BoatLocationMessage.convertCoordinateDoubleToInt(boat.getCurrentPosition().getLatitude()));
|
||||
boatLocationMessage.setLongitude(BoatLocationMessage.convertCoordinateDoubleToInt(boat.getCurrentPosition().getLongitude()));
|
||||
|
||||
boatLocationMessage.setAltitude(0);//Junk value.
|
||||
boatLocationMessage.setHeading(BoatLocationMessage.convertHeadingDoubleToInt(boat.getHeading()));
|
||||
|
||||
boatLocationMessage.setPitch((short)0);//Junk value.
|
||||
boatLocationMessage.setRoll((short)0);//Junk value.
|
||||
|
||||
boatLocationMessage.setBoatSpeed(BoatLocationMessage.convertBoatSpeedDoubleToInt(boat.getVelocity()));
|
||||
boatLocationMessage.setBoatCOG(0);//Junk value.
|
||||
boatLocationMessage.setBoatSOG(0);//Junk value.
|
||||
|
||||
boatLocationMessage.setApparentWindSpeed(0);//Junk value.
|
||||
boatLocationMessage.setApparentWindAngle((short)0);//Junk value.
|
||||
boatLocationMessage.setTrueWindSpeed(0);//Junk value.
|
||||
boatLocationMessage.setTrueWindAngle((short)0);//Junk value.
|
||||
|
||||
boatLocationMessage.setCurrentDrift(0);//Junk value.
|
||||
boatLocationMessage.setCurrentSet(0);//Junk value.
|
||||
boatLocationMessage.setRudderAngle((short)0);//Junk value.
|
||||
|
||||
//We have finished creating the message.
|
||||
//TODO at this point, we need to send the event to the visualiser.
|
||||
System.out.println(boatLocationMessage);//TEMP debug print
|
||||
|
||||
|
||||
} else {
|
||||
System.out.println("Race is over");
|
||||
System.out.println("Race is over");//TEMP debug print
|
||||
//raceFinish = true;
|
||||
stop();
|
||||
}
|
||||
@@ -194,7 +236,7 @@ public class Race implements Runnable {
|
||||
boat.setPosition("-");
|
||||
}
|
||||
}
|
||||
System.out.println("=====");
|
||||
System.out.println("=====");//TEMP debug print
|
||||
}
|
||||
|
||||
public void initialiseBoats() {
|
||||
|
||||
@@ -4,6 +4,8 @@ package seng302.RaceEventMessages;
|
||||
* Created by f123 on 21-Apr-17.
|
||||
*/
|
||||
|
||||
import seng302.Constants;
|
||||
|
||||
/**
|
||||
* Represents the information in a boat location message (AC streaming spec: 4.9).
|
||||
*/
|
||||
@@ -442,4 +444,112 @@ public class BoatLocationMessage
|
||||
return angleShort;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Converts a double representing the speed of a boat in knots to an int in millimeters per second, as required by the streaming spec format.
|
||||
* @param speed Speed in knots, stored as a double.
|
||||
* @return Speed in millimeters per second, stored as an int (using only the two least significant bytes).
|
||||
*/
|
||||
public static int convertBoatSpeedDoubleToInt(double speed)
|
||||
{
|
||||
//Calculate meters per second.
|
||||
double metersPerSecond = speed * Constants.KnotsToMetersPerSecondConversionFactor;
|
||||
|
||||
//Calculate millimeters per second.
|
||||
double millimetersPerSecond = metersPerSecond * 1000.0;
|
||||
|
||||
//Convert to an int.
|
||||
int millimetersPerSecondInt = (int)Math.round(millimetersPerSecond);
|
||||
|
||||
return millimetersPerSecondInt;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Converts an int representing the speed of a boat in millimeters per second to a double in knots, as required by the streaming spec format.
|
||||
* @param speed Speed in millimeters per second, stored as an int.
|
||||
* @return Speed in knots, stored as a double.
|
||||
*/
|
||||
public static double convertBoatSpeedIntToDouble(int speed)
|
||||
{
|
||||
//Calculate meters per second.
|
||||
double metersPerSecond = speed / 1000.0;
|
||||
|
||||
//Calculate knots.
|
||||
double knots = metersPerSecond / Constants.KnotsToMetersPerSecondConversionFactor;
|
||||
|
||||
return knots;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
builder.append("Message version number: ");
|
||||
builder.append(this.getMessageVersionNumber());
|
||||
|
||||
builder.append("\nTime: ");
|
||||
builder.append(this.getTime());
|
||||
|
||||
builder.append("\nSource ID: ");
|
||||
builder.append(this.getSourceID());
|
||||
|
||||
builder.append("\nSequence number: ");
|
||||
builder.append(this.getSequenceNumber());
|
||||
|
||||
builder.append("\nDevice type: ");
|
||||
builder.append(this.getDeviceType());
|
||||
|
||||
builder.append("\nLatitude: ");
|
||||
builder.append(this.getLatitude());
|
||||
|
||||
builder.append("\nLongitude: ");
|
||||
builder.append(this.getLongitude());
|
||||
|
||||
builder.append("\nAltitude: ");
|
||||
builder.append(this.getAltitude());
|
||||
|
||||
builder.append("\nHeading: ");
|
||||
builder.append(this.getHeading());
|
||||
|
||||
builder.append("\nPitch: ");
|
||||
builder.append(this.getPitch());
|
||||
|
||||
builder.append("\nRoll: ");
|
||||
builder.append(this.getRoll());
|
||||
|
||||
builder.append("\nBoat speed (mm/sec): ");
|
||||
builder.append(this.getBoatSpeed());
|
||||
|
||||
builder.append("\nBoat COG: ");
|
||||
builder.append(this.getBoatCOG());
|
||||
|
||||
builder.append("\nBoat SOG: ");
|
||||
builder.append(this.getBoatSOG());
|
||||
|
||||
builder.append("\nApparent wind speed: ");
|
||||
builder.append(this.getApparentWindSpeed());
|
||||
|
||||
builder.append("\nApparent wind angle: ");
|
||||
builder.append(this.getApparentWindAngle());
|
||||
|
||||
builder.append("\nTrue wind speed: ");
|
||||
builder.append(this.getTrueWindSpeed());
|
||||
|
||||
builder.append("\nTrue wind angle: ");
|
||||
builder.append(this.getTrueWindAngle());
|
||||
|
||||
builder.append("\nCurrent drift: ");
|
||||
builder.append(this.getCurrentDrift());
|
||||
|
||||
builder.append("\nCurrent set: ");
|
||||
builder.append(this.getCurrentSet());
|
||||
|
||||
builder.append("\nRudder angle: ");
|
||||
builder.append(this.getRudderAngle());
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user