diff --git a/core/src/net/sf/openrocket/database/motor/ThrustCurveMotorSet.java b/core/src/net/sf/openrocket/database/motor/ThrustCurveMotorSet.java index c15452ae3..ed77d3a47 100644 --- a/core/src/net/sf/openrocket/database/motor/ThrustCurveMotorSet.java +++ b/core/src/net/sf/openrocket/database/motor/ThrustCurveMotorSet.java @@ -74,8 +74,8 @@ public class ThrustCurveMotorSet implements Comparable { type = motor.getMotorType(); // Add "Plugged" option if hybrid if (type == Motor.Type.HYBRID) { - if (!delays.contains(Motor.PLUGGED)) { - delays.add(Motor.PLUGGED); + if (!delays.contains(Motor.PLUGGED_DELAY)) { + delays.add(Motor.PLUGGED_DELAY); } } } diff --git a/core/src/net/sf/openrocket/file/motor/RASPMotorLoader.java b/core/src/net/sf/openrocket/file/motor/RASPMotorLoader.java index 637aefae1..2b776f3fd 100644 --- a/core/src/net/sf/openrocket/file/motor/RASPMotorLoader.java +++ b/core/src/net/sf/openrocket/file/motor/RASPMotorLoader.java @@ -108,7 +108,7 @@ public class RASPMotorLoader extends AbstractMotorLoader { for (int i = 0; i < buf.length; i++) { if (buf[i].equalsIgnoreCase("P") || buf[i].equalsIgnoreCase("plugged")) { - delays.add(Motor.PLUGGED); + delays.add(Motor.PLUGGED_DELAY); } else if (buf[i].matches("[0-9]+")) { // Many RASP files have "100" as an only delay double d = Double.parseDouble(buf[i]); diff --git a/core/src/net/sf/openrocket/file/motor/RockSimMotorLoader.java b/core/src/net/sf/openrocket/file/motor/RockSimMotorLoader.java index 838e2d8fa..1e2dddc5c 100644 --- a/core/src/net/sf/openrocket/file/motor/RockSimMotorLoader.java +++ b/core/src/net/sf/openrocket/file/motor/RockSimMotorLoader.java @@ -173,12 +173,12 @@ public class RockSimMotorLoader extends AbstractMotorLoader { double d = Double.parseDouble(delay); if (d >= DELAY_LIMIT) - d = Motor.PLUGGED; + d = Motor.PLUGGED_DELAY; delayList.add(d); } catch (NumberFormatException e) { if (str.equalsIgnoreCase("P") || str.equalsIgnoreCase("plugged")) { - delayList.add(Motor.PLUGGED); + delayList.add(Motor.PLUGGED_DELAY); } } } diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/IgnitionConfigurationHandler.java b/core/src/net/sf/openrocket/file/openrocket/importt/IgnitionConfigurationHandler.java index e05248d7d..10d5c6b1a 100644 --- a/core/src/net/sf/openrocket/file/openrocket/importt/IgnitionConfigurationHandler.java +++ b/core/src/net/sf/openrocket/file/openrocket/importt/IgnitionConfigurationHandler.java @@ -10,7 +10,7 @@ import net.sf.openrocket.file.DocumentLoadingContext; import net.sf.openrocket.file.simplesax.AbstractElementHandler; import net.sf.openrocket.file.simplesax.ElementHandler; import net.sf.openrocket.file.simplesax.PlainTextHandler; -import net.sf.openrocket.rocketcomponent.IgnitionEvent; +import net.sf.openrocket.motor.IgnitionEvent; class IgnitionConfigurationHandler extends AbstractElementHandler { diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/MotorHandler.java b/core/src/net/sf/openrocket/file/openrocket/importt/MotorHandler.java index dccd1fb89..e11247c3e 100644 --- a/core/src/net/sf/openrocket/file/openrocket/importt/MotorHandler.java +++ b/core/src/net/sf/openrocket/file/openrocket/importt/MotorHandler.java @@ -51,7 +51,7 @@ class MotorHandler extends AbstractElementHandler { public double getDelay(WarningSet warnings) { if (Double.isNaN(delay)) { warnings.add(Warning.fromString("Motor delay not specified, assuming no ejection charge.")); - return Motor.PLUGGED; + return Motor.PLUGGED_DELAY; } return delay; } @@ -124,7 +124,7 @@ class MotorHandler extends AbstractElementHandler { // Delay delay = Double.NaN; if (content.equals("none")) { - delay = Motor.PLUGGED; + delay = Motor.PLUGGED_DELAY; } else { try { delay = Double.parseDouble(content.trim()); diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/MotorMountHandler.java b/core/src/net/sf/openrocket/file/openrocket/importt/MotorMountHandler.java index 581c74d4e..ddbe59fea 100644 --- a/core/src/net/sf/openrocket/file/openrocket/importt/MotorMountHandler.java +++ b/core/src/net/sf/openrocket/file/openrocket/importt/MotorMountHandler.java @@ -10,11 +10,10 @@ import net.sf.openrocket.file.DocumentLoadingContext; import net.sf.openrocket.file.simplesax.AbstractElementHandler; import net.sf.openrocket.file.simplesax.ElementHandler; import net.sf.openrocket.file.simplesax.PlainTextHandler; +import net.sf.openrocket.motor.IgnitionEvent; import net.sf.openrocket.motor.Motor; import net.sf.openrocket.motor.MotorConfiguration; -import net.sf.openrocket.motor.MotorInstanceId; import net.sf.openrocket.rocketcomponent.FlightConfigurationId; -import net.sf.openrocket.rocketcomponent.IgnitionEvent; import net.sf.openrocket.rocketcomponent.MotorMount; import net.sf.openrocket.rocketcomponent.Rocket; import net.sf.openrocket.rocketcomponent.RocketComponent; @@ -72,19 +71,15 @@ class MotorMountHandler extends AbstractElementHandler { return; } Motor motor = motorHandler.getMotor(warnings); + MotorConfiguration motorConfig = new MotorConfiguration( mount, fcid); + motorConfig.setMotor(motor); + motorConfig.setEjectionDelay(motorHandler.getDelay(warnings)); - MotorConfiguration motorInstance = new MotorConfiguration(); - motorInstance.setMotor(motor); - RocketComponent mountComponent = (RocketComponent)mount; - motorInstance.setMount(mount); - motorInstance.setID( new MotorInstanceId(mountComponent.getID(), 1)); - motorInstance.setEjectionDelay(motorHandler.getDelay(warnings)); - - mount.setMotorInstance(fcid, motorInstance); + mount.setMotorConfig( motorConfig, fcid); Rocket rkt = ((RocketComponent)mount).getRocket(); rkt.createFlightConfiguration(fcid); - rkt.getFlightConfiguration(fcid).addMotor(motorInstance); + rkt.getFlightConfiguration(fcid).addMotor(motorConfig); return; } diff --git a/core/src/net/sf/openrocket/file/openrocket/savers/RocketComponentSaver.java b/core/src/net/sf/openrocket/file/openrocket/savers/RocketComponentSaver.java index 7ba91df78..3c79edf13 100644 --- a/core/src/net/sf/openrocket/file/openrocket/savers/RocketComponentSaver.java +++ b/core/src/net/sf/openrocket/file/openrocket/savers/RocketComponentSaver.java @@ -214,7 +214,7 @@ public class RocketComponentSaver { elements.add(" " + motor.getLength() + ""); // Motor delay - if (motorInstance.getEjectionDelay() == Motor.PLUGGED) { + if (motorInstance.getEjectionDelay() == Motor.PLUGGED_DELAY) { elements.add(" none"); } else { elements.add(" " + motorInstance.getEjectionDelay() + ""); diff --git a/core/src/net/sf/openrocket/rocketcomponent/IgnitionEvent.java b/core/src/net/sf/openrocket/motor/IgnitionEvent.java similarity index 56% rename from core/src/net/sf/openrocket/rocketcomponent/IgnitionEvent.java rename to core/src/net/sf/openrocket/motor/IgnitionEvent.java index 789e3c52c..da9859fcf 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/IgnitionEvent.java +++ b/core/src/net/sf/openrocket/motor/IgnitionEvent.java @@ -1,8 +1,10 @@ -package net.sf.openrocket.rocketcomponent; +package net.sf.openrocket.motor; import java.util.Locale; import net.sf.openrocket.l10n.Translator; +import net.sf.openrocket.rocketcomponent.AxialStage; +import net.sf.openrocket.rocketcomponent.RocketComponent; import net.sf.openrocket.simulation.FlightEvent; import net.sf.openrocket.startup.Application; @@ -11,18 +13,13 @@ public enum IgnitionEvent { //// Automatic (launch or ejection charge) AUTOMATIC( "AUTOMATIC", "MotorMount.IgnitionEvent.AUTOMATIC"){ @Override - public boolean isActivationEvent(FlightEvent e, RocketComponent source) { - int count = source.getRocket().getStageCount(); - AxialStage stage = (AxialStage)source.getStage(); - - if ( stage instanceof ParallelStage ){ - return LAUNCH.isActivationEvent(e, source); - }else if (stage.getStageNumber() == count -1){ - // no good option here. The non-sequential nature of - // parallel stages prevents us from using the simple test as previousyl - return LAUNCH.isActivationEvent(e, source); - } else { - return EJECTION_CHARGE.isActivationEvent(e, source); + public boolean isActivationEvent(FlightEvent testEvent, RocketComponent targetComponent) { + AxialStage targetStage = (AxialStage)targetComponent.getStage(); + + if ( targetStage.isLaunchStage() ){ + return LAUNCH.isActivationEvent(testEvent, targetComponent); + } else { + return EJECTION_CHARGE.isActivationEvent(testEvent, targetComponent); } } }, @@ -34,24 +31,27 @@ public enum IgnitionEvent { }, EJECTION_CHARGE ("EJECTION_CHARGE", "MotorMount.IgnitionEvent.EJECTION_CHARGE"){ @Override - public boolean isActivationEvent( FlightEvent fe, RocketComponent source){ - if (fe.getType() != FlightEvent.Type.EJECTION_CHARGE){ + public boolean isActivationEvent( FlightEvent testEvent, RocketComponent targetComponent){ + if (testEvent.getType() != FlightEvent.Type.EJECTION_CHARGE){ return false; } - int charge = fe.getSource().getStageNumber(); - int mount = source.getStageNumber(); - return (mount + 1 == charge); + + AxialStage targetStage = (AxialStage)targetComponent.getStage(); + AxialStage eventStage = (AxialStage)testEvent.getSource().getStage(); + AxialStage eventParentStage = eventStage.getPreviousStage(); + return ( targetStage.equals(eventParentStage)); } }, BURNOUT ("BURNOUT", "MotorMount.IgnitionEvent.BURNOUT"){ @Override - public boolean isActivationEvent( FlightEvent fe, RocketComponent source){ - if (fe.getType() != FlightEvent.Type.BURNOUT) + public boolean isActivationEvent( FlightEvent testEvent, RocketComponent targetComponent){ + if (testEvent.getType() != FlightEvent.Type.BURNOUT) return false; - int charge = fe.getSource().getStageNumber(); - int mount = source.getStageNumber(); - return (mount + 1 == charge); + AxialStage targetStage = (AxialStage)targetComponent.getStage(); + AxialStage eventStage = (AxialStage)testEvent.getSource().getStage(); + AxialStage eventParentStage = eventStage.getPreviousStage(); + return ( targetStage.equals(eventParentStage)); } }, NEVER("NEVER", "MotorMount.IgnitionEvent.NEVER") diff --git a/core/src/net/sf/openrocket/motor/Motor.java b/core/src/net/sf/openrocket/motor/Motor.java index 5ff556a36..631272cba 100644 --- a/core/src/net/sf/openrocket/motor/Motor.java +++ b/core/src/net/sf/openrocket/motor/Motor.java @@ -50,7 +50,7 @@ public interface Motor extends Cloneable { * Ejection charge delay value signifying a "plugged" motor with no ejection charge. * The value is that of Double.POSITIVE_INFINITY. */ - public static final double PLUGGED = Double.POSITIVE_INFINITY; + public static final double PLUGGED_DELAY = Double.POSITIVE_INFINITY; /** diff --git a/core/src/net/sf/openrocket/motor/MotorConfiguration.java b/core/src/net/sf/openrocket/motor/MotorConfiguration.java index 217a216df..9f0ca7c94 100644 --- a/core/src/net/sf/openrocket/motor/MotorConfiguration.java +++ b/core/src/net/sf/openrocket/motor/MotorConfiguration.java @@ -1,7 +1,7 @@ package net.sf.openrocket.motor; import net.sf.openrocket.rocketcomponent.FlightConfigurableParameter; -import net.sf.openrocket.rocketcomponent.IgnitionEvent; +import net.sf.openrocket.rocketcomponent.FlightConfigurationId; import net.sf.openrocket.rocketcomponent.MotorMount; import net.sf.openrocket.rocketcomponent.RocketComponent; import net.sf.openrocket.util.Coordinate; @@ -15,26 +15,25 @@ public class MotorConfiguration implements FlightConfigurableParameter { public static final int DEFAULT_MOTOR_EVENT_TYPE = ComponentChangeEvent.MOTOR_CHANGE | ComponentChangeEvent.EVENT_CHANGE; - public MotorConfigurationSet(RocketComponent component ) { - super( new MotorConfiguration()); + public MotorConfigurationSet(final MotorMount mount ) { + super( new MotorConfiguration( mount, FlightConfigurationId.DEFAULT_VALUE_FCID )); } /** diff --git a/core/src/net/sf/openrocket/motor/MotorInstanceId.java b/core/src/net/sf/openrocket/motor/MotorInstanceId.java index d9fda9861..810467002 100644 --- a/core/src/net/sf/openrocket/motor/MotorInstanceId.java +++ b/core/src/net/sf/openrocket/motor/MotorInstanceId.java @@ -1,5 +1,10 @@ package net.sf.openrocket.motor; +import java.util.UUID; + +import net.sf.openrocket.rocketcomponent.FlightConfigurationId; +import net.sf.openrocket.rocketcomponent.MotorMount; + /** * An immutable identifier for a motor instance in a MotorInstanceConfiguration. * The motor is identified by the ID of its mounting component and a @@ -9,84 +14,63 @@ package net.sf.openrocket.motor; */ public final class MotorInstanceId { - private final String componentId; - private final int number; + private final String name ; + private final UUID key; - private final static String ERROR_COMPONENT_TEXT = "Error Motor Id"; - private final static int ERROR_NUMBER = 1; - public final static MotorInstanceId ERROR_ID = new MotorInstanceId(ERROR_COMPONENT_TEXT, ERROR_NUMBER); - private final static String EMPTY_COMPONENT_TEXT = "Empty Motor Id"; - private final static int EMPTY_NUMBER = 1; - public final static MotorInstanceId EMPTY_ID = new MotorInstanceId(EMPTY_COMPONENT_TEXT, EMPTY_NUMBER); + private final static String ERROR_ID_TEXT = "MotorInstance Error Id"; + private final static UUID ERROR_KEY = new UUID( 6227, 5676); + public final static MotorInstanceId ERROR_ID = new MotorInstanceId(); + + private MotorInstanceId( ) { + this.name = MotorInstanceId.ERROR_ID_TEXT; + this.key = MotorInstanceId.ERROR_KEY; + } /** * Sole constructor. * - * @param componentId the component ID, must not be null + * @param componentName the component ID, must not be null * @param number a positive motor number */ - public MotorInstanceId(String componentId, int number) { - - if (componentId == null) { - throw new IllegalArgumentException("Component ID was null"); + public MotorInstanceId(final MotorMount _mount, final FlightConfigurationId _fcid ) { + if (null == _mount ) { + throw new IllegalArgumentException("Provided MotorConfiguration was null"); } - if (number <= 0) { - throw new IllegalArgumentException("Number must be positive, n=" + number); + if (null == _fcid ) { + throw new IllegalArgumentException("Provided MotorConfiguration was null"); } // Use intern so comparison can be done using == instead of equals() - this.componentId = componentId.intern(); - this.number = number; + this.name = _mount.getID()+"-"+_fcid.toShortKey(); + final long upper = _mount.getID().hashCode() << 32; + final long lower = _fcid.key.getMostSignificantBits(); + this.key = new UUID( upper, lower); } - - - public String getComponentId() { - return componentId; - } - - public int getInstanceNumber() { - return number; - } - - + + @Override - public boolean equals(Object o) { - if (this == o) + public boolean equals(Object other) { + if (this == other) return true; - if (!(o instanceof MotorInstanceId)) + if (!(other instanceof MotorInstanceId)) return false; - - MotorInstanceId other = (MotorInstanceId) o; - // Comparison with == ok since string is intern()'ed - return this.componentId == other.componentId && this.number == other.number; + + MotorInstanceId otherId = (MotorInstanceId) other; + return ( this.key.equals( otherId.key)); } - @Override public int hashCode() { - return componentId.hashCode() + (number << 12); - } - - public String toShortKey(){ - if( this == ERROR_ID){ - return "ERROR_ID"; - }else if( this == EMPTY_ID){ - return "EMPTY_ID"; - }else{ - final String result = toString(); - return result.substring(0, Math.min(8, result.length())); - } + return key.hashCode(); } @Override public String toString(){ - if( this == ERROR_ID){ - return "ERROR_ID"; - }else if( this == EMPTY_ID){ - return "EMPTY_ID"; + if( this.key == MotorInstanceId.ERROR_KEY){ + return MotorInstanceId.ERROR_ID_TEXT; }else{ - return Integer.toString( this.hashCode()); + return name; } } } diff --git a/core/src/net/sf/openrocket/motor/ThrustCurveMotor.java b/core/src/net/sf/openrocket/motor/ThrustCurveMotor.java index 95299224e..9d581022c 100644 --- a/core/src/net/sf/openrocket/motor/ThrustCurveMotor.java +++ b/core/src/net/sf/openrocket/motor/ThrustCurveMotor.java @@ -579,7 +579,7 @@ public class ThrustCurveMotor implements Motor, Comparable, Se ////////// Static methods /** - * Return a String representation of a delay time. If the delay is {@link #PLUGGED}, + * Return a String representation of a delay time. If the delay is {@link #PLUGGED_DELAY}, * returns "P". * * @param delay the delay time. @@ -590,7 +590,7 @@ public class ThrustCurveMotor implements Motor, Comparable, Se } /** - * Return a String representation of a delay time. If the delay is {@link #PLUGGED}, + * Return a String representation of a delay time. If the delay is {@link #PLUGGED_DELAY}, * plugged is returned. * * @param delay the delay time. @@ -598,7 +598,7 @@ public class ThrustCurveMotor implements Motor, Comparable, Se * @return the String representation. */ public static String getDelayString(double delay, String plugged) { - if (delay == PLUGGED) + if (delay == PLUGGED_DELAY) return plugged; delay = Math.rint(delay * 10) / 10; if (MathUtil.equals(delay, Math.rint(delay))) diff --git a/core/src/net/sf/openrocket/rocketcomponent/AxialStage.java b/core/src/net/sf/openrocket/rocketcomponent/AxialStage.java index 76e5e9df5..1893a2ac1 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/AxialStage.java +++ b/core/src/net/sf/openrocket/rocketcomponent/AxialStage.java @@ -117,7 +117,8 @@ public class AxialStage extends ComponentAssembly implements FlightConfigurableC } public boolean isLaunchStage(){ - return ( getRocket().getBottomCoreStage().equals(this)); + return ( this instanceof ParallelStage ) + ||( getRocket().getBottomCoreStage().equals(this)); } public void setStageNumber(final int newStageNumber) { @@ -143,6 +144,20 @@ public class AxialStage extends ComponentAssembly implements FlightConfigurableC buff.append( this.separations.toDebug() ); return buff.toString(); } + + 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 ); + if( 0 < thisIndex ){ + return (AxialStage)thisStage.parent.getChild(thisIndex-1); + } + } + return null; + } diff --git a/core/src/net/sf/openrocket/rocketcomponent/BodyTube.java b/core/src/net/sf/openrocket/rocketcomponent/BodyTube.java index a09059be0..e83abb52f 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/BodyTube.java +++ b/core/src/net/sf/openrocket/rocketcomponent/BodyTube.java @@ -7,7 +7,6 @@ import java.util.Iterator; import net.sf.openrocket.l10n.Translator; import net.sf.openrocket.motor.Motor; import net.sf.openrocket.motor.MotorConfiguration; -import net.sf.openrocket.motor.MotorInstanceId; import net.sf.openrocket.motor.MotorConfigurationSet; import net.sf.openrocket.preset.ComponentPreset; import net.sf.openrocket.startup.Application; @@ -374,17 +373,15 @@ public class BodyTube extends SymmetricComponent implements MotorMount, Coaxial } @Override - public void setMotorInstance(final FlightConfigurationId fcid, final MotorConfiguration newMotorInstance){ - if((null == newMotorInstance)){ + public void setMotorConfig( final MotorConfiguration newMotorConfig, final FlightConfigurationId fcid){ + if(null == newMotorConfig){ this.motors.set( fcid, null); }else{ - if( null == newMotorInstance.getMount()){ - newMotorInstance.setMount(this); - }else if( !this.equals( newMotorInstance.getMount())){ - throw new BugException(" attempt to add a MotorInstance to a second mount, when it's already owned by another mount!"); + if( this != newMotorConfig.getMount() ){ + throw new BugException(" attempt to add a MotorConfig to a second mount! "); } - newMotorInstance.setID(new MotorInstanceId( this.getID(), 1)); - this.motors.set(fcid,newMotorInstance); + + this.motors.set(fcid,newMotorConfig); } this.isActingMount=true; diff --git a/core/src/net/sf/openrocket/rocketcomponent/FlightConfiguration.java b/core/src/net/sf/openrocket/rocketcomponent/FlightConfiguration.java index 00ee75a0d..a537c273c 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/FlightConfiguration.java +++ b/core/src/net/sf/openrocket/rocketcomponent/FlightConfiguration.java @@ -336,19 +336,19 @@ public class FlightConfiguration implements FlightConfigurableParameter { protected double ignitionDelay = 0.0; diff --git a/core/src/net/sf/openrocket/rocketcomponent/InnerTube.java b/core/src/net/sf/openrocket/rocketcomponent/InnerTube.java index 6b198ab80..3e3dc112b 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/InnerTube.java +++ b/core/src/net/sf/openrocket/rocketcomponent/InnerTube.java @@ -11,7 +11,6 @@ import net.sf.openrocket.l10n.Translator; import net.sf.openrocket.motor.Motor; import net.sf.openrocket.motor.MotorConfiguration; import net.sf.openrocket.motor.MotorConfigurationSet; -import net.sf.openrocket.motor.MotorInstanceId; import net.sf.openrocket.preset.ComponentPreset; import net.sf.openrocket.startup.Application; import net.sf.openrocket.util.BugException; @@ -282,16 +281,14 @@ public class InnerTube extends ThicknessRingComponent implements Clusterable, Ra } @Override - public void setMotorInstance(final FlightConfigurationId fcid, final MotorConfiguration newMotorConfig){ + public void setMotorConfig( final MotorConfiguration newMotorConfig, final FlightConfigurationId fcid){ if((null == newMotorConfig)){ this.motors.set( fcid, null); }else{ - if( null == newMotorConfig.getMount()){ - newMotorConfig.setMount(this); - }else if( !this.equals( newMotorConfig.getMount())){ - throw new BugException(" attempt to add a MotorInstance to a second mount, when it's already owned by another mount!"); + if( this != newMotorConfig.getMount() ){ + throw new BugException(" attempt to add a MotorConfig to a second mount!"); } - newMotorConfig.setID(new MotorInstanceId( this.getID(), 1)); + this.motors.set(fcid, newMotorConfig); } diff --git a/core/src/net/sf/openrocket/rocketcomponent/MotorMount.java b/core/src/net/sf/openrocket/rocketcomponent/MotorMount.java index d4fc59286..cc8b36f2f 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/MotorMount.java +++ b/core/src/net/sf/openrocket/rocketcomponent/MotorMount.java @@ -60,8 +60,14 @@ public interface MotorMount extends ChangeSource, FlightConfigurableComponent { * @return */ public double getLength(); - - + + // duplicate of RocketComponent + public String getID(); + public String getName(); + + // duplicate of RocketComponent + public AxialStage getStage(); + /** * * @param fcid id for which to return the motor (null retrieves the default) @@ -74,7 +80,7 @@ public interface MotorMount extends ChangeSource, FlightConfigurableComponent { * @param fcid index the supplied motor against this flight configuration * @param newMotorInstance motor instance to store */ - public void setMotorInstance(final FlightConfigurationId fcid, final MotorConfiguration newMotorInstance); + public void setMotorConfig( final MotorConfiguration newMotorConfig, final FlightConfigurationId fcid); /** * Get the number of motors available for all flight configurations diff --git a/core/src/net/sf/openrocket/rocketcomponent/Rocket.java b/core/src/net/sf/openrocket/rocketcomponent/Rocket.java index 437ebb4f1..ff80d6332 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/Rocket.java +++ b/core/src/net/sf/openrocket/rocketcomponent/Rocket.java @@ -817,11 +817,11 @@ public class Rocket extends RocketComponent { public String toDebugConfigs(){ StringBuilder buf = new StringBuilder(); buf.append(String.format("====== Dumping %d Configurations from rocket: \n", this.getConfigurationCount(), this.getName())); - final String fmt = " [%-12s]: %s\n"; + final String fmt = " [%12s]: %s\n"; for( FlightConfiguration config : this.configSet.values() ){ String shortKey = config.getId().toShortKey(); if( this.selectedConfiguration.equals( config)){ - shortKey = shortKey+"<="; + shortKey = "=>" + shortKey; } buf.append(String.format(fmt, shortKey, config.getName() )); } diff --git a/core/src/net/sf/openrocket/simulation/AbstractSimulationStepper.java b/core/src/net/sf/openrocket/simulation/AbstractSimulationStepper.java index 5031b1720..8d041d66c 100644 --- a/core/src/net/sf/openrocket/simulation/AbstractSimulationStepper.java +++ b/core/src/net/sf/openrocket/simulation/AbstractSimulationStepper.java @@ -170,12 +170,8 @@ public abstract class AbstractSimulationStepper implements SimulationStepper { thrust = 0; final double currentTime = status.getSimulationTime() + timestep; - Collection activeMotorList = status.getMotors(); - for (MotorSimulation currentMotorState : activeMotorList ) { - if ( !stepMotors ) { - currentMotorState = currentMotorState.clone(); - } - + Collection activeMotorList = status.getMotors(); + for (MotorClusterState currentMotorState : activeMotorList ) { thrust += currentMotorState.getThrust( currentTime, atmosphericConditions ); } diff --git a/core/src/net/sf/openrocket/simulation/BasicEventSimulationEngine.java b/core/src/net/sf/openrocket/simulation/BasicEventSimulationEngine.java index be63f9628..a9009411b 100644 --- a/core/src/net/sf/openrocket/simulation/BasicEventSimulationEngine.java +++ b/core/src/net/sf/openrocket/simulation/BasicEventSimulationEngine.java @@ -9,14 +9,12 @@ import org.slf4j.LoggerFactory; import net.sf.openrocket.aerodynamics.Warning; import net.sf.openrocket.l10n.Translator; -import net.sf.openrocket.motor.Motor; import net.sf.openrocket.motor.MotorConfiguration; import net.sf.openrocket.motor.MotorInstanceId; import net.sf.openrocket.rocketcomponent.AxialStage; import net.sf.openrocket.rocketcomponent.DeploymentConfiguration; import net.sf.openrocket.rocketcomponent.FlightConfiguration; import net.sf.openrocket.rocketcomponent.FlightConfigurationId; -import net.sf.openrocket.rocketcomponent.IgnitionEvent; import net.sf.openrocket.rocketcomponent.MotorMount; import net.sf.openrocket.rocketcomponent.RecoveryDevice; import net.sf.openrocket.rocketcomponent.RocketComponent; @@ -194,17 +192,10 @@ public class BasicEventSimulationEngine implements SimulationEngine { // Check for burnt out motors - for( MotorSimulation state : currentStatus.getAllMotors()){ - - state.isFinishedThrusting( ); - - MotorInstanceId motorId = state.getID(); - + for( MotorClusterState state : currentStatus.getMotors()){ + //state.update( currentStatus.getSimulationTime() ); if ( state.isFinishedThrusting()){ - // TODO : implement me! - //currentStatus.moveBurntOutMotor( motorId); - currentStatus.addBurntOutMotor(motorId); - + MotorInstanceId motorId = state.getID(); addEvent(new FlightEvent(FlightEvent.Type.BURNOUT, currentStatus.getSimulationTime(), (RocketComponent) state.getMount(), motorId)); } @@ -276,18 +267,6 @@ public class BasicEventSimulationEngine implements SimulationEngine { continue; } - if (event.getType() != FlightEvent.Type.ALTITUDE) { - log.trace("BasicEventSimulationEngine: Handling event " + event); - } - - if (event.getType() == FlightEvent.Type.IGNITION) { - MotorMount mount = (MotorMount) event.getSource(); - MotorInstanceId motorId = (MotorInstanceId) event.getData(); - MotorSimulation instance = currentStatus.getMotor(motorId); - if (!SimulationListenerHelper.fireMotorIgnition(currentStatus, motorId, mount, instance)) { - continue; - } - } if (event.getType() == FlightEvent.Type.RECOVERY_DEVICE_DEPLOYMENT) { RecoveryDevice device = (RecoveryDevice) event.getSource(); if (!SimulationListenerHelper.fireRecoveryDeviceDeployment(currentStatus, device)) { @@ -295,19 +274,33 @@ public class BasicEventSimulationEngine implements SimulationEngine { } } +// // DEBUG: +// if(( event.getType() == FlightEvent.Type.BURNOUT)|| ( event.getType() == FlightEvent.Type.EJECTION_CHARGE)){ +// System.err.println("@simulationTime: "+currentStatus.getSimulationTime()); +// System.err.println(" Processing "+event.getType().name()+" @"+event.getTime()+" from: "+event.getSource().getName()); +// MotorClusterState eventState = (MotorClusterState) event.getData(); +// System.err.println(" and motor: "+eventState.getMotor().getDesignation()+" in:"+eventState.getMount().getName() +// +" @: "+eventState.getEjectionDelay()); +// } // Check for motor ignition events, add ignition events to queue - for (MotorSimulation inst : currentStatus.getAllMotors() ){ - IgnitionEvent ignitionEvent = inst.getIgnitionEvent(); - MotorMount mount = inst.getMount(); - RocketComponent component = (RocketComponent) mount; - - if (ignitionEvent.isActivationEvent(event, component)) { - double ignitionDelay = inst.getIgnitionDelay(); - // TODO: this event seems to get enque'd multiple times -- more than necessary... - //System.err.println("Queueing ignition of mtr:"+inst.getMotor().getDesignation()+" @"+currentStatus.getSimulationTime()); - addEvent(new FlightEvent(FlightEvent.Type.IGNITION, - currentStatus.getSimulationTime() + ignitionDelay, - component, inst.getID() )); + for (MotorClusterState state : currentStatus.getAllMotors() ){ + if( state.testForIgnition(event )){ + final double simulationTime = currentStatus.getSimulationTime() ; + MotorClusterState sourceState = (MotorClusterState) event.getData(); + double ignitionDelay = 0; + if(( event.getType() == FlightEvent.Type.BURNOUT)|| ( event.getType() == FlightEvent.Type.EJECTION_CHARGE)){ + ignitionDelay = sourceState.getEjectionDelay(); + } + final double ignitionTime = currentStatus.getSimulationTime() + ignitionDelay; + final RocketComponent mount = (RocketComponent)state.getMount(); + + // TODO: this event seems to get enqueue'd multiple times ... + System.err.println("@simulationTime: "+simulationTime); + System.err.println("Queueing motorIgnitionEvent: "+state.getMotor().getDesignation()+" in:"+state.getMount().getName() + +" @: "+ignitionTime); + System.err.println(" Because of "+event.getType().name()+" @"+event.getTime()+" from: "+event.getSource().getName()); + + addEvent(new FlightEvent(FlightEvent.Type.IGNITION, ignitionTime, mount, state )); } } @@ -347,15 +340,32 @@ public class BasicEventSimulationEngine implements SimulationEngine { } case IGNITION: { - // Ignite the motor - MotorInstanceId motorId = (MotorInstanceId) event.getData(); - MotorSimulation inst = currentStatus.getMotor( motorId); - inst.ignite( event.getTime()); - //System.err.println("Igniting motor: "+inst.getMotor().getDesignation()+" @"+currentStatus.getSimulationTime()); + MotorClusterState motorState = (MotorClusterState) event.getData(); + System.err.println(" >> Igniting motor: "+motorState.getMotor().getDesignation() + +" @"+currentStatus.getSimulationTime() + +" ("+motorState.getMount().getName()); + motorState.ignite( event.getTime()); + + // Ignite the motor currentStatus.setMotorIgnited(true); currentStatus.getFlightData().addEvent(event); + // ... ignite ...uhh, again? + // TBH, I'm not sure what this call is for. It seems to be mostly a bunch of event distribution. + MotorInstanceId motorId = motorState.getID(); + MotorMount mount = (MotorMount) event.getSource(); + if (!SimulationListenerHelper.fireMotorIgnition(currentStatus, motorId, mount, motorState)) { + continue; + } + + + // and queue up the burnout for this motor, as well. + double duration = motorState.getMotor().getBurnTimeEstimate(); + double burnout = currentStatus.getSimulationTime() + duration; + addEvent(new FlightEvent(FlightEvent.Type.BURNOUT, burnout, + event.getSource(), motorState )); + break; } @@ -380,12 +390,15 @@ public class BasicEventSimulationEngine implements SimulationEngine { } // Add ejection charge event - MotorInstanceId motorId = (MotorInstanceId) event.getData(); - MotorSimulation state = currentStatus.getMotor( motorId); + MotorClusterState state = (MotorClusterState) event.getData(); + AxialStage stage = state.getMount().getStage(); + log.debug( " adding EJECTION_CHARGE event for stage "+stage.getStageNumber()+": "+stage.getName()); + log.debug( " .... for motor "+state.getMotor().getDesignation()); + double delay = state.getEjectionDelay(); - if (delay != Motor.PLUGGED) { + if ( state.hasEjectionCharge() ){ addEvent(new FlightEvent(FlightEvent.Type.EJECTION_CHARGE, currentStatus.getSimulationTime() + delay, - event.getSource(), event.getData())); + stage, event.getData())); } currentStatus.getFlightData().addEvent(event); break; @@ -483,6 +496,7 @@ public class BasicEventSimulationEngine implements SimulationEngine { break; case ALTITUDE: + log.trace("BasicEventSimulationEngine: Handling event " + event); break; case TUMBLE: diff --git a/core/src/net/sf/openrocket/simulation/FlightDataBranch.java b/core/src/net/sf/openrocket/simulation/FlightDataBranch.java index 0f523b2f1..533717832 100644 --- a/core/src/net/sf/openrocket/simulation/FlightDataBranch.java +++ b/core/src/net/sf/openrocket/simulation/FlightDataBranch.java @@ -279,7 +279,7 @@ public class FlightDataBranch implements Monitorable { */ public void addEvent(FlightEvent event) { mutable.check(); - events.add(event.resetSourceAndData()); + events.add(event); modID++; } diff --git a/core/src/net/sf/openrocket/simulation/FlightEvent.java b/core/src/net/sf/openrocket/simulation/FlightEvent.java index 665883745..a3eab8ef9 100644 --- a/core/src/net/sf/openrocket/simulation/FlightEvent.java +++ b/core/src/net/sf/openrocket/simulation/FlightEvent.java @@ -1,6 +1,8 @@ package net.sf.openrocket.simulation; import net.sf.openrocket.l10n.Translator; +import net.sf.openrocket.rocketcomponent.AxialStage; +import net.sf.openrocket.rocketcomponent.MotorMount; import net.sf.openrocket.rocketcomponent.RocketComponent; import net.sf.openrocket.startup.Application; @@ -102,23 +104,26 @@ public class FlightEvent implements Comparable { private final Object data; - public FlightEvent(Type type, double time) { - this(type, time, null); + public FlightEvent( final Type type, final double time) { + this(type, time, null, null); } - public FlightEvent(Type type, double time, RocketComponent source) { + public FlightEvent( final Type type, final double time, final RocketComponent source) { this(type, time, source, null); } - public FlightEvent(Type type, double time, RocketComponent source, Object data) { + public FlightEvent(final FlightEvent _sourceEvent, final RocketComponent _comp, final Object _data) { + this(_sourceEvent.type, _sourceEvent.time, _comp, _data); + } + + public FlightEvent( final Type type, final double time, final RocketComponent source, final Object data) { this.type = type; this.time = time; this.source = source; this.data = data; + validate(); } - - - + public Type getType() { return type; } @@ -136,16 +141,7 @@ public class FlightEvent implements Comparable { } - /** - * Return a new FlightEvent with the same information as the current event - * but with null source. This is used to avoid memory leakage by - * retaining references to obsolete components. - * - * @return a new FlightEvent with same type, time and data. - */ - public FlightEvent resetSourceAndData() { - return new FlightEvent(type, time, null, null); - } + /** @@ -167,4 +163,78 @@ public class FlightEvent implements Comparable { return "FlightEvent[type=" + type.name() + ",time=" + time + ",source=" + source + ",data=" + String.valueOf(data) + "]"; } + + /** + * verify that this event's state is well-formed. + * + * User actions should not cause these. + * + * @return + */ + public void validate(){ + if( this.time == Double.NaN ){ + throw new IllegalStateException(type.name()+" event has a NaN time!"); + } + switch( this.type ){ + case BURNOUT: + if( null != this.source){ + if( ! ( this.source instanceof MotorMount)){ + throw new IllegalStateException(type.name()+" events should have " + +MotorMount.class.getSimpleName()+" type data payloads, instead of" + +this.getSource().getClass().getSimpleName()); + } + } + if( null != this.data ){ + if( ! ( this.data instanceof MotorClusterState)){ + throw new IllegalStateException(type.name()+" events should have " + +MotorClusterState.class.getSimpleName()+" type data payloads"); + } + } + break; + case IGNITION: + if( null != this.source){ + if( ! ( this.getSource() instanceof MotorMount)){ + throw new IllegalStateException(type.name()+" events should have " + +MotorMount.class.getSimpleName()+" type data payloads, instead of" + +this.getSource().getClass().getSimpleName()); + } + } + if( null != this.data ){ + if( ! ( this.data instanceof MotorClusterState)){ + throw new IllegalStateException(type.name()+"events should have " + +MotorClusterState.class.getSimpleName()+" type data payloads"); + } + } + break; + case EJECTION_CHARGE: + if( null != this.source){ + if( ! ( this.getSource() instanceof AxialStage)){ + throw new IllegalStateException(type.name()+" events should have " + +AxialStage.class.getSimpleName()+" type data payloads, instead of" + +this.getSource().getClass().getSimpleName()); + } + } + if( null != this.data ){ + if( ! ( this.data instanceof MotorClusterState)){ + throw new IllegalStateException(type.name()+" events should have " + +MotorClusterState.class.getSimpleName()+" type data payloads"); + } + } + break; + case LAUNCH: + case LIFTOFF: + case LAUNCHROD: + case STAGE_SEPARATION: + case APOGEE: + case RECOVERY_DEVICE_DEPLOYMENT: + case GROUND_HIT: + case SIMULATION_END: + case ALTITUDE: + case TUMBLE: + case EXCEPTION: + default: + } + } + + } diff --git a/core/src/net/sf/openrocket/simulation/MotorSimulation.java b/core/src/net/sf/openrocket/simulation/MotorClusterState.java similarity index 58% rename from core/src/net/sf/openrocket/simulation/MotorSimulation.java rename to core/src/net/sf/openrocket/simulation/MotorClusterState.java index 4dc4f798b..b96937f89 100644 --- a/core/src/net/sf/openrocket/simulation/MotorSimulation.java +++ b/core/src/net/sf/openrocket/simulation/MotorClusterState.java @@ -4,49 +4,49 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import net.sf.openrocket.models.atmosphere.AtmosphericConditions; +import net.sf.openrocket.motor.IgnitionEvent; import net.sf.openrocket.motor.Motor; import net.sf.openrocket.motor.MotorConfiguration; import net.sf.openrocket.motor.MotorInstanceId; -import net.sf.openrocket.rocketcomponent.IgnitionEvent; +import net.sf.openrocket.rocketcomponent.InnerTube; import net.sf.openrocket.rocketcomponent.MotorMount; -import net.sf.openrocket.util.BugException; +import net.sf.openrocket.rocketcomponent.RocketComponent; -public class MotorSimulation { +public class MotorClusterState { - private static final Logger log = LoggerFactory.getLogger(MotorSimulation.class); + private static final Logger log = LoggerFactory.getLogger(MotorClusterState.class); // for reference: set at initialization ONLY. final protected Motor motor; final protected MotorConfiguration config; + final protected int motorCount; final protected double thrustDuration; // for state: protected double ignitionTime = Double.NaN; protected double cutoffTime = Double.NaN; protected double ejectionTime = Double.NaN; - protected MotorState currentState = MotorState.PREFLIGHT; + protected ThrustState currentState = ThrustState.PREFLIGHT; - public MotorSimulation(final MotorConfiguration _config) { + public MotorClusterState(final MotorConfiguration _config) { log.debug(" Creating motor instance of " + _config.getDescription()); this.config = _config; this.motor = _config.getMotor(); + MotorMount mount = this.config.getMount(); + if( mount instanceof InnerTube ){ + InnerTube inner = (InnerTube) mount; + this.motorCount = inner.getClusterConfiguration().getClusterCount(); + }else{ + this.motorCount =0; + } + thrustDuration = this.motor.getBurnTimeEstimate(); this.resetToPreflight(); } - @Override - public MotorSimulation clone() { - try { - return (MotorSimulation) super.clone(); - } catch (CloneNotSupportedException e) { - throw new BugException("CloneNotSupportedException", e); - } - } - - public void arm( final double _armTime ){ - if( MotorState.PREFLIGHT == currentState ){ + if( ThrustState.PREFLIGHT == currentState ){ log.info( "igniting motor: "+this.toString()+" at t="+_armTime); //this.ignitionTime = _ignitionTime; this.currentState = this.currentState.getNext(); @@ -55,10 +55,6 @@ public class MotorSimulation { } } - public boolean isFinishedThrusting(){ - return currentState.isAfter( MotorState.THRUSTING ); - } - public double getIgnitionTime() { return ignitionTime; } @@ -67,19 +63,18 @@ public class MotorSimulation { return config.getIgnitionEvent(); } - public void ignite( final double _ignitionTime ){ - if( MotorState.ARMED == currentState ){ + if( ThrustState.ARMED == currentState ){ log.info( "igniting motor: "+this.toString()+" at t="+_ignitionTime); this.ignitionTime = _ignitionTime; this.currentState = this.currentState.getNext(); }else{ throw new IllegalStateException("Attempted to ignite a motor state with status="+this.currentState.getName()); - } + } } public void burnOut( final double _burnOutTime ){ - if( MotorState.THRUSTING == currentState ){ + if( ThrustState.THRUSTING == currentState ){ log.info( "igniting motor: "+this.toString()+" at t="+_burnOutTime); this.ignitionTime = _burnOutTime; this.currentState = this.currentState.getNext(); @@ -89,7 +84,7 @@ public class MotorSimulation { } public void fireEjectionCharge( final double _ejectionTime ){ - if( MotorState.DELAYING == currentState ){ + if( ThrustState.DELAYING == currentState ){ log.info( "igniting motor: "+this.toString()+" at t="+_ejectionTime); this.ejectionTime = _ejectionTime; this.currentState = this.currentState.getNext(); @@ -98,16 +93,12 @@ public class MotorSimulation { } } - /* + /** * Alias for "burnOut(double)" */ public void cutOff( final double _cutoffTime ){ burnOut( _cutoffTime ); } - - public double getIgnitionDelay() { - return config.getEjectionDelay(); - } public double getEjectionDelay() { return config.getEjectionDelay(); @@ -120,11 +111,7 @@ public class MotorSimulation { public double getPropellantMass(){ return (motor.getLaunchMass() - motor.getBurnoutMass()); } - -// public boolean isActive( ) { -// return this.currentState.isActive(); -// } - + public MotorMount getMount(){ return config.getMount(); } @@ -136,20 +123,51 @@ public class MotorSimulation { double getCutOffTime(){ return this.cutoffTime; } + + public double getMotorTime( final double _simulationTime ){ + return _simulationTime - this.getIgnitionTime(); + } - public double getThrust( final double simTime, final AtmosphericConditions cond){ + public double getThrust( final double simulationTime, final AtmosphericConditions cond){ if( this.currentState.isThrusting() ){ - return motor.getThrustAtMotorTime( simTime - this.getIgnitionTime()); + double motorTime = this.getMotorTime( simulationTime); + return this.motorCount * motor.getThrustAtMotorTime( motorTime ); }else{ return 0.0; } } + + public boolean isPlugged(){ + return ( this.config.getEjectionDelay() == Motor.PLUGGED_DELAY); + } + + public boolean hasEjectionCharge(){ + return ! isPlugged(); + } + + public boolean isFinishedThrusting(){ + return currentState.isAfter( ThrustState.THRUSTING ); + } + + /** + * alias to 'resetToPreflight()' + */ + public void reset(){ + resetToPreflight(); + } public void resetToPreflight(){ - ignitionTime = Double.NaN; - cutoffTime = Double.NaN; - ejectionTime = Double.NaN; - currentState = MotorState.PREFLIGHT; + // i.e. in the "future" + ignitionTime = Double.POSITIVE_INFINITY; + cutoffTime = Double.POSITIVE_INFINITY; + ejectionTime = Double.POSITIVE_INFINITY; + + currentState = ThrustState.PREFLIGHT; + } + + public boolean testForIgnition( final FlightEvent _event ){ + RocketComponent mount = (RocketComponent) this.getMount(); + return getIgnitionEvent().isActivationEvent( _event, mount); } @Override @@ -157,4 +175,20 @@ public class MotorSimulation { return this.motor.getDesignation(); } -} +// public void update( final double simulationTime ){ +// final double motorTime = this.getMotorTime( simulationTime ); +// log.debug("Attempt to update this motorClusterSimulation with: "); +// log.debug(" this.ignitionTime= "+this.ignitionTime); +// log.debug(" this.thrustDuration= "+this.thrustDuration); +// log.debug(" simTime = "+simulationTime); +// log.debug(" motorTime= "+motorTime ); +// +// log.debug( " time array = "+((ThrustCurveMotor)this.getMotor()).getTimePoints() ); +// +// switch( this.currentState ){ +// +// } + + + +} \ No newline at end of file diff --git a/core/src/net/sf/openrocket/simulation/SimulationStatus.java b/core/src/net/sf/openrocket/simulation/SimulationStatus.java index 5f0d1eea5..57ee12bee 100644 --- a/core/src/net/sf/openrocket/simulation/SimulationStatus.java +++ b/core/src/net/sf/openrocket/simulation/SimulationStatus.java @@ -3,7 +3,6 @@ package net.sf.openrocket.simulation; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -48,10 +47,8 @@ public class SimulationStatus implements Monitorable { private double effectiveLaunchRodLength; - // Set of burnt out motors - Set spentMotors = new HashSet(); - - List motorStateList = new ArrayList(); + // Set of all motors + List motorStateList = new ArrayList(); /** Nanosecond time when the simulation was started. */ private long simulationStartWallTime = Long.MIN_VALUE; @@ -108,6 +105,8 @@ public class SimulationStatus implements Monitorable { double angle = -cond.getTheta() - (Math.PI / 2.0 - this.simulationConditions.getLaunchRodDirection()); o = Quaternion.rotation(new Coordinate(0, 0, angle)); + + // Launch rod angle and direction o = o.multiplyLeft(Quaternion.rotation(new Coordinate(0, this.simulationConditions.getLaunchRodAngle(), 0))); o = o.multiplyLeft(Quaternion.rotation(new Coordinate(0, 0, Math.PI / 2.0 - this.simulationConditions.getLaunchRodDirection()))); @@ -149,7 +148,9 @@ public class SimulationStatus implements Monitorable { this.apogeeReached = false; for( MotorConfiguration motorConfig : this.configuration.getActiveMotors() ) { - this.motorStateList.add( new MotorSimulation( motorConfig) ); + MotorClusterState simMotor = new MotorClusterState( motorConfig); + simMotor.arm( this.time ); + this.motorStateList.add( simMotor); } this.warnings = new WarningSet(); } @@ -184,7 +185,6 @@ public class SimulationStatus implements Monitorable { this.launchRodCleared = orig.launchRodCleared; this.apogeeReached = orig.apogeeReached; this.tumbling = orig.tumbling; - this.spentMotors = orig.spentMotors; this.deployedRecoveryDevices.clear(); this.deployedRecoveryDevices.addAll(orig.deployedRecoveryDevices); @@ -216,6 +216,11 @@ public class SimulationStatus implements Monitorable { return time; } + public void armAllMotors(){ + for( MotorClusterState motor : this.motorStateList ){ + motor.resetToPreflight(); + } + } public void setConfiguration(FlightConfiguration configuration) { if (this.configuration != null) @@ -224,11 +229,11 @@ public class SimulationStatus implements Monitorable { this.configuration = configuration; } - public Collection getMotors() { + public Collection getMotors() { return motorStateList; } - public Collection getAllMotors() { + public Collection getAllMotors() { return motorStateList; } @@ -263,15 +268,6 @@ public class SimulationStatus implements Monitorable { return flightData; } - public MotorSimulation getMotor( final MotorInstanceId motorId ){ - for( MotorSimulation state : motorStateList ) { - if ( motorId.equals(state.getID() )) { - return state; - } - } - return null; - } - public double getPreviousTimeStep() { return previousTimeStep; } @@ -318,12 +314,7 @@ public class SimulationStatus implements Monitorable { // remove motor from 'normal' list // add to spent list return false; - } - - public boolean addBurntOutMotor(MotorInstanceId motor) { - return spentMotors.add(motor); - } - + } public Quaternion getRocketOrientationQuaternion() { return orientation; diff --git a/core/src/net/sf/openrocket/simulation/MotorState.java b/core/src/net/sf/openrocket/simulation/ThrustState.java similarity index 74% rename from core/src/net/sf/openrocket/simulation/MotorState.java rename to core/src/net/sf/openrocket/simulation/ThrustState.java index b4c8b925d..d269b2bb3 100644 --- a/core/src/net/sf/openrocket/simulation/MotorState.java +++ b/core/src/net/sf/openrocket/simulation/ThrustState.java @@ -1,9 +1,9 @@ package net.sf.openrocket.simulation; -public enum MotorState { - FINISHED("Finished with sequence.", "Finished Producing thrust.", null) - ,DELAYING("Delaying", " After Burnout, but before ejection", FINISHED){ +public enum ThrustState { + SPENT("Finished with sequence.", "Finished Producing thrust.", null) + ,DELAYING("Delaying", " After Burnout, but before ejection", SPENT){ @Override public boolean needsSimulation(){ return true;} } @@ -13,8 +13,8 @@ public enum MotorState { @Override public boolean needsSimulation(){ return true;} } - ,ARMED("Armed", "Armed, but not yet lit.", FINISHED) - ,PREFLIGHT("Pre-Launch", "Safed and inactive, prior to launch.", FINISHED) + ,ARMED("Armed", "Armed, but not yet lit.", THRUSTING) + ,PREFLIGHT("Pre-Launch", "Safed and inactive, prior to launch.", ARMED) ; private final static int SEQUENCE_NUMBER_END = 10; // arbitrary number @@ -22,9 +22,9 @@ public enum MotorState { private final String name; private final String description; private final int sequenceNumber; - private final MotorState nextState; + private final ThrustState nextState; - MotorState( final String name, final String description, final MotorState _nextState) { + ThrustState( final String name, final String description, final ThrustState _nextState) { this.name = name; this.description = description; if( null == _nextState ){ @@ -43,13 +43,12 @@ public enum MotorState { public String getName() { return this.name; } - /* * - * @Return a MotorState enum telling what state should follow this one. + * @Return a MotorState which should follow this one */ - public MotorState getNext( ){ + public ThrustState getNext( ){ return this.nextState; } @@ -72,14 +71,14 @@ public enum MotorState { return this.sequenceNumber; } - public boolean isAfter( final MotorState other ){ - return this.getSequenceNumber() > other.getSequenceNumber(); - } - public boolean isBefore( final MotorState other ){ - return this.getSequenceNumber() < other.getSequenceNumber(); + public boolean isAfter( final ThrustState other ){ + return this.sequenceNumber > other.sequenceNumber; + } + + public boolean isBefore( final ThrustState other ){ + return this.sequenceNumber < other.sequenceNumber; } - /* * If this motor is in a state which produces thrust */ diff --git a/core/src/net/sf/openrocket/simulation/extension/impl/ScriptingSimulationListener.java b/core/src/net/sf/openrocket/simulation/extension/impl/ScriptingSimulationListener.java index 099aa4368..8e6a4e7e3 100644 --- a/core/src/net/sf/openrocket/simulation/extension/impl/ScriptingSimulationListener.java +++ b/core/src/net/sf/openrocket/simulation/extension/impl/ScriptingSimulationListener.java @@ -18,7 +18,7 @@ import net.sf.openrocket.rocketcomponent.MotorMount; import net.sf.openrocket.rocketcomponent.RecoveryDevice; import net.sf.openrocket.simulation.AccelerationData; import net.sf.openrocket.simulation.FlightEvent; -import net.sf.openrocket.simulation.MotorSimulation; +import net.sf.openrocket.simulation.MotorClusterState; import net.sf.openrocket.simulation.SimulationStatus; import net.sf.openrocket.simulation.exception.SimulationException; import net.sf.openrocket.simulation.exception.SimulationListenerException; @@ -105,7 +105,7 @@ public class ScriptingSimulationListener implements SimulationListener, Simulati } @Override - public boolean motorIgnition(SimulationStatus status, MotorInstanceId motorId, MotorMount mount, MotorSimulation instance) throws SimulationException { + public boolean motorIgnition(SimulationStatus status, MotorInstanceId motorId, MotorMount mount, MotorClusterState instance) throws SimulationException { return invoke(Boolean.class, true, "motorIgnition", status, motorId, mount, instance); } diff --git a/core/src/net/sf/openrocket/simulation/listeners/AbstractSimulationListener.java b/core/src/net/sf/openrocket/simulation/listeners/AbstractSimulationListener.java index c5c547683..09fc3d2b5 100644 --- a/core/src/net/sf/openrocket/simulation/listeners/AbstractSimulationListener.java +++ b/core/src/net/sf/openrocket/simulation/listeners/AbstractSimulationListener.java @@ -9,7 +9,7 @@ import net.sf.openrocket.rocketcomponent.MotorMount; import net.sf.openrocket.rocketcomponent.RecoveryDevice; import net.sf.openrocket.simulation.AccelerationData; import net.sf.openrocket.simulation.FlightEvent; -import net.sf.openrocket.simulation.MotorSimulation; +import net.sf.openrocket.simulation.MotorClusterState; import net.sf.openrocket.simulation.SimulationStatus; import net.sf.openrocket.simulation.exception.SimulationException; import net.sf.openrocket.util.BugException; @@ -72,7 +72,7 @@ public class AbstractSimulationListener implements SimulationListener, Simulatio } @Override - public boolean motorIgnition(SimulationStatus status, MotorInstanceId motorId, MotorMount mount, MotorSimulation instance) throws SimulationException { + public boolean motorIgnition(SimulationStatus status, MotorInstanceId motorId, MotorMount mount, MotorClusterState instance) throws SimulationException { return true; } diff --git a/core/src/net/sf/openrocket/simulation/listeners/SimulationEventListener.java b/core/src/net/sf/openrocket/simulation/listeners/SimulationEventListener.java index 94be38660..e90f6528b 100644 --- a/core/src/net/sf/openrocket/simulation/listeners/SimulationEventListener.java +++ b/core/src/net/sf/openrocket/simulation/listeners/SimulationEventListener.java @@ -4,7 +4,7 @@ import net.sf.openrocket.motor.MotorInstanceId; import net.sf.openrocket.rocketcomponent.MotorMount; import net.sf.openrocket.rocketcomponent.RecoveryDevice; import net.sf.openrocket.simulation.FlightEvent; -import net.sf.openrocket.simulation.MotorSimulation; +import net.sf.openrocket.simulation.MotorClusterState; import net.sf.openrocket.simulation.SimulationStatus; import net.sf.openrocket.simulation.exception.SimulationException; @@ -44,7 +44,7 @@ public interface SimulationEventListener { * @return true to ignite the motor, false to abort ignition */ public boolean motorIgnition(SimulationStatus status, MotorInstanceId motorId, MotorMount mount, - MotorSimulation instance) throws SimulationException; + MotorClusterState instance) throws SimulationException; /** diff --git a/core/src/net/sf/openrocket/simulation/listeners/SimulationListenerHelper.java b/core/src/net/sf/openrocket/simulation/listeners/SimulationListenerHelper.java index 0548f95d9..087329754 100644 --- a/core/src/net/sf/openrocket/simulation/listeners/SimulationListenerHelper.java +++ b/core/src/net/sf/openrocket/simulation/listeners/SimulationListenerHelper.java @@ -14,7 +14,7 @@ import net.sf.openrocket.rocketcomponent.MotorMount; import net.sf.openrocket.rocketcomponent.RecoveryDevice; import net.sf.openrocket.simulation.AccelerationData; import net.sf.openrocket.simulation.FlightEvent; -import net.sf.openrocket.simulation.MotorSimulation; +import net.sf.openrocket.simulation.MotorClusterState; import net.sf.openrocket.simulation.SimulationStatus; import net.sf.openrocket.simulation.exception.SimulationException; import net.sf.openrocket.util.Coordinate; @@ -168,18 +168,18 @@ public class SimulationListenerHelper { * @return true to handle the event normally, false to skip event. */ public static boolean fireMotorIgnition(SimulationStatus status, MotorInstanceId motorId, MotorMount mount, - MotorSimulation instance) throws SimulationException { - boolean b; + MotorClusterState instance) throws SimulationException { + boolean result; int modID = status.getModID(); // Contains also motor instance for (SimulationListener l : status.getSimulationConditions().getSimulationListenerList()) { if (l instanceof SimulationEventListener) { - b = ((SimulationEventListener) l).motorIgnition(status, motorId, mount, instance); + result = ((SimulationEventListener) l).motorIgnition(status, motorId, mount, instance); if (modID != status.getModID()) { warn(status, l); modID = status.getModID(); } - if (b == false) { + if ( false == result ) { warn(status, l); return false; } @@ -196,17 +196,17 @@ public class SimulationListenerHelper { */ public static boolean fireRecoveryDeviceDeployment(SimulationStatus status, RecoveryDevice device) throws SimulationException { - boolean b; + boolean result; int modID = status.getModID(); // Contains also motor instance for (SimulationListener l : status.getSimulationConditions().getSimulationListenerList()) { if (l instanceof SimulationEventListener) { - b = ((SimulationEventListener) l).recoveryDeviceDeployment(status, device); + result = ((SimulationEventListener) l).recoveryDeviceDeployment(status, device); if (modID != status.getModID()) { warn(status, l); modID = status.getModID(); } - if (b == false) { + if (false == result) { warn(status, l); return false; } diff --git a/core/src/net/sf/openrocket/util/TestRockets.java b/core/src/net/sf/openrocket/util/TestRockets.java index 8eade7b02..42ed39af6 100644 --- a/core/src/net/sf/openrocket/util/TestRockets.java +++ b/core/src/net/sf/openrocket/util/TestRockets.java @@ -12,7 +12,6 @@ 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.MotorInstanceId; import net.sf.openrocket.motor.ThrustCurveMotor; import net.sf.openrocket.preset.ComponentPreset; import net.sf.openrocket.preset.ComponentPresetFactory; @@ -97,7 +96,7 @@ public class TestRockets { } // This function is used for unit, integration tests, DO NOT CHANGE (without updating tests). - private static MotorConfiguration generateMotorInstance_A8_18mm(){ + private static Motor generateMotor_A8_18mm(){ // public ThrustCurveMotor(Manufacturer manufacturer, String designation, String description, // Motor.Type type, double[] delays, double diameter, double length, // double[] time, double[] thrust, @@ -109,11 +108,11 @@ public class TestRockets { new Coordinate[] { new Coordinate(0.035, 0, 0, 0.0164),new Coordinate(.035, 0, 0, 0.0145),new Coordinate(.035, 0, 0, 0.0131)}, "digest A8 test"); - return new MotorConfiguration(mtr); + return mtr; } // This function is used for unit, integration tests, DO NOT CHANGE (without updating tests). - private static MotorConfiguration generateMotorInstance_B4_18mm(){ + private static Motor generateMotor_B4_18mm(){ // public ThrustCurveMotor(Manufacturer manufacturer, String designation, String description, // Motor.Type type, double[] delays, double diameter, double length, // double[] time, double[] thrust, @@ -125,11 +124,11 @@ public class TestRockets { new Coordinate[] { new Coordinate(0.035, 0, 0, 0.0195),new Coordinate(.035, 0, 0, 0.0155),new Coordinate(.035, 0, 0, 0.013)}, "digest B4 test"); - return new MotorConfiguration(mtr); + return mtr; } // This function is used for unit, integration tests, DO NOT CHANGE (without updating tests). - private static MotorConfiguration generateMotorInstance_C6_18mm(){ + private static Motor generateMotor_C6_18mm(){ // public ThrustCurveMotor(Manufacturer manufacturer, String designation, String description, // Motor.Type type, double[] delays, double diameter, double length, // double[] time, double[] thrust, @@ -141,11 +140,11 @@ public class TestRockets { new Coordinate[] { new Coordinate(0.035, 0, 0, 0.0227),new Coordinate(.035, 0, 0, 0.0165),new Coordinate(.035, 0, 0, 0.012)}, "digest C6 test"); - return new MotorConfiguration(mtr); + return mtr; } // This function is used for unit, integration tests, DO NOT CHANGE (without updating tests). - private static MotorConfiguration generateMotorInstance_D21_18mm(){ + private static Motor generateMotor_D21_18mm(){ ThrustCurveMotor mtr = new ThrustCurveMotor( Manufacturer.getManufacturer("AeroTech"),"D21", "Desc", Motor.Type.SINGLE, new double[] {}, 0.018, 0.07, @@ -153,11 +152,11 @@ public class TestRockets { new Coordinate[] { new Coordinate(.035, 0, 0, 0.025),new Coordinate(.035, 0, 0, .020),new Coordinate(.035, 0, 0, 0.0154)}, "digest D21 test"); - return new MotorConfiguration(mtr); + return mtr; } // This function is used for unit, integration tests, DO NOT CHANGE (without updating tests). - private static MotorConfiguration generateMotorInstance_M1350_75mm(){ + private static Motor generateMotor_M1350_75mm(){ // public ThrustCurveMotor(Manufacturer manufacturer, String designation, String description, // Motor.Type type, double[] delays, double diameter, double length, // double[] time, double[] thrust, @@ -169,11 +168,11 @@ public class TestRockets { new Coordinate[] { new Coordinate(.311, 0, 0, 4.808),new Coordinate(.311, 0, 0, 3.389),new Coordinate(.311, 0, 0, 1.970)}, "digest M1350 test"); - return new MotorConfiguration(mtr); + return mtr; } // This function is used for unit, integration tests, DO NOT CHANGE (without updating tests). - private static MotorConfiguration generateMotorInstance_G77_29mm(){ + private static Motor generateMotor_G77_29mm(){ // public ThrustCurveMotor(Manufacturer manufacturer, String designation, String description, // Motor.Type type, double[] delays, double diameter, double length, // double[] time, double[] thrust, @@ -185,7 +184,7 @@ public class TestRockets { new Coordinate[] { new Coordinate(.062, 0, 0, 0.123),new Coordinate(.062, 0, 0, .0935),new Coordinate(.062, 0, 0, 0.064)}, "digest G77 test"); - return new MotorConfiguration(mtr); + return mtr; } // @@ -461,34 +460,39 @@ public class TestRockets { inner.setMotorMount( true); { - MotorConfiguration motorConfig = TestRockets.generateMotorInstance_A8_18mm(); + MotorConfiguration motorConfig = new MotorConfiguration(inner,fcid[0]); + Motor mtr = TestRockets.generateMotor_A8_18mm(); + motorConfig.setMotor( mtr); motorConfig.setEjectionDelay(0.0); - motorConfig.setID( new MotorInstanceId( inner.getName(), 1) ); - inner.setMotorInstance( fcid[0], motorConfig); + inner.setMotorConfig( motorConfig, fcid[0]); } { - MotorConfiguration motorConfig = TestRockets.generateMotorInstance_B4_18mm(); + MotorConfiguration motorConfig = new MotorConfiguration(inner,fcid[1]); + Motor mtr = TestRockets.generateMotor_B4_18mm(); + motorConfig.setMotor( mtr); motorConfig.setEjectionDelay(3.0); - motorConfig.setID( new MotorInstanceId( inner.getName(), 1) ); - inner.setMotorInstance( fcid[1], motorConfig); + inner.setMotorConfig( motorConfig, fcid[1]); } { - MotorConfiguration motorConfig = TestRockets.generateMotorInstance_C6_18mm(); + MotorConfiguration motorConfig = new MotorConfiguration(inner,fcid[2]); + Motor mtr = TestRockets.generateMotor_C6_18mm(); motorConfig.setEjectionDelay(3.0); - motorConfig.setID( new MotorInstanceId( inner.getName(), 1) ); - inner.setMotorInstance( fcid[2], motorConfig); + motorConfig.setMotor( mtr); + inner.setMotorConfig( motorConfig, fcid[2]); } { - MotorConfiguration motorConfig = TestRockets.generateMotorInstance_C6_18mm(); + MotorConfiguration motorConfig = new MotorConfiguration(inner,fcid[3]); + Motor mtr = TestRockets.generateMotor_C6_18mm(); motorConfig.setEjectionDelay(5.0); - motorConfig.setID( new MotorInstanceId( inner.getName(), 1) ); - inner.setMotorInstance( fcid[3], motorConfig); + motorConfig.setMotor( mtr); + inner.setMotorConfig( motorConfig, fcid[3]); } { - MotorConfiguration motorConfig = TestRockets.generateMotorInstance_C6_18mm(); + MotorConfiguration motorConfig = new MotorConfiguration(inner,fcid[4]); + Motor mtr = TestRockets.generateMotor_C6_18mm(); motorConfig.setEjectionDelay(7.0); - motorConfig.setID( new MotorInstanceId( inner.getName(), 1) ); - inner.setMotorInstance( fcid[4], motorConfig); + motorConfig.setMotor( mtr); + inner.setMotorConfig( motorConfig, fcid[4]); } } @@ -532,6 +536,12 @@ public class TestRockets { AxialStage sustainerStage = new AxialStage(); sustainerStage.setName("Sustainer Stage"); rocket.addChild(sustainerStage); + FlightConfigurationId fcid[] = new FlightConfigurationId[5]; + for( int i=0; i< fcid.length; ++i){ + fcid[i] = new FlightConfigurationId(); + rocket.createFlightConfiguration(fcid[i]); + } + FlightConfiguration selectedConfiguration = rocket.getFlightConfiguration(fcid[0]); double noseconeLength = 0.07; double noseconeRadius = 0.012; @@ -593,39 +603,39 @@ public class TestRockets { inner.setMotorMount( true); { - MotorConfiguration motorConfig = TestRockets.generateMotorInstance_A8_18mm(); + MotorConfiguration motorConfig = new MotorConfiguration(inner,fcid[0]); + Motor mtr = TestRockets.generateMotor_A8_18mm(); motorConfig.setEjectionDelay(0.0); - motorConfig.setID( new MotorInstanceId( inner.getName(), 1) ); - FlightConfigurationId motorConfigId = rocket.getSelectedConfiguration().getFlightConfigurationID(); - inner.setMotorInstance( motorConfigId, motorConfig); + motorConfig.setMotor( mtr); + inner.setMotorConfig( motorConfig, fcid[0]); } { - MotorConfiguration motorConfig = TestRockets.generateMotorInstance_B4_18mm(); + MotorConfiguration motorConfig = new MotorConfiguration(inner,fcid[1]); + Motor mtr = TestRockets.generateMotor_B4_18mm(); motorConfig.setEjectionDelay(3.0); - motorConfig.setID( new MotorInstanceId( inner.getName(), 1) ); - FlightConfigurationId motorConfigId = new FlightConfigurationId(); - inner.setMotorInstance( motorConfigId, motorConfig); + motorConfig.setMotor( mtr); + inner.setMotorConfig( motorConfig, fcid[1]); } { - MotorConfiguration motorConfig = TestRockets.generateMotorInstance_C6_18mm(); + MotorConfiguration motorConfig = new MotorConfiguration(inner,fcid[2]); + Motor mtr = TestRockets.generateMotor_C6_18mm(); motorConfig.setEjectionDelay(3.0); - motorConfig.setID( new MotorInstanceId( inner.getName(), 1) ); - FlightConfigurationId motorConfigId = new FlightConfigurationId(); - inner.setMotorInstance( motorConfigId, motorConfig); + motorConfig.setMotor( mtr); + inner.setMotorConfig( motorConfig, fcid[2]); } { - MotorConfiguration motorConfig = TestRockets.generateMotorInstance_C6_18mm(); + MotorConfiguration motorConfig = new MotorConfiguration(inner,fcid[3]); + Motor mtr = TestRockets.generateMotor_C6_18mm(); motorConfig.setEjectionDelay(5.0); - motorConfig.setID( new MotorInstanceId( inner.getName(), 1) ); - FlightConfigurationId motorConfigId = new FlightConfigurationId(); - inner.setMotorInstance( motorConfigId, motorConfig); + motorConfig.setMotor( mtr); + inner.setMotorConfig( motorConfig, fcid[3]); } { - MotorConfiguration motorConfig = TestRockets.generateMotorInstance_C6_18mm(); + MotorConfiguration motorConfig = new MotorConfiguration(inner,fcid[4]); + Motor mtr = TestRockets.generateMotor_C6_18mm(); motorConfig.setEjectionDelay(7.0); - motorConfig.setID( new MotorInstanceId( inner.getName(), 1) ); - FlightConfigurationId motorConfigId = new FlightConfigurationId(); - inner.setMotorInstance( motorConfigId, motorConfig); + motorConfig.setMotor( mtr); + inner.setMotorConfig( motorConfig, fcid[4]); } } @@ -696,14 +706,15 @@ public class TestRockets { boosterMMT.setMotorMount(true); { - FlightConfigurationId mcid = rocket.getSelectedConfiguration().getFlightConfigurationID(); - MotorConfiguration motorConfig= generateMotorInstance_D21_18mm(); - motorConfig.setID( new MotorInstanceId( boosterMMT.getName(), 1) ); - boosterMMT.setMotorInstance( mcid, motorConfig); + MotorConfiguration motorConfig= new MotorConfiguration(boosterMMT,fcid[0]); + Motor mtr = generateMotor_D21_18mm(); + motorConfig.setMotor(mtr); + boosterMMT.setMotorConfig( motorConfig, fcid[0]); } } rocket.getSelectedConfiguration().setAllStages(); + rocket.setSelectedConfiguration( selectedConfiguration ); rocket.enableEvents(); return rocket; } @@ -750,10 +761,11 @@ public class TestRockets { FlightConfigurationId fcid = config.getFlightConfigurationID(); ThrustCurveMotor motor = getTestMotor(); - MotorConfiguration instance = new MotorConfiguration(motor); + MotorConfiguration instance = new MotorConfiguration( bodytube, fcid ); + instance.setMotor( motor); instance.setEjectionDelay(5); - bodytube.setMotorInstance(fcid, instance); + bodytube.setMotorConfig( instance, fcid); bodytube.setMotorOverhang(0.005); config.setAllStages(); @@ -1017,7 +1029,8 @@ public class TestRockets { public static Rocket makeFalcon9Heavy() { Rocket rocket = new Rocket(); rocket.setName("Falcon9H Scale Rocket"); - FlightConfiguration config = rocket.getSelectedConfiguration(); + FlightConfiguration selConfig = rocket.getSelectedConfiguration(); + FlightConfigurationId selFCID = selConfig.getFlightConfigurationID(); // ====== Payload Stage ====== // ====== ====== ====== ====== @@ -1092,11 +1105,12 @@ public class TestRockets { coreBody.setMotorMount(true); coreStage.addChild( coreBody); { - MotorConfiguration motorInstance = TestRockets.generateMotorInstance_M1350_75mm(); - motorInstance.setID( new MotorInstanceId( coreBody.getName(), 1) ); + MotorConfiguration motorConfig = new MotorConfiguration(coreBody, selFCID); + Motor mtr = TestRockets.generateMotor_M1350_75mm(); + motorConfig.setMotor( mtr); coreBody.setMotorMount( true); - FlightConfigurationId motorConfigId = config.getFlightConfigurationID(); - coreBody.setMotorInstance( motorConfigId, motorInstance); + FlightConfigurationId motorConfigId = selConfig.getFlightConfigurationID(); + coreBody.setMotorConfig( motorConfig, motorConfigId); } TrapezoidFinSet coreFins = new TrapezoidFinSet(); @@ -1153,18 +1167,19 @@ public class TestRockets { boosterMotorTubes.setClusterScale(1.0); boosterBody.addChild( boosterMotorTubes); - FlightConfigurationId motorConfigId = config.getFlightConfigurationID(); - MotorConfiguration motorInstance = TestRockets.generateMotorInstance_G77_29mm(); - motorInstance.setID( new MotorInstanceId( boosterMotorTubes.getName(), 1) ); - boosterMotorTubes.setMotorInstance( motorConfigId, motorInstance); + FlightConfigurationId motorConfigId = selConfig.getFlightConfigurationID(); + MotorConfiguration motorConfig = new MotorConfiguration( boosterMotorTubes, selFCID); + Motor mtr = TestRockets.generateMotor_G77_29mm(); + motorConfig.setMotor(mtr); + boosterMotorTubes.setMotorConfig( motorConfig, motorConfigId); boosterMotorTubes.setMotorOverhang(0.01234); } } } rocket.enableEvents(); - rocket.setSelectedConfiguration(config); - config.setAllStages(); + rocket.setSelectedConfiguration(selConfig); + selConfig.setAllStages(); return rocket; } @@ -1271,11 +1286,12 @@ public class TestRockets { // create motor config and add a motor to it ThrustCurveMotor motor = getTestMotor(); - MotorConfiguration motorInst = new MotorConfiguration(motor); - motorInst.setEjectionDelay(5); + MotorConfiguration motorConfig = new MotorConfiguration(innerTube, fcid); + motorConfig.setMotor(motor); + motorConfig.setEjectionDelay(5); // add motor config to inner tube (motor mount) - innerTube.setMotorInstance(fcid, motorInst); + innerTube.setMotorConfig( motorConfig, fcid); rocket.enableEvents(); return OpenRocketDocumentFactory.createDocumentFromRocket(rocket); @@ -1307,11 +1323,12 @@ public class TestRockets { // create motor config and add a motor to it ThrustCurveMotor motor = getTestMotor(); - MotorConfiguration motorConfig = new MotorConfiguration(motor); + MotorConfiguration motorConfig = new MotorConfiguration(innerTube, fcid); + motorConfig.setMotor(motor); motorConfig.setEjectionDelay(5); // add motor config to inner tube (motor mount) - innerTube.setMotorInstance(fcid, motorConfig); + innerTube.setMotorConfig(motorConfig, fcid); OpenRocketDocument rocketDoc = OpenRocketDocumentFactory.createDocumentFromRocket(rocket); @@ -1465,12 +1482,14 @@ public class TestRockets { bodyTube.addChild(innerTube); // make inner tube with motor mount flag set - MotorConfiguration inst = new MotorConfiguration(getTestMotor()); - innerTube.setMotorInstance(fcid, inst); + 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); - inst.setIgnitionDelay(2); + motorConfig.setIgnitionDelay(2); rocket.enableEvents(); return OpenRocketDocumentFactory.createDocumentFromRocket(rocket); diff --git a/core/test/net/sf/openrocket/database/ThrustCurveMotorSetTest.java b/core/test/net/sf/openrocket/database/ThrustCurveMotorSetTest.java index a544e44b2..6198c45a5 100644 --- a/core/test/net/sf/openrocket/database/ThrustCurveMotorSetTest.java +++ b/core/test/net/sf/openrocket/database/ThrustCurveMotorSetTest.java @@ -34,7 +34,7 @@ public class ThrustCurveMotorSetTest { private static final ThrustCurveMotor motor3 = new ThrustCurveMotor( Manufacturer.getManufacturer("A"), - "F12", "Desc", Motor.Type.UNKNOWN, new double[] { 0, Motor.PLUGGED }, + "F12", "Desc", Motor.Type.UNKNOWN, new double[] { 0, Motor.PLUGGED_DELAY }, 0.024, 0.07, new double[] { 0, 1, 2 }, new double[] { 0, 2, 0 }, new Coordinate[] { Coordinate.NUL, Coordinate.NUL, Coordinate.NUL }, "digestC"); @@ -114,7 +114,7 @@ public class ThrustCurveMotorSetTest { assertEquals(motor3, set.getMotors().get(0)); assertEquals(motor2, set.getMotors().get(1)); assertEquals(motor1, set.getMotors().get(2)); - assertEquals(Arrays.asList(0.0, 5.0, Motor.PLUGGED), set.getDelays()); + assertEquals(Arrays.asList(0.0, 5.0, Motor.PLUGGED_DELAY), set.getDelays()); // Test that adding motor4 fails assertFalse(set.matches(motor4)); diff --git a/core/test/net/sf/openrocket/motor/ThrustCurveMotorTest.java b/core/test/net/sf/openrocket/motor/ThrustCurveMotorTest.java index 4dd256e0e..96d8a8d45 100644 --- a/core/test/net/sf/openrocket/motor/ThrustCurveMotorTest.java +++ b/core/test/net/sf/openrocket/motor/ThrustCurveMotorTest.java @@ -16,7 +16,7 @@ public class ThrustCurveMotorTest { private final ThrustCurveMotor motor = new ThrustCurveMotor(Manufacturer.getManufacturer("foo"), "X6", "Description of X6", Motor.Type.RELOAD, - new double[] {0, 2, Motor.PLUGGED}, radius*2, length, + new double[] {0, 2, Motor.PLUGGED_DELAY}, radius*2, length, new double[] {0, 1, 3, 4}, // time new double[] {0, 2, 3, 0}, // thrust new Coordinate[] { diff --git a/core/test/net/sf/openrocket/rocketcomponent/ParallelStageTest.java b/core/test/net/sf/openrocket/rocketcomponent/ParallelStageTest.java index d9fe39f4c..211ac06f9 100644 --- a/core/test/net/sf/openrocket/rocketcomponent/ParallelStageTest.java +++ b/core/test/net/sf/openrocket/rocketcomponent/ParallelStageTest.java @@ -9,6 +9,7 @@ import org.junit.Test; import net.sf.openrocket.rocketcomponent.RocketComponent.Position; import net.sf.openrocket.util.Coordinate; +import net.sf.openrocket.util.TestRockets; import net.sf.openrocket.util.BaseTestCase.BaseTestCase; public class ParallelStageTest extends BaseTestCase { @@ -204,6 +205,25 @@ public class ParallelStageTest extends BaseTestCase { } + + @Test + public void testStageAncestry() { + RocketComponent rocket = TestRockets.makeFalcon9Heavy(); + + AxialStage sustainer = (AxialStage) rocket.getChild(0); + AxialStage core = (AxialStage) rocket.getChild(1); + AxialStage booster = (AxialStage) core.getChild(1); + + AxialStage sustainerPrev = sustainer.getPreviousStage(); + assertThat("sustainer parent is not found correctly: ", sustainerPrev, equalTo(null)); + + AxialStage corePrev = core.getPreviousStage(); + assertThat("core parent is not found correctly: ", corePrev, equalTo(sustainer)); + + AxialStage boosterPrev = booster.getPreviousStage(); + assertThat("booster parent is not found correctly: ", boosterPrev, equalTo(core)); + } + @Test public void testSetStagePosition_topOfStack() { // setup diff --git a/swing/src/net/sf/openrocket/gui/configdialog/MotorConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/MotorConfig.java index 095a1e3bc..caa405d1c 100644 --- a/swing/src/net/sf/openrocket/gui/configdialog/MotorConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/MotorConfig.java @@ -21,8 +21,8 @@ import net.sf.openrocket.gui.components.BasicSlider; import net.sf.openrocket.gui.components.StyledLabel; import net.sf.openrocket.gui.components.UnitSelector; import net.sf.openrocket.l10n.Translator; +import net.sf.openrocket.motor.IgnitionEvent; import net.sf.openrocket.motor.MotorConfiguration; -import net.sf.openrocket.rocketcomponent.IgnitionEvent; import net.sf.openrocket.rocketcomponent.MotorMount; import net.sf.openrocket.rocketcomponent.RocketComponent; import net.sf.openrocket.startup.Application; diff --git a/swing/src/net/sf/openrocket/gui/dialogs/flightconfiguration/IgnitionSelectionDialog.java b/swing/src/net/sf/openrocket/gui/dialogs/flightconfiguration/IgnitionSelectionDialog.java index ee651fd1b..5b3e0192c 100644 --- a/swing/src/net/sf/openrocket/gui/dialogs/flightconfiguration/IgnitionSelectionDialog.java +++ b/swing/src/net/sf/openrocket/gui/dialogs/flightconfiguration/IgnitionSelectionDialog.java @@ -22,9 +22,9 @@ import net.sf.openrocket.gui.adaptors.DoubleModel; import net.sf.openrocket.gui.adaptors.EnumModel; import net.sf.openrocket.gui.util.GUIUtil; import net.sf.openrocket.l10n.Translator; +import net.sf.openrocket.motor.IgnitionEvent; import net.sf.openrocket.motor.MotorConfiguration; import net.sf.openrocket.rocketcomponent.FlightConfigurationId; -import net.sf.openrocket.rocketcomponent.IgnitionEvent; import net.sf.openrocket.rocketcomponent.MotorMount; import net.sf.openrocket.rocketcomponent.Rocket; import net.sf.openrocket.rocketcomponent.RocketComponent; diff --git a/swing/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/ThrustCurveMotorSelectionPanel.java b/swing/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/ThrustCurveMotorSelectionPanel.java index f22ea0435..8b99ba191 100644 --- a/swing/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/ThrustCurveMotorSelectionPanel.java +++ b/swing/src/net/sf/openrocket/gui/dialogs/motor/thrustcurve/ThrustCurveMotorSelectionPanel.java @@ -181,7 +181,7 @@ public class ThrustCurveMotorSelectionPanel extends JPanel implements MotorSelec String sel = (String) delayBox.getSelectedItem(); //// None if (sel.equalsIgnoreCase(trans.get("TCMotorSelPan.equalsIgnoreCase.None"))) { - selectedDelay = Motor.PLUGGED; + selectedDelay = Motor.PLUGGED_DELAY; } else { try { selectedDelay = Double.parseDouble(sel); diff --git a/swing/src/net/sf/openrocket/gui/main/flightconfigpanel/MotorConfigurationPanel.java b/swing/src/net/sf/openrocket/gui/main/flightconfigpanel/MotorConfigurationPanel.java index 7e1d781f1..07f61fcac 100644 --- a/swing/src/net/sf/openrocket/gui/main/flightconfigpanel/MotorConfigurationPanel.java +++ b/swing/src/net/sf/openrocket/gui/main/flightconfigpanel/MotorConfigurationPanel.java @@ -25,10 +25,10 @@ import net.sf.openrocket.gui.components.StyledLabel.Style; import net.sf.openrocket.gui.dialogs.flightconfiguration.IgnitionSelectionDialog; import net.sf.openrocket.gui.dialogs.flightconfiguration.MotorMountConfigurationPanel; import net.sf.openrocket.gui.dialogs.motor.MotorChooserDialog; +import net.sf.openrocket.motor.IgnitionEvent; import net.sf.openrocket.motor.Motor; import net.sf.openrocket.motor.MotorConfiguration; import net.sf.openrocket.rocketcomponent.FlightConfigurationId; -import net.sf.openrocket.rocketcomponent.IgnitionEvent; import net.sf.openrocket.rocketcomponent.MotorMount; import net.sf.openrocket.rocketcomponent.Rocket; import net.sf.openrocket.unit.UnitGroup; @@ -215,10 +215,11 @@ public class MotorConfigurationPanel extends FlightConfigurablePanel Motor mtr = motorChooserDialog.getSelectedMotor(); double d = motorChooserDialog.getSelectedDelay(); if (mtr != null) { - MotorConfiguration curInstance = new MotorConfiguration(mtr); - curInstance.setEjectionDelay(d); - curInstance.setIgnitionEvent( IgnitionEvent.NEVER); - curMount.setMotorInstance( fcid, curInstance); + MotorConfiguration curConfig = curMount.getMotorInstance(fcid); + curConfig.setMotor(mtr); + curConfig.setEjectionDelay(d); + curConfig.setIgnitionEvent( IgnitionEvent.NEVER); + curMount.setMotorConfig( curConfig, fcid); } fireTableDataChanged(); @@ -231,7 +232,7 @@ public class MotorConfigurationPanel extends FlightConfigurablePanel return; } - curMount.setMotorInstance( fcid, null); + curMount.setMotorConfig( null, fcid); fireTableDataChanged(); } diff --git a/swing/src/net/sf/openrocket/gui/simulation/SimulationRunDialog.java b/swing/src/net/sf/openrocket/gui/simulation/SimulationRunDialog.java index 1a9983725..077112d8c 100644 --- a/swing/src/net/sf/openrocket/gui/simulation/SimulationRunDialog.java +++ b/swing/src/net/sf/openrocket/gui/simulation/SimulationRunDialog.java @@ -33,9 +33,9 @@ import net.sf.openrocket.gui.dialogs.DetailDialog; import net.sf.openrocket.gui.util.GUIUtil; import net.sf.openrocket.gui.util.SwingPreferences; import net.sf.openrocket.l10n.Translator; +import net.sf.openrocket.motor.IgnitionEvent; import net.sf.openrocket.motor.MotorConfiguration; import net.sf.openrocket.rocketcomponent.FlightConfiguration; -import net.sf.openrocket.rocketcomponent.IgnitionEvent; import net.sf.openrocket.simulation.FlightEvent; import net.sf.openrocket.simulation.SimulationStatus; import net.sf.openrocket.simulation.customexpression.CustomExpression;