public RenameConfigDialog(final Window parent, final Rocket rocket) {
    super(parent, trans.get("RenameConfigDialog.title"), Dialog.ModalityType.APPLICATION_MODAL);
    final String configId = rocket.getDefaultConfiguration().getFlightConfigurationID();

    JPanel panel = new JPanel(new MigLayout("fill"));

    panel.add(new JLabel(trans.get("RenameConfigDialog.lbl.name")), "span, wrap rel");

    final JTextField textbox = new JTextField(rocket.getFlightConfigurationName(configId));
    panel.add(textbox, "span, w 200lp, growx, wrap para");

    panel.add(new JPanel(), "growx");

    JButton okButton = new JButton(trans.get("button.ok"));
    okButton.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e) {
            String newName = textbox.getText();
            rocket.setFlightConfigurationName(configId, newName);
            RenameConfigDialog.this.setVisible(false);
          }
        });
    panel.add(okButton);

    JButton defaultButton = new JButton(trans.get("RenameConfigDialog.but.reset"));
    defaultButton.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e) {
            rocket.setFlightConfigurationName(configId, null);
            RenameConfigDialog.this.setVisible(false);
          }
        });
    panel.add(defaultButton);

    JButton cancel = new JButton(trans.get("button.cancel"));
    cancel.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e) {
            RenameConfigDialog.this.setVisible(false);
          }
        });
    panel.add(cancel);

    this.add(panel);

    GUIUtil.setDisposableDialogOptions(this, okButton);
  }
  private void checkNaN() throws SimulationException {
    double d = 0;
    boolean b = false;
    d += currentStatus.getSimulationTime();
    d += currentStatus.getPreviousTimeStep();
    b |= currentStatus.getRocketPosition().isNaN();
    b |= currentStatus.getRocketVelocity().isNaN();
    b |= currentStatus.getRocketOrientationQuaternion().isNaN();
    b |= currentStatus.getRocketRotationVelocity().isNaN();
    d += currentStatus.getEffectiveLaunchRodLength();

    if (Double.isNaN(d) || b) {
      log.error(
          "Simulation resulted in NaN value:"
              + " simulationTime="
              + currentStatus.getSimulationTime()
              + " previousTimeStep="
              + currentStatus.getPreviousTimeStep()
              + " rocketPosition="
              + currentStatus.getRocketPosition()
              + " rocketVelocity="
              + currentStatus.getRocketVelocity()
              + " rocketOrientationQuaternion="
              + currentStatus.getRocketOrientationQuaternion()
              + " rocketRotationVelocity="
              + currentStatus.getRocketRotationVelocity()
              + " effectiveLaunchRodLength="
              + currentStatus.getEffectiveLaunchRodLength());
      throw new SimulationException(trans.get("BasicEventSimulationEngine.error.NaNResult"));
    }
  }
  @Override
  public FlightData simulate(SimulationConditions simulationConditions) throws SimulationException {

    // Set up flight data
    FlightData flightData = new FlightData();

    // Set up rocket configuration
    this.fcid = simulationConditions.getFlightConfigurationID();
    FlightConfiguration simulationConfig =
        simulationConditions.getRocket().getFlightConfiguration(this.fcid).clone();
    if (!simulationConfig.hasMotors()) {
      throw new MotorIgnitionException(
          trans.get("BasicEventSimulationEngine.error.noMotorsDefined"));
    }

    currentStatus = new SimulationStatus(simulationConfig, simulationConditions);
    currentStatus
        .getEventQueue()
        .add(new FlightEvent(FlightEvent.Type.LAUNCH, 0, simulationConditions.getRocket()));
    {
      // main simulation branch
      final String branchName = simulationConfig.getRocket().getTopmostStage().getName();
      currentStatus.setFlightData(new FlightDataBranch(branchName, FlightDataType.TYPE_TIME));
    }
    toSimulate.add(currentStatus);

    SimulationListenerHelper.fireStartSimulation(currentStatus);
    do {
      if (null == toSimulate.peek()) {
        break;
      }
      currentStatus = toSimulate.pop();
      log.info(">>Starting simulation of branch: " + currentStatus.getFlightData().getBranchName());

      FlightDataBranch dataBranch = simulateLoop();
      flightData.addBranch(dataBranch);
      flightData.getWarningSet().addAll(currentStatus.getWarnings());

      log.info(
          String.format(
              "<<Finished simulating branch: %s    curTime:%s    finTime:%s",
              dataBranch.getBranchName(),
              currentStatus.getSimulationTime(),
              dataBranch.getLast(FlightDataType.TYPE_TIME)));
    } while (!toSimulate.isEmpty());

    SimulationListenerHelper.fireEndSimulation(currentStatus, null);

    if (!flightData.getWarningSet().isEmpty()) {
      log.info("Warnings at the end of simulation:  " + flightData.getWarningSet());
    }

    return flightData;
  }
  private static String getToolTip(RocketComponent c) {
    StringBuilder sb = new StringBuilder();
    sb.append("<html>");

    sb.append("<b>").append(c.getName()).append("</b>");
    if (c.isMassive() || c.isMassOverridden()) {
      sb.append(" (").append(UnitGroup.UNITS_MASS.toStringUnit(c.getMass()));
      if (c.getChildCount() > 0) {
        sb.append(" of ")
            .append(UnitGroup.UNITS_MASS.toStringUnit(c.getSectionMass()))
            .append(" total");
      }
      sb.append(")");
    } else {
      if ((c.getChildCount() > 0) && (c.getSectionMass() > 0)) {
        sb.append(" (")
            .append(UnitGroup.UNITS_MASS.toStringUnit(c.getSectionMass()))
            .append(" total)");
      }
    }

    if (c.isMassOverridden()) {
      sb.append(" ").append(trans.get("ComponentTree.ttip.massoverride"));
    }

    if (c.isCGOverridden()) {
      sb.append(" ").append(trans.get("ComponentTree.ttip.cgoverride"));
    }

    String comment = c.getComment().trim();
    if (comment.length() > 0) {
      comment = TextUtil.escapeXML(comment);
      comment = comment.replace("\n", "<br>");
      sb.append("<br>").append(comment);
    }

    return sb.toString();
  }
  private void launchEditor(boolean useSystemEditor, String commandTemplate, final DecalImage decal)
      throws EditDecalHelperException {

    String decalId = decal.getName();
    // Create Temp File.
    int dotlocation = decalId.lastIndexOf('.');
    String extension = "tmp";
    if (dotlocation > 0 && dotlocation < decalId.length()) {
      extension = decalId.substring(dotlocation);
    }
    File tmpFile = null;

    try {
      tmpFile = File.createTempFile("OR_graphics", extension);
    } catch (IOException ioex) {
      String message =
          MessageFormat.format(
              trans.get("EditDecalHelper.createFileException"), "OR_graphics" + extension);
      throw new EditDecalHelperException(message, ioex);
    }

    try {
      decal.exportImage(tmpFile);
      watchService.register(
          new FileWatcher(tmpFile) {

            @Override
            public void handleEvent(WatchEvent evt) {
              decal.fireChangeEvent(evt);
              // System.out.println(this.getFile() + " has changed");

            }
          });

    } catch (IOException ioex) {
      String message =
          MessageFormat.format(
              trans.get("EditDecalHelper.createFileException"), tmpFile.getAbsoluteFile());
      throw new EditDecalHelperException(message, ioex);
    }

    if (useSystemEditor) {
      try {
        Desktop.getDesktop().edit(tmpFile);
      } catch (Exception ioex) {
        throw new EditDecalHelperException(
            trans.get("EditDecalHelper.launchSystemEditorException"),
            trans.get("EditDecalHelper.editPreferencesHelp"),
            ioex);
      }
    } else {

      String filename = tmpFile.getAbsolutePath();

      String command;
      if (commandTemplate.contains("%%")) {
        command = commandTemplate.replace("%%", filename);
      } else {
        command = commandTemplate + " " + filename;
      }

      try {
        Runtime.getRuntime().exec(command);
      } catch (IOException ioex) {
        String message =
            MessageFormat.format(trans.get("EditDecalHelper.launchCustomEditorException"), command);
        throw new EditDecalHelperException(
            message, trans.get("EditDecalHelper.editPreferencesHelp"), ioex);
      }
    }
  }
  /**
   * 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;

    log.trace("HandleEvents: current branch = " + currentStatus.getFlightData().getBranchName());
    log.trace("EventQueue = " + currentStatus.getEventQueue().toString());
    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
          && !currentStatus.getConfiguration().isComponentActive(event.getSource())) {
        continue;
      }

      // Call simulation listeners, allow aborting event handling
      if (!SimulationListenerHelper.fireHandleFlightEvent(currentStatus, event)) {
        continue;
      }

      if (event.getType() == FlightEvent.Type.RECOVERY_DEVICE_DEPLOYMENT) {
        RecoveryDevice device = (RecoveryDevice) event.getSource();
        if (!SimulationListenerHelper.fireRecoveryDeviceDeployment(currentStatus, device)) {
          continue;
        }
      }

      // Check for motor ignition events, add ignition events to queue
      for (MotorClusterState state : currentStatus.getActiveMotors()) {
        if (state.testForIgnition(event)) {
          final double simulationTime = currentStatus.getSimulationTime();
          MotorClusterState sourceState = (MotorClusterState) event.getData();
          double ignitionDelay = 0;
          if ((event.getType() == FlightEvent.Type.BURNOUT)
              || (event.getType() == FlightEvent.Type.EJECTION_CHARGE)) {
            ignitionDelay = sourceState.getEjectionDelay();
          }
          final double ignitionTime = currentStatus.getSimulationTime() + ignitionDelay;
          final RocketComponent mount = (RocketComponent) state.getMount();

          // TODO:  this event seems to get enqueue'd multiple times ...
          log.info("Queueing Ignition Event for: " + state.toDescription() + " @: " + ignitionTime);
          // log.info("     Because of "+event.getType().name()+" @"+event.getTime()+" from:
          // "+event.getSource().getName());

          addEvent(new FlightEvent(FlightEvent.Type.IGNITION, ignitionTime, mount, state));
        }
      }

      // Check for stage separation event
      for (AxialStage stage : currentStatus.getConfiguration().getActiveStages()) {
        int stageNo = stage.getStageNumber();
        if (stageNo == 0) continue;

        StageSeparationConfiguration separationConfig =
            stage.getSeparationConfigurations().get(this.fcid);
        if (separationConfig.getSeparationEvent().isSeparationEvent(event, stage)) {
          addEvent(
              new FlightEvent(
                  FlightEvent.Type.STAGE_SEPARATION,
                  event.getTime() + separationConfig.getSeparationDelay(),
                  stage));
        }
      }

      // Check for recovery device deployment, add events to queue
      for (RocketComponent c : currentStatus.getConfiguration().getActiveComponents()) {
        if (!(c instanceof RecoveryDevice)) continue;
        DeploymentConfiguration deployConfig =
            ((RecoveryDevice) c).getDeploymentConfigurations().get(this.fcid);
        if (deployConfig.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, deployConfig.getDeployDelay()),
                  c));
        }
      }

      // Handle event
      switch (event.getType()) {
        case LAUNCH:
          {
            currentStatus.getFlightData().addEvent(event);
            break;
          }

        case IGNITION:
          {
            MotorClusterState motorState = (MotorClusterState) event.getData();

            log.info(
                "  Igniting motor: "
                    + motorState.toDescription()
                    + " @"
                    + currentStatus.getSimulationTime());
            motorState.ignite(event.getTime());

            // Ignite the motor
            currentStatus.setMotorIgnited(true);
            currentStatus.getFlightData().addEvent(event);

            // ... ignite ...uhh, again?
            // TBH, I'm not sure what this call is for. It seems to be mostly a bunch of event
            // distribution.
            MotorConfigurationId motorId = motorState.getID();
            MotorMount mount = (MotorMount) event.getSource();
            if (!SimulationListenerHelper.fireMotorIgnition(
                currentStatus, motorId, mount, motorState)) {
              continue;
            }

            // and queue up the burnout for this motor, as well.
            double duration = motorState.getMotor().getBurnTimeEstimate();
            double burnout = currentStatus.getSimulationTime() + duration;
            addEvent(
                new FlightEvent(FlightEvent.Type.BURNOUT, burnout, event.getSource(), motorState));
            break;
          }

        case LIFTOFF:
          {
            // Mark lift-off as occurred
            currentStatus.setLiftoff(true);
            currentStatus.getFlightData().addEvent(event);
            break;
          }

        case LAUNCHROD:
          {
            // Mark launch rod as cleared
            currentStatus.setLaunchRodCleared(true);
            currentStatus.getFlightData().addEvent(event);
            break;
          }

        case BURNOUT:
          {
            // If motor burnout occurs without lift-off, abort
            if (!currentStatus.isLiftoff()) {
              throw new SimulationLaunchException(
                  trans.get("BasicEventSimulationEngine.error.earlyMotorBurnout"));
            }

            // Add ejection charge event
            MotorClusterState motorState = (MotorClusterState) event.getData();
            motorState.burnOut(event.getTime());

            AxialStage stage = motorState.getMount().getStage();
            log.debug(
                " adding EJECTION_CHARGE event for stage "
                    + stage.getStageNumber()
                    + ": "
                    + stage.getName());
            log.debug(
                "                         .... for motor "
                    + motorState.getMotor().getDesignation());

            double delay = motorState.getEjectionDelay();
            if (motorState.hasEjectionCharge()) {
              addEvent(
                  new FlightEvent(
                      FlightEvent.Type.EJECTION_CHARGE,
                      currentStatus.getSimulationTime() + delay,
                      stage,
                      event.getData()));
            }
            currentStatus.getFlightData().addEvent(event);
            break;
          }

        case EJECTION_CHARGE:
          {
            MotorClusterState motorState = (MotorClusterState) event.getData();
            motorState.expend(event.getTime());
            currentStatus.getFlightData().addEvent(event);
            break;
          }

        case STAGE_SEPARATION:
          {
            // Record the event.
            currentStatus.getFlightData().addEvent(event);

            RocketComponent boosterStage = event.getSource();
            final int stageNumber = boosterStage.getStageNumber();

            // Mark the status as having dropped the booster
            currentStatus.getConfiguration().clearStage(stageNumber);

            // Prepare the simulation branch
            SimulationStatus boosterStatus = new SimulationStatus(currentStatus);
            boosterStatus.setFlightData(
                new FlightDataBranch(boosterStage.getName(), FlightDataType.TYPE_TIME));
            // Mark the booster status as only having the booster.
            boosterStatus.getConfiguration().setOnlyStage(stageNumber);
            toSimulate.add(boosterStatus);
            log.info(
                String.format(
                    "==>> @ %g; from Branch: %s ---- Branching: %s ---- \n",
                    currentStatus.getSimulationTime(),
                    currentStatus.getFlightData().getBranchName(),
                    boosterStatus.getFlightData().getBranchName()));

            break;
          }

        case APOGEE:
          // Mark apogee as reached
          currentStatus.setApogeeReached(true);
          currentStatus.getFlightData().addEvent(event);
          // This apogee event might be the optimum if recovery has not already happened.
          if (currentStatus.getSimulationConditions().isCalculateExtras()
              && currentStatus.getDeployedRecoveryDevices().size() == 0) {
            currentStatus.getFlightData().setOptimumAltitude(currentStatus.getMaxAlt());
            currentStatus.getFlightData().setTimeToOptimumAltitude(currentStatus.getMaxAltTime());
          }
          break;

        case RECOVERY_DEVICE_DEPLOYMENT:
          RocketComponent c = event.getSource();
          int n = c.getStageNumber();
          // Ignore event if stage not active
          if (currentStatus.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 (MotorClusterState state : currentStatus.getActiveMotors()) {
              if (state.isSpent()) {
                continue;
              }
              currentStatus.getWarnings().add(Warning.RECOVERY_DEPLOYMENT_WHILE_BURNING);
            }

            // Check for launch rod
            if (!currentStatus.isLaunchRodCleared()) {
              currentStatus.getWarnings().add(Warning.RECOVERY_LAUNCH_ROD);
            }

            // Check current velocity
            if (currentStatus.getRocketVelocity().length() > 20) {
              currentStatus
                  .getWarnings()
                  .add(new Warning.HighSpeedDeployment(currentStatus.getRocketVelocity().length()));
            }

            currentStatus.setLiftoff(true);
            currentStatus.getDeployedRecoveryDevices().add((RecoveryDevice) c);

            // If we haven't already reached apogee, then we need to compute the actual coast time
            // to determine the optimum altitude.
            if (currentStatus.getSimulationConditions().isCalculateExtras()
                && !currentStatus.isApogeeReached()) {
              FlightData coastStatus = computeCoastTime();

              currentStatus.getFlightData().setOptimumAltitude(coastStatus.getMaxAltitude());
              currentStatus.getFlightData().setTimeToOptimumAltitude(coastStatus.getTimeToApogee());
            }

            this.currentStepper = this.landingStepper;
            this.currentStatus = currentStepper.initialize(currentStatus);

            currentStatus.getFlightData().addEvent(event);
          }
          break;

        case GROUND_HIT:
          currentStatus.getFlightData().addEvent(event);
          break;

        case SIMULATION_END:
          ret = false;
          currentStatus.getFlightData().addEvent(event);
          break;

        case ALTITUDE:
          log.trace("BasicEventSimulationEngine:  Handling event " + event);
          break;

        case TUMBLE:
          this.currentStepper = this.tumbleStepper;
          this.currentStatus = currentStepper.initialize(currentStatus);
          currentStatus.getFlightData().addEvent(event);
          break;
      }
    }

    if (1200 < currentStatus.getSimulationTime()) {
      ret = false;
      log.error("Simulation hit max time (1200s): aborting.");
      currentStatus
          .getFlightData()
          .addEvent(
              new FlightEvent(FlightEvent.Type.SIMULATION_END, currentStatus.getSimulationTime()));
    }

    // If no motor has ignited, abort
    if (!currentStatus.isMotorIgnited()) {
      throw new MotorIgnitionException(trans.get("BasicEventSimulationEngine.error.noIgnition"));
    }

    return ret;
  }
Exemple #7
0
 @Override
 public String getComponentName() {
   //// Stage
   return trans.get("PodSet.PodSet");
 }