Merge branch 'simulator' of ssh://git.wdf.sap.corp:29418/SAPSail/sapsailingcapture into simulator

This commit is contained in:
Alexandru Dimofte committed 2012-06-06 18:24:03 +03:00
commit 14befe0c99
18 files changed
+143 -61

No files matched your search

@@ -1,4 +1,5 @@
@import url(fontface.css);
@import url(CommonControls.css);
/** Add css rules here for your application. */
/*
@@ -247,4 +248,9 @@ input.magnifier {
.breadcrumbPanel-NextArrow {
display: none;
}
.replayPanel {
position: relative;
z-index: 10;
}
@@ -13,6 +13,7 @@ import com.sap.sailing.gwt.ui.shared.WindLatticeDTO;
import com.sap.sailing.gwt.ui.shared.WindLatticeGenParamsDTO;
import com.sap.sailing.gwt.ui.shared.WindPatternDTO;
import com.sap.sailing.gwt.ui.shared.windpattern.WindPatternDisplay;
import com.sap.sailing.gwt.ui.shared.windpattern.WindPatternNotFoundException;
@RemoteServiceRelativePath("simulator")
@@ -22,9 +23,9 @@ public interface SimulatorService extends RemoteService {
public WindLatticeDTO getWindLatice(WindLatticeGenParamsDTO params);
public WindFieldDTO getWindField(WindFieldGenParamsDTO params, WindPatternDisplay pattern);
public WindFieldDTO getWindField(WindFieldGenParamsDTO params, WindPatternDisplay pattern) throws WindPatternNotFoundException;
public PathDTO[] getPaths(WindFieldGenParamsDTO params, WindPatternDisplay pattern);
public PathDTO[] getPaths(WindFieldGenParamsDTO params, WindPatternDisplay pattern) throws WindPatternNotFoundException;
public List<WindPatternDTO> getWindPatterns();
@@ -28,6 +28,7 @@ import com.sap.sailing.gwt.ui.shared.WindPatternDTO;
import com.sap.sailing.gwt.ui.shared.windpattern.WindPatternDisplay;
import com.sap.sailing.gwt.ui.shared.windpattern.WindPatternDisplayManager;
import com.sap.sailing.gwt.ui.shared.windpattern.WindPatternDisplayManager.WindPattern;
import com.sap.sailing.gwt.ui.shared.windpattern.WindPatternNotFoundException;
import com.sap.sailing.gwt.ui.shared.windpattern.WindPatternSetting;
import com.sap.sailing.simulator.Path;
import com.sap.sailing.simulator.PolarDiagram;
@@ -161,40 +162,47 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
}
@Override
public WindFieldDTO getWindField(WindFieldGenParamsDTO params, WindPatternDisplay pattern) {
public WindFieldDTO getWindField(WindFieldGenParamsDTO params, WindPatternDisplay pattern)
throws WindPatternNotFoundException {
logger.info("Entering getWindField");
Position nw = new DegreePosition(params.getNorthWest().latDeg, params.getNorthWest().lngDeg);
Position se = new DegreePosition(params.getSouthEast().latDeg, params.getSouthEast().lngDeg);
List<Position> course = new ArrayList<Position>();
course.add(nw);
course.add(se);
course.add(se);
RectangularBoundary bd = new RectangularBoundary(nw, se, 0.1);
// List<Position> lattice = bd.extractLattice(params.getxRes(), params.getyRes());
retreiveWindControlParameters(pattern);
logger.info("Boundary south direction " + bd.getSouth());
controlParameters.baseWindBearing += bd.getSouth().getDegrees();
WindFieldGenerator wf = WindFieldGeneratorFactory.INSTANCE.createWindFieldGenerator(pattern.getWindPattern()
.name(), bd, controlParameters);
List<Position> lattice = bd.extractLattice(params.getxRes(),params.getyRes());//wf.extractLattice(params.getxRes(), params.getyRes());
if (wf == null) {
throw new WindPatternNotFoundException("Please select a valid wind pattern.");
}
List<Position> lattice = bd.extractLattice(params.getxRes(), params.getyRes());// wf.extractLattice(params.getxRes(),
// params.getyRes());
wf.setPositionGrid(bd.extractGrid(params.getxRes(), params.getyRes()));
TimePoint startTime = new MillisecondsTimePoint(params.getStartTime().getTime());//new MillisecondsTimePoint(0);
TimePoint timeStep = new MillisecondsTimePoint(params.getTimeStep().getTime());//new MillisecondsTimePoint(30*1000);
TimePoint endTime = new MillisecondsTimePoint(params.getEndTime().getTime());//new MillisecondsTimePoint(10 * 60 * 1000);
wf.generate(startTime,null,timeStep);
TimePoint startTime = new MillisecondsTimePoint(params.getStartTime().getTime());// new
// MillisecondsTimePoint(0);
TimePoint timeStep = new MillisecondsTimePoint(params.getTimeStep().getTime());// new
// MillisecondsTimePoint(30*1000);
TimePoint endTime = new MillisecondsTimePoint(params.getEndTime().getTime());// new MillisecondsTimePoint(10 *
// 60 * 1000);
wf.generate(startTime, null, timeStep);
List<WindDTO> wList = new ArrayList<WindDTO>();
if (lattice != null) {
TimePoint t = startTime;
while(t.compareTo(endTime) <= 0) {
while (t.compareTo(endTime) <= 0) {
for (Position p : lattice) {
Wind localWind = wf.getWind(new TimedPositionWithSpeedImpl(t,p,null));
Wind localWind = wf.getWind(new TimedPositionWithSpeedImpl(t, p, null));
logger.finer(localWind.toString());
WindDTO w = createWindDTO(localWind);
wList.add(w);
@@ -206,6 +214,7 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
WindFieldDTO wfDTO = new WindFieldDTO();
wfDTO.setMatrix(wList);
logger.info("Exiting getWindField");
return wfDTO;
}
@@ -214,7 +223,7 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
* Currently the path is a list of WindDTO objects at the path points and only a single optimal path is returned
*
* */
public PathDTO[] getPaths(WindFieldGenParamsDTO params, WindPatternDisplay pattern) {
public PathDTO[] getPaths(WindFieldGenParamsDTO params, WindPatternDisplay pattern) throws WindPatternNotFoundException {
Position nw = new DegreePosition(params.getNorthWest().latDeg, params.getNorthWest().lngDeg);
Position se = new DegreePosition(params.getSouthEast().latDeg, params.getSouthEast().lngDeg);
@@ -226,16 +235,20 @@ public class SimulatorServiceImpl extends RemoteServiceServlet implements Simula
retreiveWindControlParameters(pattern);
controlParameters.baseWindBearing += bd.getSouth().getDegrees();
WindFieldGenerator wf = WindFieldGeneratorFactory.INSTANCE.createWindFieldGenerator(pattern.getWindPattern()
.name(), bd, controlParameters);
List<Position> lattice = bd.extractLattice(params.getxRes(),params.getyRes());//wf.extractLattice(params.getxRes(), params.getyRes());
if (wf == null) {
throw new WindPatternNotFoundException("Please select a valid wind pattern.");
}
List<Position> lattice = bd.extractLattice(params.getxRes(), params.getyRes());// wf.extractLattice(params.getxRes(),
// params.getyRes());
wf.setPositionGrid(bd.extractGrid(params.getxRes(), params.getyRes()));
TimePoint start = new MillisecondsTimePoint(0);
TimePoint timeStep = new MillisecondsTimePoint(30*1000);
wf.generate(start,null,timeStep);
TimePoint timeStep = new MillisecondsTimePoint(30 * 1000);
wf.generate(start, null, timeStep);
// TODO Get all the paths that need to be displayed
List<WindDTO> path = getOptimumPath(course, wf);
PathDTO[] pathDTO = new PathDTO[1];
@@ -9,9 +9,9 @@ public interface WindPatternDisplayManager {
public enum WindPattern {
NONE ("Choose a wind pattern"),
BLASTS ("Blasts"),
BLASTS ("Gusts"),
OSCILLATIONS ("Oscillations"),
OSCILLATION_WITH_BLASTS ("Oscillation with Blasts");
OSCILLATION_WITH_BLASTS ("Oscillation with Gusts");
private String displayName;
WindPattern(String displayName) {
@@ -0,0 +1,15 @@
package com.sap.sailing.gwt.ui.shared.windpattern;
public class WindPatternNotFoundException extends Exception {
/**
*
*/
private static final long serialVersionUID = -7568555635867082357L;
public WindPatternNotFoundException() {}
public WindPatternNotFoundException(String message) {
super(message);
}
}
@@ -26,10 +26,7 @@ public class WindPatternDisplayManagerImpl implements WindPatternDisplayManager
@Override
public WindPatternDisplay getDisplay(WindPattern windPattern) {
WindPatternDisplay display = new WindPatternDisplayImpl(windPattern);
WindPatternSetting<Double> windSpeedSetting = new WindPatternSettingSliderBar("baseWindSpeed",
"Base Wind Speed (kn)", 0, 30, 3);
display.addSetting(windSpeedSetting);
switch (windPattern) {
case BLASTS:
addBlastParameters(display);
@@ -45,21 +42,29 @@ public class WindPatternDisplayManagerImpl implements WindPatternDisplayManager
}
private void addBlastParameters(WindPatternDisplay display) {
WindPatternSetting<Double> windSpeedSetting = new WindPatternSettingSliderBar("baseWindSpeed",
"Base Wind Speed (kn)", 0, 30, 3);
display.addSetting(windSpeedSetting);
WindPatternSetting<Double> blastProbability = new WindPatternSettingSliderBar("blastProbability",
"Blast Probability (%)", 0, 50, 50);
"Gust Probability (%)", 0, 50, 50);
display.addSetting(blastProbability);
WindPatternSetting<Double> maxBlastSize = new WindPatternSettingSliderBar("maxBlastSize", "Blast Size", 1, 10,
WindPatternSetting<Double> maxBlastSize = new WindPatternSettingSliderBar("maxBlastSize", "Gust Size", 1, 10,
1);
display.addSetting(maxBlastSize);
WindPatternSetting<Double> blastWindSpeed = new WindPatternSettingSliderBar("blastWindSpeed",
"Average Blast Wind Speed (%)", 0, 100, 100);
"Average Gust Wind Speed (%)", 0, 100, 100);
display.addSetting(blastWindSpeed);
WindPatternSetting<Double> blastWindSpeedVar = new WindPatternSettingSliderBar("blastWindSpeedVar",
"Blast Wind Speed Variance (%)", 1e-4, 100, 1e-4);
"Gust Wind Speed Variance (%)", 1e-4, 100, 1e-4);
display.addSetting(blastWindSpeedVar);
}
private void addOscillationParameters(WindPatternDisplay display) {
WindPatternSetting<Double> windSpeedSetting = new WindPatternSettingSliderBar("baseWindSpeed",
"Base Wind Speed (kn)", 0, 30, 3);
display.addSetting(windSpeedSetting);
WindPatternSetting<Double> baseWindBearing = new WindPatternSettingSliderBar("baseWindBearing",
"Average Wind Direction (Degrees)", -180, 180, 0);
display.addSetting(baseWindBearing);
@@ -27,7 +27,7 @@ public class ReplayPathCanvasOverlay extends PathCanvasOverlay {
@Override
public void timeChanged(Date date) {
canvas.getContext2d().clearRect(canvas.getAbsoluteLeft(), canvas.getAbsoluteTop(),
canvas.getContext2d().clearRect(0/*canvas.getAbsoluteLeft()*/, 0/*canvas.getAbsoluteTop()*/,
canvas.getCoordinateSpaceWidth(), canvas.getCoordinateSpaceHeight());
List<WindDTO> windDTOToDraw = new ArrayList<WindDTO>();
for(WindDTO windDTO : wl.getMatrix()) {
@@ -14,7 +14,8 @@ public class SimulatorEntryPoint extends AbstractEntryPoint {
private final SimulatorServiceAsync simulatorSvc = GWT.create(SimulatorService.class);
private int xRes = 5;
private int yRes = 5;
private boolean autoUpdate = true;
private static Logger logger = Logger.getLogger("com.sap.sailing");
@@ -38,7 +39,14 @@ public class SimulatorEntryPoint extends AbstractEntryPoint {
} else {
yRes = Integer.parseInt(verticalRes);
}
SimulatorMainPanel mainPanel = new SimulatorMainPanel(simulatorSvc,stringMessages, this, xRes, yRes);
String autoUpdateStr = Window.Location.getParameter("autoUpdate");
if (autoUpdateStr == null || autoUpdateStr.isEmpty()) {
logger.config("Using default auto update " + autoUpdate);
} else {
autoUpdate = Boolean.parseBoolean(autoUpdateStr);
}
SimulatorMainPanel mainPanel = new SimulatorMainPanel(simulatorSvc,stringMessages, this, xRes, yRes, autoUpdate);
RootLayoutPanel.get().add(mainPanel);
}
@@ -76,6 +76,7 @@ public class SimulatorMainPanel extends SplitLayoutPanel {
private final ErrorReporter errorReporter;
private final int xRes;
private final int yRes;
private final boolean autoUpdate;
private class WindControlCapture implements ValueChangeHandler<Double> {
@@ -92,7 +93,9 @@ public class SimulatorMainPanel extends SplitLayoutPanel {
sliderBar.setTitle(String.valueOf(Math.round(sliderBar.getCurrentValue())));
logger.info("Slider value : " + arg0.getValue());
setting.setValue(arg0.getValue());
// update();
if (autoUpdate) {
update();
}
}
}
@@ -147,13 +150,13 @@ public class SimulatorMainPanel extends SplitLayoutPanel {
WindPatternDTO pattern = patternNameDTOMap.get(windPattern);
simulatorSvc.getWindPatternDisplay(pattern, new PatternRetriever(windPattern));
}
simulatorMap.reset();
}
}
public SimulatorMainPanel(SimulatorServiceAsync svc, StringMessages stringMessages, ErrorReporter errorReporter,
int xRes, int yRes) {
int xRes, int yRes, boolean autoUpdate) {
super();
@@ -162,6 +165,7 @@ public class SimulatorMainPanel extends SplitLayoutPanel {
this.errorReporter = errorReporter;
this.xRes = xRes;
this.yRes = yRes;
this.autoUpdate = autoUpdate;
leftPanel = new FlowPanel();
rightPanel = new FlowPanel();
@@ -452,7 +456,11 @@ public class SimulatorMainPanel extends SplitLayoutPanel {
@Override
public void onClick(ClickEvent arg0) {
simulatorMap.reset();
//TODO fix so that resetting the course displays the current selection
//For now disable all button & force user to select
summaryButton.setValue(false);
replayButton.setValue(false);
windDisplayButton.setValue(false);
}
});
@@ -124,7 +124,10 @@ public class SimulatorMap extends AbsolutePanel implements RequiresDataInitializ
private void generateWindField(WindPatternDisplay windPatternDisplay) {
logger.info("In generateWindField");
if (windPatternDisplay == null) {
errorReporter.reportError("Please select a valid wind pattern.");
return;
}
PositionDTO startPointDTO = new PositionDTO(raceCourseCanvasOverlay.startPoint.getLatitude(),
raceCourseCanvasOverlay.startPoint.getLongitude());
PositionDTO endPointDTO = new PositionDTO(raceCourseCanvasOverlay.endPoint.getLatitude(),
@@ -158,7 +161,10 @@ public class SimulatorMap extends AbsolutePanel implements RequiresDataInitializ
private void generatePath(WindPatternDisplay windPatternDisplay, final boolean display) {
logger.info("In generatePath");
if (windPatternDisplay == null) {
errorReporter.reportError("Please select a valid wind pattern.");
return;
}
PositionDTO startPointDTO = new PositionDTO(raceCourseCanvasOverlay.startPoint.getLatitude(),
raceCourseCanvasOverlay.startPoint.getLongitude());
PositionDTO endPointDTO = new PositionDTO(raceCourseCanvasOverlay.endPoint.getLatitude(),
@@ -132,7 +132,7 @@ public class WindFieldCanvasOverlay extends FullCanvasOverlay implements TimeLis
}
private void clear() {
canvas.getContext2d().clearRect(canvas.getAbsoluteLeft(), canvas.getAbsoluteTop(),
canvas.getContext2d().clearRect(0.0 /*canvas.getAbsoluteLeft()*/, 0.0/*canvas.getAbsoluteTop()*/,
canvas.getCoordinateSpaceWidth(), canvas.getCoordinateSpaceHeight());
windFieldPoints.clear();
mmHandler.clear();
@@ -81,7 +81,7 @@ public class WindFieldMapMouseMoveHandler implements MapMouseMoveHandler {
context2d.setFillStyle("Blue");
String speedStr = NumberFormat.getFormat("#.00").format(windDTO.trueWindSpeedInKnots);
String bearingStr = NumberFormat.getFormat("#.00").format(windDTO.trueWindFromDeg);
String bearingStr = NumberFormat.getFormat("#.00").format(windDTO.trueWindBearingDeg);
String ttMsg = speedStr + " kn " + bearingStr + "°";
context2d.fillText(ttMsg, x+10,y+15,60);
}
@@ -30,7 +30,7 @@
<source path='simulator'/>
<inherits name='com.google.gwt.logging.Logging'/>
<set-property name="gwt.logging.enabled" value="TRUE"/>
<set-property name="gwt.logging.enabled" value="FALSE"/>
<!-- Set logging level to INFO -->
<set-property name="gwt.logging.logLevel" value="INFO"/>
<set-property name="gwt.logging.simpleRemoteHandler" value="ENABLED" />
@@ -116,13 +116,14 @@ public class SimulatorTest {
// and the speed of the wind would go over the course in 10 minutes (for the sake of the running time)
WindControlParameters windParameters = new WindControlParameters(requiredSpeed10.getKnots(), b.getSouth().getDegrees());
WindFieldGeneratorOscillationImpl wf = new WindFieldGeneratorOscillationImpl(b, windParameters);
wf.timeScale = 1;
wf.setPositionGrid(b.extractGrid(10, 5));
TimePoint start = new MillisecondsTimePoint(0);
TimePoint timeStep = new MillisecondsTimePoint(30*1000);
wf.generate(start,null,timeStep);
wf.setTimeScale(1);
PolarDiagram pd = new PolarDiagramImpl(1);
List<Position> course = new ArrayList<Position>();
course.add(p1);
@@ -87,7 +87,7 @@ public class WindFieldGeneratorTest {
RectangularBoundary bd = new RectangularBoundary(start, end, 0.1);
WindFieldGeneratorOscillationImpl wf = new WindFieldGeneratorOscillationImpl(bd, windParameters);
wf.timeScale = 1.0;
int hSteps = 30;
int vSteps = 15;
@@ -96,7 +96,8 @@ public class WindFieldGeneratorTest {
TimePoint startTime = new MillisecondsTimePoint(0);
TimePoint timeStep = new MillisecondsTimePoint(30 * 1000);
wf.generate(startTime, null, timeStep);
wf.setTimeScale(1.0);
SpeedWithBearing speed = new KilometersPerHourSpeedWithBearingImpl(0, new DegreeBearingImpl(0));
/*
@@ -154,12 +155,12 @@ public class WindFieldGeneratorTest {
assertEquals("One Time Unit Middle Wind Speed ", windList.get(windList.size() / 2 - 1).getKnots(), 8, 0);
assertEquals("One Time Unit Last Wind Speed ", windList.get(windList.size() - 1).getKnots(), 9, 0);
// Check the angle
assertEquals("One Time Unit First Wind Angle ",0.2019944, windList.get(0).getBearing().getRadians(), epsilon);
assertEquals("One Time Unit One before Middle Wind Angle ", 6.09747107 /*-0.1857142*/, windList.get(windList.size() / 2 - 2).getBearing()
assertEquals("One Time Unit First Wind Angle ",0.0584707, windList.get(0).getBearing().getRadians(), epsilon);
assertEquals("One Time Unit One before Middle Wind Angle ", 0.34031404, windList.get(windList.size() / 2 - 2).getBearing()
.getRadians(), epsilon);
assertEquals("One Time Unit Middle Wind Angle ", 6.09747107, windList.get(windList.size() / 2 - 1).getBearing()
assertEquals("One Time Unit Middle Wind Angle ", 0.34031404, windList.get(windList.size() / 2 - 1).getBearing()
.getRadians(), epsilon);
assertEquals("One Time Unit Last Wind Angle ", 5.939051/*-0.3441339*/, windList.get(windList.size() - 1).getBearing().getRadians(),
assertEquals("One Time Unit Last Wind Angle ", 0.201994, windList.get(windList.size() - 1).getBearing().getRadians(),
epsilon);
}
@@ -13,7 +13,8 @@ Bundle-ActivationPolicy: lazy
Import-Package: javax.servlet;version="2.5.0",
javax.servlet.http;version="2.5.0",
org.osgi.framework;version="1.6.0"
Bundle-ClassPath: .
Bundle-ClassPath: .,
lib/ssj.jar
Export-Package: com.sap.sailing.simulator,
com.sap.sailing.simulator.impl;x-friends:="com.sap.sailing.simulator.test"
Web-ContextPath: /simulator
@@ -2,4 +2,5 @@ source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.,\
WEB-INF/
WEB-INF/,\
lib/ssj.jar
@@ -4,6 +4,7 @@ import com.sap.sailing.domain.base.SpeedWithBearing;
import com.sap.sailing.domain.base.impl.KnotSpeedImpl;
import com.sap.sailing.domain.base.impl.KnotSpeedWithBearingImpl;
import com.sap.sailing.domain.common.Bearing;
import com.sap.sailing.domain.common.Distance;
import com.sap.sailing.domain.common.Position;
import com.sap.sailing.domain.common.Speed;
import com.sap.sailing.domain.common.TimePoint;
@@ -22,10 +23,8 @@ public class WindFieldGeneratorOscillationImpl extends WindFieldGeneratorImpl im
/* Currently the speed is time and vertical step invariant, it only changes along the horizontal
* direction*/
private Speed[] speed;
/**
* Temporary place holder for time correction, to be replaced.
*/
public double timeScale = 60.0;
private double timeScale = 0.0;
public WindFieldGeneratorOscillationImpl(Boundary boundary, WindControlParameters windParameters) {
super(boundary, windParameters);
@@ -34,6 +33,13 @@ public class WindFieldGeneratorOscillationImpl extends WindFieldGeneratorImpl im
@Override
public void generate(TimePoint start, TimePoint end, TimePoint step) {
super.generate(start,end,step);
int vPoints = positions.length;
Distance vStep = boundary.getHeight().scale(1.0/(vPoints-1));
if (windParameters.baseWindSpeed > 0) {
timeScale = vStep.getNauticalMiles()/windParameters.baseWindSpeed;
} else {
timeScale = 0;
}
initializeSpeed();
}
@@ -79,8 +85,10 @@ public class WindFieldGeneratorOscillationImpl extends WindFieldGeneratorImpl im
TimePoint timePoint = timedPosition.getTimePoint();
int timeIndex = getTimeIndex(timePoint);
Bearing phi0 = new DegreeBearingImpl(windParameters.baseWindBearing);
double vStep = 1.0/((positions.length-1)*timeScale);
double t = (timeIndex+(timeIndex+rowIndex)*vStep);
//double vStep = 1.0/((positions.length-1)*timeScale);
//double t = (timeIndex+(timeIndex+rowIndex)*vStep);
double vStep = 1.0/(positions.length-1);
double t = (timeIndex+rowIndex)*vStep*timeScale;
Bearing angle = new DegreeBearingImpl(Math.sin(2*Math.PI*t*windParameters.frequency)*windParameters.amplitude);
angle = angle.add(phi0);
return angle;
@@ -100,4 +108,12 @@ public class WindFieldGeneratorOscillationImpl extends WindFieldGeneratorImpl im
return new WindImpl(timedPosition.getPosition(), timedPosition.getTimePoint(), wspeed);
}
public double getTimeScale() {
return timeScale;
}
public void setTimeScale(double timeScale) {
this.timeScale = timeScale;
}
}