示例#1
0
 public void setLaunchRodDirection(double launchRodDirection) {
   launchRodDirection = MathUtil.reduce360(launchRodDirection);
   if (MathUtil.equals(this.getDouble(LAUNCH_ROD_DIRECTION, Math.PI / 2.0), launchRodDirection))
     return;
   this.putDouble(LAUNCH_ROD_DIRECTION, launchRodDirection);
   fireChangeEvent();
 }
示例#2
0
 public void setLaunchRodAngle(double launchRodAngle) {
   launchRodAngle = MathUtil.clamp(launchRodAngle, -Math.PI / 6.0, Math.PI / 6.0);
   if (MathUtil.equals(this.getDouble(LAUNCH_ROD_ANGLE, 0), launchRodAngle)) return;
   this.putDouble(LAUNCH_ROD_ANGLE, launchRodAngle);
   ;
   fireChangeEvent();
 }
示例#3
0
 public void setWindDirection(double direction) {
   direction = MathUtil.reduce360(direction);
   if (this.getBoolean(LAUNCH_INTO_WIND, true)) {
     this.setLaunchRodDirection(direction);
   }
   if (MathUtil.equals(this.getDouble(WIND_DIRECTION, Math.PI / 2), direction)) return;
   this.putDouble(WIND_DIRECTION, direction);
   fireChangeEvent();
 }
示例#4
0
  public final void setWindTurbulenceIntensity(double wti) {
    double oldWTI = Application.getPreferences().getChoice(Preferences.WIND_TURBULANCE, 0.9, 0.3);

    if (MathUtil.equals(oldWTI, wti)) return;
    this.putDouble(Preferences.WIND_TURBULANCE, wti);
    fireChangeEvent();
  }
示例#5
0
 public void setLaunchTemperature(double launchTemperature) {
   if (MathUtil.equals(
       this.getDouble(LAUNCH_TEMPERATURE, ExtendedISAModel.STANDARD_TEMPERATURE),
       launchTemperature)) return;
   this.putDouble(LAUNCH_TEMPERATURE, launchTemperature);
   fireChangeEvent();
 }
示例#6
0
 public void setLaunchPressure(double launchPressure) {
   if (MathUtil.equals(
       this.getDouble(LAUNCH_PRESSURE, ExtendedISAModel.STANDARD_PRESSURE), launchPressure))
     return;
   this.putDouble(LAUNCH_PRESSURE, launchPressure);
   fireChangeEvent();
 }
示例#7
0
 public void setTimeStep(double timeStep) {
   if (MathUtil.equals(
       this.getDouble(SIMULATION_TIME_STEP, RK4SimulationStepper.RECOMMENDED_TIME_STEP), timeStep))
     return;
   this.putDouble(SIMULATION_TIME_STEP, timeStep);
   fireChangeEvent();
 }
 public void setDeployDelay(double deployDelay) {
   if (MathUtil.equals(this.deployDelay, deployDelay)) {
     return;
   }
   this.deployDelay = deployDelay;
   fireChangeEvent();
 }
 public void setDeployAltitude(double deployAltitude) {
   if (MathUtil.equals(this.deployAltitude, deployAltitude)) {
     return;
   }
   this.deployAltitude = deployAltitude;
   fireChangeEvent();
 }
示例#10
0
  public final void setDefaultMach(double dfn) {
    double oldDFN =
        Application.getPreferences().getChoice(Preferences.DEFAULT_MACH_NUMBER, 0.9, 0.3);

    if (MathUtil.equals(oldDFN, dfn)) return;
    this.putDouble(Preferences.DEFAULT_MACH_NUMBER, dfn);
    fireChangeEvent();
  }
