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.desc = Optimize the root chord length of the fin set.
|
||||
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.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.evals = Evaluations
|
||||
OptimizationPlotDialog.plot.ttip.stability = Stability:
|
||||
OptimizationPlotDialog.plot.label.optimum = Optimum
|
||||
|
||||
! Optimization parameters
|
||||
MaximumAltitudeParameter.name = Apogee altitude
|
||||
|
@ -140,6 +140,7 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
|
||||
total.setCm(total.getCm() - total.getPitchDampingMoment());
|
||||
total.setCyaw(total.getCyaw() - total.getYawDampingMoment());
|
||||
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
@ -648,6 +649,8 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
|
||||
double yaw = conditions.getYawRate();
|
||||
double vel = conditions.getVelocity();
|
||||
|
||||
vel = MathUtil.max(vel, 1);
|
||||
|
||||
// double Cm = total.Cm - total.CN * total.cg.x / conditions.getRefLength();
|
||||
// System.out.printf("Damping pitch/yaw, mul=%.4f pitch rate=%.4f "+
|
||||
// "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.setPitchDampingMoment(mul * MathUtil.sign(pitch) * pow2(pitch / vel));
|
||||
total.setYawDampingMoment(mul * MathUtil.sign(yaw) * pow2(yaw / vel));
|
||||
|
||||
}
|
||||
|
||||
// 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.JToggleButton;
|
||||
import javax.swing.ListSelectionModel;
|
||||
import javax.swing.Timer;
|
||||
import javax.swing.border.TitledBorder;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
@ -95,7 +96,6 @@ import net.sf.openrocket.util.TextUtil;
|
||||
|
||||
import com.itextpdf.text.Font;
|
||||
|
||||
// FIXME: Override to zero mass produces NaN in simulation
|
||||
|
||||
/**
|
||||
* General rocket optimization dialog.
|
||||
@ -791,6 +791,18 @@ public class GeneralOptimizationDialog extends JDialog {
|
||||
|
||||
worker = null;
|
||||
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
|
||||
|
@ -34,6 +34,9 @@ import net.sf.openrocket.util.MathUtil;
|
||||
import org.jfree.chart.ChartFactory;
|
||||
import org.jfree.chart.ChartPanel;
|
||||
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.NumberAxis;
|
||||
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.XYSeriesCollection;
|
||||
import org.jfree.ui.RectangleEdge;
|
||||
import org.jfree.ui.TextAnchor;
|
||||
|
||||
/**
|
||||
* A class that plots the path of an optimization.
|
||||
@ -57,8 +61,7 @@ public class OptimizationPlotDialog extends JDialog {
|
||||
private static final LogHelper log = Application.getLogger();
|
||||
private static final Translator trans = Application.getTranslator();
|
||||
|
||||
// FIXME: Set range to optimization range
|
||||
|
||||
|
||||
private static final LinearInterpolator RED = new LinearInterpolator(
|
||||
new double[] { 0.0, 1.0 }, new double[] { 0.0, 1.0 }
|
||||
);
|
||||
@ -155,6 +158,37 @@ public class OptimizationPlotDialog extends JDialog {
|
||||
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);
|
||||
lineRenderer.setBaseShapesVisible(true);
|
||||
lineRenderer.setSeriesShapesFilled(0, false);
|
||||
@ -191,13 +225,13 @@ public class OptimizationPlotDialog extends JDialog {
|
||||
Unit yUnit = modY.getUnitGroup().getDefaultUnit();
|
||||
|
||||
// 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>();
|
||||
for (Point p : path) {
|
||||
FunctionEvaluationData data = evaluations.get(p);
|
||||
if (data != null) {
|
||||
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));
|
||||
} else {
|
||||
log.error("Could not find evaluation data for point " + p);
|
||||
@ -256,13 +290,24 @@ public class OptimizationPlotDialog extends JDialog {
|
||||
false); // Urls
|
||||
|
||||
|
||||
chart.getXYPlot().getDomainAxis().setRange(xUnit.toUnit(modX.getMinValue()),
|
||||
xUnit.toUnit(modX.getMaxValue()));
|
||||
// Set the scale of the plot to the limits
|
||||
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()),
|
||||
yUnit.toUnit(modY.getMaxValue()));
|
||||
chart.getXYPlot().getDomainAxis().setRange(x1, x2);
|
||||
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);
|
||||
|
||||
XYShapeRenderer shapeRenderer = new XYShapeRenderer();
|
||||
@ -290,7 +335,7 @@ public class OptimizationPlotDialog extends JDialog {
|
||||
|
||||
XYPlot plot = chart.getXYPlot();
|
||||
|
||||
plot.setDataset(0, new XYSeriesCollection(series));
|
||||
plot.setDataset(0, new XYSeriesCollection(pathSeries));
|
||||
plot.setRenderer(lineRenderer);
|
||||
|
||||
plot.setDataset(1, evalDataset);
|
||||
|
@ -113,7 +113,7 @@ public class ExceptionHandler implements Thread.UncaughtExceptionHandler {
|
||||
* @param message the error message.
|
||||
* @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);
|
||||
handleErrorCondition(new InternalException(message, exception));
|
||||
}
|
||||
@ -128,7 +128,7 @@ public class ExceptionHandler implements Thread.UncaughtExceptionHandler {
|
||||
*
|
||||
* @param exception the exception that occurred.
|
||||
*/
|
||||
public static void handleErrorCondition(final Exception exception) {
|
||||
public static void handleErrorCondition(final Throwable exception) {
|
||||
try {
|
||||
if (!(exception instanceof InternalException)) {
|
||||
log.error(1, "Error occurred", exception);
|
||||
|
@ -409,50 +409,15 @@ public class SimulationRunDialog extends JDialog {
|
||||
},
|
||||
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 {
|
||||
|
||||
// Probably an Error
|
||||
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);
|
||||
ExceptionHandler.handleErrorCondition("An exception occurred during the simulation", t);
|
||||
|
||||
}
|
||||
simulationDone();
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void setSimulationProgress(double p) {
|
||||
int exact = Math.max(progress, (int) (100 * p + 0.5));
|
||||
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.simulation.FlightData;
|
||||
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.SimulationException;
|
||||
import net.sf.openrocket.simulation.exception.SimulationLaunchException;
|
||||
@ -44,6 +45,9 @@ public abstract class SimulationBasedParameter implements OptimizableParameter {
|
||||
} catch (SimulationLaunchException e) {
|
||||
// Other launch exceptions result in illegal value
|
||||
return Double.NaN;
|
||||
} catch (SimulationCalculationException e) {
|
||||
// Calculation errors result in illegal value
|
||||
return Double.NaN;
|
||||
} catch (SimulationCancelledException e) {
|
||||
// Simulation cancellation stops the optimization
|
||||
throw (InterruptedException) new InterruptedException("Optimization was interrupted").initCause(e);
|
||||
|
@ -208,7 +208,7 @@ public abstract class AbstractSimulationStepper implements SimulationStepper {
|
||||
*/
|
||||
protected void checkNaN(Coordinate c) {
|
||||
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) {
|
||||
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.logging.LogHelper;
|
||||
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.listeners.SimulationListenerHelper;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
@ -255,6 +256,13 @@ public class RK4SimulationStepper extends AbstractSimulationStepper {
|
||||
status.setSimulationTime(status.getSimulationTime() + 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
|
||||
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;
|
||||
// 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