From 6532743c3f6e56845f0dc08a77dae4f7287d5a7c Mon Sep 17 00:00:00 2001 From: Kevin Ruland Date: Mon, 10 Oct 2016 19:50:17 -0500 Subject: [PATCH] Revising previous commit to include the missing files. --- .../datafiles/thrustcurves/thrustcurves.ser | Bin 2733123 -> 2796409 bytes .../database/motor/ThrustCurveMotorSet.java | 31 + .../file/motor/AbstractMotorLoader.java | 4 +- .../file/motor/GeneralMotorLoader.java | 6 +- .../file/motor/RASPMotorLoader.java | 55 +- .../file/motor/RockSimMotorLoader.java | 79 +- .../file/motor/ZipFileMotorLoader.java | 6 +- .../file/simplesax/DelegatorHandler.java | 14 +- core/src/net/sf/openrocket/motor/Motor.java | 5 +- .../sf/openrocket/motor/ThrustCurveMotor.java | 379 +- .../openrocket/thrustcurve/MotorBurnFile.java | 4 +- .../thrustcurve/SearchResponseParser.java | 5 +- .../SerializeThrustcurveMotors.java | 15 +- .../net/sf/openrocket/util/TestRockets.java | 164 +- .../sf/openrocket/utils/MotorCorrelation.java | 51 - .../database/ThrustCurveMotorSetTest.java | 72 +- .../file/motor/TestMotorLoader.java | 5 +- .../file/openrocket/OpenRocketSaverTest.java | 22 +- .../motor/ThrustCurveMotorTest.java | 51 +- .../thrustcurve/SampleSearchResponse.xml | 6387 +++++++++++++++++ .../thrustcurve/SearchResponseParserTest.java | 19 + .../thrustcurve/MotorInformationPanel.java | 1 + .../ThrustCurveMotorSelectionPanel.java | 2 + .../net/sf/openrocket/IntegrationTest.java | 5 +- 24 files changed, 6941 insertions(+), 441 deletions(-) create mode 100644 core/test/net/sf/openrocket/thrustcurve/SampleSearchResponse.xml create mode 100644 core/test/net/sf/openrocket/thrustcurve/SearchResponseParserTest.java diff --git a/core/resources/datafiles/thrustcurves/thrustcurves.ser b/core/resources/datafiles/thrustcurves/thrustcurves.ser index d68f92c37d95301c22b8fb0efa4766b48e6880d2..eef07e2d826158ad6d477fea687e8e0e94e1248c 100644 GIT binary patch delta 104022 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󍨐zw5#KLVF;c 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 delta 59728 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 { private Manufacturer manufacturer = null; private String designation = null; + private String simplifiedDesignation = null; private double diameter = -1; private double length = -1; private long totalImpulse = 0; @@ -51,6 +54,7 @@ public class ThrustCurveMotorSet implements Comparable { if (motors.isEmpty()) { manufacturer = motor.getManufacturer(); designation = motor.getDesignation(); + simplifiedDesignation = simplifyDesignation(designation); diameter = motor.getDiameter(); length = motor.getLength(); totalImpulse = Math.round((motor.getTotalImpulseEstimate())); @@ -80,6 +84,11 @@ public class ThrustCurveMotorSet implements Comparable { } } + // Change the simplified designation if necessary + if (!designation.equalsIgnoreCase(motor.getDesignation().trim())) { + designation = simplifiedDesignation; + } + if (caseInfo == null) { caseInfo = motor.getCaseInfo(); } @@ -146,6 +155,9 @@ public class ThrustCurveMotorSet implements Comparable { return false; } + if (!simplifiedDesignation.equalsIgnoreCase(simplifyDesignation(m.getDesignation()))) + return false; + if (!designation.equalsIgnoreCase(m.getDesignation())) return false; @@ -250,6 +262,25 @@ public class ThrustCurveMotorSet implements Comparable { ", type=" + type + ", count=" + motors.size() + "]"; } + private static final Pattern SIMPLIFY_PATTERN = Pattern.compile("^[0-9]*[ -]*([A-Z][0-9]+).*"); + + /** + * Simplify a motor designation, if possible. This attempts to reduce the designation + * into a simple letter + number notation for the impulse class and average thrust. + * + * @param str the designation to simplify + * @return the simplified designation, or the string itself if the format was not detected + */ + public static String simplifyDesignation(String str) { + str = str.trim(); + Matcher m = SIMPLIFY_PATTERN.matcher(str); + if (m.matches()) { + return m.group(1); + } else { + return str.replaceAll("\\s", ""); + } + } + /** * Comparator for deciding in which order to display matching motors. */ diff --git a/core/src/net/sf/openrocket/file/motor/AbstractMotorLoader.java b/core/src/net/sf/openrocket/file/motor/AbstractMotorLoader.java index a56f37233..478e9447a 100644 --- a/core/src/net/sf/openrocket/file/motor/AbstractMotorLoader.java +++ b/core/src/net/sf/openrocket/file/motor/AbstractMotorLoader.java @@ -174,10 +174,10 @@ public abstract class AbstractMotorLoader implements MotorLoader { @SuppressWarnings("unchecked") protected static void finalizeThrustCurve(List time, List thrust, List... lists) { - + if (time.size() == 0) return; - + // Start if (!MathUtil.equals(time.get(0), 0) || !MathUtil.equals(thrust.get(0), 0)) { time.add(0, 0.0); diff --git a/core/src/net/sf/openrocket/file/motor/GeneralMotorLoader.java b/core/src/net/sf/openrocket/file/motor/GeneralMotorLoader.java index c3822bc5b..974a4afbd 100644 --- a/core/src/net/sf/openrocket/file/motor/GeneralMotorLoader.java +++ b/core/src/net/sf/openrocket/file/motor/GeneralMotorLoader.java @@ -25,7 +25,7 @@ public class GeneralMotorLoader implements MotorLoader { } - + /** * {@inheritDoc} * @@ -37,7 +37,7 @@ public class GeneralMotorLoader implements MotorLoader { } - + /** * Return an array containing the supported file extensions. * @@ -65,7 +65,7 @@ public class GeneralMotorLoader implements MotorLoader { if (point > 0) ext = filename.substring(point + 1); - + if (ext.equalsIgnoreCase("eng")) { return RASP_LOADER; } else if (ext.equalsIgnoreCase("rse")) { diff --git a/core/src/net/sf/openrocket/file/motor/RASPMotorLoader.java b/core/src/net/sf/openrocket/file/motor/RASPMotorLoader.java index 808132578..26c102f71 100644 --- a/core/src/net/sf/openrocket/file/motor/RASPMotorLoader.java +++ b/core/src/net/sf/openrocket/file/motor/RASPMotorLoader.java @@ -21,11 +21,15 @@ public class RASPMotorLoader extends AbstractMotorLoader { public static final Charset CHARSET = Charset.forName(CHARSET_NAME); + + + @Override protected Charset getDefaultCharset() { return CHARSET; } + /** * Load a Motor from a RASP file specified by the Reader. * The Reader is responsible for using the correct charset. @@ -39,7 +43,7 @@ public class RASPMotorLoader extends AbstractMotorLoader { */ @Override public List load(Reader reader, String filename) throws IOException { - List motors = new ArrayList(); + List motors = new ArrayList<>(); BufferedReader in = new BufferedReader(reader); String manufacturer = ""; @@ -62,7 +66,7 @@ public class RASPMotorLoader extends AbstractMotorLoader { line = in.readLine(); main: while (line != null) { // Until EOF - + manufacturer = ""; designation = ""; comment = ""; @@ -98,7 +102,7 @@ public class RASPMotorLoader extends AbstractMotorLoader { length = Double.parseDouble(pieces[2]) / 1000.0; if (pieces[3].equalsIgnoreCase("None")) { - + } else { buf = split(pieces[3], "[-,]+"); for (int i = 0; i < buf.length; i++) { @@ -169,8 +173,8 @@ public class RASPMotorLoader extends AbstractMotorLoader { private static ThrustCurveMotor.Builder createRASPMotor(String manufacturer, String designation, String comment, double length, double diameter, double[] delays, double propW, double totalW, List time, List thrust) - throws IOException { - + throws IOException { + // Add zero time/thrust if necessary sortLists(time, thrust); finalizeThrustCurve(time, thrust); @@ -194,23 +198,28 @@ public class RASPMotorLoader extends AbstractMotorLoader { motorDigest.update(DataType.FORCE_PER_TIME, thrustArray); final String digest = motorDigest.getDigest(); - Manufacturer m = Manufacturer.getManufacturer(manufacturer); - - ThrustCurveMotor.Builder builder = new ThrustCurveMotor.Builder(); - builder.setManufacturer(m) - .setDesignation(designation) - .setDescription(comment) - .setDigest(digest) - .setMotorType(m.getMotorType()) - .setStandardDelays(delays) - .setDiameter(diameter) - .setLength(length) - .setTimePoints(timeArray) - .setThrustPoints(thrustArray) - .setCGPoints(cgArray) - .setInitialMass(totalW) - .setPropellantMass(propW); - - return builder; + try { + + Manufacturer m = Manufacturer.getManufacturer(manufacturer); + ThrustCurveMotor.Builder builder = new ThrustCurveMotor.Builder(); + builder.setManufacturer(m) + .setDesignation(designation) + .setDescription(comment) + .setMotorType(m.getMotorType()) + .setStandardDelays(delays) + .setDiameter(diameter) + .setLength(length) + .setTimePoints(timeArray) + .setThrustPoints(thrustArray) + .setCGPoints(cgArray) + .setDigest(digest); + return builder; + + } catch (IllegalArgumentException e) { + + // Bad data read from file. + throw new IOException("Illegal file format.", e); + + } } } diff --git a/core/src/net/sf/openrocket/file/motor/RockSimMotorLoader.java b/core/src/net/sf/openrocket/file/motor/RockSimMotorLoader.java index 00e908a30..b1fee2686 100644 --- a/core/src/net/sf/openrocket/file/motor/RockSimMotorLoader.java +++ b/core/src/net/sf/openrocket/file/motor/RockSimMotorLoader.java @@ -23,6 +23,7 @@ import net.sf.openrocket.motor.Motor; import net.sf.openrocket.motor.MotorDigest; import net.sf.openrocket.motor.MotorDigest.DataType; import net.sf.openrocket.motor.ThrustCurveMotor; +import net.sf.openrocket.motor.ThrustCurveMotor.Builder; import net.sf.openrocket.util.Coordinate; public class RockSimMotorLoader extends AbstractMotorLoader { @@ -79,7 +80,7 @@ public class RockSimMotorLoader extends AbstractMotorLoader { * Initial handler for the RockSim engine files. */ private static class RSEHandler extends AbstractElementHandler { - private final List motors = new ArrayList(); + private final List motors = new ArrayList<>(); private RSEMotorHandler motorHandler; @@ -90,7 +91,7 @@ public class RockSimMotorLoader extends AbstractMotorLoader { @Override public ElementHandler openElement(String element, HashMap attributes, WarningSet warnings) throws SAXException { - + if (element.equals("engine-database") || element.equals("engine-list")) { // Ignore and elements @@ -113,7 +114,7 @@ public class RockSimMotorLoader extends AbstractMotorLoader { @Override public void closeElement(String element, HashMap attributes, String content, WarningSet warnings) throws SAXException { - + if (element.equals("engine")) { ThrustCurveMotor.Builder motor = motorHandler.getMotor(); motors.add(motor); @@ -265,7 +266,7 @@ public class RockSimMotorLoader extends AbstractMotorLoader { @Override public ElementHandler openElement(String element, HashMap attributes, WarningSet warnings) throws SAXException { - + if (element.equals("comments")) { return PlainTextHandler.INSTANCE; } @@ -286,7 +287,7 @@ public class RockSimMotorLoader extends AbstractMotorLoader { @Override public void closeElement(String element, HashMap attributes, String content, WarningSet warnings) { - + if (element.equals("comments")) { if (description.length() > 0) { description = description + "\n\n" + content.trim(); @@ -320,10 +321,10 @@ public class RockSimMotorLoader extends AbstractMotorLoader { } } - public ThrustCurveMotor.Builder getMotor() throws SAXException { + public Builder getMotor() throws SAXException { if (time == null || time.size() == 0) throw new SAXException("Illegal motor data"); - + finalizeThrustCurve(time, force, mass, cg); final int n = time.size(); @@ -332,7 +333,7 @@ public class RockSimMotorLoader extends AbstractMotorLoader { calculateMass = true; if (hasIllegalValue(cg)) calculateCG = true; - + if (calculateMass) { mass = calculateMass(time, force, initMass, propMass); } @@ -350,6 +351,7 @@ public class RockSimMotorLoader extends AbstractMotorLoader { cgArray[i] = new Coordinate(cg.get(i), 0, 0, mass.get(i)); } + // Create the motor digest from all data available in the file MotorDigest motorDigest = new MotorDigest(); motorDigest.update(DataType.TIME_ARRAY, timeArray); @@ -364,35 +366,36 @@ public class RockSimMotorLoader extends AbstractMotorLoader { motorDigest.update(DataType.FORCE_PER_TIME, thrustArray); final String digest = motorDigest.getDigest(); - Manufacturer m = Manufacturer.getManufacturer(manufacturer); - Motor.Type t = type; - if (t == Motor.Type.UNKNOWN) { - t = m.getMotorType(); - } else { - if (m.getMotorType() != Motor.Type.UNKNOWN && m.getMotorType() != t) { - log.warn("Loaded motor type inconsistent with manufacturer," + - " loaded type=" + t + " manufacturer=" + m + - " manufacturer type=" + m.getMotorType() + - " designation=" + designation); - } - } - ThrustCurveMotor.Builder builder = new ThrustCurveMotor.Builder(); - builder.setManufacturer(m) - .setDesignation(designation) - .setDescription(description) - .setDigest(digest) - .setMotorType(t) - .setStandardDelays(delays) - .setDiameter(diameter) - .setLength(length) - .setTimePoints(timeArray) - .setThrustPoints(thrustArray) - .setCGPoints(cgArray) - .setInitialMass(initMass) - .setPropellantMass(propMass); - - return builder; + try { + Manufacturer m = Manufacturer.getManufacturer(manufacturer); + Motor.Type t = type; + if (t == Motor.Type.UNKNOWN) { + t = m.getMotorType(); + } else { + if (m.getMotorType() != Motor.Type.UNKNOWN && m.getMotorType() != t) { + log.warn("Loaded motor type inconsistent with manufacturer," + + " loaded type=" + t + " manufacturer=" + m + + " manufacturer type=" + m.getMotorType() + + " designation=" + designation); + } + } + + return new ThrustCurveMotor.Builder() + .setManufacturer(m) + .setDesignation(designation) + .setDescription(description) + .setMotorType(t) + .setStandardDelays(delays) + .setDiameter(diameter) + .setLength(length) + .setTimePoints(timeArray) + .setThrustPoints(thrustArray) + .setCGPoints(cgArray) + .setDigest(digest); + } catch (IllegalArgumentException e) { + throw new SAXException("Illegal motor data", e); + } } } @@ -428,7 +431,7 @@ public class RockSimMotorLoader extends AbstractMotorLoader { @Override public ElementHandler openElement(String element, HashMap attributes, WarningSet warnings) { - + if (element.equals("eng-data")) { return NullElementHandler.INSTANCE; } @@ -440,7 +443,7 @@ public class RockSimMotorLoader extends AbstractMotorLoader { @Override public void closeElement(String element, HashMap attributes, String content, WarningSet warnings) throws SAXException { - + double t = parseDouble(attributes.get("t")); double f = parseDouble(attributes.get("f")); double m = parseDouble(attributes.get("m")) / 1000.0; diff --git a/core/src/net/sf/openrocket/file/motor/ZipFileMotorLoader.java b/core/src/net/sf/openrocket/file/motor/ZipFileMotorLoader.java index 0b319bcd0..176da2dc6 100644 --- a/core/src/net/sf/openrocket/file/motor/ZipFileMotorLoader.java +++ b/core/src/net/sf/openrocket/file/motor/ZipFileMotorLoader.java @@ -45,7 +45,7 @@ public class ZipFileMotorLoader implements MotorLoader { @Override public List load(InputStream stream, String filename) throws IOException { - List motors = new ArrayList(); + List motors = new ArrayList<>(); ZipInputStream is = new ZipInputStream(stream); @@ -56,10 +56,10 @@ public class ZipFileMotorLoader implements MotorLoader { ZipEntry entry = is.getNextEntry(); if (entry == null) break; - + if (entry.isDirectory()) continue; - + // Get the file name of the entry String name = entry.getName(); int index = name.lastIndexOf('/'); diff --git a/core/src/net/sf/openrocket/file/simplesax/DelegatorHandler.java b/core/src/net/sf/openrocket/file/simplesax/DelegatorHandler.java index 13f396283..6023f43ee 100644 --- a/core/src/net/sf/openrocket/file/simplesax/DelegatorHandler.java +++ b/core/src/net/sf/openrocket/file/simplesax/DelegatorHandler.java @@ -8,7 +8,6 @@ import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; -import net.sf.openrocket.aerodynamics.Warning; import net.sf.openrocket.aerodynamics.WarningSet; /** @@ -22,7 +21,6 @@ class DelegatorHandler extends DefaultHandler { private final Deque elementData = new ArrayDeque(); private final Deque> elementAttributes = new ArrayDeque>(); - // Ignore all elements as long as ignore > 0 private int ignore = 0; @@ -39,21 +37,13 @@ class DelegatorHandler extends DefaultHandler { @Override public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException { - + // Check for ignore if (ignore > 0) { ignore++; return; } - // Check for unknown namespace - if (!uri.equals("")) { - warnings.add(Warning.fromString("Unknown namespace element '" + uri - + "' encountered, ignoring.")); - ignore++; - return; - } - // Add layer to data stacks elementData.push(new StringBuilder()); elementAttributes.push(copyAttributes(attributes)); @@ -78,7 +68,7 @@ class DelegatorHandler extends DefaultHandler { // Check for ignore if (ignore > 0) return; - + StringBuilder sb = elementData.peek(); sb.append(chars, start, length); } diff --git a/core/src/net/sf/openrocket/motor/Motor.java b/core/src/net/sf/openrocket/motor/Motor.java index a3c468818..ae9199251 100644 --- a/core/src/net/sf/openrocket/motor/Motor.java +++ b/core/src/net/sf/openrocket/motor/Motor.java @@ -1,6 +1,6 @@ package net.sf.openrocket.motor; -public interface Motor extends Cloneable { +public interface Motor { /** * Enum of rocket motor types. @@ -119,8 +119,6 @@ public interface Motor extends Cloneable { public String getDigest(); - public Motor clone(); - public double getAverageThrust( final double startTime, final double endTime ); public double getLaunchCGx(); @@ -187,4 +185,5 @@ public interface Motor extends Cloneable { public double getUnitIyy(); public double getUnitIzz(); + } diff --git a/core/src/net/sf/openrocket/motor/ThrustCurveMotor.java b/core/src/net/sf/openrocket/motor/ThrustCurveMotor.java index 518c6b004..e78edc061 100644 --- a/core/src/net/sf/openrocket/motor/ThrustCurveMotor.java +++ b/core/src/net/sf/openrocket/motor/ThrustCurveMotor.java @@ -7,10 +7,9 @@ import java.util.Locale; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import net.sf.openrocket.models.atmosphere.AtmosphericConditions; + import net.sf.openrocket.util.BugException; import net.sf.openrocket.util.Coordinate; -import net.sf.openrocket.util.Inertia; import net.sf.openrocket.util.MathUtil; public class ThrustCurveMotor implements Motor, Comparable, Serializable { @@ -32,163 +31,198 @@ public class ThrustCurveMotor implements Motor, Comparable, Se private String digest; - private final Manufacturer manufacturer; - private final String designation; - private final String description; - private final Motor.Type type; - private final double[] delays; - private final double diameter; - private final double length; - private final double[] time; - private final double[] thrust; - private final Coordinate[] cg; + private Manufacturer manufacturer; + private String designation; + private String description; + private Motor.Type type; + private double[] delays; + private double diameter; + private double length; + private double[] time; + private double[] thrust; + private Coordinate[] cg; private String caseInfo; private String propellantInfo; private double initialMass; + private double propellantMass; private double maxThrust; private double burnTimeEstimate; private double averageThrust; private double totalImpulse; - - private final double unitRotationalInertia; - private final double unitLongitudinalInertia; - private boolean available = true; - /** - * Deep copy constructor. - * Constructs a new ThrustCurveMotor from an existing ThrustCurveMotor. - * @param m - */ - protected ThrustCurveMotor(ThrustCurveMotor m) { - this.digest = m.digest; - this.manufacturer = m.manufacturer; - this.designation = m.designation; - this.description = m.description; - this.type = m.type; - this.delays = Arrays.copyOf(m.delays, m.delays.length); - this.diameter = m.diameter; - this.length = m.length; - this.time = Arrays.copyOf(m.time, m.time.length); - this.thrust = Arrays.copyOf(m.thrust, m.thrust.length); - this.cg = m.getCGPoints().clone(); + private double unitRotationalInertia; + private double unitLongitudinalInertia; + + public static class Builder { - this.caseInfo = m.caseInfo; - this.propellantInfo = m.propellantInfo; + ThrustCurveMotor motor = new ThrustCurveMotor(); - this.initialMass = m.initialMass; - this.maxThrust = m.maxThrust; - this.burnTimeEstimate = m.burnTimeEstimate; - this.averageThrust = m.averageThrust; - this.totalImpulse = m.totalImpulse; + public Builder setAverageThrustEstimate(double v) { + motor.averageThrust = v; + return this; + } - this.unitRotationalInertia = m.unitRotationalInertia; - this.unitLongitudinalInertia = m.unitLongitudinalInertia; + public Builder setBurnTimeEstimate(double v) { + motor.burnTimeEstimate = v; + return this; + } + + public Builder setCaseInfo(String v) { + motor.caseInfo = v; + return this; + } + + public Builder setCGPoints(Coordinate[] cg) { + motor.cg = cg; + return this; + } + + public Builder setDescription(String d) { + motor.description = d; + return this; + } + + public Builder setDesignation(String d) { + motor.designation = d; + return this; + } + + public Builder setDiameter(double v) { + motor.diameter = v; + return this; + } + + public Builder setDigest(String d) { + motor.digest = d; + return this; + } + + public Builder setInitialMass(double v) { + motor.initialMass = v; + return this; + } + + public Builder setLength(double v) { + motor.length = v; + return this; + } + + public Builder setManufacturer(Manufacturer m) { + motor.manufacturer = m; + return this; + } + + public Builder setMaxThrustEstimate(double v) { + motor.maxThrust = v; + return this; + } + + public Builder setMotorType(Motor.Type t) { + motor.type = t; + return this; + } + + public Builder setPropellantInfo(String v) { + motor.propellantInfo = v; + return this; + } + + public Builder setPropellantMass(double v) { + motor.propellantMass = v; + return this; + } + + public Builder setStandardDelays(double[] d) { + motor.delays = d; + return this; + } + + public Builder setThrustPoints(double[] d) { + motor.thrust = d; + return this; + } + + public Builder setTimePoints(double[] d) { + motor.time = d; + return this; + } + + public Builder setTotalThrustEstimate(double v) { + motor.totalImpulse = v; + return this; + } + + public Builder setAvailablity(boolean avail) { + motor.available = avail; + return this; + } + + public ThrustCurveMotor build() { + // Check argument validity + if ((motor.time.length != motor.thrust.length) || (motor.time.length != motor.cg.length)) { + throw new IllegalArgumentException("Array lengths do not match, " + + "time:" + motor.time.length + " thrust:" + motor.thrust.length + + " cg:" + motor.cg.length); + } + if (motor.time.length < 2) { + throw new IllegalArgumentException("Too short thrust-curve, length=" + motor.time.length); + } + for (int i = 0; i < motor.time.length - 1; i++) { + if (motor.time[i + 1] < motor.time[i]) { + throw new IllegalArgumentException("Time goes backwards, " + + "time[" + i + "]=" + motor.time[i] + " " + + "time[" + (i + 1) + "]=" + motor.time[i + 1]); + } + } + if (!MathUtil.equals(motor.time[0], 0)) { + throw new IllegalArgumentException("Curve starts at time " + motor.time[0]); + } + if (!MathUtil.equals(motor.thrust[0], 0)) { + throw new IllegalArgumentException("Curve starts at thrust " + motor.thrust[0]); + } + if (!MathUtil.equals(motor.thrust[motor.thrust.length - 1], 0)) { + throw new IllegalArgumentException("Curve ends at thrust " + + motor.thrust[motor.thrust.length - 1]); + } + for (double t : motor.thrust) { + if (t < 0) { + throw new IllegalArgumentException("Negative thrust."); + } + if (t > MAX_THRUST || Double.isNaN(t)) { + throw new IllegalArgumentException("Invalid thrust " + t); + } + } + for (Coordinate c : motor.cg) { + if (c.isNaN()) { + throw new IllegalArgumentException("Invalid CG " + c); + } + if (c.x < 0) { + throw new IllegalArgumentException("Invalid CG position " + String.format("%f", c.x) + ": CG is below the start of the motor."); + } + if (c.x > motor.length) { + throw new IllegalArgumentException("Invalid CG position: " + String.format("%f", c.x) + ": CG is above the end of the motor."); + } + if (c.weight < 0) { + throw new IllegalArgumentException("Negative mass " + c.weight + "at time=" + motor.time[Arrays.asList(motor.cg).indexOf(c)]); + } + } + + if (motor.type != Motor.Type.SINGLE && motor.type != Motor.Type.RELOAD && + motor.type != Motor.Type.HYBRID && motor.type != Motor.Type.UNKNOWN) { + throw new IllegalArgumentException("Illegal motor type=" + motor.type); + } + + + motor.computeStatistics(); + + return motor; + } } - /** - * 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 type the motor type - * @param delays the delays defined for this thrust curve - * @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, String digest) { - this.digest = digest; - // 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); - } - } - for (Coordinate c : cg) { - if (c.isNaN()) { - throw new IllegalArgumentException("Invalid CG " + c); - } - if (c.x < 0) { - throw new IllegalArgumentException("Invalid CG position " + String.format("%f", c.x) + ": CG is below the start of the motor."); - } - if (c.x > length) { - throw new IllegalArgumentException("Invalid CG position: " + String.format("%f", c.x) + ": CG is above the end of the motor."); - } - if (c.weight < 0) { - throw new IllegalArgumentException("Negative mass " + c.weight + "at time=" + time[Arrays.asList(cg).indexOf(c)]); - } - } - - if (type != Motor.Type.SINGLE && type != Motor.Type.RELOAD && - type != Motor.Type.HYBRID && type != Motor.Type.UNKNOWN) { - throw new IllegalArgumentException("Illegal motor type=" + type); - } - - - this.manufacturer = manufacturer; - this.designation = designation; - this.description = description; - this.type = type; - this.delays = delays.clone(); - this.diameter = diameter; - this.length = length; - this.time = time.clone(); - this.thrust = thrust.clone(); - this.cg = cg.clone(); - // this.cgx = new double[ cg.length]; - // this.mass = new double[ cg.length]; - // for (int cgIndex = 0; cgIndex < cg.length; ++cgIndex){ - // this.cgx[cgIndex] = cg[cgIndex].x; - // this.mass[cgIndex] = cg[cgIndex].weight; - // } - unitRotationalInertia = Inertia.filledCylinderRotational( this.diameter / 2); - unitLongitudinalInertia = Inertia.filledCylinderLongitudinal( this.diameter / 2, this.length); - - computeStatistics(); - - // This constructor is not called upon serialized data constructor. - //System.err.println("loading motor: "+designation); - } - - /** * Get the manufacturer of this motor. @@ -208,32 +242,6 @@ public class ThrustCurveMotor implements Motor, Comparable, Se return time.clone(); } - public String getCaseInfo() { - return caseInfo; - } - - public CaseInfo getCaseInfoEnum() { - return CaseInfo.parse(caseInfo); - } - - public CaseInfo[] getCompatibleCases() { - CaseInfo myCase = getCaseInfoEnum(); - if (myCase == null) { - return new CaseInfo[] {}; - } - return myCase.getCompatibleCases(); - } - - public String getPropellantInfo() { - return propellantInfo; - } - - - public double getInitialMass() { - return initialMass; - } - - /* * find the index to data that corresponds to the given time: * @@ -354,6 +362,32 @@ public class ThrustCurveMotor implements Motor, Comparable, Se + public String getCaseInfo() { + return caseInfo; + } + + public CaseInfo getCaseInfoEnum() { + return CaseInfo.parse(caseInfo); + } + + public CaseInfo[] getCompatibleCases() { + CaseInfo myCase = getCaseInfoEnum(); + if (myCase == null) { + return new CaseInfo[] {}; + } + return myCase.getCompatibleCases(); + } + + public String getPropellantInfo() { + return propellantInfo; + } + + + public double getInitialMass() { + return initialMass; + } + + /** * Returns the array of thrust points for this thrust curve. * @return an array of thrust samples @@ -450,11 +484,6 @@ public class ThrustCurveMotor implements Motor, Comparable, Se return length; } - @Override - public Motor clone() { - return new ThrustCurveMotor(this); - } - @Override public double getLaunchCGx() { return cg[0].x;//cgx[0]; @@ -526,7 +555,7 @@ public class ThrustCurveMotor implements Motor, Comparable, Se } public double getPropellantMass(){ - return (getLaunchMass() - getBurnoutMass()); + return propellantMass; } @Override @@ -750,5 +779,5 @@ public class ThrustCurveMotor implements Motor, Comparable, Se return value; } - + } diff --git a/core/src/net/sf/openrocket/thrustcurve/MotorBurnFile.java b/core/src/net/sf/openrocket/thrustcurve/MotorBurnFile.java index b20afe939..4f07c9551 100644 --- a/core/src/net/sf/openrocket/thrustcurve/MotorBurnFile.java +++ b/core/src/net/sf/openrocket/thrustcurve/MotorBurnFile.java @@ -35,11 +35,11 @@ public class MotorBurnFile { if (SupportedFileTypes.RASP_FORMAT.equals(filetype)) { RASPMotorLoader loader = new RASPMotorLoader(); List motors = loader.load(new StringReader(data), "download"); - this.thrustCurveMotor = motors.get(0); + this.thrustCurveMotor = (ThrustCurveMotor.Builder)motors.get(0); } else if (SupportedFileTypes.ROCKSIM_FORMAT.equals(filetype)) { RockSimMotorLoader loader = new RockSimMotorLoader(); List motors = loader.load(new StringReader(data), "download"); - this.thrustCurveMotor = motors.get(0); + this.thrustCurveMotor = (ThrustCurveMotor.Builder)motors.get(0); } } catch (IOException ex) { this.thrustCurveMotor = null; diff --git a/core/src/net/sf/openrocket/thrustcurve/SearchResponseParser.java b/core/src/net/sf/openrocket/thrustcurve/SearchResponseParser.java index 9d589cebe..3c8b08fe7 100644 --- a/core/src/net/sf/openrocket/thrustcurve/SearchResponseParser.java +++ b/core/src/net/sf/openrocket/thrustcurve/SearchResponseParser.java @@ -100,6 +100,9 @@ public class SearchResponseParser implements ElementHandler { } response.addMotor(currentMotor); break; + case matches: + this.response.setMatches(Integer.parseInt(content)); + break; case motor_id: currentMotor.setMotor_id(Integer.parseInt(content)); break; @@ -172,7 +175,7 @@ public class SearchResponseParser implements ElementHandler { } } - + @Override public void endHandler(String element, HashMap attributes, String content, WarningSet warnings) throws SAXException { } diff --git a/core/src/net/sf/openrocket/thrustcurve/SerializeThrustcurveMotors.java b/core/src/net/sf/openrocket/thrustcurve/SerializeThrustcurveMotors.java index 94dedc08b..87afda839 100644 --- a/core/src/net/sf/openrocket/thrustcurve/SerializeThrustcurveMotors.java +++ b/core/src/net/sf/openrocket/thrustcurve/SerializeThrustcurveMotors.java @@ -17,7 +17,6 @@ import net.sf.openrocket.file.motor.GeneralMotorLoader; import net.sf.openrocket.gui.util.SimpleFileFilter; import net.sf.openrocket.motor.Motor; import net.sf.openrocket.motor.ThrustCurveMotor; -import net.sf.openrocket.motor.ThrustCurveMotor.Builder; import net.sf.openrocket.util.Pair; public class SerializeThrustcurveMotors { @@ -130,11 +129,11 @@ public class SerializeThrustcurveMotors { builder.setPropellantMass(mi.getProp_mass_g() / 1000.0); } - builder.setCaseInfo(mi.getCase_info()) - .setPropellantInfo(mi.getProp_info()) - .setDiameter(mi.getDiameter() / 1000.0) - .setLength(mi.getLength() / 1000.0) - .setMotorType(type); + builder.setCaseInfo(mi.getCase_info()); + builder.setPropellantInfo(mi.getProp_info()); + builder.setDiameter(mi.getDiameter() / 1000.0); + builder.setLength(mi.getLength() / 1000.0); + builder.setMotorType(type); if ("OOP".equals(mi.getAvailiability())) { builder.setDesignation(mi.getDesignation()); @@ -183,9 +182,9 @@ public class SerializeThrustcurveMotors { String fileName = f.getU(); InputStream is = f.getV(); - List motors = loader.load(is, fileName); + List motors = loader.load(is, fileName); - for (Builder builder : motors) { + for (ThrustCurveMotor.Builder builder : motors) { allMotors.add(builder.build()); } } diff --git a/core/src/net/sf/openrocket/util/TestRockets.java b/core/src/net/sf/openrocket/util/TestRockets.java index e859efff0..8ef2316e2 100644 --- a/core/src/net/sf/openrocket/util/TestRockets.java +++ b/core/src/net/sf/openrocket/util/TestRockets.java @@ -88,97 +88,127 @@ public class TestRockets { // Minimal motor without any useful numbers data private static ThrustCurveMotor getTestMotor() { - return new ThrustCurveMotor( - Manufacturer.getManufacturer("A"), - "F12X", "Desc", Motor.Type.UNKNOWN, new double[] {}, - 0.024, 0.07, new double[] { 0, 1, 2 }, new double[] { 0, 1, 0 }, - new Coordinate[] { Coordinate.NUL, Coordinate.NUL, Coordinate.NUL }, "digestA"); + return new ThrustCurveMotor.Builder() + .setManufacturer(Manufacturer.getManufacturer("A")) + .setDesignation("F12X") + .setDescription("Desc") + .setMotorType(Motor.Type.UNKNOWN) + .setStandardDelays(new double[] {}) + .setDiameter(0.024) + .setLength(0.07) + .setTimePoints(new double[] { 0, 1, 2 }) + .setThrustPoints(new double[] { 0, 1, 0 }) + .setCGPoints(new Coordinate[] { Coordinate.NUL, Coordinate.NUL, Coordinate.NUL }) + .setDigest("digestA") + .build(); } // This function is used for unit, integration tests, DO NOT CHANGE (without updating tests). private static Motor generateMotor_A8_18mm(){ - // public ThrustCurveMotor(Manufacturer manufacturer, String designation, String description, - // Motor.Type type, double[] delays, double diameter, double length, - // double[] time, double[] thrust, - // Coordinate[] cg, String digest); - return new ThrustCurveMotor( - Manufacturer.getManufacturer("Estes"),"A8", " SU Black Powder", - Motor.Type.SINGLE, new double[] {0,3,5}, 0.018, 0.070, - new double[] { 0, 1, 2 }, new double[] { 0, 9, 0 }, - new Coordinate[] { - new Coordinate(0.035, 0, 0, 0.0164),new Coordinate(.035, 0, 0, 0.0145),new Coordinate(.035, 0, 0, 0.0131)}, - "digest A8 test"); + return new ThrustCurveMotor.Builder() + .setManufacturer(Manufacturer.getManufacturer("Estes")) + .setDesignation("A8") + .setDescription(" SU Black Powder") + .setMotorType(Motor.Type.SINGLE) + .setStandardDelays(new double[] {0,3,5}) + .setDiameter(0.018) + .setLength(0.070) + .setTimePoints(new double[] { 0, 1, 2 }) + .setThrustPoints(new double[] { 0, 9, 0 }) + .setCGPoints(new Coordinate[] { + new Coordinate(0.035, 0, 0, 0.0164),new Coordinate(.035, 0, 0, 0.0145),new Coordinate(.035, 0, 0, 0.0131)}) + .setDigest("digest A8 test") + .build(); } // This function is used for unit, integration tests, DO NOT CHANGE (without updating tests). private static Motor generateMotor_B4_18mm(){ - // public ThrustCurveMotor(Manufacturer manufacturer, String designation, String description, - // Motor.Type type, double[] delays, double diameter, double length, - // double[] time, double[] thrust, - // Coordinate[] cg, String digest); - return new ThrustCurveMotor( - Manufacturer.getManufacturer("Estes"),"B4", " SU Black Powder", - Motor.Type.SINGLE, new double[] {0,3,5}, 0.018, 0.070, - new double[] { 0, 1, 2 }, new double[] { 0, 11.4, 0 }, - new Coordinate[] { - new Coordinate(0.035, 0, 0, 0.0195),new Coordinate(.035, 0, 0, 0.0155),new Coordinate(.035, 0, 0, 0.013)}, - "digest B4 test"); + return new ThrustCurveMotor.Builder() + .setManufacturer(Manufacturer.getManufacturer("Estes")) + .setDesignation("B4") + .setDescription(" SU Black Powder") + .setMotorType(Motor.Type.SINGLE) + .setStandardDelays(new double[] {0,3,5}) + .setDiameter(0.018) + .setLength(0.070) + .setTimePoints(new double[] { 0, 1, 2 }) + .setThrustPoints(new double[] { 0, 11.4, 0 }) + .setCGPoints(new Coordinate[] { + new Coordinate(0.035, 0, 0, 0.0195),new Coordinate(.035, 0, 0, 0.0155),new Coordinate(.035, 0, 0, 0.013)}) + .setDigest("digest B4 test") + .build(); } // This function is used for unit, integration tests, DO NOT CHANGE (without updating tests). private static Motor generateMotor_C6_18mm(){ - // public ThrustCurveMotor(Manufacturer manufacturer, String designation, String description, - // Motor.Type type, double[] delays, double diameter, double length, - // double[] time, double[] thrust, - // Coordinate[] cg, String digest); - return new ThrustCurveMotor( - Manufacturer.getManufacturer("Estes"),"C6", " SU Black Powder", - Motor.Type.SINGLE, new double[] {0,3,5,7}, 0.018, 0.070, - new double[] { 0, 1, 2 }, new double[] { 0, 6, 0 }, - new Coordinate[] { - new Coordinate(0.035, 0, 0, 0.0227),new Coordinate(.035, 0, 0, 0.0165),new Coordinate(.035, 0, 0, 0.012)}, - "digest C6 test"); + return new ThrustCurveMotor.Builder() + .setManufacturer(Manufacturer.getManufacturer("Estes")) + .setDesignation("C6") + .setDescription(" SU Black Powder") + .setMotorType(Motor.Type.SINGLE) + .setStandardDelays(new double[] {0,3,5,7}) + .setDiameter(0.018) + .setLength(0.070) + .setTimePoints(new double[] { 0, 1, 2 }) + .setThrustPoints(new double[] { 0, 6, 0 }) + .setCGPoints(new Coordinate[] { + new Coordinate(0.035, 0, 0, 0.0227),new Coordinate(.035, 0, 0, 0.0165),new Coordinate(.035, 0, 0, 0.012)}) + .setDigest("digest C6 test") + .build(); } // This function is used for unit, integration tests, DO NOT CHANGE (without updating tests). private static Motor generateMotor_D21_18mm(){ - return new ThrustCurveMotor( - Manufacturer.getManufacturer("AeroTech"),"D21", "Desc", - Motor.Type.SINGLE, new double[] {}, 0.018, 0.07, - new double[] { 0, 1, 2 }, new double[] { 0, 32, 0 }, - new Coordinate[] { - new Coordinate(.035, 0, 0, 0.025),new Coordinate(.035, 0, 0, .020),new Coordinate(.035, 0, 0, 0.0154)}, - "digest D21 test"); + return new ThrustCurveMotor.Builder() + .setManufacturer(Manufacturer.getManufacturer("AeroTech")) + .setDesignation("D21") + .setDescription("Desc") + .setMotorType(Motor.Type.SINGLE) + .setStandardDelays(new double[] {}) + .setDiameter(0.018) + .setLength(0.070) + .setTimePoints(new double[] { 0, 1, 2 }) + .setThrustPoints(new double[] { 0, 32, 0 }) + .setCGPoints(new Coordinate[] { + new Coordinate(.035, 0, 0, 0.025),new Coordinate(.035, 0, 0, .020),new Coordinate(.035, 0, 0, 0.0154)}) + .setDigest("digest D21 test") + .build(); } // This function is used for unit, integration tests, DO NOT CHANGE (without updating tests). private static Motor generateMotor_M1350_75mm(){ - // public ThrustCurveMotor(Manufacturer manufacturer, String designation, String description, - // Motor.Type type, double[] delays, double diameter, double length, - // double[] time, double[] thrust, - // Coordinate[] cg, String digest); - return new ThrustCurveMotor( - Manufacturer.getManufacturer("AeroTech"),"M1350", "Desc", - Motor.Type.SINGLE, new double[] {}, 0.075, 0.622, - new double[] { 0, 1, 2 }, new double[] { 0, 1357, 0 }, - new Coordinate[] { - new Coordinate(.311, 0, 0, 4.808),new Coordinate(.311, 0, 0, 3.389),new Coordinate(.311, 0, 0, 1.970)}, - "digest M1350 test"); + return new ThrustCurveMotor.Builder() + .setManufacturer(Manufacturer.getManufacturer("AeroTech")) + .setDesignation("M1350") + .setDescription("Desc") + .setMotorType(Motor.Type.SINGLE) + .setStandardDelays(new double[] {}) + .setDiameter(0.075) + .setLength(0.622) + .setTimePoints(new double[] { 0, 1, 2 }) + .setThrustPoints(new double[] { 0, 1357, 0 }) + .setCGPoints(new Coordinate[] { + new Coordinate(.311, 0, 0, 4.808),new Coordinate(.311, 0, 0, 3.389),new Coordinate(.311, 0, 0, 1.970)}) + .setDigest("digest M1350 test") + .build(); } // This function is used for unit, integration tests, DO NOT CHANGE (without updating tests). private static Motor generateMotor_G77_29mm(){ - // public ThrustCurveMotor(Manufacturer manufacturer, String designation, String description, - // Motor.Type type, double[] delays, double diameter, double length, - // double[] time, double[] thrust, - // Coordinate[] cg, String digest); - return new ThrustCurveMotor( - Manufacturer.getManufacturer("AeroTech"),"G77", "Desc", - Motor.Type.SINGLE, new double[] {4,7,10},0.029, 0.124, - new double[] { 0, 1, 2 }, new double[] { 0, 1, 0 }, - new Coordinate[] { - new Coordinate(.062, 0, 0, 0.123),new Coordinate(.062, 0, 0, .0935),new Coordinate(.062, 0, 0, 0.064)}, - "digest G77 test"); + return new ThrustCurveMotor.Builder() + .setManufacturer(Manufacturer.getManufacturer("AeroTech")) + .setDesignation("G77") + .setDescription("Desc") + .setMotorType(Motor.Type.SINGLE) + .setStandardDelays(new double[] {4,7,10}) + .setDiameter(0.029) + .setLength(0.124) + .setTimePoints(new double[] { 0, 1, 2 }) + .setThrustPoints(new double[] { 0, 1, 0 }) + .setCGPoints(new Coordinate[] { + new Coordinate(.062, 0, 0, 0.123),new Coordinate(.062, 0, 0, .0935),new Coordinate(.062, 0, 0, 0.064)}) + .setDigest("digest G77 test") + .build(); } // diff --git a/core/src/net/sf/openrocket/utils/MotorCorrelation.java b/core/src/net/sf/openrocket/utils/MotorCorrelation.java index 009a6d45b..227ee7579 100644 --- a/core/src/net/sf/openrocket/utils/MotorCorrelation.java +++ b/core/src/net/sf/openrocket/utils/MotorCorrelation.java @@ -1,13 +1,5 @@ package net.sf.openrocket.utils; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.List; - -import net.sf.openrocket.file.motor.GeneralMotorLoader; -import net.sf.openrocket.file.motor.MotorLoader; import net.sf.openrocket.motor.Motor; import net.sf.openrocket.util.BugException; import net.sf.openrocket.util.MathUtil; @@ -85,47 +77,4 @@ public class MotorCorrelation { return cross / auto; } - - - - public static void main(String[] args) { - - MotorLoader loader = new GeneralMotorLoader(); - List motors = new ArrayList(); - List files = new ArrayList(); - - // Load files - for (String file : args) { - List m = null; - try { - InputStream stream = new FileInputStream(file); - m = loader.load(stream, file); - stream.close(); - } catch (IOException e) { - e.printStackTrace(); - System.exit(1); - } - if (m != null) { - motors.addAll(m); - for (int i = 0; i < m.size(); i++) - files.add(file); - } - } - - // Output motor digests - final int count = motors.size(); - for (int i = 0; i < count; i++) { - System.out.println(files.get(i) + ": " + ((Motor) motors.get(i)).getDigest()); - } - - // Cross-correlate every pair - for (int i = 0; i < count; i++) { - for (int j = i + 1; j < count; j++) { - System.out.println(files.get(i) + " " + files.get(j) + " : " + - crossCorrelation(motors.get(i), motors.get(j))); - } - } - - } - } \ No newline at end of file diff --git a/core/test/net/sf/openrocket/database/ThrustCurveMotorSetTest.java b/core/test/net/sf/openrocket/database/ThrustCurveMotorSetTest.java index 6198c45a5..bd17f6b70 100644 --- a/core/test/net/sf/openrocket/database/ThrustCurveMotorSetTest.java +++ b/core/test/net/sf/openrocket/database/ThrustCurveMotorSetTest.java @@ -20,29 +20,61 @@ import org.junit.Test; public class ThrustCurveMotorSetTest { - private static final ThrustCurveMotor motor1 = new ThrustCurveMotor( - Manufacturer.getManufacturer("A"), - "F12X", "Desc", Motor.Type.UNKNOWN, new double[] {}, - 0.024, 0.07, new double[] { 0, 1, 2 }, new double[] { 0, 1, 0 }, - new Coordinate[] { Coordinate.NUL, Coordinate.NUL, Coordinate.NUL }, "digestA"); + private static final ThrustCurveMotor motor1 = new ThrustCurveMotor.Builder() + .setManufacturer(Manufacturer.getManufacturer("A")) + .setDesignation("F12X") + .setDescription("Desc") + .setMotorType(Motor.Type.UNKNOWN) + .setStandardDelays(new double[] {}) + .setDiameter(0.024) + .setLength(0.07) + .setTimePoints(new double[] { 0, 1, 2 }) + .setThrustPoints(new double[] { 0, 1, 0 }) + .setCGPoints(new Coordinate[] { Coordinate.NUL, Coordinate.NUL, Coordinate.NUL }) + .setDigest("digestA") + .build(); - private static final ThrustCurveMotor motor2 = new ThrustCurveMotor( - Manufacturer.getManufacturer("A"), - "F12H", "Desc", Motor.Type.SINGLE, new double[] { 5 }, - 0.024, 0.07, new double[] { 0, 1, 2 }, new double[] { 0, 1, 0 }, - new Coordinate[] { Coordinate.NUL, Coordinate.NUL, Coordinate.NUL }, "digestB"); + private static final ThrustCurveMotor motor2 = new ThrustCurveMotor.Builder() + .setManufacturer(Manufacturer.getManufacturer("A")) + .setDesignation("F12H") + .setDescription("Desc") + .setMotorType(Motor.Type.SINGLE) + .setStandardDelays(new double[] { 5 }) + .setDiameter(0.024) + .setLength(0.07) + .setTimePoints(new double[] { 0, 1, 2 }) + .setThrustPoints(new double[] { 0, 1, 0 }) + .setCGPoints(new Coordinate[] { Coordinate.NUL, Coordinate.NUL, Coordinate.NUL }) + .setDigest("digestB") + .build(); - private static final ThrustCurveMotor motor3 = new ThrustCurveMotor( - Manufacturer.getManufacturer("A"), - "F12", "Desc", Motor.Type.UNKNOWN, new double[] { 0, Motor.PLUGGED_DELAY }, - 0.024, 0.07, new double[] { 0, 1, 2 }, new double[] { 0, 2, 0 }, - new Coordinate[] { Coordinate.NUL, Coordinate.NUL, Coordinate.NUL }, "digestC"); + private static final ThrustCurveMotor motor3 = new ThrustCurveMotor.Builder() + .setManufacturer(Manufacturer.getManufacturer("A")) + .setDesignation("F12") + .setDescription("Desc") + .setMotorType(Motor.Type.UNKNOWN) + .setStandardDelays(new double[] { 0, Motor.PLUGGED_DELAY }) + .setDiameter(0.024) + .setLength(0.07) + .setTimePoints(new double[] { 0, 1, 2 }) + .setThrustPoints(new double[] { 0, 2, 0 }) + .setCGPoints(new Coordinate[] { Coordinate.NUL, Coordinate.NUL, Coordinate.NUL }) + .setDigest("digestC") + .build(); - private static final ThrustCurveMotor motor4 = new ThrustCurveMotor( - Manufacturer.getManufacturer("A"), - "F12", "Desc", Motor.Type.HYBRID, new double[] { 0 }, - 0.024, 0.07, new double[] { 0, 1, 2 }, new double[] { 0, 2, 0 }, - new Coordinate[] { Coordinate.NUL, Coordinate.NUL, Coordinate.NUL }, "digestD"); + private static final ThrustCurveMotor motor4 = new ThrustCurveMotor.Builder() + .setManufacturer(Manufacturer.getManufacturer("A")) + .setDesignation("F12") + .setDesignation("Desc") + .setMotorType(Motor.Type.HYBRID) + .setStandardDelays(new double[] { 0 }) + .setDiameter(0.024) + .setLength(0.07) + .setTimePoints(new double[] { 0, 1, 2 }) + .setThrustPoints(new double[] { 0, 2, 0 }) + .setCGPoints(new Coordinate[] { Coordinate.NUL, Coordinate.NUL, Coordinate.NUL }) + .setDigest("digestD") + .build(); @Test diff --git a/core/test/net/sf/openrocket/file/motor/TestMotorLoader.java b/core/test/net/sf/openrocket/file/motor/TestMotorLoader.java index 8d1cc719a..3a603fc7e 100644 --- a/core/test/net/sf/openrocket/file/motor/TestMotorLoader.java +++ b/core/test/net/sf/openrocket/file/motor/TestMotorLoader.java @@ -10,6 +10,7 @@ import java.util.Arrays; import java.util.List; import net.sf.openrocket.motor.Motor; +import net.sf.openrocket.motor.ThrustCurveMotor; import org.junit.Test; @@ -52,7 +53,7 @@ public class TestMotorLoader { private void test(MotorLoader loader, String file, String... digests) throws IOException { - List motors; + List motors; InputStream is = this.getClass().getResourceAsStream(file); assertNotNull("File " + file + " not found", is); @@ -62,7 +63,7 @@ public class TestMotorLoader { String[] d = new String[digests.length]; for (int i = 0; i < motors.size(); i++) { - d[i] = ((Motor) motors.get(i)).getDigest(); + d[i] = motors.get(i).build().getDigest(); } Arrays.sort(digests); diff --git a/core/test/net/sf/openrocket/file/openrocket/OpenRocketSaverTest.java b/core/test/net/sf/openrocket/file/openrocket/OpenRocketSaverTest.java index 362d2c8a1..b1e2695aa 100644 --- a/core/test/net/sf/openrocket/file/openrocket/OpenRocketSaverTest.java +++ b/core/test/net/sf/openrocket/file/openrocket/OpenRocketSaverTest.java @@ -284,8 +284,8 @@ public class OpenRocketSaverTest { InputStream is = OpenRocketSaverTest.class.getResourceAsStream("/net/sf/openrocket/Estes_A8.rse"); assertNotNull("Problem in unit test, cannot find Estes_A8.rse", is); try { - for (Motor m : loader.load(is, "Estes_A8.rse")) { - return (ThrustCurveMotor) m; + for (ThrustCurveMotor.Builder m : loader.load(is, "Estes_A8.rse")) { + return m.build(); } is.close(); } catch (IOException e) { @@ -311,11 +311,19 @@ public class OpenRocketSaverTest { public MotorDbProvider() { db.addMotor(readMotor()); - db.addMotor( new ThrustCurveMotor( - Manufacturer.getManufacturer("A"), - "F12X", "Desc", Motor.Type.UNKNOWN, new double[] {}, - 0.024, 0.07, new double[] { 0, 1, 2 }, new double[] { 0, 1, 0 }, - new Coordinate[] { Coordinate.NUL, Coordinate.NUL, Coordinate.NUL }, "digestA")); + db.addMotor( new ThrustCurveMotor.Builder() + .setManufacturer(Manufacturer.getManufacturer("A")) + .setDesignation("F12X") + .setDescription("Desc") + .setMotorType(Motor.Type.UNKNOWN) + .setStandardDelays(new double[] {}) + .setDiameter(0.024) + .setLength(0.07) + .setTimePoints(new double[] { 0, 1, 2 }) + .setThrustPoints(new double[] { 0, 1, 0 }) + .setCGPoints(new Coordinate[] { Coordinate.NUL, Coordinate.NUL, Coordinate.NUL }) + .setDigest("digestA") + .build()); assertEquals(2, db.getMotorSets().size()); } diff --git a/core/test/net/sf/openrocket/motor/ThrustCurveMotorTest.java b/core/test/net/sf/openrocket/motor/ThrustCurveMotorTest.java index f6ccbe773..f2c93cfb4 100644 --- a/core/test/net/sf/openrocket/motor/ThrustCurveMotorTest.java +++ b/core/test/net/sf/openrocket/motor/ThrustCurveMotorTest.java @@ -16,49 +16,58 @@ public class ThrustCurveMotorTest { private final double radius = 0.025; private final double length = 0.10; - private final ThrustCurveMotor motorX6 = - new ThrustCurveMotor(Manufacturer.getManufacturer("foo"), - "X6", "Description of X6", Motor.Type.RELOAD, - new double[] {0, 2, Motor.PLUGGED_DELAY}, radius*2, length, - new double[] {0, 1, 3, 4}, // time - new double[] {0, 2, 3, 0}, // thrust - new Coordinate[] { + private final ThrustCurveMotor motorX6 = new ThrustCurveMotor.Builder() + .setManufacturer(Manufacturer.getManufacturer("foo")) + .setDesignation("X6") + .setDescription("Description of X6") + .setMotorType(Motor.Type.RELOAD) + .setStandardDelays(new double[] {0, 2, Motor.PLUGGED_DELAY}) + .setDiameter(radius*2) + .setLength(length) + .setTimePoints(new double[] {0, 1, 3, 4}) + .setThrustPoints(new double[] {0, 2, 3, 0}) + .setCGPoints(new Coordinate[] { new Coordinate(0.02,0,0,0.05), new Coordinate(0.02,0,0,0.05), new Coordinate(0.02,0,0,0.05), - new Coordinate(0.03,0,0,0.03) - }, "digestA"); + new Coordinate(0.03,0,0,0.03)}) + .setDigest("digestA") + .build(); private final double radiusA8 = 0.018; private final double lengthA8 = 0.10; - private final ThrustCurveMotor motorEstesA8_3 = - new ThrustCurveMotor(Manufacturer.getManufacturer("Estes"), - "A8-3", "A8 Test Motor", Motor.Type.SINGLE, - new double[] {0, 2, Motor.PLUGGED_DELAY}, radiusA8*2, lengthA8, - - new double[] { // time (sec) + private final ThrustCurveMotor motorEstesA8_3 = new ThrustCurveMotor.Builder() + .setManufacturer(Manufacturer.getManufacturer("Estes")) + .setDesignation("A8-3") + .setDescription("A8 Test Motor") + .setMotorType(Motor.Type.SINGLE) + .setStandardDelays(new double[] {0, 2, Motor.PLUGGED_DELAY}) + .setDiameter(radiusA8*2) + .setLength(lengthA8) + .setTimePoints(new double[] { 0, 0.041, 0.084, 0.127, 0.166, 0.192, 0.206, 0.226, 0.236, 0.247, 0.261, 0.277, 0.306, 0.351, 0.405, 0.467, 0.532, 0.589, 0.632, 0.652, - 0.668, 0.684, 0.703, 0.73}, - new double[] { // thrust (N) + 0.668, 0.684, 0.703, 0.73}) + .setThrustPoints(new double[] { 0, 0.512, 2.115, 4.358, 6.794, 8.588, 9.294, 9.73, 8.845, 7.179, 5.063, 3.717, 3.205, 2.884, 2.499, 2.371, 2.307, 2.371, 2.371, 2.243, - 1.794, 1.153, 0.448, 0}, - new Coordinate[] { /// ( m, m, m, kg) + 1.794, 1.153, 0.448, 0}) + .setCGPoints(new Coordinate[] { new Coordinate(0.0350, 0, 0, 0.016350),new Coordinate(0.0352, 0, 0, 0.016335),new Coordinate(0.0354, 0, 0, 0.016255),new Coordinate(0.0356, 0, 0, 0.016057), new Coordinate(0.0358, 0, 0, 0.015748),new Coordinate(0.0360, 0, 0, 0.015463),new Coordinate(0.0362, 0, 0, 0.015285),new Coordinate(0.0364, 0, 0, 0.015014), new Coordinate(0.0366, 0, 0, 0.014882),new Coordinate(0.0368, 0, 0, 0.014757),new Coordinate(0.0370, 0, 0, 0.014635),new Coordinate(0.0372, 0, 0, 0.014535), new Coordinate(0.0374, 0, 0, 0.014393),new Coordinate(0.0376, 0, 0, 0.014198),new Coordinate(0.0378, 0, 0, 0.013991),new Coordinate(0.0380, 0, 0, 0.013776), new Coordinate(0.0382, 0, 0, 0.013560),new Coordinate(0.0384, 0, 0, 0.013370),new Coordinate(0.0386, 0, 0, 0.013225),new Coordinate(0.0388, 0, 0, 0.013160), - new Coordinate(0.0390, 0, 0, 0.013114),new Coordinate(0.0392, 0, 0, 0.013080),new Coordinate(0.0394, 0, 0, 0.013059),new Coordinate(0.0396, 0, 0, 0.013050) - }, "digestA8-3"); + new Coordinate(0.0390, 0, 0, 0.013114),new Coordinate(0.0392, 0, 0, 0.013080),new Coordinate(0.0394, 0, 0, 0.013059),new Coordinate(0.0396, 0, 0, 0.013050)}) + .setDigest("digestA8-3") + .build(); @Test diff --git a/core/test/net/sf/openrocket/thrustcurve/SampleSearchResponse.xml b/core/test/net/sf/openrocket/thrustcurve/SampleSearchResponse.xml new file mode 100644 index 000000000..5fe7b95ff --- /dev/null +++ b/core/test/net/sf/openrocket/thrustcurve/SampleSearchResponse.xml @@ -0,0 +1,6387 @@ + + + + + manufacturer + AeroTech + 252 + + 252 + + + + 1036 + AeroTech + AeroTech + C3.4T + C3.4 + C3 + C + 18.0 + 72.0 + reload + National Association of Rocketry + 3.14 + 9.08 + 8.96 + 2.86 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=1036 + 23.9 + 5.2 + P + RMS-R/C-18/70 + Blue Thunder + 2014-07-22 + regular + + + 739 + AeroTech + AeroTech + D10W + D10 + D10 + D + 18.0 + 70.0 + SU + National Association of Rocketry + 13.39 + 25.13 + 18.75 + 1.4 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=739 + 25.9 + 9.8 + 3,5,7 + White Lightning + 2014-07-22 + regular + + + 33 + AeroTech + AeroTech + D13W + D13 + D13 + D + 18.0 + 70.0 + reload + National Association of Rocketry + 12.67 + 23.61 + 19.26 + 1.52 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=33 + 9.8 + 4,7,10 + RMS-R/C-18/70 + White Lightning + 2014-07-22 + regular + + + 34 + AeroTech + AeroTech + D15T + D15 + D15 + D + 24.0 + 70.0 + reload + National Association of Rocketry + 16.49 + 31.36 + 18.96 + 1.15 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=34 + 8.9 + 4,7 + RMS-24/40 + Blue Thunder + 2014-07-22 + regular + + + 1037 + AeroTech + AeroTech + D2.3T + D2.3 + D2 + D + 18.0 + 72.0 + reload + National Association of Rocketry + 2.12 + 10.14 + 17.21 + 8.14 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=1037 + 29.3 + 10.7 + P + RMS-R/C-18/70 + Blue Thunder + 2014-07-22 + regular + + + 35 + AeroTech + AeroTech + D21T + D21 + D21 + D + 18.0 + 70.0 + SU + National Association of Rocketry + 20.84 + 32.12 + 19.59 + 0.94 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=35 + 9.6 + 4,7 + Blue Thunder + 2014-07-22 + regular + + + 36 + AeroTech + AeroTech + D24T + D24 + D24 + D + 18.0 + 70.0 + reload + National Association of Rocketry + 14.77 + 25.52 + 18.02 + 1.22 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=36 + 32.0 + 8.7 + 4,7,10 + RMS-R/C-18/70 + Blue Thunder + 2014-07-22 + regular + + + 28 + AeroTech + AeroTech + D7-RCT + D7 + D7 + D + 24.0 + 70.0 + reload + National Association of Rocketry + 6.46 + 10.99 + 18.53 + 2.87 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=28 + 10.5 + RMS-R/C-24/20-40 + Blue Thunder + 2014-07-22 + regular + + + 29 + AeroTech + AeroTech + D9W + D9 + D9 + D + 24.0 + 70.0 + reload + National Association of Rocketry + 9.98 + 20.0 + 18.76 + 1.88 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=29 + 10.1 + 4,7 + RMS-24/40 + White Lightning + 2014-07-22 + regular + + + 505 + AeroTech + AeroTech + E11J + E11J + E11 + E + 24.0 + 70.0 + reload + National Association of Rocketry + 11.5689045936396 + 19.85 + 32.74 + 2.83 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=505 + 62.4 + 25.0 + 3 + RMS-24/40 + Blackjack + 2014-07-22 + regular + + + 44 + AeroTech + AeroTech + E12-RCJ + E12J + E12 + E + 24.0 + 70.0 + reload + National Association of Rocketry + 11.22 + 18.33 + 34.22 + 3.05 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=44 + 30.3 + RMS-R/C-24/20-40 + Blackjack + 2014-07-22 + regular + + + 45 + AeroTech + AeroTech + E15W + E15 + E15 + E + 24.0 + 70.0 + SU + National Association of Rocketry + 15.0 + 40.0 + 2.66666666666667 + 3 + http://www.thrustcurve.org/motorsearch.jsp?id=45 + 20.1 + 4,7,P + White Lightning + 2014-07-22 + regular + + + 48 + AeroTech + AeroTech + E16W + E16 + E16 + E + 29.0 + 124.0 + reload + National Association of Rocketry + 18.84 + 37.2 + 37.67 + 2.0 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=48 + 19.0 + 4,7 + RMS-29/40 + White Lightning + 2014-07-22 + regular + + + 49 + AeroTech + AeroTech + E18W + E18 + E18 + E + 24.0 + 70.0 + reload + National Association of Rocketry + 17.07 + 30.08 + 36.54 + 2.14 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=49 + 20.7 + 4,7 + RMS-24/40 + White Lightning + 2014-07-22 + regular + + + 782 + AeroTech + AeroTech + E20W + E20W + E20 + E + 24.0 + 70.0 + SU + National Association of Rocketry + 21.8 + 34.9 + 35.0 + 1.6 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=782 + 49.0 + 16.2 + 4,7 + White Lightning + 2014-07-22 + regular + + + 50 + AeroTech + AeroTech + E23T + E23 + E23 + E + 29.0 + 124.0 + reload + National Association of Rocketry + 22.5 + 38.22 + 35.32 + 1.57 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=50 + 17.4 + 5,8 + RMS-29/40 + Blue Thunder + 2014-07-22 + regular + + + 51 + AeroTech + AeroTech + E28T + E28 + E28 + E + 24.0 + 70.0 + reload + National Association of Rocketry + 32.53 + 50.52 + 39.69 + 1.22 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=51 + 18.4 + 4,7 + RMS-24/40 + Blue Thunder + 2014-07-22 + regular + + + 52 + AeroTech + AeroTech + E30T + E30 + E30 + E + 24.0 + 70.0 + SU + National Association of Rocketry + 32.38 + 48.27 + 39.51 + 1.22 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=52 + 19.3 + 4,7 + Blue Thunder + 2014-07-22 + regular + + + 37 + AeroTech + AeroTech + E6 + E6 + E6 + E + 24.0 + 70.0 + SU + National Association of Rocketry + 6.0 + 40.0 + 6.66666666666667 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=37 + 21.5 + 4,6,8,P + RMS 24/20-40 R/C + Blackjack + 2014-07-31 + OOP + + + 38 + AeroTech + AeroTech + E6-RCT + E6-RC + E6 + E + 24.0 + 70.0 + reload + National Association of Rocketry + 5.27 + 11.9 + 37.5 + 7.12 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=38 + 50.0 + 21.5 + RMS-R/C-24/20-40 + Blue Thunder + 2014-07-22 + regular + + + 39 + AeroTech + AeroTech + E7-RCT + E7 + E7 + E + 24.0 + 70.0 + reload + National Association of Rocketry + 5.41 + 11.58 + 29.35 + 5.43 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=39 + 17.1 + RMS-R/C-24/20-40 + Blue Thunder + 2014-07-22 + regular + + + 53 + AeroTech + AeroTech + F10 + F10 + F10 + F + 29.0 + 85.0 + SU + National Association of Rocketry + 10.71 + 28.22 + 76.33 + 7.13 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=53 + 40.7 + 4,6,8 + SU 29x85 + 2014-07-22 + OOP + + + 54 + AeroTech + AeroTech + F12J + F12 + F12 + F + 24.0 + 70.0 + reload + National Association of Rocketry + 14.74 + 23.54 + 43.2 + 2.93 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=54 + 30.3 + 3,5 + RMS-24/40 + Blackjack + 2014-07-22 + regular + + + 55 + AeroTech + AeroTech + F13-RCT + F13-RC + F13 + F + 32.0 + 107.0 + reload + National Association of Rocketry + 12.17 + 19.98 + 62.07 + 5.1 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=55 + 32.3 + RMS-R/C-32/60-100 + Blue Thunder + 2014-07-22 + regular + + + 56 + AeroTech + AeroTech + F16-RCJ + F16-RC + F16 + F + 32.0 + 107.0 + reload + National Association of Rocketry + 13.27 + 26.35 + 75.48 + 5.69 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=56 + 62.5 + RMS-R/C-32/60-100 + Blackjack + 2014-07-22 + regular + + + 57 + AeroTech + AeroTech + F20W/L + F20 + F20 + F + 29.0 + 83.0 + SU + National Association of Rocketry + 20.8 + 40.33 + 51.75 + 2.49 + 3 + http://www.thrustcurve.org/motorsearch.jsp?id=57 + 80.2 + 30.0 + 4,7 + White Lightning + 2014-09-23 + regular + + + 58 + AeroTech + AeroTech + F21W + F21W + F21 + F + 24.0 + 95.0 + SU + Tripoli Rocketry Association, Inc. + 21.0 + 42.0 + 55.0 + 2.5 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=58 + 64.0 + 30.0 + 4,6,8 + SU 24x95 + White Lightning + 2014-07-22 + OOP + + + 59 + AeroTech + AeroTech + F22J + F22 + F22 + F + 29.0 + 124.0 + reload + National Association of Rocketry + 19.64 + 31.15 + 65.0 + 3.31 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=59 + 46.3 + 5,7 + RMS-29/40 + Blackjack + 2014-07-22 + regular + + + 61 + AeroTech + AeroTech + F23-RCW-SK + F23-RC-SK + F23 + F + 32.0 + 107.0 + reload + National Association of Rocketry + 23.0 + 70.0 + 3.47 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=61 + 37.8 + RMS-R/C-32/60-100 + White Lightning + 2014-07-22 + regular + + + 60 + AeroTech + AeroTech + F23FJ/L + F23FJ + F23 + F + 29.0 + 83.0 + SU + National Association of Rocketry + 18.58 + 29.8 + 41.2 + 2.21 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=60 + 82.3 + 30.0 + 4,7 + Fast Blackjack + 2014-07-22 + regular + + + 63 + AeroTech + AeroTech + F24W + F24 + F24 + F + 24.0 + 70.0 + reload + National Association of Rocketry + 22.21 + 40.95 + 47.31 + 2.13 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=63 + 19.0 + 4,7 + RMS-24/40 + White Lightning + 2014-07-22 + regular + + + 64 + AeroTech + AeroTech + F25W + F25W + F25 + F + 29.0 + 98.0 + SU + National Association of Rocketry + 25.55 + 46.79 + 77.92 + 3.05 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=64 + 35.6 + 4,6,9 + White Lightning + 2014-07-22 + regular + + + 65 + AeroTech + AeroTech + F26FJ + F26FJ + F26 + F + 29.0 + 98.0 + SU + National Association of Rocketry + 26.0 + 62.2 + 2.39230769230769 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=65 + 43.1 + 6,9 + Fast Blackjack + 2014-07-22 + regular + + + 468 + AeroTech + AeroTech + F27R/L + F27R + F27 + F + 29.0 + 83.0 + SU + National Association of Rocketry + 24.4 + 37.7 + 49.6 + 2.03 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=468 + 28.4 + 4,8 + Redline + 2014-07-22 + regular + + + 944 + AeroTech + AeroTech + F30FJ + F30FJ + F30 + F + 24.0 + 95.0 + SU + National Association of Rocketry + 30.4 + 40.6 + 47.0 + 1.54605263157895 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=944 + 31.2 + 4,6,8 + Fast Blackjack + 2014-07-22 + regular + + + 593 + AeroTech + AeroTech + F32T + F32T + F32 + F + 24.0 + 95.0 + SU + National Association of Rocketry + 34.1 + 61.3 + 56.9 + 1.659 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=593 + 64.0 + 31.0 + 4,6,8 + Blue Thunder + 2014-07-22 + regular + + + 66 + AeroTech + AeroTech + F32W + F32W + F32 + F + 24.0 + 95.0 + SU + National Association of Rocketry + 29.12 + 55.64 + 79.2 + 2.72 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=66 + 37.7 + 5,10,15 + SU 24x95 + White Lightning + 2014-07-22 + OOP + + + 559 + AeroTech + AeroTech + F35W + F35W + F35 + F + 24.0 + 95.0 + reload + National Association of Rocketry + 34.9 + 55.2 + 57.1 + 1.63 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=559 + 85.0 + 30.0 + 5,8,11 + RMS-24/60 + White Lightning + 2014-07-22 + regular + + + 69 + AeroTech + AeroTech + F37W + F37 + F37 + F + 29.0 + 99.0 + reload + National Association of Rocketry + 31.67 + 46.47 + 50.67 + 1.6 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=69 + 28.2 + M + RMS-29/60 + White Lightning + 2014-07-22 + regular + + + 70 + AeroTech + AeroTech + F39T + F39 + F39 + F + 24.0 + 70.0 + reload + National Association of Rocketry + 37.34 + 59.47 + 49.66 + 1.33 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=70 + 22.7 + 6,9 + RMS-24/40 + Blue Thunder + 2014-07-22 + regular + + + 71 + AeroTech + AeroTech + F40W + F40 + F40 + F + 29.0 + 124.0 + reload + National Association of Rocketry + 37.91 + 68.07 + 78.09 + 2.06 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=71 + 40.0 + 4,7,10 + RMS-29/40 + White Lightning + 2014-07-22 + regular + + + 72 + AeroTech + AeroTech + F42T/L + F42T + F42 + F + 29.0 + 83.0 + SU + National Association of Rocketry + 42.0 + 52.9 + 1.25952380952381 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=72 + 27.0 + 4,8 + Blue Thunder + 2014-07-22 + regular + + + 1023 + AeroTech + AeroTech + F44W + AT + F44 + F + 24.0 + 70.0 + SU + National Association of Rocketry + 44.0 + 50.0 + 41.5 + 1.0 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=1023 + 48.0 + 19.7 + 4,8 + White Lightning + 2014-07-22 + regular + + + 73 + AeroTech + AeroTech + F50T + F50 + F50 + F + 29.0 + 98.0 + SU + National Association of Rocketry + 53.73 + 79.59 + 76.83 + 1.43 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=73 + 37.9 + 4,6,9 + Blue Thunder + 2014-07-22 + regular + + + 75 + AeroTech + AeroTech + F52T + F52 + F52 + F + 29.0 + 124.0 + reload + National Association of Rocketry + 51.37 + 78.95 + 72.95 + 1.42 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=75 + 36.6 + 5,8,11 + RMS-29/40 + Blue Thunder + 2014-07-22 + regular + + + 77 + AeroTech + AeroTech + F62T + F62T + F62 + F + 29.0 + 89.0 + reload + Tripoli Rocketry Association, Inc. + 62.0 + 56.5 + 51.0 + 1.13 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=77 + 109.0 + 30.5 + M + RMS-29/60 + Blue Thunder + 2014-07-22 + regular + + + 78 + AeroTech + AeroTech + F72 + F72 + F72 + F + 24.0 + 124.0 + SU + National Association of Rocketry + 61.92 + 98.78 + 74.92 + 1.21 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=78 + 36.8 + 5,10,15 + SU 24x124 + 2014-07-22 + OOP + + + 108 + AeroTech + AeroTech + G101T + G101T + G101 + G + 29.0 + 125.0 + reload + Tripoli Rocketry Association, Inc. + 101.0 + 102.3 + 85.0 + 1.0 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=108 + 46.0 + S,M,L + RMS-29/100 + Blue Thunder + 2016-01-17 + OOP + + + 109 + AeroTech + AeroTech + G104T + G104T + G104 + G + 29.0 + 125.0 + reload + Tripoli Rocketry Association, Inc. + 104.0 + 113.8 + 81.5 + 1.0 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=109 + 136.0 + 43.9 + M + RMS-29/100 + Blue Thunder + 2014-07-22 + regular + + + 80 + AeroTech + AeroTech + G12-RCT + G12-RC + G12 + G + 32.0 + 107.0 + reload + National Association of Rocketry + 10.2 + 20.64 + 87.22 + 8.55 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=80 + 51.1 + RMS-R/C-32/60-100 + Blue Thunder + 2014-07-22 + regular + + + 1017 + AeroTech + AeroTech + G125T + G125T + G125 + G + 29.0 + 124.0 + SU + Tripoli Rocketry Association, Inc. + 125.0 + 160.0 + 128.0 + 0.95 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=1017 + 125.0 + 59.6 + 0-14 + Blue Thunder + 2014-07-22 + regular + + + 583 + AeroTech + AeroTech + G142T + G142 + G142 + G + 29.0 + 113.0 + SU + National Association of Rocketry + 135.9 + 173.9 + 84.3 + 0.618 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=583 + 98.0 + 44.0 + 6,10,14 + SU 29x113 + Blue Thunder + 2014-07-22 + OOP + + + 82 + AeroTech + AeroTech + G25W + G25 + G25 + G + 29.0 + 124.0 + reload + National Association of Rocketry + 22.17 + 41.18 + 117.5 + 5.3 + 3 + http://www.thrustcurve.org/motorsearch.jsp?id=82 + 62.5 + 0-10 + RMS-29/120 + White Lightning + 2014-07-22 + regular + + + 83 + AeroTech + AeroTech + G33 + G33 + G33 + G + 29.0 + 124.0 + reload + National Association of Rocketry + 30.09 + 50.92 + 98.39 + 3.27 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=83 + 72.2 + 5,7 + RMS-29/40-120 + 2016-01-17 + OOP + + + 459 + AeroTech + AeroTech + G339N + G339N-P + G339 + G + 38.0 + 97.0 + reload + Tripoli Rocketry Association, Inc. + 307.53 + 503.51 + 108.9 + 0.35 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=459 + 49.0 + P + RMS-38/120 + Warp-9 + 2014-07-22 + regular + + + 84 + AeroTech + AeroTech + G35 + G35 + G35 + G + 29.0 + 98.0 + SU + National Association of Rocketry + 34.65 + 76.22 + 100.82 + 2.91 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=84 + 50.0 + 4,7 + SU 29x98 + 2014-07-22 + OOP + + + 87 + AeroTech + AeroTech + G38FJ + G38FJ + G38 + G + 29.0 + 124.0 + SU + National Association of Rocketry + 40.22 + 78.19 + 87.68 + 2.18 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=87 + 55.0 + 4,7 + Fast Blackjack + 2014-07-22 + regular + + + 89 + AeroTech + AeroTech + G40W + G40W + G40 + G + 29.0 + 124.0 + SU + National Association of Rocketry + 37.17 + 66.85 + 113.74 + 3.06 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=89 + 62.4 + 4,7,10 + White Lightning + 2014-07-22 + regular + + + 482 + AeroTech + AeroTech + G53FJ + G53FJ + G53 + G + 29.0 + 124.0 + reload + National Association of Rocketry + 53.1 + 87.3 + 90.9 + 1.71 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=482 + 146.0 + 60.0 + 5,7,10 + RMS-29/40 + Fast Blackjack + 2014-07-22 + regular + + + 90 + AeroTech + AeroTech + G54W + G54 + G54 + G + 29.0 + 124.0 + reload + National Association of Rocketry + 53.68 + 81.64 + 81.05 + 1.51 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=90 + 46.0 + M + RMS-29/100 + White Lightning + 2014-07-22 + regular + + + 91 + AeroTech + AeroTech + G55 + G55 + G55 + G + 24.0 + 177.0 + SU + National Association of Rocketry + 49.0 + 84.65 + 119.57 + 2.44 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=91 + 62.5 + 5,10,15 + SU 24x177 + 2014-07-22 + OOP + + + 94 + AeroTech + AeroTech + G61W + G61W + G61 + G + 38.0 + 106.0 + reload + Tripoli Rocketry Association, Inc. + 61.0 + 63.2 + 110.5 + 2.04 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=94 + 194.0 + 62.3 + M + RMS-38/120 + White Lightning + 2014-07-22 + regular + + + 96 + AeroTech + AeroTech + G64W + G64 + G64 + G + 29.0 + 124.0 + reload + National Association of Rocketry + 56.84 + 98.31 + 118.8 + 2.09 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=96 + 151.0 + 62.5 + 4,7,10 + RMS-29/40 + White Lightning + 2014-07-22 + regular + + + 97 + AeroTech + AeroTech + G67R + G67R + G67 + G + 38.0 + 106.0 + reload + Tripoli Rocketry Association, Inc. + 67.0 + 110.0 + 1.64179104477612 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=97 + 201.0 + 60.0 + M + RMS-38/120 + Redline + 2014-07-22 + regular + + + 469 + AeroTech + AeroTech + G69N + G69N + G69 + G + 38.0 + 106.0 + reload + National Association of Rocketry + 72.3 + 87.3 + 136.7 + 1.88 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=469 + 62.2 + P + RMS-38/120 + Warp-9 + 2014-07-22 + regular + + + 464 + AeroTech + AeroTech + G71R + G71R + G71 + G + 29.0 + 124.0 + reload + National Association of Rocketry + 71.0 + 117.0 + 107.0 + 1.51 + 3 + http://www.thrustcurve.org/motorsearch.jsp?id=464 + 147.0 + 64.0 + 4, 7, 10 + RMS-29/40-120 + Redline + 2016-01-17 + OOP + + + 1024 + AeroTech + AeroTech + G74W + AT + G74 + G + 29.0 + 93.0 + SU + National Association of Rocketry + 74.0 + 95.0 + 82.75 + 1.1 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=1024 + 87.0 + 39.3 + 6,8 + White Lightning + 2014-09-02 + regular + + + 100 + AeroTech + AeroTech + G75J + G75J + G75 + G + 29.0 + 194.0 + reload + Tripoli Rocketry Association, Inc. + 75.0 + 70.3 + 135.6 + 2.43 + 5 + http://www.thrustcurve.org/motorsearch.jsp?id=100 + 232.96 + 104.3 + M + RMS-29/180 + Blackjack + 2014-07-22 + regular + + + 532 + AeroTech + AeroTech + G76G + G76G + G76 + G + 29.0 + 124.0 + reload + National Association of Rocketry + 76.0 + 196.0 + 118.0 + 1.5 + 3 + http://www.thrustcurve.org/motorsearch.jsp?id=532 + 147.0 + 60.0 + 4,7,10 + RMS-29/40 + Mojave Green + 2014-07-22 + regular + + + 101 + AeroTech + AeroTech + G77R + G77R + G77 + G + 29.0 + 150.0 + reload + Tripoli Rocketry Association, Inc. + 77.0 + 105.0 + 1.36363636363636 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=101 + 165.0 + 58.0 + M + RMS-29/120 + Redline + 2014-07-22 + regular + + + 582 + AeroTech + AeroTech + G77R/L + G77R + G77 + G + 29.0 + 124.0 + SU + National Association of Rocketry + 80.12 + 100.5 + 102.86 + 1.28 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=582 + 122.5 + 64.0 + 4,7,10 + Redline + 2014-07-22 + regular + + + 560 + AeroTech + AeroTech + G78G/L + G78G + G78 + G + 29.0 + 124.0 + SU + National Association of Rocketry + 79.9 + 101.9 + 109.94 + 1.378 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=560 + 125.0 + 59.7 + 4,7,10 + Mojave Green + 2014-07-22 + regular + + + 103 + AeroTech + AeroTech + G79W + G79W + G79 + G + 29.0 + 150.0 + reload + Tripoli Rocketry Association, Inc. + 79.0 + 100.74 + 108.56 + 1.42 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=103 + 157.0 + 62.0 + M + RMS-29/120 + White Lightning + 2014-07-22 + regular + + + 581 + AeroTech + AeroTech + G79W/L + G79W + G79 + G + 29.0 + 124.0 + SU + National Association of Rocketry + 72.6 + 93.9 + 108.3 + 1.5 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=581 + 124.0 + 65.0 + 4,7,10 + White Lightning + 2014-07-22 + regular + + + 104 + AeroTech + AeroTech + G80T + G80 + G80 + G + 29.0 + 124.0 + SU + National Association of Rocketry + 86.71 + 117.945 + 132.17 + 1.53 + 5 + http://www.thrustcurve.org/motorsearch.jsp?id=104 + 127.9 + 62.5 + 7,10,13,0-14 + Blue Thunder + 2014-07-22 + regular + + + 1088 + AeroTech + AeroTech + H100W DMS + + H100 + H + 38.0 + 153.1 + SU + Tripoli Rocketry Association, Inc. + 97.7 + 137.75 + 226.8 + 2.32 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=1088 + 261.0 + 121.0 + 10 + DMS + White Lightning + 2015-08-07 + regular + + + 126 + AeroTech + AeroTech + H112J + H112J + H112 + H + 38.0 + 191.0 + reload + Tripoli Rocketry Association, Inc. + 112.0 + 121.7 + 261.1 + 2.92 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=126 + 379.456 + 191.2 + M + RMS-38/360 + Blackjack + 2014-07-22 + regular + + + 128 + AeroTech + AeroTech + H123W + H123W + H123 + H + 38.0 + 152.0 + reload + Tripoli Rocketry Association, Inc. + 123.0 + 174.2 + 223.6 + 1.76 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=128 + 275.0 + 128.7 + M + RMS-38/240 + White Lightning + 2014-07-22 + regular + + + 130 + AeroTech + AeroTech + H125W + H125W + H125 + H + 29.0 + 330.0 + SU + Tripoli Rocketry Association, Inc. + 125.0 + 307.0 + 299.4 + 2.6 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=130 + 322.56 + 187.9 + S,M,L + SU 29x330 + White Lightning + 2014-07-22 + OOP + + + 131 + AeroTech + AeroTech + H128W + H128W + H128 + H + 29.0 + 194.0 + reload + Tripoli Rocketry Association, Inc. + 128.0 + 168.7 + 172.9 + 1.27 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=131 + 206.0 + 94.2 + M + RMS-29/180 + White Lightning + 2014-07-22 + regular + + + 1090 + AeroTech + AeroTech + H130W + + H130 + H + 38.0 + 152.0 + reload + Tripoli Rocketry Association, Inc. + 130.0 + 260.0 + 210.0 + 1.65 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=1090 + 237.0 + 120.0 + 6-8-10-12-14 + 28/240 + White Lightning + 2016-03-20 + regular + + + 135 + AeroTech + AeroTech + H148R + H148R + H148 + H + 38.0 + 152.0 + reload + Tripoli Rocketry Association, Inc. + 148.0 + 206.0 + 1.39189189189189 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=135 + 309.12 + 122.0 + M + RMS-38/240 + Redline + 2014-07-22 + regular + + + 138 + AeroTech + AeroTech + H165R + H165R + H165 + H + 29.0 + 194.0 + reload + Tripoli Rocketry Association, Inc. + 165.0 + 165.0 + 1.0 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=138 + 201.6 + 90.0 + M + RMS-29/180 + Redline + 2014-07-22 + regular + + + 903 + AeroTech + AeroTech + H170M + AT, Aerotech, ISP, RCS + H170 + H + 38.0 + 191.0 + reload + Tripoli Rocketry Association, Inc. + 166.8 + 208.0 + 319.9 + 1.91 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=903 + 330.0 + 182.5 + 0-14 + RMS-38/360 + Metalstorm + 2014-07-22 + regular + + + 965 + AeroTech + AeroTech + H178DM + H178DM-14A + H178 + H + 38.0 + 191.0 + reload + Tripoli Rocketry Association, Inc. + 162.0 + 202.0 + 283.0 + 1.74 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=965 + 324.0 + 177.0 + 0-14 + RMS-38/360 + Dark Matter + 2014-07-22 + regular + + + 139 + AeroTech + AeroTech + H180W + H180W + H180 + H + 29.0 + 238.0 + reload + Tripoli Rocketry Association, Inc. + 180.0 + 228.5 + 217.7 + 1.3 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=139 + 252.0 + 123.9 + M + RMS-29/240 + White Lightning + 2014-07-22 + regular + + + 140 + AeroTech + AeroTech + H210R + H210R + H210 + H + 29.0 + 238.0 + reload + National Association of Rocketry + 215.41 + 275.73 + 215.41 + 1.0 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=140 + 246.4 + 106.4 + M + RMS-29/240 + Redline + 2014-07-22 + regular + + + 142 + AeroTech + AeroTech + H220T + H220T + H220 + H + 29.0 + 238.0 + reload + National Association of Rocketry + 220.0 + 220.0 + 1.0 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=142 + 106.4 + M + RMS-29/240 + Blue Thunder + 2014-07-22 + regular + + + 144 + AeroTech + AeroTech + H238T + H238T + H238 + H + 29.0 + 194.0 + reload + Tripoli Rocketry Association, Inc. + 238.0 + 263.4 + 165.5 + 0.71 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=144 + 196.0 + 83.4 + M + RMS-29/180 + Blue Thunder + 2014-07-22 + regular + + + 145 + AeroTech + AeroTech + H242T + H242T + H242 + H + 38.0 + 152.0 + reload + Tripoli Rocketry Association, Inc. + 242.0 + 276.6 + 231.7 + 1.06 + 7 + http://www.thrustcurve.org/motorsearch.jsp?id=145 + 264.0 + 114.7 + M + RMS-38/240 + Blue Thunder + 2014-07-22 + regular + + + 483 + AeroTech + AeroTech + H250G + H250G + H250 + H + 29.0 + 238.0 + reload + Tripoli Rocketry Association, Inc. + 250.0 + 231.0 + 0.9 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=483 + 256.0 + 116.3 + M + RMS-29/240 + Mojave Green + 2014-07-22 + regular + + + 147 + AeroTech + AeroTech + H268R + H268R + H268 + H + 29.0 + 333.0 + reload + National Association of Rocketry + 268.0 + 320.0 + 1.19402985074627 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=147 + 358.4 + 166.0 + M + RMS-29/360 + Redline + 2014-07-22 + regular + + + 115 + AeroTech + AeroTech + H45W + H45W + H45 + H + 38.0 + 194.0 + SU + Tripoli Rocketry Association, Inc. + 45.0 + 102.0 + 289.0 + 6.0 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=115 + 294.784 + 197.4 + 10,15 + SU 38x194 + White Lightning + 2014-07-22 + OOP + + + 118 + AeroTech + AeroTech + H55W + H55W + H55 + H + 29.0 + 191.0 + SU + Tripoli Rocketry Association, Inc. + 55.0 + 113.3 + 162.3 + 2.45 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=118 + 188.16 + 99.7 + 6,10,14 + SU 29x191 + White Lightning + 2014-07-22 + OOP + + + 155 + AeroTech + AeroTech + H669N + H669N + H669 + H + 38.0 + 152.0 + reload + Tripoli Rocketry Association, Inc. + 651.4 + 961.5 + 221.0 + 0.339 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=155 + 98.0 + P + RMS-38/240 + Warp-9 + 2014-07-22 + regular + + + 121 + AeroTech + AeroTech + H70W + H70W + H70 + H + 29.0 + 229.0 + SU + Tripoli Rocketry Association, Inc. + 70.0 + 174.0 + 215.0 + 2.0 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=121 + 224.0 + 126.0 + 6,10,14 + SU 29x229 + White Lightning + 2014-07-22 + OOP + + + 122 + AeroTech + AeroTech + H73J + H73J + H73 + H + 38.0 + 152.0 + reload + Tripoli Rocketry Association, Inc. + 73.0 + 97.1 + 185.6 + 2.55 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=122 + 309.12 + 142.7 + M + RMS-38/240 + Blackjack + 2014-07-22 + regular + + + 124 + AeroTech + AeroTech + H97J + H97J + H97 + H + 29.0 + 238.0 + reload + Tripoli Rocketry Association, Inc. + 97.0 + 111.5 + 177.3 + 2.23 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=124 + 277.76 + 137.1 + M + RMS-29/240 + Blackjack + 2014-07-22 + regular + + + 156 + AeroTech + AeroTech + H999N + H999 + H999 + H + 38.0 + 203.0 + reload + Tripoli Rocketry Association, Inc. + 999.0 + 319.9 + 0.32022022022022 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=156 + 147.0 + P + RMS-38/360 + Warp-9 + 2014-07-22 + regular + + + 945 + AeroTech + AeroTech + HP-G138T + G138T + G138 + G + 29.0 + 124.0 + reload + National Association of Rocketry + 138.0 + 190.1 + 157.1 + 1.13840579710145 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=945 + 70.0 + 0-14 + RMS-29/40 + Blue Thunder + 2014-07-22 + regular + + + 902 + AeroTech + AeroTech + HP-G75M + Aerotech, AT, ISP + G75 + G + 29.0 + 123.9 + SU + Tripoli Rocketry Association, Inc. + 74.74 + 102.0 + 120.39 + 1.61 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=902 + 131.0 + 66.8 + 4,7,10 + Metalstorm + 2014-07-22 + regular + + + 1018 + AeroTech + AeroTech + HP-H115DM + H115DM + H115 + H + 29.0 + 203.0 + SU + Tripoli Rocketry Association, Inc. + 115.0 + 126.0 + 172.0 + 1.5 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=1018 + 205.0 + 113.0 + 0-14 + Dark Matter + 2014-07-22 + regular + + + 1009 + AeroTech + AeroTech + HP-H135W + H135W + H135 + H + 29.0 + 216.0 + SU + Tripoli Rocketry Association, Inc. + 115.86 + 159.88 + 225.84 + 1.95 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=1009 + 212.0 + 82.0 + 0-14 + White Lightning + 2014-07-22 + regular + + + 1029 + AeroTech + AeroTech + HP-H182R + H182R-14A + H182 + H + 29.0 + 203.0 + SU + Tripoli Rocketry Association, Inc. + 182.0 + 192.0 + 218.0 + 1.2 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=1029 + 207.0 + 115.0 + 0-14 + Redline + 2014-07-22 + regular + + + 1011 + AeroTech + AeroTech + HP-H195NT + H195NT + H195 + H + 29.0 + 203.0 + SU + Tripoli Rocketry Association, Inc. + 206.676 + 247.1561 + 236.0919 + 1.14 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=1011 + 197.0 + 115.0 + 0-14 + Blue Thunder + 2014-07-22 + regular + + + 1031 + AeroTech + AeroTech + HP-H45W + H45W-10A + H45 + H + 38.0 + 203.0 + SU + Tripoli Rocketry Association, Inc. + 45.0 + 87.0 + 320.0 + 6.0 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=1031 + 365.0 + 180.0 + 0-10 + White Lightning + 2014-07-31 + regular + + + 1074 + AeroTech + AeroTech + HP-H550ST + + H550 + H + 38.0 + 206.0 + SU + Tripoli Rocketry Association, Inc. + 552.0 + 640.0 + 312.0 + 0.56 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=1074 + 316.0 + 176.0 + 14 + 38 DMS + Super Thunder + 2014-08-02 + regular + + + 1013 + AeroTech + AeroTech + HP-I140W + I140W + I140 + I + 38.0 + 202.7 + SU + Tripoli Rocketry Association, Inc. + 140.0 + 181.0 + 336.0 + 2.4 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=1013 + 356.0 + 183.0 + 0-14 + White Lightning + 2014-07-31 + regular + + + 1030 + AeroTech + AeroTech + HP-I205W + I205W-14A + I205 + I + 29.0 + 305.0 + SU + Tripoli Rocketry Association, Inc. + 205.0 + 253.0 + 345.0 + 1.7 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=1030 + 315.0 + 188.0 + 0-14 + White Lightning + 2014-07-22 + regular + + + 1014 + AeroTech + AeroTech + HP-I280DM + AT + I280 + I + 38.0 + 356.4 + SU + Tripoli Rocketry Association, Inc. + 280.0 + 386.0 + 561.0 + 1.9 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=1014 + 616.0 + 355.0 + 0-14 + Dark Matter + 2014-07-31 + regular + + + 1019 + AeroTech + AeroTech + HP-I500T + I500T + I500 + I + 38.0 + 356.0 + SU + Tripoli Rocketry Association, Inc. + 500.0 + 138.0 + 620.0 + 1.24 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=1019 + 576.0 + 312.0 + 0-14 + Blue Thunder + 2014-07-31 + regular + + + 1033 + AeroTech + AeroTech + HP-I65W + I65W-10A + I65 + I + 54.0 + 218.0 + SU + Tripoli Rocketry Association, Inc. + 65.0 + 178.0 + 640.0 + 9.0 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=1033 + 752.0 + 377.0 + 0-10 + White Lightning + 2014-07-31 + regular + + + 1015 + AeroTech + AeroTech + HP-J270W + AT + J270 + J + 38.0 + 356.4 + SU + Tripoli Rocketry Association, Inc. + 270.0 + 356.0 + 703.0 + 2.6 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=1015 + 642.0 + 381.0 + 0-14 + White Lightning + 2014-07-31 + regular + + + 1032 + AeroTech + AeroTech + HP-J425R + J425R-14A + J425 + J + 38.0 + 356.0 + SU + Tripoli Rocketry Association, Inc. + 425.0 + 452.0 + 676.0 + 1.6 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=1032 + 631.0 + 364.0 + 0-14 + Redline + 2014-07-31 + regular + + + 1034 + AeroTech + AeroTech + HP-K535W + K535W-14A + K535 + K + 54.0 + 358.0 + SU + Tripoli Rocketry Association, Inc. + 535.0 + 655.0 + 1434.0 + 2.8 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=1034 + 1264.0 + 745.0 + 0-14 + White Lightning + 2014-07-31 + regular + + + 1035 + AeroTech + AeroTech + HP-L1000W + L1000W-18A + L1000 + L + 54.0 + 635.0 + SU + Tripoli Rocketry Association, Inc. + 1000.0 + 1261.0 + 2714.0 + 2.7 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=1035 + 2194.0 + 1400.0 + 0-18 + White Lightning + 2014-07-31 + regular + + + 487 + AeroTech + AeroTech + I115W + I115W + I115 + I + 54.0 + 156.0 + reload + Tripoli Rocketry Association, Inc. + 115.0 + 412.0 + 3.58260869565217 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=487 + 545.0 + 219.0 + M + RMS-54/426 + White Lightning + 2014-07-22 + regular + + + 491 + AeroTech + AeroTech + I117FJ + I117FJ + I117 + I + 54.0 + 156.0 + reload + Tripoli Rocketry Association, Inc. + 117.0 + 361.0 + 3.1 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=491 + 566.0 + 243.0 + M + RMS-54/426 + Fast Blackjack + 2014-07-22 + regular + + + 453 + AeroTech + AeroTech + I1299N + I1299N + I1299 + I + 38.0 + 249.0 + reload + Tripoli Rocketry Association, Inc. + 1335.0 + 1851.42 + 422.95 + 0.316 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=453 + 422.0 + 192.0 + P + RMS-38/480 + Warp-9 + 2014-07-22 + regular + + + 167 + AeroTech + AeroTech + I132W + I132W + I132 + I + 38.0 + 335.0 + SU + Tripoli Rocketry Association, Inc. + 132.0 + 512.9 + 610.7 + 4.83 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=167 + 512.064 + 376.4 + M,L + SU 38x335 + White Lightning + 2014-07-22 + OOP + + + 173 + AeroTech + AeroTech + I154J + I154J + I154 + I + 38.0 + 241.0 + reload + Tripoli Rocketry Association, Inc. + 154.0 + 170.5 + 378.0 + 2.99 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=173 + 491.904 + 252.8 + M + RMS-38/480 + Blackjack + 2014-07-22 + regular + + + 177 + AeroTech + AeroTech + I161W + I161W + I161 + I + 38.0 + 191.0 + reload + Tripoli Rocketry Association, Inc. + 161.0 + 266.6 + 328.7 + 1.82 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=177 + 366.0 + 193.2 + 0-14 + RMS-38/360 + White Lightning + 2014-07-22 + regular + + + 911 + AeroTech + AeroTech + I170G + I170G + I170 + I + 54.0 + 147.1 + reload + Tripoli Rocketry Association, Inc. + 171.78 + 207.35 + 418.54 + 2.4 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=911 + 528.0 + 227.0 + 0-10 + RMS-54/426 + Mojave Green + 2014-07-22 + regular + + + 1091 + AeroTech + AeroTech + I180W + + I180 + I + 38.0 + 191.0 + reload + Tripoli Rocketry Association, Inc. + 180.0 + 362.0 + 326.0 + 1.8 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=1091 + 385.0 + 180.0 + 6,8,10,12,14 + 38/360 + While Lighting + 2016-03-20 + regular + + + 180 + AeroTech + AeroTech + I195J + I195J + I195 + I + 38.0 + 299.0 + reload + Tripoli Rocketry Association, Inc. + 195.0 + 216.3 + 426.1 + 2.1 + 7 + http://www.thrustcurve.org/motorsearch.jsp?id=180 + 572.0 + 301.0 + M + RMS-38/600 + Blackjack + 2014-07-22 + regular + + + 181 + AeroTech + AeroTech + I200W + I200W + I200 + I + 29.0 + 333.0 + reload + Tripoli Rocketry Association, Inc. + 200.0 + 463.3 + 324.5 + 1.65 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=181 + 357.504 + 187.3 + M + RMS-29/360 + White Lightning + 2014-07-22 + regular + + + 185 + AeroTech + AeroTech + I211W + I211W + I211 + I + 38.0 + 248.0 + reload + Tripoli Rocketry Association, Inc. + 211.0 + 399.5 + 441.6 + 1.72 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=185 + 455.0 + 251.3 + 0-14 + RMS-38/480 + White Lightning + 2014-07-22 + regular + + + 489 + AeroTech + AeroTech + I215R + I215R + I215 + I + 54.0 + 156.0 + reload + Tripoli Rocketry Association, Inc. + 215.0 + 399.0 + 1.85581395348837 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=489 + 527.0 + 208.0 + M + RMS-54/426 + Redline + 2014-07-22 + regular + + + 187 + AeroTech + AeroTech + I218R + I218R + I218 + I + 38.0 + 203.0 + reload + National Association of Rocketry + 218.0 + 330.0 + 1.51376146788991 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=187 + 371.84 + 172.7 + M + RMS-38/360 + Redline + 2014-07-22 + regular + + + 456 + AeroTech + AeroTech + I225FJ + I225FJ + I225 + I + 38.0 + 240.0 + reload + Tripoli Rocketry Association, Inc. + 230.5 + 276.6 + 367.89 + 1.59 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=456 + 264.0 + M + RMS-38/480 + Fast Blackjack + 2014-07-22 + regular + + + 488 + AeroTech + AeroTech + I229T + I229T + I229 + I + 54.0 + 156.0 + reload + Tripoli Rocketry Association, Inc. + 229.0 + 407.0 + 1.77729257641921 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=488 + 514.0 + 196.0 + M + RMS-54/426 + Blue Thunder + 2014-07-22 + regular + + + 484 + AeroTech + AeroTech + I245G + I245G + I245 + I + 38.0 + 202.0 + reload + + 245.0 + 351.0 + 1.4 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=484 + 365.0 + 181.3 + M + RMS-38/360 + Mojave Green + 2014-07-22 + regular + + + 197 + AeroTech + AeroTech + I284W + I284W + I284 + I + 38.0 + 299.0 + reload + Tripoli Rocketry Association, Inc. + 284.0 + 570.6 + 607.3 + 1.94 + 7 + http://www.thrustcurve.org/motorsearch.jsp?id=197 + 555.52 + 315.9 + M + RMS-38/600 + White Lightning + 2014-07-22 + regular + + + 199 + AeroTech + AeroTech + I285R + I285R + I285 + I + 38.0 + 250.0 + reload + National Association of Rocketry + 285.0 + 420.0 + 1.47368421052632 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=199 + 492.8 + 230.2 + M + RMS-38/480 + Redline + 2014-07-22 + regular + + + 203 + AeroTech + AeroTech + I300T + I300T + I300 + I + 38.0 + 250.0 + reload + National Association of Rocketry + 300.36 + 474.43 + 426.51 + 1.42 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=203 + 221.6 + M + RMS-38/480 + Blue Thunder + 2014-07-22 + regular + + + 457 + AeroTech + AeroTech + I305FJ + I305FJ + I305 + I + 38.0 + 288.0 + reload + Tripoli Rocketry Association, Inc. + 313.5 + 418.2 + 452.1 + 1.44 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=457 + 330.0 + M + RMS-38/600 + Fast Blackjack + 2014-07-22 + regular + + + 966 + AeroTech + AeroTech + I327DM + I327DM + I327 + I + 38.0 + 337.0 + reload + Tripoli Rocketry Association, Inc. + 327.0 + 400.0 + 539.0 + 1.72 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=966 + 628.0 + 354.0 + 0-14 + RMS-38/720 + Dark Matter + 2014-07-22 + regular + + + 951 + AeroTech + AeroTech + I350R + I350R + I350 + I + 38.0 + 355.6 + SU + Tripoli Rocketry Association, Inc. + 340.0 + 473.0 + 634.6 + 1.86 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=951 + 616.0 + 348.0 + 10 + Redline + 2014-07-22 + regular + + + 211 + AeroTech + AeroTech + I357T + I357T + I357 + I + 38.0 + 203.0 + reload + Tripoli Rocketry Association, Inc. + 357.0 + 432.8 + 342.0 + 1.0 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=211 + 343.0 + 174.4 + 0-14 + RMS-38/360 + Blue Thunder + 2014-07-22 + regular + + + 455 + AeroTech + AeroTech + I364FJ + I364FJ + I364 + I + 38.0 + 335.0 + reload + Tripoli Rocketry Association, Inc. + 373.8 + 487.3 + 570.13 + 1.52 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=455 + 396.0 + M + RMS-38/720 + Fast Blackjack + 2014-07-22 + regular + + + 213 + AeroTech + AeroTech + I366R + I366R + I366 + I + 38.0 + 299.0 + reload + Tripoli Rocketry Association, Inc. + 366.0 + 507.0 + 539.0 + 1.0 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=213 + 555.52 + 300.0 + M + RMS-38/600 + Redline + 2014-07-22 + regular + + + 218 + AeroTech + AeroTech + I435T + I435T + I435 + I + 38.0 + 299.0 + reload + Tripoli Rocketry Association, Inc. + 435.0 + 785.6 + 568.9 + 1.1 + 7 + http://www.thrustcurve.org/motorsearch.jsp?id=218 + 518.0 + 269.9 + M + RMS-38/600 + Blue Thunder + 2014-07-22 + regular + + + 719 + AeroTech + AeroTech + I49N + I49N + I49 + I + 38.0 + 184.0 + reload + National Association of Rocketry + 49.4 + 63.7 + 383.0 + 7.68 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=719 + 398.0 + 205.0 + P + RMS-38/360 + Warp-9 + 2014-07-22 + regular + + + 490 + AeroTech + AeroTech + I599N + I599N + I599 + I + 54.0 + 156.0 + reload + Tripoli Rocketry Association, Inc. + 667.82 + 763.46 + 404.87 + 0.6 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=490 + 512.0 + 195.0 + P + RMS-54/426 + Warp-9 + 2014-07-22 + regular + + + 720 + AeroTech + AeroTech + I59WN + I59WN + I59 + I + 38.0 + 232.0 + reload + National Association of Rocketry + 60.8 + 172.9 + 486.0 + 7.99 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=720 + 487.0 + 272.0 + P + RMS-38/480 + White Lightning + 2014-07-22 + regular + + + 506 + AeroTech + AeroTech + I600R + I600R + I600 + I + 38.0 + 345.4 + reload + Tripoli Rocketry Association, Inc. + 612.0 + 811.7 + 597.3 + 1.09 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=506 + 602.0 + 324.0 + M + RMS-38/720 + Redline + 2014-07-22 + regular + + + 157 + AeroTech + AeroTech + I65W + I65W + I65 + I + 54.0 + 235.0 + SU + National Association of Rocketry + 76.33 + 150.07 + 630.5 + 8.26 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=157 + 761.6 + 369.7 + SU 54x235 + White Lightning + 2014-07-22 + OOP + + + 227 + AeroTech + AeroTech + J125W + J125W + J125 + J + 54.0 + 368.0 + SU + Tripoli Rocketry Association, Inc. + 125.0 + 338.9 + 1202.4 + 7.75 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=227 + 1288.0 + 638.7 + SU 54x368 + White Lightning + 2014-07-22 + OOP + + + 462 + AeroTech + AeroTech + J1299N + J1299N-P + J1299 + J + 54.0 + 231.0 + reload + Tripoli Rocketry Association, Inc. + 1291.58 + 1468.28 + 843.4 + 0.653 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=462 + 834.0 + 371.6 + P + RMS-54/852 + Warp-9 + 2014-07-22 + regular + + + 228 + AeroTech + AeroTech + J135W + J135W + J135 + J + 54.0 + 368.0 + reload + Tripoli Rocketry Association, Inc. + 157.0 + 274.0 + 1069.0 + 6.83 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=228 + 1141.06 + 633.0 + L + RMS-54/1280 + White Lightning + 2014-07-22 + regular + + + 231 + AeroTech + AeroTech + J145H 2-jet std. + J145H 2-jet std. + J145 + J + 54.0 + 709.0 + hybrid + Tripoli Rocketry Association, Inc. + 145.0 + 303.3 + 825.7 + 5.65 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=231 + 1797.38 + 409.5 + RMS 54/1280 + 2014-07-22 + OOP + + + 237 + AeroTech + AeroTech + J170H 3-jet std. + J170H 3-jet std. + J170 + J + 54.0 + 709.0 + hybrid + Tripoli Rocketry Association, Inc. + 170.0 + 739.0 + 4.4 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=237 + 409.5 + RMS 54/1280 + 2014-07-22 + OOP + + + 463 + AeroTech + AeroTech + J1799N + J1799N-P + J1799 + J + 54.0 + 316.0 + reload + Tripoli Rocketry Association, Inc. + 1963.39 + 2965.88 + 1214.8 + 0.61 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=463 + 591.0 + P + RMS-54/1280 + Warp-9 + 2014-07-22 + regular + + + 238 + AeroTech + AeroTech + J180T + J180T + J180 + J + 54.0 + 230.0 + reload + Tripoli Rocketry Association, Inc. + 180.0 + 392.0 + 764.0 + 4.5 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=238 + 809.088 + 437.1 + L + RMS-54/852 + Blue Thunder + 2014-07-22 + regular + + + 241 + AeroTech + AeroTech + J210H 4-jet std. + J210H 4-jet std. + J210 + J + 54.0 + 709.0 + hybrid + Tripoli Rocketry Association, Inc. + 213.46 + 651.819 + 853.842 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=241 + 1497.0 + 471.0 + RMS 54/1280 + 2016-01-23 + OOP + + + 492 + AeroTech + AeroTech + J250FJ + J250FJ + J250 + J + 54.0 + 241.0 + reload + Tripoli Rocketry Association, Inc. + 250.0 + 731.0 + 2.9 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=492 + 907.0 + 487.0 + L + RMS-54/852 + Fast Blackjack + 2014-07-22 + regular + + + 1087 + AeroTech + AeroTech + J250W + + J250 + J + 54.0 + 218.2 + SU + Tripoli Rocketry Association, Inc. + 260.0 + 338.0 + 704.0 + 2.7 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=1087 + 708.0 + 363.0 + 14 + DMS + White Lightning + 2015-08-07 + regular + + + 251 + AeroTech + AeroTech + J260HW 3-jet EFX + J260HW 3-jet EFX + J260 + J + 54.0 + 709.0 + hybrid + Tripoli Rocketry Association, Inc. + 260.049 + 598.969 + 1170.22 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=251 + 1574.0 + 558.0 + RMS 54/1280 + 2016-01-23 + OOP + + + 255 + AeroTech + AeroTech + J275W + J275W + J275 + J + 54.0 + 230.0 + reload + Tripoli Rocketry Association, Inc. + 275.0 + 370.0 + 774.0 + 3.3 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=255 + 864.192 + 472.0 + L + RMS-54/852 + White Lightning + 2014-07-22 + regular + + + 262 + AeroTech + AeroTech + J315R + J315R + J315 + J + 54.0 + 230.0 + reload + Tripoli Rocketry Association, Inc. + 315.0 + 763.3 + 2.4231746031746 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=262 + 851.2 + 438.0 + L + RMS-54/852 + Redline + 2014-07-22 + regular + + + 904 + AeroTech + AeroTech + J340M + AT, Aerotech, ISP, RCS + J340 + J + 38.0 + 337.0 + reload + Tripoli Rocketry Association, Inc. + 354.1 + 605.0 + 651.68 + 1.836 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=904 + 577.3 + 365.0 + 0-14 + RMS-38/720 + Metalstorm + 2014-07-22 + regular + + + 269 + AeroTech + AeroTech + J350W + J350W-L + J350 + J + 38.0 + 337.0 + reload + Tripoli Rocketry Association, Inc. + 445.0 + 822.5 + 670.1 + 1.5 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=269 + 361.1 + M + RMS-38/720 + White Lightning + 2014-07-31 + regular + + + 270 + AeroTech + AeroTech + J350W-OLD + J350W + J350 + J + 38.0 + 337.0 + reload + Tripoli Rocketry Association, Inc. + 394.2 + 890.4 + 697.4 + 1.78 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=270 + 381.1 + S,M,L + RMS-38/720 + White Lightning + 2016-01-17 + OOP + + + 278 + AeroTech + AeroTech + J390H-turbo + J390H-turbo + J390 + J + 54.0 + 709.0 + hybrid + Tripoli Rocketry Association, Inc. + 390.0 + 1280.0 + 3.28205128205128 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=278 + 391.0 + RMS 54/1280 + 2014-07-22 + OOP + + + 586 + AeroTech + AeroTech + J401FJ + J401FJ + J401 + J + 54.0 + 325.0 + reload + Tripoli Rocketry Association, Inc. + 408.88 + 479.99 + 1115.38 + 2.8 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=586 + 912.0 + 511.0 + L + RMS-54/1280 + Fast Blackjack + 2014-07-22 + regular + + + 282 + AeroTech + AeroTech + J415W + J415W + J415 + J + 54.0 + 314.0 + reload + Tripoli Rocketry Association, Inc. + 415.0 + 732.8 + 1231.7 + 2.88 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=282 + 1168.0 + 693.3 + L + RMS-54/1280 + White Lightning + 2014-07-22 + regular + + + 284 + AeroTech + AeroTech + J420R + J420R + J420 + J + 38.0 + 337.0 + reload + Tripoli Rocketry Association, Inc. + 420.0 + 658.0 + 1.56666666666667 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=284 + 649.6 + 345.0 + M + RMS-38/720 + Redline + 2014-07-22 + regular + + + 287 + AeroTech + AeroTech + J460T + J460T + J460 + J + 54.0 + 230.0 + reload + Tripoli Rocketry Association, Inc. + 460.0 + 870.5 + 805.5 + 1.81 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=287 + 789.0 + 415.4 + L + RMS-54/852 + Blue Thunder + 2014-07-22 + regular + + + 485 + AeroTech + AeroTech + J500G + J500G + J500 + J + 38.0 + 345.0 + reload + Tripoli Rocketry Association, Inc. + 500.0 + 723.0 + 1.4 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=485 + 654.0 + 362.6 + M + RMS-38/720 + Mojave Green + 2014-07-22 + regular + + + 778 + AeroTech + AeroTech + J510W + Aerotech + J510 + J + 38.0 + 584.2 + reload + Tripoli Rocketry Association, Inc. + 509.9 + 1041.7 + 1162.0 + 2.27 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=778 + 1080.0 + 662.0 + L + RMS-38/1320 + White Lightning + 2016-06-01 + regular + + + 292 + AeroTech + AeroTech + J540R + J540R + J540 + J + 54.0 + 314.0 + reload + Tripoli Rocketry Association, Inc. + 540.0 + 1161.0 + 2.15 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=292 + 1084.16 + 679.0 + L + RMS-54/1280 + Redline + 2014-07-22 + regular + + + 294 + AeroTech + AeroTech + J570W + J570W + J570 + J + 38.0 + 479.0 + reload + Tripoli Rocketry Association, Inc. + 509.3 + 1142.5 + 973.1 + 1.91 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=294 + 902.0 + 535.8 + M + RMS-38/1080 + White Lightning + 2014-07-22 + regular + + + 460 + AeroTech + AeroTech + J575FJ + J575FJ + J575 + J + 38.0 + 478.0 + reload + Tripoli Rocketry Association, Inc. + 593.95 + 839.5 + 798.116 + 1.34 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=460 + 576.0 + M + RMS-38/1080 + Fast Blackjack + 2014-07-22 + regular + + + 297 + AeroTech + AeroTech + J800T + J800T + J800 + J + 54.0 + 316.0 + reload + Tripoli Rocketry Association, Inc. + 696.5 + 1001.0 + 1229.11 + 1.76 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=297 + 1085.95 + 618.0 + L + RMS-54/1280 + Blue Thunder + 2014-07-22 + regular + + + 470 + AeroTech + AeroTech + J825R + J825R + J825 + J + 38.0 + 478.0 + reload + Tripoli Rocketry Association, Inc. + 892.9 + 1244.3 + 974.9 + 1.15 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=470 + 500.0 + M + RMS-38/1080 + Redline + 2014-07-22 + regular + + + 223 + AeroTech + AeroTech + J90W + J90W + J90 + J + 54.0 + 243.0 + reload + Tripoli Rocketry Association, Inc. + 90.0 + 188.0 + 707.0 + 6.85 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=223 + 852.544 + 426.0 + L + RMS-54/852 + White Lightning + 2014-07-22 + regular + + + 777 + AeroTech + AeroTech + J99N + J99N + J99 + J + 54.0 + 231.0 + reload + Tripoli Rocketry Association, Inc. + 92.4 + 151.95 + 945.2 + 10.2 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=777 + 899.0 + 556.0 + P + RMS-54/852 + Warp-9 + 2016-01-17 + OOP + + + 887 + AeroTech + AeroTech + K1000T + K1000NT + K1000 + K + 75.0 + 382.9 + reload + Tripoli Rocketry Association, Inc. + 1066.0 + 1674.0 + 2511.5 + 2.35 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=887 + 2602.0 + 1234.0 + P + RMS-75/2560 + Blue Thunder + 2014-07-22 + regular + + + 590 + AeroTech + AeroTech + K1050W + K1050W + K1050 + K + 54.0 + 627.0 + reload + Tripoli Rocketry Association, Inc. + 1132.92 + 2172.0 + 2426.35 + 2.14 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=590 + 2203.0 + 1265.0 + P + RMS-54/2800 + White Lightning + 2014-07-22 + regular + + + 356 + AeroTech + AeroTech + K1050W-SU + K1050W + K1050 + K + 54.0 + 676.0 + SU + Tripoli Rocketry Association, Inc. + 1050.0 + 2164.0 + 2530.0 + 2.28 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=356 + 2128.45 + 1362.2 + SU 54x676 + White Lightning + 2014-07-22 + OOP + + + 358 + AeroTech + AeroTech + K1100T + K1100T + K1100 + K + 54.0 + 398.0 + reload + Tripoli Rocketry Association, Inc. + 1100.0 + 2004.0 + 1472.0 + 1.61 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=358 + 1336.0 + 773.3 + L + RMS-54/1706 + Blue Thunder + 2014-07-22 + regular + + + 969 + AeroTech + AeroTech + K1103X + K1103X + K1103 + K + 54.0 + 401.0 + reload + Tripoli Rocketry Association, Inc. + 1103.0 + 1780.0 + 1789.0 + 1.6 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=969 + 1459.0 + 830.0 + 0-14 + RMS-54/1706 + Propellant X + 2014-07-22 + regular + + + 359 + AeroTech + AeroTech + K1275R + K1275R + K1275 + K + 54.0 + 568.0 + reload + Tripoli Rocketry Association, Inc. + 1275.0 + 1554.0 + 2224.9 + 1.75 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=359 + 1986.0 + 1222.0 + P + RMS-54/2560 + Redline + 2014-07-22 + regular + + + 454 + AeroTech + AeroTech + K1499N + K1499N + K1499 + K + 75.0 + 260.0 + reload + Tripoli Rocketry Association, Inc. + 1499.8 + 1720.12 + 1321.7 + 0.88 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=454 + 1741.0 + 604.0 + P + RMS-75/1280 + Warp-9 + 2014-07-22 + regular + + + 301 + AeroTech + AeroTech + K185W + K185W + K185 + K + 54.0 + 437.0 + reload + Tripoli Rocketry Association, Inc. + 185.0 + 404.7 + 1417.2 + 6.87 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=301 + 1434.05 + 836.8 + L + RMS-54/1706 + White Lightning + 2014-07-22 + regular + + + 458 + AeroTech + AeroTech + K1999N + K1999N + K1999 + K + 98.0 + 289.0 + reload + Tripoli Rocketry Association, Inc. + 1887.37 + 2159.6 + 2540.0 + 1.34 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=458 + 1225.0 + P + RMS-98/2560 + Warp-9 + 2014-07-26 + regular + + + 306 + AeroTech + AeroTech + K250W + K250W + K250 + K + 54.0 + 673.0 + SU + Tripoli Rocketry Association, Inc. + 250.0 + 545.8 + 2353.0 + 9.0 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=306 + 2211.33 + 1434.0 + P + White Lightning + 2014-07-22 + regular + + + 486 + AeroTech + AeroTech + K270W + K270W + K270 + K + 54.0 + 579.0 + reload + Tripoli Rocketry Association, Inc. + 249.76 + 438.38 + 1967.955 + 7.87 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=486 + 2100.0 + 1188.0 + P + RMS-54/2560 + White Lightning + 2014-07-22 + regular + + + 898 + AeroTech + AeroTech + K375NW + K375NW + K375 + K + 54.0 + 579.0 + reload + Tripoli Rocketry Association, Inc. + 430.58 + 1371.77 + 2228.136 + 5.78 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=898 + 2106.0 + 1318.0 + P + RMS-54/2560 + White Lightning + 2014-07-22 + regular + + + 967 + AeroTech + AeroTech + K456DM + K456DM + K456 + K + 54.0 + 401.0 + reload + Tripoli Rocketry Association, Inc. + 438.0 + 534.0 + 1281.0 + 2.89 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=967 + 1484.0 + 866.0 + 0-14 + RMS-54/1706 + Dark Matter + 2014-07-22 + regular + + + 318 + AeroTech + AeroTech + K458W + K458W + K458 + K + 98.0 + 275.0 + reload + Tripoli Rocketry Association, Inc. + 458.0 + 585.8 + 2464.6 + 6.0 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=318 + 3163.78 + 1425.0 + P + RMS-98/2560 + White Lightning + 2014-07-26 + regular + + + 899 + AeroTech + AeroTech + K480W + K480W + K480 + K + 54.0 + 579.0 + reload + Tripoli Rocketry Association, Inc. + 545.27 + 1017.79 + 2273.26 + 4.26 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=899 + 2078.0 + 1292.0 + P + RMS-54/2560 + White Lightning + 2014-07-22 + regular + + + 322 + AeroTech + AeroTech + K485H (3 jet) + K485H (3 jet) + K485 + K + 54.0 + 699.0 + hybrid + Tripoli Rocketry Association, Inc. + 485.0 + 851.1 + 1686.8 + 3.5 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=322 + 2220.29 + 923.4 + RMS 54/1280 + 2014-07-22 + OOP + + + 494 + AeroTech + AeroTech + K513FJ + K513FJ + K513 + K + 54.0 + 410.0 + reload + Tripoli Rocketry Association, Inc. + 556.84 + 658.25 + 1496.27 + 2.79 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=494 + 1647.0 + 974.0 + L + RMS-54/1706 + Fast Blackjack + 2014-07-22 + regular + + + 905 + AeroTech + AeroTech + K540M + AT,Aerotech,ISP,RCS + K540 + K + 54.0 + 401.0 + reload + Tripoli Rocketry Association, Inc. + 557.4 + 854.0 + 1596.33 + 2.85 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=905 + 1275.0 + 876.7 + 0-14 + RMS-54/1706 + Metalstorm + 2014-07-22 + regular + + + 326 + AeroTech + AeroTech + K550W + K550W + K550 + K + 54.0 + 410.0 + reload + Tripoli Rocketry Association, Inc. + 396.8 + 655.3 + 1539.118 + 3.879 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=326 + 1487.36 + 889.1 + L + RMS-54/1706 + White Lightning + 2014-07-22 + regular + + + 329 + AeroTech + AeroTech + K560W + K560W + K560 + K + 75.0 + 396.0 + reload + Tripoli Rocketry Association, Inc. + 560.0 + 753.7 + 2417.0 + 4.09 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=329 + 2744.0 + 1424.9 + P + RMS-75/2560 + White Lightning + 2014-07-22 + regular + + + 339 + AeroTech + AeroTech + K650T + K650T + K650 + K + 98.0 + 289.0 + reload + Tripoli Rocketry Association, Inc. + 650.0 + 752.8 + 2405.7 + 3.67 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=339 + 2935.3 + 1280.0 + P + RMS-98/2560 + Blue Thunder + 2014-07-26 + regular + + + 343 + AeroTech + AeroTech + K680R + K680R + K680 + K + 98.0 + 289.0 + reload + Tripoli Rocketry Association, Inc. + 680.0 + 835.0 + 2358.0 + 3.49 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=343 + 1316.0 + P + RMS-98/2560 + Redline + 2014-07-26 + regular + + + 344 + AeroTech + AeroTech + K695R + K695R + K695 + K + 54.0 + 410.0 + reload + Tripoli Rocketry Association, Inc. + 695.0 + 1514.0 + 2.17841726618705 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=344 + 1487.36 + 903.0 + L + RMS-54/1706 + Redline + 2014-07-22 + regular + + + 346 + AeroTech + AeroTech + K700W + K700W + K700 + K + 54.0 + 568.0 + reload + Tripoli Rocketry Association, Inc. + 700.0 + 1617.0 + 2261.0 + 3.51 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=346 + 2035.26 + 1303.3 + P + RMS-54/2560 + White Lightning + 2014-07-22 + regular + + + 349 + AeroTech + AeroTech + K780R + K780R + K780 + K + 75.0 + 395.0 + reload + Tripoli Rocketry Association, Inc. + 780.0 + 965.0 + 2371.0 + 2.98 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=349 + 2934.4 + 1268.0 + P + RMS-75/2560 + Redline + 2014-07-22 + regular + + + 529 + AeroTech + AeroTech + K805G + K805G + K805 + K + 54.0 + 401.0 + reload + Tripoli Rocketry Association, Inc. + 805.0 + 1762.0 + 2.2 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=529 + 1543.0 + 871.1 + P + RMS-54/1706 + Mojave Green + 2014-07-22 + regular + + + 495 + AeroTech + AeroTech + K828FJ + K828FJ + K828 + K + 54.0 + 579.0 + reload + Tripoli Rocketry Association, Inc. + 828.0 + 2120.0 + 2.5 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=495 + 2223.0 + 1373.0 + P + RMS-54/2560 + Fast Blackjack + 2014-07-22 + regular + + + 974 + AeroTech + AeroTech + L1040DM + L1040DM + L1040 + L + 75.0 + 681.0 + reload + Tripoli Rocketry Association, Inc. + 992.0 + 1255.0 + 3769.0 + 3.79 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=974 + 4717.0 + 2602.0 + PS + RMS-75/5120 + Dark Matter + 2014-07-22 + regular + + + 1089 + AeroTech + AeroTech + L1090W + + L1090 + L + 54.0 + 625.8 + reload + Tripoli Rocketry Association, Inc. + 1090.0 + 1487.0 + 2671.0 + 2.45 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=1089 + 2432.0 + 1400.0 + P + RMS-54/2800 + White Thunder + 2016-01-17 + regular + + + 398 + AeroTech + AeroTech + L1120W + L1120W + L1120 + L + 75.0 + 665.0 + reload + Tripoli Rocketry Association, Inc. + 1120.0 + 1794.0 + 4947.0 + 4.43 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=398 + 4657.86 + 2777.8 + RMS-75/5120 + White Lightning + 2016-01-17 + OOP + + + 399 + AeroTech + AeroTech + L1150R + L1150R + L1150 + L + 75.0 + 530.0 + reload + Tripoli Rocketry Association, Inc. + 1150.0 + 1346.0 + 3517.0 + 3.07 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=399 + 3673.6 + 1902.0 + P + RMS-75/3840 + Redline + 2014-07-22 + regular + + + 740 + AeroTech + AeroTech + L1170FJ + L1170 FJ + L1170 + L + 75.0 + 665.0 + reload + Tripoli Rocketry Association, Inc. + 1141.0 + 1489.0 + 4232.0 + 3.7 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=740 + 4990.0 + 2800.0 + P + RMS-75/5120 + Fast Blackjack + 2014-07-22 + regular + + + 1021 + AeroTech + AeroTech + L1250DM + AT + L1250 + L + 75.0 + 801.0 + reload + Tripoli Rocketry Association, Inc. + 2042.0 + 1254.0 + 4374.0 + 3.7 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=1021 + 5647.0 + 2565.0 + P + RMS-75/6400 + Dark Matter + 2014-07-22 + regular + + + 402 + AeroTech + AeroTech + L1300R + L1300R + L1300 + L + 98.0 + 443.0 + reload + Tripoli Rocketry Association, Inc. + 1300.0 + 4567.0 + 3.51307692307692 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=402 + 2632.0 + P + RMS-98/5120 + Redline + 2014-07-22 + regular + + + 1020 + AeroTech + AeroTech + L1365M + AT + L1365 + L + 75.0 + 665.0 + reload + Tripoli Rocketry Association, Inc. + 1365.0 + 1735.0 + 4780.0 + 3.5 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=1020 + 4908.0 + 2648.0 + PS + RMS-75/5120 + Metalstorm + 2014-07-22 + regular + + + 600 + AeroTech + AeroTech + L1390G + L1390G + L1390 + L + 75.0 + 530.0 + reload + Tripoli Rocketry Association, Inc. + 1390.0 + 3949.0 + 2.63 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=600 + 3879.0 + 1973.0 + P + RMS-75/3840 + Mojave Green + 2014-07-22 + regular + + + 405 + AeroTech + AeroTech + L1420R + L1420R + L1420 + L + 75.0 + 665.0 + reload + Tripoli Rocketry Association, Inc. + 1420.0 + 1814.0 + 4603.0 + 3.24 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=405 + 4562.0 + 2560.0 + P + RMS-75/5120 + Redline + 2014-07-22 + regular + + + 406 + AeroTech + AeroTech + L1500T + L1500T + L1500 + L + 98.0 + 665.0 + reload + Tripoli Rocketry Association, Inc. + 1500.0 + 1752.0 + 5089.3 + 3.47 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=406 + 4659.2 + 2490.9 + P + RMS-98/5120 + Blue Thunder + 2014-07-22 + regular + + + 910 + AeroTech + AeroTech + L1520T + L1520T + L1520 + L + 75.0 + 517.9 + reload + Tripoli Rocketry Association, Inc. + 1567.8 + 1765.25 + 3715.9 + 2.36 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=910 + 3651.4 + 1854.0 + PS + RMS-75/3840 + Blue Thunder + 2014-07-22 + regular + + + 587 + AeroTech + AeroTech + L2200G + L2200G + L2200 + L + 75.0 + 681.0 + reload + Tripoli Rocketry Association, Inc. + 2200.0 + 5104.0 + 2.32 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=587 + 4783.0 + 2518.0 + P + RMS-75/5120 + Mojave Green + 2014-07-22 + regular + + + 1092 + AeroTech + AeroTech + L2500ST + + L2500 + L + 98.0 + 443.0 + reload + Tripoli Rocketry Association, Inc. + 2504.0 + 2830.0 + 4668.0 + 1.86 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=1092 + 4989.0 + 2313.0 + P + 98/5120 + Super Thunder + 2016-06-24 + regular + + + 589 + AeroTech + AeroTech + L339N + L339N + L339 + L + 98.0 + 302.0 + reload + Tripoli Rocketry Association, Inc. + 316.5 + 445.5 + 3042.9 + 8.82 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=589 + 3210.0 + 1796.0 + P + RMS-98/2560 + Warp-9 + 2014-07-31 + regular + + + 909 + AeroTech + AeroTech + L400W + L400W + L400 + L + 98.0 + 443.9 + reload + Tripoli Rocketry Association, Inc. + 379.15 + 770.24 + 4641.58 + 12.24 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=909 + 5170.0 + 2696.0 + PS + RMS-98/5120 + White Lightning + 2014-07-22 + regular + + + 385 + AeroTech + AeroTech + L850W + L850W + L850 + L + 75.0 + 531.0 + reload + Tripoli Rocketry Association, Inc. + 850.0 + 1866.2 + 3646.2 + 4.42 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=385 + 3742.0 + 2094.8 + P + RMS-75/3840 + White Lightning + 2014-07-22 + regular + + + 968 + AeroTech + AeroTech + L900DM + L900DM + L900 + L + 75.0 + 665.0 + reload + Tripoli Rocketry Association, Inc. + 900.0 + 3868.0 + 4.4 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=968 + 4724.0 + 2472.0 + PS + RMS-75/5120 + Dark Matter + 2014-07-22 + regular + + + 389 + AeroTech + AeroTech + L952W + L952W + L952 + L + 98.0 + 427.0 + reload + Tripoli Rocketry Association, Inc. + 952.0 + 1021.5 + 4656.0 + 6.15 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=389 + 5012.22 + 2749.7 + P + RMS-98/5120 + White Lightning + 2014-07-22 + regular + + + 973 + AeroTech + AeroTech + M1075DM + M1075DM + M1075 + M + 98.0 + 597.0 + reload + Tripoli Rocketry Association, Inc. + 1070.0 + 1330.0 + 5571.0 + 5.2 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=973 + 6971.0 + 3846.0 + PS + RMS-98/7680 + Dark Matter + 2014-07-22 + regular + + + 420 + AeroTech + AeroTech + M1297W + M1297W + M1297 + M + 75.0 + 665.0 + reload + Tripoli Rocketry Association, Inc. + 1297.0 + 2048.98 + 5416.6 + 4.17 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=420 + 4637.0 + 2722.0 + P + RMS-75/5120 + White Lightning + 2014-07-22 + regular + + + 972 + AeroTech + AeroTech + M1305M + M1305M + M1305 + M + 98.0 + 597.0 + reload + Tripoli Rocketry Association, Inc. + 1406.0 + 2098.0 + 6891.0 + 4.8 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=972 + 7098.0 + 4080.0 + PS + RMS-98/7680 + Metalstorm + 2014-07-22 + regular + + + 421 + AeroTech + AeroTech + M1315W + M1315W + M1315 + M + 75.0 + 801.0 + reload + Tripoli Rocketry Association, Inc. + 1315.0 + 2362.5 + 6713.5 + 5.4 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=421 + 5644.8 + 3499.4 + P + RMS-75/6400 + White Lightning + 2014-07-22 + regular + + + 1073 + AeroTech + AeroTech + M1350W + + M1350 + M + 75.0 + 622.0 + SU + Tripoli Rocketry Association, Inc. + 1356.725 + 1765.489 + 5178.154 + 3.8166 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=1073 + 4808.0 + 1970.0 + P + White Lightning + 2014-07-25 + regular + + + 424 + AeroTech + AeroTech + M1419W + M1419W + M1419 + M + 98.0 + 579.0 + reload + Tripoli Rocketry Association, Inc. + 1419.0 + 1590.9 + 7755.5 + 7.1 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=424 + 6916.22 + 4077.0 + P + RMS-98/7680 + White Lightning + 2014-07-22 + regular + + + 588 + AeroTech + AeroTech + M1500G + M1500G + M1500 + M + 75.0 + 681.0 + reload + Tripoli Rocketry Association, Inc. + 1508.67052023121 + 5220.0 + 3.46 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=588 + 4896.0 + 2631.0 + P + RMS-75/5120 + Mojave Green + 2014-07-22 + regular + + + 426 + AeroTech + AeroTech + M1550R + M1550R + M1550 + M + 75.0 + 801.0 + reload + Tripoli Rocketry Association, Inc. + 1550.0 + 2180.0 + 5600.0 + 3.0 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=426 + 5644.8 + 3170.0 + P + RMS-75/6400 + Redline + 2014-07-22 + regular + + + 428 + AeroTech + AeroTech + M1600R + M1600R + M1600 + M + 98.0 + 579.0 + reload + Tripoli Rocketry Association, Inc. + 1600.0 + 1917.0 + 7084.0 + 4.0 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=428 + 6917.12 + 4026.0 + P + RMS-98/7680 + Redline + 2014-07-22 + regular + + + 779 + AeroTech + AeroTech + M1780NT + M1780T + M1780 + M + 75.0 + 665.0 + reload + Tripoli Rocketry Association, Inc. + 1859.0 + 3056.0 + 5783.0 + 3.1 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=779 + 4715.0 + 2560.0 + PS + RMS-75/5120 + Blue Thunder + 2014-07-22 + regular + + + 584 + AeroTech + AeroTech + M1800FJ + M1800FJ + M1800 + M + 98.0 + 751.0 + reload + Tripoli Rocketry Association, Inc. + 1833.29 + 3956.0 + 8207.7 + 4.5 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=584 + 9162.0 + 5599.0 + P + RMS-98/10240 + Fast Blackjack + 2014-07-22 + regular + + + 780 + AeroTech + AeroTech + M1845NT + M1845T + M1845 + M + 98.0 + 597.0 + reload + Tripoli Rocketry Association, Inc. + 1875.0 + 3081.0 + 8307.0 + 4.43 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=780 + 6682.0 + 3772.0 + PS + RMS-98/7680 + Blue Thunder + 2014-07-22 + regular + + + 461 + AeroTech + AeroTech + M1850W + M1850W-PS + M1850 + M + 75.0 + 923.0 + reload + Tripoli Rocketry Association, Inc. + 1909.6 + 4489.4 + 7658.6 + 4.01 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=461 + 4122.0 + P + RMS-75/7680 + White Lightning + 2014-07-22 + regular + + + 433 + AeroTech + AeroTech + M1939W + M1939W + M1939 + M + 98.0 + 732.0 + reload + Tripoli Rocketry Association, Inc. + 1939.0 + 2429.7 + 10481.5 + 6.2 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=433 + 8988.22 + 5719.1 + P + RMS-98/10240 + White Lightning + 2014-07-22 + regular + + + 434 + AeroTech + AeroTech + M2000R + M2000R + M2000 + M + 98.0 + 732.0 + reload + Tripoli Rocketry Association, Inc. + 2000.0 + 2327.0 + 9218.0 + 4.0 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=434 + 8986.88 + 5368.0 + P + RMS-98/10240 + Redline + 2014-07-22 + regular + + + 530 + AeroTech + AeroTech + M2030G-P + M2030G + M2030 + M + 75.0 + 653.0 + reload + Tripoli Rocketry Association, Inc. + 2030.0 + 5485.0 + 2.6 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=530 + 4906.0 + 2663.0 + RMS-75/5120 + Mojave Green + 2016-01-17 + OOP + + + 531 + AeroTech + AeroTech + M2100G + M2100G + M2100 + M + 98.0 + 598.0 + reload + Tripoli Rocketry Association, Inc. + 2100.0 + 7802.0 + 3.7 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=531 + 6918.0 + 3948.0 + P + RMS-98/7680 + Mojave Green + 2014-07-22 + regular + + + 438 + AeroTech + AeroTech + M2400T + M2400T + M2400 + M + 98.0 + 597.0 + reload + Tripoli Rocketry Association, Inc. + 2400.0 + 3401.6 + 7716.5 + 3.2 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=438 + 6451.2 + 3692.6 + P + RMS-98/7680 + Blue Thunder + 2014-07-22 + regular + + + 440 + AeroTech + AeroTech + M2500T + M2500T + M2500 + M + 98.0 + 751.0 + reload + Tripoli Rocketry Association, Inc. + 2500.0 + 3710.9 + 9671.0 + 3.85 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=440 + 8064.0 + 4711.2 + P + RMS-98/10240 + Blue Thunder + 2014-07-22 + regular + + + 1093 + AeroTech + AeroTech + M4500ST + + M4500 + M + 98.0 + 597.0 + reload + Tripoli Rocketry Association, Inc. + 4533.0 + 5549.0 + 7301.0 + 1.6 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=1093 + 6622.0 + 3425.0 + P + 98/7840 + Super Thunder + 2016-06-24 + regular + + + 471 + AeroTech + AeroTech + M650W + M650W + M650 + M + 75.0 + 801.0 + reload + National Association of Rocketry + 656.0 + 1475.0 + 5964.0 + 9.13 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=471 + 5125.0 + 2893.0 + P + RMS-75/6400 + White Lightning + 2014-07-22 + regular + + + 1008 + AeroTech + AeroTech + M685W + + M685 + M + 75.0 + 935.9 + reload + Tripoli Rocketry Association, Inc. + 657.0 + 1517.0 + 7561.0 + 11.5 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=1008 + 7008.0 + 4320.0 + P + RMS-75/7680 + White Lightning + 2014-07-22 + regular + + + 472 + AeroTech + AeroTech + M750W + M750W + M750 + M + 98.0 + 732.0 + reload + National Association of Rocketry + 744.0 + 1454.0 + 9325.0 + 12.65 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=472 + 8776.0 + 5540.0 + P + RMS-98/10240 + White Lightning + 2014-07-22 + regular + + + 410 + AeroTech + AeroTech + M845H + M845 + M845 + M + 98.0 + 782.0 + hybrid + Tripoli Rocketry Association, Inc. + 845.0 + 6159.0 + 7.2887573964497 + 2 + http://www.thrustcurve.org/motorsearch.jsp?id=410 + 3433.0 + RMS 98/5120 + 2014-07-22 + OOP + + + 638 + AeroTech + AeroTech + N1000W + N1000W + N1000 + N + 98.0 + 1046.0 + reload + National Association of Rocketry + 1079.0 + 2262.0 + 14126.0 + 13.05 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=638 + 12771.0 + 8293.0 + P + RMS-98/15360 + White Lightning + 2014-07-22 + regular + + + 447 + AeroTech + AeroTech + N2000W + N2000W + N2000 + N + 98.0 + 1046.0 + reload + Tripoli Rocketry Association, Inc. + 2000.0 + 3140.8 + 13347.1 + 6.9 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=447 + 12282.8 + 7752.6 + P + RMS-98/15360 + White Lightning + 2014-07-22 + regular + + + 1022 + AeroTech + AeroTech + N2220DM + AT + N2220 + N + 98.0 + 1046.0 + reload + Tripoli Rocketry Association, Inc. + 2199.0 + 4472.0 + 10657.0 + 5.4 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=1022 + 11997.0 + 7183.0 + P + RMS-98/15360 + Dark Matter + 2016-01-17 + OOP + + + 781 + AeroTech + AeroTech + N3300R + N3300R + N3300 + N + 98.0 + 1046.0 + reload + Tripoli Rocketry Association, Inc. + 3168.0 + 4301.0 + 14041.0 + 4.37 + 1 + http://www.thrustcurve.org/motorsearch.jsp?id=781 + 12054.0 + 7512.0 + PS + RMS-98/15360 + Redline + 2014-07-22 + regular + + + 450 + AeroTech + AeroTech + N4800T + N4800T + N4800 + N + 98.0 + 1201.0 + reload + Tripoli Rocketry Association, Inc. + 4800.0 + 6599.35 + 19361.0 + 4.44 + 4 + http://www.thrustcurve.org/motorsearch.jsp?id=450 + 14784.0 + 9570.8 + RMS-98/18000 + Blue Thunder + 2016-01-17 + OOP + + + \ No newline at end of file diff --git a/core/test/net/sf/openrocket/thrustcurve/SearchResponseParserTest.java b/core/test/net/sf/openrocket/thrustcurve/SearchResponseParserTest.java new file mode 100644 index 000000000..a1c423679 --- /dev/null +++ b/core/test/net/sf/openrocket/thrustcurve/SearchResponseParserTest.java @@ -0,0 +1,19 @@ +package net.sf.openrocket.thrustcurve; + +import static org.junit.Assert.assertEquals; + +import java.io.InputStream; + +import org.junit.Test; + +import net.sf.openrocket.util.BaseTestCase.BaseTestCase; + +public class SearchResponseParserTest extends BaseTestCase { + + @Test + public void simpleParseTest() throws Exception { + InputStream is = SearchResponseParserTest.class.getResourceAsStream("SampleSearchResponse.xml"); + SearchResponse response = SearchResponseParser.parse(is); + assertEquals(252, response.getMatches()); + } +} diff --git a/swing/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/MotorInformationPanel.java b/swing/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/MotorInformationPanel.java index b9ff3b405..ed7c77aa8 100644 --- a/swing/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/MotorInformationPanel.java +++ b/swing/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/MotorInformationPanel.java @@ -1,5 +1,6 @@ package net.sf.openrocket.gui.dialogs.motor.thrustcurve; +import java.awt.BasicStroke; import java.awt.Color; import java.awt.Cursor; import java.awt.Font; diff --git a/swing/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/ThrustCurveMotorSelectionPanel.java b/swing/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/ThrustCurveMotorSelectionPanel.java index 917e876e1..f3f466b6a 100644 --- a/swing/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/ThrustCurveMotorSelectionPanel.java +++ b/swing/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/ThrustCurveMotorSelectionPanel.java @@ -60,6 +60,7 @@ import net.sf.openrocket.rocketcomponent.FlightConfigurationId; import net.sf.openrocket.rocketcomponent.MotorMount; import net.sf.openrocket.startup.Application; import net.sf.openrocket.util.BugException; +import net.sf.openrocket.utils.MotorCorrelation; public class ThrustCurveMotorSelectionPanel extends JPanel implements MotorSelector { private static final long serialVersionUID = -8737784181512143155L; @@ -492,6 +493,7 @@ public class ThrustCurveMotorSelectionPanel extends JPanel implements MotorSelec } motors = filtered; } + Collections.sort(motors, MOTOR_COMPARATOR); return motors; diff --git a/swing/test/net/sf/openrocket/IntegrationTest.java b/swing/test/net/sf/openrocket/IntegrationTest.java index f14fdec3e..7700e2245 100644 --- a/swing/test/net/sf/openrocket/IntegrationTest.java +++ b/swing/test/net/sf/openrocket/IntegrationTest.java @@ -43,7 +43,6 @@ import net.sf.openrocket.gui.main.UndoRedoAction; import net.sf.openrocket.l10n.DebugTranslator; import net.sf.openrocket.l10n.Translator; import net.sf.openrocket.masscalc.MassCalculator; -import net.sf.openrocket.motor.Motor; import net.sf.openrocket.motor.ThrustCurveMotor; import net.sf.openrocket.plugin.PluginModule; import net.sf.openrocket.rocketcomponent.EngineBlock; @@ -265,8 +264,8 @@ public class IntegrationTest { InputStream is = IntegrationTest.class.getResourceAsStream("Estes_A8.rse"); assertNotNull("Problem in unit test, cannot find Estes_A8.rse", is); try { - for (Motor m : loader.load(is, "Estes_A8.rse")) { - return (ThrustCurveMotor) m; + for (ThrustCurveMotor.Builder m : loader.load(is, "Estes_A8.rse")) { + return m.build(); } is.close(); } catch (IOException e) {