Improvements to wake

This commit is contained in:
Calum
2017-04-30 19:32:29 +12:00
parent b9900925b8
commit 45b77c05d4
3 changed files with 102 additions and 46 deletions
+74 -23
View File
@@ -10,7 +10,9 @@ import javafx.scene.transform.Rotate;
import seng302.models.parsers.StreamParser; import seng302.models.parsers.StreamParser;
/** /**
* Created by CJIRWIN on 25/04/2017. * BoatGroup is a javafx group that by default contains a graphical objects for representing a 2 dimensional boat.
* It contains a single polygon for the boat, a group of lines to show it's path, a wake object and two text labels to
* annotate the boat teams name and the boats velocity.
*/ */
public class BoatGroup extends RaceObject{ public class BoatGroup extends RaceObject{
@@ -20,7 +22,7 @@ public class BoatGroup extends RaceObject{
private static final double VELOCITY_Y_OFFSET = -5d; private static final double VELOCITY_Y_OFFSET = -5d;
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;
private static final int LINE_INTERVAL = 30; private static final int LINE_INTERVAL = 180;
private static double expectedUpdateInterval = 200; private static double expectedUpdateInterval = 200;
private double framesForNewLine = 0; private double framesForNewLine = 0;
private boolean destinationSet; private boolean destinationSet;
@@ -34,16 +36,34 @@ public class BoatGroup extends RaceObject{
private Text velocityObject; private Text velocityObject;
private Wake wake; private Wake wake;
/**
* Creates a BoatGroup with the default triangular boat polygon.
* @param boat The boat that the BoatGroup will represent. Must contain an ID which will be used to tell which
* BoatGroup to update.
* @param color The colour of the boat polygon and the trailing line.
*/
public BoatGroup (Boat boat, Color color){ public BoatGroup (Boat boat, Color color){
this.boat = boat; this.boat = boat;
initChildren(color); initChildren(color);
} }
/**
* Creates a BoatGroup with the boat being the default polygon. The head of the boat should be at point (0,0).
* @param boat The boat that the BoatGroup will represent. Must contain an ID which will be used to tell which
* BoatGroup to update.
* @param color The colour of the boat polygon and the trailing line.
* @param points An array of co-ordinates x1,y1,x2,y2,x3,y3... that will make up the boat polygon.
*/
public BoatGroup (Boat boat, Color color, double... points) public BoatGroup (Boat boat, Color color, double... points)
{ {
initChildren(color, points); initChildren(color, points);
} }
/**
* Creates the javafx objects that will be the in the group by default.
* @param color The colour of the boat polygon and the trailing line.
* @param points An array of co-ordinates x1,y1,x2,y2,x3,y3... that will make up the boat polygon.
*/
private void initChildren (Color color, double... points) { private void initChildren (Color color, double... points) {
boatPoly = new Polygon(points); boatPoly = new Polygon(points);
boatPoly.setFill(color); boatPoly.setFill(color);
@@ -60,16 +80,20 @@ public class BoatGroup extends RaceObject{
velocityObject.relocate(velocityObject.getX(), velocityObject.getY()); velocityObject.relocate(velocityObject.getX(), velocityObject.getY());
destinationSet = false; destinationSet = false;
wake = new Wake(0, 0); wake = new Wake(0, -BOAT_HEIGHT);
wakeGenerationDelay = wake.numWakes; wakeGenerationDelay = wake.numWakes;
super.getChildren().addAll(teamNameObject, velocityObject, boatPoly); super.getChildren().addAll(teamNameObject, velocityObject, boatPoly);
} }
/**
* Creates the javafx objects that will be the in the group by default.
* @param color The colour of the boat polygon and the trailing line.
*/
private void initChildren (Color color) { private void initChildren (Color color) {
initChildren(color, initChildren(color,
-BOAT_WIDTH / 2, BOAT_HEIGHT, -BOAT_WIDTH / 2, BOAT_HEIGHT / 2,
0.0, 0.0, 0.0, -BOAT_HEIGHT / 2,
BOAT_WIDTH / 2, BOAT_HEIGHT); BOAT_WIDTH / 2, BOAT_HEIGHT / 2);
} }
/** /**
@@ -93,12 +117,18 @@ public class BoatGroup extends RaceObject{
* Moves the boat and its children annotations to coordinates specified * Moves the boat and its children annotations to coordinates specified
* @param x The X coordinate to move the boat to * @param x The X coordinate to move the boat to
* @param y The Y coordinate to move the boat to * @param y The Y coordinate to move the boat to
* @param rotation The heading in degrees from north the boat should rotate to.
*/ */
public void moveTo (double x, double y, double rotation) { public void moveTo (double x, double y, double rotation) {
rotateTo(rotation); rotateTo(rotation);
moveTo(x, y); moveTo(x, y);
} }
/**
* Moves the boat and its children annotations to coordinates specified
* @param x The X coordinate to move the boat to
* @param y The Y coordinate to move the boat to
*/
public void moveTo (double x, double y) { public void moveTo (double x, double y) {
boatPoly.setLayoutX(x); boatPoly.setLayoutX(x);
boatPoly.setLayoutY(y); boatPoly.setLayoutY(y);
@@ -108,13 +138,18 @@ public class BoatGroup extends RaceObject{
velocityObject.setLayoutY(y); velocityObject.setLayoutY(y);
wake.setLayoutX(x); wake.setLayoutX(x);
wake.setLayoutY(y); wake.setLayoutY(y);
//wake.rotate(currentRotation); wake.rotate(currentRotation);
} }
/**
* Updates the position of all graphics in the BoatGroup based off of the given time interval.
* @param timeInterval The interval, in microseconds, the boat should update it's position based on.
*/
public void updatePosition (long timeInterval) { public void updatePosition (long timeInterval) {
//Calculate the movement of the boat.
double dx = pixelVelocityX * timeInterval; double dx = pixelVelocityX * timeInterval;
double dy = pixelVelocityY * timeInterval; double dy = pixelVelocityY * timeInterval;
double rotation = 0d; double rotation = rotationalVelocity * timeInterval;
moveGroupBy(dx, dy, rotation); moveGroupBy(dx, dy, rotation);
@@ -134,7 +169,7 @@ public class BoatGroup extends RaceObject{
if (destinationSet){ if (destinationSet){
lastPoint = new Point2D(boatPoly.getLayoutX(), boatPoly.getLayoutY()); lastPoint = new Point2D(boatPoly.getLayoutX(), boatPoly.getLayoutY());
} }
if (lineGroup.getChildren().size() > 80) if (lineGroup.getChildren().size() > 60)
lineGroup.getChildren().remove(0); lineGroup.getChildren().remove(0);
} }
wake.updatePosition(timeInterval); wake.updatePosition(timeInterval);
@@ -143,20 +178,38 @@ public class BoatGroup extends RaceObject{
public void setDestination (double newXValue, double newYValue, double rotation, int... raceIds) { public void setDestination (double newXValue, double newYValue, double rotation, int... raceIds) {
destinationSet = true; destinationSet = true;
boat.setVelocity(StreamParser.boatSpeeds.get((long)boat.getId())); boat.setVelocity(StreamParser.boatSpeeds.get((long)boat.getId()));
velocityObject.setText(String.valueOf(boat.getVelocity()));
if (hasRaceId(raceIds)) { if (hasRaceId(raceIds)) {
this.pixelVelocityX = (newXValue - boatPoly.getLayoutX()) / expectedUpdateInterval; double dx = newXValue - boatPoly.getLayoutX();
this.pixelVelocityY = (newYValue - boatPoly.getLayoutY()) / expectedUpdateInterval; if ((dx > 0 && pixelVelocityX < 0) || (dx < 0 && pixelVelocityX > 0)) {
this.rotationalGoal = rotation; pixelVelocityX = 0;
} else {
pixelVelocityX = dx / expectedUpdateInterval;
}
double dy = newYValue - boatPoly.getLayoutY();
if ((dy > 0 && pixelVelocityY < 0) || (dy < 0 && pixelVelocityY > 0)) {
pixelVelocityY = 0;
} else {
pixelVelocityY = dy / expectedUpdateInterval;
}
// this.pixelVelocityX = (newXValue - boatPoly.getLayoutX()) / expectedUpdateInterval;
// this.pixelVelocityY = (newYValue - boatPoly.getLayoutY()) / expectedUpdateInterval;
rotationalGoal = rotation;
calculateRotationalVelocity(); calculateRotationalVelocity();
System.out.println("rotationalVelocity = " + rotationalVelocity); //Sometimes rotations are way too big.
rotateTo(rotation); //if (Math.abs(rotationalVelocity) > 0.00003)
// if (wakeGenerationDelay > 0) { // rotationalVelocity = 0;
// wake.rotate(rotationalGoal); //
// wakeGenerationDelay--; if (wakeGenerationDelay > 0) {
// } else { wake.rotate(rotationalGoal);
wakeGenerationDelay--;
} else {
if (Math.abs(rotationalVelocity) > 0.1)
// rotationalVelocity = 0;
//
wake.setRotationalVelocity(0, rotationalGoal, pixelVelocityX, pixelVelocityY);
else
wake.setRotationalVelocity(rotationalVelocity, rotationalGoal, pixelVelocityX, pixelVelocityY); wake.setRotationalVelocity(rotationalVelocity, rotationalGoal, pixelVelocityX, pixelVelocityY);
// } }
} }
} }
@@ -181,11 +234,9 @@ public class BoatGroup extends RaceObject{
boatPoly.getTransforms().add(new Rotate(rotation)); boatPoly.getTransforms().add(new Rotate(rotation));
} }
public void forceRotation () { public void forceRotation () {
rotateTo (rotationalGoal); rotateTo (rotationalGoal);
//wake.rotate(rotationalGoal); wake.rotate(rotationalGoal);
} }
public void toggleAnnotations () { public void toggleAnnotations () {
+5 -14
View File
@@ -50,13 +50,10 @@ class Wake extends Group {
void setRotationalVelocity (double rotationalVelocity, double rotationGoal, double velocityX, double velocityY) { void setRotationalVelocity (double rotationalVelocity, double rotationGoal, double velocityX, double velocityY) {
sum -= Math.abs(velocities[velocityIndices[0]]); sum -= Math.abs(velocities[velocityIndices[0]]);
sum += Math.abs(rotationalVelocity); sum += Math.abs(rotationalVelocity);
if (sum < 0.0001) { if (sum < 0.00002)
System.out.println("***************************************************************************"); rotate (rotationGoal); //In relatively straight segments the wake snaps to match the boats current position.
System.out.println(sum);
System.out.println("***************************************************************************");
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. //This stops the wake from eventually becoming out of sync with the boat.
}
//Update the index of the array of recent velocities that each wake uses. Each wake is 3 velocities behind the //Update the index of the array of recent velocities that each wake uses. Each wake is 3 velocities behind the
//next smallest wake. //next smallest wake.
velocityIndices[0] = (13 + (velocityIndices[0] - 1) % 13) % 13; velocityIndices[0] = (13 + (velocityIndices[0] - 1) % 13) % 13;
@@ -66,9 +63,9 @@ class Wake extends Group {
//Scale wakes based on velocity. Assumes boats are always moving at a decent pace. //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 scaleFactor = Math.abs(Math.log10(Math.abs(velocityX) + Math.abs(velocityY)));
double baseRad = 30; double baseRad = 25;
for (Arc arc :arcs) { for (Arc arc :arcs) {
double rad = Math.min(baseRad + 4 * scaleFactor, baseRad + 12); double rad = Math.min(baseRad + 5 * scaleFactor, baseRad + 15);
arc.setRadiusX(rad); arc.setRadiusX(rad);
arc.setRadiusY(rad); arc.setRadiusY(rad);
baseRad += 10; baseRad += 10;
@@ -84,12 +81,6 @@ class Wake extends Group {
rotations[i] = rotations[i] + velocities[velocityIndices[i]] * timeInterval; rotations[i] = rotations[i] + velocities[velocityIndices[i]] * timeInterval;
arcs[i].getTransforms().setAll(new Rotate(rotations[i])); arcs[i].getTransforms().setAll(new Rotate(rotations[i]));
} }
System.out.println("rotations[0] = " + rotations[0]);
System.out.println("rotations[1] = " + rotations[1]);
System.out.println("rotations[2] = " + rotations[2]);
System.out.println("rotations[3] = " + rotations[3]);
System.out.println("rotations[4] = " + rotations[4]);
} }
/** /**
@@ -4,6 +4,8 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.net.Socket; import java.net.Socket;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator; import java.util.Comparator;
import java.util.concurrent.PriorityBlockingQueue; import java.util.concurrent.PriorityBlockingQueue;
import java.util.zip.CRC32; import java.util.zip.CRC32;
@@ -14,7 +16,7 @@ public class StreamReceiver extends Thread {
private InputStream stream; private InputStream stream;
private Socket host; private Socket host;
private ByteArrayOutputStream crcBuffer; private ByteArrayOutputStream crcBuffer;
private Thread thread; private Thread t;
private String threadName; private String threadName;
public static PriorityBlockingQueue<StreamPacket> packetBuffer; public static PriorityBlockingQueue<StreamPacket> packetBuffer;
@@ -29,20 +31,21 @@ public class StreamReceiver extends Thread {
} }
public void run(){ public void run(){
packetBuffer = new PriorityBlockingQueue<>(256, new Comparator<StreamPacket>() { PriorityBlockingQueue<StreamPacket> pq = new PriorityBlockingQueue<>(256, new Comparator<StreamPacket>() {
@Override @Override
public int compare(StreamPacket s1, StreamPacket s2) { public int compare(StreamPacket s1, StreamPacket s2) {
return (int) (s1.getTimeStamp() - s2.getTimeStamp()); return (int) (s1.getTimeStamp() - s2.getTimeStamp());
} }
}); });
packetBuffer = pq;
connect(); connect();
} }
public void start () { public void start () {
System.out.println("Starting " + threadName ); System.out.println("Starting " + threadName );
if (thread == null) { if (t == null) {
thread = new Thread (this, threadName); t = new Thread (this, threadName);
thread.start (); t.start ();
} }
} }
@@ -138,4 +141,15 @@ public class StreamReceiver extends Thread {
} }
return partialLong; return partialLong;
} }
public static void main(String[] args) {
StreamReceiver sr = new StreamReceiver("csse-s302staff.canterbury.ac.nz", 4941,"TestThread1");
//StreamReceiver sr = new StreamReceiver("livedata.americascup.com", 4941, "TestThread2");
sr.start();
}
} }