Merge pull request #782 from JoePfeiffer/fix-768a
Only consider active stages when calculating drag
This commit is contained in:
commit
2a46d67097
@ -1632,7 +1632,7 @@ FlightDataType.TYPE_ROLL_RATE = Roll rate
|
||||
FlightDataType.TYPE_PITCH_RATE = Pitch rate
|
||||
FlightDataType.TYPE_YAW_RATE = Yaw rate
|
||||
FlightDataType.TYPE_MASS = Mass
|
||||
FlightDataType.TYPE_PROPELLANT_MASS = Propellant mass
|
||||
FlightDataType.TYPE_MOTOR_MASS = Motor mass
|
||||
FlightDataType.TYPE_LONGITUDINAL_INERTIA = Longitudinal moment of inertia
|
||||
FlightDataType.TYPE_ROTATIONAL_INERTIA = Rotational moment of inertia
|
||||
FlightDataType.TYPE_CP_LOCATION = CP location
|
||||
|
@ -314,7 +314,7 @@ FlightDataType.TYPE_POSITION_X = Posici\u00f3n contra el viento
|
||||
FlightDataType.TYPE_POSITION_XY = Distancia lateral
|
||||
FlightDataType.TYPE_POSITION_Y = Posici\u00f3n a favor del viento
|
||||
FlightDataType.TYPE_PRESSURE_DRAG_COEFF = Presi\u00f3n del Coeficiente de rozamiento
|
||||
FlightDataType.TYPE_PROPELLANT_MASS = Masa del propulsor
|
||||
FlightDataType.TYPE_MOTOR_MASS = Masa del propulsor
|
||||
FlightDataType.TYPE_REFERENCE_AREA = \u00c1rea de referencia
|
||||
FlightDataType.TYPE_REFERENCE_LENGTH = Longitud de referencia
|
||||
FlightDataType.TYPE_REYNOLDS_NUMBER = N\u00famero de Reynolds
|
||||
|
@ -305,7 +305,7 @@ FlightDataType.TYPE_POSITION_X = Position contre le vent
|
||||
FlightDataType.TYPE_POSITION_XY = Distance lat\u00E9rale
|
||||
FlightDataType.TYPE_POSITION_Y = Position parall\u00E8le au vent
|
||||
FlightDataType.TYPE_PRESSURE_DRAG_COEFF = Coefficient de tra\u00EEn\u00E9e de pression
|
||||
FlightDataType.TYPE_PROPELLANT_MASS = Masse du propergol
|
||||
FlightDataType.TYPE_MOTOR_MASS = Masse du propergol
|
||||
FlightDataType.TYPE_REFERENCE_AREA = Surface de r\u00E9f\u00E9rence
|
||||
FlightDataType.TYPE_REFERENCE_LENGTH = Longueur de r\u00E9f\u00E9rence
|
||||
FlightDataType.TYPE_REYNOLDS_NUMBER = Nombre de Reynolds
|
||||
|
@ -1385,7 +1385,7 @@ FlightDataType.TYPE_ROLL_RATE = \u89D2\u901F\u5EA6\uFF08\u30ED\u30FC\u30EB\uFF0
|
||||
FlightDataType.TYPE_PITCH_RATE = \u89D2\u901F\u5EA6\uFF08\u30D4\u30C3\u30C1\uFF09
|
||||
FlightDataType.TYPE_YAW_RATE = \u89D2\u901F\u5EA6\uFF08\u30E8\u30FC\uFF09
|
||||
FlightDataType.TYPE_MASS = \u8CEA\u91CF
|
||||
FlightDataType.TYPE_PROPELLANT_MASS = \u8EF8\u65B9\u5411\u6163\u6027\u30E2\u30FC\u30E1\u30F3\u30C8
|
||||
FlightDataType.TYPE_MOTOR_MASS = \u8EF8\u65B9\u5411\u6163\u6027\u30E2\u30FC\u30E1\u30F3\u30C8
|
||||
FlightDataType.TYPE_LONGITUDINAL_INERTIA = \u9577\u624B\u65B9\u5411\u6163\u6027\u30E2\u30FC\u30E1\u30F3\u30C8
|
||||
FlightDataType.TYPE_ROTATIONAL_INERTIA = \u30ED\u30FC\u30EB\u65B9\u5411\u6163\u6027\u30E2\u30FC\u30E1\u30F3\u30C8
|
||||
FlightDataType.TYPE_CP_LOCATION = CP\u4F4D\u7F6E
|
||||
|
@ -294,7 +294,7 @@ FlightDataType.TYPE_POSITION_X = Posi\u00e7\u00e3o a favor do ve
|
||||
FlightDataType.TYPE_POSITION_XY = Dist\u00e2ncia lateral
|
||||
FlightDataType.TYPE_POSITION_Y = Posi\u00e7\u00e3o paralela ao vento
|
||||
FlightDataType.TYPE_PRESSURE_DRAG_COEFF = Coeficiente de arrasto de press\u00e3o
|
||||
FlightDataType.TYPE_PROPELLANT_MASS = Massa do propelente
|
||||
FlightDataType.TYPE_MOTOR_MASS = Massa do propelente
|
||||
FlightDataType.TYPE_REFERENCE_AREA = \u00c1rea de refer\u00eancia
|
||||
FlightDataType.TYPE_REFERENCE_LENGTH = Comprimento de refer\u00eancia
|
||||
FlightDataType.TYPE_REYNOLDS_NUMBER = N\u00famero de Reynolds
|
||||
|
@ -1477,7 +1477,7 @@ FlightDataType.TYPE_ROLL_RATE = \u0423\u0433\u043b\u043e\u0432\u0430\u044f \u044
|
||||
FlightDataType.TYPE_PITCH_RATE = \u0423\u0433\u043b\u043e\u0432\u0430\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0442\u0430\u043d\u0433\u0430\u0436\u0430
|
||||
FlightDataType.TYPE_YAW_RATE = \u0423\u0433\u043b\u043e\u0432\u0430\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u044b\u0441\u043a\u0430\u043d\u044c\u044f
|
||||
FlightDataType.TYPE_MASS = \u041c\u0430\u0441\u0441\u0430
|
||||
FlightDataType.TYPE_PROPELLANT_MASS = \u041c\u0430\u0441\u0441\u0430 \u0442\u043e\u043f\u043b\u0438\u0432\u0430
|
||||
FlightDataType.TYPE_MOTOR_MASS = \u041c\u0430\u0441\u0441\u0430 \u0442\u043e\u043f\u043b\u0438\u0432\u0430
|
||||
FlightDataType.TYPE_LONGITUDINAL_INERTIA = \u041f\u0440\u043e\u0434\u043e\u043b\u044c\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0438\u043d\u0435\u0440\u0446\u0438\u0438
|
||||
FlightDataType.TYPE_ROTATIONAL_INERTIA = \u041a\u0440\u0443\u0442\u044f\u0449\u0438\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0438\u043d\u0435\u0440\u0446\u0438\u0438
|
||||
FlightDataType.TYPE_CP_LOCATION = \u041f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0426\u0414
|
||||
|
@ -1483,7 +1483,7 @@ FlightDataType.TYPE_ROLL_RATE = Roll rate
|
||||
FlightDataType.TYPE_PITCH_RATE = Pitch rate
|
||||
FlightDataType.TYPE_YAW_RATE = Yaw rate
|
||||
FlightDataType.TYPE_MASS = Mass
|
||||
FlightDataType.TYPE_PROPELLANT_MASS = Propellant mass
|
||||
FlightDataType.TYPE_MOTOR_MASS = Motor mass
|
||||
FlightDataType.TYPE_LONGITUDINAL_INERTIA = Longitudinal moment of inertia
|
||||
FlightDataType.TYPE_ROTATIONAL_INERTIA = Rotational moment of inertia
|
||||
FlightDataType.TYPE_CP_LOCATION = CP location
|
||||
|
@ -330,7 +330,7 @@ FlightDataType.TYPE_POSITION_X = \u8FCE\u98CE\u4F4D\u7F6E
|
||||
FlightDataType.TYPE_POSITION_XY = \u6A2A\u5411\u8DE8\u8DDD
|
||||
FlightDataType.TYPE_POSITION_Y = \u5E73\u884C\u98CE\u4F4D\u7F6E
|
||||
FlightDataType.TYPE_PRESSURE_DRAG_COEFF = \u538B\u5DEE\u963B\u529B\u7CFB\u6570
|
||||
FlightDataType.TYPE_PROPELLANT_MASS = \u63A8\u8FDB\u5242\u8D28\u91CF
|
||||
FlightDataType.TYPE_MOTOR_MASS = \u63A8\u8FDB\u5242\u8D28\u91CF
|
||||
FlightDataType.TYPE_REFERENCE_AREA = \u53C2\u8003\u9762\u79EF
|
||||
FlightDataType.TYPE_REFERENCE_LENGTH = \u53C2\u8003\u957F\u5EA6
|
||||
FlightDataType.TYPE_REYNOLDS_NUMBER = \u96F7\u8BFA\u6570
|
||||
|
@ -1,11 +1,13 @@
|
||||
package net.sf.openrocket.masscalc;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
import net.sf.openrocket.motor.Motor;
|
||||
import net.sf.openrocket.motor.MotorConfiguration;
|
||||
import net.sf.openrocket.rocketcomponent.*;
|
||||
import net.sf.openrocket.simulation.MotorClusterState;
|
||||
import net.sf.openrocket.util.Coordinate;
|
||||
import net.sf.openrocket.util.MathUtil;
|
||||
import net.sf.openrocket.util.Transformation;
|
||||
@ -71,7 +73,7 @@ public class MassCalculation {
|
||||
}
|
||||
|
||||
public MassCalculation copy( final RocketComponent _root, final Transformation _transform){
|
||||
return new MassCalculation( this.type, this.config, this.simulationTime, _root, _transform, this.analysisMap);
|
||||
return new MassCalculation( this.type, this.config, this.simulationTime, this.activeMotorList, _root, _transform, this.analysisMap);
|
||||
}
|
||||
|
||||
public Coordinate getCM() {
|
||||
@ -108,12 +110,14 @@ public class MassCalculation {
|
||||
}
|
||||
|
||||
public MassCalculation( final Type _type, final FlightConfiguration _config, final double _time,
|
||||
final Collection<MotorClusterState> _activeMotorList,
|
||||
final RocketComponent _root, final Transformation _transform,
|
||||
Map<Integer, CMAnalysisEntry> _map)
|
||||
{
|
||||
type = _type;
|
||||
config = _config;
|
||||
simulationTime = _time;
|
||||
activeMotorList = _activeMotorList;
|
||||
root = _root;
|
||||
transform = _transform;
|
||||
analysisMap = _map;
|
||||
@ -156,6 +160,7 @@ public class MassCalculation {
|
||||
// === package-private ===
|
||||
final FlightConfiguration config;
|
||||
final double simulationTime;
|
||||
final Collection<MotorClusterState> activeMotorList;
|
||||
final RocketComponent root;
|
||||
final Transformation transform;
|
||||
final Type type;
|
||||
@ -182,11 +187,24 @@ public class MassCalculation {
|
||||
|
||||
final MotorMount mount = (MotorMount)root;
|
||||
MotorConfiguration motorConfig = mount.getMotorConfig( config.getId() );
|
||||
final Motor motor = motorConfig.getMotor();
|
||||
if( motorConfig.isEmpty() ){
|
||||
return this;
|
||||
}
|
||||
final Motor motor = motorConfig.getMotor();
|
||||
|
||||
// If we don't have any MotorClusterStates,
|
||||
// we're using a synthetic time to do a static analysis.
|
||||
// If we do have MotorClusterStates, we need to adjust
|
||||
// time according to motor ignition time.
|
||||
double motorTime = simulationTime;
|
||||
if (activeMotorList != null) {
|
||||
for (MotorClusterState currentMotorState : activeMotorList ) {
|
||||
if (currentMotorState.getMotor() == motor) {
|
||||
motorTime = currentMotorState.getMotorTime(simulationTime);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final double mountXPosition = root.getPosition().x;
|
||||
|
||||
@ -199,14 +217,14 @@ public class MassCalculation {
|
||||
double eachCMx; // CoM from beginning of motor
|
||||
|
||||
if ( this.type.includesMotorCasing && this.type.includesPropellant ){
|
||||
eachMass = motor.getTotalMass( simulationTime );
|
||||
eachCMx = motor.getCMx( simulationTime);
|
||||
eachMass = motor.getTotalMass( motorTime );
|
||||
eachCMx = motor.getCMx( motorTime);
|
||||
}else if( this.type.includesMotorCasing ) {
|
||||
eachMass = motor.getTotalMass( Motor.PSEUDO_TIME_BURNOUT );
|
||||
eachCMx = motor.getCMx( Motor.PSEUDO_TIME_BURNOUT );
|
||||
} else {
|
||||
final double eachMotorMass = motor.getTotalMass( simulationTime );
|
||||
final double eachMotorCMx = motor.getCMx( simulationTime); // CoM from beginning of motor
|
||||
final double eachMotorMass = motor.getTotalMass( motorTime );
|
||||
final double eachMotorCMx = motor.getCMx( motorTime ); // CoM from beginning of motor
|
||||
final double eachCasingMass = motor.getBurnoutMass();
|
||||
final double eachCasingCMx = motor.getBurnoutCGx();
|
||||
|
||||
@ -214,7 +232,7 @@ public class MassCalculation {
|
||||
eachCMx = (eachMotorCMx*eachMotorMass - eachCasingCMx*eachCasingMass)/eachMass;
|
||||
}
|
||||
|
||||
// System.err.println(String.format("%-40s|Motor: %s.... Mass @%f = %.6f", prefix, motorConfig.toDescription(), simulationTime, eachMass ));
|
||||
// System.err.println(String.format("%-40s|Motor: %s.... Mass @%f = %.6f", prefix, motorConfig.toDescription(), motorTime, eachMass ));
|
||||
|
||||
|
||||
// coordinates in rocket frame; Ir, It about CoM.
|
||||
@ -390,15 +408,15 @@ public class MassCalculation {
|
||||
// }
|
||||
|
||||
if (component.isMotorMount()) {
|
||||
MassCalculation propellant = this.copy(component, parentTransform);
|
||||
MassCalculation motor = this.copy(component, parentTransform);
|
||||
|
||||
propellant.calculateMountData();
|
||||
motor.calculateMountData();
|
||||
|
||||
this.merge( propellant );
|
||||
this.merge( motor );
|
||||
|
||||
// // vvv DEBUG
|
||||
// if( 0 < propellant.getMass() ) {
|
||||
// System.err.println(String.format( "%s........++ propellantData: %s", prefix, propellant.toCMDebug()));
|
||||
// if( 0 < motor.getMass() ) {
|
||||
// System.err.println(String.format( "%s........++ motorData: %s", prefix, propellant.toCMDebug()));
|
||||
// }
|
||||
|
||||
}
|
||||
|
@ -1,11 +1,13 @@
|
||||
package net.sf.openrocket.masscalc;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import net.sf.openrocket.motor.Motor;
|
||||
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
import net.sf.openrocket.simulation.MotorClusterState;
|
||||
import net.sf.openrocket.simulation.SimulationStatus;
|
||||
import net.sf.openrocket.util.*;
|
||||
|
||||
@ -19,7 +21,7 @@ public class MassCalculator implements Monitorable {
|
||||
*/
|
||||
// private HashMap< Integer, MassData> stageMassCache = new HashMap<Integer, MassData >();
|
||||
// private MassData rocketSpentMassCache;
|
||||
// private MassData propellantMassCache;
|
||||
// private MassData motorMassCache;
|
||||
|
||||
private int modId = 0;
|
||||
|
||||
@ -97,20 +99,23 @@ public class MassCalculator implements Monitorable {
|
||||
////////////////// Mass property Wrappers ///////////////////
|
||||
// all mass calculation calls should probably call through one of these two wrappers.
|
||||
|
||||
// convenience wrapper -- use this to implicitly create a plain MassCalculation object with common parameters
|
||||
// convenience wrapper -- use this to implicitly create a plain MassCalculation object with common parameters,
|
||||
// for calculations in the course of a simulation
|
||||
public static RigidBody calculate( final MassCalculation.Type _type, final SimulationStatus status ){
|
||||
final FlightConfiguration config = status.getConfiguration();
|
||||
final double time = status.getSimulationTime();
|
||||
MassCalculation calculation= new MassCalculation( _type, config, time, config.getRocket(), Transformation.IDENTITY, null);
|
||||
final Collection<MotorClusterState> activeMotorList = status.getMotors();
|
||||
MassCalculation calculation= new MassCalculation( _type, config, time, activeMotorList, config.getRocket(), Transformation.IDENTITY, null);
|
||||
|
||||
calculation.calculateAssembly();
|
||||
RigidBody result = calculation.calculateMomentOfInertia();
|
||||
return result;
|
||||
}
|
||||
|
||||
// convenience wrapper -- use this to implicitly create a plain MassCalculation object with common parameters
|
||||
// convenience wrapper -- use this to implicitly create a plain MassCalculation object with common parameters,
|
||||
// for static mass calculations
|
||||
public static RigidBody calculate( final MassCalculation.Type _type, final FlightConfiguration _config, double _time){
|
||||
MassCalculation calculation = new MassCalculation( _type, _config, _time, _config.getRocket(), Transformation.IDENTITY, null);
|
||||
MassCalculation calculation = new MassCalculation( _type, _config, _time, null, _config.getRocket(), Transformation.IDENTITY, null);
|
||||
calculation.calculateAssembly();
|
||||
return calculation.calculateMomentOfInertia();
|
||||
}
|
||||
@ -141,6 +146,7 @@ public class MassCalculator implements Monitorable {
|
||||
MassCalculation.Type.LAUNCH,
|
||||
config,
|
||||
Motor.PSEUDO_TIME_LAUNCH,
|
||||
null,
|
||||
config.getRocket(),
|
||||
Transformation.IDENTITY,
|
||||
analysisMap);
|
||||
|
@ -204,7 +204,7 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
|
||||
*/
|
||||
public boolean isStageActive(int stageNumber) {
|
||||
if( -1 == stageNumber ) {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
return stages.get(stageNumber).active;
|
||||
@ -289,15 +289,17 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
|
||||
*/
|
||||
public InstanceMap getActiveInstances() {
|
||||
InstanceMap contexts = new InstanceMap();
|
||||
getContextListAt( this.rocket, contexts, Transformation.IDENTITY);
|
||||
getActiveContextListAt( this.rocket, contexts, Transformation.IDENTITY);
|
||||
return contexts;
|
||||
}
|
||||
|
||||
private InstanceMap getContextListAt(final RocketComponent component, final InstanceMap results, final Transformation parentTransform ){
|
||||
private InstanceMap getActiveContextListAt(final RocketComponent component, final InstanceMap results, final Transformation parentTransform ){
|
||||
final boolean active = this.isComponentActive(component);
|
||||
if (!active)
|
||||
return results;
|
||||
final int instanceCount = component.getInstanceCount();
|
||||
final Coordinate[] allOffsets = component.getInstanceOffsets();
|
||||
final double[] allAngles = component.getInstanceAngles();
|
||||
final boolean active = this.isComponentActive(component);
|
||||
|
||||
final Transformation compLocTransform = Transformation.getTranslationTransform( component.getPosition() );
|
||||
final Transformation componentTransform = parentTransform.applyTransformation(compLocTransform);
|
||||
@ -307,13 +309,13 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
|
||||
final Transformation offsetTransform = Transformation.getTranslationTransform( allOffsets[currentInstanceNumber] );
|
||||
final Transformation angleTransform = Transformation.getAxialRotation(allAngles[currentInstanceNumber]);
|
||||
final Transformation currentTransform = componentTransform.applyTransformation(offsetTransform)
|
||||
.applyTransformation(angleTransform);
|
||||
|
||||
.applyTransformation(angleTransform);
|
||||
|
||||
// constructs entry in-place
|
||||
results.emplace(component, active, currentInstanceNumber, currentTransform);
|
||||
|
||||
for(RocketComponent child : component.getChildren()) {
|
||||
getContextListAt(child, results, currentTransform);
|
||||
getActiveContextListAt(child, results, currentTransform);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -122,7 +122,7 @@ public class BasicLandingStepper extends AbstractSimulationStepper {
|
||||
data.setValue(FlightDataType.TYPE_MACH_NUMBER, mach);
|
||||
|
||||
data.setValue(FlightDataType.TYPE_MASS, mass);
|
||||
data.setValue(FlightDataType.TYPE_PROPELLANT_MASS, 0.0); // Is this a reasonable assumption? Probably.
|
||||
data.setValue(FlightDataType.TYPE_MOTOR_MASS, 0.0); // Is this a reasonable assumption? Probably.
|
||||
|
||||
data.setValue(FlightDataType.TYPE_THRUST_FORCE, 0);
|
||||
data.setValue(FlightDataType.TYPE_DRAG_FORCE, dragForce);
|
||||
|
@ -121,7 +121,7 @@ public class BasicTumbleStepper extends AbstractSimulationStepper {
|
||||
data.setValue(FlightDataType.TYPE_MACH_NUMBER, mach);
|
||||
|
||||
data.setValue(FlightDataType.TYPE_MASS, mass);
|
||||
data.setValue(FlightDataType.TYPE_PROPELLANT_MASS, 0.0); // Is this a reasonable assumption? Probably.
|
||||
data.setValue(FlightDataType.TYPE_MOTOR_MASS, 0.0); // Is this a reasonable assumption? Probably.
|
||||
|
||||
data.setValue(FlightDataType.TYPE_THRUST_FORCE, 0);
|
||||
data.setValue(FlightDataType.TYPE_DRAG_FORCE, dragForce);
|
||||
|
@ -91,8 +91,8 @@ public class FlightDataType implements Comparable<FlightDataType> {
|
||||
//// Stability information
|
||||
//// Mass
|
||||
public static final FlightDataType TYPE_MASS = newType(trans.get("FlightDataType.TYPE_MASS"), "m", UnitGroup.UNITS_MASS, 50);
|
||||
//// Propellant mass
|
||||
public static final FlightDataType TYPE_PROPELLANT_MASS = newType(trans.get("FlightDataType.TYPE_PROPELLANT_MASS"), "mp", UnitGroup.UNITS_MASS, 51);
|
||||
//// Motor mass
|
||||
public static final FlightDataType TYPE_MOTOR_MASS = newType(trans.get("FlightDataType.TYPE_MOTOR_MASS"), "mp", UnitGroup.UNITS_MASS, 51);
|
||||
//// Longitudinal moment of inertia
|
||||
public static final FlightDataType TYPE_LONGITUDINAL_INERTIA = newType(trans.get("FlightDataType.TYPE_LONGITUDINAL_INERTIA"), "Il", UnitGroup.UNITS_INERTIA, 52);
|
||||
//// Rotational moment of inertia
|
||||
@ -209,7 +209,7 @@ public class FlightDataType implements Comparable<FlightDataType> {
|
||||
TYPE_PITCH_RATE,
|
||||
TYPE_YAW_RATE,
|
||||
TYPE_MASS,
|
||||
TYPE_PROPELLANT_MASS,
|
||||
TYPE_MOTOR_MASS,
|
||||
TYPE_LONGITUDINAL_INERTIA,
|
||||
TYPE_ROTATIONAL_INERTIA,
|
||||
TYPE_CP_LOCATION,
|
||||
|
@ -62,7 +62,7 @@ public class GroundStepper extends AbstractSimulationStepper {
|
||||
data.setValue(FlightDataType.TYPE_MACH_NUMBER, 0.0);
|
||||
|
||||
data.setValue(FlightDataType.TYPE_MASS, calculateStructureMass(status).getMass());
|
||||
data.setValue(FlightDataType.TYPE_PROPELLANT_MASS, 0.0); // Is this a reasonable assumption? Probably.
|
||||
data.setValue(FlightDataType.TYPE_MOTOR_MASS, 0.0); // Is this a reasonable assumption? Probably.
|
||||
|
||||
data.setValue(FlightDataType.TYPE_THRUST_FORCE, 0.0);
|
||||
data.setValue(FlightDataType.TYPE_DRAG_FORCE, 0.0);
|
||||
|
@ -115,7 +115,7 @@ public class MotorClusterState {
|
||||
}
|
||||
|
||||
public double getMotorTime( final double _simulationTime ){
|
||||
return _simulationTime - this.getIgnitionTime();
|
||||
return Math.max(_simulationTime - this.getIgnitionTime(), 0.0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -613,9 +613,9 @@ public class RK4SimulationStepper extends AbstractSimulationStepper {
|
||||
}
|
||||
|
||||
if( null != store.motorMass ){
|
||||
data.setValue(FlightDataType.TYPE_PROPELLANT_MASS, store.motorMass.getMass());
|
||||
//data.setValue(FlightDataType.TYPE_PROPELLANT_LONGITUDINAL_INERTIA, store.propellantMassData.getLongitudinalInertia());
|
||||
//data.setValue(FlightDataType.TYPE_PROPELLANT_ROTATIONAL_INERTIA, store.propellantMassData.getRotationalInertia());
|
||||
data.setValue(FlightDataType.TYPE_MOTOR_MASS, store.motorMass.getMass());
|
||||
//data.setValue(FlightDataType.TYPE_MOTOR_LONGITUDINAL_INERTIA, store.motorMassData.getLongitudinalInertia());
|
||||
//data.setValue(FlightDataType.TYPE_MOTOR_ROTATIONAL_INERTIA, store.motorMassData.getRotationalInertia());
|
||||
}
|
||||
if (store.rocketMass != null) {
|
||||
// N.B.: These refer to total mass
|
||||
|
@ -41,7 +41,7 @@ public class DampingMoment extends AbstractSimulationListener {
|
||||
// dm/dt = (thrust - ma)/v
|
||||
FlightDataBranch data = status.getFlightData();
|
||||
|
||||
List<Double> mpAll = data.get(FlightDataType.TYPE_PROPELLANT_MASS);
|
||||
List<Double> mpAll = data.get(FlightDataType.TYPE_MOTOR_MASS);
|
||||
List<Double> time = data.get(FlightDataType.TYPE_TIME);
|
||||
if (mpAll == null || time == null) {
|
||||
return Double.NaN;
|
||||
|
@ -2,6 +2,8 @@ package net.sf.openrocket.masscalc;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import net.sf.openrocket.rocketcomponent.*;
|
||||
import net.sf.openrocket.rocketcomponent.position.AngleMethod;
|
||||
import net.sf.openrocket.rocketcomponent.position.AxialMethod;
|
||||
@ -9,6 +11,7 @@ import net.sf.openrocket.rocketcomponent.position.RadiusMethod;
|
||||
import org.junit.Test;
|
||||
|
||||
import net.sf.openrocket.motor.Motor;
|
||||
import net.sf.openrocket.simulation.MotorClusterState;
|
||||
import net.sf.openrocket.simulation.SimulationConditions;
|
||||
import net.sf.openrocket.simulation.SimulationStatus;
|
||||
import net.sf.openrocket.util.Coordinate;
|
||||
@ -135,26 +138,31 @@ public class MassCalculatorTest extends BaseTestCase {
|
||||
|
||||
// this is probably not enough for a full-up simulation, but it IS enough for a motor-mass calculation.
|
||||
SimulationStatus status = new SimulationStatus(config, new SimulationConditions());
|
||||
|
||||
|
||||
// Ignite motor at 1.0 seconds
|
||||
MotorClusterState currentMotorState = ((List<MotorClusterState>) status.getMotors()).get(0);
|
||||
final double ignitionTime = 1.0;
|
||||
currentMotorState.ignite(ignitionTime);
|
||||
|
||||
{
|
||||
final double simTime = 0.03; // almost launch
|
||||
final double simTime = 1.03; // almost launch
|
||||
status.setSimulationTime(simTime);
|
||||
RigidBody actualMotorData = MassCalculator.calculateMotor(status);
|
||||
double expMass = activeMotor.getTotalMass(simTime);
|
||||
double expMass = activeMotor.getTotalMass(simTime - ignitionTime);
|
||||
assertEquals(" Motor Mass " + desig + " is incorrect: ", expMass, actualMotorData.getMass(), EPSILON);
|
||||
}
|
||||
{
|
||||
final double simTime = 1.03; // middle
|
||||
final double simTime = 2.03; // middle
|
||||
status.setSimulationTime(simTime);
|
||||
RigidBody actualMotorData = MassCalculator.calculateMotor(status);
|
||||
double expMass = activeMotor.getTotalMass(simTime);
|
||||
double expMass = activeMotor.getTotalMass(simTime - ignitionTime);
|
||||
assertEquals(" Motor Mass " + desig + " is incorrect: ", expMass, actualMotorData.getMass(), EPSILON);
|
||||
}
|
||||
{
|
||||
final double simTime = 2.03; // after burnout
|
||||
final double simTime = 3.03; // after burnout
|
||||
status.setSimulationTime(simTime);
|
||||
RigidBody actualMotorData = MassCalculator.calculateMotor(status);
|
||||
double expMass = activeMotor.getTotalMass(simTime);
|
||||
double expMass = activeMotor.getTotalMass(simTime - ignitionTime);
|
||||
assertEquals(" Motor Mass " + desig + " is incorrect: ", expMass, actualMotorData.getMass(), EPSILON);
|
||||
}
|
||||
}
|
||||
|
@ -350,6 +350,7 @@ public class FlightConfigurationTest extends BaseTestCase {
|
||||
FlightConfiguration selected = rocket.getSelectedConfiguration();
|
||||
|
||||
selected.clearAllStages();
|
||||
selected.toggleStage(1);
|
||||
selected.toggleStage(2);
|
||||
|
||||
// vvvv Test Target vvvv
|
||||
|
@ -145,7 +145,7 @@ public class DesignReport {
|
||||
private static final String MAX_THRUST = "Max Thrust";
|
||||
private static final String TOTAL_IMPULSE = "Total Impulse";
|
||||
private static final String THRUST_TO_WT = "Thrust to Wt";
|
||||
private static final String PROPELLANT_WT = "Propellant Wt";
|
||||
private static final String MOTOR_WT = "Motor Wt";
|
||||
private static final String SIZE = "Size";
|
||||
private static final String ALTITUDE = "Altitude";
|
||||
private static final String FLIGHT_TIME = "Flight Time";
|
||||
@ -377,7 +377,7 @@ public class DesignReport {
|
||||
motorTable.addCell(ITextHelper.createCell(MAX_THRUST, PdfPCell.BOTTOM, PrintUtilities.SMALL));
|
||||
motorTable.addCell(ITextHelper.createCell(TOTAL_IMPULSE, PdfPCell.BOTTOM, PrintUtilities.SMALL));
|
||||
motorTable.addCell(ITextHelper.createCell(THRUST_TO_WT, PdfPCell.BOTTOM, PrintUtilities.SMALL));
|
||||
motorTable.addCell(ITextHelper.createCell(PROPELLANT_WT, PdfPCell.BOTTOM, PrintUtilities.SMALL));
|
||||
motorTable.addCell(ITextHelper.createCell(MOTOR_WT, PdfPCell.BOTTOM, PrintUtilities.SMALL));
|
||||
motorTable.addCell(ITextHelper.createCell(SIZE, PdfPCell.BOTTOM, PrintUtilities.SMALL));
|
||||
|
||||
DecimalFormat ttwFormat = new DecimalFormat("0.00");
|
||||
|
Loading…
x
Reference in New Issue
Block a user