Convert DampingMoment listener to simulation extension

This commit is contained in:
JoePfeiffer 2022-12-07 15:17:17 -07:00
parent c3d2d5fc16
commit 17a4f1ffdb
3 changed files with 160 additions and 116 deletions

View File

@ -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<FlightDataType> types = new ArrayList<FlightDataType>();
DampingMoment() {
types.add(cdm);
}
@Override
public List<FlightDataType> 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<Double> mpAll = data.get(FlightDataType.TYPE_MOTOR_MASS);
List<Double> 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<RocketComponent, AerodynamicForces> forces = aerocalc.getForceAnalysis(status.getConfiguration(), flightConditions, status.getWarnings());
for (Map.Entry<RocketComponent, AerodynamicForces> 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;
}
}
}

View File

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

View File

@ -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<Double> mpAll = data.get(FlightDataType.TYPE_MOTOR_MASS);
List<Double> 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<RocketComponent, AerodynamicForces> forces = aerocalc.getForceAnalysis(status.getConfiguration(), flightConditions, status.getWarnings());
for (Map.Entry<RocketComponent, AerodynamicForces> 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;
}
}