boat movement working reliably now, still need to fix one bug at initialization #story[923]

This commit is contained in:
Peter Galloway
2017-05-17 17:34:47 +12:00
parent 9e3036e134
commit aaa3dc93f1
4 changed files with 77 additions and 47 deletions
+1 -1
View File
@@ -62,7 +62,7 @@ public class App extends Application
} }
//Change the StreamReceiver in this else block to change the default data source. //Change the StreamReceiver in this else block to change the default data source.
else{ else{
sr = new StreamReceiver("livedata.americascup.com", 4941, "RaceStream"); sr = new StreamReceiver("localhost", 4949, "RaceStream");
} }
sr.start(); sr.start();
@@ -51,10 +51,12 @@ public class CanvasController {
private Mark maxLonPoint; private Mark maxLonPoint;
private double referencePointX; private double referencePointX;
private double referencePointY; private double referencePointY;
private List<MarkGroup> markGroups = new ArrayList<>(); private List<MarkGroup> markGroups = new ArrayList<>();
private List<BoatGroup> boatGroups = new ArrayList<>(); private List<BoatGroup> boatGroups = new ArrayList<>();
//FRAME RATE //FRAME RATE
private Double frameRate = 60.0;
private final long[] frameTimes = new long[30]; private final long[] frameTimes = new long[30];
private int frameTimeIndex = 0; private int frameTimeIndex = 0;
private boolean arrayFilled = false; private boolean arrayFilled = false;
@@ -93,7 +95,7 @@ public class CanvasController {
// TODO: 1/05/17 wmu16 - Change this call to now draw the marks as from the xml // TODO: 1/05/17 wmu16 - Change this call to now draw the marks as from the xml
drawBoats(); initializeBoats();
timer = new AnimationTimer() { timer = new AnimationTimer() {
@Override @Override
@@ -110,7 +112,7 @@ public class CanvasController {
if (arrayFilled) { if (arrayFilled) {
elapsedNanos = now - oldFrameTime ; elapsedNanos = now - oldFrameTime ;
long elapsedNanosPerFrame = elapsedNanos / frameTimes.length ; long elapsedNanosPerFrame = elapsedNanos / frameTimes.length ;
Double frameRate = 1_000_000_000.0 / elapsedNanosPerFrame ; frameRate = 1_000_000_000.0 / elapsedNanosPerFrame ;
drawFps(frameRate.intValue()); drawFps(frameRate.intValue());
} }
@@ -167,30 +169,38 @@ public class CanvasController {
private void updateGroups(){ private void updateGroups(){
for (BoatGroup boatGroup : boatGroups) { for (BoatGroup boatGroup : boatGroups) {
boatGroup.updatePosition();
// some raceObjects will have multiple ID's (for instance gate marks) // some raceObjects will have multiple ID's (for instance gate marks)
//checking if the current "ID" has any updates associated with it //checking if the current "ID" has any updates associated with it
if (StreamParser.boatPositions.containsKey(boatGroup.getRaceId())) { if (StreamParser.boatPositions.containsKey(boatGroup.getRaceId())) {
moveBoatGroup(boatGroup); if (boatGroup.isStopped()) {
updateBoatGroup(boatGroup);
} }
} }
boatGroup.move();
}
for (MarkGroup markGroup : markGroups) { for (MarkGroup markGroup : markGroups) {
for (int id : markGroup.getRaceIds()) { for (int id : markGroup.getRaceIds()) {
if (StreamParser.boatPositions.containsKey(id)) { if (StreamParser.boatPositions.containsKey(id)) {
moveMarkGroup(id, markGroup); UpdateMarkGroup(id, markGroup);
} }
} }
} }
} }
private void moveBoatGroup(BoatGroup boatGroup) { private void updateBoatGroup(BoatGroup boatGroup) {
PriorityBlockingQueue<BoatPositionPacket> movementQueue = StreamParser.boatPositions.get(boatGroup.getRaceId()); PriorityBlockingQueue<BoatPositionPacket> movementQueue = StreamParser.boatPositions.get(boatGroup.getRaceId());
if (movementQueue.size() > 0){ // giving the movementQueue a 5 packet buffer to account for slightly out of order packets
if (movementQueue.size() > 5){
try { try {
BoatPositionPacket positionPacket = movementQueue.take(); BoatPositionPacket positionPacket = movementQueue.take();
Point2D p2d = findScaledXY(positionPacket.getLat(), positionPacket.getLon()); Point2D p2d = findScaledXY(positionPacket.getLat(), positionPacket.getLon());
if (boatGroup.getRaceId() == 106){
// System.out.println("p2d.getX() = " + p2d.getX());
// System.out.println("p2d.getY() = " + p2d.getY());
// System.out.println("positionPacket.getTimeValid() = " + positionPacket.getTimeValid());
}
double heading = 360.0 / 0xffff * positionPacket.getHeading(); double heading = 360.0 / 0xffff * positionPacket.getHeading();
boatGroup.setDestination(p2d.getX(), p2d.getY(), heading, positionPacket.getGroundSpeed(), boatGroup.getRaceId()); boatGroup.setDestination(p2d.getX(), p2d.getY(), heading, positionPacket.getGroundSpeed(), positionPacket.getTimeValid(), frameRate, boatGroup.getRaceId());
} catch (InterruptedException e){ } catch (InterruptedException e){
e.printStackTrace(); e.printStackTrace();
} }
@@ -198,7 +208,7 @@ public class CanvasController {
} }
} }
void moveMarkGroup (int raceId, MarkGroup markGroup) { void UpdateMarkGroup (int raceId, MarkGroup markGroup) {
PriorityBlockingQueue<BoatPositionPacket> movementQueue = StreamParser.boatPositions.get(raceId); PriorityBlockingQueue<BoatPositionPacket> movementQueue = StreamParser.boatPositions.get(raceId);
if (movementQueue.size() > 0){ if (movementQueue.size() > 0){
try { try {
@@ -211,6 +221,23 @@ public class CanvasController {
} }
} }
/**
* Draws all the boats.
*/
private void initializeBoats() {
Map<Integer, Yacht> boats = StreamParser.getBoats();
Group boatAnnotations = new Group();
for (Yacht boat : boats.values()) {
boat.setColour(Colors.getColor());
BoatGroup boatGroup = new BoatGroup(boat, boat.getColour());
boatGroups.add(boatGroup);
boatAnnotations.getChildren().add(boatGroup.getLowPriorityAnnotations());
}
group.getChildren().add(boatAnnotations);
group.getChildren().addAll(boatGroups);
}
class ResizableCanvas extends Canvas { class ResizableCanvas extends Canvas {
ResizableCanvas() { ResizableCanvas() {
@@ -236,11 +263,11 @@ public class CanvasController {
public double prefWidth(double height) { public double prefWidth(double height) {
return getWidth(); return getWidth();
} }
@Override @Override
public double prefHeight(double width) { public double prefHeight(double width) {
return getHeight(); return getHeight();
} }
} }
private void drawFps(int fps){ private void drawFps(int fps){
@@ -259,23 +286,6 @@ public class CanvasController {
} }
} }
/**
* Draws all the boats.
*/
private void drawBoats() {
Map<Integer, Yacht> boats = StreamParser.getBoats();
Group boatAnnotations = new Group();
for (Yacht boat : boats.values()) {
boat.setColour(Colors.getColor());
BoatGroup boatGroup = new BoatGroup(boat, boat.getColour());
boatGroups.add(boatGroup);
boatAnnotations.getChildren().add(boatGroup.getLowPriorityAnnotations());
}
group.getChildren().add(boatAnnotations);
group.getChildren().addAll(boatGroups);
}
/** /**
* Calculates x and y location for every marker that fits it to the canvas the race will be drawn on. * Calculates x and y location for every marker that fits it to the canvas the race will be drawn on.
*/ */
@@ -382,6 +392,7 @@ public class CanvasController {
* Give all markers in the course an x,y location relative to a given reference with a known x,y location. Distances * Give all markers in the course an x,y location relative to a given reference with a known x,y location. Distances
* are scaled according to the distanceScaleFactor variable. * are scaled according to the distanceScaleFactor variable.
*/ */
// DEPRECATED create an initialize marks method like the initialize boats method
private void givePointsXY() { private void givePointsXY() {
// List<XMLParser.RaceXMLObject.CompoundMark> allPoints = StreamParser.getXmlObject().getRaceXML().getCompoundMarks(); // List<XMLParser.RaceXMLObject.CompoundMark> allPoints = StreamParser.getXmlObject().getRaceXML().getCompoundMarks();
// List<XMLParser.RaceXMLObject.CompoundMark> processed = new ArrayList<>(); // List<XMLParser.RaceXMLObject.CompoundMark> processed = new ArrayList<>();
+37 -18
View File
@@ -29,13 +29,16 @@ public class BoatGroup extends Group{
private static final double BOAT_HEIGHT = 15d; private static final double BOAT_HEIGHT = 15d;
private static final double BOAT_WIDTH = 10d; private static final double BOAT_WIDTH = 10d;
//Variables for boat logic. //Variables for boat logic.
private boolean isStopped = true;
private double xIncrement;
private double yIncrement;
private long lastTimeValid = 0;
private long framesToMove;
private Point2D lastPoint; private Point2D lastPoint;
double oldTime; double oldTime;
double newTime; double newTime;
double lastYValue = 0; double lastYValue = 0;
double lastXValue = 0; double lastXValue = 0;
private double dx;
private double dy;
private double pixelVelocityX; private double pixelVelocityX;
private double pixelVelocityY; private double pixelVelocityY;
private static final int expectedUpdateInterval = 200; private static final int expectedUpdateInterval = 200;
@@ -118,8 +121,6 @@ public class BoatGroup extends Group{
teamNameObject.setLayoutY(teamNameObject.getLayoutY() + dy); teamNameObject.setLayoutY(teamNameObject.getLayoutY() + dy);
velocityObject.setLayoutX(velocityObject.getLayoutX() + dx); velocityObject.setLayoutX(velocityObject.getLayoutX() + dx);
velocityObject.setLayoutY(velocityObject.getLayoutY() + dy); velocityObject.setLayoutY(velocityObject.getLayoutY() + dy);
wake.setLayoutX(wake.getLayoutX() + dx);
wake.setLayoutY(wake.getLayoutY() + dy);
} }
@@ -136,16 +137,18 @@ public class BoatGroup extends Group{
teamNameObject.setLayoutY(y); teamNameObject.setLayoutY(y);
velocityObject.setLayoutX(x); velocityObject.setLayoutX(x);
velocityObject.setLayoutY(y); velocityObject.setLayoutY(y);
wake.setLayoutX(x);
wake.setLayoutY(y);
} }
public void rotateTo (double rotation) { public void rotateTo (double rotation) {
boatPoly.getTransforms().setAll(new Rotate(rotation)); boatPoly.getTransforms().setAll(new Rotate(rotation));
} }
public void updatePosition () { public void move() {
moveGroupBy(dx, dy); moveGroupBy(xIncrement, yIncrement);
framesToMove = framesToMove - 1;
if (framesToMove <= 0){
isStopped = true;
}
} }
/** /**
@@ -153,20 +156,32 @@ public class BoatGroup extends Group{
* @param newXValue The X co-ordinate the boat needs to move to. * @param newXValue The X co-ordinate the boat needs to move to.
* @param newYValue The Y co-ordinate the boat needs to move to. * @param newYValue The Y co-ordinate the boat needs to move to.
* @param rotation Rotation to move graphics to. * @param rotation Rotation to move graphics to.
* @param raceIds RaceID of the object to move. * @param timeValid the time the position values are valid for
*/ */
public void setDestination (double newXValue, double newYValue, double rotation, double groundSpeed, long raceIds) { public void setDestination (double newXValue, double newYValue, double rotation, double groundSpeed, long timeValid, double frameRate, long id) {
System.currentTimeMillis(); if (lastTimeValid == 0){
moveTo(lastXValue, lastYValue, rotation); lastTimeValid = timeValid - 200;
moveTo(newXValue, newYValue, rotation);
}
dx = (newXValue - lastXValue)/12;
dy = (newYValue - lastYValue)/12;
lastXValue = newXValue; rotateTo(rotation);
lastYValue = newYValue; framesToMove = Math.round((frameRate/(1000.0f/(timeValid-lastTimeValid))));
boat.setVelocity(groundSpeed); double dx = newXValue - boatPoly.getLayoutX();
velocityObject.setText(String.format("%.2f m/s", boat.getVelocity())); double dy = newYValue - boatPoly.getLayoutY();
xIncrement = dx/framesToMove;
yIncrement = dy/framesToMove;
if (id == 106){
System.out.println(framesToMove);
System.out.println("xIncrement = " + xIncrement);
}
velocityObject.setText(String.format("%.2f m/s", groundSpeed));
lastTimeValid = timeValid;
isStopped = false;
} }
@@ -230,4 +245,8 @@ public class BoatGroup extends Group{
group.getChildren().addAll(wake, lineGroup); group.getChildren().addAll(wake, lineGroup);
return group; return group;
} }
public boolean isStopped() {
return isStopped;
}
} }
@@ -44,7 +44,7 @@ public class BoatLocationMessage extends Message {
public BoatLocationMessage(int sourceId, int sequenceNum, double latitude, double longitude, double heading, long boatSpeed){ public BoatLocationMessage(int sourceId, int sequenceNum, double latitude, double longitude, double heading, long boatSpeed){
boatSpeed /= 10; boatSpeed /= 10;
messageVersionNumber = 1; messageVersionNumber = 1;
time = System.currentTimeMillis() / 1000L; time = System.currentTimeMillis();
this.sourceId = sourceId; this.sourceId = sourceId;
this.sequenceNum = sequenceNum; this.sequenceNum = sequenceNum;
this.deviceType = DeviceType.RACING_YACHT; this.deviceType = DeviceType.RACING_YACHT;