folded AbstractMassCalculator into BasicMassCalculator

This commit is contained in:
Daniel_M_Williams 2015-09-05 11:39:47 -04:00
parent 54f1a4c672
commit 7978771e1b
2 changed files with 79 additions and 103 deletions

View File

@ -1,54 +0,0 @@
package net.sf.openrocket.masscalc;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import net.sf.openrocket.rocketcomponent.Configuration;
/**
* Abstract base for mass calculators. Provides functionality for cacheing mass data.
*
* @author Sampo Niskanen <sampo.niskanen@iki.fi>
*/
public abstract class AbstractMassCalculator implements MassCalculator {
private static final Logger log = LoggerFactory.getLogger(AbstractMassCalculator.class);
private int rocketMassModID = -1;
private int rocketTreeModID = -1;
/**
* 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() {
// No-op
}
}

View File

@ -2,6 +2,7 @@ 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;
@ -10,16 +11,24 @@ 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;
public class BasicMassCalculator extends AbstractMassCalculator {
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
@ -238,21 +247,19 @@ public class BasicMassCalculator extends AbstractMassCalculator {
private void calculateStageCache(Configuration config) {
if (cgCache == null) {
ArrayList<AxialStage> stageList = config.getRocket().getStageList();
int stageCount = stageList.size();
//int stages = config.getRocket().getStageCount();
// temporary fix . this undercounts the stages
int stages = config.getRocket().getChildCount();
cgCache = new Coordinate[stageCount];
longitudinalInertiaCache = new double[stageCount];
rotationalInertiaCache = new double[stageCount];
cgCache = new Coordinate[stages];
longitudinalInertiaCache = new double[stages];
rotationalInertiaCache = new double[stages];
for (int i = 0; i < stages; i++) {
RocketComponent stage = config.getRocket().getChild(i);
for (int i = 0; i < stageCount; i++) {
RocketComponent stage = stageList.get(i);
MassData data = calculateAssemblyMassData(stage);
cgCache[i] = stage.toAbsolute(data.cg)[0];
longitudinalInertiaCache[i] = data.longitudinalInertia;
rotationalInertiaCache[i] = data.rotationalInetria;
cgCache[i] = stage.toAbsolute(data.getCG())[0];
longitudinalInertiaCache[i] = data.getLongitudinalInertia();
rotationalInertiaCache[i] = data.getRotationalInertia();
}
}
@ -266,24 +273,26 @@ public class BasicMassCalculator extends AbstractMassCalculator {
* of the specified component, not global coordinates.
*/
private MassData calculateAssemblyMassData(RocketComponent parent) {
MassData parentData = new MassData();
Coordinate parentCG = Coordinate.ZERO;
double longitudinalInertia = 0.0;
double rotationalInertia = 0.0;
// Calculate data for this component
parentData.cg = parent.getComponentCG();
if (parentData.cg.weight < MIN_MASS)
parentData.cg = parentData.cg.setWeight(MIN_MASS);
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())
parentData.cg = parentData.cg.setWeight(MathUtil.max(parent.getOverrideMass(), MIN_MASS));
parentCG = parentCG.setWeight(MathUtil.max(parent.getOverrideMass(), MIN_MASS));
if (parent.isCGOverridden())
parentData.cg = parentData.cg.setXYZ(parent.getOverrideCG());
parentCG = parentCG.setXYZ(parent.getOverrideCG());
}
parentData.longitudinalInertia = parent.getLongitudinalUnitInertia() * parentData.cg.weight;
parentData.rotationalInetria = parent.getRotationalUnitInertia() * parentData.cg.weight;
longitudinalInertia = parent.getLongitudinalUnitInertia() * parentCG.weight;
rotationalInertia = parent.getRotationalUnitInertia() * parentCG.weight;
// Combine data for subcomponents
@ -293,68 +302,87 @@ public class BasicMassCalculator extends AbstractMassCalculator {
// Compute data of sibling
MassData siblingData = calculateAssemblyMassData(sibling);
Coordinate[] siblingCGs = sibling.toRelative(siblingData.cg, parent);
Coordinate[] siblingCGs = sibling.toRelative(siblingData.getCG(), parent);
for (Coordinate siblingCG : siblingCGs) {
// Compute CG of this + sibling
combinedCG = parentData.cg.average(siblingCG);
combinedCG = parentCG.average(siblingCG);
// Add effect of this CG change to parent inertia
dx2 = pow2(parentData.cg.x - combinedCG.x);
parentData.longitudinalInertia += parentData.cg.weight * dx2;
dx2 = pow2(parentCG.x - combinedCG.x);
longitudinalInertia += parentCG.weight * dx2;
dr2 = pow2(parentData.cg.y - combinedCG.y) + pow2(parentData.cg.z - combinedCG.z);
parentData.rotationalInetria += parentData.cg.weight * dr2;
dr2 = pow2(parentCG.y - combinedCG.y) + pow2(parentCG.z - combinedCG.z);
rotationalInertia += parentCG.weight * dr2;
// Add inertia of sibling
parentData.longitudinalInertia += siblingData.longitudinalInertia;
parentData.rotationalInetria += siblingData.rotationalInetria;
longitudinalInertia += siblingData.getLongitudinalInertia();
rotationalInertia += siblingData.getRotationalInertia();
// Add effect of sibling CG change
dx2 = pow2(siblingData.cg.x - combinedCG.x);
parentData.longitudinalInertia += siblingData.cg.weight * dx2;
dx2 = pow2(siblingData.getCG().x - combinedCG.x);
longitudinalInertia += siblingData.getCG().weight * dx2;
dr2 = pow2(siblingData.cg.y - combinedCG.y) + pow2(siblingData.cg.z - combinedCG.z);
parentData.rotationalInetria += siblingData.cg.weight * dr2;
dr2 = pow2(siblingData.getCG().y - combinedCG.y) + pow2(siblingData.getCG().z - combinedCG.z);
rotationalInertia += siblingData.getCG().weight * dr2;
// Set combined CG
parentData.cg = combinedCG;
parentCG = combinedCG;
}
}
// Override total data
if (parent.getOverrideSubcomponents()) {
if (parent.isMassOverridden()) {
double oldMass = parentData.cg.weight;
double oldMass = parentCG.weight;
double newMass = MathUtil.max(parent.getOverrideMass(), MIN_MASS);
parentData.longitudinalInertia = parentData.longitudinalInertia * newMass / oldMass;
parentData.rotationalInetria = parentData.rotationalInetria * newMass / oldMass;
parentData.cg = parentData.cg.setWeight(newMass);
longitudinalInertia = longitudinalInertia * newMass / oldMass;
rotationalInertia = rotationalInertia * newMass / oldMass;
parentCG = parentCG.setWeight(newMass);
}
if (parent.isCGOverridden()) {
double oldx = parentData.cg.x;
double oldx = parentCG.x;
double newx = parent.getOverrideCGX();
parentData.longitudinalInertia += parentData.cg.weight * pow2(oldx - newx);
parentData.cg = parentData.cg.setX(newx);
longitudinalInertia += parentCG.weight * pow2(oldx - newx);
parentCG = parentCG.setX(newx);
}
}
MassData parentData = new MassData(parentCG, longitudinalInertia, rotationalInertia, 0);
return parentData;
}
private static class MassData {
public Coordinate cg = Coordinate.NUL;
public double longitudinalInertia = 0;
public double rotationalInetria = 0;
/**
* 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();
}
}
@Override
/**
* 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() {
super.voidMassCache();
this.cgCache = null;
this.longitudinalInertiaCache = null;
this.rotationalInertiaCache = null;
@ -370,4 +398,6 @@ public class BasicMassCalculator extends AbstractMassCalculator {
}