[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.Motor;
|
||||||
import net.sf.openrocket.motor.MotorConfiguration;
|
import net.sf.openrocket.motor.MotorConfiguration;
|
||||||
|
import net.sf.openrocket.motor.ThrustCurveMotor;
|
||||||
import net.sf.openrocket.rocketcomponent.AxialStage;
|
import net.sf.openrocket.rocketcomponent.AxialStage;
|
||||||
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
|
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
|
||||||
import net.sf.openrocket.rocketcomponent.Instanceable;
|
import net.sf.openrocket.rocketcomponent.Instanceable;
|
||||||
|
import net.sf.openrocket.rocketcomponent.MotorMount;
|
||||||
import net.sf.openrocket.rocketcomponent.ParallelStage;
|
import net.sf.openrocket.rocketcomponent.ParallelStage;
|
||||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||||
import net.sf.openrocket.util.BugException;
|
import net.sf.openrocket.util.BugException;
|
||||||
@ -61,7 +63,7 @@ public class MassCalculator implements Monitorable {
|
|||||||
// private Vector< MassData> motorData = new Vector<MassData>();
|
// private Vector< MassData> motorData = new Vector<MassData>();
|
||||||
|
|
||||||
// this turns on copious amounts of debug. Recommend leaving this false
|
// 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;
|
public boolean debug = false;
|
||||||
|
|
||||||
////////////////// Constructors ///////////////////
|
////////////////// 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()+")");
|
throw new BugException("method: calculateStageCache(...) is faulty-- returned null data for an active stage: "+stage.getName()+"("+stage.getStageNumber()+")");
|
||||||
}
|
}
|
||||||
dryCM = stageData.cm.average(dryCM);
|
dryCM = stageData.cm.average(dryCM);
|
||||||
// if( debug){
|
|
||||||
// System.err.println(" stageData <<@"+stageNumber+"mass: "+dryCM.weight+" @"+dryCM.toString());
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Coordinate totalCM=null;
|
Coordinate totalCM=null;
|
||||||
if( MassCalcType.NO_MOTORS == type ){
|
if( MassCalcType.NO_MOTORS == type ){
|
||||||
totalCM = dryCM;
|
totalCM = dryCM;
|
||||||
@ -110,62 +111,83 @@ public class MassCalculator implements Monitorable {
|
|||||||
totalCM = dryCM.average(motorCM);
|
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;
|
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 configuration the rocket configuration
|
||||||
* @param motors the motor configuration
|
* @param motors the motor configuration
|
||||||
* @return the CG of the 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 ){
|
if( MassCalcType.NO_MOTORS == type ){
|
||||||
return MassData.ZERO_DATA;
|
return MassData.ZERO_DATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add motor CGs
|
// // vvvv DEVEL vvvv
|
||||||
|
// //String massFormat = " [%2s]: %-16s %6s x %6s = %6s += %6s @ (%s, %s, %s )";
|
||||||
MassData motorData = MassData.ZERO_DATA;
|
// String inertiaFormat = " [%2s](%2s): %-16s %6s %6s";
|
||||||
|
|
||||||
// vvvv DEVEL vvvv
|
|
||||||
// if( debug){
|
// if( debug){
|
||||||
// System.err.println("====== ====== getMotorCM: (type: "+type.name()+") ====== ====== ====== ====== ====== ======");
|
// System.err.println("====== ====== getMotorMassData( config:"+config.toDebug()+", type: "+type.name()+") ====== ====== ====== ====== ====== ======");
|
||||||
// System.err.println(" [Number] [Name] [mass]");
|
// //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;
|
MassData allMotorData = MassData.ZERO_DATA;
|
||||||
for (MotorConfiguration inst : config.getActiveMotors() ) {
|
//int motorIndex = 0;
|
||||||
//ThrustCurveMotor motor = (ThrustCurveMotor) inst.getMotor();
|
for (MotorConfiguration mtrConfig : config.getActiveMotors() ) {
|
||||||
|
ThrustCurveMotor mtr = (ThrustCurveMotor) mtrConfig.getMotor();
|
||||||
|
|
||||||
Coordinate position = inst.getPosition();
|
MotorMount mount = mtrConfig.getMount();
|
||||||
Coordinate curMotorCM = type.getCG(inst.getMotor()).add(position);
|
RocketComponent mountComp = (RocketComponent)mount;
|
||||||
double Ir = inst.getRotationalInertia();
|
Coordinate[] locations = mountComp.getLocations(); // location of mount, w/in entire rocket
|
||||||
double It = inst.getLongitudinalInertia();
|
int instanceCount = locations.length;
|
||||||
|
double motorXPosition = mtrConfig.getX(); // location of motor from mount
|
||||||
|
|
||||||
MassData instData = new MassData( curMotorCM, Ir, It);
|
Coordinate localCM = type.getCG( mtr ); // CoM from beginning of motor
|
||||||
motorData = motorData.add( instData );
|
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
|
// BEGIN DEVEL
|
||||||
// if( debug){
|
//if( debug){
|
||||||
// System.err.println(String.format(" motor %2d: %s %s", //%5.3gg @( %g, %g, %g)",
|
// // Inertia
|
||||||
// motorCount, inst.getMotor().getDesignation(), instData.toDebug()));
|
// System.err.println(String.format( inertiaFormat, motorIndex, instanceCount, mtr.getDesignation(), Ir, It));
|
||||||
// System.err.println(String.format(" >> %s",
|
// // mass only
|
||||||
// motorData.toDebug()));
|
//double singleMass = type.getCG( mtr ).weight;
|
||||||
// }
|
//System.err.println(String.format( massFormat, motorIndex, mtr.getDesignation(),
|
||||||
// motorCount++;
|
// singleMass, instanceCount, curMotorCM.weight, allMotorData.getMass(),curMotorCM.x, curMotorCM.y, curMotorCM.z ));
|
||||||
|
//}
|
||||||
|
//motorIndex++;
|
||||||
// END DEVEL
|
// END DEVEL
|
||||||
}
|
}
|
||||||
|
|
||||||
return motorData;
|
return allMotorData;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -197,10 +219,11 @@ public class MassCalculator implements Monitorable {
|
|||||||
|
|
||||||
|
|
||||||
MassData totalData = structureData.add( motorData);
|
MassData totalData = structureData.add( motorData);
|
||||||
// if(debug){
|
if(debug){
|
||||||
// System.err.println(String.format("==>> Combined MassData: %s", totalData.toDebug()));
|
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();
|
return totalData.getLongitudinalInertia();
|
||||||
}
|
}
|
||||||
@ -233,10 +256,11 @@ public class MassCalculator implements Monitorable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
MassData totalData = structureData.add( motorData);
|
MassData totalData = structureData.add( motorData);
|
||||||
// if(debug){
|
if(debug){
|
||||||
// System.err.println(String.format("==>> Combined MassData: %s", totalData.toDebug()));
|
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();
|
return totalData.getRotationalInertia();
|
||||||
}
|
}
|
||||||
@ -254,9 +278,9 @@ public class MassCalculator implements Monitorable {
|
|||||||
//throw new BugException("getPropellantMass is not yet implemented.... ");
|
//throw new BugException("getPropellantMass is not yet implemented.... ");
|
||||||
// add up the masses of all motors in the rocket
|
// add up the masses of all motors in the rocket
|
||||||
if ( MassCalcType.NO_MOTORS != calcType ){
|
if ( MassCalcType.NO_MOTORS != calcType ){
|
||||||
for (MotorConfiguration curInstance : configuration.getActiveMotors()) {
|
for (MotorConfiguration curConfig : configuration.getActiveMotors()) {
|
||||||
mass = mass + curInstance.getPropellantMass();
|
int instanceCount = curConfig.getMount().getInstanceCount();
|
||||||
mass = curInstance.getMotor().getLaunchCG().weight - curInstance.getMotor().getEmptyCG().weight;
|
mass = mass + curConfig.getPropellantMass()*instanceCount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return mass;
|
return mass;
|
||||||
|
|||||||
@ -16,7 +16,6 @@ public class MotorConfiguration implements FlightConfigurableParameter<MotorConf
|
|||||||
|
|
||||||
protected MotorMount mount = null;
|
protected MotorMount mount = null;
|
||||||
protected Motor motor = null;
|
protected Motor motor = null;
|
||||||
protected Coordinate position = Coordinate.ZERO;
|
|
||||||
protected double ejectionDelay = 0.0;
|
protected double ejectionDelay = 0.0;
|
||||||
|
|
||||||
protected MotorInstanceId id = null;
|
protected MotorInstanceId id = null;
|
||||||
@ -100,13 +99,15 @@ public class MotorConfiguration implements FlightConfigurableParameter<MotorConf
|
|||||||
this.ejectionDelay = delay;
|
this.ejectionDelay = delay;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Coordinate getPosition() {
|
public Coordinate getPosition(){
|
||||||
return this.position;
|
return new Coordinate( getX(), 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPosition(Coordinate _position) {
|
public double getX(){
|
||||||
this.position = _position;
|
if( isEmpty()){
|
||||||
modID++;
|
return 0.0;
|
||||||
|
}
|
||||||
|
return mount.getLength() - motor.getLength() + mount.getMotorOverhang();
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getIgnitionTime() {
|
public double getIgnitionTime() {
|
||||||
@ -151,18 +152,16 @@ public class MotorConfiguration implements FlightConfigurableParameter<MotorConf
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getLongitudinalInertia() {
|
public double getUnitLongitudinalInertia() {
|
||||||
if ( motor != null ) {
|
if ( motor != null ) {
|
||||||
double unitLongitudinalInertia = Inertia.filledCylinderLongitudinal(motor.getDiameter() / 2, motor.getLength());
|
return Inertia.filledCylinderLongitudinal(motor.getDiameter() / 2, motor.getLength());
|
||||||
return unitLongitudinalInertia * Coordinate.ZERO.weight;
|
|
||||||
}
|
}
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getRotationalInertia() {
|
public double getUnitRotationalInertia() {
|
||||||
if ( motor != null ) {
|
if ( motor != null ) {
|
||||||
double unitRotationalInertia = Inertia.filledCylinderRotational(motor.getDiameter() / 2);
|
return Inertia.filledCylinderRotational(motor.getDiameter() / 2);
|
||||||
return unitRotationalInertia * Coordinate.ZERO.weight;
|
|
||||||
}
|
}
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,11 +13,9 @@ import org.slf4j.LoggerFactory;
|
|||||||
import net.sf.openrocket.motor.MotorConfiguration;
|
import net.sf.openrocket.motor.MotorConfiguration;
|
||||||
import net.sf.openrocket.motor.MotorInstanceId;
|
import net.sf.openrocket.motor.MotorInstanceId;
|
||||||
import net.sf.openrocket.util.ArrayList;
|
import net.sf.openrocket.util.ArrayList;
|
||||||
import net.sf.openrocket.util.ChangeSource;
|
|
||||||
import net.sf.openrocket.util.Coordinate;
|
import net.sf.openrocket.util.Coordinate;
|
||||||
import net.sf.openrocket.util.MathUtil;
|
import net.sf.openrocket.util.MathUtil;
|
||||||
import net.sf.openrocket.util.Monitorable;
|
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.
|
// Note the motors and stages are updated in the constructor call.
|
||||||
FlightConfiguration clone = new FlightConfiguration( this.getRocket(), this.fcid );
|
FlightConfiguration clone = new FlightConfiguration( this.getRocket(), this.fcid );
|
||||||
clone.setName("clone[#"+clone.instanceNumber+"]"+clone.fcid.toShortKey());
|
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.cachedBounds = this.cachedBounds.clone();
|
||||||
clone.modID = this.modID;
|
clone.modID = this.modID;
|
||||||
clone.boundsModID = -1;
|
clone.boundsModID = -1;
|
||||||
@ -516,7 +516,7 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
|
|||||||
|
|
||||||
|
|
||||||
public String toDebug() {
|
public String toDebug() {
|
||||||
return this.fcid.toDebug()+" #"+instanceNumber;
|
return this.fcid.toDebug()+" (#"+instanceNumber+")";
|
||||||
}
|
}
|
||||||
|
|
||||||
// DEBUG / DEVEL
|
// DEBUG / DEVEL
|
||||||
|
|||||||
@ -10,8 +10,8 @@ import org.slf4j.LoggerFactory;
|
|||||||
import net.sf.openrocket.l10n.Translator;
|
import net.sf.openrocket.l10n.Translator;
|
||||||
import net.sf.openrocket.motor.Motor;
|
import net.sf.openrocket.motor.Motor;
|
||||||
import net.sf.openrocket.motor.MotorConfiguration;
|
import net.sf.openrocket.motor.MotorConfiguration;
|
||||||
import net.sf.openrocket.motor.MotorInstanceId;
|
|
||||||
import net.sf.openrocket.motor.MotorConfigurationSet;
|
import net.sf.openrocket.motor.MotorConfigurationSet;
|
||||||
|
import net.sf.openrocket.motor.MotorInstanceId;
|
||||||
import net.sf.openrocket.preset.ComponentPreset;
|
import net.sf.openrocket.preset.ComponentPreset;
|
||||||
import net.sf.openrocket.startup.Application;
|
import net.sf.openrocket.startup.Application;
|
||||||
import net.sf.openrocket.util.BugException;
|
import net.sf.openrocket.util.BugException;
|
||||||
@ -146,7 +146,7 @@ public class InnerTube extends ThicknessRingComponent implements Clusterable, Ra
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getInstanceCount() {
|
public int getInstanceCount() {
|
||||||
return cluster.getClusterCount();
|
return this.getLocations().length;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -282,17 +282,17 @@ public class InnerTube extends ThicknessRingComponent implements Clusterable, Ra
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setMotorInstance(final FlightConfigurationId fcid, final MotorConfiguration newMotorInstance){
|
public void setMotorInstance(final FlightConfigurationId fcid, final MotorConfiguration newMotorConfig){
|
||||||
if((null == newMotorInstance)){
|
if((null == newMotorConfig)){
|
||||||
this.motors.set( fcid, null);
|
this.motors.set( fcid, null);
|
||||||
}else{
|
}else{
|
||||||
if( null == newMotorInstance.getMount()){
|
if( null == newMotorConfig.getMount()){
|
||||||
newMotorInstance.setMount(this);
|
newMotorConfig.setMount(this);
|
||||||
}else if( !this.equals( newMotorInstance.getMount())){
|
}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!");
|
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));
|
newMotorConfig.setID(new MotorInstanceId( this.getID(), 1));
|
||||||
this.motors.set(fcid, newMotorInstance);
|
this.motors.set(fcid, newMotorConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.isActingMount = true;
|
this.isActingMount = true;
|
||||||
@ -379,6 +379,7 @@ public class InnerTube extends ThicknessRingComponent implements Clusterable, Ra
|
|||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For a given coordinate that represents one tube in a cluster, create an instance of that tube. Must be called
|
* 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.
|
* once for each tube in the cluster.
|
||||||
|
|||||||
@ -54,6 +54,14 @@ public interface MotorMount extends ChangeSource, FlightConfigurableComponent {
|
|||||||
*/
|
*/
|
||||||
public int getInstanceCount();
|
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)
|
* @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.exception.SimulationException;
|
||||||
import net.sf.openrocket.simulation.listeners.AbstractSimulationListener;
|
import net.sf.openrocket.simulation.listeners.AbstractSimulationListener;
|
||||||
import net.sf.openrocket.unit.UnitGroup;
|
import net.sf.openrocket.unit.UnitGroup;
|
||||||
import net.sf.openrocket.util.Coordinate;
|
|
||||||
|
|
||||||
public class DampingMoment extends AbstractSimulationListener {
|
public class DampingMoment extends AbstractSimulationListener {
|
||||||
|
|
||||||
@ -70,9 +69,8 @@ public class DampingMoment extends AbstractSimulationListener {
|
|||||||
double nozzleDistance = 0;
|
double nozzleDistance = 0;
|
||||||
FlightConfiguration config = status.getConfiguration();
|
FlightConfiguration config = status.getConfiguration();
|
||||||
for (MotorConfiguration inst : config.getActiveMotors()) {
|
for (MotorConfiguration inst : config.getActiveMotors()) {
|
||||||
Coordinate position = inst.getPosition();
|
double x_position= inst.getX();
|
||||||
|
double x = x_position + inst.getMotor().getLaunchCG().x;
|
||||||
double x = position.x + inst.getMotor().getLength();
|
|
||||||
if (x > nozzleDistance) {
|
if (x > nozzleDistance) {
|
||||||
nozzleDistance = x;
|
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).
|
// This function is used for unit, integration tests, DO NOT CHANGE (without updating tests).
|
||||||
private static MotorConfiguration generateMotorInstance_M1350_75mm(){
|
private static MotorConfiguration generateMotorInstance_M1350_75mm(){
|
||||||
// public ThrustCurveMotor(Manufacturer manufacturer, String designation, String description,
|
// public ThrustCurveMotor(Manufacturer manufacturer, String designation, String description,
|
||||||
@ -315,7 +331,6 @@ public class TestRockets {
|
|||||||
// It is picked as a standard, simple, validation rocket.
|
// It is picked as a standard, simple, validation rocket.
|
||||||
// This function is used for unit, integration tests, DO NOT CHANGE (without updating tests).
|
// This function is used for unit, integration tests, DO NOT CHANGE (without updating tests).
|
||||||
public static final Rocket makeEstesAlphaIII(){
|
public static final Rocket makeEstesAlphaIII(){
|
||||||
|
|
||||||
Rocket rocket = new Rocket();
|
Rocket rocket = new Rocket();
|
||||||
rocket.setName("Estes Alpha III / Code Verification Rocket");
|
rocket.setName("Estes Alpha III / Code Verification Rocket");
|
||||||
AxialStage stage = new AxialStage();
|
AxialStage stage = new AxialStage();
|
||||||
@ -379,6 +394,12 @@ public class TestRockets {
|
|||||||
thrustBlock.setThickness(0.00075);
|
thrustBlock.setThickness(0.00075);
|
||||||
thrustBlock.setName("Engine Block");
|
thrustBlock.setName("Engine Block");
|
||||||
inner.addChild(thrustBlock);
|
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
|
// parachute
|
||||||
@ -406,6 +427,7 @@ public class TestRockets {
|
|||||||
bodytube.setMaterial(material);
|
bodytube.setMaterial(material);
|
||||||
finset.setMaterial(material);
|
finset.setMaterial(material);
|
||||||
|
|
||||||
|
rocket.getSelectedConfiguration().setAllStages();
|
||||||
rocket.enableEvents();
|
rocket.enableEvents();
|
||||||
return rocket;
|
return rocket;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,16 +2,14 @@ package net.sf.openrocket.masscalc;
|
|||||||
|
|
||||||
//import junit.framework.TestCase;
|
//import junit.framework.TestCase;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import net.sf.openrocket.masscalc.MassCalculator.MassCalcType;
|
import net.sf.openrocket.masscalc.MassCalculator.MassCalcType;
|
||||||
import net.sf.openrocket.motor.MotorConfiguration;
|
import net.sf.openrocket.motor.Motor;
|
||||||
import net.sf.openrocket.rocketcomponent.ParallelStage;
|
|
||||||
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
|
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
|
||||||
import net.sf.openrocket.rocketcomponent.FlightConfigurationId;
|
|
||||||
import net.sf.openrocket.rocketcomponent.InnerTube;
|
import net.sf.openrocket.rocketcomponent.InnerTube;
|
||||||
|
import net.sf.openrocket.rocketcomponent.ParallelStage;
|
||||||
import net.sf.openrocket.rocketcomponent.Rocket;
|
import net.sf.openrocket.rocketcomponent.Rocket;
|
||||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||||
import net.sf.openrocket.util.Coordinate;
|
import net.sf.openrocket.util.Coordinate;
|
||||||
@ -288,21 +286,88 @@ public class MassCalculatorTest extends BaseTestCase {
|
|||||||
assertEquals(" Delta Heavy Booster CM is incorrect: ", expCM, boosterSetCM);
|
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
|
@Test
|
||||||
public void testBoosterTotalCM() {
|
public void testBoosterTotalCM() {
|
||||||
Rocket rocket = TestRockets.makeFalcon9Heavy();
|
Rocket rocket = TestRockets.makeFalcon9Heavy();
|
||||||
rocket.setName("TestRocket."+Thread.currentThread().getStackTrace()[1].getMethodName());
|
|
||||||
|
|
||||||
ParallelStage boosters = (ParallelStage) rocket.getChild(1).getChild(1);
|
ParallelStage boosters = (ParallelStage) rocket.getChild(1).getChild(1);
|
||||||
int boostNum = boosters.getStageNumber();
|
int boostNum = boosters.getStageNumber();
|
||||||
//rocket.getDefaultConfiguration().setAllStages(false);
|
//rocket.getDefaultConfiguration().setAllStages(false);
|
||||||
rocket.getSelectedConfiguration().setOnlyStage( boostNum);
|
rocket.getSelectedConfiguration().setOnlyStage( boostNum);
|
||||||
|
|
||||||
//String treeDump = rocket.toDebugTree();
|
// String treeDump = rocket.toDebugTree();
|
||||||
//System.err.println( treeDump);
|
// System.err.println( treeDump);
|
||||||
{
|
{
|
||||||
// Validate Booster Launch Mass
|
// Validate Booster Launch Mass
|
||||||
MassCalculator mc = new MassCalculator();
|
MassCalculator mc = new MassCalculator();
|
||||||
|
//mc.debug = true;
|
||||||
Coordinate boosterSetCM = mc.getCM( rocket.getSelectedConfiguration(), MassCalcType.LAUNCH_MASS);
|
Coordinate boosterSetCM = mc.getCM( rocket.getSelectedConfiguration(), MassCalcType.LAUNCH_MASS);
|
||||||
double calcTotalMass = boosterSetCM.weight;
|
double calcTotalMass = boosterSetCM.weight;
|
||||||
|
|
||||||
@ -318,6 +383,7 @@ public class MassCalculatorTest extends BaseTestCase {
|
|||||||
{
|
{
|
||||||
// Validate Booster Burnout Mass
|
// Validate Booster Burnout Mass
|
||||||
MassCalculator mc = new MassCalculator();
|
MassCalculator mc = new MassCalculator();
|
||||||
|
//mc.debug = true;
|
||||||
Coordinate boosterSetCM = mc.getCM( rocket.getSelectedConfiguration(), MassCalcType.BURNOUT_MASS);
|
Coordinate boosterSetCM = mc.getCM( rocket.getSelectedConfiguration(), MassCalcType.BURNOUT_MASS);
|
||||||
double calcTotalMass = boosterSetCM.weight;
|
double calcTotalMass = boosterSetCM.weight;
|
||||||
|
|
||||||
@ -374,12 +440,11 @@ public class MassCalculatorTest extends BaseTestCase {
|
|||||||
|
|
||||||
// Validate Boosters
|
// Validate Boosters
|
||||||
MassCalculator mc = new MassCalculator();
|
MassCalculator mc = new MassCalculator();
|
||||||
//mc.debug = true;
|
final double expMOI_axial = 0.05009613217;//0.00752743;
|
||||||
double expMOI_axial = 0.00752743;
|
final double boosterMOI_xx= mc.getRotationalInertia( defaultConfig, MassCalcType.LAUNCH_MASS);
|
||||||
double boosterMOI_xx= mc.getRotationalInertia( defaultConfig, MassCalcType.LAUNCH_MASS);
|
|
||||||
|
|
||||||
double expMOI_tr = 0.0436639379937;
|
final double expMOI_tr = 0.05263041249; // 0.0436639379937;
|
||||||
double boosterMOI_tr= mc.getLongitudinalInertia( defaultConfig, MassCalcType.LAUNCH_MASS);
|
final double boosterMOI_tr= mc.getLongitudinalInertia( defaultConfig, MassCalcType.LAUNCH_MASS);
|
||||||
|
|
||||||
assertEquals(" Booster x-axis MOI is incorrect: ", expMOI_axial, boosterMOI_xx, EPSILON);
|
assertEquals(" Booster x-axis MOI is incorrect: ", expMOI_axial, boosterMOI_xx, EPSILON);
|
||||||
assertEquals(" Booster transverse MOI is incorrect: ", expMOI_tr, boosterMOI_tr, 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 junit.framework.TestCase;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
|
||||||
import net.sf.openrocket.util.Coordinate;
|
import net.sf.openrocket.util.Coordinate;
|
||||||
import net.sf.openrocket.util.MathUtil;
|
import net.sf.openrocket.util.MathUtil;
|
||||||
import net.sf.openrocket.util.BaseTestCase.BaseTestCase;
|
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(" @(1): "+ body1.toDebug());
|
||||||
// System.err.println(" @(2): "+ body2.toDebug());
|
// System.err.println(" @(2): "+ body2.toDebug());
|
||||||
// System.err.println(" @(3): "+ asbly3.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() );
|
assertEquals(" Center of Mass calculated incorrectly: ", cm3_expected, asbly3.getCM() );
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user