Implemented a DeploymentConfiguration object which includes the values
used to determine the deployment of a recovery device. The DeployEvent enum was moved into this class. Added a map of configuration id strings to DeploymentConfiguration objects in the RecoveryDevice. Modified various setter/getters in RecoveryDevice to support a "default" configuration defined in the device's configuration dialog. Modified BasicSimulationEngine to use the DeploymentConfiguration based on the selected configuration. Added to the FlightConfiguration dialogs to support editing these configuration. Missing are serialization of the map in ork files.
This commit is contained in:
parent
e18b081273
commit
3a8d2d5560
@ -185,10 +185,15 @@ edtmotorconfdlg.selectcomp = <html>Select which components function as motor mou
|
|||||||
edtmotorconfdlg.lbl.Motorconfig = <html><b>Motor configurations:</b>
|
edtmotorconfdlg.lbl.Motorconfig = <html><b>Motor configurations:</b>
|
||||||
edtmotorconfdlg.lbl.Configname = Configuration name:
|
edtmotorconfdlg.lbl.Configname = Configuration name:
|
||||||
edtmotorconfdlg.lbl.Motortab = Motors
|
edtmotorconfdlg.lbl.Motortab = Motors
|
||||||
|
edtmotorconfdlg.lbl.Recoverytab = Recovery
|
||||||
edtmotorconfdlg.tbl.None = None
|
edtmotorconfdlg.tbl.None = None
|
||||||
edtmotorconfdlg.tbl.Motorheader = Motor
|
edtmotorconfdlg.tbl.Motorheader = Motor
|
||||||
edtmotorconfdlg.tbl.Mountheader = Motor Mount
|
edtmotorconfdlg.tbl.Mountheader = Motor Mount
|
||||||
edtmotorconfdlg.tbl.Ignitionheader = Ignition
|
edtmotorconfdlg.tbl.Ignitionheader = Ignition
|
||||||
|
edtmotorconfdlg.but.Resetdeployment = Reset to default
|
||||||
|
edtmotorconfdlg.but.Selectdeployment = Select deployment
|
||||||
|
edtmotorconfdlg.tbl.Recoveryheader = Recovery Device
|
||||||
|
edtmotorconfdlg.tbl.Deploymentheader = Deployment
|
||||||
|
|
||||||
! Example design dialog
|
! Example design dialog
|
||||||
exdesigndlg.but.open = Open
|
exdesigndlg.but.open = Open
|
||||||
|
@ -17,10 +17,10 @@ import net.sf.openrocket.document.Simulation;
|
|||||||
import net.sf.openrocket.document.StorageOptions;
|
import net.sf.openrocket.document.StorageOptions;
|
||||||
import net.sf.openrocket.file.RocketSaver;
|
import net.sf.openrocket.file.RocketSaver;
|
||||||
import net.sf.openrocket.logging.LogHelper;
|
import net.sf.openrocket.logging.LogHelper;
|
||||||
|
import net.sf.openrocket.rocketcomponent.DeploymentConfiguration.DeployEvent;
|
||||||
import net.sf.openrocket.rocketcomponent.FinSet;
|
import net.sf.openrocket.rocketcomponent.FinSet;
|
||||||
import net.sf.openrocket.rocketcomponent.MotorMount;
|
import net.sf.openrocket.rocketcomponent.MotorMount;
|
||||||
import net.sf.openrocket.rocketcomponent.RecoveryDevice;
|
import net.sf.openrocket.rocketcomponent.RecoveryDevice;
|
||||||
import net.sf.openrocket.rocketcomponent.RecoveryDevice.DeployEvent;
|
|
||||||
import net.sf.openrocket.rocketcomponent.Rocket;
|
import net.sf.openrocket.rocketcomponent.Rocket;
|
||||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||||
import net.sf.openrocket.rocketcomponent.TubeCoupler;
|
import net.sf.openrocket.rocketcomponent.TubeCoupler;
|
||||||
@ -250,7 +250,7 @@ public class OpenRocketSaver extends RocketSaver {
|
|||||||
// Search for recovery device deployment type LOWER_STAGE_SEPARATION (version 1.5)
|
// Search for recovery device deployment type LOWER_STAGE_SEPARATION (version 1.5)
|
||||||
for (RocketComponent c : document.getRocket()) {
|
for (RocketComponent c : document.getRocket()) {
|
||||||
if (c instanceof RecoveryDevice) {
|
if (c instanceof RecoveryDevice) {
|
||||||
if (((RecoveryDevice) c).getDeployEvent() == DeployEvent.LOWER_STAGE_SEPARATION) {
|
if (((RecoveryDevice) c).getDefaultDeployEvent() == DeployEvent.LOWER_STAGE_SEPARATION) {
|
||||||
return FILE_VERSION_DIVISOR + 5;
|
return FILE_VERSION_DIVISOR + 5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,7 @@ import net.sf.openrocket.rocketcomponent.Bulkhead;
|
|||||||
import net.sf.openrocket.rocketcomponent.CenteringRing;
|
import net.sf.openrocket.rocketcomponent.CenteringRing;
|
||||||
import net.sf.openrocket.rocketcomponent.ClusterConfiguration;
|
import net.sf.openrocket.rocketcomponent.ClusterConfiguration;
|
||||||
import net.sf.openrocket.rocketcomponent.Clusterable;
|
import net.sf.openrocket.rocketcomponent.Clusterable;
|
||||||
|
import net.sf.openrocket.rocketcomponent.DeploymentConfiguration.DeployEvent;
|
||||||
import net.sf.openrocket.rocketcomponent.EllipticalFinSet;
|
import net.sf.openrocket.rocketcomponent.EllipticalFinSet;
|
||||||
import net.sf.openrocket.rocketcomponent.EngineBlock;
|
import net.sf.openrocket.rocketcomponent.EngineBlock;
|
||||||
import net.sf.openrocket.rocketcomponent.ExternalComponent;
|
import net.sf.openrocket.rocketcomponent.ExternalComponent;
|
||||||
@ -445,13 +446,13 @@ class DocumentConfig {
|
|||||||
Reflection.findMethod(RecoveryDevice.class, "setCD", double.class),
|
Reflection.findMethod(RecoveryDevice.class, "setCD", double.class),
|
||||||
"auto",
|
"auto",
|
||||||
Reflection.findMethod(RecoveryDevice.class, "setCDAutomatic", boolean.class)));
|
Reflection.findMethod(RecoveryDevice.class, "setCDAutomatic", boolean.class)));
|
||||||
setters.put("RecoveryDevice:deployevent", new EnumSetter<RecoveryDevice.DeployEvent>(
|
setters.put("RecoveryDevice:deployevent", new EnumSetter<DeployEvent>(
|
||||||
Reflection.findMethod(RecoveryDevice.class, "setDeployEvent", RecoveryDevice.DeployEvent.class),
|
Reflection.findMethod(RecoveryDevice.class, "setDefaultDeployEvent", DeployEvent.class),
|
||||||
RecoveryDevice.DeployEvent.class));
|
DeployEvent.class));
|
||||||
setters.put("RecoveryDevice:deployaltitude", new DoubleSetter(
|
setters.put("RecoveryDevice:deployaltitude", new DoubleSetter(
|
||||||
Reflection.findMethod(RecoveryDevice.class, "setDeployAltitude", double.class)));
|
Reflection.findMethod(RecoveryDevice.class, "setDefaultDeployAltitude", double.class)));
|
||||||
setters.put("RecoveryDevice:deploydelay", new DoubleSetter(
|
setters.put("RecoveryDevice:deploydelay", new DoubleSetter(
|
||||||
Reflection.findMethod(RecoveryDevice.class, "setDeployDelay", double.class)));
|
Reflection.findMethod(RecoveryDevice.class, "setDefaultDeployDelay", double.class)));
|
||||||
setters.put("RecoveryDevice:material", new MaterialSetter(
|
setters.put("RecoveryDevice:material", new MaterialSetter(
|
||||||
Reflection.findMethod(RecoveryDevice.class, "setMaterial", Material.class),
|
Reflection.findMethod(RecoveryDevice.class, "setMaterial", Material.class),
|
||||||
Material.Type.SURFACE));
|
Material.Type.SURFACE));
|
||||||
@ -876,7 +877,6 @@ class ComponentParameterHandler extends AbstractElementHandler {
|
|||||||
return new MotorConfigurationHandler((Rocket) component, context);
|
return new MotorConfigurationHandler((Rocket) component, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return PlainTextHandler.INSTANCE;
|
return PlainTextHandler.INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,10 +19,12 @@ public class RecoveryDeviceSaver extends MassObjectSaver {
|
|||||||
else
|
else
|
||||||
elements.add("<cd>" + dev.getCD() + "</cd>");
|
elements.add("<cd>" + dev.getCD() + "</cd>");
|
||||||
|
|
||||||
elements.add("<deployevent>" + dev.getDeployEvent().name().toLowerCase(Locale.ENGLISH).replace("_", "") + "</deployevent>");
|
elements.add("<deployevent>" + dev.getDefaultDeployEvent().name().toLowerCase(Locale.ENGLISH).replace("_", "") + "</deployevent>");
|
||||||
elements.add("<deployaltitude>" + dev.getDeployAltitude() + "</deployaltitude>");
|
elements.add("<deployaltitude>" + dev.getDefaultDeployAltitude() + "</deployaltitude>");
|
||||||
elements.add("<deploydelay>" + dev.getDeployDelay() + "</deploydelay>");
|
elements.add("<deploydelay>" + dev.getDefaultDeployDelay() + "</deploydelay>");
|
||||||
elements.add(materialParam(dev.getMaterial()));
|
elements.add(materialParam(dev.getMaterial()));
|
||||||
|
|
||||||
|
// FIXME - add mapping.
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
48
core/src/net/sf/openrocket/gui/adaptors/BasicEnumModel.java
Normal file
48
core/src/net/sf/openrocket/gui/adaptors/BasicEnumModel.java
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
package net.sf.openrocket.gui.adaptors;
|
||||||
|
|
||||||
|
import javax.swing.AbstractListModel;
|
||||||
|
import javax.swing.ComboBoxModel;
|
||||||
|
|
||||||
|
|
||||||
|
public class BasicEnumModel<T extends Enum<T>> extends AbstractListModel implements ComboBoxModel {
|
||||||
|
|
||||||
|
private final String nullText;
|
||||||
|
|
||||||
|
private final Enum<T>[] values;
|
||||||
|
private Enum<T> currentValue = null;
|
||||||
|
|
||||||
|
public BasicEnumModel( Class<? extends Enum<T>> clazz ) {
|
||||||
|
this(clazz, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public BasicEnumModel(Class<? extends Enum<T>> clazz, String nullText) {
|
||||||
|
this.values = clazz.getEnumConstants();
|
||||||
|
this.nullText = nullText;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSelectedItem(Object anItem) {
|
||||||
|
currentValue = (Enum<T>) anItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getSelectedItem() {
|
||||||
|
if (currentValue==null)
|
||||||
|
return nullText;
|
||||||
|
return currentValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getElementAt(int index) {
|
||||||
|
if (values[index] == null)
|
||||||
|
return nullText;
|
||||||
|
return values[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSize() {
|
||||||
|
return values.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -192,14 +192,14 @@ public class ParachuteConfig extends RecoveryDeviceConfig {
|
|||||||
//// Deploys at:
|
//// Deploys at:
|
||||||
panel.add(new JLabel(trans.get("ParachuteCfg.lbl.Deploysat")), "");
|
panel.add(new JLabel(trans.get("ParachuteCfg.lbl.Deploysat")), "");
|
||||||
|
|
||||||
combo = new JComboBox(new EnumModel<IgnitionEvent>(component, "DeployEvent"));
|
combo = new JComboBox(new EnumModel<IgnitionEvent>(component, "DefaultDeployEvent"));
|
||||||
panel.add(combo, "spanx 3, growx, wrap");
|
panel.add(combo, "spanx 3, growx, wrap");
|
||||||
|
|
||||||
// ... and delay
|
// ... and delay
|
||||||
//// plus
|
//// plus
|
||||||
panel.add(new JLabel(trans.get("ParachuteCfg.lbl.plusdelay")), "right");
|
panel.add(new JLabel(trans.get("ParachuteCfg.lbl.plusdelay")), "right");
|
||||||
|
|
||||||
m = new DoubleModel(component, "DeployDelay", 0);
|
m = new DoubleModel(component, "DefaultDeployDelay", 0);
|
||||||
spin = new JSpinner(m.getSpinnerModel());
|
spin = new JSpinner(m.getSpinnerModel());
|
||||||
spin.setEditor(new SpinnerEditor(spin,3));
|
spin.setEditor(new SpinnerEditor(spin,3));
|
||||||
panel.add(spin, "spanx, split");
|
panel.add(spin, "spanx, split");
|
||||||
@ -212,7 +212,7 @@ public class ParachuteConfig extends RecoveryDeviceConfig {
|
|||||||
altitudeComponents.add(label);
|
altitudeComponents.add(label);
|
||||||
panel.add(label);
|
panel.add(label);
|
||||||
|
|
||||||
m = new DoubleModel(component, "DeployAltitude", UnitGroup.UNITS_DISTANCE, 0);
|
m = new DoubleModel(component, "DefaultDeployAltitude", UnitGroup.UNITS_DISTANCE, 0);
|
||||||
|
|
||||||
spin = new JSpinner(m.getSpinnerModel());
|
spin = new JSpinner(m.getSpinnerModel());
|
||||||
spin.setEditor(new SpinnerEditor(spin));
|
spin.setEditor(new SpinnerEditor(spin));
|
||||||
|
@ -6,6 +6,7 @@ import java.util.List;
|
|||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
|
|
||||||
import net.sf.openrocket.document.OpenRocketDocument;
|
import net.sf.openrocket.document.OpenRocketDocument;
|
||||||
|
import net.sf.openrocket.rocketcomponent.DeploymentConfiguration.DeployEvent;
|
||||||
import net.sf.openrocket.rocketcomponent.RecoveryDevice;
|
import net.sf.openrocket.rocketcomponent.RecoveryDevice;
|
||||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||||
|
|
||||||
@ -27,8 +28,7 @@ public abstract class RecoveryDeviceConfig extends RocketComponentConfig {
|
|||||||
if (altitudeComponents == null)
|
if (altitudeComponents == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
boolean enabled = (((RecoveryDevice) component).getDeployEvent()
|
boolean enabled = (((RecoveryDevice) component).getDefaultDeployEvent() == DeployEvent.ALTITUDE);
|
||||||
== RecoveryDevice.DeployEvent.ALTITUDE);
|
|
||||||
|
|
||||||
for (JComponent c : altitudeComponents) {
|
for (JComponent c : altitudeComponents) {
|
||||||
c.setEnabled(enabled);
|
c.setEnabled(enabled);
|
||||||
|
@ -193,14 +193,14 @@ public class StreamerConfig extends RecoveryDeviceConfig {
|
|||||||
//// Deploys at:
|
//// Deploys at:
|
||||||
panel.add(new JLabel(trans.get("StreamerCfg.lbl.Deploysat")), "");
|
panel.add(new JLabel(trans.get("StreamerCfg.lbl.Deploysat")), "");
|
||||||
|
|
||||||
combo = new JComboBox(new EnumModel<IgnitionEvent>(component, "DeployEvent"));
|
combo = new JComboBox(new EnumModel<IgnitionEvent>(component, "DefaultDeployEvent"));
|
||||||
panel.add(combo, "spanx 3, growx, wrap");
|
panel.add(combo, "spanx 3, growx, wrap");
|
||||||
|
|
||||||
// ... and delay
|
// ... and delay
|
||||||
//// plus
|
//// plus
|
||||||
panel.add(new JLabel(trans.get("StreamerCfg.lbl.plusdelay")), "right");
|
panel.add(new JLabel(trans.get("StreamerCfg.lbl.plusdelay")), "right");
|
||||||
|
|
||||||
m = new DoubleModel(component, "DeployDelay", 0);
|
m = new DoubleModel(component, "DefaultDeployDelay", 0);
|
||||||
spin = new JSpinner(m.getSpinnerModel());
|
spin = new JSpinner(m.getSpinnerModel());
|
||||||
spin.setEditor(new SpinnerEditor(spin,3));
|
spin.setEditor(new SpinnerEditor(spin,3));
|
||||||
panel.add(spin, "spanx, split");
|
panel.add(spin, "spanx, split");
|
||||||
@ -213,7 +213,7 @@ public class StreamerConfig extends RecoveryDeviceConfig {
|
|||||||
altitudeComponents.add(label);
|
altitudeComponents.add(label);
|
||||||
panel.add(label);
|
panel.add(label);
|
||||||
|
|
||||||
m = new DoubleModel(component, "DeployAltitude", UnitGroup.UNITS_DISTANCE, 0);
|
m = new DoubleModel(component, "DefaultDeployAltitude", UnitGroup.UNITS_DISTANCE, 0);
|
||||||
|
|
||||||
spin = new JSpinner(m.getSpinnerModel());
|
spin = new JSpinner(m.getSpinnerModel());
|
||||||
spin.setEditor(new SpinnerEditor(spin));
|
spin.setEditor(new SpinnerEditor(spin));
|
||||||
|
@ -122,11 +122,14 @@ public class FlightConfigurationDialog extends JDialog {
|
|||||||
|
|
||||||
//// Tabs for advanced view.
|
//// Tabs for advanced view.
|
||||||
JTabbedPane tabs = new JTabbedPane();
|
JTabbedPane tabs = new JTabbedPane();
|
||||||
|
panel.add( tabs, "spanx, w 700lp, h 500lp, wrap");
|
||||||
|
|
||||||
//// Motor tabs
|
//// Motor tabs
|
||||||
JComponent motorTab = makeMotorTab();
|
JComponent motorTab = makeMotorTab();
|
||||||
tabs.add(trans.get("edtmotorconfdlg.lbl.Motortab"), motorTab);
|
tabs.add(trans.get("edtmotorconfdlg.lbl.Motortab"), motorTab);
|
||||||
panel.add( tabs, "spanx, w 700lp, h 500lp, wrap");
|
|
||||||
|
//// Recovery tab
|
||||||
|
tabs.add(trans.get("edtmotorconfdlg.lbl.Recoverytab"), new RecoveryConfigurationPanel(this,rocket));
|
||||||
|
|
||||||
//// Close button
|
//// Close button
|
||||||
JButton close = new JButton(trans.get("dlg.but.close"));
|
JButton close = new JButton(trans.get("dlg.but.close"));
|
||||||
|
@ -0,0 +1,168 @@
|
|||||||
|
package net.sf.openrocket.gui.dialogs.flightconfiguration;
|
||||||
|
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
import java.awt.event.MouseAdapter;
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
import javax.swing.JButton;
|
||||||
|
import javax.swing.JDialog;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.JScrollPane;
|
||||||
|
import javax.swing.JTable;
|
||||||
|
import javax.swing.ListSelectionModel;
|
||||||
|
import javax.swing.table.AbstractTableModel;
|
||||||
|
|
||||||
|
import net.miginfocom.swing.MigLayout;
|
||||||
|
import net.sf.openrocket.rocketcomponent.DeploymentConfiguration;
|
||||||
|
import net.sf.openrocket.rocketcomponent.RecoveryDevice;
|
||||||
|
import net.sf.openrocket.rocketcomponent.Rocket;
|
||||||
|
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||||
|
|
||||||
|
public class RecoveryConfigurationPanel extends JPanel {
|
||||||
|
|
||||||
|
private final FlightConfigurationDialog flightConfigurationDialog;
|
||||||
|
private final Rocket rocket;
|
||||||
|
private final JButton selectDeploymentButton;
|
||||||
|
private final JButton resetDeploymentButton;
|
||||||
|
|
||||||
|
private RecoveryDevice selectedComponent;
|
||||||
|
|
||||||
|
RecoveryConfigurationPanel( FlightConfigurationDialog flightConfigurationDialog, Rocket rocket ) {
|
||||||
|
super( new MigLayout("fill") );
|
||||||
|
this.flightConfigurationDialog = flightConfigurationDialog;
|
||||||
|
this.rocket = rocket;
|
||||||
|
|
||||||
|
//// Recovery selection
|
||||||
|
JTable table = new JTable( new RecoveryTableModel() );
|
||||||
|
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||||
|
table.setCellSelectionEnabled(true);
|
||||||
|
table.addMouseListener(new MouseAdapter() {
|
||||||
|
@Override
|
||||||
|
public void mouseClicked(MouseEvent e) {
|
||||||
|
JTable table = (JTable) e.getComponent();
|
||||||
|
int row = table.getSelectedRow();
|
||||||
|
int column = table.getSelectedColumn();
|
||||||
|
|
||||||
|
if ( row >= 0 & column == 1) {
|
||||||
|
selectedComponent = findRecoveryDevice(row);
|
||||||
|
} else {
|
||||||
|
selectedComponent = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.getClickCount() == 1) {
|
||||||
|
// Single click updates selection
|
||||||
|
updateButtonState();
|
||||||
|
} else if (e.getClickCount() == 2) {
|
||||||
|
// Double-click edits
|
||||||
|
selectDeployment();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
JScrollPane scroll = new JScrollPane(table);
|
||||||
|
this.add(scroll, "span, grow, wrap");
|
||||||
|
|
||||||
|
//// Select deployment
|
||||||
|
selectDeploymentButton = new JButton(FlightConfigurationDialog.trans.get("edtmotorconfdlg.but.Selectdeployment"));
|
||||||
|
selectDeploymentButton.setEnabled(false);
|
||||||
|
selectDeploymentButton.addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
selectDeployment();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.add(selectDeploymentButton, "skip, split, sizegroup button");
|
||||||
|
|
||||||
|
//// Reset deployment
|
||||||
|
resetDeploymentButton = new JButton(FlightConfigurationDialog.trans.get("edtmotorconfdlg.but.Resetdeployment"));
|
||||||
|
resetDeploymentButton.setEnabled(false);
|
||||||
|
resetDeploymentButton.addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
//resetDeployment;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.add(resetDeploymentButton,"sizegroup button, wrap");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void selectDeployment() {
|
||||||
|
JDialog d = new SelectDeploymentConfigDialog( flightConfigurationDialog, rocket, selectedComponent );
|
||||||
|
d.setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateButtonState() {
|
||||||
|
boolean buttonsEnabled = selectedComponent != null;
|
||||||
|
selectDeploymentButton.setEnabled(buttonsEnabled);
|
||||||
|
resetDeploymentButton.setEnabled(buttonsEnabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
private RecoveryDevice findRecoveryDevice( int count ) {
|
||||||
|
RecoveryDevice d = null;
|
||||||
|
Iterator<RocketComponent> it = rocket.iterator();
|
||||||
|
while( it.hasNext() && count >= 0 ) {
|
||||||
|
RocketComponent c = it.next();
|
||||||
|
if ( c instanceof RecoveryDevice ) {
|
||||||
|
d = (RecoveryDevice) c;
|
||||||
|
count--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class RecoveryTableModel extends AbstractTableModel {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getRowCount() {
|
||||||
|
int count = 0;
|
||||||
|
Iterator<RocketComponent> it = rocket.iterator();
|
||||||
|
while( it.hasNext() ) {
|
||||||
|
RocketComponent c = it.next();
|
||||||
|
if ( c instanceof RecoveryDevice ) {
|
||||||
|
count ++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getColumnCount() {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getValueAt(int rowIndex, int columnIndex) {
|
||||||
|
RecoveryDevice d = RecoveryConfigurationPanel.this.findRecoveryDevice(rowIndex);
|
||||||
|
switch ( columnIndex ) {
|
||||||
|
case 0:
|
||||||
|
return d.getName();
|
||||||
|
case 1:
|
||||||
|
DeploymentConfiguration deployConfig = d.getDeploymentConfiguration(rocket.getDefaultConfiguration().getMotorConfigurationID());
|
||||||
|
if ( deployConfig == null ) {
|
||||||
|
return "[" + d.getDefaultDeploymentConfiguration().toString() + "]";
|
||||||
|
} else {
|
||||||
|
return deployConfig.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getColumnName(int column) {
|
||||||
|
switch ( column ) {
|
||||||
|
case 0:
|
||||||
|
return FlightConfigurationDialog.trans.get("edtmotorconfdlg.tbl.Recoveryheader");
|
||||||
|
case 1:
|
||||||
|
return FlightConfigurationDialog.trans.get("edtmotorconfdlg.tbl.Deploymentheader");
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,144 @@
|
|||||||
|
package net.sf.openrocket.gui.dialogs.flightconfiguration;
|
||||||
|
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
|
||||||
|
import javax.swing.JButton;
|
||||||
|
import javax.swing.JComboBox;
|
||||||
|
import javax.swing.JDialog;
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.JSpinner;
|
||||||
|
|
||||||
|
import net.miginfocom.swing.MigLayout;
|
||||||
|
import net.sf.openrocket.gui.SpinnerEditor;
|
||||||
|
import net.sf.openrocket.gui.adaptors.BasicEnumModel;
|
||||||
|
import net.sf.openrocket.gui.adaptors.DoubleModel;
|
||||||
|
import net.sf.openrocket.gui.components.BasicSlider;
|
||||||
|
import net.sf.openrocket.gui.components.UnitSelector;
|
||||||
|
import net.sf.openrocket.rocketcomponent.DeploymentConfiguration;
|
||||||
|
import net.sf.openrocket.rocketcomponent.DeploymentConfiguration.DeployEvent;
|
||||||
|
import net.sf.openrocket.rocketcomponent.MotorMount.IgnitionEvent;
|
||||||
|
import net.sf.openrocket.rocketcomponent.RecoveryDevice;
|
||||||
|
import net.sf.openrocket.rocketcomponent.Rocket;
|
||||||
|
import net.sf.openrocket.unit.UnitGroup;
|
||||||
|
|
||||||
|
public class SelectDeploymentConfigDialog extends JDialog {
|
||||||
|
|
||||||
|
DeploymentConfiguration newConfiguration;
|
||||||
|
|
||||||
|
|
||||||
|
SelectDeploymentConfigDialog( JDialog parent, final Rocket rocket, final RecoveryDevice component ) {
|
||||||
|
super(parent);
|
||||||
|
super.setModal(true);
|
||||||
|
final String configId = rocket.getDefaultConfiguration().getMotorConfigurationID();
|
||||||
|
|
||||||
|
newConfiguration = component.getDeploymentConfiguration(configId);
|
||||||
|
if ( newConfiguration == null ) {
|
||||||
|
newConfiguration = component.getDefaultDeploymentConfiguration().clone();
|
||||||
|
} else {
|
||||||
|
// Clone the existing so cancel works. When the user selects OK, this configuration
|
||||||
|
// is put back in there.
|
||||||
|
newConfiguration = newConfiguration.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
JPanel panel = new JPanel(new MigLayout("fill"));
|
||||||
|
|
||||||
|
//// Deployment
|
||||||
|
//// Deploys at:
|
||||||
|
panel.add(new JLabel(FlightConfigurationDialog.trans.get("ParachuteCfg.lbl.Deploysat")), "");
|
||||||
|
|
||||||
|
final JComboBox event = new JComboBox(new BasicEnumModel<DeployEvent>(DeployEvent.class));
|
||||||
|
panel.add(event, "spanx 3, growx, wrap");
|
||||||
|
|
||||||
|
// ... and delay
|
||||||
|
//// plus
|
||||||
|
panel.add(new JLabel(FlightConfigurationDialog.trans.get("ParachuteCfg.lbl.plusdelay")), "right");
|
||||||
|
|
||||||
|
final DoubleModel delay = new DoubleModel(newConfiguration.getDeployDelay(), UnitGroup.UNITS_NONE, 0);
|
||||||
|
final JSpinner delaySpinner = new JSpinner( delay.getSpinnerModel() );
|
||||||
|
delaySpinner.setEditor(new SpinnerEditor(delaySpinner,3));
|
||||||
|
panel.add(delaySpinner, "spanx, split");
|
||||||
|
|
||||||
|
//// seconds
|
||||||
|
panel.add(new JLabel(FlightConfigurationDialog.trans.get("ParachuteCfg.lbl.seconds")), "wrap paragraph");
|
||||||
|
|
||||||
|
// Altitude:
|
||||||
|
JLabel label = new JLabel(FlightConfigurationDialog.trans.get("ParachuteCfg.lbl.Altitude"));
|
||||||
|
panel.add(label);
|
||||||
|
|
||||||
|
final DoubleModel alt = new DoubleModel(newConfiguration.getDeployAltitude(), UnitGroup.UNITS_DISTANCE, 0);
|
||||||
|
|
||||||
|
final JSpinner altSpinner = new JSpinner(alt.getSpinnerModel());
|
||||||
|
altSpinner.setEditor(new SpinnerEditor(altSpinner));
|
||||||
|
panel.add(altSpinner, "growx");
|
||||||
|
UnitSelector unit = new UnitSelector(alt);
|
||||||
|
panel.add(unit, "growx");
|
||||||
|
BasicSlider slider = new BasicSlider(alt.getSliderModel(100, 1000));
|
||||||
|
panel.add(slider, "w 100lp, wrap");
|
||||||
|
|
||||||
|
event.addActionListener( new ActionListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
if ( event.getSelectedItem() == DeployEvent.ALTITUDE ) {
|
||||||
|
delaySpinner.setEnabled(true);
|
||||||
|
altSpinner.setEnabled(true);
|
||||||
|
} else {
|
||||||
|
delaySpinner.setEnabled(false);
|
||||||
|
altSpinner.setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
// Set the value of the combo box at the end to take advantage of the action listener above.
|
||||||
|
event.setSelectedItem( newConfiguration.getDeployEvent() );
|
||||||
|
|
||||||
|
JButton okButton = new JButton("Ok");
|
||||||
|
okButton.addActionListener( new ActionListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
|
||||||
|
//// extract deployment type;
|
||||||
|
DeployEvent deployEvent = (DeployEvent) event.getSelectedItem();
|
||||||
|
newConfiguration.setDeployEvent(deployEvent);
|
||||||
|
|
||||||
|
//// extract deployment time;
|
||||||
|
double deployDelay = delay.getValue();
|
||||||
|
newConfiguration.setDeployDelay(deployDelay);
|
||||||
|
|
||||||
|
//// extract altitude;
|
||||||
|
double deployAltitude = alt.getValue();
|
||||||
|
newConfiguration.setDeployDelay(deployAltitude);
|
||||||
|
|
||||||
|
component.setDeploymentConfiguration(configId, newConfiguration);
|
||||||
|
|
||||||
|
SelectDeploymentConfigDialog.this.setVisible(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
panel.add( okButton );
|
||||||
|
|
||||||
|
JButton cancel = new JButton("Cancel");
|
||||||
|
cancel.addActionListener( new ActionListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
SelectDeploymentConfigDialog.this.setVisible(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
panel.add( cancel );
|
||||||
|
|
||||||
|
this.setContentPane(panel);
|
||||||
|
this.validate();
|
||||||
|
this.pack();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -14,6 +14,7 @@ import net.sf.openrocket.optimization.general.OptimizationException;
|
|||||||
import net.sf.openrocket.optimization.rocketoptimization.SimulationModifier;
|
import net.sf.openrocket.optimization.rocketoptimization.SimulationModifier;
|
||||||
import net.sf.openrocket.optimization.rocketoptimization.modifiers.GenericComponentModifier;
|
import net.sf.openrocket.optimization.rocketoptimization.modifiers.GenericComponentModifier;
|
||||||
import net.sf.openrocket.rocketcomponent.BodyTube;
|
import net.sf.openrocket.rocketcomponent.BodyTube;
|
||||||
|
import net.sf.openrocket.rocketcomponent.DeploymentConfiguration.DeployEvent;
|
||||||
import net.sf.openrocket.rocketcomponent.EllipticalFinSet;
|
import net.sf.openrocket.rocketcomponent.EllipticalFinSet;
|
||||||
import net.sf.openrocket.rocketcomponent.FinSet;
|
import net.sf.openrocket.rocketcomponent.FinSet;
|
||||||
import net.sf.openrocket.rocketcomponent.FreeformFinSet;
|
import net.sf.openrocket.rocketcomponent.FreeformFinSet;
|
||||||
@ -24,7 +25,6 @@ import net.sf.openrocket.rocketcomponent.MotorMount;
|
|||||||
import net.sf.openrocket.rocketcomponent.NoseCone;
|
import net.sf.openrocket.rocketcomponent.NoseCone;
|
||||||
import net.sf.openrocket.rocketcomponent.Parachute;
|
import net.sf.openrocket.rocketcomponent.Parachute;
|
||||||
import net.sf.openrocket.rocketcomponent.RecoveryDevice;
|
import net.sf.openrocket.rocketcomponent.RecoveryDevice;
|
||||||
import net.sf.openrocket.rocketcomponent.RecoveryDevice.DeployEvent;
|
|
||||||
import net.sf.openrocket.rocketcomponent.Rocket;
|
import net.sf.openrocket.rocketcomponent.Rocket;
|
||||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||||
import net.sf.openrocket.rocketcomponent.Streamer;
|
import net.sf.openrocket.rocketcomponent.Streamer;
|
||||||
@ -256,7 +256,7 @@ public class DefaultSimulationModifierService implements SimulationModifierServi
|
|||||||
mod.setMaxValue(10);
|
mod.setMaxValue(10);
|
||||||
modifiers.add(mod);
|
modifiers.add(mod);
|
||||||
|
|
||||||
if (device.getDeployEvent() == DeployEvent.ALTITUDE) {
|
if (device.getDefaultDeployEvent() == DeployEvent.ALTITUDE) {
|
||||||
mod = new GenericComponentModifier(
|
mod = new GenericComponentModifier(
|
||||||
trans.get("optimization.modifier.recoverydevice.deployAltitude"),
|
trans.get("optimization.modifier.recoverydevice.deployAltitude"),
|
||||||
trans.get("optimization.modifier.recoverydevice.deployAltitude.desc"),
|
trans.get("optimization.modifier.recoverydevice.deployAltitude.desc"),
|
||||||
|
@ -0,0 +1,138 @@
|
|||||||
|
package net.sf.openrocket.rocketcomponent;
|
||||||
|
|
||||||
|
import net.sf.openrocket.l10n.Translator;
|
||||||
|
import net.sf.openrocket.simulation.FlightEvent;
|
||||||
|
import net.sf.openrocket.startup.Application;
|
||||||
|
import net.sf.openrocket.unit.UnitGroup;
|
||||||
|
import net.sf.openrocket.util.Pair;
|
||||||
|
|
||||||
|
public class DeploymentConfiguration implements Cloneable {
|
||||||
|
|
||||||
|
private static final Translator trans = Application.getTranslator();
|
||||||
|
|
||||||
|
private DeployEvent deployEvent = DeployEvent.EJECTION;
|
||||||
|
private double deployAltitude = 200;
|
||||||
|
private double deployDelay = 0;
|
||||||
|
|
||||||
|
public boolean isActivationEvent( FlightEvent e, RocketComponent source ) {
|
||||||
|
return deployEvent.isActivationEvent(this, e, source);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DeployEvent getDeployEvent() {
|
||||||
|
return deployEvent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDeployEvent(DeployEvent deployEvent) {
|
||||||
|
this.deployEvent = deployEvent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getDeployAltitude() {
|
||||||
|
return deployAltitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDeployAltitude(double deployAltitude) {
|
||||||
|
this.deployAltitude = deployAltitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getDeployDelay() {
|
||||||
|
return deployDelay;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDeployDelay(double deployDelay) {
|
||||||
|
this.deployDelay = deployDelay;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
String description = deployEvent.toString();
|
||||||
|
if ( deployDelay > 0 ) {
|
||||||
|
description += " + " + deployDelay + "s";
|
||||||
|
}
|
||||||
|
if ( deployEvent == DeployEvent.ALTITUDE && deployAltitude != 0 ) {
|
||||||
|
description += " " + UnitGroup.UNITS_DISTANCE.fromUnit(deployAltitude);
|
||||||
|
}
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DeploymentConfiguration clone() {
|
||||||
|
DeploymentConfiguration that = new DeploymentConfiguration();
|
||||||
|
that.deployAltitude = this.deployAltitude;
|
||||||
|
that.deployDelay = this.deployDelay;
|
||||||
|
that.deployEvent = this.deployEvent;
|
||||||
|
return that;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static enum DeployEvent {
|
||||||
|
LAUNCH(trans.get("RecoveryDevice.DeployEvent.LAUNCH")) {
|
||||||
|
@Override
|
||||||
|
public boolean isActivationEvent(DeploymentConfiguration config, FlightEvent e, RocketComponent source) {
|
||||||
|
return e.getType() == FlightEvent.Type.LAUNCH;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
EJECTION(trans.get("RecoveryDevice.DeployEvent.EJECTION")) {
|
||||||
|
@Override
|
||||||
|
public boolean isActivationEvent(DeploymentConfiguration config, FlightEvent e, RocketComponent source) {
|
||||||
|
if (e.getType() != FlightEvent.Type.EJECTION_CHARGE)
|
||||||
|
return false;
|
||||||
|
RocketComponent charge = e.getSource();
|
||||||
|
return charge.getStageNumber() == source.getStageNumber();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
APOGEE(trans.get("RecoveryDevice.DeployEvent.APOGEE")) {
|
||||||
|
@Override
|
||||||
|
public boolean isActivationEvent(DeploymentConfiguration config, FlightEvent e, RocketComponent source) {
|
||||||
|
return e.getType() == FlightEvent.Type.APOGEE;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ALTITUDE(trans.get("RecoveryDevice.DeployEvent.ALTITUDE")) {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
public boolean isActivationEvent(DeploymentConfiguration config, FlightEvent e, RocketComponent source) {
|
||||||
|
if (e.getType() != FlightEvent.Type.ALTITUDE)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
double alt = config.deployAltitude;
|
||||||
|
Pair<Double, Double> altitude = (Pair<Double, Double>) e.getData();
|
||||||
|
|
||||||
|
return (altitude.getU() >= alt) && (altitude.getV() <= alt);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
LOWER_STAGE_SEPARATION(trans.get("RecoveryDevice.DeployEvent.LOWER_STAGE_SEPARATION")) {
|
||||||
|
@Override
|
||||||
|
public boolean isActivationEvent(DeploymentConfiguration config, FlightEvent e, RocketComponent source) {
|
||||||
|
if (e.getType() != FlightEvent.Type.STAGE_SEPARATION)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int separation = e.getSource().getStageNumber();
|
||||||
|
int current = source.getStageNumber();
|
||||||
|
return (current + 1 == separation);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
NEVER(trans.get("RecoveryDevice.DeployEvent.NEVER")) {
|
||||||
|
@Override
|
||||||
|
public boolean isActivationEvent(DeploymentConfiguration config, FlightEvent e, RocketComponent source) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private final String description;
|
||||||
|
|
||||||
|
DeployEvent(String description) {
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract boolean isActivationEvent(DeploymentConfiguration config, FlightEvent e, RocketComponent source);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -1,12 +1,14 @@
|
|||||||
package net.sf.openrocket.rocketcomponent;
|
package net.sf.openrocket.rocketcomponent;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import net.sf.openrocket.l10n.Translator;
|
import net.sf.openrocket.l10n.Translator;
|
||||||
import net.sf.openrocket.material.Material;
|
import net.sf.openrocket.material.Material;
|
||||||
import net.sf.openrocket.preset.ComponentPreset;
|
import net.sf.openrocket.preset.ComponentPreset;
|
||||||
import net.sf.openrocket.simulation.FlightEvent;
|
import net.sf.openrocket.rocketcomponent.DeploymentConfiguration.DeployEvent;
|
||||||
import net.sf.openrocket.startup.Application;
|
import net.sf.openrocket.startup.Application;
|
||||||
import net.sf.openrocket.util.MathUtil;
|
import net.sf.openrocket.util.MathUtil;
|
||||||
import net.sf.openrocket.util.Pair;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -24,78 +26,9 @@ import net.sf.openrocket.util.Pair;
|
|||||||
public abstract class RecoveryDevice extends MassObject {
|
public abstract class RecoveryDevice extends MassObject {
|
||||||
private static final Translator trans = Application.getTranslator();
|
private static final Translator trans = Application.getTranslator();
|
||||||
|
|
||||||
public static enum DeployEvent {
|
private Map<String,DeploymentConfiguration> deploymentConfigurations = new HashMap<String,DeploymentConfiguration>();
|
||||||
LAUNCH(trans.get("RecoveryDevice.DeployEvent.LAUNCH")) {
|
|
||||||
@Override
|
|
||||||
public boolean isActivationEvent(FlightEvent e, RocketComponent source) {
|
|
||||||
return e.getType() == FlightEvent.Type.LAUNCH;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
EJECTION(trans.get("RecoveryDevice.DeployEvent.EJECTION")) {
|
|
||||||
@Override
|
|
||||||
public boolean isActivationEvent(FlightEvent e, RocketComponent source) {
|
|
||||||
if (e.getType() != FlightEvent.Type.EJECTION_CHARGE)
|
|
||||||
return false;
|
|
||||||
RocketComponent charge = e.getSource();
|
|
||||||
return charge.getStageNumber() == source.getStageNumber();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
APOGEE(trans.get("RecoveryDevice.DeployEvent.APOGEE")) {
|
|
||||||
@Override
|
|
||||||
public boolean isActivationEvent(FlightEvent e, RocketComponent source) {
|
|
||||||
return e.getType() == FlightEvent.Type.APOGEE;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
ALTITUDE(trans.get("RecoveryDevice.DeployEvent.ALTITUDE")) {
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
@Override
|
|
||||||
public boolean isActivationEvent(FlightEvent e, RocketComponent source) {
|
|
||||||
if (e.getType() != FlightEvent.Type.ALTITUDE)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
double alt = ((RecoveryDevice) source).getDeployAltitude();
|
private DeploymentConfiguration defaultDeploymentConfig = new DeploymentConfiguration();
|
||||||
Pair<Double, Double> altitude = (Pair<Double, Double>) e.getData();
|
|
||||||
|
|
||||||
return (altitude.getU() >= alt) && (altitude.getV() <= alt);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
LOWER_STAGE_SEPARATION(trans.get("RecoveryDevice.DeployEvent.LOWER_STAGE_SEPARATION")) {
|
|
||||||
@Override
|
|
||||||
public boolean isActivationEvent(FlightEvent e, RocketComponent source) {
|
|
||||||
if (e.getType() != FlightEvent.Type.STAGE_SEPARATION)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
int separation = e.getSource().getStageNumber();
|
|
||||||
int current = source.getStageNumber();
|
|
||||||
return (current + 1 == separation);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
NEVER(trans.get("RecoveryDevice.DeployEvent.NEVER")) {
|
|
||||||
@Override
|
|
||||||
public boolean isActivationEvent(FlightEvent e, RocketComponent source) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private final String description;
|
|
||||||
|
|
||||||
DeployEvent(String description) {
|
|
||||||
this.description = description;
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract boolean isActivationEvent(FlightEvent e, RocketComponent source);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return description;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private DeployEvent deployEvent = DeployEvent.EJECTION;
|
|
||||||
private double deployAltitude = 200;
|
|
||||||
private double deployDelay = 0;
|
|
||||||
|
|
||||||
private double cd = Parachute.DEFAULT_CD;
|
private double cd = Parachute.DEFAULT_CD;
|
||||||
private boolean cdAutomatic = true;
|
private boolean cdAutomatic = true;
|
||||||
@ -175,44 +108,61 @@ public abstract class RecoveryDevice extends MassObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the deployment configuration for this configurationId or null if using default.
|
||||||
public DeployEvent getDeployEvent() {
|
*
|
||||||
return deployEvent;
|
* @param configID
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public DeploymentConfiguration getDeploymentConfiguration( String configID ) {
|
||||||
|
DeploymentConfiguration config = deploymentConfigurations.get(configID);
|
||||||
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDeployEvent(DeployEvent deployEvent) {
|
public DeploymentConfiguration getDefaultDeploymentConfiguration() {
|
||||||
if (this.deployEvent == deployEvent)
|
return defaultDeploymentConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDeploymentConfiguration( String configID, DeploymentConfiguration config ) {
|
||||||
|
deploymentConfigurations.put(configID, config);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DeployEvent getDefaultDeployEvent() {
|
||||||
|
return defaultDeploymentConfig.getDeployEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDefaultDeployEvent(DeployEvent deployEvent) {
|
||||||
|
if (this.defaultDeploymentConfig.getDeployEvent() == deployEvent)
|
||||||
return;
|
return;
|
||||||
this.deployEvent = deployEvent;
|
this.defaultDeploymentConfig.setDeployEvent(deployEvent);
|
||||||
fireComponentChangeEvent(ComponentChangeEvent.EVENT_CHANGE);
|
fireComponentChangeEvent(ComponentChangeEvent.EVENT_CHANGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public double getDeployAltitude() {
|
public double getDefaultDeployAltitude() {
|
||||||
return deployAltitude;
|
return defaultDeploymentConfig.getDeployAltitude();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDeployAltitude(double deployAltitude) {
|
public void setDefaultDeployAltitude(double deployAltitude) {
|
||||||
if (MathUtil.equals(this.deployAltitude, deployAltitude))
|
if (MathUtil.equals(getDefaultDeployAltitude(), deployAltitude))
|
||||||
return;
|
return;
|
||||||
this.deployAltitude = deployAltitude;
|
defaultDeploymentConfig.setDeployAltitude(deployAltitude);
|
||||||
if (getDeployEvent() == DeployEvent.ALTITUDE)
|
if (getDefaultDeployEvent() == DeployEvent.ALTITUDE)
|
||||||
fireComponentChangeEvent(ComponentChangeEvent.EVENT_CHANGE);
|
fireComponentChangeEvent(ComponentChangeEvent.EVENT_CHANGE);
|
||||||
else
|
else
|
||||||
fireComponentChangeEvent(ComponentChangeEvent.NONFUNCTIONAL_CHANGE);
|
fireComponentChangeEvent(ComponentChangeEvent.NONFUNCTIONAL_CHANGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public double getDeployDelay() {
|
public double getDefaultDeployDelay() {
|
||||||
return deployDelay;
|
return defaultDeploymentConfig.getDeployDelay();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDeployDelay(double delay) {
|
public void setDefaultDeployDelay(double delay) {
|
||||||
delay = MathUtil.max(delay, 0);
|
delay = MathUtil.max(delay, 0);
|
||||||
if (MathUtil.equals(this.deployDelay, delay))
|
if (MathUtil.equals(getDefaultDeployDelay(), delay))
|
||||||
return;
|
return;
|
||||||
this.deployDelay = delay;
|
defaultDeploymentConfig.setDeployDelay(delay);
|
||||||
fireComponentChangeEvent(ComponentChangeEvent.EVENT_CHANGE);
|
fireComponentChangeEvent(ComponentChangeEvent.EVENT_CHANGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ import net.sf.openrocket.motor.MotorId;
|
|||||||
import net.sf.openrocket.motor.MotorInstance;
|
import net.sf.openrocket.motor.MotorInstance;
|
||||||
import net.sf.openrocket.motor.MotorInstanceConfiguration;
|
import net.sf.openrocket.motor.MotorInstanceConfiguration;
|
||||||
import net.sf.openrocket.rocketcomponent.Configuration;
|
import net.sf.openrocket.rocketcomponent.Configuration;
|
||||||
|
import net.sf.openrocket.rocketcomponent.DeploymentConfiguration;
|
||||||
import net.sf.openrocket.rocketcomponent.LaunchLug;
|
import net.sf.openrocket.rocketcomponent.LaunchLug;
|
||||||
import net.sf.openrocket.rocketcomponent.MotorMount;
|
import net.sf.openrocket.rocketcomponent.MotorMount;
|
||||||
import net.sf.openrocket.rocketcomponent.RecoveryDevice;
|
import net.sf.openrocket.rocketcomponent.RecoveryDevice;
|
||||||
@ -43,6 +44,8 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
|||||||
|
|
||||||
private SimulationStatus status;
|
private SimulationStatus status;
|
||||||
|
|
||||||
|
private String flightConfigurationId;
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FlightData simulate(SimulationConditions simulationConditions) throws SimulationException {
|
public FlightData simulate(SimulationConditions simulationConditions) throws SimulationException {
|
||||||
@ -53,6 +56,7 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
|||||||
|
|
||||||
// Set up rocket configuration
|
// Set up rocket configuration
|
||||||
Configuration configuration = setupConfiguration(simulationConditions);
|
Configuration configuration = setupConfiguration(simulationConditions);
|
||||||
|
flightConfigurationId = configuration.getMotorConfigurationID();
|
||||||
MotorInstanceConfiguration motorConfiguration = setupMotorConfiguration(configuration);
|
MotorInstanceConfiguration motorConfiguration = setupMotorConfiguration(configuration);
|
||||||
if (motorConfiguration.getMotorIDs().isEmpty()) {
|
if (motorConfiguration.getMotorIDs().isEmpty()) {
|
||||||
throw new MotorIgnitionException("No motors defined in the simulation.");
|
throw new MotorIgnitionException("No motors defined in the simulation.");
|
||||||
@ -371,10 +375,14 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
|||||||
RocketComponent c = rci.next();
|
RocketComponent c = rci.next();
|
||||||
if (!(c instanceof RecoveryDevice))
|
if (!(c instanceof RecoveryDevice))
|
||||||
continue;
|
continue;
|
||||||
if (((RecoveryDevice) c).getDeployEvent().isActivationEvent(event, c)) {
|
DeploymentConfiguration deployConfig = ((RecoveryDevice) c).getDeploymentConfiguration(flightConfigurationId);
|
||||||
|
if ( deployConfig == null ) {
|
||||||
|
deployConfig = ((RecoveryDevice) c).getDefaultDeploymentConfiguration();
|
||||||
|
}
|
||||||
|
if (deployConfig.isActivationEvent(event, c)) {
|
||||||
// Delay event by at least 1ms to allow stage separation to occur first
|
// Delay event by at least 1ms to allow stage separation to occur first
|
||||||
addEvent(new FlightEvent(FlightEvent.Type.RECOVERY_DEVICE_DEPLOYMENT,
|
addEvent(new FlightEvent(FlightEvent.Type.RECOVERY_DEVICE_DEPLOYMENT,
|
||||||
event.getTime() + Math.max(0.001, ((RecoveryDevice) c).getDeployDelay()), c));
|
event.getTime() + Math.max(0.001, deployConfig.getDeployDelay()), c));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user