a29f55719c9131730660892c69dbc84ef155e5b3
[debian/openrocket] / src / net / sf / openrocket / rocketcomponent / ThrustCurveMotor.java
1 package net.sf.openrocket.rocketcomponent;
2
3 import net.sf.openrocket.util.Coordinate;
4
5 /**
6  * A class of motors specified by a fixed thrust curve.  This is the most
7  * accurate for solid rocket motors.
8  * 
9  * @author Sampo Niskanen <sampo.niskanen@iki.fi>
10  */
11 public class ThrustCurveMotor extends Motor {
12
13         private final double[] time;
14         private final double[] thrust;
15         private final Coordinate[] cg;
16         
17         private final double totalTime;
18         private final double maxThrust;
19         
20
21         /**
22          * Sole constructor.  Sets all the properties of the motor.
23          * 
24          * @param manufacturer  the manufacturer of the motor.
25          * @param designation   the designation of the motor.
26          * @param description   extra description of the motor.
27          * @param diameter      diameter of the motor.
28          * @param length        length of the motor.
29          * @param time          the time points for the thrust curve.
30          * @param thrust        thrust at the time points.
31          * @param cg            cg at the time points.
32          */
33         public ThrustCurveMotor(String manufacturer, String designation, String description, 
34                         Motor.Type type, double[] delays, double diameter, double length,
35                         double[] time, double[] thrust, Coordinate[] cg) {
36                 super(manufacturer, designation, description, type, delays, diameter, length);
37
38                 double max = -1;
39
40                 // Check argument validity
41                 if ((time.length != thrust.length) || (time.length != cg.length)) {
42                         throw new IllegalArgumentException("Array lengths do not match, " +
43                                         "time:" + time.length + " thrust:" + thrust.length +
44                                         " cg:" + cg.length);
45                 }
46                 if (time.length < 2) {
47                         throw new IllegalArgumentException("Too short thrust-curve, length=" + 
48                                         time.length);
49                 }
50                 for (int i=0; i < time.length-1; i++) {
51                         if (time[i+1] < time[i]) {
52                                 throw new IllegalArgumentException("Time goes backwards, " +
53                                                 "time[" + i + "]=" + time[i] + " " +
54                                                 "time[" + (i+1) + "]=" + time[i+1]);
55                         }
56                 }
57                 if (time[0] != 0) {
58                         throw new IllegalArgumentException("Curve starts at time=" + time[0]);
59                 }
60                 for (double t: thrust) {
61                         if (t < 0) {
62                                 throw new IllegalArgumentException("Negative thrust.");
63                         }
64                         if (t > max)
65                                 max = t;
66                 }
67
68                 this.maxThrust = max;
69                 this.time = time.clone();
70                 this.thrust = thrust.clone();
71                 this.cg = cg.clone();
72                 this.totalTime = time[time.length-1];
73         }
74
75
76         @Override
77         public double getTotalTime() {
78                 return totalTime;
79         }
80
81         @Override
82         public double getMaxThrust() {
83                 return maxThrust;
84         }
85         
86         @Override
87         public double getThrust(double t) {
88                 if ((t < 0) || (t > totalTime))
89                         return 0;
90
91                 for (int i=0; i < time.length-1; i++) {
92                         if ((t >= time[i]) && (t <= time[i+1])) {
93                                 double delta = time[i+1] - time[i];
94                                 t = t - time[i];
95                                 return thrust[i] * (1 - t/delta) + thrust[i+1] * (t/delta);
96                         }
97                 }
98                 assert false : "Should not be reached.";
99                 return 0;
100         }
101
102
103         @Override
104         public Coordinate getCG(double t) {
105                 if (t <= 0)
106                         return cg[0];
107                 if (t >= totalTime)
108                         return cg[cg.length-1];
109                 
110                 for (int i=0; i < time.length-1; i++) {
111                         if ((t >= time[i]) && (t <= time[i+1])) {
112                                 double delta = time[i+1] - time[i];
113                                 t = t - time[i];
114                                 return cg[i].multiply(1 - t/delta).add(cg[i+1].multiply(t/delta));
115                         }
116                 }
117                 assert false : "Should not be reached.";
118                 return cg[cg.length-1];
119         }
120
121 }