Implemented optimization for FlightConfigurableParameters. Added back

support optimization of deployment delay, deployment altitude, and
ignition delay.  GeneralOptimizationDialog was changed to remove the
sorting or the optimization variables.  It was catestrophically broken
even after previous attempts to fix it.  Note: the change to
GeneralOptimizationDialog accidentally slipped into the previous commit.
This commit is contained in:
kruland2607 2013-03-29 00:39:49 -05:00
parent af7ef8360f
commit ec8248fd10
5 changed files with 144 additions and 30 deletions

View File

@ -98,7 +98,7 @@ import net.sf.openrocket.util.TextUtil;
import com.itextpdf.text.Font;
/**
* General rocket optimization dialog.
* General rocket optimization dialog.
*
* @author Sampo Niskanen <sampo.niskanen@iki.fi>
*/

View File

@ -89,7 +89,7 @@ public interface SimulationModifier extends ChangeSource {
public double getCurrentScaledValue(Simulation simulation) throws OptimizationException;
/**
* Modify the specified simulation to the corresponding parameter value.
*
@ -99,6 +99,13 @@ public interface SimulationModifier extends ChangeSource {
*/
public void modify(Simulation simulation, double scaledValue) throws OptimizationException;
/**
* Called once at the start of the optimization.
* This method can be used to ensure the simulation or rocket are properly configured.
*
* @param simulation
*/
public void initialize(Simulation simulation) throws OptimizationException;
/**
* Compare whether this SimulationModifier is equivalent to another simulation modifier.

View File

@ -76,6 +76,10 @@ public abstract class AbstractSimulationModifier implements SimulationModifier {
return toScaledValue(value);
}
@Override
public void initialize(Simulation simulation) throws OptimizationException {
// Default is no-op.
}
/**

View File

@ -0,0 +1,77 @@
package net.sf.openrocket.optimization.rocketoptimization.modifiers;
import java.util.Locale;
import net.sf.openrocket.document.Simulation;
import net.sf.openrocket.optimization.general.OptimizationException;
import net.sf.openrocket.rocketcomponent.FlightConfigurableParameter;
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.unit.UnitGroup;
import net.sf.openrocket.util.BugException;
import net.sf.openrocket.util.Reflection.Method;
public class FlightConfigurationModifier<E extends FlightConfigurableParameter<E>> extends GenericModifier<E> {
private final Class<? extends RocketComponent> componentClass;
private final String componentId;
private final Method configGetter;
/**
* Sole constructor.
*
* @param modifierName the name of this modifier (returned by {@link #getName()})
* @param modifierDescription the description of this modifier (returned by {@link #getDescription()})
* @param relatedObject the related object (returned by {@link #getRelatedObject()})
* @param unitGroup the unit group (returned by {@link #getUnitGroup()})
* @param multiplier the multiplier by which the value returned by the getter is multiplied
* to obtain the desired value
* @param componentClass the RocketComponent class type that is being modified
* @param componentId the ID of the component to modify
* @param configName the name of the configuration object (base name of the getter)
* @param flightConfigClass the class of the FlightConfigurableParameter
* @param methodName the base name of the getter/setter methods (without "get"/"set")
*/
public FlightConfigurationModifier(
String modifierName,
String modifierDescription,
Object relatedObject,
UnitGroup unitGroup,
double multiplier,
Class<? extends RocketComponent> componentClass,
String componentId,
String configName,
Class<E> flightConfigClass,
String methodName) {
super(modifierName, modifierDescription, relatedObject, unitGroup, multiplier, flightConfigClass, methodName);
this.componentClass = componentClass;
this.componentId = componentId;
try {
configName = configName.substring(0, 1).toUpperCase(Locale.ENGLISH) + configName.substring(1);
configGetter = new Method(componentClass.getMethod("get" + configName));
} catch (SecurityException e) {
throw new BugException("Trying to find method get/set" + configName + " in class " + componentClass, e);
} catch (NoSuchMethodException e) {
throw new BugException("Trying to find method get/set" + configName + " in class " + componentClass, e);
}
}
@Override
protected E getModifiedObject(Simulation simulation) throws OptimizationException {
RocketComponent c = simulation.getRocket().findComponent(componentId);
if (c == null) {
throw new OptimizationException("Could not find component of type " + componentClass.getSimpleName()
+ " with correct ID");
}
FlightConfiguration<E> configs = (FlightConfiguration<E>) configGetter.invoke(c);
return configs.get(simulation.getConfiguration().getFlightConfigurationID());
}
}

View File

