diff --git a/core/src/net/sf/openrocket/motor/IgnitionEvent.java b/core/src/net/sf/openrocket/motor/IgnitionEvent.java index da9859fcf..f932a6661 100644 --- a/core/src/net/sf/openrocket/motor/IgnitionEvent.java +++ b/core/src/net/sf/openrocket/motor/IgnitionEvent.java @@ -38,7 +38,7 @@ public enum IgnitionEvent { AxialStage targetStage = (AxialStage)targetComponent.getStage(); AxialStage eventStage = (AxialStage)testEvent.getSource().getStage(); - AxialStage eventParentStage = eventStage.getPreviousStage(); + AxialStage eventParentStage = eventStage.getUpperStage(); return ( targetStage.equals(eventParentStage)); } }, @@ -50,7 +50,7 @@ public enum IgnitionEvent { AxialStage targetStage = (AxialStage)targetComponent.getStage(); AxialStage eventStage = (AxialStage)testEvent.getSource().getStage(); - AxialStage eventParentStage = eventStage.getPreviousStage(); + AxialStage eventParentStage = eventStage.getUpperStage(); return ( targetStage.equals(eventParentStage)); } }, diff --git a/core/src/net/sf/openrocket/rocketcomponent/AxialStage.java b/core/src/net/sf/openrocket/rocketcomponent/AxialStage.java index 4d481a676..99a982620 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/AxialStage.java +++ b/core/src/net/sf/openrocket/rocketcomponent/AxialStage.java @@ -82,13 +82,7 @@ public class AxialStage extends ComponentAssembly implements FlightConfigurableC */ @Override public boolean isCompatible(Class type) { - if (ParallelStage.class.isAssignableFrom(type)) { - return true; - } else if (PodSet.class.isAssignableFrom(type)) { - return true; - } - - return BodyComponent.class.isAssignableFrom(type); + return BodyComponent.class.isAssignableFrom(type); } @Override @@ -180,18 +174,18 @@ public class AxialStage extends ComponentAssembly implements FlightConfigurableC * returns null if this is the first stage * @return the previous stage in the rocket */ - public AxialStage getPreviousStage() { - if( this instanceof ParallelStage ){ - return (AxialStage) this.parent; - } - AxialStage thisStage = this.getStage(); // necessary in case of pods or other assemblies - if( thisStage.parent instanceof Rocket ){ - final int thisIndex = parent.getChildPosition( thisStage ); + public AxialStage getUpperStage() { + if( null == this.parent ) { + return null; + }else if(Rocket.class.isAssignableFrom(this.parent.getClass()) ){ + final int thisIndex = getStageNumber(); if( 0 < thisIndex ){ - return (AxialStage)thisStage.parent.getChild(thisIndex-1); + return (AxialStage)parent.getChild(thisIndex-1); } + }else { + return this.parent.getStage(); } - return null; + return null; } @Override diff --git a/core/src/net/sf/openrocket/rocketcomponent/BodyTube.java b/core/src/net/sf/openrocket/rocketcomponent/BodyTube.java index aba1030b2..be4d06a9a 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/BodyTube.java +++ b/core/src/net/sf/openrocket/rocketcomponent/BodyTube.java @@ -351,6 +351,11 @@ public class BodyTube extends SymmetricComponent implements MotorMount, Coaxial */ @Override public boolean isCompatible(Class type) { + if (ParallelStage.class.isAssignableFrom(type)) + return true; + if (PodSet.class.isAssignableFrom(type)) + return true; + if (InternalComponent.class.isAssignableFrom(type)) return true; if (ExternalComponent.class.isAssignableFrom(type) && diff --git a/core/src/net/sf/openrocket/rocketcomponent/ComponentAssembly.java b/core/src/net/sf/openrocket/rocketcomponent/ComponentAssembly.java index a2e3fdf6e..6a909af80 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/ComponentAssembly.java +++ b/core/src/net/sf/openrocket/rocketcomponent/ComponentAssembly.java @@ -38,7 +38,7 @@ public abstract class ComponentAssembly extends RocketComponent { @Override public double getAxialOffset() { - return super.asPositionValue(this.relativePosition); + return asPositionValue(this.relativePosition); } /** diff --git a/core/src/net/sf/openrocket/rocketcomponent/ParallelStage.java b/core/src/net/sf/openrocket/rocketcomponent/ParallelStage.java index c234a1b92..f231dabb2 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/ParallelStage.java +++ b/core/src/net/sf/openrocket/rocketcomponent/ParallelStage.java @@ -183,6 +183,7 @@ public class ParallelStage extends AxialStage implements FlightConfigurableCompo return this.autoRadialPosition; } + @Override public void setAutoRadialOffset( final boolean enabled ){ this.autoRadialPosition = enabled; fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); @@ -205,13 +206,13 @@ public class ParallelStage extends AxialStage implements FlightConfigurableCompo @Override protected void update() { super.update(); - - if( this.autoRadialPosition ){ - ComponentAssembly parentAssembly = (ComponentAssembly)this.parent; - if( null == parentAssembly ){ + + if( this.autoRadialPosition){ + if( null == this.parent ){ this.radialPosition_m = this.getOuterRadius(); - }else{ - this.radialPosition_m = this.getOuterRadius() + parentAssembly.getOuterRadius(); + }else if( BodyTube.class.isAssignableFrom(this.parent.getClass())) { + BodyTube parentBody = (BodyTube)this.parent; + this.radialPosition_m = this.getOuterRadius() + parentBody.getOuterRadius(); } } } diff --git a/core/src/net/sf/openrocket/rocketcomponent/PodSet.java b/core/src/net/sf/openrocket/rocketcomponent/PodSet.java index 65c2fec1e..c495edbac 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/PodSet.java +++ b/core/src/net/sf/openrocket/rocketcomponent/PodSet.java @@ -227,11 +227,11 @@ public class PodSet extends ComponentAssembly implements RingInstanceable { super.update(); if( this.autoRadialPosition){ - ComponentAssembly parentAssembly = (ComponentAssembly)this.parent; - if( null == parentAssembly ){ + if( null == this.parent ){ this.radialPosition_m = this.getOuterRadius(); - }else{ - this.radialPosition_m = this.getOuterRadius() + parentAssembly.getOuterRadius(); + }else if( BodyTube.class.isAssignableFrom(this.parent.getClass())) { + BodyTube parentBody = (BodyTube)this.parent; + this.radialPosition_m = this.getOuterRadius() + parentBody.getOuterRadius(); } } } diff --git a/core/src/net/sf/openrocket/rocketcomponent/RocketComponent.java b/core/src/net/sf/openrocket/rocketcomponent/RocketComponent.java index 835226bca..f1c820f5e 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/RocketComponent.java +++ b/core/src/net/sf/openrocket/rocketcomponent/RocketComponent.java @@ -11,6 +11,7 @@ import java.util.NoSuchElementException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import junit.framework.Assert; import net.sf.openrocket.appearance.Appearance; import net.sf.openrocket.appearance.Decal; import net.sf.openrocket.motor.Motor; @@ -110,7 +111,7 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab protected double length = 0; /** - * Positioning of this component relative to the parent component. + * How this component is axially positioned, possibly in relative to the parent component. */ protected Position relativePosition = Position.AFTER; @@ -992,32 +993,29 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab * @return double position of the component relative to the parent, with respect to position */ public double asPositionValue(Position thePosition) { - double relativeLength; + double parentLength; if (null == this.parent) { - relativeLength = 0; + parentLength = 0; }else{ - relativeLength = this.parent.length; + parentLength = this.parent.length; } - double thisX = this.position.x; double result = Double.NaN; - switch (thePosition) { case AFTER: - result = thisX - relativeLength; + result = this.position.x - parentLength; break; case ABSOLUTE: - Coordinate[] insts = this.getLocations(); - result = insts[0].x; + result = this.getComponentLocations()[0].x; break; case TOP: - result = thisX; + result = this.position.x; break; case MIDDLE: - result = thisX + (-relativeLength + this.getLength()) / 2; + result = this.position.x + ( this.length - parentLength) / 2; break; case BOTTOM: - result = thisX + (-relativeLength + this.getLength()); + result = this.position.x + ( this.length - parentLength); break; default: throw new BugException("Unknown position type: " + thePosition); @@ -1096,6 +1094,7 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab }else{ this.relativePosition = positionMethod; } + if (null == this.parent) { // if this is the root of a hierarchy, constrain the position to zero. if( this instanceof Rocket ){ @@ -1113,9 +1112,10 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab final double EPSILON = 0.000001; double newAxialPosition = Double.NaN; final double refLength = this.parent.getLength(); + switch (this.relativePosition) { case ABSOLUTE: - newAxialPosition = newOffset - this.parent.position.x; + newAxialPosition = newOffset - this.parent.getComponentLocations()[0].x; break; case AFTER: // no-op @@ -1129,6 +1129,7 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab break; case BOTTOM: newAxialPosition = (refLength - this.length) + newOffset; + //System.err.println(String.format("____( %.6g - %.6g) + %.6g = %.6g", refLength, this.length, newOffset, newAxialPosition )); break; default: throw new BugException("Unknown position type: " + this.relativePosition); diff --git a/core/src/net/sf/openrocket/util/TestRockets.java b/core/src/net/sf/openrocket/util/TestRockets.java index 8eb1c22e1..218d403b3 100644 --- a/core/src/net/sf/openrocket/util/TestRockets.java +++ b/core/src/net/sf/openrocket/util/TestRockets.java @@ -935,75 +935,75 @@ public class TestRockets { coreBody.setMotorMount(true); coreStage.addChild( coreBody); { - MotorConfiguration motorConfig = new MotorConfiguration(coreBody, selFCID); + MotorConfiguration coreMotorConfig = new MotorConfiguration(coreBody, selFCID); Motor mtr = TestRockets.generateMotor_M1350_75mm(); - motorConfig.setMotor( mtr); + coreMotorConfig.setMotor( mtr); coreBody.setMotorMount( true); FlightConfigurationId motorConfigId = selFCID; - coreBody.setMotorConfig( motorConfig, motorConfigId); - } + coreBody.setMotorConfig( coreMotorConfig, motorConfigId); - TrapezoidFinSet coreFins = new TrapezoidFinSet(); - coreFins.setName("Core Fins"); - coreFins.setFinCount(4); - coreFins.setRelativePosition(Position.BOTTOM); - coreFins.setAxialOffset(0.0); - coreFins.setBaseRotation( Math.PI / 4); - coreFins.setThickness(0.003); - coreFins.setCrossSection(CrossSection.ROUNDED); - coreFins.setRootChord(0.32); - coreFins.setTipChord(0.12); - coreFins.setHeight(0.12); - coreFins.setSweep(0.18); - coreBody.addChild(coreFins); - + TrapezoidFinSet coreFins = new TrapezoidFinSet(); + coreFins.setName("Core Fins"); + coreFins.setFinCount(4); + coreFins.setRelativePosition(Position.BOTTOM); + coreFins.setAxialOffset(0.0); + coreFins.setBaseRotation( Math.PI / 4); + coreFins.setThickness(0.003); + coreFins.setCrossSection(CrossSection.ROUNDED); + coreFins.setRootChord(0.32); + coreFins.setTipChord(0.12); + coreFins.setHeight(0.12); + coreFins.setSweep(0.18); + coreBody.addChild(coreFins); - // ====== Booster Stage Set ====== - // ====== ====== ====== ====== - ParallelStage boosterStage = new ParallelStage(); - boosterStage.setName("Booster Stage"); - coreStage.addChild( boosterStage); - boosterStage.setRelativePositionMethod(Position.BOTTOM); - boosterStage.setAxialOffset(0.0); - boosterStage.setInstanceCount(2); - boosterStage.setRadialOffset(0.075); - - { - 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); - - BodyTube boosterBody = new BodyTube(0.8, 0.0385, 0.001); - boosterBody.setName("Booster Body"); - boosterBody.setOuterRadiusAutomatic(true); - boosterStage.addChild( boosterBody); + + // ====== Booster Stage Set ====== + // ====== ====== ====== ====== + ParallelStage boosterStage = new ParallelStage(); + boosterStage.setName("Booster Stage"); + coreBody.addChild( boosterStage); + boosterStage.setRelativePositionMethod(Position.BOTTOM); + boosterStage.setAxialOffset(0.0); + boosterStage.setInstanceCount(2); + boosterStage.setRadialOffset(0.075); { - 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); + 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); - FlightConfigurationId motorConfigId = selFCID; - MotorConfiguration motorConfig = new MotorConfiguration( boosterMotorTubes, selFCID); - Motor mtr = TestRockets.generateMotor_G77_29mm(); - motorConfig.setMotor(mtr); - boosterMotorTubes.setMotorConfig( motorConfig, motorConfigId); - boosterMotorTubes.setMotorOverhang(0.01234); + BodyTube boosterBody = new BodyTube(0.8, 0.0385, 0.001); + boosterBody.setName("Booster Body"); + boosterBody.setOuterRadiusAutomatic(true); + boosterStage.addChild( boosterBody); + + { + 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); + } } + } } diff --git a/core/test/net/sf/openrocket/aerodynamics/BarrowmanCalculatorTest.java b/core/test/net/sf/openrocket/aerodynamics/BarrowmanCalculatorTest.java index 5d372d8b9..928204d97 100644 --- a/core/test/net/sf/openrocket/aerodynamics/BarrowmanCalculatorTest.java +++ b/core/test/net/sf/openrocket/aerodynamics/BarrowmanCalculatorTest.java @@ -180,7 +180,7 @@ public class BarrowmanCalculatorTest { Rocket rocket = TestRockets.makeFalcon9Heavy(); AerodynamicCalculator calc = new BarrowmanCalculator(); - ParallelStage booster = (ParallelStage)rocket.getChild(1).getChild(1); + ParallelStage booster = (ParallelStage)rocket.getChild(1).getChild(0).getChild(1); NoseCone nose = (NoseCone)booster.getChild(0); BodyTube body = (BodyTube)booster.getChild(1); diff --git a/core/test/net/sf/openrocket/masscalc/MassCalculatorTest.java b/core/test/net/sf/openrocket/masscalc/MassCalculatorTest.java index 236617b1e..611383fb4 100644 --- a/core/test/net/sf/openrocket/masscalc/MassCalculatorTest.java +++ b/core/test/net/sf/openrocket/masscalc/MassCalculatorTest.java @@ -205,7 +205,7 @@ public class MassCalculatorTest extends BaseTestCase { // ====== Booster Set Stage ====== // ====== ====== ====== - ParallelStage boosters = (ParallelStage) rkt.getChild(1).getChild(1); + ParallelStage boosters = (ParallelStage) rkt.getChild(1).getChild(0).getChild(1); { expMass = 0.0222459863653; // think of the casts as an assert that ( child instanceof NoseCone) == true @@ -288,7 +288,7 @@ public class MassCalculatorTest extends BaseTestCase { // ====== Booster Set Stage ====== // ====== ====== ====== - ParallelStage boosters = (ParallelStage) rkt.getChild(1).getChild(1); + ParallelStage boosters = (ParallelStage) rkt.getChild(1).getChild(0).getChild(1); { expCMx = 0.055710581052; // think of the casts as an assert that ( child instanceof NoseCone) == true @@ -406,7 +406,7 @@ public class MassCalculatorTest extends BaseTestCase { // ====== Booster Set Stage ====== // ====== ====== ====== - ParallelStage boosters = (ParallelStage) rocket.getChild(1).getChild(1); + ParallelStage boosters = (ParallelStage) rocket.getChild(1).getChild(0).getChild(1); { cc= boosters.getChild(0); expInertia = 1.82665797857e-5; @@ -535,7 +535,7 @@ public class MassCalculatorTest extends BaseTestCase { FlightConfiguration config = rocket.getEmptyConfiguration(); - ParallelStage boosters = (ParallelStage) rocket.getChild(1).getChild(1); + ParallelStage boosters = (ParallelStage) rocket.getChild(1).getChild(0).getChild(1); config.setOnlyStage( boosters.getStageNumber() ); final RigidBody actualData = MassCalculator.calculateStructure( config ); @@ -606,7 +606,7 @@ public class MassCalculatorTest extends BaseTestCase { RigidBody actualPropellant = MassCalculator.calculateMotor( config ); final Coordinate actCM= actualPropellant.getCM(); - ParallelStage boosters = (ParallelStage) rocket.getChild(1).getChild(1); + ParallelStage boosters = (ParallelStage) rocket.getChild(1).getChild(0).getChild(1); final MotorMount mnt = (MotorMount)boosters.getChild(1).getChild(0); final Motor boosterMotor = mnt.getMotorConfig( config.getFlightConfigurationID()).getMotor(); @@ -690,7 +690,7 @@ public class MassCalculatorTest extends BaseTestCase { rocket.setSelectedConfiguration( config.getId() ); config.setOnlyStage( TestRockets.FALCON_9H_BOOSTER_STAGE_NUMBER ); - final ParallelStage boosters = (ParallelStage) rocket.getChild(1).getChild(1); + final ParallelStage boosters = (ParallelStage) rocket.getChild(1).getChild(0).getChild(1); final double overrideMass = 0.5; boosters.setOverrideSubcomponents(true); boosters.setMassOverridden(true); @@ -730,7 +730,7 @@ public class MassCalculatorTest extends BaseTestCase { FlightConfiguration config = rocket.getEmptyConfiguration(); rocket.setSelectedConfiguration( config.getId() ); - ParallelStage boosters = (ParallelStage) rocket.getChild(1).getChild(1); + ParallelStage boosters = (ParallelStage) rocket.getChild(1).getChild(0).getChild(1); config.setOnlyStage( boosters.getStageNumber() ); NoseCone nose = (NoseCone)boosters.getChild(0); @@ -777,7 +777,7 @@ public class MassCalculatorTest extends BaseTestCase { rocket.setSelectedConfiguration( config.getId() ); config.setOnlyStage( TestRockets.FALCON_9H_BOOSTER_STAGE_NUMBER ); - ParallelStage boosters = (ParallelStage) rocket.getChild(1).getChild(1); + ParallelStage boosters = (ParallelStage) rocket.getChild(1).getChild(0).getChild(1); NoseCone nose = (NoseCone)boosters.getChild(0); nose.setCGOverridden(true); diff --git a/core/test/net/sf/openrocket/rocketcomponent/ParallelStageTest.java b/core/test/net/sf/openrocket/rocketcomponent/ParallelStageTest.java index 2f970728e..de56e2b6a 100644 --- a/core/test/net/sf/openrocket/rocketcomponent/ParallelStageTest.java +++ b/core/test/net/sf/openrocket/rocketcomponent/ParallelStageTest.java @@ -7,6 +7,7 @@ import static org.junit.Assert.assertThat; import org.junit.Test; +import junit.framework.Assert; import net.sf.openrocket.rocketcomponent.RocketComponent.Position; import net.sf.openrocket.util.Coordinate; import net.sf.openrocket.util.TestRockets; @@ -15,71 +16,10 @@ import net.sf.openrocket.util.BaseTestCase.BaseTestCase; public class ParallelStageTest extends BaseTestCase { // tolerance for compared double test results - protected final double EPSILON = 0.00001; + protected final double EPSILON = 0.000001; protected final Coordinate ZERO = new Coordinate(0., 0., 0.); - public void test() { - // fail("Not yet implemented"); - } - - public Rocket createTestRocket() { - double tubeRadius = 1.2; - // setup - Rocket rocket = new Rocket(); - rocket.setName("Rocket"); - - AxialStage sustainer = new AxialStage(); - sustainer.setName("Sustainer stage"); - RocketComponent sustainerNose = new NoseCone(Transition.Shape.CONICAL, 2.0, tubeRadius); - sustainerNose.setName("Sustainer Nosecone"); - sustainer.addChild(sustainerNose); - RocketComponent sustainerBody = new BodyTube(3.0, tubeRadius, 0.01); - sustainerBody.setName("Sustainer Body "); - sustainer.addChild(sustainerBody); - rocket.addChild(sustainer); - - AxialStage core = new AxialStage(); - core.setName("Core stage"); - rocket.addChild(core); - BodyTube coreUpperBody = new BodyTube(1.8, tubeRadius, 0.01); - coreUpperBody.setName("Core UpBody "); - core.addChild(coreUpperBody); - BodyTube coreLowerBody = new BodyTube(4.2, tubeRadius, 0.01); - coreLowerBody.setName("Core LoBody "); - core.addChild(coreLowerBody); - FinSet coreFins = new TrapezoidFinSet(4, 4, 2, 2, 4); - coreFins.setName("Core Fins"); - coreLowerBody.addChild(coreFins); - - rocket.enableEvents(); - return rocket; - } - - public ParallelStage createBooster() { - double tubeRadius = 0.8; - - ParallelStage strapon = new ParallelStage(); - strapon.setName("Booster Stage"); - RocketComponent boosterNose = new NoseCone(Transition.Shape.CONICAL, 2.0, tubeRadius); - boosterNose.setName("Booster Nosecone"); - strapon.addChild(boosterNose); - RocketComponent boosterBody = new BodyTube(2.0, tubeRadius, 0.01); - boosterBody.setName("Booster Body "); - strapon.addChild(boosterBody); - Transition boosterTail = new Transition(); - boosterTail.setName("Booster Tail"); - boosterTail.setForeRadius(1.0); - boosterTail.setAftRadius(0.5); - boosterTail.setLength(1.0); - strapon.addChild(boosterTail); - - strapon.setInstanceCount(3); - strapon.setRadialOffset(1.8); - strapon.setAutoRadialOffset(false); - - return strapon; - } /* From OpenRocket Technical Documentation * @@ -90,10 +30,36 @@ public class ParallelStageTest extends BaseTestCase { * when discussing the fins. During simulation, however, the y- and z-axes are fixed in relation to the rocket, * and do not necessarily align with the plane of the pitching moments. */ + + public ParallelStage createBooster() { + double tubeRadius = 0.8; + + ParallelStage strapon = new ParallelStage(); + strapon.setName("Booster Stage"); + RocketComponent boosterNose = new NoseCone(Transition.Shape.CONICAL, 2.0, tubeRadius); + boosterNose.setName("Booster Nosecone"); + strapon.addChild(boosterNose); + RocketComponent boosterBody = new BodyTube(2.0, tubeRadius, 0.01); + boosterBody.setName("Booster Body "); + strapon.addChild(boosterBody); + Transition boosterTail = new Transition(); + boosterTail.setName("Booster Tail"); + boosterTail.setForeRadius(1.0); + boosterTail.setAftRadius(0.5); + boosterTail.setLength(1.0); + strapon.addChild(boosterTail); + + strapon.setInstanceCount(3); + strapon.setRadialOffset(1.8); + strapon.setAutoRadialOffset(false); + + return strapon; + } + @Test public void testSetRocketPositionFail() { - RocketComponent rocket = createTestRocket(); + Rocket rocket = TestRockets.makeFalcon9Heavy(); Coordinate expectedPosition; Coordinate targetPosition; Coordinate resultPosition; @@ -108,101 +74,82 @@ public class ParallelStageTest extends BaseTestCase { } @Test - public void testCreateSustainer() { - RocketComponent rocket = createTestRocket(); + public void testPayload() { + Rocket rocket = TestRockets.makeFalcon9Heavy(); // Sustainer Stage - AxialStage sustainer = (AxialStage) rocket.getChild(0); - RocketComponent sustainerNose = sustainer.getChild(0); - RocketComponent sustainerBody = sustainer.getChild(1); - assertThat(" createTestRocket failed: is sustainer stage an ancestor of the sustainer stage? ", sustainer.isAncestor(sustainer), equalTo(false)); - assertThat(" createTestRocket failed: is sustainer stage an ancestor of the sustainer nose? ", sustainer.isAncestor(sustainerNose), equalTo(true)); - assertThat(" createTestRocket failed: is the rocket rocket an ancestor of the sustainer Nose? ", rocket.isAncestor(sustainerNose), equalTo(true)); - assertThat(" createTestRocket failed: is sustainer Body an ancestor of the sustainer Nose? ", sustainerBody.isAncestor(sustainerNose), equalTo(false)); - - String rocketTree = rocket.toDebugTree(); + AxialStage payloadStage = (AxialStage) rocket.getChild(0); + RocketComponent payloadNose = payloadStage.getChild(0); + RocketComponent payloadBody = payloadStage.getChild(1); + assertThat(" createTestRocket failed: is payload stage an ancestor of the payload stage? ", payloadStage.isAncestor(payloadStage), equalTo(false)); + assertThat(" createTestRocket failed: is payload stage an ancestor of the payload nose? ", payloadStage.isAncestor(payloadNose), equalTo(true)); + assertThat(" createTestRocket failed: is the rocket an ancestor of the sustainer Nose? ", rocket.isAncestor(payloadNose), equalTo(true)); + assertThat(" createTestRocket failed: is payload Body an ancestor of the payload Nose? ", payloadBody.isAncestor(payloadNose), equalTo(false)); int relToExpected = -1; - int relToStage = sustainer.getRelativeToStage(); + int relToStage = payloadStage.getRelativeToStage(); assertThat(" createTestRocket failed: sustainer relative position: ", relToStage, equalTo(relToExpected)); - double expectedSustainerLength = 5.0; - assertThat(" createTestRocket failed: Sustainer size: ", sustainer.getLength(), equalTo(expectedSustainerLength)); - double expectedSustainerX = 0; - double sustainerX; - sustainerX = sustainer.getOffset().x; - assertThat(" createTestRocket failed:\n" + rocketTree + " sustainer Relative position: ", sustainerX, equalTo(expectedSustainerX)); - sustainerX = sustainer.getLocations()[0].x; - assertThat(" createTestRocket failed:\n" + rocketTree + " sustainer Absolute position: ", sustainerX, equalTo(expectedSustainerX)); + double expectedPayloadLength = 0.564; + Assert.assertEquals( payloadStage.getLength(), expectedPayloadLength, EPSILON); - double expectedSustainerNoseX = 0; - double sustainerNosePosition = sustainerNose.getOffset().x; - assertThat(" createTestRocket failed:\n" + rocketTree + " sustainer Nose X position: ", sustainerNosePosition, equalTo(expectedSustainerNoseX)); - expectedSustainerNoseX = 0; - sustainerNosePosition = sustainerNose.getLocations()[0].x; - assertThat(" createTestRocket failed:\n" + rocketTree + " sustainer Nose X position: ", sustainerNosePosition, equalTo(expectedSustainerNoseX)); + double expectedPayloadStageX = 0; + Assert.assertEquals( payloadStage.getOffset().x, expectedPayloadStageX, EPSILON); + Assert.assertEquals( payloadStage.getComponentLocations()[0].x, expectedPayloadStageX, EPSILON); - double expectedSustainerBodyX = 2; - double sustainerBodyX = sustainerBody.getOffset().x; - assertThat(" createTestRocket failed:\n" + rocketTree + " sustainer body rel X position: ", sustainerBodyX, equalTo(expectedSustainerBodyX)); - expectedSustainerBodyX = 2; - sustainerBodyX = sustainerBody.getLocations()[0].x; - assertThat(" createTestRocket failed:\n" + rocketTree + " sustainer body abs X position: ", sustainerBodyX, equalTo(expectedSustainerBodyX)); + double expectedPayloadNoseX = 0; + Assert.assertEquals( payloadNose.getOffset().x, expectedPayloadNoseX, EPSILON); + Assert.assertEquals( payloadNose.getComponentLocations()[0].x, expectedPayloadNoseX, EPSILON); + double expectedPayloadBodyX = payloadNose.getLength(); + Assert.assertEquals( payloadBody.getOffset().x, expectedPayloadBodyX, EPSILON); + Assert.assertEquals( payloadBody.getComponentLocations()[0].x, expectedPayloadBodyX, EPSILON); } // WARNING: this test will not pass unless 'testAddTopStage' is passing as well -- that function tests the dependencies... @Test - public void testAddCoreStage() { + public void testCoreStage() { // vvvv function under test vvvv ( which indirectly tests initialization code, and that the test setup creates the preconditions that we expect - RocketComponent rocket = createTestRocket(); + Rocket rocket = TestRockets.makeFalcon9Heavy(); // ^^^^ function under test ^^^^ + String rocketTree = rocket.toDebugTree(); + // Payload Stage + AxialStage payloadStage = (AxialStage)rocket.getChild(0); + final double expectedPayloadLength = 0.564; + final double payloadLength = payloadStage.getLength(); + Assert.assertEquals( payloadLength, expectedPayloadLength, EPSILON); + // Core Stage - AxialStage core = (AxialStage) rocket.getChild(1); - double expectedCoreLength = 6.0; - assertThat(" createTestRocket failed: Core size: ", core.getLength(), equalTo(expectedCoreLength)); - double expectedCoreX = 5; - double coreX; + AxialStage coreStage = (AxialStage) rocket.getChild(1); + double expectedCoreLength = 0.8; + assertThat(" createTestRocket failed: Core size: ", coreStage.getLength(), equalTo(expectedCoreLength)); int relToExpected = 0; - int relToStage = core.getRelativeToStage(); + int relToStage = coreStage.getRelativeToStage(); assertThat(" createTestRocket failed:\n" + rocketTree + " core relative position: ", relToStage, equalTo(relToExpected)); - coreX = core.getOffset().x; - assertThat(" createTestRocket failed:\n" + rocketTree + " core Relative position: ", coreX, equalTo(expectedCoreX)); - coreX = core.getLocations()[0].x; - assertThat(" createTestRocket failed:\n" + rocketTree + " core Absolute position: ", coreX, equalTo(expectedCoreX)); - - RocketComponent coreUpperBody = core.getChild(0); - double expectedX = 0; - double resultantX = coreUpperBody.getOffset().x; - assertThat(" createTestRocket failed:\n" + rocketTree + " core body rel X: ", resultantX, equalTo(expectedX)); - expectedX = expectedCoreX; - resultantX = coreUpperBody.getLocations()[0].x; - assertThat(" createTestRocket failed:\n" + rocketTree + " core body abs X: ", resultantX, equalTo(expectedX)); - - RocketComponent coreLowerBody = core.getChild(1); - expectedX = coreUpperBody.getLength(); - resultantX = coreLowerBody.getOffset().x; - assertEquals(" createTestRocket failed:\n" + rocketTree + " core body rel X: ", expectedX, resultantX, EPSILON); - expectedX = expectedCoreX + coreUpperBody.getLength(); - resultantX = coreLowerBody.getLocations()[0].x; - assertEquals(" createTestRocket failed:\n" + rocketTree + " core body abs X: ", expectedX, resultantX, EPSILON); + final double expectedCoreStageX = payloadLength; + Assert.assertEquals( expectedCoreStageX, 0.564, EPSILON); + Assert.assertEquals( coreStage.getOffset().x, expectedCoreStageX, EPSILON); + Assert.assertEquals( coreStage.getComponentLocations()[0].x, expectedCoreStageX, EPSILON); - RocketComponent coreFins = coreLowerBody.getChild(0); - // default is offset=0, method=0 - expectedX = 0.2; - resultantX = coreFins.getOffset().x; - assertEquals(" createTestRocket failed:\n" + rocketTree + " core Fins rel X: ", expectedX, resultantX, EPSILON); - // 5 + 1.8 + 4.2 = 11 - // 11 - 4 = 7; - expectedX = 7.0; - resultantX = coreFins.getLocations()[0].x; - assertEquals(" createTestRocket failed:\n" + rocketTree + " core Fins abs X: ", expectedX, resultantX, EPSILON); + RocketComponent coreBody = coreStage.getChild(0); + Assert.assertEquals( coreBody.getOffset().x, 0.0, EPSILON); + Assert.assertEquals( coreBody.getComponentLocations()[0].x, expectedCoreStageX, EPSILON); + FinSet coreFins = (FinSet)coreBody.getChild(0); + + // default is offset=0, method=BOTTOM + assertEquals( Position.BOTTOM, coreFins.getRelativePosition() ); + assertEquals( 0.0, coreFins.getAxialOffset(), EPSILON); + + assertEquals( 0.480, coreFins.getOffset().x, EPSILON); + + assertEquals( 1.044, coreFins.getComponentLocations()[0].x, EPSILON); + } @@ -211,23 +158,23 @@ public class ParallelStageTest extends BaseTestCase { RocketComponent rocket = TestRockets.makeFalcon9Heavy(); AxialStage sustainer = (AxialStage) rocket.getChild(0); - AxialStage core = (AxialStage) rocket.getChild(1); - AxialStage booster = (AxialStage) core.getChild(1); + AxialStage coreStage = (AxialStage) rocket.getChild(1); + AxialStage booster = (AxialStage) coreStage.getChild(0).getChild(1); - AxialStage sustainerPrev = sustainer.getPreviousStage(); + AxialStage sustainerPrev = sustainer.getUpperStage(); assertThat("sustainer parent is not found correctly: ", sustainerPrev, equalTo(null)); - AxialStage corePrev = core.getPreviousStage(); + AxialStage corePrev = coreStage.getUpperStage(); assertThat("core parent is not found correctly: ", corePrev, equalTo(sustainer)); - AxialStage boosterPrev = booster.getPreviousStage(); - assertThat("booster parent is not found correctly: ", boosterPrev, equalTo(core)); + AxialStage boosterPrev = booster.getUpperStage(); + assertThat("booster parent is not found correctly: ", boosterPrev, equalTo(coreStage)); } @Test public void testSetStagePosition_topOfStack() { // setup - RocketComponent rocket = createTestRocket(); + Rocket rocket = TestRockets.makeFalcon9Heavy(); AxialStage sustainer = (AxialStage) rocket.getChild(0); Coordinate expectedPosition = new Coordinate(0, 0., 0.); // i.e. half the tube length Coordinate targetPosition = new Coordinate(+4.0, 0., 0.); @@ -246,91 +193,84 @@ public class ParallelStageTest extends BaseTestCase { Coordinate resultantRelativePosition = sustainer.getOffset(); assertThat(" 'setAxialPosition(double)' failed:\n" + rocketTree + " Relative position: ", resultantRelativePosition.x, equalTo(expectedPosition.x)); // for all stages, the absolute position should equal the relative, because the direct parent is the rocket component (i.e. the Rocket) - Coordinate resultantAbsolutePosition = sustainer.getLocations()[0]; + Coordinate resultantAbsolutePosition = sustainer.getComponentLocations()[0]; assertThat(" 'setAxialPosition(double)' failed:\n" + rocketTree + " Absolute position: ", resultantAbsolutePosition.x, equalTo(expectedPosition.x)); } @Test public void testBoosterInitializationSimple() { - // setup - RocketComponent rocket = createTestRocket(); - AxialStage core = (AxialStage) rocket.getChild(1); - ParallelStage set0 = createBooster(); - core.addChild(set0); - + final RocketComponent rocket = TestRockets.makeFalcon9Heavy(); + final AxialStage coreStage = (AxialStage) rocket.getChild(1); + final ParallelStage boosterStage = (ParallelStage)coreStage.getChild(0).getChild(1); + double targetOffset = 0; - set0.setAxialOffset(Position.BOTTOM, targetOffset); + boosterStage .setAxialOffset(Position.BOTTOM, targetOffset); // vvvv function under test - set0.setInstanceCount(2); - set0.setRadialOffset(4.0); - set0.setAngularOffset(Math.PI / 2); + boosterStage.setInstanceCount(2); + boosterStage.setRadialOffset(4.0); + boosterStage.setAngularOffset(Math.PI / 2); // ^^ function under test String treeDump = rocket.toDebugTree(); int expectedInstanceCount = 2; - int instanceCount = set0.getInstanceCount(); + int instanceCount = boosterStage.getInstanceCount(); assertThat(" 'setInstancecount(int)' failed: ", instanceCount, equalTo(expectedInstanceCount)); - double expectedAbsX = 6.0; - double resultantX = set0.getLocations()[0].x; + double expectedAbsX = 0.484; + double resultantX = boosterStage.getComponentLocations()[0].x; assertEquals(">>'setAxialOffset()' failed:\n" + treeDump + " 1st Inst absolute position", expectedAbsX, resultantX, EPSILON); double expectedRadialOffset = 4.0; - double radialOffset = set0.getRadialOffset(); + double radialOffset = boosterStage.getRadialOffset(); assertEquals(" 'setRadialOffset(double)' failed: \n" + treeDump + " radial offset: ", expectedRadialOffset, radialOffset, EPSILON); double expectedAngularOffset = Math.PI / 2; - double angularOffset = set0.getAngularOffset(); + double angularOffset = boosterStage.getAngularOffset(); assertEquals(" 'setAngularOffset(double)' failed:\n" + treeDump + " angular offset: ", expectedAngularOffset, angularOffset, EPSILON); } @Test public void testBoosterInitializationAutoRadius() { - // setup - RocketComponent rocket = createTestRocket(); - AxialStage core = (AxialStage) rocket.getChild(1); - ParallelStage set0 = createBooster(); - core.addChild(set0); + final RocketComponent rocket = TestRockets.makeFalcon9Heavy(); + final AxialStage coreStage = (AxialStage) rocket.getChild(1); + final ParallelStage boosterStage = (ParallelStage)coreStage.getChild(0).getChild(1); double targetOffset = 0; - set0.setAxialOffset(Position.BOTTOM, targetOffset); + boosterStage.setAxialOffset(Position.BOTTOM, targetOffset); // vvvv function under test - set0.setAutoRadialOffset(true); - set0.setRadialOffset(4.0); // this called will be overriden by the AutoRadialOffset above + boosterStage.setAutoRadialOffset(true); + boosterStage.setRadialOffset(4.0); // this call will be overriden by the AutoRadialOffset above // ^^^^ function under test - String treeDump = rocket.toDebugTree(); - double expectedRadialOffset = 2.2; - double radialOffset = set0.getRadialOffset(); - assertEquals(" 'setRadialOffset(double)' failed: \n" + treeDump + " radial offset: ", expectedRadialOffset, radialOffset, EPSILON); + double expectedRadialOffset = 0.077; + double radialOffset = boosterStage.getRadialOffset(); + assertEquals(" 'setRadialOffset(double)' failed for radial offset: ", expectedRadialOffset, radialOffset, EPSILON); } @Test public void testAddStraponAuto() { - // setup - RocketComponent rocket = createTestRocket(); - AxialStage core = (AxialStage) rocket.getChild(1); - ParallelStage strapons = createBooster(); - core.addChild( strapons); + final RocketComponent rocket = TestRockets.makeFalcon9Heavy(); + final AxialStage coreStage = (AxialStage) rocket.getChild(1); + final ParallelStage boosterStage = (ParallelStage)coreStage.getChild(0).getChild(1); double targetXOffset = +1.0; - strapons.setAxialOffset(Position.BOTTOM, targetXOffset); + boosterStage.setAxialOffset(Position.BOTTOM, targetXOffset); double targetRadialOffset = 0.01; // vv function under test - strapons.setRadialOffset(targetRadialOffset); - strapons.setAutoRadialOffset(true); + boosterStage.setRadialOffset(targetRadialOffset); + boosterStage.setAutoRadialOffset(true); // ^^ function under test String treeDump = rocket.toDebugTree(); - double expectedRadialOffset = core.getOuterRadius() + strapons.getOuterRadius(); - double actualRadialOffset = strapons.getRadialOffset(); + double expectedRadialOffset = coreStage.getOuterRadius() + boosterStage.getOuterRadius(); + double actualRadialOffset = boosterStage.getRadialOffset(); assertEquals(" 'setAutoRadialOffset()' failed:\n" + treeDump , expectedRadialOffset, actualRadialOffset, EPSILON); -// Coordinate[] instanceAbsoluteCoords = set0.getLocations(); +// Coordinate[] instanceAbsoluteCoords = set0.getComponentLocations; // // Coordinate[] instanceRelativeCoords = new Coordinate[] { componentAbsolutePosition }; // // instanceRelativeCoords = boosterSet.shiftCoordinates(instanceRelativeCoords); // @@ -355,27 +295,25 @@ public class ParallelStageTest extends BaseTestCase { // also an error with a well-defined failure result (i.e. just failover to AFTER placement as the first stage of a rocket. @Test public void testBoosterInstanceLocation_BOTTOM() { - // setup - RocketComponent rocket = createTestRocket(); - AxialStage core = (AxialStage) rocket.getChild(1); - ParallelStage set0 = createBooster(); - core.addChild(set0); + final RocketComponent rocket = TestRockets.makeFalcon9Heavy(); + final AxialStage coreStage = (AxialStage) rocket.getChild(1); + final ParallelStage boosterStage = (ParallelStage)coreStage.getChild(0).getChild(1); double targetOffset = 0; - set0.setAxialOffset(Position.BOTTOM, targetOffset); + boosterStage.setAxialOffset(Position.BOTTOM, targetOffset); int targetInstanceCount = 3; double targetRadialOffset = 1.8; // vv function under test - set0.setInstanceCount(targetInstanceCount); - set0.setRadialOffset(targetRadialOffset); + boosterStage.setInstanceCount(targetInstanceCount); + boosterStage.setRadialOffset(targetRadialOffset); // ^^ function under test String treeDump = rocket.toDebugTree(); - double expectedX = 6; + double expectedX = 0.484; double angle = Math.PI * 2 / targetInstanceCount; double radius = targetRadialOffset; - Coordinate[] instanceAbsoluteCoords = set0.getLocations(); + Coordinate[] instanceAbsoluteCoords = boosterStage.getComponentLocations(); // Coordinate[] instanceRelativeCoords = new Coordinate[] { componentAbsolutePosition }; // instanceRelativeCoords = boosterSet.shiftCoordinates(instanceRelativeCoords); @@ -400,30 +338,29 @@ public class ParallelStageTest extends BaseTestCase { // also an error with a well-defined failure result (i.e. just failover to AFTER placement as the first stage of a rocket. @Test public void testSetStagePosition_outsideABSOLUTE() { - // setup - RocketComponent rocket = createTestRocket(); - AxialStage core = (AxialStage) rocket.getChild(1); - ParallelStage booster = createBooster(); - core.addChild(booster); + final RocketComponent rocket = TestRockets.makeFalcon9Heavy(); + final BodyTube coreBody= (BodyTube) rocket.getChild(1).getChild(0); + final ParallelStage boosterStage = (ParallelStage)coreBody.getChild(1); - double targetX = +17.0; - double expectedX = targetX - core.getLocations()[0].x; + double targetAbsoluteX = 0.8; + double expectedRelativeX = 0.236; + double expectedAbsoluteX = 0.8; // when subStages should be freely movable // vv function under test - booster.setAxialOffset(Position.ABSOLUTE, targetX); + boosterStage.setAxialOffset(Position.ABSOLUTE, targetAbsoluteX); // ^^ function under test + String treeDump = rocket.toDebugTree(); - Coordinate resultantRelativePosition = booster.getOffset(); - assertThat(" 'setAxialPosition(double)' failed: \n" + treeDump + " Relative position: ", resultantRelativePosition.x, equalTo(expectedX)); - double resultantPositionValue = booster.getAxialOffset(); - assertThat(" 'setAxialPosition(double)' failed: \n" + treeDump + " PositionValue: ", resultantPositionValue, equalTo(targetX)); - double resultantAxialPosition = booster.getAxialOffset(); - assertThat(" 'setAxialPosition(double)' failed: \n" + treeDump + " Relative position: ", resultantAxialPosition, equalTo(targetX)); - // for all stages, the absolute position should equal the relative, because the direct parent is the rocket component (i.e. the Rocket) - Coordinate resultantAbsolutePosition = booster.getLocations()[0]; - assertThat(" 'setAxialPosition(double)' failed: \n" + treeDump + " Absolute position: ", resultantAbsolutePosition.x, equalTo(targetX)); + double actualAxialOffset = boosterStage.getAxialOffset(); + assertThat(" 'setAxialPosition(double)' failed: \n" + treeDump + " Absolute position: ", actualAxialOffset, equalTo(expectedAbsoluteX)); + + double actualRelativeX = boosterStage.asPositionValue(Position.TOP); + assertThat(" 'setAxialPosition(double)' failed: \n" + treeDump + " Relative position: ", actualRelativeX, equalTo(expectedRelativeX)); + + double actualAbsoluteX = boosterStage.getComponentLocations()[0].x; + assertThat(" 'setAxialPosition(double)' failed: \n" + treeDump + " Absolute position: ", actualAbsoluteX, equalTo(expectedAbsoluteX)); } // WARNING: @@ -431,293 +368,259 @@ public class ParallelStageTest extends BaseTestCase { // also an error with a well-defined failure result (i.e. just failover to AFTER placement as the first stage of a rocket. @Test public void testSetStagePosition_outsideTopOfStack() { - // setup - RocketComponent rocket = createTestRocket(); - AxialStage sustainer = (AxialStage) rocket.getChild(0); - Coordinate targetPosition = new Coordinate(+4.0, 0., 0.); + final RocketComponent rocket = TestRockets.makeFalcon9Heavy(); + final AxialStage payloadStage = (AxialStage) rocket.getChild(0); +// final AxialStage coreStage = (AxialStage) rocket.getChild(1); +// final ParallelStage boosterStage = (ParallelStage)coreStage.getChild(0).getChild(1); + Coordinate targetPosition = new Coordinate(+4.0, 0., 0.); + int expectedRelativeIndex = -1; - int resultantRelativeIndex = sustainer.getRelativeToStage(); + int resultantRelativeIndex = payloadStage.getRelativeToStage(); assertThat(" 'setRelativeToStage(int)' failed. Relative stage index:", expectedRelativeIndex, equalTo(resultantRelativeIndex)); // vv function under test // when 'external' the stage should be freely movable - sustainer.setAxialOffset(Position.TOP, targetPosition.x); + payloadStage.setAxialOffset(Position.TOP, targetPosition.x); // ^^ function under test String treeDump = rocket.toDebugTree(); double expectedX = 0; - Coordinate resultantRelativePosition = sustainer.getOffset(); + Coordinate resultantRelativePosition = payloadStage.getOffset(); assertThat(" 'setAxialPosition(double)' failed: \n" + treeDump + " Sustainer Relative position: ", resultantRelativePosition.x, equalTo(expectedX)); double expectedPositionValue = 0; - double resultantPositionValue = sustainer.getAxialOffset(); + double resultantPositionValue = payloadStage.getAxialOffset(); assertThat(" 'setPositionValue()' failed: \n" + treeDump + " Sustainer Position Value: ", resultantPositionValue, equalTo(expectedPositionValue)); double expectedAxialOffset = 0; - double resultantAxialOffset = sustainer.getAxialOffset(); + double resultantAxialOffset = payloadStage.getAxialOffset(); assertThat(" 'getAxialPosition()' failed: \n" + treeDump + " Relative position: ", resultantAxialOffset, equalTo(expectedAxialOffset)); // for all stages, the absolute position should equal the relative, because the direct parent is the rocket component (i.e. the Rocket) - Coordinate resultantAbsolutePosition = sustainer.getLocations()[0]; + Coordinate resultantAbsolutePosition = payloadStage.getComponentLocations()[0]; assertThat(" 'setAbsolutePositionVector()' failed: \n" + treeDump + " Absolute position: ", resultantAbsolutePosition.x, equalTo(expectedX)); } @Test public void testSetStagePosition_outsideTOP() { - Rocket rocket = this.createTestRocket(); - AxialStage core = (AxialStage) rocket.getChild(1); - ParallelStage booster = createBooster(); - core.addChild(booster); + final RocketComponent rocket = TestRockets.makeFalcon9Heavy(); + final AxialStage coreStage = (AxialStage) rocket.getChild(1); + final ParallelStage boosterStage = (ParallelStage)coreStage.getChild(0).getChild(1); - double targetOffset = +2.0; + double targetOffset = 0.2; // vv function under test - booster.setAxialOffset(Position.TOP, targetOffset); + boosterStage.setAxialOffset(Position.TOP, targetOffset); // ^^ function under test + String treeDump = rocket.toDebugTree(); - double expectedRelativeX = 2; - double expectedAbsoluteX = 7; - Coordinate resultantRelativePosition = booster.getOffset(); + double expectedRelativeX = 0.2; + double expectedAbsoluteX = 0.764; + Coordinate resultantRelativePosition = boosterStage.getOffset(); assertThat(" 'setAxialPosition(double)' failed: \n" + treeDump + " Relative position: ", resultantRelativePosition.x, equalTo(expectedRelativeX)); // for all stages, the absolute position should equal the relative, because the direct parent is the rocket component (i.e. the Rocket) - Coordinate resultantAbsolutePosition = booster.getLocations()[0]; + Coordinate resultantAbsolutePosition = boosterStage.getComponentLocations()[0]; assertThat(" 'setAxialPosition(double)' failed: \n" + treeDump + " Absolute position: ", resultantAbsolutePosition.x, equalTo(expectedAbsoluteX)); - double resultantAxialOffset = booster.getAxialOffset(); + double resultantAxialOffset = boosterStage.getAxialOffset(); assertThat(" 'getAxialPosition()' failed: \n" + treeDump + " Axial Offset: ", resultantAxialOffset, equalTo(targetOffset)); - double resultantPositionValue = booster.getAxialOffset(); + double resultantPositionValue = boosterStage.getAxialOffset(); assertThat(" 'setPositionValue()' failed: \n" + treeDump + " Position Value: ", resultantPositionValue, equalTo(targetOffset)); } @Test - public void testSetStagePosition_outsideMIDDLE() { - // setup - RocketComponent rocket = createTestRocket(); - AxialStage core = (AxialStage) rocket.getChild(1); - ParallelStage booster = createBooster(); - core.addChild(booster); + public void testSetMIDDLE() { + final RocketComponent rocket = TestRockets.makeFalcon9Heavy(); + final AxialStage coreStage = (AxialStage) rocket.getChild(1); + final ParallelStage boosterStage = (ParallelStage)coreStage.getChild(0).getChild(1); // when 'external' the stage should be freely movable // vv function under test - double targetOffset = +2.0; - booster.setAxialOffset(Position.MIDDLE, targetOffset); + double targetOffset = 0.2; + boosterStage.setAxialOffset(Position.MIDDLE, targetOffset); // ^^ function under test - String treeDump = rocket.toDebugTree(); + + Assert.assertEquals( targetOffset, boosterStage.getAxialOffset(), EPSILON ); - double expectedRelativeX = 2.5; - double expectedAbsoluteX = 7.5; - Coordinate resultantRelativePosition = booster.getOffset(); - assertThat(" 'setAxialPosition(double)' failed: \n" + treeDump + " Relative position: ", resultantRelativePosition.x, equalTo(expectedRelativeX)); - // for all stages, the absolute position should equal the relative, because the direct parent is the rocket component (i.e. the Rocket) - Coordinate resultantAbsolutePosition = booster.getLocations()[0]; - assertThat(" 'setAxialPosition(double)' failed: \n" + treeDump + " Absolute position: ", resultantAbsolutePosition.x, equalTo(expectedAbsoluteX)); + Assert.assertEquals( 0.16, boosterStage.getOffset().x, EPSILON ); - double resultantPositionValue = booster.getAxialOffset(); - assertThat(" 'setPositionValue()' failed: \n" + treeDump + " Position Value: ", resultantPositionValue, equalTo(targetOffset)); + Assert.assertEquals( 0.724, boosterStage.getComponentLocations()[0].x, EPSILON ); - double resultantAxialOffset = booster.getAxialOffset(); - assertThat(" 'getAxialPosition()' failed:\n" + treeDump + " Axial Offset: ", resultantAxialOffset, equalTo(targetOffset)); } @Test - public void testSetStagePosition_outsideBOTTOM() { - // setup - RocketComponent rocket = createTestRocket(); - AxialStage core = (AxialStage) rocket.getChild(1); - ParallelStage booster = createBooster(); - core.addChild(booster); + public void testSetBOTTOM() { + final RocketComponent rocket = TestRockets.makeFalcon9Heavy(); + final ParallelStage boosterStage = (ParallelStage)rocket.getChild(1).getChild(0).getChild(1); // vv function under test - double targetOffset = +4.0; - booster.setAxialOffset(Position.BOTTOM, targetOffset); + double targetOffset = 0.2; + boosterStage.setAxialOffset(Position.BOTTOM, targetOffset); // ^^ function under test - String treeDump = rocket.toDebugTree(); + + Assert.assertEquals( 0.120, boosterStage.getOffset().x, EPSILON); + + Assert.assertEquals( 0.684, boosterStage.getComponentLocations()[0].x, EPSILON); - double expectedRelativeX = 5; - double expectedAbsoluteX = +10; - Coordinate resultantRelativePosition = booster.getOffset(); - assertThat(" 'setAxialPosition(double)' failed: \n" + treeDump + " Relative position: ", resultantRelativePosition.x, equalTo(expectedRelativeX)); - // for all stages, the absolute position should equal the relative, because the direct parent is the rocket component (i.e. the Rocket) - Coordinate resultantAbsolutePosition = booster.getLocations()[0]; - assertThat(" 'setAxialPosition(double)' failed: \n" + treeDump + " Absolute position: ", resultantAbsolutePosition.x, equalTo(expectedAbsoluteX)); - - double resultantPositionValue = booster.getAxialOffset(); - assertThat(" 'setPositionValue()' failed: \n" + treeDump + " Position Value: ", resultantPositionValue, equalTo(targetOffset)); - - double resultantAxialOffset = booster.getAxialOffset(); - assertThat(" 'getAxialPosition()' failed: \n" + treeDump + " Axial Offset: ", resultantAxialOffset, equalTo(targetOffset)); + Assert.assertEquals( targetOffset, boosterStage.getAxialOffset(), EPSILON); } @Test - public void testAxial_setTOP_getABSOLUTE() { - // setup - RocketComponent rocket = createTestRocket(); - AxialStage core = (AxialStage) rocket.getChild(1); - ParallelStage booster = createBooster(); - core.addChild(booster); + public void testSetTOP_getABSOLUTE() { + final RocketComponent rocket = TestRockets.makeFalcon9Heavy(); + final AxialStage coreStage = (AxialStage) rocket.getChild(1); + final ParallelStage boosterStage = (ParallelStage)coreStage.getChild(0).getChild(1); - double targetOffset = +4.50; - booster.setAxialOffset(Position.TOP, targetOffset); - String treeDump = rocket.toDebugTree(); - - double expectedRelativePositionX = targetOffset; - Coordinate resultantRelativePosition = booster.getOffset(); - assertThat(" 'setAxialPosition(double)' failed: \n" + treeDump + " Relative position: ", resultantRelativePosition.x, equalTo(expectedRelativePositionX)); + double targetOffset = 0.2; // vv function under test - double resultantAxialPosition = booster.asPositionValue(Position.ABSOLUTE); + boosterStage.setAxialOffset(Position.TOP, targetOffset); // ^^ function under test - double expectedAbsoluteX = 9.5; - assertThat(" 'setPositionValue()' failed: \n" + treeDump + " asPositionValue: ", resultantAxialPosition, equalTo(expectedAbsoluteX)); + Assert.assertEquals( targetOffset, boosterStage.getAxialOffset(), EPSILON ); + Assert.assertEquals( 0.2, boosterStage.getOffset().x, EPSILON ); + + final double expectedRelativePositionX = targetOffset; + final double resultantRelativePosition = boosterStage.getOffset().x; + Assert.assertEquals(expectedRelativePositionX, resultantRelativePosition, EPSILON); + + // vv function under test + final double actualAbsoluteX = boosterStage.asPositionValue(Position.ABSOLUTE); + // ^^ function under test + + Assert.assertEquals( 0.764, actualAbsoluteX, EPSILON ); } @Test - public void testAxial_setTOP_getAFTER() { - // setup - RocketComponent rocket = createTestRocket(); - AxialStage core = (AxialStage) rocket.getChild(1); - ParallelStage booster = createBooster(); - core.addChild(booster); + public void testSetTOP_getAFTER() { + final RocketComponent rocket = TestRockets.makeFalcon9Heavy(); + final AxialStage coreStage = (AxialStage) rocket.getChild(1); + final ParallelStage boosterStage = (ParallelStage)coreStage.getChild(0).getChild(1); - double targetOffset = +4.50; - booster.setAxialOffset(Position.TOP, targetOffset); - String treeDump = rocket.toDebugTree(); - - double expectedRelativeX = targetOffset; - double resultantX = booster.getOffset().x; - assertThat(" 'setAxialPosition(double)' failed: \n" + treeDump + " Relative position: ", resultantX, equalTo(expectedRelativeX)); + double targetOffset = 0.2; // vv function under test - resultantX = booster.asPositionValue(Position.AFTER); + boosterStage.setAxialOffset(Position.TOP, targetOffset); // ^^ function under test - double expectedAfterX = -1.5; - assertEquals(" 'setPositionValue()' failed: \n" + treeDump + " asPosition: ", expectedAfterX, resultantX, EPSILON); + Assert.assertEquals( targetOffset, boosterStage.getAxialOffset(), EPSILON ); + Assert.assertEquals( 0.2, boosterStage.getOffset().x, EPSILON ); + + + // vv function under test + double actualPositionXAfter = boosterStage.asPositionValue(Position.AFTER); + // ^^ function under test + + Assert.assertEquals( -0.6, actualPositionXAfter, EPSILON ); } @Test - public void testAxial_setTOP_getMIDDLE() { - // setup - RocketComponent rocket = createTestRocket(); - AxialStage core = (AxialStage) rocket.getChild(1); - ParallelStage booster = createBooster(); - core.addChild(booster); + public void testSetTOP_getMIDDLE() { + final RocketComponent rocket = TestRockets.makeFalcon9Heavy(); + final AxialStage coreStage = (AxialStage) rocket.getChild(1); + final ParallelStage boosterStage = (ParallelStage)coreStage.getChild(0).getChild(1); - double targetOffset = +4.50; - booster.setAxialOffset(Position.TOP, targetOffset); - String treeDump = rocket.toDebugTree(); + double targetOffset = 0.2; - double expectedRelativeX = targetOffset; - double resultantX = booster.getOffset().x; - assertThat(" 'setAxialPosition(double)' failed: \n" + treeDump + " Relative position: ", resultantX, equalTo(expectedRelativeX)); - - double resultantAxialPosition; - double expectedAxialPosition = +4.0; // vv function under test - resultantAxialPosition = booster.asPositionValue(Position.MIDDLE); + boosterStage.setAxialOffset(Position.TOP, targetOffset); // ^^ function under test - assertEquals(" 'setPositionValue()' failed: \n" + treeDump + " Relative position: ", expectedAxialPosition, resultantAxialPosition, EPSILON); + Assert.assertEquals( targetOffset, boosterStage.getAxialOffset(), EPSILON ); + Assert.assertEquals( 0.2, boosterStage.getOffset().x, EPSILON ); + + // vv function under test + final double actualAxialPosition = boosterStage.asPositionValue(Position.MIDDLE); + // ^^ function under test + + Assert.assertEquals( 0.24, actualAxialPosition, EPSILON ); } @Test - public void testAxial_setTOP_getBOTTOM() { - // setup - RocketComponent rocket = createTestRocket(); - AxialStage core = (AxialStage) rocket.getChild(1); - ParallelStage booster = createBooster(); - core.addChild(booster); + public void testSetTOP_getBOTTOM() { + final RocketComponent rocket = TestRockets.makeFalcon9Heavy(); + final AxialStage coreStage = (AxialStage) rocket.getChild(1); + final ParallelStage boosterStage = (ParallelStage)coreStage.getChild(0).getChild(1); - - double targetOffset = +4.50; - booster.setAxialOffset(Position.TOP, targetOffset); - String treeDump = rocket.toDebugTree(); - - double expectedRelativeX = targetOffset; - double resultantX = booster.getOffset().x; - assertThat(" 'setAxialPosition(double)' failed: \n" + treeDump + " Relative position: ", resultantX, equalTo(expectedRelativeX)); + double targetOffset = 0.2; // vv function under test - double resultantAxialOffset = booster.asPositionValue(Position.BOTTOM); + boosterStage.setAxialOffset(Position.TOP, targetOffset); // ^^ function under test - double expectedAxialOffset = +3.5; - assertEquals(" 'setPositionValue()' failed: \n" + treeDump + " Relative position: ", expectedAxialOffset, resultantAxialOffset, EPSILON); + + Assert.assertEquals( targetOffset, boosterStage.getAxialOffset(), EPSILON ); + Assert.assertEquals( 0.2, boosterStage.getOffset().x, EPSILON ); + + // vv function under test + double actualAxialBottomOffset = boosterStage.asPositionValue(Position.BOTTOM); + // ^^ function under test + + Assert.assertEquals( 0.28, actualAxialBottomOffset, EPSILON ); } @Test - public void testAxial_setBOTTOM_getTOP() { - // setup - RocketComponent rocket = createTestRocket(); - AxialStage core = (AxialStage) rocket.getChild(1); - ParallelStage booster = createBooster(); - core.addChild(booster); - - double targetOffset = +4.50; - booster.setAxialOffset(Position.BOTTOM, targetOffset); - String treeDump = rocket.toDebugTree(); - - double expectedRelativeX = +5.5; - double resultantX = booster.getOffset().x; - assertEquals(" 'setAxialPosition(double)' failed: \n" + treeDump + " Relative position: ", expectedRelativeX, resultantX, EPSILON); + public void testSetBOTTOM_getTOP() { + final RocketComponent rocket = TestRockets.makeFalcon9Heavy(); + final ParallelStage boosterStage = (ParallelStage)rocket.getChild(1).getChild(0).getChild(1); // vv function under test - double resultantAxialOffset = booster.asPositionValue(Position.TOP); + double targetOffset = 0.2; + boosterStage.setAxialOffset(Position.BOTTOM, targetOffset); // ^^ function under test - double expectedAxialOffset = expectedRelativeX; - assertEquals(" 'setPositionValue()' failed: \n" + treeDump + " Relative position: ", expectedAxialOffset, resultantAxialOffset, EPSILON); + + Assert.assertEquals( targetOffset, boosterStage.getAxialOffset(), EPSILON); + Assert.assertEquals( 0.120, boosterStage.getOffset().x, EPSILON); + + // vv function under test + double actualAxialTopOffset = boosterStage.asPositionValue(Position.TOP); + // ^^ function under test + + Assert.assertEquals( 0.12, actualAxialTopOffset, EPSILON); } @Test public void testOutsideStageRepositionTOPAfterAdd() { - final double boosterRadius = 0.8; - Rocket rocket = createTestRocket(); - AxialStage core = (AxialStage) rocket.getChild(1); + final RocketComponent rocket = TestRockets.makeFalcon9Heavy(); + final AxialStage coreStage = (AxialStage) rocket.getChild(1); + final ParallelStage boosterStage = (ParallelStage)coreStage.getChild(0).getChild(1); - ParallelStage booster = new ParallelStage(); - booster.setName("Booster Stage"); - core.addChild(booster); final double targetOffset = +2.50; final Position targetMethod = Position.TOP; - booster.setAxialOffset(targetMethod, targetOffset); + boosterStage.setAxialOffset(targetMethod, targetOffset); String treeDumpBefore = rocket.toDebugTree(); // requirement: regardless of initialization order (which we cannot control) // a booster should retain it's positioning method and offset while adding on children double expectedRelativeX = 2.5; - double resultantOffset = booster.getOffset().x; + double resultantOffset = boosterStage.getOffset().x; assertEquals(" init order error: Booster: " + treeDumpBefore + " initial relative X: ", expectedRelativeX, resultantOffset, EPSILON); double expectedAxialOffset = targetOffset; - resultantOffset = booster.getAxialOffset(); + resultantOffset = boosterStage.getAxialOffset(); assertEquals(" init order error: Booster: " + treeDumpBefore + " Initial axial offset: ", expectedAxialOffset, resultantOffset, EPSILON); - - // Body Component 2 - RocketComponent boosterBody = new BodyTube(4.0, boosterRadius, 0.01); - boosterBody.setName("Booster Body "); - booster.addChild(boosterBody); - + String treeDumpAfter = rocket.toDebugTree(); expectedRelativeX = 2.5; // no change - resultantOffset = booster.getOffset().x; + resultantOffset = boosterStage.getOffset().x; assertEquals(" init order error: Booster: " + treeDumpBefore + " =======> " + treeDumpAfter + " populated relative X: ", expectedRelativeX, resultantOffset, EPSILON); expectedAxialOffset = targetOffset; // again, no change - resultantOffset = booster.getAxialOffset(); + resultantOffset = boosterStage.getAxialOffset(); assertEquals(" init order error: Booster: " + treeDumpBefore + " =======> " + treeDumpAfter + " populated axial offset: ", expectedAxialOffset, resultantOffset, EPSILON); } @Test public void testStageInitializationMethodValueOrder() { - Rocket rocket = createTestRocket(); - AxialStage core = (AxialStage) rocket.getChild(1); + final RocketComponent rocket = TestRockets.makeFalcon9Heavy(); + final BodyTube coreBody = (BodyTube) rocket.getChild(1).getChild(0); + ParallelStage boosterA = createBooster(); boosterA.setName("Booster A Stage"); - core.addChild(boosterA); + coreBody.addChild(boosterA); ParallelStage boosterB = createBooster(); boosterB.setName("Booster B Stage"); - core.addChild(boosterB); + coreBody.addChild(boosterB); double targetOffset = +4.5; double expectedOffset = +4.5; @@ -739,90 +642,101 @@ public class ParallelStageTest extends BaseTestCase { @Test public void testStageNumbering() { - Rocket rocket = createTestRocket(); - AxialStage sustainer = (AxialStage) rocket.getChild(0); - AxialStage core = (AxialStage) rocket.getChild(1); - ParallelStage boosterA = createBooster(); - boosterA.setName("Booster A Stage"); - core.addChild(boosterA); - boosterA.setAxialOffset(Position.BOTTOM, 0.0); + final Rocket rocket = TestRockets.makeFalcon9Heavy(); + final FlightConfiguration config = rocket.getSelectedConfiguration(); + final AxialStage payloadStage = (AxialStage) rocket.getChild(0); + final AxialStage coreStage = (AxialStage) rocket.getChild(1); + final BodyTube coreBody = (BodyTube) coreStage.getChild(0); + + ParallelStage boosterA = (ParallelStage)coreBody.getChild(1); + ParallelStage boosterB = createBooster(); - boosterB.setName("Booster B Stage"); - core.addChild(boosterB); - boosterB.setAxialOffset(Position.BOTTOM, 0); + boosterB.setName("Booster A Stage"); + coreBody.addChild(boosterB); + boosterB.setAxialOffset(Position.BOTTOM, 0.0); + + ParallelStage boosterC = createBooster(); + boosterC.setName("Booster B Stage"); + coreBody.addChild(boosterC); + boosterC.setAxialOffset(Position.BOTTOM, 0); int expectedStageNumber = 0; - int actualStageNumber = sustainer.getStageNumber(); + int actualStageNumber = payloadStage.getStageNumber(); assertEquals(" init order error: sustainer: resultant positions: ", expectedStageNumber, actualStageNumber); expectedStageNumber = 1; - actualStageNumber = core.getStageNumber(); + actualStageNumber = coreStage.getStageNumber(); assertEquals(" init order error: core: resultant positions: ", expectedStageNumber, actualStageNumber); - + expectedStageNumber = 2; actualStageNumber = boosterA.getStageNumber(); - assertEquals(" init order error: Booster A: resultant positions: ", expectedStageNumber, actualStageNumber); - + assertEquals(" init order error: core: resultant positions: ", expectedStageNumber, actualStageNumber); + expectedStageNumber = 3; actualStageNumber = boosterB.getStageNumber(); + assertEquals(" init order error: Booster A: resultant positions: ", expectedStageNumber, actualStageNumber); + + expectedStageNumber = 4; + actualStageNumber = boosterC.getStageNumber(); assertEquals(" init order error: Booster B: resultant positions: ", expectedStageNumber, actualStageNumber); // remove Booster A - core.removeChild(2); + coreBody.removeChild(2); String treedump = rocket.toDebugTree(); - int expectedStageCount = 3; - int actualStageCount = rocket.getStageCount(); + int expectedStageCount = 4; + int actualStageCount = config.getStageCount(); assertEquals(" Stage tracking error: removed booster A, but count not updated: " + treedump, expectedStageCount, actualStageCount); actualStageCount = rocket.getSelectedConfiguration().getStageCount(); assertEquals(" Stage tracking error: removed booster A, but configuration not updated: " + treedump, expectedStageCount, actualStageCount); - ParallelStage boosterC = createBooster(); - boosterC.setName("Booster C Stage"); - core.addChild(boosterC); + ParallelStage boosterD = createBooster(); + boosterC.setName("Booster D Stage"); + coreBody.addChild(boosterD); boosterC.setAxialOffset(Position.BOTTOM, 0); - expectedStageNumber = 2; - actualStageNumber = boosterC.getStageNumber(); - assertEquals(" init order error: Booster B: resultant positions: ", expectedStageNumber, actualStageNumber); + expectedStageNumber = 3; + actualStageNumber = boosterD.getStageNumber(); + assertEquals(" init order error: Booster D: resultant positions: ", expectedStageNumber, actualStageNumber); //rocket.getDefaultConfiguration().dumpConfig(); } @Test public void testToAbsolute() { - Rocket rocket = createTestRocket(); - AxialStage core = (AxialStage) rocket.getChild(1); + final RocketComponent rocket = TestRockets.makeFalcon9Heavy(); + final AxialStage coreStage = (AxialStage) rocket.getChild(1); String treeDump = rocket.toDebugTree(); Coordinate input = new Coordinate(3, 0, 0); - Coordinate[] actual = core.toAbsolute(input); + Coordinate[] actual = coreStage.toAbsolute(input); - double expectedX = 8; + double expectedX = 3.564; assertEquals(treeDump + " coordinate transform through 'core.toAbsolute(c)' failed: ", expectedX, actual[0].x, EPSILON); } @Test public void testToRelative() { - Rocket rocket = createTestRocket(); - AxialStage core = (AxialStage) rocket.getChild(1); - RocketComponent ubody = core.getChild(0); - RocketComponent lbody = core.getChild(1); + final RocketComponent rocket = TestRockets.makeFalcon9Heavy(); + final AxialStage payloadStage = (AxialStage) rocket.getChild(0); + + RocketComponent payloadNose = payloadStage.getChild(1); + RocketComponent payloadBody = payloadStage.getChild(3); String treeDump = rocket.toDebugTree(); Coordinate input = new Coordinate(1, 0, 0); - Coordinate actual = core.toAbsolute(input)[0]; + Coordinate actual = payloadStage.toAbsolute(input)[0]; - double expectedX = 6; + double expectedX = 1.0; assertEquals(treeDump + " coordinate transform through 'core.toAbsolute(c)' failed: ", expectedX, actual.x, EPSILON); input = new Coordinate(1, 0, 0); - actual = ubody.toRelative(input, lbody)[0]; + actual = payloadNose.toRelative(input, payloadBody)[0]; - expectedX = -0.8; + expectedX = 0.853999; assertEquals(treeDump + " coordinate transform through 'core.toAbsolute(c)' failed: ", expectedX, actual.x, EPSILON); diff --git a/swing/resources/datafiles/examples/Parallel Staging Example.ork b/swing/resources/datafiles/examples/Parallel Staging Example.ork index 6aa38087b..005988191 100644 Binary files a/swing/resources/datafiles/examples/Parallel Staging Example.ork and b/swing/resources/datafiles/examples/Parallel Staging Example.ork differ diff --git a/swing/resources/datafiles/examples/Pods Example.ork b/swing/resources/datafiles/examples/Pods Example.ork index 08eac01dd..e8192d108 100644 Binary files a/swing/resources/datafiles/examples/Pods Example.ork and b/swing/resources/datafiles/examples/Pods Example.ork differ