From 34b572969366244a2bcf87b5a5492d28c3510803 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Wed, 8 Jun 2022 21:17:48 +0200 Subject: [PATCH 1/2] [#1231] Include non-aerodynamic components in bounding box calculations --- .../sf/openrocket/rocketcomponent/FlightConfiguration.java | 6 ------ 1 file changed, 6 deletions(-) diff --git a/core/src/net/sf/openrocket/rocketcomponent/FlightConfiguration.java b/core/src/net/sf/openrocket/rocketcomponent/FlightConfiguration.java index 8e65f29c7..d97a0b049 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/FlightConfiguration.java +++ b/core/src/net/sf/openrocket/rocketcomponent/FlightConfiguration.java @@ -601,12 +601,6 @@ public class FlightConfiguration implements FlightConfigurableParameter contexts = entry.getValue(); - - if( ! component.isAerodynamic()){ -// System.err.println(" << non-aerodynamic"); - // all non-aerodynamic components should be surrounded by aerodynamic ones - continue; - } // FinSets already provide a bounding box, so let's use that. if (component instanceof BoxBounded) { From 1b9751562aca5f3b89328d9b307ea71a6596a8f7 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Wed, 8 Jun 2022 22:14:19 +0200 Subject: [PATCH 2/2] [#1231] Split bounding box and length in aerodynamic and all Some parts of the program need only the bounding box of aerodynamic parts (most parts of the program), but a couple others need the bounding box and length of all components --- .../aerodynamics/BarrowmanCalculator.java | 6 +- .../rocketcomponent/AxialStage.java | 2 +- .../rocketcomponent/FlightConfiguration.java | 72 +++++++++++++++---- .../sf/openrocket/rocketcomponent/PodSet.java | 2 +- .../rocketcomponent/RadialParent.java | 4 +- .../rocketcomponent/RailButton.java | 2 +- .../sf/openrocket/rocketcomponent/Rocket.java | 2 +- .../simulation/BasicLandingStepper.java | 4 +- .../simulation/BasicTumbleStepper.java | 4 +- .../simulation/RK4SimulationStepper.java | 2 +- .../unit/PercentageOfLengthUnit.java | 2 +- .../rocketcomponent/BoundingBoxTest.java | 14 ++-- .../FlightConfigurationTest.java | 6 +- .../figure3d/geometry/ComponentRenderer.java | 2 +- .../gui/scalefigure/RocketPanel.java | 3 - 15 files changed, 82 insertions(+), 45 deletions(-) diff --git a/core/src/net/sf/openrocket/aerodynamics/BarrowmanCalculator.java b/core/src/net/sf/openrocket/aerodynamics/BarrowmanCalculator.java index b12e8983e..b1d2f3bfc 100644 --- a/core/src/net/sf/openrocket/aerodynamics/BarrowmanCalculator.java +++ b/core/src/net/sf/openrocket/aerodynamics/BarrowmanCalculator.java @@ -299,7 +299,7 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator { // warnings.add(Warning.DISCONTINUITY); // radius = 0; //} - //componentX = component.toAbsolute(new Coordinate(component.getLength()))[0].x; + //componentX = component.toAbsolute(new Coordinate(component.getLengthAerodynamic()))[0].x; prevComp = sym; }else if( comp instanceof ComponentAssembly ){ @@ -364,7 +364,7 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator { Finish finish = ((ExternalComponent) c).getFinish(); if (Double.isNaN(roughnessLimited[finish.ordinal()])) { roughnessLimited[finish.ordinal()] = - 0.032 * Math.pow(finish.getRoughnessSize() / configuration.getLength(), 0.2) * + 0.032 * Math.pow(finish.getRoughnessSize() / configuration.getLengthAerodynamic(), 0.2) * roughnessCorrection; } @@ -442,7 +442,7 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator { * @return Reynolds Number */ private double calculateReynoldsNumber(FlightConfiguration configuration, FlightConditions conditions) { - return conditions.getVelocity() * configuration.getLength() / + return conditions.getVelocity() * configuration.getLengthAerodynamic() / conditions.getAtmosphericConditions().getKinematicViscosity(); } diff --git a/core/src/net/sf/openrocket/rocketcomponent/AxialStage.java b/core/src/net/sf/openrocket/rocketcomponent/AxialStage.java index fd657b3f4..20f3a13f5 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/AxialStage.java +++ b/core/src/net/sf/openrocket/rocketcomponent/AxialStage.java @@ -137,7 +137,7 @@ public class AxialStage extends ComponentAssembly implements FlightConfigurableC // Stage refStage = (Stage) this.parent; // System.err.println(" >>refStageName: " + refStage.getName() + "\n"); // System.err.println(" ..refCenterX: " + refStage.position.x + "\n"); - // System.err.println(" ..refLength: " + refStage.getLength() + "\n"); + // System.err.println(" ..refLength: " + refStage.getLengthAerodynamic() + "\n"); // } return buf; } diff --git a/core/src/net/sf/openrocket/rocketcomponent/FlightConfiguration.java b/core/src/net/sf/openrocket/rocketcomponent/FlightConfiguration.java index d97a0b049..5f5ad884e 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/FlightConfiguration.java +++ b/core/src/net/sf/openrocket/rocketcomponent/FlightConfiguration.java @@ -1,7 +1,6 @@ package net.sf.openrocket.rocketcomponent; import java.util.ArrayDeque; -import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.List; @@ -67,8 +66,10 @@ public class FlightConfiguration implements FlightConfigurableParameterCollection containing coordinates bounding the rocket. * - * @deprecated Migrate to .getBoundingBox(), when practical. + * @deprecated Migrate to .getBoundingBoxAerodynamic(), when practical. */ @Deprecated public Collection getBounds() { - return getBoundingBox().toCollection(); + return getBoundingBoxAerodynamic().toCollection(); } /** - * Return the bounding box of the current configuration. + * Return the bounding box of the current configuration (of aerodynamic components). * * @return the rocket's bounding box (under the selected configuration) */ + public BoundingBox getBoundingBoxAerodynamic() { +// if (rocket.getModID() != boundsModID) { + calculateBounds(); +// } + + if(cachedBoundsAerodynamic.isEmpty()) + cachedBoundsAerodynamic = new BoundingBox(Coordinate.ZERO,Coordinate.X_UNIT); + + return cachedBoundsAerodynamic; + } + + /** + * Return the bounding box of the current configuration (of all components). + * + * @return the rocket's bounding box (under the selected configuration) + */ public BoundingBox getBoundingBox() { // if (rocket.getModID() != boundsModID) { calculateBounds(); // } - + if(cachedBounds.isEmpty()) cachedBounds = new BoundingBox(Coordinate.ZERO,Coordinate.X_UNIT); - + return cachedBounds; } @@ -593,25 +610,30 @@ public class FlightConfiguration implements FlightConfigurableParameter> entry : map.entrySet()) { final RocketComponent component = entry.getKey(); + final BoundingBox componentBoundsAerodynamic = new BoundingBox(); final BoundingBox componentBounds = new BoundingBox(); final List contexts = entry.getValue(); // FinSets already provide a bounding box, so let's use that. if (component instanceof BoxBounded) { final BoundingBox instanceBounds = ((BoxBounded) component).getInstanceBoundingBox(); - if(instanceBounds.isEmpty()) { + if (instanceBounds.isEmpty()) { // probably redundant // this component is probably non-physical (like an assembly) or has invalid bounds. Skip. continue; } for (InstanceContext context : contexts) { + if (component.isAerodynamic()) { + componentBoundsAerodynamic.update(instanceBounds.transform(context.transform)); + } componentBounds.update(instanceBounds.transform(context.transform)); } } else { @@ -623,32 +645,54 @@ public class FlightConfiguration implements FlightConfigurableParameter>refStageName: " + refStage.getName() + "\n"); // System.err.println(" ..refCenterX: " + refStage.position.x + "\n"); - // System.err.println(" ..refLength: " + refStage.getLength() + "\n"); + // System.err.println(" ..refLength: " + refStage.getLengthAerodynamic() + "\n"); // } return buf; } diff --git a/core/src/net/sf/openrocket/rocketcomponent/RadialParent.java b/core/src/net/sf/openrocket/rocketcomponent/RadialParent.java index 41c731af6..eacca6178 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/RadialParent.java +++ b/core/src/net/sf/openrocket/rocketcomponent/RadialParent.java @@ -4,7 +4,7 @@ public interface RadialParent { /** * Return the outer radius of the component at local coordinate x. - * Values for x < 0 and x > getLength() are undefined. + * Values for x < 0 and x > getLengthAerodynamic() are undefined. * * @param x the lengthwise position in the coordinates of this component. * @return the outer radius of the component at that position. @@ -13,7 +13,7 @@ public interface RadialParent { /** * Return the inner radius of the component at local coordinate x. - * Values for x < 0 and x > getLength() are undefined. + * Values for x < 0 and x > getLengthAerodynamic() are undefined. * * @param x the lengthwise position in the coordinates of this component. * @return the inner radius of the component at that position. diff --git a/core/src/net/sf/openrocket/rocketcomponent/RailButton.java b/core/src/net/sf/openrocket/rocketcomponent/RailButton.java index 9e1e96cac..a5b0e08fa 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/RailButton.java +++ b/core/src/net/sf/openrocket/rocketcomponent/RailButton.java @@ -395,7 +395,7 @@ public class RailButton extends ExternalComponent implements AnglePositionable, @Override public double getLongitudinalUnitInertia() { // 1/12 * (3 * (r2^2 + r1^2) + h^2) -// return (3 * (MathUtil.pow2(getOuterRadius()) + MathUtil.pow2(getInnerRadius())) + MathUtil.pow2(getLength())) / 12; +// return (3 * (MathUtil.pow2(getOuterRadius()) + MathUtil.pow2(getInnerRadius())) + MathUtil.pow2(getLengthAerodynamic())) / 12; return 0.0; } diff --git a/core/src/net/sf/openrocket/rocketcomponent/Rocket.java b/core/src/net/sf/openrocket/rocketcomponent/Rocket.java index 92767e62f..7a3f1780a 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/Rocket.java +++ b/core/src/net/sf/openrocket/rocketcomponent/Rocket.java @@ -91,7 +91,7 @@ public class Rocket extends ComponentAssembly { * * @return Return a bounding box enveloping the rocket */ - public BoundingBox getBoundingBox (){ return selectedConfiguration.getBoundingBox(); } + public BoundingBox getBoundingBox (){ return selectedConfiguration.getBoundingBoxAerodynamic(); } public String getDesigner() { checkState(); diff --git a/core/src/net/sf/openrocket/simulation/BasicLandingStepper.java b/core/src/net/sf/openrocket/simulation/BasicLandingStepper.java index 48b848937..78e1e00bb 100644 --- a/core/src/net/sf/openrocket/simulation/BasicLandingStepper.java +++ b/core/src/net/sf/openrocket/simulation/BasicLandingStepper.java @@ -17,7 +17,7 @@ public class BasicLandingStepper extends AbstractSimulationStepper { private static final double RECOVERY_TIME_STEP = 0.5; @Override - public SimulationStatus initialize(SimulationStatus status) { + public SimulationStatus initialize(SimulationStatus status) { return status; } @@ -138,7 +138,7 @@ public class BasicLandingStepper extends AbstractSimulationStepper { data.setValue(FlightDataType.TYPE_ACCELERATION_TOTAL, linearAcceleration.length()); double Re = airSpeed.length() * - status.getConfiguration().getLength() / + status.getConfiguration().getLengthAerodynamic() / atmosphere.getKinematicViscosity(); data.setValue(FlightDataType.TYPE_REYNOLDS_NUMBER, Re); } diff --git a/core/src/net/sf/openrocket/simulation/BasicTumbleStepper.java b/core/src/net/sf/openrocket/simulation/BasicTumbleStepper.java index 0c0824dd4..e8af5b890 100644 --- a/core/src/net/sf/openrocket/simulation/BasicTumbleStepper.java +++ b/core/src/net/sf/openrocket/simulation/BasicTumbleStepper.java @@ -13,7 +13,7 @@ public class BasicTumbleStepper extends AbstractSimulationStepper { private static final double RECOVERY_TIME_STEP = 0.5; @Override - public SimulationStatus initialize(SimulationStatus status) { + public SimulationStatus initialize(SimulationStatus status) { return new BasicTumbleStatus(status); } @@ -101,7 +101,7 @@ public class BasicTumbleStepper extends AbstractSimulationStepper { data.setValue(FlightDataType.TYPE_ACCELERATION_TOTAL, linearAcceleration.length()); double Re = airSpeed.length() * - status.getConfiguration().getLength() / + status.getConfiguration().getLengthAerodynamic() / atmosphere.getKinematicViscosity(); data.setValue(FlightDataType.TYPE_REYNOLDS_NUMBER, Re); } diff --git a/core/src/net/sf/openrocket/simulation/RK4SimulationStepper.java b/core/src/net/sf/openrocket/simulation/RK4SimulationStepper.java index 6a1d99e8a..7786876c9 100644 --- a/core/src/net/sf/openrocket/simulation/RK4SimulationStepper.java +++ b/core/src/net/sf/openrocket/simulation/RK4SimulationStepper.java @@ -582,7 +582,7 @@ public class RK4SimulationStepper extends AbstractSimulationStepper { if (store.flightConditions != null) { double Re = (store.flightConditions.getVelocity() * - status.getConfiguration().getLength() / + status.getConfiguration().getLengthAerodynamic() / store.flightConditions.getAtmosphericConditions().getKinematicViscosity()); data.setValue(FlightDataType.TYPE_REYNOLDS_NUMBER, Re); } diff --git a/core/src/net/sf/openrocket/unit/PercentageOfLengthUnit.java b/core/src/net/sf/openrocket/unit/PercentageOfLengthUnit.java index 5cafe6520..310328df8 100644 --- a/core/src/net/sf/openrocket/unit/PercentageOfLengthUnit.java +++ b/core/src/net/sf/openrocket/unit/PercentageOfLengthUnit.java @@ -83,7 +83,7 @@ public class PercentageOfLengthUnit extends GeneralUnit { * @return the reference length of the rocket */ public static double getReferenceLength(FlightConfiguration config) { - return config.getLength(); + return config.getLengthAerodynamic(); } /** diff --git a/core/test/net/sf/openrocket/rocketcomponent/BoundingBoxTest.java b/core/test/net/sf/openrocket/rocketcomponent/BoundingBoxTest.java index 251fcfc60..8394a3dfb 100644 --- a/core/test/net/sf/openrocket/rocketcomponent/BoundingBoxTest.java +++ b/core/test/net/sf/openrocket/rocketcomponent/BoundingBoxTest.java @@ -1,18 +1,12 @@ package net.sf.openrocket.rocketcomponent; -import net.sf.openrocket.rocketcomponent.position.AngleMethod; -import net.sf.openrocket.rocketcomponent.position.AxialMethod; -import net.sf.openrocket.rocketcomponent.position.RadiusMethod; -import net.sf.openrocket.util.ArrayList; import net.sf.openrocket.util.BaseTestCase.BaseTestCase; import net.sf.openrocket.util.BoundingBox; -import net.sf.openrocket.util.Coordinate; import net.sf.openrocket.util.MathUtil; import net.sf.openrocket.util.TestRockets; import org.junit.Test; -import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.not; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; @@ -25,7 +19,7 @@ public class BoundingBoxTest extends BaseTestCase { final Rocket rocket = TestRockets.makeEstesAlphaIII(); final FlightConfiguration config = rocket.getSelectedConfiguration(); - final BoundingBox bounds = config.getBoundingBox(); + final BoundingBox bounds = config.getBoundingBoxAerodynamic(); assertEquals("bounds max x", 0.000000000, bounds.min.x, EPSILON); assertEquals("bounds max x", 0.270000000, bounds.max.x, EPSILON); @@ -48,7 +42,7 @@ public class BoundingBoxTest extends BaseTestCase { // DEBUG System.err.println("==== Case A: All Stages ===="); - final BoundingBox bounds = config.getBoundingBox(); + final BoundingBox bounds = config.getBoundingBoxAerodynamic(); assertEquals("bounds min x", 0.000000000, bounds.min.x, EPSILON); assertEquals("bounds max x", 0.335000000, bounds.max.x, EPSILON); @@ -63,7 +57,7 @@ public class BoundingBoxTest extends BaseTestCase { // DEBUG System.err.println("==== Case B: Sustainer Only ===="); - final BoundingBox bounds = config.getBoundingBox(); + final BoundingBox bounds = config.getBoundingBoxAerodynamic(); assertEquals("bounds min x", 0.000000000, bounds.min.x, EPSILON); assertEquals("bounds max x", 0.270000000, bounds.max.x, EPSILON); @@ -79,7 +73,7 @@ public class BoundingBoxTest extends BaseTestCase { System.err.println("==== Case C: Booster Only ===="); System.err.println(rocket.toDebugTree()); - final BoundingBox bounds = config.getBoundingBox(); + final BoundingBox bounds = config.getBoundingBoxAerodynamic(); assertEquals("bounds min x", 0.270000000, bounds.min.x, EPSILON); assertEquals("bounds max x", 0.335000000, bounds.max.x, EPSILON); diff --git a/core/test/net/sf/openrocket/rocketcomponent/FlightConfigurationTest.java b/core/test/net/sf/openrocket/rocketcomponent/FlightConfigurationTest.java index 7b82c3a66..c4ad802af 100644 --- a/core/test/net/sf/openrocket/rocketcomponent/FlightConfigurationTest.java +++ b/core/test/net/sf/openrocket/rocketcomponent/FlightConfigurationTest.java @@ -45,7 +45,7 @@ public class FlightConfigurationTest extends BaseTestCase { assertThat("active stage count doesn't match", config.getActiveStageCount(), equalTo(2)); final double expectedLength = 0.335; - final double calculatedLength = config.getLength(); + final double calculatedLength = config.getLengthAerodynamic(); assertEquals("source config length doesn't match: ", expectedLength, calculatedLength, EPSILON); double expectedReferenceLength = 0.024; @@ -71,7 +71,7 @@ public class FlightConfigurationTest extends BaseTestCase { int actualMotorCount = config1.getActiveMotors().size(); assertThat("active motor count doesn't match", actualMotorCount, equalTo(expectedMotorCount)); double expectedLength = 0.335; - assertEquals("source config length doesn't match: ", expectedLength, config1.getLength(), EPSILON); + assertEquals("source config length doesn't match: ", expectedLength, config1.getLengthAerodynamic(), EPSILON); double expectedReferenceLength = 0.024; assertEquals("source config reference length doesn't match: ", expectedReferenceLength, config1.getReferenceLength(), EPSILON); double expectedReferenceArea = Math.pow(expectedReferenceLength/2,2)*Math.PI; @@ -90,7 +90,7 @@ public class FlightConfigurationTest extends BaseTestCase { expectedMotorCount = 2; actualMotorCount = config2.getActiveMotors().size(); assertThat("active motor count doesn't match", actualMotorCount, equalTo(expectedMotorCount)); - assertEquals("source config length doesn't match: ", expectedLength, config2.getLength(), EPSILON); + assertEquals("source config length doesn't match: ", expectedLength, config2.getLengthAerodynamic(), EPSILON); assertEquals("source config reference length doesn't match: ", expectedReferenceLength, config2.getReferenceLength(), EPSILON); assertEquals("source config reference area doesn't match: ", expectedReferenceArea, config2.getReferenceArea(), EPSILON); diff --git a/swing/src/net/sf/openrocket/gui/figure3d/geometry/ComponentRenderer.java b/swing/src/net/sf/openrocket/gui/figure3d/geometry/ComponentRenderer.java index 2f364d708..b83143638 100644 --- a/swing/src/net/sf/openrocket/gui/figure3d/geometry/ComponentRenderer.java +++ b/swing/src/net/sf/openrocket/gui/figure3d/geometry/ComponentRenderer.java @@ -203,7 +203,7 @@ public class ComponentRenderer { if (t.getForeShoulderLength() > 0) { gl.glPushMatrix(); gl.glRotated(180, 0, 1.0, 0); - //gl.glTranslated(t.getLength(), 0, 0); + //gl.glTranslated(t.getLengthAerodynamic(), 0, 0); double iR = (t.isFilled() || t.isForeShoulderCapped()) ? 0 : t.getForeShoulderRadius() - t.getForeShoulderThickness(); if (which == Surface.EDGES) { renderTube(gl, Surface.OUTSIDE, t.getForeShoulderRadius(), iR, t.getForeShoulderLength()); diff --git a/swing/src/net/sf/openrocket/gui/scalefigure/RocketPanel.java b/swing/src/net/sf/openrocket/gui/scalefigure/RocketPanel.java index 01f57a6a4..ada4418b0 100644 --- a/swing/src/net/sf/openrocket/gui/scalefigure/RocketPanel.java +++ b/swing/src/net/sf/openrocket/gui/scalefigure/RocketPanel.java @@ -33,7 +33,6 @@ import net.sf.openrocket.aerodynamics.AerodynamicCalculator; import net.sf.openrocket.aerodynamics.BarrowmanCalculator; import net.sf.openrocket.aerodynamics.FlightConditions; import net.sf.openrocket.aerodynamics.WarningSet; -import net.sf.openrocket.arch.SystemInfo; import net.sf.openrocket.document.OpenRocketDocument; import net.sf.openrocket.document.Simulation; import net.sf.openrocket.document.events.SimulationChangeEvent; @@ -63,10 +62,8 @@ import net.sf.openrocket.rocketcomponent.Rocket; import net.sf.openrocket.rocketcomponent.RocketComponent; import net.sf.openrocket.rocketcomponent.SymmetricComponent; import net.sf.openrocket.simulation.FlightData; -import net.sf.openrocket.simulation.SimulationStatus; import net.sf.openrocket.simulation.customexpression.CustomExpression; import net.sf.openrocket.simulation.customexpression.CustomExpressionSimulationListener; -import net.sf.openrocket.simulation.exception.SimulationException; import net.sf.openrocket.simulation.listeners.SimulationListener; import net.sf.openrocket.simulation.listeners.system.GroundHitListener; import net.sf.openrocket.simulation.listeners.system.InterruptListener;