[#2438] Support RockSim booster exporting

This commit is contained in:
SiboVG 2024-01-19 16:51:46 +01:00
parent b908424971
commit ff1ed750c4
5 changed files with 131 additions and 37 deletions

View File

@ -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";

View File

@ -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<RocketComponent> 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);
}
}
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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) {