Added support for Rocksim Tube Fin Set file elements (import and export).

This commit is contained in:
Doug Pedrick 2015-03-29 11:56:15 -05:00
parent 3d64b58144
commit f1cf8c88bd
9 changed files with 2575 additions and 3 deletions

View File

@ -84,6 +84,8 @@ public class RocksimCommonConstants {
public static final String RING_TAIL = "RingTail";
public static final String EXTERNAL_POD = "ExternalPod";
public static final String TEXTURE = "Texture";
public static final String TUBE_COUNT = "TubeCount";
public static final String MAX_TUBES_ALLOWED = "MaxTubesAllowed";
/**
* Length conversion. Rocksim is in millimeters, OpenRocket in meters.

View File

@ -15,6 +15,7 @@ import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.rocketcomponent.Streamer;
import net.sf.openrocket.rocketcomponent.Transition;
import net.sf.openrocket.rocketcomponent.TubeCoupler;
import net.sf.openrocket.rocketcomponent.TubeFinSet;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
@ -53,10 +54,11 @@ public class BodyTubeDTO extends BasePartDTO implements AttachableParts {
@XmlElementRef(name = RocksimCommonConstants.LAUNCH_LUG, type = LaunchLugDTO.class),
@XmlElementRef(name = RocksimCommonConstants.FIN_SET, type = FinSetDTO.class),
@XmlElementRef(name = RocksimCommonConstants.CUSTOM_FIN_SET, type = CustomFinSetDTO.class),
@XmlElementRef(name = RocksimCommonConstants.TUBE_FIN_SET, type = TubeFinSetDTO.class),
@XmlElementRef(name = RocksimCommonConstants.STREAMER, type = StreamerDTO.class),
@XmlElementRef(name = RocksimCommonConstants.PARACHUTE, type = ParachuteDTO.class),
@XmlElementRef(name = RocksimCommonConstants.MASS_OBJECT, type = MassObjectDTO.class)})
List<BasePartDTO> attachedParts = new ArrayList<BasePartDTO>();
List<BasePartDTO> attachedParts = new ArrayList();
/**
* Constructor.
@ -121,6 +123,8 @@ public class BodyTubeDTO extends BasePartDTO implements AttachableParts {
attachedParts.add(new CustomFinSetDTO((FreeformFinSet) rocketComponents));
} else if (rocketComponents instanceof FinSet) {
attachedParts.add(new FinSetDTO((FinSet) rocketComponents));
} else if (rocketComponents instanceof TubeFinSet) {
attachedParts.add(new TubeFinSetDTO((TubeFinSet) rocketComponents));
}
}
}

View File

@ -0,0 +1,109 @@
package net.sf.openrocket.file.rocksim.export;
import net.sf.openrocket.file.rocksim.RocksimCommonConstants;
import net.sf.openrocket.rocketcomponent.TubeFinSet;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
/**
* This class models an XML element for a Rocksim TubeFinSet.
*/
@XmlRootElement(name = RocksimCommonConstants.TUBE_FIN_SET)
@XmlAccessorType(XmlAccessType.FIELD)
public class TubeFinSetDTO extends BasePartDTO {
@XmlElement(name = RocksimCommonConstants.OD)
private double od = 0d;
@XmlElement(name = RocksimCommonConstants.ID)
private double id = 0d;
@XmlElement(name = RocksimCommonConstants.TUBE_COUNT)
private int tubeCount = 0;
@XmlElement(name = RocksimCommonConstants.MAX_TUBES_ALLOWED)
private int maxTubeCount = 0;
/**
* Default constructor.
*/
public TubeFinSetDTO() {
}
/**
* Copy constructor. Fully populates this instance with values taken from the OR TubeFinSet.
*
* @param theORTubeFinSet The OR TubeFinSet component to be serialized in Rocksim format
*/
public TubeFinSetDTO(TubeFinSet theORTubeFinSet) {
super(theORTubeFinSet);
setId(theORTubeFinSet.getInnerRadius() * RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_RADIUS);
setOd(theORTubeFinSet.getOuterRadius() * RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_RADIUS);
setRadialAngle(theORTubeFinSet.getBaseRotation());
setTubeCount(theORTubeFinSet.getFinCount());
}
/**
* Set the outer diameter of the tube fin(s).
*
* @return diameter in meters
*/
public double getOd() {
return od;
}
/**
* Set the outer diameter of the tube fin(s).
*
* @param theOd diameter in meters
*/
public void setOd(double theOd) {
od = theOd;
}
/**
* Get the inner diameter of the tube fin(s).
*
* @return diameter in meters
*/
public double getId() {
return id;
}
/**
* Set the inner diameter of the tube fin(s).
*
* @param theId diameter in meters
*/
public void setId(double theId) {
id = theId;
}
/**
* Get the tube fin count.
*
* @return # tube fins
*/
public int getTubeCount() {
return tubeCount;
}
/**
* Set the tube fin count.
*
* @param theTubeCount # tube fins
*/
public void setTubeCount(final int theTubeCount) {
tubeCount = theTubeCount;
maxTubeCount = tubeCount;
}
/**
* Get the max tube fin count. Since OR doesn't have this concept, just set it to the actual count.
*
* @return # tube fins
*/
public int getMaxTubeCount() {
return maxTubeCount;
}
}

View File

@ -77,7 +77,7 @@ class AttachedPartsHandler extends AbstractElementHandler {
return new SubAssemblyHandler(context, component);
}
if (RocksimCommonConstants.TUBE_FIN_SET.equals(element)) {
warnings.add("Tube fins are not currently supported. Ignoring.");
return new TubeFinSetHandler(context, component, warnings);
}
if (RocksimCommonConstants.RING_TAIL.equals(element)) {
warnings.add("Ring tails are not currently supported. Ignoring.");

View File

@ -0,0 +1,119 @@
package net.sf.openrocket.file.rocksim.importt;
import net.sf.openrocket.aerodynamics.WarningSet;
import net.sf.openrocket.file.DocumentLoadingContext;
import net.sf.openrocket.file.rocksim.RocksimCommonConstants;
import net.sf.openrocket.file.rocksim.RocksimFinishCode;
import net.sf.openrocket.file.simplesax.ElementHandler;
import net.sf.openrocket.file.simplesax.PlainTextHandler;
import net.sf.openrocket.material.Material;
import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.rocketcomponent.TubeFinSet;
import org.xml.sax.SAXException;
import java.util.HashMap;
/**
* Rocksim import SAX handler for Tube Fin Sets.
*/
public class TubeFinSetHandler extends PositionDependentHandler<TubeFinSet> {
/**
* The OpenRocket TubeFinSet instance.
*/
private final TubeFinSet tubeFin;
/**
* Constructor.
*
* @param c the parent
* @param warnings the warning set
*
* @throws IllegalArgumentException thrown if <code>c</code> is null
*/
public TubeFinSetHandler(DocumentLoadingContext context, RocketComponent c, WarningSet warnings) throws IllegalArgumentException {
super(context);
if (c == null) {
throw new IllegalArgumentException("The parent component of a tube fin may not be null.");
}
tubeFin = new TubeFinSet();
if (isCompatible(c, TubeFinSet.class, warnings)) {
c.addChild(tubeFin);
}
}
/**
* Set the relative position onto the component.
*
* @param position the OpenRocket position
*/
@Override
protected void setRelativePosition(final RocketComponent.Position position) {
tubeFin.setRelativePosition(position);
}
/**
* Get the OR instance after the XML parsing is done.
*
* @return a TubeFinSet instance
*/
@Override
protected TubeFinSet getComponent() {
return tubeFin;
}
/**
* Get the type of material the tube fins are constructed from.
*
* @return Material.Type
*/
@Override
protected Material.Type getMaterialType() {
return Material.Type.BULK;
}
/**
* {@inheritDoc}
*/
@Override
public ElementHandler openElement(final String element, final HashMap<String, String> attributes, final WarningSet warnings) throws SAXException {
return PlainTextHandler.INSTANCE;
}
/**
* {@inheritDoc}
*/
@Override
public void closeElement(String element, HashMap<String, String> attributes, String content, WarningSet warnings)
throws SAXException {
super.closeElement(element, attributes, content, warnings);
try {
if (RocksimCommonConstants.OD.equals(element)) {
tubeFin.setOuterRadius(Math.max(0, Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_RADIUS));
}
if (RocksimCommonConstants.ID.equals(element)) {
tubeFin.setInnerRadius(Math.max(0, Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_RADIUS));
}
if (RocksimCommonConstants.LEN.equals(element)) {
tubeFin.setLength(Math.max(0, Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH));
}
if (RocksimCommonConstants.MATERIAL.equals(element)) {
setMaterialName(content);
}
if (RocksimCommonConstants.RADIAL_ANGLE.equals(element)) {
tubeFin.setBaseRotation(Double.parseDouble(content));
}
if (RocksimCommonConstants.TUBE_COUNT.equals(element)) {
tubeFin.setFinCount(Integer.parseInt(content));
}
if (RocksimCommonConstants.FINISH_CODE.equals(element)) {
tubeFin.setFinish(RocksimFinishCode.fromCode(Integer.parseInt(content)).asOpenRocket());
}
} catch (NumberFormatException nfe) {
warnings.add("Could not convert " + element + " value of " + content + ". It is expected to be a number.");
}
}
}

View File

@ -122,7 +122,7 @@ public class RocksimLoaderTest extends BaseTestCase {
Assert.assertEquals(0.185d, stage1.getOverrideMass(), 0.001);
Assert.assertTrue(stage1.isCGOverridden());
Assert.assertEquals(0.3d, stage1.getOverrideCG().x, 0.001);
Assert.assertEquals(4, loader.getWarnings().size());
Assert.assertEquals(3, loader.getWarnings().size());
Assert.assertEquals(1, stage2.getChildCount());
Assert.assertEquals("2nd Stage Tube", stage2.getChild(0).getName());

View File

@ -0,0 +1,84 @@
package net.sf.openrocket.file.rocksim.importt;
import net.sf.openrocket.aerodynamics.WarningSet;
import net.sf.openrocket.file.rocksim.RocksimCommonConstants;
import net.sf.openrocket.rocketcomponent.BodyTube;
import net.sf.openrocket.rocketcomponent.ExternalComponent;
import net.sf.openrocket.rocketcomponent.TubeFinSet;
import org.junit.Assert;
import java.util.HashMap;
/**
* Test for importing a Rocksim TubeFinSet into OR.
*/
public class TubeFinSetHandlerTest {
/**
* Method: asOpenRocket(WarningSet warnings)
*
* @throws Exception thrown if something goes awry
*/
@org.junit.Test
public void testAsOpenRocket() throws Exception {
WarningSet warnings = new WarningSet();
TubeFinSetHandler handler = new TubeFinSetHandler(null, new BodyTube(), warnings);
HashMap<String, String> attributes = new HashMap<>();
handler.closeElement("Name", attributes, "The name", warnings);
handler.closeElement("TubeCount", attributes, "4", warnings);
handler.closeElement("RadialAngle", attributes, ".123", warnings);
TubeFinSet fins = handler.getComponent();
Assert.assertNotNull(fins);
Assert.assertEquals(0, warnings.size());
Assert.assertEquals("The name", fins.getName());
Assert.assertEquals(4, fins.getFinCount());
Assert.assertEquals(.123d, fins.getBaseRotation(), 0d);
handler.closeElement("OD", attributes, "-1", warnings);
Assert.assertEquals(0d, fins.getOuterRadius(), 0.001);
handler.closeElement("OD", attributes, "0", warnings);
Assert.assertEquals(0d, fins.getOuterRadius(), 0.001);
handler.closeElement("OD", attributes, "75", warnings);
Assert.assertEquals(75d / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_RADIUS, fins.getOuterRadius(), 0.001);
handler.closeElement("OD", attributes, "foo", warnings);
Assert.assertEquals(1, warnings.size());
warnings.clear();
handler.closeElement("ID", attributes, "-1", warnings);
Assert.assertEquals(0d, fins.getInnerRadius(), 0.001);
handler.closeElement("ID", attributes, "0", warnings);
Assert.assertEquals(0d, fins.getInnerRadius(), 0.001);
handler.closeElement("ID", attributes, "75", warnings);
Assert.assertEquals(75d / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_RADIUS, fins.getInnerRadius(), 0.001);
handler.closeElement("ID", attributes, "foo", warnings);
Assert.assertEquals(1, warnings.size());
warnings.clear();
handler.closeElement("Len", attributes, "-1", warnings);
Assert.assertEquals(0d, fins.getLength(), 0.001);
handler.closeElement("Len", attributes, "10", warnings);
Assert.assertEquals(10d / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH, fins.getLength(), 0.001);
handler.closeElement("Len", attributes, "10.0", warnings);
Assert.assertEquals(10d / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH, fins.getLength(), 0.001);
handler.closeElement("Len", attributes, "foo", warnings);
Assert.assertEquals(1, warnings.size());
warnings.clear();
handler.closeElement("FinishCode", attributes, "-1", warnings);
Assert.assertEquals(ExternalComponent.Finish.NORMAL, fins.getFinish());
handler.closeElement("FinishCode", attributes, "100", warnings);
Assert.assertEquals(ExternalComponent.Finish.NORMAL, fins.getFinish());
handler.closeElement("FinishCode", attributes, "foo", warnings);
Assert.assertEquals(1, warnings.size());
warnings.clear();
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff