diff --git a/.travis.yml b/.travis.yml index 5d030ed65..a8fef4513 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,11 @@ language: java +dist: trusty +sudo: false +addons: + apt: + packages: + - ant-optional jdk: - - oraclejdk7 + - openjdk7 script: - "ant -buildfile build.xml clean check jar unittest" diff --git a/core/build.xml b/core/build.xml index 9252b6bc6..f04b037eb 100644 --- a/core/build.xml +++ b/core/build.xml @@ -43,7 +43,7 @@ - + @@ -88,7 +88,7 @@ Building unit tests - + Running unit tests diff --git a/core/resources/l10n/messages.properties b/core/resources/l10n/messages.properties index 3af0267b3..0adeb934a 100644 --- a/core/resources/l10n/messages.properties +++ b/core/resources/l10n/messages.properties @@ -830,8 +830,8 @@ RocketCompCfg.lbl.Componentname = Component name: RocketCompCfg.ttip.Thecomponentname = The component name. RocketCompCfg.tab.Override = Override RocketCompCfg.tab.MassandCGoverride = Mass and CG override options -RocketCompCfg.tab.Parallel = Parallel -RocketCompCfg.tab.ParallelComment = Options for locating stages parallel to other stages +RocketCompCfg.tab.Assembly = General +RocketCompCfg.tab.AssemblyComment = Options for locating stages parallel to other stages RocketCompCfg.tab.Figure = Figure RocketCompCfg.tab.Figstyleopt = Figure style options RocketCompCfg.tab.Comment = Comment diff --git a/core/resources/l10n/messages_fr.properties b/core/resources/l10n/messages_fr.properties index 166943359..c5fd19271 100644 --- a/core/resources/l10n/messages_fr.properties +++ b/core/resources/l10n/messages_fr.properties @@ -819,6 +819,7 @@ RocketCompCfg.but.Setforall = Appliquer \u00E0 tous RocketCompCfg.but.ttip.Setforall = R\u00E9gler la finition pour tous les composants de la fus\u00E9e. RocketCompCfg.checkbox.Endcapped = Arri\u00E8re clos RocketCompCfg.checkbox.Overridecenterofgrav = Forcer le centre de gravit\u00E9: +RocketCompCfg.checkbox.Overridecoeffofdrag = Modifier le coefficient de trainee: RocketCompCfg.checkbox.Overridemass = Forcer la masse: RocketCompCfg.checkbox.OverridemassandCG = Forcer la masse et le centre de gravit\u00E9 de tous les sous composants RocketCompCfg.checkbox.Usedefaultcolor = Utiliser la couleur par d\u00E9faut diff --git a/core/resources/l10n/messages_pt.properties b/core/resources/l10n/messages_pt.properties index 25603129c..33b1c387a 100644 --- a/core/resources/l10n/messages_pt.properties +++ b/core/resources/l10n/messages_pt.properties @@ -804,6 +804,7 @@ RocketCompCfg.but.Setforall = Definir para todos RocketCompCfg.but.ttip.Setforall = Definir este acabamento para todos os componentes do foguete. RocketCompCfg.checkbox.Endcapped = Fim tampado RocketCompCfg.checkbox.Overridecenterofgrav = Modificar o centro de gravidade: +RocketCompCfg.checkbox.Overridecoeffofdrag = Modificar o coeficiente de arrasto: RocketCompCfg.checkbox.Overridemass = Modificar massa: RocketCompCfg.checkbox.OverridemassandCG = Modificar a massa e o CG de todos os subcomponentes RocketCompCfg.checkbox.Usedefaultcolor = Use a cor padr\u00e3o diff --git a/core/resources/l10n/messages_uk_UA.properties b/core/resources/l10n/messages_uk_UA.properties index d2a159432..05fbebbc7 100644 --- a/core/resources/l10n/messages_uk_UA.properties +++ b/core/resources/l10n/messages_uk_UA.properties @@ -799,6 +799,7 @@ RocketCompCfg.but.ttip.Setforall = Set this finish for all components of the roc RocketCompCfg.lbl.Overridemassorcenter = Override the mass or center of gravity of the RocketCompCfg.checkbox.Overridemass = Override mass: RocketCompCfg.checkbox.Overridecenterofgrav = Override center of gravity: +RocketCompCfg.checkbox.Overridecoeffofdrag = Override coefficient of drag: RocketCompCfg.checkbox.OverridemassandCG = Override mass and CG of all subcomponents RocketCompCfg.lbl.longB1 = The overridden mass does not include motors.
RocketCompCfg.lbl.longB2 = The center of gravity is measured from the front end of the diff --git a/core/src/net/sf/openrocket/aerodynamics/AerodynamicForces.java b/core/src/net/sf/openrocket/aerodynamics/AerodynamicForces.java index ebf11c01e..cbfc3ddb7 100644 --- a/core/src/net/sf/openrocket/aerodynamics/AerodynamicForces.java +++ b/core/src/net/sf/openrocket/aerodynamics/AerodynamicForces.java @@ -196,6 +196,10 @@ public class AerodynamicForces implements Cloneable, Monitorable { } public double getCD() { + if(component == null) return CD; + if(component.isCDOverridden()) { + return component.getOverrideCD(); + } return CD; } @@ -205,6 +209,10 @@ public class AerodynamicForces implements Cloneable, Monitorable { } public double getPressureCD() { + if(component == null) return pressureCD; + if(component.isCDOverridden()) { + return 0; + } return pressureCD; } @@ -214,6 +222,10 @@ public class AerodynamicForces implements Cloneable, Monitorable { } public double getBaseCD() { + if(component == null) return baseCD; + if(component.isCDOverridden()) { + return component.getOverrideCD(); + } return baseCD; } @@ -223,6 +235,10 @@ public class AerodynamicForces implements Cloneable, Monitorable { } public double getFrictionCD() { + if(component == null) return frictionCD; + if(component.isCDOverridden()) { + return 0; + } return frictionCD; } diff --git a/core/src/net/sf/openrocket/aerodynamics/BarrowmanCalculator.java b/core/src/net/sf/openrocket/aerodynamics/BarrowmanCalculator.java index 95ea867f4..cd5d07759 100644 --- a/core/src/net/sf/openrocket/aerodynamics/BarrowmanCalculator.java +++ b/core/src/net/sf/openrocket/aerodynamics/BarrowmanCalculator.java @@ -463,6 +463,10 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator { } + //Handle Overriden CD for Whole Rocket + if(c.isCDOverridden()) { + continue; + } // Calculate the friction drag: @@ -496,6 +500,8 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator { } } + + } // fB may be POSITIVE_INFINITY, but that's ok for us @@ -510,6 +516,8 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator { } } } + + return (finFriction + correction * bodyFriction) / conditions.getRefArea(); } @@ -550,7 +558,9 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator { map.get(c).setPressureCD(cd); } - + if(c.isCDOverridden()) continue; + + // Stagnation drag if (c instanceof SymmetricComponent) { SymmetricComponent s = (SymmetricComponent) c; @@ -599,6 +609,11 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator { continue; SymmetricComponent s = (SymmetricComponent) c; + + if(c.isCDOverridden()) { + total += c.getOverrideCD(); + continue; + } if (radius > s.getForeRadius()) { double area = Math.PI * (pow2(radius) - pow2(s.getForeRadius())); diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/DocumentConfig.java b/core/src/net/sf/openrocket/file/openrocket/importt/DocumentConfig.java index 0e0ae9d2f..8f143c463 100644 --- a/core/src/net/sf/openrocket/file/openrocket/importt/DocumentConfig.java +++ b/core/src/net/sf/openrocket/file/openrocket/importt/DocumentConfig.java @@ -125,6 +125,9 @@ class DocumentConfig { setters.put("RocketComponent:overridecg", new OverrideSetter( Reflection.findMethod(RocketComponent.class, "setOverrideCGX", double.class), Reflection.findMethod(RocketComponent.class, "setCGOverridden", boolean.class))); + setters.put("RocketComponent:overridecd", new OverrideSetter( + Reflection.findMethod(RocketComponent.class, "setOverrideCD", double.class), + Reflection.findMethod(RocketComponent.class, "setCDOverridden", boolean.class))); setters.put("RocketComponent:overridesubcomponents", new BooleanSetter( Reflection.findMethod(RocketComponent.class, "setOverrideSubcomponents", boolean.class))); setters.put("RocketComponent:comment", new StringSetter( 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 45c7eaa1f..960def5a3 100644 --- a/core/src/net/sf/openrocket/file/openrocket/savers/RocketComponentSaver.java +++ b/core/src/net/sf/openrocket/file/openrocket/savers/RocketComponentSaver.java @@ -125,6 +125,10 @@ public class RocketComponentSaver { elements.add("" + c.getOverrideCGX() + ""); overridden = true; } + if (c.isCDOverridden()) { + elements.add("" + c.getOverrideCD() + ""); + overridden = true; + } if (overridden) { elements.add("" + c.getOverrideSubcomponents() + ""); diff --git a/core/src/net/sf/openrocket/optimization/services/DefaultSimulationModifierService.java b/core/src/net/sf/openrocket/optimization/services/DefaultSimulationModifierService.java index ab207f6df..8fad9a573 100644 --- a/core/src/net/sf/openrocket/optimization/services/DefaultSimulationModifierService.java +++ b/core/src/net/sf/openrocket/optimization/services/DefaultSimulationModifierService.java @@ -215,7 +215,7 @@ public class DefaultSimulationModifierService implements SimulationModifierServi trans.get("optimization.modifier.internalcomponent.position"), trans.get("optimization.modifier.internalcomponent.position.desc"), c, UnitGroup.UNITS_LENGTH, - 1.0, c.getClass(), c.getID(), "PositionValue"); + 1.0, c.getClass(), c.getID(), "RelativePosition"); mod.setMinValue(0); mod.setMaxValue(parent.getLength()); modifiers.add(mod); @@ -229,7 +229,7 @@ public class DefaultSimulationModifierService implements SimulationModifierServi trans.get("optimization.modifier.finset.position"), trans.get("optimization.modifier.finset.position.desc"), c, UnitGroup.UNITS_LENGTH, - 1.0, c.getClass(), c.getID(), "PositionValue"); + 1.0, c.getClass(), c.getID(), "RelativePosition"); mod.setMinValue(0); mod.setMaxValue(parent.getLength()); modifiers.add(mod); @@ -243,7 +243,7 @@ public class DefaultSimulationModifierService implements SimulationModifierServi trans.get("optimization.modifier.launchlug.position"), trans.get("optimization.modifier.launchlug.position.desc"), c, UnitGroup.UNITS_LENGTH, - 1.0, c.getClass(), c.getID(), "PositionValue"); + 1.0, c.getClass(), c.getID(), "RelativePosition"); mod.setMinValue(0); mod.setMaxValue(parent.getLength()); modifiers.add(mod); diff --git a/core/src/net/sf/openrocket/rocketcomponent/ParallelStage.java b/core/src/net/sf/openrocket/rocketcomponent/ParallelStage.java index 274fc9872..7c0681ab4 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/ParallelStage.java +++ b/core/src/net/sf/openrocket/rocketcomponent/ParallelStage.java @@ -218,11 +218,11 @@ public class ParallelStage extends AxialStage implements FlightConfigurableCompo super.update(); if( this.autoRadialPosition ){ - AxialStage parentStage = (AxialStage)this.parent; - if( null == parentStage ){ + ComponentAssembly parentAssembly = (ComponentAssembly)this.parent; + if( null == parentAssembly ){ this.radialPosition_m = this.getOuterRadius(); }else{ - this.radialPosition_m = this.getOuterRadius() + parentStage.getOuterRadius(); + this.radialPosition_m = this.getOuterRadius() + parentAssembly.getOuterRadius(); } } } diff --git a/core/src/net/sf/openrocket/rocketcomponent/PodSet.java b/core/src/net/sf/openrocket/rocketcomponent/PodSet.java index 675c6aae2..87128953f 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/PodSet.java +++ b/core/src/net/sf/openrocket/rocketcomponent/PodSet.java @@ -17,6 +17,7 @@ public class PodSet extends ComponentAssembly implements RingInstanceable { protected double angularSeparation = Math.PI; protected double angularPosition_rad = 0; + protected boolean autoRadialPosition = false; protected double radialPosition_m = 0; public PodSet() { @@ -175,18 +176,21 @@ public class PodSet extends ComponentAssembly implements RingInstanceable { return (this.getInstanceCount() + "-ring"); } + @Override + public boolean getAutoRadialOffset(){ + return this.autoRadialPosition; + } + public void setAutoRadialOffset( final boolean enabled ){ + this.autoRadialPosition = enabled; + fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); + } @Override public double getRadialOffset() { return this.radialPosition_m; } - - @Override - public boolean getAutoRadialOffset(){ - return false; - } - + @Override public int getInstanceCount() { return this.count; @@ -234,4 +238,17 @@ public class PodSet extends ComponentAssembly implements RingInstanceable { fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE); } + @Override + protected void update(){ + super.update(); + + if( this.autoRadialPosition){ + ComponentAssembly parentAssembly = (ComponentAssembly)this.parent; + if( null == parentAssembly ){ + this.radialPosition_m = this.getOuterRadius(); + }else{ + this.radialPosition_m = this.getOuterRadius() + parentAssembly.getOuterRadius(); + } + } + } } diff --git a/core/src/net/sf/openrocket/rocketcomponent/RocketComponent.java b/core/src/net/sf/openrocket/rocketcomponent/RocketComponent.java index 50c45a61e..ccb33fb05 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/RocketComponent.java +++ b/core/src/net/sf/openrocket/rocketcomponent/RocketComponent.java @@ -133,6 +133,8 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab private boolean massOverriden = false; private double overrideCGX = 0; private boolean cgOverriden = false; + private double overrideCD = 0; + private boolean cdOverriden = false; private boolean overrideSubcomponents = false; @@ -635,6 +637,60 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab cgOverriden = o; fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); } + + + + /** Return the current override CD. The CD is not neccesarily overriden. + * + * @return the override CG. + */ + public final double getOverrideCD() { + mutex.verify(); + return overrideCD; + } + + /** + * Set the current override CD to x. + * + * @param x the override CD to set. + */ + public final void setOverrideCD(double x) { + if (MathUtil.equals(overrideCD, x)) + return; + checkState(); + this.overrideCD = x; + if (isCDOverridden()) + fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); + else + fireComponentChangeEvent(ComponentChangeEvent.NONFUNCTIONAL_CHANGE); + } + + + + /** + * Return whether the CD is currently overriden. + * + * @return whether the CD is overridden + */ + public final boolean isCDOverridden() { + mutex.verify(); + return cdOverriden; + } + + + /** + * Set whether the CD is currently overriden. + * + * @param o whether the CD is overriden + */ + public final void setCDOverridden(boolean o) { + if(cdOverriden == o) { + return; + } + checkState(); + cdOverriden = o; + fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); + } diff --git a/core/src/net/sf/openrocket/simulation/AbstractSimulationStepper.java b/core/src/net/sf/openrocket/simulation/AbstractSimulationStepper.java index e3180ffef..20307f419 100644 --- a/core/src/net/sf/openrocket/simulation/AbstractSimulationStepper.java +++ b/core/src/net/sf/openrocket/simulation/AbstractSimulationStepper.java @@ -174,7 +174,7 @@ public abstract class AbstractSimulationStepper implements SimulationStepper { * @param stepMotors whether to step the motors forward or work on a clone object * @return the average thrust during the time step. */ - protected double calculateAvrageThrust(SimulationStatus status, double timestep, + protected double calculateAverageThrust(SimulationStatus status, double timestep, double acceleration, AtmosphericConditions atmosphericConditions, boolean stepMotors) throws SimulationException { double thrust; diff --git a/core/src/net/sf/openrocket/simulation/MotorClusterState.java b/core/src/net/sf/openrocket/simulation/MotorClusterState.java index 7a7defbe4..39a97d746 100644 --- a/core/src/net/sf/openrocket/simulation/MotorClusterState.java +++ b/core/src/net/sf/openrocket/simulation/MotorClusterState.java @@ -129,7 +129,9 @@ public class MotorClusterState { if( this.currentState.isThrusting() ) { double motorStartTime = this.getMotorTime( startSimulationTime); double motorEndTime = this.getMotorTime( endSimulationTime); - return this.motorCount * motor.getAverageThrust( motorStartTime, motorEndTime ); + + int instanceCount = this.config.getMount().getLocations().length; + return instanceCount * motor.getAverageThrust( motorStartTime, motorEndTime ); }else{ return 0.00; } diff --git a/core/src/net/sf/openrocket/simulation/RK4SimulationStepper.java b/core/src/net/sf/openrocket/simulation/RK4SimulationStepper.java index e658469f7..7d137be15 100644 --- a/core/src/net/sf/openrocket/simulation/RK4SimulationStepper.java +++ b/core/src/net/sf/openrocket/simulation/RK4SimulationStepper.java @@ -111,7 +111,7 @@ public class RK4SimulationStepper extends AbstractSimulationStepper { /* * Compute the initial thrust estimate. This is used for the first time step computation. */ - store.thrustForce = calculateAvrageThrust(status, store.timestep, status.getPreviousAcceleration(), + store.thrustForce = calculateAverageThrust(status, store.timestep, status.getPreviousAcceleration(), status.getPreviousAtmosphericConditions(), false); @@ -180,7 +180,7 @@ public class RK4SimulationStepper extends AbstractSimulationStepper { * diminished by it affecting only 1/6th of the total, so it's an acceptable error. */ double thrustEstimate = store.thrustForce; - store.thrustForce = calculateAvrageThrust(status, store.timestep, store.longitudinalAcceleration, + store.thrustForce = calculateAverageThrust(status, store.timestep, store.longitudinalAcceleration, store.atmosphericConditions, true); log.trace("Thrust at time " + store.timestep + " thrustForce = " + store.thrustForce); double thrustDiff = Math.abs(store.thrustForce - thrustEstimate); diff --git a/swing/src/net/sf/openrocket/gui/configdialog/ComponentAssemblyConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/ComponentAssemblyConfig.java index 1a3ea0a95..1bca9bfd7 100644 --- a/swing/src/net/sf/openrocket/gui/configdialog/ComponentAssemblyConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/ComponentAssemblyConfig.java @@ -1,14 +1,114 @@ package net.sf.openrocket.gui.configdialog; -import net.sf.openrocket.document.OpenRocketDocument; -import net.sf.openrocket.rocketcomponent.RocketComponent; +import javax.swing.ComboBoxModel; +import javax.swing.JCheckBox; +import javax.swing.JComboBox; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JSpinner; + +import net.miginfocom.swing.MigLayout; +import net.sf.openrocket.document.OpenRocketDocument; +import net.sf.openrocket.gui.SpinnerEditor; +import net.sf.openrocket.gui.adaptors.BooleanModel; +import net.sf.openrocket.gui.adaptors.DoubleModel; +import net.sf.openrocket.gui.adaptors.EnumModel; +import net.sf.openrocket.gui.adaptors.IntegerModel; +import net.sf.openrocket.gui.components.UnitSelector; +import net.sf.openrocket.l10n.Translator; +import net.sf.openrocket.rocketcomponent.ComponentAssembly; +import net.sf.openrocket.rocketcomponent.ParallelStage; +import net.sf.openrocket.rocketcomponent.PodSet; +import net.sf.openrocket.rocketcomponent.RocketComponent; +import net.sf.openrocket.startup.Application; +import net.sf.openrocket.unit.UnitGroup; + -@SuppressWarnings("serial") public class ComponentAssemblyConfig extends RocketComponentConfig { + private static final long serialVersionUID = -5153592258788614257L; + private static final Translator trans = Application.getTranslator(); public ComponentAssemblyConfig(OpenRocketDocument document, RocketComponent component) { super(document, component); + // only stages which are actually off-centerline will get the dialog here: + if( ParallelStage.class.isAssignableFrom( component.getClass()) || PodSet.class.isAssignableFrom( component.getClass())){ + tabbedPane.insertTab( trans.get("RocketCompCfg.tab.Assembly"), null, parallelTab( (ComponentAssembly)component ), trans.get("RocketCompCfg.tab.AssemblyComment"), 0); + tabbedPane.setSelectedIndex(0); + } } + + private JPanel parallelTab( final ComponentAssembly boosters ){ + JPanel motherPanel = new JPanel( new MigLayout("fill")); + + // auto radial distance + BooleanModel autoRadOffsModel = new BooleanModel( boosters, "AutoRadialOffset"); + JCheckBox autoRadCheckBox = new JCheckBox( autoRadOffsModel ); + autoRadCheckBox.setText( trans.get("StageConfig.parallel.autoradius")); + motherPanel.add( autoRadCheckBox, "align left, wrap"); + // set radial distance + JLabel radiusLabel = new JLabel(trans.get("StageConfig.parallel.radius")); + motherPanel.add( radiusLabel , "align left"); + autoRadOffsModel.addEnableComponent(radiusLabel, false); + DoubleModel radiusModel = new DoubleModel( boosters, "RadialOffset", UnitGroup.UNITS_LENGTH, 0); + + JSpinner radiusSpinner = new JSpinner( radiusModel.getSpinnerModel()); + radiusSpinner.setEditor(new SpinnerEditor(radiusSpinner )); + motherPanel.add(radiusSpinner , "growx 1, align right"); + autoRadOffsModel.addEnableComponent(radiusSpinner, false); + UnitSelector radiusUnitSelector = new UnitSelector(radiusModel); + motherPanel.add(radiusUnitSelector, "growx 1, wrap"); + autoRadOffsModel.addEnableComponent(radiusUnitSelector, false); + + // set location angle around the primary stage + JLabel angleLabel = new JLabel(trans.get("StageConfig.parallel.angle")); + motherPanel.add( angleLabel, "align left"); + DoubleModel angleModel = new DoubleModel( boosters, "AngularOffset", 1.0, UnitGroup.UNITS_ANGLE, 0.0, Math.PI*2); + + JSpinner angleSpinner = new JSpinner(angleModel.getSpinnerModel()); + angleSpinner.setEditor(new SpinnerEditor(angleSpinner)); + motherPanel.add(angleSpinner, "growx 1"); + UnitSelector angleUnitSelector = new UnitSelector(angleModel); + motherPanel.add( angleUnitSelector, "growx 1, wrap"); + + // set multiplicity + JLabel countLabel = new JLabel(trans.get("StageConfig.parallel.count")); + motherPanel.add( countLabel, "align left"); + + IntegerModel countModel = new IntegerModel( boosters, "InstanceCount", 2); + JSpinner countSpinner = new JSpinner(countModel.getSpinnerModel()); + countSpinner.setEditor(new SpinnerEditor(countSpinner)); + motherPanel.add(countSpinner, "growx 1, wrap"); + + // setPositions relative to parent component + JLabel positionLabel = new JLabel(trans.get("LaunchLugCfg.lbl.Posrelativeto")); + motherPanel.add( positionLabel); + + ComboBoxModel relativePositionMethodModel = new EnumModel(component, "RelativePositionMethod", + new RocketComponent.Position[] { + RocketComponent.Position.TOP, + RocketComponent.Position.MIDDLE, + RocketComponent.Position.BOTTOM, + RocketComponent.Position.ABSOLUTE + }); + JComboBox positionMethodCombo = new JComboBox( relativePositionMethodModel ); + motherPanel.add(positionMethodCombo, "spanx 2, growx, wrap"); + + // relative offset labels + JLabel positionPlusLabel = new JLabel(trans.get("StageConfig.parallel.offset")); + motherPanel.add( positionPlusLabel ); + DoubleModel axialOffsetModel = new DoubleModel( boosters, "AxialOffset", UnitGroup.UNITS_LENGTH); + + JSpinner axPosSpin= new JSpinner( axialOffsetModel.getSpinnerModel()); + axPosSpin.setEditor(new SpinnerEditor(axPosSpin)); + motherPanel.add(axPosSpin, "growx"); + UnitSelector axialOffsetUnitSelector = new UnitSelector(axialOffsetModel); + motherPanel.add(axialOffsetUnitSelector, "growx 1, wrap"); + + // For DEBUG purposes + //System.err.println(assembly.getRocket().toDebugTree()); + + return motherPanel; + } } diff --git a/swing/src/net/sf/openrocket/gui/configdialog/ParallelStageConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/ParallelStageConfig.java deleted file mode 100644 index 5741a4404..000000000 --- a/swing/src/net/sf/openrocket/gui/configdialog/ParallelStageConfig.java +++ /dev/null @@ -1,110 +0,0 @@ -package net.sf.openrocket.gui.configdialog; - -import javax.swing.ComboBoxModel; -import javax.swing.JCheckBox; -import javax.swing.JComboBox; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JSpinner; - -import net.miginfocom.swing.MigLayout; -import net.sf.openrocket.document.OpenRocketDocument; -import net.sf.openrocket.gui.SpinnerEditor; -import net.sf.openrocket.gui.adaptors.BooleanModel; -import net.sf.openrocket.gui.adaptors.DoubleModel; -import net.sf.openrocket.gui.adaptors.EnumModel; -import net.sf.openrocket.gui.adaptors.IntegerModel; -import net.sf.openrocket.gui.components.UnitSelector; -import net.sf.openrocket.l10n.Translator; -import net.sf.openrocket.rocketcomponent.ParallelStage; -import net.sf.openrocket.rocketcomponent.RocketComponent; -import net.sf.openrocket.startup.Application; -import net.sf.openrocket.unit.UnitGroup; - -public class ParallelStageConfig extends AxialStageConfig { - private static final long serialVersionUID = -944969957186522471L; - private static final Translator trans = Application.getTranslator(); - - public ParallelStageConfig(OpenRocketDocument document, RocketComponent component) { - super(document, component); - - // only stages which are actually off-centerline will get the dialog here: - tabbedPane.insertTab( trans.get("RocketCompCfg.tab.Parallel"), null, parallelTab( (ParallelStage)component ), trans.get("RocketCompCfg.tab.ParallelComment"), 1); - } - - private JPanel parallelTab( final ParallelStage boosters ){ - JPanel motherPanel = new JPanel( new MigLayout("fill")); - - // auto radial distance - BooleanModel autoRadOffsModel = new BooleanModel( boosters, "AutoRadialOffset"); - JCheckBox autoRadCheckBox = new JCheckBox( autoRadOffsModel ); - autoRadCheckBox.setText( trans.get("StageConfig.parallel.autoradius")); - motherPanel.add( autoRadCheckBox, "align left, wrap"); - // set radial distance - JLabel radiusLabel = new JLabel(trans.get("StageConfig.parallel.radius")); - motherPanel.add( radiusLabel , "align left"); - autoRadOffsModel.addEnableComponent(radiusLabel, false); - DoubleModel radiusModel = new DoubleModel( boosters, "RadialOffset", UnitGroup.UNITS_LENGTH, 0); - - JSpinner radiusSpinner = new JSpinner( radiusModel.getSpinnerModel()); - radiusSpinner.setEditor(new SpinnerEditor(radiusSpinner )); - motherPanel.add(radiusSpinner , "growx 1, align right"); - autoRadOffsModel.addEnableComponent(radiusSpinner, false); - UnitSelector radiusUnitSelector = new UnitSelector(radiusModel); - motherPanel.add(radiusUnitSelector, "growx 1, wrap"); - autoRadOffsModel.addEnableComponent(radiusUnitSelector, false); - - // set location angle around the primary stage - JLabel angleLabel = new JLabel(trans.get("StageConfig.parallel.angle")); - motherPanel.add( angleLabel, "align left"); - DoubleModel angleModel = new DoubleModel( boosters, "AngularOffset", 1.0, UnitGroup.UNITS_ANGLE, 0.0, Math.PI*2); - - JSpinner angleSpinner = new JSpinner(angleModel.getSpinnerModel()); - angleSpinner.setEditor(new SpinnerEditor(angleSpinner)); - motherPanel.add(angleSpinner, "growx 1"); - UnitSelector angleUnitSelector = new UnitSelector(angleModel); - motherPanel.add( angleUnitSelector, "growx 1, wrap"); - - // set multiplicity - JLabel countLabel = new JLabel(trans.get("StageConfig.parallel.count")); - motherPanel.add( countLabel, "align left"); - - IntegerModel countModel = new IntegerModel( boosters, "InstanceCount", 2); - JSpinner countSpinner = new JSpinner(countModel.getSpinnerModel()); - countSpinner.setEditor(new SpinnerEditor(countSpinner)); - motherPanel.add(countSpinner, "growx 1, wrap"); - - // setPositions relative to parent component - JLabel positionLabel = new JLabel(trans.get("LaunchLugCfg.lbl.Posrelativeto")); - motherPanel.add( positionLabel); - - // EnumModel(ChangeSource source, String valueName, Enum[] values) { - @SuppressWarnings("unchecked") - ComboBoxModel relativePositionMethodModel = new EnumModel(component, "RelativePositionMethod", - new RocketComponent.Position[] { - RocketComponent.Position.TOP, - RocketComponent.Position.MIDDLE, - RocketComponent.Position.BOTTOM, - RocketComponent.Position.ABSOLUTE - }); - JComboBox positionMethodCombo = new JComboBox( relativePositionMethodModel ); - motherPanel.add(positionMethodCombo, "spanx 2, growx, wrap"); - - // relative offset labels - JLabel positionPlusLabel = new JLabel(trans.get("StageConfig.parallel.offset")); - motherPanel.add( positionPlusLabel ); - DoubleModel axialOffsetModel = new DoubleModel( boosters, "AxialOffset", UnitGroup.UNITS_LENGTH); - - JSpinner axPosSpin= new JSpinner( axialOffsetModel.getSpinnerModel()); - axPosSpin.setEditor(new SpinnerEditor(axPosSpin)); - motherPanel.add(axPosSpin, "growx"); - UnitSelector axialOffsetUnitSelector = new UnitSelector(axialOffsetModel); - motherPanel.add(axialOffsetUnitSelector, "growx 1, wrap"); - - // For DEBUG purposes - //System.err.println(assembly.getRocket().toDebugTree()); - - return motherPanel; - } - -} diff --git a/swing/src/net/sf/openrocket/gui/configdialog/PodSetConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/PodSetConfig.java deleted file mode 100644 index 2f7dfac01..000000000 --- a/swing/src/net/sf/openrocket/gui/configdialog/PodSetConfig.java +++ /dev/null @@ -1,100 +0,0 @@ -package net.sf.openrocket.gui.configdialog; - -import javax.swing.ComboBoxModel; -import javax.swing.JComboBox; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JSpinner; - -import net.miginfocom.swing.MigLayout; -import net.sf.openrocket.document.OpenRocketDocument; -import net.sf.openrocket.gui.SpinnerEditor; -import net.sf.openrocket.gui.adaptors.DoubleModel; -import net.sf.openrocket.gui.adaptors.EnumModel; -import net.sf.openrocket.gui.adaptors.IntegerModel; -import net.sf.openrocket.gui.components.UnitSelector; -import net.sf.openrocket.l10n.Translator; -import net.sf.openrocket.rocketcomponent.ComponentAssembly; -import net.sf.openrocket.rocketcomponent.RocketComponent; -import net.sf.openrocket.startup.Application; -import net.sf.openrocket.unit.UnitGroup; - -@SuppressWarnings("serial") -public class PodSetConfig extends RocketComponentConfig { - - private static final Translator trans = Application.getTranslator(); - - public PodSetConfig(OpenRocketDocument document, RocketComponent component) { - super(document, component); - - // only stages which are actually off-centerline will get the dialog here: - tabbedPane.insertTab( trans.get("RocketCompCfg.tab.Parallel"), null, parallelTab( (ComponentAssembly) component ), trans.get("RocketCompCfg.tab.ParallelComment"), 1); - } - - private JPanel parallelTab( final ComponentAssembly assembly ){ - JPanel motherPanel = new JPanel( new MigLayout("fill")); - - // set radial distance - JLabel radiusLabel = new JLabel(trans.get("StageConfig.parallel.radius")); - motherPanel.add( radiusLabel , "align left"); - DoubleModel radiusModel = new DoubleModel( assembly, "RadialOffset", UnitGroup.UNITS_LENGTH, 0); - - JSpinner radiusSpinner = new JSpinner( radiusModel.getSpinnerModel()); - radiusSpinner.setEditor(new SpinnerEditor(radiusSpinner )); - motherPanel.add(radiusSpinner , "growx 1, align right"); - UnitSelector radiusUnitSelector = new UnitSelector(radiusModel); - motherPanel.add(radiusUnitSelector, "growx 1, wrap"); - - // set location angle around the primary stage - JLabel angleLabel = new JLabel(trans.get("StageConfig.parallel.angle")); - motherPanel.add( angleLabel, "align left"); - DoubleModel angleModel = new DoubleModel( assembly, "AngularOffset", 1.0, UnitGroup.UNITS_ANGLE, 0.0, Math.PI*2); - - JSpinner angleSpinner = new JSpinner(angleModel.getSpinnerModel()); - angleSpinner.setEditor(new SpinnerEditor(angleSpinner)); - motherPanel.add(angleSpinner, "growx 1"); - UnitSelector angleUnitSelector = new UnitSelector(angleModel); - motherPanel.add( angleUnitSelector, "growx 1, wrap"); - - // set multiplicity - JLabel countLabel = new JLabel(trans.get("StageConfig.parallel.count")); - motherPanel.add( countLabel, "align left"); - - IntegerModel countModel = new IntegerModel( assembly, "InstanceCount", 2); - JSpinner countSpinner = new JSpinner(countModel.getSpinnerModel()); - countSpinner.setEditor(new SpinnerEditor(countSpinner)); - motherPanel.add(countSpinner, "growx 1, wrap"); - - // setPositions relative to parent component - JLabel positionLabel = new JLabel(trans.get("LaunchLugCfg.lbl.Posrelativeto")); - motherPanel.add( positionLabel); - - // EnumModel(ChangeSource source, String valueName, Enum[] values) { - ComboBoxModel relativePositionMethodModel = new EnumModel(component, "RelativePositionMethod", - new RocketComponent.Position[] { - RocketComponent.Position.TOP, - RocketComponent.Position.MIDDLE, - RocketComponent.Position.BOTTOM, - RocketComponent.Position.ABSOLUTE - }); - JComboBox positionMethodCombo = new JComboBox( relativePositionMethodModel ); - motherPanel.add(positionMethodCombo, "spanx 2, growx, wrap"); - - // relative offset labels - JLabel positionPlusLabel = new JLabel(trans.get("StageConfig.parallel.offset")); - motherPanel.add( positionPlusLabel ); - DoubleModel axialOffsetModel = new DoubleModel( assembly, "AxialOffset", UnitGroup.UNITS_LENGTH); - - JSpinner axPosSpin= new JSpinner( axialOffsetModel.getSpinnerModel()); - axPosSpin.setEditor(new SpinnerEditor(axPosSpin)); - motherPanel.add(axPosSpin, "growx"); - UnitSelector axialOffsetUnitSelector = new UnitSelector(axialOffsetModel); - motherPanel.add(axialOffsetUnitSelector, "growx 1, wrap"); - - // For DEBUG purposes - //System.err.println(assembly.getRocket().toDebugTree()); - - return motherPanel; - } - -} diff --git a/swing/src/net/sf/openrocket/gui/configdialog/RocketComponentConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/RocketComponentConfig.java index b40a87c20..8730f1d73 100644 --- a/swing/src/net/sf/openrocket/gui/configdialog/RocketComponentConfig.java +++ b/swing/src/net/sf/openrocket/gui/configdialog/RocketComponentConfig.java @@ -24,6 +24,8 @@ import javax.swing.JTabbedPane; import javax.swing.JTextArea; import javax.swing.JTextField; +import java.text.DecimalFormat; + import net.miginfocom.swing.MigLayout; import net.sf.openrocket.database.ComponentPresetDatabase; import net.sf.openrocket.document.OpenRocketDocument; @@ -330,7 +332,9 @@ public class RocketComponentConfig extends JPanel { bm.addEnableComponent(bs); panel.add(bs, "growx 5, w 100lp, wrap"); - + + //OVERRIDES CG ---------------------------------- + //// CG override bm = new BooleanModel(component, "CGOverridden"); check = new JCheckBox(bm); @@ -368,6 +372,37 @@ public class RocketComponentConfig extends JPanel { bm.addEnableComponent(bs); panel.add(bs, "growx 5, w 100lp, wrap 35lp"); + + //END OVERRIDES CG --------------------------------------------------- + + + //BEGIN OVERRIDES CD --------------------------------------------------- + + + bm = new BooleanModel(component, "CDOverridden"); + check = new JCheckBox(bm); + //// Override mass: + check.setText("Set coefficient of drag:"); + panel.add(check, "growx 1, gapright 20lp"); + + m = new DoubleModel(component, "OverrideCD", UnitGroup.UNITS_NONE, 0); + + spin = new JSpinner(m.getSpinnerModel()); + + spin.setEditor(new SpinnerEditor(spin)); + bm.addEnableComponent(spin, true); + panel.add(spin, "growx 1"); + + + bs = new BasicSlider(m.getSliderModel(0, 0.01, 1.0)); + bm.addEnableComponent(bs); + panel.add(bs, "growx 5, w 100lp, wrap"); + + + //END OVERRIDES CP -------------------------------------------------- + + + // Override subcomponents checkbox bm = new BooleanModel(component, "OverrideSubcomponents"); @@ -596,6 +631,7 @@ public class RocketComponentConfig extends JPanel { } + protected static void setDeepEnabled(Component component, boolean enabled) { component.setEnabled(enabled); if (component instanceof Container) { @@ -604,4 +640,4 @@ public class RocketComponentConfig extends JPanel { } } } -} \ No newline at end of file +} diff --git a/swing/src/net/sf/openrocket/gui/dialogs/ScaleDialog.java b/swing/src/net/sf/openrocket/gui/dialogs/ScaleDialog.java index a377539e9..49da90aef 100644 --- a/swing/src/net/sf/openrocket/gui/dialogs/ScaleDialog.java +++ b/swing/src/net/sf/openrocket/gui/dialogs/ScaleDialog.java @@ -82,7 +82,7 @@ public class ScaleDialog extends JDialog { List list; // RocketComponent - addScaler(RocketComponent.class, "PositionValue"); + addScaler(RocketComponent.class, "RelativePosition"); SCALERS.get(RocketComponent.class).add(new OverrideScaler()); // BodyComponent @@ -589,6 +589,8 @@ public class ScaleDialog extends JDialog { mass = mass * MathUtil.pow3(multiplier); component.setOverrideMass(mass); } + + //TODO: Fix overridden pressure! } }