mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-11-15 14:56:41 +00:00
First cut at Blast pattern, WIP.
This commit is contained in:
1 parent
80dc774380
commit
00513a1ccc
5 files changed
+191
-3
No files matched your search
+1
-1
@@ -87,7 +87,7 @@ public class SimulatorMainPanel extends SplitLayoutPanel {
|
||||
public void onValueChange(ValueChangeEvent<Double> arg0) {
|
||||
logger.info("Slider value : " + arg0.getValue());
|
||||
setting.setValue(arg0.getValue());
|
||||
update();
|
||||
//update();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${workspace_loc}"/>
|
||||
<stringAttribute key="pde.version" value="3.3"/>
|
||||
<booleanAttribute key="show_selected_only" value="false"/>
|
||||
<stringAttribute key="target_bundles" value="javax.servlet@default:default,jcl.over.slf4j@default:default,org.apache.activemq.activeio-core@default:default,org.apache.activemq.activemq-core@default:default,org.apache.activemq.kahadb@default:default,org.apache.geronimo.specs.geronimo-annotation_1.0_spec@default:default,org.apache.geronimo.specs.geronimo-j2ee-management_1.1_spec@default:default,org.apache.geronimo.specs.geronimo-jms_1.1_spec@default:default,org.eclipse.equinox.transforms.hook@default:false,org.eclipse.jetty.continuation@default:default,org.eclipse.jetty.deploy@default:default,org.eclipse.jetty.http@default:default,org.eclipse.jetty.io@default:default,org.eclipse.jetty.jmx@default:default,org.eclipse.jetty.nested@default:default,org.eclipse.jetty.osgi.boot@default:default,org.eclipse.jetty.security@default:default,org.eclipse.jetty.server@default:default,org.eclipse.jetty.servlet@default:default,org.eclipse.jetty.util@default:default,org.eclipse.jetty.webapp@default:default,org.eclipse.jetty.xml@default:default,org.eclipse.osgi.services@default:default,org.eclipse.osgi@-1:true,slf4j.api@default:default,slf4j.jdk14@default:false"/>
|
||||
<stringAttribute key="target_bundles" value="javax.servlet@default:default,jcl.over.slf4j@default:default,org.apache.activemq.activeio-core@default:default,org.apache.activemq.activemq-core@default:default,org.apache.activemq.kahadb@default:default,org.apache.geronimo.specs.geronimo-annotation_1.0_spec@default:default,org.apache.geronimo.specs.geronimo-j2ee-management_1.1_spec@default:default,org.apache.geronimo.specs.geronimo-jms_1.1_spec@default:default,org.eclipse.equinox.transforms.hook@default:false,org.eclipse.jetty.continuation@default:default,org.eclipse.jetty.deploy@default:default,org.eclipse.jetty.http@default:default,org.eclipse.jetty.io@default:default,org.eclipse.jetty.jmx@default:default,org.eclipse.jetty.nested@default:default,org.eclipse.jetty.osgi.boot@default:default,org.eclipse.jetty.security@default:default,org.eclipse.jetty.server@default:default,org.eclipse.jetty.servlet@default:default,org.eclipse.jetty.util@default:default,org.eclipse.jetty.webapp@default:default,org.eclipse.jetty.xml@default:default,org.eclipse.osgi.services@default:default,org.eclipse.osgi@-1:true,org.hamcrest.core@default:default,org.junit4@default:default,slf4j.api@default:default,slf4j.jdk14@default:false"/>
|
||||
<booleanAttribute key="tracing" value="false"/>
|
||||
<booleanAttribute key="useCustomFeatures" value="false"/>
|
||||
<booleanAttribute key="useDefaultConfigArea" value="false"/>
|
||||
|
||||
+43
@@ -163,6 +163,49 @@ public class WindFieldGeneratorTest {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWindFieldGeneratorBlast() {
|
||||
Position start = new DegreePosition(54.32447456461419, 10.15613079071045);
|
||||
Position end = new DegreePosition(54.32877915239163, 10.156173706054688);
|
||||
List<Position> course = new LinkedList<Position>();
|
||||
course.add(start);
|
||||
course.add(end);
|
||||
|
||||
WindControlParameters windParameters = new WindControlParameters(10, 180);
|
||||
windParameters.blastProbability = 15.0;
|
||||
windParameters.maxBlastSize = 4.0;
|
||||
windParameters.blastWindSpeed = 15.0;
|
||||
windParameters.blastWindSpeedVar = 15.0;
|
||||
|
||||
RectangularBoundary bd = new RectangularBoundary(start, end, 0.1);
|
||||
WindFieldGeneratorBlastImpl wf = new WindFieldGeneratorBlastImpl(bd, windParameters);
|
||||
int hSteps = 10;
|
||||
int vSteps = 5;
|
||||
|
||||
wf.setPositionGrid(bd.extractGrid(hSteps, vSteps));
|
||||
Position[][] positionGrid = wf.getPositionsGrid();
|
||||
TimePoint startTime = new MillisecondsTimePoint(0);
|
||||
TimePoint timeStep = new MillisecondsTimePoint(30 * 1000);
|
||||
wf.generate(startTime, null, timeStep);
|
||||
|
||||
SpeedWithBearing speed = new KilometersPerHourSpeedWithBearingImpl(0, new DegreeBearingImpl(0));
|
||||
|
||||
/*
|
||||
* Check the speed & angle at the start time
|
||||
*/
|
||||
List<Wind> windList = new ArrayList<Wind>();
|
||||
for (int i = 0; i < vSteps; ++i) {
|
||||
for (int j = 0; j < hSteps; ++j) {
|
||||
Wind localWind = wf.getWind(new TimedPositionWithSpeedImpl(startTime, positionGrid[i][j], speed));
|
||||
logger.info("Wind[" + i + "][" + j + "]" + localWind.toString());
|
||||
windList.add(localWind);
|
||||
}
|
||||
}
|
||||
assertEquals("Size of windList ", hSteps * vSteps, windList.size());
|
||||
double epsilon = 1e-6;
|
||||
// Check the speed
|
||||
assertEquals("StartTime First Wind Speed ", 0, windList.get(0).getKnots(), 0);
|
||||
}
|
||||
private Pair<Integer, Integer> getIndex(int listIndex, int numCols) {
|
||||
Pair<Integer, Integer> indexPair = new Pair<Integer, Integer>(1 + (listIndex - 1) / numCols, 1
|
||||
+ (listIndex - 1) % numCols);
|
||||
|
||||
Binary file not shown.
+146
-1
@@ -1,21 +1,166 @@
|
||||
package com.sap.sailing.simulator.impl;
|
||||
|
||||
import umontreal.iro.lecuyer.randvar.GeometricGen;
|
||||
import umontreal.iro.lecuyer.randvar.NormalGen;
|
||||
import umontreal.iro.lecuyer.randvar.UniformGen;
|
||||
import umontreal.iro.lecuyer.rng.LFSR113;
|
||||
import umontreal.iro.lecuyer.rng.MRG32k3a;
|
||||
import umontreal.iro.lecuyer.rng.RandomStreamBase;
|
||||
|
||||
import com.sap.sailing.domain.base.SpeedWithBearing;
|
||||
import com.sap.sailing.domain.base.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.domain.common.Speed;
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.Util.Pair;
|
||||
import com.sap.sailing.domain.tracking.Wind;
|
||||
import com.sap.sailing.domain.tracking.impl.WindImpl;
|
||||
import com.sap.sailing.simulator.Boundary;
|
||||
import com.sap.sailing.simulator.TimedPosition;
|
||||
import com.sap.sailing.simulator.WindControlParameters;
|
||||
import com.sap.sailing.simulator.WindFieldGenerator;
|
||||
import com.sap.sailing.simulator.impl.WindFieldGeneratorImpl;
|
||||
|
||||
public class WindFieldGeneratorBlastImpl extends WindFieldGeneratorImpl implements WindFieldGenerator {
|
||||
|
||||
private SpeedWithBearing[][] speedWithBearing;
|
||||
|
||||
private double blastSizeProbability = 70;
|
||||
private double blastEdgeProbability = 30;
|
||||
private double blastBearingMean = 0;
|
||||
private double blastBearingVar = 8;
|
||||
|
||||
public WindFieldGeneratorBlastImpl(Boundary boundary, WindControlParameters windParameters) {
|
||||
super(boundary, windParameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(TimePoint start, TimePoint end, TimePoint step) {
|
||||
// TODO Auto-generated method stub
|
||||
super.generate(start, end, step);
|
||||
initializeSpeedWithBearing();
|
||||
}
|
||||
|
||||
private void initializeSpeedWithBearing() {
|
||||
if (positions == null || positions.length < 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
int nrow = positions.length;
|
||||
int ncol = positions[0].length;
|
||||
speedWithBearing = new KnotSpeedWithBearingImpl[nrow][ncol];
|
||||
|
||||
for (int i = 0; i < nrow; ++i) {
|
||||
for (int j = 0; j < ncol; ++j) {
|
||||
if (isBlastSeed()) {
|
||||
double blastSpeed = getBlastSpeed();
|
||||
double blastAngle = getBlastAngle();
|
||||
SpeedWithBearing blastSpeedWithBearing = new KnotSpeedWithBearingImpl(blastSpeed,
|
||||
new DegreeBearingImpl(blastAngle));
|
||||
growBlast(i, j, blastSpeedWithBearing);
|
||||
} else {
|
||||
speedWithBearing[i][j] = new KnotSpeedWithBearingImpl(0,
|
||||
new DegreeBearingImpl(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void growBlast(int rowIndex, int colIndex, SpeedWithBearing blastSpeedWithBearing) {
|
||||
|
||||
if (speedWithBearing[rowIndex][colIndex] != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
int blastSize = (int) Math.min(getBlastSize(), windParameters.maxBlastSize);
|
||||
logger.info("Blast Size:"+ blastSize);
|
||||
int nrow = positions.length;
|
||||
int ncol = positions[0].length;
|
||||
int hSpanStart = Math.max(0, colIndex-blastSize/2);
|
||||
int hSpanEnd = Math.min(colIndex+blastSize-blastSize/2, ncol-1);
|
||||
int vSpan = Math.min(rowIndex+blastSize, nrow-1);
|
||||
for (int i = rowIndex; i <= vSpan; ++i) {
|
||||
for (int j = hSpanStart; j <= hSpanEnd; ++j) {
|
||||
speedWithBearing[i][j] = blastSpeedWithBearing;
|
||||
}
|
||||
}
|
||||
|
||||
if (hSpanEnd-hSpanStart > 1) {
|
||||
for(int i = rowIndex; i <= vSpan; ++i) {
|
||||
if (isBlastCell()) {
|
||||
speedWithBearing[i][hSpanStart] = blastSpeedWithBearing;
|
||||
} else {
|
||||
speedWithBearing[i][hSpanStart] = new KnotSpeedWithBearingImpl(0,
|
||||
new DegreeBearingImpl(0));
|
||||
}
|
||||
if (isBlastCell()) {
|
||||
speedWithBearing[i][hSpanEnd] = blastSpeedWithBearing;
|
||||
} else {
|
||||
speedWithBearing[i][hSpanEnd] = new KnotSpeedWithBearingImpl(0,
|
||||
new DegreeBearingImpl(0));
|
||||
}
|
||||
}
|
||||
for(int j = hSpanStart+1; j <= hSpanEnd-1;++j) {
|
||||
if (isBlastCell()) {
|
||||
speedWithBearing[rowIndex][j] = blastSpeedWithBearing;
|
||||
} else {
|
||||
speedWithBearing[rowIndex][j] = new KnotSpeedWithBearingImpl(0,
|
||||
new DegreeBearingImpl(0));
|
||||
}
|
||||
if (isBlastCell()) {
|
||||
speedWithBearing[vSpan][j] = blastSpeedWithBearing;
|
||||
} else {
|
||||
speedWithBearing[vSpan][j] = new KnotSpeedWithBearingImpl(0,
|
||||
new DegreeBearingImpl(0));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isBlastSeed() {
|
||||
return UniformGen.nextDouble(new LFSR113("BlastSeedStream"), 0, 1) < windParameters.blastProbability/100.0;
|
||||
}
|
||||
|
||||
private boolean isBlastCell() {
|
||||
return UniformGen.nextDouble(new LFSR113("BlastCellStream"), 0, 1) > this.blastEdgeProbability/100.0;
|
||||
}
|
||||
|
||||
private double getBlastSpeed() {
|
||||
return Math.abs(NormalGen.nextDouble(new LFSR113("BlastSpeedStream"), windParameters.baseWindSpeed
|
||||
* windParameters.blastWindSpeed / 100.0,
|
||||
windParameters.baseWindSpeed * Math.sqrt(windParameters.blastWindSpeedVar) / 100.0));
|
||||
|
||||
}
|
||||
|
||||
private int getBlastSize() {
|
||||
return GeometricGen.nextInt(new MRG32k3a("BlastSizeStream"), blastSizeProbability/100.0);
|
||||
}
|
||||
|
||||
private double getBlastAngle() {
|
||||
return NormalGen.nextDouble(new LFSR113("BlastAngleStream"), blastBearingMean, Math.sqrt(blastBearingVar));
|
||||
|
||||
}
|
||||
|
||||
private SpeedWithBearing getSpeedWithBearing(TimedPosition timedPosition) {
|
||||
Position p = timedPosition.getPosition();
|
||||
Pair<Integer, Integer> positionIndex = getPositionIndex(p);
|
||||
if (positionIndex != null) {
|
||||
int rowIndex = positionIndex.getA();
|
||||
int colIndex = positionIndex.getB();
|
||||
return speedWithBearing[rowIndex][colIndex];
|
||||
} else {
|
||||
logger.severe("Error finding position " + p);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Wind getWind(TimedPosition timedPosition) {
|
||||
|
||||
return new WindImpl(timedPosition.getPosition(), timedPosition.getTimePoint(),
|
||||
getSpeedWithBearing(timedPosition));
|
||||
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user