From 17a4f1ffdbf9f3801cd85cda896e841e46b37dbb Mon Sep 17 00:00:00 2001 From: JoePfeiffer Date: Wed, 7 Dec 2022 15:17:17 -0700 Subject: [PATCH] Convert DampingMoment listener to simulation extension --- .../extension/example/DampingMoment.java | 147 ++++++++++++++++++ .../example/DampingMomentProvider.java | 13 ++ .../listeners/example/DampingMoment.java | 116 -------------- 3 files changed, 160 insertions(+), 116 deletions(-) create mode 100644 core/src/net/sf/openrocket/simulation/extension/example/DampingMoment.java create mode 100644 core/src/net/sf/openrocket/simulation/extension/example/DampingMomentProvider.java delete mode 100644 core/src/net/sf/openrocket/simulation/listeners/example/DampingMoment.java diff --git a/core/src/net/sf/openrocket/simulation/extension/example/DampingMoment.java b/core/src/net/sf/openrocket/simulation/extension/example/DampingMoment.java new file mode 100644 index 000000000..effbded87 --- /dev/null +++ b/core/src/net/sf/openrocket/simulation/extension/example/DampingMoment.java @@ -0,0 +1,147 @@ +package net.sf.openrocket.simulation.extension.impl; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import net.sf.openrocket.aerodynamics.AerodynamicCalculator; +import net.sf.openrocket.aerodynamics.AerodynamicForces; +import net.sf.openrocket.aerodynamics.FlightConditions; +import net.sf.openrocket.aerodynamics.WarningSet; +import net.sf.openrocket.motor.MotorConfiguration; +import net.sf.openrocket.rocketcomponent.FlightConfiguration; +import net.sf.openrocket.rocketcomponent.RocketComponent; +import net.sf.openrocket.simulation.FlightDataBranch; +import net.sf.openrocket.simulation.FlightDataType; +import net.sf.openrocket.simulation.SimulationConditions; +import net.sf.openrocket.simulation.SimulationStatus; +import net.sf.openrocket.simulation.exception.SimulationException; +import net.sf.openrocket.simulation.extension.AbstractSimulationExtension; +import net.sf.openrocket.simulation.listeners.AbstractSimulationListener; +import net.sf.openrocket.unit.UnitGroup; + +public class DampingMoment extends AbstractSimulationExtension { + private static final Logger log = LoggerFactory.getLogger(DampingMoment.class); + + // Save it as a FlightDataType + private static final FlightDataType cdm = FlightDataType.getType("Damping moment coefficient", "Cdm", UnitGroup.UNITS_COEFFICIENT); + private static final ArrayList types = new ArrayList(); + + DampingMoment() { + types.add(cdm); + } + + @Override + public List getFlightDataTypes() { + return types; + } + + @Override + public void initialize(SimulationConditions conditions) throws SimulationException { + log.debug("initializing..."); + conditions.getSimulationListenerList().add(new DampingMomentListener()); + } + + @Override + public String getName() { + return "Damping Moment Coeficient(Cdm)"; + } + + @Override + public String getDescription() { + return "Calculate damping moment coefficient after every simulation step and publish to FlightData as Cdm"; + } + + private class DampingMomentListener extends AbstractSimulationListener { + + @Override + public FlightConditions postFlightConditions(SimulationStatus status, FlightConditions flightConditions) throws SimulationException { + + //status.getFlightData().setValue(cdm, aerodynamicPart + propulsivePart); + status.getFlightData().setValue(cdm, calculate(status, flightConditions)); + + return flightConditions; + } + + private double calculate(SimulationStatus status, FlightConditions flightConditions) { + + // Work out the propulsive/jet damping part of the moment. + + // dm/dt = (thrust - ma)/v + FlightDataBranch data = status.getFlightData(); + + List mpAll = data.get(FlightDataType.TYPE_MOTOR_MASS); + List time = data.get(FlightDataType.TYPE_TIME); + if (mpAll == null || time == null) { + return Double.NaN; + } + + int len = mpAll.size(); + + // This isn't as accurate as I would like + double mdot = Double.NaN; + if (len > 2) { + // Using polynomial interpolator for derivative. Doesn't help much + //double[] x = { time.get(len-5), time.get(len-4), time.get(len-3), time.get(len-2), time.get(len-1) }; + //double[] y = { mpAll.get(len-5), mpAll.get(len-4), mpAll.get(len-3), mpAll.get(len-2), mpAll.get(len-1) }; + //PolyInterpolator interp = new PolyInterpolator(x); + //double[] coeff = interp.interpolator(y); + //double dt = .01; + //mdot = (interp.eval(x[4], coeff) - interp.eval(x[4]-dt, coeff))/dt; + + mdot = (mpAll.get(len - 1) - mpAll.get(len - 2)) / (time.get(len - 1) - time.get(len - 2)); + } + + double cg = data.getLast(FlightDataType.TYPE_CG_LOCATION); + + // find the maximum distance from nose to nozzle. + double nozzleDistance = 0; + FlightConfiguration config = status.getConfiguration(); + for (MotorConfiguration inst : config.getActiveMotors()) { + double x_position= inst.getX(); + double x = x_position + inst.getMotor().getLaunchCGx(); + if (x > nozzleDistance) { + nozzleDistance = x; + } + } + + // now can get the propulsive part + double propulsivePart = mdot * Math.pow(nozzleDistance - cg, 2); + + // Work out the aerodynamic part of the moment. + double aerodynamicPart = 0; + + AerodynamicCalculator aerocalc = status.getSimulationConditions().getAerodynamicCalculator(); + + // Must go through each component ... + Map forces = aerocalc.getForceAnalysis(status.getConfiguration(), flightConditions, status.getWarnings()); + for (Map.Entry entry : forces.entrySet()) { + + RocketComponent comp = entry.getKey(); + + if (!comp.isAerodynamic()) + continue; + + //System.out.println(comp.toString()); + + double CNa = entry.getValue().getCNa(); //? + double Cp = entry.getValue().getCP().length(); + double z = comp.getAxialOffset(); + + aerodynamicPart += CNa * Math.pow(z - Cp, 2); + } + + double v = flightConditions.getVelocity(); + double rho = flightConditions.getAtmosphericConditions().getDensity(); + double ar = flightConditions.getRefArea(); + + aerodynamicPart = aerodynamicPart * .5 * rho * v * ar; + + return aerodynamicPart + propulsivePart; + } + } + +} diff --git a/core/src/net/sf/openrocket/simulation/extension/example/DampingMomentProvider.java b/core/src/net/sf/openrocket/simulation/extension/example/DampingMomentProvider.java new file mode 100644 index 000000000..992e0f1d4 --- /dev/null +++ b/core/src/net/sf/openrocket/simulation/extension/example/DampingMomentProvider.java @@ -0,0 +1,13 @@ +package net.sf.openrocket.simulation.extension.impl; + +import net.sf.openrocket.plugin.Plugin; +import net.sf.openrocket.simulation.extension.AbstractSimulationExtensionProvider; + +@Plugin +public class DampingMomentProvider extends AbstractSimulationExtensionProvider { + + public DampingMomentProvider() { + super(DampingMoment.class, "Post-step flight conditions", "Damping Moment Coefficient (Cdm)"); + } + +} diff --git a/core/src/net/sf/openrocket/simulation/listeners/example/DampingMoment.java b/core/src/net/sf/openrocket/simulation/listeners/example/DampingMoment.java deleted file mode 100644 index 6d5839e07..000000000 --- a/core/src/net/sf/openrocket/simulation/listeners/example/DampingMoment.java +++ /dev/null @@ -1,116 +0,0 @@ -package net.sf.openrocket.simulation.listeners.example; - -import java.util.List; -import java.util.Map; - -import net.sf.openrocket.aerodynamics.AerodynamicCalculator; -import net.sf.openrocket.aerodynamics.AerodynamicForces; -import net.sf.openrocket.aerodynamics.FlightConditions; -import net.sf.openrocket.aerodynamics.WarningSet; -import net.sf.openrocket.motor.MotorConfiguration; -import net.sf.openrocket.rocketcomponent.FlightConfiguration; -import net.sf.openrocket.rocketcomponent.RocketComponent; -import net.sf.openrocket.simulation.FlightDataBranch; -import net.sf.openrocket.simulation.FlightDataType; -import net.sf.openrocket.simulation.SimulationStatus; -import net.sf.openrocket.simulation.exception.SimulationException; -import net.sf.openrocket.simulation.listeners.AbstractSimulationListener; -import net.sf.openrocket.unit.UnitGroup; - -public class DampingMoment extends AbstractSimulationListener { - - private static final FlightDataType type = FlightDataType.getType("Damping moment coefficient", "Cdm", UnitGroup.UNITS_COEFFICIENT); - - // unused - //private static final FlightDataType[] typeList = { type }; - - @Override - public FlightConditions postFlightConditions(SimulationStatus status, FlightConditions flightConditions) throws SimulationException { - - // Save it as a flightdatatype - - //status.getFlightData().setValue(type, aerodynamicPart + propulsivePart); - status.getFlightData().setValue(type, calculate(status, flightConditions)); - - return flightConditions; - } - - private double calculate(SimulationStatus status, FlightConditions flightConditions) { - - // Work out the propulsive/jet damping part of the moment. - - // dm/dt = (thrust - ma)/v - FlightDataBranch data = status.getFlightData(); - - List mpAll = data.get(FlightDataType.TYPE_MOTOR_MASS); - List time = data.get(FlightDataType.TYPE_TIME); - if (mpAll == null || time == null) { - return Double.NaN; - } - - int len = mpAll.size(); - - // This isn't as accurate as I would like - double mdot = Double.NaN; - if (len > 2) { - // Using polynomial interpolator for derivative. Doesn't help much - //double[] x = { time.get(len-5), time.get(len-4), time.get(len-3), time.get(len-2), time.get(len-1) }; - //double[] y = { mpAll.get(len-5), mpAll.get(len-4), mpAll.get(len-3), mpAll.get(len-2), mpAll.get(len-1) }; - //PolyInterpolator interp = new PolyInterpolator(x); - //double[] coeff = interp.interpolator(y); - //double dt = .01; - //mdot = (interp.eval(x[4], coeff) - interp.eval(x[4]-dt, coeff))/dt; - - mdot = (mpAll.get(len - 1) - mpAll.get(len - 2)) / (time.get(len - 1) - time.get(len - 2)); - } - - double cg = data.getLast(FlightDataType.TYPE_CG_LOCATION); - - // find the maximum distance from nose to nozzle. - double nozzleDistance = 0; - FlightConfiguration config = status.getConfiguration(); - for (MotorConfiguration inst : config.getActiveMotors()) { - double x_position= inst.getX(); - double x = x_position + inst.getMotor().getLaunchCGx(); - if (x > nozzleDistance) { - nozzleDistance = x; - } - } - - // now can get the propulsive part - double propulsivePart = mdot * Math.pow(nozzleDistance - cg, 2); - - // Work out the aerodynamic part of the moment. - double aerodynamicPart = 0; - - AerodynamicCalculator aerocalc = status.getSimulationConditions().getAerodynamicCalculator(); - - // Must go through each component ... - Map forces = aerocalc.getForceAnalysis(status.getConfiguration(), flightConditions, status.getWarnings()); - for (Map.Entry entry : forces.entrySet()) { - - RocketComponent comp = entry.getKey(); - - if (!comp.isAerodynamic()) - continue; - - //System.out.println(comp.toString()); - - double CNa = entry.getValue().getCNa(); //? - double Cp = entry.getValue().getCP().length(); - double z = comp.getAxialOffset(); - - aerodynamicPart += CNa * Math.pow(z - Cp, 2); - } - - double v = flightConditions.getVelocity(); - double rho = flightConditions.getAtmosphericConditions().getDensity(); - double ar = flightConditions.getRefArea(); - - aerodynamicPart = aerodynamicPart * .5 * rho * v * ar; - - return aerodynamicPart + propulsivePart; - - } - -}