Merge branch 'master' into Configure-wind-direction

This commit is contained in:
Craig Earls 2014-12-21 19:00:30 -07:00
commit 5e9eca3715
10 changed files with 161 additions and 20 deletions

View File

@ -265,6 +265,8 @@ pref.dlg.opengl.lbl.useFBO = Use Off-screen Rendering
pref.dlg.lbl.Positiontoinsert = Position to insert new body components: pref.dlg.lbl.Positiontoinsert = Position to insert new body components:
pref.dlg.lbl.Confirmdeletion = Confirm deletion of simulations: pref.dlg.lbl.Confirmdeletion = Confirm deletion of simulations:
pref.dlg.checkbox.Runsimulations = Run out-dated simulations when you open the simulation tab.
pref.dlg.checkbox.Updateestimates = Update estimated flight parameters in design window
pref.dlg.lbl.User-definedthrust = User-defined thrust curves: pref.dlg.lbl.User-definedthrust = User-defined thrust curves:
pref.dlg.lbl.Windspeed = Wind speed pref.dlg.lbl.Windspeed = Wind speed
pref.dlg.Allthrustcurvefiles = All thrust curve files (*.eng; *.rse; *.zip; directories) pref.dlg.Allthrustcurvefiles = All thrust curve files (*.eng; *.rse; *.zip; directories)

View File

