optimization updates

This commit is contained in:
Sampo Niskanen 2011-08-12 18:56:24 +00:00
parent 8b29435bac
commit 784c76091b
10 changed files with 122 additions and 54 deletions

View File

@ -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

View File

@ -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?

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);
}
}
}

View File

@ -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?

View File

@ -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
}
}