From 31bd111a1ebc7400047a784d5b19392212eab335 Mon Sep 17 00:00:00 2001 From: hcraigmiller <68821492+hcraigmiller@users.noreply.github.com> Date: Tue, 19 Apr 2022 03:05:55 -0700 Subject: [PATCH] Parachute configuration preset input enhancements Presets for selected parachute changes the Component Name to the parachute Description; input the parachute Cd; and input the override mass, checking the mass override box. The parachute packed values are also input, with the diameter of the parachute sized to the inner diameter of the parent component (where nose cones and transitions have inconsistent inner diameters, these components are sized to the largest diameter). Parachutes without a length and diameter (or without those fields) are sized using the default length and diameter. Once created, the parachute length and diameter do not automatically change if the parent diameter is changed, or the parachute is moved to a different component. --- .../sf/openrocket/preset/ComponentPreset.java | 11 ++ .../openrocket/preset/xml/ParachuteDTO.java | 56 +++++++ .../rocketcomponent/BodyComponent.java | 8 +- .../rocketcomponent/MassObject.java | 2 +- .../openrocket/rocketcomponent/Parachute.java | 142 ++++++++++++++++-- .../rocketcomponent/RecoveryDevice.java | 10 +- .../rocketcomponent/RocketComponent.java | 8 +- 7 files changed, 211 insertions(+), 26 deletions(-) diff --git a/core/src/net/sf/openrocket/preset/ComponentPreset.java b/core/src/net/sf/openrocket/preset/ComponentPreset.java index 46df68c88..7309998f8 100644 --- a/core/src/net/sf/openrocket/preset/ComponentPreset.java +++ b/core/src/net/sf/openrocket/preset/ComponentPreset.java @@ -153,6 +153,9 @@ public class ComponentPreset implements Comparable, Serializabl ComponentPreset.DESCRIPTION, ComponentPreset.DIAMETER, ComponentPreset.SIDES, + ComponentPreset.PARACHUTE_CD, + ComponentPreset.PACKED_DIAMETER, + ComponentPreset.PACKED_LENGTH, ComponentPreset.LINE_COUNT, ComponentPreset.LINE_LENGTH, ComponentPreset.LINE_MATERIAL, @@ -208,6 +211,9 @@ public class ComponentPreset implements Comparable, Serializabl public final static TypedKey MASS = new TypedKey("Mass", Double.class, UnitGroup.UNITS_MASS); public final static TypedKey DIAMETER = new TypedKey("Diameter", Double.class, UnitGroup.UNITS_LENGTH); public final static TypedKey SIDES = new TypedKey("Sides", Integer.class); + public static final TypedKey PARACHUTE_CD = new TypedKey("DragCoefficient", Double.class, UnitGroup.UNITS_COEFFICIENT); + public final static TypedKey PACKED_LENGTH = new TypedKey("PackedLength", Double.class, UnitGroup.UNITS_LENGTH); + public final static TypedKey PACKED_DIAMETER = new TypedKey("PackedDiameter", Double.class, UnitGroup.UNITS_LENGTH); public final static TypedKey LINE_COUNT = new TypedKey("LineCount", Integer.class); public final static TypedKey LINE_LENGTH = new TypedKey("LineLength", Double.class, UnitGroup.UNITS_LENGTH); public final static TypedKey LINE_MATERIAL = new TypedKey("LineMaterial", Material.class); @@ -237,6 +243,11 @@ public class ComponentPreset implements Comparable, Serializabl FILLED, DIAMETER, SIDES, + /** DO NOT add new presets to this list without defining table.column + PARACHUTE_CD, + PACKED_LENGTH, + PACKED_DIAMETER, + */ LINE_COUNT, LINE_LENGTH, LINE_MATERIAL, diff --git a/core/src/net/sf/openrocket/preset/xml/ParachuteDTO.java b/core/src/net/sf/openrocket/preset/xml/ParachuteDTO.java index 1bf861570..e7137fe99 100644 --- a/core/src/net/sf/openrocket/preset/xml/ParachuteDTO.java +++ b/core/src/net/sf/openrocket/preset/xml/ParachuteDTO.java @@ -23,6 +23,12 @@ public class ParachuteDTO extends BaseComponentDTO { private AnnotatedLengthDTO diameter; @XmlElement(name = "Sides") private Integer sides; + @XmlElement(name = "PackedDiameter") + private AnnotatedLengthDTO PackedDiameter; + @XmlElement(name = "PackedLength") + private AnnotatedLengthDTO PackedLength; + @XmlElement(name = "DragCoefficient") + private AnnotatedLengthDTO DragCoefficient; @XmlElement(name = "LineCount") private Integer lineCount; @XmlElement(name = "LineLength") @@ -57,6 +63,38 @@ public class ParachuteDTO extends BaseComponentDTO { this.sides = sides; } + + public double getPackedDiameter() { + return PackedDiameter.getValue(); + } + + public void setPackedDiameter(AnnotatedLengthDTO PackedDiameter) { + this.PackedDiameter = PackedDiameter; + } + public void setPackedDiameter(double PackedDiameter) { + this.PackedDiameter = new AnnotatedLengthDTO(PackedDiameter); + } + + public double getPackedLength() { + return PackedLength.getValue(); + } + + public void setPackedLength(AnnotatedLengthDTO PackedLength) { + this.PackedLength = PackedLength; + } + public void setPackedLength(double PackedLength) { + this.PackedLength = new AnnotatedLengthDTO(PackedLength); + } + + public double getDragCoefficient() { + return DragCoefficient.getValue(); + } + + public void setDragCoefficient(AnnotatedLengthDTO DragCoefficient) { + this.DragCoefficient = DragCoefficient; + } + public void setDragCoefficient(double DragCoefficient) { this.DragCoefficient = new AnnotatedLengthDTO(DragCoefficient); } + public Integer getLineCount() { return lineCount; } @@ -102,6 +140,15 @@ public class ParachuteDTO extends BaseComponentDTO { if ( preset.has(ComponentPreset.SIDES)) { setSides(preset.get(ComponentPreset.SIDES)); } + if ( preset.has(ComponentPreset.PACKED_DIAMETER)) { + setPackedDiameter(preset.get(ComponentPreset.PACKED_DIAMETER)); + } + if ( preset.has(ComponentPreset.PACKED_LENGTH)) { + setPackedLength(preset.get(ComponentPreset.PACKED_LENGTH)); + } + if ( preset.has(ComponentPreset.PARACHUTE_CD)) { + setDragCoefficient(preset.get(ComponentPreset.PARACHUTE_CD)); + } if ( preset.has(ComponentPreset.LINE_MATERIAL)) { setLineMaterial(new AnnotatedMaterialDTO(preset.get(ComponentPreset.LINE_MATERIAL))); } @@ -120,6 +167,15 @@ public class ParachuteDTO extends BaseComponentDTO { // need to fix the MATERIAL packed into the componentpreset. props.put(ComponentPreset.TYPE, type); props.put(ComponentPreset.DIAMETER, this.getDiameter()); + if ( this.PackedDiameter != null ) { + props.put(ComponentPreset.PACKED_DIAMETER, this.getPackedDiameter()); + } + if ( this.PackedLength != null ) { + props.put(ComponentPreset.PACKED_LENGTH, this.getPackedLength()); + } + if ( this.PackedLength != null ) { + props.put(ComponentPreset.PARACHUTE_CD, this.getDragCoefficient()); + } props.put(ComponentPreset.LINE_COUNT, this.getLineCount()); if ( this.lineLength != null ) { props.put(ComponentPreset.LINE_LENGTH, this.getLineLength()); diff --git a/core/src/net/sf/openrocket/rocketcomponent/BodyComponent.java b/core/src/net/sf/openrocket/rocketcomponent/BodyComponent.java index 4e0c7b1a4..1ed38b185 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/BodyComponent.java +++ b/core/src/net/sf/openrocket/rocketcomponent/BodyComponent.java @@ -17,7 +17,9 @@ import net.sf.openrocket.rocketcomponent.position.AxialMethod; */ public abstract class BodyComponent extends ExternalComponent { - + + private double InnerRadius; + /** * Default constructor. Sets the relative position to POSITION_RELATIVE_AFTER, * i.e. body components come after one another. @@ -81,5 +83,7 @@ public abstract class BodyComponent extends ExternalComponent { public boolean allowsChildren() { return true; } - + + public double getInnerRadius() { + return InnerRadius; } } diff --git a/core/src/net/sf/openrocket/rocketcomponent/MassObject.java b/core/src/net/sf/openrocket/rocketcomponent/MassObject.java index 125d59279..80ac7c2b6 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/MassObject.java +++ b/core/src/net/sf/openrocket/rocketcomponent/MassObject.java @@ -21,7 +21,7 @@ import net.sf.openrocket.util.MathUtil; */ public abstract class MassObject extends InternalComponent { - private double radius; + protected double radius; private double radialPosition; private double radialDirection; diff --git a/core/src/net/sf/openrocket/rocketcomponent/Parachute.java b/core/src/net/sf/openrocket/rocketcomponent/Parachute.java index 55d634be7..f8b440de2 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/Parachute.java +++ b/core/src/net/sf/openrocket/rocketcomponent/Parachute.java @@ -10,19 +10,19 @@ import net.sf.openrocket.util.MathUtil; public class Parachute extends RecoveryDevice { private static final Translator trans = Application.getTranslator(); - public static final double DEFAULT_CD = 0.8; + public static double DEFAULT_CD = 0.8; private double diameter; - + private final double InitialPackedLength = this.length; + private final double InitialPackedRadius = this.radius; + private Material lineMaterial; private int lineCount = 6; private double lineLength = 0.3; - - + public Parachute() { this.diameter = 0.3; this.lineMaterial = Application.getPreferences().getDefaultComponentMaterial(Parachute.class, Material.Type.LINE); - this.lineLength = 0.3; super.displayOrder_side = 11; // Order for displaying the component in the 2D side view super.displayOrder_back = 9; // Order for displaying the component in the 2D back view } @@ -159,25 +159,135 @@ public class Parachute extends RecoveryDevice { @Override protected void loadFromPreset(ComponentPreset preset) { - if( preset.has( ComponentPreset.DIAMETER )) { - this.diameter = preset.get( ComponentPreset.DIAMETER ); + + // BEGIN Substitute parachute description for component name + if (preset.has(ComponentPreset.DESCRIPTION)) { // If the preset has a Description field + String temporaryName = preset.get(ComponentPreset.DESCRIPTION); + int size = temporaryName.length(); + if (size > 0) { // If the preset description => 1 character + this.name = preset.get(ComponentPreset.DESCRIPTION); + } else { // If the preset description = 0 characters + this.name = getComponentName(); + } + } else { // Fail safe - no preset description field + this.name = getComponentName(); } - if( preset.has( ComponentPreset.LINE_COUNT )) { - this.lineCount = preset.get( ComponentPreset.LINE_COUNT ); + // END Substitute parachute description for component name + + if (preset.has(ComponentPreset.DIAMETER)) { + this.diameter = preset.get(ComponentPreset.DIAMETER); } - if( preset.has( ComponentPreset.LINE_LENGTH )) { - this.lineLength = preset.get( ComponentPreset.LINE_LENGTH ); + + // BEGIN Implement parachute cd + if (preset.has(ComponentPreset.PARACHUTE_CD)) { // If the preset has a DragCoefficient field + if (preset.get(ComponentPreset.PARACHUTE_CD) > 0) { // If the preset DragCoefficient > 0 + cdAutomatic = false; + cd = preset.get(ComponentPreset.PARACHUTE_CD); + } + else { // If the preset DragCoefficient <= 0 + cdAutomatic = true; + cd = Parachute.DEFAULT_CD; + } + } else { // Fail-safe - no preset DragCoefficient field + cdAutomatic = true; + cd = Parachute.DEFAULT_CD; + } + // END Implement parachute cd + + // BEGIN Implement parachute length, diameter, and volume + //// BEGIN Implement parachute packed length + if (preset.has(ComponentPreset.PACKED_LENGTH)) { // If the preset has a PackedLength field + this.PackedLength = preset.get(ComponentPreset.PACKED_LENGTH); + if (PackedLength > 0) { // If the preset PackedLength length > 0 + length = PackedLength; + } + if (PackedLength <= 0) { // If the preset PackedLength length <= 0 + length = InitialPackedLength; + } + } else { // fail-safe - no preset PackedLength field + length = InitialPackedLength; } - if( preset.has( ComponentPreset.LINE_MATERIAL )) { - this.lineMaterial = preset.get( ComponentPreset.LINE_MATERIAL ); + //// END Implement parachute packed length + //// BEGIN Implement parachute packed diameter + if (preset.has(ComponentPreset.PACKED_DIAMETER)) { // If the preset has a PackedDiameter field + this.PackedDiameter = preset.get(ComponentPreset.PACKED_DIAMETER); + if (PackedDiameter > 0) { // If the preset PackedDiameter length > 0 + radius = PackedDiameter / 2; + } + if (PackedDiameter <= 0) { // If the preset PackedDiameter length <= 0 + radius = InitialPackedRadius; + } + } else { // Fail safe - no preset PackedDiameter field + radius = InitialPackedRadius; + } + //// END Implement parachute packed diameter + //// BEGIN Size parachute packed diameter within parent inner diameter + if (length > 0 && radius > 0) { // If preset parachute length & diameter + double innerRadius; + double parachuteVolume; + double trimPackedRadius = .975; + parachuteVolume = (Math.PI * Math.pow(radius, 2) * length); + + if (parent instanceof BodyComponent) { // If parent is a body tube + innerRadius = ((BodyComponent) parent).getInnerRadius(); + radius = innerRadius * trimPackedRadius; + length = parachuteVolume / (Math.PI * Math.pow((radius), 2)); + } + if (parent instanceof InnerTube) { // If parent is an inner tube + innerRadius = ((InnerTube) parent).getInnerRadius(); + radius = innerRadius * trimPackedRadius; + length = parachuteVolume / (Math.PI * Math.pow((radius), 2)); + } + if (parent instanceof TubeCoupler) { // If parent is a tube coupler + innerRadius = ((TubeCoupler) parent).getInnerRadius(); + radius = innerRadius * trimPackedRadius; + length = parachuteVolume / (Math.PI * Math.pow((radius), 2)); + } + if (parent instanceof NoseCone) { // If parent is nose cone + innerRadius = ((NoseCone) parent).getAftRadius(); + radius = innerRadius * Math.pow((trimPackedRadius), 2); + length = parachuteVolume / (Math.PI * Math.pow((radius), 2)); + } + if (parent instanceof Transition) { // If parent is nose cone|transition + double foreRadius = ((Transition) parent).getForeRadius(); + double aftRadius = ((Transition) parent).getAftRadius(); + innerRadius = (Math.max(foreRadius, aftRadius)); + radius = innerRadius * Math.pow((trimPackedRadius), 2); + length = parachuteVolume / (Math.PI * Math.pow((radius), 2)); + } + } + //// END Size parachute packed diameter within parent inner diameter + // END Implement parachute length, diameter, and volume + + // BEGIN Activate Override Mass Preset + if (preset.has(ComponentPreset.MASS)) { // If the preset has a mass field + this.overrideMass = (preset.get(ComponentPreset.MASS)); + if (overrideMass > 0) { // If the preset mass value > 0 + massOverridden = true; + } else { // If the preset mass value <= 0 + this.overrideMass = 0; + massOverridden = false; + } + } else { // Fail safe - no mass value field + this.overrideMass = 0; + massOverridden = false; + } + // END Activate Override Mass Preset + + if (preset.has(ComponentPreset.LINE_COUNT)) { + this.lineCount = preset.get(ComponentPreset.LINE_COUNT); + } + if (preset.has(ComponentPreset.LINE_LENGTH)) { + this.lineLength = preset.get(ComponentPreset.LINE_LENGTH); + } + if (preset.has(ComponentPreset.LINE_MATERIAL)) { + this.lineMaterial = preset.get(ComponentPreset.LINE_MATERIAL); } super.loadFromPreset(preset); } - @Override public Type getPresetType() { - return ComponentPreset.Type.PARACHUTE; + return Type.PARACHUTE; } - } diff --git a/core/src/net/sf/openrocket/rocketcomponent/RecoveryDevice.java b/core/src/net/sf/openrocket/rocketcomponent/RecoveryDevice.java index ec3fe5542..e74fba077 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/RecoveryDevice.java +++ b/core/src/net/sf/openrocket/rocketcomponent/RecoveryDevice.java @@ -19,9 +19,13 @@ import net.sf.openrocket.util.MathUtil; * @author Sampo Niskanen */ public abstract class RecoveryDevice extends MassObject implements FlightConfigurableComponent { - - private double cd = Parachute.DEFAULT_CD; - private boolean cdAutomatic = true; + //// + protected double DragCoefficient; + protected double PackedDiameter; + protected double PackedLength; + //// + protected double cd = Parachute.DEFAULT_CD; + protected boolean cdAutomatic = true; private Material.Surface material; diff --git a/core/src/net/sf/openrocket/rocketcomponent/RocketComponent.java b/core/src/net/sf/openrocket/rocketcomponent/RocketComponent.java index bcdca0897..af2e046c9 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/RocketComponent.java +++ b/core/src/net/sf/openrocket/rocketcomponent/RocketComponent.java @@ -90,15 +90,15 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab * Defaults to (0,0,0) */ protected Coordinate position = new Coordinate(); - + // Color of the component, null means to use the default color private Color color = null; private LineStyle lineStyle = null; // Override mass/CG - private double overrideMass = 0; - private boolean massOverridden = false; + protected double overrideMass = 0; + protected boolean massOverridden = false; private double overrideCGX = 0; private boolean cgOverridden = false; private double overrideCD = 0; @@ -108,7 +108,7 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab // User-given name of the component - private String name = null; + protected String name = null; // User-specified comment private String comment = "";