From 18ce41d9e7bc1a48adee253b5bfd3c0b39b4767e Mon Sep 17 00:00:00 2001 From: JoePfeiffer Date: Wed, 13 Mar 2019 14:45:30 -0600 Subject: [PATCH 1/3] Modified setTabHeight, setTabLength, and setTabOffset to take a second parameter, determining whether to validate fin tab, and made them private. Created two public wrappers for each, one calling for validation (which has the same signature as the original three methods), and the other not. Called NoValidate versions of the three in file loading functions so validation doesn't interfere with tab length when tab is read before fin. Tried to make the coding of the three more consistent with each other. --- .../openrocket/importt/DocumentConfig.java | 4 +- .../importt/FinTabPositionSetter.java | 4 +- .../file/rocksim/importt/FinSetHandler.java | 6 +- .../sf/openrocket/rocketcomponent/FinSet.java | 106 +- .../net/sf/openrocket/util/#TestRockets.java# | 1633 +++++++++++++++++ 5 files changed, 1727 insertions(+), 26 deletions(-) create mode 100644 core/src/net/sf/openrocket/util/#TestRockets.java# 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; + } + +} From f51ce5e93145d0eb5c3578c02ca2f9966aeab7cf Mon Sep 17 00:00:00 2001 From: JoePfeiffer Date: Wed, 13 Mar 2019 14:51:06 -0600 Subject: [PATCH 2/3] oops, that shouldn't have been in there --- .../net/sf/openrocket/util/#TestRockets.java# | 1633 ----------------- 1 file changed, 1633 deletions(-) delete mode 100644 core/src/net/sf/openrocket/util/#TestRockets.java# diff --git a/core/src/net/sf/openrocket/util/#TestRockets.java# b/core/src/net/sf/openrocket/util/#TestRockets.java# deleted file mode 100644 index 2213a18ad..000000000 --- a/core/src/net/sf/openrocket/util/#TestRockets.java# +++ /dev/null @@ -1,1633 +0,0 @@ -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; - } - -} From d635ed4c741f2ff6fcba9a2d2ef7f84d85c10a0d Mon Sep 17 00:00:00 2001 From: JoePfeiffer Date: Tue, 19 Mar 2019 14:35:45 -0600 Subject: [PATCH 3/3] Remove validation when modifying fin tab --- .../openrocket/importt/DocumentConfig.java | 4 +- .../importt/FinTabPositionSetter.java | 2 +- .../file/rocksim/importt/FinSetHandler.java | 6 +- .../sf/openrocket/rocketcomponent/FinSet.java | 87 +++---------------- 4 files changed, 20 insertions(+), 79 deletions(-) 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 0d3c657e6..3dd43b81b 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, "setTabHeightNoValidate", double.class))); + Reflection.findMethod(FinSet.class, "setTabHeight", double.class))); setters.put("FinSet:tablength", new DoubleSetter( - Reflection.findMethod(FinSet.class, "setTabLengthNoValidate", double.class))); + Reflection.findMethod(FinSet.class, "setTabLength", 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 64072455f..309a54de7 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, "setTabOffsetNoValidate", double.class)); + super(Reflection.findMethod(FinSet.class, "setTabOffset", double.class)); } @Override 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 ed84c8f3a..f2f9d7f64 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.setTabHeightNoValidate(tabDepth); - result.setTabLengthNoValidate(tabLength); - result.setTabOffsetNoValidate(taboffset); + result.setTabHeight(tabDepth); + result.setTabLength(tabLength); + result.setTabOffset(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 2b42be1e6..52ba40843 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/FinSet.java +++ b/core/src/net/sf/openrocket/rocketcomponent/FinSet.java @@ -247,45 +247,30 @@ 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 - * height deep, and the bottom edge of the tab will be parallel to the stage centerline. If the tab is located via TOP, the the front edge will have corresponding height/depth. + * 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 height deep, + * and the bottom edge of the tab will be parallel to the stage + * centerline. If the tab is located via TOP, the the front edge + * will have corresponding height/depth. * If the tab is located via MIDDLE, the tab's midpoint is used. * - * Note this function also does bounds checking, and will not set a tab height that passes through it's parent's midpoint. + * Note this function also does bounds checking, and will not set + * a tab height that passes through it's parent's midpoint. * - * @param newHeightRequest how deep the fin tab should project from the fin root, at the reference point + * @param newHeightRequest how deep the fin tab should project + * from the fin root, at the reference point * */ - private void setTabHeight(final double heightRequest, final boolean validate) { + public void setTabHeight(final double heightRequest) { if (MathUtil.equals(this.tabHeight, MathUtil.max(heightRequest, 0))){ return; } tabHeight = heightRequest; - if (validate) - validateFinTab(); - fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); } @@ -295,58 +280,17 @@ public abstract class FinSet extends ExternalComponent implements RingInstanceab } /** - * 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 + * set 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 = lengthRequest; - if (validate) { - validateFinTab(); - } - fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); } - - /** - * 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 setTabOffsetNoValidate(final double offsetRequest) { - setTabOffset(offsetRequest, false); - } - - /** - * 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 @@ -354,13 +298,10 @@ public abstract class FinSet extends ExternalComponent implements RingInstanceab * @param offsetRequest new requested shift of tab -- from * @param validate wehther or not to validate */ - private void setTabOffset( final double offsetRequest, final boolean validate) { + public void setTabOffset( final double offsetRequest) { tabOffset = offsetRequest; tabPosition = tabOffsetMethod.getAsPosition( tabOffset, tabLength, length); - - if (validate) { - validateFinTab(); - } + fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); }