X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fnet%2Fsf%2Fopenrocket%2Fmotor%2FThrustCurveMotor.java;fp=src%2Fnet%2Fsf%2Fopenrocket%2Fmotor%2FThrustCurveMotor.java;h=e495defeb2ff50a833c8cd508307cb5e6f220a04;hb=dfc10c016c5f1bb4b7714dff414562f2f32e2866;hp=0000000000000000000000000000000000000000;hpb=84086eec3f20c7af0c4817548de4e8296c7674f8;p=debian%2Fopenrocket diff --git a/src/net/sf/openrocket/motor/ThrustCurveMotor.java b/src/net/sf/openrocket/motor/ThrustCurveMotor.java new file mode 100644 index 00000000..e495defe --- /dev/null +++ b/src/net/sf/openrocket/motor/ThrustCurveMotor.java @@ -0,0 +1,161 @@ +package net.sf.openrocket.motor; + +import net.sf.openrocket.util.Coordinate; +import net.sf.openrocket.util.MathUtil; + +/** + * A class of motors specified by a fixed thrust curve. This is the most + * accurate for solid rocket motors. + * + * @author Sampo Niskanen + */ +public class ThrustCurveMotor extends Motor { + + public static final double MAX_THRUST = 10e6; + + private final double[] time; + private final double[] thrust; + private final Coordinate[] cg; + + private final double totalTime; + private final double maxThrust; + + + /** + * Sole constructor. Sets all the properties of the motor. + * + * @param manufacturer the manufacturer of the motor. + * @param designation the designation of the motor. + * @param description extra description of the motor. + * @param diameter diameter of the motor. + * @param length length of the motor. + * @param time the time points for the thrust curve. + * @param thrust thrust at the time points. + * @param cg cg at the time points. + */ + public ThrustCurveMotor(Manufacturer manufacturer, String designation, String description, + Motor.Type type, double[] delays, double diameter, double length, + double[] time, double[] thrust, Coordinate[] cg) { + super(manufacturer, designation, description, type, delays, diameter, length); + + double max = -1; + + // Check argument validity + if ((time.length != thrust.length) || (time.length != cg.length)) { + throw new IllegalArgumentException("Array lengths do not match, " + + "time:" + time.length + " thrust:" + thrust.length + + " cg:" + cg.length); + } + if (time.length < 2) { + throw new IllegalArgumentException("Too short thrust-curve, length=" + + time.length); + } + for (int i=0; i < time.length-1; i++) { + if (time[i+1] < time[i]) { + throw new IllegalArgumentException("Time goes backwards, " + + "time[" + i + "]=" + time[i] + " " + + "time[" + (i+1) + "]=" + time[i+1]); + } + } + if (!MathUtil.equals(time[0], 0)) { + throw new IllegalArgumentException("Curve starts at time " + time[0]); + } + if (!MathUtil.equals(thrust[0], 0)) { + throw new IllegalArgumentException("Curve starts at thrust " + thrust[0]); + } + if (!MathUtil.equals(thrust[thrust.length-1], 0)) { + throw new IllegalArgumentException("Curve ends at thrust " + + thrust[thrust.length-1]); + } + for (double t: thrust) { + if (t < 0) { + throw new IllegalArgumentException("Negative thrust."); + } + if (t > MAX_THRUST || Double.isNaN(t)) { + throw new IllegalArgumentException("Invalid thrust " + t); + } + if (t > max) + max = t; + } + for (Coordinate c: cg) { + if (c.isNaN()) { + throw new IllegalArgumentException("Invalid CG " + c); + } + if (c.x < 0 || c.x > length) { + throw new IllegalArgumentException("Invalid CG position " + c.x); + } + if (c.weight < 0) { + throw new IllegalArgumentException("Negative mass " + c.weight); + } + } + + this.maxThrust = max; + this.time = time.clone(); + this.thrust = thrust.clone(); + this.cg = cg.clone(); + this.totalTime = time[time.length-1]; + } + + + @Override + public double getTotalTime() { + return totalTime; + } + + @Override + public double getMaxThrust() { + return maxThrust; + } + + @Override + public double getThrust(double t) { + if ((t < 0) || (t > totalTime)) + return 0; + + for (int i=0; i < time.length-1; i++) { + if ((t >= time[i]) && (t <= time[i+1])) { + double delta = time[i+1] - time[i]; + if (delta < 0.0001) { + return thrust[i]; + } + t = t - time[i]; + return thrust[i] * (1 - t/delta) + thrust[i+1] * (t/delta); + } + } + assert false : "Should not be reached."; + return 0; + } + + + @Override + public Coordinate getCG(double t) { + if (t <= 0) + return cg[0]; + if (t >= totalTime) + return cg[cg.length-1]; + + for (int i=0; i < time.length-1; i++) { + if ((t >= time[i]) && (t <= time[i+1])) { + double delta = time[i+1] - time[i]; + t = t - time[i]; + return cg[i].multiply(1 - t/delta).add(cg[i+1].multiply(t/delta)); + } + } + assert false : "Should not be reached."; + return cg[cg.length-1]; + } + + + public double[] getTimePoints() { + return time.clone(); + } + + public double[] getThrustPoints() { + return thrust.clone(); + } + + public Coordinate[] getCGPoints() { + return cg.clone(); + } + +}