@ -2,6 +2,7 @@ package net.sf.openrocket.document;
import java.util.EventListener; import java.util.EventListener;
import java.util.EventObject; import java.util.EventObject;
import java.util.Iterator;
import java.util.List; import java.util.List;
import net.sf.openrocket.aerodynamics.AerodynamicCalculator; import net.sf.openrocket.aerodynamics.AerodynamicCalculator;
@ -10,8 +11,14 @@ import net.sf.openrocket.aerodynamics.WarningSet;
import net.sf.openrocket.formatting.RocketDescriptor; import net.sf.openrocket.formatting.RocketDescriptor;
import net.sf.openrocket.masscalc.BasicMassCalculator; import net.sf.openrocket.masscalc.BasicMassCalculator;
import net.sf.openrocket.masscalc.MassCalculator; import net.sf.openrocket.masscalc.MassCalculator;
import net.sf.openrocket.motor.Motor;
import net.sf.openrocket.motor.MotorInstanceConfiguration;
import net.sf.openrocket.rocketcomponent.Configuration; import net.sf.openrocket.rocketcomponent.Configuration;
import net.sf.openrocket.rocketcomponent.IgnitionConfiguration;
import net.sf.openrocket.rocketcomponent.MotorConfiguration;
import net.sf.openrocket.rocketcomponent.MotorMount;
import net.sf.openrocket.rocketcomponent.Rocket; import net.sf.openrocket.rocketcomponent.Rocket;
import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.simulation.BasicEventSimulationEngine; import net.sf.openrocket.simulation.BasicEventSimulationEngine;
import net.sf.openrocket.simulation.DefaultSimulationOptionFactory; import net.sf.openrocket.simulation.DefaultSimulationOptionFactory;
import net.sf.openrocket.simulation.FlightData; import net.sf.openrocket.simulation.FlightData;
@ -58,7 +65,10 @@ public class Simulation implements ChangeSource, Cloneable {
EXTERNAL, EXTERNAL,
/** Not yet simulated */ /** Not yet simulated */
NOT_SIMULATED NOT_SIMULATED,
/** Can't be simulated, NO_MOTORS **/
CANT_RUN
} }
private RocketDescriptor descriptor = Application.getInjector().getInstance(RocketDescriptor.class); private RocketDescriptor descriptor = Application.getInjector().getInstance(RocketDescriptor.class);
@ -250,13 +260,35 @@ public class Simulation implements ChangeSource, Cloneable {
*/ */
public Status getStatus() { public Status getStatus() {
mutex.verify(); mutex.verify();
if (status == Status.UPTODATE || status == Status.LOADED) { if (status == Status.UPTODATE || status == Status.LOADED) {
if (rocket.getFunctionalModID() != simulatedRocketID || if (rocket.getFunctionalModID() != simulatedRocketID || !options.equals(simulatedConditions)) {
!options.equals(simulatedConditions)) status = Status.OUTDATED;
return Status.OUTDATED; }
} }
//Make sure this simulation has motors.
Configuration c = new Configuration(this.getRocket());
MotorInstanceConfiguration motors = new MotorInstanceConfiguration();
c.setFlightConfigurationID(options.getMotorConfigurationID());
final String flightConfigId = c.getFlightConfigurationID();
Iterator<MotorMount> iterator = c.motorIterator();
boolean no_motors = true;
while (iterator.hasNext()) {
MotorMount mount = iterator.next();
RocketComponent component = (RocketComponent) mount;
MotorConfiguration motorConfig = mount.getMotorConfiguration().get(flightConfigId);
IgnitionConfiguration ignitionConfig = mount.getIgnitionConfiguration().get(flightConfigId);
Motor motor = motorConfig.getMotor();
if (motor != null)
no_motors = false;
}
if (no_motors)
status = Status.CANT_RUN;
return status; return status;
} }

View File

@ -43,8 +43,8 @@ public class BasicEventSimulationEngine implements SimulationEngine {
private SimulationStepper landingStepper = new BasicLandingStepper(); private SimulationStepper landingStepper = new BasicLandingStepper();
private SimulationStepper tumbleStepper = new BasicTumbleStepper(); private SimulationStepper tumbleStepper = new BasicTumbleStepper();
// Constant holding 20 degress in radians. This is the AOA condition // Constant holding 20 degrees in radians. This is the AOA condition
// necessary to transistion to tumbling. // necessary to transition to tumbling.
private final static double AOA_TUMBLE_CONDITION = Math.PI / 9.0; private final static double AOA_TUMBLE_CONDITION = Math.PI / 9.0;
// The thrust must be below this value for the transition to tumbling. // The thrust must be below this value for the transition to tumbling.

View File

@ -30,6 +30,8 @@ public abstract class Preferences {
public static final String BODY_COMPONENT_INSERT_POSITION_KEY = "BodyComponentInsertPosition"; public static final String BODY_COMPONENT_INSERT_POSITION_KEY = "BodyComponentInsertPosition";
public static final String USER_THRUST_CURVES_KEY = "UserThrustCurves"; public static final String USER_THRUST_CURVES_KEY = "UserThrustCurves";
public static final String CONFIRM_DELETE_SIMULATION = "ConfirmDeleteSimulation"; public static final String CONFIRM_DELETE_SIMULATION = "ConfirmDeleteSimulation";
public static final String AUTO_RUN_SIMULATIONS = "AutoRunSimulations";
// Preferences related to data export // Preferences related to data export
public static final String EXPORT_FIELD_SEPARATOR = "ExportFieldSeparator"; public static final String EXPORT_FIELD_SEPARATOR = "ExportFieldSeparator";
public static final String EXPORT_SIMULATION_COMMENT = "ExportSimulationComment"; public static final String EXPORT_SIMULATION_COMMENT = "ExportSimulationComment";
@ -101,6 +103,14 @@ public abstract class Preferences {
this.putBoolean(CHECK_UPDATES, check); this.putBoolean(CHECK_UPDATES, check);
} }
public final boolean getAutoRunSimulations() {
return this.getBoolean(AUTO_RUN_SIMULATIONS, false);
}
public final void setAutoRunSimulations(boolean check) {
this.putBoolean(AUTO_RUN_SIMULATIONS, check);
}
public final double getDefaultMach() { public final double getDefaultMach() {
// TODO: HIGH: implement custom default mach number // TODO: HIGH: implement custom default mach number
return 0.3; return 0.3;

View File

@ -295,6 +295,7 @@ public class PreferencesDialog extends JDialog {
//// Check for software updates at startup //// Check for software updates at startup
final JCheckBox softwareUpdateBox = final JCheckBox softwareUpdateBox =
new JCheckBox(trans.get("pref.dlg.checkbox.Checkupdates")); new JCheckBox(trans.get("pref.dlg.checkbox.Checkupdates"));
@ -327,7 +328,31 @@ public class PreferencesDialog extends JDialog {
preferences.setAutoOpenLastDesignOnStartup(autoOpenDesignFile.isSelected()); preferences.setAutoOpenLastDesignOnStartup(autoOpenDesignFile.isSelected());
} }
}); });
panel.add(autoOpenDesignFile); panel.add(autoOpenDesignFile, "wrap, growx, span 2");
//// Automatically run all simulation out-dated by design changes.
final JCheckBox automaticallyRunSimsBox =
new JCheckBox(trans.get("pref.dlg.checkbox.Runsimulations"));
automaticallyRunSimsBox.setSelected(preferences.getAutoRunSimulations());
automaticallyRunSimsBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
preferences.setAutoRunSimulations(automaticallyRunSimsBox.isSelected());
}
});
panel.add(automaticallyRunSimsBox, "wrap, growx, sg combos ");
//// Update flight estimates in the design window
final JCheckBox updateEstimates =
new JCheckBox(trans.get("pref.dlg.checkbox.Updateestimates"));
updateEstimates.setSelected(preferences.computeFlightInBackground());
updateEstimates.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
preferences.setComputeFlightInBackground(updateEstimates.isSelected());
}
});
panel.add(updateEstimates, "wrap, growx, sg combos ");
return panel; return panel;
} }