示例#11
0
  /**
   * Helper function to convert a string representation into a net.sf.openrocket.util.Color object.
   *
   * @param color
   * @return
   */
  protected static Color parseColor(String color) {
    if (color == null) {
      return null;
    }

    String[] rgb = color.split(",");
    if (rgb.length == 3) {
      try {
        int red = MathUtil.clamp(Integer.parseInt(rgb[0]), 0, 255);
        int green = MathUtil.clamp(Integer.parseInt(rgb[1]), 0, 255);
        int blue = MathUtil.clamp(Integer.parseInt(rgb[2]), 0, 255);
        return new Color(red, green, blue);
      } catch (NumberFormatException ignore) {
      }
    }
    return null;
  }
  @Override
  public void optimize(Point initial, OptimizationController control) throws OptimizationException {

    if (initial.dim() != 1) {
      throw new IllegalArgumentException(
          "Only single-dimensional optimization supported, dim=" + initial.dim());
    }

    log.info("Starting golden section search for optimization");

    Point guessAC = null;
    Point guessBD = null;

    try {
      boolean guessedAC;

      Point previous = p(0);
      double previousValue = Double.NaN;
      current = previous;
      double currentValue = Double.NaN;

      /*
       * Initialize the points + computation.
       */
      Point a = p(0);
      Point d = p(1.0);
      Point b = section1(a, d);
      Point c = section2(a, d);

      functionExecutor.compute(a);
      functionExecutor.compute(d);
      functionExecutor.compute(b);
      functionExecutor.compute(c);

      // Wait for points a and d, which normally are already precomputed
      functionExecutor.waitFor(a);
      functionExecutor.waitFor(d);

      boolean continueOptimization = true;
      while (continueOptimization) {

        /*
         * Get values at A & D for guessing.
         * These are pre-calculated except during the first step.
         */
        double fa, fd;
        fa = functionExecutor.getValue(a);
        fd = functionExecutor.getValue(d);

        /*
         * Start calculating possible two next points.  The order of evaluation
         * is selected based on the function values at A and D.
         */
        guessAC = section1(a, c);
        guessBD = section2(b, d);
        if (Double.isNaN(fd) || fa < fd) {
          guessedAC = true;
          functionExecutor.compute(guessAC);
          functionExecutor.compute(guessBD);
        } else {
          guessedAC = false;
          functionExecutor.compute(guessBD);
          functionExecutor.compute(guessAC);
        }

        /*
         * Get values at B and C.
         */
        double fb, fc;
        functionExecutor.waitFor(b);
        functionExecutor.waitFor(c);
        fb = functionExecutor.getValue(b);
        fc = functionExecutor.getValue(c);

        double min = MathUtil.min(fa, fb, fc, fd);
        if (Double.isNaN(min)) {
          throw new OptimizationException("Unable to compute initial function values");
        }

        /*
         * Update previous and current values for step control.
         */
        previousValue = currentValue;
        currentValue = min;
        previous = current;
        if (min == fa) {
          current = a;
        } else if (min == fb) {
          current = b;
        } else if (min == fc) {
          current = c;
        } else {
          current = d;
        }

        /*
         * Select next positions.  These are already being calculated in the background
         * as guessAC and guessBD.
         */
        if (min == fa || min == fb) {
          d = c;
          c = b;
          b = guessAC;
          functionExecutor.abort(guessBD);
          guessBD = null;
          log.debug("Selecting A-C region, a=" + a.get(0) + " c=" + c.get(0));
          if (guessedAC) {
            guessSuccess++;
          } else {
            guessFailure++;
          }
        } else {
          a = b;
          b = c;
          c = guessBD;
          functionExecutor.abort(guessAC);
          guessAC = null;
          log.debug("Selecting B-D region, b=" + b.get(0) + " d=" + d.get(0));
          if (!guessedAC) {
            guessSuccess++;
          } else {
            guessFailure++;
          }
        }

        /*
         * Check optimization control.
         */
        continueOptimization =
            control.stepTaken(previous, previousValue, current, currentValue, c.get(0) - a.get(0));

        if (Thread.interrupted()) {
          throw new InterruptedException();
        }
      }

    } catch (InterruptedException e) {
      log.info("Optimization was interrupted with InterruptedException");
    }

    if (guessAC != null) {
      functionExecutor.abort(guessAC);
    }
    if (guessBD != null) {
      functionExecutor.abort(guessBD);
    }

    log.info(
        "Finishing optimization at point " + getOptimumPoint() + " value " + getOptimumValue());
    log.info("Optimization statistics: " + getStatistics());
  }
