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]
main
fjc40 9 years ago
parent 5304f7df7d
commit 091ee4735b

@ -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();
}
}

Loading…
Cancel
Save