View File

@ -54,6 +54,7 @@ import javax.swing.border.BevelBorder;
import javax.swing.border.TitledBorder; import javax.swing.border.TitledBorder;
import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener; import javax.swing.event.TreeSelectionListener;
import javax.swing.event.ChangeEvent;
import javax.swing.tree.DefaultTreeSelectionModel; import javax.swing.tree.DefaultTreeSelectionModel;
import javax.swing.tree.TreePath; import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel; import javax.swing.tree.TreeSelectionModel;
@ -153,7 +154,7 @@ public class BasicFrame extends JFrame {
/** Actions available for rocket modifications */ /** Actions available for rocket modifications */
private final RocketActions actions; private final RocketActions actions;
private SimulationPanel simulationPanel;
/** /**
@ -174,7 +175,7 @@ public class BasicFrame extends JFrame {
componentSelectionModel.setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); componentSelectionModel.setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
// Obtain the simulation selection model that will be used // Obtain the simulation selection model that will be used
SimulationPanel simulationPanel = new SimulationPanel(document); simulationPanel = new SimulationPanel(document);
simulationSelectionModel = simulationPanel.getSimulationListSelectionModel(); simulationSelectionModel = simulationPanel.getSimulationListSelectionModel();
// Combine into a DocumentSelectionModel // Combine into a DocumentSelectionModel
@ -203,6 +204,11 @@ public class BasicFrame extends JFrame {
//// Flight simulations //// Flight simulations
tabbedPane.addTab(trans.get("BasicFrame.tab.Flightsim"), null, simulationPanel); tabbedPane.addTab(trans.get("BasicFrame.tab.Flightsim"), null, simulationPanel);
// Add change listener to catch when the tabs are changed. This is to run simulations
// automagically when the simulation tab is selected.
tabbedPane.addChangeListener(new BasicFrame_changeAdapter(this));
vertical.setTopComponent(tabbedPane); vertical.setTopComponent(tabbedPane);
@ -1553,4 +1559,24 @@ public class BasicFrame extends JFrame {
return null; return null;
} }
} }
public void stateChanged(ChangeEvent e) {
JTabbedPane tabSource = (JTabbedPane) e.getSource();
String tab = tabSource.getTitleAt(tabSource.getSelectedIndex());
if (tab.equals(trans.get("BasicFrame.tab.Flightsim"))) {
simulationPanel.activating();
}
}
}
class BasicFrame_changeAdapter implements javax.swing.event.ChangeListener {
BasicFrame adaptee;
BasicFrame_changeAdapter(BasicFrame adaptee) {
this.adaptee = adaptee;
}
public void stateChanged(ChangeEvent e) {
adaptee.stateChanged(e);
}
} }

View File

@ -44,6 +44,7 @@ import net.sf.openrocket.gui.simulation.SimulationEditDialog;
import net.sf.openrocket.gui.simulation.SimulationRunDialog; import net.sf.openrocket.gui.simulation.SimulationRunDialog;
import net.sf.openrocket.gui.simulation.SimulationWarningDialog; import net.sf.openrocket.gui.simulation.SimulationWarningDialog;
import net.sf.openrocket.gui.util.Icons; import net.sf.openrocket.gui.util.Icons;
import net.sf.openrocket.gui.util.SwingPreferences;
import net.sf.openrocket.l10n.Translator; import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.rocketcomponent.ComponentChangeEvent; import net.sf.openrocket.rocketcomponent.ComponentChangeEvent;
import net.sf.openrocket.rocketcomponent.ComponentChangeListener; import net.sf.openrocket.rocketcomponent.ComponentChangeListener;
@ -586,6 +587,44 @@ public class SimulationPanel extends JPanel {
} }
/// when the simulation tab is selected this run outdated simulated if appropriate.
public void activating(){
if( ((Preferences) Application.getPreferences()).getAutoRunSimulations()){
int nSims = simulationTable.getRowCount();
int outdated = 0;
if (nSims == 0) {
return;
}
for (int i = 0; i < nSims; i++) {
Simulation.Status s = document.getSimulation(simulationTable.convertRowIndexToModel(i)).getStatus();
if((s==Simulation.Status.NOT_SIMULATED) ||
(s==Simulation.Status.OUTDATED)){
outdated++;
}
}
if(outdated>0){
Simulation[] sims = new Simulation[outdated];
int index=0;
for (int i = 0; i < nSims; i++) {
int t = simulationTable.convertRowIndexToModel(i);
Simulation s = document.getSimulation(t);
if((s.getStatus()==Status.NOT_SIMULATED)||(s.getStatus()==Status.OUTDATED)){
sims[index] = s;
index++;
}
}
long t = System.currentTimeMillis();
new SimulationRunDialog(SwingUtilities.getWindowAncestor(
SimulationPanel.this), document, sims).setVisible(true);
log.info("Running simulations took " + (System.currentTimeMillis() - t) + " ms");
fireMaintainSelection();
}
}
}
public ListSelectionModel getSimulationListSelectionModel() { public ListSelectionModel getSimulationListSelectionModel() {
return simulationTable.getSelectionModel(); return simulationTable.getSelectionModel();
} }

View File

@ -699,15 +699,17 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
} }
// Start calculation process // Start calculation process
extraText.setCalculatingData(true); if(((SwingPreferences) Application.getPreferences()).computeFlightInBackground()){
extraText.setCalculatingData(true);
Rocket duplicate = (Rocket) configuration.getRocket().copy(); Rocket duplicate = (Rocket) configuration.getRocket().copy();
Simulation simulation = ((SwingPreferences) Application.getPreferences()).getBackgroundSimulation(duplicate); Simulation simulation = ((SwingPreferences) Application.getPreferences()).getBackgroundSimulation(duplicate);
simulation.getOptions().setMotorConfigurationID( simulation.getOptions().setMotorConfigurationID(
configuration.getFlightConfigurationID()); configuration.getFlightConfigurationID());
backgroundSimulationWorker = new BackgroundSimulationWorker(document, simulation); backgroundSimulationWorker = new BackgroundSimulationWorker(document, simulation);
backgroundSimulationExecutor.execute(backgroundSimulationWorker); backgroundSimulationExecutor.execute(backgroundSimulationWorker);
}
} }
/** /**

View File

@ -31,6 +31,7 @@ public class Icons {
static { static {
HashMap<Simulation.Status, Icon> map = new HashMap<Simulation.Status, Icon>(); HashMap<Simulation.Status, Icon> map = new HashMap<Simulation.Status, Icon>();
map.put(Simulation.Status.NOT_SIMULATED, loadImageIcon("pix/spheres/gray-16x16.png", "Not simulated")); map.put(Simulation.Status.NOT_SIMULATED, loadImageIcon("pix/spheres/gray-16x16.png", "Not simulated"));
map.put(Simulation.Status.CANT_RUN, loadImageIcon("pix/spheres/yellow-16x16.png", "Can't run, no motors assigned."));
map.put(Simulation.Status.UPTODATE, loadImageIcon("pix/spheres/green-16x16.png", "Up to date")); map.put(Simulation.Status.UPTODATE, loadImageIcon("pix/spheres/green-16x16.png", "Up to date"));
map.put(Simulation.Status.LOADED, loadImageIcon("pix/spheres/yellow-16x16.png", "Loaded from file")); map.put(Simulation.Status.LOADED, loadImageIcon("pix/spheres/yellow-16x16.png", "Loaded from file"));
map.put(Simulation.Status.OUTDATED, loadImageIcon("pix/spheres/red-16x16.png", "Out-of-date")); map.put(Simulation.Status.OUTDATED, loadImageIcon("pix/spheres/red-16x16.png", "Out-of-date"));

View File

@ -419,6 +419,10 @@ public class SwingPreferences extends net.sf.openrocket.startup.Preferences {
return PREFNODE.getBoolean("backgroundFlight", true); return PREFNODE.getBoolean("backgroundFlight", true);
} }
public void setComputeFlightInBackground(boolean b) {
PREFNODE.putBoolean("backgroundFlight", b);
}
public Simulation getBackgroundSimulation(Rocket rocket) { public Simulation getBackgroundSimulation(Rocket rocket) {
Simulation s = new Simulation(rocket); Simulation s = new Simulation(rocket);
SimulationOptions cond = s.getOptions(); SimulationOptions cond = s.getOptions();