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
|
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 startLineMarker1 = new GPSCoordinate(32.296577, -64.854304);
|
||||||
public static final GPSCoordinate startLineMarker2 = new GPSCoordinate(32.293771, -64.855242);
|
public static final GPSCoordinate startLineMarker2 = new GPSCoordinate(32.293771, -64.855242);
|
||||||
public static final GPSCoordinate mark1 = new GPSCoordinate(32.293039, -64.843983);
|
public static final GPSCoordinate mark1 = new GPSCoordinate(32.293039, -64.843983);
|
||||||
|
|||||||
@@ -29,6 +29,9 @@ public class BoatInRace extends Boat {
|
|||||||
private StringProperty position;
|
private StringProperty position;
|
||||||
private double heading;
|
private double heading;
|
||||||
|
|
||||||
|
///While generating BoatLocationMessages, each one needs a sequence number relating to each boat.
|
||||||
|
private long sequenceNumber = 0;
|
||||||
|
|
||||||
private boolean trackVisible = true;
|
private boolean trackVisible = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -263,4 +266,18 @@ public class BoatInRace extends Boat {
|
|||||||
this.position.set(position);
|
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.Constants;
|
||||||
import seng302.GPSCoordinate;
|
import seng302.GPSCoordinate;
|
||||||
import seng302.RaceDataSource;
|
import seng302.RaceDataSource;
|
||||||
|
import seng302.RaceEventMessages.BoatLocationMessage;
|
||||||
|
|
||||||
|
|
||||||
import java.awt.geom.Point2D;
|
import java.awt.geom.Point2D;
|
||||||
@@ -158,20 +159,61 @@ public class Race implements Runnable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
new AnimationTimer() {
|
new AnimationTimer() {
|
||||||
|
//Start time of loop.
|
||||||
long timeRaceStarted = System.currentTimeMillis(); //start time of loop
|
long timeRaceStarted = System.currentTimeMillis();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handle(long arg0) {
|
public void handle(long arg0) {
|
||||||
if (boatsFinished < startingBoats.size()) {
|
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) {
|
for (BoatInRace boat : startingBoats) {
|
||||||
if (boat != null && !boat.isFinished()) {
|
if (boat != null && !boat.isFinished()) {
|
||||||
|
//Update position.
|
||||||
updatePosition(boat, Math.round(1000 / lastFPS) > 20 ? 15 : Math.round(1000 / lastFPS));
|
updatePosition(boat, Math.round(1000 / lastFPS) > 20 ? 15 : Math.round(1000 / lastFPS));
|
||||||
checkPosition(boat, totalTimeElapsed);
|
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 {
|
} else {
|
||||||
System.out.println("Race is over");
|
System.out.println("Race is over");//TEMP debug print
|
||||||
//raceFinish = true;
|
//raceFinish = true;
|
||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
@@ -194,7 +236,7 @@ public class Race implements Runnable {
|
|||||||
boat.setPosition("-");
|
boat.setPosition("-");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
System.out.println("=====");
|
System.out.println("=====");//TEMP debug print
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initialiseBoats() {
|
public void initialiseBoats() {
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ package seng302.RaceEventMessages;
|
|||||||
* Created by f123 on 21-Apr-17.
|
* Created by f123 on 21-Apr-17.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import seng302.Constants;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents the information in a boat location message (AC streaming spec: 4.9).
|
* Represents the information in a boat location message (AC streaming spec: 4.9).
|
||||||
*/
|
*/
|
||||||
@@ -442,4 +444,112 @@ public class BoatLocationMessage
|
|||||||
return angleShort;
|
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