Merge branch 'refactor-events-to-update-boat-positions' into 'master'

Removed Legs from the race, using coordinates instead

Tags: #implement #refactor #test #story[9]

See merge request !17
This commit is contained in:
Michael Rausch
2017-03-16 20:30:48 +13:00
9 changed files with 180 additions and 126 deletions
+17
View File
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8" inherit-compiler-output="false">
<output url="file://$MODULE_DIR$/target/classes" />
<output-test url="file://$MODULE_DIR$/target/test-classes" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.12" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
<orderEntry type="library" name="Maven: com.googlecode.json-simple:json-simple:1.1.1" level="project" />
</component>
</module>
+2 -2
View File
@@ -1,7 +1,7 @@
{
"race-name": "AC35",
"time-scale": 2.0,
"race-size": 6,
"time-scale": 1.0,
"race-size": 2,
"teams": [
{
"team-name": "Oracle Team USA",
+2 -1
View File
@@ -6,7 +6,6 @@ import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class App extends Application
{
@Override
@@ -17,6 +16,8 @@ public class App extends Application
primaryStage.setTitle("RaceVision");
primaryStage.setScene(new Scene(root));
//OldApp.main(); // Run this to show how positions are updated
primaryStage.show();
}
+30
View File
@@ -7,10 +7,16 @@ public class Boat {
private String teamName; // The name of the team, this is also the name of the boat
private double velocity; // In meters/second
private double lat; // Boats position
private double lon; // -
private double distanceToNextMark;
public Boat(String teamName) {
this.teamName = teamName;
this.velocity = 10; // Default velocity
this.lat = 0.0;
this.lon = 0.0;
this.distanceToNextMark = 0.0;
}
/**
@@ -22,6 +28,7 @@ public class Boat {
public Boat(String teamName, double boatVelocity) {
this.teamName = teamName;
this.velocity = boatVelocity;
this.distanceToNextMark = 0.0;
}
/**
@@ -59,4 +66,27 @@ public class Boat {
public void setVelocity(double velocity) {
this.velocity = velocity;
}
/**
* Sets the boats location
*
* @param lat, the boats latitude
* @param lon, the boats longitude
*/
public void setLocation(double lat, double lon) {
this.lat = lat;
this.lon = lon;
}
public void setDistanceToNextMark(double distance){
this.distanceToNextMark = distance;
}
public double getLatitude(){
return this.lat;
}
public double getLongitude(){
return this.lon;
}
}
+50 -36
View File
@@ -8,11 +8,12 @@ import java.util.Date;
* event location such as leg.
*/
public class Event {
private long time; // Time the event occurs
private Double time; // Time the event occurs
private Boat boat;
private Leg leg; // Leg of the race the event occurs on
private boolean isFinishingEvent = false; // This event occurs when a boat finishes the race
private Mark mark1; // This mark
private Mark mark2; // Next Mark
/**
* Event class containing the time of specific event, related team/boat, and
@@ -20,12 +21,13 @@ public class Event {
*
* @param eventTime, what time the event happens
* @param eventBoat, the boat that the event belongs to
* @param eventLeg, the leg the event happens on
*/
public Event(long eventTime, Boat eventBoat, Leg eventLeg) {
public Event(Double eventTime, Boat eventBoat, Mark mark1, Mark mark2) {
this.time = eventTime;
this.boat = eventBoat;
this.leg = eventLeg;
//this.leg = eventLeg;
this.mark1 = mark1;
this.mark2 = mark2;
}
/**
@@ -34,14 +36,12 @@ public class Event {
*
* @param eventTime, what time the event happens
* @param eventBoat, the boat that the event belongs to
* @param eventLeg, the leg the event happens on
* @param isFinishingEvent, true if this event is the boat crossing the finishing line
*/
public Event(long eventTime, Boat eventBoat, Leg eventLeg, boolean isFinishingEvent) {
public Event(Double eventTime, Boat eventBoat, Mark mark1) {
this.time = eventTime;
this.boat = eventBoat;
this.leg = eventLeg;
this.isFinishingEvent = isFinishingEvent;
this.mark1 = mark1;
this.isFinishingEvent = true;
}
/**
@@ -49,7 +49,7 @@ public class Event {
*
* @return the time for event in millisecond
*/
public long getTime() {
public double getTime() {
return this.time;
}
@@ -58,7 +58,7 @@ public class Event {
*
* @param eventTime the time for event in millisecond
*/
public void setTime(long eventTime) {
public void setTime(double eventTime) {
this.time = eventTime;
}
@@ -68,7 +68,7 @@ public class Event {
* @return the string of time
*/
public String getTimeString() {
return (new SimpleDateFormat("mm:ss:SSS")).format(new Date(time));
return (new SimpleDateFormat("mm:ss:SSS")).format(new Date(time.longValue()));
}
/**
@@ -89,30 +89,12 @@ public class Event {
this.boat = eventBoat;
}
/**
* Gets the involved location/leg
*
* @return the leg involved in the event
*/
public Leg getLeg() {
return this.leg;
}
/**
* Sets the involved location/leg
*
* @param eventLeg the involved leg
*/
public void setLeg(Leg eventLeg) {
this.leg = eventLeg;
}
/**
* Called when the boat in this event passes
* the marker.
*/
public void boatPassedMarker() {
this.leg.addBoatToMarker(boat);
this.mark1.addBoat(boat);
}
/**
@@ -128,13 +110,45 @@ public class Event {
* @return A string that details what happened in this event
*/
public String getEventString() {
String currentHeading = Integer.toString(this.getLeg().getHeading());
// This event is a boat finishing the race
if (this.isFinishingEvent) {
return (this.getTimeString() + ", " + this.getBoat().getTeamName() + " finished the race");
}
return (this.getTimeString() + ", " + this.getBoat().getTeamName() + " passed " + this.getLeg().getMarkerLabel() + " going heading " + currentHeading + "°");
return (this.getTimeString() + ", " + this.getBoat().getTeamName() + " passed " + this.mark1.getName() + " going heading " + this.getBoatHeading() + "°");
}
/**
* @return the distance between the two marks
*/
public double getDistanceBetweenMarks(){
return Math.sqrt(Math.pow(mark1.getLatitude()-mark2.getLatitude(), 2) + Math.pow(mark1.getLongitude()-mark2.getLongitude(), 2));
}
/**
* @return the boats heading
*/
public double getBoatHeading(){
double bearing = Math.atan2(mark2.getLatitude() - mark1.getLatitude(), mark2.getLongitude() - mark1.getLongitude());
if (bearing < 0) {
bearing += Math.PI * 2;
}
return bearing * 180 / Math.PI;
}
/**
* Get the mark the event happened on
* @return the mark
*/
public Mark getMark(){
return this.mark1;
}
/**
* Get the next mark
* @return the next mark
*/
public Mark getNextMark(){
return this.mark2;
}
}
+23 -2
View File
@@ -12,9 +12,11 @@ public class Mark {
private ArrayList<Boat> boatOrder;
/**
* Represents the marker at the beginning of a leg
* Represents a marker
*
* @param name, the name of the marker
* @param name, the name of the marker*
* @param lat, the latitude of the marker
* @param lon, the longitude of the marker
*/
public Mark(String name, double lat, double lon){
this.name = name;
@@ -23,6 +25,18 @@ public class Mark {
this.boatOrder = new ArrayList<Boat>();
}
/**
* Represents the marker at the beginning of a leg
*
* @param name, the name of the marker
*/
public Mark(String name){
this.name = name;
this.lat = 0;
this.lon = 0;
this.boatOrder = new ArrayList<Boat>();
}
public void setName(String name){
this.name = name;
}
@@ -35,4 +49,11 @@ public class Mark {
public Boat[] getBoats(){
return this.boatOrder.toArray(new Boat[this.boatOrder.size()]);
}
public double getLatitude(){
return this.lat;
}
public double getLongitude(){
return this.lon;
}
}
@@ -7,7 +7,7 @@ import java.util.Map;
import java.util.Random;
import java.io.FileNotFoundException;
public class App {
public class OldApp {
/**
* Builds a race object for the AC35 course
@@ -54,30 +54,22 @@ public class App {
race.addBoat(new Boat(boatNames.get(i), (Double) (teams.get(i).get("velocity"))));
}
race.addLeg(new Leg(35, 100, "Start"));
race.addLeg(new Leg(10, 300, "Mark 1"));
race.addLeg(new Leg(350, 400, "Leeward Gate"));
race.addLeg(new Leg(10, 400, "Windward Gate"));
Leg finishingLeg = new Leg(10, 400, "Leeward Gate");
finishingLeg.setFinishingLeg(true);
race.addLeg(finishingLeg);
// Add marks to race in order
race.addMark(new Mark("Start", 32.296038,-64.854401 ));
race.addMark(new Mark("Mid Mark", 32.292881,-64.843231 ));
race.addMark(new Mark("Leeward Gate", 32.283808,-64.850012 ));
race.addMark(new Mark("Windward Gate", 32.309908,-64.833665 ));
race.addMark(new Mark("Finish", 32.318439,-64.837367 ));
return race;
}
public static void main(String[] args) {
public static void main() {
Race race = null;
String raceConfigFile;
if (args.length == 2 && args[0].equals("-f")){
raceConfigFile = args[1];
}
else{
// Use default config
raceConfigFile = "doc/examples/config.json";
}
try {
race = createRace(raceConfigFile);
@@ -101,7 +93,7 @@ public class App {
System.out.println("# Race Results ");
System.out.println("######################");
race.showRaceMarkerResults();
//race.showRaceMarkerResults();
race.displayFinishingOrder();
} else {
+33 -49
View File
@@ -8,9 +8,9 @@ import java.util.*;
*/
public class Race {
private ArrayList<Boat> boats; // The boats in the race
private ArrayList<Leg> legs; // The legs in the race
private ArrayList<Boat> finishingOrder; // The order in which the boats finish the race
private PriorityQueue<Event> events; // The events that occur in the race
private ArrayList<Mark> marks; // Marks in the race
private int numberOfBoats = 0;
private long startTime = 0;
private double timeScale = 1;
@@ -20,15 +20,15 @@ public class Race {
*/
public Race() {
this.boats = new ArrayList<Boat>();
this.legs = new ArrayList<Leg>();
this.finishingOrder = new ArrayList<Boat>();
this.marks = new ArrayList<Mark>();
// create a priority queue with a custom Comparator to order events
this.events = new PriorityQueue<Event>(new Comparator<Event>() {
@Override
public int compare(Event o1, Event o2) {
Long time1 = o1.getTime();
Long time2 = o2.getTime();
Double time1 = o1.getTime();
Double time2 = o2.getTime();
// order event asc. by time. if tie appears, then order team
// name alphabetically.
@@ -123,25 +123,6 @@ public class Race {
System.out.println(boats[i].getTeamName() + " Velocity: " + velocityKnots + " Knots/s");
}
}
/**
* Adds a leg to the race
*
* @param leg, the leg to add to the race
*/
public void addLeg(Leg leg) {
this.legs.add(leg);
}
/**
* Gets legs array
*
* @return an array of legs
*/
public ArrayList<Leg> getLegs() {
return this.legs;
}
/**
* Sets time scale
*
@@ -156,18 +137,24 @@ public class Race {
*/
private void generateEvents() {
//calculate the time every boat passes each leg, and create an event
for (Boat boat : this.boats) {
long totalDistance = 0;
for (Leg leg : this.legs) {
long time = (long) (1000 * totalDistance / boat.getVelocity());
Event event = new Event(time, boat, leg);
events.add(event);
totalDistance += leg.getDistance();
// If finishing leg, add another event for when the boat finishes the race
if (leg.getIsFinishingLeg()) {
time = (long) (1000 * totalDistance / boat.getVelocity());
event = new Event(time, boat, leg, true);
for (Boat boat : this.boats) {
double totalDistance = 0;
int numberOfMarks = this.marks.size();
for(int i = 0; i < numberOfMarks; i++){
Double time = (Double) (1000 * totalDistance / boat.getVelocity());
// If there are marks after this event
if (i < numberOfMarks-1) {
Event event = new Event(time, boat, marks.get(i), marks.get(i + 1));
events.add(event);
totalDistance += event.getDistanceBetweenMarks();
}
// There are no more marks after this event
else{
Event event = new Event(time, boat, marks.get(i));
events.add(event);
}
}
@@ -192,6 +179,7 @@ public class Race {
*/
public void iterateEvents() {
// iterates all events. ends when no event in events.
while (!events.isEmpty()) {
Event peekEvent = events.peek();
long currentTime = (long) ((System.currentTimeMillis() - this.startTime) * this.timeScale);
@@ -201,7 +189,13 @@ public class Race {
// Display a summary of the event
System.out.println(nextEvent.getEventString());
nextEvent.boatPassedMarker();
// Display latitude and longitude
if (!nextEvent.getIsFinishingEvent()){
System.out.println(nextEvent.getMark().getLatitude() + ", " + nextEvent.getNextMark().getLongitude());
}
System.out.println();
// If event is a boat finishing the race
if (nextEvent.getIsFinishingEvent()) {
@@ -230,20 +224,10 @@ public class Race {
}
/**
* Print the order in which the boats passed each marker
* Add a mark to the race (in order)
* @param mark, the mark to add
*/
public void showRaceMarkerResults() {
for (Leg leg : this.legs) {
Boat[] boats = leg.getMarker().getBoats();
System.out.println("--- " + leg.getMarkerLabel() + " ---");
// Print the order in which the boats passed the marker
for (int i = 0; i < this.getNumberOfBoats(); i++) {
System.out.println("#" + Integer.toString(i + 1) + " - " + boats[i].getTeamName());
}
System.out.println("");
}
public void addMark(Mark mark){
this.marks.add(mark);
}
}
+12 -17
View File
@@ -3,7 +3,7 @@ package seng302;
import org.junit.Test;
import seng302.models.Boat;
import seng302.models.Event;
import seng302.models.Leg;
import seng302.models.Mark;
import static org.junit.Assert.assertEquals;
@@ -15,29 +15,24 @@ public class EventTest {
@Test
public void getTimeString() throws Exception {
Leg leg = new Leg(35, 100, "Start");
Boat boat = new Boat("testBoat");
Event event = new Event(1231242, boat, leg);
Event event = new Event(1231242.2, boat, new Mark("mark1"), new Mark("mark2"));
assertEquals("20:31:242", event.getTimeString());
}
/**
* ensure all boats are added as they pass the marker
*/
@Test
public void boatOrderTest() throws Exception {
Leg leg = new Leg(35, 100, "1");
public void testBoatHeading() throws Exception {
Boat boat = new Boat("testBoat");
Event event = new Event(1231242.2, boat, new Mark("mark1", 142.5, 122.1), new Mark("mark2", 121.9,99.2));
Boat boat1 = new Boat("testBoat");
Boat boat2 = new Boat("testBoat2");
assertEquals(event.getBoatHeading(), 221.9733862944651, 1e-15);
}
Event event1 = new Event(1231242, boat1, leg);
Event event2 = new Event(1231242, boat2, leg);
@Test
public void testDistanceBetweenMarks() throws Exception {
Boat boat = new Boat("testBoat");
Event event = new Event(1231242.2, boat, new Mark("mark1", 142.5, 122.1), new Mark("mark2", 121.9,99.2));
event1.boatPassedMarker();
event2.boatPassedMarker();
assertEquals(event1.getLeg().getMarker().getBoats()[0].getTeamName(), "testBoat");
assertEquals(event2.getLeg().getMarker().getBoats()[1].getTeamName(), "testBoat2");
assertEquals(event.getDistanceBetweenMarks(), 30.80211031731429, 1e-15);
}
}