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(); }
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(); }
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(); }
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(); }
public void setLaunchTemperature(double launchTemperature) { if (MathUtil.equals( this.getDouble(LAUNCH_TEMPERATURE, ExtendedISAModel.STANDARD_TEMPERATURE), launchTemperature)) return; this.putDouble(LAUNCH_TEMPERATURE, launchTemperature); fireChangeEvent(); }
public void setLaunchPressure(double launchPressure) { if (MathUtil.equals( this.getDouble(LAUNCH_PRESSURE, ExtendedISAModel.STANDARD_PRESSURE), launchPressure)) return; this.putDouble(LAUNCH_PRESSURE, launchPressure); fireChangeEvent(); }
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(); }
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(); }
/** * 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()); }
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(); }
@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; }
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(); }
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(); }
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())); }
public void setWindSpeedAverage(double windAverage) { if (MathUtil.equals(this.getDouble(WIND_AVERAGE, 2), windAverage)) return; this.putDouble(WIND_AVERAGE, MathUtil.max(windAverage, 0)); fireChangeEvent(); }
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; }