1 package net.sf.openrocket.aerodynamics;
\r
3 import java.util.Random;
\r
5 import net.sf.openrocket.util.MathUtil;
\r
6 import net.sf.openrocket.util.PinkNoise;
\r
9 public class WindSimulator {
\r
11 /** Source for seed numbers. */
\r
12 private static final Random seedSource = new Random();
\r
14 /** Pink noise alpha parameter. */
\r
15 private static final double ALPHA = 5.0/3.0;
\r
17 /** Number of poles to use in the pink noise IIR filter. */
\r
18 private static final int POLES = 2;
\r
20 /** The standard deviation of the generated pink noise with the specified number of poles. */
\r
21 private static final double STDDEV = 2.252;
\r
23 /** Time difference between random samples. */
\r
24 private static final double DELTA_T = 0.05;
\r
27 private double average = 0;
\r
28 private double standardDeviation = 0;
\r
32 private PinkNoise randomSource = null;
\r
33 private double time1;
\r
34 private double value1, value2;
\r
38 * Construct a new wind simulator with a random starting seed value.
\r
40 public WindSimulator() {
\r
41 synchronized(seedSource) {
\r
42 seed = seedSource.nextInt();
\r
49 * Return the average wind speed.
\r
51 * @return the average wind speed.
\r
53 public double getAverage() {
\r
57 * Set the average wind speed. This method will also modify the
\r
58 * standard deviation such that the turbulence intensity remains constant.
\r
60 * @param average the average wind speed to set
\r
62 public void setAverage(double average) {
\r
63 double intensity = getTurbulenceIntensity();
\r
64 this.average = Math.max(average, 0);
\r
65 setTurbulenceIntensity(intensity);
\r
71 * Return the standard deviation from the average wind speed.
\r
73 * @return the standard deviation of the wind speed
\r
75 public double getStandardDeviation() {
\r
76 return standardDeviation;
\r
80 * Set the standard deviation of the average wind speed.
\r
82 * @param standardDeviation the standardDeviation to set
\r
84 public void setStandardDeviation(double standardDeviation) {
\r
85 this.standardDeviation = Math.max(standardDeviation, 0);
\r
90 * Return the turbulence intensity (standard deviation / average).
\r
92 * @return the turbulence intensity
\r
94 public double getTurbulenceIntensity() {
\r
95 if (MathUtil.equals(average, 0)) {
\r
96 if (MathUtil.equals(standardDeviation, 0))
\r
101 return standardDeviation / average;
\r
105 * Set the standard deviation to match the turbulence intensity.
\r
107 * @param intensity the turbulence intensity
\r
109 public void setTurbulenceIntensity(double intensity) {
\r
110 setStandardDeviation(intensity * average);
\r
117 public int getSeed() {
\r
121 public void setSeed(int seed) {
\r
122 if (this.seed == seed)
\r
129 public double getWindSpeed(double time) {
\r
131 throw new IllegalArgumentException("Requesting wind speed at t="+time);
\r
134 if (randomSource == null) {
\r
135 randomSource = new PinkNoise(ALPHA, POLES, new Random(seed));
\r
137 value1 = randomSource.nextValue();
\r
138 value2 = randomSource.nextValue();
\r
141 if (time < time1) {
\r
143 return getWindSpeed(time);
\r
146 while (time1 + DELTA_T < time) {
\r
148 value2 = randomSource.nextValue();
\r
152 double a = (time - time1)/DELTA_T;
\r
155 return average + (value1 * (1-a) + value2 * a) * standardDeviation / STDDEV;
\r
159 private void reset() {
\r
160 randomSource = null;
\r
164 public static void main(String[] str) {
\r
166 WindSimulator sim = new WindSimulator();
\r
169 sim.setStandardDeviation(0.5);
\r
171 for (int i=0; i < 10000; i++) {
\r
173 double v = sim.getWindSpeed(t);
\r
174 System.out.printf("%d.%03d %d.%03d\n", (int)t,((int)(t*1000))%1000, (int)v, ((int)(v*1000))%1000);
\r
175 // if ((i % 5) == 0)
\r
176 // System.out.println(" ***");
\r
178 // System.out.println("");
\r