示例#13
0
 public Appearance(final Color paint, final double shine) {
   this.paint = paint;
   this.shine = MathUtil.clamp(shine, 0, 1);
   this.texture = null;
 }
  private FlightDataBranch simulateLoop() {

    // Initialize the simulation
    currentStepper = flightStepper;
    currentStatus = currentStepper.initialize(currentStatus);

    // Get originating position (in case listener has modified launch position)
    Coordinate origin = currentStatus.getRocketPosition();
    Coordinate originVelocity = currentStatus.getRocketVelocity();

    try {

      // Start the simulation
      while (handleEvents()) {
        // Take the step
        double oldAlt = currentStatus.getRocketPosition().z;

        if (SimulationListenerHelper.firePreStep(currentStatus)) {
          // Step at most to the next event
          double maxStepTime = Double.MAX_VALUE;
          FlightEvent nextEvent = currentStatus.getEventQueue().peek();
          if (nextEvent != null) {
            maxStepTime =
                MathUtil.max(nextEvent.getTime() - currentStatus.getSimulationTime(), 0.001);
          }
          log.trace(
              "BasicEventSimulationEngine: Taking simulation step at t="
                  + currentStatus.getSimulationTime());
          currentStepper.step(currentStatus, maxStepTime);
        }
        SimulationListenerHelper.firePostStep(currentStatus);

        // Check for NaN values in the simulation status
        checkNaN();

        // Add altitude event
        addEvent(
            new FlightEvent(
                FlightEvent.Type.ALTITUDE,
                currentStatus.getSimulationTime(),
                currentStatus.getConfiguration().getRocket(),
                new Pair<Double, Double>(oldAlt, currentStatus.getRocketPosition().z)));

        if (currentStatus.getRocketPosition().z > currentStatus.getMaxAlt()) {
          currentStatus.setMaxAlt(currentStatus.getRocketPosition().z);
        }

        // Position relative to start location
        Coordinate relativePosition = currentStatus.getRocketPosition().sub(origin);

        // Add appropriate events
        if (!currentStatus.isLiftoff()) {

          // Avoid sinking into ground before liftoff
          if (relativePosition.z < 0) {
            currentStatus.setRocketPosition(origin);
            currentStatus.setRocketVelocity(originVelocity);
          }
          // Detect lift-off
          if (relativePosition.z > 0.02) {
            addEvent(new FlightEvent(FlightEvent.Type.LIFTOFF, currentStatus.getSimulationTime()));
          }

        } else {

          // Check ground hit after liftoff
          if (currentStatus.getRocketPosition().z < 0) {
            currentStatus.setRocketPosition(currentStatus.getRocketPosition().setZ(0));
            addEvent(
                new FlightEvent(FlightEvent.Type.GROUND_HIT, currentStatus.getSimulationTime()));
            addEvent(
                new FlightEvent(
                    FlightEvent.Type.SIMULATION_END, currentStatus.getSimulationTime()));
          }
        }

        // Check for launch guide clearance
        if (!currentStatus.isLaunchRodCleared()
            && relativePosition.length()
                > currentStatus.getSimulationConditions().getLaunchRodLength()) {
          addEvent(
              new FlightEvent(FlightEvent.Type.LAUNCHROD, currentStatus.getSimulationTime(), null));
        }

        // Check for apogee
        if (!currentStatus.isApogeeReached()
            && currentStatus.getRocketPosition().z < currentStatus.getMaxAlt() - 0.01) {
          currentStatus.setMaxAltTime(currentStatus.getSimulationTime());
          addEvent(
              new FlightEvent(
                  FlightEvent.Type.APOGEE,
                  currentStatus.getSimulationTime(),
                  currentStatus.getConfiguration().getRocket()));
        }

        //				//@Obsolete
        //				//@Redundant
        //				// Check for burnt out motors
        //				for( MotorClusterState state : currentStatus.getActiveMotors()){
        //					if ( state.isSpent()){
        //						addEvent(new FlightEvent(FlightEvent.Type.BURNOUT,
        // currentStatus.getSimulationTime(),
        //								(RocketComponent) state.getMount(), state));
        //					}
        //				}

        // Check for Tumbling
        // Conditions for transision are:
        //  apogee reached (if sustainer stage)
        // and is not already tumbling
        // and not stable (cg > cp)
        // and aoa > AOA_TUMBLE_CONDITION threshold
        // and thrust < THRUST_TUMBLE_CONDITION threshold

        if (!currentStatus.isTumbling()) {
          final double t = currentStatus.getFlightData().getLast(FlightDataType.TYPE_THRUST_FORCE);
          final double cp = currentStatus.getFlightData().getLast(FlightDataType.TYPE_CP_LOCATION);
          final double cg = currentStatus.getFlightData().getLast(FlightDataType.TYPE_CG_LOCATION);
          final double aoa = currentStatus.getFlightData().getLast(FlightDataType.TYPE_AOA);

          final boolean wantToTumble = (cg > cp && aoa > AOA_TUMBLE_CONDITION);

          if (wantToTumble) {
            final boolean tooMuchThrust = t > THRUST_TUMBLE_CONDITION;
            // final boolean isSustainer = status.getConfiguration().isStageActive(0);
            final boolean isApogee = currentStatus.isApogeeReached();
            if (tooMuchThrust) {
              currentStatus.getWarnings().add(Warning.TUMBLE_UNDER_THRUST);
            } else if (isApogee) {
              addEvent(new FlightEvent(FlightEvent.Type.TUMBLE, currentStatus.getSimulationTime()));
              currentStatus.setTumbling(true);
            }
          }
        }
      }

    } catch (SimulationException e) {
      SimulationListenerHelper.fireEndSimulation(currentStatus, e);
      // Add FlightEvent for Abort.
      currentStatus
          .getFlightData()
          .addEvent(
              new FlightEvent(
                  FlightEvent.Type.EXCEPTION,
                  currentStatus.getSimulationTime(),
                  currentStatus.getConfiguration().getRocket(),
                  e.getLocalizedMessage()));
      currentStatus.getWarnings().add(e.getLocalizedMessage());
    }

    return currentStatus.getFlightData();
  }
