Merge pull request #952 from SiboVG/issue-927
[fixes #927 & #771] Fix auto-run simulation NA values
This commit is contained in:
commit
a513c676de
@ -810,7 +810,7 @@ public class OpenRocketDocument implements ComponentChangeListener {
|
|||||||
listeners.remove(listener);
|
listeners.remove(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void fireDocumentChangeEvent(DocumentChangeEvent event) {
|
public void fireDocumentChangeEvent(DocumentChangeEvent event) {
|
||||||
DocumentChangeListener[] array = listeners.toArray(new DocumentChangeListener[0]);
|
DocumentChangeListener[] array = listeners.toArray(new DocumentChangeListener[0]);
|
||||||
for (DocumentChangeListener l : array) {
|
for (DocumentChangeListener l : array) {
|
||||||
l.documentChanged(event);
|
l.documentChanged(event);
|
||||||
|
|||||||
@ -18,10 +18,20 @@ public abstract class InterpolatingAtmosphericModel implements AtmosphericModel
|
|||||||
if (levels == null)
|
if (levels == null)
|
||||||
computeLayers();
|
computeLayers();
|
||||||
|
|
||||||
if (altitude <= 0)
|
if (altitude <= 0) {
|
||||||
|
// TODO: LOW: levels[0] returned null in some cases, see GitHub issue #952 for more information
|
||||||
|
if (levels[0] == null) {
|
||||||
|
computeLayers();
|
||||||
|
}
|
||||||
return levels[0];
|
return levels[0];
|
||||||
if (altitude >= DELTA * (levels.length - 1))
|
}
|
||||||
|
if (altitude >= DELTA * (levels.length - 1)) {
|
||||||
|
// TODO: LOW: levels[levels.length - 1] returned null in some cases, see GitHub issue #952 for more information
|
||||||
|
if (levels[levels.length - 1] == null) {
|
||||||
|
computeLayers();
|
||||||
|
}
|
||||||
return levels[levels.length - 1];
|
return levels[levels.length - 1];
|
||||||
|
}
|
||||||
|
|
||||||
int n = (int) (altitude / DELTA);
|
int n = (int) (altitude / DELTA);
|
||||||
double d = (altitude - n * DELTA) / DELTA;
|
double d = (altitude - n * DELTA) / DELTA;
|
||||||
|
|||||||
@ -115,6 +115,8 @@ public class MotorConfiguration implements FlightConfigurableParameter<MotorConf
|
|||||||
|
|
||||||
public void useDefaultIgnition() {
|
public void useDefaultIgnition() {
|
||||||
this.ignitionOveride = false;
|
this.ignitionOveride = false;
|
||||||
|
setIgnitionDelay(0);
|
||||||
|
setIgnitionEvent(IgnitionEvent.AUTOMATIC);
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getIgnitionDelay() {
|
public double getIgnitionDelay() {
|
||||||
|
|||||||
@ -8,6 +8,8 @@ import net.sf.openrocket.unit.UnitGroup;
|
|||||||
import net.sf.openrocket.util.MathUtil;
|
import net.sf.openrocket.util.MathUtil;
|
||||||
import net.sf.openrocket.util.Pair;
|
import net.sf.openrocket.util.Pair;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
public class DeploymentConfiguration implements FlightConfigurableParameter<DeploymentConfiguration> {
|
public class DeploymentConfiguration implements FlightConfigurableParameter<DeploymentConfiguration> {
|
||||||
|
|
||||||
|
|
||||||
@ -155,4 +157,16 @@ public class DeploymentConfiguration implements FlightConfigurableParameter<Depl
|
|||||||
public void update(){
|
public void update(){
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
DeploymentConfiguration that = (DeploymentConfiguration) o;
|
||||||
|
return Double.compare(that.deployAltitude, deployAltitude) == 0 && Double.compare(that.deployDelay, deployDelay) == 0 && deployEvent == that.deployEvent;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(deployEvent, deployAltitude, deployDelay);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -5,6 +5,8 @@ import net.sf.openrocket.simulation.FlightEvent;
|
|||||||
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 java.util.Objects;
|
||||||
|
|
||||||
public class StageSeparationConfiguration implements FlightConfigurableParameter<StageSeparationConfiguration> {
|
public class StageSeparationConfiguration implements FlightConfigurableParameter<StageSeparationConfiguration> {
|
||||||
|
|
||||||
public static enum SeparationEvent {
|
public static enum SeparationEvent {
|
||||||
@ -145,6 +147,18 @@ public class StageSeparationConfiguration implements FlightConfigurableParameter
|
|||||||
return clone;
|
return clone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
StageSeparationConfiguration that = (StageSeparationConfiguration) o;
|
||||||
|
return Double.compare(that.separationDelay, separationDelay) == 0 && separationEvent == that.separationEvent;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(separationEvent, separationDelay);
|
||||||
|
}
|
||||||
|
|
||||||
private void fireChangeEvent() {
|
private void fireChangeEvent() {
|
||||||
|
|
||||||
|
|||||||
@ -300,7 +300,7 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
|||||||
// Ignore events for components that are no longer attached to the rocket
|
// Ignore events for components that are no longer attached to the rocket
|
||||||
if (event.getSource() != null && event.getSource().getParent() != null &&
|
if (event.getSource() != null && event.getSource().getParent() != null &&
|
||||||
!currentStatus.getConfiguration().isComponentActive(event.getSource())) {
|
!currentStatus.getConfiguration().isComponentActive(event.getSource())) {
|
||||||
log.trace("Ignoring event from unattached componenent");
|
log.trace("Ignoring event from unattached component");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -332,6 +332,7 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
|||||||
|
|
||||||
|
|
||||||
// Check for recovery device deployment, add events to queue
|
// Check for recovery device deployment, add events to queue
|
||||||
|
// TODO: LOW: check if deprecated function getActiveComponents needs to be replaced
|
||||||
for (RocketComponent c : currentStatus.getConfiguration().getActiveComponents()) {
|
for (RocketComponent c : currentStatus.getConfiguration().getActiveComponents()) {
|
||||||
if (!(c instanceof RecoveryDevice))
|
if (!(c instanceof RecoveryDevice))
|
||||||
continue;
|
continue;
|
||||||
@ -533,6 +534,7 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO : FUTURE : do not hard code the 1200 (maybe even make it configurable by the user)
|
||||||
if( 1200 < currentStatus.getSimulationTime() ){
|
if( 1200 < currentStatus.getSimulationTime() ){
|
||||||
ret = false;
|
ret = false;
|
||||||
log.error("Simulation hit max time (1200s): aborting.");
|
log.error("Simulation hit max time (1200s): aborting.");
|
||||||
|
|||||||
@ -220,7 +220,7 @@ public class FlightData {
|
|||||||
timeToApogee = Double.NaN;
|
timeToApogee = Double.NaN;
|
||||||
|
|
||||||
|
|
||||||
// Launch rod velocity
|
// Launch rod velocity + deployment velocity + ground hit velocity
|
||||||
for (FlightEvent event : branch.getEvents()) {
|
for (FlightEvent event : branch.getEvents()) {
|
||||||
if (event.getType() == FlightEvent.Type.LAUNCHROD) {
|
if (event.getType() == FlightEvent.Type.LAUNCHROD) {
|
||||||
double t = event.getTime();
|
double t = event.getTime();
|
||||||
|
|||||||
@ -0,0 +1,29 @@
|
|||||||
|
package net.sf.openrocket.simulation.listeners.system;
|
||||||
|
|
||||||
|
import net.sf.openrocket.simulation.FlightEvent;
|
||||||
|
import net.sf.openrocket.simulation.SimulationStatus;
|
||||||
|
import net.sf.openrocket.simulation.listeners.AbstractSimulationListener;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A simulation listeners that ends the simulation when the ground is hit.
|
||||||
|
*
|
||||||
|
* @author Sibo Van Gool <sibo.vangool@hotmail.com>
|
||||||
|
*/
|
||||||
|
public class GroundHitListener extends AbstractSimulationListener {
|
||||||
|
|
||||||
|
public static final GroundHitListener INSTANCE = new GroundHitListener();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handleFlightEvent(SimulationStatus status, FlightEvent event) {
|
||||||
|
if (event.getType() == FlightEvent.Type.GROUND_HIT) {
|
||||||
|
status.getEventQueue().add(new FlightEvent(FlightEvent.Type.SIMULATION_END, status.getSimulationTime()));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSystemListener() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -221,7 +221,7 @@ public class BasicFrame extends JFrame {
|
|||||||
|
|
||||||
// Bottom segment, rocket figure
|
// Bottom segment, rocket figure
|
||||||
|
|
||||||
rocketpanel = new RocketPanel(document);
|
rocketpanel = new RocketPanel(document, this);
|
||||||
vertical.setBottomComponent(rocketpanel);
|
vertical.setBottomComponent(rocketpanel);
|
||||||
|
|
||||||
rocketpanel.setSelectionModel(tree.getSelectionModel());
|
rocketpanel.setSelectionModel(tree.getSelectionModel());
|
||||||
@ -1099,6 +1099,9 @@ public class BasicFrame extends JFrame {
|
|||||||
tabbedPane.setSelectedIndex(tab);
|
tabbedPane.setSelectedIndex(tab);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getSelectedTab() {
|
||||||
|
return tabbedPane.getSelectedIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private void openAction() {
|
private void openAction() {
|
||||||
|
|||||||
@ -576,7 +576,7 @@ public class SimulationPanel extends JPanel {
|
|||||||
public void documentChanged(DocumentChangeEvent event) {
|
public void documentChanged(DocumentChangeEvent event) {
|
||||||
if (!(event instanceof SimulationChangeEvent))
|
if (!(event instanceof SimulationChangeEvent))
|
||||||
return;
|
return;
|
||||||
simulationTableModel.fireTableDataChanged();
|
fireMaintainSelection();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -54,10 +54,14 @@ public abstract class FlightConfigurablePanel<T extends FlightConfigurableCompon
|
|||||||
synchronizeConfigurationSelection();
|
synchronizeConfigurationSelection();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void fireTableDataChanged() {
|
/**
|
||||||
|
* Update the data in the table, with component change event type {cce}
|
||||||
|
* @param cce index of the ComponentChangeEvent to use (e.g. ComponentChangeEvent.NONFUNCTIONAL_CHANGE)
|
||||||
|
*/
|
||||||
|
public void fireTableDataChanged(int cce) {
|
||||||
int selectedRow = table.getSelectedRow();
|
int selectedRow = table.getSelectedRow();
|
||||||
int selectedColumn = table.getSelectedColumn();
|
int selectedColumn = table.getSelectedColumn();
|
||||||
this.rocket.fireComponentChangeEvent(ComponentChangeEvent.NONFUNCTIONAL_CHANGE);
|
this.rocket.fireComponentChangeEvent(cce);
|
||||||
((AbstractTableModel)table.getModel()).fireTableDataChanged();
|
((AbstractTableModel)table.getModel()).fireTableDataChanged();
|
||||||
restoreSelection(selectedRow,selectedColumn);
|
restoreSelection(selectedRow,selectedColumn);
|
||||||
updateButtonState();
|
updateButtonState();
|
||||||
|
|||||||
@ -15,6 +15,7 @@ import net.sf.openrocket.document.Simulation;
|
|||||||
import net.sf.openrocket.gui.dialogs.flightconfiguration.RenameConfigDialog;
|
import net.sf.openrocket.gui.dialogs.flightconfiguration.RenameConfigDialog;
|
||||||
import net.sf.openrocket.gui.main.BasicFrame;
|
import net.sf.openrocket.gui.main.BasicFrame;
|
||||||
import net.sf.openrocket.l10n.Translator;
|
import net.sf.openrocket.l10n.Translator;
|
||||||
|
import net.sf.openrocket.rocketcomponent.ComponentChangeEvent;
|
||||||
import net.sf.openrocket.rocketcomponent.FlightConfigurableComponent;
|
import net.sf.openrocket.rocketcomponent.FlightConfigurableComponent;
|
||||||
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
|
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
|
||||||
import net.sf.openrocket.rocketcomponent.FlightConfigurationId;
|
import net.sf.openrocket.rocketcomponent.FlightConfigurationId;
|
||||||
@ -79,7 +80,7 @@ public class FlightConfigurationPanel extends JPanel implements StateChangeListe
|
|||||||
int lastCol = motorConfigurationPanel.table.getColumnCount() - 1;
|
int lastCol = motorConfigurationPanel.table.getColumnCount() - 1;
|
||||||
motorConfigurationPanel.table.setRowSelectionInterval(lastRow, lastRow);
|
motorConfigurationPanel.table.setRowSelectionInterval(lastRow, lastRow);
|
||||||
motorConfigurationPanel.table.setColumnSelectionInterval(lastCol, lastCol);
|
motorConfigurationPanel.table.setColumnSelectionInterval(lastCol, lastCol);
|
||||||
configurationChanged();
|
configurationChanged(ComponentChangeEvent.MOTOR_CHANGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
@ -91,7 +92,7 @@ public class FlightConfigurationPanel extends JPanel implements StateChangeListe
|
|||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
renameConfiguration();
|
renameConfiguration();
|
||||||
configurationChanged();
|
configurationChanged(ComponentChangeEvent.NONFUNCTIONAL_CHANGE);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.add(renameConfButton,"gapright para");
|
this.add(renameConfButton,"gapright para");
|
||||||
@ -101,7 +102,7 @@ public class FlightConfigurationPanel extends JPanel implements StateChangeListe
|
|||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
removeConfiguration();
|
removeConfiguration();
|
||||||
configurationChanged();
|
configurationChanged(ComponentChangeEvent.NONFUNCTIONAL_CHANGE);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.add(removeConfButton,"gapright para");
|
this.add(removeConfButton,"gapright para");
|
||||||
@ -111,7 +112,7 @@ public class FlightConfigurationPanel extends JPanel implements StateChangeListe
|
|||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
addOrCopyConfiguration(true);
|
addOrCopyConfiguration(true);
|
||||||
configurationChanged();
|
configurationChanged(ComponentChangeEvent.MOTOR_CHANGE);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.add(copyConfButton, "wrap");
|
this.add(copyConfButton, "wrap");
|
||||||
@ -172,13 +173,13 @@ public class FlightConfigurationPanel extends JPanel implements StateChangeListe
|
|||||||
if (currentId == null)
|
if (currentId == null)
|
||||||
return;
|
return;
|
||||||
document.removeFlightConfigurationAndSimulations(currentId);
|
document.removeFlightConfigurationAndSimulations(currentId);
|
||||||
configurationChanged();
|
configurationChanged(ComponentChangeEvent.NONFUNCTIONAL_CHANGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void configurationChanged() {
|
private void configurationChanged(int cce) {
|
||||||
motorConfigurationPanel.fireTableDataChanged();
|
motorConfigurationPanel.fireTableDataChanged(cce);
|
||||||
recoveryConfigurationPanel.fireTableDataChanged();
|
recoveryConfigurationPanel.fireTableDataChanged(cce);
|
||||||
separationConfigurationPanel.fireTableDataChanged();
|
separationConfigurationPanel.fireTableDataChanged(cce);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateButtonState() {
|
private void updateButtonState() {
|
||||||
|
|||||||
@ -29,10 +29,12 @@ import net.sf.openrocket.gui.widgets.SelectColorButton;
|
|||||||
import net.sf.openrocket.motor.IgnitionEvent;
|
import net.sf.openrocket.motor.IgnitionEvent;
|
||||||
import net.sf.openrocket.motor.Motor;
|
import net.sf.openrocket.motor.Motor;
|
||||||
import net.sf.openrocket.motor.MotorConfiguration;
|
import net.sf.openrocket.motor.MotorConfiguration;
|
||||||
|
import net.sf.openrocket.rocketcomponent.ComponentChangeEvent;
|
||||||
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
|
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
|
||||||
import net.sf.openrocket.rocketcomponent.FlightConfigurationId;
|
import net.sf.openrocket.rocketcomponent.FlightConfigurationId;
|
||||||
import net.sf.openrocket.rocketcomponent.MotorMount;
|
import net.sf.openrocket.rocketcomponent.MotorMount;
|
||||||
import net.sf.openrocket.rocketcomponent.Rocket;
|
import net.sf.openrocket.rocketcomponent.Rocket;
|
||||||
|
import net.sf.openrocket.startup.Application;
|
||||||
import net.sf.openrocket.unit.UnitGroup;
|
import net.sf.openrocket.unit.UnitGroup;
|
||||||
import net.sf.openrocket.util.Chars;
|
import net.sf.openrocket.util.Chars;
|
||||||
|
|
||||||
@ -201,20 +203,25 @@ public class MotorConfigurationPanel extends FlightConfigurablePanel<MotorMount>
|
|||||||
throw new IllegalStateException("Attempting to set a motor on the default FCID.");
|
throw new IllegalStateException("Attempting to set a motor on the default FCID.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double initDelay = curMount.getMotorConfig(fcid).getEjectionDelay();
|
||||||
|
|
||||||
motorChooserDialog.setMotorMountAndConfig( fcid, curMount );
|
motorChooserDialog.setMotorMountAndConfig( fcid, curMount );
|
||||||
motorChooserDialog.setVisible(true);
|
motorChooserDialog.setVisible(true);
|
||||||
|
|
||||||
Motor mtr = motorChooserDialog.getSelectedMotor();
|
Motor mtr = motorChooserDialog.getSelectedMotor();
|
||||||
double d = motorChooserDialog.getSelectedDelay();
|
double d = motorChooserDialog.getSelectedDelay();
|
||||||
if (mtr != null) {
|
if (mtr != null) {
|
||||||
|
if (mtr == curMount.getMotorConfig(fcid).getMotor() && d == initDelay) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
final MotorConfiguration templateConfig = curMount.getMotorConfig(fcid);
|
final MotorConfiguration templateConfig = curMount.getMotorConfig(fcid);
|
||||||
final MotorConfiguration newConfig = new MotorConfiguration( curMount, fcid, templateConfig);
|
final MotorConfiguration newConfig = new MotorConfiguration( curMount, fcid, templateConfig);
|
||||||
newConfig.setMotor(mtr);
|
newConfig.setMotor(mtr);
|
||||||
newConfig.setEjectionDelay(d);
|
newConfig.setEjectionDelay(d);
|
||||||
curMount.setMotorConfig( newConfig, fcid);
|
curMount.setMotorConfig( newConfig, fcid);
|
||||||
}
|
|
||||||
|
|
||||||
fireTableDataChanged();
|
fireTableDataChanged(ComponentChangeEvent.MOTOR_CHANGE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void removeMotor() {
|
private void removeMotor() {
|
||||||
@ -226,7 +233,7 @@ public class MotorConfigurationPanel extends FlightConfigurablePanel<MotorMount>
|
|||||||
|
|
||||||
curMount.setMotorConfig( null, fcid);
|
curMount.setMotorConfig( null, fcid);
|
||||||
|
|
||||||
fireTableDataChanged();
|
fireTableDataChanged(ComponentChangeEvent.MOTOR_CHANGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void selectIgnition() {
|
private void selectIgnition() {
|
||||||
@ -236,6 +243,10 @@ public class MotorConfigurationPanel extends FlightConfigurablePanel<MotorMount>
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MotorConfiguration curInstance = curMount.getMotorConfig(fcid);
|
||||||
|
IgnitionEvent initialIgnitionEvent = curInstance.getIgnitionEvent();
|
||||||
|
double initialIgnitionDelay = curInstance.getIgnitionDelay();
|
||||||
|
|
||||||
// this call also performs the update changes
|
// this call also performs the update changes
|
||||||
IgnitionSelectionDialog ignitionDialog = new IgnitionSelectionDialog(
|
IgnitionSelectionDialog ignitionDialog = new IgnitionSelectionDialog(
|
||||||
SwingUtilities.getWindowAncestor(this.flightConfigurationPanel),
|
SwingUtilities.getWindowAncestor(this.flightConfigurationPanel),
|
||||||
@ -243,7 +254,9 @@ public class MotorConfigurationPanel extends FlightConfigurablePanel<MotorMount>
|
|||||||
curMount);
|
curMount);
|
||||||
ignitionDialog.setVisible(true);
|
ignitionDialog.setVisible(true);
|
||||||
|
|
||||||
fireTableDataChanged();
|
if (!initialIgnitionEvent.equals(curInstance.getIgnitionEvent()) || (initialIgnitionDelay != curInstance.getIgnitionDelay())) {
|
||||||
|
fireTableDataChanged(ComponentChangeEvent.MOTOR_CHANGE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -254,10 +267,14 @@ public class MotorConfigurationPanel extends FlightConfigurablePanel<MotorMount>
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
MotorConfiguration curInstance = curMount.getMotorConfig(fcid);
|
MotorConfiguration curInstance = curMount.getMotorConfig(fcid);
|
||||||
|
IgnitionEvent initialIgnitionEvent = curInstance.getIgnitionEvent();
|
||||||
|
double initialIgnitionDelay = curInstance.getIgnitionDelay();
|
||||||
|
|
||||||
curInstance.useDefaultIgnition();
|
curInstance.useDefaultIgnition();
|
||||||
|
|
||||||
fireTableDataChanged();
|
if (!initialIgnitionEvent.equals(curInstance.getIgnitionEvent()) || (initialIgnitionDelay != curInstance.getIgnitionDelay())) {
|
||||||
|
fireTableDataChanged(ComponentChangeEvent.MOTOR_CHANGE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -99,22 +99,31 @@ public class RecoveryConfigurationPanel extends FlightConfigurablePanel<Recovery
|
|||||||
|
|
||||||
private void selectDeployment() {
|
private void selectDeployment() {
|
||||||
RecoveryDevice c = getSelectedComponent();
|
RecoveryDevice c = getSelectedComponent();
|
||||||
if (c == null) {
|
FlightConfigurationId fcid = getSelectedConfigurationId();
|
||||||
|
if ((c == null) || (fcid == null)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
DeploymentConfiguration initialConfig = c.getDeploymentConfigurations().get(fcid).copy(fcid);
|
||||||
JDialog d = new DeploymentSelectionDialog(SwingUtilities.getWindowAncestor(this), rocket, c);
|
JDialog d = new DeploymentSelectionDialog(SwingUtilities.getWindowAncestor(this), rocket, c);
|
||||||
d.setVisible(true);
|
d.setVisible(true);
|
||||||
fireTableDataChanged();
|
if (!initialConfig.equals(c.getDeploymentConfigurations().get(fcid))) {
|
||||||
|
fireTableDataChanged(ComponentChangeEvent.AERODYNAMIC_CHANGE);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resetDeployment() {
|
private void resetDeployment() {
|
||||||
RecoveryDevice c = getSelectedComponent();
|
RecoveryDevice c = getSelectedComponent();
|
||||||
if (c == null) {
|
FlightConfigurationId fcid = getSelectedConfigurationId();
|
||||||
|
if ((c == null) || (fcid == null)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
DeploymentConfiguration initialConfig = c.getDeploymentConfigurations().get(fcid).copy(fcid);
|
||||||
FlightConfigurationId id = rocket.getSelectedConfiguration().getFlightConfigurationID();
|
FlightConfigurationId id = rocket.getSelectedConfiguration().getFlightConfigurationID();
|
||||||
c.getDeploymentConfigurations().reset(id);
|
c.getDeploymentConfigurations().reset(id);
|
||||||
fireTableDataChanged();
|
if (!initialConfig.equals(c.getDeploymentConfigurations().get(fcid))) {
|
||||||
|
fireTableDataChanged(ComponentChangeEvent.AERODYNAMIC_CHANGE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateButtonState() {
|
public void updateButtonState() {
|
||||||
|
|||||||
@ -17,6 +17,7 @@ import net.sf.openrocket.formatting.RocketDescriptor;
|
|||||||
import net.sf.openrocket.gui.dialogs.flightconfiguration.SeparationSelectionDialog;
|
import net.sf.openrocket.gui.dialogs.flightconfiguration.SeparationSelectionDialog;
|
||||||
import net.sf.openrocket.l10n.Translator;
|
import net.sf.openrocket.l10n.Translator;
|
||||||
import net.sf.openrocket.rocketcomponent.AxialStage;
|
import net.sf.openrocket.rocketcomponent.AxialStage;
|
||||||
|
import net.sf.openrocket.rocketcomponent.ComponentChangeEvent;
|
||||||
import net.sf.openrocket.rocketcomponent.FlightConfigurationId;
|
import net.sf.openrocket.rocketcomponent.FlightConfigurationId;
|
||||||
import net.sf.openrocket.rocketcomponent.Rocket;
|
import net.sf.openrocket.rocketcomponent.Rocket;
|
||||||
import net.sf.openrocket.rocketcomponent.StageSeparationConfiguration;
|
import net.sf.openrocket.rocketcomponent.StageSeparationConfiguration;
|
||||||
@ -46,7 +47,7 @@ public class SeparationConfigurationPanel extends FlightConfigurablePanel<AxialS
|
|||||||
selectSeparationButton.addActionListener(new ActionListener() {
|
selectSeparationButton.addActionListener(new ActionListener() {
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
selectDeployment();
|
selectSeparation();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.add(selectSeparationButton, "split, align right, sizegroup button");
|
this.add(selectSeparationButton, "split, align right, sizegroup button");
|
||||||
@ -57,7 +58,7 @@ public class SeparationConfigurationPanel extends FlightConfigurablePanel<AxialS
|
|||||||
resetDeploymentButton.addActionListener(new ActionListener() {
|
resetDeploymentButton.addActionListener(new ActionListener() {
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
resetDeployment();
|
resetSeparation();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.add(resetDeploymentButton, "sizegroup button, wrap");
|
this.add(resetDeploymentButton, "sizegroup button, wrap");
|
||||||
@ -86,7 +87,7 @@ public class SeparationConfigurationPanel extends FlightConfigurablePanel<AxialS
|
|||||||
updateButtonState();
|
updateButtonState();
|
||||||
if (e.getClickCount() == 2) {
|
if (e.getClickCount() == 2) {
|
||||||
// Double-click edits
|
// Double-click edits
|
||||||
selectDeployment();
|
selectSeparation();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -95,27 +96,35 @@ public class SeparationConfigurationPanel extends FlightConfigurablePanel<AxialS
|
|||||||
return separationTable;
|
return separationTable;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void selectDeployment() {
|
private void selectSeparation() {
|
||||||
AxialStage stage = getSelectedComponent();
|
AxialStage stage = getSelectedComponent();
|
||||||
if (stage == null) {
|
FlightConfigurationId fcid = getSelectedConfigurationId();
|
||||||
|
if ((stage == null) || (fcid == null)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
StageSeparationConfiguration initialConfig = stage.getSeparationConfigurations().get(fcid).copy(fcid);
|
||||||
JDialog d = new SeparationSelectionDialog(SwingUtilities.getWindowAncestor(this), rocket, stage);
|
JDialog d = new SeparationSelectionDialog(SwingUtilities.getWindowAncestor(this), rocket, stage);
|
||||||
d.setVisible(true);
|
d.setVisible(true);
|
||||||
fireTableDataChanged();
|
if (!initialConfig.equals(stage.getSeparationConfigurations().get(fcid))) {
|
||||||
|
fireTableDataChanged(ComponentChangeEvent.AEROMASS_CHANGE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resetDeployment() {
|
private void resetSeparation() {
|
||||||
AxialStage stage = getSelectedComponent();
|
AxialStage stage = getSelectedComponent();
|
||||||
if (stage == null) {
|
FlightConfigurationId fcid = getSelectedConfigurationId();
|
||||||
|
if ((stage == null) || (fcid == null)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StageSeparationConfiguration initialConfig = stage.getSeparationConfigurations().get(fcid).copy(fcid);
|
||||||
// why?
|
// why?
|
||||||
FlightConfigurationId id = rocket.getSelectedConfiguration().getFlightConfigurationID();
|
FlightConfigurationId id = rocket.getSelectedConfiguration().getFlightConfigurationID();
|
||||||
stage.getSeparationConfigurations().reset(id);
|
stage.getSeparationConfigurations().reset(id);
|
||||||
|
|
||||||
fireTableDataChanged();
|
if (!initialConfig.equals(stage.getSeparationConfigurations().get(fcid))) {
|
||||||
|
fireTableDataChanged(ComponentChangeEvent.AEROMASS_CHANGE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
public void updateButtonState() {
|
public void updateButtonState() {
|
||||||
boolean componentSelected = getSelectedComponent() != null;
|
boolean componentSelected = getSelectedComponent() != null;
|
||||||
|
|||||||
@ -8,22 +8,15 @@ import java.awt.Point;
|
|||||||
import java.awt.event.InputEvent;
|
import java.awt.event.InputEvent;
|
||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.EventListener;
|
import java.util.EventListener;
|
||||||
import java.util.EventObject;
|
import java.util.EventObject;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.LinkedList;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.ThreadFactory;
|
import java.util.concurrent.ThreadFactory;
|
||||||
|
|
||||||
import javax.swing.ComboBoxModel;
|
import javax.swing.*;
|
||||||
import javax.swing.DefaultComboBoxModel;
|
|
||||||
import javax.swing.JComboBox;
|
|
||||||
import javax.swing.JLabel;
|
|
||||||
import javax.swing.JPanel;
|
|
||||||
import javax.swing.JSlider;
|
|
||||||
import javax.swing.JViewport;
|
|
||||||
import javax.swing.SwingUtilities;
|
|
||||||
import javax.swing.event.ChangeEvent;
|
import javax.swing.event.ChangeEvent;
|
||||||
import javax.swing.event.ChangeListener;
|
import javax.swing.event.ChangeListener;
|
||||||
import javax.swing.event.TreeSelectionEvent;
|
import javax.swing.event.TreeSelectionEvent;
|
||||||
@ -38,6 +31,7 @@ import net.sf.openrocket.aerodynamics.FlightConditions;
|
|||||||
import net.sf.openrocket.aerodynamics.WarningSet;
|
import net.sf.openrocket.aerodynamics.WarningSet;
|
||||||
import net.sf.openrocket.document.OpenRocketDocument;
|
import net.sf.openrocket.document.OpenRocketDocument;
|
||||||
import net.sf.openrocket.document.Simulation;
|
import net.sf.openrocket.document.Simulation;
|
||||||
|
import net.sf.openrocket.document.events.SimulationChangeEvent;
|
||||||
import net.sf.openrocket.gui.adaptors.DoubleModel;
|
import net.sf.openrocket.gui.adaptors.DoubleModel;
|
||||||
import net.sf.openrocket.gui.components.BasicSlider;
|
import net.sf.openrocket.gui.components.BasicSlider;
|
||||||
import net.sf.openrocket.gui.components.ConfigurationComboBox;
|
import net.sf.openrocket.gui.components.ConfigurationComboBox;
|
||||||
@ -49,6 +43,7 @@ import net.sf.openrocket.gui.figureelements.CGCaret;
|
|||||||
import net.sf.openrocket.gui.figureelements.CPCaret;
|
import net.sf.openrocket.gui.figureelements.CPCaret;
|
||||||
import net.sf.openrocket.gui.figureelements.Caret;
|
import net.sf.openrocket.gui.figureelements.Caret;
|
||||||
import net.sf.openrocket.gui.figureelements.RocketInfo;
|
import net.sf.openrocket.gui.figureelements.RocketInfo;
|
||||||
|
import net.sf.openrocket.gui.main.BasicFrame;
|
||||||
import net.sf.openrocket.gui.main.componenttree.ComponentTreeModel;
|
import net.sf.openrocket.gui.main.componenttree.ComponentTreeModel;
|
||||||
import net.sf.openrocket.gui.simulation.SimulationWorker;
|
import net.sf.openrocket.gui.simulation.SimulationWorker;
|
||||||
import net.sf.openrocket.gui.util.SwingPreferences;
|
import net.sf.openrocket.gui.util.SwingPreferences;
|
||||||
@ -63,10 +58,12 @@ import net.sf.openrocket.rocketcomponent.Rocket;
|
|||||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||||
import net.sf.openrocket.rocketcomponent.SymmetricComponent;
|
import net.sf.openrocket.rocketcomponent.SymmetricComponent;
|
||||||
import net.sf.openrocket.simulation.FlightData;
|
import net.sf.openrocket.simulation.FlightData;
|
||||||
|
import net.sf.openrocket.simulation.SimulationStatus;
|
||||||
import net.sf.openrocket.simulation.customexpression.CustomExpression;
|
import net.sf.openrocket.simulation.customexpression.CustomExpression;
|
||||||
import net.sf.openrocket.simulation.customexpression.CustomExpressionSimulationListener;
|
import net.sf.openrocket.simulation.customexpression.CustomExpressionSimulationListener;
|
||||||
|
import net.sf.openrocket.simulation.exception.SimulationException;
|
||||||
import net.sf.openrocket.simulation.listeners.SimulationListener;
|
import net.sf.openrocket.simulation.listeners.SimulationListener;
|
||||||
import net.sf.openrocket.simulation.listeners.system.ApogeeEndListener;
|
import net.sf.openrocket.simulation.listeners.system.GroundHitListener;
|
||||||
import net.sf.openrocket.simulation.listeners.system.InterruptListener;
|
import net.sf.openrocket.simulation.listeners.system.InterruptListener;
|
||||||
import net.sf.openrocket.startup.Application;
|
import net.sf.openrocket.startup.Application;
|
||||||
import net.sf.openrocket.unit.UnitGroup;
|
import net.sf.openrocket.unit.UnitGroup;
|
||||||
@ -75,6 +72,8 @@ import net.sf.openrocket.util.Chars;
|
|||||||
import net.sf.openrocket.util.Coordinate;
|
import net.sf.openrocket.util.Coordinate;
|
||||||
import net.sf.openrocket.util.MathUtil;
|
import net.sf.openrocket.util.MathUtil;
|
||||||
import net.sf.openrocket.util.StateChangeListener;
|
import net.sf.openrocket.util.StateChangeListener;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -87,6 +86,7 @@ import net.sf.openrocket.util.StateChangeListener;
|
|||||||
public class RocketPanel extends JPanel implements TreeSelectionListener, ChangeSource {
|
public class RocketPanel extends JPanel implements TreeSelectionListener, ChangeSource {
|
||||||
|
|
||||||
private static final Translator trans = Application.getTranslator();
|
private static final Translator trans = Application.getTranslator();
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(RocketPanel.class);
|
||||||
|
|
||||||
public enum VIEW_TYPE {
|
public enum VIEW_TYPE {
|
||||||
SideView(false, RocketFigure.VIEW_SIDE),
|
SideView(false, RocketFigure.VIEW_SIDE),
|
||||||
@ -148,13 +148,16 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
|
|||||||
|
|
||||||
private List<EventListener> listeners = new ArrayList<EventListener>();
|
private List<EventListener> listeners = new ArrayList<EventListener>();
|
||||||
|
|
||||||
|
// Store the basic frame to know which tab is selected (Rocket design, Motors & Configuration, Flight simulations)
|
||||||
|
private final BasicFrame basicFrame;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The executor service used for running the background simulations.
|
* The executor service used for running the background simulations.
|
||||||
* This uses a fixed-sized thread pool for all background simulations
|
* This uses a fixed-sized thread pool for all background simulations
|
||||||
* with all threads in daemon mode and with minimum priority.
|
* with all threads in daemon mode and with minimum priority.
|
||||||
*/
|
*/
|
||||||
private static final Executor backgroundSimulationExecutor;
|
private static final ExecutorService backgroundSimulationExecutor;
|
||||||
static {
|
static {
|
||||||
backgroundSimulationExecutor = Executors.newFixedThreadPool(SwingPreferences.getMaxThreadCount(),
|
backgroundSimulationExecutor = Executors.newFixedThreadPool(SwingPreferences.getMaxThreadCount(),
|
||||||
new ThreadFactory() {
|
new ThreadFactory() {
|
||||||
@ -170,13 +173,17 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public OpenRocketDocument getDocument(){
|
public OpenRocketDocument getDocument(){
|
||||||
return this.document;
|
return this.document;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RocketPanel(OpenRocketDocument document) {
|
public RocketPanel(OpenRocketDocument document) {
|
||||||
|
this(document, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RocketPanel(OpenRocketDocument document, BasicFrame basicFrame) {
|
||||||
this.document = document;
|
this.document = document;
|
||||||
|
this.basicFrame = basicFrame;
|
||||||
Rocket rkt = document.getRocket();
|
Rocket rkt = document.getRocket();
|
||||||
|
|
||||||
|
|
||||||
@ -216,6 +223,7 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
|
|||||||
rkt.addComponentChangeListener(new ComponentChangeListener() {
|
rkt.addComponentChangeListener(new ComponentChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
public void componentChanged(ComponentChangeEvent e) {
|
public void componentChanged(ComponentChangeEvent e) {
|
||||||
|
updateExtras();
|
||||||
if (is3d) {
|
if (is3d) {
|
||||||
if (e.isTextureChange()) {
|
if (e.isTextureChange()) {
|
||||||
figure3d.flushTextureCaches();
|
figure3d.flushTextureCaches();
|
||||||
@ -557,7 +565,7 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the extra data included in the figure. Currently this includes
|
* Updates the extra data included in the figure. Currently this includes
|
||||||
* the CP and CG carets.
|
* the CP and CG carets. Also start the background simulator.
|
||||||
*/
|
*/
|
||||||
private WarningSet warnings = new WarningSet();
|
private WarningSet warnings = new WarningSet();
|
||||||
|
|
||||||
@ -683,35 +691,120 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start calculation process
|
// Update simulations
|
||||||
if(((SwingPreferences) Application.getPreferences()).computeFlightInBackground()){
|
if (Application.getPreferences().getAutoRunSimulations()) {
|
||||||
extraText.setCalculatingData(true);
|
// Update only current flight config simulation when you are not in the simulations tab
|
||||||
|
updateSims(this.basicFrame != null && this.basicFrame.getSelectedTab() == BasicFrame.SIMULATION_TAB);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Always update the simulation of the current configuration
|
||||||
|
updateSims(false);
|
||||||
|
}
|
||||||
|
|
||||||
Rocket duplicate = (Rocket) document.getRocket().copy();
|
// Update flight data and add flight data update trigger upon simulation changes
|
||||||
|
|
||||||
// find a Simulation based on the current flight configuration
|
|
||||||
FlightConfigurationId curID = curConfig.getFlightConfigurationID();
|
|
||||||
Simulation simulation = null;
|
|
||||||
for (Simulation sim : document.getSimulations()) {
|
for (Simulation sim : document.getSimulations()) {
|
||||||
if (sim.getFlightConfigurationId().compareTo(curID) == 0) {
|
sim.addChangeListener(new StateChangeListener() {
|
||||||
simulation = sim;
|
@Override
|
||||||
|
public void stateChanged(EventObject e) {
|
||||||
|
if (updateFlightData(sim)) {
|
||||||
|
updateFigures();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (updateFlightData(sim)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the simulations. If *currentConfig* is false, only update the simulation of the current flight
|
||||||
|
* configuration. If it is true, update all the simulations.
|
||||||
|
*
|
||||||
|
* @param updateAllSims flag to check whether to update all the simulations (true) or only the current
|
||||||
|
* flight config sim (false)
|
||||||
|
*/
|
||||||
|
private void updateSims(boolean updateAllSims) {
|
||||||
|
// Stop previous computation (if any)
|
||||||
|
stopBackgroundSimulation();
|
||||||
|
|
||||||
|
FlightConfigurationId curID = document.getSelectedConfiguration().getFlightConfigurationID();
|
||||||
|
extraText.setCalculatingData(true);
|
||||||
|
Rocket duplicate = (Rocket)document.getRocket().copy();
|
||||||
|
|
||||||
|
// Re-run the present simulation(s)
|
||||||
|
List<Simulation> sims = new LinkedList<>();
|
||||||
|
for (Simulation sim : document.getSimulations()) {
|
||||||
|
if (sim.getStatus() == Simulation.Status.UPTODATE || sim.getStatus() == Simulation.Status.LOADED
|
||||||
|
|| !document.getRocket().getFlightConfiguration(sim.getFlightConfigurationId()).hasMotors())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Find a Simulation based on the current flight configuration
|
||||||
|
if (!updateAllSims) {
|
||||||
|
if (sim.getFlightConfigurationId().compareTo(curID) == 0) {
|
||||||
|
sims.add(sim);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sims.add(sim);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
runBackgroundSimulations(sims, duplicate);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the flight data text with the data of {sim}. Only update if sim is the simulation of the current flight
|
||||||
|
* configuration.
|
||||||
|
* @param sim: simulation from which the flight data is taken
|
||||||
|
* @return true if the flight data was updated, false if not
|
||||||
|
*/
|
||||||
|
private boolean updateFlightData(Simulation sim) {
|
||||||
|
FlightConfigurationId curID = document.getSelectedConfiguration().getFlightConfigurationID();
|
||||||
|
if (sim.getFlightConfigurationId().compareTo(curID) == 0) {
|
||||||
|
if (sim.hasSimulationData()) {
|
||||||
|
extraText.setFlightData(sim.getSimulatedData());
|
||||||
|
} else {
|
||||||
|
extraText.setFlightData(FlightData.NaN_DATA);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs a new background simulation for simulations *sims*. It will run all the simulations in sims sequentially
|
||||||
|
* in the background.
|
||||||
|
*
|
||||||
|
* @param sims simulations which should be run
|
||||||
|
* @param rkt rocket for which the simulations are run
|
||||||
|
*/
|
||||||
|
private void runBackgroundSimulations(List<Simulation> sims, Rocket rkt) {
|
||||||
|
if (sims.size() == 0) {
|
||||||
|
extraText.setCalculatingData(false);
|
||||||
|
for (Simulation sim : document.getSimulations()) {
|
||||||
|
if (updateFlightData(sim)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
extraText.setFlightData(FlightData.NaN_DATA);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// I *think* every FlightConfiguration has at least one associated simulation; just in case I'm wrong,
|
// I *think* every FlightConfiguration has at least one associated simulation; just in case I'm wrong,
|
||||||
// if there isn't one we'll create a new simulation to update the statistics in the panel using the
|
// if there isn't one we'll create a new simulation to update the statistics in the panel using the
|
||||||
// default simulation conditions
|
// default simulation conditions
|
||||||
if (simulation == null) {
|
for (Simulation sim : sims) {
|
||||||
System.out.println("creating new simulation");
|
if (sim == null) {
|
||||||
simulation = ((SwingPreferences) Application.getPreferences()).getBackgroundSimulation(duplicate);
|
log.info("creating new simulation");
|
||||||
simulation.setFlightConfigurationId( document.getSelectedConfiguration().getId());
|
sim = ((SwingPreferences) Application.getPreferences()).getBackgroundSimulation(rkt);
|
||||||
|
sim.setFlightConfigurationId(document.getSelectedConfiguration().getId());
|
||||||
} else
|
} else
|
||||||
System.out.println("using pre-existing simulation");
|
log.info("using pre-existing simulation");
|
||||||
|
|
||||||
backgroundSimulationWorker = new BackgroundSimulationWorker(document, simulation);
|
|
||||||
backgroundSimulationExecutor.execute(backgroundSimulationWorker);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
backgroundSimulationWorker = new BackgroundSimulationWorker(document, sims);
|
||||||
|
backgroundSimulationExecutor.execute(backgroundSimulationWorker);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -732,16 +825,20 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
|
|||||||
private class BackgroundSimulationWorker extends SimulationWorker {
|
private class BackgroundSimulationWorker extends SimulationWorker {
|
||||||
|
|
||||||
private final CustomExpressionSimulationListener exprListener;
|
private final CustomExpressionSimulationListener exprListener;
|
||||||
|
private final OpenRocketDocument doc;
|
||||||
|
private List<Simulation> sims;
|
||||||
|
|
||||||
public BackgroundSimulationWorker(OpenRocketDocument doc, Simulation sim) {
|
public BackgroundSimulationWorker(OpenRocketDocument doc, List<Simulation> sims) {
|
||||||
super(sim);
|
super(sims.get(0));
|
||||||
|
this.sims = sims;
|
||||||
|
this.doc = doc;
|
||||||
List<CustomExpression> exprs = doc.getCustomExpressions();
|
List<CustomExpression> exprs = doc.getCustomExpressions();
|
||||||
exprListener = new CustomExpressionSimulationListener(exprs);
|
exprListener = new CustomExpressionSimulationListener(exprs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected FlightData doInBackground() {
|
protected FlightData doInBackground() {
|
||||||
|
extraText.setCalculatingData(true);
|
||||||
// Pause a little while to allow faster UI reaction
|
// Pause a little while to allow faster UI reaction
|
||||||
try {
|
try {
|
||||||
Thread.sleep(300);
|
Thread.sleep(300);
|
||||||
@ -749,7 +846,6 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
|
|||||||
}
|
}
|
||||||
if (isCancelled() || backgroundSimulationWorker != this)
|
if (isCancelled() || backgroundSimulationWorker != this)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
return super.doInBackground();
|
return super.doInBackground();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -758,19 +854,27 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
|
|||||||
// Do nothing if cancelled
|
// Do nothing if cancelled
|
||||||
if (isCancelled() || backgroundSimulationWorker != this)
|
if (isCancelled() || backgroundSimulationWorker != this)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
backgroundSimulationWorker = null;
|
backgroundSimulationWorker = null;
|
||||||
extraText.setFlightData(simulation.getSimulatedData());
|
|
||||||
|
// Only set the flight data information of the current flight configuration
|
||||||
extraText.setCalculatingData(false);
|
extraText.setCalculatingData(false);
|
||||||
figure.repaint();
|
figure.repaint();
|
||||||
figure3d.repaint();
|
figure3d.repaint();
|
||||||
|
document.fireDocumentChangeEvent(new SimulationChangeEvent(simulation));
|
||||||
|
|
||||||
|
// Run the new simulation after this one has ended
|
||||||
|
this.sims.remove(0);
|
||||||
|
if (this.sims.size() > 0) {
|
||||||
|
backgroundSimulationWorker = new BackgroundSimulationWorker(this.doc, this.sims);
|
||||||
|
backgroundSimulationExecutor.execute(backgroundSimulationWorker);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected SimulationListener[] getExtraListeners() {
|
protected SimulationListener[] getExtraListeners() {
|
||||||
return new SimulationListener[] {
|
return new SimulationListener[] {
|
||||||
InterruptListener.INSTANCE,
|
InterruptListener.INSTANCE,
|
||||||
ApogeeEndListener.INSTANCE,
|
GroundHitListener.INSTANCE,
|
||||||
exprListener };
|
exprListener };
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user