optimization updates
This commit is contained in:
parent
8b29435bac
commit
784c76091b
@ -1344,7 +1344,7 @@ optimization.modifier.trapezoidfinset.height.desc = Optimize the height (semi-sp
|
|||||||
optimization.modifier.ellipticalfinset.length = Root chord
|
optimization.modifier.ellipticalfinset.length = Root chord
|
||||||
optimization.modifier.ellipticalfinset.length.desc = Optimize the root chord length of the fin set.
|
optimization.modifier.ellipticalfinset.length.desc = Optimize the root chord length of the fin set.
|
||||||
optimization.modifier.ellipticalfinset.height = Height
|
optimization.modifier.ellipticalfinset.height = Height
|
||||||
optimization.modifier.ellipticalfinset.height = Optimize the height (semi-span) of the fin set.
|
optimization.modifier.ellipticalfinset.height.desc = Optimize the height (semi-span) of the fin set.
|
||||||
|
|
||||||
optimization.modifier.finset.cant = Cant angle
|
optimization.modifier.finset.cant = Cant angle
|
||||||
optimization.modifier.finset.cant.desc = Optimize the cant angle of the fin set.
|
optimization.modifier.finset.cant.desc = Optimize the cant angle of the fin set.
|
||||||
@ -1471,6 +1471,7 @@ OptimizationPlotDialog.plot2d.title = Optimization path
|
|||||||
OptimizationPlotDialog.plot2d.path = Optimization path
|
OptimizationPlotDialog.plot2d.path = Optimization path
|
||||||
OptimizationPlotDialog.plot2d.evals = Evaluations
|
OptimizationPlotDialog.plot2d.evals = Evaluations
|
||||||
OptimizationPlotDialog.plot.ttip.stability = Stability:
|
OptimizationPlotDialog.plot.ttip.stability = Stability:
|
||||||
|
OptimizationPlotDialog.plot.label.optimum = Optimum
|
||||||
|
|
||||||
! Optimization parameters
|
! Optimization parameters
|
||||||
MaximumAltitudeParameter.name = Apogee altitude
|
MaximumAltitudeParameter.name = Apogee altitude
|
||||||
|
@ -140,6 +140,7 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
|
|||||||
total.setCm(total.getCm() - total.getPitchDampingMoment());
|
total.setCm(total.getCm() - total.getPitchDampingMoment());
|
||||||
total.setCyaw(total.getCyaw() - total.getYawDampingMoment());
|
total.setCyaw(total.getCyaw() - total.getYawDampingMoment());
|
||||||
|
|
||||||
|
|
||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -648,6 +649,8 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
|
|||||||
double yaw = conditions.getYawRate();
|
double yaw = conditions.getYawRate();
|
||||||
double vel = conditions.getVelocity();
|
double vel = conditions.getVelocity();
|
||||||
|
|
||||||
|
vel = MathUtil.max(vel, 1);
|
||||||
|
|
||||||
// double Cm = total.Cm - total.CN * total.cg.x / conditions.getRefLength();
|
// double Cm = total.Cm - total.CN * total.cg.x / conditions.getRefLength();
|
||||||
// System.out.printf("Damping pitch/yaw, mul=%.4f pitch rate=%.4f "+
|
// System.out.printf("Damping pitch/yaw, mul=%.4f pitch rate=%.4f "+
|
||||||
// "Cm=%.4f / %.4f effect=%.4f aoa=%.4f\n", mul, pitch, total.Cm, Cm,
|
// "Cm=%.4f / %.4f effect=%.4f aoa=%.4f\n", mul, pitch, total.Cm, Cm,
|
||||||
@ -660,7 +663,6 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
|
|||||||
// total.Cyaw -= mul * yaw / pow2(vel);
|
// total.Cyaw -= mul * yaw / pow2(vel);
|
||||||
total.setPitchDampingMoment(mul * MathUtil.sign(pitch) * pow2(pitch / vel));
|
total.setPitchDampingMoment(mul * MathUtil.sign(pitch) * pow2(pitch / vel));
|
||||||
total.setYawDampingMoment(mul * MathUtil.sign(yaw) * pow2(yaw / vel));
|
total.setYawDampingMoment(mul * MathUtil.sign(yaw) * pow2(yaw / vel));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: MEDIUM: Are the rotation etc. being added correctly? sin/cos theta?
|
// TODO: MEDIUM: Are the rotation etc. being added correctly? sin/cos theta?
|
||||||
|
@ -37,6 +37,7 @@ import javax.swing.JSpinner;
|
|||||||
import javax.swing.JTable;
|
import javax.swing.JTable;
|
||||||
import javax.swing.JToggleButton;
|
import javax.swing.JToggleButton;
|
||||||
import javax.swing.ListSelectionModel;
|
import javax.swing.ListSelectionModel;
|
||||||
|
import javax.swing.Timer;
|
||||||
import javax.swing.border.TitledBorder;
|
import javax.swing.border.TitledBorder;
|
||||||
import javax.swing.event.ChangeEvent;
|
import javax.swing.event.ChangeEvent;
|
||||||
import javax.swing.event.ChangeListener;
|
import javax.swing.event.ChangeListener;
|
||||||
@ -95,7 +96,6 @@ import net.sf.openrocket.util.TextUtil;
|
|||||||
|
|
||||||
import com.itextpdf.text.Font;
|
import com.itextpdf.text.Font;
|
||||||
|
|
||||||
// FIXME: Override to zero mass produces NaN in simulation
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* General rocket optimization dialog.
|
* General rocket optimization dialog.
|
||||||
@ -791,6 +791,18 @@ public class GeneralOptimizationDialog extends JDialog {
|
|||||||
|
|
||||||
worker = null;
|
worker = null;
|
||||||
stopOptimization();
|
stopOptimization();
|
||||||
|
|
||||||
|
// Disable the start/stop button for a short while after ending the simulation
|
||||||
|
// to prevent accidentally starting a new optimization when trying to stop it
|
||||||
|
startButton.setEnabled(false);
|
||||||
|
Timer timer = new Timer(750, new ActionListener() {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
startButton.setEnabled(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
timer.setRepeats(false);
|
||||||
|
timer.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -34,6 +34,9 @@ import net.sf.openrocket.util.MathUtil;
|
|||||||
import org.jfree.chart.ChartFactory;
|
import org.jfree.chart.ChartFactory;
|
||||||
import org.jfree.chart.ChartPanel;
|
import org.jfree.chart.ChartPanel;
|
||||||
import org.jfree.chart.JFreeChart;
|
import org.jfree.chart.JFreeChart;
|
||||||
|
import org.jfree.chart.annotations.XYBoxAnnotation;
|
||||||
|
import org.jfree.chart.annotations.XYLineAnnotation;
|
||||||
|
import org.jfree.chart.annotations.XYPointerAnnotation;
|
||||||
import org.jfree.chart.axis.AxisLocation;
|
import org.jfree.chart.axis.AxisLocation;
|
||||||
import org.jfree.chart.axis.NumberAxis;
|
import org.jfree.chart.axis.NumberAxis;
|
||||||
import org.jfree.chart.labels.CustomXYToolTipGenerator;
|
import org.jfree.chart.labels.CustomXYToolTipGenerator;
|
||||||
@ -47,6 +50,7 @@ import org.jfree.data.xy.DefaultXYZDataset;
|
|||||||
import org.jfree.data.xy.XYSeries;
|
import org.jfree.data.xy.XYSeries;
|
||||||
import org.jfree.data.xy.XYSeriesCollection;
|
import org.jfree.data.xy.XYSeriesCollection;
|
||||||
import org.jfree.ui.RectangleEdge;
|
import org.jfree.ui.RectangleEdge;
|
||||||
|
import org.jfree.ui.TextAnchor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class that plots the path of an optimization.
|
* A class that plots the path of an optimization.
|
||||||
@ -57,7 +61,6 @@ public class OptimizationPlotDialog extends JDialog {
|
|||||||
private static final LogHelper log = Application.getLogger();
|
private static final LogHelper log = Application.getLogger();
|
||||||
private static final Translator trans = Application.getTranslator();
|
private static final Translator trans = Application.getTranslator();
|
||||||
|
|
||||||
// FIXME: Set range to optimization range
|
|
||||||
|
|
||||||
private static final LinearInterpolator RED = new LinearInterpolator(
|
private static final LinearInterpolator RED = new LinearInterpolator(
|
||||||
new double[] { 0.0, 1.0 }, new double[] { 0.0, 1.0 }
|
new double[] { 0.0, 1.0 }, new double[] { 0.0, 1.0 }
|
||||||
@ -155,6 +158,37 @@ public class OptimizationPlotDialog extends JDialog {
|
|||||||
false); // Urls
|
false); // Urls
|
||||||
|
|
||||||
|
|
||||||
|
// Set the scale of the plot to the limits
|
||||||
|
double x1 = xUnit.toUnit(modX.getMinValue());
|
||||||
|
double x2 = xUnit.toUnit(modX.getMaxValue());
|
||||||
|
|
||||||
|
chart.getXYPlot().getDomainAxis().setRange(x1, x2);
|
||||||
|
|
||||||
|
// Add lines to show optimization limits
|
||||||
|
XYLineAnnotation line = new XYLineAnnotation(x1, -1e19, x1, 1e19);
|
||||||
|
chart.getXYPlot().addAnnotation(line);
|
||||||
|
line = new XYLineAnnotation(x2, -1e19, x2, 1e19);
|
||||||
|
chart.getXYPlot().addAnnotation(line);
|
||||||
|
|
||||||
|
// Mark the optimum point
|
||||||
|
Point optimum = path.get(path.size() - 1);
|
||||||
|
FunctionEvaluationData data = evaluations.get(optimum);
|
||||||
|
if (data != null) {
|
||||||
|
if (data.getParameterValue() != null) {
|
||||||
|
Value[] state = data.getState();
|
||||||
|
double x = xUnit.toUnit(state[0].getValue());
|
||||||
|
double y = yUnit.toUnit(data.getParameterValue().getValue());
|
||||||
|
|
||||||
|
XYPointerAnnotation text = new XYPointerAnnotation(trans.get("plot.label.optimum"),
|
||||||
|
x, y, Math.PI / 2);
|
||||||
|
text.setTextAnchor(TextAnchor.TOP_LEFT);
|
||||||
|
chart.getXYPlot().addAnnotation(text);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.error("Could not find evaluation data for point " + optimum);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
XYLineAndShapeRenderer lineRenderer = new XYLineAndShapeRenderer(true, true);
|
XYLineAndShapeRenderer lineRenderer = new XYLineAndShapeRenderer(true, true);
|
||||||
lineRenderer.setBaseShapesVisible(true);
|
lineRenderer.setBaseShapesVisible(true);
|
||||||
lineRenderer.setSeriesShapesFilled(0, false);
|
lineRenderer.setSeriesShapesFilled(0, false);
|
||||||
@ -191,13 +225,13 @@ public class OptimizationPlotDialog extends JDialog {
|
|||||||
Unit yUnit = modY.getUnitGroup().getDefaultUnit();
|
Unit yUnit = modY.getUnitGroup().getDefaultUnit();
|
||||||
|
|
||||||
// Create the optimization path dataset
|
// Create the optimization path dataset
|
||||||
XYSeries series = new XYSeries(trans.get("plot2d.path"), false, true);
|
XYSeries pathSeries = new XYSeries(trans.get("plot2d.path"), false, true);
|
||||||
List<String> pathTooltips = new ArrayList<String>();
|
List<String> pathTooltips = new ArrayList<String>();
|
||||||
for (Point p : path) {
|
for (Point p : path) {
|
||||||
FunctionEvaluationData data = evaluations.get(p);
|
FunctionEvaluationData data = evaluations.get(p);
|
||||||
if (data != null) {
|
if (data != null) {
|
||||||
Value[] state = data.getState();
|
Value[] state = data.getState();
|
||||||
series.add(xUnit.toUnit(state[0].getValue()), yUnit.toUnit(state[1].getValue()));
|
pathSeries.add(xUnit.toUnit(state[0].getValue()), yUnit.toUnit(state[1].getValue()));
|
||||||
pathTooltips.add(getTooltip(data, parameter));
|
pathTooltips.add(getTooltip(data, parameter));
|
||||||
} else {
|
} else {
|
||||||
log.error("Could not find evaluation data for point " + p);
|
log.error("Could not find evaluation data for point " + p);
|
||||||
@ -256,12 +290,23 @@ public class OptimizationPlotDialog extends JDialog {
|
|||||||
false); // Urls
|
false); // Urls
|
||||||
|
|
||||||
|
|
||||||
chart.getXYPlot().getDomainAxis().setRange(xUnit.toUnit(modX.getMinValue()),
|
// Set the scale of the plot to the limits
|
||||||
xUnit.toUnit(modX.getMaxValue()));
|
double x1 = xUnit.toUnit(modX.getMinValue());
|
||||||
|
double x2 = xUnit.toUnit(modX.getMaxValue());
|
||||||
|
double y1 = yUnit.toUnit(modY.getMinValue());
|
||||||
|
double y2 = yUnit.toUnit(modY.getMaxValue());
|
||||||
|
|
||||||
chart.getXYPlot().getRangeAxis().setRange(yUnit.toUnit(modY.getMinValue()),
|
chart.getXYPlot().getDomainAxis().setRange(x1, x2);
|
||||||
yUnit.toUnit(modY.getMaxValue()));
|
chart.getXYPlot().getRangeAxis().setRange(y1, y2);
|
||||||
|
|
||||||
|
XYBoxAnnotation box = new XYBoxAnnotation(x1, y1, x2, y2);
|
||||||
|
chart.getXYPlot().addAnnotation(box);
|
||||||
|
|
||||||
|
int n = pathSeries.getItemCount();
|
||||||
|
XYPointerAnnotation text = new XYPointerAnnotation(trans.get("plot.label.optimum"),
|
||||||
|
(Double) pathSeries.getX(n - 1), (Double) pathSeries.getY(n - 1), -Math.PI / 5);
|
||||||
|
text.setTextAnchor(TextAnchor.BASELINE_LEFT);
|
||||||
|
chart.getXYPlot().addAnnotation(text);
|
||||||
|
|
||||||
PaintScale paintScale = new GradientScale(min, max);
|
PaintScale paintScale = new GradientScale(min, max);
|
||||||
|
|
||||||
@ -290,7 +335,7 @@ public class OptimizationPlotDialog extends JDialog {
|
|||||||
|
|
||||||
XYPlot plot = chart.getXYPlot();
|
XYPlot plot = chart.getXYPlot();
|
||||||
|
|
||||||
plot.setDataset(0, new XYSeriesCollection(series));
|
plot.setDataset(0, new XYSeriesCollection(pathSeries));
|
||||||
plot.setRenderer(lineRenderer);
|
plot.setRenderer(lineRenderer);
|
||||||
|
|
||||||
plot.setDataset(1, evalDataset);
|
plot.setDataset(1, evalDataset);
|
||||||
|
@ -113,7 +113,7 @@ public class ExceptionHandler implements Thread.UncaughtExceptionHandler {
|
|||||||
* @param message the error message.
|
* @param message the error message.
|
||||||
* @param exception the exception that occurred.
|
* @param exception the exception that occurred.
|
||||||
*/
|
*/
|
||||||
public static void handleErrorCondition(String message, Exception exception) {
|
public static void handleErrorCondition(String message, Throwable exception) {
|
||||||
log.error(1, message, exception);
|
log.error(1, message, exception);
|
||||||
handleErrorCondition(new InternalException(message, exception));
|
handleErrorCondition(new InternalException(message, exception));
|
||||||
}
|
}
|
||||||
@ -128,7 +128,7 @@ public class ExceptionHandler implements Thread.UncaughtExceptionHandler {
|
|||||||
*
|
*
|
||||||
* @param exception the exception that occurred.
|
* @param exception the exception that occurred.
|
||||||
*/
|
*/
|
||||||
public static void handleErrorCondition(final Exception exception) {
|
public static void handleErrorCondition(final Throwable exception) {
|
||||||
try {
|
try {
|
||||||
if (!(exception instanceof InternalException)) {
|
if (!(exception instanceof InternalException)) {
|
||||||
log.error(1, "Error occurred", exception);
|
log.error(1, "Error occurred", exception);
|
||||||
|
@ -409,50 +409,15 @@ public class SimulationRunDialog extends JDialog {
|
|||||||
},
|
},
|
||||||
stackTrace, simulation.getName(), JOptionPane.ERROR_MESSAGE);
|
stackTrace, simulation.getName(), JOptionPane.ERROR_MESSAGE);
|
||||||
|
|
||||||
} else if (t instanceof Exception) {
|
|
||||||
|
|
||||||
// TODO: MEDIUM: Check the exception handling here...
|
|
||||||
t.printStackTrace();
|
|
||||||
DetailDialog.showDetailedMessageDialog(SimulationRunDialog.this,
|
|
||||||
new Object[] {
|
|
||||||
//// An exception occurred during the simulation:
|
|
||||||
trans.get("SimuRunDlg.msg.AnException1"),
|
|
||||||
t.getMessage(),
|
|
||||||
simulation.getSimulationListeners().isEmpty() ?
|
|
||||||
trans.get("SimuRunDlg.msg.AnException2") : ""
|
|
||||||
},
|
|
||||||
stackTrace, simulation.getName(), JOptionPane.ERROR_MESSAGE);
|
|
||||||
|
|
||||||
} else if (t instanceof AssertionError) {
|
|
||||||
|
|
||||||
t.printStackTrace();
|
|
||||||
DetailDialog.showDetailedMessageDialog(SimulationRunDialog.this,
|
|
||||||
new Object[] {
|
|
||||||
//// A computation error occurred during the simulation.
|
|
||||||
trans.get("SimuRunDlg.msg.AssertionError1"),
|
|
||||||
//// Please report this as a bug along with the details below.
|
|
||||||
trans.get("SimuRunDlg.msg.AssertionError2")
|
|
||||||
},
|
|
||||||
stackTrace, simulation.getName(), JOptionPane.ERROR_MESSAGE);
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// Probably an Error
|
ExceptionHandler.handleErrorCondition("An exception occurred during the simulation", t);
|
||||||
DetailDialog.showDetailedMessageDialog(SimulationRunDialog.this,
|
|
||||||
new Object[] {
|
|
||||||
//// An unknown error was encountered during the simulation.
|
|
||||||
trans.get("SimuRunDlg.msg.unknownerror1"),
|
|
||||||
//// The program may be unstable, you should save all your designs and restart OpenRocket now!
|
|
||||||
trans.get("SimuRunDlg.msg.unknownerror2")
|
|
||||||
},
|
|
||||||
stackTrace, simulation.getName(), JOptionPane.ERROR_MESSAGE);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
simulationDone();
|
simulationDone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private void setSimulationProgress(double p) {
|
private void setSimulationProgress(double p) {
|
||||||
int exact = Math.max(progress, (int) (100 * p + 0.5));
|
int exact = Math.max(progress, (int) (100 * p + 0.5));
|
||||||
progress = MathUtil.clamp(exact, 0, 100);
|
progress = MathUtil.clamp(exact, 0, 100);
|
||||||
|
@ -8,6 +8,7 @@ import net.sf.openrocket.optimization.general.OptimizationException;
|
|||||||
import net.sf.openrocket.optimization.rocketoptimization.OptimizableParameter;
|
import net.sf.openrocket.optimization.rocketoptimization.OptimizableParameter;
|
||||||
import net.sf.openrocket.simulation.FlightData;
|
import net.sf.openrocket.simulation.FlightData;
|
||||||
import net.sf.openrocket.simulation.exception.MotorIgnitionException;
|
import net.sf.openrocket.simulation.exception.MotorIgnitionException;
|
||||||
|
import net.sf.openrocket.simulation.exception.SimulationCalculationException;
|
||||||
import net.sf.openrocket.simulation.exception.SimulationCancelledException;
|
import net.sf.openrocket.simulation.exception.SimulationCancelledException;
|
||||||
import net.sf.openrocket.simulation.exception.SimulationException;
|
import net.sf.openrocket.simulation.exception.SimulationException;
|
||||||
import net.sf.openrocket.simulation.exception.SimulationLaunchException;
|
import net.sf.openrocket.simulation.exception.SimulationLaunchException;
|
||||||
@ -44,6 +45,9 @@ public abstract class SimulationBasedParameter implements OptimizableParameter {
|
|||||||
} catch (SimulationLaunchException e) {
|
} catch (SimulationLaunchException e) {
|
||||||
// Other launch exceptions result in illegal value
|
// Other launch exceptions result in illegal value
|
||||||
return Double.NaN;
|
return Double.NaN;
|
||||||
|
} catch (SimulationCalculationException e) {
|
||||||
|
// Calculation errors result in illegal value
|
||||||
|
return Double.NaN;
|
||||||
} catch (SimulationCancelledException e) {
|
} catch (SimulationCancelledException e) {
|
||||||
// Simulation cancellation stops the optimization
|
// Simulation cancellation stops the optimization
|
||||||
throw (InterruptedException) new InterruptedException("Optimization was interrupted").initCause(e);
|
throw (InterruptedException) new InterruptedException("Optimization was interrupted").initCause(e);
|
||||||
|
@ -208,7 +208,7 @@ public abstract class AbstractSimulationStepper implements SimulationStepper {
|
|||||||
*/
|
*/
|
||||||
protected void checkNaN(Coordinate c) {
|
protected void checkNaN(Coordinate c) {
|
||||||
if (c.isNaN()) {
|
if (c.isNaN()) {
|
||||||
throw new BugException("Simulation resulted in not-a-number (NaN) value, please report a bug.");
|
throw new BugException("Simulation resulted in not-a-number (NaN) value, please report a bug, c=" + c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,7 +221,7 @@ public abstract class AbstractSimulationStepper implements SimulationStepper {
|
|||||||
*/
|
*/
|
||||||
protected void checkNaN(Quaternion q) {
|
protected void checkNaN(Quaternion q) {
|
||||||
if (q.isNaN()) {
|
if (q.isNaN()) {
|
||||||
throw new BugException("Simulation resulted in not-a-number (NaN) value, please report a bug.");
|
throw new BugException("Simulation resulted in not-a-number (NaN) value, please report a bug, q=" + q);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ import net.sf.openrocket.aerodynamics.FlightConditions;
|
|||||||
import net.sf.openrocket.aerodynamics.WarningSet;
|
import net.sf.openrocket.aerodynamics.WarningSet;
|
||||||
import net.sf.openrocket.logging.LogHelper;
|
import net.sf.openrocket.logging.LogHelper;
|
||||||
import net.sf.openrocket.models.atmosphere.AtmosphericConditions;
|
import net.sf.openrocket.models.atmosphere.AtmosphericConditions;
|
||||||
|
import net.sf.openrocket.simulation.exception.SimulationCalculationException;
|
||||||
import net.sf.openrocket.simulation.exception.SimulationException;
|
import net.sf.openrocket.simulation.exception.SimulationException;
|
||||||
import net.sf.openrocket.simulation.listeners.SimulationListenerHelper;
|
import net.sf.openrocket.simulation.listeners.SimulationListenerHelper;
|
||||||
import net.sf.openrocket.startup.Application;
|
import net.sf.openrocket.startup.Application;
|
||||||
@ -255,6 +256,13 @@ public class RK4SimulationStepper extends AbstractSimulationStepper {
|
|||||||
status.setSimulationTime(status.getSimulationTime() + store.timestep);
|
status.setSimulationTime(status.getSimulationTime() + store.timestep);
|
||||||
|
|
||||||
status.setPreviousTimeStep(store.timestep);
|
status.setPreviousTimeStep(store.timestep);
|
||||||
|
|
||||||
|
// Verify that values don't run out of range
|
||||||
|
if (status.getRocketVelocity().length2() > 1e18 ||
|
||||||
|
status.getRocketPosition().length2() > 1e18 ||
|
||||||
|
status.getRocketRotationVelocity().length2() > 1e18) {
|
||||||
|
throw new SimulationCalculationException("Simulation values exceeded limits");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -360,7 +368,8 @@ public class RK4SimulationStepper extends AbstractSimulationStepper {
|
|||||||
|
|
||||||
// Compute acceleration in rocket coordinates
|
// Compute acceleration in rocket coordinates
|
||||||
store.angularAcceleration = new Coordinate(momX / store.massData.getLongitudinalInertia(),
|
store.angularAcceleration = new Coordinate(momX / store.massData.getLongitudinalInertia(),
|
||||||
momY / store.massData.getLongitudinalInertia(), momZ / store.massData.getRotationalInertia());
|
momY / store.massData.getLongitudinalInertia(),
|
||||||
|
momZ / store.massData.getRotationalInertia());
|
||||||
|
|
||||||
store.rollAcceleration = store.angularAcceleration.z;
|
store.rollAcceleration = store.angularAcceleration.z;
|
||||||
// TODO: LOW: This should be hypot, but does it matter?
|
// TODO: LOW: This should be hypot, but does it matter?
|
||||||
|
@ -0,0 +1,30 @@
|
|||||||
|
package net.sf.openrocket.simulation.exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An exception that indicates that a computation problem has occurred during
|
||||||
|
* the simulation, for example that some values have exceed reasonable bounds.
|
||||||
|
*
|
||||||
|
* @author Sampo Niskanen <sampo.niskanen@iki.fi>
|
||||||
|
*/
|
||||||
|
public class SimulationCalculationException extends SimulationException {
|
||||||
|
|
||||||
|
public SimulationCalculationException() {
|
||||||
|
// TODO Auto-generated constructor stub
|
||||||
|
}
|
||||||
|
|
||||||
|
public SimulationCalculationException(String message) {
|
||||||
|
super(message);
|
||||||
|
// TODO Auto-generated constructor stub
|
||||||
|
}
|
||||||
|
|
||||||
|
public SimulationCalculationException(Throwable cause) {
|
||||||
|
super(cause);
|
||||||
|
// TODO Auto-generated constructor stub
|
||||||
|
}
|
||||||
|
|
||||||
|
public SimulationCalculationException(String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
// TODO Auto-generated constructor stub
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user