[Bugfix] Fixed Stage Separation Bugs
UI elements now change per-configuration separations not the defaults fixed separation configuration file-write code. Added max-time guard for simulations at 1200 seconds.
This commit is contained in:
parent
238726f371
commit
ec05e46a0e
@ -150,7 +150,7 @@ class DocumentConfig {
|
||||
"auto",
|
||||
Reflection.findMethod(BodyTube.class, "setOuterRadiusAutomatic", boolean.class)));
|
||||
|
||||
// ParallelStage
|
||||
// Parallel Stage
|
||||
setters.put("ParallelStage:instancecount", new IntSetter(
|
||||
Reflection.findMethod(ParallelStage.class, "setInstanceCount",int.class)));
|
||||
setters.put("ParallelStage:radialoffset", new DoubleSetter(
|
||||
|
@ -51,24 +51,20 @@ public class AxialStageSaver extends ComponentAssemblySaver {
|
||||
// Note - getFlightConfigurationIDs returns at least one element. The first element
|
||||
// is null and means "default".
|
||||
|
||||
int configCount = rocket.getConfigSet().size();
|
||||
if (1 < configCount ){
|
||||
|
||||
for (FlightConfiguration curConfig : rocket.getConfigSet()){
|
||||
FlightConfigurationID fcid = curConfig.getFlightConfigurationID();
|
||||
if (fcid == null) {
|
||||
continue;
|
||||
}
|
||||
if (stage.getSeparationConfigurations().isDefault(fcid)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
StageSeparationConfiguration separationConfig = stage.getSeparationConfigurations().get(fcid);
|
||||
elements.add("<separationconfiguration configid=\"" + fcid.key + "\">");
|
||||
elements.addAll(separationConfig(separationConfig, true));
|
||||
elements.add("</separationconfiguration>");
|
||||
|
||||
for (FlightConfiguration curConfig : rocket.getConfigSet()){
|
||||
FlightConfigurationID fcid = curConfig.getFlightConfigurationID();
|
||||
if (fcid == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
StageSeparationConfiguration curSepCfg = stage.getSeparationConfigurations().get(fcid);
|
||||
if( stage.getSeparationConfigurations().isDefault( curSepCfg )){
|
||||
continue;
|
||||
}
|
||||
|
||||
elements.add("<separationconfiguration configid=\"" + fcid.key + "\">");
|
||||
elements.addAll(separationConfig(curSepCfg, true));
|
||||
elements.add("</separationconfiguration>");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,12 +12,12 @@ public class AxialStage extends ComponentAssembly implements FlightConfigurableC
|
||||
private static final Translator trans = Application.getTranslator();
|
||||
//private static final Logger log = LoggerFactory.getLogger(AxialStage.class);
|
||||
|
||||
protected ParameterSet<StageSeparationConfiguration> separationConfigurations;
|
||||
protected ParameterSet<StageSeparationConfiguration> separations;
|
||||
|
||||
protected int stageNumber;
|
||||
|
||||
public AxialStage(){
|
||||
this.separationConfigurations = new ParameterSet<StageSeparationConfiguration>(
|
||||
this.separations = new ParameterSet<StageSeparationConfiguration>(
|
||||
this, ComponentChangeEvent.EVENT_CHANGE, new StageSeparationConfiguration());
|
||||
this.relativePosition = Position.AFTER;
|
||||
this.stageNumber = 0;
|
||||
@ -35,7 +35,7 @@ public class AxialStage extends ComponentAssembly implements FlightConfigurableC
|
||||
}
|
||||
|
||||
public ParameterSet<StageSeparationConfiguration> getSeparationConfigurations() {
|
||||
return separationConfigurations;
|
||||
return separations;
|
||||
}
|
||||
|
||||
// not strictly accurate, but this should provide an acceptable estimate for total vehicle size
|
||||
@ -74,13 +74,13 @@ public class AxialStage extends ComponentAssembly implements FlightConfigurableC
|
||||
|
||||
@Override
|
||||
public void cloneFlightConfiguration(FlightConfigurationID oldConfigId, FlightConfigurationID newConfigId) {
|
||||
separationConfigurations.cloneFlightConfiguration(oldConfigId, newConfigId);
|
||||
separations.cloneFlightConfiguration(oldConfigId, newConfigId);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RocketComponent copyWithOriginalID() {
|
||||
AxialStage copy = (AxialStage) super.copyWithOriginalID();
|
||||
copy.separationConfigurations = new ParameterSet<StageSeparationConfiguration>(separationConfigurations,
|
||||
copy.separations = new ParameterSet<StageSeparationConfiguration>(separations,
|
||||
copy, ComponentChangeEvent.EVENT_CHANGE);
|
||||
return copy;
|
||||
}
|
||||
@ -135,6 +135,12 @@ public class AxialStage extends ComponentAssembly implements FlightConfigurableC
|
||||
// }
|
||||
return buf;
|
||||
}
|
||||
|
||||
public String toDebugSeparation() {
|
||||
StringBuilder buff = new StringBuilder();
|
||||
buff.append( this.separations.toDebug() );
|
||||
return buff.toString();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -82,7 +82,7 @@ public class ParallelStage extends AxialStage implements FlightConfigurableCompo
|
||||
|
||||
@Override
|
||||
public void cloneFlightConfiguration(FlightConfigurationID oldConfigId, FlightConfigurationID newConfigId) {
|
||||
this.separationConfigurations.cloneFlightConfiguration(oldConfigId, newConfigId);
|
||||
this.separations.cloneFlightConfiguration(oldConfigId, newConfigId);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -22,7 +22,7 @@ import net.sf.openrocket.util.Utils;
|
||||
*/
|
||||
public class ParameterSet<E extends FlightConfigurableParameter<E>> implements FlightConfigurable<E> {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(ParameterSet.class);
|
||||
//private static final Logger log = LoggerFactory.getLogger(ParameterSet.class);
|
||||
protected final HashMap<FlightConfigurationID, E> map = new HashMap<FlightConfigurationID, E>();
|
||||
|
||||
protected E defaultValue;
|
||||
@ -185,12 +185,8 @@ public class ParameterSet<E extends FlightConfigurableParameter<E>> implements F
|
||||
|
||||
@Override
|
||||
public void reset( FlightConfigurationID fcid) {
|
||||
// enforce at least one value in the set
|
||||
if( 1 < this.map.size() ){
|
||||
if( fcid.isValid() ){
|
||||
set( fcid, null);
|
||||
}else{
|
||||
log.warn(" attempted to remove last element from the FlightConfigurationSet<"+this.getDefault().getClass().getSimpleName()+"> attached to: "+component.getName()+". Ignoring. ");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -230,22 +226,27 @@ public class ParameterSet<E extends FlightConfigurableParameter<E>> implements F
|
||||
public String toDebug(){
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append(String.format("====== Dumping ConfigurationSet for: '%s' of type: %s ======\n", this.component.getName(), this.component.getClass().getSimpleName() ));
|
||||
buf.append(String.format(" >> FlightConfigurationSet (%d configurations)\n", this.size() ));
|
||||
buf.append(String.format(" >> ParameterSet<%s> (%d configurations)\n", this.defaultValue.getClass().getSimpleName(), this.size() ));
|
||||
|
||||
if( 0 == this.map.size() ){
|
||||
buf.append(String.format(" >> [%s]= %s\n", "*DEFAULT*", this.getDefault().toString() ));
|
||||
}else{
|
||||
for( FlightConfigurationID loopFCID : this.getSortedConfigurationIDs()){
|
||||
String shortKey = loopFCID.toShortKey();
|
||||
|
||||
E inst = this.map.get(loopFCID);
|
||||
if( this.isDefault(inst)){
|
||||
shortKey = "*"+shortKey+"*";
|
||||
}
|
||||
buf.append(String.format(" >> [%s]= %s\n", shortKey, inst ));
|
||||
buf.append(String.format(" >> [%s]= %s\n", "DEFAULT", this.getDefault().toString() ));
|
||||
for( FlightConfigurationID loopFCID : this.getSortedConfigurationIDs()){
|
||||
String shortKey = loopFCID.toShortKey();
|
||||
|
||||
E inst = this.map.get(loopFCID);
|
||||
if( this.isDefault(inst)){
|
||||
shortKey = "*"+shortKey+"*";
|
||||
}
|
||||
buf.append(String.format(" >> [%s]= %s\n", shortKey, inst ));
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/*
|
||||
* Clears all configuration-specific settings -- meaning querying the parameter for any configuration will return the default value.
|
||||
*
|
||||
*/
|
||||
public void clear() {
|
||||
this.map.clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ public class StageSeparationConfiguration implements FlightConfigurableParameter
|
||||
|
||||
private final List<StateChangeListener> listeners = new ArrayList<StateChangeListener>();
|
||||
|
||||
private SeparationEvent separationEvent = SeparationEvent.UPPER_IGNITION;
|
||||
private SeparationEvent separationEvent = SeparationEvent.NEVER;
|
||||
private double separationDelay = 0;
|
||||
|
||||
public SeparationEvent getSeparationEvent() {
|
||||
|
@ -21,6 +21,7 @@ import net.sf.openrocket.rocketcomponent.MotorMount;
|
||||
import net.sf.openrocket.rocketcomponent.RecoveryDevice;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
import net.sf.openrocket.rocketcomponent.StageSeparationConfiguration;
|
||||
import net.sf.openrocket.simulation.FlightEvent.Type;
|
||||
import net.sf.openrocket.simulation.exception.MotorIgnitionException;
|
||||
import net.sf.openrocket.simulation.exception.SimulationException;
|
||||
import net.sf.openrocket.simulation.exception.SimulationLaunchException;
|
||||
@ -483,6 +484,12 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
||||
|
||||
}
|
||||
|
||||
if( 1200 < currentStatus.getSimulationTime() ){
|
||||
ret = false;
|
||||
log.error("Simulation hit max time (1200s): aborting.");
|
||||
currentStatus.getFlightData().addEvent(new FlightEvent( FlightEvent.Type.SIMULATION_END, currentStatus.getSimulationTime()));
|
||||
}
|
||||
|
||||
|
||||
// If no motor has ignited, abort
|
||||
if (!currentStatus.isMotorIgnited()) {
|
||||
|
@ -14,6 +14,7 @@ import net.sf.openrocket.gui.components.StyledLabel;
|
||||
import net.sf.openrocket.gui.components.StyledLabel.Style;
|
||||
import net.sf.openrocket.l10n.Translator;
|
||||
import net.sf.openrocket.rocketcomponent.AxialStage;
|
||||
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
import net.sf.openrocket.rocketcomponent.StageSeparationConfiguration;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
@ -31,7 +32,6 @@ public class AxialStageConfig extends ComponentAssemblyConfig {
|
||||
tabbedPane.insertTab(trans.get("StageConfig.tab.Separation"), null, tab,
|
||||
trans.get("StageConfig.tab.Separation.ttip"), 2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -41,14 +41,30 @@ public class AxialStageConfig extends ComponentAssemblyConfig {
|
||||
// Select separation event
|
||||
panel.add(new StyledLabel(trans.get("StageConfig.separation.lbl.title") + " " + CommonStrings.dagger, Style.BOLD), "spanx, wrap rel");
|
||||
|
||||
StageSeparationConfiguration config = stage.getSeparationConfigurations().getDefault();
|
||||
JComboBox<?> combo = new JComboBox(new EnumModel<StageSeparationConfiguration.SeparationEvent>(config, "SeparationEvent"));
|
||||
FlightConfiguration flConfig = stage.getRocket().getDefaultConfiguration();
|
||||
StageSeparationConfiguration sepConfig = stage.getSeparationConfigurations().get(flConfig.getId());
|
||||
// to ensure the configuration is distinct, and we're not modifying the default
|
||||
if( sepConfig == stage.getSeparationConfigurations().getDefault() ){
|
||||
sepConfig = new StageSeparationConfiguration();
|
||||
stage.getSeparationConfigurations().set( flConfig.getId(), sepConfig );
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
JComboBox<?> combo = new JComboBox<StageSeparationConfiguration.SeparationEvent>(
|
||||
new EnumModel<StageSeparationConfiguration.SeparationEvent>( sepConfig, "SeparationEvent",
|
||||
new StageSeparationConfiguration.SeparationEvent[] {
|
||||
StageSeparationConfiguration.SeparationEvent.UPPER_IGNITION,
|
||||
StageSeparationConfiguration.SeparationEvent.IGNITION,
|
||||
StageSeparationConfiguration.SeparationEvent.BURNOUT,
|
||||
StageSeparationConfiguration.SeparationEvent.EJECTION,
|
||||
StageSeparationConfiguration.SeparationEvent.LAUNCH,
|
||||
StageSeparationConfiguration.SeparationEvent.NEVER }));
|
||||
//combo.setSelectedItem(sepConfig);
|
||||
panel.add(combo, "");
|
||||
|
||||
// ... and delay
|
||||
panel.add(new JLabel(trans.get("StageConfig.separation.lbl.plus")), "");
|
||||
|
||||
DoubleModel dm = new DoubleModel(config, "SeparationDelay", 0);
|
||||
DoubleModel dm = new DoubleModel( sepConfig, "SeparationDelay", 0);
|
||||
JSpinner spin = new JSpinner(dm.getSpinnerModel());
|
||||
spin.setEditor(new SpinnerEditor(spin));
|
||||
panel.add(spin, "width 45");
|
||||
|
@ -16,27 +16,18 @@ 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.AxialStage;
|
||||
import net.sf.openrocket.rocketcomponent.ParallelStage;
|
||||
import net.sf.openrocket.rocketcomponent.ComponentAssembly;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
import net.sf.openrocket.unit.UnitGroup;
|
||||
import net.sf.openrocket.util.ChangeSource;
|
||||
|
||||
public class ParallelStageConfig extends RocketComponentConfig {
|
||||
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);
|
||||
|
||||
// For DEBUG purposes
|
||||
if( component instanceof AxialStage ){
|
||||
System.err.println(" Dumping AxialStage tree info for devel / debugging.");
|
||||
System.err.println(component.toDebugTree());
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
@ -88,6 +79,7 @@ public class ParallelStageConfig extends RocketComponentConfig {
|
||||
motherPanel.add( positionLabel);
|
||||
|
||||
// EnumModel(ChangeSource source, String valueName, Enum<T>[] values) {
|
||||
@SuppressWarnings("unchecked")
|
||||
ComboBoxModel<RocketComponent.Position> relativePositionMethodModel = new EnumModel<RocketComponent.Position>(component, "RelativePositionMethod",
|
||||
new RocketComponent.Position[] {
|
||||
RocketComponent.Position.TOP,
|
||||
|
@ -23,6 +23,7 @@ import net.sf.openrocket.gui.util.GUIUtil;
|
||||
import net.sf.openrocket.l10n.Translator;
|
||||
import net.sf.openrocket.rocketcomponent.AxialStage;
|
||||
import net.sf.openrocket.rocketcomponent.FlightConfigurationID;
|
||||
import net.sf.openrocket.rocketcomponent.ParameterSet;
|
||||
import net.sf.openrocket.rocketcomponent.Rocket;
|
||||
import net.sf.openrocket.rocketcomponent.StageSeparationConfiguration;
|
||||
import net.sf.openrocket.rocketcomponent.StageSeparationConfiguration.SeparationEvent;
|
||||
@ -39,11 +40,14 @@ public class SeparationSelectionDialog extends JDialog {
|
||||
|
||||
private StageSeparationConfiguration newConfiguration;
|
||||
|
||||
public SeparationSelectionDialog(Window parent, final Rocket rocket, final AxialStage component) {
|
||||
public SeparationSelectionDialog(Window parent, final Rocket rocket, final AxialStage stage) {
|
||||
super(parent, trans.get("edtmotorconfdlg.title.Selectseparationconf"), Dialog.ModalityType.APPLICATION_MODAL);
|
||||
final FlightConfigurationID id = rocket.getDefaultConfiguration().getFlightConfigurationID();
|
||||
|
||||
newConfiguration = component.getSeparationConfigurations().get(id).clone();
|
||||
newConfiguration = stage.getSeparationConfigurations().get(id);
|
||||
if( stage.getSeparationConfigurations().isDefault( newConfiguration )){
|
||||
newConfiguration = newConfiguration.clone();
|
||||
}
|
||||
|
||||
JPanel panel = new JPanel(new MigLayout("fill"));
|
||||
|
||||
@ -51,7 +55,7 @@ public class SeparationSelectionDialog extends JDialog {
|
||||
// Select separation event
|
||||
panel.add(new JLabel(trans.get("SeparationSelectionDialog.opt.title")), "span, wrap rel");
|
||||
|
||||
boolean isDefault = component.getSeparationConfigurations().isDefault(id);
|
||||
boolean isDefault = stage.getSeparationConfigurations().isDefault(id);
|
||||
final JRadioButton defaultButton = new JRadioButton(trans.get("SeparationSelectionDialog.opt.default"), isDefault);
|
||||
panel.add(defaultButton, "span, gapleft para, wrap rel");
|
||||
String str = trans.get("SeparationSelectionDialog.opt.override");
|
||||
@ -65,12 +69,13 @@ public class SeparationSelectionDialog extends JDialog {
|
||||
|
||||
// Select the button based on current configuration. If the configuration is overridden
|
||||
// The the overrideButton is selected.
|
||||
boolean isOverridden = !component.getSeparationConfigurations().isDefault(id);
|
||||
boolean isOverridden = !stage.getSeparationConfigurations().isDefault(id);
|
||||
if (isOverridden) {
|
||||
overrideButton.setSelected(true);
|
||||
}
|
||||
|
||||
final JComboBox event = new JComboBox(new EnumModel<SeparationEvent>(newConfiguration, "SeparationEvent"));
|
||||
@SuppressWarnings("unchecked")
|
||||
final JComboBox<?> event = new JComboBox<SeparationEvent>(new EnumModel<SeparationEvent>(newConfiguration, "SeparationEvent"));
|
||||
event.setSelectedItem(newConfiguration.getSeparationEvent());
|
||||
panel.add(event, "wrap rel");
|
||||
|
||||
@ -92,14 +97,14 @@ public class SeparationSelectionDialog extends JDialog {
|
||||
okButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if( newConfiguration.getSeparationEvent() == StageSeparationConfiguration.SeparationEvent.NEVER ){
|
||||
newConfiguration.setSeparationDelay(0);
|
||||
}
|
||||
if (defaultButton.isSelected()) {
|
||||
// FlightConfigurationSet<StageSeparationConfiguration> sepConfigSet = component.getSeparationConfigurations();
|
||||
// StageSeparationConfiguration sepConfig = sepConfigSet.get(FlightConfigurationID.DEFAULT_CONFIGURATION_ID);
|
||||
// component.getSeparationConfigurations().setDefault( sepConfig);
|
||||
// old version
|
||||
//component.getSeparationConfigurations().setDefault( fcid?, newConfiguration);
|
||||
stage.getSeparationConfigurations().clear();
|
||||
stage.getSeparationConfigurations().setDefault( newConfiguration);
|
||||
} else {
|
||||
component.getSeparationConfigurations().set(id, newConfiguration);
|
||||
stage.getSeparationConfigurations().set(id, newConfiguration);
|
||||
}
|
||||
SeparationSelectionDialog.this.setVisible(false);
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ import net.sf.openrocket.startup.Application;
|
||||
import net.sf.openrocket.unit.UnitGroup;
|
||||
|
||||
public class SeparationConfigurationPanel extends FlightConfigurablePanel<AxialStage> {
|
||||
|
||||
private static final long serialVersionUID = -1556652925279847316L;
|
||||
static final Translator trans = Application.getTranslator();
|
||||
private RocketDescriptor descriptor = Application.getInjector().getInstance(RocketDescriptor.class);
|
||||
|
||||
@ -67,6 +67,8 @@ public class SeparationConfigurationPanel extends FlightConfigurablePanel<AxialS
|
||||
protected JTable initializeTable() {
|
||||
//// Separation selection
|
||||
separationTableModel = new FlightConfigurableTableModel<AxialStage>(AxialStage.class, rocket) {
|
||||
private static final long serialVersionUID = 7979648984099308970L;
|
||||
|
||||
@Override
|
||||
protected boolean includeComponent(AxialStage component) {
|
||||
return component.getStageNumber() > 0;
|
||||
@ -121,7 +123,8 @@ public class SeparationConfigurationPanel extends FlightConfigurablePanel<AxialS
|
||||
}
|
||||
|
||||
private class SeparationTableCellRenderer extends FlightConfigurablePanel<AxialStage>.FlightConfigurableCellRenderer {
|
||||
|
||||
private static final long serialVersionUID = -7066580803931938686L;
|
||||
|
||||
@Override
|
||||
protected JLabel format(AxialStage stage, FlightConfigurationID configId, JLabel label) {
|
||||
StageSeparationConfiguration sepConfig = stage.getSeparationConfigurations().get(configId);
|
||||
|
Loading…
x
Reference in New Issue
Block a user