diff --git a/core/resources/l10n/messages.properties b/core/resources/l10n/messages.properties index 6bb9d119f..d124867cf 100644 --- a/core/resources/l10n/messages.properties +++ b/core/resources/l10n/messages.properties @@ -366,12 +366,17 @@ simedtdlg.lbl.ttip.Altitude = The launch altitude above mean sea level.
Checking this box makes the launch rod point into the wind.
+simedtdlg.checkbox.ttip.Intowind2 = A zero launchrod angle will point directly up.
+simedtdlg.checkbox.ttip.Intowind3 = A negative launchrod angle will launch with the wind.
If you uncheck this box you can point the launchrod any direction you please. +simedtdlg.checkbox.ttip.Intowind4 = If you uncheck this box you can point the launchrod any direction you please. simedtdlg.lbl.Angle = Angle: -simedtdlg.lbl.ttip.Angle = The angle of the launch rod from vertical. +simedtdlg.lbl.ttip.Angle = The angle of the launch rod from vertical.
Positive angles point upwind. simedtdlg.lbl.Direction = Direction: simedtdlg.lbl.ttip.Direction1 = Direction of the launch rod relative to the wind.
-simedtdlg.lbl.ttip.Direction2 = = towards the wind, -simedtdlg.lbl.ttip.Direction3 = = downwind. +simedtdlg.lbl.ttip.Direction2 = - +simedtdlg.lbl.ttip.Direction3 = 0 is North. simedtdlg.border.Simopt = Simulator options simedtdlg.lbl.Calcmethod = Calculation method: simedtdlg.lbl.ttip.Calcmethod = The Extended Barrowman method calculates aerodynamic forces according
to the Barrowman equations extended to accommodate more components. @@ -1485,8 +1490,8 @@ FlightDataType.TYPE_VELOCITY_Z = Vertical velocity FlightDataType.TYPE_ACCELERATION_Z = Vertical acceleration FlightDataType.TYPE_VELOCITY_TOTAL = Total velocity FlightDataType.TYPE_ACCELERATION_TOTAL = Total acceleration -FlightDataType.TYPE_POSITION_X = Position East-West -FlightDataType.TYPE_POSITION_Y = Position North-South +FlightDataType.TYPE_POSITION_X = Position East of launch +FlightDataType.TYPE_POSITION_Y = Position North of launch FlightDataType.TYPE_POSITION_XY = Lateral distance FlightDataType.TYPE_POSITION_DIRECTION = Lateral direction FlightDataType.TYPE_VELOCITY_XY = Lateral velocity diff --git a/core/src/net/sf/openrocket/file/openrocket/OpenRocketSaver.java b/core/src/net/sf/openrocket/file/openrocket/OpenRocketSaver.java index a21354f7f..cea1e2a9d 100644 --- a/core/src/net/sf/openrocket/file/openrocket/OpenRocketSaver.java +++ b/core/src/net/sf/openrocket/file/openrocket/OpenRocketSaver.java @@ -431,7 +431,7 @@ public class OpenRocketSaver extends RocketSaver { writeElement("configid", cond.getMotorConfigurationID()); writeElement("launchrodlength", cond.getLaunchRodLength()); writeElement("launchrodangle", cond.getLaunchRodAngle() * 180.0 / Math.PI); - writeElement("launchroddirection", cond.getLaunchRodDirection() * 180.0 / Math.PI); + writeElement("launchroddirection", cond.getLaunchRodDirection() * 360.0 / (2.0 * Math.PI)); writeElement("windaverage", cond.getWindSpeedAverage()); writeElement("windturbulence", cond.getWindTurbulenceIntensity()); writeElement("launchaltitude", cond.getLaunchAltitude()); diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/SimulationConditionsHandler.java b/core/src/net/sf/openrocket/file/openrocket/importt/SimulationConditionsHandler.java index f0cde3a4c..2094b0320 100644 --- a/core/src/net/sf/openrocket/file/openrocket/importt/SimulationConditionsHandler.java +++ b/core/src/net/sf/openrocket/file/openrocket/importt/SimulationConditionsHandler.java @@ -70,7 +70,7 @@ class SimulationConditionsHandler extends AbstractElementHandler { if (Double.isNaN(d)) { warnings.add("Illegal launch rod direction defined, ignoring."); } else { - conditions.setLaunchRodDirection(d * Math.PI / 180); + conditions.setLaunchRodDirection(d * 2.0 * Math.PI / 360); } } else if (element.equals("windaverage")) { if (Double.isNaN(d)) { @@ -113,7 +113,7 @@ class SimulationConditionsHandler extends AbstractElementHandler { } else if (element.equals("atmosphere")) { atmosphereHandler.storeSettings(conditions, warnings); } else if (element.equals("timestep")) { - if (Double.isNaN(d) || d <= 0 ) { + if (Double.isNaN(d) || d <= 0) { warnings.add("Illegal time step defined, ignoring."); } else { conditions.setTimeStep(d); diff --git a/core/src/net/sf/openrocket/simulation/RK4SimulationStepper.java b/core/src/net/sf/openrocket/simulation/RK4SimulationStepper.java index 9ddfec972..d431569af 100644 --- a/core/src/net/sf/openrocket/simulation/RK4SimulationStepper.java +++ b/core/src/net/sf/openrocket/simulation/RK4SimulationStepper.java @@ -59,24 +59,24 @@ public class RK4SimulationStepper extends AbstractSimulationStepper { private static final double MIN_TIME_STEP = 0.001; - + private Random random; - - + + @Override public RK4SimulationStatus initialize(SimulationStatus original) { RK4SimulationStatus status = new RK4SimulationStatus(original); // Copy the existing warnings - status.setWarnings( original.getWarnings() ); + status.setWarnings(original.getWarnings()); SimulationConditions sim = original.getSimulationConditions(); status.setLaunchRodDirection(new Coordinate( - Math.sin(sim.getLaunchRodAngle()) * Math.cos(sim.getLaunchRodDirection()), - Math.sin(sim.getLaunchRodAngle()) * Math.sin(sim.getLaunchRodDirection()), + Math.sin(sim.getLaunchRodAngle()) * Math.cos(Math.PI / 2.0 - sim.getLaunchRodDirection()), + Math.sin(sim.getLaunchRodAngle()) * Math.sin(Math.PI / 2.0 - sim.getLaunchRodDirection()), Math.cos(sim.getLaunchRodAngle()) )); diff --git a/core/src/net/sf/openrocket/simulation/SimulationConditions.java b/core/src/net/sf/openrocket/simulation/SimulationConditions.java index 61bad44c6..067417d3b 100644 --- a/core/src/net/sf/openrocket/simulation/SimulationConditions.java +++ b/core/src/net/sf/openrocket/simulation/SimulationConditions.java @@ -35,7 +35,7 @@ public class SimulationConditions implements Monitorable, Cloneable { /** Launch rod angle >= 0, radians from vertical */ private double launchRodAngle = 0; - /** Launch rod direction, 0 = upwind, PI = downwind. */ + /** Launch rod direction, 0 = north */ private double launchRodDirection = 0; // TODO: Depreciate these and use worldCoordinate only. diff --git a/core/src/net/sf/openrocket/simulation/SimulationOptions.java b/core/src/net/sf/openrocket/simulation/SimulationOptions.java index bb8bfaf82..ba8110cd7 100644 --- a/core/src/net/sf/openrocket/simulation/SimulationOptions.java +++ b/core/src/net/sf/openrocket/simulation/SimulationOptions.java @@ -59,10 +59,12 @@ public class SimulationOptions implements ChangeSource, Cloneable { private double launchRodLength = 1; - /** Launch rod angle > 0, radians from vertical */ + /** Keep launch rod parallel to wind*/ + private boolean launchIntoWind = true; + /** Launch rod angle, |radians|<90 from vertical, positive is upwind, negative is downwind */ private double launchRodAngle = 0; - /** Launch rod direction, 0 = upwind, PI = downwind. */ + /** Launch rod direction, 0 = north. */ private double launchRodDirection = 0; @@ -139,12 +141,20 @@ public class SimulationOptions implements ChangeSource, Cloneable { } + public boolean getLaunchIntoWind() { + return launchIntoWind; + } + + public void setLaunchIntoWind(boolean i) { + launchIntoWind = i; + } + public double getLaunchRodAngle() { return launchRodAngle; } public void setLaunchRodAngle(double launchRodAngle) { - launchRodAngle = MathUtil.clamp(launchRodAngle, 0, MAX_LAUNCH_ROD_ANGLE); + launchRodAngle = MathUtil.clamp(launchRodAngle, -MAX_LAUNCH_ROD_ANGLE, MAX_LAUNCH_ROD_ANGLE); if (MathUtil.equals(this.launchRodAngle, launchRodAngle)) return; this.launchRodAngle = launchRodAngle; @@ -157,7 +167,7 @@ public class SimulationOptions implements ChangeSource, Cloneable { } public void setLaunchRodDirection(double launchRodDirection) { - launchRodDirection = MathUtil.reduce180(launchRodDirection); + launchRodDirection = MathUtil.reduce360(launchRodDirection); if (MathUtil.equals(this.launchRodDirection, launchRodDirection)) return; this.launchRodDirection = launchRodDirection; diff --git a/core/src/net/sf/openrocket/simulation/SimulationStatus.java b/core/src/net/sf/openrocket/simulation/SimulationStatus.java index 79b266a5a..17998a551 100644 --- a/core/src/net/sf/openrocket/simulation/SimulationStatus.java +++ b/core/src/net/sf/openrocket/simulation/SimulationStatus.java @@ -103,12 +103,12 @@ public class SimulationStatus implements Monitorable { Quaternion o; FlightConditions cond = new FlightConditions(this.configuration); this.simulationConditions.getAerodynamicCalculator().getWorstCP(this.configuration, cond, null); - double angle = -cond.getTheta() - this.simulationConditions.getLaunchRodDirection(); + double angle = -cond.getTheta() - (Math.PI / 2.0 - this.simulationConditions.getLaunchRodDirection()); o = Quaternion.rotation(new Coordinate(0, 0, angle)); // Launch rod angle and direction o = o.multiplyLeft(Quaternion.rotation(new Coordinate(0, this.simulationConditions.getLaunchRodAngle(), 0))); - o = o.multiplyLeft(Quaternion.rotation(new Coordinate(0, 0, this.simulationConditions.getLaunchRodDirection()))); + o = o.multiplyLeft(Quaternion.rotation(new Coordinate(0, 0, Math.PI / 2.0 - this.simulationConditions.getLaunchRodDirection()))); this.orientation = o; this.rotationVelocity = Coordinate.NUL; diff --git a/swing/src/net/sf/openrocket/gui/simulation/SimulationConditionsPanel.java b/swing/src/net/sf/openrocket/gui/simulation/SimulationConditionsPanel.java index f21746f4a..0ba49a3fc 100644 --- a/swing/src/net/sf/openrocket/gui/simulation/SimulationConditionsPanel.java +++ b/swing/src/net/sf/openrocket/gui/simulation/SimulationConditionsPanel.java @@ -352,7 +352,19 @@ public class SimulationConditionsPanel extends JPanel { slider.setToolTipText(tip); sub.add(slider, "w 75lp, wrap"); + // Keep launch rod parallel to the wind. + BooleanModel intoWind = new BooleanModel(conditions, "LaunchIntoWind"); + JCheckBox checkWind = new JCheckBox(intoWind); + //// Use International Standard Atmosphere + checkWind.setText(trans.get("simedtdlg.checkbox.Intowind")); + checkWind.setToolTipText( + trans.get("simedtdlg.checkbox.ttip.Intowind1") + + trans.get("simedtdlg.checkbox.ttip.Intowind2") + + trans.get("simedtdlg.checkbox.ttip.Intowind3") + + trans.get("simedtdlg.checkbox.ttip.Intowind4")); + sub.add(checkWind, "spanx, wrap unrel"); + // Angle: label = new JLabel(trans.get("simedtdlg.lbl.Angle")); @@ -362,7 +374,7 @@ public class SimulationConditionsPanel extends JPanel { sub.add(label); m = new DoubleModel(conditions, "LaunchRodAngle", UnitGroup.UNITS_ANGLE, - 0, SimulationOptions.MAX_LAUNCH_ROD_ANGLE); + -SimulationOptions.MAX_LAUNCH_ROD_ANGLE, SimulationOptions.MAX_LAUNCH_ROD_ANGLE); spin = new JSpinner(m.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); @@ -372,7 +384,7 @@ public class SimulationConditionsPanel extends JPanel { unit = new UnitSelector(m); unit.setToolTipText(tip); sub.add(unit, "growx"); - slider = new BasicSlider(m.getSliderModel(0, Math.PI / 9, + slider = new BasicSlider(m.getSliderModel(-SimulationOptions.MAX_LAUNCH_ROD_ANGLE, 0, SimulationOptions.MAX_LAUNCH_ROD_ANGLE)); slider.setToolTipText(tip); sub.add(slider, "w 75lp, wrap"); @@ -381,19 +393,17 @@ public class SimulationConditionsPanel extends JPanel { // Direction: label = new JLabel(trans.get("simedtdlg.lbl.Direction")); - //// Direction of the launch rod relative to the wind.
- //// = towards the wind, - //// = downwind. + //// Direction of the launch rod. tip = trans.get("simedtdlg.lbl.ttip.Direction1") + UnitGroup.UNITS_ANGLE.toStringUnit(0) + " " + trans.get("simedtdlg.lbl.ttip.Direction2") + " " + - UnitGroup.UNITS_ANGLE.toStringUnit(Math.PI) + + UnitGroup.UNITS_ANGLE.toStringUnit(2*Math.PI) + " " + trans.get("simedtdlg.lbl.ttip.Direction3"); label.setToolTipText(tip); sub.add(label); - m = new DoubleModel(conditions, "LaunchRodDirection", UnitGroup.UNITS_ANGLE, - -Math.PI, Math.PI); + m = new DoubleModel(conditions, "LaunchRodDirection", 1.0, UnitGroup.UNITS_ANGLE, + 0, 2*Math.PI); spin = new JSpinner(m.getSpinnerModel()); spin.setEditor(new SpinnerEditor(spin)); @@ -403,10 +413,11 @@ public class SimulationConditionsPanel extends JPanel { unit = new UnitSelector(m); unit.setToolTipText(tip); sub.add(unit, "growx"); - slider = new BasicSlider(m.getSliderModel(-Math.PI, Math.PI)); + slider = new BasicSlider(m.getSliderModel(0, 2*Math.PI)); slider.setToolTipText(tip); sub.add(slider, "w 75lp, wrap"); + JButton restoreDefaults = new JButton(trans.get("simedtdlg.but.resettodefault")); restoreDefaults.addActionListener(new ActionListener() {