Merge branch 'wind_(story53)' into 'master'
Wind (story53) AC: Note: "Back" means that the wind shifts counterclockwise while "veer" means clockwise. Shifts should follow the following patterns: 1. The wind should usually oscillate regularly around a mean (several minutes per oscillation and no more than 5 degrees either way.) 2. Occasionally it will either "back" or "veer" (a few degrees a minute, up to 180 degrees shift), and then return to oscillations. Acceptance criteria: - The wind direction follows the above patterns during a race. * Test wind works at 0 to small degree amounts. See merge request !36
This commit is contained in:
@@ -4,6 +4,9 @@ import mock.dataInput.PolarParser;
|
||||
import mock.exceptions.EventConstructionException;
|
||||
import mock.model.*;
|
||||
import mock.model.commandFactory.CompositeCommand;
|
||||
import mock.model.wind.RandomWindGenerator;
|
||||
import mock.model.wind.ShiftingWindGenerator;
|
||||
import mock.model.wind.WindGenerator;
|
||||
import mock.xml.RaceXMLCreator;
|
||||
import network.Messages.LatestMessages;
|
||||
import org.xml.sax.SAXException;
|
||||
@@ -18,11 +21,8 @@ import shared.model.Constants;
|
||||
|
||||
import javax.xml.bind.JAXBException;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import java.io.IOException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.Duration;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
@@ -124,14 +124,10 @@ public class Event {
|
||||
this.compositeCommand = new CompositeCommand();
|
||||
this.latestMessages = new LatestMessages();
|
||||
|
||||
//Create and start race.
|
||||
WindGenerator windGenerator = new RandomWindGenerator(
|
||||
WindGenerator windGenerator = new ShiftingWindGenerator(
|
||||
Bearing.fromDegrees(225),
|
||||
Bearing.fromDegrees(215),
|
||||
Bearing.fromDegrees(235),
|
||||
12d,
|
||||
8d,
|
||||
16d );
|
||||
12
|
||||
);
|
||||
RaceLogic newRace = new RaceLogic(
|
||||
new MockRace(
|
||||
boatDataSource,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package mock.model;
|
||||
|
||||
import mock.model.wind.WindGenerator;
|
||||
import javafx.animation.AnimationTimer;
|
||||
import mock.model.collider.ColliderRegistry;
|
||||
import mock.xml.*;
|
||||
|
||||
+1
-3
@@ -1,11 +1,9 @@
|
||||
package mock.model;
|
||||
package mock.model.wind;
|
||||
|
||||
|
||||
import shared.model.Bearing;
|
||||
import shared.model.Wind;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* This class generates Wind objects for use in a MockRace.
|
||||
* Initialised with a baseline wind speed and direction, and keeps it constant.
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package mock.model;
|
||||
package mock.model.wind;
|
||||
|
||||
|
||||
import shared.model.Bearing;
|
||||
@@ -0,0 +1,152 @@
|
||||
package mock.model.wind;
|
||||
|
||||
import shared.model.Bearing;
|
||||
import shared.model.Wind;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class ShiftingWindGenerator implements WindGenerator {
|
||||
private Bearing baselineBearing;
|
||||
private double baseLineSpeed;
|
||||
private double windSpeedVariance = 5;
|
||||
private double bearingVariance = 5; // In degrees
|
||||
private double oscillationVariance = 0.25;
|
||||
private double oscillationPeriod = 1e3 * 60 * 1; // In milliseconds
|
||||
private double shiftTime = 1e3 * 60;
|
||||
private double shiftedSoFar = 0;
|
||||
|
||||
private double timeOfLastOscillationReset = 0;
|
||||
private double timeOfLastChange = 0;
|
||||
private double timeOfLastShift = 0; // Back / veer
|
||||
|
||||
private boolean anticlockwise = false;
|
||||
private boolean shiftAnticlockwise = false;//true for Back, false for veer
|
||||
private boolean shiftThisRace = Math.random() > 0.5;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param baselineBearing baseline bearing for wind
|
||||
* @param baseLineSpeed base line speed for wind
|
||||
*/
|
||||
public ShiftingWindGenerator(Bearing baselineBearing, double baseLineSpeed) {
|
||||
this.baselineBearing = baselineBearing;
|
||||
this.baseLineSpeed = baseLineSpeed;
|
||||
initialiseOscillationDirection();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Wind generateBaselineWind() {
|
||||
return new Wind(baselineBearing, baseLineSpeed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Wind generateNextWind(Wind currentWind) {
|
||||
return changeWind(currentWind);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param wind the wind to change
|
||||
* @return the changed wind
|
||||
*/
|
||||
private Wind changeWind(Wind wind) {
|
||||
Wind newWind = new Wind(wind.getWindDirection(), wind.getWindSpeed());
|
||||
oscillateWind(newWind);
|
||||
if (shiftThisRace){shiftWind(newWind);}
|
||||
changeWindSpeed(newWind);
|
||||
timeOfLastChange = System.currentTimeMillis();
|
||||
return newWind;
|
||||
}
|
||||
|
||||
/**
|
||||
* moves the wind 5 degrees up and down
|
||||
* @param wind the wind to oscillate
|
||||
*/
|
||||
private void oscillateWind(Wind wind) {
|
||||
double timeSinceLastOscillationReset = System.currentTimeMillis() - timeOfLastOscillationReset;
|
||||
double timeSinceLastChange = System.currentTimeMillis() - timeOfLastChange;
|
||||
double newBearing = wind.getWindDirection().degrees();
|
||||
double degreeChange = timeSinceLastChange * 2 * bearingVariance / oscillationPeriod;
|
||||
degreeChange = (1 - oscillationVariance) * degreeChange + (2 * oscillationVariance) * degreeChange * Math.random();
|
||||
|
||||
if (timeSinceLastOscillationReset >= oscillationPeriod) {
|
||||
timeOfLastOscillationReset = System.currentTimeMillis();
|
||||
anticlockwise = !anticlockwise;
|
||||
}
|
||||
if (anticlockwise) {
|
||||
newBearing -= degreeChange;
|
||||
if (newBearing < baselineBearing.degrees() - bearingVariance) {
|
||||
anticlockwise = !anticlockwise;
|
||||
timeOfLastOscillationReset = System.currentTimeMillis();
|
||||
} else {
|
||||
wind.setWindDirection(Bearing.fromDegrees(newBearing % 360));
|
||||
}
|
||||
} else {
|
||||
newBearing += degreeChange;
|
||||
if (newBearing > baselineBearing.degrees() + bearingVariance) {
|
||||
anticlockwise = !anticlockwise;
|
||||
timeOfLastOscillationReset = System.currentTimeMillis();
|
||||
} else {
|
||||
wind.setWindDirection(Bearing.fromDegrees(newBearing % 360));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Slowly shifts the wind up to 180 degrees from where it started
|
||||
* @param wind the wind to change
|
||||
*/
|
||||
private void shiftWind(Wind wind) {
|
||||
double timeSinceLastShift = System.currentTimeMillis() - timeOfLastShift;
|
||||
double newBearing = wind.getWindDirection().degrees();
|
||||
double degreeChange = 7;
|
||||
|
||||
if (timeSinceLastShift >= shiftTime){
|
||||
shiftedSoFar += degreeChange;
|
||||
if (shiftedSoFar >= 180){
|
||||
shiftAnticlockwise = Math.random() > 0.5;
|
||||
shiftedSoFar = 0;
|
||||
System.out.println("Swapping");
|
||||
}
|
||||
|
||||
timeOfLastShift = System.currentTimeMillis();
|
||||
if (shiftAnticlockwise){
|
||||
newBearing -= degreeChange;
|
||||
wind.setWindDirection(Bearing.fromDegrees(newBearing % 360));
|
||||
} else {
|
||||
newBearing += degreeChange;
|
||||
wind.setWindDirection(Bearing.fromDegrees(newBearing % 360));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the wind speed
|
||||
* @param wind the wind to change
|
||||
*/
|
||||
private void changeWindSpeed(Wind wind) {
|
||||
double offsetAngle = (wind.getWindDirection().radians() - baselineBearing.radians());
|
||||
double offset = Math.sin(offsetAngle) * windSpeedVariance;
|
||||
double newWindSpeed = baseLineSpeed + offset;
|
||||
wind.setWindSpeed(newWindSpeed);
|
||||
}
|
||||
|
||||
/**
|
||||
* starts the wind oscillation direction
|
||||
*/
|
||||
private void initialiseOscillationDirection() {
|
||||
anticlockwise = new Random().nextBoolean();
|
||||
timeOfLastOscillationReset = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public void setBearingVariance(double maxBearingVariance) {
|
||||
this.bearingVariance = maxBearingVariance;
|
||||
}
|
||||
|
||||
public void setWindSpeedVariance(double windSpeedVariance) {
|
||||
this.windSpeedVariance = windSpeedVariance;
|
||||
}
|
||||
|
||||
public void setOscillationPeriod(double oscillationPeriod) {
|
||||
this.oscillationPeriod = oscillationPeriod;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package mock.model;
|
||||
package mock.model.wind;
|
||||
|
||||
import shared.model.Wind;
|
||||
|
||||
@@ -48,4 +48,11 @@ public class Wind {
|
||||
return windSpeed;
|
||||
}
|
||||
|
||||
public void setWindSpeed(double windSpeed) {
|
||||
this.windSpeed = windSpeed;
|
||||
}
|
||||
|
||||
public void setWindDirection(Bearing windDirection) {
|
||||
this.windDirection = windDirection;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package visualiser.Controllers;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import visualiser.app.App;
|
||||
import visualiser.gameController.ControllerClient;
|
||||
import visualiser.model.VisualiserBoat;
|
||||
import visualiser.model.VisualiserRaceEvent;
|
||||
@@ -40,6 +39,7 @@ public class MainController extends Controller {
|
||||
* Transitions from the StartController screen (displays pre-race information) to the RaceController (displays the actual race).
|
||||
* @param visualiserRace The object modelling the race.
|
||||
* @param controllerClient Socket Client that manipulates the controller.
|
||||
* @param isHost if the client is the host of a race or not.
|
||||
*/
|
||||
public void beginRace(VisualiserRaceEvent visualiserRace, ControllerClient controllerClient, Boolean isHost) {
|
||||
raceController.startRace(visualiserRace, controllerClient, isHost);
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 9.2 KiB |
@@ -1,5 +1,7 @@
|
||||
package mock.model;
|
||||
|
||||
import mock.model.wind.ConstantWindGenerator;
|
||||
import mock.model.wind.WindGenerator;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import shared.model.Bearing;
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
package mock.model;
|
||||
|
||||
import mock.dataInput.PolarParserTest;
|
||||
import network.Messages.LatestMessages;
|
||||
import mock.model.wind.ConstantWindGenerator;
|
||||
import mock.model.wind.WindGenerator;
|
||||
import shared.dataInput.*;
|
||||
import shared.exceptions.InvalidBoatDataException;
|
||||
import shared.exceptions.InvalidRaceDataException;
|
||||
@@ -9,8 +10,6 @@ import shared.exceptions.InvalidRegattaDataException;
|
||||
import shared.model.Bearing;
|
||||
import shared.model.Constants;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class MockRaceTest {
|
||||
//TODO
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package mock.model;
|
||||
|
||||
import mock.model.wind.RandomWindGenerator;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import shared.model.Bearing;
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<java version="1.8.0_111" class="java.beans.XMLDecoder">
|
||||
<object class="java.util.HashMap">
|
||||
<void method="put">
|
||||
<string>SPACE</string>
|
||||
<object class="visualiser.gameController.Keys.VMGKey"/>
|
||||
</void>
|
||||
<void method="put">
|
||||
<string>SHIFT</string>
|
||||
<object class="visualiser.gameController.Keys.SailsToggleKey"/>
|
||||
</void>
|
||||
<void method="put">
|
||||
<string>DOWN</string>
|
||||
<object class="visualiser.gameController.Keys.DownWindKey"/>
|
||||
</void>
|
||||
<void method="put">
|
||||
<string>X</string>
|
||||
<object class="visualiser.gameController.Keys.ZoomOutKey"/>
|
||||
</void>
|
||||
<void method="put">
|
||||
<string>ENTER</string>
|
||||
<object class="visualiser.gameController.Keys.TackGybeKey"/>
|
||||
</void>
|
||||
<void method="put">
|
||||
<string>Z</string>
|
||||
<object class="visualiser.gameController.Keys.ZoomInKey"/>
|
||||
</void>
|
||||
<void method="put">
|
||||
<string>UP</string>
|
||||
<object class="visualiser.gameController.Keys.UpWindKey"/>
|
||||
</void>
|
||||
</object>
|
||||
</java>
|
||||
Reference in New Issue
Block a user