mirror of
https://github.com/michaelrausch/Party-Parrots-At-Sea.git
synced 2026-05-09 06:18:44 +00:00
Merge branch 'develop' into 38b_LayLines
# Conflicts: # src/main/java/seng302/App.java # src/main/java/seng302/models/Yacht.java # src/main/java/seng302/models/stream/StreamParser.java
This commit is contained in:
@@ -5,7 +5,6 @@ import javafx.fxml.FXMLLoader;
|
|||||||
import javafx.scene.Parent;
|
import javafx.scene.Parent;
|
||||||
import javafx.scene.Scene;
|
import javafx.scene.Scene;
|
||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
import seng302.models.PolarTable;
|
|
||||||
import seng302.models.stream.StreamParser;
|
import seng302.models.stream.StreamParser;
|
||||||
import seng302.models.stream.StreamReceiver;
|
import seng302.models.stream.StreamReceiver;
|
||||||
import seng302.server.ServerThread;
|
import seng302.server.ServerThread;
|
||||||
@@ -14,8 +13,6 @@ public class App extends Application {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void start(Stage primaryStage) throws Exception {
|
public void start(Stage primaryStage) throws Exception {
|
||||||
PolarTable.parsePolarFile(getClass().getResource("/config/acc_polars.csv").getFile());
|
|
||||||
|
|
||||||
Parent root = FXMLLoader.load(getClass().getResource("/views/MainView.fxml"));
|
Parent root = FXMLLoader.load(getClass().getResource("/views/MainView.fxml"));
|
||||||
primaryStage.setTitle("RaceVision");
|
primaryStage.setTitle("RaceVision");
|
||||||
primaryStage.setScene(new Scene(root, 1530, 960));
|
primaryStage.setScene(new Scene(root, 1530, 960));
|
||||||
@@ -57,7 +54,7 @@ public class App extends Application {
|
|||||||
sr = new StreamReceiver("localhost", 4949, "RaceStream");
|
sr = new StreamReceiver("localhost", 4949, "RaceStream");
|
||||||
break;
|
break;
|
||||||
case "staffserver":
|
case "staffserver":
|
||||||
sr = new StreamReceiver("csse-s302staff.canterbury.ac.nz", 4942, "RaceStream");
|
sr = new StreamReceiver("csse-s302staff.canterbury.ac.nz", 4941, "RaceStream");
|
||||||
break;
|
break;
|
||||||
case "official":
|
case "official":
|
||||||
sr = new StreamReceiver("livedata.americascup.com", 4941, "RaceStream");
|
sr = new StreamReceiver("livedata.americascup.com", 4941, "RaceStream");
|
||||||
@@ -65,11 +62,11 @@ 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("localhost", 4949, "RaceStream");
|
sr = new StreamReceiver("localhost", 4949, "RaceStream");
|
||||||
// sr = new StreamReceiver("csse-s302staff.canterbury.ac.nz", 4941, "RaceStream");
|
// sr = new StreamReceiver("csse-s302staff.canterbury.ac.nz", 4941, "RaceStream");
|
||||||
sr = new StreamReceiver("livedata.americascup.com", 4941, "RaceStream");
|
|
||||||
// sr = new StreamReceiver("csse-s302staff.canterbury.ac.nz", 4942, "RaceStream");
|
// sr = new StreamReceiver("csse-s302staff.canterbury.ac.nz", 4942, "RaceStream");
|
||||||
|
// sr = new StreamReceiver("livedata.americascup.com", 4941, "RaceStream");
|
||||||
}
|
}
|
||||||
|
|
||||||
sr.start();
|
sr.start();
|
||||||
@@ -77,6 +74,7 @@ public class App extends Application {
|
|||||||
streamParser.start();
|
streamParser.start();
|
||||||
|
|
||||||
launch(args);
|
launch(args);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -214,7 +214,7 @@ public class CanvasController {
|
|||||||
for (BoatGroup boatGroup : boatGroups) {
|
for (BoatGroup boatGroup : boatGroups) {
|
||||||
// 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.boatLocations.containsKey(boatGroup.getRaceId())) {
|
||||||
if (boatGroup.isStopped()) {
|
if (boatGroup.isStopped()) {
|
||||||
updateBoatGroup(boatGroup);
|
updateBoatGroup(boatGroup);
|
||||||
}
|
}
|
||||||
@@ -223,7 +223,7 @@ public class CanvasController {
|
|||||||
}
|
}
|
||||||
for (MarkGroup markGroup : markGroups) {
|
for (MarkGroup markGroup : markGroups) {
|
||||||
for (Long id : markGroup.getRaceIds()) {
|
for (Long id : markGroup.getRaceIds()) {
|
||||||
if (StreamParser.markPositions.containsKey(id)) {
|
if (StreamParser.markLocations.containsKey(id)) {
|
||||||
updateMarkGroup(id, markGroup);
|
updateMarkGroup(id, markGroup);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -240,7 +240,7 @@ public class CanvasController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void updateBoatGroup(BoatGroup boatGroup) {
|
private void updateBoatGroup(BoatGroup boatGroup) {
|
||||||
PriorityBlockingQueue<BoatPositionPacket> movementQueue = StreamParser.boatPositions.get(boatGroup.getRaceId());
|
PriorityBlockingQueue<BoatPositionPacket> movementQueue = StreamParser.boatLocations.get(boatGroup.getRaceId());
|
||||||
// giving the movementQueue a 5 packet buffer to account for slightly out of order packets
|
// giving the movementQueue a 5 packet buffer to account for slightly out of order packets
|
||||||
if (movementQueue.size() > 0){
|
if (movementQueue.size() > 0){
|
||||||
try {
|
try {
|
||||||
@@ -256,7 +256,7 @@ public class CanvasController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void updateMarkGroup (long raceId, MarkGroup markGroup) {
|
void updateMarkGroup (long raceId, MarkGroup markGroup) {
|
||||||
PriorityBlockingQueue<BoatPositionPacket> movementQueue = StreamParser.markPositions.get(raceId);
|
PriorityBlockingQueue<BoatPositionPacket> movementQueue = StreamParser.markLocations.get(raceId);
|
||||||
if (movementQueue.size() > 0){
|
if (movementQueue.size() > 0){
|
||||||
try {
|
try {
|
||||||
BoatPositionPacket positionPacket = movementQueue.take();
|
BoatPositionPacket positionPacket = movementQueue.take();
|
||||||
|
|||||||
@@ -34,6 +34,6 @@ public class Controller implements Initializable {
|
|||||||
public void initialize(URL location, ResourceBundle resources) {
|
public void initialize(URL location, ResourceBundle resources) {
|
||||||
contentPane.getStylesheets().add(getClass().getResource("/css/master.css").toString());
|
contentPane.getStylesheets().add(getClass().getResource("/css/master.css").toString());
|
||||||
setContentPane("/views/StartScreenView.fxml");
|
setContentPane("/views/StartScreenView.fxml");
|
||||||
StreamParser.boatPositions.clear();
|
StreamParser.boatLocations.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
|||||||
@FXML
|
@FXML
|
||||||
private CanvasController includedCanvasController;
|
private CanvasController includedCanvasController;
|
||||||
|
|
||||||
private ArrayList<Yacht> startingBoats = new ArrayList<>();
|
private static ArrayList<Yacht> startingBoats = new ArrayList<>();
|
||||||
private boolean displayFps;
|
private boolean displayFps;
|
||||||
private Timeline timerTimeline;
|
private Timeline timerTimeline;
|
||||||
private Stage stage;
|
private Stage stage;
|
||||||
@@ -227,7 +227,6 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
// Adds the new data series to the sparkline (and set the colour of the series)
|
// Adds the new data series to the sparkline (and set the colour of the series)
|
||||||
raceSparkLine.setCreateSymbols(false);
|
raceSparkLine.setCreateSymbols(false);
|
||||||
positions.stream().filter(spark -> !raceSparkLine.getData().contains(spark)).forEach(spark -> {
|
positions.stream().filter(spark -> !raceSparkLine.getData().contains(spark)).forEach(spark -> {
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ public class StartScreenController implements Initializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void switchToRaceView() {
|
public void switchToRaceView() {
|
||||||
StreamParser.boatPositions.clear();
|
StreamParser.boatLocations.clear();
|
||||||
switchedToRaceView = true;
|
switchedToRaceView = true;
|
||||||
setContentPane("/views/RaceView.fxml");
|
setContentPane("/views/RaceView.fxml");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import seng302.controllers.RaceViewController;
|
|||||||
|
|
||||||
import java.text.DateFormat;
|
import java.text.DateFormat;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
|
import seng302.models.stream.StreamParser;
|
||||||
import seng302.models.stream.XMLParser.RaceXMLObject.Corner;
|
import seng302.models.stream.XMLParser.RaceXMLObject.Corner;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import java.util.ArrayList;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
@@ -35,8 +34,8 @@ import seng302.models.stream.packets.StreamPacket;
|
|||||||
*/
|
*/
|
||||||
public class StreamParser extends Thread {
|
public class StreamParser extends Thread {
|
||||||
|
|
||||||
public static ConcurrentHashMap<Long, PriorityBlockingQueue<BoatPositionPacket>> markPositions = new ConcurrentHashMap<>();
|
public static ConcurrentHashMap<Long, PriorityBlockingQueue<BoatPositionPacket>> markLocations = new ConcurrentHashMap<>();
|
||||||
public static ConcurrentHashMap<Long, PriorityBlockingQueue<BoatPositionPacket>> boatPositions = new ConcurrentHashMap<>();
|
public static ConcurrentHashMap<Long, PriorityBlockingQueue<BoatPositionPacket>> boatLocations = new ConcurrentHashMap<>();
|
||||||
private String threadName;
|
private String threadName;
|
||||||
private Thread t;
|
private Thread t;
|
||||||
private static boolean newRaceXmlReceived = false;
|
private static boolean newRaceXmlReceived = false;
|
||||||
@@ -46,7 +45,7 @@ public class StreamParser extends Thread {
|
|||||||
private static boolean streamStatus = false;
|
private static boolean streamStatus = false;
|
||||||
private static long timeSinceStart = -1;
|
private static long timeSinceStart = -1;
|
||||||
private static Map<Integer, Yacht> boats = new ConcurrentHashMap<>();
|
private static Map<Integer, Yacht> boats = new ConcurrentHashMap<>();
|
||||||
private static Map<Long, Yacht> boatsPos = new ConcurrentSkipListMap<>();
|
private static Map<Integer, Yacht> boatsPos = new ConcurrentSkipListMap<>();
|
||||||
private static double windDirection = 0;
|
private static double windDirection = 0;
|
||||||
private static Double windSpeed = 0d;
|
private static Double windSpeed = 0d;
|
||||||
private static Long currentTimeLong;
|
private static Long currentTimeLong;
|
||||||
@@ -151,6 +150,7 @@ public class StreamParser extends Thread {
|
|||||||
}
|
}
|
||||||
} catch (NullPointerException e) {
|
} catch (NullPointerException e) {
|
||||||
System.out.println("Error parsing packet");
|
System.out.println("Error parsing packet");
|
||||||
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -225,13 +225,12 @@ public class StreamParser extends Thread {
|
|||||||
|
|
||||||
int noBoats = payload[22];
|
int noBoats = payload[22];
|
||||||
int raceType = payload[23];
|
int raceType = payload[23];
|
||||||
boatsPos = new TreeMap<>();
|
|
||||||
for (int i = 0; i < noBoats; i++) {
|
for (int i = 0; i < noBoats; i++) {
|
||||||
long boatStatusSourceID = bytesToLong(
|
long boatStatusSourceID = bytesToLong(
|
||||||
Arrays.copyOfRange(payload, 24 + (i * 20), 28 + (i * 20)));
|
Arrays.copyOfRange(payload, 24 + (i * 20), 28 + (i * 20)));
|
||||||
Yacht boat = boats.get((int) boatStatusSourceID);
|
Yacht boat = boats.get((int) boatStatusSourceID);
|
||||||
boat.setBoatStatus((int) payload[28 + (i * 20)]);
|
boat.setBoatStatus((int) payload[28 + (i * 20)]);
|
||||||
boat.setLegNumber((int) payload[29 + (i * 20)]);
|
setBoatLegPosition(boat, (int) payload[29 + (i * 20)]);
|
||||||
boat.setPenaltiesAwarded((int) payload[30 + (i * 20)]);
|
boat.setPenaltiesAwarded((int) payload[30 + (i * 20)]);
|
||||||
boat.setPenaltiesServed((int) payload[31 + (i * 20)]);
|
boat.setPenaltiesServed((int) payload[31 + (i * 20)]);
|
||||||
Long estTimeAtNextMark = bytesToLong(
|
Long estTimeAtNextMark = bytesToLong(
|
||||||
@@ -240,7 +239,7 @@ public class StreamParser extends Thread {
|
|||||||
Long estTimeAtFinish = bytesToLong(
|
Long estTimeAtFinish = bytesToLong(
|
||||||
Arrays.copyOfRange(payload, 38 + (i * 20), 44 + (i * 20)));
|
Arrays.copyOfRange(payload, 38 + (i * 20), 44 + (i * 20)));
|
||||||
boat.setEstimateTimeAtFinish(estTimeAtFinish);
|
boat.setEstimateTimeAtFinish(estTimeAtFinish);
|
||||||
boatsPos.put(estTimeAtFinish, boat);
|
// boatsPos.put(estTimeAtFinish, boat);
|
||||||
// String boatStatus = "SourceID: " + boatStatusSourceID;
|
// String boatStatus = "SourceID: " + boatStatusSourceID;
|
||||||
// boatStatus += "\nBoat Status: " + (int)payload[28 + (i * 20)];
|
// boatStatus += "\nBoat Status: " + (int)payload[28 + (i * 20)];
|
||||||
// boatStatus += "\nLegNumber: " + (int)payload[29 + (i * 20)];
|
// boatStatus += "\nLegNumber: " + (int)payload[29 + (i * 20)];
|
||||||
@@ -250,16 +249,34 @@ public class StreamParser extends Thread {
|
|||||||
// boatStatus += "\nEstTimeAtFinish: " + bytesToLong(Arrays.copyOfRange(payload,37 + (i * 20),43+ (i * 20)));
|
// boatStatus += "\nEstTimeAtFinish: " + bytesToLong(Arrays.copyOfRange(payload,37 + (i * 20),43+ (i * 20)));
|
||||||
// boatStatuses.add(boatStatus);
|
// boatStatuses.add(boatStatus);
|
||||||
}
|
}
|
||||||
if (isRaceStarted()) {
|
// if (isRaceStarted()) {
|
||||||
int pos = 1;
|
// int pos = 1;
|
||||||
for (Yacht yacht : boatsPos.values()) {
|
// for (Yacht yacht : boatsPos.values()) {
|
||||||
yacht.setPosition(String.valueOf(pos));
|
// yacht.setPosition(String.valueOf(pos));
|
||||||
pos++;
|
// pos++;
|
||||||
}
|
// }
|
||||||
} else {
|
// } else {
|
||||||
for (Yacht yacht : boatsPos.values()) {
|
// for (Yacht yacht : boatsPos.values()) {
|
||||||
yacht.setPosition("-");
|
// yacht.setPosition("-");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void setBoatLegPosition(Yacht updatingBoat, Integer leg){
|
||||||
|
Integer placing = 1;
|
||||||
|
if (leg != updatingBoat.getLegNumber() && (raceStarted || raceFinished)) {
|
||||||
|
for (Yacht boat : boats.values()) {
|
||||||
|
if (boat.getLegNumber() != null && leg <= boat.getLegNumber()){
|
||||||
|
placing += 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
updatingBoat.setPosition(placing.toString());
|
||||||
|
updatingBoat.setLegNumber(leg);
|
||||||
|
boatsPos.putIfAbsent(placing, updatingBoat);
|
||||||
|
boatsPos.replace(placing, updatingBoat);
|
||||||
|
} else if(updatingBoat.getLegNumber() == null){
|
||||||
|
updatingBoat.setPosition("1");
|
||||||
|
updatingBoat.setLegNumber(leg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -403,9 +420,9 @@ public class StreamParser extends Thread {
|
|||||||
BoatPositionPacket boatPacket = new BoatPositionPacket(boatId, timeValid, lat, lon,
|
BoatPositionPacket boatPacket = new BoatPositionPacket(boatId, timeValid, lat, lon,
|
||||||
heading, groundSpeed);
|
heading, groundSpeed);
|
||||||
|
|
||||||
//add a new priority que to the boatPositions HashMap
|
//add a new priority que to the boatLocations HashMap
|
||||||
if (!boatPositions.containsKey(boatId)) {
|
if (!boatLocations.containsKey(boatId)) {
|
||||||
boatPositions.put(boatId,
|
boatLocations.put(boatId,
|
||||||
new PriorityBlockingQueue<>(256, new Comparator<BoatPositionPacket>() {
|
new PriorityBlockingQueue<>(256, new Comparator<BoatPositionPacket>() {
|
||||||
@Override
|
@Override
|
||||||
public int compare(BoatPositionPacket p1, BoatPositionPacket p2) {
|
public int compare(BoatPositionPacket p1, BoatPositionPacket p2) {
|
||||||
@@ -413,14 +430,14 @@ public class StreamParser extends Thread {
|
|||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
boatPositions.get(boatId).put(boatPacket);
|
boatLocations.get(boatId).put(boatPacket);
|
||||||
} else if (deviceType == 3) {
|
} else if (deviceType == 3) {
|
||||||
BoatPositionPacket markPacket = new BoatPositionPacket(boatId, timeValid, lat, lon,
|
BoatPositionPacket markPacket = new BoatPositionPacket(boatId, timeValid, lat, lon,
|
||||||
heading, groundSpeed);
|
heading, groundSpeed);
|
||||||
|
|
||||||
//add a new priority que to the boatPositions HashMap
|
//add a new priority que to the boatLocations HashMap
|
||||||
if (!markPositions.containsKey(boatId)) {
|
if (!markLocations.containsKey(boatId)) {
|
||||||
markPositions.put(boatId,
|
markLocations.put(boatId,
|
||||||
new PriorityBlockingQueue<>(256, new Comparator<BoatPositionPacket>() {
|
new PriorityBlockingQueue<>(256, new Comparator<BoatPositionPacket>() {
|
||||||
@Override
|
@Override
|
||||||
public int compare(BoatPositionPacket p1, BoatPositionPacket p2) {
|
public int compare(BoatPositionPacket p1, BoatPositionPacket p2) {
|
||||||
@@ -428,7 +445,7 @@ public class StreamParser extends Thread {
|
|||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
markPositions.get(boatId).put(markPacket);
|
markLocations.get(boatId).put(markPacket);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -615,7 +632,8 @@ public class StreamParser extends Thread {
|
|||||||
*
|
*
|
||||||
* @return a map of time to finish and boat.
|
* @return a map of time to finish and boat.
|
||||||
*/
|
*/
|
||||||
public static Map<Long, Yacht> getBoatsPos() {
|
public static Map<Integer, Yacht> getBoatsPos() {
|
||||||
|
|
||||||
return boatsPos;
|
return boatsPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
<Label layoutX="11.0" layoutY="14.0" text="Timer" textFill="WHITE" />
|
<Label layoutX="11.0" layoutY="14.0" text="Timer" textFill="WHITE" />
|
||||||
<Label layoutX="11.0" layoutY="88.0" text="Wind direction" textFill="WHITE" />
|
<Label layoutX="11.0" layoutY="88.0" text="Wind direction" textFill="WHITE" />
|
||||||
<Circle fx:id="windBackgroundCircle" blendMode="DARKEN" fill="#3dcdc8" layoutX="110.0" layoutY="166.0" radius="35.0" stroke="#d7d7d7" strokeType="INSIDE" strokeWidth="3.0" />
|
<Circle fx:id="windBackgroundCircle" blendMode="DARKEN" fill="#3dcdc8" layoutX="110.0" layoutY="166.0" radius="35.0" stroke="#d7d7d7" strokeType="INSIDE" strokeWidth="3.0" />
|
||||||
<Text fx:id="windArrowText" fill="#a8a8a8" layoutX="86.0" layoutY="186.0" strokeType="OUTSIDE" strokeWidth="0.0" text="↑">
|
<Text fx:id="windArrowText" fill="#a8a8a8" layoutX="86.0" layoutY="186.0" strokeType="OUTSIDE" strokeWidth="0.0" text="↓">
|
||||||
<font>
|
<font>
|
||||||
<Font name="AdobeArabic-Regular" size="55.0" />
|
<Font name="AdobeArabic-Regular" size="55.0" />
|
||||||
</font>
|
</font>
|
||||||
|
|||||||
Reference in New Issue
Block a user