示例#15
0
  @Override
  public Variable evaluate(SimulationStatus status) {

    Calculable startCalc = buildExpression(startBuilder);
    Calculable endCalc = buildExpression(endBuilder);
    if (startCalc == null || endCalc == null) {
      return new Variable("Unknown");
    }

    // Set the variables in the start and end calculators
    for (FlightDataType type : status.getFlightData().getTypes()) {
      double value = status.getFlightData().getLast(type);
      startCalc.setVariable(new Variable(type.getSymbol(), value));
      endCalc.setVariable(new Variable(type.getSymbol(), value));
    }

    // From the given datatype, get the time and function values and make an interpolator

    // Note: must get in a way that flight data system will figure out units. Otherwise there will
    // be a type conflict when we get the new data.
    FlightDataType type = FlightDataType.getType(null, getSymbol(), null);

    List<Double> data = status.getFlightData().get(type);
    List<Double> time = status.getFlightData().get(FlightDataType.TYPE_TIME);
    LinearInterpolator interp = new LinearInterpolator(time, data);

    // Evaluate the expression to get the start and end of the range
    double startTime, endTime;
    try {
      startTime = startCalc.calculate().getDoubleValue();
      startTime = MathUtil.clamp(startTime, 0, Double.MAX_VALUE);

      endTime = endCalc.calculate().getDoubleValue();
      endTime = MathUtil.clamp(endTime, 0, time.get(time.size() - 1));
    } catch (java.util.EmptyStackException e) {
      log.info(
          Markers.USER_MARKER,
          "Unable to calculate time index for range expression "
              + getSymbol()
              + " due to empty stack exception");
      return new Variable("Unknown");
    }

    // generate an array representing the range
    double step = status.getSimulationConditions().getSimulation().getOptions().getTimeStep();
    double[] t = ArrayUtils.range(startTime, endTime, step);
    double[] y = new double[t.length];
    int i = 0;
    for (double tval : t) {
      y[i] = interp.getValue(tval);
      i++;
    }

    Variable result;
    if (y.length == 0) {
      result = new Variable("Unknown");
    } else {
      result = new Variable(hash(), y, startTime, step);
    }

    return result;
  }