@ -12,17 +12,22 @@ import net.sf.openrocket.document.Simulation;
import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.optimization.general.OptimizationException;
import net.sf.openrocket.optimization.rocketoptimization.SimulationModifier;
import net.sf.openrocket.optimization.rocketoptimization.modifiers.FlightConfigurationModifier;
import net.sf.openrocket.optimization.rocketoptimization.modifiers.GenericComponentModifier;
import net.sf.openrocket.rocketcomponent.BodyTube;
import net.sf.openrocket.rocketcomponent.DeploymentConfiguration;
import net.sf.openrocket.rocketcomponent.DeploymentConfiguration.DeployEvent;
import net.sf.openrocket.rocketcomponent.EllipticalFinSet;
import net.sf.openrocket.rocketcomponent.FinSet;
import net.sf.openrocket.rocketcomponent.FreeformFinSet;
import net.sf.openrocket.rocketcomponent.IgnitionConfiguration;
import net.sf.openrocket.rocketcomponent.InternalComponent;
import net.sf.openrocket.rocketcomponent.LaunchLug;
import net.sf.openrocket.rocketcomponent.MassComponent;
import net.sf.openrocket.rocketcomponent.MotorMount;
import net.sf.openrocket.rocketcomponent.NoseCone;
import net.sf.openrocket.rocketcomponent.Parachute;
import net.sf.openrocket.rocketcomponent.RecoveryDevice;
import net.sf.openrocket.rocketcomponent.Rocket;
import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.rocketcomponent.Streamer;
@ -186,15 +191,20 @@ public class DefaultSimulationModifierService implements SimulationModifierServi
setDefaultMinMax(mod, simulation);
modifiers.add(mod);
mod = new GenericComponentModifier(
mod = new FlightConfigurationModifier<IgnitionConfiguration>(
trans.get("optimization.modifier.motormount.delay"),
trans.get("optimization.modifier.motormount.delay.desc"),
c, UnitGroup.UNITS_SHORT_TIME,
1.0, c.getClass(), c.getID(), "DefaultIgnitionDelay");
1.0,
c.getClass(),
c.getID(),
"IgnitionConfiguration",
IgnitionConfiguration.class,
"IgnitionDelay");
mod.setMinValue(0);
mod.setMaxValue(5);
modifiers.add(mod);
}
}
@ -241,31 +251,48 @@ public class DefaultSimulationModifierService implements SimulationModifierServi
}
// FIXME: Reimplement for flight-configuration controlled modifiers
// Recovery device deployment altitude and delay
// if (c instanceof RecoveryDevice) {
// RecoveryDevice device = (RecoveryDevice) c;
//
// SimulationModifier mod = new GenericComponentModifier(
// trans.get("optimization.modifier.recoverydevice.deployDelay"),
// trans.get("optimization.modifier.recoverydevice.deployDelay.desc"),
// c, UnitGroup.UNITS_SHORT_TIME,
// 1.0, c.getClass(), c.getID(), "DefaultDeployDelay");
// mod.setMinValue(0);
// mod.setMaxValue(10);
// modifiers.add(mod);
//
// if (device.getDefaultDeployEvent() == DeployEvent.ALTITUDE) {
// mod = new GenericComponentModifier(
// trans.get("optimization.modifier.recoverydevice.deployAltitude"),
// trans.get("optimization.modifier.recoverydevice.deployAltitude.desc"),
// c, UnitGroup.UNITS_DISTANCE,
// 1.0, c.getClass(), c.getID(), "DefaultDeployAltitude");
// setDefaultMinMax(mod, simulation);
// modifiers.add(mod);
// }
// }
if (c instanceof RecoveryDevice) {
RecoveryDevice device = (RecoveryDevice) c;
SimulationModifier mod = new FlightConfigurationModifier<DeploymentConfiguration>(
trans.get("optimization.modifier.recoverydevice.deployDelay"),
trans.get("optimization.modifier.recoverydevice.deployDelay.desc"),
c,
UnitGroup.UNITS_SHORT_TIME,
1.0,
c.getClass(),
c.getID(),
"DeploymentConfiguration",
DeploymentConfiguration.class,
"DeployDelay");
mod.setMinValue(0);
mod.setMaxValue(10);
modifiers.add(mod);
mod = new FlightConfigurationModifier<DeploymentConfiguration>(
trans.get("optimization.modifier.recoverydevice.deployAltitude"),
trans.get("optimization.modifier.recoverydevice.deployAltitude.desc"),
c,
UnitGroup.UNITS_DISTANCE,
1.0,
c.getClass(),
c.getID(),
"DeploymentConfiguration",
DeploymentConfiguration.class,
"DeployAltitude") {
@Override
public void initialize(Simulation simulation) throws OptimizationException {
DeploymentConfiguration config = getModifiedObject(simulation);
config.setDeployEvent(DeployEvent.APOGEE);
}
};
setDefaultMinMax(mod, simulation);
modifiers.add(mod);
}
// Conditional shape parameter of Transition
@ -288,7 +315,6 @@ public class DefaultSimulationModifierService implements SimulationModifierServi
return modifiers;
}
private void setDefaultMinMax(SimulationModifier mod, Simulation simulation) {
try {
double current = mod.getCurrentSIValue(simulation);