Revising previous commit to include the missing files.

This commit is contained in:
Kevin Ruland 2016-10-10 19:50:17 -05:00
parent f121def910
commit 6532743c3f
24 changed files with 6941 additions and 441 deletions

@ -7,6 +7,8 @@ import java.util.IdentityHashMap;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import net.sf.openrocket.motor.DesignationComparator; import net.sf.openrocket.motor.DesignationComparator;
import net.sf.openrocket.motor.Manufacturer; import net.sf.openrocket.motor.Manufacturer;
@ -37,6 +39,7 @@ public class ThrustCurveMotorSet implements Comparable<ThrustCurveMotorSet> {
private Manufacturer manufacturer = null; private Manufacturer manufacturer = null;
private String designation = null; private String designation = null;
private String simplifiedDesignation = null;
private double diameter = -1; private double diameter = -1;
private double length = -1; private double length = -1;
private long totalImpulse = 0; private long totalImpulse = 0;
@ -51,6 +54,7 @@ public class ThrustCurveMotorSet implements Comparable<ThrustCurveMotorSet> {
if (motors.isEmpty()) { if (motors.isEmpty()) {
manufacturer = motor.getManufacturer(); manufacturer = motor.getManufacturer();
designation = motor.getDesignation(); designation = motor.getDesignation();
simplifiedDesignation = simplifyDesignation(designation);
diameter = motor.getDiameter(); diameter = motor.getDiameter();
length = motor.getLength(); length = motor.getLength();
totalImpulse = Math.round((motor.getTotalImpulseEstimate())); totalImpulse = Math.round((motor.getTotalImpulseEstimate()));
@ -80,6 +84,11 @@ public class ThrustCurveMotorSet implements Comparable<ThrustCurveMotorSet> {
} }
} }
// Change the simplified designation if necessary
if (!designation.equalsIgnoreCase(motor.getDesignation().trim())) {
designation = simplifiedDesignation;
}
if (caseInfo == null) { if (caseInfo == null) {
caseInfo = motor.getCaseInfo(); caseInfo = motor.getCaseInfo();
} }
@ -146,6 +155,9 @@ public class ThrustCurveMotorSet implements Comparable<ThrustCurveMotorSet> {
return false; return false;
} }
if (!simplifiedDesignation.equalsIgnoreCase(simplifyDesignation(m.getDesignation())))
return false;
if (!designation.equalsIgnoreCase(m.getDesignation())) if (!designation.equalsIgnoreCase(m.getDesignation()))
return false; return false;
@ -250,6 +262,25 @@ public class ThrustCurveMotorSet implements Comparable<ThrustCurveMotorSet> {
", type=" + type + ", count=" + motors.size() + "]"; ", 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. * Comparator for deciding in which order to display matching motors.
*/ */

@ -174,10 +174,10 @@ public abstract class AbstractMotorLoader implements MotorLoader {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
protected static void finalizeThrustCurve(List<Double> time, List<Double> thrust, protected static void finalizeThrustCurve(List<Double> time, List<Double> thrust,
List... lists) { List... lists) {
if (time.size() == 0) if (time.size() == 0)
return; return;
// Start // Start
if (!MathUtil.equals(time.get(0), 0) || !MathUtil.equals(thrust.get(0), 0)) { if (!MathUtil.equals(time.get(0), 0) || !MathUtil.equals(thrust.get(0), 0)) {
time.add(0, 0.0); time.add(0, 0.0);

@ -25,7 +25,7 @@ public class GeneralMotorLoader implements MotorLoader {
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
* *
@ -37,7 +37,7 @@ public class GeneralMotorLoader implements MotorLoader {
} }
/** /**
* Return an array containing the supported file extensions. * Return an array containing the supported file extensions.
* *
@ -65,7 +65,7 @@ public class GeneralMotorLoader implements MotorLoader {
if (point > 0) if (point > 0)
ext = filename.substring(point + 1); ext = filename.substring(point + 1);
if (ext.equalsIgnoreCase("eng")) { if (ext.equalsIgnoreCase("eng")) {
return RASP_LOADER; return RASP_LOADER;
} else if (ext.equalsIgnoreCase("rse")) { } else if (ext.equalsIgnoreCase("rse")) {

@ -21,11 +21,15 @@ public class RASPMotorLoader extends AbstractMotorLoader {
public static final Charset CHARSET = Charset.forName(CHARSET_NAME); public static final Charset CHARSET = Charset.forName(CHARSET_NAME);
@Override @Override
protected Charset getDefaultCharset() { protected Charset getDefaultCharset() {
return CHARSET; return CHARSET;
} }
/** /**
* Load a <code>Motor</code> from a RASP file specified by the <code>Reader</code>. * Load a <code>Motor</code> from a RASP file specified by the <code>Reader</code>.
* The <code>Reader</code> is responsible for using the correct charset. * The <code>Reader</code> is responsible for using the correct charset.
@ -39,7 +43,7 @@ public class RASPMotorLoader extends AbstractMotorLoader {
*/ */
@Override @Override
public List<ThrustCurveMotor.Builder> load(Reader reader, String filename) throws IOException { public List<ThrustCurveMotor.Builder> load(Reader reader, String filename) throws IOException {
List<ThrustCurveMotor.Builder> motors = new ArrayList<ThrustCurveMotor.Builder>(); List<ThrustCurveMotor.Builder> motors = new ArrayList<>();
BufferedReader in = new BufferedReader(reader); BufferedReader in = new BufferedReader(reader);
String manufacturer = ""; String manufacturer = "";
@ -62,7 +66,7 @@ public class RASPMotorLoader extends AbstractMotorLoader {
line = in.readLine(); line = in.readLine();
main: while (line != null) { // Until EOF main: while (line != null) { // Until EOF
manufacturer = ""; manufacturer = "";
designation = ""; designation = "";
comment = ""; comment = "";
@ -98,7 +102,7 @@ public class RASPMotorLoader extends AbstractMotorLoader {
length = Double.parseDouble(pieces[2]) / 1000.0; length = Double.parseDouble(pieces[2]) / 1000.0;
if (pieces[3].equalsIgnoreCase("None")) { if (pieces[3].equalsIgnoreCase("None")) {
} else { } else {
buf = split(pieces[3], "[-,]+"); buf = split(pieces[3], "[-,]+");
for (int i = 0; i < buf.length; i++) { 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, private static ThrustCurveMotor.Builder createRASPMotor(String manufacturer, String designation,
String comment, double length, double diameter, double[] delays, String comment, double length, double diameter, double[] delays,
double propW, double totalW, List<Double> time, List<Double> thrust) double propW, double totalW, List<Double> time, List<Double> thrust)
throws IOException { throws IOException {
// Add zero time/thrust if necessary // Add zero time/thrust if necessary
sortLists(time, thrust); sortLists(time, thrust);
finalizeThrustCurve(time, thrust); finalizeThrustCurve(time, thrust);
@ -194,23 +198,28 @@ public class RASPMotorLoader extends AbstractMotorLoader {
motorDigest.update(DataType.FORCE_PER_TIME, thrustArray); motorDigest.update(DataType.FORCE_PER_TIME, thrustArray);
final String digest = motorDigest.getDigest(); final String digest = motorDigest.getDigest();
Manufacturer m = Manufacturer.getManufacturer(manufacturer); try {
ThrustCurveMotor.Builder builder = new ThrustCurveMotor.Builder(); Manufacturer m = Manufacturer.getManufacturer(manufacturer);
builder.setManufacturer(m) ThrustCurveMotor.Builder builder = new ThrustCurveMotor.Builder();
.setDesignation(designation) builder.setManufacturer(m)
.setDescription(comment) .setDesignation(designation)
.setDigest(digest) .setDescription(comment)
.setMotorType(m.getMotorType()) .setMotorType(m.getMotorType())
.setStandardDelays(delays) .setStandardDelays(delays)
.setDiameter(diameter) .setDiameter(diameter)
.setLength(length) .setLength(length)
.setTimePoints(timeArray) .setTimePoints(timeArray)
.setThrustPoints(thrustArray) .setThrustPoints(thrustArray)
.setCGPoints(cgArray) .setCGPoints(cgArray)
.setInitialMass(totalW) .setDigest(digest);
.setPropellantMass(propW); return builder;
return builder; } catch (IllegalArgumentException e) {
// Bad data read from file.
throw new IOException("Illegal file format.", e);
}
} }
} }

@ -23,6 +23,7 @@ import net.sf.openrocket.motor.Motor;
import net.sf.openrocket.motor.MotorDigest; import net.sf.openrocket.motor.MotorDigest;
import net.sf.openrocket.motor.MotorDigest.DataType; import net.sf.openrocket.motor.MotorDigest.DataType;
import net.sf.openrocket.motor.ThrustCurveMotor; import net.sf.openrocket.motor.ThrustCurveMotor;
import net.sf.openrocket.motor.ThrustCurveMotor.Builder;
import net.sf.openrocket.util.Coordinate; import net.sf.openrocket.util.Coordinate;
public class RockSimMotorLoader extends AbstractMotorLoader { public class RockSimMotorLoader extends AbstractMotorLoader {
@ -79,7 +80,7 @@ public class RockSimMotorLoader extends AbstractMotorLoader {
* Initial handler for the RockSim engine files. * Initial handler for the RockSim engine files.
*/ */
private static class RSEHandler extends AbstractElementHandler { private static class RSEHandler extends AbstractElementHandler {
private final List<ThrustCurveMotor.Builder> motors = new ArrayList<ThrustCurveMotor.Builder>(); private final List<ThrustCurveMotor.Builder> motors = new ArrayList<>();
private RSEMotorHandler motorHandler; private RSEMotorHandler motorHandler;
@ -90,7 +91,7 @@ public class RockSimMotorLoader extends AbstractMotorLoader {
@Override @Override
public ElementHandler openElement(String element, public ElementHandler openElement(String element,
HashMap<String, String> attributes, WarningSet warnings) throws SAXException { HashMap<String, String> attributes, WarningSet warnings) throws SAXException {
if (element.equals("engine-database") || if (element.equals("engine-database") ||
element.equals("engine-list")) { element.equals("engine-list")) {
// Ignore <engine-database> and <engine-list> elements // Ignore <engine-database> and <engine-list> elements
@ -113,7 +114,7 @@ public class RockSimMotorLoader extends AbstractMotorLoader {
@Override @Override
public void closeElement(String element, HashMap<String, String> attributes, public void closeElement(String element, HashMap<String, String> attributes,
String content, WarningSet warnings) throws SAXException { String content, WarningSet warnings) throws SAXException {
if (element.equals("engine")) { if (element.equals("engine")) {
ThrustCurveMotor.Builder motor = motorHandler.getMotor(); ThrustCurveMotor.Builder motor = motorHandler.getMotor();
motors.add(motor); motors.add(motor);
@ -265,7 +266,7 @@ public class RockSimMotorLoader extends AbstractMotorLoader {
@Override @Override
public ElementHandler openElement(String element, public ElementHandler openElement(String element,
HashMap<String, String> attributes, WarningSet warnings) throws SAXException { HashMap<String, String> attributes, WarningSet warnings) throws SAXException {
if (element.equals("comments")) { if (element.equals("comments")) {
return PlainTextHandler.INSTANCE; return PlainTextHandler.INSTANCE;
} }
@ -286,7 +287,7 @@ public class RockSimMotorLoader extends AbstractMotorLoader {
@Override @Override
public void closeElement(String element, HashMap<String, String> attributes, public void closeElement(String element, HashMap<String, String> attributes,
String content, WarningSet warnings) { String content, WarningSet warnings) {
if (element.equals("comments")) { if (element.equals("comments")) {
if (description.length() > 0) { if (description.length() > 0) {
description = description + "\n\n" + content.trim(); 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) if (time == null || time.size() == 0)
throw new SAXException("Illegal motor data"); throw new SAXException("Illegal motor data");
finalizeThrustCurve(time, force, mass, cg); finalizeThrustCurve(time, force, mass, cg);
final int n = time.size(); final int n = time.size();
@ -332,7 +333,7 @@ public class RockSimMotorLoader extends AbstractMotorLoader {
calculateMass = true; calculateMass = true;
if (hasIllegalValue(cg)) if (hasIllegalValue(cg))
calculateCG = true; calculateCG = true;
if (calculateMass) { if (calculateMass) {
mass = calculateMass(time, force, initMass, propMass); 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)); cgArray[i] = new Coordinate(cg.get(i), 0, 0, mass.get(i));
} }
// Create the motor digest from all data available in the file // Create the motor digest from all data available in the file
MotorDigest motorDigest = new MotorDigest(); MotorDigest motorDigest = new MotorDigest();
motorDigest.update(DataType.TIME_ARRAY, timeArray); motorDigest.update(DataType.TIME_ARRAY, timeArray);
@ -364,35 +366,36 @@ public class RockSimMotorLoader extends AbstractMotorLoader {
motorDigest.update(DataType.FORCE_PER_TIME, thrustArray); motorDigest.update(DataType.FORCE_PER_TIME, thrustArray);
final String digest = motorDigest.getDigest(); 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(); try {
builder.setManufacturer(m) Manufacturer m = Manufacturer.getManufacturer(manufacturer);
.setDesignation(designation) Motor.Type t = type;
.setDescription(description) if (t == Motor.Type.UNKNOWN) {
.setDigest(digest) t = m.getMotorType();
.setMotorType(t) } else {
.setStandardDelays(delays) if (m.getMotorType() != Motor.Type.UNKNOWN && m.getMotorType() != t) {
.setDiameter(diameter) log.warn("Loaded motor type inconsistent with manufacturer," +
.setLength(length) " loaded type=" + t + " manufacturer=" + m +
.setTimePoints(timeArray) " manufacturer type=" + m.getMotorType() +
.setThrustPoints(thrustArray) " designation=" + designation);
.setCGPoints(cgArray) }
.setInitialMass(initMass) }
.setPropellantMass(propMass);
return new ThrustCurveMotor.Builder()
return 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 @Override
public ElementHandler openElement(String element, public ElementHandler openElement(String element,
HashMap<String, String> attributes, WarningSet warnings) { HashMap<String, String> attributes, WarningSet warnings) {
if (element.equals("eng-data")) { if (element.equals("eng-data")) {
return NullElementHandler.INSTANCE; return NullElementHandler.INSTANCE;
} }
@ -440,7 +443,7 @@ public class RockSimMotorLoader extends AbstractMotorLoader {
@Override @Override
public void closeElement(String element, HashMap<String, String> attributes, public void closeElement(String element, HashMap<String, String> attributes,
String content, WarningSet warnings) throws SAXException { String content, WarningSet warnings) throws SAXException {
double t = parseDouble(attributes.get("t")); double t = parseDouble(attributes.get("t"));
double f = parseDouble(attributes.get("f")); double f = parseDouble(attributes.get("f"));
double m = parseDouble(attributes.get("m")) / 1000.0; double m = parseDouble(attributes.get("m")) / 1000.0;

@ -45,7 +45,7 @@ public class ZipFileMotorLoader implements MotorLoader {
@Override @Override
public List<ThrustCurveMotor.Builder> load(InputStream stream, String filename) throws IOException { public List<ThrustCurveMotor.Builder> load(InputStream stream, String filename) throws IOException {
List<ThrustCurveMotor.Builder> motors = new ArrayList<ThrustCurveMotor.Builder>(); List<ThrustCurveMotor.Builder> motors = new ArrayList<>();
ZipInputStream is = new ZipInputStream(stream); ZipInputStream is = new ZipInputStream(stream);
@ -56,10 +56,10 @@ public class ZipFileMotorLoader implements MotorLoader {
ZipEntry entry = is.getNextEntry(); ZipEntry entry = is.getNextEntry();
if (entry == null) if (entry == null)
break; break;
if (entry.isDirectory()) if (entry.isDirectory())
continue; continue;
// Get the file name of the entry // Get the file name of the entry
String name = entry.getName(); String name = entry.getName();
int index = name.lastIndexOf('/'); int index = name.lastIndexOf('/');

@ -8,7 +8,6 @@ import org.xml.sax.Attributes;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler; import org.xml.sax.helpers.DefaultHandler;
import net.sf.openrocket.aerodynamics.Warning;
import net.sf.openrocket.aerodynamics.WarningSet; import net.sf.openrocket.aerodynamics.WarningSet;
/** /**
@ -22,7 +21,6 @@ class DelegatorHandler extends DefaultHandler {
private final Deque<StringBuilder> elementData = new ArrayDeque<StringBuilder>(); private final Deque<StringBuilder> elementData = new ArrayDeque<StringBuilder>();
private final Deque<HashMap<String, String>> elementAttributes = new ArrayDeque<HashMap<String, String>>(); private final Deque<HashMap<String, String>> elementAttributes = new ArrayDeque<HashMap<String, String>>();
// Ignore all elements as long as ignore > 0 // Ignore all elements as long as ignore > 0
private int ignore = 0; private int ignore = 0;
@ -39,21 +37,13 @@ class DelegatorHandler extends DefaultHandler {
@Override @Override
public void startElement(String uri, String localName, String name, public void startElement(String uri, String localName, String name,
Attributes attributes) throws SAXException { Attributes attributes) throws SAXException {
// Check for ignore // Check for ignore
if (ignore > 0) { if (ignore > 0) {
ignore++; ignore++;
return; 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 // Add layer to data stacks
elementData.push(new StringBuilder()); elementData.push(new StringBuilder());
elementAttributes.push(copyAttributes(attributes)); elementAttributes.push(copyAttributes(attributes));
@ -78,7 +68,7 @@ class DelegatorHandler extends DefaultHandler {
// Check for ignore // Check for ignore
if (ignore > 0) if (ignore > 0)
return; return;
StringBuilder sb = elementData.peek(); StringBuilder sb = elementData.peek();
sb.append(chars, start, length); sb.append(chars, start, length);
} }

@ -1,6 +1,6 @@
package net.sf.openrocket.motor; package net.sf.openrocket.motor;
public interface Motor extends Cloneable { public interface Motor {
/** /**
* Enum of rocket motor types. * Enum of rocket motor types.
@ -119,8 +119,6 @@ public interface Motor extends Cloneable {
public String getDigest(); public String getDigest();
public Motor clone();
public double getAverageThrust( final double startTime, final double endTime ); public double getAverageThrust( final double startTime, final double endTime );
public double getLaunchCGx(); public double getLaunchCGx();
@ -187,4 +185,5 @@ public interface Motor extends Cloneable {
public double getUnitIyy(); public double getUnitIyy();
public double getUnitIzz(); public double getUnitIzz();
} }

@ -7,10 +7,9 @@ import java.util.Locale;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import net.sf.openrocket.models.atmosphere.AtmosphericConditions;
import net.sf.openrocket.util.BugException; import net.sf.openrocket.util.BugException;
import net.sf.openrocket.util.Coordinate; import net.sf.openrocket.util.Coordinate;
import net.sf.openrocket.util.Inertia;
import net.sf.openrocket.util.MathUtil; import net.sf.openrocket.util.MathUtil;
public class ThrustCurveMotor implements Motor, Comparable<ThrustCurveMotor>, Serializable { public class ThrustCurveMotor implements Motor, Comparable<ThrustCurveMotor>, Serializable {
@ -32,163 +31,198 @@ public class ThrustCurveMotor implements Motor, Comparable<ThrustCurveMotor>, Se
private String digest; private String digest;
private final Manufacturer manufacturer; private Manufacturer manufacturer;
private final String designation; private String designation;
private final String description; private String description;
private final Motor.Type type; private Motor.Type type;
private final double[] delays; private double[] delays;
private final double diameter; private double diameter;
private final double length; private double length;
private final double[] time; private double[] time;
private final double[] thrust; private double[] thrust;
private final Coordinate[] cg; private Coordinate[] cg;
private String caseInfo; private String caseInfo;
private String propellantInfo; private String propellantInfo;
private double initialMass; private double initialMass;
private double propellantMass;
private double maxThrust; private double maxThrust;
private double burnTimeEstimate; private double burnTimeEstimate;
private double averageThrust; private double averageThrust;
private double totalImpulse; private double totalImpulse;
private final double unitRotationalInertia;
private final double unitLongitudinalInertia;
private boolean available = true; private boolean available = true;
/** private double unitRotationalInertia;
* Deep copy constructor. private double unitLongitudinalInertia;
* Constructs a new ThrustCurveMotor from an existing ThrustCurveMotor.
* @param m public static class Builder {
*/
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();
this.caseInfo = m.caseInfo; ThrustCurveMotor motor = new ThrustCurveMotor();
this.propellantInfo = m.propellantInfo;
this.initialMass = m.initialMass; public Builder setAverageThrustEstimate(double v) {
this.maxThrust = m.maxThrust; motor.averageThrust = v;
this.burnTimeEstimate = m.burnTimeEstimate; return this;
this.averageThrust = m.averageThrust; }
this.totalImpulse = m.totalImpulse;
this.unitRotationalInertia = m.unitRotationalInertia; public Builder setBurnTimeEstimate(double v) {
this.unitLongitudinalInertia = m.unitLongitudinalInertia; 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. * Get the manufacturer of this motor.
@ -208,32 +242,6 @@ public class ThrustCurveMotor implements Motor, Comparable<ThrustCurveMotor>, Se
return time.clone(); 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: * find the index to data that corresponds to the given time:
* *
@ -354,6 +362,32 @@ public class ThrustCurveMotor implements Motor, Comparable<ThrustCurveMotor>, 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. * Returns the array of thrust points for this thrust curve.
* @return an array of thrust samples * @return an array of thrust samples
@ -450,11 +484,6 @@ public class ThrustCurveMotor implements Motor, Comparable<ThrustCurveMotor>, Se
return length; return length;
} }
@Override
public Motor clone() {
return new ThrustCurveMotor(this);
}
@Override @Override
public double getLaunchCGx() { public double getLaunchCGx() {
return cg[0].x;//cgx[0]; return cg[0].x;//cgx[0];
@ -526,7 +555,7 @@ public class ThrustCurveMotor implements Motor, Comparable<ThrustCurveMotor>, Se
} }
public double getPropellantMass(){ public double getPropellantMass(){
return (getLaunchMass() - getBurnoutMass()); return propellantMass;
} }
@Override @Override
@ -750,5 +779,5 @@ public class ThrustCurveMotor implements Motor, Comparable<ThrustCurveMotor>, Se
return value; return value;
} }
} }

@ -35,11 +35,11 @@ public class MotorBurnFile {
if (SupportedFileTypes.RASP_FORMAT.equals(filetype)) { if (SupportedFileTypes.RASP_FORMAT.equals(filetype)) {
RASPMotorLoader loader = new RASPMotorLoader(); RASPMotorLoader loader = new RASPMotorLoader();
List<ThrustCurveMotor.Builder> motors = loader.load(new StringReader(data), "download"); List<ThrustCurveMotor.Builder> 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)) { } else if (SupportedFileTypes.ROCKSIM_FORMAT.equals(filetype)) {
RockSimMotorLoader loader = new RockSimMotorLoader(); RockSimMotorLoader loader = new RockSimMotorLoader();
List<ThrustCurveMotor.Builder> motors = loader.load(new StringReader(data), "download"); List<ThrustCurveMotor.Builder> motors = loader.load(new StringReader(data), "download");
this.thrustCurveMotor = motors.get(0); this.thrustCurveMotor = (ThrustCurveMotor.Builder)motors.get(0);
} }
} catch (IOException ex) { } catch (IOException ex) {
this.thrustCurveMotor = null; this.thrustCurveMotor = null;

@ -100,6 +100,9 @@ public class SearchResponseParser implements ElementHandler {
} }
response.addMotor(currentMotor); response.addMotor(currentMotor);
break; break;
case matches:
this.response.setMatches(Integer.parseInt(content));
break;
case motor_id: case motor_id:
currentMotor.setMotor_id(Integer.parseInt(content)); currentMotor.setMotor_id(Integer.parseInt(content));
break; break;
@ -172,7 +175,7 @@ public class SearchResponseParser implements ElementHandler {
} }
} }
@Override @Override
public void endHandler(String element, HashMap<String, String> attributes, String content, WarningSet warnings) throws SAXException { public void endHandler(String element, HashMap<String, String> attributes, String content, WarningSet warnings) throws SAXException {
} }

@ -17,7 +17,6 @@ import net.sf.openrocket.file.motor.GeneralMotorLoader;
import net.sf.openrocket.gui.util.SimpleFileFilter; import net.sf.openrocket.gui.util.SimpleFileFilter;
import net.sf.openrocket.motor.Motor; import net.sf.openrocket.motor.Motor;
import net.sf.openrocket.motor.ThrustCurveMotor; import net.sf.openrocket.motor.ThrustCurveMotor;
import net.sf.openrocket.motor.ThrustCurveMotor.Builder;
import net.sf.openrocket.util.Pair; import net.sf.openrocket.util.Pair;
public class SerializeThrustcurveMotors { public class SerializeThrustcurveMotors {
@ -130,11 +129,11 @@ public class SerializeThrustcurveMotors {
builder.setPropellantMass(mi.getProp_mass_g() / 1000.0); builder.setPropellantMass(mi.getProp_mass_g() / 1000.0);
} }
builder.setCaseInfo(mi.getCase_info()) builder.setCaseInfo(mi.getCase_info());
.setPropellantInfo(mi.getProp_info()) builder.setPropellantInfo(mi.getProp_info());
.setDiameter(mi.getDiameter() / 1000.0) builder.setDiameter(mi.getDiameter() / 1000.0);
.setLength(mi.getLength() / 1000.0) builder.setLength(mi.getLength() / 1000.0);
.setMotorType(type); builder.setMotorType(type);
if ("OOP".equals(mi.getAvailiability())) { if ("OOP".equals(mi.getAvailiability())) {
builder.setDesignation(mi.getDesignation()); builder.setDesignation(mi.getDesignation());
@ -183,9 +182,9 @@ public class SerializeThrustcurveMotors {
String fileName = f.getU(); String fileName = f.getU();
InputStream is = f.getV(); InputStream is = f.getV();
List<Builder> motors = loader.load(is, fileName); List<ThrustCurveMotor.Builder> motors = loader.load(is, fileName);
for (Builder builder : motors) { for (ThrustCurveMotor.Builder builder : motors) {
allMotors.add(builder.build()); allMotors.add(builder.build());
} }
} }

@ -88,97 +88,127 @@ public class TestRockets {
// Minimal motor without any useful numbers data // Minimal motor without any useful numbers data
private static ThrustCurveMotor getTestMotor() { private static ThrustCurveMotor getTestMotor() {
return new ThrustCurveMotor( return new ThrustCurveMotor.Builder()
Manufacturer.getManufacturer("A"), .setManufacturer(Manufacturer.getManufacturer("A"))
"F12X", "Desc", Motor.Type.UNKNOWN, new double[] {}, .setDesignation("F12X")
0.024, 0.07, new double[] { 0, 1, 2 }, new double[] { 0, 1, 0 }, .setDescription("Desc")
new Coordinate[] { Coordinate.NUL, Coordinate.NUL, Coordinate.NUL }, "digestA"); .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). // This function is used for unit, integration tests, DO NOT CHANGE (without updating tests).
private static Motor generateMotor_A8_18mm(){ private static Motor generateMotor_A8_18mm(){
// public ThrustCurveMotor(Manufacturer manufacturer, String designation, String description, return new ThrustCurveMotor.Builder()
// Motor.Type type, double[] delays, double diameter, double length, .setManufacturer(Manufacturer.getManufacturer("Estes"))
// double[] time, double[] thrust, .setDesignation("A8")
// Coordinate[] cg, String digest); .setDescription(" SU Black Powder")
return new ThrustCurveMotor( .setMotorType(Motor.Type.SINGLE)
Manufacturer.getManufacturer("Estes"),"A8", " SU Black Powder", .setStandardDelays(new double[] {0,3,5})
Motor.Type.SINGLE, new double[] {0,3,5}, 0.018, 0.070, .setDiameter(0.018)
new double[] { 0, 1, 2 }, new double[] { 0, 9, 0 }, .setLength(0.070)
new Coordinate[] { .setTimePoints(new double[] { 0, 1, 2 })
new Coordinate(0.035, 0, 0, 0.0164),new Coordinate(.035, 0, 0, 0.0145),new Coordinate(.035, 0, 0, 0.0131)}, .setThrustPoints(new double[] { 0, 9, 0 })
"digest A8 test"); .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). // This function is used for unit, integration tests, DO NOT CHANGE (without updating tests).
private static Motor generateMotor_B4_18mm(){ private static Motor generateMotor_B4_18mm(){
// public ThrustCurveMotor(Manufacturer manufacturer, String designation, String description, return new ThrustCurveMotor.Builder()
// Motor.Type type, double[] delays, double diameter, double length, .setManufacturer(Manufacturer.getManufacturer("Estes"))
// double[] time, double[] thrust, .setDesignation("B4")
// Coordinate[] cg, String digest); .setDescription(" SU Black Powder")
return new ThrustCurveMotor( .setMotorType(Motor.Type.SINGLE)
Manufacturer.getManufacturer("Estes"),"B4", " SU Black Powder", .setStandardDelays(new double[] {0,3,5})
Motor.Type.SINGLE, new double[] {0,3,5}, 0.018, 0.070, .setDiameter(0.018)
new double[] { 0, 1, 2 }, new double[] { 0, 11.4, 0 }, .setLength(0.070)
new Coordinate[] { .setTimePoints(new double[] { 0, 1, 2 })
new Coordinate(0.035, 0, 0, 0.0195),new Coordinate(.035, 0, 0, 0.0155),new Coordinate(.035, 0, 0, 0.013)}, .setThrustPoints(new double[] { 0, 11.4, 0 })
"digest B4 test"); .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). // This function is used for unit, integration tests, DO NOT CHANGE (without updating tests).
private static Motor generateMotor_C6_18mm(){ private static Motor generateMotor_C6_18mm(){
// public ThrustCurveMotor(Manufacturer manufacturer, String designation, String description, return new ThrustCurveMotor.Builder()
// Motor.Type type, double[] delays, double diameter, double length, .setManufacturer(Manufacturer.getManufacturer("Estes"))
// double[] time, double[] thrust, .setDesignation("C6")
// Coordinate[] cg, String digest); .setDescription(" SU Black Powder")
return new ThrustCurveMotor( .setMotorType(Motor.Type.SINGLE)
Manufacturer.getManufacturer("Estes"),"C6", " SU Black Powder", .setStandardDelays(new double[] {0,3,5,7})
Motor.Type.SINGLE, new double[] {0,3,5,7}, 0.018, 0.070, .setDiameter(0.018)
new double[] { 0, 1, 2 }, new double[] { 0, 6, 0 }, .setLength(0.070)
new Coordinate[] { .setTimePoints(new double[] { 0, 1, 2 })
new Coordinate(0.035, 0, 0, 0.0227),new Coordinate(.035, 0, 0, 0.0165),new Coordinate(.035, 0, 0, 0.012)}, .setThrustPoints(new double[] { 0, 6, 0 })
"digest C6 test"); .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). // This function is used for unit, integration tests, DO NOT CHANGE (without updating tests).
private static Motor generateMotor_D21_18mm(){ private static Motor generateMotor_D21_18mm(){
return new ThrustCurveMotor( return new ThrustCurveMotor.Builder()
Manufacturer.getManufacturer("AeroTech"),"D21", "Desc", .setManufacturer(Manufacturer.getManufacturer("AeroTech"))
Motor.Type.SINGLE, new double[] {}, 0.018, 0.07, .setDesignation("D21")
new double[] { 0, 1, 2 }, new double[] { 0, 32, 0 }, .setDescription("Desc")
new Coordinate[] { .setMotorType(Motor.Type.SINGLE)
new Coordinate(.035, 0, 0, 0.025),new Coordinate(.035, 0, 0, .020),new Coordinate(.035, 0, 0, 0.0154)}, .setStandardDelays(new double[] {})
"digest D21 test"); .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). // This function is used for unit, integration tests, DO NOT CHANGE (without updating tests).
private static Motor generateMotor_M1350_75mm(){ private static Motor generateMotor_M1350_75mm(){
// public ThrustCurveMotor(Manufacturer manufacturer, String designation, String description, return new ThrustCurveMotor.Builder()
// Motor.Type type, double[] delays, double diameter, double length, .setManufacturer(Manufacturer.getManufacturer("AeroTech"))
// double[] time, double[] thrust, .setDesignation("M1350")
// Coordinate[] cg, String digest); .setDescription("Desc")
return new ThrustCurveMotor( .setMotorType(Motor.Type.SINGLE)
Manufacturer.getManufacturer("AeroTech"),"M1350", "Desc", .setStandardDelays(new double[] {})
Motor.Type.SINGLE, new double[] {}, 0.075, 0.622, .setDiameter(0.075)
new double[] { 0, 1, 2 }, new double[] { 0, 1357, 0 }, .setLength(0.622)
new Coordinate[] { .setTimePoints(new double[] { 0, 1, 2 })
new Coordinate(.311, 0, 0, 4.808),new Coordinate(.311, 0, 0, 3.389),new Coordinate(.311, 0, 0, 1.970)}, .setThrustPoints(new double[] { 0, 1357, 0 })
"digest M1350 test"); .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). // This function is used for unit, integration tests, DO NOT CHANGE (without updating tests).
private static Motor generateMotor_G77_29mm(){ private static Motor generateMotor_G77_29mm(){
// public ThrustCurveMotor(Manufacturer manufacturer, String designation, String description, return new ThrustCurveMotor.Builder()
// Motor.Type type, double[] delays, double diameter, double length, .setManufacturer(Manufacturer.getManufacturer("AeroTech"))
// double[] time, double[] thrust, .setDesignation("G77")
// Coordinate[] cg, String digest); .setDescription("Desc")
return new ThrustCurveMotor( .setMotorType(Motor.Type.SINGLE)
Manufacturer.getManufacturer("AeroTech"),"G77", "Desc", .setStandardDelays(new double[] {4,7,10})
Motor.Type.SINGLE, new double[] {4,7,10},0.029, 0.124, .setDiameter(0.029)
new double[] { 0, 1, 2 }, new double[] { 0, 1, 0 }, .setLength(0.124)
new Coordinate[] { .setTimePoints(new double[] { 0, 1, 2 })
new Coordinate(.062, 0, 0, 0.123),new Coordinate(.062, 0, 0, .0935),new Coordinate(.062, 0, 0, 0.064)}, .setThrustPoints(new double[] { 0, 1, 0 })
"digest G77 test"); .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();
} }
// //

@ -1,13 +1,5 @@
package net.sf.openrocket.utils; 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.motor.Motor;
import net.sf.openrocket.util.BugException; import net.sf.openrocket.util.BugException;
import net.sf.openrocket.util.MathUtil; import net.sf.openrocket.util.MathUtil;
@ -85,47 +77,4 @@ public class MotorCorrelation {
return cross / auto; return cross / auto;
} }
public static void main(String[] args) {
MotorLoader loader = new GeneralMotorLoader();
List<Motor> motors = new ArrayList<Motor>();
List<String> files = new ArrayList<String>();
// Load files
for (String file : args) {
List<Motor> 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)));
}
}
}
} }

@ -20,29 +20,61 @@ import org.junit.Test;
public class ThrustCurveMotorSetTest { public class ThrustCurveMotorSetTest {
private static final ThrustCurveMotor motor1 = new ThrustCurveMotor( private static final ThrustCurveMotor motor1 = new ThrustCurveMotor.Builder()
Manufacturer.getManufacturer("A"), .setManufacturer(Manufacturer.getManufacturer("A"))
"F12X", "Desc", Motor.Type.UNKNOWN, new double[] {}, .setDesignation("F12X")
0.024, 0.07, new double[] { 0, 1, 2 }, new double[] { 0, 1, 0 }, .setDescription("Desc")
new Coordinate[] { Coordinate.NUL, Coordinate.NUL, Coordinate.NUL }, "digestA"); .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( private static final ThrustCurveMotor motor2 = new ThrustCurveMotor.Builder()
Manufacturer.getManufacturer("A"), .setManufacturer(Manufacturer.getManufacturer("A"))
"F12H", "Desc", Motor.Type.SINGLE, new double[] { 5 }, .setDesignation("F12H")
0.024, 0.07, new double[] { 0, 1, 2 }, new double[] { 0, 1, 0 }, .setDescription("Desc")
new Coordinate[] { Coordinate.NUL, Coordinate.NUL, Coordinate.NUL }, "digestB"); .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( private static final ThrustCurveMotor motor3 = new ThrustCurveMotor.Builder()
Manufacturer.getManufacturer("A"), .setManufacturer(Manufacturer.getManufacturer("A"))
"F12", "Desc", Motor.Type.UNKNOWN, new double[] { 0, Motor.PLUGGED_DELAY }, .setDesignation("F12")
0.024, 0.07, new double[] { 0, 1, 2 }, new double[] { 0, 2, 0 }, .setDescription("Desc")
new Coordinate[] { Coordinate.NUL, Coordinate.NUL, Coordinate.NUL }, "digestC"); .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( private static final ThrustCurveMotor motor4 = new ThrustCurveMotor.Builder()
Manufacturer.getManufacturer("A"), .setManufacturer(Manufacturer.getManufacturer("A"))
"F12", "Desc", Motor.Type.HYBRID, new double[] { 0 }, .setDesignation("F12")
0.024, 0.07, new double[] { 0, 1, 2 }, new double[] { 0, 2, 0 }, .setDesignation("Desc")
new Coordinate[] { Coordinate.NUL, Coordinate.NUL, Coordinate.NUL }, "digestD"); .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 @Test

@ -10,6 +10,7 @@ import java.util.Arrays;
import java.util.List; import java.util.List;
import net.sf.openrocket.motor.Motor; import net.sf.openrocket.motor.Motor;
import net.sf.openrocket.motor.ThrustCurveMotor;
import org.junit.Test; import org.junit.Test;
@ -52,7 +53,7 @@ public class TestMotorLoader {
private void test(MotorLoader loader, String file, String... digests) throws IOException { private void test(MotorLoader loader, String file, String... digests) throws IOException {
List<Motor> motors; List<ThrustCurveMotor.Builder> motors;
InputStream is = this.getClass().getResourceAsStream(file); InputStream is = this.getClass().getResourceAsStream(file);
assertNotNull("File " + file + " not found", is); assertNotNull("File " + file + " not found", is);
@ -62,7 +63,7 @@ public class TestMotorLoader {
String[] d = new String[digests.length]; String[] d = new String[digests.length];
for (int i = 0; i < motors.size(); i++) { 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); Arrays.sort(digests);

@ -284,8 +284,8 @@ public class OpenRocketSaverTest {
InputStream is = OpenRocketSaverTest.class.getResourceAsStream("/net/sf/openrocket/Estes_A8.rse"); InputStream is = OpenRocketSaverTest.class.getResourceAsStream("/net/sf/openrocket/Estes_A8.rse");
assertNotNull("Problem in unit test, cannot find Estes_A8.rse", is); assertNotNull("Problem in unit test, cannot find Estes_A8.rse", is);
try { try {
for (Motor m : loader.load(is, "Estes_A8.rse")) { for (ThrustCurveMotor.Builder m : loader.load(is, "Estes_A8.rse")) {
return (ThrustCurveMotor) m; return m.build();
} }
is.close(); is.close();
} catch (IOException e) { } catch (IOException e) {
@ -311,11 +311,19 @@ public class OpenRocketSaverTest {
public MotorDbProvider() { public MotorDbProvider() {
db.addMotor(readMotor()); db.addMotor(readMotor());
db.addMotor( new ThrustCurveMotor( db.addMotor( new ThrustCurveMotor.Builder()
Manufacturer.getManufacturer("A"), .setManufacturer(Manufacturer.getManufacturer("A"))
"F12X", "Desc", Motor.Type.UNKNOWN, new double[] {}, .setDesignation("F12X")
0.024, 0.07, new double[] { 0, 1, 2 }, new double[] { 0, 1, 0 }, .setDescription("Desc")
new Coordinate[] { Coordinate.NUL, Coordinate.NUL, Coordinate.NUL }, "digestA")); .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()); assertEquals(2, db.getMotorSets().size());
} }

@ -16,49 +16,58 @@ public class ThrustCurveMotorTest {
private final double radius = 0.025; private final double radius = 0.025;
private final double length = 0.10; private final double length = 0.10;
private final ThrustCurveMotor motorX6 = private final ThrustCurveMotor motorX6 = new ThrustCurveMotor.Builder()
new ThrustCurveMotor(Manufacturer.getManufacturer("foo"), .setManufacturer(Manufacturer.getManufacturer("foo"))
"X6", "Description of X6", Motor.Type.RELOAD, .setDesignation("X6")
new double[] {0, 2, Motor.PLUGGED_DELAY}, radius*2, length, .setDescription("Description of X6")
new double[] {0, 1, 3, 4}, // time .setMotorType(Motor.Type.RELOAD)
new double[] {0, 2, 3, 0}, // thrust .setStandardDelays(new double[] {0, 2, Motor.PLUGGED_DELAY})
new Coordinate[] { .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.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) new Coordinate(0.03,0,0,0.03)})
}, "digestA"); .setDigest("digestA")
.build();
private final double radiusA8 = 0.018; private final double radiusA8 = 0.018;
private final double lengthA8 = 0.10; private final double lengthA8 = 0.10;
private final ThrustCurveMotor motorEstesA8_3 = private final ThrustCurveMotor motorEstesA8_3 = new ThrustCurveMotor.Builder()
new ThrustCurveMotor(Manufacturer.getManufacturer("Estes"), .setManufacturer(Manufacturer.getManufacturer("Estes"))
"A8-3", "A8 Test Motor", Motor.Type.SINGLE, .setDesignation("A8-3")
new double[] {0, 2, Motor.PLUGGED_DELAY}, radiusA8*2, lengthA8, .setDescription("A8 Test Motor")
.setMotorType(Motor.Type.SINGLE)
new double[] { // time (sec) .setStandardDelays(new double[] {0, 2, Motor.PLUGGED_DELAY})
.setDiameter(radiusA8*2)
.setLength(lengthA8)
.setTimePoints(new double[] {
0, 0.041, 0.084, 0.127, 0, 0.041, 0.084, 0.127,
0.166, 0.192, 0.206, 0.226, 0.166, 0.192, 0.206, 0.226,
0.236, 0.247, 0.261, 0.277, 0.236, 0.247, 0.261, 0.277,
0.306, 0.351, 0.405, 0.467, 0.306, 0.351, 0.405, 0.467,
0.532, 0.589, 0.632, 0.652, 0.532, 0.589, 0.632, 0.652,
0.668, 0.684, 0.703, 0.73}, 0.668, 0.684, 0.703, 0.73})
new double[] { // thrust (N) .setThrustPoints(new double[] {
0, 0.512, 2.115, 4.358, 0, 0.512, 2.115, 4.358,
6.794, 8.588, 9.294, 9.73, 6.794, 8.588, 9.294, 9.73,
8.845, 7.179, 5.063, 3.717, 8.845, 7.179, 5.063, 3.717,
3.205, 2.884, 2.499, 2.371, 3.205, 2.884, 2.499, 2.371,
2.307, 2.371, 2.371, 2.243, 2.307, 2.371, 2.371, 2.243,
1.794, 1.153, 0.448, 0}, 1.794, 1.153, 0.448, 0})
new Coordinate[] { /// ( m, m, m, kg) .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.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.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.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.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.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) 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"); .setDigest("digestA8-3")
.build();
@Test @Test

File diff suppressed because it is too large Load Diff

@ -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());
}
}

@ -1,5 +1,6 @@
package net.sf.openrocket.gui.dialogs.motor.thrustcurve; package net.sf.openrocket.gui.dialogs.motor.thrustcurve;
import java.awt.BasicStroke;
import java.awt.Color; import java.awt.Color;
import java.awt.Cursor; import java.awt.Cursor;
import java.awt.Font; import java.awt.Font;

@ -60,6 +60,7 @@ import net.sf.openrocket.rocketcomponent.FlightConfigurationId;
import net.sf.openrocket.rocketcomponent.MotorMount; import net.sf.openrocket.rocketcomponent.MotorMount;
import net.sf.openrocket.startup.Application; import net.sf.openrocket.startup.Application;
import net.sf.openrocket.util.BugException; import net.sf.openrocket.util.BugException;
import net.sf.openrocket.utils.MotorCorrelation;
public class ThrustCurveMotorSelectionPanel extends JPanel implements MotorSelector { public class ThrustCurveMotorSelectionPanel extends JPanel implements MotorSelector {
private static final long serialVersionUID = -8737784181512143155L; private static final long serialVersionUID = -8737784181512143155L;
@ -492,6 +493,7 @@ public class ThrustCurveMotorSelectionPanel extends JPanel implements MotorSelec
} }
motors = filtered; motors = filtered;
} }
Collections.sort(motors, MOTOR_COMPARATOR); Collections.sort(motors, MOTOR_COMPARATOR);
return motors; return motors;

@ -43,7 +43,6 @@ import net.sf.openrocket.gui.main.UndoRedoAction;
import net.sf.openrocket.l10n.DebugTranslator; import net.sf.openrocket.l10n.DebugTranslator;
import net.sf.openrocket.l10n.Translator; import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.masscalc.MassCalculator; import net.sf.openrocket.masscalc.MassCalculator;
import net.sf.openrocket.motor.Motor;
import net.sf.openrocket.motor.ThrustCurveMotor; import net.sf.openrocket.motor.ThrustCurveMotor;
import net.sf.openrocket.plugin.PluginModule; import net.sf.openrocket.plugin.PluginModule;
import net.sf.openrocket.rocketcomponent.EngineBlock; import net.sf.openrocket.rocketcomponent.EngineBlock;
@ -265,8 +264,8 @@ public class IntegrationTest {
InputStream is = IntegrationTest.class.getResourceAsStream("Estes_A8.rse"); InputStream is = IntegrationTest.class.getResourceAsStream("Estes_A8.rse");
assertNotNull("Problem in unit test, cannot find Estes_A8.rse", is); assertNotNull("Problem in unit test, cannot find Estes_A8.rse", is);
try { try {
for (Motor m : loader.load(is, "Estes_A8.rse")) { for (ThrustCurveMotor.Builder m : loader.load(is, "Estes_A8.rse")) {
return (ThrustCurveMotor) m; return m.build();
} }
is.close(); is.close();
} catch (IOException e) { } catch (IOException e) {