示例#16
0
 public void setLaunchLatitude(double launchLatitude) {
   launchLatitude = MathUtil.clamp(launchLatitude, -90, 90);
   if (MathUtil.equals(this.getDouble(LAUNCH_LATITUDE, 28.61), launchLatitude)) return;
   this.putDouble(LAUNCH_LATITUDE, launchLatitude);
   fireChangeEvent();
 }
示例#17
0
 public void setLaunchLongitude(double launchLongitude) {
   launchLongitude = MathUtil.clamp(launchLongitude, -180, 180);
   if (MathUtil.equals(this.getDouble(LAUNCH_LONGITUDE, -80.60), launchLongitude)) return;
   this.putDouble(LAUNCH_LONGITUDE, launchLongitude);
   fireChangeEvent();
 }
示例#18
0
 public void setLaunchAltitude(double altitude) {
   if (MathUtil.equals(this.getDouble(LAUNCH_ALTITUDE, 0), altitude)) return;
   this.putDouble(LAUNCH_ALTITUDE, altitude);
   fireChangeEvent();
 }
  @Override
  public boolean equals(Object obj) {
    if (this == obj) return true;
    if (!(obj instanceof AerodynamicForces)) return false;
    AerodynamicForces other = (AerodynamicForces) obj;

    return (MathUtil.equals(this.getCNa(), other.getCNa())
        && MathUtil.equals(this.getCN(), other.getCN())
        && MathUtil.equals(this.getCm(), other.getCm())
        && MathUtil.equals(this.getCside(), other.getCside())
        && MathUtil.equals(this.getCyaw(), other.getCyaw())
        && MathUtil.equals(this.getCroll(), other.getCroll())
        && MathUtil.equals(this.getCrollDamp(), other.getCrollDamp())
        && MathUtil.equals(this.getCrollForce(), other.getCrollForce())
        && MathUtil.equals(this.getCaxial(), other.getCaxial())
        && MathUtil.equals(this.getCD(), other.getCD())
        && MathUtil.equals(this.getPressureCD(), other.getPressureCD())
        && MathUtil.equals(this.getBaseCD(), other.getBaseCD())
        && MathUtil.equals(this.getFrictionCD(), other.getFrictionCD())
        && MathUtil.equals(this.getPitchDampingMoment(), other.getPitchDampingMoment())
        && MathUtil.equals(this.getYawDampingMoment(), other.getYawDampingMoment())
        && this.getCP().equals(other.getCP()));
  }
示例#20
0
 public void setWindSpeedAverage(double windAverage) {
   if (MathUtil.equals(this.getDouble(WIND_AVERAGE, 2), windAverage)) return;
   this.putDouble(WIND_AVERAGE, MathUtil.max(windAverage, 0));
   fireChangeEvent();
 }
