[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:
parent
9d78d823b6
commit
ee887cae08
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user