major optimization updates
[debian/openrocket] / src / net / sf / openrocket / optimization / rocketoptimization / parameters / StabilityParameter.java
1 package net.sf.openrocket.optimization.rocketoptimization.parameters;
2
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.l10n.Translator;
8 import net.sf.openrocket.logging.LogHelper;
9 import net.sf.openrocket.masscalc.BasicMassCalculator;
10 import net.sf.openrocket.masscalc.MassCalculator;
11 import net.sf.openrocket.masscalc.MassCalculator.MassCalcType;
12 import net.sf.openrocket.optimization.general.OptimizationException;
13 import net.sf.openrocket.optimization.rocketoptimization.OptimizableParameter;
14 import net.sf.openrocket.rocketcomponent.Configuration;
15 import net.sf.openrocket.rocketcomponent.RocketComponent;
16 import net.sf.openrocket.rocketcomponent.SymmetricComponent;
17 import net.sf.openrocket.startup.Application;
18 import net.sf.openrocket.unit.UnitGroup;
19 import net.sf.openrocket.util.Coordinate;
20 import net.sf.openrocket.util.MathUtil;
21 import net.sf.openrocket.util.Prefs;
22
23 /**
24  * An optimization parameter that computes either the absolute or relative stability of a rocket.
25  * 
26  * @author Sampo Niskanen <sampo.niskanen@iki.fi>
27  */
28 public class StabilityParameter implements OptimizableParameter {
29         
30         private static final LogHelper log = Application.getLogger();
31         private static final Translator trans = Application.getTranslator();
32         
33
34         private final boolean absolute;
35         
36         public StabilityParameter(boolean absolute) {
37                 this.absolute = absolute;
38         }
39         
40         
41         @Override
42         public String getName() {
43                 return trans.get("name") + " (" + getUnitGroup().getDefaultUnit().getUnit() + ")";
44         }
45         
46         @Override
47         public double computeValue(Simulation simulation) throws OptimizationException {
48                 Coordinate cp, cg;
49                 double cpx, cgx;
50                 double stability;
51                 
52                 log.debug("Calculating stability of simulation, absolute=" + absolute);
53                 
54                 /*
55                  * These are instantiated each time because this class must be thread-safe.
56                  * Caching would in any case be inefficient since the rocket changes all the time.
57                  */
58                 AerodynamicCalculator aerodynamicCalculator = new BarrowmanCalculator();
59                 MassCalculator massCalculator = new BasicMassCalculator();
60                 
61
62                 Configuration configuration = simulation.getConfiguration();
63                 FlightConditions conditions = new FlightConditions(configuration);
64                 conditions.setMach(Prefs.getDefaultMach());
65                 conditions.setAOA(0);
66                 conditions.setRollRate(0);
67                 
68                 cp = aerodynamicCalculator.getWorstCP(configuration, conditions, null);
69                 cg = massCalculator.getCG(configuration, MassCalcType.LAUNCH_MASS);
70                 
71                 if (cp.weight > 0.000001)
72                         cpx = cp.x;
73                 else
74                         cpx = Double.NaN;
75                 
76                 if (cg.weight > 0.000001)
77                         cgx = cg.x;
78                 else
79                         cgx = Double.NaN;
80                 
81
82                 // Calculate the reference (absolute or relative)
83                 stability = cpx - cgx;
84                 
85                 if (!absolute) {
86                         double diameter = 0;
87                         for (RocketComponent c : configuration) {
88                                 if (c instanceof SymmetricComponent) {
89                                         double d1 = ((SymmetricComponent) c).getForeRadius() * 2;
90                                         double d2 = ((SymmetricComponent) c).getAftRadius() * 2;
91                                         diameter = MathUtil.max(diameter, d1, d2);
92                                 }
93                         }
94                         stability = stability / diameter;
95                 }
96                 
97                 log.debug("Resulting stability is " + stability + ", absolute=" + absolute);
98                 
99                 return stability;
100         }
101         
102         @Override
103         public UnitGroup getUnitGroup() {
104                 if (absolute) {
105                         return UnitGroup.UNITS_LENGTH;
106                 } else {
107                         return UnitGroup.UNITS_STABILITY_CALIBERS;
108                 }
109         }
110         
111 }