[BugFix] Fixed MassCalculator Unit Tests
- Added debug statements to MassCalculator, enabled by a 'debug' flag - Adjusted values in MassCalculatorTest -- added additional unit test cases - Fixed implementations in MassCalculator - Implemented getPosition() and getX() in MotorConfiguration - added motor to test rocket Estes Alpha 3 in TestRockets
This commit is contained in:
parent
c649292f56
commit
206214e47a
@ -8,9 +8,11 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import net.sf.openrocket.motor.Motor;
|
||||
import net.sf.openrocket.motor.MotorConfiguration;
|
||||
import net.sf.openrocket.motor.ThrustCurveMotor;
|
||||
import net.sf.openrocket.rocketcomponent.AxialStage;
|
||||
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
|
||||
import net.sf.openrocket.rocketcomponent.Instanceable;
|
||||
import net.sf.openrocket.rocketcomponent.MotorMount;
|
||||
import net.sf.openrocket.rocketcomponent.ParallelStage;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
import net.sf.openrocket.util.BugException;
|
||||
@ -61,7 +63,7 @@ public class MassCalculator implements Monitorable {
|
||||
// private Vector< MassData> motorData = new Vector<MassData>();
|
||||
|
||||
// this turns on copious amounts of debug. Recommend leaving this false
|
||||
// until reaching code that causes interesting conditions.
|
||||
// until reaching code that causes troublesome conditions.
|
||||
public boolean debug = false;
|
||||
|
||||
////////////////// Constructors ///////////////////
|
||||
@ -96,11 +98,10 @@ public class MassCalculator implements Monitorable {
|
||||
throw new BugException("method: calculateStageCache(...) is faulty-- returned null data for an active stage: "+stage.getName()+"("+stage.getStageNumber()+")");
|
||||
}
|
||||
dryCM = stageData.cm.average(dryCM);
|
||||
// if( debug){
|
||||
// System.err.println(" stageData <<@"+stageNumber+"mass: "+dryCM.weight+" @"+dryCM.toString());
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
|
||||
Coordinate totalCM=null;
|
||||
if( MassCalcType.NO_MOTORS == type ){
|
||||
totalCM = dryCM;
|
||||
@ -110,62 +111,83 @@ public class MassCalculator implements Monitorable {
|
||||
totalCM = dryCM.average(motorCM);
|
||||
}
|
||||
|
||||
// if(debug){
|
||||
// Coordinate cm = totalCM;
|
||||
// System.err.println(String.format("==>> Combined Mass: %5.3gg @( %g, %g, %g)",
|
||||
// cm.weight, cm.x, cm.y, cm.z ));
|
||||
// }
|
||||
|
||||
return totalCM;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the CG of the rocket with the provided motor configuration.
|
||||
* Compute the CM of all motors, given a configuration and type
|
||||
*
|
||||
* @param configuration the rocket configuration
|
||||
* @param motors the motor configuration
|
||||
* @return the CG of the configuration
|
||||
*/
|
||||
private MassData getMotorMassData(FlightConfiguration config, MassCalcType type) {
|
||||
public MassData getMotorMassData(FlightConfiguration config, MassCalcType type) {
|
||||
if( MassCalcType.NO_MOTORS == type ){
|
||||
return MassData.ZERO_DATA;
|
||||
}
|
||||
|
||||
// Add motor CGs
|
||||
|
||||
MassData motorData = MassData.ZERO_DATA;
|
||||
|
||||
// vvvv DEVEL vvvv
|
||||
// // 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("====== ====== getMotorCM: (type: "+type.name()+") ====== ====== ====== ====== ====== ======");
|
||||
// System.err.println(" [Number] [Name] [mass]");
|
||||
// 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 ^^^^
|
||||
// // ^^^^ DEVEL ^^^^
|
||||
|
||||
// int motorCount = 0;
|
||||
for (MotorConfiguration inst : config.getActiveMotors() ) {
|
||||
//ThrustCurveMotor motor = (ThrustCurveMotor) inst.getMotor();
|
||||
MassData allMotorData = MassData.ZERO_DATA;
|
||||
//int motorIndex = 0;
|
||||
for (MotorConfiguration mtrConfig : config.getActiveMotors() ) {
|
||||
ThrustCurveMotor mtr = (ThrustCurveMotor) mtrConfig.getMotor();
|
||||
|
||||
Coordinate position = inst.getPosition();
|
||||
Coordinate curMotorCM = type.getCG(inst.getMotor()).add(position);
|
||||
double Ir = inst.getRotationalInertia();
|
||||
double It = inst.getLongitudinalInertia();
|
||||
MotorMount mount = mtrConfig.getMount();
|
||||
RocketComponent mountComp = (RocketComponent)mount;
|
||||
Coordinate[] locations = mountComp.getLocations(); // location of mount, w/in entire rocket
|
||||
int instanceCount = locations.length;
|
||||
double motorXPosition = mtrConfig.getX(); // location of motor from mount
|
||||
|
||||
MassData instData = new MassData( curMotorCM, Ir, It);
|
||||
motorData = motorData.add( instData );
|
||||
Coordinate localCM = type.getCG( mtr ); // CoM from beginning of motor
|
||||
localCM = localCM.setWeight( localCM.weight * instanceCount);
|
||||
// a *bit* hacky :P
|
||||
Coordinate curMotorCM = localCM.setX( localCM.x + locations[0].x + motorXPosition );
|
||||
|
||||
double motorMass = curMotorCM.weight;
|
||||
double Ir_single = mtrConfig.getUnitRotationalInertia()*motorMass;
|
||||
double It_single = mtrConfig.getUnitLongitudinalInertia()*motorMass;
|
||||
double Ir=0;
|
||||
double It=0;
|
||||
if( 1 == instanceCount ){
|
||||
Ir=Ir_single;
|
||||
It=It_single;
|
||||
}else{
|
||||
It = It_single * instanceCount;
|
||||
|
||||
Ir = Ir_single*instanceCount;
|
||||
// these need more complex instancing code...
|
||||
for( Coordinate coord : locations ){
|
||||
double distance = Math.hypot( coord.y, coord.z);
|
||||
Ir += motorMass*Math.pow( distance, 2);
|
||||
}
|
||||
}
|
||||
|
||||
MassData configData = new MassData( curMotorCM, Ir, It);
|
||||
allMotorData = allMotorData.add( configData );
|
||||
|
||||
// BEGIN DEVEL
|
||||
// if( debug){
|
||||
// System.err.println(String.format(" motor %2d: %s %s", //%5.3gg @( %g, %g, %g)",
|
||||
// motorCount, inst.getMotor().getDesignation(), instData.toDebug()));
|
||||
// System.err.println(String.format(" >> %s",
|
||||
// motorData.toDebug()));
|
||||
// }
|
||||
// motorCount++;
|
||||
//if( debug){
|
||||
// // Inertia
|
||||
// System.err.println(String.format( inertiaFormat, motorIndex, instanceCount, mtr.getDesignation(), Ir, It));
|
||||
// // mass only
|
||||
//double singleMass = type.getCG( mtr ).weight;
|
||||
//System.err.println(String.format( massFormat, motorIndex, mtr.getDesignation(),
|
||||
// singleMass, instanceCount, curMotorCM.weight, allMotorData.getMass(),curMotorCM.x, curMotorCM.y, curMotorCM.z ));
|
||||
//}
|
||||
//motorIndex++;
|
||||
// END DEVEL
|
||||
}
|
||||
|
||||
return motorData;
|
||||
return allMotorData;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -197,10 +219,11 @@ public class MassCalculator implements Monitorable {
|
||||
|
||||
|
||||
MassData totalData = structureData.add( motorData);
|
||||
// if(debug){
|
||||
// System.err.println(String.format("==>> Combined MassData: %s", totalData.toDebug()));
|
||||
//
|
||||
// }
|
||||
if(debug){
|
||||
System.err.println(String.format(" >> Structural MassData: %s", structureData.toDebug()));
|
||||
System.err.println(String.format(" >> Motor MassData: %s", motorData.toDebug()));
|
||||
System.err.println(String.format("==>> Combined MassData: %s", totalData.toDebug()));
|
||||
}
|
||||
|
||||
return totalData.getLongitudinalInertia();
|
||||
}
|
||||
@ -233,10 +256,11 @@ public class MassCalculator implements Monitorable {
|
||||
}
|
||||
|
||||
MassData totalData = structureData.add( motorData);
|
||||
// if(debug){
|
||||
// System.err.println(String.format("==>> Combined MassData: %s", totalData.toDebug()));
|
||||
//
|
||||
// }
|
||||
if(debug){
|
||||
System.err.println(String.format(" >> Structural MassData: %s", structureData.toDebug()));
|
||||
System.err.println(String.format(" >> Motor MassData: %s", motorData.toDebug()));
|
||||
System.err.println(String.format("==>> Combined MassData: %s", totalData.toDebug()));
|
||||
}
|
||||
|
||||
return totalData.getRotationalInertia();
|
||||
}
|
||||
@ -254,9 +278,9 @@ public class MassCalculator implements Monitorable {
|
||||
//throw new BugException("getPropellantMass is not yet implemented.... ");
|
||||
// add up the masses of all motors in the rocket
|
||||
if ( MassCalcType.NO_MOTORS != calcType ){
|
||||
for (MotorConfiguration curInstance : configuration.getActiveMotors()) {
|
||||
mass = mass + curInstance.getPropellantMass();
|
||||
mass = curInstance.getMotor().getLaunchCG().weight - curInstance.getMotor().getEmptyCG().weight;
|
||||
for (MotorConfiguration curConfig : configuration.getActiveMotors()) {
|
||||
int instanceCount = curConfig.getMount().getInstanceCount();
|
||||
mass = mass + curConfig.getPropellantMass()*instanceCount;
|
||||
}
|
||||
}
|
||||
return mass;
|
||||
|
||||
@ -16,7 +16,6 @@ public class MotorConfiguration implements FlightConfigurableParameter<MotorConf
|
||||
|
||||
protected MotorMount mount = null;
|
||||
protected Motor motor = null;
|
||||
protected Coordinate position = Coordinate.ZERO;
|
||||
protected double ejectionDelay = 0.0;
|
||||
|
||||
protected MotorInstanceId id = null;
|
||||
@ -100,13 +99,15 @@ public class MotorConfiguration implements FlightConfigurableParameter<MotorConf
|
||||
this.ejectionDelay = delay;
|
||||
}
|
||||
|
||||
public Coordinate getPosition() {
|
||||
return this.position;
|
||||
public Coordinate getPosition(){
|
||||
return new Coordinate( getX(), 0, 0);
|
||||
}
|
||||
|
||||
public void setPosition(Coordinate _position) {
|
||||
this.position = _position;
|
||||
modID++;
|
||||
public double getX(){
|
||||
if( isEmpty()){
|
||||
return 0.0;
|
||||
}
|
||||
return mount.getLength() - motor.getLength() + mount.getMotorOverhang();
|
||||
}
|
||||
|
||||
public double getIgnitionTime() {
|
||||
@ -151,18 +152,16 @@ public class MotorConfiguration implements FlightConfigurableParameter<MotorConf
|
||||
}
|
||||
}
|
||||
|
||||
public double getLongitudinalInertia() {
|
||||
public double getUnitLongitudinalInertia() {
|
||||
if ( motor != null ) {
|
||||
double unitLongitudinalInertia = Inertia.filledCylinderLongitudinal(motor.getDiameter() / 2, motor.getLength());
|
||||
return unitLongitudinalInertia * Coordinate.ZERO.weight;
|
||||
return Inertia.filledCylinderLongitudinal(motor.getDiameter() / 2, motor.getLength());
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
public double getRotationalInertia() {
|
||||
public double getUnitRotationalInertia() {
|
||||
if ( motor != null ) {
|
||||
double unitRotationalInertia = Inertia.filledCylinderRotational(motor.getDiameter() / 2);
|
||||
return unitRotationalInertia * Coordinate.ZERO.weight;
|
||||
return Inertia.filledCylinderRotational(motor.getDiameter() / 2);
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
@ -13,11 +13,9 @@ import org.slf4j.LoggerFactory;
|
||||
import net.sf.openrocket.motor.MotorConfiguration;
|
||||
import net.sf.openrocket.motor.MotorInstanceId;
|
||||
import net.sf.openrocket.util.ArrayList;
|
||||
import net.sf.openrocket.util.ChangeSource;
|
||||
import net.sf.openrocket.util.Coordinate;
|
||||
import net.sf.openrocket.util.MathUtil;
|
||||
import net.sf.openrocket.util.Monitorable;
|
||||
import net.sf.openrocket.util.StateChangeListener;
|
||||
|
||||
|
||||
/**
|
||||
@ -466,10 +464,12 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
|
||||
// Note the motors and stages are updated in the constructor call.
|
||||
FlightConfiguration clone = new FlightConfiguration( this.getRocket(), this.fcid );
|
||||
clone.setName("clone[#"+clone.instanceNumber+"]"+clone.fcid.toShortKey());
|
||||
log.error(">> Why am I being cloned!?", new IllegalStateException(this.toDebug()+" >to> "+clone.toDebug()));
|
||||
// log.error(">> Why am I being cloned!?", new IllegalStateException(this.toDebug()+" >to> "+clone.toDebug()));
|
||||
|
||||
|
||||
// DO NOT UPDATE this.stages or this.motors;
|
||||
// these are are updated correctly on their own.
|
||||
|
||||
// DO NOT UPDATE:
|
||||
// this.stages and this.motors are updated correctly on their own.
|
||||
clone.cachedBounds = this.cachedBounds.clone();
|
||||
clone.modID = this.modID;
|
||||
clone.boundsModID = -1;
|
||||
@ -516,7 +516,7 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
|
||||
|
||||
|
||||
public String toDebug() {
|
||||
return this.fcid.toDebug()+" #"+instanceNumber;
|
||||
return this.fcid.toDebug()+" (#"+instanceNumber+")";
|
||||
}
|
||||
|
||||
// DEBUG / DEVEL
|
||||
|
||||
@ -10,8 +10,8 @@ import org.slf4j.LoggerFactory;
|
||||
import net.sf.openrocket.l10n.Translator;
|
||||
import net.sf.openrocket.motor.Motor;
|
||||
import net.sf.openrocket.motor.MotorConfiguration;
|
||||
import net.sf.openrocket.motor.MotorInstanceId;
|
||||
import net.sf.openrocket.motor.MotorConfigurationSet;
|
||||
import net.sf.openrocket.motor.MotorInstanceId;
|
||||
import net.sf.openrocket.preset.ComponentPreset;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
import net.sf.openrocket.util.BugException;
|
||||
@ -146,7 +146,7 @@ public class InnerTube extends ThicknessRingComponent implements Clusterable, Ra
|
||||
|
||||
@Override
|
||||
public int getInstanceCount() {
|
||||
return cluster.getClusterCount();
|
||||
return this.getLocations().length;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -282,17 +282,17 @@ public class InnerTube extends ThicknessRingComponent implements Clusterable, Ra
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMotorInstance(final FlightConfigurationId fcid, final MotorConfiguration newMotorInstance){
|
||||
if((null == newMotorInstance)){
|
||||
public void setMotorInstance(final FlightConfigurationId fcid, final MotorConfiguration newMotorConfig){
|
||||
if((null == newMotorConfig)){
|
||||
this.motors.set( fcid, null);
|
||||
}else{
|
||||
if( null == newMotorInstance.getMount()){
|
||||
newMotorInstance.setMount(this);
|
||||
}else if( !this.equals( newMotorInstance.getMount())){
|
||||
if( null == newMotorConfig.getMount()){
|
||||
newMotorConfig.setMount(this);
|
||||
}else if( !this.equals( newMotorConfig.getMount())){
|
||||
throw new BugException(" attempt to add a MotorInstance to a second mount, when it's already owned by another mount!");
|
||||
}
|
||||
newMotorInstance.setID(new MotorInstanceId( this.getID(), 1));
|
||||
this.motors.set(fcid, newMotorInstance);
|
||||
newMotorConfig.setID(new MotorInstanceId( this.getID(), 1));
|
||||
this.motors.set(fcid, newMotorConfig);
|
||||
}
|
||||
|
||||
this.isActingMount = true;
|
||||
@ -379,6 +379,7 @@ public class InnerTube extends ThicknessRingComponent implements Clusterable, Ra
|
||||
return copy;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* For a given coordinate that represents one tube in a cluster, create an instance of that tube. Must be called
|
||||
* once for each tube in the cluster.
|
||||
|
||||
@ -54,6 +54,14 @@ public interface MotorMount extends ChangeSource, FlightConfigurableComponent {
|
||||
*/
|
||||
public int getInstanceCount();
|
||||
|
||||
/**
|
||||
* Get the length of this motor mount. Synonymous with the RocketComponent method.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public double getLength();
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param fcid id for which to return the motor (null retrieves the default)
|
||||
|
||||
@ -15,7 +15,6 @@ import net.sf.openrocket.simulation.SimulationStatus;
|
||||
import net.sf.openrocket.simulation.exception.SimulationException;
|
||||
import net.sf.openrocket.simulation.listeners.AbstractSimulationListener;
|
||||
import net.sf.openrocket.unit.UnitGroup;
|
||||
import net.sf.openrocket.util.Coordinate;
|
||||
|
||||
public class DampingMoment extends AbstractSimulationListener {
|
||||
|
||||
@ -70,9 +69,8 @@ public class DampingMoment extends AbstractSimulationListener {
|
||||
double nozzleDistance = 0;
|
||||
FlightConfiguration config = status.getConfiguration();
|
||||
for (MotorConfiguration inst : config.getActiveMotors()) {
|
||||
Coordinate position = inst.getPosition();
|
||||
|
||||
double x = position.x + inst.getMotor().getLength();
|
||||
double x_position= inst.getX();
|
||||
double x = x_position + inst.getMotor().getLaunchCG().x;
|
||||
if (x > nozzleDistance) {
|
||||
nozzleDistance = x;
|
||||
}
|
||||
|
||||
@ -88,6 +88,22 @@ public class TestRockets {
|
||||
|
||||
}
|
||||
|
||||
// This function is used for unit, integration tests, DO NOT CHANGE (without updating tests).
|
||||
private static MotorConfiguration generateMotorInstance_C6_18mm(){
|
||||
// public ThrustCurveMotor(Manufacturer manufacturer, String designation, String description,
|
||||
// Motor.Type type, double[] delays, double diameter, double length,
|
||||
// double[] time, double[] thrust,
|
||||
// Coordinate[] cg, String digest);
|
||||
ThrustCurveMotor mtr = new ThrustCurveMotor(
|
||||
Manufacturer.getManufacturer("Estes"),"C6", " SU Black Powder",
|
||||
Motor.Type.SINGLE, new double[] {0,3,5,7}, 0.018, 0.070,
|
||||
new double[] { 0, 1, 2 }, new double[] { 0, 6, 0 },
|
||||
new Coordinate[] {
|
||||
new Coordinate(0.035, 0, 0, 0.0227),new Coordinate(.035, 0, 0, 0.0165),new Coordinate(.035, 0, 0, 0.0102)},
|
||||
"digest C6 test");
|
||||
return new MotorConfiguration(mtr);
|
||||
}
|
||||
|
||||
// This function is used for unit, integration tests, DO NOT CHANGE (without updating tests).
|
||||
private static MotorConfiguration generateMotorInstance_M1350_75mm(){
|
||||
// public ThrustCurveMotor(Manufacturer manufacturer, String designation, String description,
|
||||
@ -315,7 +331,6 @@ public class TestRockets {
|
||||
// It is picked as a standard, simple, validation rocket.
|
||||
// This function is used for unit, integration tests, DO NOT CHANGE (without updating tests).
|
||||
public static final Rocket makeEstesAlphaIII(){
|
||||
|
||||
Rocket rocket = new Rocket();
|
||||
rocket.setName("Estes Alpha III / Code Verification Rocket");
|
||||
AxialStage stage = new AxialStage();
|
||||
@ -379,6 +394,12 @@ public class TestRockets {
|
||||
thrustBlock.setThickness(0.00075);
|
||||
thrustBlock.setName("Engine Block");
|
||||
inner.addChild(thrustBlock);
|
||||
|
||||
MotorConfiguration motorConfig = TestRockets.generateMotorInstance_C6_18mm();
|
||||
motorConfig.setID( new MotorInstanceId( inner.getName(), 1) );
|
||||
inner.setMotorMount( true);
|
||||
FlightConfigurationId motorConfigId = rocket.getSelectedConfiguration().getFlightConfigurationID();
|
||||
inner.setMotorInstance( motorConfigId, motorConfig);
|
||||
}
|
||||
|
||||
// parachute
|
||||
@ -406,6 +427,7 @@ public class TestRockets {
|
||||
bodytube.setMaterial(material);
|
||||
finset.setMaterial(material);
|
||||
|
||||
rocket.getSelectedConfiguration().setAllStages();
|
||||
rocket.enableEvents();
|
||||
return rocket;
|
||||
}
|
||||
|
||||
@ -2,16 +2,14 @@ package net.sf.openrocket.masscalc;
|
||||
|
||||
//import junit.framework.TestCase;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import net.sf.openrocket.masscalc.MassCalculator.MassCalcType;
|
||||
import net.sf.openrocket.motor.MotorConfiguration;
|
||||
import net.sf.openrocket.rocketcomponent.ParallelStage;
|
||||
import net.sf.openrocket.motor.Motor;
|
||||
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
|
||||
import net.sf.openrocket.rocketcomponent.FlightConfigurationId;
|
||||
import net.sf.openrocket.rocketcomponent.InnerTube;
|
||||
import net.sf.openrocket.rocketcomponent.ParallelStage;
|
||||
import net.sf.openrocket.rocketcomponent.Rocket;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
import net.sf.openrocket.util.Coordinate;
|
||||
@ -288,21 +286,88 @@ public class MassCalculatorTest extends BaseTestCase {
|
||||
assertEquals(" Delta Heavy Booster CM is incorrect: ", expCM, boosterSetCM);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testSingleMotorMass() {
|
||||
Rocket rocket = TestRockets.makeEstesAlphaIII();
|
||||
|
||||
InnerTube mmt = (InnerTube) rocket.getChild(0).getChild(1).getChild(2);
|
||||
Motor activeMotor = mmt.getMotorInstance( rocket.getSelectedConfiguration().getId()).getMotor();
|
||||
String desig = activeMotor.getDesignation();
|
||||
|
||||
double expLaunchMass = 0.0227; // kg
|
||||
double expSpentMass = 0.0102; // kg
|
||||
assertEquals(" Motor Mass "+desig+" is incorrect: ", expLaunchMass, activeMotor.getLaunchCG().weight, EPSILON);
|
||||
assertEquals(" Motor Mass "+desig+" is incorrect: ", expSpentMass, activeMotor.getEmptyCG().weight, EPSILON);
|
||||
|
||||
// Validate Booster Launch Mass
|
||||
MassCalculator mc = new MassCalculator();
|
||||
double actPropMass = mc.getPropellantMass( rocket.getSelectedConfiguration(), MassCalcType.LAUNCH_MASS);
|
||||
|
||||
double expPropMass = expLaunchMass - expSpentMass;
|
||||
assertEquals(" Motor Mass "+desig+" is incorrect: ", expPropMass, actPropMass, EPSILON);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testBoosterMotorMass() {
|
||||
Rocket rocket = TestRockets.makeFalcon9Heavy();
|
||||
ParallelStage boosters = (ParallelStage) rocket.getChild(1).getChild(1);
|
||||
int boostNum = boosters.getStageNumber();
|
||||
rocket.getSelectedConfiguration().setOnlyStage( boostNum);
|
||||
|
||||
// String treeDump = rocket.toDebugTree();
|
||||
// System.err.println( treeDump);
|
||||
|
||||
{
|
||||
InnerTube mmt = (InnerTube) boosters.getChild(1).getChild(0);
|
||||
double expX = (.564 + 0.8 - 0.150 );
|
||||
double actX = mmt.getLocations()[0].x;
|
||||
assertEquals(" Booster motor mount tubes located incorrectly: ", expX, actX, EPSILON);
|
||||
}
|
||||
{
|
||||
// Validate Booster Launch Mass
|
||||
MassCalculator mc = new MassCalculator();
|
||||
MassData launchMotorData = mc.getMotorMassData( rocket.getSelectedConfiguration(), MassCalcType.LAUNCH_MASS);
|
||||
Coordinate launchCM = launchMotorData.getCM();
|
||||
// 1.214 = beginning of engine mmt
|
||||
// 1.364-.062 = middle of engine: 1.302
|
||||
Coordinate expLaunchCM = new Coordinate(1.31434, 0, 0, 0.123*2*4);
|
||||
assertEquals(" Booster Launch Mass is incorrect: ", expLaunchCM.weight, launchCM.weight, EPSILON);
|
||||
assertEquals(" Booster Launch CM.x is incorrect: ", expLaunchCM.x, launchCM.x, EPSILON);
|
||||
assertEquals(" Booster Launch CM.y is incorrect: ", expLaunchCM.y, launchCM.y, EPSILON);
|
||||
assertEquals(" Booster Launch CM.z is incorrect: ", expLaunchCM.z, launchCM.z, EPSILON);
|
||||
assertEquals(" Booster Launch CM is incorrect: ", expLaunchCM, launchCM);
|
||||
|
||||
|
||||
MassData spentMotorData = mc.getMotorMassData( rocket.getSelectedConfiguration(), MassCalcType.BURNOUT_MASS);
|
||||
Coordinate spentCM = spentMotorData.getCM();
|
||||
Coordinate expSpentCM = new Coordinate(1.31434, 0, 0, 0.064*2*4);
|
||||
assertEquals(" Booster Spent Mass is incorrect: ", expSpentCM.weight, spentCM.weight, EPSILON);
|
||||
assertEquals(" Booster Launch CM.x is incorrect: ", expSpentCM.x, spentCM.x, EPSILON);
|
||||
assertEquals(" Booster Launch CM.y is incorrect: ", expSpentCM.y, spentCM.y, EPSILON);
|
||||
assertEquals(" Booster Launch CM.z is incorrect: ", expSpentCM.z, spentCM.z, EPSILON);
|
||||
assertEquals(" Booster Launch CM is incorrect: ", expSpentCM, spentCM);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testBoosterTotalCM() {
|
||||
Rocket rocket = TestRockets.makeFalcon9Heavy();
|
||||
rocket.setName("TestRocket."+Thread.currentThread().getStackTrace()[1].getMethodName());
|
||||
|
||||
ParallelStage boosters = (ParallelStage) rocket.getChild(1).getChild(1);
|
||||
int boostNum = boosters.getStageNumber();
|
||||
//rocket.getDefaultConfiguration().setAllStages(false);
|
||||
rocket.getSelectedConfiguration().setOnlyStage( boostNum);
|
||||
|
||||
//String treeDump = rocket.toDebugTree();
|
||||
//System.err.println( treeDump);
|
||||
// String treeDump = rocket.toDebugTree();
|
||||
// System.err.println( treeDump);
|
||||
{
|
||||
// Validate Booster Launch Mass
|
||||
MassCalculator mc = new MassCalculator();
|
||||
//mc.debug = true;
|
||||
Coordinate boosterSetCM = mc.getCM( rocket.getSelectedConfiguration(), MassCalcType.LAUNCH_MASS);
|
||||
double calcTotalMass = boosterSetCM.weight;
|
||||
|
||||
@ -318,6 +383,7 @@ public class MassCalculatorTest extends BaseTestCase {
|
||||
{
|
||||
// Validate Booster Burnout Mass
|
||||
MassCalculator mc = new MassCalculator();
|
||||
//mc.debug = true;
|
||||
Coordinate boosterSetCM = mc.getCM( rocket.getSelectedConfiguration(), MassCalcType.BURNOUT_MASS);
|
||||
double calcTotalMass = boosterSetCM.weight;
|
||||
|
||||
@ -374,12 +440,11 @@ public class MassCalculatorTest extends BaseTestCase {
|
||||
|
||||
// Validate Boosters
|
||||
MassCalculator mc = new MassCalculator();
|
||||
//mc.debug = true;
|
||||
double expMOI_axial = 0.00752743;
|
||||
double boosterMOI_xx= mc.getRotationalInertia( defaultConfig, MassCalcType.LAUNCH_MASS);
|
||||
final double expMOI_axial = 0.05009613217;//0.00752743;
|
||||
final double boosterMOI_xx= mc.getRotationalInertia( defaultConfig, MassCalcType.LAUNCH_MASS);
|
||||
|
||||
double expMOI_tr = 0.0436639379937;
|
||||
double boosterMOI_tr= mc.getLongitudinalInertia( defaultConfig, MassCalcType.LAUNCH_MASS);
|
||||
final double expMOI_tr = 0.05263041249; // 0.0436639379937;
|
||||
final double boosterMOI_tr= mc.getLongitudinalInertia( defaultConfig, MassCalcType.LAUNCH_MASS);
|
||||
|
||||
assertEquals(" Booster x-axis MOI is incorrect: ", expMOI_axial, boosterMOI_xx, EPSILON);
|
||||
assertEquals(" Booster transverse MOI is incorrect: ", expMOI_tr, boosterMOI_tr, EPSILON);
|
||||
|
||||
@ -2,11 +2,9 @@ package net.sf.openrocket.masscalc;
|
||||
|
||||
//import junit.framework.TestCase;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
|
||||
import net.sf.openrocket.util.Coordinate;
|
||||
import net.sf.openrocket.util.MathUtil;
|
||||
import net.sf.openrocket.util.BaseTestCase.BaseTestCase;
|
||||
@ -86,7 +84,7 @@ public class MassDataTest extends BaseTestCase {
|
||||
// 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);
|
||||
// System.err.println(" Center of Mass: (3) expected: "+ cm3_expected);
|
||||
assertEquals(" Center of Mass calculated incorrectly: ", cm3_expected, asbly3.getCM() );
|
||||
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user