folded BasicMassCalculator into MassCalculator
This commit is contained in:
parent
7978771e1b
commit
85dff39fb9
@ -9,7 +9,6 @@ import net.sf.openrocket.aerodynamics.AerodynamicCalculator;
|
|||||||
import net.sf.openrocket.aerodynamics.BarrowmanCalculator;
|
import net.sf.openrocket.aerodynamics.BarrowmanCalculator;
|
||||||
import net.sf.openrocket.aerodynamics.WarningSet;
|
import net.sf.openrocket.aerodynamics.WarningSet;
|
||||||
import net.sf.openrocket.formatting.RocketDescriptor;
|
import net.sf.openrocket.formatting.RocketDescriptor;
|
||||||
import net.sf.openrocket.masscalc.BasicMassCalculator;
|
|
||||||
import net.sf.openrocket.masscalc.MassCalculator;
|
import net.sf.openrocket.masscalc.MassCalculator;
|
||||||
import net.sf.openrocket.motor.Motor;
|
import net.sf.openrocket.motor.Motor;
|
||||||
import net.sf.openrocket.motor.MotorInstanceConfiguration;
|
import net.sf.openrocket.motor.MotorInstanceConfiguration;
|
||||||
@ -93,7 +92,7 @@ public class Simulation implements ChangeSource, Cloneable {
|
|||||||
private Class<? extends SimulationStepper> simulationStepperClass = RK4SimulationStepper.class;
|
private Class<? extends SimulationStepper> simulationStepperClass = RK4SimulationStepper.class;
|
||||||
private Class<? extends AerodynamicCalculator> aerodynamicCalculatorClass = BarrowmanCalculator.class;
|
private Class<? extends AerodynamicCalculator> aerodynamicCalculatorClass = BarrowmanCalculator.class;
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
private Class<? extends MassCalculator> massCalculatorClass = BasicMassCalculator.class;
|
private Class<? extends MassCalculator> massCalculatorClass = MassCalculator.class;
|
||||||
|
|
||||||
/** Listeners for this object */
|
/** Listeners for this object */
|
||||||
private List<EventListener> listeners = new ArrayList<EventListener>();
|
private List<EventListener> listeners = new ArrayList<EventListener>();
|
||||||
|
@ -13,11 +13,10 @@ import net.sf.openrocket.document.OpenRocketDocument;
|
|||||||
import net.sf.openrocket.document.StorageOptions;
|
import net.sf.openrocket.document.StorageOptions;
|
||||||
import net.sf.openrocket.file.RocketSaver;
|
import net.sf.openrocket.file.RocketSaver;
|
||||||
import net.sf.openrocket.file.rocksim.RocksimCommonConstants;
|
import net.sf.openrocket.file.rocksim.RocksimCommonConstants;
|
||||||
import net.sf.openrocket.masscalc.BasicMassCalculator;
|
|
||||||
import net.sf.openrocket.masscalc.MassCalculator;
|
import net.sf.openrocket.masscalc.MassCalculator;
|
||||||
|
import net.sf.openrocket.rocketcomponent.AxialStage;
|
||||||
import net.sf.openrocket.rocketcomponent.Configuration;
|
import net.sf.openrocket.rocketcomponent.Configuration;
|
||||||
import net.sf.openrocket.rocketcomponent.Rocket;
|
import net.sf.openrocket.rocketcomponent.Rocket;
|
||||||
import net.sf.openrocket.rocketcomponent.AxialStage;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@ -93,7 +92,7 @@ public class RocksimSaver extends RocketSaver {
|
|||||||
private RocketDesignDTO toRocketDesignDTO(Rocket rocket) {
|
private RocketDesignDTO toRocketDesignDTO(Rocket rocket) {
|
||||||
RocketDesignDTO result = new RocketDesignDTO();
|
RocketDesignDTO result = new RocketDesignDTO();
|
||||||
|
|
||||||
MassCalculator massCalc = new BasicMassCalculator();
|
MassCalculator massCalc = new MassCalculator();
|
||||||
|
|
||||||
final Configuration configuration = new Configuration(rocket);
|
final Configuration configuration = new Configuration(rocket);
|
||||||
final double cg = massCalc.getCG(configuration, MassCalculator.MassCalcType.NO_MOTORS).x *
|
final double cg = massCalc.getCG(configuration, MassCalculator.MassCalcType.NO_MOTORS).x *
|
||||||
|
@ -1,403 +0,0 @@
|
|||||||
package net.sf.openrocket.masscalc;
|
|
||||||
|
|
||||||
import static net.sf.openrocket.util.MathUtil.pow2;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import net.sf.openrocket.motor.Motor;
|
|
||||||
import net.sf.openrocket.motor.MotorId;
|
|
||||||
import net.sf.openrocket.motor.MotorInstance;
|
|
||||||
import net.sf.openrocket.motor.MotorInstanceConfiguration;
|
|
||||||
import net.sf.openrocket.rocketcomponent.AxialStage;
|
|
||||||
import net.sf.openrocket.rocketcomponent.Configuration;
|
|
||||||
import net.sf.openrocket.rocketcomponent.MotorMount;
|
|
||||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
|
||||||
import net.sf.openrocket.simulation.MassData;
|
|
||||||
import net.sf.openrocket.util.Coordinate;
|
|
||||||
import net.sf.openrocket.util.MathUtil;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
public class BasicMassCalculator implements MassCalculator {
|
|
||||||
|
|
||||||
private static final double MIN_MASS = 0.001 * MathUtil.EPSILON;
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(MassCalculator.class);
|
|
||||||
|
|
||||||
private int rocketMassModID = -1;
|
|
||||||
private int rocketTreeModID = -1;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Cached data. All CG data is in absolute coordinates. All moments of inertia
|
|
||||||
* are relative to their respective CG.
|
|
||||||
*/
|
|
||||||
private Coordinate[] cgCache = null;
|
|
||||||
private double longitudinalInertiaCache[] = null;
|
|
||||||
private double rotationalInertiaCache[] = null;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
////////////////// Mass property calculations ///////////////////
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the CG of the rocket with the specified motor status (no motors,
|
|
||||||
* ignition, burnout).
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public Coordinate getCG(Configuration configuration, MassCalcType type) {
|
|
||||||
checkCache(configuration);
|
|
||||||
calculateStageCache(configuration);
|
|
||||||
|
|
||||||
Coordinate totalCG = null;
|
|
||||||
|
|
||||||
// Stage contribution
|
|
||||||
for (int stage : configuration.getActiveStages()) {
|
|
||||||
totalCG = cgCache[stage].average(totalCG);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (totalCG == null)
|
|
||||||
totalCG = Coordinate.NUL;
|
|
||||||
|
|
||||||
// Add motor CGs
|
|
||||||
String motorId = configuration.getFlightConfigurationID();
|
|
||||||
if (type != MassCalcType.NO_MOTORS && motorId != null) {
|
|
||||||
Iterator<MotorMount> iterator = configuration.motorIterator();
|
|
||||||
while (iterator.hasNext()) {
|
|
||||||
MotorMount mount = iterator.next();
|
|
||||||
RocketComponent comp = (RocketComponent) mount;
|
|
||||||
Motor motor = mount.getMotor(motorId);
|
|
||||||
if (motor == null)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
Coordinate motorCG = type.getCG(motor).add(mount.getMotorPosition(motorId));
|
|
||||||
Coordinate[] cgs = comp.toAbsolute(motorCG);
|
|
||||||
for (Coordinate cg : cgs) {
|
|
||||||
totalCG = totalCG.average(cg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return totalCG;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the CG of the rocket with the provided motor configuration.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public Coordinate getCG(Configuration configuration, MotorInstanceConfiguration motors) {
|
|
||||||
checkCache(configuration);
|
|
||||||
calculateStageCache(configuration);
|
|
||||||
|
|
||||||
Coordinate totalCG = getCG(configuration, MassCalcType.NO_MOTORS);
|
|
||||||
|
|
||||||
// Add motor CGs
|
|
||||||
if (motors != null) {
|
|
||||||
for (MotorId id : motors.getMotorIDs()) {
|
|
||||||
int stage = ((RocketComponent) motors.getMotorMount(id)).getStageNumber();
|
|
||||||
if (configuration.isStageActive(stage)) {
|
|
||||||
|
|
||||||
MotorInstance motor = motors.getMotorInstance(id);
|
|
||||||
Coordinate position = motors.getMotorPosition(id);
|
|
||||||
Coordinate cg = motor.getCG().add(position);
|
|
||||||
totalCG = totalCG.average(cg);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return totalCG;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the longitudinal inertia of the rocket with the specified motor instance
|
|
||||||
* configuration.
|
|
||||||
*
|
|
||||||
* @param configuration the current motor instance configuration
|
|
||||||
* @return the longitudinal inertia of the rocket
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public double getLongitudinalInertia(Configuration configuration, MotorInstanceConfiguration motors) {
|
|
||||||
checkCache(configuration);
|
|
||||||
calculateStageCache(configuration);
|
|
||||||
|
|
||||||
final Coordinate totalCG = getCG(configuration, motors);
|
|
||||||
double totalInertia = 0;
|
|
||||||
|
|
||||||
// Stages
|
|
||||||
for (int stage : configuration.getActiveStages()) {
|
|
||||||
Coordinate stageCG = cgCache[stage];
|
|
||||||
|
|
||||||
totalInertia += (longitudinalInertiaCache[stage] +
|
|
||||||
stageCG.weight * MathUtil.pow2(stageCG.x - totalCG.x));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Motors
|
|
||||||
if (motors != null) {
|
|
||||||
for (MotorId id : motors.getMotorIDs()) {
|
|
||||||
int stage = ((RocketComponent) motors.getMotorMount(id)).getStageNumber();
|
|
||||||
if (configuration.isStageActive(stage)) {
|
|
||||||
MotorInstance motor = motors.getMotorInstance(id);
|
|
||||||
Coordinate position = motors.getMotorPosition(id);
|
|
||||||
Coordinate cg = motor.getCG().add(position);
|
|
||||||
|
|
||||||
double inertia = motor.getLongitudinalInertia();
|
|
||||||
totalInertia += inertia + cg.weight * MathUtil.pow2(cg.x - totalCG.x);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return totalInertia;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the rotational inertia of the rocket with the specified motor instance
|
|
||||||
* configuration.
|
|
||||||
*
|
|
||||||
* @param configuration the current motor instance configuration
|
|
||||||
* @return the rotational inertia of the rocket
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public double getRotationalInertia(Configuration configuration, MotorInstanceConfiguration motors) {
|
|
||||||
checkCache(configuration);
|
|
||||||
calculateStageCache(configuration);
|
|
||||||
|
|
||||||
final Coordinate totalCG = getCG(configuration, motors);
|
|
||||||
double totalInertia = 0;
|
|
||||||
|
|
||||||
// Stages
|
|
||||||
for (int stage : configuration.getActiveStages()) {
|
|
||||||
Coordinate stageCG = cgCache[stage];
|
|
||||||
|
|
||||||
totalInertia += (rotationalInertiaCache[stage] +
|
|
||||||
stageCG.weight * (MathUtil.pow2(stageCG.y - totalCG.y) +
|
|
||||||
MathUtil.pow2(stageCG.z - totalCG.z)));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Motors
|
|
||||||
if (motors != null) {
|
|
||||||
for (MotorId id : motors.getMotorIDs()) {
|
|
||||||
int stage = ((RocketComponent) motors.getMotorMount(id)).getStageNumber();
|
|
||||||
if (configuration.isStageActive(stage)) {
|
|
||||||
MotorInstance motor = motors.getMotorInstance(id);
|
|
||||||
Coordinate position = motors.getMotorPosition(id);
|
|
||||||
Coordinate cg = motor.getCG().add(position);
|
|
||||||
|
|
||||||
double inertia = motor.getRotationalInertia();
|
|
||||||
totalInertia += inertia + cg.weight * (MathUtil.pow2(cg.y - totalCG.y) +
|
|
||||||
MathUtil.pow2(cg.z - totalCG.z));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return totalInertia;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the total mass of the motors
|
|
||||||
*
|
|
||||||
* @param configuration the current motor instance configuration
|
|
||||||
* @return the total mass of all motors
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public double getPropellantMass(Configuration configuration, MotorInstanceConfiguration motors) {
|
|
||||||
double mass = 0;
|
|
||||||
|
|
||||||
// add up the masses of all motors in the rocket
|
|
||||||
if (motors != null) {
|
|
||||||
for (MotorId id : motors.getMotorIDs()) {
|
|
||||||
MotorInstance motor = motors.getMotorInstance(id);
|
|
||||||
mass = mass + motor.getCG().weight - motor.getParentMotor().getEmptyCG().weight;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return mass;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<RocketComponent, Coordinate> getCGAnalysis(Configuration configuration, MassCalcType type) {
|
|
||||||
checkCache(configuration);
|
|
||||||
calculateStageCache(configuration);
|
|
||||||
|
|
||||||
Map<RocketComponent, Coordinate> map = new HashMap<RocketComponent, Coordinate>();
|
|
||||||
|
|
||||||
for (RocketComponent c : configuration) {
|
|
||||||
Coordinate[] cgs = c.toAbsolute(c.getCG());
|
|
||||||
Coordinate totalCG = Coordinate.NUL;
|
|
||||||
for (Coordinate cg : cgs) {
|
|
||||||
totalCG = totalCG.average(cg);
|
|
||||||
}
|
|
||||||
map.put(c, totalCG);
|
|
||||||
}
|
|
||||||
|
|
||||||
map.put(configuration.getRocket(), getCG(configuration, type));
|
|
||||||
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
//////// Cache computations ////////
|
|
||||||
|
|
||||||
private void calculateStageCache(Configuration config) {
|
|
||||||
if (cgCache == null) {
|
|
||||||
ArrayList<AxialStage> stageList = config.getRocket().getStageList();
|
|
||||||
int stageCount = stageList.size();
|
|
||||||
|
|
||||||
cgCache = new Coordinate[stageCount];
|
|
||||||
longitudinalInertiaCache = new double[stageCount];
|
|
||||||
rotationalInertiaCache = new double[stageCount];
|
|
||||||
|
|
||||||
for (int i = 0; i < stageCount; i++) {
|
|
||||||
RocketComponent stage = stageList.get(i);
|
|
||||||
MassData data = calculateAssemblyMassData(stage);
|
|
||||||
cgCache[i] = stage.toAbsolute(data.getCG())[0];
|
|
||||||
longitudinalInertiaCache[i] = data.getLongitudinalInertia();
|
|
||||||
rotationalInertiaCache[i] = data.getRotationalInertia();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the mass and inertia data for this component and all subcomponents.
|
|
||||||
* The inertia is returned relative to the CG, and the CG is in the coordinates
|
|
||||||
* of the specified component, not global coordinates.
|
|
||||||
*/
|
|
||||||
private MassData calculateAssemblyMassData(RocketComponent parent) {
|
|
||||||
Coordinate parentCG = Coordinate.ZERO;
|
|
||||||
double longitudinalInertia = 0.0;
|
|
||||||
double rotationalInertia = 0.0;
|
|
||||||
|
|
||||||
// Calculate data for this component
|
|
||||||
parentCG = parent.getComponentCG();
|
|
||||||
if (parentCG.weight < MIN_MASS)
|
|
||||||
parentCG = parentCG.setWeight(MIN_MASS);
|
|
||||||
|
|
||||||
|
|
||||||
// Override only this component's data
|
|
||||||
if (!parent.getOverrideSubcomponents()) {
|
|
||||||
if (parent.isMassOverridden())
|
|
||||||
parentCG = parentCG.setWeight(MathUtil.max(parent.getOverrideMass(), MIN_MASS));
|
|
||||||
if (parent.isCGOverridden())
|
|
||||||
parentCG = parentCG.setXYZ(parent.getOverrideCG());
|
|
||||||
}
|
|
||||||
|
|
||||||
longitudinalInertia = parent.getLongitudinalUnitInertia() * parentCG.weight;
|
|
||||||
rotationalInertia = parent.getRotationalUnitInertia() * parentCG.weight;
|
|
||||||
|
|
||||||
|
|
||||||
// Combine data for subcomponents
|
|
||||||
for (RocketComponent sibling : parent.getChildren()) {
|
|
||||||
Coordinate combinedCG;
|
|
||||||
double dx2, dr2;
|
|
||||||
|
|
||||||
// Compute data of sibling
|
|
||||||
MassData siblingData = calculateAssemblyMassData(sibling);
|
|
||||||
Coordinate[] siblingCGs = sibling.toRelative(siblingData.getCG(), parent);
|
|
||||||
|
|
||||||
for (Coordinate siblingCG : siblingCGs) {
|
|
||||||
|
|
||||||
// Compute CG of this + sibling
|
|
||||||
combinedCG = parentCG.average(siblingCG);
|
|
||||||
|
|
||||||
// Add effect of this CG change to parent inertia
|
|
||||||
dx2 = pow2(parentCG.x - combinedCG.x);
|
|
||||||
longitudinalInertia += parentCG.weight * dx2;
|
|
||||||
|
|
||||||
dr2 = pow2(parentCG.y - combinedCG.y) + pow2(parentCG.z - combinedCG.z);
|
|
||||||
rotationalInertia += parentCG.weight * dr2;
|
|
||||||
|
|
||||||
|
|
||||||
// Add inertia of sibling
|
|
||||||
longitudinalInertia += siblingData.getLongitudinalInertia();
|
|
||||||
rotationalInertia += siblingData.getRotationalInertia();
|
|
||||||
|
|
||||||
// Add effect of sibling CG change
|
|
||||||
dx2 = pow2(siblingData.getCG().x - combinedCG.x);
|
|
||||||
longitudinalInertia += siblingData.getCG().weight * dx2;
|
|
||||||
|
|
||||||
dr2 = pow2(siblingData.getCG().y - combinedCG.y) + pow2(siblingData.getCG().z - combinedCG.z);
|
|
||||||
rotationalInertia += siblingData.getCG().weight * dr2;
|
|
||||||
|
|
||||||
// Set combined CG
|
|
||||||
parentCG = combinedCG;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Override total data
|
|
||||||
if (parent.getOverrideSubcomponents()) {
|
|
||||||
if (parent.isMassOverridden()) {
|
|
||||||
double oldMass = parentCG.weight;
|
|
||||||
double newMass = MathUtil.max(parent.getOverrideMass(), MIN_MASS);
|
|
||||||
longitudinalInertia = longitudinalInertia * newMass / oldMass;
|
|
||||||
rotationalInertia = rotationalInertia * newMass / oldMass;
|
|
||||||
parentCG = parentCG.setWeight(newMass);
|
|
||||||
}
|
|
||||||
if (parent.isCGOverridden()) {
|
|
||||||
double oldx = parentCG.x;
|
|
||||||
double newx = parent.getOverrideCGX();
|
|
||||||
longitudinalInertia += parentCG.weight * pow2(oldx - newx);
|
|
||||||
parentCG = parentCG.setX(newx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MassData parentData = new MassData(parentCG, longitudinalInertia, rotationalInertia, 0);
|
|
||||||
return parentData;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check the current cache consistency. This method must be called by all
|
|
||||||
* methods that may use any cached data before any other operations are
|
|
||||||
* performed. If the rocket has changed since the previous call to
|
|
||||||
* <code>checkCache()</code>, then {@link #voidMassCache()} is called.
|
|
||||||
* <p>
|
|
||||||
* This method performs the checking based on the rocket's modification IDs,
|
|
||||||
* so that these method may be called from listeners of the rocket itself.
|
|
||||||
*
|
|
||||||
* @param configuration the configuration of the current call
|
|
||||||
*/
|
|
||||||
protected final void checkCache(Configuration configuration) {
|
|
||||||
if (rocketMassModID != configuration.getRocket().getMassModID() ||
|
|
||||||
rocketTreeModID != configuration.getRocket().getTreeModID()) {
|
|
||||||
rocketMassModID = configuration.getRocket().getMassModID();
|
|
||||||
rocketTreeModID = configuration.getRocket().getTreeModID();
|
|
||||||
log.debug("Voiding the mass cache");
|
|
||||||
voidMassCache();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Void cached mass data. This method is called whenever a change occurs in
|
|
||||||
* the rocket structure that affects the mass of the rocket and when a new
|
|
||||||
* Rocket is used. This method must be overridden to void any cached data
|
|
||||||
* necessary. The method must call <code>super.voidMassCache()</code> during
|
|
||||||
* its execution.
|
|
||||||
*/
|
|
||||||
protected void voidMassCache() {
|
|
||||||
this.cgCache = null;
|
|
||||||
this.longitudinalInertiaCache = null;
|
|
||||||
this.rotationalInertiaCache = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getModID() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -1,15 +1,29 @@
|
|||||||
package net.sf.openrocket.masscalc;
|
package net.sf.openrocket.masscalc;
|
||||||
|
|
||||||
|
import static net.sf.openrocket.util.MathUtil.pow2;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import net.sf.openrocket.motor.Motor;
|
import net.sf.openrocket.motor.Motor;
|
||||||
|
import net.sf.openrocket.motor.MotorId;
|
||||||
|
import net.sf.openrocket.motor.MotorInstance;
|
||||||
import net.sf.openrocket.motor.MotorInstanceConfiguration;
|
import net.sf.openrocket.motor.MotorInstanceConfiguration;
|
||||||
|
import net.sf.openrocket.rocketcomponent.AxialStage;
|
||||||
import net.sf.openrocket.rocketcomponent.Configuration;
|
import net.sf.openrocket.rocketcomponent.Configuration;
|
||||||
|
import net.sf.openrocket.rocketcomponent.MotorMount;
|
||||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||||
|
import net.sf.openrocket.simulation.MassData;
|
||||||
import net.sf.openrocket.util.Coordinate;
|
import net.sf.openrocket.util.Coordinate;
|
||||||
|
import net.sf.openrocket.util.MathUtil;
|
||||||
import net.sf.openrocket.util.Monitorable;
|
import net.sf.openrocket.util.Monitorable;
|
||||||
|
|
||||||
public interface MassCalculator extends Monitorable {
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class MassCalculator implements Monitorable {
|
||||||
|
|
||||||
public static enum MassCalcType {
|
public static enum MassCalcType {
|
||||||
NO_MOTORS {
|
NO_MOTORS {
|
||||||
@ -34,41 +48,186 @@ public interface MassCalculator extends Monitorable {
|
|||||||
public abstract Coordinate getCG(Motor motor);
|
public abstract Coordinate getCG(Motor motor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static final double MIN_MASS = 0.001 * MathUtil.EPSILON;
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(MassCalculator.class);
|
||||||
|
|
||||||
|
private int rocketMassModID = -1;
|
||||||
|
private int rocketTreeModID = -1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Cached data. All CG data is in absolute coordinates. All moments of inertia
|
||||||
|
* are relative to their respective CG.
|
||||||
|
*/
|
||||||
|
private Coordinate[] cgCache = null;
|
||||||
|
private double longitudinalInertiaCache[] = null;
|
||||||
|
private double rotationalInertiaCache[] = null;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////// Mass property calculations ///////////////////
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compute the CG of the provided configuration.
|
* Return the CG of the rocket with the specified motor status (no motors,
|
||||||
|
* ignition, burnout).
|
||||||
*
|
*
|
||||||
* @param configuration the rocket configuration
|
* @param configuration the rocket configuration
|
||||||
* @param type the state of the motors (none, launch mass, burnout mass)
|
* @param type the state of the motors (none, launch mass, burnout mass)
|
||||||
* @return the CG of the configuration
|
* @return the CG of the configuration
|
||||||
*/
|
*/
|
||||||
public Coordinate getCG(Configuration configuration, MassCalcType type);
|
public Coordinate getCG(Configuration configuration, MassCalcType type) {
|
||||||
|
checkCache(configuration);
|
||||||
|
calculateStageCache(configuration);
|
||||||
|
|
||||||
|
Coordinate totalCG = null;
|
||||||
|
|
||||||
|
// Stage contribution
|
||||||
|
for (int stage : configuration.getActiveStages()) {
|
||||||
|
totalCG = cgCache[stage].average(totalCG);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (totalCG == null)
|
||||||
|
totalCG = Coordinate.NUL;
|
||||||
|
|
||||||
|
// Add motor CGs
|
||||||
|
String motorId = configuration.getFlightConfigurationID();
|
||||||
|
if (type != MassCalcType.NO_MOTORS && motorId != null) {
|
||||||
|
Iterator<MotorMount> iterator = configuration.motorIterator();
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
MotorMount mount = iterator.next();
|
||||||
|
RocketComponent comp = (RocketComponent) mount;
|
||||||
|
Motor motor = mount.getMotorConfiguration().get(motorId).getMotor();
|
||||||
|
if (motor == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Coordinate motorCG = type.getCG(motor).add(mount.getMotorPosition(motorId));
|
||||||
|
Coordinate[] cgs = comp.toAbsolute(motorCG);
|
||||||
|
for (Coordinate cg : cgs) {
|
||||||
|
totalCG = totalCG.average(cg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return totalCG;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compute the CG of the provided configuration with specified motors.
|
* Compute the CG of the rocket with the provided motor configuration.
|
||||||
*
|
*
|
||||||
* @param configuration the rocket configuration
|
* @param configuration the rocket configuration
|
||||||
* @param motors the motor configuration
|
* @param motors the motor configuration
|
||||||
* @return the CG of the configuration
|
* @return the CG of the configuration
|
||||||
*/
|
*/
|
||||||
public Coordinate getCG(Configuration configuration, MotorInstanceConfiguration motors);
|
public Coordinate getCG(Configuration configuration, MotorInstanceConfiguration motors) {
|
||||||
|
checkCache(configuration);
|
||||||
|
calculateStageCache(configuration);
|
||||||
|
|
||||||
|
Coordinate totalCG = getCG(configuration, MassCalcType.NO_MOTORS);
|
||||||
|
|
||||||
|
// Add motor CGs
|
||||||
|
if (motors != null) {
|
||||||
|
for (MotorId id : motors.getMotorIDs()) {
|
||||||
|
int stage = ((RocketComponent) motors.getMotorMount(id)).getStageNumber();
|
||||||
|
if (configuration.isStageActive(stage)) {
|
||||||
|
|
||||||
|
MotorInstance motor = motors.getMotorInstance(id);
|
||||||
|
Coordinate position = motors.getMotorPosition(id);
|
||||||
|
Coordinate cg = motor.getCG().add(position);
|
||||||
|
totalCG = totalCG.average(cg);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return totalCG;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compute the longitudinal inertia of the provided configuration with specified motors.
|
* Return the longitudinal inertia of the rocket with the specified motor instance
|
||||||
|
* configuration.
|
||||||
*
|
*
|
||||||
* @param configuration the rocket configuration
|
* @param configuration the current motor instance configuration
|
||||||
* @param motors the motor configuration
|
* @param motors the motor configuration
|
||||||
* @return the longitudinal inertia of the configuration
|
* @return the longitudinal inertia of the rocket
|
||||||
*/
|
*/
|
||||||
public double getLongitudinalInertia(Configuration configuration, MotorInstanceConfiguration motors);
|
public double getLongitudinalInertia(Configuration configuration, MotorInstanceConfiguration motors) {
|
||||||
|
checkCache(configuration);
|
||||||
|
calculateStageCache(configuration);
|
||||||
|
|
||||||
|
final Coordinate totalCG = getCG(configuration, motors);
|
||||||
|
double totalInertia = 0;
|
||||||
|
|
||||||
|
// Stages
|
||||||
|
for (int stage : configuration.getActiveStages()) {
|
||||||
|
Coordinate stageCG = cgCache[stage];
|
||||||
|
|
||||||
|
totalInertia += (longitudinalInertiaCache[stage] +
|
||||||
|
stageCG.weight * MathUtil.pow2(stageCG.x - totalCG.x));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Motors
|
||||||
|
if (motors != null) {
|
||||||
|
for (MotorId id : motors.getMotorIDs()) {
|
||||||
|
int stage = ((RocketComponent) motors.getMotorMount(id)).getStageNumber();
|
||||||
|
if (configuration.isStageActive(stage)) {
|
||||||
|
MotorInstance motor = motors.getMotorInstance(id);
|
||||||
|
Coordinate position = motors.getMotorPosition(id);
|
||||||
|
Coordinate cg = motor.getCG().add(position);
|
||||||
|
|
||||||
|
double inertia = motor.getLongitudinalInertia();
|
||||||
|
totalInertia += inertia + cg.weight * MathUtil.pow2(cg.x - totalCG.x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return totalInertia;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compute the rotational inertia of the provided configuration with specified motors.
|
* Compute the rotational inertia of the provided configuration with specified motors.
|
||||||
*
|
*
|
||||||
* @param configuration the rocket configuration
|
* @param configuration the current motor instance configuration
|
||||||
* @param motors the motor configuration
|
* @param motors the motor configuration
|
||||||
* @return the rotational inertia of the configuration
|
* @return the rotational inertia of the configuration
|
||||||
*/
|
*/
|
||||||
public double getRotationalInertia(Configuration configuration, MotorInstanceConfiguration motors);
|
public double getRotationalInertia(Configuration configuration, MotorInstanceConfiguration motors) {
|
||||||
|
checkCache(configuration);
|
||||||
|
calculateStageCache(configuration);
|
||||||
|
|
||||||
|
final Coordinate totalCG = getCG(configuration, motors);
|
||||||
|
double totalInertia = 0;
|
||||||
|
|
||||||
|
// Stages
|
||||||
|
for (int stage : configuration.getActiveStages()) {
|
||||||
|
Coordinate stageCG = cgCache[stage];
|
||||||
|
|
||||||
|
totalInertia += (rotationalInertiaCache[stage] +
|
||||||
|
stageCG.weight * (MathUtil.pow2(stageCG.y - totalCG.y) +
|
||||||
|
MathUtil.pow2(stageCG.z - totalCG.z)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Motors
|
||||||
|
if (motors != null) {
|
||||||
|
for (MotorId id : motors.getMotorIDs()) {
|
||||||
|
int stage = ((RocketComponent) motors.getMotorMount(id)).getStageNumber();
|
||||||
|
if (configuration.isStageActive(stage)) {
|
||||||
|
MotorInstance motor = motors.getMotorInstance(id);
|
||||||
|
Coordinate position = motors.getMotorPosition(id);
|
||||||
|
Coordinate cg = motor.getCG().add(position);
|
||||||
|
|
||||||
|
double inertia = motor.getRotationalInertia();
|
||||||
|
totalInertia += inertia + cg.weight * (MathUtil.pow2(cg.y - totalCG.y) +
|
||||||
|
MathUtil.pow2(cg.z - totalCG.z));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return totalInertia;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the total mass of the motors
|
* Return the total mass of the motors
|
||||||
@ -77,7 +236,18 @@ public interface MassCalculator extends Monitorable {
|
|||||||
* @param configuration the current motor instance configuration
|
* @param configuration the current motor instance configuration
|
||||||
* @return the total mass of all motors
|
* @return the total mass of all motors
|
||||||
*/
|
*/
|
||||||
public double getPropellantMass(Configuration configuration, MotorInstanceConfiguration motors);
|
public double getPropellantMass(Configuration configuration, MotorInstanceConfiguration motors) {
|
||||||
|
double mass = 0;
|
||||||
|
|
||||||
|
// add up the masses of all motors in the rocket
|
||||||
|
if (motors != null) {
|
||||||
|
for (MotorId id : motors.getMotorIDs()) {
|
||||||
|
MotorInstance motor = motors.getMotorInstance(id);
|
||||||
|
mass = mass + motor.getCG().weight - motor.getParentMotor().getEmptyCG().weight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return mass;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compute an analysis of the per-component CG's of the provided configuration.
|
* Compute an analysis of the per-component CG's of the provided configuration.
|
||||||
@ -90,7 +260,175 @@ public interface MassCalculator extends Monitorable {
|
|||||||
* @param type the state of the motors (none, launch mass, burnout mass)
|
* @param type the state of the motors (none, launch mass, burnout mass)
|
||||||
* @return a map from each rocket component to its corresponding CG.
|
* @return a map from each rocket component to its corresponding CG.
|
||||||
*/
|
*/
|
||||||
public Map<RocketComponent, Coordinate> getCGAnalysis(Configuration configuration, MassCalcType type);
|
public Map<RocketComponent, Coordinate> getCGAnalysis(Configuration configuration, MassCalcType type) {
|
||||||
|
checkCache(configuration);
|
||||||
|
calculateStageCache(configuration);
|
||||||
|
|
||||||
|
Map<RocketComponent, Coordinate> map = new HashMap<RocketComponent, Coordinate>();
|
||||||
|
|
||||||
|
for (RocketComponent c : configuration) {
|
||||||
|
Coordinate[] cgs = c.toAbsolute(c.getCG());
|
||||||
|
Coordinate totalCG = Coordinate.NUL;
|
||||||
|
for (Coordinate cg : cgs) {
|
||||||
|
totalCG = totalCG.average(cg);
|
||||||
|
}
|
||||||
|
map.put(c, totalCG);
|
||||||
|
}
|
||||||
|
|
||||||
|
map.put(configuration.getRocket(), getCG(configuration, type));
|
||||||
|
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
//////// Cache computations ////////
|
||||||
|
|
||||||
|
private void calculateStageCache(Configuration config) {
|
||||||
|
if (cgCache == null) {
|
||||||
|
ArrayList<AxialStage> stageList = config.getRocket().getStageList();
|
||||||
|
int stageCount = stageList.size();
|
||||||
|
|
||||||
|
cgCache = new Coordinate[stageCount];
|
||||||
|
longitudinalInertiaCache = new double[stageCount];
|
||||||
|
rotationalInertiaCache = new double[stageCount];
|
||||||
|
|
||||||
|
for (int i = 0; i < stageCount; i++) {
|
||||||
|
RocketComponent stage = stageList.get(i);
|
||||||
|
MassData data = calculateAssemblyMassData(stage);
|
||||||
|
cgCache[i] = stage.toAbsolute(data.getCG())[0];
|
||||||
|
longitudinalInertiaCache[i] = data.getLongitudinalInertia();
|
||||||
|
rotationalInertiaCache[i] = data.getRotationalInertia();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the mass and inertia data for this component and all subcomponents.
|
||||||
|
* The inertia is returned relative to the CG, and the CG is in the coordinates
|
||||||
|
* of the specified component, not global coordinates.
|
||||||
|
*/
|
||||||
|
private MassData calculateAssemblyMassData(RocketComponent parent) {
|
||||||
|
Coordinate parentCG = Coordinate.ZERO;
|
||||||
|
double longitudinalInertia = 0.0;
|
||||||
|
double rotationalInertia = 0.0;
|
||||||
|
|
||||||
|
// Calculate data for this component
|
||||||
|
parentCG = parent.getComponentCG();
|
||||||
|
if (parentCG.weight < MIN_MASS)
|
||||||
|
parentCG = parentCG.setWeight(MIN_MASS);
|
||||||
|
|
||||||
|
|
||||||
|
// Override only this component's data
|
||||||
|
if (!parent.getOverrideSubcomponents()) {
|
||||||
|
if (parent.isMassOverridden())
|
||||||
|
parentCG = parentCG.setWeight(MathUtil.max(parent.getOverrideMass(), MIN_MASS));
|
||||||
|
if (parent.isCGOverridden())
|
||||||
|
parentCG = parentCG.setXYZ(parent.getOverrideCG());
|
||||||
|
}
|
||||||
|
|
||||||
|
longitudinalInertia = parent.getLongitudinalUnitInertia() * parentCG.weight;
|
||||||
|
rotationalInertia = parent.getRotationalUnitInertia() * parentCG.weight;
|
||||||
|
|
||||||
|
|
||||||
|
// Combine data for subcomponents
|
||||||
|
for (RocketComponent sibling : parent.getChildren()) {
|
||||||
|
Coordinate combinedCG;
|
||||||
|
double dx2, dr2;
|
||||||
|
|
||||||
|
// Compute data of sibling
|
||||||
|
MassData siblingData = calculateAssemblyMassData(sibling);
|
||||||
|
Coordinate[] siblingCGs = sibling.toRelative(siblingData.getCG(), parent);
|
||||||
|
|
||||||
|
for (Coordinate siblingCG : siblingCGs) {
|
||||||
|
|
||||||
|
// Compute CG of this + sibling
|
||||||
|
combinedCG = parentCG.average(siblingCG);
|
||||||
|
|
||||||
|
// Add effect of this CG change to parent inertia
|
||||||
|
dx2 = pow2(parentCG.x - combinedCG.x);
|
||||||
|
longitudinalInertia += parentCG.weight * dx2;
|
||||||
|
|
||||||
|
dr2 = pow2(parentCG.y - combinedCG.y) + pow2(parentCG.z - combinedCG.z);
|
||||||
|
rotationalInertia += parentCG.weight * dr2;
|
||||||
|
|
||||||
|
|
||||||
|
// Add inertia of sibling
|
||||||
|
longitudinalInertia += siblingData.getLongitudinalInertia();
|
||||||
|
rotationalInertia += siblingData.getRotationalInertia();
|
||||||
|
|
||||||
|
// Add effect of sibling CG change
|
||||||
|
dx2 = pow2(siblingData.getCG().x - combinedCG.x);
|
||||||
|
longitudinalInertia += siblingData.getCG().weight * dx2;
|
||||||
|
|
||||||
|
dr2 = pow2(siblingData.getCG().y - combinedCG.y) + pow2(siblingData.getCG().z - combinedCG.z);
|
||||||
|
rotationalInertia += siblingData.getCG().weight * dr2;
|
||||||
|
|
||||||
|
// Set combined CG
|
||||||
|
parentCG = combinedCG;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Override total data
|
||||||
|
if (parent.getOverrideSubcomponents()) {
|
||||||
|
if (parent.isMassOverridden()) {
|
||||||
|
double oldMass = parentCG.weight;
|
||||||
|
double newMass = MathUtil.max(parent.getOverrideMass(), MIN_MASS);
|
||||||
|
longitudinalInertia = longitudinalInertia * newMass / oldMass;
|
||||||
|
rotationalInertia = rotationalInertia * newMass / oldMass;
|
||||||
|
parentCG = parentCG.setWeight(newMass);
|
||||||
|
}
|
||||||
|
if (parent.isCGOverridden()) {
|
||||||
|
double oldx = parentCG.x;
|
||||||
|
double newx = parent.getOverrideCGX();
|
||||||
|
longitudinalInertia += parentCG.weight * pow2(oldx - newx);
|
||||||
|
parentCG = parentCG.setX(newx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MassData parentData = new MassData(parentCG, longitudinalInertia, rotationalInertia, 0);
|
||||||
|
return parentData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check the current cache consistency. This method must be called by all
|
||||||
|
* methods that may use any cached data before any other operations are
|
||||||
|
* performed. If the rocket has changed since the previous call to
|
||||||
|
* <code>checkCache()</code>, then {@link #voidMassCache()} is called.
|
||||||
|
* <p>
|
||||||
|
* This method performs the checking based on the rocket's modification IDs,
|
||||||
|
* so that these method may be called from listeners of the rocket itself.
|
||||||
|
*
|
||||||
|
* @param configuration the configuration of the current call
|
||||||
|
*/
|
||||||
|
protected final void checkCache(Configuration configuration) {
|
||||||
|
if (rocketMassModID != configuration.getRocket().getMassModID() ||
|
||||||
|
rocketTreeModID != configuration.getRocket().getTreeModID()) {
|
||||||
|
rocketMassModID = configuration.getRocket().getMassModID();
|
||||||
|
rocketTreeModID = configuration.getRocket().getTreeModID();
|
||||||
|
log.debug("Voiding the mass cache");
|
||||||
|
voidMassCache();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Void cached mass data. This method is called whenever a change occurs in
|
||||||
|
* the rocket structure that affects the mass of the rocket and when a new
|
||||||
|
* Rocket is used. This method must be overridden to void any cached data
|
||||||
|
* necessary. The method must call <code>super.voidMassCache()</code> during
|
||||||
|
* its execution.
|
||||||
|
*/
|
||||||
|
protected void voidMassCache() {
|
||||||
|
this.cgCache = null;
|
||||||
|
this.longitudinalInertiaCache = null;
|
||||||
|
this.rotationalInertiaCache = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getModID() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@ import net.sf.openrocket.aerodynamics.AerodynamicCalculator;
|
|||||||
import net.sf.openrocket.aerodynamics.BarrowmanCalculator;
|
import net.sf.openrocket.aerodynamics.BarrowmanCalculator;
|
||||||
import net.sf.openrocket.aerodynamics.FlightConditions;
|
import net.sf.openrocket.aerodynamics.FlightConditions;
|
||||||
import net.sf.openrocket.document.Simulation;
|
import net.sf.openrocket.document.Simulation;
|
||||||
import net.sf.openrocket.masscalc.BasicMassCalculator;
|
|
||||||
import net.sf.openrocket.masscalc.MassCalculator;
|
import net.sf.openrocket.masscalc.MassCalculator;
|
||||||
import net.sf.openrocket.masscalc.MassCalculator.MassCalcType;
|
import net.sf.openrocket.masscalc.MassCalculator.MassCalcType;
|
||||||
import net.sf.openrocket.optimization.rocketoptimization.SimulationDomain;
|
import net.sf.openrocket.optimization.rocketoptimization.SimulationDomain;
|
||||||
@ -64,7 +63,7 @@ public class StabilityDomain implements SimulationDomain {
|
|||||||
* Caching would in any case be inefficient since the rocket changes all the time.
|
* Caching would in any case be inefficient since the rocket changes all the time.
|
||||||
*/
|
*/
|
||||||
AerodynamicCalculator aerodynamicCalculator = new BarrowmanCalculator();
|
AerodynamicCalculator aerodynamicCalculator = new BarrowmanCalculator();
|
||||||
MassCalculator massCalculator = new BasicMassCalculator();
|
MassCalculator massCalculator = new MassCalculator();
|
||||||
|
|
||||||
|
|
||||||
Configuration configuration = simulation.getConfiguration();
|
Configuration configuration = simulation.getConfiguration();
|
||||||
|
@ -1,14 +1,10 @@
|
|||||||
package net.sf.openrocket.optimization.rocketoptimization.parameters;
|
package net.sf.openrocket.optimization.rocketoptimization.parameters;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import net.sf.openrocket.aerodynamics.AerodynamicCalculator;
|
import net.sf.openrocket.aerodynamics.AerodynamicCalculator;
|
||||||
import net.sf.openrocket.aerodynamics.BarrowmanCalculator;
|
import net.sf.openrocket.aerodynamics.BarrowmanCalculator;
|
||||||
import net.sf.openrocket.aerodynamics.FlightConditions;
|
import net.sf.openrocket.aerodynamics.FlightConditions;
|
||||||
import net.sf.openrocket.document.Simulation;
|
import net.sf.openrocket.document.Simulation;
|
||||||
import net.sf.openrocket.l10n.Translator;
|
import net.sf.openrocket.l10n.Translator;
|
||||||
import net.sf.openrocket.masscalc.BasicMassCalculator;
|
|
||||||
import net.sf.openrocket.masscalc.MassCalculator;
|
import net.sf.openrocket.masscalc.MassCalculator;
|
||||||
import net.sf.openrocket.masscalc.MassCalculator.MassCalcType;
|
import net.sf.openrocket.masscalc.MassCalculator.MassCalcType;
|
||||||
import net.sf.openrocket.optimization.general.OptimizationException;
|
import net.sf.openrocket.optimization.general.OptimizationException;
|
||||||
@ -21,6 +17,9 @@ import net.sf.openrocket.unit.UnitGroup;
|
|||||||
import net.sf.openrocket.util.Coordinate;
|
import net.sf.openrocket.util.Coordinate;
|
||||||
import net.sf.openrocket.util.MathUtil;
|
import net.sf.openrocket.util.MathUtil;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An optimization parameter that computes either the absolute or relative stability of a rocket.
|
* An optimization parameter that computes either the absolute or relative stability of a rocket.
|
||||||
*
|
*
|
||||||
@ -57,7 +56,7 @@ public class StabilityParameter implements OptimizableParameter {
|
|||||||
* Caching would in any case be inefficient since the rocket changes all the time.
|
* Caching would in any case be inefficient since the rocket changes all the time.
|
||||||
*/
|
*/
|
||||||
AerodynamicCalculator aerodynamicCalculator = new BarrowmanCalculator();
|
AerodynamicCalculator aerodynamicCalculator = new BarrowmanCalculator();
|
||||||
MassCalculator massCalculator = new BasicMassCalculator();
|
MassCalculator massCalculator = new MassCalculator();
|
||||||
|
|
||||||
|
|
||||||
Configuration configuration = simulation.getConfiguration();
|
Configuration configuration = simulation.getConfiguration();
|
||||||
|
@ -2,7 +2,6 @@ package net.sf.openrocket.rocketcomponent;
|
|||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
import net.sf.openrocket.masscalc.BasicMassCalculator;
|
|
||||||
import net.sf.openrocket.masscalc.MassCalculator;
|
import net.sf.openrocket.masscalc.MassCalculator;
|
||||||
import net.sf.openrocket.masscalc.MassCalculator.MassCalcType;
|
import net.sf.openrocket.masscalc.MassCalculator.MassCalcType;
|
||||||
import net.sf.openrocket.util.Coordinate;
|
import net.sf.openrocket.util.Coordinate;
|
||||||
@ -26,7 +25,7 @@ public abstract class RocketUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static Coordinate getCG(Rocket rocket, MassCalcType calcType) {
|
public static Coordinate getCG(Rocket rocket, MassCalcType calcType) {
|
||||||
MassCalculator massCalculator = new BasicMassCalculator();
|
MassCalculator massCalculator = new MassCalculator();
|
||||||
Coordinate cg = massCalculator.getCG(rocket.getDefaultConfiguration(), calcType);
|
Coordinate cg = massCalculator.getCG(rocket.getDefaultConfiguration(), calcType);
|
||||||
return cg;
|
return cg;
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ import java.util.Random;
|
|||||||
|
|
||||||
import net.sf.openrocket.aerodynamics.BarrowmanCalculator;
|
import net.sf.openrocket.aerodynamics.BarrowmanCalculator;
|
||||||
import net.sf.openrocket.formatting.MotorDescriptionSubstitutor;
|
import net.sf.openrocket.formatting.MotorDescriptionSubstitutor;
|
||||||
import net.sf.openrocket.masscalc.BasicMassCalculator;
|
import net.sf.openrocket.masscalc.MassCalculator;
|
||||||
import net.sf.openrocket.models.atmosphere.AtmosphericModel;
|
import net.sf.openrocket.models.atmosphere.AtmosphericModel;
|
||||||
import net.sf.openrocket.models.atmosphere.ExtendedISAModel;
|
import net.sf.openrocket.models.atmosphere.ExtendedISAModel;
|
||||||
import net.sf.openrocket.models.gravity.GravityModel;
|
import net.sf.openrocket.models.gravity.GravityModel;
|
||||||
@ -37,6 +37,7 @@ import org.slf4j.LoggerFactory;
|
|||||||
*/
|
*/
|
||||||
public class SimulationOptions implements ChangeSource, Cloneable {
|
public class SimulationOptions implements ChangeSource, Cloneable {
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
private static final Logger log = LoggerFactory.getLogger(SimulationOptions.class);
|
private static final Logger log = LoggerFactory.getLogger(SimulationOptions.class);
|
||||||
|
|
||||||
public static final double MAX_LAUNCH_ROD_ANGLE = Math.PI / 3;
|
public static final double MAX_LAUNCH_ROD_ANGLE = Math.PI / 3;
|
||||||
@ -638,7 +639,7 @@ public class SimulationOptions implements ChangeSource, Cloneable {
|
|||||||
conditions.setGravityModel(gravityModel);
|
conditions.setGravityModel(gravityModel);
|
||||||
|
|
||||||
conditions.setAerodynamicCalculator(new BarrowmanCalculator());
|
conditions.setAerodynamicCalculator(new BarrowmanCalculator());
|
||||||
conditions.setMassCalculator(new BasicMassCalculator());
|
conditions.setMassCalculator(new MassCalculator());
|
||||||
|
|
||||||
conditions.setTimeStep(getTimeStep());
|
conditions.setTimeStep(getTimeStep());
|
||||||
conditions.setMaximumAngleStep(getMaximumStepAngle());
|
conditions.setMaximumAngleStep(getMaximumStepAngle());
|
||||||
|
@ -54,7 +54,6 @@ import net.sf.openrocket.gui.components.UnitSelector;
|
|||||||
import net.sf.openrocket.gui.scalefigure.RocketPanel;
|
import net.sf.openrocket.gui.scalefigure.RocketPanel;
|
||||||
import net.sf.openrocket.gui.util.GUIUtil;
|
import net.sf.openrocket.gui.util.GUIUtil;
|
||||||
import net.sf.openrocket.l10n.Translator;
|
import net.sf.openrocket.l10n.Translator;
|
||||||
import net.sf.openrocket.masscalc.BasicMassCalculator;
|
|
||||||
import net.sf.openrocket.masscalc.MassCalculator;
|
import net.sf.openrocket.masscalc.MassCalculator;
|
||||||
import net.sf.openrocket.masscalc.MassCalculator.MassCalcType;
|
import net.sf.openrocket.masscalc.MassCalculator.MassCalcType;
|
||||||
import net.sf.openrocket.rocketcomponent.Configuration;
|
import net.sf.openrocket.rocketcomponent.Configuration;
|
||||||
@ -69,7 +68,7 @@ import net.sf.openrocket.util.MathUtil;
|
|||||||
import net.sf.openrocket.util.StateChangeListener;
|
import net.sf.openrocket.util.StateChangeListener;
|
||||||
|
|
||||||
public class ComponentAnalysisDialog extends JDialog implements StateChangeListener {
|
public class ComponentAnalysisDialog extends JDialog implements StateChangeListener {
|
||||||
|
private static final long serialVersionUID = 9131240570600307935L;
|
||||||
private static ComponentAnalysisDialog singletonDialog = null;
|
private static ComponentAnalysisDialog singletonDialog = null;
|
||||||
private static final Translator trans = Application.getTranslator();
|
private static final Translator trans = Application.getTranslator();
|
||||||
|
|
||||||
@ -80,7 +79,7 @@ public class ComponentAnalysisDialog extends JDialog implements StateChangeListe
|
|||||||
private final JToggleButton worstToggle;
|
private final JToggleButton worstToggle;
|
||||||
private boolean fakeChange = false;
|
private boolean fakeChange = false;
|
||||||
private AerodynamicCalculator aerodynamicCalculator;
|
private AerodynamicCalculator aerodynamicCalculator;
|
||||||
private final MassCalculator massCalculator = new BasicMassCalculator();
|
private final MassCalculator massCalculator = new MassCalculator();
|
||||||
|
|
||||||
private final ColumnTableModel cpTableModel;
|
private final ColumnTableModel cpTableModel;
|
||||||
private final ColumnTableModel dragTableModel;
|
private final ColumnTableModel dragTableModel;
|
||||||
|
@ -13,7 +13,6 @@ import net.sf.openrocket.formatting.RocketDescriptor;
|
|||||||
import net.sf.openrocket.gui.figureelements.FigureElement;
|
import net.sf.openrocket.gui.figureelements.FigureElement;
|
||||||
import net.sf.openrocket.gui.figureelements.RocketInfo;
|
import net.sf.openrocket.gui.figureelements.RocketInfo;
|
||||||
import net.sf.openrocket.gui.scalefigure.RocketPanel;
|
import net.sf.openrocket.gui.scalefigure.RocketPanel;
|
||||||
import net.sf.openrocket.masscalc.BasicMassCalculator;
|
|
||||||
import net.sf.openrocket.masscalc.MassCalculator;
|
import net.sf.openrocket.masscalc.MassCalculator;
|
||||||
import net.sf.openrocket.masscalc.MassCalculator.MassCalcType;
|
import net.sf.openrocket.masscalc.MassCalculator.MassCalcType;
|
||||||
import net.sf.openrocket.motor.Motor;
|
import net.sf.openrocket.motor.Motor;
|
||||||
@ -325,7 +324,7 @@ public class DesignReport {
|
|||||||
|
|
||||||
DecimalFormat ttwFormat = new DecimalFormat("0.00");
|
DecimalFormat ttwFormat = new DecimalFormat("0.00");
|
||||||
|
|
||||||
MassCalculator massCalc = new BasicMassCalculator();
|
MassCalculator massCalc = new MassCalculator();
|
||||||
|
|
||||||
Configuration config = new Configuration(rocket);
|
Configuration config = new Configuration(rocket);
|
||||||
config.setFlightConfigurationID(motorId);
|
config.setFlightConfigurationID(motorId);
|
||||||
|
@ -54,7 +54,6 @@ import net.sf.openrocket.gui.main.componenttree.ComponentTreeModel;
|
|||||||
import net.sf.openrocket.gui.simulation.SimulationWorker;
|
import net.sf.openrocket.gui.simulation.SimulationWorker;
|
||||||
import net.sf.openrocket.gui.util.SwingPreferences;
|
import net.sf.openrocket.gui.util.SwingPreferences;
|
||||||
import net.sf.openrocket.l10n.Translator;
|
import net.sf.openrocket.l10n.Translator;
|
||||||
import net.sf.openrocket.masscalc.BasicMassCalculator;
|
|
||||||
import net.sf.openrocket.masscalc.MassCalculator;
|
import net.sf.openrocket.masscalc.MassCalculator;
|
||||||
import net.sf.openrocket.masscalc.MassCalculator.MassCalcType;
|
import net.sf.openrocket.masscalc.MassCalculator.MassCalcType;
|
||||||
import net.sf.openrocket.rocketcomponent.ComponentChangeEvent;
|
import net.sf.openrocket.rocketcomponent.ComponentChangeEvent;
|
||||||
@ -184,7 +183,7 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
|
|||||||
|
|
||||||
// TODO: FUTURE: calculator selection
|
// TODO: FUTURE: calculator selection
|
||||||
aerodynamicCalculator = new BarrowmanCalculator();
|
aerodynamicCalculator = new BarrowmanCalculator();
|
||||||
massCalculator = new BasicMassCalculator();
|
massCalculator = new MassCalculator();
|
||||||
|
|
||||||
// Create figure and custom scroll pane
|
// Create figure and custom scroll pane
|
||||||
figure = new RocketFigure(configuration);
|
figure = new RocketFigure(configuration);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user