示例#21
0
 public void setLaunchRodLength(double launchRodLength) {
   if (MathUtil.equals(this.getDouble(LAUNCH_ROD_LENGTH, 1), launchRodLength)) return;
   this.putDouble(LAUNCH_ROD_LENGTH, launchRodLength);
   fireChangeEvent();
 }
  @Override
  public FlightData simulate(SimulationConditions simulationConditions) throws SimulationException {
    Set<MotorId> motorBurntOut = new HashSet<MotorId>();

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

    // Set up rocket configuration
    Configuration configuration = setupConfiguration(simulationConditions);
    MotorInstanceConfiguration motorConfiguration = setupMotorConfiguration(configuration);
    if (motorConfiguration.getMotorIDs().isEmpty()) {
      throw new MotorIgnitionException("No motors defined in the simulation.");
    }

    // Initialize the simulation
    currentStepper = flightStepper;
    status = initialStatus(configuration, motorConfiguration, simulationConditions, flightData);
    status = currentStepper.initialize(status);

    SimulationListenerHelper.fireStartSimulation(status);
    // Get originating position (in case listener has modified launch position)
    Coordinate origin = status.getRocketPosition();
    Coordinate originVelocity = status.getRocketVelocity();

    try {
      double maxAlt = Double.NEGATIVE_INFINITY;

      // Start the simulation
      while (handleEvents()) {

        // Take the step
        double oldAlt = status.getRocketPosition().z;

        if (SimulationListenerHelper.firePreStep(status)) {
          // Step at most to the next event
          double maxStepTime = Double.MAX_VALUE;
          FlightEvent nextEvent = status.getEventQueue().peek();
          if (nextEvent != null) {
            maxStepTime = MathUtil.max(nextEvent.getTime() - status.getSimulationTime(), 0.001);
          }
          log.verbose(
              "BasicEventSimulationEngine: Taking simulation step at t="
                  + status.getSimulationTime());
          currentStepper.step(status, maxStepTime);
        }
        SimulationListenerHelper.firePostStep(status);

        // Calculate values for custom expressions
        FlightDataBranch data = status.getFlightData();
        ArrayList<CustomExpression> allExpressions =
            status.getSimulationConditions().getSimulation().getCustomExpressions();
        for (CustomExpression expression : allExpressions) {
          data.setValue(expression.getType(), expression.evaluate(status));
        }

        // Check for NaN values in the simulation status
        checkNaN();

        // Add altitude event
        addEvent(
            new FlightEvent(
                FlightEvent.Type.ALTITUDE,
                status.getSimulationTime(),
                status.getConfiguration().getRocket(),
                new Pair<Double, Double>(oldAlt, status.getRocketPosition().z)));

        if (status.getRocketPosition().z > maxAlt) {
          maxAlt = status.getRocketPosition().z;
        }

        // Position relative to start location
        Coordinate relativePosition = status.getRocketPosition().sub(origin);

        // Add appropriate events
        if (!status.isLiftoff()) {

          // Avoid sinking into ground before liftoff
          if (relativePosition.z < 0) {
            status.setRocketPosition(origin);
            status.setRocketVelocity(originVelocity);
          }
          // Detect lift-off
          if (relativePosition.z > 0.02) {
            addEvent(new FlightEvent(FlightEvent.Type.LIFTOFF, status.getSimulationTime()));
          }

        } else {

          // Check ground hit after liftoff
          if (status.getRocketPosition().z < 0) {
            status.setRocketPosition(status.getRocketPosition().setZ(0));
            addEvent(new FlightEvent(FlightEvent.Type.GROUND_HIT, status.getSimulationTime()));
            addEvent(new FlightEvent(FlightEvent.Type.SIMULATION_END, status.getSimulationTime()));
          }
        }

        // Check for launch guide clearance
        if (!status.isLaunchRodCleared()
            && relativePosition.length() > status.getSimulationConditions().getLaunchRodLength()) {
          addEvent(new FlightEvent(FlightEvent.Type.LAUNCHROD, status.getSimulationTime(), null));
        }

        // Check for apogee
        if (!status.isApogeeReached() && status.getRocketPosition().z < maxAlt - 0.01) {
          addEvent(
              new FlightEvent(
                  FlightEvent.Type.APOGEE,
                  status.getSimulationTime(),
                  status.getConfiguration().getRocket()));
        }

        // Check for burnt out motors
        for (MotorId motorId : status.getMotorConfiguration().getMotorIDs()) {
          MotorInstance motor = status.getMotorConfiguration().getMotorInstance(motorId);
          if (!motor.isActive() && motorBurntOut.add(motorId)) {
            addEvent(
                new FlightEvent(
                    FlightEvent.Type.BURNOUT,
                    status.getSimulationTime(),
                    (RocketComponent) status.getMotorConfiguration().getMotorMount(motorId),
                    motorId));
          }
        }
      }

    } catch (SimulationException e) {
      SimulationListenerHelper.fireEndSimulation(status, e);
      throw e;
    }

    SimulationListenerHelper.fireEndSimulation(status, null);

    flightData.addBranch(status.getFlightData());

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

    // TODO: HIGH: Simulate branches
    return flightData;
  }