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.WarningSet;
|
||||
import net.sf.openrocket.formatting.RocketDescriptor;
|
||||
import net.sf.openrocket.masscalc.BasicMassCalculator;
|
||||
import net.sf.openrocket.masscalc.MassCalculator;
|
||||
import net.sf.openrocket.motor.Motor;
|
||||
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 AerodynamicCalculator> aerodynamicCalculatorClass = BarrowmanCalculator.class;
|
||||
@SuppressWarnings("unused")
|
||||
private Class<? extends MassCalculator> massCalculatorClass = BasicMassCalculator.class;
|
||||
private Class<? extends MassCalculator> massCalculatorClass = MassCalculator.class;
|
||||
|
||||
/** Listeners for this object */
|
||||
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.file.RocketSaver;
|
||||
import net.sf.openrocket.file.rocksim.RocksimCommonConstants;
|
||||
import net.sf.openrocket.masscalc.BasicMassCalculator;
|
||||
import net.sf.openrocket.masscalc.MassCalculator;
|
||||
import net.sf.openrocket.rocketcomponent.AxialStage;
|
||||
import net.sf.openrocket.rocketcomponent.Configuration;
|
||||
import net.sf.openrocket.rocketcomponent.Rocket;
|
||||
import net.sf.openrocket.rocketcomponent.AxialStage;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@ -93,7 +92,7 @@ public class RocksimSaver extends RocketSaver {
|
||||
private RocketDesignDTO toRocketDesignDTO(Rocket rocket) {
|
||||
RocketDesignDTO result = new RocketDesignDTO();
|
||||
|
||||
MassCalculator massCalc = new BasicMassCalculator();
|
||||
MassCalculator massCalc = new MassCalculator();
|
||||
|
||||
final Configuration configuration = new Configuration(rocket);
|
||||
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;
|
||||
|
||||
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 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 {
|
||||
NO_MOTORS {
|
||||
@ -34,41 +48,186 @@ public interface MassCalculator extends Monitorable {
|
||||
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 type the state of the motors (none, launch mass, burnout mass)
|
||||
* @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 motors the motor 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
|
||||
* @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.
|
||||
*
|
||||
* @param configuration the rocket configuration
|
||||
* @param configuration the current motor instance configuration
|
||||
* @param motors the motor 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
|
||||
@ -77,7 +236,18 @@ public interface MassCalculator extends Monitorable {
|
||||
* @param configuration the current motor instance configuration
|
||||
* @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.
|
||||
@ -90,7 +260,175 @@ public interface MassCalculator extends Monitorable {
|
||||
* @param type the state of the motors (none, launch mass, burnout mass)
|
||||
* @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.FlightConditions;
|
||||
import net.sf.openrocket.document.Simulation;
|
||||
import net.sf.openrocket.masscalc.BasicMassCalculator;
|
||||
import net.sf.openrocket.masscalc.MassCalculator;
|
||||
import net.sf.openrocket.masscalc.MassCalculator.MassCalcType;
|
||||
import net.sf.openrocket.optimization.rocketoptimization.SimulationDomain;
|
||||
@ -50,8 +49,8 @@ public class StabilityDomain implements SimulationDomain {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public Pair<Double, Value> getDistanceToDomain(Simulation simulation) {
|
||||
Coordinate cp, cg;
|
||||
@ -64,9 +63,9 @@ public class StabilityDomain implements SimulationDomain {
|
||||
* Caching would in any case be inefficient since the rocket changes all the time.
|
||||
*/
|
||||
AerodynamicCalculator aerodynamicCalculator = new BarrowmanCalculator();
|
||||
MassCalculator massCalculator = new BasicMassCalculator();
|
||||
MassCalculator massCalculator = new MassCalculator();
|
||||
|
||||
|
||||
|
||||
Configuration configuration = simulation.getConfiguration();
|
||||
FlightConditions conditions = new FlightConditions(configuration);
|
||||
conditions.setMach(Application.getPreferences().getDefaultMach());
|
||||
@ -87,7 +86,7 @@ public class StabilityDomain implements SimulationDomain {
|
||||
else
|
||||
cgx = Double.NaN;
|
||||
|
||||
|
||||
|
||||
// Calculate the reference (absolute or relative)
|
||||
absolute = cpx - cgx;
|
||||
|
||||
@ -101,7 +100,7 @@ public class StabilityDomain implements SimulationDomain {
|
||||
}
|
||||
relative = absolute / diameter;
|
||||
|
||||
|
||||
|
||||
Value desc;
|
||||
if (minAbsolute && maxAbsolute) {
|
||||
desc = new Value(absolute, UnitGroup.UNITS_LENGTH);
|
||||
|
@ -1,14 +1,10 @@
|
||||
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.BarrowmanCalculator;
|
||||
import net.sf.openrocket.aerodynamics.FlightConditions;
|
||||
import net.sf.openrocket.document.Simulation;
|
||||
import net.sf.openrocket.l10n.Translator;
|
||||
import net.sf.openrocket.masscalc.BasicMassCalculator;
|
||||
import net.sf.openrocket.masscalc.MassCalculator;
|
||||
import net.sf.openrocket.masscalc.MassCalculator.MassCalcType;
|
||||
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.MathUtil;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* An optimization parameter that computes either the absolute or relative stability of a rocket.
|
||||
*
|
||||
@ -31,7 +30,7 @@ public class StabilityParameter implements OptimizableParameter {
|
||||
private static final Logger log = LoggerFactory.getLogger(StabilityParameter.class);
|
||||
private static final Translator trans = Application.getTranslator();
|
||||
|
||||
|
||||
|
||||
private final boolean absolute;
|
||||
|
||||
public StabilityParameter(boolean absolute) {
|
||||
@ -57,9 +56,9 @@ public class StabilityParameter implements OptimizableParameter {
|
||||
* Caching would in any case be inefficient since the rocket changes all the time.
|
||||
*/
|
||||
AerodynamicCalculator aerodynamicCalculator = new BarrowmanCalculator();
|
||||
MassCalculator massCalculator = new BasicMassCalculator();
|
||||
MassCalculator massCalculator = new MassCalculator();
|
||||
|
||||
|
||||
|
||||
Configuration configuration = simulation.getConfiguration();
|
||||
FlightConditions conditions = new FlightConditions(configuration);
|
||||
conditions.setMach(Application.getPreferences().getDefaultMach());
|
||||
@ -79,7 +78,7 @@ public class StabilityParameter implements OptimizableParameter {
|
||||
else
|
||||
cgx = Double.NaN;
|
||||
|
||||
|
||||
|
||||
// Calculate the reference (absolute or relative)
|
||||
stability = cpx - cgx;
|
||||
|
||||
|
@ -2,13 +2,12 @@ package net.sf.openrocket.rocketcomponent;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import net.sf.openrocket.masscalc.BasicMassCalculator;
|
||||
import net.sf.openrocket.masscalc.MassCalculator;
|
||||
import net.sf.openrocket.masscalc.MassCalculator.MassCalcType;
|
||||
import net.sf.openrocket.util.Coordinate;
|
||||
|
||||
public abstract class RocketUtils {
|
||||
|
||||
|
||||
public static double getLength(Rocket rocket) {
|
||||
double length = 0;
|
||||
Collection<Coordinate> bounds = rocket.getDefaultConfiguration().getBounds();
|
||||
@ -24,9 +23,9 @@ public abstract class RocketUtils {
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
public static Coordinate getCG(Rocket rocket, MassCalcType calcType) {
|
||||
MassCalculator massCalculator = new BasicMassCalculator();
|
||||
MassCalculator massCalculator = new MassCalculator();
|
||||
Coordinate cg = massCalculator.getCG(rocket.getDefaultConfiguration(), calcType);
|
||||
return cg;
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ import java.util.Random;
|
||||
|
||||
import net.sf.openrocket.aerodynamics.BarrowmanCalculator;
|
||||
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.ExtendedISAModel;
|
||||
import net.sf.openrocket.models.gravity.GravityModel;
|
||||
@ -37,6 +37,7 @@ import org.slf4j.LoggerFactory;
|
||||
*/
|
||||
public class SimulationOptions implements ChangeSource, Cloneable {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static final Logger log = LoggerFactory.getLogger(SimulationOptions.class);
|
||||
|
||||
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.setAerodynamicCalculator(new BarrowmanCalculator());
|
||||
conditions.setMassCalculator(new BasicMassCalculator());
|
||||
conditions.setMassCalculator(new MassCalculator());
|
||||
|
||||
conditions.setTimeStep(getTimeStep());
|
||||
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.util.GUIUtil;
|
||||
import net.sf.openrocket.l10n.Translator;
|
||||
import net.sf.openrocket.masscalc.BasicMassCalculator;
|
||||
import net.sf.openrocket.masscalc.MassCalculator;
|
||||
import net.sf.openrocket.masscalc.MassCalculator.MassCalcType;
|
||||
import net.sf.openrocket.rocketcomponent.Configuration;
|
||||
@ -69,7 +68,7 @@ import net.sf.openrocket.util.MathUtil;
|
||||
import net.sf.openrocket.util.StateChangeListener;
|
||||
|
||||
public class ComponentAnalysisDialog extends JDialog implements StateChangeListener {
|
||||
|
||||
private static final long serialVersionUID = 9131240570600307935L;
|
||||
private static ComponentAnalysisDialog singletonDialog = null;
|
||||
private static final Translator trans = Application.getTranslator();
|
||||
|
||||
@ -80,7 +79,7 @@ public class ComponentAnalysisDialog extends JDialog implements StateChangeListe
|
||||
private final JToggleButton worstToggle;
|
||||
private boolean fakeChange = false;
|
||||
private AerodynamicCalculator aerodynamicCalculator;
|
||||
private final MassCalculator massCalculator = new BasicMassCalculator();
|
||||
private final MassCalculator massCalculator = new MassCalculator();
|
||||
|
||||
private final ColumnTableModel cpTableModel;
|
||||
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.RocketInfo;
|
||||
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.MassCalcType;
|
||||
import net.sf.openrocket.motor.Motor;
|
||||
@ -325,7 +324,7 @@ public class DesignReport {
|
||||
|
||||
DecimalFormat ttwFormat = new DecimalFormat("0.00");
|
||||
|
||||
MassCalculator massCalc = new BasicMassCalculator();
|
||||
MassCalculator massCalc = new MassCalculator();
|
||||
|
||||
Configuration config = new Configuration(rocket);
|
||||
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.util.SwingPreferences;
|
||||
import net.sf.openrocket.l10n.Translator;
|
||||
import net.sf.openrocket.masscalc.BasicMassCalculator;
|
||||
import net.sf.openrocket.masscalc.MassCalculator;
|
||||
import net.sf.openrocket.masscalc.MassCalculator.MassCalcType;
|
||||
import net.sf.openrocket.rocketcomponent.ComponentChangeEvent;
|
||||
@ -184,7 +183,7 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
|
||||
|
||||
// TODO: FUTURE: calculator selection
|
||||
aerodynamicCalculator = new BarrowmanCalculator();
|
||||
massCalculator = new BasicMassCalculator();
|
||||
massCalculator = new MassCalculator();
|
||||
|
||||
// Create figure and custom scroll pane
|
||||
figure = new RocketFigure(configuration);
|
||||
|
Loading…
x
Reference in New Issue
Block a user