[Bugfix] Tested/Fixed Mass Override Calculation Code

- MassCalculator class:
    fixed mass
    fixed CG x-value overrides
- MassCalculatorTest class:
    added tests for:
        setOverrideMass(...)
        setOverrideCGX(...)
This commit is contained in:
Daniel_M_Williams 2015-11-17 10:04:30 -05:00
parent 9d78d823b6
commit ee887cae08
2 changed files with 150 additions and 46 deletions

View File

@ -65,8 +65,9 @@ public class MassCalculator implements Monitorable {
// private MassData launchData = null;
// private Vector< MassData> motorData = new Vector<MassData>();
// unless in active development, this should be set to false.
//public boolean debug = false;
// this turns on copious amounts of debug. Recommend leaving this false
// until reaching code that causes interesting conditions.
public boolean debug = false;
////////////////// Constructors ///////////////////
public MassCalculator() {
@ -301,17 +302,13 @@ public class MassCalculator implements Monitorable {
private void calculateStageCache(FlightConfiguration config) {
int stageCount = config.getActiveStageCount();
// if(debug){
// System.err.println(">> Calculating CG cache for config: "+config.toShort()+" with "+stageCount+" stages");
// }
if(debug){
System.err.println(">> Calculating massData cache for config: "+config.toShort()+" with "+stageCount+" stages");
}
if( 0 < stageCount ){
for( AxialStage curStage : config.getActiveStages()){
int index = curStage.getStageNumber();
MassData stageData = calculateAssemblyMassData( curStage);
if( curStage instanceof BoosterSet ){
// hacky correction for the fact Booster Stages aren't direct subchildren to the rocket
stageData = stageData.move( curStage.getParent().getOffset() );
}
cache.put(index, stageData);
}
}
@ -325,27 +322,25 @@ public class MassCalculator implements Monitorable {
* of the specified component, not global coordinates.
*/
private MassData calculateAssemblyMassData(RocketComponent component) {
// return calculateAssemblyMassData(component, "....");
// }
//
// private MassData calculateAssemblyMassData(RocketComponent component, String indent) {
return calculateAssemblyMassData(component, "....");
}
private MassData calculateAssemblyMassData(RocketComponent component, String indent) {
Coordinate parentCM = component.getComponentCG();
double parentIx = component.getRotationalUnitInertia() * parentCM.weight;
double parentIt = component.getLongitudinalUnitInertia() * parentCM.weight;
MassData parentData = new MassData( parentCM, parentIx, parentIt);
// if(( debug) &&( 0 < component.getChildCount()) && (MIN_MASS < parentCM.weight)){
// //System.err.println(String.format("%-32s: %s ",indent+">>["+ component.getName()+"]", parentData.toCMDebug() ));
// System.err.println(String.format("%-32s: %s ",indent+">>["+ component.getName()+"]", parentData.toDebug() ));
// }
if (!component.getOverrideSubcomponents()) {
if (component.isMassOverridden())
parentCM = parentCM.setWeight(MathUtil.max(component.getOverrideMass(), MIN_MASS));
if (component.isCGOverridden())
parentCM = parentCM.setXYZ(component.getOverrideCG());
}
if(( debug) &&( 0 < component.getChildCount()) && (MIN_MASS < parentCM.weight)){
System.err.println(String.format("%-32s: %s ",indent+">>["+ component.getName()+"]", parentData.toDebug() ));
}
MassData childrenData = MassData.ZERO_DATA;
// Combine data for subcomponents
@ -356,7 +351,7 @@ public class MassCalculator implements Monitorable {
}
// child data, relative to parent's reference frame
MassData childData = calculateAssemblyMassData(child);//, indent+"....");
MassData childData = calculateAssemblyMassData(child, indent+"....");
childrenData = childrenData.add( childData );
}
@ -400,35 +395,47 @@ public class MassCalculator implements Monitorable {
// combine the parent's and children's data
resultantData = parentData.add( childrenData);
// Override total data
// if (component.getOverrideSubcomponents()) {
// if (component.isMassOverridden()) {
// double oldMass = parentCM.weight;
// double newMass = MathUtil.max(component.getOverrideMass(), MIN_MASS);
// longitudinalInertia = longitudinalInertia * newMass / oldMass;
// rotationalInertia = rotationalInertia * newMass / oldMass;
// parentCM = parentCM.setWeight(newMass);
// }
// if (component.isCGOverridden()) {
// double oldx = parentCM.x;
// double newx = component.getOverrideCGX();
// longitudinalInertia += parentCM.weight * MathUtil.pow2(oldx - newx);
// parentCM = parentCM.setX(newx);
// }
// }
// if( debug){
// //System.err.println(String.format("%-32s: %s ", indent+"<<["+component.getName()+"][asbly]", resultantData.toCMDebug()));
// System.err.println(String.format("%-32s: %s ", indent+"@@["+component.getName()+"][asbly]", resultantData.toDebug()));
// }
//
if( debug){
System.err.println(String.format("%-32s: %s ", indent+"<==>["+component.getName()+"][asbly]", resultantData.toDebug()));
}
// move to parent's reference point
resultantData = resultantData.move( component.getOffset() );
// if( debug){
// //System.err.println(String.format("%-32s: %s ", indent+"<<["+component.getName()+"][asbly]", resultantData.toCMDebug()));
// System.err.println(String.format("%-32s: %s ", indent+"<<["+component.getName()+"][asbly]", resultantData.toDebug()));
// }
if( component instanceof BoosterSet ){
// hacky correction for the fact Booster Stages aren't direct subchildren to the rocket
resultantData = resultantData.move( component.getParent().getOffset() );
}
// Override total data
if (component.getOverrideSubcomponents()) {
if( debug){
System.err.println(String.format("%-32s: %s ", indent+"vv["+component.getName()+"][asbly]", resultantData.toDebug()));
}
if (component.isMassOverridden()) {
double oldMass = resultantData.getMass();
double newMass = MathUtil.max(component.getOverrideMass(), MIN_MASS);
Coordinate newCM = resultantData.getCM().setWeight(newMass);
double newIxx = resultantData.getIxx() * newMass / oldMass;
double newIyy = resultantData.getIyy() * newMass / oldMass;
double newIzz = resultantData.getIzz() * newMass / oldMass;
resultantData = new MassData( newCM, newIxx, newIyy, newIzz );
}
if (component.isCGOverridden()) {
double oldx = resultantData.getCM().x;
double newx = component.getOverrideCGX();
Coordinate delta = new Coordinate(newx-oldx, 0, 0);
if(debug){
System.err.println(String.format("%-32s: x: %g => %g (%g)", indent+" 88", oldx, newx, delta.x));
}
resultantData = resultantData.move( delta );
}
}
if( debug){
System.err.println(String.format("%-32s: %s ", indent+"<<["+component.getName()+"][asbly]", resultantData.toDebug()));
}
return resultantData;

View File

@ -389,4 +389,101 @@ public class MassCalculatorTest extends BaseTestCase {
assertEquals(" Booster transverse MOI is incorrect: ", expMOI_tr, boosterMOI_tr, EPSILON);
}
@Test
public void testMassOverride() {
Rocket rocket = TestRockets.makeFalcon9Heavy();
FlightConfiguration config = rocket.getDefaultConfiguration();
rocket.setName("TestRocket."+Thread.currentThread().getStackTrace()[1].getMethodName());
BoosterSet boosters = (BoosterSet) rocket.getChild(1).getChild(1);
int boostNum = boosters.getStageNumber();
config.setAllStages(false);
config.setOnlyStage( boostNum);
// String treeDump = rocket.toDebugTree();
// System.err.println( treeDump);
double overrideMass = 0.5;
boosters.setMassOverridden(true);
boosters.setOverrideMass(overrideMass);
{
// Validate Mass
MassCalculator mc = new MassCalculator();
//mc.debug = true;
Coordinate boosterSetCM = mc.getCM( rocket.getDefaultConfiguration(), MassCalcType.NO_MOTORS);
double calcTotalMass = boosterSetCM.weight;
double expTotalMass = overrideMass;
assertEquals(" Booster Launch Mass is incorrect: ", expTotalMass, calcTotalMass, EPSILON);
double expCMx = 0.9615865040919498;
Coordinate expCM = new Coordinate( expCMx, 0, 0, expTotalMass);
assertEquals(" Booster Launch CM.x is incorrect: ", expCM.x, boosterSetCM.x, EPSILON);
assertEquals(" Booster Launch CM.y is incorrect: ", expCM.y, boosterSetCM.y, EPSILON);
assertEquals(" Booster Launch CM.z is incorrect: ", expCM.z, boosterSetCM.z, EPSILON);
assertEquals(" Booster Launch CM is incorrect: ", expCM, boosterSetCM);
// Validate MOI
double oldMass = 0.23590802751203407;
double scaleMass = overrideMass / oldMass;
//mc.debug = true;
double expMOI_axial = .00144619 * scaleMass;
double boosterMOI_xx= mc.getRotationalInertia( config, MassCalcType.NO_MOTORS);
assertEquals(" Booster x-axis MOI is incorrect: ", expMOI_axial, boosterMOI_xx, EPSILON);
double expMOI_tr = 0.01845152840733412 * scaleMass;
double boosterMOI_tr= mc.getLongitudinalInertia( config, MassCalcType.NO_MOTORS);
assertEquals(" Booster transverse MOI is incorrect: ", expMOI_tr, boosterMOI_tr, EPSILON);
}
}
@Test
public void testCMOverride() {
Rocket rocket = TestRockets.makeFalcon9Heavy();
FlightConfiguration config = rocket.getDefaultConfiguration();
rocket.setName("TestRocket."+Thread.currentThread().getStackTrace()[1].getMethodName());
BoosterSet boosters = (BoosterSet) rocket.getChild(1).getChild(1);
int boostNum = boosters.getStageNumber();
config.setAllStages(false);
config.setOnlyStage( boostNum);
//String treeDump = rocket.toDebugTree();
//System.err.println( treeDump);
double overrideCMx = 0.5;
boosters.setCGOverridden(true);
boosters.setOverrideCGX(overrideCMx); // only allows x-axis corrections
{
// Validate Mass
MassCalculator mc = new MassCalculator();
//mc.debug = true;
Coordinate boosterSetCM = mc.getCM( rocket.getDefaultConfiguration(), MassCalcType.NO_MOTORS);
double expMass = 0.23590802751203407;
double calcTotalMass = boosterSetCM.weight;
assertEquals(" Booster Launch Mass is incorrect: ", expMass, calcTotalMass, EPSILON);
double expCMx = overrideCMx; //0.9615865040919498;
Coordinate expCM = new Coordinate( expCMx, 0, 0, expMass);
assertEquals(" Booster Launch CM.x is incorrect: ", expCM.x, boosterSetCM.x, EPSILON);
assertEquals(" Booster Launch CM.y is incorrect: ", expCM.y, boosterSetCM.y, EPSILON);
assertEquals(" Booster Launch CM.z is incorrect: ", expCM.z, boosterSetCM.z, EPSILON);
assertEquals(" Booster Launch CM is incorrect: ", expCM, boosterSetCM);
// Validate MOI
double expMOI_axial = .00144619 ;
double boosterMOI_xx= mc.getRotationalInertia( config, MassCalcType.NO_MOTORS);
assertEquals(" Booster x-axis MOI is incorrect: ", expMOI_axial, boosterMOI_xx, EPSILON);
double expMOI_tr = 0.01845152840733412 ;
double boosterMOI_tr= mc.getLongitudinalInertia( config, MassCalcType.NO_MOTORS);
assertEquals(" Booster transverse MOI is incorrect: ", expMOI_tr, boosterMOI_tr, EPSILON);
}
}
}