optimization updates

This commit is contained in:
Sampo Niskanen 2011-08-10 05:08:47 +00:00
parent 2639d13391
commit 8b29435bac
13 changed files with 248 additions and 152 deletions

View File

@ -1479,3 +1479,6 @@ MaximumAccelerationParameter.name = Maximum acceleration
StabilityParameter.name = Stability
GroundHitVelocityParameter.name = Ground hit speed
LandingDistanceParameter.name = Landing distance
TotalFlightTimeParameter.name = Total flight time
DeploymentVelocityParameter.name = Velocity at parachute deployment

View File

@ -57,7 +57,8 @@ 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 }
);
@ -165,7 +166,6 @@ public class OptimizationPlotDialog extends JDialog {
tooltipGenerator.addToolTipSeries(tooltips);
lineRenderer.setBaseToolTipGenerator(tooltipGenerator);
XYPlot plot = chart.getXYPlot();
plot.setDataset(0, new XYSeriesCollection(series));
@ -255,6 +255,14 @@ public class OptimizationPlotDialog extends JDialog {
true, // Tooltips
false); // Urls
chart.getXYPlot().getDomainAxis().setRange(xUnit.toUnit(modX.getMinValue()),
xUnit.toUnit(modX.getMaxValue()));
chart.getXYPlot().getRangeAxis().setRange(yUnit.toUnit(modY.getMinValue()),
yUnit.toUnit(modY.getMaxValue()));
PaintScale paintScale = new GradientScale(min, max);
XYShapeRenderer shapeRenderer = new XYShapeRenderer();

View File

@ -111,6 +111,9 @@ public class MultidirectionalSearchOptimizer implements FunctionOptimizer, Stati
functionExecutor.compute(expansion);
// Check reflection acceptance
System.err.println("stepsize = " + step);
System.err.println("Simplex = " + simplex);
System.err.println("Reflection = " + reflection);
log.debug("Computing reflection");
functionExecutor.waitFor(reflection);
@ -188,11 +191,13 @@ public class MultidirectionalSearchOptimizer implements FunctionOptimizer, Stati
} else {
log.debug("Coordinate search unsuccessful, halving step.");
step /= 2;
simplexComputed = false;
reductionFallback++;
}
} else {
log.debug("Coordinate search not used, halving step.");
step /= 2;
simplexComputed = false;
reductionFallback++;
}
@ -223,8 +228,11 @@ public class MultidirectionalSearchOptimizer implements FunctionOptimizer, Stati
private void createReflection(List<Point> base, List<Point> reflection) {
Point current = base.get(0);
reflection.clear();
/* new = - (old - current) + current = 2*current - old */
for (int i = 1; i < base.size(); i++) {
Point p = current.mul(2).sub(base.get(i));
Point p = base.get(i);
p = current.mul(2).sub(p);
reflection.add(p);
}
}
@ -242,6 +250,9 @@ public class MultidirectionalSearchOptimizer implements FunctionOptimizer, Stati
Point current = base.get(0);
for (int i = 1; i < base.size(); i++) {
Point p = base.get(i);
/* new = (old - current)*0.5 + current = old*0.5 + current*0.5 = (old + current)*0.5 */
p = p.add(current).mul(0.5);
base.set(i, p);
}

View File

@ -0,0 +1,40 @@
package net.sf.openrocket.optimization.rocketoptimization.parameters;
import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.simulation.FlightData;
import net.sf.openrocket.simulation.FlightDataType;
import net.sf.openrocket.simulation.listeners.SimulationListener;
import net.sf.openrocket.simulation.listeners.system.RecoveryDeviceDeploymentEndListener;
import net.sf.openrocket.startup.Application;
import net.sf.openrocket.unit.UnitGroup;
/**
* An optimization parameter that computes the total flight time.
*
* @author Sampo Niskanen <sampo.niskanen@iki.fi>
*/
public class DeploymentVelocityParameter extends SimulationBasedParameter {
private static final Translator trans = Application.getTranslator();
@Override
public String getName() {
return trans.get("name");
}
@Override
protected SimulationListener[] getSimulationListeners() {
return new SimulationListener[] { new RecoveryDeviceDeploymentEndListener() };
}
@Override
protected double getResultValue(FlightData simulatedData) {
return simulatedData.getBranch(0).getLast(FlightDataType.TYPE_VELOCITY_TOTAL);
}
@Override
public UnitGroup getUnitGroup() {
return UnitGroup.UNITS_VELOCITY;
}
}

View File

