diff --git a/core/resources/l10n/messages.properties b/core/resources/l10n/messages.properties index 71ebd9d86..69cec92ad 100644 --- a/core/resources/l10n/messages.properties +++ b/core/resources/l10n/messages.properties @@ -1412,6 +1412,8 @@ RASAeroExport.error25 = Invalid stage number '%d' for simulation '%s' RASAeroExport.error26 = RASAero only supports conical transitions. RASAeroExport.error27 = Transition '%s' has no previous component. RASAeroExport.error28 = Transition '%s' should have the same fore radius as the aft radius (%f) of its previous component, not %f. +RASAeroExport.error29 = Boattail length may not be zero. +RASAeroExport.error30 = Boattail rear diameter may not be zero. ! SaveAsFileChooser SaveAsFileChooser.illegalFilename.title = Illegal filename diff --git a/core/src/net/sf/openrocket/file/rasaero/export/BoattailDTO.java b/core/src/net/sf/openrocket/file/rasaero/export/BoattailDTO.java new file mode 100644 index 000000000..bb28be19c --- /dev/null +++ b/core/src/net/sf/openrocket/file/rasaero/export/BoattailDTO.java @@ -0,0 +1,28 @@ +package net.sf.openrocket.file.rasaero.export; + +import net.sf.openrocket.file.rasaero.RASAeroCommonConstants; +import net.sf.openrocket.logging.ErrorSet; +import net.sf.openrocket.logging.WarningSet; +import net.sf.openrocket.rocketcomponent.Transition; +import net.sf.openrocket.file.rasaero.export.RASAeroSaver.RASAeroExportException; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; + +@XmlRootElement(name = RASAeroCommonConstants.BOATTAIL) +@XmlAccessorType(XmlAccessType.FIELD) +public class BoattailDTO extends TransitionDTO { + /** + * We need a default no-args constructor. + */ + public BoattailDTO() { + super(); + } + + public BoattailDTO(Transition boattail, WarningSet warnings, ErrorSet errors) throws RASAeroExportException { + super(boattail, warnings, errors); + + setPartType(RASAeroCommonConstants.BOATTAIL); + } +} diff --git a/core/src/net/sf/openrocket/file/rasaero/export/BodyTubeDTOAdapter.java b/core/src/net/sf/openrocket/file/rasaero/export/BodyTubeDTOAdapter.java index 31776816e..2fd2e8870 100644 --- a/core/src/net/sf/openrocket/file/rasaero/export/BodyTubeDTOAdapter.java +++ b/core/src/net/sf/openrocket/file/rasaero/export/BodyTubeDTOAdapter.java @@ -89,11 +89,11 @@ public interface BodyTubeDTOAdapter { Double getBoattailLength(); - void setBoattailLength(Double boattailLength); + void setBoattailLength(Double boattailLength) throws RASAeroExportException; Double getBoattailRearDiameter(); - void setBoattailRearDiameter(Double boattailRearDiameter); + void setBoattailRearDiameter(Double boattailRearDiameter) throws RASAeroExportException; FinDTO getFin(); diff --git a/core/src/net/sf/openrocket/file/rasaero/export/BoosterDTO.java b/core/src/net/sf/openrocket/file/rasaero/export/BoosterDTO.java index e22acd5ab..1080f9b1a 100644 --- a/core/src/net/sf/openrocket/file/rasaero/export/BoosterDTO.java +++ b/core/src/net/sf/openrocket/file/rasaero/export/BoosterDTO.java @@ -168,6 +168,14 @@ public class BoosterDTO implements BodyTubeDTOAdapter { finSet = getFinSetFromBodyTube((BodyTube) comp); } } else { + // If this booster is the last stage, and the last component is a transition, it could be a boattail + if (stageNr == rocket.getChildCount() - 1 && (comp instanceof Transition && !(comp instanceof NoseCone)) && + i == stage.getChildCount() - 1) { + Transition transition = (Transition) comp; + setBoattailLength(transition.getLength() * RASAeroCommonConstants.OPENROCKET_TO_RASAERO_LENGTH); + setBoattailRearDiameter(transition.getAftRadius() * 2 * RASAeroCommonConstants.OPENROCKET_TO_RASAERO_LENGTH); + } + // Case: normal body tube if (stage.getChildPosition(firstTube) == 0) { warnings.add(String.format(trans.get("RASAeroExport.warning10"), @@ -324,7 +332,10 @@ public class BoosterDTO implements BodyTubeDTOAdapter { return boattailLength; } - public void setBoattailLength(Double boattailLength) { + public void setBoattailLength(Double boattailLength) throws RASAeroExportException { + if (boattailLength == 0) { + throw new RASAeroExportException(trans.get("RASAeroExport.error29")); + } this.boattailLength = boattailLength; } @@ -332,7 +343,10 @@ public class BoosterDTO implements BodyTubeDTOAdapter { return boattailRearDiameter; } - public void setBoattailRearDiameter(Double boattailRearDiameter) { + public void setBoattailRearDiameter(Double boattailRearDiameter) throws RASAeroExportException { + if (boattailRearDiameter == 0) { + throw new RASAeroExportException(trans.get("RASAeroExport.error30")); + } this.boattailRearDiameter = boattailRearDiameter; } diff --git a/core/src/net/sf/openrocket/file/rasaero/export/RocketDesignDTO.java b/core/src/net/sf/openrocket/file/rasaero/export/RocketDesignDTO.java index b14929bdb..30a9e3938 100644 --- a/core/src/net/sf/openrocket/file/rasaero/export/RocketDesignDTO.java +++ b/core/src/net/sf/openrocket/file/rasaero/export/RocketDesignDTO.java @@ -78,8 +78,8 @@ public class RocketDesignDTO { if (rocket.getChildCount() > 3) { warnings.add(trans.get("RASAeroExport.warning12")); } - setUseBooster1(rocket.getStageCount() >= 2); - setUseBooster2(rocket.getStageCount() == 3); + setUseBooster1(rocket.getChildCount() >= 2); + setUseBooster2(rocket.getChildCount() == 3); AxialStage sustainer = rocket.getStage(0); @@ -106,7 +106,12 @@ public class RocketDesignDTO { setSurface(RASAeroCommonConstants.OPENROCKET_TO_RASAERO_SURFACE(((NoseCone) component).getFinish(), warnings)); } else if (component instanceof Transition) { - addExternalPart(new TransitionDTO((Transition) component, warnings, errors)); + // If there is only a sustainer & this is the last child of the sustainer, it's a boattail + if (rocket.getChildCount() == 1 && (i == sustainer.getChildCount() - 1)) { + addExternalPart(new BoattailDTO((Transition) component, warnings, errors)); + } else { + addExternalPart(new TransitionDTO((Transition) component, warnings, errors)); + } } } catch (RASAeroExportException e) { errors.add(e.getMessage()); diff --git a/core/src/net/sf/openrocket/file/rasaero/export/TransitionDTO.java b/core/src/net/sf/openrocket/file/rasaero/export/TransitionDTO.java index 9b2d2bc36..a54fc2dc9 100644 --- a/core/src/net/sf/openrocket/file/rasaero/export/TransitionDTO.java +++ b/core/src/net/sf/openrocket/file/rasaero/export/TransitionDTO.java @@ -10,6 +10,7 @@ import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlSeeAlso; import javax.xml.bind.annotation.XmlTransient; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; @@ -19,10 +20,9 @@ import net.sf.openrocket.rocketcomponent.Transition; import net.sf.openrocket.startup.Application; import net.sf.openrocket.util.MathUtil; -import java.util.Objects; - @XmlRootElement(name = RASAeroCommonConstants.TRANSITION) @XmlAccessorType(XmlAccessType.FIELD) +@XmlSeeAlso({BoattailDTO.class}) public class TransitionDTO extends BasePartDTO { @XmlElement(name = RASAeroCommonConstants.REAR_DIAMETER) @@ -31,6 +31,8 @@ public class TransitionDTO extends BasePartDTO { @XmlTransient private static final Translator trans = Application.getTranslator(); + @XmlTransient + private static Transition component = null; /** * We need a default no-args constructor. @@ -41,6 +43,8 @@ public class TransitionDTO extends BasePartDTO { public TransitionDTO(Transition transition, WarningSet warnings, ErrorSet errors) throws RASAeroExportException { super(transition, warnings, errors); + component = transition; + if (!transition.getShapeType().equals(Transition.Shape.CONICAL)) { throw new RASAeroExportException(trans.get("RASAeroExport.error26")); } @@ -62,7 +66,10 @@ public class TransitionDTO extends BasePartDTO { return rearDiameter; } - public void setRearDiameter(Double rearDiameter) { + public void setRearDiameter(Double rearDiameter) throws RASAeroExportException { + if (rearDiameter < 0.0001) { + throw new RASAeroExportException(String.format("'%s' rear diameter must be greater than 0.0001 inch", component)); + } this.rearDiameter = rearDiameter; } }