Merge pull request #688 from JoePfeiffer/fin-moi

fixes Fin MOI calculations
This commit is contained in:
Joe Pfeiffer 2020-07-11 11:33:48 -06:00 committed by GitHub
commit 056c6b2b39
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 61 additions and 39 deletions

View File

@ -638,17 +638,18 @@ public abstract class FinSet extends ExternalComponent implements RingInstanceab
}
/*
* Return an approximation of the longitudinal unitary inertia of the fin set.
* Return an approximation of the longitudinal unitary moment of inertia
*
* The process is the following:
*
* 1. Approximate the fin with a rectangular fin
* 1. Approximate a fin with a rectangular thin plate
*
* 2. The inertia of one fin is taken as the average of the moments of inertia
* through its center perpendicular to the plane, and the inertia through
* its center parallel to the plane
* 2. The unitary moment of inertia of one fin is taken as the average
* of the unitary moments of inertia through its center perpendicular
* to the plane (Izz/M), and through its center parallel to the plane (Iyy/M)
*
* 3. If there are multiple fins, the inertia is shifted to the center of the fin
* set and multiplied by the number of fins.
* 3. If there are multiple fins, the inertia is shifted to the center of the
* FinSet using the Parallel Axis Theorem
*/
@Override
public double getLongitudinalUnitInertia() {
@ -661,23 +662,34 @@ public abstract class FinSet extends ExternalComponent implements RingInstanceab
double w = getLength();
double h = getSpan();
double w2, h2;
if (MathUtil.equals(w * h, 0)) {
// If either h or w is 0, we punt and treat the fin as square
if (MathUtil.equals(h * w, 0)) {
w2 = singlePlanformArea;
h2 = singlePlanformArea;
} else {
w2 = w * singlePlanformArea / h;
h2 = h * singlePlanformArea / w;
}
double inertia = (h2 + 2 * w2) / 24;
// Iyy = h * w^3 / 12, so Iyy/M = w^2 / 12
// Izz = h * w * (h^2 + w^2) / 12, so Izz/M = (h^2 + w^2) / 12
// (Iyy / M + Izz / M) / 2 = (h^2 + 2 * w^2)/24
final double inertia = (h2 + 2 * w2) / 24;
System.out.println("component " + this);
System.out.println("finCount " + finCount);
System.out.println("inertia " + inertia);
if (finCount == 1)
return inertia;
final double rFront = this.getFinFront().y;
return finCount * (inertia + MathUtil.pow2(MathUtil.safeSqrt(h2) + rFront));
// Move axis to center of FinSet. We need to apply the Parallel Axis Theorem
// to Izz, but not to Iyy (as the displacement as we move to the new axis
// is along Y). Since our moment of inertia is the average of Iyy and Izz,
// this is accomplished by just weighting the transformation from the theorem
// by 1/2
return inertia + MathUtil.pow2(MathUtil.safeSqrt(h2) / 2 + getBodyRadius()) / 2;
}
@ -685,11 +697,13 @@ public abstract class FinSet extends ExternalComponent implements RingInstanceab
* Return an approximation of the rotational unitary inertia of the fin set.
* The process is the following:
*
* 1. Approximate the fin with a rectangular fin and calculate the inertia of the
* rectangular approximate
* 1. Approximate the fin with a rectangular thin plate
*
* 2. calculate the unitary rotational inertia (Ixx/M) of the
* rectangular approximation, about the center of the approximated fin.
*
* 2. If there are multiple fins, shift the inertia center to the fin set center
* and multiply with the number of fins.
* 2. If there are multiple fins, shift the inertia axis to the center
* of the Finset.
*/
@Override
public double getRotationalUnitInertia() {
@ -698,18 +712,26 @@ public abstract class FinSet extends ExternalComponent implements RingInstanceab
}
// Approximate fin with a rectangular fin
// h2 is square of fin height
double w = getLength();
double h = getSpan();
double h2;
// If either h or w is 0, punt and treat it as a square fin
if (MathUtil.equals(w * h, 0)) {
h = MathUtil.safeSqrt(singlePlanformArea);
h2 = singlePlanformArea;
} else {
h = MathUtil.safeSqrt(h * singlePlanformArea/ w);
h2 = h * singlePlanformArea / w;
}
final double rFront = this.getFinFront().y;
// Ixx = w * h^3 / 12, so Ixx / M = h^2 / 12
final double inertia = h2 / 12;
return finCount * (h * h / 12 + MathUtil.pow2(h / 2 + rFront));
if (finCount == 1)
return inertia;
// Move axis to center of FinSet using Parallel Axis Theorem
return inertia + MathUtil.pow2(MathUtil.safeSqrt(h2) / 2 + getBodyRadius());
}

View File

