Skip to content

Commit

Permalink
Merge pull request #4 from ajayyy/multi-data-source
Browse files Browse the repository at this point in the history
Multi data source for Google earth, new config and layout saving/loading
  • Loading branch information
ajayyy authored Feb 15, 2020
2 parents abd3bbc + 2e528ca commit 91efc04
Show file tree
Hide file tree
Showing 11 changed files with 397 additions and 194 deletions.
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Work in progress UI for data coming from the rocket.

# Add labels

Make a folder called `data` and a file called `labels[NUMBER]txt` in data. The number represents the data source index, starting at `0`. This should be a comma separated file of all the labels in the dataset. The number of labels should be the same as the `DATA_LENGTH` variable.
Make a folder called `data` and a file called `config.json` in data. This is a JSON file. Follow the format from `data-example/config.json`.

For convenience, you can rename the `data-example` folder to `data` to get the labels.

Expand All @@ -16,11 +16,15 @@ For convenience, you can rename the `data-example` folder to `data` to get the l

Load this folder in your preferred Java IDE (ex. Eclipse).

Add the libraries from `libs`

Setup the labels as described above.

Run `Main.java`

# Simulation

Save your file in the `data` folder with the name `data[NUMBER].txt`. Replace `number` with an index of the data source starting at `0`.
Save your file in the `data` folder with the name `data[NUMBER].txt`. Replace `number` with an index of the data source starting at `0`. Make sure you have labels in `data/config.json` for every data file you have.

# Window Management

Expand Down
30 changes: 30 additions & 0 deletions data-example/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"datasets": [
{
"name": "Rocket",
"color": "DD000000",
"labels": [
"Timestamp (ms)",
"Altitude (m)",
"Latitude",
"Longitude",
"Pitch",
"Roll",
"Yaw",
"Acceleration X (g)",
"Acceleration Y (g)",
"Acceleration Z (g)",
"Velocity (m/s)",
"Brake Percentage",
"Actual Brake Value",
"GPS Fix",
"GPS Fix Quality"
],
"coordinateIndexes": {
"altitude": 1,
"latitude": 2,
"longitude": 3
}
}
]
}
1 change: 0 additions & 1 deletion data-example/labels0.txt

This file was deleted.

Binary file added libs/json-20190722.jar
Binary file not shown.
Binary file removed libs/xchart-3.6.0.jar
Binary file not shown.
Binary file added libs/xchart-3.6.1.jar
Binary file not shown.
6 changes: 4 additions & 2 deletions src/uorocketry/basestation/DataHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import javax.swing.JTable;
import javax.swing.table.TableModel;

import org.json.JSONObject;

public class DataHandler {

static final DataType TIMESTAMP = new DataType(0, 0);
Expand Down Expand Up @@ -46,9 +48,9 @@ public void updateTableUIWithData(JTable table, String[] labels) {
}
}

