From 246083460ef2bc979c8b86ad9257b7521ba16235 Mon Sep 17 00:00:00 2001 From: Peter Galloway Date: Sat, 29 Apr 2017 20:13:34 +1200 Subject: [PATCH 1/7] partway through fixing boat movement to be updated from the data valid timestamp rather than the data sent timestamp #story[820] --- src/main/java/seng302/models/BoatGroup.java | 32 +++++------ .../seng302/models/parsers/StreamParser.java | 47 +++++++++------- .../models/parsers/StreamReceiver.java | 2 + .../parsers/packets/BoatPositionPacket.java | 23 ++++++++ .../models/parsers/packets/PacketType.java | 53 +++++++++++++++++++ .../models/parsers/packets/StreamPacket.java | 44 +++++++++++++++ 6 files changed, 166 insertions(+), 35 deletions(-) create mode 100644 src/main/java/seng302/models/parsers/packets/BoatPositionPacket.java create mode 100644 src/main/java/seng302/models/parsers/packets/PacketType.java create mode 100644 src/main/java/seng302/models/parsers/packets/StreamPacket.java diff --git a/src/main/java/seng302/models/BoatGroup.java b/src/main/java/seng302/models/BoatGroup.java index a262e61d..8171bdeb 100644 --- a/src/main/java/seng302/models/BoatGroup.java +++ b/src/main/java/seng302/models/BoatGroup.java @@ -146,21 +146,23 @@ public class BoatGroup extends RaceObject{ } public void setDestination (double newXValue, double newYValue, double rotation, int... raceIds) { - destinationSet = true; - boat.setVelocity(StreamParser.boatSpeeds.get((long)boat.getId())); - if (hasRaceId(raceIds)) { - this.pixelVelocityX = (newXValue - boatPoly.getLayoutX()) / expectedUpdateInterval; - this.pixelVelocityY = (newYValue - boatPoly.getLayoutY()) / expectedUpdateInterval; - this.rotationalGoal = rotation; - calculateRotationalVelocity(); - rotateTo(rotation); - if (wakeGenerationDelay > 0) { - wake.rotate(rotationalGoal); - wakeGenerationDelay--; - } else { - wake.setRotationalVelocity(rotationalVelocity, rotationalGoal, pixelVelocityX, pixelVelocityY); - } - } + moveGroupBy(newXValue - boatPoly.getLayoutX(), newYValue - boatPoly.getLayoutY(), rotation); + +// destinationSet = true; +// boat.setVelocity(StreamParser.boatSpeeds.get((long)boat.getId())); +// if (hasRaceId(raceIds)) { +// this.pixelVelocityX = (newXValue - boatPoly.getLayoutX()) / expectedUpdateInterval; +// this.pixelVelocityY = (newYValue - boatPoly.getLayoutY()) / expectedUpdateInterval; +// this.rotationalGoal = rotation; +// calculateRotationalVelocity(); +// rotateTo(rotation); +// if (wakeGenerationDelay > 0) { +// wake.rotate(rotationalGoal); +// wakeGenerationDelay--; +// } else { +// wake.setRotationalVelocity(rotationalVelocity, rotationalGoal, pixelVelocityX, pixelVelocityY); +// } +// } } public void setDestination (double newXValue, double newYValue, int... raceIDs) { diff --git a/src/main/java/seng302/models/parsers/StreamParser.java b/src/main/java/seng302/models/parsers/StreamParser.java index 7cbfc90d..3c7890c8 100644 --- a/src/main/java/seng302/models/parsers/StreamParser.java +++ b/src/main/java/seng302/models/parsers/StreamParser.java @@ -5,6 +5,8 @@ import javafx.geometry.Point3D; import org.w3c.dom.Document; import org.xml.sax.InputSource; import org.xml.sax.SAXException; +import seng302.models.parsers.packets.BoatPositionPacket; +import seng302.models.parsers.packets.StreamPacket; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; @@ -12,12 +14,11 @@ import javax.xml.parsers.ParserConfigurationException; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.StringReader; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.*; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.PriorityBlockingQueue; /** * The purpose of this class is to take in the stream of divided packets so they can be read @@ -27,14 +28,17 @@ import java.util.concurrent.ConcurrentHashMap; */ public class StreamParser extends Thread{ - public static ConcurrentHashMap boatPositions = new ConcurrentHashMap<>(); - public static ConcurrentHashMap boatSpeeds = new ConcurrentHashMap<>(); + public static ConcurrentHashMap> boatPositions = new ConcurrentHashMap<>(); private String threadName; private Thread t; private static boolean raceStarted = false; + + + + public StreamParser(String threadName){ - this.threadName = threadName; + this.threadName = threadName; } /** @@ -313,28 +317,31 @@ public class StreamParser extends Thread{ byte[] headingBytes = Arrays.copyOfRange(payload,28,30); byte[] groundSpeedBytes = Arrays.copyOfRange(payload,38,40); - long timeStamp = extractTimeStamp(Arrays.copyOfRange(payload,1,7), 6); + long timeValid = extractTimeStamp(Arrays.copyOfRange(payload,1,7), 6); // int boatSeq = ByteBuffer.wrap(seqBytes).getInt(); long seq = bytesToLong(seqBytes); long boatId = bytesToLong(boatIdBytes); - long lat = bytesToLong(latBytes); - long lon = bytesToLong(lonBytes); + long rawLat = bytesToLong(latBytes); + long rawLon = bytesToLong(lonBytes); + double lat = ((180d * (double)rawLat)/Math.pow(2,31)); + double lon = ((180d *(double)rawLon)/Math.pow(2,31)); long heading = bytesToLong(headingBytes); // long speed = extractTimeStamp(speedBytes, 2); double groundSpeed = bytesToLong(groundSpeedBytes)/1000.0; short s = (short) ((groundSpeedBytes[1] & 0xFF) << 8 | (groundSpeedBytes[0] & 0xFF)); - if ((int)deviceType == 1 || (int)deviceType == 4){ -// System.out.println("boatId = " + boatId); -// System.out.println("deviceType = " + (long)deviceType); -// System.out.println("seq = " + seq); - //needs to be validated - Point3D point = new Point3D(((180d * (double)lat)/Math.pow(2,31)),((180d *(double)lon)/Math.pow(2,31)),(double)heading); - boatPositions.put(boatId, point); - boatSpeeds.put(boatId, groundSpeed); -// boatPositions.replace(boatId, point); -// boatSpeeds.replace(boatId, groundSpeed); -// System.out.println("lon = " + ((180d * (double)lon)/Math.pow(2,31))); -// System.out.println("lat = " + ((180d *(double)lat)/Math.pow(2,31))); + if ((int)deviceType == 1){ + + BoatPositionPacket boatPacket = new BoatPositionPacket(boatId, timeValid, lat, lon, heading, groundSpeed); + + if (!boatPositions.containsKey(boatId)){ + boatPositions.put(boatId, new PriorityBlockingQueue(256, new Comparator() { + @Override + public int compare(BoatPositionPacket p1, BoatPositionPacket p2) { + return (int) (p1.getTimeValid() - p2.getTimeValid()); + } + })); + } + boatPositions.get(boatId).put(boatPacket); } } diff --git a/src/main/java/seng302/models/parsers/StreamReceiver.java b/src/main/java/seng302/models/parsers/StreamReceiver.java index 74ce4748..7636b6ae 100644 --- a/src/main/java/seng302/models/parsers/StreamReceiver.java +++ b/src/main/java/seng302/models/parsers/StreamReceiver.java @@ -1,5 +1,7 @@ package seng302.models.parsers; +import seng302.models.parsers.packets.StreamPacket; + import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; diff --git a/src/main/java/seng302/models/parsers/packets/BoatPositionPacket.java b/src/main/java/seng302/models/parsers/packets/BoatPositionPacket.java new file mode 100644 index 00000000..b2f07c5c --- /dev/null +++ b/src/main/java/seng302/models/parsers/packets/BoatPositionPacket.java @@ -0,0 +1,23 @@ +package seng302.models.parsers.packets; + +public class BoatPositionPacket { + private long boatId; + private long timeValid; + private double lat; + private double lon; + private double heading; + private double groundSpeed; + + public BoatPositionPacket(long boatId, long timeValid, double lat, double lon, double heading, double groundSpeed) { + this.boatId = boatId; + this.timeValid = timeValid; + this.lat = lat; + this.lon = lon; + this.heading = heading; + this.groundSpeed = groundSpeed; + } + + public long getTimeValid() { + return timeValid; + } +} diff --git a/src/main/java/seng302/models/parsers/packets/PacketType.java b/src/main/java/seng302/models/parsers/packets/PacketType.java new file mode 100644 index 00000000..f522dec9 --- /dev/null +++ b/src/main/java/seng302/models/parsers/packets/PacketType.java @@ -0,0 +1,53 @@ +package seng302.models.parsers.packets; + +/** + * Created by Kusal on 4/24/2017. + */ +public enum PacketType { + HEARTBEAT, + RACE_STATUS, + DISPLAY_TEXT_MESSAGE, + XML_MESSAGE, + RACE_START_STATUS, + YACHT_EVENT_CODE, + YACHT_ACTION_CODE, + CHATTER_TEXT, + BOAT_LOCATION, + MARK_ROUNDING, + COURSE_WIND, + AVG_WIND, + OTHER; + + public static PacketType assignPacketType(int packetType){ + switch(packetType){ + case 1: + return HEARTBEAT; + case 12: + return RACE_STATUS; + case 20: + return DISPLAY_TEXT_MESSAGE; + case 26: + return XML_MESSAGE; + case 27: + return RACE_START_STATUS; + case 29: + return YACHT_EVENT_CODE; + case 31: + return YACHT_ACTION_CODE; + case 36: + return CHATTER_TEXT; + case 37: + return BOAT_LOCATION; + case 38: + return MARK_ROUNDING; + case 44: + return COURSE_WIND; + case 47: + return AVG_WIND; + default: + } + return OTHER; + } + + +} diff --git a/src/main/java/seng302/models/parsers/packets/StreamPacket.java b/src/main/java/seng302/models/parsers/packets/StreamPacket.java new file mode 100644 index 00000000..3b5c4faa --- /dev/null +++ b/src/main/java/seng302/models/parsers/packets/StreamPacket.java @@ -0,0 +1,44 @@ +package seng302.models.parsers.packets; + +/** + * Created by kre39 on 23/04/17. + */ +public class StreamPacket { + + //Change int to an ENUM for the type + private PacketType type; + + private long messageLength; + private long timeStamp; + private byte[] payload; + + StreamPacket(int type, long messageLength, long timeStamp, byte[] payload) { + this.type = PacketType.assignPacketType(type); + this.messageLength = messageLength; + this.timeStamp = timeStamp; + this.payload = payload; +// System.out.println("type = " + this.type.toString()); + //switch the packet type to deal with what ever specific packet you want to deal with +// if (this.type == PacketType.XML_MESSAGE){ +// //System.out.println("--------"); +// System.out.println(new String(payload)); +// StreamParser.parsePacket(this); +// } + } + + public PacketType getType() { + return type; + } + + public long getMessageLength() { + return messageLength; + } + + public byte[] getPayload() { + return payload; + } + + public long getTimeStamp() { + return timeStamp; + } +} From a898290c0b9d4b644b242e5484e5091b40d58b82 Mon Sep 17 00:00:00 2001 From: Peter Galloway Date: Sat, 29 Apr 2017 20:13:34 +1200 Subject: [PATCH 2/7] partway through fixing boat movement to be updated from the data valid timestamp rather than the data sent timestamp #pair[kre39, ptg19] #story[820] --- src/main/java/seng302/models/BoatGroup.java | 32 +++++------ .../seng302/models/parsers/StreamParser.java | 47 +++++++++------- .../models/parsers/StreamReceiver.java | 2 + .../parsers/packets/BoatPositionPacket.java | 23 ++++++++ .../models/parsers/packets/PacketType.java | 53 +++++++++++++++++++ .../models/parsers/packets/StreamPacket.java | 44 +++++++++++++++ 6 files changed, 166 insertions(+), 35 deletions(-) create mode 100644 src/main/java/seng302/models/parsers/packets/BoatPositionPacket.java create mode 100644 src/main/java/seng302/models/parsers/packets/PacketType.java create mode 100644 src/main/java/seng302/models/parsers/packets/StreamPacket.java diff --git a/src/main/java/seng302/models/BoatGroup.java b/src/main/java/seng302/models/BoatGroup.java index a262e61d..8171bdeb 100644 --- a/src/main/java/seng302/models/BoatGroup.java +++ b/src/main/java/seng302/models/BoatGroup.java @@ -146,21 +146,23 @@ public class BoatGroup extends RaceObject{ } public void setDestination (double newXValue, double newYValue, double rotation, int... raceIds) { - destinationSet = true; - boat.setVelocity(StreamParser.boatSpeeds.get((long)boat.getId())); - if (hasRaceId(raceIds)) { - this.pixelVelocityX = (newXValue - boatPoly.getLayoutX()) / expectedUpdateInterval; - this.pixelVelocityY = (newYValue - boatPoly.getLayoutY()) / expectedUpdateInterval; - this.rotationalGoal = rotation; - calculateRotationalVelocity(); - rotateTo(rotation); - if (wakeGenerationDelay > 0) { - wake.rotate(rotationalGoal); - wakeGenerationDelay--; - } else { - wake.setRotationalVelocity(rotationalVelocity, rotationalGoal, pixelVelocityX, pixelVelocityY); - } - } + moveGroupBy(newXValue - boatPoly.getLayoutX(), newYValue - boatPoly.getLayoutY(), rotation); + +// destinationSet = true; +// boat.setVelocity(StreamParser.boatSpeeds.get((long)boat.getId())); +// if (hasRaceId(raceIds)) { +// this.pixelVelocityX = (newXValue - boatPoly.getLayoutX()) / expectedUpdateInterval; +// this.pixelVelocityY = (newYValue - boatPoly.getLayoutY()) / expectedUpdateInterval; +// this.rotationalGoal = rotation; +// calculateRotationalVelocity(); +// rotateTo(rotation); +// if (wakeGenerationDelay > 0) { +// wake.rotate(rotationalGoal); +// wakeGenerationDelay--; +// } else { +// wake.setRotationalVelocity(rotationalVelocity, rotationalGoal, pixelVelocityX, pixelVelocityY); +// } +// } } public void setDestination (double newXValue, double newYValue, int... raceIDs) { diff --git a/src/main/java/seng302/models/parsers/StreamParser.java b/src/main/java/seng302/models/parsers/StreamParser.java index 7cbfc90d..3c7890c8 100644 --- a/src/main/java/seng302/models/parsers/StreamParser.java +++ b/src/main/java/seng302/models/parsers/StreamParser.java @@ -5,6 +5,8 @@ import javafx.geometry.Point3D; import org.w3c.dom.Document; import org.xml.sax.InputSource; import org.xml.sax.SAXException; +import seng302.models.parsers.packets.BoatPositionPacket; +import seng302.models.parsers.packets.StreamPacket; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; @@ -12,12 +14,11 @@ import javax.xml.parsers.ParserConfigurationException; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.StringReader; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.*; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.PriorityBlockingQueue; /** * The purpose of this class is to take in the stream of divided packets so they can be read @@ -27,14 +28,17 @@ import java.util.concurrent.ConcurrentHashMap; */ public class StreamParser extends Thread{ - public static ConcurrentHashMap boatPositions = new ConcurrentHashMap<>(); - public static ConcurrentHashMap boatSpeeds = new ConcurrentHashMap<>(); + public static ConcurrentHashMap> boatPositions = new ConcurrentHashMap<>(); private String threadName; private Thread t; private static boolean raceStarted = false; + + + + public StreamParser(String threadName){ - this.threadName = threadName; + this.threadName = threadName; } /** @@ -313,28 +317,31 @@ public class StreamParser extends Thread{ byte[] headingBytes = Arrays.copyOfRange(payload,28,30); byte[] groundSpeedBytes = Arrays.copyOfRange(payload,38,40); - long timeStamp = extractTimeStamp(Arrays.copyOfRange(payload,1,7), 6); + long timeValid = extractTimeStamp(Arrays.copyOfRange(payload,1,7), 6); // int boatSeq = ByteBuffer.wrap(seqBytes).getInt(); long seq = bytesToLong(seqBytes); long boatId = bytesToLong(boatIdBytes); - long lat = bytesToLong(latBytes); - long lon = bytesToLong(lonBytes); + long rawLat = bytesToLong(latBytes); + long rawLon = bytesToLong(lonBytes); + double lat = ((180d * (double)rawLat)/Math.pow(2,31)); + double lon = ((180d *(double)rawLon)/Math.pow(2,31)); long heading = bytesToLong(headingBytes); // long speed = extractTimeStamp(speedBytes, 2); double groundSpeed = bytesToLong(groundSpeedBytes)/1000.0; short s = (short) ((groundSpeedBytes[1] & 0xFF) << 8 | (groundSpeedBytes[0] & 0xFF)); - if ((int)deviceType == 1 || (int)deviceType == 4){ -// System.out.println("boatId = " + boatId); -// System.out.println("deviceType = " + (long)deviceType); -// System.out.println("seq = " + seq); - //needs to be validated - Point3D point = new Point3D(((180d * (double)lat)/Math.pow(2,31)),((180d *(double)lon)/Math.pow(2,31)),(double)heading); - boatPositions.put(boatId, point); - boatSpeeds.put(boatId, groundSpeed); -// boatPositions.replace(boatId, point); -// boatSpeeds.replace(boatId, groundSpeed); -// System.out.println("lon = " + ((180d * (double)lon)/Math.pow(2,31))); -// System.out.println("lat = " + ((180d *(double)lat)/Math.pow(2,31))); + if ((int)deviceType == 1){ + + BoatPositionPacket boatPacket = new BoatPositionPacket(boatId, timeValid, lat, lon, heading, groundSpeed); + + if (!boatPositions.containsKey(boatId)){ + boatPositions.put(boatId, new PriorityBlockingQueue(256, new Comparator() { + @Override + public int compare(BoatPositionPacket p1, BoatPositionPacket p2) { + return (int) (p1.getTimeValid() - p2.getTimeValid()); + } + })); + } + boatPositions.get(boatId).put(boatPacket); } } diff --git a/src/main/java/seng302/models/parsers/StreamReceiver.java b/src/main/java/seng302/models/parsers/StreamReceiver.java index 74ce4748..7636b6ae 100644 --- a/src/main/java/seng302/models/parsers/StreamReceiver.java +++ b/src/main/java/seng302/models/parsers/StreamReceiver.java @@ -1,5 +1,7 @@ package seng302.models.parsers; +import seng302.models.parsers.packets.StreamPacket; + import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; diff --git a/src/main/java/seng302/models/parsers/packets/BoatPositionPacket.java b/src/main/java/seng302/models/parsers/packets/BoatPositionPacket.java new file mode 100644 index 00000000..b2f07c5c --- /dev/null +++ b/src/main/java/seng302/models/parsers/packets/BoatPositionPacket.java @@ -0,0 +1,23 @@ +package seng302.models.parsers.packets; + +public class BoatPositionPacket { + private long boatId; + private long timeValid; + private double lat; + private double lon; + private double heading; + private double groundSpeed; + + public BoatPositionPacket(long boatId, long timeValid, double lat, double lon, double heading, double groundSpeed) { + this.boatId = boatId; + this.timeValid = timeValid; + this.lat = lat; + this.lon = lon; + this.heading = heading; + this.groundSpeed = groundSpeed; + } + + public long getTimeValid() { + return timeValid; + } +} diff --git a/src/main/java/seng302/models/parsers/packets/PacketType.java b/src/main/java/seng302/models/parsers/packets/PacketType.java new file mode 100644 index 00000000..f522dec9 --- /dev/null +++ b/src/main/java/seng302/models/parsers/packets/PacketType.java @@ -0,0 +1,53 @@ +package seng302.models.parsers.packets; + +/** + * Created by Kusal on 4/24/2017. + */ +public enum PacketType { + HEARTBEAT, + RACE_STATUS, + DISPLAY_TEXT_MESSAGE, + XML_MESSAGE, + RACE_START_STATUS, + YACHT_EVENT_CODE, + YACHT_ACTION_CODE, + CHATTER_TEXT, + BOAT_LOCATION, + MARK_ROUNDING, + COURSE_WIND, + AVG_WIND, + OTHER; + + public static PacketType assignPacketType(int packetType){ + switch(packetType){ + case 1: + return HEARTBEAT; + case 12: + return RACE_STATUS; + case 20: + return DISPLAY_TEXT_MESSAGE; + case 26: + return XML_MESSAGE; + case 27: + return RACE_START_STATUS; + case 29: + return YACHT_EVENT_CODE; + case 31: + return YACHT_ACTION_CODE; + case 36: + return CHATTER_TEXT; + case 37: + return BOAT_LOCATION; + case 38: + return MARK_ROUNDING; + case 44: + return COURSE_WIND; + case 47: + return AVG_WIND; + default: + } + return OTHER; + } + + +} diff --git a/src/main/java/seng302/models/parsers/packets/StreamPacket.java b/src/main/java/seng302/models/parsers/packets/StreamPacket.java new file mode 100644 index 00000000..3b5c4faa --- /dev/null +++ b/src/main/java/seng302/models/parsers/packets/StreamPacket.java @@ -0,0 +1,44 @@ +package seng302.models.parsers.packets; + +/** + * Created by kre39 on 23/04/17. + */ +public class StreamPacket { + + //Change int to an ENUM for the type + private PacketType type; + + private long messageLength; + private long timeStamp; + private byte[] payload; + + StreamPacket(int type, long messageLength, long timeStamp, byte[] payload) { + this.type = PacketType.assignPacketType(type); + this.messageLength = messageLength; + this.timeStamp = timeStamp; + this.payload = payload; +// System.out.println("type = " + this.type.toString()); + //switch the packet type to deal with what ever specific packet you want to deal with +// if (this.type == PacketType.XML_MESSAGE){ +// //System.out.println("--------"); +// System.out.println(new String(payload)); +// StreamParser.parsePacket(this); +// } + } + + public PacketType getType() { + return type; + } + + public long getMessageLength() { + return messageLength; + } + + public byte[] getPayload() { + return payload; + } + + public long getTimeStamp() { + return timeStamp; + } +} From a5ca9218da538afb77974730b0efa5911d5ee494 Mon Sep 17 00:00:00 2001 From: Peter Galloway Date: Mon, 1 May 2017 16:56:53 +1200 Subject: [PATCH 3/7] Discovered the time valid timestamp in the boat location packet is quite inconsistent and either the stream or my implementation is making the display really buggy. Because the way it was before I changed things is more reliable at the moment, I have decided to wait until our mock stream is merged before continuing this development. #story[820] --- .../seng302/controllers/CanvasController.java | 56 ++++++++++++++----- .../seng302/models/parsers/StreamParser.java | 9 ++- .../models/parsers/StreamReceiver.java | 5 +- .../parsers/packets/BoatPositionPacket.java | 12 ++++ .../models/parsers/packets/StreamPacket.java | 9 +-- 5 files changed, 63 insertions(+), 28 deletions(-) diff --git a/src/main/java/seng302/controllers/CanvasController.java b/src/main/java/seng302/controllers/CanvasController.java index fda4eed2..5799d4b5 100644 --- a/src/main/java/seng302/controllers/CanvasController.java +++ b/src/main/java/seng302/controllers/CanvasController.java @@ -18,10 +18,13 @@ import seng302.models.BoatGroup; import seng302.models.Colors; import seng302.models.RaceObject; import seng302.models.mark.*; +import seng302.models.parsers.StreamPacket; import seng302.models.parsers.StreamParser; +import seng302.models.parsers.packets.BoatPositionPacket; import java.text.DecimalFormat; import java.util.*; +import java.util.concurrent.PriorityBlockingQueue; /** * Created by ptg19 on 15/03/17. @@ -105,12 +108,7 @@ public class CanvasController { @Override public void handle(long now) { - boolean raceFinished = true; - boolean descending; - boolean leftToRight; - int boatIndex = 0; - Mark nextMark; long oldFrameTime = frameTimes[frameTimeIndex] ; frameTimes[frameTimeIndex] = now ; @@ -126,20 +124,52 @@ public class CanvasController { } for (RaceObject raceObject : raceObjects) { raceObject.updatePosition(1000 / 60); - for (int id : raceObject.getRaceIds()) { - if (StreamParser.boatPositions.containsKey((long) id)) { - Point3D p = StreamParser.boatPositions.get((long) id); - Point2D p2d = latLonToXY(p.getX(), p.getY()); - double heading = 360.0 / 0xffff * p.getZ(); - raceObject.setDestination(p2d.getX(), p2d.getY(), heading, id); + for (long id : raceObject.getRaceIds()) { + if (StreamParser.boatPositions.containsKey(id)) { + + PriorityBlockingQueue movementQueue = StreamParser.boatPositions.get(id); + if (movementQueue.size() > 0){ + BoatPositionPacket positionPacket = movementQueue.peek(); + + int delayTime = 5000; + int loopTime = delayTime + 1000; + //System.out.println("id = " + id); + long timeDiff = (System.currentTimeMillis()%loopTime - positionPacket.getTimeValid()%loopTime); + if (timeDiff < 0){ + timeDiff = loopTime + timeDiff; + } + if (id == 106) { + //System.out.println("timeDiff = " + timeDiff); + //System.out.println("movementQueue.size() = " + movementQueue.size()); + } + //System.out.println("timeDiff = " + timeDiff); + //System.out.println("movementQueue.size() = " + movementQueue.size()); + if (timeDiff > delayTime) { + if (id == 106){ + //System.out.println("processing"); + } + try { + positionPacket = movementQueue.take(); + + Point2D p2d = latLonToXY(positionPacket.getLat(), positionPacket.getLon()); + double heading = 360.0 / 0xffff * positionPacket.getHeading(); + raceObject.setDestination(p2d.getX(), p2d.getY(), heading, (int) id); + + } catch (InterruptedException e){ + e.printStackTrace(); + } + } + + + } } - StreamParser.boatPositions.remove((long) id); + //StreamParser.boatPositions.remove((long) id); } } } }; for (Mark m : raceViewController.getRace().getCourse()) { - System.out.println(m.getName()); +// System.out.println(m.getName()); } //timer.start(); } diff --git a/src/main/java/seng302/models/parsers/StreamParser.java b/src/main/java/seng302/models/parsers/StreamParser.java index 3c7890c8..73961179 100644 --- a/src/main/java/seng302/models/parsers/StreamParser.java +++ b/src/main/java/seng302/models/parsers/StreamParser.java @@ -58,13 +58,13 @@ public class StreamParser extends Thread{ long sleepTime = 0; long transitTime = (System.currentTimeMillis()%loopTime - packet.getTimeStamp()%loopTime); if (transitTime < 0){ - transitTime = loopTime + delayTime; + transitTime = loopTime + transitTime; } if (transitTime < delayTime) { sleepTime = delayTime - (transitTime); Thread.sleep(sleepTime); } - System.out.println(sleepTime); +// System.out.println(sleepTime); packet = StreamReceiver.packetBuffer.take(); parsePacket(packet); @@ -169,7 +169,7 @@ public class StreamParser extends Thread{ System.out.println("RACE HAS STARTED"); } if (timeTillStart % 10 == 0){ - System.out.println("Time since start: " + -1 * timeTillStart + " Seconds"); + //System.out.println("Time since start: " + -1 * timeTillStart + " Seconds"); } } long windDir = bytesToLong(Arrays.copyOfRange(payload,18,20)); @@ -332,6 +332,9 @@ public class StreamParser extends Thread{ if ((int)deviceType == 1){ BoatPositionPacket boatPacket = new BoatPositionPacket(boatId, timeValid, lat, lon, heading, groundSpeed); + if (boatId == 106){ + System.out.println("timeValid = " + timeValid); + } if (!boatPositions.containsKey(boatId)){ boatPositions.put(boatId, new PriorityBlockingQueue(256, new Comparator() { diff --git a/src/main/java/seng302/models/parsers/StreamReceiver.java b/src/main/java/seng302/models/parsers/StreamReceiver.java index 7636b6ae..0d50315a 100644 --- a/src/main/java/seng302/models/parsers/StreamReceiver.java +++ b/src/main/java/seng302/models/parsers/StreamReceiver.java @@ -78,9 +78,6 @@ public class StreamReceiver extends Thread { long computedCrc = checksum.getValue(); long packetCrc = bytesToLong(getBytes(4)); if (computedCrc == packetCrc) { -// System.out.println("message type: " + type); -// System.out.println("timeStamp = " + timeStamp); -// System.out.println("payload length: " + payloadLength); packetBuffer.add(new StreamPacket(type, payloadLength, timeStamp, payload)); } else { System.err.println("Packet has been dropped"); @@ -126,7 +123,7 @@ public class StreamReceiver extends Thread { * takes an array of up to 7 bytes and returns a positive * long constructed from the input bytes * - * @return a positive long if there is less than 7 bytes -1 otherwise + * @return a positive long if there is less than 8 bytes -1 otherwise */ private long bytesToLong(byte[] bytes){ long partialLong = 0; diff --git a/src/main/java/seng302/models/parsers/packets/BoatPositionPacket.java b/src/main/java/seng302/models/parsers/packets/BoatPositionPacket.java index b2f07c5c..b0b958df 100644 --- a/src/main/java/seng302/models/parsers/packets/BoatPositionPacket.java +++ b/src/main/java/seng302/models/parsers/packets/BoatPositionPacket.java @@ -20,4 +20,16 @@ public class BoatPositionPacket { public long getTimeValid() { return timeValid; } + + public double getLat() { + return lat; + } + + public double getLon() { + return lon; + } + + public double getHeading() { + return heading; + } } diff --git a/src/main/java/seng302/models/parsers/packets/StreamPacket.java b/src/main/java/seng302/models/parsers/packets/StreamPacket.java index 3b5c4faa..4f10008c 100644 --- a/src/main/java/seng302/models/parsers/packets/StreamPacket.java +++ b/src/main/java/seng302/models/parsers/packets/StreamPacket.java @@ -12,18 +12,11 @@ public class StreamPacket { private long timeStamp; private byte[] payload; - StreamPacket(int type, long messageLength, long timeStamp, byte[] payload) { + public StreamPacket(int type, long messageLength, long timeStamp, byte[] payload) { this.type = PacketType.assignPacketType(type); this.messageLength = messageLength; this.timeStamp = timeStamp; this.payload = payload; -// System.out.println("type = " + this.type.toString()); - //switch the packet type to deal with what ever specific packet you want to deal with -// if (this.type == PacketType.XML_MESSAGE){ -// //System.out.println("--------"); -// System.out.println(new String(payload)); -// StreamParser.parsePacket(this); -// } } public PacketType getType() { From 7df55fc1a3eff67830668469ae3e55032bbff572 Mon Sep 17 00:00:00 2001 From: Peter Galloway Date: Mon, 1 May 2017 18:55:21 +1200 Subject: [PATCH 4/7] problems appear to be fixed and the boats are updating properly from the timeValid field of the boat location. #story[820] --- .../seng302/controllers/CanvasController.java | 85 +++++++++---------- .../seng302/models/parsers/StreamParser.java | 18 ++-- 2 files changed, 48 insertions(+), 55 deletions(-) diff --git a/src/main/java/seng302/controllers/CanvasController.java b/src/main/java/seng302/controllers/CanvasController.java index 5799d4b5..ad4e8c36 100644 --- a/src/main/java/seng302/controllers/CanvasController.java +++ b/src/main/java/seng302/controllers/CanvasController.java @@ -109,7 +109,7 @@ public class CanvasController { @Override public void handle(long now) { - + //fps stuff long oldFrameTime = frameTimes[frameTimeIndex] ; frameTimes[frameTimeIndex] = now ; frameTimeIndex = (frameTimeIndex + 1) % frameTimes.length ; @@ -122,50 +122,9 @@ public class CanvasController { Double frameRate = 1_000_000_000.0 / elapsedNanosPerFrame ; drawFps(frameRate.intValue()); } - for (RaceObject raceObject : raceObjects) { - raceObject.updatePosition(1000 / 60); - for (long id : raceObject.getRaceIds()) { - if (StreamParser.boatPositions.containsKey(id)) { - PriorityBlockingQueue movementQueue = StreamParser.boatPositions.get(id); - if (movementQueue.size() > 0){ - BoatPositionPacket positionPacket = movementQueue.peek(); + updateRaceObjects(); - int delayTime = 5000; - int loopTime = delayTime + 1000; - //System.out.println("id = " + id); - long timeDiff = (System.currentTimeMillis()%loopTime - positionPacket.getTimeValid()%loopTime); - if (timeDiff < 0){ - timeDiff = loopTime + timeDiff; - } - if (id == 106) { - //System.out.println("timeDiff = " + timeDiff); - //System.out.println("movementQueue.size() = " + movementQueue.size()); - } - //System.out.println("timeDiff = " + timeDiff); - //System.out.println("movementQueue.size() = " + movementQueue.size()); - if (timeDiff > delayTime) { - if (id == 106){ - //System.out.println("processing"); - } - try { - positionPacket = movementQueue.take(); - - Point2D p2d = latLonToXY(positionPacket.getLat(), positionPacket.getLon()); - double heading = 360.0 / 0xffff * positionPacket.getHeading(); - raceObject.setDestination(p2d.getX(), p2d.getY(), heading, (int) id); - - } catch (InterruptedException e){ - e.printStackTrace(); - } - } - - - } - } - //StreamParser.boatPositions.remove((long) id); - } - } } }; for (Mark m : raceViewController.getRace().getCourse()) { @@ -174,6 +133,46 @@ public class CanvasController { //timer.start(); } + private void updateRaceObjects(){ + for (RaceObject raceObject : raceObjects) { + raceObject.updatePosition(1000 / 60); + // some raceObjects will have multiply ID's (for instance gate marks) + for (long id : raceObject.getRaceIds()) { + //checking if the current "ID" has any updates associated with it + if (StreamParser.boatPositions.containsKey(id)) { + move(id, raceObject); + } + } + } + } + + private void move(long id, RaceObject raceObject){ + PriorityBlockingQueue movementQueue = StreamParser.boatPositions.get(id); + if (movementQueue.size() > 0){ + BoatPositionPacket positionPacket = movementQueue.peek(); + + //this code adds a delay to reading from the movementQueue + //in case things being put into the movement queue are slightly + //out of order + int delayTime = 1000; + int loopTime = delayTime * 10; + long timeDiff = (System.currentTimeMillis()%loopTime - positionPacket.getTimeValid()%loopTime); + if (timeDiff < 0){ + timeDiff = loopTime + timeDiff; + } + if (timeDiff > delayTime) { + try { + positionPacket = movementQueue.take(); + Point2D p2d = latLonToXY(positionPacket.getLat(), positionPacket.getLon()); + double heading = 360.0 / 0xffff * positionPacket.getHeading(); + raceObject.setDestination(p2d.getX(), p2d.getY(), heading, (int) id); + } catch (InterruptedException e){ + e.printStackTrace(); + } + } + } + } + class ResizableCanvas extends Canvas { public ResizableCanvas() { diff --git a/src/main/java/seng302/models/parsers/StreamParser.java b/src/main/java/seng302/models/parsers/StreamParser.java index 73961179..4a2ed055 100644 --- a/src/main/java/seng302/models/parsers/StreamParser.java +++ b/src/main/java/seng302/models/parsers/StreamParser.java @@ -51,21 +51,20 @@ public class StreamParser extends Thread{ while (StreamReceiver.packetBuffer == null || StreamReceiver.packetBuffer.size() < 1) { Thread.sleep(1); } - while (StreamReceiver.packetBuffer.peek() != null){ + while (true){ StreamPacket packet = StreamReceiver.packetBuffer.peek(); + //this code adds a delay to reading from the packetBuffer so + //out of order packets have time to order themselves in the queue int delayTime = 1000; - int loopTime = delayTime + 1000; - long sleepTime = 0; + int loopTime = delayTime * 10; long transitTime = (System.currentTimeMillis()%loopTime - packet.getTimeStamp()%loopTime); if (transitTime < 0){ transitTime = loopTime + transitTime; } if (transitTime < delayTime) { - sleepTime = delayTime - (transitTime); + long sleepTime = delayTime - (transitTime); Thread.sleep(sleepTime); } -// System.out.println(sleepTime); - packet = StreamReceiver.packetBuffer.take(); parsePacket(packet); Thread.sleep(1); @@ -73,7 +72,6 @@ public class StreamParser extends Thread{ Thread.sleep(1); } } - System.out.println("END OF STREAM"); } catch (Exception e){ e.printStackTrace(); } @@ -317,7 +315,7 @@ public class StreamParser extends Thread{ byte[] headingBytes = Arrays.copyOfRange(payload,28,30); byte[] groundSpeedBytes = Arrays.copyOfRange(payload,38,40); - long timeValid = extractTimeStamp(Arrays.copyOfRange(payload,1,7), 6); + long timeValid = bytesToLong(Arrays.copyOfRange(payload,1,7)); // int boatSeq = ByteBuffer.wrap(seqBytes).getInt(); long seq = bytesToLong(seqBytes); long boatId = bytesToLong(boatIdBytes); @@ -326,15 +324,11 @@ public class StreamParser extends Thread{ double lat = ((180d * (double)rawLat)/Math.pow(2,31)); double lon = ((180d *(double)rawLon)/Math.pow(2,31)); long heading = bytesToLong(headingBytes); -// long speed = extractTimeStamp(speedBytes, 2); double groundSpeed = bytesToLong(groundSpeedBytes)/1000.0; short s = (short) ((groundSpeedBytes[1] & 0xFF) << 8 | (groundSpeedBytes[0] & 0xFF)); if ((int)deviceType == 1){ BoatPositionPacket boatPacket = new BoatPositionPacket(boatId, timeValid, lat, lon, heading, groundSpeed); - if (boatId == 106){ - System.out.println("timeValid = " + timeValid); - } if (!boatPositions.containsKey(boatId)){ boatPositions.put(boatId, new PriorityBlockingQueue(256, new Comparator() { From 33ae7beeb42c69525193360c17db7a1da6c11783 Mon Sep 17 00:00:00 2001 From: Peter Galloway Date: Mon, 1 May 2017 20:09:51 +1200 Subject: [PATCH 5/7] merging with wake remake #story[820] --- src/main/java/seng302/App.java | 4 +-- .../seng302/controllers/CanvasController.java | 2 +- src/main/java/seng302/models/BoatGroup.java | 30 ++++++++++--------- src/main/java/seng302/models/RaceObject.java | 3 +- .../java/seng302/models/mark/MarkGroup.java | 2 +- .../seng302/models/parsers/StreamParser.java | 3 +- .../parsers/packets/BoatPositionPacket.java | 4 +++ 7 files changed, 28 insertions(+), 20 deletions(-) diff --git a/src/main/java/seng302/App.java b/src/main/java/seng302/App.java index dc6de280..68107866 100644 --- a/src/main/java/seng302/App.java +++ b/src/main/java/seng302/App.java @@ -26,8 +26,8 @@ public class App extends Application sr = new StreamReceiver("localhost", 8085, "TestThread1"); } else{ -// sr = new StreamReceiver("csse-s302staff.canterbury.ac.nz", 4941,"TestThread1"); - sr = new StreamReceiver("livedata.americascup.com", 4941, "TestThread1"); + sr = new StreamReceiver("csse-s302staff.canterbury.ac.nz", 4941,"TestThread1"); + //sr = new StreamReceiver("livedata.americascup.com", 4941, "TestThread1"); } sr.start(); diff --git a/src/main/java/seng302/controllers/CanvasController.java b/src/main/java/seng302/controllers/CanvasController.java index 6ee934b1..94721e39 100644 --- a/src/main/java/seng302/controllers/CanvasController.java +++ b/src/main/java/seng302/controllers/CanvasController.java @@ -166,7 +166,7 @@ public class CanvasController { positionPacket = movementQueue.take(); Point2D p2d = latLonToXY(positionPacket.getLat(), positionPacket.getLon()); double heading = 360.0 / 0xffff * positionPacket.getHeading(); - raceObject.setDestination(p2d.getX(), p2d.getY(), heading, (int) id); + raceObject.setDestination(p2d.getX(), p2d.getY(), heading, positionPacket.getGroundSpeed(), (int) id); } catch (InterruptedException e){ e.printStackTrace(); } diff --git a/src/main/java/seng302/models/BoatGroup.java b/src/main/java/seng302/models/BoatGroup.java index 618a3b59..d53edfe2 100644 --- a/src/main/java/seng302/models/BoatGroup.java +++ b/src/main/java/seng302/models/BoatGroup.java @@ -179,10 +179,10 @@ public class BoatGroup extends RaceObject{ * @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) { + public void setDestination (double newXValue, double newYValue, double rotation, double groundSpeed, int... raceIds) { if (hasRaceId(raceIds)) { destinationSet = true; - boat.setVelocity(StreamParser.boatSpeeds.get((long)boat.getId())); + boat.setVelocity(groundSpeed); if (currentRotation < 0) currentRotation = 360 - currentRotation; double dx = newXValue - boatPoly.getLayoutX(); @@ -227,19 +227,21 @@ public class BoatGroup extends RaceObject{ } public void setDestination (double newXValue, double newYValue, int... raceIDs) { - destinationSet = true; - - if (hasRaceId(raceIDs)) { - double rotation = Math.abs( - Math.toDegrees( - Math.atan( - (newYValue - boatPoly.getLayoutY()) / (newXValue - boatPoly.getLayoutX()) - ) - ) - ); - setDestination(newXValue, newYValue, rotation, raceIDs); - } } +// public void setDestination (double newXValue, double newYValue, int... raceIDs) { +// destinationSet = true; +// +// if (hasRaceId(raceIDs)) { +// double rotation = Math.abs( +// Math.toDegrees( +// Math.atan( +// (newYValue - boatPoly.getLayoutY()) / (newXValue - boatPoly.getLayoutX()) +// ) +// ) +// ); +// setDestination(newXValue, newYValue, rotation, raceIDs); +// } +// } public void rotateTo (double rotation) { currentRotation = rotation; diff --git a/src/main/java/seng302/models/RaceObject.java b/src/main/java/seng302/models/RaceObject.java index af29cb5c..21eaece9 100644 --- a/src/main/java/seng302/models/RaceObject.java +++ b/src/main/java/seng302/models/RaceObject.java @@ -59,9 +59,10 @@ public abstract class RaceObject extends Group { * @param x X co-ordinate to move the graphics to. * @param y Y co-ordinate to move the graphics to. * @param rotation Rotation to move graphics to. + * @param groundSpeed boat groundspeed. * @param raceIds RaceID of the object to move. */ - public abstract void setDestination (double x, double y, double rotation, int... raceIds); + public abstract void setDestination (double x, double y, double rotation, double groundSpeed, int... raceIds); /** * Sets the destination of everything within the RaceObject that has an ID in the array raceIds. The destination is * set to the co-ordinates (x, y). diff --git a/src/main/java/seng302/models/mark/MarkGroup.java b/src/main/java/seng302/models/mark/MarkGroup.java index b0ef4768..916bcd41 100644 --- a/src/main/java/seng302/models/mark/MarkGroup.java +++ b/src/main/java/seng302/models/mark/MarkGroup.java @@ -102,7 +102,7 @@ public class MarkGroup extends RaceObject { //moveTo(points[0].getX(), points[0].getY()); } - public void setDestination (double x, double y, double rotation, int... raceIds) { + public void setDestination (double x, double y, double rotation, double groundSpeed, int... raceIds) { setDestination(x, y, raceIds); this.rotationalGoal = rotation; calculateRotationalVelocity(); diff --git a/src/main/java/seng302/models/parsers/StreamParser.java b/src/main/java/seng302/models/parsers/StreamParser.java index 34b76b80..47f3b123 100644 --- a/src/main/java/seng302/models/parsers/StreamParser.java +++ b/src/main/java/seng302/models/parsers/StreamParser.java @@ -5,6 +5,7 @@ import javafx.geometry.Point3D; import org.w3c.dom.Document; import org.xml.sax.InputSource; import org.xml.sax.SAXException; +import seng302.models.Boat; import seng302.models.parsers.packets.BoatPositionPacket; import seng302.models.parsers.packets.StreamPacket; @@ -337,7 +338,7 @@ public class StreamParser extends Thread{ long heading = bytesToLong(headingBytes); double groundSpeed = bytesToLong(groundSpeedBytes)/1000.0; short s = (short) ((groundSpeedBytes[1] & 0xFF) << 8 | (groundSpeedBytes[0] & 0xFF)); - if ((int)deviceType == 1){ + if ((int)deviceType == 1 || (int)deviceType == 3){ BoatPositionPacket boatPacket = new BoatPositionPacket(boatId, timeValid, lat, lon, heading, groundSpeed); diff --git a/src/main/java/seng302/models/parsers/packets/BoatPositionPacket.java b/src/main/java/seng302/models/parsers/packets/BoatPositionPacket.java index b0b958df..d6f0700d 100644 --- a/src/main/java/seng302/models/parsers/packets/BoatPositionPacket.java +++ b/src/main/java/seng302/models/parsers/packets/BoatPositionPacket.java @@ -32,4 +32,8 @@ public class BoatPositionPacket { public double getHeading() { return heading; } + + public double getGroundSpeed() { + return groundSpeed; + } } From 56fab768f3198b560db90f6d961d197be74799c3 Mon Sep 17 00:00:00 2001 From: Peter Galloway Date: Mon, 1 May 2017 20:37:26 +1200 Subject: [PATCH 6/7] fixing error from merge #story[820] --- src/main/java/seng302/models/parsers/StreamParser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/seng302/models/parsers/StreamParser.java b/src/main/java/seng302/models/parsers/StreamParser.java index 837636e7..dc42963f 100644 --- a/src/main/java/seng302/models/parsers/StreamParser.java +++ b/src/main/java/seng302/models/parsers/StreamParser.java @@ -276,7 +276,7 @@ public class StreamParser extends Thread{ private static void extractYachtActionCode(StreamPacket packet){ byte[] payload = packet.getPayload(); int messageVersionNo = payload[0]; - long timeStamp = extractTimeStamp(Arrays.copyOfRange(payload,1,7), 6); + long timeStamp = bytesToLong(Arrays.copyOfRange(payload,1,7)); long subjectId = bytesToLong(Arrays.copyOfRange(payload,9,13)); long incidentId = bytesToLong(Arrays.copyOfRange(payload,13,17)); int eventId = payload[17]; From f8d003002b4e7fabc6e9a244d06bf9f533283c56 Mon Sep 17 00:00:00 2001 From: Peter Galloway Date: Mon, 1 May 2017 20:37:26 +1200 Subject: [PATCH 7/7] fixing error from merge #story[820] --- src/main/java/seng302/models/parsers/StreamParser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/seng302/models/parsers/StreamParser.java b/src/main/java/seng302/models/parsers/StreamParser.java index 837636e7..dc42963f 100644 --- a/src/main/java/seng302/models/parsers/StreamParser.java +++ b/src/main/java/seng302/models/parsers/StreamParser.java @@ -276,7 +276,7 @@ public class StreamParser extends Thread{ private static void extractYachtActionCode(StreamPacket packet){ byte[] payload = packet.getPayload(); int messageVersionNo = payload[0]; - long timeStamp = extractTimeStamp(Arrays.copyOfRange(payload,1,7), 6); + long timeStamp = bytesToLong(Arrays.copyOfRange(payload,1,7)); long subjectId = bytesToLong(Arrays.copyOfRange(payload,9,13)); long incidentId = bytesToLong(Arrays.copyOfRange(payload,13,17)); int eventId = payload[17];