@ -45,8 +45,8 @@ public class MassCalculatorTest extends BaseTestCase {
assertEquals("Simple Rocket CM is incorrect: ", expCM, actualRocketDryCM);
double expMOIrot = 5.394503232245634E-5;
double expMOIlong = 3.029224106873237E-4;
double expMOIrot = 1.8763734635622462E-5;
double expMOIlong = 1.7808603404853048E-4;
double actualMOIrot = actualStructure.getRotationalInertia();
double actualMOIlong = actualStructure.getLongitudinalInertia();
@ -442,10 +442,10 @@ public class MassCalculatorTest extends BaseTestCase {
assertEquals(cc.getName() + " Longitudinal MOI calculated incorrectly: ", expInertia, compInertia, EPSILON);
final FinSet boosterFins = (FinSet) boosters.getChild(1).getChild(1);
expInertia = 0.00413298;
expInertia = 0.001377661595723823;
compInertia = boosterFins.getRotationalInertia();
assertEquals(boosterFins.getName() + " Rotational MOI calculated incorrectly: ", expInertia, compInertia, EPSILON);
expInertia = 0.01215133;
expInertia = 0.0016272177418619116;
compInertia = boosterFins.getLongitudinalInertia();
assertEquals(boosterFins.getName() + " Longitudinal MOI calculated incorrectly: ", expInertia, compInertia, EPSILON);
@ -668,11 +668,11 @@ public class MassCalculatorTest extends BaseTestCase {
RigidBody spent = MassCalculator.calculateBurnout(config);
double expMOIRotational = 0.01593066;
double expMOIRotational = 0.010420016485489425;
double boosterMOIRotational = spent.getRotationalInertia();
assertEquals(" Booster x-axis MOI is incorrect: ", expMOIRotational, boosterMOIRotational, EPSILON);
double expMOI_tr = 0.08018692435877221;
double expMOI_tr = 0.05913869705973017;
double boosterMOI_tr = spent.getLongitudinalInertia();
assertEquals(" Booster transverse MOI is incorrect: ", expMOI_tr, boosterMOI_tr, EPSILON);
}
@ -688,9 +688,9 @@ public class MassCalculatorTest extends BaseTestCase {
RigidBody launchData = MassCalculator.calculateLaunch(config);
final double expIxx = 0.01899116;
final double expIxx = 0.013480523485489424;
final double actIxx = launchData.getRotationalInertia();
final double expIyy = 0.08637653;
final double expIyy = 0.06532830810235105;
final double actIyy = launchData.getLongitudinalInertia();
assertEquals(" Booster x-axis MOI is incorrect: ", expIxx, actIxx, EPSILON);
@ -731,11 +731,11 @@ public class MassCalculatorTest extends BaseTestCase {
assertEquals(" Booster Launch CM is incorrect: ", expCM, boosterSetCM);
// Validate MOI
double expMOI_axial = 0.01261079;
double expMOI_axial = 0.007100144485489424;
double boosterMOI_xx = burnout.getRotationalInertia();
assertEquals(" Booster x-axis MOI is incorrect: ", expMOI_axial, boosterMOI_xx, EPSILON);
double expMOI_tr = 16.046826943504207;
double expMOI_tr = 16.025778716205167;
double boosterMOI_tr = burnout.getLongitudinalInertia();
assertEquals(" Booster transverse MOI is incorrect: ", expMOI_tr, boosterMOI_tr, EPSILON);
}
@ -785,11 +785,11 @@ public class MassCalculatorTest extends BaseTestCase {
assertEquals(" Booster Launch CM is incorrect: ", expCM, boosterCM);
// Validate MOI
double expMOI_axial = 0.031538609;
double expMOI_axial = 0.026027963480146098;
double boosterMOI_xx = boosterData.getRotationalInertia();
assertEquals(" Booster x-axis MOI is incorrect: ", expMOI_axial, boosterMOI_xx, EPSILON);
double expMOI_tr = 0.37548843;
double expMOI_tr = 0.35444021118310487;
double boosterMOI_tr = boosterData.getLongitudinalInertia();
assertEquals(" Booster transverse MOI is incorrect: ", expMOI_tr, boosterMOI_tr, EPSILON);
}
@ -798,7 +798,7 @@ public class MassCalculatorTest extends BaseTestCase {
public void testFalcon9HeavyComponentCMxOverride() {
Rocket rocket = TestRockets.makeFalcon9Heavy();
rocket.setName("Falcon9Heavy." + Thread.currentThread().getStackTrace()[1].getMethodName());
FlightConfiguration config = rocket.getEmptyConfiguration();
rocket.setSelectedConfiguration(config.getId());
@ -832,11 +832,11 @@ public class MassCalculatorTest extends BaseTestCase {
assertEquals(" Booster Launch CM is incorrect: ", expCM, structure.getCM());
// Validate MOI
final double expMOI_axial = 0.012610790;
final double expMOI_axial = 0.007100144485489424;
double boosterMOI_xx = structure.getRotationalInertia();
assertEquals(" Booster x-axis MOI is incorrect: ", expMOI_axial, boosterMOI_xx, EPSILON);
final double expMOI_tr = 0.063491225;
final double expMOI_tr = 0.04244299775219597;
double boosterMOI_tr = structure.getLongitudinalInertia();
assertEquals(" Booster transverse MOI is incorrect: ", expMOI_tr, boosterMOI_tr, EPSILON);
}