From ec8248fd1061741a631d67d237a3e433a4db54d2 Mon Sep 17 00:00:00 2001 From: kruland2607 Date: Fri, 29 Mar 2013 00:39:49 -0500 Subject: [PATCH] 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. --- .../GeneralOptimizationDialog.java | 2 +- .../SimulationModifier.java | 9 +- .../modifiers/AbstractSimulationModifier.java | 4 + .../FlightConfigurationModifier.java | 77 +++++++++++++++++ .../DefaultSimulationModifierService.java | 82 ++++++++++++------- 5 files changed, 144 insertions(+), 30 deletions(-) create mode 100644 core/src/net/sf/openrocket/optimization/rocketoptimization/modifiers/FlightConfigurationModifier.java diff --git a/core/src/net/sf/openrocket/gui/dialogs/optimization/GeneralOptimizationDialog.java b/core/src/net/sf/openrocket/gui/dialogs/optimization/GeneralOptimizationDialog.java index 9f4e75470..767c50f38 100644 --- a/core/src/net/sf/openrocket/gui/dialogs/optimization/GeneralOptimizationDialog.java +++ b/core/src/net/sf/openrocket/gui/dialogs/optimization/GeneralOptimizationDialog.java @@ -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 */ diff --git a/core/src/net/sf/openrocket/optimization/rocketoptimization/SimulationModifier.java b/core/src/net/sf/openrocket/optimization/rocketoptimization/SimulationModifier.java index 1989ea074..b85751ae3 100644 --- a/core/src/net/sf/openrocket/optimization/rocketoptimization/SimulationModifier.java +++ b/core/src/net/sf/openrocket/optimization/rocketoptimization/SimulationModifier.java @@ -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. diff --git a/core/src/net/sf/openrocket/optimization/rocketoptimization/modifiers/AbstractSimulationModifier.java b/core/src/net/sf/openrocket/optimization/rocketoptimization/modifiers/AbstractSimulationModifier.java index 20bfcd03e..32f237365 100644 --- a/core/src/net/sf/openrocket/optimization/rocketoptimization/modifiers/AbstractSimulationModifier.java +++ b/core/src/net/sf/openrocket/optimization/rocketoptimization/modifiers/AbstractSimulationModifier.java @@ -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. + } /** diff --git a/core/src/net/sf/openrocket/optimization/rocketoptimization/modifiers/FlightConfigurationModifier.java b/core/src/net/sf/openrocket/optimization/rocketoptimization/modifiers/FlightConfigurationModifier.java new file mode 100644 index 000000000..d25ed55f0 --- /dev/null +++ b/core/src/net/sf/openrocket/optimization/rocketoptimization/modifiers/FlightConfigurationModifier.java @@ -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> extends GenericModifier { + + private final Class 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 componentClass, + String componentId, + String configName, + Class 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 configs = (FlightConfiguration) configGetter.invoke(c); + return configs.get(simulation.getConfiguration().getFlightConfigurationID()); + } + +} diff --git a/core/src/net/sf/openrocket/optimization/services/DefaultSimulationModifierService.java b/core/src/net/sf/openrocket/optimization/services/DefaultSimulationModifierService.java index a04a3c1b1..d2c8f5524 100644 --- a/core/src/net/sf/openrocket/optimization/services/DefaultSimulationModifierService.java +++ b/core/src/net/sf/openrocket/optimization/services/DefaultSimulationModifierService.java @@ -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( 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( + 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( + 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);