[fixes #755] Correctly calculates mass override (particularly on stages)
This commit is contained in:
parent
5b94bedb5f
commit
bd09354fd3
@ -53,11 +53,9 @@ public class MassCalculation {
|
|||||||
// =========== Instance Functions ========================
|
// =========== Instance Functions ========================
|
||||||
|
|
||||||
public void merge( final MassCalculation other ) {
|
public void merge( final MassCalculation other ) {
|
||||||
if( MIN_MASS < other.getMass()) {
|
// Adjust Center-of-mass
|
||||||
// Adjust Center-of-mass
|
this.addMass( other.getCM() );
|
||||||
this.addMass( other.getCM() );
|
this.bodies.addAll( other.bodies );
|
||||||
this.bodies.addAll( other.bodies );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addInertia( final RigidBody data ) {
|
public void addInertia( final RigidBody data ) {
|
||||||
@ -320,25 +318,11 @@ public class MassCalculation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( MIN_MASS < children.getMass() ) {
|
this.merge( children );
|
||||||
this.merge( children );
|
|
||||||
// // vvv DEBUG
|
|
||||||
// System.err.println(String.format( "%s....assembly mass (incl/children): %s", prefix, this.toCMDebug()));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.config.isComponentActive(component) ){
|
if (this.config.isComponentActive(component) ){
|
||||||
Coordinate compCM = component.getComponentCG();
|
Coordinate compCM = component.getComponentCG();
|
||||||
|
|
||||||
if (!component.getOverrideSubcomponents()) {
|
|
||||||
if (component.isMassOverridden()) {
|
|
||||||
compCM = compCM.setWeight(MathUtil.max(component.getOverrideMass(), MIN_MASS));
|
|
||||||
// // vvv DEBUG
|
|
||||||
// System.err.println(String.format( "%s....mass overridden to: %s", prefix, compCM.toPreciseString()));
|
|
||||||
}
|
|
||||||
if (component.isCGOverridden())
|
|
||||||
compCM = compCM.setXYZ(component.getOverrideCG());
|
|
||||||
}
|
|
||||||
|
|
||||||
// mass data for *this component only* in the rocket-frame
|
// mass data for *this component only* in the rocket-frame
|
||||||
compCM = parentTransform.transform( compCM.add(component.getPosition()) );
|
compCM = parentTransform.transform( compCM.add(component.getPosition()) );
|
||||||
if (component.getOverrideSubcomponents()) {
|
if (component.getOverrideSubcomponents()) {
|
||||||
@ -351,18 +335,24 @@ public class MassCalculation {
|
|||||||
if (component.isCGOverridden()) {
|
if (component.isCGOverridden()) {
|
||||||
this.setCM( this.getCM().setX( compCM.x + component.getOverrideCGX()));
|
this.setCM( this.getCM().setX( compCM.x + component.getOverrideCGX()));
|
||||||
}
|
}
|
||||||
|
}else {
|
||||||
|
if (component.isMassOverridden()) {
|
||||||
|
compCM = compCM.setWeight(MathUtil.max(component.getOverrideMass(), MIN_MASS));
|
||||||
|
}
|
||||||
|
if (component.isCGOverridden()) {
|
||||||
|
compCM = compCM.setXYZ(component.getOverrideCG());
|
||||||
|
}
|
||||||
|
this.addMass( compCM );
|
||||||
}
|
}
|
||||||
this.addMass( compCM );
|
|
||||||
|
|
||||||
if(null != analysisMap){
|
if(null != analysisMap){
|
||||||
|
final CMAnalysisEntry entry = analysisMap.get(component.hashCode());
|
||||||
if( component instanceof ComponentAssembly) {
|
if( component instanceof ComponentAssembly) {
|
||||||
// For ComponentAssemblies, record the _assembly_ information
|
// For ComponentAssemblies, record the _assembly_ information
|
||||||
CMAnalysisEntry entry = analysisMap.get(component.hashCode());
|
|
||||||
entry.updateEachMass(children.getMass() / component.getInstanceCount());
|
entry.updateEachMass(children.getMass() / component.getInstanceCount());
|
||||||
entry.updateAverageCM(this.centerOfMass);
|
entry.updateAverageCM(this.centerOfMass);
|
||||||
}else{
|
}else{
|
||||||
// For actual components, record the mass of the component, and disregard children
|
// For actual components, record the mass of the component, and disregard children
|
||||||
CMAnalysisEntry entry = analysisMap.get(component.hashCode());
|
|
||||||
entry.updateEachMass(compCM.weight);
|
entry.updateEachMass(compCM.weight);
|
||||||
entry.updateAverageCM(compCM);
|
entry.updateAverageCM(compCM);
|
||||||
}
|
}
|
||||||
|
@ -160,7 +160,7 @@ public class MassCalculatorTest extends BaseTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testStageOverride() {
|
public void testStageCMxOverride() {
|
||||||
final Rocket rocket = TestRockets.makeSimple2Stage();
|
final Rocket rocket = TestRockets.makeSimple2Stage();
|
||||||
final AxialStage sustainerStage = (AxialStage) rocket.getChild(0);
|
final AxialStage sustainerStage = (AxialStage) rocket.getChild(0);
|
||||||
final AxialStage boosterStage = (AxialStage) rocket.getChild(1);
|
final AxialStage boosterStage = (AxialStage) rocket.getChild(1);
|
||||||
@ -181,28 +181,85 @@ public class MassCalculatorTest extends BaseTestCase {
|
|||||||
|
|
||||||
final double actualRocketDryMass = actualStructure.cm.weight;
|
final double actualRocketDryMass = actualStructure.cm.weight;
|
||||||
final double expRocketDryMass = 0.0081178754;
|
final double expRocketDryMass = 0.0081178754;
|
||||||
assertEquals(" Alpha III Empty Mass is incorrect: ", expRocketDryMass, actualRocketDryMass, EPSILON);
|
assertEquals(expRocketDryMass, actualRocketDryMass, EPSILON);
|
||||||
|
|
||||||
final Coordinate actualRocketDryCM = actualStructure.cm;
|
final Coordinate actualRocketDryCM = actualStructure.cm;
|
||||||
final double expCMx = 0.10;
|
final double expCMx = 0.10;
|
||||||
assertEquals("Simple Rocket CM.x is incorrect: ", expCMx, actualRocketDryCM.x, EPSILON);
|
assertEquals(expCMx, actualRocketDryCM.x, EPSILON);
|
||||||
}
|
}
|
||||||
|
|
||||||
boosterStage.setOverrideSubcomponents(true);
|
boosterStage.setOverrideSubcomponents(true);
|
||||||
boosterStage.setCGOverridden(true);
|
boosterStage.setCGOverridden(true);
|
||||||
boosterStage.setOverrideCGX(0.0);
|
boosterStage.setOverrideCGX(0.0);
|
||||||
|
|
||||||
|
{ // [1] test Rocket CM, before:
|
||||||
|
final RigidBody actualStructure = MassCalculator.calculateStructure(config);
|
||||||
|
|
||||||
|
final double actualRocketDryMass = actualStructure.cm.weight;
|
||||||
|
final double expRocketDryMass = 0.0081178754;
|
||||||
|
assertEquals(expRocketDryMass, actualRocketDryMass, EPSILON);
|
||||||
|
|
||||||
|
final Coordinate actualRocketDryCM = actualStructure.cm;
|
||||||
|
final double expCMx = 0.075;
|
||||||
|
assertEquals(expCMx, actualRocketDryCM.x, EPSILON);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStageMassOverride() {
|
||||||
|
final Rocket rocket = TestRockets.makeSimple2Stage();
|
||||||
|
final AxialStage sustainerStage = (AxialStage) rocket.getChild(0);
|
||||||
|
final AxialStage boosterStage = (AxialStage) rocket.getChild(1);
|
||||||
|
final FlightConfiguration config = rocket.getSelectedConfiguration();
|
||||||
|
|
||||||
|
{ // [0] verify / document structure
|
||||||
|
final double expMass = 0.0040589377;
|
||||||
|
final BodyTube sustainerBody = (BodyTube) sustainerStage.getChild(0);
|
||||||
|
assertEquals(0.0, sustainerBody.getPosition().x, EPSILON);
|
||||||
|
assertEquals(0.1, sustainerBody.getLength(), EPSILON);
|
||||||
|
assertEquals(expMass, sustainerBody.getMass(), EPSILON);
|
||||||
|
|
||||||
|
final BodyTube boosterBody = (BodyTube) boosterStage.getChild(0);
|
||||||
|
assertEquals(0.10, boosterBody.getComponentLocations()[0].x, EPSILON);
|
||||||
|
assertEquals(0.10, boosterBody.getLength(), EPSILON);
|
||||||
|
assertEquals(expMass, sustainerBody.getMass(), EPSILON);
|
||||||
|
}
|
||||||
|
|
||||||
{ // [1] test Rocket CM, before:
|
{ // [1] test Rocket CM, before:
|
||||||
final RigidBody actualStructure = MassCalculator.calculateStructure(config);
|
final RigidBody actualStructure = MassCalculator.calculateStructure(config);
|
||||||
|
|
||||||
final double actualRocketDryMass = actualStructure.cm.weight;
|
final double actualRocketDryMass = actualStructure.cm.weight;
|
||||||
final double expRocketDryMass = 0.0081178754;
|
final double expRocketDryMass = 0.0081178754;
|
||||||
assertEquals(" Alpha III Empty Mass is incorrect: ", expRocketDryMass, actualRocketDryMass, EPSILON);
|
assertEquals(expRocketDryMass, actualRocketDryMass, EPSILON);
|
||||||
|
|
||||||
final Coordinate actualRocketDryCM = actualStructure.cm;
|
final Coordinate actualRocketDryCM = actualStructure.cm;
|
||||||
final double expCMx = 0.075;
|
final double expCMx = 0.10;
|
||||||
assertEquals("Simple Rocket CM.x is incorrect: ", expCMx, actualRocketDryCM.x, EPSILON);
|
assertEquals(expCMx, actualRocketDryCM.x, EPSILON);
|
||||||
|
}
|
||||||
|
|
||||||
|
final BodyTube boosterBody = (BodyTube) boosterStage.getChild(0);
|
||||||
|
final double bodyMass = boosterBody.getMass();
|
||||||
|
assertEquals(0.0040589377, bodyMass, EPSILON);
|
||||||
|
|
||||||
|
boosterStage.setOverrideSubcomponents(true);
|
||||||
|
boosterStage.setMassOverridden(true);
|
||||||
|
boosterStage.setOverrideMass(bodyMass);
|
||||||
|
|
||||||
|
boosterBody.setOverrideSubcomponents(false);
|
||||||
|
boosterBody.setMassOverridden(true);
|
||||||
|
boosterBody.setOverrideMass(0.0);
|
||||||
|
|
||||||
|
{ // [1] test Rocket CM, before:
|
||||||
|
final RigidBody actualStructure = MassCalculator.calculateStructure(config);
|
||||||
|
|
||||||
|
final double actualRocketDryMass = actualStructure.cm.weight;
|
||||||
|
final double expRocketDryMass = 0.0081178754;
|
||||||
|
assertEquals(expRocketDryMass, actualRocketDryMass, EPSILON);
|
||||||
|
|
||||||
|
final Coordinate actualRocketDryCM = actualStructure.cm;
|
||||||
|
final double expCMx = 0.10;
|
||||||
|
assertEquals(expCMx, actualRocketDryCM.x, EPSILON);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -869,7 +926,7 @@ public class MassCalculatorTest extends BaseTestCase {
|
|||||||
double calcTotalMass = structure.getMass();
|
double calcTotalMass = structure.getMass();
|
||||||
assertEquals(" Booster Launch Mass is incorrect: ", expMass, calcTotalMass, EPSILON);
|
assertEquals(" Booster Launch Mass is incorrect: ", expMass, calcTotalMass, EPSILON);
|
||||||
|
|
||||||
final double expCMx = 1.1191303646;
|
final double expCMx = 0.76762318688;
|
||||||
Coordinate expCM = new Coordinate(expCMx, 0, 0, expMass);
|
Coordinate expCM = new Coordinate(expCMx, 0, 0, expMass);
|
||||||
assertEquals(" Booster Launch CM.x is incorrect: ", expCM.x, structure.getCM().x, EPSILON);
|
assertEquals(" Booster Launch CM.x is incorrect: ", expCM.x, structure.getCM().x, EPSILON);
|
||||||
assertEquals(" Booster Launch CM.y is incorrect: ", expCM.y, structure.getCM().y, EPSILON);
|
assertEquals(" Booster Launch CM.y is incorrect: ", expCM.y, structure.getCM().y, EPSILON);
|
||||||
@ -877,11 +934,11 @@ public class MassCalculatorTest extends BaseTestCase {
|
|||||||
assertEquals(" Booster Launch CM is incorrect: ", expCM, structure.getCM());
|
assertEquals(" Booster Launch CM is incorrect: ", expCM, structure.getCM());
|
||||||
|
|
||||||
// Validate MOI
|
// Validate MOI
|
||||||
final double expMOI_axial = 0.005885793421431532;
|
final double expMOI_axial = 0.0038576236;
|
||||||
double boosterMOI_xx = structure.getRotationalInertia();
|
double boosterMOI_xx = structure.getRotationalInertia();
|
||||||
assertEquals(" Booster x-axis MOI is incorrect: ", expMOI_axial, boosterMOI_xx, EPSILON);
|
assertEquals(" Booster x-axis MOI is incorrect: ", expMOI_axial, boosterMOI_xx, EPSILON);
|
||||||
|
|
||||||
final double expMOI_tr = 0.04098909591063;
|
final double expMOI_tr = 0.123258667252;
|
||||||
double boosterMOI_tr = structure.getLongitudinalInertia();
|
double boosterMOI_tr = structure.getLongitudinalInertia();
|
||||||
assertEquals(" Booster transverse MOI is incorrect: ", expMOI_tr, boosterMOI_tr, EPSILON);
|
assertEquals(" Booster transverse MOI is incorrect: ", expMOI_tr, boosterMOI_tr, EPSILON);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user