Merge pull request #281 from teyrana/massfix
Cleaning up the code from: PR #273
This commit is contained in:
commit
b158485a2d
@ -14,28 +14,15 @@ import net.sf.openrocket.rocketcomponent.ParallelStage;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
import net.sf.openrocket.simulation.MotorClusterState;
|
||||
import net.sf.openrocket.simulation.SimulationStatus;
|
||||
import net.sf.openrocket.util.BugException;
|
||||
import net.sf.openrocket.util.Coordinate;
|
||||
import net.sf.openrocket.util.MathUtil;
|
||||
import net.sf.openrocket.util.Monitorable;
|
||||
|
||||
public class MassCalculator implements Monitorable {
|
||||
|
||||
// public static enum MassCalcType {
|
||||
// NO_MOTORS( Double.NaN),
|
||||
// LAUNCH_MASS(0.),
|
||||
// BURNOUT_MASS(Double.MAX_VALUE);
|
||||
//
|
||||
// public final double motorTime;
|
||||
//
|
||||
// MassCalcType( final double _motorTime ){
|
||||
// this.motorTime = _motorTime; }
|
||||
//
|
||||
// };
|
||||
|
||||
//private static final Logger log = LoggerFactory.getLogger(MassCalculator.class);
|
||||
|
||||
public boolean debug=false;
|
||||
|
||||
public static final double MIN_MASS = 0.001 * MathUtil.EPSILON;
|
||||
|
||||
private int rocketMassModID = -1;
|
||||
@ -90,15 +77,6 @@ public class MassCalculator implements Monitorable {
|
||||
protected MassData calculatePropellantMassData( final FlightConfiguration config ){
|
||||
MassData allPropellantData = MassData.ZERO_DATA;
|
||||
|
||||
if(debug){// vvvv DEVEL vvvv
|
||||
System.err.println("====== ====== calculatePropellantMassData( config: "+config.toDebug()+" ) ====== ====== ====== ====== ====== ======");
|
||||
//String massFormat = " [%2s]: %-16s %6s x %6s = %6s += %6s @ (%s, %s, %s )";
|
||||
//System.err.println(String.format(massFormat, " #", "<Designation>","Mass","Count","Config","Sum", "x","y","z"));
|
||||
String inertiaFormat = " [%2s](%2s): %-16s %6s %6s";
|
||||
System.err.println(String.format(inertiaFormat, " #","ct", "<Designation>","I_ax","I_tr"));
|
||||
}// ^^^^ DEVEL ^^^^
|
||||
|
||||
|
||||
Collection<MotorConfiguration> activeMotorList = config.getActiveMotors();
|
||||
for (MotorConfiguration mtrConfig : activeMotorList ) {
|
||||
MassData curMotorConfigData = calculateClusterPropellantData( mtrConfig, Motor.PSEUDO_TIME_LAUNCH );
|
||||
@ -117,15 +95,6 @@ public class MassCalculator implements Monitorable {
|
||||
protected MassData calculatePropellantMassData( final SimulationStatus status ){
|
||||
MassData allPropellantData = MassData.ZERO_DATA;
|
||||
|
||||
if(debug){// vvvv DEVEL vvvv
|
||||
System.err.println("====== ====== calculatePropellantMassData( status.config: "+status.getConfiguration().toDebug()+" ) ====== ====== ====== ====== ====== ======");
|
||||
//String massFormat = " [%2s]: %-16s %6s x %6s = %6s += %6s @ (%s, %s, %s )";
|
||||
//System.err.println(String.format(massFormat, " #", "<Designation>","Mass","Count","Config","Sum", "x","y","z"));
|
||||
String inertiaFormat = " [%2s](%2s): %-16s %6s %6s";
|
||||
System.err.println(String.format(inertiaFormat, " #","ct", "<Designation>","I_ax","I_tr"));
|
||||
}// ^^^^ DEVEL ^^^^
|
||||
|
||||
|
||||
Collection<MotorClusterState> motorStates = status.getActiveMotors();
|
||||
for (MotorClusterState state: motorStates) {
|
||||
final double motorTime = state.getMotorTime( status.getSimulationTime() );
|
||||
@ -158,11 +127,6 @@ public class MassCalculator implements Monitorable {
|
||||
final double unitLongitudinalInertiaEach = mtrConfig.getUnitLongitudinalInertia();
|
||||
double Ir=unitRotationalInertiaEach*instanceCount*propMassEach;
|
||||
double It=unitLongitudinalInertiaEach*instanceCount*propMassEach;
|
||||
|
||||
if(debug){
|
||||
System.err.println(String.format(" Motor: %-16s ( %2dx): m: %6.4f l: %6.4f od: %6.4f I_xx_u: %6.4g I_yy_u: %6.4g",
|
||||
mtr.getDesignation(), instanceCount, propMassEach, mtr.getLength(), mtr.getDiameter(), unitRotationalInertiaEach, unitLongitudinalInertiaEach));
|
||||
}// ^^^^ DEVEL ^^^^
|
||||
|
||||
if( 1 < instanceCount ){
|
||||
// if not on rocket centerline, then add an offset factor, according to the parallel axis theorem:
|
||||
@ -171,10 +135,7 @@ public class MassCalculator implements Monitorable {
|
||||
Ir += propMassEach*Math.pow( distance, 2);
|
||||
}
|
||||
}
|
||||
if(debug){
|
||||
System.err.println(String.format(" :cluster: m: %6.4f Ixx: %6.4g Iyy: %6.4g", curClusterCM.weight, Ir, It));
|
||||
}
|
||||
|
||||
|
||||
return new MassData( curClusterCM, Ir, It);
|
||||
}
|
||||
|
||||
@ -187,29 +148,10 @@ public class MassCalculator implements Monitorable {
|
||||
* @return the CG of the configuration
|
||||
*/
|
||||
protected MassData calculateBurnoutMassData( final FlightConfiguration config) {
|
||||
if(debug){// vvvv DEVEL vvvv
|
||||
//String massFormat = " [%2s]: %-16s %6s x %6s = %6s += %6s @ (%s, %s, %s )";
|
||||
String inertiaFormat = " [%2s](%2s): %-16s %6s %6s";
|
||||
System.err.println("====== ====== getMotorMassData( config:"+config.toDebug()+" ) ====== ====== ====== ====== ====== ======");
|
||||
//System.err.println(String.format(massFormat, " #", "<Designation>","Mass","Count","Config","Sum", "x","y","z"));
|
||||
System.err.println(String.format(inertiaFormat, " #","ct", "<Designation>","I_ax","I_tr"));
|
||||
}// ^^^^ DEVEL ^^^^
|
||||
|
||||
MassData exceptMotorsMassData = calculateStageData( config);
|
||||
|
||||
if(debug){// vvvv DEVEL vvvv
|
||||
System.err.println(" exc motors stage data: "+exceptMotorsMassData );
|
||||
System.err.println(" ====== ====== ^^^^ stage data ^^^^ ====== ======\n");
|
||||
System.err.println(" ====== ====== vvvv motor spent mass data vvvv ====== ======\n");
|
||||
}// ^^^^ DEVEL ^^^^
|
||||
|
||||
MassData motorMassData = calculateMotorBurnoutMassData( config);
|
||||
|
||||
if(debug){ // vvvv DEVEL vvvv
|
||||
System.err.println(" exc motors stage data: "+motorMassData);
|
||||
System.err.println(" ====== ====== ^^^^ motor spent mass data ^^^^ ====== ======\n\n");
|
||||
} // ^^^^ DEVEL ^^^^
|
||||
|
||||
return exceptMotorsMassData.add( motorMassData );
|
||||
}
|
||||
|
||||
@ -240,15 +182,6 @@ public class MassCalculator implements Monitorable {
|
||||
* @return the MassData struct of the motors at burnout
|
||||
*/
|
||||
private MassData calculateMotorBurnoutMassData(FlightConfiguration config) {
|
||||
// // vvvv DEVEL vvvv
|
||||
// //String massFormat = " [%2s]: %-16s %6s x %6s = %6s += %6s @ (%s, %s, %s )";
|
||||
// String inertiaFormat = " [%2s](%2s): %-16s %6s %6s";
|
||||
// if( debug){
|
||||
// System.err.println("====== ====== getMotorMassData( config:"+config.toDebug()+", type: "+type.name()+") ====== ====== ====== ====== ====== ======");
|
||||
// //System.err.println(String.format(massFormat, " #", "<Designation>","Mass","Count","Config","Sum", "x","y","z"));
|
||||
// System.err.println(String.format(inertiaFormat, " #","ct", "<Designation>","I_ax","I_tr"));
|
||||
// }
|
||||
// // ^^^^ DEVEL ^^^^
|
||||
|
||||
MassData allMotorData = MassData.ZERO_DATA;
|
||||
|
||||
@ -273,31 +206,15 @@ public class MassCalculator implements Monitorable {
|
||||
final double unitRotationalInertia = mtrConfig.getUnitRotationalInertia();
|
||||
final double unitLongitudinalInertia = mtrConfig.getUnitLongitudinalInertia();
|
||||
|
||||
if(debug){// vv DEBUG
|
||||
System.err.println(String.format(" Processing f/mount: %s [%8s] (ct: %d)(w/spent mass = %g)", mtrConfig.getMount(), mtr.getDesignation(), instanceCount, mtr.getBurnoutMass()));
|
||||
double eachIxx = unitRotationalInertia*burnoutMassEach;
|
||||
double eachIyy = unitLongitudinalInertia*burnoutMassEach;
|
||||
System.err.println(String.format("(MOI: [%8g, %8g])", eachIxx, eachIyy));
|
||||
} // ^^ DEBUG
|
||||
|
||||
double Ir=(unitRotationalInertia*burnoutMassEach)*instanceCount;
|
||||
double It=(unitLongitudinalInertia*burnoutMassEach)*instanceCount;
|
||||
if( 1 < instanceCount ){
|
||||
if(debug){// vv DEBUG
|
||||
System.err.println(String.format(" Instanced. %d motors in a %s", instanceCount, mount.getClusterConfiguration().getXMLName()));
|
||||
System.err.println(String.format(" I_long: %6g * %6g * %d = %6g ", unitLongitudinalInertia, burnoutMassEach, instanceCount, It));
|
||||
System.err.println(String.format(" I_rot_base: %6g * %6g * %d = %6g ", unitRotationalInertia, burnoutMassEach, instanceCount, Ir));
|
||||
} // ^^ DEBUG
|
||||
|
||||
for( Coordinate coord : locations ){
|
||||
double distance_squared = ((coord.y*coord.y) + (coord.z*coord.z));
|
||||
double instance_correction = burnoutMassEach*distance_squared;
|
||||
|
||||
Ir += instance_correction;
|
||||
}
|
||||
if(debug){// vv DEBUG
|
||||
System.err.println(String.format(" I_rot: %6g ", Ir));
|
||||
} // ^^ DEBUG
|
||||
}
|
||||
|
||||
MassData configData = new MassData( clusterCM, Ir, It);
|
||||
@ -368,6 +285,15 @@ public class MassCalculator implements Monitorable {
|
||||
Coordinate compCM = component.getComponentCG();
|
||||
double compIx = component.getRotationalUnitInertia() * compCM.weight;
|
||||
double compIt = component.getLongitudinalUnitInertia() * compCM.weight;
|
||||
if( 0 > compCM.weight ){
|
||||
throw new BugException(" computed a negative rotational inertia value.");
|
||||
}
|
||||
if( 0 > compIx ){
|
||||
throw new BugException(" computed a negative rotational inertia value.");
|
||||
}
|
||||
if( 0 > compIt ){
|
||||
throw new BugException(" computed a negative longitudinal inertia value.");
|
||||
}
|
||||
|
||||
if (!component.getOverrideSubcomponents()) {
|
||||
if (component.isMassOverridden())
|
||||
@ -379,15 +305,6 @@ public class MassCalculator implements Monitorable {
|
||||
// default if not instanced (instance count == 1)
|
||||
MassData assemblyData = new MassData( compCM, compIx, compIt);
|
||||
|
||||
if( debug && ( MIN_MASS < compCM.weight)){
|
||||
System.err.println(String.format("%-32s: %s ",indent+"ea["+ component.getName()+"]", compCM ));
|
||||
if( component.isMassOverridden() && component.isMassOverridden() && component.getOverrideSubcomponents()){
|
||||
System.err.println(indent+" ?["+ component.isMassOverridden()+"]["+
|
||||
component.isMassOverridden()+"]["+
|
||||
component.getOverrideSubcomponents()+"]");
|
||||
}
|
||||
}
|
||||
|
||||
MassData childrenData = MassData.ZERO_DATA;
|
||||
// Combine data for subcomponents
|
||||
for (RocketComponent child : component.getChildren()) {
|
||||
@ -405,10 +322,6 @@ public class MassCalculator implements Monitorable {
|
||||
|
||||
// if instanced, adjust children's data too.
|
||||
if ( 1 < component.getInstanceCount() ){
|
||||
if(debug){// vv DEBUG
|
||||
System.err.println(String.format("%s Found instanceable with %d children: %s (t= %s)",
|
||||
indent, component.getInstanceCount(), component.getName(), component.getClass().getSimpleName() ));
|
||||
}// ^^ DEBUG
|
||||
|
||||
final double curIxx = childrenData.getIxx(); // MOI about x-axis
|
||||
final double curIyy = childrenData.getIyy(); // MOI about y axis
|
||||
@ -427,11 +340,6 @@ public class MassCalculator implements Monitorable {
|
||||
}
|
||||
|
||||
assemblyData = instAccumData;
|
||||
|
||||
if( debug && (MIN_MASS < compCM.weight)){
|
||||
System.err.println(String.format("%-32s: %s ", indent+"x"+component.getInstanceCount()+"["+component.getName()+"][asbly]", assemblyData.toDebug()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -443,11 +351,7 @@ public class MassCalculator implements Monitorable {
|
||||
}
|
||||
|
||||
// Override total data
|
||||
if (component.getOverrideSubcomponents()) {
|
||||
if(debug){// vv DEBUG
|
||||
System.err.println(String.format("%-32s: %s ", indent+"vv["+component.getName()+"][asbly]", assemblyData.toDebug()));
|
||||
}// ^^ DEBUG
|
||||
|
||||
if (component.getOverrideSubcomponents()) {
|
||||
if (component.isMassOverridden()) {
|
||||
double oldMass = assemblyData.getMass();
|
||||
double newMass = MathUtil.max(component.getOverrideMass(), MIN_MASS);
|
||||
@ -463,30 +367,19 @@ public class MassCalculator implements Monitorable {
|
||||
double oldx = assemblyData.getCM().x;
|
||||
double newx = component.getOverrideCGX();
|
||||
Coordinate delta = new Coordinate(newx-oldx, 0, 0);
|
||||
if(debug){// vv DEBUG
|
||||
System.err.println(String.format("%-32s: x: %g => %g (%g)", indent+" 88", oldx, newx, delta.x));
|
||||
}// ^^ DEBUG
|
||||
|
||||
assemblyData = assemblyData.move( delta );
|
||||
}
|
||||
}
|
||||
|
||||
if(debug){// vv DEBUG
|
||||
System.err.println(String.format("%-32s: %s ", indent+"<<["+component.getName()+"][asbly]", assemblyData.toDebug()));
|
||||
}// ^^ DEBUG
|
||||
|
||||
return assemblyData;
|
||||
}
|
||||
|
||||
|
||||
/// nooooot quite done, yet.
|
||||
public void revalidateCache( final SimulationStatus status ){
|
||||
//if( ... check what? the config may not have changed, but if the time has, we want to recalculate the cache!
|
||||
rocketSpentMassCache = calculateBurnoutMassData( status.getConfiguration() );
|
||||
rocketSpentMassCache = calculateBurnoutMassData( status.getConfiguration() );
|
||||
|
||||
propellantMassCache = calculatePropellantMassData( status);
|
||||
|
||||
//}
|
||||
propellantMassCache = calculatePropellantMassData( status);
|
||||
}
|
||||
|
||||
public void revalidateCache( final FlightConfiguration config ){
|
||||
@ -511,7 +404,6 @@ public class MassCalculator implements Monitorable {
|
||||
* @param configuration the configuration of the current call
|
||||
*/
|
||||
protected final boolean checkCache(FlightConfiguration configuration) {
|
||||
//System.err.println("?? Checking the cache ... ");
|
||||
if (rocketMassModID != configuration.getRocket().getMassModID() ||
|
||||
rocketTreeModID != configuration.getRocket().getTreeModID()) {
|
||||
rocketMassModID = configuration.getRocket().getMassModID();
|
||||
|
@ -136,23 +136,6 @@ public class MassData {
|
||||
InertiaMatrix combinedMOI = I1_at_3.add(I2_at_3);
|
||||
MassData sumData = new MassData( combinedCM, combinedMOI);
|
||||
|
||||
{ // vvvv DEVEL vvvv
|
||||
// System.err.println(" ?? body1: "+ body1.toDebug() );
|
||||
// System.err.println(" delta 1=>3: "+ delta1);
|
||||
// System.err.println(String.format(" >> 1@3: == [ %g, %g, %g ]",
|
||||
// I1_at_3.xx, I1_at_3.yy, I1_at_3.zz));
|
||||
//
|
||||
// System.err.println(" ?? body2: "+ body2.toDebug() );
|
||||
// System.err.println(" delta 2=>3: "+ delta2);
|
||||
// System.err.println(String.format(" >> 2@3: [ %g, %g, %g ]",
|
||||
// I2_at_3.xx, I2_at_3.yy, I2_at_3.zz));
|
||||
// System.err.println(" ?? asbly3: "+sumData.toDebug()+"\n");
|
||||
|
||||
// InertiaMatrix rev1 = It1.translateInertia(delta1.multiply(-1), body1.getMass());
|
||||
// System.err.println(String.format(" !!XX orig: %s\n", childDataChild.toDebug() ));
|
||||
// System.err.println(String.format("%s!!XX revr: %s\n", indent, reverse.toDebug() ));
|
||||
}
|
||||
|
||||
return sumData;
|
||||
}
|
||||
|
||||
@ -249,11 +232,6 @@ public class MassData {
|
||||
|
||||
MassData newData = new MassData( newCM, this.I_cm);
|
||||
|
||||
{ // DEVEL-DEBUG
|
||||
// System.err.println(" ?? body1: "+ body1.toDebug() );
|
||||
// System.err.println(" delta: "+ delta);
|
||||
// System.err.println(" ?? asbly3: "+newData.toDebug()+"\n");
|
||||
}
|
||||
return newData;
|
||||
}
|
||||
|
||||
|
@ -47,9 +47,6 @@ public class MassCalculatorTest extends BaseTestCase {
|
||||
config.setAllStages();
|
||||
rkt.setName("TestRocket."+Thread.currentThread().getStackTrace()[1].getMethodName());
|
||||
|
||||
// String treeDump = rkt.toDebugTree();
|
||||
// System.err.println( treeDump);
|
||||
|
||||
// Validate Boosters
|
||||
MassCalculator mc = new MassCalculator();
|
||||
// any config will do, beceause the rocket literally has no defined motors.
|
||||
|
@ -64,7 +64,6 @@ public class MassDataTest extends BaseTestCase {
|
||||
|
||||
@Test
|
||||
public void testTwoPointGeneral() {
|
||||
boolean debug=false;
|
||||
double m1 = 2.5;
|
||||
Coordinate r1 = new Coordinate(0,-40, -10, m1);
|
||||
double I1xx=28.7;
|
||||
@ -81,20 +80,8 @@ public class MassDataTest extends BaseTestCase {
|
||||
MassData asbly3 = body1.add(body2);
|
||||
|
||||
Coordinate cm3_expected = r1.average(r2);
|
||||
// System.err.println(" @(1): "+ body1.toDebug());
|
||||
// System.err.println(" @(2): "+ body2.toDebug());
|
||||
// System.err.println(" @(3): "+ asbly3.toDebug());
|
||||
// System.err.println(" Center of Mass: (3) expected: "+ cm3_expected);
|
||||
assertEquals(" Center of Mass calculated incorrectly: ", cm3_expected, asbly3.getCM() );
|
||||
|
||||
|
||||
if(debug){
|
||||
System.err.println(" Body 1: "+ body1.toDebug() );
|
||||
System.err.println(" Body 2: "+ body2.toDebug() );
|
||||
System.err.println(" Body 3: "+ asbly3.toDebug() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
// these are a bit of a hack, and depend upon all the bodies being along the y=0, z=0 line.
|
||||
Coordinate delta13 = asbly3.getCM().sub( r1);
|
||||
Coordinate delta23 = asbly3.getCM().sub( r2);
|
||||
@ -152,10 +139,6 @@ public class MassDataTest extends BaseTestCase {
|
||||
MassData asbly4_indirect = asbly3.add(body5);
|
||||
Coordinate cm4_expected = r1.average(r2).average(r5);
|
||||
|
||||
//System.err.println(" Center of Mass: (3): "+ asbly3.toCMDebug() );
|
||||
//System.err.println(" MOI: (3): "+ asbly3.toIMDebug() );
|
||||
//System.err.println(" Center of Mass: indirect:"+ asbly4_indirect.getCM() );
|
||||
//System.err.println(" Center of Mass: (4) direct: "+ cm4_expected);
|
||||
assertEquals(" Center of Mass calculated incorrectly: ", cm4_expected, new Coordinate( 0, 7.233644859813085, 0, m1+m2+m5 ) );
|
||||
|
||||
// these are a bit of a hack, and depend upon all the bodies being along the y=0, z=0 line.
|
||||
@ -166,21 +149,17 @@ public class MassDataTest extends BaseTestCase {
|
||||
|
||||
double I14zz = I1t + m1*MathUtil.pow2( Math.abs(body1.getCM().y - y4) );
|
||||
double I24zz = I2t + m2*MathUtil.pow2( Math.abs(body2.getCM().y - y4) );
|
||||
// System.err.println(String.format(" I24yy: %8g = %6g + %3g*%g", I24zz, I2t, m2, MathUtil.pow2( Math.abs(body2.getCM().y - y4)) ));
|
||||
// System.err.println(String.format(" : delta y24: %8g = ||%g - %g||", Math.abs(body2.getCM().y - y4), body2.getCM().y, y4 ));
|
||||
double I54zz = I5t + m5*MathUtil.pow2( Math.abs(body5.getCM().y - y4) );
|
||||
|
||||
double I4xx = I14ax+I24ax+I54ax;
|
||||
double I4yy = I1t+I2t+I5t;
|
||||
double I4zz = I14zz+I24zz+I54zz;
|
||||
MassData asbly4_expected = new MassData( cm4_expected, I4xx, I4yy, I4zz);
|
||||
//System.err.println(String.format(" Ixx: direct: %12g", I4xx ));
|
||||
|
||||
assertEquals("x-axis MOI don't match: ", asbly4_indirect.getIxx(), asbly4_expected.getIxx(), EPSILON*10);
|
||||
|
||||
//System.err.println(String.format(" Iyy: direct: %12g", I4yy ));
|
||||
|
||||
assertEquals("y-axis MOI don't match: ", asbly4_indirect.getIyy(), asbly4_expected.getIyy(), EPSILON*10);
|
||||
|
||||
//System.err.println(String.format(" Izz: direct: %12g", I4zz));
|
||||
assertEquals("z-axis MOI don't match: ", asbly4_indirect.getIzz(), asbly4_expected.getIzz(), EPSILON*10);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user