public void set(int index, String currentData) {
public void set(int index, String currentData, JSONObject coordinateIndexes) {
// Check for special cases first
if (LATITUDE.equals(index, tableIndex) || LONGITUDE.equals(index, tableIndex)) {
if (coordinateIndexes.getInt("latitude") == index || coordinateIndexes.getInt("longitude") == index) {
float degrees = 0;
float minutes = 0;

Expand Down
128 changes: 81 additions & 47 deletions src/uorocketry/basestation/GoogleEarthUpdater.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
import java.util.Timer;
import java.util.TimerTask;

import org.json.JSONArray;
import org.json.JSONObject;

public class GoogleEarthUpdater {

/**
Expand All @@ -27,7 +30,7 @@ public GoogleEarthUpdater() {
*
* @param main
*/
public String generateKMLFile(List<DataHandler> allData, int currentDataIndex) {
public String generateKMLFile(List<List<DataHandler>> allData, List<Integer> minDataIndex, List<Integer> currentDataIndex, JSONArray dataSets) {
StringBuilder content = new StringBuilder();

content.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" +
Expand All @@ -41,75 +44,106 @@ public String generateKMLFile(List<DataHandler> allData, int currentDataIndex) {
" </LineStyle>" +
" </Style>");

content.append("<Placemark>\r\n");
content.append("<name>Rocket Path</name>\r\n");
content.append("<styleUrl>#blackLine</styleUrl>");
content.append("<LineString><altitudeMode>absolute</altitudeMode><coordinates>\r\n");

for (int i = 0; i <= currentDataIndex; i++) {
String currentString = getCoordinateString(allData.get(i));

if (currentString != null) {
content.append(currentString + "\r\n");
}
for (int i = 0; i < allData.size(); i++) {
// Add style
content.append("<Style id='blackLine'>\r\n");
content.append("<LineStyle>\r\n");
content.append("<color>" + dataSets.getJSONObject(i).getString("color"));
content.append("</color>\r\n");
content.append("<width>5</width>\r\n");
content.append("</LineStyle>");
content.append("</Style>");

}

content.append("</coordinates></LineString>\r\n");
content.append("</Placemark>\r\n");

//Add the latest coordinate as a placemark
String latestDataString = getCoordinateString(allData.get(currentDataIndex));
if (latestDataString != null) {
content.append("<Placemark>\r\n");
content.append("<name>Latest Position</name>\r\n");
content.append("<Point>\r\n<altitudeMode>absolute</altitudeMode>\r\n<coordinates>");
content.append("<name>Path of " + dataSets.getJSONObject(i).getString("name"));
content.append("</name>\r\n");
content.append("<styleUrl>#blackLine</styleUrl>");
content.append("<LineString><altitudeMode>absolute</altitudeMode><coordinates>\r\n");

for (int j = minDataIndex.get(i); j <= currentDataIndex.get(i); j++) {
String currentString = getCoordinateString(allData.get(i).get(j), dataSets.getJSONObject(i).getJSONObject("coordinateIndexes"));

if (currentString != null) {
content.append(currentString + "\r\n");
}

}

content.append(latestDataString);
content.append("</coordinates></LineString>\r\n");
content.append("</Placemark>\r\n");

content.append("</coordinates>\r\n</Point>\r\n</Placemark>\r\n");
//Add the latest coordinate as a placemark
String latestDataString = getCoordinateString(allData.get(i).get(currentDataIndex.get(i)), dataSets.getJSONObject(i).getJSONObject("coordinateIndexes"));
if (latestDataString != null) {
content.append("<Placemark>\r\n");
content.append("<name>Latest Position of " + dataSets.getJSONObject(i).getString("name"));
content.append("</name>\r\n");
content.append("<Point>\r\n<altitudeMode>absolute</altitudeMode>\r\n<coordinates>");

content.append(latestDataString);

content.append("</coordinates>\r\n</Point>\r\n</Placemark>\r\n");
}
}


content.append("</Document></kml>");

return content.toString();
}

public void updateKMLFile(int tableIndex, List<DataHandler> allData, int currentDataIndex) {
String fileContent = generateKMLFile(allData, currentDataIndex);
/**
* Updates the KML file with the data up to currentDataIndex.
*
* @param tableIndex
* @param allData
* @param currentDataIndex
* @param dataSets
* @param secondRun Is this a second run? This is true if it is being run from a task called by this function.
* The task is run to force Google Earth to update the display.
*/
public void updateKMLFile(List<List<DataHandler>> allData, List<Integer> minDataIndex, List<Integer> currentDataIndex, JSONArray dataSets, boolean secondRun) {
String fileContent = generateKMLFile(allData, minDataIndex, currentDataIndex, dataSets);

try (Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(Main.GOOGLE_EARTH_DATA_LOCATION), StandardCharsets.UTF_8))) {
try (Writer writer = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(Main.GOOGLE_EARTH_DATA_LOCATION), StandardCharsets.UTF_8))) {
writer.write(fileContent);
} catch (IOException e) {
e.printStackTrace();
}

if (mapRefreshTaskTimer != null) {
if (!secondRun) {
if (mapRefreshTaskTimer != null) {
try {
mapRefreshTaskTimer.cancel();
} catch (IllegalStateException e) {
// Ignore if it is already canceled
}
}

// Start a new task
mapRefreshTaskTimer = new TimerTask() {
@Override
public void run() {
updateKMLFile(allData, minDataIndex, currentDataIndex, dataSets, true);
}
};
try {
mapRefreshTaskTimer.cancel();
mapRefreshTimer.schedule(mapRefreshTaskTimer, 1000);
} catch (IllegalStateException e) {
// Ignore if it is already canceled
// Ignore as another has already started
}
}

// Start a new task
mapRefreshTaskTimer = new TimerTask() {
@Override
public void run() {
updateKMLFile(tableIndex, allData, currentDataIndex);
}
};
try {
mapRefreshTimer.schedule(mapRefreshTaskTimer, 50);
} catch (IllegalStateException e) {
// Ignore as another has already started
}
}

public String getCoordinateString(DataHandler dataPoint) {
if (dataPoint != null && dataPoint.data[DataHandler.LONGITUDE.index].data != 0 && dataPoint.data[DataHandler.LATITUDE.index].data != 0) {
return "-" + dataPoint.data[DataHandler.LONGITUDE.index].getDecimalCoordinate() + "," + dataPoint.data[DataHandler.LATITUDE.index].getDecimalCoordinate() + "," + dataPoint.data[DataHandler.ALTITUDE.index].data;
public String getCoordinateString(DataHandler dataPoint, JSONObject coordinateIndexes) {
if (dataPoint == null) return null;

Data altitudeData = dataPoint.data[coordinateIndexes.getInt("altitude")];
Data longitudeData = dataPoint.data[coordinateIndexes.getInt("longitude")];
Data latitudeData = dataPoint.data[coordinateIndexes.getInt("latitude")];

if (longitudeData.data != 0 && latitudeData.data != 0) {
return "-" + longitudeData.getDecimalCoordinate() + "," + latitudeData.getDecimalCoordinate() + "," + altitudeData.data;
}

return null;
Expand Down
Loading

0 comments on commit 91efc04

Please sign in to comment.