[#1460] Exclude inactive stages in tbe simulation calculations
This commit is contained in:
parent
77bad60155
commit
027ed2eaa6
@ -68,5 +68,5 @@ public interface AerodynamicCalculator extends Monitorable {
|
||||
*/
|
||||
public AerodynamicCalculator newInstance();
|
||||
|
||||
public boolean isContinuous( final Rocket rkt);
|
||||
public boolean isContinuous(FlightConfiguration configuration, final Rocket rkt);
|
||||
}
|
||||
|
@ -81,7 +81,7 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
|
||||
Map<RocketComponent, AerodynamicForces> assemblyMap = new LinkedHashMap<>();
|
||||
|
||||
// Calculate non-axial force data
|
||||
calculateForceAnalysis(conditions, configuration.getRocket(), instMap, eachMap, assemblyMap, warnings);
|
||||
calculateForceAnalysis(configuration, conditions, configuration.getRocket(), instMap, eachMap, assemblyMap, warnings);
|
||||
|
||||
// Calculate drag coefficient data
|
||||
AerodynamicForces rocketForces = assemblyMap.get(configuration.getRocket());
|
||||
@ -126,7 +126,8 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
|
||||
return finalMap;
|
||||
}
|
||||
|
||||
private AerodynamicForces calculateForceAnalysis( FlightConditions conds,
|
||||
private AerodynamicForces calculateForceAnalysis( FlightConfiguration configuration,
|
||||
FlightConditions conds,
|
||||
RocketComponent comp,
|
||||
InstanceMap instances,
|
||||
Map<RocketComponent, AerodynamicForces> eachForces,
|
||||
@ -154,12 +155,11 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
|
||||
|
||||
for( RocketComponent child : comp.getChildren()) {
|
||||
// Ignore inactive stages
|
||||
if (child instanceof AxialStage &&
|
||||
!((AxialStage) child).isStageActive()) {
|
||||
if (child instanceof AxialStage && !configuration.isStageActive(child.getStageNumber())) {
|
||||
continue;
|
||||
}
|
||||
// forces particular to each component
|
||||
AerodynamicForces childForces = calculateForceAnalysis(conds, child, instances, eachForces, assemblyForces, warnings);
|
||||
AerodynamicForces childForces = calculateForceAnalysis(configuration, conds, child, instances, eachForces, assemblyForces, warnings);
|
||||
|
||||
if(null != childForces) {
|
||||
aggregateForces.merge(childForces);
|
||||
@ -246,7 +246,7 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
|
||||
if (calcMap == null)
|
||||
buildCalcMap(configuration);
|
||||
|
||||
if( ! isContinuous( configuration.getRocket() ) ){
|
||||
if (!isContinuous(configuration, configuration.getRocket())){
|
||||
warnings.add( Warning.DIAMETER_DISCONTINUITY);
|
||||
}
|
||||
|
||||
@ -272,16 +272,15 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isContinuous( final Rocket rkt){
|
||||
return testIsContinuous( rkt);
|
||||
public boolean isContinuous(FlightConfiguration configuration, final Rocket rkt){
|
||||
return testIsContinuous(configuration, rkt);
|
||||
}
|
||||
|
||||
private boolean testIsContinuous( final RocketComponent treeRoot ){
|
||||
private boolean testIsContinuous(FlightConfiguration configuration, final RocketComponent treeRoot ){
|
||||
Queue<RocketComponent> queue = new LinkedList<>();
|
||||
for (RocketComponent child : treeRoot.getChildren()) {
|
||||
// Ignore inactive stages
|
||||
if (child instanceof AxialStage &&
|
||||
!((AxialStage) child).isStageActive()) {
|
||||
if (child instanceof AxialStage && !configuration.isStageActive(child.getStageNumber())) {
|
||||
continue;
|
||||
}
|
||||
queue.add(child);
|
||||
@ -294,8 +293,7 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
|
||||
if( comp instanceof SymmetricComponent ){
|
||||
for (RocketComponent child : comp.getChildren()) {
|
||||
// Ignore inactive stages
|
||||
if (child instanceof AxialStage &&
|
||||
!((AxialStage) child).isStageActive()) {
|
||||
if (child instanceof AxialStage && !configuration.isStageActive(child.getStageNumber())) {
|
||||
continue;
|
||||
}
|
||||
queue.add(child);
|
||||
@ -323,7 +321,7 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
|
||||
|
||||
prevComp = sym;
|
||||
}else if( comp instanceof ComponentAssembly ){
|
||||
isContinuous &= testIsContinuous( comp );
|
||||
isContinuous &= testIsContinuous(configuration, comp);
|
||||
}
|
||||
|
||||
}
|
||||
@ -339,7 +337,7 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
|
||||
* @param configuration Rocket configuration
|
||||
* @param conditions Flight conditions taken into account
|
||||
* @param map ?
|
||||
* @param set Set to handle
|
||||
* @param warningSet Set to handle warnings
|
||||
* @return friction drag for entire rocket
|
||||
*/
|
||||
private double calculateFrictionCD(FlightConfiguration configuration, FlightConditions conditions,
|
||||
|
@ -104,7 +104,7 @@ public class MassCalculator implements Monitorable {
|
||||
public static RigidBody calculate( final MassCalculation.Type _type, final SimulationStatus status ){
|
||||
final FlightConfiguration config = status.getConfiguration();
|
||||
final double time = status.getSimulationTime();
|
||||
final Collection<MotorClusterState> activeMotorList = status.getMotors();
|
||||
final Collection<MotorClusterState> activeMotorList = status.getActiveMotors();
|
||||
MassCalculation calculation= new MassCalculation( _type, config, time, activeMotorList, config.getRocket(), Transformation.IDENTITY, null);
|
||||
|
||||
calculation.calculateAssembly();
|
||||
|
@ -4,6 +4,7 @@ import java.util.Locale;
|
||||
|
||||
import net.sf.openrocket.l10n.Translator;
|
||||
import net.sf.openrocket.rocketcomponent.AxialStage;
|
||||
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
import net.sf.openrocket.simulation.FlightEvent;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
@ -13,25 +14,25 @@ public enum IgnitionEvent {
|
||||
//// Automatic (launch or ejection charge)
|
||||
AUTOMATIC( "AUTOMATIC", "MotorMount.IgnitionEvent.AUTOMATIC"){
|
||||
@Override
|
||||
public boolean isActivationEvent(FlightEvent testEvent, RocketComponent targetComponent) {
|
||||
public boolean isActivationEvent(FlightConfiguration config, FlightEvent testEvent, RocketComponent targetComponent) {
|
||||
AxialStage targetStage = targetComponent.getStage();
|
||||
|
||||
if ( targetStage.isLaunchStage() ){
|
||||
return LAUNCH.isActivationEvent(testEvent, targetComponent);
|
||||
if (targetStage.isLaunchStage(config)) {
|
||||
return LAUNCH.isActivationEvent(config, testEvent, targetComponent);
|
||||
} else {
|
||||
return EJECTION_CHARGE.isActivationEvent(testEvent, targetComponent);
|
||||
return EJECTION_CHARGE.isActivationEvent(config, testEvent, targetComponent);
|
||||
}
|
||||
}
|
||||
},
|
||||
LAUNCH ( "LAUNCH", "MotorMount.IgnitionEvent.LAUNCH"){
|
||||
@Override
|
||||
public boolean isActivationEvent( FlightEvent fe, RocketComponent source){
|
||||
public boolean isActivationEvent(FlightConfiguration config, FlightEvent fe, RocketComponent source){
|
||||
return (fe.getType() == FlightEvent.Type.LAUNCH);
|
||||
}
|
||||
},
|
||||
EJECTION_CHARGE ("EJECTION_CHARGE", "MotorMount.IgnitionEvent.EJECTION_CHARGE"){
|
||||
@Override
|
||||
public boolean isActivationEvent( FlightEvent testEvent, RocketComponent targetComponent){
|
||||
public boolean isActivationEvent(FlightConfiguration config, FlightEvent testEvent, RocketComponent targetComponent){
|
||||
if (testEvent.getType() != FlightEvent.Type.EJECTION_CHARGE){
|
||||
return false;
|
||||
}
|
||||
@ -44,7 +45,7 @@ public enum IgnitionEvent {
|
||||
},
|
||||
BURNOUT ("BURNOUT", "MotorMount.IgnitionEvent.BURNOUT"){
|
||||
@Override
|
||||
public boolean isActivationEvent( FlightEvent testEvent, RocketComponent targetComponent){
|
||||
public boolean isActivationEvent(FlightConfiguration config, FlightEvent testEvent, RocketComponent targetComponent){
|
||||
if (testEvent.getType() != FlightEvent.Type.BURNOUT)
|
||||
return false;
|
||||
|
||||
@ -64,7 +65,7 @@ public enum IgnitionEvent {
|
||||
|
||||
//public static final IgnitionEvent[] events = {AUTOMATIC, LAUNCH, EJECTION_CHARGE, BURNOUT, NEVER};
|
||||
|
||||
public boolean isActivationEvent( FlightEvent fe, RocketComponent source){
|
||||
public boolean isActivationEvent(FlightConfiguration config, FlightEvent fe, RocketComponent source){
|
||||
// default behavior. Also for the NEVER case.
|
||||
return false;
|
||||
}
|
||||
|
@ -130,11 +130,12 @@ public class AxialStage extends ComponentAssembly implements FlightConfigurableC
|
||||
|
||||
/**
|
||||
* returns if the object is a launch stage
|
||||
* @param config the flight configuration which will check which stages are active
|
||||
* @return if the object is a launch stage
|
||||
*/
|
||||
public boolean isLaunchStage(){
|
||||
return ( this instanceof ParallelStage )
|
||||
||( getRocket().getBottomCoreStage().equals(this));
|
||||
public boolean isLaunchStage(FlightConfiguration config) {
|
||||
return ((this instanceof ParallelStage && config.isStageActive(this.stageNumber))
|
||||
||( getRocket().getBottomCoreStage(config).equals(this)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -60,8 +60,8 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
|
||||
}
|
||||
|
||||
/* Cached data */
|
||||
final protected HashMap<Integer, StageFlags> stages = new HashMap<Integer, StageFlags>();
|
||||
final protected HashMap<MotorConfigurationId, MotorConfiguration> motors = new HashMap<MotorConfigurationId, MotorConfiguration>();
|
||||
final protected Map<Integer, StageFlags> stages = new HashMap<Integer, StageFlags>();
|
||||
final protected Map<MotorConfigurationId, MotorConfiguration> motors = new HashMap<MotorConfigurationId, MotorConfiguration>();
|
||||
final private Collection<MotorConfiguration> activeMotors = new ArrayList<MotorConfiguration>();
|
||||
final private InstanceMap activeInstances = new InstanceMap();
|
||||
|
||||
@ -190,7 +190,7 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
|
||||
* @param stageNumber stage number to flag
|
||||
* @param _active inactive (<code>false</code>) or active (<code>true</code>)
|
||||
*/
|
||||
private void _setStageActive(final int stageNumber, final boolean _active ) {
|
||||
public void _setStageActive(final int stageNumber, final boolean _active ) {
|
||||
if ((0 <= stageNumber) && (stages.containsKey(stageNumber))) {
|
||||
stages.get(stageNumber).active = _active;
|
||||
fireChangeEvent();
|
||||
@ -338,6 +338,18 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all the stages in this configuration.
|
||||
* @return all the stages in this configuration.
|
||||
*/
|
||||
public List<AxialStage> getAllStages() {
|
||||
List<AxialStage> stages = new ArrayList<>();
|
||||
for (StageFlags flags : this.stages.values()) {
|
||||
stages.add( rocket.getStage(flags.stageNumber));
|
||||
}
|
||||
return stages;
|
||||
}
|
||||
|
||||
public List<AxialStage> getActiveStages() {
|
||||
List<AxialStage> activeStages = new ArrayList<>();
|
||||
|
@ -197,24 +197,37 @@ public class Rocket extends ComponentAssembly {
|
||||
public AxialStage getStage( final int stageNumber ) {
|
||||
return this.stageMap.get( stageNumber);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the stage at the top of the central stack
|
||||
*
|
||||
* @Return a reference to the topmost stage
|
||||
|
||||
/**
|
||||
* Get the topmost stage, only taking into account active stages from the flight configuration.
|
||||
* @param config flight configuration dictating which stages are active
|
||||
* @return the topmost active stage, or null if there are no active stages.
|
||||
*/
|
||||
public AxialStage getTopmostStage(){
|
||||
return (AxialStage) getChild(0);
|
||||
public AxialStage getTopmostStage(FlightConfiguration config) {
|
||||
if (config == null) return null;
|
||||
|
||||
for (int i = 0; i < getChildCount(); i++) {
|
||||
if (getChild(i) instanceof AxialStage && config.isStageActive(getChild(i).getStageNumber())) {
|
||||
return (AxialStage) getChild(i);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the stage at the top of the central stack
|
||||
*
|
||||
* @Return a reference to the topmost stage
|
||||
|
||||
/**
|
||||
* Get the bottommost stage, only taking into account active stages from the flight configuration.
|
||||
* @param config flight configuration dictating which stages are active
|
||||
* @return the bottommost active stage, or null if there are no active stages.
|
||||
*/
|
||||
/*package-local*/ AxialStage getBottomCoreStage(){
|
||||
// get last stage that's a direct child of the rocket.
|
||||
return (AxialStage) children.get( children.size()-1 );
|
||||
public AxialStage getBottomCoreStage(FlightConfiguration config) {
|
||||
if (config == null) return null;
|
||||
|
||||
for (int i = getChildCount() - 1; i >= 0; i--) {
|
||||
if (getChild(i) instanceof AxialStage && config.isStageActive(getChild(i).getStageNumber())) {
|
||||
return (AxialStage) getChild(i);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -45,7 +45,7 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
||||
private final static double AOA_TUMBLE_CONDITION = Math.PI / 9.0;
|
||||
|
||||
// The thrust must be below this value for the transition to tumbling.
|
||||
// TODO: this is an arbitrary value
|
||||
// TODO HIGH: this is an arbitrary value
|
||||
private final static double THRUST_TUMBLE_CONDITION = 0.01;
|
||||
|
||||
private SimulationStepper currentStepper;
|
||||
@ -65,7 +65,9 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
||||
|
||||
// Set up rocket configuration
|
||||
this.fcid = simulationConditions.getFlightConfigurationID();
|
||||
FlightConfiguration simulationConfig = simulationConditions.getRocket().getFlightConfiguration( this.fcid).clone();
|
||||
FlightConfiguration origConfig = simulationConditions.getRocket().getFlightConfiguration(this.fcid);
|
||||
FlightConfiguration simulationConfig = origConfig.clone();
|
||||
simulationConfig.copyStages(origConfig); // Clone the stage activation configuration
|
||||
if ( ! simulationConfig.hasMotors() ) {
|
||||
throw new MotorIgnitionException(trans.get("BasicEventSimulationEngine.error.noMotorsDefined"));
|
||||
}
|
||||
@ -74,7 +76,7 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
||||
currentStatus.getEventQueue().add(new FlightEvent(FlightEvent.Type.LAUNCH, 0, simulationConditions.getRocket()));
|
||||
{
|
||||
// main simulation branch
|
||||
final String branchName = simulationConfig.getRocket().getTopmostStage().getName();
|
||||
final String branchName = simulationConfig.getRocket().getTopmostStage(currentStatus.getConfiguration()).getName();
|
||||
currentStatus.setFlightData(new FlightDataBranch( branchName, FlightDataType.TYPE_TIME));
|
||||
}
|
||||
toSimulate.push(currentStatus);
|
||||
@ -273,9 +275,7 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
||||
|
||||
// Check for motor ignition events, add ignition events to queue
|
||||
for (MotorClusterState state : currentStatus.getActiveMotors() ){
|
||||
if( state.testForIgnition(event )){
|
||||
final double simulationTime = currentStatus.getSimulationTime() ;
|
||||
|
||||
if (state.testForIgnition(currentStatus.getConfiguration(), event)) {
|
||||
MotorClusterState sourceState = (MotorClusterState) event.getData();
|
||||
double ignitionDelay = 0;
|
||||
if (event.getType() == FlightEvent.Type.BURNOUT)
|
||||
@ -543,7 +543,7 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
||||
|
||||
}
|
||||
|
||||
// TODO : FUTURE : do not hard code the 1200 (maybe even make it configurable by the user)
|
||||
// TODO FUTURE : do not hard code the 1200 (maybe even make it configurable by the user)
|
||||
if( 1200 < currentStatus.getSimulationTime() ){
|
||||
ret = false;
|
||||
log.error("Simulation hit max time (1200s): aborting.");
|
||||
@ -553,6 +553,7 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
||||
|
||||
// If no motor has ignited, abort
|
||||
if (!currentStatus.isMotorIgnited()) {
|
||||
// TODO MEDIUM: display this as a warning to the user (e.g. highlight the cell in the simulation panel in red and a hover: 'make sure the motor ignition is correct' or something)
|
||||
throw new MotorIgnitionException(trans.get("BasicEventSimulationEngine.error.noIgnition"));
|
||||
}
|
||||
|
||||
|
@ -172,7 +172,7 @@ public class FlightEvent implements Comparable<FlightEvent> {
|
||||
* @return
|
||||
*/
|
||||
public void validate(){
|
||||
if( this.time == Double.NaN ){
|
||||
if(Double.isNaN(this.time)){
|
||||
throw new IllegalStateException(type.name()+" event has a NaN time!");
|
||||
}
|
||||
switch( this.type ){
|
||||
|
@ -4,6 +4,7 @@ import net.sf.openrocket.motor.IgnitionEvent;
|
||||
import net.sf.openrocket.motor.Motor;
|
||||
import net.sf.openrocket.motor.MotorConfiguration;
|
||||
import net.sf.openrocket.motor.MotorConfigurationId;
|
||||
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
|
||||
import net.sf.openrocket.rocketcomponent.MotorMount;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
|
||||
@ -121,8 +122,8 @@ public class MotorClusterState {
|
||||
/**
|
||||
* Compute the average thrust over an interval.
|
||||
*
|
||||
* @param simulationTime
|
||||
* @param cond
|
||||
* @param startSimulationTime start time of the averaging interval
|
||||
* @param endSimulationTime end time of the averaging interval
|
||||
* @return
|
||||
*/
|
||||
public double getAverageThrust( final double startSimulationTime, final double endSimulationTime) {
|
||||
@ -141,7 +142,6 @@ public class MotorClusterState {
|
||||
* Compute the average thrust over an interval.
|
||||
*
|
||||
* @param simulationTime
|
||||
* @param cond
|
||||
* @return
|
||||
*/
|
||||
public double getThrust( final double simulationTime){
|
||||
@ -182,9 +182,9 @@ public class MotorClusterState {
|
||||
currentState = ThrustState.ARMED;
|
||||
}
|
||||
|
||||
public boolean testForIgnition( final FlightEvent _event ){
|
||||
public boolean testForIgnition(FlightConfiguration flightConfiguration, final FlightEvent _event ){
|
||||
RocketComponent mount = (RocketComponent) this.getMount();
|
||||
return getIgnitionEvent().isActivationEvent( _event, mount);
|
||||
return getIgnitionEvent().isActivationEvent(flightConfiguration, _event, mount);
|
||||
}
|
||||
|
||||
public String toDescription(){
|
||||
|
@ -267,22 +267,25 @@ public class BarrowmanCalculatorTest {
|
||||
public void testContinuousRocket() {
|
||||
Rocket rocket = TestRockets.makeEstesAlphaIII();
|
||||
AerodynamicCalculator calc = new BarrowmanCalculator();
|
||||
FlightConfiguration configuration = rocket.getSelectedConfiguration();
|
||||
|
||||
assertTrue("Estes Alpha III should be continous: ", calc.isContinuous( rocket));
|
||||
assertTrue("Estes Alpha III should be continous: ", calc.isContinuous(configuration, rocket));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testContinuousRocketWithStrapOns() {
|
||||
Rocket rocket = TestRockets.makeFalcon9Heavy();
|
||||
AerodynamicCalculator calc = new BarrowmanCalculator();
|
||||
FlightConfiguration configuration = rocket.getSelectedConfiguration();
|
||||
|
||||
assertTrue("F9H should be continuous: ", calc.isContinuous( rocket));
|
||||
assertTrue("F9H should be continuous: ", calc.isContinuous(configuration, rocket));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRadialDiscontinuousRocket() {
|
||||
Rocket rocket = TestRockets.makeEstesAlphaIII();
|
||||
AerodynamicCalculator calc = new BarrowmanCalculator();
|
||||
FlightConfiguration configuration = rocket.getSelectedConfiguration();
|
||||
|
||||
NoseCone nose = (NoseCone)rocket.getChild(0).getChild(0);
|
||||
BodyTube body = (BodyTube)rocket.getChild(0).getChild(1);
|
||||
@ -291,13 +294,14 @@ public class BarrowmanCalculatorTest {
|
||||
body.setOuterRadius( 0.012 );
|
||||
body.setName( body.getName()+" << discontinuous");
|
||||
|
||||
assertFalse(" Estes Alpha III has an undetected discontinuity:", calc.isContinuous( rocket));
|
||||
assertFalse(" Estes Alpha III has an undetected discontinuity:", calc.isContinuous(configuration, rocket));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRadialDiscontinuityWithStrapOns() {
|
||||
Rocket rocket = TestRockets.makeFalcon9Heavy();
|
||||
AerodynamicCalculator calc = new BarrowmanCalculator();
|
||||
FlightConfiguration configuration = rocket.getSelectedConfiguration();
|
||||
|
||||
final AxialStage coreStage = (AxialStage)rocket.getChild(1);
|
||||
final ParallelStage booster = (ParallelStage)coreStage.getChild(0).getChild(0);
|
||||
@ -309,7 +313,7 @@ public class BarrowmanCalculatorTest {
|
||||
body.setOuterRadius( 0.012 );
|
||||
body.setName( body.getName()+" << discontinuous");
|
||||
|
||||
assertFalse(" Missed discontinuity in Falcon 9 Heavy:", calc.isContinuous( rocket));
|
||||
assertFalse(" Missed discontinuity in Falcon 9 Heavy:", calc.isContinuous(configuration, rocket));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -295,8 +295,8 @@ public class FlightConfigurationTest extends BaseTestCase {
|
||||
config.toggleStage(0);
|
||||
assertThat(" toggle stage #0: ", config.isStageActive(0), equalTo(false));
|
||||
|
||||
AxialStage sustainer = rkt.getTopmostStage();
|
||||
AxialStage booster = rkt.getBottomCoreStage();
|
||||
AxialStage sustainer = rkt.getTopmostStage(config);
|
||||
AxialStage booster = rkt.getBottomCoreStage(config);
|
||||
assertThat(" sustainer stage is stage #0: ", sustainer.getStageNumber(), equalTo(0));
|
||||
assertThat(" booster stage is stage #1: ", booster.getStageNumber(), equalTo(1));
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user