diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/DocumentConfig.java b/core/src/net/sf/openrocket/file/openrocket/importt/DocumentConfig.java
index 3dd43b81b..0d3c657e6 100644
--- a/core/src/net/sf/openrocket/file/openrocket/importt/DocumentConfig.java
+++ b/core/src/net/sf/openrocket/file/openrocket/importt/DocumentConfig.java
@@ -253,9 +253,9 @@ class DocumentConfig {
setters.put("FinSet:cant", new DoubleSetter(
Reflection.findMethod(FinSet.class, "setCantAngle", double.class), Math.PI / 180.0));
setters.put("FinSet:tabheight", new DoubleSetter(
- Reflection.findMethod(FinSet.class, "setTabHeight", double.class)));
+ Reflection.findMethod(FinSet.class, "setTabHeightNoValidate", double.class)));
setters.put("FinSet:tablength", new DoubleSetter(
- Reflection.findMethod(FinSet.class, "setTabLength", double.class)));
+ Reflection.findMethod(FinSet.class, "setTabLengthNoValidate", double.class)));
setters.put("FinSet:tabposition", new FinTabPositionSetter());
setters.put("FinSet:filletradius", new DoubleSetter(
Reflection.findMethod(FinSet.class, "setFilletRadius", double.class)));
diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/FinTabPositionSetter.java b/core/src/net/sf/openrocket/file/openrocket/importt/FinTabPositionSetter.java
index b0e3fda77..64072455f 100644
--- a/core/src/net/sf/openrocket/file/openrocket/importt/FinTabPositionSetter.java
+++ b/core/src/net/sf/openrocket/file/openrocket/importt/FinTabPositionSetter.java
@@ -11,7 +11,7 @@ import net.sf.openrocket.util.Reflection;
class FinTabPositionSetter extends DoubleSetter {
public FinTabPositionSetter() {
- super(Reflection.findMethod(FinSet.class, "setTabOffset", double.class));
+ super(Reflection.findMethod(FinSet.class, "setTabOffsetNoValidate", double.class));
}
@Override
@@ -50,4 +50,4 @@ class FinTabPositionSetter extends DoubleSetter {
}
-}
\ No newline at end of file
+}
diff --git a/core/src/net/sf/openrocket/file/rocksim/importt/FinSetHandler.java b/core/src/net/sf/openrocket/file/rocksim/importt/FinSetHandler.java
index f2f9d7f64..ed84c8f3a 100644
--- a/core/src/net/sf/openrocket/file/rocksim/importt/FinSetHandler.java
+++ b/core/src/net/sf/openrocket/file/rocksim/importt/FinSetHandler.java
@@ -315,9 +315,9 @@ class FinSetHandler extends AbstractElementHandler {
result.setFinish(finish);
//All TTW tabs in Rocksim are relative to the front of the fin.
result.setTabOffsetMethod( AxialMethod.TOP);
- result.setTabHeight(tabDepth);
- result.setTabLength(tabLength);
- result.setTabOffset(taboffset);
+ result.setTabHeightNoValidate(tabDepth);
+ result.setTabLengthNoValidate(tabLength);
+ result.setTabOffsetNoValidate(taboffset);
result.setBaseRotation(radialAngle);
result.setCrossSection(convertTipShapeCode(tipShapeCode));
result.setAxialMethod(axialMethod);
diff --git a/core/src/net/sf/openrocket/rocketcomponent/FinSet.java b/core/src/net/sf/openrocket/rocketcomponent/FinSet.java
index 57bb50b27..2b42be1e6 100644
--- a/core/src/net/sf/openrocket/rocketcomponent/FinSet.java
+++ b/core/src/net/sf/openrocket/rocketcomponent/FinSet.java
@@ -247,6 +247,24 @@ public abstract class FinSet extends ExternalComponent implements RingInstanceab
public double getTabHeight() {
return tabHeight;
}
+
+ /**
+ * wrapper to call setTabHeight without validating tab.
+ * This is intended to be used when reading a rocket from a file,
+ * since if the fin tab is read before the fin, validation will
+ * reduce the tab length to the default fin length
+ */
+ public void setTabHeightNoValidate(final double heightRequest) {
+ setTabHeight(heightRequest, false);
+ }
+
+ /**
+ * wrapper to call setTabHeight and validate tab.
+ * This is intended to be used from the GUI
+ */
+ public void setTabHeight(final double heightRequest) {
+ setTabHeight(heightRequest, true);
+ }
/**
* Set the height from the fin's base at the reference point -- i.e. where the tab is located from. If the tab is located via BOTTOM, then the back edge will be
@@ -258,14 +276,16 @@ public abstract class FinSet extends ExternalComponent implements RingInstanceab
* @param newHeightRequest how deep the fin tab should project from the fin root, at the reference point
*
*/
- public void setTabHeight(final double newHeightRequest) {
- if (MathUtil.equals(this.tabHeight, MathUtil.max(newHeightRequest, 0))){
+ private void setTabHeight(final double heightRequest, final boolean validate) {
+ if (MathUtil.equals(this.tabHeight, MathUtil.max(heightRequest, 0))){
return;
}
- this.tabHeight = newHeightRequest;
-
- validateFinTab();
+ tabHeight = heightRequest;
+
+ if (validate)
+ validateFinTab();
+
fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE);
}
@@ -273,26 +293,74 @@ public abstract class FinSet extends ExternalComponent implements RingInstanceab
public double getTabLength() {
return tabLength;
}
-
- public void setTabLength(double length) {
- length = MathUtil.max(length, 0);
- if (MathUtil.equals(this.tabLength, length))
+
+ /**
+ * Wrapper to call setTabLength with no validation
+ * This is only intended to be used when reading a
+ * rocket from a file. If the fin tab is read before
+ * the fin, validation will reduce the length of the tab
+ * to the default length of the fin
+ */
+ public void setTabLengthNoValidate(final double lengthRequest) {
+ setTabLength(lengthRequest, false);
+ }
+
+ /**
+ * Wrapper to call full setTabLength function, and validate
+ * tab length
+ */
+ public void setTabLength(final double lengthRequest) {
+ setTabLength(lengthRequest, true);
+ }
+
+ /**
+ * set tab length and optionally validate parameters
+ */
+ private void setTabLength(final double lengthRequest, final boolean validate) {
+ if (MathUtil.equals(tabLength, MathUtil.max(lengthRequest, 0))) {
return;
- tabLength = length;
- validateFinTab();
+ }
+
+ tabLength = lengthRequest;
+
+ if (validate) {
+ validateFinTab();
+ }
+
fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE);
}
- /**
- * internally, set the internal
- *
- * @param newOffset new requested shift of tab -- from
+ /**
+ * wrapper to call setTabOffset without validating tab.
+ * This is intended to be used when reading a rocket from a file,
+ * since if the fin tab is read before the fin, validation will
+ * reduce the tab length to the default fin length
*/
- public void setTabOffset( final double newOffset) {
- this.tabOffset = newOffset;
- this.tabPosition = this.tabOffsetMethod.getAsPosition( newOffset, this.tabLength, this.length);
+ public void setTabOffsetNoValidate(final double offsetRequest) {
+ setTabOffset(offsetRequest, false);
+ }
- validateFinTab();
+ /**
+ * wrapper to call setTabOffset and validate tab.
+ * This is intended to be used in the gui
+ */
+ public void setTabOffset(final double offsetRequest) {
+ setTabOffset(offsetRequest, true);
+ }
+
+ /**
+ * internally, set the internal offset and optionally validate tab
+ *
+ * @param offsetRequest new requested shift of tab -- from
+ * @param validate wehther or not to validate
+ */
+ private void setTabOffset( final double offsetRequest, final boolean validate) {
+ tabOffset = offsetRequest;
+ tabPosition = tabOffsetMethod.getAsPosition( tabOffset, tabLength, length);
+
+ if (validate) {
+ validateFinTab();
+ }
fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE);
}
diff --git a/core/src/net/sf/openrocket/util/#TestRockets.java# b/core/src/net/sf/openrocket/util/#TestRockets.java#
new file mode 100644
index 000000000..2213a18ad
--- /dev/null
+++ b/core/src/net/sf/openrocket/util/#TestRockets.java#
@@ -0,0 +1,1633 @@
+package net.sf.openrocket.util;
+
+import java.util.Random;
+
+import net.sf.openrocket.appearance.Appearance;
+import net.sf.openrocket.file.openrocket.OpenRocketSaver;
+import net.sf.openrocket.database.Databases;
+import net.sf.openrocket.document.OpenRocketDocument;
+import net.sf.openrocket.document.OpenRocketDocumentFactory;
+import net.sf.openrocket.document.Simulation;
+import net.sf.openrocket.material.Material;
+import net.sf.openrocket.material.Material.Type;
+import net.sf.openrocket.motor.Manufacturer;
+import net.sf.openrocket.motor.Motor;
+import net.sf.openrocket.motor.MotorConfiguration;
+import net.sf.openrocket.motor.ThrustCurveMotor;
+import net.sf.openrocket.preset.ComponentPreset;
+import net.sf.openrocket.preset.ComponentPresetFactory;
+import net.sf.openrocket.preset.InvalidComponentPresetException;
+import net.sf.openrocket.preset.TypedPropertyMap;
+import net.sf.openrocket.rocketcomponent.AxialStage;
+import net.sf.openrocket.rocketcomponent.BodyTube;
+import net.sf.openrocket.rocketcomponent.Bulkhead;
+import net.sf.openrocket.rocketcomponent.CenteringRing;
+import net.sf.openrocket.rocketcomponent.ClusterConfiguration;
+import net.sf.openrocket.rocketcomponent.DeploymentConfiguration;
+import net.sf.openrocket.rocketcomponent.DeploymentConfiguration.DeployEvent;
+import net.sf.openrocket.rocketcomponent.EngineBlock;
+import net.sf.openrocket.rocketcomponent.ExternalComponent;
+import net.sf.openrocket.rocketcomponent.ExternalComponent.Finish;
+import net.sf.openrocket.rocketcomponent.FinSet;
+import net.sf.openrocket.rocketcomponent.FinSet.CrossSection;
+import net.sf.openrocket.rocketcomponent.FlightConfiguration;
+import net.sf.openrocket.rocketcomponent.FlightConfigurationId;
+import net.sf.openrocket.rocketcomponent.FreeformFinSet;
+import net.sf.openrocket.rocketcomponent.InnerTube;
+import net.sf.openrocket.rocketcomponent.InternalComponent;
+import net.sf.openrocket.rocketcomponent.LaunchLug;
+import net.sf.openrocket.rocketcomponent.MassComponent;
+import net.sf.openrocket.rocketcomponent.NoseCone;
+import net.sf.openrocket.rocketcomponent.Parachute;
+import net.sf.openrocket.rocketcomponent.ParallelStage;
+import net.sf.openrocket.rocketcomponent.PodSet;
+import net.sf.openrocket.rocketcomponent.RecoveryDevice;
+import net.sf.openrocket.rocketcomponent.ReferenceType;
+import net.sf.openrocket.rocketcomponent.Rocket;
+import net.sf.openrocket.rocketcomponent.RocketComponent;
+import net.sf.openrocket.rocketcomponent.ShockCord;
+import net.sf.openrocket.rocketcomponent.StageSeparationConfiguration;
+import net.sf.openrocket.rocketcomponent.Transition;
+import net.sf.openrocket.rocketcomponent.Transition.Shape;
+import net.sf.openrocket.rocketcomponent.TrapezoidFinSet;
+import net.sf.openrocket.rocketcomponent.TubeCoupler;
+import net.sf.openrocket.rocketcomponent.position.*;
+import net.sf.openrocket.simulation.customexpression.CustomExpression;
+import net.sf.openrocket.simulation.exception.SimulationException;
+import net.sf.openrocket.simulation.extension.impl.ScriptingExtension;
+import net.sf.openrocket.simulation.listeners.AbstractSimulationListener;
+import net.sf.openrocket.simulation.listeners.SimulationListener;
+import net.sf.openrocket.startup.Application;
+
+public class TestRockets {
+
+ private final String key;
+ private final Random rnd;
+
+
+ public TestRockets(String key) {
+
+ if (key == null) {
+ Random myRnd = new Random();
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < 6; i++) {
+ int n = myRnd.nextInt(62);
+ if (n < 10) {
+ sb.append((char) ('0' + n));
+ } else if (n < 36) {
+ sb.append((char) ('A' + n - 10));
+ } else {
+ sb.append((char) ('a' + n - 36));
+ }
+ }
+ key = sb.toString();
+ }
+
+ this.key = key;
+ this.rnd = new Random(key.hashCode());
+
+ }
+
+ // Minimal motor without any useful numbers data
+ private static ThrustCurveMotor getTestMotor() {
+ 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(){
+ 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(){
+ 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(){
+ 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.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(){
+ 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(){
+ 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();
+ }
+
+ /**
+ * Create a new test rocket based on the value 'key'. The rocket utilizes most of the
+ * properties and features available. The same key always returns the same rocket,
+ * but different key values produce slightly different rockets. A key value of
+ * null
generates a rocket using a random key.
+ *
+ * The rocket created by this method is not fly-worthy. It is also NOT guaranteed
+ * that later versions would produce exactly the same rocket!
+ *
+ * @return a rocket design.
+ */
+ public Rocket makeTestRocket() {
+
+ Rocket rocket = new Rocket();
+ setBasics(rocket);
+ rocket.setCustomReferenceLength(rnd(0.05));
+ rocket.setDesigner("Designer " + key);
+ rocket.setReferenceType((ReferenceType) randomEnum(ReferenceType.class));
+ rocket.setRevision("Rocket revision " + key);
+ rocket.setName(key);
+
+ AxialStage stage = new AxialStage();
+ setBasics(stage);
+ rocket.addChild(stage);
+
+ NoseCone nose = new NoseCone();
+ setBasics(stage);
+ nose.setAftRadius(rnd(0.03));
+ nose.setAftRadiusAutomatic(rnd.nextBoolean());
+ nose.setAftShoulderCapped(rnd.nextBoolean());
+ nose.setAftShoulderLength(rnd(0.02));
+ nose.setAftShoulderRadius(rnd(0.02));
+ nose.setAftShoulderThickness(rnd(0.002));
+ nose.setClipped(rnd.nextBoolean());
+ nose.setThickness(rnd(0.002));
+ nose.setFilled(rnd.nextBoolean());
+ nose.setForeRadius(rnd(0.1)); // Unset
+ nose.setLength(rnd(0.15));
+ nose.setShapeParameter(rnd(0.5));
+ nose.setType((Shape) randomEnum(Shape.class));
+ stage.addChild(nose);
+
+ Transition shoulder = new Transition();
+ setBasics(shoulder);
+ shoulder.setAftRadius(rnd(0.06));
+ shoulder.setAftRadiusAutomatic(rnd.nextBoolean());
+ shoulder.setAftShoulderCapped(rnd.nextBoolean());
+ shoulder.setAftShoulderLength(rnd(0.02));
+ shoulder.setAftShoulderRadius(rnd(0.05));
+ shoulder.setAftShoulderThickness(rnd(0.002));
+ shoulder.setClipped(rnd.nextBoolean());
+ shoulder.setThickness(rnd(0.002));
+ shoulder.setFilled(rnd.nextBoolean());
+ shoulder.setForeRadius(rnd(0.03));
+ shoulder.setForeRadiusAutomatic(rnd.nextBoolean());
+ shoulder.setForeShoulderCapped(rnd.nextBoolean());
+ shoulder.setForeShoulderLength(rnd(0.02));
+ shoulder.setForeShoulderRadius(rnd(0.02));
+ shoulder.setForeShoulderThickness(rnd(0.002));
+ shoulder.setLength(rnd(0.15));
+ shoulder.setShapeParameter(rnd(0.5));
+ shoulder.setThickness(rnd(0.003));
+ shoulder.setType((Shape) randomEnum(Shape.class));
+ stage.addChild(shoulder);
+
+ BodyTube body = new BodyTube();
+ setBasics(body);
+ body.setThickness(rnd(0.002));
+ body.setFilled(rnd.nextBoolean());
+ body.setLength(rnd(0.3));
+ //body.setMotorMount(rnd.nextBoolean());
+ body.setMotorOverhang(rnd.nextGaussian() * 0.03);
+ body.setOuterRadius(rnd(0.06));
+ body.setOuterRadiusAutomatic(rnd.nextBoolean());
+ stage.addChild(body);
+
+ Transition boattail = new Transition();
+ setBasics(boattail);
+ boattail.setAftRadius(rnd(0.03));
+ boattail.setAftRadiusAutomatic(rnd.nextBoolean());
+ boattail.setAftShoulderCapped(rnd.nextBoolean());
+ boattail.setAftShoulderLength(rnd(0.02));
+ boattail.setAftShoulderRadius(rnd(0.02));
+ boattail.setAftShoulderThickness(rnd(0.002));
+ boattail.setClipped(rnd.nextBoolean());
+ boattail.setThickness(rnd(0.002));
+ boattail.setFilled(rnd.nextBoolean());
+ boattail.setForeRadius(rnd(0.06));
+ boattail.setForeRadiusAutomatic(rnd.nextBoolean());
+ boattail.setForeShoulderCapped(rnd.nextBoolean());
+ boattail.setForeShoulderLength(rnd(0.02));
+ boattail.setForeShoulderRadius(rnd(0.05));
+ boattail.setForeShoulderThickness(rnd(0.002));
+ boattail.setLength(rnd(0.15));
+ boattail.setShapeParameter(rnd(0.5));
+ boattail.setThickness(rnd(0.003));
+ boattail.setType((Shape) randomEnum(Shape.class));
+ stage.addChild(boattail);
+
+ MassComponent mass = new MassComponent();
+ setBasics(mass);
+ mass.setComponentMass(rnd(0.05));
+ mass.setLength(rnd(0.05));
+ mass.setRadialDirection(rnd(100));
+ mass.setRadialPosition(rnd(0.02));
+ mass.setRadius(rnd(0.05));
+ nose.addChild(mass);
+
+ rocket.enableEvents();
+ return rocket;
+ }
+
+
+ private void setBasics(RocketComponent c) {
+ c.setComment(c.getComponentName() + " comment " + key);
+ c.setName(c.getComponentName() + " name " + key);
+
+ c.setCGOverridden(rnd.nextBoolean());
+ c.setMassOverridden(rnd.nextBoolean());
+ c.setOverrideCGX(rnd(0.2));
+ c.setOverrideMass(rnd(0.05));
+ c.setOverrideSubcomponents(rnd.nextBoolean());
+
+ if (c.isMassive()) {
+ // Only massive components are drawn
+ c.setColor(randomColor());
+ c.setLineStyle((LineStyle) randomEnum(LineStyle.class));
+ }
+
+ if (c instanceof ExternalComponent) {
+ ExternalComponent e = (ExternalComponent) c;
+ e.setFinish((Finish) randomEnum(Finish.class));
+ double d = rnd(100);
+ e.setMaterial(Databases.findMaterial(Type.BULK, "Testmat " + d, d));
+ }
+
+ if (c instanceof InternalComponent) {
+ InternalComponent i = (InternalComponent) c;
+ i.setAxialMethod((AxialMethod) randomEnum(AxialMethod.class));
+ i.setAxialOffset(rnd(0.3));
+ }
+ }
+
+ private double rnd(double scale) {
+ return (rnd.nextDouble() * 0.2 + 0.9) * scale;
+ }
+
+ private Color randomColor() {
+ return new Color(rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256));
+ }
+
+ private > Enum randomEnum(Class c) {
+ Enum[] values = c.getEnumConstants();
+ if (values.length == 0)
+ return null;
+
+ return values[rnd.nextInt(values.length)];
+ }
+
+ final static FlightConfigurationId ESTES_ALPHA_III_FCID[] = {
+ null, // treat the array as 1-indexed.
+ new FlightConfigurationId("test_config #1: A8-0"),
+ new FlightConfigurationId("test_config #2: B4-3"),
+ new FlightConfigurationId("test_config #3: C6-3"),
+ new FlightConfigurationId("test_config #4: C6-5"),
+ new FlightConfigurationId("test_config #5: C6-7"),
+ };
+
+ // This is a Estes Alpha III
+ // http://www.rocketreviews.com/alpha-iii---estes-221256.html
+ // It is picked as a standard, simple, validation rocket.
+ // This function is used for unit, integration tests, DO NOT CHANGE (without updating tests).
+ public static final Rocket makeEstesAlphaIII(){
+ Rocket rocket = new Rocket();
+ FlightConfigurationId fcid[] = new FlightConfigurationId[5];
+ fcid[0] = rocket.createFlightConfiguration( ESTES_ALPHA_III_FCID[1] );
+ fcid[1] = rocket.createFlightConfiguration( ESTES_ALPHA_III_FCID[2] );
+ fcid[2] = rocket.createFlightConfiguration( ESTES_ALPHA_III_FCID[3] );
+ fcid[3] = rocket.createFlightConfiguration( ESTES_ALPHA_III_FCID[4] );
+ fcid[4] = rocket.createFlightConfiguration( ESTES_ALPHA_III_FCID[5] );
+
+
+ rocket.setName("Estes Alpha III / Code Verification Rocket");
+ AxialStage stage = new AxialStage();
+ stage.setName("Stage");
+ rocket.addChild(stage);
+
+ double noseconeLength = 0.07;
+ double noseconeRadius = 0.012;
+ NoseCone nosecone = new NoseCone(Transition.Shape.OGIVE, noseconeLength, noseconeRadius);
+ nosecone.setAftShoulderLength(0.02);
+ nosecone.setAftShoulderRadius(0.011);
+ nosecone.setName("Nose Cone");
+ stage.addChild(nosecone);
+
+ double bodytubeLength = 0.20;
+ double bodytubeRadius = 0.012;
+ double bodytubeThickness = 0.0003;
+ BodyTube bodytube = new BodyTube(bodytubeLength, bodytubeRadius, bodytubeThickness);
+ bodytube.setName("Body Tube");
+ stage.addChild(bodytube);
+
+ TrapezoidFinSet finset;
+ {
+ int finCount = 3;
+ double finRootChord = .05;
+ double finTipChord = .03;
+ double finSweep = 0.02;
+ double finHeight = 0.05;
+ finset = new TrapezoidFinSet(finCount, finRootChord, finTipChord, finSweep, finHeight);
+ finset.setThickness( 0.0032);
+ finset.setAxialMethod(AxialMethod.BOTTOM);
+ finset.setName("3 Fin Set");
+ bodytube.addChild(finset);
+
+ LaunchLug lug = new LaunchLug();
+ lug.setName("Launch Lugs");
+ lug.setAxialMethod(AxialMethod.TOP);
+ lug.setAxialOffset(0.111);
+ lug.setLength(0.050);
+ lug.setOuterRadius(0.0022);
+ lug.setInnerRadius(0.0020);
+ bodytube.addChild(lug);
+
+ InnerTube inner = new InnerTube();
+ inner.setAxialMethod(AxialMethod.TOP);
+ inner.setAxialOffset(0.133);
+ inner.setLength(0.07);
+ inner.setOuterRadius(0.009);
+ inner.setThickness(0.0003);
+ inner.setMotorMount(true);
+ inner.setName("Motor Mount Tube");
+ bodytube.addChild(inner);
+
+ {
+ // MotorBlock
+ EngineBlock thrustBlock= new EngineBlock();
+ thrustBlock.setAxialMethod(AxialMethod.TOP);
+ thrustBlock.setAxialOffset(0.0);
+ thrustBlock.setLength(0.005);
+ thrustBlock.setOuterRadius(0.009);
+ thrustBlock.setThickness(0.0008);
+ thrustBlock.setName("Engine Block");
+ inner.addChild(thrustBlock);
+ inner.setMotorMount( true);
+
+ {
+ MotorConfiguration motorConfig = new MotorConfiguration(inner,fcid[0]);
+ Motor mtr = TestRockets.generateMotor_A8_18mm();
+ motorConfig.setMotor( mtr);
+ motorConfig.setEjectionDelay(0.0);
+ inner.setMotorConfig( motorConfig, fcid[0]);
+ }
+ {
+ MotorConfiguration motorConfig = new MotorConfiguration(inner,fcid[1]);
+ Motor mtr = TestRockets.generateMotor_B4_18mm();
+ motorConfig.setMotor( mtr);
+ motorConfig.setEjectionDelay(3.0);
+ inner.setMotorConfig( motorConfig, fcid[1]);
+ }
+ {
+ MotorConfiguration motorConfig = new MotorConfiguration(inner,fcid[2]);
+ Motor mtr = TestRockets.generateMotor_C6_18mm();
+ motorConfig.setEjectionDelay(3.0);
+ motorConfig.setMotor( mtr);
+ inner.setMotorConfig( motorConfig, fcid[2]);
+ }
+ {
+ MotorConfiguration motorConfig = new MotorConfiguration(inner,fcid[3]);
+ Motor mtr = TestRockets.generateMotor_C6_18mm();
+ motorConfig.setEjectionDelay(5.0);
+ motorConfig.setMotor( mtr);
+ inner.setMotorConfig( motorConfig, fcid[3]);
+ }
+ {
+ MotorConfiguration motorConfig = new MotorConfiguration(inner,fcid[4]);
+ Motor mtr = TestRockets.generateMotor_C6_18mm();
+ motorConfig.setEjectionDelay(7.0);
+ motorConfig.setMotor( mtr);
+ inner.setMotorConfig( motorConfig, fcid[4]);
+ }
+ }
+
+ // parachute
+ Parachute chute = new Parachute();
+ chute.setAxialMethod(AxialMethod.TOP);
+ chute.setName("Parachute");
+ chute.setAxialOffset(0.028);
+ chute.setOverrideMass(0.002);
+ chute.setMassOverridden(true);
+ bodytube.addChild(chute);
+
+ // bulkhead x2
+ CenteringRing centerings = new CenteringRing();
+ centerings.setName("Centering Rings");
+ centerings.setAxialMethod(AxialMethod.TOP);
+ centerings.setAxialOffset(0.14);
+ centerings.setLength(0.006);
+ centerings.setInstanceCount(2);
+ centerings.setInstanceSeparation(0.035);
+ bodytube.addChild(centerings);
+ }
+
+ Material material = Application.getPreferences().getDefaultComponentMaterial(null, Material.Type.BULK);
+ nosecone.setMaterial(material);
+ bodytube.setMaterial(material);
+ finset.setMaterial(material);
+
+
+ // preserve default default configuration of rocket -- to test what the default is set to upon initialization.
+
+ rocket.enableEvents();
+ return rocket;
+ }
+
+ // This is an extra stage tacked onto the end of an Estes Alpha III
+ // http://www.rocketreviews.com/alpha-iii---estes-221256.html
+ //
+ // This function is used for unit, integration tests, DO NOT CHANGE WITHOUT UPDATING TESTS
+ public static final Rocket makeBeta(){
+ Rocket rocket = makeEstesAlphaIII();
+ rocket.setName("Kit-bash Beta");
+
+ AxialStage sustainerStage = (AxialStage)rocket.getChild(0);
+ sustainerStage.setName( "Sustainer Stage");
+ BodyTube sustainerBody = (BodyTube)sustainerStage.getChild(1);
+ final double sustainerRadius = sustainerBody.getAftRadius();
+ final double sustainerThickness = sustainerBody.getThickness();
+
+ AxialStage boosterStage = new AxialStage();
+ boosterStage.setName("Booster Stage");
+ rocket.addChild( boosterStage );
+ {
+ BodyTube boosterBody = new BodyTube(0.06, sustainerRadius, sustainerThickness);
+ boosterBody.setName("Booster Body");
+ boosterStage.addChild( boosterBody);
+ {
+ TubeCoupler coupler = new TubeCoupler();
+ coupler.setName("Coupler");
+ coupler.setOuterRadiusAutomatic(true);
+ coupler.setThickness( sustainerThickness );
+ coupler.setLength(0.03);
+ coupler.setAxialMethod(AxialMethod.TOP);
+ coupler.setAxialOffset(-0.015);
+ boosterBody.addChild(coupler);
+
+ int finCount = 3;
+ double finRootChord = .05;
+ double finTipChord = .03;
+ double finSweep = 0.02;
+ double finHeight = 0.05;
+ FinSet finset = new TrapezoidFinSet(finCount, finRootChord, finTipChord, finSweep, finHeight);
+ finset.setName("Booster Fins");
+ finset.setThickness( 0.0032);
+ finset.setAxialMethod(AxialMethod.BOTTOM);
+ finset.setAxialOffset(0.);
+ boosterBody.addChild(finset);
+
+ // Motor mount
+ InnerTube boosterMMT = new InnerTube();
+ boosterMMT.setName("Booster MMT");
+ boosterMMT.setAxialOffset(0.005);
+ boosterMMT.setAxialMethod(AxialMethod.BOTTOM);
+ boosterMMT.setOuterRadius(0.019 / 2);
+ boosterMMT.setInnerRadius(0.018 / 2);
+ boosterMMT.setLength(0.05);
+ boosterMMT.setMotorMount(true);
+ {
+ MotorConfiguration motorConfig= new MotorConfiguration(boosterMMT, ESTES_ALPHA_III_FCID[1] );
+ Motor mtr = generateMotor_D21_18mm();
+ motorConfig.setMotor(mtr);
+ boosterMMT.setMotorConfig( motorConfig, ESTES_ALPHA_III_FCID[1]);
+ }
+ boosterBody.addChild(boosterMMT);
+ }
+ }
+
+ rocket.setSelectedConfiguration( ESTES_ALPHA_III_FCID[1] );
+ rocket.getSelectedConfiguration().setAllStages();
+ rocket.enableEvents();
+
+ return rocket;
+ }
+
+ public static Rocket makeBigBlue() {
+ Rocket rocket;
+ AxialStage stage;
+ NoseCone nosecone;
+ BodyTube bodytube;
+ FreeformFinSet finset;
+ MassComponent mcomp;
+
+ rocket = new Rocket();
+ stage = new AxialStage();
+ stage.setName("Stage1");
+
+ nosecone = new NoseCone(Transition.Shape.ELLIPSOID, 0.105, 0.033);
+ nosecone.setThickness(0.001);
+ bodytube = new BodyTube(0.69, 0.033, 0.001);
+
+ finset = new FreeformFinSet();
+ final Coordinate[] finPoints = {
+ new Coordinate(0, 0),
+ new Coordinate(0.115, 0.072),
+ new Coordinate(0.255, 0.072),
+ new Coordinate(0.255, 0.037),
+ new Coordinate(0.150, 0)};
+ finset.setPoints(finPoints);
+
+ finset.setThickness(0.003);
+ finset.setFinCount(4);
+
+ finset.setCantAngle(0 * Math.PI / 180);
+ //System.err.println("Fin cant angle: " + (finset.getCantAngle() * 180 / Math.PI));
+
+ mcomp = new MassComponent(0.2, 0.03, 0.045 + 0.060);
+ mcomp.setAxialMethod(AxialMethod.TOP);
+ mcomp.setAxialOffset(0);
+
+ // Stage construction
+ rocket.addChild(stage);
+ rocket.setPerfectFinish(false);
+
+ // Component construction
+ stage.addChild(nosecone);
+ stage.addChild(bodytube);
+
+ bodytube.addChild(finset);
+
+ bodytube.addChild(mcomp);
+
+ // Material material = new Material("Test material", 500);
+ // nosecone.setMaterial(material);
+ // bodytube.setMaterial(material);
+ // finset.setMaterial(material);
+
+// FlightConfiguration config = rocket.getDefaultConfiguration();
+// FlightConfigurationID fcid = config.getFlightConfigurationID();
+// config.setAllStages();
+
+ // Motor m = Application.getMotorSetDatabase().findMotors(null, null, "F12J", Double.NaN, Double.NaN).get(0);
+ // bodytube.setMotor(id, m);
+ // bodytube.setMotorOverhang(0.005);
+
+ rocket.enableEvents();
+ return rocket;
+ }
+
+
+
+
+ public static Rocket makeIsoHaisu() {
+ Rocket rocket;
+ AxialStage stage;
+ NoseCone nosecone;
+ BodyTube tube1, tube2, tube3;
+ TrapezoidFinSet finset;
+ TrapezoidFinSet auxfinset;
+ @SuppressWarnings("unused")
+ MassComponent mcomp;
+
+ final double R = 0.07;
+
+ rocket = new Rocket();
+ stage = new AxialStage();
+ stage.setName("Stage1");
+
+ nosecone = new NoseCone(Transition.Shape.OGIVE, 0.53, R);
+ nosecone.setThickness(0.005);
+ nosecone.setMassOverridden(true);
+ nosecone.setOverrideMass(0.588);
+ stage.addChild(nosecone);
+
+ tube1 = new BodyTube(0.505, R, 0.005);
+ tube1.setMassOverridden(true);
+ tube1.setOverrideMass(0.366);
+ stage.addChild(tube1);
+
+ tube2 = new BodyTube(0.605, R, 0.005);
+ tube2.setMassOverridden(true);
+ tube2.setOverrideMass(0.427);
+ stage.addChild(tube2);
+
+ tube3 = new BodyTube(1.065, R, 0.005);
+ tube3.setMassOverridden(true);
+ tube3.setOverrideMass(0.730);
+ stage.addChild(tube3);
+
+ LaunchLug lug = new LaunchLug();
+ tube1.addChild(lug);
+
+ TubeCoupler coupler = new TubeCoupler();
+ coupler.setOuterRadiusAutomatic(true);
+ coupler.setThickness(0.005);
+ coupler.setLength(0.28);
+ coupler.setMassOverridden(true);
+ coupler.setOverrideMass(0.360);
+ coupler.setAxialMethod(AxialMethod.BOTTOM);
+ coupler.setAxialOffset(-0.14);
+ tube1.addChild(coupler);
+
+ // Parachute
+ MassComponent mass = new MassComponent(0.05, 0.05, 0.280);
+ mass.setAxialMethod(AxialMethod.TOP);
+ mass.setAxialOffset(0.2);
+ tube1.addChild(mass);
+
+ // Cord
+ mass = new MassComponent(0.05, 0.05, 0.125);
+ mass.setAxialMethod(AxialMethod.TOP);
+ mass.setAxialOffset(0.2);
+ tube1.addChild(mass);
+
+ // Payload
+ mass = new MassComponent(0.40, R, 1.500);
+ mass.setAxialMethod(AxialMethod.TOP);
+ mass.setAxialOffset(0.25);
+ tube1.addChild(mass);
+
+ auxfinset = new TrapezoidFinSet();
+ auxfinset.setName("CONTROL");
+ auxfinset.setFinCount(2);
+ auxfinset.setRootChord(0.05);
+ auxfinset.setTipChord(0.05);
+ auxfinset.setHeight(0.10);
+ auxfinset.setSweep(0);
+ auxfinset.setThickness(0.008);
+ auxfinset.setCrossSection(CrossSection.AIRFOIL);
+ auxfinset.setAxialMethod(AxialMethod.TOP);
+ auxfinset.setAxialOffset(0.28);
+ auxfinset.setBaseRotation(Math.PI / 2);
+ tube1.addChild(auxfinset);
+
+ coupler = new TubeCoupler();
+ coupler.setOuterRadiusAutomatic(true);
+ coupler.setLength(0.28);
+ coupler.setAxialMethod(AxialMethod.TOP);
+ coupler.setAxialOffset(0.47);
+ coupler.setMassOverridden(true);
+ coupler.setOverrideMass(0.360);
+ tube2.addChild(coupler);
+
+ // Parachute
+ mass = new MassComponent(0.1, 0.05, 0.028);
+ mass.setAxialMethod(AxialMethod.TOP);
+ mass.setAxialOffset(0.14);
+ tube2.addChild(mass);
+
+ Bulkhead bulk = new Bulkhead();
+ bulk.setOuterRadiusAutomatic(true);
+ bulk.setMassOverridden(true);
+ bulk.setOverrideMass(0.050);
+ bulk.setAxialMethod(AxialMethod.TOP);
+ bulk.setAxialOffset(0.27);
+ tube2.addChild(bulk);
+
+ // Chord
+ mass = new MassComponent(0.1, 0.05, 0.125);
+ mass.setAxialMethod(AxialMethod.TOP);
+ mass.setAxialOffset(0.19);
+ tube2.addChild(mass);
+
+ InnerTube inner = new InnerTube();
+ inner.setOuterRadius(0.08 / 2);
+ inner.setInnerRadius(0.0762 / 2);
+ inner.setLength(0.86);
+ inner.setMassOverridden(true);
+ inner.setOverrideMass(0.388);
+ tube3.addChild(inner);
+
+ CenteringRing center = new CenteringRing();
+ center.setInnerRadiusAutomatic(true);
+ center.setOuterRadiusAutomatic(true);
+ center.setLength(0.005);
+ center.setMassOverridden(true);
+ center.setOverrideMass(0.038);
+ center.setAxialMethod(AxialMethod.BOTTOM);
+ center.setAxialOffset(0);
+ tube3.addChild(center);
+
+ center = new CenteringRing();
+ center.setInnerRadiusAutomatic(true);
+ center.setOuterRadiusAutomatic(true);
+ center.setLength(0.005);
+ center.setMassOverridden(true);
+ center.setOverrideMass(0.038);
+ center.setAxialMethod(AxialMethod.TOP);
+ center.setAxialOffset(0.28);
+ tube3.addChild(center);
+
+ center = new CenteringRing();
+ center.setInnerRadiusAutomatic(true);
+ center.setOuterRadiusAutomatic(true);
+ center.setLength(0.005);
+ center.setMassOverridden(true);
+ center.setOverrideMass(0.038);
+ center.setAxialMethod(AxialMethod.TOP);
+ center.setAxialOffset(0.83);
+ tube3.addChild(center);
+
+ finset = new TrapezoidFinSet();
+ finset.setRootChord(0.495);
+ finset.setTipChord(0.1);
+ finset.setHeight(0.185);
+ finset.setThickness(0.005);
+ finset.setSweep(0.3);
+ finset.setAxialMethod(AxialMethod.BOTTOM);
+ finset.setAxialOffset(-0.03);
+ finset.setBaseRotation(Math.PI / 2);
+ tube3.addChild(finset);
+
+ finset.setCantAngle(0 * Math.PI / 180);
+ //System.err.println("Fin cant angle: " + (finset.getCantAngle() * 180 / Math.PI));
+
+ // Stage construction
+ rocket.addChild(stage);
+ rocket.setPerfectFinish(false);
+
+ FlightConfiguration config = rocket.getSelectedConfiguration();
+// FlightConfigurationID fcid = config.getFlightConfigurationID();
+
+ // Motor m = Application.getMotorSetDatabase().findMotors(null, null, "L540", Double.NaN, Double.NaN).get(0);
+ // tube3.setMotor(id, m);
+ // tube3.setMotorOverhang(0.02);
+
+ // tube3.setIgnitionEvent(MotorMount.IgnitionEvent.NEVER);
+
+ config.setAllStages();
+ rocket.enableEvents();
+ return rocket;
+ }
+
+ public final static String FALCON_9H_FCID_1="test_config #1: [ M1350, G77]";
+ public final static int FALCON_9H_PAYLOAD_STAGE_NUMBER=0;
+ public final static int FALCON_9H_CORE_STAGE_NUMBER=1;
+ public final static int FALCON_9H_BOOSTER_STAGE_NUMBER=2;
+
+
+
+ // This function is used for unit, integration tests, DO NOT CHANGE (without updating tests).
+ // Comments starting with cp: are center of pressure calculations
+ // for components of the rocket. Note that a cp: without a weight
+ // has a weight of 0 (see for example body tubes) -- included for
+ // completeness.
+ // Instanced components (ie components on the side boosters) have
+ // a cp: for each instance.
+ // The unit tests change the number of fins on the side boosters;
+ // cp: comments are shown for 1-fin, 2-fin, and 3-fin cases
+ public static Rocket makeFalcon9Heavy() {
+ Rocket rocket = new Rocket();
+ rocket.setName("Falcon9H Scale Rocket");
+
+ FlightConfigurationId selFCID = rocket.createFlightConfiguration( new FlightConfigurationId( FALCON_9H_FCID_1 ));
+ rocket.setSelectedConfiguration(selFCID);
+
+ // ====== Payload Stage ======
+ // ====== ====== ====== ======
+ AxialStage payloadStage = new AxialStage();
+ payloadStage.setName("Payload Fairing Stage");
+ rocket.addChild(payloadStage);
+
+ {
+ NoseCone payloadFairingNoseCone = new NoseCone(Transition.Shape.POWER, 0.118, 0.052);
+ payloadFairingNoseCone.setName("PL Fairing Nose");
+ payloadFairingNoseCone.setThickness(0.001);
+ payloadFairingNoseCone.setShapeParameter(0.5);
+ //payloadFairingNoseCone.setLength(0.118);
+ //payloadFairingNoseCone.setAftRadius(0.052);
+ payloadFairingNoseCone.setAftShoulderRadius( 0.051 );
+ payloadFairingNoseCone.setAftShoulderLength( 0.02 );
+ payloadFairingNoseCone.setAftShoulderThickness( 0.001 );
+ payloadFairingNoseCone.setAftShoulderCapped( false );
+ payloadStage.addChild(payloadFairingNoseCone);
+ // cp:(0.05900,0.00000,0.00000,w=2.00000)
+
+ BodyTube payloadBody = new BodyTube(0.132, 0.052, 0.001);
+ payloadBody.setName("PL Fairing Body");
+ payloadStage.addChild(payloadBody);
+ // cp:(0.18400,0.00000,0.00000)
+
+ Transition payloadFairingTail = new Transition();
+ payloadFairingTail.setName("PL Fairing Transition");
+ payloadFairingTail.setLength(0.014);
+ payloadFairingTail.setThickness(0.002);
+ payloadFairingTail.setForeRadiusAutomatic(true);
+ payloadFairingTail.setAftRadiusAutomatic(true);
+ payloadStage.addChild(payloadFairingTail);
+ // cp:(0.25665,0.00000,0.00000,w=-0.90366)
+
+ BodyTube upperStageBody= new BodyTube(0.18, 0.0385, 0.001);
+ upperStageBody.setName("Upper Stage Body ");
+ payloadStage.addChild( upperStageBody);
+ // cp:(0.35400,0.00000,0.00000)
+
+ {
+ // Parachute
+ Parachute upperChute= new Parachute();
+ upperChute.setName("Parachute");
+ upperChute.setAxialMethod(AxialMethod.MIDDLE);
+ upperChute.setAxialOffset(0.0);
+ upperChute.setDiameter(0.3);
+ upperChute.setLineCount(6);
+ upperChute.setLineLength(0.3);
+ upperStageBody.addChild( upperChute);
+
+ // Cord
+ ShockCord cord = new ShockCord();
+ cord.setName("Shock Cord");
+ cord.setAxialMethod(AxialMethod.BOTTOM);
+ cord.setAxialOffset(0.0);
+ cord.setCordLength(0.4);
+ upperStageBody.addChild( cord);
+ }
+
+ BodyTube interstage= new BodyTube(0.12, 0.0385, 0.001);
+ interstage.setName("Interstage");
+ payloadStage.addChild( interstage);
+ // cp:(0.50400,0.00000,0.00000)
+ }
+
+ // ====== Core Stage ======
+ // ====== ====== ====== ======
+ AxialStage coreStage = new AxialStage();
+ coreStage.setName("Core Stage");
+ rocket.addChild(coreStage);
+
+ {
+ BodyTube coreBody = new BodyTube(0.8, 0.0385, 0.001);
+ // 74 mm inner dia
+ coreBody.setName("Core Stage Body");
+ coreBody.setMotorMount(true);
+ coreStage.addChild( coreBody);
+ // cp:(0.96400,0.00000,0.00000)
+ {
+ MotorConfiguration coreMotorConfig = new MotorConfiguration(coreBody, selFCID);
+ Motor mtr = TestRockets.generateMotor_M1350_75mm();
+ coreMotorConfig.setMotor( mtr);
+ coreBody.setMotorMount( true);
+ FlightConfigurationId motorConfigId = selFCID;
+ coreBody.setMotorConfig( coreMotorConfig, motorConfigId);
+
+ // ====== Booster Stage Set ======
+ // ====== ====== ====== ======
+ ParallelStage boosterStage = new ParallelStage();
+ boosterStage.setName("Booster Stage");
+ coreBody.addChild( boosterStage);
+ boosterStage.setAxialMethod(AxialMethod.BOTTOM);
+ boosterStage.setAxialOffset(0.0);
+ boosterStage.setInstanceCount(2);
+ boosterStage.setRadius( RadiusMethod.SURFACE, 0.0 );
+ boosterStage.setAngleMethod( AngleMethod.RELATIVE );
+
+ {
+ NoseCone boosterCone = new NoseCone(Transition.Shape.POWER, 0.08, 0.0385);
+ boosterCone.setShapeParameter(0.5);
+ boosterCone.setName("Booster Nose");
+ boosterCone.setThickness(0.002);
+ //payloadFairingNoseCone.setLength(0.118);
+ //payloadFairingNoseCone.setAftRadius(0.052);
+ boosterCone.setAftShoulderRadius( 0.051 );
+ boosterCone.setAftShoulderLength( 0.02 );
+ boosterCone.setAftShoulderThickness( 0.001 );
+ boosterCone.setAftShoulderCapped( false );
+ boosterStage.addChild( boosterCone);
+ // cp:(0.52400,0.07700,0.00000,w=1.09634)
+ // cp:(0.52400,-0.07700,0.00000,w=1.09634)
+
+ BodyTube boosterBody = new BodyTube(0.8, 0.0385, 0.001);
+ boosterBody.setName("Booster Body");
+ boosterBody.setOuterRadiusAutomatic(true);
+ boosterStage.addChild( boosterBody);
+ // cp:(0.96400,0.07700,0.00000)
+ // cp:(0.96400,-0.07700,0.00000)
+ {
+ InnerTube boosterMotorTubes = new InnerTube();
+ boosterMotorTubes.setName("Booster Motor Tubes");
+ boosterMotorTubes.setLength(0.15);
+ boosterMotorTubes.setOuterRadius(0.015); // => 29mm motors
+ boosterMotorTubes.setThickness(0.0005);
+ boosterMotorTubes.setClusterConfiguration( ClusterConfiguration.CONFIGURATIONS[5]); // 4-ring
+ //boosterMotorTubes.setClusterConfiguration( ClusterConfiguration.CONFIGURATIONS[13]); // 9-star
+ boosterMotorTubes.setClusterScale(1.0);
+ boosterBody.addChild( boosterMotorTubes);
+
+ MotorConfiguration boosterMotorConfig = new MotorConfiguration( boosterMotorTubes, selFCID);
+ Motor boosterMotor = TestRockets.generateMotor_G77_29mm();
+ boosterMotorConfig.setMotor( boosterMotor );
+ boosterMotorTubes.setMotorConfig( boosterMotorConfig, motorConfigId);
+ boosterMotorTubes.setMotorOverhang(0.01234);
+
+ TrapezoidFinSet boosterFins = new TrapezoidFinSet();
+ boosterBody.addChild(boosterFins);
+ boosterFins.setName("Booster Fins");
+ boosterFins.setFinCount(3);
+ boosterFins.setBaseRotation( Math.PI / 4);
+ boosterFins.setThickness(0.003);
+ boosterFins.setCrossSection(CrossSection.ROUNDED);
+ boosterFins.setRootChord(0.32);
+ boosterFins.setTipChord(0.12);
+ boosterFins.setHeight(0.12);
+ boosterFins.setSweep(0.18);
+ boosterFins.setAxialMethod(AxialMethod.BOTTOM);
+ boosterFins.setAxialOffset(0.0);
+ // cp:(1.17873,0.10422,0.02722,w=6.07405) (1 fin case)
+ // cp:(1.17873,-0.10422,-0.02722,w=6.07405) (1 fin case)
+ // cp:(1.17873,0.10422,0.02722,w=12.14810) (2 fin case)
+ // cp:(1.17873,-0.10422,-0.02722,w=12.14810) (2 fin case)
+ // cp:(1.17873,0.00000,0.00000,w=9.11107) (3 fin case)
+ // cp:(1.17873,0.00000,0.00000,w=9.11107) (3 fin case)
+ }
+ }
+
+ }
+ }
+
+ rocket.enableEvents();
+ rocket.setSelectedConfiguration( selFCID);
+ rocket.getFlightConfiguration( selFCID).setAllStages();
+
+ return rocket;
+ }
+
+ // This is a simple four-fin rocket with large endplates on the
+ // fins, for testing CG and CP calculations with fins on pods.
+ // not a complete rocket (no motor mount nor recovery system)
+
+ // it's parameterized to make things easy to change, but be sure
+ // to adjust the unit test to match!
+ public static Rocket makeEndPlateRocket() {
+
+ // rocket design parameters
+ double radius = 0.01; // note this is diameter/2!
+ int finCount = 4; // also determines pod count
+
+ // nose cone
+ double noseThick = 0.002;
+ double noseLength = 0.05;
+
+ // body tube
+ double bodyWallThick = 0.002;
+ double bodyLength = 0.254;
+
+ // main body tube fins
+ int bodyFinCount = 4;
+ double bodyFinRootChord = 0.05;
+ double bodyFinTipChord = bodyFinRootChord;
+ double bodyFinHeight = 0.025;
+ double bodyFinSweep = 0.0;
+ AxialMethod bodyFinAxialMethod = AxialMethod.BOTTOM;
+ double bodyFinAxialOffset = 0.0;
+ double bodyFinThickness = 0.003;
+
+ // pods for end plates
+ int podSetCount = bodyFinCount;
+ double podSetOffset = bodyFinHeight;
+ AxialMethod podSetAxialMethod = bodyFinAxialMethod;
+ double podSetAxialOffset = 0.0;
+
+ // "phantom" tube on pods to give us somewhere to connect end
+ // plates
+ double phantomLength = bodyFinTipChord;
+ double phantomRadius = 0;
+ double phantomWallThickness = 0;
+
+ // end plates
+ int endPlateCount = 2;
+ double endPlateRootChord = bodyFinTipChord;
+ double endPlateTipChord = endPlateRootChord;
+ double endPlateSweep = 0.0;
+ double endPlateThickness = bodyFinThickness;
+ double endPlateHeight = bodyFinHeight;
+ double endPlateRotation = Math.PI/2.0;
+ AxialMethod endPlateAxialMethod = AxialMethod.BOTTOM;
+ double endPlateAxialOffset = 0;
+
+ // create bare rocket
+ Rocket rocket = new Rocket();
+ rocket.enableEvents();
+ rocket.setName("End Plate Test");
+
+ // rocket has one stage
+ AxialStage sustainer = new AxialStage();
+ rocket.addChild(sustainer);
+ sustainer.setName("Sustainer");
+
+ // nose cone
+ NoseCone noseCone = new NoseCone(Transition.Shape.OGIVE, noseLength, radius);
+ sustainer.addChild(noseCone);
+ noseCone.setName("Nose Cone");
+ // cp:(0.02303,0.00000,0.00000,w=2.00000)
+
+ // body tube
+ BodyTube bodyTube = new BodyTube(bodyLength, radius, bodyWallThick);
+ sustainer.addChild(bodyTube);
+ bodyTube.setName("Body tube");
+ // cp:(0.17700,0.00000,0.00000)
+
+ // Trapezoidal fin set on body tube
+ TrapezoidFinSet bodyFinSet = new TrapezoidFinSet(bodyFinCount, bodyFinRootChord, bodyFinTipChord, bodyFinSweep, bodyFinHeight);
+ bodyTube.addChild(bodyFinSet);
+ bodyFinSet.setName("Body Tube FinSet");
+ bodyFinSet.setAxialMethod(bodyFinAxialMethod);
+ bodyFinSet.setAxialOffset(bodyFinAxialOffset);
+ bodyFinSet.setThickness(bodyFinThickness);
+ // cp:(0.26650,0.00000,0.00000,w=15.24857)
+
+ // Pod set to put an end plate on each fin
+ PodSet podSet = new PodSet();
+ bodyTube.addChild(podSet);
+ podSet.setName("Pod Set");
+ podSet.setInstanceCount(podSetCount);
+ podSet.setRadiusOffset(podSetOffset);
+ podSet.setAxialMethod(podSetAxialMethod);
+ podSet.setAxialOffset(podSetAxialOffset);
+
+ // 0-diameter "body tube" to give us something to hook the
+ // endplates to. Note that this causes a "thick fins"
+ // warning.
+ BodyTube phantom = new BodyTube(phantomLength, phantomRadius, phantomWallThickness);
+ podSet.addChild(phantom);
+ phantom.setName("Phantom");
+ // cp:(0.25400,0.03540,0.00000)
+ // cp:(0.25400,0.00000,0.03540)
+ // cp:(0.25400,-0.03540,0.00000)
+ // cp:(0.25400,-0.00000,-0.03540)
+
+ // end plates
+ TrapezoidFinSet endPlate = new TrapezoidFinSet(endPlateCount, endPlateRootChord, endPlateTipChord, endPlateSweep, endPlateHeight);
+ phantom.addChild(endPlate);
+ endPlate.setName("End plates");
+ endPlate.setBaseRotation(endPlateRotation);
+ endPlate.setAxialMethod(endPlateAxialMethod);
+ endPlate.setAxialOffset(endPlateAxialOffset);
+ endPlate.setThickness(endPlateThickness);
+ // cp:(0.26650,0.03540,0.00000,w=0.00000)
+ // cp:(0.26650,0.00000,0.03540,w=11.86000)
+ // cp:(0.26650,-0.03540,0.00000,w=0.00000)
+ // cp:(0.26650,-0.00000,-0.03540,w=11.86000)
+
+ // Total cp:(0.25461,-0.00000,0.00000,w=40.96857)
+
+ return rocket;
+ }
+
+ /*
+ * Create a new file version 1.00 rocket
+ */
+ public static OpenRocketDocument makeTestRocket_v100() {
+ Rocket rocket = new Rocket();
+ rocket.setName("v100");
+
+ // make stage
+ AxialStage stage = new AxialStage();
+ stage.setName("Stage1");
+
+ // make body tube
+ BodyTube bodyTube = new BodyTube(12, 1, 0.05);
+ stage.addChild(bodyTube);
+
+ rocket.addChild(stage);
+ rocket.enableEvents();
+ return OpenRocketDocumentFactory.createDocumentFromRocket(rocket);
+ }
+
+ /*
+ * Create a new file version 1.01 rocket with finTabs
+ */
+ public static OpenRocketDocument makeTestRocket_v101_withFinTabs() {
+
+ Rocket rocket = new Rocket();
+ rocket.setName("v101_withFinTabs");
+
+ // make stage
+ AxialStage stage = new AxialStage();
+ stage.setName("Stage1");
+ rocket.addChild(stage);
+
+ // make body tube
+ BodyTube bodyTube = new BodyTube(12, 1, 0.05);
+ stage.addChild(bodyTube);
+
+ // make fins with fin tabs and add to body tube
+ TrapezoidFinSet fins = new TrapezoidFinSet();
+ fins.setFinCount(3);
+ fins.setFinShape(1.0, 1.0, 0.0, 1.0, .005);
+ fins.setTabHeight(0.25);
+ fins.setTabLength(0.25, true);
+ bodyTube.addChild(fins);
+
+ rocket.enableEvents();
+ return OpenRocketDocumentFactory.createDocumentFromRocket(rocket);
+ }
+
+ /*
+ * Create a new file version 1.01 rocket with tube coupler child
+ */
+ public static OpenRocketDocument makeTestRocket_v101_withTubeCouplerChild() {
+
+ Rocket rocket = new Rocket();
+ rocket.setName("v101_withTubeCouplerChild");
+
+ // make stage
+ AxialStage stage = new AxialStage();
+ stage.setName("Stage1");
+ rocket.addChild(stage);
+
+ // make body tube
+ BodyTube bodyTube = new BodyTube(12, 1, 0.05);
+ stage.addChild(bodyTube);
+
+ // make tube coupler with centering ring, add to stage
+ TubeCoupler tubeCoupler = new TubeCoupler();
+ CenteringRing centeringRing = new CenteringRing();
+ tubeCoupler.addChild(centeringRing);
+ bodyTube.addChild(tubeCoupler);
+
+ rocket.enableEvents();
+ return OpenRocketDocumentFactory.createDocumentFromRocket(rocket);
+ }
+
+ /*
+ * Create a new file version 1.04 rocket with motor in flight config
+ */
+ public static OpenRocketDocument makeTestRocket_v104_withMotor() {
+
+ Rocket rocket = new Rocket();
+ rocket.setName("v104_withMotorConfig");
+ FlightConfiguration config = rocket.getSelectedConfiguration();
+ FlightConfigurationId fcid = config.getFlightConfigurationID();
+ config.setName("F12X");
+
+ // make stage
+ AxialStage stage = new AxialStage();
+ stage.setName("Stage1");
+ rocket.addChild(stage);
+
+ // make body tube
+ BodyTube bodyTube = new BodyTube(12, 1, 0.05);
+ stage.addChild(bodyTube);
+
+ // make inner tube with motor mount flag set
+ InnerTube innerTube = new InnerTube();
+ bodyTube.addChild(innerTube);
+
+ // create motor config and add a motor to it
+ ThrustCurveMotor motor = getTestMotor();
+ MotorConfiguration motorConfig = new MotorConfiguration(innerTube, fcid);
+ motorConfig.setMotor(motor);
+ motorConfig.setEjectionDelay(5);
+
+ // add motor config to inner tube (motor mount)
+ innerTube.setMotorConfig( motorConfig, fcid);
+
+ rocket.enableEvents();
+ return OpenRocketDocumentFactory.createDocumentFromRocket(rocket);
+ }
+
+ /*
+ * Create a new file version 1.04 rocket with simulation data
+ */
+ public static OpenRocketDocument makeTestRocket_v104_withSimulationData() {
+
+ Rocket rocket = new Rocket();
+ rocket.setName("v104_withSimulationData");
+ FlightConfiguration config = rocket.getSelectedConfiguration();
+ FlightConfigurationId fcid = config.getFlightConfigurationID();
+ config.setName("F12X");
+
+ // make stage
+ AxialStage stage = new AxialStage();
+ stage.setName("Stage1");
+ rocket.addChild(stage);
+
+ // make body tube
+ BodyTube bodyTube = new BodyTube(12, 1, 0.05);
+ stage.addChild(bodyTube);
+
+ // make inner tube with motor mount flag set
+ InnerTube innerTube = new InnerTube();
+ bodyTube.addChild(innerTube);
+
+ // create motor config and add a motor to it
+ ThrustCurveMotor motor = getTestMotor();
+ MotorConfiguration motorConfig = new MotorConfiguration(innerTube, fcid);
+ motorConfig.setMotor(motor);
+ motorConfig.setEjectionDelay(5);
+
+ // add motor config to inner tube (motor mount)
+ innerTube.setMotorConfig(motorConfig, fcid);
+
+ OpenRocketDocument rocketDoc = OpenRocketDocumentFactory.createDocumentFromRocket(rocket);
+
+ // create simulation data
+ Simulation simulation1 = new Simulation(rocket);
+ simulation1.setFlightConfigurationId(fcid);
+
+ rocketDoc.addSimulation(simulation1);
+ Simulation simulation2 = new Simulation(rocket);
+ rocketDoc.addSimulation(simulation2);
+
+ rocket.enableEvents();
+ return rocketDoc;
+ }
+
+ /*
+ * Create a new file version 1.05 rocket with custom expression
+ */
+ public static OpenRocketDocument makeTestRocket_v105_withCustomExpression() {
+ Rocket rocket = new Rocket();
+ rocket.setName("v105_withCustomExpression");
+
+ // make stage
+ AxialStage stage = new AxialStage();
+ stage.setName("Stage1");
+ rocket.addChild(stage);
+
+ // make body tube
+ BodyTube bodyTube = new BodyTube();
+ stage.addChild(bodyTube);
+
+ OpenRocketDocument rocketDoc = OpenRocketDocumentFactory.createDocumentFromRocket(rocket);
+
+ CustomExpression expression = new CustomExpression(rocketDoc, "name", "symbol", "unit", "expression");
+ rocketDoc.addCustomExpression(expression);
+
+ rocket.enableEvents();
+ return rocketDoc;
+ }
+
+ /*
+ * Create a new file version 1.05 rocket with component preset
+ */
+ public static OpenRocketDocument makeTestRocket_v105_withComponentPreset() {
+ Rocket rocket = new Rocket();
+ rocket.setName("v105_withComponentPreset");
+
+ // make stage
+ AxialStage stage = new AxialStage();
+ stage.setName("Stage1");
+ rocket.addChild(stage);
+
+ // make body tube
+ BodyTube bodyTube = new BodyTube();
+
+ TypedPropertyMap presetspec = new TypedPropertyMap();
+ presetspec.put(ComponentPreset.TYPE, ComponentPreset.Type.BODY_TUBE);
+ presetspec.put(ComponentPreset.MANUFACTURER, Manufacturer.getManufacturer("manufacturer"));
+ presetspec.put(ComponentPreset.PARTNO, "partno");
+ presetspec.put(ComponentPreset.LENGTH, 2.0);
+ presetspec.put(ComponentPreset.OUTER_DIAMETER, 2.0);
+ presetspec.put(ComponentPreset.INNER_DIAMETER, 1.0);
+ presetspec.put(ComponentPreset.MASS, 100.0);
+ ComponentPreset preset;
+ try {
+ preset = ComponentPresetFactory.create(presetspec);
+ bodyTube.loadPreset(preset);
+ stage.addChild(bodyTube);
+ } catch (InvalidComponentPresetException e) {
+ // should never happen
+ e.printStackTrace();
+ }
+
+ rocket.enableEvents();
+ return OpenRocketDocumentFactory.createDocumentFromRocket(rocket);
+ }
+
+ /*
+ * Create a new file version 1.05 rocket with lower stage recovery device
+ */
+ public static OpenRocketDocument makeTestRocket_v105_withLowerStageRecoveryDevice() {
+ Rocket rocket = new Rocket();
+ rocket.setName("v105_withLowerStageRecoveryDevice");
+
+ // make 1st stage
+ AxialStage stage1 = new AxialStage();
+ stage1.setName("Stage1");
+ rocket.addChild(stage1);
+
+ // make 1st stage body tube
+ BodyTube bodyTube1 = new BodyTube(5, 1, 0.05);
+ stage1.addChild(bodyTube1);
+
+ // make 1st stage recovery device with deployment config in default
+ RecoveryDevice parachute = new Parachute();
+ DeploymentConfiguration deploymentConfig = new DeploymentConfiguration();
+ deploymentConfig.setDeployEvent(DeployEvent.LOWER_STAGE_SEPARATION);
+ parachute.getDeploymentConfigurations().setDefault(deploymentConfig);
+ bodyTube1.addChild(parachute);
+
+ // make 2nd stage
+ AxialStage stage2 = new AxialStage();
+ stage2.setName("Stage2");
+ rocket.addChild(stage2);
+
+ rocket.enableEvents();
+ return OpenRocketDocumentFactory.createDocumentFromRocket(rocket);
+ }
+
+ /*
+ * Create a new file version 1.06 rocket with appearance
+ */
+ public static OpenRocketDocument makeTestRocket_v106_withAppearance() {
+ Rocket rocket = new Rocket();
+ rocket.setName("v106_withAppearance");
+
+ // make stage
+ AxialStage stage = new AxialStage();
+ stage.setName("Stage1");
+ rocket.addChild(stage);
+
+ // make body tube with an appearance setting
+ BodyTube bodyTube = new BodyTube(12, 1, 0.05);
+ Appearance appearance = new Appearance(new Color(100, 25, 50), 1, null);
+ bodyTube.setAppearance(appearance);
+ stage.addChild(bodyTube);
+
+ rocket.enableEvents();
+ return OpenRocketDocumentFactory.createDocumentFromRocket(rocket);
+ }
+
+ /*
+ * Create a new file version 1.06 rocket with flight configuration with motor mount ignition configuration
+ */
+ public static OpenRocketDocument makeTestRocket_v106_withMotorMountIgnitionConfig() {
+ Rocket rocket = new Rocket();
+ rocket.setName("v106_withwithMotorMountIgnitionConfig");
+ FlightConfigurationId fcid = new FlightConfigurationId();
+
+ // make stage
+ AxialStage stage = new AxialStage();
+ stage.setName("Stage1");
+ rocket.addChild(stage);
+
+ // make body tube
+ BodyTube bodyTube = new BodyTube(12, 1, 0.05);
+ stage.addChild(bodyTube);
+
+ // make inner tube with motor mount flag set
+ InnerTube innerTube = new InnerTube();
+ bodyTube.addChild(innerTube);
+
+ // make inner tube with motor mount flag set
+ MotorConfiguration motorConfig = new MotorConfiguration(innerTube, fcid);
+ Motor mtr = getTestMotor();
+ motorConfig.setMotor( mtr);
+ innerTube.setMotorConfig(motorConfig,fcid);
+
+ // set ignition parameters for motor mount
+ // inst.setIgnitionEvent( IgnitionEvent.AUTOMATIC);
+ motorConfig.setIgnitionDelay(2);
+
+ rocket.enableEvents();
+ return OpenRocketDocumentFactory.createDocumentFromRocket(rocket);
+ }
+
+ /*
+ * Create a new file version 1.06 rocket with flight configuration with recovery device deployment configuration non-default
+ */
+ public static OpenRocketDocument makeTestRocket_v106_withRecoveryDeviceDeploymentConfig() {
+ Rocket rocket = new Rocket();
+ rocket.setName("v106_withRecoveryDeviceDeploymentConfig");
+ FlightConfigurationId testFCID = new FlightConfigurationId("testParachute");
+
+ // make stage
+ AxialStage stage = new AxialStage();
+ stage.setName("Stage1");
+ rocket.addChild(stage);
+
+ // make body tube
+ BodyTube bodyTube = new BodyTube(12, 1, 0.05);
+ stage.addChild(bodyTube);
+
+ // make recovery device with deployment config
+ RecoveryDevice parachute = new Parachute();
+ DeploymentConfiguration deploymentConfig = new DeploymentConfiguration();
+ deploymentConfig.setDeployAltitude(1000);
+ parachute.getDeploymentConfigurations().set(testFCID, deploymentConfig);
+ bodyTube.addChild(parachute);
+
+ rocket.enableEvents();
+ return OpenRocketDocumentFactory.createDocumentFromRocket(rocket);
+ }
+
+ /*
+ * Create a new file version 1.06 rocket with flight configuration with stage separation configuration
+ */
+ public static OpenRocketDocument makeTestRocket_v106_withStageSeparationConfig() {
+ Rocket rocket = new Rocket();
+ rocket.setName("v106_withStageSeparationConfig");
+ FlightConfigurationId fcid = new FlightConfigurationId("3SecondDelay");
+ // make 1st stage
+ AxialStage stage1 = new AxialStage();
+ stage1.setName("Stage1");
+ rocket.addChild(stage1);
+
+ // make 1st stage body tube
+ BodyTube bodyTube1 = new BodyTube(5, 1, 0.05);
+ stage1.addChild(bodyTube1);
+
+ // make1st stage recovery device
+ RecoveryDevice parachute = new Parachute();
+ bodyTube1.addChild(parachute);
+
+ // set stage separation configuration
+ StageSeparationConfiguration stageSepConfig = new StageSeparationConfiguration();
+ stageSepConfig.setSeparationDelay(3);
+ stage1.getSeparationConfigurations().set(fcid, stageSepConfig);
+
+ // make 2nd stage
+ AxialStage stage2 = new AxialStage();
+ stage2.setName("Stage2");
+ rocket.addChild(stage2);
+
+ // make 2st stage body tube
+ BodyTube bodyTube2 = new BodyTube(12, 1, 0.05);
+ stage2.addChild(bodyTube2);
+
+ rocket.enableEvents();
+ return OpenRocketDocumentFactory.createDocumentFromRocket(rocket);
+ }
+
+
+ public static OpenRocketDocument makeTestRocket_v107_withSimulationExtension(String script) {
+ Rocket rocket = makeEstesAlphaIII();
+ OpenRocketDocument document = OpenRocketDocumentFactory.createDocumentFromRocket(rocket);
+ Simulation sim = new Simulation(rocket);
+ ScriptingExtension ext = new ScriptingExtension();
+ ext.setEnabled(true);
+ ext.setLanguage("JavaScript");
+ ext.setScript(script);
+ sim.getSimulationExtensions().add(ext);
+ document.addSimulation(sim);
+
+ rocket.enableEvents();
+ return document;
+ }
+
+ public static OpenRocketDocument makeTestRocket_v108_withBoosters() {
+ Rocket rocket = makeFalcon9Heavy();
+ OpenRocketDocument document = OpenRocketDocumentFactory.createDocumentFromRocket(rocket);
+
+ return document;
+ }
+
+ /*
+ * Create a new test rocket for testing OpenRocketSaver.estimateFileSize()
+ */
+ public static OpenRocketDocument makeTestRocket_for_estimateFileSize() {
+ Rocket rocket = new Rocket();
+ rocket.setName("for_estimateFileSize");
+
+ // make 1st stage
+ AxialStage stage1 = new AxialStage();
+ stage1.setName("Stage1");
+ rocket.addChild(stage1);
+
+ // make 1st stage body tube
+ BodyTube bodyTube1 = new BodyTube(5, 1, 0.05);
+ stage1.addChild(bodyTube1);
+
+ TrapezoidFinSet fins1 = new TrapezoidFinSet();
+ fins1.setFinCount(3);
+ fins1.setFinShape(1.5, 1.5, 0.0, 1.5, .005);
+ bodyTube1.addChild(fins1);
+
+ // make 1st stage recovery device with deployment config in default
+ RecoveryDevice parachute = new Parachute();
+ DeploymentConfiguration deploymentConfig = new DeploymentConfiguration();
+ deploymentConfig.setDeployEvent(DeployEvent.LOWER_STAGE_SEPARATION);
+ deploymentConfig.setDeployEvent(DeployEvent.ALTITUDE);
+ parachute.getDeploymentConfigurations().setDefault(deploymentConfig);
+ bodyTube1.addChild(parachute);
+
+ // make 2nd stage
+ AxialStage stage2 = new AxialStage();
+ stage2.setName("Stage2");
+ rocket.addChild(stage2);
+
+ // make 2nd stage nose cone
+ NoseCone noseCone = new NoseCone(Transition.Shape.OGIVE, 6 * 0.5, 0.5);
+ stage2.addChild(noseCone);
+
+ // make 2nd stage body tube
+ BodyTube bodyTube2 = new BodyTube(15, 1, 0.05);
+ stage2.addChild(bodyTube2);
+
+ // make 2nd stage fins
+ TrapezoidFinSet fins2 = new TrapezoidFinSet();
+ fins2.setFinCount(3);
+ fins2.setFinShape(1.0, 1.0, 0.0, 1.0, .005);
+ bodyTube2.addChild(fins2);
+
+ OpenRocketDocument rocketDoc = OpenRocketDocumentFactory.createDocumentFromRocket(rocket);
+
+ // create simulation data
+ Simulation simulation1 = new Simulation(rocket);
+ simulation1.getOptions().setISAAtmosphere(false); // helps cover code in saveComponent()
+ simulation1.getOptions().setTimeStep(0.05);
+ rocketDoc.addSimulation(simulation1);
+
+ Simulation simulation2 = new Simulation(rocket);
+ simulation2.getOptions().setISAAtmosphere(true); // helps cover code in saveComponent()
+ simulation2.getOptions().setTimeStep(0.05);
+ rocketDoc.addSimulation(simulation2);
+
+ SimulationListener simulationListener = new AbstractSimulationListener();
+ try {
+ simulation1.simulate(simulationListener);
+ simulation2.simulate(simulationListener);
+ } catch (SimulationException e) {
+ // do nothing, we don't care
+ }
+
+ rocket.enableEvents();
+ return rocketDoc;
+ }
+
+}