diff --git a/src/main/java/seng302/App.java b/src/main/java/seng302/App.java index a66be5a9..dc6de280 100644 --- a/src/main/java/seng302/App.java +++ b/src/main/java/seng302/App.java @@ -26,7 +26,7 @@ public class App extends Application sr = new StreamReceiver("localhost", 8085, "TestThread1"); } else{ - //StreamReceiver sr = new StreamReceiver("csse-s302staff.canterbury.ac.nz", 4941,"TestThread1"); +// sr = new StreamReceiver("csse-s302staff.canterbury.ac.nz", 4941,"TestThread1"); sr = new StreamReceiver("livedata.americascup.com", 4941, "TestThread1"); } diff --git a/src/main/java/seng302/controllers/CanvasController.java b/src/main/java/seng302/controllers/CanvasController.java index a862b607..84a58663 100644 --- a/src/main/java/seng302/controllers/CanvasController.java +++ b/src/main/java/seng302/controllers/CanvasController.java @@ -125,7 +125,6 @@ public class CanvasController { } // TODO: 1/05/17 cir27 - Make the RaceObjects update on the actual delay. elapsedNanos = 1000 / 60; - System.out.println("elapsedNanos = " + elapsedNanos); for (RaceObject raceObject : raceObjects) { raceObject.updatePosition(elapsedNanos); for (int id : raceObject.getRaceIds()) { diff --git a/src/main/java/seng302/models/BoatGroup.java b/src/main/java/seng302/models/BoatGroup.java index 99fcf0a6..618a3b59 100644 --- a/src/main/java/seng302/models/BoatGroup.java +++ b/src/main/java/seng302/models/BoatGroup.java @@ -22,11 +22,11 @@ public class BoatGroup extends RaceObject{ private static final double VELOCITY_Y_OFFSET = -5d; private static final double BOAT_HEIGHT = 15d; private static final double BOAT_WIDTH = 10d; - private static final int LINE_INTERVAL = 30; - private double framesForNewLine = 0; + private static double expectedUpdateInterval = 200; private boolean destinationSet; private Point2D lastPoint; - private int wakeGenerationDelay; + private int wakeGenerationDelay = 10; + private double distanceTravelled; private Boat boat; private Group lineGroup = new Group(); @@ -81,7 +81,6 @@ public class BoatGroup extends RaceObject{ destinationSet = false; wake = new Wake(0, -BOAT_HEIGHT); - wakeGenerationDelay = wake.numWakes; super.getChildren().addAll(teamNameObject, velocityObject, boatPoly); } @@ -150,10 +149,11 @@ public class BoatGroup extends RaceObject{ double dx = pixelVelocityX * timeInterval; double dy = pixelVelocityY * timeInterval; double rotation = rotationalVelocity * timeInterval; + distanceTravelled += Math.abs(dx) + Math.abs(dy); moveGroupBy(dx, dy, rotation); - - if (framesForNewLine-- == 0) { - framesForNewLine = LINE_INTERVAL; + //Draw a new section of the trail every 20 pixels of movement. + if (distanceTravelled > 20) { + distanceTravelled = 0; if (lastPoint != null) { Line l = new Line( lastPoint.getX(), @@ -161,19 +161,24 @@ public class BoatGroup extends RaceObject{ boatPoly.getLayoutX(), boatPoly.getLayoutY() ); - l.getStrokeDashArray().setAll(4d, 6d); + l.getStrokeDashArray().setAll(3d, 7d); l.setStroke(boatPoly.getFill()); lineGroup.getChildren().add(l); } - if (destinationSet){ + if (destinationSet){ //Only begin drawing after the first destination is set lastPoint = new Point2D(boatPoly.getLayoutX(), boatPoly.getLayoutY()); } - if (lineGroup.getChildren().size() > 60) - lineGroup.getChildren().remove(0); } wake.updatePosition(timeInterval); } + /** + * Sets the destination of the boat and the headng it should have once it reaches + * @param newXValue + * @param newYValue + * @param rotation Rotation to move graphics to. + * @param raceIds RaceID of the object to move. + */ public void setDestination (double newXValue, double newYValue, double rotation, int... raceIds) { if (hasRaceId(raceIds)) { destinationSet = true; @@ -187,19 +192,37 @@ public class BoatGroup extends RaceObject{ pixelVelocityX = dx / expectedUpdateInterval; } double dy = newYValue - boatPoly.getLayoutY(); - if ((dy > 0 && pixelVelocityY < 0) || (dy < 0 && pixelVelocityY > 0)) { - pixelVelocityY = 0; - } else { - pixelVelocityY = dy / expectedUpdateInterval; + //Check movement is reasonable. Assumes a 1000 * 1000 canvas + if (Math.abs(dx) > 50 || Math.abs(dy) > 50) { +// System.out.println("dx = " + dx); +// System.out.println("dy = " + dy); + dx = 0; + dy = 0; + moveTo(newXValue, newYValue); } + //Slight delay on changing X/Y direction that could help jitter. Disabled since there was an issue with + //packets that might be causing it. +// if ((dx > 0 && pixelVelocityX < 0) || (dx < 0 && pixelVelocityX > 0)) { +// pixelVelocityX = 0; +// } else { +// pixelVelocityX = dx / expectedUpdateInterval; +// } +// if ((dy > 0 && pixelVelocityY < 0) || (dy < 0 && pixelVelocityY > 0)) { +// pixelVelocityY = 0; +// } else { +// pixelVelocityY = dy / expectedUpdateInterval; +// } + pixelVelocityX = dx / expectedUpdateInterval; + pixelVelocityY = dy / expectedUpdateInterval; rotationalGoal = rotation; calculateRotationalVelocity(); if (wakeGenerationDelay > 0) { wake.rotate(rotationalGoal); wakeGenerationDelay--; } else { - wake.setRotationalVelocity(rotationalVelocity, currentRotation, pixelVelocityX, pixelVelocityY); + wake.setRotationalVelocity(rotationalVelocity, currentRotation, boat.getVelocity()); } + velocityObject.setText(String.format("%.2f m/s", boat.getVelocity())); } } diff --git a/src/main/java/seng302/models/Wake.java b/src/main/java/seng302/models/Wake.java index a064dc7e..d389e8e7 100644 --- a/src/main/java/seng302/models/Wake.java +++ b/src/main/java/seng302/models/Wake.java @@ -15,12 +15,13 @@ import javafx.scene.transform.Rotate; */ class Wake extends Group { - final int numWakes = 5; + private int numWakes = 5; private double[] velocities = new double[13]; private Arc[] arcs = new Arc[numWakes]; private double[] rotations = new double[numWakes]; private int[] velocityIndices = new int[numWakes]; private double sum = 0; + private static double max; /** * Create a wake at the given location. @@ -46,15 +47,19 @@ class Wake extends Group { * Sets the rotationalVelocity of each arc. Each arc is 3 velocities behind the next smallest arc. The smallest uses * the latest given velocity. * @param rotationalVelocity The rotationalVelocity the wake should move at. + * @param rotationGoal Where the wake will rotate to if the wake is calculated to be on a straight section. This is + * used to prevent desynchronisation with the Boat polygon. + * @param velocity The real world velocity of the boat in m/s. */ - void setRotationalVelocity (double rotationalVelocity, double rotationGoal, double velocityX, double velocityY) { - if (Math.abs(rotationalVelocity) > 0.5) { - rotationalVelocity = 0; - } + void setRotationalVelocity (double rotationalVelocity, double rotationGoal, double velocity) { +// if (Math.abs(rotationalVelocity) > 0.5) { +// rotationalVelocity = 0; +// } sum -= Math.abs(velocities[(velocityIndices[0] + 10) % 13]); sum += Math.abs(rotationalVelocity); - System.out.println("sum = " + sum); - if (sum < 0.9) +// System.out.println("sum = " + sum); + max = Math.max(max, rotationalVelocity); + if (sum < max) rotate (rotationGoal); //In relatively straight segments the wake snaps to match the boats current position. //This stops the wake from eventually becoming out of sync with the boat. @@ -65,14 +70,14 @@ class Wake extends Group { for (int i = 1; i < numWakes; i++) velocityIndices[i] = (velocityIndices[0] + 3 * i) % 13; - //Scale wakes based on velocity. Assumes boats are always moving at a decent pace. - double scaleFactor = Math.abs(Math.log10(Math.abs(velocityX) + Math.abs(velocityY))); - double baseRad = 25; + //Scale wakes based on velocity. + double baseRad = 20; + double rad; for (Arc arc :arcs) { - double rad = Math.min(baseRad + 5 * scaleFactor, baseRad + 15); + rad = baseRad + velocity; arc.setRadiusX(rad); arc.setRadiusY(rad); - baseRad += 10; + baseRad += 5 + (velocity / 2); } } diff --git a/src/main/java/seng302/models/mark/MarkGroup.java b/src/main/java/seng302/models/mark/MarkGroup.java index 6448f2e2..b0ef4768 100644 --- a/src/main/java/seng302/models/mark/MarkGroup.java +++ b/src/main/java/seng302/models/mark/MarkGroup.java @@ -142,13 +142,13 @@ public class MarkGroup extends RaceObject { if (nodePixelVelocitiesX[0] > 0 && markCircle.getCenterX() > nodeDestinations[0].getX() || nodePixelVelocitiesX[0] < 0 && markCircle.getCenterX() < nodeDestinations[0].getY()) nodePixelVelocitiesX[0] = 0; - else + else if (nodePixelVelocitiesX[0] != 0) markCircle.setCenterX(markCircle.getCenterX() + nodePixelVelocitiesX[0] * timeInterval); if (nodePixelVelocitiesY[0] > 0 && markCircle.getCenterY() > nodeDestinations[0].getY() || nodePixelVelocitiesY[0] < 0 && markCircle.getCenterY() < nodeDestinations[0].getY()) nodePixelVelocitiesY[0] = 0; - else + else if (nodePixelVelocitiesY[0] != 0) markCircle.setCenterY(markCircle.getCenterY() + nodePixelVelocitiesY[0] * timeInterval); if (mainMark.getMarkType() != MarkType.SINGLE_MARK) { @@ -162,13 +162,13 @@ public class MarkGroup extends RaceObject { if (nodePixelVelocitiesX[1] > 0 && markCircle.getCenterX() >= nodeDestinations[1].getX() || nodePixelVelocitiesX[1] < 0 && markCircle.getCenterX() <= nodeDestinations[1].getX()) nodePixelVelocitiesX[1] = 0; - else + else if (nodePixelVelocitiesX[1] != 0) markCircle.setCenterX(markCircle.getCenterX() + nodePixelVelocitiesX[1] * timeInterval); if (nodePixelVelocitiesY[1] > 0 && markCircle.getCenterY() > nodeDestinations[1].getY() || nodePixelVelocitiesY[1] < 0 && markCircle.getCenterY() < nodeDestinations[1].getY()) nodePixelVelocitiesY[1] = 0; - else + else if (nodePixelVelocitiesY[1] != 0) markCircle.setCenterY(markCircle.getCenterY() + nodePixelVelocitiesY[1] * timeInterval); line.setEndX(markCircle.getCenterX()); line.setEndY(markCircle.getCenterY());