@ -1,16 +1,8 @@
package net.sf.openrocket.optimization.rocketoptimization.parameters;
import net.sf.openrocket.document.Simulation;
import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.logging.LogHelper;
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.FlightDataType;
import net.sf.openrocket.simulation.exception.MotorIgnitionException;
import net.sf.openrocket.simulation.exception.SimulationCancelledException;
import net.sf.openrocket.simulation.exception.SimulationException;
import net.sf.openrocket.simulation.exception.SimulationLaunchException;
import net.sf.openrocket.simulation.listeners.system.InterruptListener;
import net.sf.openrocket.startup.Application;
import net.sf.openrocket.unit.UnitGroup;
@ -19,9 +11,8 @@ import net.sf.openrocket.unit.UnitGroup;
*
* @author Sampo Niskanen <sampo.niskanen@iki.fi>
*/
public class GroundHitVelocityParameter implements OptimizableParameter {
public class GroundHitVelocityParameter extends SimulationBasedParameter {
private static final LogHelper log = Application.getLogger();
private static final Translator trans = Application.getTranslator();
@Override
@ -30,25 +21,8 @@ public class GroundHitVelocityParameter implements OptimizableParameter {
}
@Override
public double computeValue(Simulation simulation) throws OptimizationException, InterruptedException {
try {
log.debug("Running simulation to evaluate ground hit speed");
simulation.simulate(new InterruptListener());
double value = simulation.getSimulatedData().getBranch(0).getLast(FlightDataType.TYPE_VELOCITY_TOTAL);
log.debug("Ground hit speed was " + value);
return value;
} catch (MotorIgnitionException e) {
// A problem with motor ignition will cause optimization to fail
throw new OptimizationException(e);
} catch (SimulationLaunchException e) {
// Other launch exceptions result in zero altitude
return Double.NaN;
} catch (SimulationCancelledException e) {
throw (InterruptedException) new InterruptedException("Optimization was interrupted").initCause(e);
} catch (SimulationException e) {
// Other exceptions fail
throw new OptimizationException(e);
}
protected double getResultValue(FlightData simulatedData) {
return simulatedData.getBranch(0).getLast(FlightDataType.TYPE_VELOCITY_TOTAL);
}
@Override
@ -56,4 +30,5 @@ public class GroundHitVelocityParameter implements OptimizableParameter {
return UnitGroup.UNITS_VELOCITY;
}
}

View File

@ -1,16 +1,8 @@
package net.sf.openrocket.optimization.rocketoptimization.parameters;
import net.sf.openrocket.document.Simulation;
import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.logging.LogHelper;
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.FlightDataType;
import net.sf.openrocket.simulation.exception.MotorIgnitionException;
import net.sf.openrocket.simulation.exception.SimulationCancelledException;
import net.sf.openrocket.simulation.exception.SimulationException;
import net.sf.openrocket.simulation.exception.SimulationLaunchException;
import net.sf.openrocket.simulation.listeners.system.InterruptListener;
import net.sf.openrocket.startup.Application;
import net.sf.openrocket.unit.UnitGroup;
@ -19,9 +11,8 @@ import net.sf.openrocket.unit.UnitGroup;
*
* @author Sampo Niskanen <sampo.niskanen@iki.fi>
*/
public class LandingDistanceParameter implements OptimizableParameter {
public class LandingDistanceParameter extends SimulationBasedParameter {
private static final LogHelper log = Application.getLogger();
private static final Translator trans = Application.getTranslator();
@Override
@ -30,25 +21,8 @@ public class LandingDistanceParameter implements OptimizableParameter {
}
@Override
public double computeValue(Simulation simulation) throws OptimizationException, InterruptedException {
try {
log.debug("Running simulation to evaluate rocket landing distance");
simulation.simulate(new InterruptListener());
double value = simulation.getSimulatedData().getBranch(0).getLast(FlightDataType.TYPE_POSITION_XY);
log.debug("Landing distance was " + value);
return value;
} catch (MotorIgnitionException e) {
// A problem with motor ignition will cause optimization to fail
throw new OptimizationException(e);
} catch (SimulationLaunchException e) {
// Other launch exceptions result in zero altitude
return Double.NaN;
} catch (SimulationCancelledException e) {
throw (InterruptedException) new InterruptedException("Optimization was interrupted").initCause(e);
} catch (SimulationException e) {
// Other exceptions fail
throw new OptimizationException(e);
}
protected double getResultValue(FlightData simulatedData) {
return simulatedData.getBranch(0).getLast(FlightDataType.TYPE_POSITION_XY);
}
@Override

View File

@ -1,17 +1,10 @@
package net.sf.openrocket.optimization.rocketoptimization.parameters;
import net.sf.openrocket.document.Simulation;
import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.logging.LogHelper;
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.FlightDataType;
import net.sf.openrocket.simulation.exception.MotorIgnitionException;
import net.sf.openrocket.simulation.exception.SimulationCancelledException;
import net.sf.openrocket.simulation.exception.SimulationException;
import net.sf.openrocket.simulation.exception.SimulationLaunchException;
import net.sf.openrocket.simulation.listeners.SimulationListener;
import net.sf.openrocket.simulation.listeners.system.ApogeeEndListener;
import net.sf.openrocket.simulation.listeners.system.InterruptListener;
import net.sf.openrocket.startup.Application;
import net.sf.openrocket.unit.UnitGroup;
@ -20,9 +13,8 @@ import net.sf.openrocket.unit.UnitGroup;
*
* @author Sampo Niskanen <sampo.niskanen@iki.fi>
*/
public class MaximumAccelerationParameter implements OptimizableParameter {
public class MaximumAccelerationParameter extends SimulationBasedParameter {
private static final LogHelper log = Application.getLogger();
private static final Translator trans = Application.getTranslator();
@Override
@ -31,25 +23,13 @@ public class MaximumAccelerationParameter implements OptimizableParameter {
}
@Override
public double computeValue(Simulation simulation) throws OptimizationException, InterruptedException {
try {
log.debug("Running simulation to evaluate maximum acceleration");
simulation.simulate(new ApogeeEndListener(), new InterruptListener());
double value = simulation.getSimulatedData().getBranch(0).getMaximum(FlightDataType.TYPE_ACCELERATION_TOTAL);
log.debug("Maximum acceleration was " + value);
return value;
} catch (MotorIgnitionException e) {
// A problem with motor ignition will cause optimization to fail
throw new OptimizationException(e);
} catch (SimulationLaunchException e) {
// Other launch exceptions result in zero velocity
return Double.NaN;
} catch (SimulationCancelledException e) {
throw (InterruptedException) new InterruptedException("Optimization was interrupted").initCause(e);
} catch (SimulationException e) {
// Other exceptions fail
throw new OptimizationException(e);
}
protected SimulationListener[] getSimulationListeners() {
return new SimulationListener[] { new ApogeeEndListener() };
}
@Override
protected double getResultValue(FlightData simulatedData) {
return simulatedData.getBranch(0).getMaximum(FlightDataType.TYPE_ACCELERATION_TOTAL);
}
@Override

View File

@ -1,17 +1,10 @@
package net.sf.openrocket.optimization.rocketoptimization.parameters;
import net.sf.openrocket.document.Simulation;
import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.logging.LogHelper;
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.FlightDataType;
import net.sf.openrocket.simulation.exception.MotorIgnitionException;
import net.sf.openrocket.simulation.exception.SimulationCancelledException;
import net.sf.openrocket.simulation.exception.SimulationException;
import net.sf.openrocket.simulation.exception.SimulationLaunchException;
import net.sf.openrocket.simulation.listeners.SimulationListener;
import net.sf.openrocket.simulation.listeners.system.ApogeeEndListener;
import net.sf.openrocket.simulation.listeners.system.InterruptListener;
import net.sf.openrocket.startup.Application;
import net.sf.openrocket.unit.UnitGroup;
@ -20,9 +13,8 @@ import net.sf.openrocket.unit.UnitGroup;
*
* @author Sampo Niskanen <sampo.niskanen@iki.fi>
*/
public class MaximumAltitudeParameter implements OptimizableParameter {
public class MaximumAltitudeParameter extends SimulationBasedParameter {
private static final LogHelper log = Application.getLogger();
private static final Translator trans = Application.getTranslator();
@Override
@ -31,24 +23,13 @@ public class MaximumAltitudeParameter implements OptimizableParameter {
}
@Override
public double computeValue(Simulation simulation) throws OptimizationException, InterruptedException {
try {
log.debug("Running simulation to evaluate apogee altitude");
simulation.simulate(new ApogeeEndListener(), new InterruptListener());
log.debug("Maximum altitude was " + simulation.getSimulatedData().getBranch(0).getMaximum(FlightDataType.TYPE_ALTITUDE));
return simulation.getSimulatedData().getBranch(0).getMaximum(FlightDataType.TYPE_ALTITUDE);
} catch (MotorIgnitionException e) {
// A problem with motor ignition will cause optimization to fail
throw new OptimizationException(e);
} catch (SimulationLaunchException e) {
// Other launch exceptions result in zero altitude
return 0.0;
} catch (SimulationCancelledException e) {
throw (InterruptedException) new InterruptedException("Optimization was interrupted").initCause(e);
} catch (SimulationException e) {
// Other exceptions fail
throw new OptimizationException(e);
}
protected SimulationListener[] getSimulationListeners() {
return new SimulationListener[] { new ApogeeEndListener() };
}
@Override
protected double getResultValue(FlightData simulatedData) {
return simulatedData.getBranch(0).getMaximum(FlightDataType.TYPE_ALTITUDE);
}
@Override

View File

@ -1,17 +1,10 @@
package net.sf.openrocket.optimization.rocketoptimization.parameters;
import net.sf.openrocket.document.Simulation;
import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.logging.LogHelper;
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.FlightDataType;
import net.sf.openrocket.simulation.exception.MotorIgnitionException;
import net.sf.openrocket.simulation.exception.SimulationCancelledException;
import net.sf.openrocket.simulation.exception.SimulationException;
import net.sf.openrocket.simulation.exception.SimulationLaunchException;
import net.sf.openrocket.simulation.listeners.SimulationListener;
import net.sf.openrocket.simulation.listeners.system.ApogeeEndListener;
import net.sf.openrocket.simulation.listeners.system.InterruptListener;
import net.sf.openrocket.startup.Application;
import net.sf.openrocket.unit.UnitGroup;
@ -20,9 +13,8 @@ import net.sf.openrocket.unit.UnitGroup;
*
* @author Sampo Niskanen <sampo.niskanen@iki.fi>
*/
public class MaximumVelocityParameter implements OptimizableParameter {
public class MaximumVelocityParameter extends SimulationBasedParameter {
private static final LogHelper log = Application.getLogger();
private static final Translator trans = Application.getTranslator();
@Override
@ -31,25 +23,13 @@ public class MaximumVelocityParameter implements OptimizableParameter {
}
@Override
public double computeValue(Simulation simulation) throws OptimizationException, InterruptedException {
try {
log.debug("Running simulation to evaluate maximum velocity");
simulation.simulate(new ApogeeEndListener(), new InterruptListener());
double value = simulation.getSimulatedData().getBranch(0).getMaximum(FlightDataType.TYPE_VELOCITY_TOTAL);
log.debug("Maximum velocity was " + value);
return value;
} catch (MotorIgnitionException e) {
// A problem with motor ignition will cause optimization to fail
throw new OptimizationException(e);
} catch (SimulationLaunchException e) {
// Other launch exceptions result in zero velocity
return Double.NaN;
} catch (SimulationCancelledException e) {
throw (InterruptedException) new InterruptedException("Optimization was interrupted").initCause(e);
} catch (SimulationException e) {
// Other exceptions fail
throw new OptimizationException(e);
}
protected SimulationListener[] getSimulationListeners() {
return new SimulationListener[] { new ApogeeEndListener() };
}
@Override
protected double getResultValue(FlightData simulatedData) {
return simulatedData.getBranch(0).getMaximum(FlightDataType.TYPE_VELOCITY_TOTAL);
}
@Override

View File

@ -0,0 +1,78 @@
package net.sf.openrocket.optimization.rocketoptimization.parameters;
import java.util.Arrays;
import net.sf.openrocket.document.Simulation;
import net.sf.openrocket.logging.LogHelper;
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.SimulationCancelledException;
import net.sf.openrocket.simulation.exception.SimulationException;
import net.sf.openrocket.simulation.exception.SimulationLaunchException;
import net.sf.openrocket.simulation.listeners.SimulationListener;
import net.sf.openrocket.simulation.listeners.system.InterruptListener;
import net.sf.openrocket.startup.Application;
/**
* An abstract optimization parameter that simulates a rocket flight and obtains
* a value from the simulation result.
*
* @author Sampo Niskanen <sampo.niskanen@iki.fi>
*/
public abstract class SimulationBasedParameter implements OptimizableParameter {
private static final LogHelper log = Application.getLogger();
@Override
public double computeValue(Simulation simulation) throws OptimizationException, InterruptedException {
try {
log.debug("Running simulation for " + getName());
SimulationListener[] listeners = getSimulationListeners();
listeners = Arrays.copyOf(listeners, listeners.length + 1);
listeners[listeners.length - 1] = new InterruptListener();
simulation.simulate(listeners);
double value = getResultValue(simulation.getSimulatedData());
log.debug("Parameter '" + getName() + " was " + value);
return value;
} catch (MotorIgnitionException e) {
// A problem with motor ignition will cause optimization to fail
throw new OptimizationException(e);
} catch (SimulationLaunchException e) {
// Other launch exceptions result in illegal value
return Double.NaN;
} catch (SimulationCancelledException e) {
// Simulation cancellation stops the optimization
throw (InterruptedException) new InterruptedException("Optimization was interrupted").initCause(e);
} catch (SimulationException e) {
// Other exceptions fail
throw new OptimizationException(e);
}
}
/**
* Return the optimization parameter from the simulation flight data.
*
* @param simulatedData the simulated data.
* @return the optimization parameter.
*/
protected abstract double getResultValue(FlightData simulatedData);
/**
* Return an array of simulation listeners to provide to the simulation.
* This may include a listener that stops the simulation after the necessary value
* has been computed.
* <p>
* This array should NOT contain InterruptListener, it will be added implicitly.
*
* @return an array of simulation listeners to include.
*/
protected SimulationListener[] getSimulationListeners() {
return new SimulationListener[0];
}
}

View File

@ -0,0 +1,33 @@
package net.sf.openrocket.optimization.rocketoptimization.parameters;
import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.simulation.FlightData;
import net.sf.openrocket.simulation.FlightDataType;
import net.sf.openrocket.startup.Application;
import net.sf.openrocket.unit.UnitGroup;
/**
* An optimization parameter that computes the total flight time.
*
* @author Sampo Niskanen <sampo.niskanen@iki.fi>
*/
public class TotalFlightTimeParameter extends SimulationBasedParameter {
private static final Translator trans = Application.getTranslator();
@Override
public String getName() {
return trans.get("name");
}
@Override
protected double getResultValue(FlightData simulatedData) {
return simulatedData.getBranch(0).getLast(FlightDataType.TYPE_TIME);
}
@Override
public UnitGroup getUnitGroup() {
return UnitGroup.UNITS_FLIGHT_TIME;
}
}

View File

@ -6,12 +6,14 @@ import java.util.List;
import net.sf.openrocket.document.OpenRocketDocument;
import net.sf.openrocket.optimization.rocketoptimization.OptimizableParameter;
import net.sf.openrocket.optimization.rocketoptimization.parameters.DeploymentVelocityParameter;
import net.sf.openrocket.optimization.rocketoptimization.parameters.GroundHitVelocityParameter;
import net.sf.openrocket.optimization.rocketoptimization.parameters.LandingDistanceParameter;
import net.sf.openrocket.optimization.rocketoptimization.parameters.MaximumAccelerationParameter;
import net.sf.openrocket.optimization.rocketoptimization.parameters.MaximumAltitudeParameter;
import net.sf.openrocket.optimization.rocketoptimization.parameters.MaximumVelocityParameter;
import net.sf.openrocket.optimization.rocketoptimization.parameters.StabilityParameter;
import net.sf.openrocket.optimization.rocketoptimization.parameters.TotalFlightTimeParameter;
/**
* Default implementation for optimization parameter service.
@ -31,6 +33,8 @@ public class DefaultOptimizableParameterService implements OptimizableParameterS
list.add(new StabilityParameter(true));
list.add(new GroundHitVelocityParameter());
list.add(new LandingDistanceParameter());
list.add(new TotalFlightTimeParameter());
list.add(new DeploymentVelocityParameter());
return list;
}

View File

@ -0,0 +1,29 @@
package net.sf.openrocket.simulation.listeners.system;
import net.sf.openrocket.rocketcomponent.RecoveryDevice;
import net.sf.openrocket.simulation.FlightEvent;
import net.sf.openrocket.simulation.SimulationStatus;
import net.sf.openrocket.simulation.exception.SimulationException;
import net.sf.openrocket.simulation.listeners.AbstractSimulationListener;
/**
* A simulation listeners that ends the simulation when apogee is reached.
*
* @author Sampo Niskanen <sampo.niskanen@iki.fi>
*/
public class RecoveryDeviceDeploymentEndListener extends AbstractSimulationListener {
public static final RecoveryDeviceDeploymentEndListener INSTANCE = new RecoveryDeviceDeploymentEndListener();
@Override
public boolean recoveryDeviceDeployment(SimulationStatus status, RecoveryDevice recoveryDevice) throws SimulationException {
status.getEventQueue().add(new FlightEvent(FlightEvent.Type.SIMULATION_END, status.getSimulationTime()));
return true;
}
@Override
public boolean isSystemListener() {
return true;
}
}