mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-09-22 21:55:39 +00:00
adaptation of simulation time-step based on race course and boat class;
This commit is contained in:
+935
-730
File diff suppressed because it is too large
Load Diff
+127
-102
@@ -78,6 +78,7 @@ import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
|
||||
public class SimulatorServiceImpl extends RemoteServiceServlet implements SimulatorService {
|
||||
|
||||
private static final long serialVersionUID = 4445427185387524086L;
|
||||
@@ -200,7 +201,8 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
|
||||
throw new WindPatternNotFoundException("Please select a valid wind pattern.");
|
||||
}
|
||||
|
||||
Position[][] grid = bd.generatePositions(params.getxRes(), params.getyRes(), params.getBorderY(), params.getBorderX());
|
||||
Position[][] grid = bd.generatePositions(params.getxRes(), params.getyRes(), params.getBorderY(),
|
||||
params.getBorderX());
|
||||
wf.setPositionGrid(grid);
|
||||
|
||||
TimePoint startTime = new MillisecondsTimePoint(params.getStartTime().getTime());
|
||||
@@ -235,13 +237,13 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimulatorResultsDTO getSimulatorResults(char mode, char rcDirection, WindFieldGenParamsDTO params, WindPatternDisplay pattern, boolean withWindField,
|
||||
SimulatorUISelectionDTO selection) throws WindPatternNotFoundException,
|
||||
ConfigurationException {
|
||||
public SimulatorResultsDTO getSimulatorResults(char mode, char rcDirection, WindFieldGenParamsDTO params,
|
||||
WindPatternDisplay pattern, boolean withWindField, SimulatorUISelectionDTO selection)
|
||||
throws WindPatternNotFoundException, ConfigurationException {
|
||||
WindFieldGenerator wf = null;
|
||||
List<Position> course = null;
|
||||
TimePoint startTime = new MillisecondsTimePoint(params.getStartTime().getTime());
|
||||
@@ -250,7 +252,7 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
|
||||
this.controlParameters.resetBlastRandomStream = params.isKeepState();
|
||||
this.retreiveWindControlParameters(pattern);
|
||||
if (rcDirection == SailingSimulatorConstants.LegTypeDownwind) {
|
||||
this.controlParameters.baseWindBearing += 180.0;
|
||||
this.controlParameters.baseWindBearing += 180.0;
|
||||
}
|
||||
|
||||
wf = wfGenFactory.createWindFieldGenerator(pattern.getWindPatternName(), null, this.controlParameters);
|
||||
@@ -274,13 +276,14 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
|
||||
gridRes[0] = params.getxRes();
|
||||
gridRes[1] = params.getyRes();
|
||||
gridRes[2] = params.getBorderY();
|
||||
gridRes[3] = params.getBorderX();
|
||||
gridRes[3] = params.getBorderX();
|
||||
wf.setGridResolution(gridRes);
|
||||
|
||||
wf.generate(startTime, null, timeStep);
|
||||
Long longestPathTime = 0L;
|
||||
|
||||
SimulatedPathsEvenTimedResultDTO simulatedPaths = this.getSimulatedPathsEvenTimed(course, wf, mode, selection, params.showOmniscient, params.showOpportunist);
|
||||
SimulatedPathsEvenTimedResultDTO simulatedPaths = this.getSimulatedPathsEvenTimed(course, wf, mode, selection,
|
||||
params.showOmniscient, params.showOpportunist);
|
||||
PathDTO[] pathDTOs = simulatedPaths.pathDTOs;
|
||||
RaceMapDataDTO rcDTO = simulatedPaths.raceMapDataDTO;
|
||||
|
||||
@@ -298,10 +301,13 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
|
||||
|
||||
WindFieldDTO windFieldDTO = null;
|
||||
if (pattern != null) {
|
||||
windFieldDTO = this.createWindFieldDTO(wf, startTime, endTime, timeStep, params); // params.isShowStreamlets2(), params.isShowLines(), params.getSeedLines());
|
||||
windFieldDTO = this.createWindFieldDTO(wf, startTime, endTime, timeStep, params); // params.isShowStreamlets2(),
|
||||
// params.isShowLines(),
|
||||
// params.getSeedLines());
|
||||
}
|
||||
|
||||
return new SimulatorResultsDTO(null, timeStep.asMillis(), 0, rcDTO, pathDTOs, windFieldDTO, simulatedPaths.notificationMessage);
|
||||
return new SimulatorResultsDTO(null, timeStep.asMillis(), 0, rcDTO, pathDTOs, windFieldDTO,
|
||||
simulatedPaths.notificationMessage);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -364,20 +370,23 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
|
||||
@Override
|
||||
public ResponseTotalTimeDTO getTotalTime(RequestTotalTimeDTO requestData) throws ConfigurationException {
|
||||
|
||||
this.averageWind = requestData.useRealAverageWindSpeed ? SimulatorServiceUtils.getAverage(requestData.allPoints)
|
||||
: SimulatorServiceUtils.DEFAULT_AVERAGE_WIND;
|
||||
this.averageWind = requestData.useRealAverageWindSpeed ? SimulatorServiceUtils
|
||||
.getAverage(requestData.allPoints) : SimulatorServiceUtils.DEFAULT_AVERAGE_WIND;
|
||||
|
||||
this.stepSizeMeters = SimulatorServiceUtils.knotsToMetersPerSecond(this.averageWind.getKnots()) * (requestData.stepDurationMilliseconds / 1000.);
|
||||
this.stepSizeMeters = SimulatorServiceUtils.knotsToMetersPerSecond(this.averageWind.getKnots())
|
||||
* (requestData.stepDurationMilliseconds / 1000.);
|
||||
|
||||
// List<Position> points = SimulatorServiceUtils.getIntermediatePoints2(requestData.turnPoints,
|
||||
// this.stepSizeMeters);
|
||||
// int noOfPointsMinus1 = points.size() - 1;
|
||||
|
||||
Util.Pair<PolarDiagram, String> polarDiagramAndNotificationMessage = this.getPolarDiagram(requestData.selection.boatClassIndex);
|
||||
Util.Pair<PolarDiagram, String> polarDiagramAndNotificationMessage = this
|
||||
.getPolarDiagram(requestData.selection.boatClassIndex);
|
||||
PolarDiagram polarDiagram = polarDiagramAndNotificationMessage.getA();
|
||||
String notificationMessage = polarDiagramAndNotificationMessage.getB();
|
||||
|
||||
SailingSimulator simulator = new SailingSimulatorImpl(new SimulationParametersImpl(null, polarDiagram, null, SailingSimulatorConstants.ModeMeasured, true, true));
|
||||
SailingSimulator simulator = new SailingSimulatorImpl(new SimulationParametersImpl(null, polarDiagram, null,
|
||||
null, SailingSimulatorConstants.ModeMeasured, true, true));
|
||||
Path gpsTrack = simulator.getLegGPSTrack(SimulatorServiceUtils.toSimulatorUISelection(requestData.selection));
|
||||
|
||||
// Position startPoint = null;
|
||||
@@ -420,14 +429,12 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
|
||||
//
|
||||
// double totalTimeSeconds = (timepointAsMillis - courseStartPoint.timepoint) / 1000;
|
||||
//
|
||||
double totalTimeGPSTrackSeconds = (gpsTrack.getPathPoints().get(gpsTrack.getPathPoints().size() - 1).getTimePoint().asMillis() - gpsTrack
|
||||
.getPathPoints().get(0).getTimePoint().asMillis()) / 1000;
|
||||
|
||||
|
||||
//while (totalTimeSeconds > totalTimeGPSTrackSeconds) {
|
||||
// totalTimeSeconds *= TOTAL_TIME_SCALE_FACTOR;
|
||||
//}
|
||||
double totalTimeGPSTrackSeconds = (gpsTrack.getPathPoints().get(gpsTrack.getPathPoints().size() - 1)
|
||||
.getTimePoint().asMillis() - gpsTrack.getPathPoints().get(0).getTimePoint().asMillis()) / 1000;
|
||||
|
||||
// while (totalTimeSeconds > totalTimeGPSTrackSeconds) {
|
||||
// totalTimeSeconds *= TOTAL_TIME_SCALE_FACTOR;
|
||||
// }
|
||||
|
||||
long startTimePoint = requestData.allPoints.get(0).timepoint;
|
||||
long segmentTime = 0;
|
||||
@@ -440,8 +447,9 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
|
||||
|
||||
totalTime += segmentTime;
|
||||
|
||||
segmentTime = getTimeMillisecondsBetween(requestData.turnPoints.get(index), requestData.turnPoints.get(index + 1), this.stepSizeMeters,
|
||||
requestData.useRealAverageWindSpeed, gpsTrack, polarDiagram, startTimePoint + totalTime);
|
||||
segmentTime = getTimeMillisecondsBetween(requestData.turnPoints.get(index),
|
||||
requestData.turnPoints.get(index + 1), this.stepSizeMeters, requestData.useRealAverageWindSpeed,
|
||||
gpsTrack, polarDiagram, startTimePoint + totalTime);
|
||||
|
||||
System.out.println("Total time of segment " + segmentIndex + " = " + segmentTime + " milliseconds");
|
||||
}
|
||||
@@ -452,25 +460,30 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
|
||||
|
||||
System.out.println("TotalTimeGPS: " + totalTimeGPSTrackSeconds + " TotalTimePoly: " + totalTimeSeconds);
|
||||
|
||||
return new ResponseTotalTimeDTO(totalTimeSeconds, totalTimeSeconds/totalTimeGPSTrackSeconds, notificationMessage);
|
||||
return new ResponseTotalTimeDTO(totalTimeSeconds, totalTimeSeconds / totalTimeGPSTrackSeconds,
|
||||
notificationMessage);
|
||||
}
|
||||
|
||||
//@Override
|
||||
// @Override
|
||||
public ResponseTotalTimeDTO getTotalTimeOld(RequestTotalTimeDTO requestData) throws ConfigurationException {
|
||||
|
||||
this.averageWind = requestData.useRealAverageWindSpeed ? SimulatorServiceUtils.getAverage(requestData.allPoints)
|
||||
: SimulatorServiceUtils.DEFAULT_AVERAGE_WIND;
|
||||
this.averageWind = requestData.useRealAverageWindSpeed ? SimulatorServiceUtils
|
||||
.getAverage(requestData.allPoints) : SimulatorServiceUtils.DEFAULT_AVERAGE_WIND;
|
||||
|
||||
this.stepSizeMeters = SimulatorServiceUtils.knotsToMetersPerSecond(this.averageWind.getKnots()) * (requestData.stepDurationMilliseconds / 1000.);
|
||||
this.stepSizeMeters = SimulatorServiceUtils.knotsToMetersPerSecond(this.averageWind.getKnots())
|
||||
* (requestData.stepDurationMilliseconds / 1000.);
|
||||
|
||||
List<Position> points = SimulatorServiceUtils.getIntermediatePoints2(requestData.turnPoints, this.stepSizeMeters);
|
||||
List<Position> points = SimulatorServiceUtils.getIntermediatePoints2(requestData.turnPoints,
|
||||
this.stepSizeMeters);
|
||||
int noOfPointsMinus1 = points.size() - 1;
|
||||
|
||||
Util.Pair<PolarDiagram, String> polarDiagramAndNotificationMessage = this.getPolarDiagram(requestData.selection.boatClassIndex);
|
||||
Util.Pair<PolarDiagram, String> polarDiagramAndNotificationMessage = this
|
||||
.getPolarDiagram(requestData.selection.boatClassIndex);
|
||||
PolarDiagram polarDiagram = polarDiagramAndNotificationMessage.getA();
|
||||
String notificationMessage = polarDiagramAndNotificationMessage.getB();
|
||||
|
||||
SailingSimulator simulator = new SailingSimulatorImpl(new SimulationParametersImpl(null, polarDiagram, null, SailingSimulatorConstants.ModeMeasured, true, true));
|
||||
SailingSimulator simulator = new SailingSimulatorImpl(new SimulationParametersImpl(null, polarDiagram, null,
|
||||
null, SailingSimulatorConstants.ModeMeasured, true, true));
|
||||
Path gpsTrack = simulator.getLegGPSTrack(SimulatorServiceUtils.toSimulatorUISelection(requestData.selection));
|
||||
|
||||
Position startPoint = null;
|
||||
@@ -491,17 +504,18 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
|
||||
endPoint = points.get(index + 1);
|
||||
distanceMeters = startPoint.getDistance(endPoint).getMeters();
|
||||
|
||||
windAtTimePoint = requestData.useRealAverageWindSpeed ? SimulatorServiceUtils.getWindAtTimepoint(timepointAsMillis, gpsTrack)
|
||||
: SimulatorServiceUtils.DEFAULT_AVERAGE_WIND;
|
||||
windAtTimePoint = requestData.useRealAverageWindSpeed ? SimulatorServiceUtils.getWindAtTimepoint(
|
||||
timepointAsMillis, gpsTrack) : SimulatorServiceUtils.DEFAULT_AVERAGE_WIND;
|
||||
|
||||
boatBearingDeg = SimulatorServiceUtils.getInitialBearing(startPoint, endPoint);
|
||||
polarDiagram.setWind(windAtTimePoint);
|
||||
boatSpeedMetersPerSecond = polarDiagram.getSpeedAtBearing(new DegreeBearingImpl(boatBearingDeg)).getMetersPerSecond();
|
||||
boatSpeedMetersPerSecond = polarDiagram.getSpeedAtBearing(new DegreeBearingImpl(boatBearingDeg))
|
||||
.getMetersPerSecond();
|
||||
stepTimeMilliseconds = (long) ((distanceMeters / boatSpeedMetersPerSecond) * 1000);
|
||||
//problem right here
|
||||
//boatSpeed might be 0 for very small distances
|
||||
//this is a rough fix
|
||||
if(boatSpeedMetersPerSecond == 0.0) {
|
||||
// problem right here
|
||||
// boatSpeed might be 0 for very small distances
|
||||
// this is a rough fix
|
||||
if (boatSpeedMetersPerSecond == 0.0) {
|
||||
stepTimeMilliseconds = 1000;
|
||||
}
|
||||
|
||||
@@ -511,23 +525,23 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
|
||||
|
||||
double totalTimeSeconds = (timepointAsMillis - requestData.allPoints.get(0).timepoint) / 1000;
|
||||
|
||||
double totalTimeGPSTrackSeconds = (gpsTrack.getPathPoints().get(gpsTrack.getPathPoints().size() - 1).getTimePoint().asMillis() - gpsTrack
|
||||
.getPathPoints().get(0).getTimePoint().asMillis()) / 1000;
|
||||
double totalTimeGPSTrackSeconds = (gpsTrack.getPathPoints().get(gpsTrack.getPathPoints().size() - 1)
|
||||
.getTimePoint().asMillis() - gpsTrack.getPathPoints().get(0).getTimePoint().asMillis()) / 1000;
|
||||
|
||||
// while (totalTimeSeconds > totalTimeGPSTrackSeconds) {
|
||||
// totalTimeSeconds *= TOTAL_TIME_SCALE_FACTOR;
|
||||
// }
|
||||
System.out.println("TotalTimeGPS: " + totalTimeGPSTrackSeconds + " TotalTimePoly: " + totalTimeSeconds);
|
||||
|
||||
//while (totalTimeSeconds > totalTimeGPSTrackSeconds) {
|
||||
// totalTimeSeconds *= TOTAL_TIME_SCALE_FACTOR;
|
||||
//}
|
||||
System.out.println("TotalTimeGPS: "+totalTimeGPSTrackSeconds+" TotalTimePoly: "+totalTimeSeconds);
|
||||
|
||||
return new ResponseTotalTimeDTO((long) totalTimeSeconds, (double)totalTimeSeconds/(double)totalTimeGPSTrackSeconds, notificationMessage);
|
||||
return new ResponseTotalTimeDTO((long) totalTimeSeconds, (double) totalTimeSeconds
|
||||
/ (double) totalTimeGPSTrackSeconds, notificationMessage);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Response1TurnerDTO get1Turner(Request1TurnerDTO requestData) throws ConfigurationException {
|
||||
|
||||
Util.Pair<PolarDiagram, String> polarDiagramAndNotificationMessage = this.getPolarDiagram(requestData.selection.boatClassIndex);
|
||||
Util.Pair<PolarDiagram, String> polarDiagramAndNotificationMessage = this
|
||||
.getPolarDiagram(requestData.selection.boatClassIndex);
|
||||
PolarDiagram polarDiagram = polarDiagramAndNotificationMessage.getA();
|
||||
String notificationMessage = polarDiagramAndNotificationMessage.getB();
|
||||
|
||||
@@ -537,16 +551,19 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
|
||||
Position oldMovedPosition = SimulatorServiceUtils.toPosition(requestData.oldMovedPoint);
|
||||
Position newMovedPosition = SimulatorServiceUtils.toPosition(requestData.newMovedPoint);
|
||||
Bearing oldMovedToNewMovedBearing = oldMovedPosition.getBearingGreatCircle(newMovedPosition);
|
||||
boolean areTowardsSameDirection = SimulatorServiceUtils.areTowardsSameDirection(oldMovedToNewMovedBearing, new DegreeBearingImpl(
|
||||
requestData.startToEndBearingDegrees));
|
||||
boolean areTowardsSameDirection = SimulatorServiceUtils.areTowardsSameDirection(oldMovedToNewMovedBearing,
|
||||
new DegreeBearingImpl(requestData.startToEndBearingDegrees));
|
||||
|
||||
System.out.println("oldMovedToNewMovedBearing = " + oldMovedToNewMovedBearing.getDegrees() + " degrees");
|
||||
System.out.println("requestData.startToEndBearingDegrees = " + requestData.startToEndBearingDegrees + " degrees");
|
||||
System.out.println("requestData.startToEndBearingDegrees = " + requestData.startToEndBearingDegrees
|
||||
+ " degrees");
|
||||
System.out.println("areTowardsSameDirection = " + areTowardsSameDirection);
|
||||
|
||||
SimulationParameters simulationParameters = new SimulationParametersImpl(null, polarDiagram, null, SailingSimulatorConstants.ModeMeasured, true, true);
|
||||
SimulationParameters simulationParameters = new SimulationParametersImpl(null, polarDiagram, null, null,
|
||||
SailingSimulatorConstants.ModeMeasured, true, true);
|
||||
SailingSimulator sailingSimulator = new SailingSimulatorImpl(simulationParameters);
|
||||
Path gpsWind = sailingSimulator.getLegGPSTrack(SimulatorServiceUtils.toSimulatorUISelection(requestData.selection));
|
||||
Path gpsWind = sailingSimulator.getLegGPSTrack(SimulatorServiceUtils
|
||||
.toSimulatorUISelection(requestData.selection));
|
||||
|
||||
Grid grid = new CurvedGrid(oldMovedPosition, newMovedPosition);
|
||||
this.controlParameters.baseWindBearing += grid.getSouth().getDegrees();
|
||||
@@ -563,17 +580,18 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
|
||||
Position realStart = areTowardsSameDirection ? oldMovedPosition : newMovedPosition;
|
||||
Position realEnd = areTowardsSameDirection ? newMovedPosition : oldMovedPosition;
|
||||
|
||||
leftSide1Turner = pathGenerator.get1Turner(windFieldGenerator, polarDiagram, realStart, realEnd, startTime, true, DEFAULT_STEP_MAX, DEFAULT_TIMESTEP);
|
||||
rightSide1Turner = pathGenerator.get1Turner(windFieldGenerator, polarDiagram, realStart, realEnd, startTime, false, DEFAULT_STEP_MAX, DEFAULT_TIMESTEP);
|
||||
leftSide1Turner = pathGenerator.get1Turner(windFieldGenerator, polarDiagram, realStart, realEnd, startTime,
|
||||
true, DEFAULT_STEP_MAX, DEFAULT_TIMESTEP);
|
||||
rightSide1Turner = pathGenerator.get1Turner(windFieldGenerator, polarDiagram, realStart, realEnd, startTime,
|
||||
false, DEFAULT_STEP_MAX, DEFAULT_TIMESTEP);
|
||||
|
||||
boolean isLeftSide1TurnerOnTheInside = SimulatorServiceUtils.isPointInsideTriangle(SimulatorServiceUtils.toPositionDTO(leftSide1Turner.getPosition()),
|
||||
requestData.beforeMovedPoint,
|
||||
boolean isLeftSide1TurnerOnTheInside = SimulatorServiceUtils.isPointInsideTriangle(
|
||||
SimulatorServiceUtils.toPositionDTO(leftSide1Turner.getPosition()), requestData.beforeMovedPoint,
|
||||
requestData.newMovedPoint, requestData.edgeStart);
|
||||
System.out.println("isLeftSide1TurnerOnTheInside = " + isLeftSide1TurnerOnTheInside);
|
||||
|
||||
boolean isRightSide1TurnerOnTheInside = SimulatorServiceUtils.isPointInsideTriangle(
|
||||
SimulatorServiceUtils.toPositionDTO(rightSide1Turner.getPosition()),
|
||||
requestData.beforeMovedPoint,
|
||||
SimulatorServiceUtils.toPositionDTO(rightSide1Turner.getPosition()), requestData.beforeMovedPoint,
|
||||
requestData.newMovedPoint, requestData.edgeStart);
|
||||
System.out.println("isRightSide1TurnerOnTheInside = " + isRightSide1TurnerOnTheInside);
|
||||
|
||||
@@ -594,8 +612,7 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
|
||||
} else if (SimulatorServiceUtils.equals(rightSide1Turner.getPosition(), newMovedPosition, 0.0001)) {
|
||||
System.out.println("voi folosi endPosition = rightSide1Turner!");
|
||||
correct1Turner = rightSide1Turner;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
System.out.println("nu ar trebui sa ajunga aici NICIODATA!");
|
||||
}
|
||||
}
|
||||
@@ -603,16 +620,14 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
|
||||
long timeStepMilliseconds = 2000;
|
||||
double minimumDistanceMeters = 4.0;
|
||||
|
||||
List<TimedPositionWithSpeed> path = pathGenerator.getIntersectionOptimalTowardWind(windFieldGenerator, polarDiagram, edgeStart, edgeEnd,
|
||||
correct1Turner,
|
||||
true,
|
||||
timeStepMilliseconds, minimumDistanceMeters);
|
||||
List<TimedPositionWithSpeed> path = pathGenerator.getIntersectionOptimalTowardWind(windFieldGenerator,
|
||||
polarDiagram, edgeStart, edgeEnd, correct1Turner, true, timeStepMilliseconds, minimumDistanceMeters);
|
||||
|
||||
|
||||
return new Response1TurnerDTO(SimulatorServiceUtils.toSimulatorWindDTOList(path), SimulatorServiceUtils.toSimulatorWindDTO(leftSide1Turner),
|
||||
SimulatorServiceUtils.toSimulatorWindDTO(rightSide1Turner), SimulatorServiceUtils.toPositionDTO(oldMovedPosition),
|
||||
SimulatorServiceUtils.toPositionDTO(newMovedPosition),
|
||||
notificationMessage);
|
||||
return new Response1TurnerDTO(SimulatorServiceUtils.toSimulatorWindDTOList(path),
|
||||
SimulatorServiceUtils.toSimulatorWindDTO(leftSide1Turner),
|
||||
SimulatorServiceUtils.toSimulatorWindDTO(rightSide1Turner),
|
||||
SimulatorServiceUtils.toPositionDTO(oldMovedPosition),
|
||||
SimulatorServiceUtils.toPositionDTO(newMovedPosition), notificationMessage);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -622,7 +637,8 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
|
||||
selectedRaceIndex = 0;
|
||||
}
|
||||
|
||||
SailingSimulator simulator = new SailingSimulatorImpl(new SimulationParametersImpl(null, null, null, SailingSimulatorConstants.ModeMeasured, true, true));
|
||||
SailingSimulator simulator = new SailingSimulatorImpl(new SimulationParametersImpl(null, null, null, null,
|
||||
SailingSimulatorConstants.ModeMeasured, true, true));
|
||||
|
||||
return simulator.getLegsNames(selectedRaceIndex);
|
||||
}
|
||||
@@ -630,7 +646,8 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
|
||||
@Override
|
||||
public List<String> getRacesNames() {
|
||||
|
||||
SailingSimulator simulator = new SailingSimulatorImpl(new SimulationParametersImpl(null, null, null, SailingSimulatorConstants.ModeMeasured, true, true));
|
||||
SailingSimulator simulator = new SailingSimulatorImpl(new SimulationParametersImpl(null, null, null, null,
|
||||
SailingSimulatorConstants.ModeMeasured, true, true));
|
||||
|
||||
return simulator.getRacesNames();
|
||||
}
|
||||
@@ -642,7 +659,8 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
|
||||
selectedRaceIndex = 0;
|
||||
}
|
||||
|
||||
SailingSimulator simulator = new SailingSimulatorImpl(new SimulationParametersImpl(null, null, null, SailingSimulatorConstants.ModeMeasured,true, true));
|
||||
SailingSimulator simulator = new SailingSimulatorImpl(new SimulationParametersImpl(null, null, null, null,
|
||||
SailingSimulatorConstants.ModeMeasured, true, true));
|
||||
|
||||
return simulator.getComeptitorsNames(selectedRaceIndex);
|
||||
}
|
||||
@@ -702,11 +720,11 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
|
||||
|
||||
SimulatorWindDTO result = new SimulatorWindDTO();
|
||||
if (speedWithBearing == null) {
|
||||
result.trueWindBearingDeg = 0.0;
|
||||
result.trueWindSpeedInKnots = 0.0;
|
||||
result.trueWindBearingDeg = 0.0;
|
||||
result.trueWindSpeedInKnots = 0.0;
|
||||
} else {
|
||||
result.trueWindBearingDeg = speedWithBearing.getBearing().getDegrees();
|
||||
result.trueWindSpeedInKnots = speedWithBearing.getKnots();
|
||||
result.trueWindBearingDeg = speedWithBearing.getBearing().getDegrees();
|
||||
result.trueWindSpeedInKnots = speedWithBearing.getKnots();
|
||||
}
|
||||
|
||||
if (position != null) {
|
||||
@@ -775,8 +793,8 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
|
||||
TimePoint t = startTime;
|
||||
Position p0 = positionGrid[0][j];
|
||||
Position p1 = positionGrid[1][j];
|
||||
Position seed = new DegreePosition(p0.getLatDeg() + 0.5 * (p0.getLatDeg() - p1.getLatDeg()), p0.getLngDeg() + 0.5
|
||||
* (p0.getLngDeg() - p1.getLngDeg()));
|
||||
Position seed = new DegreePosition(p0.getLatDeg() + 0.5 * (p0.getLatDeg() - p1.getLatDeg()),
|
||||
p0.getLngDeg() + 0.5 * (p0.getLngDeg() - p1.getLngDeg()));
|
||||
PositionDTO startPosition = new PositionDTO(seed.getLatDeg(), seed.getLngDeg());
|
||||
while (t.compareTo(endTime) <= 0) {
|
||||
TimedPosition tp = new TimedPositionImpl(t, seed);
|
||||
@@ -795,9 +813,9 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
|
||||
}
|
||||
}
|
||||
}
|
||||
//TODO: throws null pointer exception for when reading serialized paths.
|
||||
//TODO: should windlines also be serialized?
|
||||
//logger.info("Added : " + windFieldDTO.getWindLinesDTO().getWindLinesMap().size() + " wind lines");
|
||||
// TODO: throws null pointer exception for when reading serialized paths.
|
||||
// TODO: should windlines also be serialized?
|
||||
// logger.info("Added : " + windFieldDTO.getWindLinesDTO().getWindLinesMap().size() + " wind lines");
|
||||
}
|
||||
|
||||
private void getWindLinesFromEndLine(WindFieldGenerator wf, WindFieldDTO windFieldDTO, TimePoint startTime,
|
||||
@@ -815,8 +833,8 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
|
||||
TimePoint t = startTime;
|
||||
Position p0 = positionGrid[lastRowIndex][j];
|
||||
Position p1 = positionGrid[lastRowIndex - 1][j];
|
||||
Position seed = new DegreePosition(p0.getLatDeg() + 0.5 * (p0.getLatDeg() - p1.getLatDeg()), p0.getLngDeg() + 0.5
|
||||
* (p0.getLngDeg() - p1.getLngDeg()));
|
||||
Position seed = new DegreePosition(p0.getLatDeg() + 0.5 * (p0.getLatDeg() - p1.getLatDeg()),
|
||||
p0.getLngDeg() + 0.5 * (p0.getLngDeg() - p1.getLngDeg()));
|
||||
PositionDTO startPosition = new PositionDTO(seed.getLatDeg(), seed.getLngDeg());
|
||||
while (t.compareTo(endTime) <= 0) {
|
||||
TimedPosition tp = new TimedPositionImpl(t, seed);
|
||||
@@ -867,21 +885,26 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
|
||||
}
|
||||
}
|
||||
|
||||
private SimulatedPathsEvenTimedResultDTO getSimulatedPathsEvenTimed(List<Position> course, WindFieldGenerator wf, char mode,
|
||||
SimulatorUISelectionDTO selection, boolean showOmniscient, boolean showOpportunist) throws ConfigurationException {
|
||||
private SimulatedPathsEvenTimedResultDTO getSimulatedPathsEvenTimed(List<Position> course, WindFieldGenerator wf,
|
||||
char mode, SimulatorUISelectionDTO selection, boolean showOmniscient, boolean showOpportunist)
|
||||
throws ConfigurationException {
|
||||
|
||||
LOGGER.info("Retrieving simulated paths");
|
||||
|
||||
Util.Pair<PolarDiagram, String> polarDiagramAndNotificationMessage = this.getPolarDiagram(selection.boatClassIndex);
|
||||
Util.Pair<PolarDiagram, String> polarDiagramAndNotificationMessage = this
|
||||
.getPolarDiagram(selection.boatClassIndex);
|
||||
PolarDiagram pd = polarDiagramAndNotificationMessage.getA();
|
||||
|
||||
SimulationParameters sp = new SimulationParametersImpl(course, pd, wf, mode, showOmniscient, showOpportunist);
|
||||
SimulationParameters sp = new SimulationParametersImpl(course, pd, wf, null, mode, showOmniscient,
|
||||
showOpportunist);
|
||||
SailingSimulator simulator = new SailingSimulatorImpl(sp);
|
||||
|
||||
Map<String, Path> pathsAndNames = null;
|
||||
|
||||
pathsAndNames = simulator.getAllPathsEvenTimed(wf.getTimeStep().asMillis(),
|
||||
(mode == SailingSimulatorConstants.ModeMeasured) ? SimulatorServiceUtils.toSimulatorUISelection(selection) : null);
|
||||
pathsAndNames = simulator.getAllPathsEvenTimed(
|
||||
wf.getTimeStep().asMillis(),
|
||||
(mode == SailingSimulatorConstants.ModeMeasured) ? SimulatorServiceUtils
|
||||
.toSimulatorUISelection(selection) : null);
|
||||
|
||||
int noOfPaths = pathsAndNames.size();
|
||||
if (mode == SailingSimulatorConstants.ModeMeasured) {
|
||||
@@ -899,7 +922,7 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
|
||||
LOGGER.info("Path " + entry.getKey());
|
||||
|
||||
// NOTE: pathName convention is: sort-digit + "#" + path-name
|
||||
// pathsAndNames is TreeMap which ensures sorting
|
||||
// pathsAndNames is TreeMap which ensures sorting
|
||||
pathDTOs[index] = new PathDTO(entry.getKey());
|
||||
|
||||
// fill pathDTO with path points where speed is true wind speed
|
||||
@@ -999,8 +1022,10 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
|
||||
isTurn = false;
|
||||
|
||||
for (TimedPositionWithSpeed turn : turns) {
|
||||
if (turn.getPosition().getLatDeg() == point.getPosition().getLatDeg() && turn.getPosition().getLngDeg() == point.getPosition().getLngDeg()
|
||||
&& turn.getTimePoint().asMillis() == point.getTimePoint().asMillis() && turn.getSpeed().getKnots() == point.getSpeed().getKnots()
|
||||
if (turn.getPosition().getLatDeg() == point.getPosition().getLatDeg()
|
||||
&& turn.getPosition().getLngDeg() == point.getPosition().getLngDeg()
|
||||
&& turn.getTimePoint().asMillis() == point.getTimePoint().asMillis()
|
||||
&& turn.getSpeed().getKnots() == point.getSpeed().getKnots()
|
||||
&& turn.getSpeed().getBearing().getDegrees() == point.getSpeed().getBearing().getDegrees()) {
|
||||
isTurn = true;
|
||||
break;
|
||||
@@ -1011,8 +1036,7 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
|
||||
position = point.getPosition();
|
||||
|
||||
points.add(new SimulatorWindDTO(position.getLatDeg(), position.getLngDeg(), speedWithBearing.getKnots(),
|
||||
speedWithBearing.getBearing()
|
||||
.getDegrees(), point.getTimePoint().asMillis(), isTurn));
|
||||
speedWithBearing.getBearing().getDegrees(), point.getTimePoint().asMillis(), isTurn));
|
||||
}
|
||||
|
||||
PathDTO result = new PathDTO(POLYLINE_PATH_NAME);
|
||||
@@ -1077,8 +1101,8 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
|
||||
return result;
|
||||
}
|
||||
|
||||
public long getTimeMillisecondsBetween(PositionDTO turn1, PositionDTO turn2, double stepSizeMeters, boolean useRealAverageWindSpeed, Path gpsTrack,
|
||||
PolarDiagram polarDiagram, long startTimePoint2) {
|
||||
public long getTimeMillisecondsBetween(PositionDTO turn1, PositionDTO turn2, double stepSizeMeters,
|
||||
boolean useRealAverageWindSpeed, Path gpsTrack, PolarDiagram polarDiagram, long startTimePoint2) {
|
||||
|
||||
Position p1 = new DegreePosition(turn1.latDeg, turn1.lngDeg);
|
||||
Position p2 = new DegreePosition(turn2.latDeg, turn2.lngDeg);
|
||||
@@ -1103,17 +1127,18 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
|
||||
endPoint = points.get(index + 1);
|
||||
distanceMeters = startPoint.getDistance(endPoint).getMeters();
|
||||
|
||||
windAtTimePoint = useRealAverageWindSpeed ? SimulatorServiceUtils.getWindAtTimepoint(timepointAsMillis, gpsTrack)
|
||||
: SimulatorServiceUtils.DEFAULT_AVERAGE_WIND;
|
||||
windAtTimePoint = useRealAverageWindSpeed ? SimulatorServiceUtils.getWindAtTimepoint(timepointAsMillis,
|
||||
gpsTrack) : SimulatorServiceUtils.DEFAULT_AVERAGE_WIND;
|
||||
|
||||
boatBearingDeg = SimulatorServiceUtils.getInitialBearing(startPoint, endPoint);
|
||||
polarDiagram.setWind(windAtTimePoint);
|
||||
boatSpeedMetersPerSecond = polarDiagram.getSpeedAtBearing(new DegreeBearingImpl(boatBearingDeg)).getMetersPerSecond();
|
||||
boatSpeedMetersPerSecond = polarDiagram.getSpeedAtBearing(new DegreeBearingImpl(boatBearingDeg))
|
||||
.getMetersPerSecond();
|
||||
stepTimeMilliseconds = (long) ((distanceMeters / boatSpeedMetersPerSecond) * 1000);
|
||||
|
||||
// problem right here: boatSpeed might be 0 for very small distances
|
||||
// this is a rough fix
|
||||
if(boatSpeedMetersPerSecond == 0.0) {
|
||||
if (boatSpeedMetersPerSecond == 0.0) {
|
||||
stepTimeMilliseconds = 1000;
|
||||
}
|
||||
|
||||
|
||||
+11
-10
@@ -32,17 +32,17 @@ public class SimulatorTest {
|
||||
|
||||
@Test
|
||||
public void testSailingSimulatorALL() {
|
||||
|
||||
|
||||
// race course: copacabana, rio de janeiro, brasil
|
||||
Position start = new DegreePosition(-22.975779,-43.17421);
|
||||
Position end = new DegreePosition(-22.99016,-43.156013);
|
||||
//System.out.println("race course size: "+start.getDistance(end).getKilometers());
|
||||
Position start = new DegreePosition(-22.975779, -43.17421);
|
||||
Position end = new DegreePosition(-22.99016, -43.156013);
|
||||
// System.out.println("race course size: "+start.getDistance(end).getKilometers());
|
||||
|
||||
List<Position> course = new LinkedList<Position>();
|
||||
course.add(start);
|
||||
course.add(end);
|
||||
PolarDiagram pd = new PolarDiagram49STG();//PolarDiagram49.CreateStandard49();
|
||||
|
||||
PolarDiagram pd = new PolarDiagram49STG();// PolarDiagram49.CreateStandard49();
|
||||
|
||||
RectangularGrid bd = new RectangularGrid(start, end);
|
||||
Position[][] positions = bd.generatePositions(10, 10, 0, 0);
|
||||
Bearing windBear = end.getBearingGreatCircle(start);
|
||||
@@ -54,15 +54,16 @@ public class SimulatorTest {
|
||||
Duration timeStep = new MillisecondsDurationImpl(30000);
|
||||
wf.generate(startTime, null, timeStep);
|
||||
|
||||
SimulationParameters param = new SimulationParametersImpl(course, pd, wf, SailingSimulatorConstants.ModeFreestyle, true, true);
|
||||
SimulationParameters param = new SimulationParametersImpl(course, pd, wf, null,
|
||||
SailingSimulatorConstants.ModeFreestyle, true, true);
|
||||
SailingSimulatorImpl sailingSim = new SailingSimulatorImpl(param);
|
||||
|
||||
//Map<String, Path> paths = sailingSim.getAllPathsForLeg(new SimulatorUISelectionImpl(0, 0, 0, 0));
|
||||
// Map<String, Path> paths = sailingSim.getAllPathsForLeg(new SimulatorUISelectionImpl(0, 0, 0, 0));
|
||||
Map<String, Path> paths = sailingSim.getAllPaths();
|
||||
|
||||
//System.out.println("opportunistic path points: "+paths.get("2#Opportunist Left").getPathPoints().size());
|
||||
// System.out.println("opportunistic path points: "+paths.get("2#Opportunist Left").getPathPoints().size());
|
||||
Assert.assertNotNull(paths.get("2#Opportunist Left").getPathPoints());
|
||||
//System.out.println("omnciscient path points: "+paths.get("1#Omniscient").getPathPoints().size());
|
||||
// System.out.println("omnciscient path points: "+paths.get("1#Omniscient").getPathPoints().size());
|
||||
Assert.assertNotNull(paths.get("1#Omniscient").getPathPoints());
|
||||
}
|
||||
|
||||
|
||||
+23
-19
@@ -34,44 +34,48 @@ public class TreeGrowTest {
|
||||
@Test
|
||||
public void testSailingSimulatorALL() {
|
||||
|
||||
Position start = new DegreePosition(54.001917,10.82222);
|
||||
//Position end = new DegreePosition(54.023806,10.822048);
|
||||
SpeedWithBearing bearNorth = new KnotSpeedWithBearingImpl(6.0, new DegreeBearingImpl(33.0));
|
||||
Position end = bearNorth.travelTo(start, new MillisecondsTimePoint(0), new MillisecondsTimePoint(10*60*1000));
|
||||
//System.out.println(start.getDistance(end).getKilometers());
|
||||
Position start = new DegreePosition(54.001917, 10.82222);
|
||||
// Position end = new DegreePosition(54.023806,10.822048);
|
||||
SpeedWithBearing bearNorth = new KnotSpeedWithBearingImpl(6.0, new DegreeBearingImpl(33.0));
|
||||
Position end = bearNorth.travelTo(start, new MillisecondsTimePoint(0),
|
||||
new MillisecondsTimePoint(10 * 60 * 1000));
|
||||
// System.out.println(start.getDistance(end).getKilometers());
|
||||
|
||||
List<Position> course = new LinkedList<Position>();
|
||||
course.add(start);
|
||||
course.add(end);
|
||||
PolarDiagram pd = new PolarDiagram49STG();//PolarDiagram49.CreateStandard49();
|
||||
PolarDiagram pd = new PolarDiagram49STG();// PolarDiagram49.CreateStandard49();
|
||||
RectangularGrid bd = new RectangularGrid(start, end);
|
||||
Position[][] positions = bd.generatePositions(10, 10, 0, 0);
|
||||
//RectangularBoundary new_bd = new RectangularBoundary(start, end, 0.1);
|
||||
//Speed knotSpeed = new KnotSpeedImpl(8);
|
||||
WindControlParameters windParameters = new WindControlParameters(12, start.getBearingGreatCircle(end).reverse().getDegrees());
|
||||
// RectangularBoundary new_bd = new RectangularBoundary(start, end, 0.1);
|
||||
// Speed knotSpeed = new KnotSpeedImpl(8);
|
||||
WindControlParameters windParameters = new WindControlParameters(12, start.getBearingGreatCircle(end).reverse()
|
||||
.getDegrees());
|
||||
WindFieldGenerator wf = new WindFieldGeneratorOscillationImpl(bd, windParameters);
|
||||
wf.setPositionGrid(positions);
|
||||
Date startDate = new Date(0);
|
||||
TimePoint startTime = new MillisecondsTimePoint(startDate.getTime());
|
||||
Duration timeStep = new MillisecondsDurationImpl(20000);
|
||||
wf.generate(startTime, null, timeStep);
|
||||
SimulationParameters param = new SimulationParametersImpl(course, pd, wf, SailingSimulatorConstants.ModeFreestyle, true, true);
|
||||
SimulationParameters param = new SimulationParametersImpl(course, pd, wf, null,
|
||||
SailingSimulatorConstants.ModeFreestyle, true, true);
|
||||
|
||||
/*param.setProperty("Heuristic.targetTolerance[double]", 0.05);
|
||||
param.setProperty("Heuristic.timeResolution[long]", 30000.0);
|
||||
param.setProperty("Djikstra.gridv[int]", 10.0);
|
||||
param.setProperty("Djikstra.gridh[int]", 100.0);*/
|
||||
/*
|
||||
* param.setProperty("Heuristic.targetTolerance[double]", 0.05);
|
||||
* param.setProperty("Heuristic.timeResolution[long]", 30000.0); param.setProperty("Djikstra.gridv[int]", 10.0);
|
||||
* param.setProperty("Djikstra.gridh[int]", 100.0);
|
||||
*/
|
||||
|
||||
PathGeneratorTreeGrow treeGrow = new PathGeneratorTreeGrow(param);
|
||||
|
||||
Path path = treeGrow.getPath();
|
||||
|
||||
//System.out.println("tree-grow path points: "+path.getPathPoints().size());
|
||||
// System.out.println("tree-grow path points: "+path.getPathPoints().size());
|
||||
Assert.assertNotNull(path.getPathPoints());
|
||||
|
||||
//for(TimedPositionWithSpeed pos : path.getPathPoints()) {
|
||||
// System.out.println(""+pos.getPosition().getLatDeg()+", "+pos.getPosition().getLngDeg());
|
||||
//}
|
||||
|
||||
// for(TimedPositionWithSpeed pos : path.getPathPoints()) {
|
||||
// System.out.println(""+pos.getPosition().getLatDeg()+", "+pos.getPosition().getLngDeg());
|
||||
// }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+12
-9
@@ -41,11 +41,12 @@ public class PathGenerator1TurnerEval {
|
||||
public static void main(String[] args) throws IOException {
|
||||
System.out.println("Collection of test methods for evaluating path segments.");
|
||||
}
|
||||
|
||||
|
||||
public void initialize() throws IOException, ClassNotFoundException {
|
||||
|
||||
this._polarDiagram = new PolarDiagramCSV(POLAR_DIAGRAM_49_STG_CSV_FILE_PATH);
|
||||
this._simulationParameters = new SimulationParametersImpl(null, this._polarDiagram, null, SailingSimulatorConstants.ModeMeasured, true, true);
|
||||
this._simulationParameters = new SimulationParametersImpl(null, this._polarDiagram, null, null,
|
||||
SailingSimulatorConstants.ModeMeasured, true, true);
|
||||
this._pathGenerator = new PathGenerator1Turner(this._simulationParameters);
|
||||
|
||||
this._windField = readWindFieldGeneratorFromExternalFile("windField.dat");
|
||||
@@ -60,8 +61,8 @@ public class PathGenerator1TurnerEval {
|
||||
int stepMax = 300;
|
||||
long timeStep = 6666;
|
||||
|
||||
TimedPositionWithSpeed result = this._pathGenerator.get1Turner(this._windField, this._polarDiagram, start, end, startTime, leftSide,
|
||||
stepMax, timeStep);
|
||||
TimedPositionWithSpeed result = this._pathGenerator.get1Turner(this._windField, this._polarDiagram, start, end,
|
||||
startTime, leftSide, stepMax, timeStep);
|
||||
|
||||
Assert.assertNotNull(result);
|
||||
Assert.assertNotNull(result.getPosition());
|
||||
@@ -85,8 +86,8 @@ public class PathGenerator1TurnerEval {
|
||||
int stepMax = 300;
|
||||
long timeStep = 1000;
|
||||
|
||||
TimedPositionWithSpeed result = this._pathGenerator.get1Turner(this._windField, this._polarDiagram, start, end, startTime, leftSide,
|
||||
stepMax, timeStep);
|
||||
TimedPositionWithSpeed result = this._pathGenerator.get1Turner(this._windField, this._polarDiagram, start, end,
|
||||
startTime, leftSide, stepMax, timeStep);
|
||||
|
||||
Assert.assertNotNull(result);
|
||||
Assert.assertNotNull(result.getPosition());
|
||||
@@ -112,7 +113,8 @@ public class PathGenerator1TurnerEval {
|
||||
int stepMax = 300;
|
||||
long timeStep = 1000;
|
||||
|
||||
TimedPositionWithSpeed result = this._pathGenerator.get1Turner(this._windField, this._polarDiagram, end, start, startTime, leftSide, stepMax, timeStep);
|
||||
TimedPositionWithSpeed result = this._pathGenerator.get1Turner(this._windField, this._polarDiagram, end, start,
|
||||
startTime, leftSide, stepMax, timeStep);
|
||||
|
||||
Assert.assertNotNull(result);
|
||||
Assert.assertNotNull(result.getPosition());
|
||||
@@ -143,7 +145,8 @@ public class PathGenerator1TurnerEval {
|
||||
file.close();
|
||||
}
|
||||
} catch (final ClassNotFoundException ex) {
|
||||
System.err.println("[ERROR][PathGenerator1Turner][readFromExternalFile][ClassNotFoundException] " + ex.getMessage());
|
||||
System.err.println("[ERROR][PathGenerator1Turner][readFromExternalFile][ClassNotFoundException] "
|
||||
+ ex.getMessage());
|
||||
result = null;
|
||||
} catch (final IOException ex) {
|
||||
System.err.println("[ERROR][PathGenerator1Turner][readFromExternalFile][IOException] " + ex.getMessage());
|
||||
@@ -152,7 +155,7 @@ public class PathGenerator1TurnerEval {
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
private File getFile(String fileName) {
|
||||
return new File(RESOURCES + fileName);
|
||||
}
|
||||
|
||||
+4
-8
@@ -1,13 +1,12 @@
|
||||
package com.sap.sailing.simulator;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.simulator.windfield.WindFieldGenerator;
|
||||
import com.sap.sse.common.Duration;
|
||||
|
||||
public interface SimulationParameters {
|
||||
|
||||
char getMode();
|
||||
|
||||
void setCourse(List<Position> course);
|
||||
@@ -18,14 +17,11 @@ public interface SimulationParameters {
|
||||
|
||||
WindFieldGenerator getWindField();
|
||||
|
||||
Duration getSimuStep();
|
||||
|
||||
Grid getGrid();
|
||||
|
||||
Map<String,Double> getSettings();
|
||||
|
||||
void setProperty(String name, Double value);
|
||||
|
||||
Double getProperty(String name);
|
||||
|
||||
boolean showOmniscient();
|
||||
|
||||
boolean showOpportunist();
|
||||
}
|
||||
|
||||
+3
-4
@@ -34,8 +34,7 @@ public class PathGeneratorDijkstra extends PathGeneratorBase {
|
||||
public Path getPath() {
|
||||
|
||||
// retrieve simulation parameters
|
||||
Grid boundary = new RectangularGrid(this.parameters.getCourse().get(0), this.parameters
|
||||
.getCourse().get(1));// simulationParameters.getBoundaries();
|
||||
Grid boundary = new RectangularGrid(this.parameters.getCourse().get(0), this.parameters.getCourse().get(1));// simulationParameters.getBoundaries();
|
||||
WindFieldGenerator windField = this.parameters.getWindField();
|
||||
PolarDiagram polarDiagram = this.parameters.getBoatPolarDiagram();
|
||||
Position start = this.parameters.getCourse().get(0);
|
||||
@@ -46,8 +45,8 @@ public class PathGeneratorDijkstra extends PathGeneratorBase {
|
||||
LinkedList<TimedPositionWithSpeed> lst = new LinkedList<TimedPositionWithSpeed>();
|
||||
|
||||
// initiate grid
|
||||
int gridv = this.parameters.getProperty("Djikstra.gridv[int]").intValue(); // number of vertical grid steps
|
||||
int gridh = this.parameters.getProperty("Djikstra.gridh[int]").intValue(); // number of horizontal grid
|
||||
int gridv = 10; // number of vertical grid steps
|
||||
int gridh = 100; // number of horizontal grid
|
||||
// steps
|
||||
Position[][] sailGrid = boundary.generatePositions(gridh, gridv, 0, 0);
|
||||
|
||||
|
||||
+155
-131
@@ -86,7 +86,7 @@ public class PathGeneratorTreeGrow extends PathGeneratorBase {
|
||||
return 0;
|
||||
} else {
|
||||
return (p1.hrz < p2.hrz ? -1 : +1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -95,16 +95,16 @@ public class PathGeneratorTreeGrow extends PathGeneratorBase {
|
||||
PathCandidate getBestCand() {
|
||||
return this.bestCand;
|
||||
}
|
||||
|
||||
long getUsedTimeStep() {
|
||||
return this.usedTimeStep;
|
||||
}
|
||||
|
||||
long getUsedTimeStep() {
|
||||
return this.usedTimeStep;
|
||||
}
|
||||
|
||||
// generate step in one of the possible directions
|
||||
// default: L - left, R - right
|
||||
// extended: M - wide left, S - wide right
|
||||
TimedPosition getStep(TimedPosition pos, Wind posWind, long timeStep, long turnLoss, boolean sameBaseDirection, char nextDirection) {
|
||||
TimedPosition getStep(TimedPosition pos, Wind posWind, long timeStep, long turnLoss, boolean sameBaseDirection,
|
||||
char nextDirection) {
|
||||
|
||||
double offDeg = 3.0;
|
||||
TimePoint curTime = pos.getTimePoint();
|
||||
@@ -117,40 +117,40 @@ public class PathGeneratorTreeGrow extends PathGeneratorBase {
|
||||
Bearing travelBearing = null;
|
||||
Bearing tmpBearing = null;
|
||||
if (nextDirection == 'L') {
|
||||
if (this.upwindLeg) {
|
||||
travelBearing = pd.optimalDirectionsUpwind()[0];
|
||||
} else {
|
||||
travelBearing = pd.optimalDirectionsDownwind()[0];
|
||||
}
|
||||
if (this.upwindLeg) {
|
||||
travelBearing = pd.optimalDirectionsUpwind()[0];
|
||||
} else {
|
||||
travelBearing = pd.optimalDirectionsDownwind()[0];
|
||||
}
|
||||
} else if (nextDirection == 'R') {
|
||||
if (this.upwindLeg) {
|
||||
travelBearing = pd.optimalDirectionsUpwind()[1];
|
||||
} else {
|
||||
travelBearing = pd.optimalDirectionsDownwind()[1];
|
||||
}
|
||||
if (this.upwindLeg) {
|
||||
travelBearing = pd.optimalDirectionsUpwind()[1];
|
||||
} else {
|
||||
travelBearing = pd.optimalDirectionsDownwind()[1];
|
||||
}
|
||||
} else if (nextDirection == 'M') {
|
||||
if (this.upwindLeg) {
|
||||
if (this.upwindLeg) {
|
||||
tmpBearing = pd.optimalDirectionsUpwind()[0];
|
||||
travelBearing = tmpBearing.add(new DegreeBearingImpl(-offDeg));
|
||||
} else {
|
||||
} else {
|
||||
tmpBearing = pd.optimalDirectionsDownwind()[0];
|
||||
travelBearing = tmpBearing.add(new DegreeBearingImpl(-offDeg));
|
||||
}
|
||||
}
|
||||
} else if (nextDirection == 'S') {
|
||||
if (this.upwindLeg) {
|
||||
tmpBearing = pd.optimalDirectionsUpwind()[1];
|
||||
travelBearing = tmpBearing.add(new DegreeBearingImpl(+offDeg));
|
||||
} else {
|
||||
tmpBearing = pd.optimalDirectionsDownwind()[1];
|
||||
travelBearing = tmpBearing.add(new DegreeBearingImpl(+offDeg));
|
||||
}
|
||||
if (this.upwindLeg) {
|
||||
tmpBearing = pd.optimalDirectionsUpwind()[1];
|
||||
travelBearing = tmpBearing.add(new DegreeBearingImpl(+offDeg));
|
||||
} else {
|
||||
tmpBearing = pd.optimalDirectionsDownwind()[1];
|
||||
travelBearing = tmpBearing.add(new DegreeBearingImpl(+offDeg));
|
||||
}
|
||||
}
|
||||
|
||||
// determine beat-speed left and right
|
||||
SpeedWithBearing travelSpeed = pd.getSpeedAtBearing(travelBearing);
|
||||
|
||||
TimePoint travelTime;
|
||||
TimePoint nextTime = new MillisecondsTimePoint(curTime.asMillis()+timeStep);
|
||||
TimePoint nextTime = new MillisecondsTimePoint(curTime.asMillis() + timeStep);
|
||||
if (sameBaseDirection) {
|
||||
travelTime = nextTime;
|
||||
} else {
|
||||
@@ -163,13 +163,14 @@ public class PathGeneratorTreeGrow extends PathGeneratorBase {
|
||||
|
||||
// check whether nextDirection is same base direction as previous direction, i.e. no turn
|
||||
boolean isSameDirection(char prevDirection, char nextDirection) {
|
||||
return ((nextDirection == prevDirection)||(prevDirection == '0'));
|
||||
return ((nextDirection == prevDirection) || (prevDirection == '0'));
|
||||
}
|
||||
|
||||
// get path candidate measuring height towards (local, current-apparent) wind
|
||||
PathCandidate getPathCandWind(PathCandidate path, char nextDirection, long timeStep, long turnLoss, Position posStart, Position posEnd, double tgtHeight) {
|
||||
PathCandidate getPathCandWind(PathCandidate path, char nextDirection, long timeStep, long turnLoss,
|
||||
Position posStart, Position posEnd, double tgtHeight) {
|
||||
|
||||
char prevDirection = path.path.charAt(path.path.length()-1);
|
||||
char prevDirection = path.path.charAt(path.path.length() - 1);
|
||||
boolean sameBaseDirection = this.isSameDirection(prevDirection, nextDirection);
|
||||
|
||||
int turnCount = path.trn;
|
||||
@@ -179,7 +180,7 @@ public class PathGeneratorTreeGrow extends PathGeneratorBase {
|
||||
|
||||
// calculate next path position (taking turn-loss into account)
|
||||
TimedPosition pathPos = this.getStep(path.pos, path.wind, timeStep, turnLoss, sameBaseDirection, nextDirection);
|
||||
|
||||
|
||||
// determine apparent wind at next path position & time
|
||||
Wind posWind = this.parameters.getWindField().getWind(pathPos);
|
||||
PolarDiagram pd = this.parameters.getBoatPolarDiagram();
|
||||
@@ -196,7 +197,7 @@ public class PathGeneratorTreeGrow extends PathGeneratorBase {
|
||||
if (Math.abs(bearHeightSide) > 170.0) {
|
||||
vrtSide = (this.upwindLeg ? +1.0 : -1.0);
|
||||
}
|
||||
double vrtDist = vrtSide*Math.round(posHeight.getDistance(posEnd).getMeters()*1000.0)/1000.0;
|
||||
double vrtDist = vrtSide * Math.round(posHeight.getDistance(posEnd).getMeters() * 1000.0) / 1000.0;
|
||||
|
||||
// scale last step to exactly reach height of posEnd (in reference to appWind) and adjust time correspondingly
|
||||
boolean reachedEnd = false;
|
||||
@@ -205,26 +206,28 @@ public class PathGeneratorTreeGrow extends PathGeneratorBase {
|
||||
Position prevPos = path.pos.getPosition();
|
||||
TimePoint prevTime = path.pos.getTimePoint();
|
||||
double heightFrac = path.vrt / (path.vrt - vrtDist);
|
||||
Position newPos = prevPos.translateGreatCircle(prevPos.getBearingGreatCircle(pathPos.getPosition()), prevPos.getDistance(pathPos.getPosition()).scale(heightFrac));
|
||||
long newTimeMillis = Math.round((prevTime.asMillis() + (pathPos.getTimePoint().asMillis() - prevTime.asMillis()) * heightFrac)/1000.0)*1000;
|
||||
Position newPos = prevPos.translateGreatCircle(prevPos.getBearingGreatCircle(pathPos.getPosition()),
|
||||
prevPos.getDistance(pathPos.getPosition()).scale(heightFrac));
|
||||
long newTimeMillis = Math.round((prevTime.asMillis() + (pathPos.getTimePoint().asMillis() - prevTime
|
||||
.asMillis()) * heightFrac) / 1000.0) * 1000;
|
||||
TimePoint newTime = new MillisecondsTimePoint(newTimeMillis);
|
||||
pathPos = new TimedPositionImpl(newTime, newPos);
|
||||
reachedEnd = true;
|
||||
}
|
||||
|
||||
// calculate horizontal side: left or right in reference to race course
|
||||
|
||||
// calculate horizontal side: left or right in reference to race course
|
||||
double posSide = 1;
|
||||
Bearing posBear = posStart.getBearingGreatCircle(pathPos.getPosition());
|
||||
Bearing bearVrt = posStart.getBearingGreatCircle(posEnd);
|
||||
double posBearDiff = bearVrt.getDifferenceTo(posBear).getDegrees();
|
||||
if ((posBearDiff < 0.0)||(posBearDiff > 180.0)) {
|
||||
if ((posBearDiff < 0.0) || (posBearDiff > 180.0)) {
|
||||
posSide = -1;
|
||||
} else if ((posBearDiff == 0.0)||(posBearDiff == 180.0)) {
|
||||
} else if ((posBearDiff == 0.0) || (posBearDiff == 180.0)) {
|
||||
posSide = 0;
|
||||
}
|
||||
// calculate horizontal distance as distance of height-position to current position
|
||||
Position posHeightTrgt = pathPos.getPosition().projectToLineThrough(posStart, bearVrt);
|
||||
double hrzDist = Math.round(posSide*posHeightTrgt.getDistance(pathPos.getPosition()).getMeters()*1000.0)/1000.0;
|
||||
double hrzDist = Math.round(posSide * posHeightTrgt.getDistance(pathPos.getPosition()).getMeters() * 1000.0) / 1000.0;
|
||||
|
||||
// extend path-string by step-direction
|
||||
String pathStr = path.path + nextDirection;
|
||||
@@ -232,22 +235,22 @@ public class PathGeneratorTreeGrow extends PathGeneratorBase {
|
||||
return (new PathCandidate(pathPos, reachedEnd, vrtDist, hrzDist, turnCount, pathStr, nextDirection, posWind));
|
||||
}
|
||||
|
||||
|
||||
// generate path candidates based on beat angles
|
||||
List<PathCandidate> getPathCandsBeatWind(PathCandidate path, long timeStep, long turnLoss, Position posStart, Position posEnd, double tgtHeight) {
|
||||
List<PathCandidate> getPathCandsBeatWind(PathCandidate path, long timeStep, long turnLoss, Position posStart,
|
||||
Position posEnd, double tgtHeight) {
|
||||
|
||||
List<PathCandidate> result = new ArrayList<PathCandidate>();
|
||||
PathCandidate newPathCand;
|
||||
|
||||
if (this.maxTurns > 0) {
|
||||
|
||||
char prevDirection = path.path.charAt(path.path.length()-1);
|
||||
if ((path.trn < this.maxTurns)||(this.isSameDirection(prevDirection, 'L'))) {
|
||||
char prevDirection = path.path.charAt(path.path.length() - 1);
|
||||
if ((path.trn < this.maxTurns) || (this.isSameDirection(prevDirection, 'L'))) {
|
||||
newPathCand = getPathCandWind(path, 'L', timeStep, turnLoss, posStart, posEnd, tgtHeight);
|
||||
result.add(newPathCand);
|
||||
}
|
||||
|
||||
if ((path.trn < this.maxTurns)||(this.isSameDirection(prevDirection, 'R'))) {
|
||||
if ((path.trn < this.maxTurns) || (this.isSameDirection(prevDirection, 'R'))) {
|
||||
newPathCand = getPathCandWind(path, 'R', timeStep, turnLoss, posStart, posEnd, tgtHeight);
|
||||
result.add(newPathCand);
|
||||
}
|
||||
@@ -267,17 +270,18 @@ public class PathGeneratorTreeGrow extends PathGeneratorBase {
|
||||
return result;
|
||||
}
|
||||
|
||||
Util.Pair<List<PathCandidate>,List<PathCandidate>> generateCandidate(List<PathCandidate> oldPaths, long timeStep, long turnLoss, Position posStart, Position posMiddle, Position posEnd, double tgtHeight) {
|
||||
Util.Pair<List<PathCandidate>, List<PathCandidate>> generateCandidate(List<PathCandidate> oldPaths, long timeStep,
|
||||
long turnLoss, Position posStart, Position posMiddle, Position posEnd, double tgtHeight) {
|
||||
|
||||
List<PathCandidate> newPathCands;
|
||||
List<PathCandidate> leftPaths = new ArrayList<PathCandidate>();
|
||||
List<PathCandidate> rightPaths = new ArrayList<PathCandidate>();
|
||||
for(PathCandidate curPath : oldPaths) {
|
||||
for (PathCandidate curPath : oldPaths) {
|
||||
|
||||
if (curPath.reached) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
newPathCands = this.getPathCandsBeatWind(curPath, timeStep, turnLoss, posStart, posEnd, tgtHeight);
|
||||
for (PathCandidate curNewPath : newPathCands) {
|
||||
// check whether path is *outside* regatta-area
|
||||
@@ -296,11 +300,11 @@ public class PathGeneratorTreeGrow extends PathGeneratorBase {
|
||||
|
||||
}
|
||||
|
||||
Util.Pair<List<PathCandidate>,List<PathCandidate>> newPaths = new Util.Pair<List<PathCandidate>,List<PathCandidate>>(leftPaths, rightPaths);
|
||||
Util.Pair<List<PathCandidate>, List<PathCandidate>> newPaths = new Util.Pair<List<PathCandidate>, List<PathCandidate>>(
|
||||
leftPaths, rightPaths);
|
||||
return newPaths;
|
||||
}
|
||||
|
||||
|
||||
List<PathCandidate> filterCandidates(List<PathCandidate> allCands, double hrzBinWidth) {
|
||||
|
||||
boolean[] filterMap = new boolean[allCands.size()];
|
||||
@@ -314,20 +318,20 @@ public class PathGeneratorTreeGrow extends PathGeneratorBase {
|
||||
int idxR = 0;
|
||||
|
||||
// for each candidate, check the neighborhoods and identify bad candidates
|
||||
for(int idx = 0; idx < allCands.size(); idx++) {
|
||||
for (int idx = 0; idx < allCands.size(); idx++) {
|
||||
|
||||
// current horizontal distance
|
||||
double hrzDist = allCands.get(idx).hrz;
|
||||
|
||||
// align left index
|
||||
while(Math.abs(hrzDist - allCands.get(idxL).hrz) > hrzBinWidth) {
|
||||
while (Math.abs(hrzDist - allCands.get(idxL).hrz) > hrzBinWidth) {
|
||||
idxL++;
|
||||
}
|
||||
|
||||
// align right index
|
||||
boolean finished = false;
|
||||
while(!finished && (idxR < (allCands.size()-1))) {
|
||||
if (Math.abs(hrzDist - allCands.get(idxR+1).hrz) <= hrzBinWidth) {
|
||||
while (!finished && (idxR < (allCands.size() - 1))) {
|
||||
if (Math.abs(hrzDist - allCands.get(idxR + 1).hrz) <= hrzBinWidth) {
|
||||
idxR++;
|
||||
} else {
|
||||
finished = true;
|
||||
@@ -344,7 +348,7 @@ public class PathGeneratorTreeGrow extends PathGeneratorBase {
|
||||
|
||||
// evaluate remainder of neighborhood
|
||||
if (idxL < idxR) {
|
||||
for(int jdx = (idxL+1); jdx <= idxR; jdx++) {
|
||||
for (int jdx = (idxL + 1); jdx <= idxR; jdx++) {
|
||||
if (allCands.get(jdx).vrt > vrtMax) {
|
||||
// reset previous max candidate
|
||||
filterMap[vrtIdx] = true;
|
||||
@@ -364,7 +368,7 @@ public class PathGeneratorTreeGrow extends PathGeneratorBase {
|
||||
|
||||
// collect all good candidates (i.e. filterMap == false)
|
||||
List<PathCandidate> filterCands = new ArrayList<PathCandidate>();
|
||||
for(int idx=0; idx < allCands.size(); idx++) {
|
||||
for (int idx = 0; idx < allCands.size(); idx++) {
|
||||
if (!filterMap[idx]) {
|
||||
filterCands.add(allCands.get(idx));
|
||||
}
|
||||
@@ -374,11 +378,10 @@ public class PathGeneratorTreeGrow extends PathGeneratorBase {
|
||||
return filterCands;
|
||||
}
|
||||
|
||||
|
||||
List<PathCandidate> filterIsochrone(List<PathCandidate> allCands, double hrzBinWidth) {
|
||||
|
||||
boolean[] filterMap = new boolean[allCands.size()];
|
||||
for(int idx = 0; idx < allCands.size(); idx++) {
|
||||
for (int idx = 0; idx < allCands.size(); idx++) {
|
||||
filterMap[idx] = true;
|
||||
}
|
||||
|
||||
@@ -391,20 +394,20 @@ public class PathGeneratorTreeGrow extends PathGeneratorBase {
|
||||
int idxR = 0;
|
||||
|
||||
// for each candidate, check the neighborhoods and identify bad candidates
|
||||
for(int idx = 0; idx < allCands.size(); idx++) {
|
||||
for (int idx = 0; idx < allCands.size(); idx++) {
|
||||
|
||||
// current horizontal distance
|
||||
double hrzDist = allCands.get(idx).hrz;
|
||||
|
||||
// align left index
|
||||
while(Math.abs(hrzDist - allCands.get(idxL).hrz) > hrzBinWidth) {
|
||||
while (Math.abs(hrzDist - allCands.get(idxL).hrz) > hrzBinWidth) {
|
||||
idxL++;
|
||||
}
|
||||
|
||||
// align right index
|
||||
boolean finished = false;
|
||||
while(!finished && (idxR < (allCands.size()-1))) {
|
||||
if (Math.abs(hrzDist - allCands.get(idxR+1).hrz) <= hrzBinWidth) {
|
||||
while (!finished && (idxR < (allCands.size() - 1))) {
|
||||
if (Math.abs(hrzDist - allCands.get(idxR + 1).hrz) <= hrzBinWidth) {
|
||||
idxR++;
|
||||
} else {
|
||||
finished = true;
|
||||
@@ -421,7 +424,7 @@ public class PathGeneratorTreeGrow extends PathGeneratorBase {
|
||||
|
||||
// evaluate remainder of neighborhood
|
||||
if (idxL < idxR) {
|
||||
for(int jdx = (idxL+1); jdx <= idxR; jdx++) {
|
||||
for (int jdx = (idxL + 1); jdx <= idxR; jdx++) {
|
||||
if (allCands.get(jdx).vrt > vrtMax) {
|
||||
// keep max height
|
||||
vrtMax = allCands.get(jdx).vrt;
|
||||
@@ -435,7 +438,7 @@ public class PathGeneratorTreeGrow extends PathGeneratorBase {
|
||||
}
|
||||
}
|
||||
|
||||
for(Integer jdx : vrtIdx) {
|
||||
for (Integer jdx : vrtIdx) {
|
||||
filterMap[jdx] = false;
|
||||
}
|
||||
|
||||
@@ -443,7 +446,7 @@ public class PathGeneratorTreeGrow extends PathGeneratorBase {
|
||||
|
||||
// collect all good candidates (i.e. filterMap == false)
|
||||
List<PathCandidate> filterCands = new ArrayList<PathCandidate>();
|
||||
for(int idx=0; idx < allCands.size(); idx++) {
|
||||
for (int idx = 0; idx < allCands.size(); idx++) {
|
||||
if (!filterMap[idx]) {
|
||||
filterCands.add(allCands.get(idx));
|
||||
}
|
||||
@@ -457,13 +460,13 @@ public class PathGeneratorTreeGrow extends PathGeneratorBase {
|
||||
public Path getPath() {
|
||||
WindFieldGenerator wf = this.parameters.getWindField();
|
||||
PolarDiagram pd = this.parameters.getBoatPolarDiagram();
|
||||
|
||||
|
||||
Position startPos = this.parameters.getCourse().get(0);
|
||||
Position endPos = this.parameters.getCourse().get(1);
|
||||
|
||||
|
||||
// test downwind: exchange start and end
|
||||
//Position startPos = this.parameters.getCourse().get(1);
|
||||
//Position endPos = this.parameters.getCourse().get(0);
|
||||
// Position startPos = this.parameters.getCourse().get(1);
|
||||
// Position endPos = this.parameters.getCourse().get(0);
|
||||
|
||||
TimePoint startTime = wf.getStartTime();// new MillisecondsTimePoint(0);
|
||||
List<TimedPositionWithSpeed> path = new ArrayList<TimedPositionWithSpeed>();
|
||||
@@ -478,41 +481,48 @@ public class PathGeneratorTreeGrow extends PathGeneratorBase {
|
||||
logger.fine("wndStart speed:" + wndStart.getKnots() + " angle:" + wndStart.getBearing().getDegrees());
|
||||
pd.setWind(wndStart);
|
||||
Bearing bearVrt = startPos.getBearingGreatCircle(endPos);
|
||||
//Bearing bearHrz = bearVrt.add(new DegreeBearingImpl(90.0));
|
||||
// Bearing bearHrz = bearVrt.add(new DegreeBearingImpl(90.0));
|
||||
Position middlePos = startPos.translateGreatCircle(bearVrt, distStartEnd.scale(0.5));
|
||||
|
||||
|
||||
Bearing bearRCWind = wndStart.getBearing().getDifferenceTo(bearVrt);
|
||||
String legType = "downwind";
|
||||
this.upwindLeg = false;
|
||||
|
||||
if ((Math.abs(bearRCWind.getDegrees()) > 90.0)&&(Math.abs(bearRCWind.getDegrees()) < 270.0)) {
|
||||
legType = "upwind";
|
||||
|
||||
if ((Math.abs(bearRCWind.getDegrees()) > 90.0) && (Math.abs(bearRCWind.getDegrees()) < 270.0)) {
|
||||
legType = "upwind";
|
||||
this.upwindLeg = true;
|
||||
}
|
||||
|
||||
|
||||
if (debugMsgOn) {
|
||||
System.out.println("start : "+startPos.getLatDeg()+", "+startPos.getLngDeg());
|
||||
System.out.println("middle: "+middlePos.getLatDeg()+", "+middlePos.getLngDeg());
|
||||
System.out.println("end : "+endPos.getLatDeg()+", "+endPos.getLngDeg());
|
||||
System.out.println("start : " + startPos.getLatDeg() + ", " + startPos.getLngDeg());
|
||||
System.out.println("middle: " + middlePos.getLatDeg() + ", " + middlePos.getLngDeg());
|
||||
System.out.println("end : " + endPos.getLatDeg() + ", " + endPos.getLngDeg());
|
||||
}
|
||||
logger.info("Leg Direction: "+legType);
|
||||
logger.info("Leg Direction: " + legType);
|
||||
|
||||
long turnLoss = pd.getTurnLoss(); // time lost when doing a turn
|
||||
if (!this.upwindLeg) {
|
||||
turnLoss = turnLoss / 2;
|
||||
turnLoss = turnLoss / 2;
|
||||
}
|
||||
logger.info("Turnloss :" + turnLoss);
|
||||
|
||||
this.usedTimeStep = turnLoss + 1000; // time-step larger than turn-loss is required (this may be removed by extended handling of turn-loss)
|
||||
if ((this.parameters.getSimuStep() != null) && (this.parameters.getSimuStep().asMillis() > turnLoss + 1000)) {
|
||||
this.usedTimeStep = this.parameters.getSimuStep().asMillis();
|
||||
} else {
|
||||
this.usedTimeStep = turnLoss + 1000; // time-step larger than turn-loss is required (this may be removed by
|
||||
// extended handling of turn-loss)
|
||||
}
|
||||
logger.info("Time step :" + usedTimeStep);
|
||||
|
||||
|
||||
// calculate initial position according to initPathStr
|
||||
PathCandidate initPath = new PathCandidate(new TimedPositionImpl(currentTime, currentPosition), false, 0.0, 0.0, 0, "0", '0', wndStart);
|
||||
if (initPathStr.length()>1) {
|
||||
PathCandidate initPath = new PathCandidate(new TimedPositionImpl(currentTime, currentPosition), false, 0.0,
|
||||
0.0, 0, "0", '0', wndStart);
|
||||
if (initPathStr.length() > 1) {
|
||||
char nextDirection = '0';
|
||||
for(int idx=1; idx<initPathStr.length(); idx++) {
|
||||
for (int idx = 1; idx < initPathStr.length(); idx++) {
|
||||
nextDirection = initPathStr.charAt(idx);
|
||||
PathCandidate newPathCand = getPathCandWind(initPath, nextDirection, usedTimeStep, turnLoss, startPos, endPos, distStartEndMeters);
|
||||
PathCandidate newPathCand = getPathCandWind(initPath, nextDirection, usedTimeStep, turnLoss, startPos,
|
||||
endPos, distStartEndMeters);
|
||||
initPath = newPathCand;
|
||||
}
|
||||
}
|
||||
@@ -520,36 +530,37 @@ public class PathGeneratorTreeGrow extends PathGeneratorBase {
|
||||
List<PathCandidate> trgPaths = new ArrayList<PathCandidate>();
|
||||
allPaths.add(initPath);
|
||||
|
||||
|
||||
TimedPosition tstPosition = this.getStep(new TimedPositionImpl(startTime, startPos), wndStart, usedTimeStep, turnLoss, true, 'L');
|
||||
TimedPosition tstPosition = this.getStep(new TimedPositionImpl(startTime, startPos), wndStart, usedTimeStep,
|
||||
turnLoss, true, 'L');
|
||||
double tstDist1 = startPos.getDistance(tstPosition.getPosition()).getMeters();
|
||||
tstPosition = this.getStep(new TimedPositionImpl(startTime, startPos), wndStart, usedTimeStep, turnLoss, true, 'R');
|
||||
tstPosition = this.getStep(new TimedPositionImpl(startTime, startPos), wndStart, usedTimeStep, turnLoss, true,
|
||||
'R');
|
||||
double tstDist2 = startPos.getDistance(tstPosition.getPosition()).getMeters();
|
||||
|
||||
double hrzBinSize = (tstDist1 + tstDist2)/6.0; // horizontal bin size in meters
|
||||
double hrzBinSize = (tstDist1 + tstDist2) / 6.0; // horizontal bin size in meters
|
||||
if (debugMsgOn) {
|
||||
System.out.println("Horizontal Bin Size: "+hrzBinSize);
|
||||
System.out.println("Horizontal Bin Size: " + hrzBinSize);
|
||||
}
|
||||
|
||||
boolean reachedEnd = false;
|
||||
int addSteps = 0;
|
||||
int finalSteps = 0; // maximum number of additional steps after first target-path found
|
||||
|
||||
while ((!reachedEnd)||(addSteps<finalSteps)) {
|
||||
while ((!reachedEnd) || (addSteps < finalSteps)) {
|
||||
|
||||
if (reachedEnd) {
|
||||
addSteps++;
|
||||
}
|
||||
|
||||
// generate new candidates (inside regatta-area)
|
||||
Util.Pair<List<PathCandidate>,List<PathCandidate>> newPaths = this.generateCandidate(allPaths, usedTimeStep, turnLoss, startPos, middlePos, endPos, distStartEndMeters);
|
||||
|
||||
Util.Pair<List<PathCandidate>, List<PathCandidate>> newPaths = this.generateCandidate(allPaths,
|
||||
usedTimeStep, turnLoss, startPos, middlePos, endPos, distStartEndMeters);
|
||||
|
||||
// select good candidates
|
||||
List<PathCandidate> leftPaths = this.filterCandidates(newPaths.getA(), hrzBinSize/2.0);
|
||||
List<PathCandidate> rightPaths = this.filterCandidates(newPaths.getB(), hrzBinSize/2.0);
|
||||
List<PathCandidate> leftPaths = this.filterCandidates(newPaths.getA(), hrzBinSize / 2.0);
|
||||
List<PathCandidate> rightPaths = this.filterCandidates(newPaths.getB(), hrzBinSize / 2.0);
|
||||
|
||||
List<PathCandidate> nextPaths = new ArrayList<PathCandidate> ();
|
||||
List<PathCandidate> nextPaths = new ArrayList<PathCandidate>();
|
||||
nextPaths.addAll(leftPaths);
|
||||
nextPaths.addAll(rightPaths);
|
||||
|
||||
@@ -557,11 +568,10 @@ public class PathGeneratorTreeGrow extends PathGeneratorBase {
|
||||
|
||||
if (this.gridStore) {
|
||||
|
||||
/*ArrayList<TimedPosition> isoChrone = new ArrayList<TimedPosition>();
|
||||
for(PathCand curCand : allPaths) {
|
||||
isoChrone.add(curCand.pos);
|
||||
}
|
||||
this.gridPositions.add(isoChrone);*/
|
||||
/*
|
||||
* ArrayList<TimedPosition> isoChrone = new ArrayList<TimedPosition>(); for(PathCand curCand : allPaths)
|
||||
* { isoChrone.add(curCand.pos); } this.gridPositions.add(isoChrone);
|
||||
*/
|
||||
|
||||
this.gridPositions.add(allPaths);
|
||||
|
||||
@@ -573,12 +583,13 @@ public class PathGeneratorTreeGrow extends PathGeneratorBase {
|
||||
// check if there are still paths in the regatta-area
|
||||
if (allPaths.size() > 0) {
|
||||
|
||||
for(PathCandidate curPath : allPaths) {
|
||||
for (PathCandidate curPath : allPaths) {
|
||||
// terminate path-search if paths are found that are close enough to target
|
||||
//if ((curPath.vrt > distStartEndMeters)) {
|
||||
// if ((curPath.vrt > distStartEndMeters)) {
|
||||
if (curPath.reached) {
|
||||
//logger.info("\ntPath: " + curPath.path + "\n Time: " + (Math.round((curPath.pos.getTimePoint().asMillis()-startTime.asMillis())/1000.0/60.0*10.0)/10.0)+", Height: "+curPath.vrt+" of "+(Math.round(startPos.getDistance(endPos).getMeters()*100.0)/100.0)+", Dist: "+curPath.hrz+"m ~ "+(Math.round(curPath.pos.getPosition().getDistance(endPos).getMeters()*100.0)/100.0)+"m");
|
||||
int curBin = (int)Math.round(Math.floor( (curPath.hrz + hrzBinSize/2.0) / hrzBinSize ));
|
||||
// logger.info("\ntPath: " + curPath.path + "\n Time: " +
|
||||
// (Math.round((curPath.pos.getTimePoint().asMillis()-startTime.asMillis())/1000.0/60.0*10.0)/10.0)+", Height: "+curPath.vrt+" of "+(Math.round(startPos.getDistance(endPos).getMeters()*100.0)/100.0)+", Dist: "+curPath.hrz+"m ~ "+(Math.round(curPath.pos.getPosition().getDistance(endPos).getMeters()*100.0)/100.0)+"m");
|
||||
int curBin = (int) Math.round(Math.floor((curPath.hrz + hrzBinSize / 2.0) / hrzBinSize));
|
||||
if ((Math.abs(curBin) <= 4)) {
|
||||
reachedEnd = true;
|
||||
trgPaths.add(curPath); // add path to list of target-paths
|
||||
@@ -595,18 +606,20 @@ public class PathGeneratorTreeGrow extends PathGeneratorBase {
|
||||
|
||||
if (this.gridStore) {
|
||||
|
||||
double distResolution = distStartEndMeters*0.01;
|
||||
double distResolution = distStartEndMeters * 0.01;
|
||||
BufferedWriter outputCSV;
|
||||
try {
|
||||
outputCSV = new BufferedWriter(new FileWriter(this.gridFile+"-grid.csv"));
|
||||
outputCSV = new BufferedWriter(new FileWriter(this.gridFile + "-grid.csv"));
|
||||
outputCSV.write("step; lat; lng; time; side; path; vrt\n");
|
||||
outputCSV.write("0; "+startPos.getLatDeg()+"; "+startPos.getLngDeg()+"; "+(startTime.asMillis()/1000)+"; 0; 0; "+(-distStartEndMeters)+"\n");
|
||||
outputCSV.write("0; "+endPos.getLatDeg()+"; "+endPos.getLngDeg()+"; "+(startTime.asMillis()/1000)+"; 0; 0; 0\n");
|
||||
outputCSV.write("0; " + startPos.getLatDeg() + "; " + startPos.getLngDeg() + "; "
|
||||
+ (startTime.asMillis() / 1000) + "; 0; 0; " + (-distStartEndMeters) + "\n");
|
||||
outputCSV.write("0; " + endPos.getLatDeg() + "; " + endPos.getLngDeg() + "; "
|
||||
+ (startTime.asMillis() / 1000) + "; 0; 0; 0\n");
|
||||
int stepCount = 0;
|
||||
for(List<PathCandidate> isoChrone : this.gridPositions) {
|
||||
for (List<PathCandidate> isoChrone : this.gridPositions) {
|
||||
stepCount++;
|
||||
PathCandidate prevPos = null;
|
||||
for(PathCandidate isoPos : isoChrone) {
|
||||
for (PathCandidate isoPos : isoChrone) {
|
||||
|
||||
if (prevPos != null) {
|
||||
if (prevPos.pos.getPosition().getDistance(isoPos.pos.getPosition()).getMeters() < distResolution) {
|
||||
@@ -614,8 +627,10 @@ public class PathGeneratorTreeGrow extends PathGeneratorBase {
|
||||
}
|
||||
}
|
||||
|
||||
String outStr = ""+stepCount+"; "+isoPos.pos.getPosition().getLatDeg()+"; "+isoPos.pos.getPosition().getLngDeg()+"; "+(isoPos.pos.getTimePoint().asMillis()/1000)+"; "+isoPos.sid;
|
||||
outStr += "; "+isoPos.path+"; "+isoPos.vrt;
|
||||
String outStr = "" + stepCount + "; " + isoPos.pos.getPosition().getLatDeg() + "; "
|
||||
+ isoPos.pos.getPosition().getLngDeg() + "; "
|
||||
+ (isoPos.pos.getTimePoint().asMillis() / 1000) + "; " + isoPos.sid;
|
||||
outStr += "; " + isoPos.path + "; " + isoPos.vrt;
|
||||
outStr += "\n";
|
||||
outputCSV.write(outStr);
|
||||
|
||||
@@ -628,15 +643,17 @@ public class PathGeneratorTreeGrow extends PathGeneratorBase {
|
||||
e.printStackTrace();
|
||||
}
|
||||
try {
|
||||
outputCSV = new BufferedWriter(new FileWriter(this.gridFile+"-isoc.csv"));
|
||||
outputCSV = new BufferedWriter(new FileWriter(this.gridFile + "-isoc.csv"));
|
||||
outputCSV.write("step; lat; lng; time; side; path; vrt\n");
|
||||
outputCSV.write("0; "+startPos.getLatDeg()+"; "+startPos.getLngDeg()+"; "+(startTime.asMillis()/1000)+"; 0; 0; "+(-distStartEndMeters)+"\n");
|
||||
outputCSV.write("0; "+endPos.getLatDeg()+"; "+endPos.getLngDeg()+"; "+(startTime.asMillis()/1000)+"; 0; 0; 0\n");
|
||||
outputCSV.write("0; " + startPos.getLatDeg() + "; " + startPos.getLngDeg() + "; "
|
||||
+ (startTime.asMillis() / 1000) + "; 0; 0; " + (-distStartEndMeters) + "\n");
|
||||
outputCSV.write("0; " + endPos.getLatDeg() + "; " + endPos.getLngDeg() + "; "
|
||||
+ (startTime.asMillis() / 1000) + "; 0; 0; 0\n");
|
||||
int stepCount = 0;
|
||||
for(List<PathCandidate> isoChrone : this.isocPositions) {
|
||||
for (List<PathCandidate> isoChrone : this.isocPositions) {
|
||||
stepCount++;
|
||||
PathCandidate prevPos = null;
|
||||
for(PathCandidate isoPos : isoChrone) {
|
||||
for (PathCandidate isoPos : isoChrone) {
|
||||
|
||||
if (prevPos != null) {
|
||||
if (prevPos.pos.getPosition().getDistance(isoPos.pos.getPosition()).getMeters() < distResolution) {
|
||||
@@ -644,8 +661,10 @@ public class PathGeneratorTreeGrow extends PathGeneratorBase {
|
||||
}
|
||||
}
|
||||
|
||||
String outStr = ""+stepCount+"; "+isoPos.pos.getPosition().getLatDeg()+"; "+isoPos.pos.getPosition().getLngDeg()+"; "+(isoPos.pos.getTimePoint().asMillis()/1000)+"; "+isoPos.sid;
|
||||
outStr += "; "+isoPos.path+"; "+isoPos.vrt;
|
||||
String outStr = "" + stepCount + "; " + isoPos.pos.getPosition().getLatDeg() + "; "
|
||||
+ isoPos.pos.getPosition().getLngDeg() + "; "
|
||||
+ (isoPos.pos.getTimePoint().asMillis() / 1000) + "; " + isoPos.sid;
|
||||
outStr += "; " + isoPos.path + "; " + isoPos.vrt;
|
||||
outStr += "\n";
|
||||
outputCSV.write(outStr);
|
||||
|
||||
@@ -660,10 +679,9 @@ public class PathGeneratorTreeGrow extends PathGeneratorBase {
|
||||
|
||||
}
|
||||
|
||||
|
||||
// if no target-paths were found, return empty path
|
||||
if (trgPaths.size() == 0) {
|
||||
//trgPaths = allPaths; // TODO: only for testing; remove lateron
|
||||
// trgPaths = allPaths; // TODO: only for testing; remove lateron
|
||||
TimedPositionWithSpeed curPosition = new TimedPositionWithSpeedImpl(startTime, startPos, null);
|
||||
path.add(curPosition);
|
||||
return new PathImpl(path, wf); // return empty path
|
||||
@@ -673,10 +691,14 @@ public class PathGeneratorTreeGrow extends PathGeneratorBase {
|
||||
Collections.sort(trgPaths);
|
||||
|
||||
// debug output
|
||||
for(PathCandidate curPath : trgPaths) {
|
||||
logger.info("\nPath: " + curPath.path + "\n Time: " + (curPath.pos.getTimePoint().asMillis()-startTime.asMillis()) +", Height: "+curPath.vrt+" of "+(Math.round(startPos.getDistance(endPos).getMeters()*100.0)/100.0)+", Dist: "+curPath.hrz+"m ~ "+(Math.round(curPath.pos.getPosition().getDistance(endPos).getMeters()*100.0)/100.0)+"m");
|
||||
//System.out.print(""+curPath.path+": "+curPath.pos.getTimePoint().asMillis()+", "+curPath.pos.getPosition().getLatDeg()+", "+curPath.pos.getPosition().getLngDeg()+", ");
|
||||
//System.out.println(" height:"+curPath.vrt+" of "+startPos.getDistance(endPos).getMeters()+", dist:"+curPath.hrz+" ~ "+curPath.pos.getPosition().getDistance(endPos));
|
||||
for (PathCandidate curPath : trgPaths) {
|
||||
logger.info("\nPath: " + curPath.path + "\n Time: "
|
||||
+ (curPath.pos.getTimePoint().asMillis() - startTime.asMillis()) + ", Height: " + curPath.vrt
|
||||
+ " of " + (Math.round(startPos.getDistance(endPos).getMeters() * 100.0) / 100.0) + ", Dist: "
|
||||
+ curPath.hrz + "m ~ "
|
||||
+ (Math.round(curPath.pos.getPosition().getDistance(endPos).getMeters() * 100.0) / 100.0) + "m");
|
||||
// System.out.print(""+curPath.path+": "+curPath.pos.getTimePoint().asMillis()+", "+curPath.pos.getPosition().getLatDeg()+", "+curPath.pos.getPosition().getLngDeg()+", ");
|
||||
// System.out.println(" height:"+curPath.vrt+" of "+startPos.getDistance(endPos).getMeters()+", dist:"+curPath.hrz+" ~ "+curPath.pos.getPosition().getDistance(endPos));
|
||||
}
|
||||
|
||||
//
|
||||
@@ -689,7 +711,7 @@ public class PathGeneratorTreeGrow extends PathGeneratorBase {
|
||||
TimedPositionWithSpeed curPosition = null;
|
||||
char nextDirection = '0';
|
||||
char prevDirection = '0';
|
||||
for(int step=0; step<(bestCand.path.length()-1); step++) {
|
||||
for (int step = 0; step < (bestCand.path.length() - 1); step++) {
|
||||
|
||||
nextDirection = bestCand.path.charAt(step);
|
||||
|
||||
@@ -702,10 +724,12 @@ public class PathGeneratorTreeGrow extends PathGeneratorBase {
|
||||
|
||||
boolean sameBaseDirection = this.isSameDirection(prevDirection, nextDirection);
|
||||
Wind curWind = wf.getWind(curPosition);
|
||||
TimedPosition newPosition = this.getStep(curPosition, curWind, usedTimeStep, turnLoss, sameBaseDirection, nextDirection);
|
||||
TimedPosition newPosition = this.getStep(curPosition, curWind, usedTimeStep, turnLoss,
|
||||
sameBaseDirection, nextDirection);
|
||||
if (newPosition.getTimePoint().asMillis() < endTime) {
|
||||
curPosition = new TimedPositionWithSpeedImpl(newPosition.getTimePoint(), newPosition.getPosition(), null);
|
||||
path.add(curPosition);
|
||||
curPosition = new TimedPositionWithSpeedImpl(newPosition.getTimePoint(), newPosition.getPosition(),
|
||||
null);
|
||||
path.add(curPosition);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -713,7 +737,7 @@ public class PathGeneratorTreeGrow extends PathGeneratorBase {
|
||||
}
|
||||
|
||||
// add final position (rescaled before to end on height of target)
|
||||
path.add(new TimedPositionWithSpeedImpl(bestCand.pos.getTimePoint(), bestCand.pos.getPosition(), null));
|
||||
path.add(new TimedPositionWithSpeedImpl(bestCand.pos.getTimePoint(), bestCand.pos.getPosition(), null));
|
||||
|
||||
return new PathImpl(path, wf);
|
||||
|
||||
|
||||
+56
-40
@@ -24,10 +24,11 @@ public class PolarDiagramGPS extends PolarDiagramBase {
|
||||
private static final long serialVersionUID = -9219705955440602679L;
|
||||
private final BoatClass boatClass;
|
||||
private final PolarDataService polarData;
|
||||
private double avgSpeed;
|
||||
|
||||
public PolarDiagramGPS(BoatClass boatClass, PolarDataService polarData) {
|
||||
this.boatClass = boatClass;
|
||||
this.polarData = polarData;
|
||||
this.boatClass = boatClass;
|
||||
this.polarData = polarData;
|
||||
|
||||
List<Speed> windSpeeds = new ArrayList<Speed>();
|
||||
List<Bearing> beatAngles = new ArrayList<Bearing>();
|
||||
@@ -49,45 +50,56 @@ public class PolarDiagramGPS extends PolarDiagramBase {
|
||||
// initialize beat-angles and -speeds
|
||||
SpeedWithBearing beatPort;
|
||||
SpeedWithBearing beatStar;
|
||||
int avgCount = 0;
|
||||
avgSpeed = 0;
|
||||
for (int i = 0; i < windSpeeds.size(); i++) {
|
||||
try {
|
||||
beatPort = this.polarData.getAverageSpeedWithBearing(this.boatClass, windSpeeds.get(i), LegType.UPWIND, Tack.PORT).getObject();
|
||||
beatStar = this.polarData.getAverageSpeedWithBearing(this.boatClass, windSpeeds.get(i), LegType.UPWIND, Tack.STARBOARD).getObject();
|
||||
} catch (NotEnoughDataHasBeenAddedException e) {
|
||||
beatPort = null;
|
||||
beatStar = null;
|
||||
}
|
||||
if (beatStar != null) {
|
||||
Bearing avgBeatAngle = new DegreeBearingImpl((beatStar.getBearing().getDegrees() + (360-beatPort.getBearing().getDegrees())%360)/2.0);
|
||||
beatAngles.add(avgBeatAngle);
|
||||
Speed avgBeatSpeed = new KnotSpeedImpl((beatStar.getKnots() + beatPort.getKnots())/2.0);
|
||||
beatSpeed.add(avgBeatSpeed);
|
||||
} else {
|
||||
beatAngles.add(null);
|
||||
beatSpeed.add(null);
|
||||
}
|
||||
try {
|
||||
beatPort = this.polarData.getAverageSpeedWithBearing(this.boatClass, windSpeeds.get(i), LegType.UPWIND,
|
||||
Tack.PORT).getObject();
|
||||
beatStar = this.polarData.getAverageSpeedWithBearing(this.boatClass, windSpeeds.get(i), LegType.UPWIND,
|
||||
Tack.STARBOARD).getObject();
|
||||
} catch (NotEnoughDataHasBeenAddedException e) {
|
||||
beatPort = null;
|
||||
beatStar = null;
|
||||
}
|
||||
if (beatStar != null) {
|
||||
Bearing avgBeatAngle = new DegreeBearingImpl((beatStar.getBearing().getDegrees() + (360 - beatPort
|
||||
.getBearing().getDegrees()) % 360) / 2.0);
|
||||
beatAngles.add(avgBeatAngle);
|
||||
Speed avgBeatSpeed = new KnotSpeedImpl((beatStar.getKnots() + beatPort.getKnots()) / 2.0);
|
||||
beatSpeed.add(avgBeatSpeed);
|
||||
avgSpeed += avgBeatSpeed.getKnots();
|
||||
avgCount++;
|
||||
} else {
|
||||
beatAngles.add(null);
|
||||
beatSpeed.add(null);
|
||||
}
|
||||
}
|
||||
avgSpeed /= avgCount;
|
||||
|
||||
// initialize jibe-angles and -speeds
|
||||
SpeedWithBearing jibePort;
|
||||
SpeedWithBearing jibeStar;
|
||||
for (int i = 0; i < windSpeeds.size(); i++) {
|
||||
try {
|
||||
jibePort = this.polarData.getAverageSpeedWithBearing(this.boatClass, windSpeeds.get(i), LegType.DOWNWIND, Tack.PORT).getObject();
|
||||
jibeStar = this.polarData.getAverageSpeedWithBearing(this.boatClass, windSpeeds.get(i), LegType.DOWNWIND, Tack.STARBOARD).getObject();
|
||||
} catch (NotEnoughDataHasBeenAddedException e) {
|
||||
jibePort = null;
|
||||
jibeStar = null;
|
||||
}
|
||||
if (jibeStar != null) {
|
||||
Bearing avgJibeAngle = new DegreeBearingImpl((jibeStar.getBearing().getDegrees() + (360-jibePort.getBearing().getDegrees())%360)/2.0);
|
||||
jibeAngles.add(avgJibeAngle);
|
||||
Speed avgJibeSpeed = new KnotSpeedImpl((jibeStar.getKnots() + jibePort.getKnots())/2.0);
|
||||
jibeSpeed.add(avgJibeSpeed);
|
||||
} else {
|
||||
jibeAngles.add(null);
|
||||
jibeSpeed.add(null);
|
||||
}
|
||||
try {
|
||||
jibePort = this.polarData.getAverageSpeedWithBearing(this.boatClass, windSpeeds.get(i),
|
||||
LegType.DOWNWIND, Tack.PORT).getObject();
|
||||
jibeStar = this.polarData.getAverageSpeedWithBearing(this.boatClass, windSpeeds.get(i),
|
||||
LegType.DOWNWIND, Tack.STARBOARD).getObject();
|
||||
} catch (NotEnoughDataHasBeenAddedException e) {
|
||||
jibePort = null;
|
||||
jibeStar = null;
|
||||
}
|
||||
if (jibeStar != null) {
|
||||
Bearing avgJibeAngle = new DegreeBearingImpl((jibeStar.getBearing().getDegrees() + (360 - jibePort
|
||||
.getBearing().getDegrees()) % 360) / 2.0);
|
||||
jibeAngles.add(avgJibeAngle);
|
||||
Speed avgJibeSpeed = new KnotSpeedImpl((jibeStar.getKnots() + jibePort.getKnots()) / 2.0);
|
||||
jibeSpeed.add(avgJibeSpeed);
|
||||
} else {
|
||||
jibeAngles.add(null);
|
||||
jibeSpeed.add(null);
|
||||
}
|
||||
}
|
||||
|
||||
NavigableMap<Speed, NavigableMap<Bearing, Speed>> mapSpeedTable = new TreeMap<Speed, NavigableMap<Bearing, Speed>>();
|
||||
@@ -103,8 +115,8 @@ public class PolarDiagramGPS extends PolarDiagramBase {
|
||||
for (int index = 0; index < windSpeeds.size(); index++) {
|
||||
windSpeed = windSpeeds.get(index);
|
||||
if (windSpeed.getKnots() == 0.0) {
|
||||
mapBeatSOG.put(new KnotSpeedImpl(0.0), new KnotSpeedImpl(0.0));
|
||||
mapJibeSOG.put(new KnotSpeedImpl(0.0), new KnotSpeedImpl(0.0));
|
||||
mapBeatSOG.put(new KnotSpeedImpl(0.0), new KnotSpeedImpl(0.0));
|
||||
mapJibeSOG.put(new KnotSpeedImpl(0.0), new KnotSpeedImpl(0.0));
|
||||
}
|
||||
speedTableLine = new TreeMap<Bearing, Speed>(bearingComparator);
|
||||
for (Entry<Bearing, List<Speed>> entry : speeds.entrySet()) {
|
||||
@@ -121,16 +133,16 @@ public class PolarDiagramGPS extends PolarDiagramBase {
|
||||
|
||||
mapSpeedTable.put(windSpeed, speedTableLine);
|
||||
if (beatAngles.get(index) != null) {
|
||||
mapBeatAngles.put(windSpeed, beatAngles.get(index));
|
||||
mapBeatAngles.put(windSpeed, beatAngles.get(index));
|
||||
}
|
||||
if (jibeAngles.get(index) != null) {
|
||||
mapJibeAngles.put(windSpeed, jibeAngles.get(index));
|
||||
mapJibeAngles.put(windSpeed, jibeAngles.get(index));
|
||||
}
|
||||
if (beatSpeed.get(index) != null) {
|
||||
mapBeatSOG.put(windSpeed, beatSpeed.get(index));
|
||||
mapBeatSOG.put(windSpeed, beatSpeed.get(index));
|
||||
}
|
||||
if (jibeSpeed.get(index) != null) {
|
||||
mapJibeSOG.put(windSpeed, jibeSpeed.get(index));
|
||||
mapJibeSOG.put(windSpeed, jibeSpeed.get(index));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,4 +166,8 @@ public class PolarDiagramGPS extends PolarDiagramBase {
|
||||
|
||||
}
|
||||
|
||||
public double getAvgSpeed() {
|
||||
return this.avgSpeed;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+14
-32
@@ -1,39 +1,31 @@
|
||||
package com.sap.sailing.simulator.impl;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.simulator.Grid;
|
||||
import com.sap.sailing.simulator.PolarDiagram;
|
||||
import com.sap.sailing.simulator.SimulationParameters;
|
||||
import com.sap.sailing.simulator.windfield.WindFieldGenerator;
|
||||
import com.sap.sse.common.Duration;
|
||||
|
||||
public class SimulationParametersImpl implements SimulationParameters {
|
||||
|
||||
private List<Position> course;
|
||||
private PolarDiagram polarDiagram;
|
||||
private WindFieldGenerator windField;
|
||||
private Map<String, Double> settings;
|
||||
private Duration simuStep;
|
||||
private char mode;
|
||||
private boolean showOmniscient;
|
||||
private boolean showOpportunist;
|
||||
|
||||
|
||||
public SimulationParametersImpl(List<Position> crs, PolarDiagram pd, WindFieldGenerator wf, char mode, boolean showOmniscient, boolean showOpportunist) {
|
||||
public SimulationParametersImpl(List<Position> crs, PolarDiagram pd, WindFieldGenerator wf, Duration simuStep,
|
||||
char mode, boolean showOmniscient, boolean showOpportunist) {
|
||||
this.course = crs;
|
||||
this.polarDiagram = pd;
|
||||
this.windField = wf;
|
||||
this.simuStep = simuStep;
|
||||
this.mode = mode;
|
||||
|
||||
this.settings = new HashMap<String, Double>();
|
||||
|
||||
this.settings.put("Heuristic.targetTolerance[double]", 0.05);
|
||||
this.settings.put("Heuristic.timeResolution[long]", 30000.0);
|
||||
this.settings.put("Djikstra.gridv[int]", 10.0);
|
||||
this.settings.put("Djikstra.gridh[int]", 100.0);
|
||||
|
||||
this.showOmniscient = showOmniscient;
|
||||
this.showOpportunist = showOpportunist;
|
||||
}
|
||||
@@ -63,34 +55,24 @@ public class SimulationParametersImpl implements SimulationParameters {
|
||||
return windField;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Duration getSimuStep() {
|
||||
return simuStep;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Grid getGrid() {
|
||||
return windField.getGrid();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Double> getSettings() {
|
||||
return settings;
|
||||
public boolean showOmniscient() {
|
||||
return showOmniscient;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProperty(String name, Double value) {
|
||||
settings.put(name, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getProperty(String name) {
|
||||
return settings.get(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean showOmniscient() {
|
||||
return showOmniscient;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean showOpportunist() {
|
||||
return showOpportunist;
|
||||
public boolean showOpportunist() {
|
||||
return showOpportunist;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user