public void setMotorMount(MotorMount mount) { if (mount != null) { for (MotorConfiguration m : mount.getMotorConfiguration()) { this.usedMotors.add((ThrustCurveMotor) m.getMotor()); } } }
/** * Create a new motor instance configuration for the rocket configuration. * * @param configuration the rocket configuration. * @return a new motor instance configuration with all motors in place. */ private MotorInstanceConfiguration setupMotorConfiguration(Configuration configuration) { MotorInstanceConfiguration motors = new MotorInstanceConfiguration(); final String motorId = configuration.getMotorConfigurationID(); Iterator<MotorMount> iterator = configuration.motorIterator(); while (iterator.hasNext()) { MotorMount mount = iterator.next(); RocketComponent component = (RocketComponent) mount; Motor motor = mount.getMotor(motorId); if (motor != null) { Coordinate[] positions = component.toAbsolute(mount.getMotorPosition(motorId)); for (int i = 0; i < positions.length; i++) { Coordinate position = positions[i]; MotorId id = new MotorId(component.getID(), i + 1); motors.addMotor(id, motor.getInstance(), mount, position); } } } return motors; }
/** * Handles events occurring during the flight from the event queue. Each event that has occurred * before or at the current simulation time is processed. Suitable events are also added to the * flight data. */ private boolean handleEvents() throws SimulationException { boolean ret = true; FlightEvent event; for (event = nextEvent(); event != null; event = nextEvent()) { // Ignore events for components that are no longer attached to the rocket if (event.getSource() != null && event.getSource().getParent() != null && !status.getConfiguration().isStageActive(event.getSource().getStageNumber())) { continue; } // Call simulation listeners, allow aborting event handling if (!SimulationListenerHelper.fireHandleFlightEvent(status, event)) { continue; } if (event.getType() != FlightEvent.Type.ALTITUDE) { log.verbose("BasicEventSimulationEngine: Handling event " + event); } if (event.getType() == FlightEvent.Type.IGNITION) { MotorMount mount = (MotorMount) event.getSource(); MotorId motorId = (MotorId) event.getData(); MotorInstance instance = status.getMotorConfiguration().getMotorInstance(motorId); if (!SimulationListenerHelper.fireMotorIgnition(status, motorId, mount, instance)) { continue; } } if (event.getType() == FlightEvent.Type.RECOVERY_DEVICE_DEPLOYMENT) { RecoveryDevice device = (RecoveryDevice) event.getSource(); if (!SimulationListenerHelper.fireRecoveryDeviceDeployment(status, device)) { continue; } } // Check for motor ignition events, add ignition events to queue for (MotorId id : status.getMotorConfiguration().getMotorIDs()) { MotorMount mount = status.getMotorConfiguration().getMotorMount(id); RocketComponent component = (RocketComponent) mount; if (mount.getIgnitionEvent().isActivationEvent(event, component)) { addEvent( new FlightEvent( FlightEvent.Type.IGNITION, status.getSimulationTime() + mount.getIgnitionDelay(), component, id)); } } // Check for stage separation event for (int stageNo : status.getConfiguration().getActiveStages()) { if (stageNo == 0) continue; Stage stage = (Stage) status.getConfiguration().getRocket().getChild(stageNo); if (stage.getSeparationEvent().isSeparationEvent(event, stage)) { addEvent( new FlightEvent( FlightEvent.Type.STAGE_SEPARATION, event.getTime() + stage.getSeparationDelay(), stage)); } } // Check for recovery device deployment, add events to queue Iterator<RocketComponent> rci = status.getConfiguration().iterator(); while (rci.hasNext()) { RocketComponent c = rci.next(); if (!(c instanceof RecoveryDevice)) continue; if (((RecoveryDevice) c).getDeployEvent().isActivationEvent(event, c)) { // Delay event by at least 1ms to allow stage separation to occur first addEvent( new FlightEvent( FlightEvent.Type.RECOVERY_DEVICE_DEPLOYMENT, event.getTime() + Math.max(0.001, ((RecoveryDevice) c).getDeployDelay()), c)); } } // Handle event switch (event.getType()) { case LAUNCH: { status.getFlightData().addEvent(event); break; } case IGNITION: { // Ignite the motor MotorMount mount = (MotorMount) event.getSource(); RocketComponent component = (RocketComponent) mount; MotorId motorId = (MotorId) event.getData(); MotorInstanceConfiguration config = status.getMotorConfiguration(); config.setMotorIgnitionTime(motorId, event.getTime()); status.setMotorIgnited(true); status.getFlightData().addEvent(event); break; } case LIFTOFF: { // Mark lift-off as occurred status.setLiftoff(true); status.getFlightData().addEvent(event); break; } case LAUNCHROD: { // Mark launch rod as cleared status.setLaunchRodCleared(true); status.getFlightData().addEvent(event); break; } case BURNOUT: { // If motor burnout occurs without lift-off, abort if (!status.isLiftoff()) { throw new SimulationLaunchException("Motor burnout without liftoff."); } // Add ejection charge event String id = status.getConfiguration().getMotorConfigurationID(); MotorMount mount = (MotorMount) event.getSource(); double delay = mount.getMotorDelay(id); if (delay != Motor.PLUGGED) { addEvent( new FlightEvent( FlightEvent.Type.EJECTION_CHARGE, status.getSimulationTime() + delay, event.getSource(), event.getData())); } status.getFlightData().addEvent(event); break; } case EJECTION_CHARGE: { status.getFlightData().addEvent(event); break; } case STAGE_SEPARATION: { // TODO: HIGH: Store lower stages to be simulated later RocketComponent stage = event.getSource(); int n = stage.getStageNumber(); status.getConfiguration().setToStage(n - 1); status.getFlightData().addEvent(event); break; } case APOGEE: // Mark apogee as reached status.setApogeeReached(true); status.getFlightData().addEvent(event); break; case RECOVERY_DEVICE_DEPLOYMENT: RocketComponent c = event.getSource(); int n = c.getStageNumber(); // Ignore event if stage not active if (status.getConfiguration().isStageActive(n)) { // TODO: HIGH: Check stage activeness for other events as well? // Check whether any motor in the active stages is active anymore for (MotorId motorId : status.getMotorConfiguration().getMotorIDs()) { int stage = ((RocketComponent) status.getMotorConfiguration().getMotorMount(motorId)) .getStageNumber(); if (!status.getConfiguration().isStageActive(stage)) continue; if (!status.getMotorConfiguration().getMotorInstance(motorId).isActive()) continue; status.getWarnings().add(Warning.RECOVERY_DEPLOYMENT_WHILE_BURNING); } // Check for launch rod if (!status.isLaunchRodCleared()) { status .getWarnings() .add( Warning.fromString( "Recovery device device deployed while on " + "the launch guide.")); } // Check current velocity if (status.getRocketVelocity().length() > 20) { // TODO: LOW: Custom warning. status .getWarnings() .add( Warning.fromString( "Recovery device deployment at high " + "speed (" + UnitGroup.UNITS_VELOCITY.toStringUnit( status.getRocketVelocity().length()) + ").")); } status.setLiftoff(true); status.getDeployedRecoveryDevices().add((RecoveryDevice) c); this.currentStepper = this.landingStepper; this.status = currentStepper.initialize(status); status.getFlightData().addEvent(event); } break; case GROUND_HIT: status.getFlightData().addEvent(event); break; case SIMULATION_END: ret = false; status.getFlightData().addEvent(event); break; case ALTITUDE: break; } } // If no motor has ignited, abort if (!status.isMotorIgnited()) { throw new MotorIgnitionException("No motors ignited."); } return ret; }