1 package net.sf.openrocket.optimization.rocketoptimization.domains;
3 import net.sf.openrocket.aerodynamics.AerodynamicCalculator;
4 import net.sf.openrocket.aerodynamics.BarrowmanCalculator;
5 import net.sf.openrocket.aerodynamics.FlightConditions;
6 import net.sf.openrocket.document.Simulation;
7 import net.sf.openrocket.masscalc.BasicMassCalculator;
8 import net.sf.openrocket.masscalc.MassCalculator;
9 import net.sf.openrocket.masscalc.MassCalculator.MassCalcType;
10 import net.sf.openrocket.optimization.rocketoptimization.SimulationDomain;
11 import net.sf.openrocket.rocketcomponent.Configuration;
12 import net.sf.openrocket.rocketcomponent.RocketComponent;
13 import net.sf.openrocket.rocketcomponent.SymmetricComponent;
14 import net.sf.openrocket.util.Coordinate;
15 import net.sf.openrocket.util.MathUtil;
16 import net.sf.openrocket.util.Pair;
17 import net.sf.openrocket.util.Prefs;
20 * A simulation domain that limits the requires stability of the rocket.
22 * @author Sampo Niskanen <sampo.niskanen@iki.fi>
24 public class StabilityDomain implements SimulationDomain {
27 * FIXME: Should this rather inspect stability during flight
30 private final double limit;
31 private final boolean absolute;
34 public StabilityDomain(double limit, boolean absolute) {
36 this.absolute = absolute;
41 public Pair<Double, Double> getDistanceToDomain(Simulation simulation) {
47 * These are instantiated each time because this class must be thread-safe.
48 * Caching would in any case be inefficient since the rocket changes all the time.
50 AerodynamicCalculator aerodynamicCalculator = new BarrowmanCalculator();
51 MassCalculator massCalculator = new BasicMassCalculator();
54 Configuration configuration = simulation.getConfiguration();
55 FlightConditions conditions = new FlightConditions(configuration);
56 conditions.setMach(Prefs.getDefaultMach());
58 conditions.setRollRate(0);
60 // TODO: HIGH: This re-calculates the worst theta value every time
61 cp = aerodynamicCalculator.getWorstCP(configuration, conditions, null);
62 cg = massCalculator.getCG(configuration, MassCalcType.LAUNCH_MASS);
64 if (cp.weight > 0.000001)
69 if (cg.weight > 0.000001)
75 // Calculate the reference (absolute or relative)
76 reference = cpx - cgx;
79 for (RocketComponent c : configuration) {
80 if (c instanceof SymmetricComponent) {
81 double d1 = ((SymmetricComponent) c).getForeRadius() * 2;
82 double d2 = ((SymmetricComponent) c).getAftRadius() * 2;
83 diameter = MathUtil.max(diameter, d1, d2);
87 reference = (cpx - cgx) / diameter;
90 System.out.println("DOMAIN: limit=" + limit + " reference=" + reference + " result=" + (limit - reference));
92 return new Pair<Double, Double>(limit - reference, reference);