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