From ff1ed750c41aab4c8e1d8318d859e679aa28920e Mon Sep 17 00:00:00 2001 From: SiboVG Date: Fri, 19 Jan 2024 16:51:46 +0100 Subject: [PATCH] [#2438] Support RockSim booster exporting --- .../file/rocksim/RockSimCommonConstants.java | 2 + .../file/rocksim/export/BodyTubeDTO.java | 69 ++++++++++--------- .../file/rocksim/export/ParallelStageDTO.java | 39 +++++++++++ .../file/rocksim/export/PodSetDTO.java | 55 +++++++++++++-- .../file/rocksim/export/RockSimSaver.java | 3 +- 5 files changed, 131 insertions(+), 37 deletions(-) create mode 100644 core/src/net/sf/openrocket/file/rocksim/export/ParallelStageDTO.java diff --git a/core/src/net/sf/openrocket/file/rocksim/RockSimCommonConstants.java b/core/src/net/sf/openrocket/file/rocksim/RockSimCommonConstants.java index 24ae530a5..fd116f206 100644 --- a/core/src/net/sf/openrocket/file/rocksim/RockSimCommonConstants.java +++ b/core/src/net/sf/openrocket/file/rocksim/RockSimCommonConstants.java @@ -85,6 +85,8 @@ public class RockSimCommonConstants { public static final String TUBE_FIN_SET = "TubeFinSet"; public static final String RING_TAIL = "RingTail"; public static final String EXTERNAL_POD = "ExternalPod"; + public static final String DETACHABLE = "Detachable"; + public static final String REMOVED = "Removed"; public static final String TEXTURE = "Texture"; public static final String TUBE_COUNT = "TubeCount"; public static final String MAX_TUBES_ALLOWED = "MaxTubesAllowed"; diff --git a/core/src/net/sf/openrocket/file/rocksim/export/BodyTubeDTO.java b/core/src/net/sf/openrocket/file/rocksim/export/BodyTubeDTO.java index 0eeb7c8f3..d4438ac25 100644 --- a/core/src/net/sf/openrocket/file/rocksim/export/BodyTubeDTO.java +++ b/core/src/net/sf/openrocket/file/rocksim/export/BodyTubeDTO.java @@ -11,6 +11,7 @@ import net.sf.openrocket.rocketcomponent.InnerTube; import net.sf.openrocket.rocketcomponent.LaunchLug; import net.sf.openrocket.rocketcomponent.MassObject; import net.sf.openrocket.rocketcomponent.Parachute; +import net.sf.openrocket.rocketcomponent.ParallelStage; import net.sf.openrocket.rocketcomponent.PodSet; import net.sf.openrocket.rocketcomponent.RocketComponent; import net.sf.openrocket.rocketcomponent.Streamer; @@ -94,42 +95,48 @@ public class BodyTubeDTO extends BasePartDTO implements AttachableParts { List children = theORBodyTube.getChildren(); for (int i = 0; i < children.size(); i++) { - RocketComponent rocketComponents = children.get(i); - if (rocketComponents instanceof InnerTube) { - final InnerTube innerTube = (InnerTube) rocketComponents; + RocketComponent rocketComponent = children.get(i); + if (rocketComponent instanceof InnerTube) { + final InnerTube innerTube = (InnerTube) rocketComponent; final InnerBodyTubeDTO innerBodyTubeDTO = new InnerBodyTubeDTO(innerTube, this); //Only add the inner tube if it is NOT a cluster. if (innerTube.getInstanceCount() == 1) { addAttachedPart(innerBodyTubeDTO); } - } else if (rocketComponents instanceof BodyTube) { - addAttachedPart(new BodyTubeDTO((BodyTube) rocketComponents)); - } else if (rocketComponents instanceof Transition) { - addAttachedPart(new TransitionDTO((Transition) rocketComponents)); - } else if (rocketComponents instanceof EngineBlock) { - addAttachedPart(new EngineBlockDTO((EngineBlock) rocketComponents)); - } else if (rocketComponents instanceof TubeCoupler) { - addAttachedPart(new TubeCouplerDTO((TubeCoupler) rocketComponents, this)); - } else if (rocketComponents instanceof CenteringRing) { - addAttachedPart(new CenteringRingDTO((CenteringRing) rocketComponents)); - } else if (rocketComponents instanceof Bulkhead) { - addAttachedPart(new BulkheadDTO((Bulkhead) rocketComponents)); - } else if (rocketComponents instanceof LaunchLug) { - addAttachedPart(new LaunchLugDTO((LaunchLug) rocketComponents)); - } else if (rocketComponents instanceof Streamer) { - addAttachedPart(new StreamerDTO((Streamer) rocketComponents)); - } else if (rocketComponents instanceof Parachute) { - addAttachedPart(new ParachuteDTO((Parachute) rocketComponents)); - } else if (rocketComponents instanceof MassObject) { - addAttachedPart(new MassObjectDTO((MassObject) rocketComponents)); - } else if (rocketComponents instanceof FreeformFinSet) { - addAttachedPart(new CustomFinSetDTO((FreeformFinSet) rocketComponents)); - } else if (rocketComponents instanceof FinSet) { - addAttachedPart(new FinSetDTO((FinSet) rocketComponents)); - } else if (rocketComponents instanceof TubeFinSet) { - addAttachedPart(new TubeFinSetDTO((TubeFinSet) rocketComponents)); - } else if (rocketComponents instanceof PodSet) { - addAttachedPart(new PodSetDTO((PodSet) rocketComponents)); + } else if (rocketComponent instanceof BodyTube) { + addAttachedPart(new BodyTubeDTO((BodyTube) rocketComponent)); + } else if (rocketComponent instanceof Transition) { + addAttachedPart(new TransitionDTO((Transition) rocketComponent)); + } else if (rocketComponent instanceof EngineBlock) { + addAttachedPart(new EngineBlockDTO((EngineBlock) rocketComponent)); + } else if (rocketComponent instanceof TubeCoupler) { + addAttachedPart(new TubeCouplerDTO((TubeCoupler) rocketComponent, this)); + } else if (rocketComponent instanceof CenteringRing) { + addAttachedPart(new CenteringRingDTO((CenteringRing) rocketComponent)); + } else if (rocketComponent instanceof Bulkhead) { + addAttachedPart(new BulkheadDTO((Bulkhead) rocketComponent)); + } else if (rocketComponent instanceof LaunchLug) { + addAttachedPart(new LaunchLugDTO((LaunchLug) rocketComponent)); + } else if (rocketComponent instanceof Streamer) { + addAttachedPart(new StreamerDTO((Streamer) rocketComponent)); + } else if (rocketComponent instanceof Parachute) { + addAttachedPart(new ParachuteDTO((Parachute) rocketComponent)); + } else if (rocketComponent instanceof MassObject) { + addAttachedPart(new MassObjectDTO((MassObject) rocketComponent)); + } else if (rocketComponent instanceof FreeformFinSet) { + addAttachedPart(new CustomFinSetDTO((FreeformFinSet) rocketComponent)); + } else if (rocketComponent instanceof FinSet) { + addAttachedPart(new FinSetDTO((FinSet) rocketComponent)); + } else if (rocketComponent instanceof TubeFinSet) { + addAttachedPart(new TubeFinSetDTO((TubeFinSet) rocketComponent)); + } else if (rocketComponent instanceof PodSet) { + for (PodSetDTO podSetDTO : PodSetDTO.generatePodSetDTOs((PodSet) rocketComponent)) { + addAttachedPart(podSetDTO); + } + } else if (rocketComponent instanceof ParallelStage) { + for (ParallelStageDTO parallelStageDTO : ParallelStageDTO.generateParallelStageDTOs((ParallelStage) rocketComponent)) { + addAttachedPart(parallelStageDTO); + } } } } diff --git a/core/src/net/sf/openrocket/file/rocksim/export/ParallelStageDTO.java b/core/src/net/sf/openrocket/file/rocksim/export/ParallelStageDTO.java new file mode 100644 index 000000000..510673fd1 --- /dev/null +++ b/core/src/net/sf/openrocket/file/rocksim/export/ParallelStageDTO.java @@ -0,0 +1,39 @@ +package net.sf.openrocket.file.rocksim.export; + +import net.sf.openrocket.rocketcomponent.ParallelStage; + +public class ParallelStageDTO extends PodSetDTO { + + /** + * Default constructor. + */ + protected ParallelStageDTO() { + } + + /** + * Copy constructor. Fully populates this instance with values taken from the OR PodSet. + * + * @param theORParallelStage + */ + protected ParallelStageDTO(ParallelStage theORParallelStage, double angle) { + super(theORParallelStage, angle); + setDetachable(true); + setEjected(false); + } + + /** + * Generate a set of ParallelStageDTOs from the given OR ParallelStage. + * RockSim only allows single-instance ParallelStages, so we need to generate a set of them. + * @param theORParallelStage the OR ParallelStage + * @return the set of ParallelStageDTOs + */ + public static ParallelStageDTO[] generateParallelStageDTOs(ParallelStage theORParallelStage) { + ParallelStageDTO[] set = new ParallelStageDTO[theORParallelStage.getInstanceCount()]; + int i = 0; + for (double angle : theORParallelStage.getInstanceAngles()) { + set[i] = new ParallelStageDTO(theORParallelStage, angle); + i++; + } + return set; + } +} diff --git a/core/src/net/sf/openrocket/file/rocksim/export/PodSetDTO.java b/core/src/net/sf/openrocket/file/rocksim/export/PodSetDTO.java index d2be13493..a9470fefc 100644 --- a/core/src/net/sf/openrocket/file/rocksim/export/PodSetDTO.java +++ b/core/src/net/sf/openrocket/file/rocksim/export/PodSetDTO.java @@ -2,12 +2,13 @@ package net.sf.openrocket.file.rocksim.export; import net.sf.openrocket.file.rocksim.RockSimCommonConstants; import net.sf.openrocket.rocketcomponent.BodyTube; +import net.sf.openrocket.rocketcomponent.ComponentAssembly; import net.sf.openrocket.rocketcomponent.NoseCone; +import net.sf.openrocket.rocketcomponent.ParallelStage; import net.sf.openrocket.rocketcomponent.PodSet; import net.sf.openrocket.rocketcomponent.RocketComponent; import net.sf.openrocket.rocketcomponent.Transition; import net.sf.openrocket.rocketcomponent.position.AxialMethod; -import net.sf.openrocket.rocketcomponent.position.RadiusMethod; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; @@ -29,6 +30,10 @@ public class PodSetDTO extends BasePartDTO implements AttachableParts { private int autoCalcRadialDistance = 0; @XmlElement(name = RockSimCommonConstants.AUTO_CALC_RADIAL_ANGLE) private int autoCalcRadialAngle = 0; + @XmlElement(name = RockSimCommonConstants.DETACHABLE) + private boolean isDetachable = false; // This pod can be ejected during simulations + @XmlElement(name = RockSimCommonConstants.REMOVED) + private boolean isEjected = false; // Mark this pod as ejected @XmlElementWrapper(name = RockSimCommonConstants.ATTACHED_PARTS) @XmlElementRefs({ @XmlElementRef(name = RockSimCommonConstants.BODY_TUBE, type = BodyTubeDTO.class), @@ -40,7 +45,23 @@ public class PodSetDTO extends BasePartDTO implements AttachableParts { /** * Default constructor. */ - public PodSetDTO() { + protected PodSetDTO() { + } + + /** + * Generate a set of PodSetDTOs from the given OR PodSet. + * RockSim only allows single-instance PodSets, so we need to generate a set of them. + * @param theORPodSet the OR PodSet + * @return the set of PodSetDTOs + */ + public static PodSetDTO[] generatePodSetDTOs(ComponentAssembly theORPodSet) { + PodSetDTO[] set = new PodSetDTO[theORPodSet.getInstanceCount()]; + int i = 0; + for (double angle : theORPodSet.getInstanceAngles()) { + set[i] = new PodSetDTO(theORPodSet, angle); + i++; + } + return set; } /** @@ -48,12 +69,14 @@ public class PodSetDTO extends BasePartDTO implements AttachableParts { * * @param theORPodSet */ - public PodSetDTO(PodSet theORPodSet) { + protected PodSetDTO(ComponentAssembly theORPodSet, double angleOffset) { super(theORPodSet); // OR should always override the radial angle and distance setAutoCalcRadialDistance(false); setAutoCalcRadialAngle(false); - setRadialAngle(theORPodSet.getAngleOffset()); + setDetachable(false); + setEjected(false); + setRadialAngle(angleOffset); setRadialLoc(theORPodSet.getRadiusMethod().getRadius( theORPodSet.getParent(), theORPodSet, theORPodSet.getRadiusOffset()) * RockSimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH); @@ -61,7 +84,13 @@ public class PodSetDTO extends BasePartDTO implements AttachableParts { for (RocketComponent child : theORPodSet.getChildren()) { if (child instanceof PodSet) { - addAttachedPart(new PodSetDTO((PodSet) child)); + for (PodSetDTO podSetDTO : generatePodSetDTOs((PodSet) child)) { + addAttachedPart(podSetDTO); + } + } else if (child instanceof ParallelStage) { + for (ParallelStageDTO parallelStageDTO : ParallelStageDTO.generateParallelStageDTOs((ParallelStage) child)) { + addAttachedPart(parallelStageDTO); + } } else if (child instanceof BodyTube) { addAttachedPart(new BodyTubeDTO((BodyTube) child)); } else if (child instanceof NoseCone) { @@ -111,4 +140,20 @@ public class PodSetDTO extends BasePartDTO implements AttachableParts { public void removeAttachedPart(BasePartDTO part) { attachedParts.remove(part); } + + public boolean isEjected() { + return isEjected; + } + + public void setEjected(boolean ejected) { + isEjected = ejected; + } + + public boolean isDetachable() { + return isDetachable; + } + + public void setDetachable(boolean detachable) { + isDetachable = detachable; + } } diff --git a/core/src/net/sf/openrocket/file/rocksim/export/RockSimSaver.java b/core/src/net/sf/openrocket/file/rocksim/export/RockSimSaver.java index 593c8657d..a04ea25b1 100644 --- a/core/src/net/sf/openrocket/file/rocksim/export/RockSimSaver.java +++ b/core/src/net/sf/openrocket/file/rocksim/export/RockSimSaver.java @@ -94,13 +94,14 @@ public class RockSimSaver extends RocketSaver { } private RocketDesignDTO toRocketDesignDTO(Rocket rocket) { + rocket = rocket.copyWithOriginalID(); // Make sure we don't change the original design. RocketDesignDTO result = new RocketDesignDTO(); final FlightConfiguration configuration = rocket.getEmptyConfiguration(); final RigidBody spentData = MassCalculator.calculateStructure( configuration); final double cg = spentData.cm.x * RockSimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH; - int stageCount = rocket.getStageCount(); + int stageCount = rocket.getChildCount(); if (stageCount == 3) { result.setStage321CG(cg); } else if (stageCount == 2) {