2 * ParachuteHandler.java
4 package net.sf.openrocket.file.rocksim.importt;
6 import net.sf.openrocket.aerodynamics.WarningSet;
7 import net.sf.openrocket.file.rocksim.RocksimCommonConstants;
8 import net.sf.openrocket.file.simplesax.ElementHandler;
9 import net.sf.openrocket.file.simplesax.PlainTextHandler;
10 import net.sf.openrocket.material.Material;
11 import net.sf.openrocket.rocketcomponent.BodyTube;
12 import net.sf.openrocket.rocketcomponent.InnerTube;
13 import net.sf.openrocket.rocketcomponent.Parachute;
14 import net.sf.openrocket.rocketcomponent.RocketComponent;
15 import org.xml.sax.SAXException;
17 import java.util.HashMap;
20 * A SAX handler for Rocksim's Parachute XML type.
22 class ParachuteHandler extends RecoveryDeviceHandler<Parachute> {
24 * The OpenRocket Parachute instance
26 private final Parachute chute;
28 * The shroud line density.
30 private double shroudLineDensity = 0.0d;
35 * @param c the parent component
36 * @param warnings the warning set
38 * @throws IllegalArgumentException thrown if <code>c</code> is null
40 public ParachuteHandler(RocketComponent c, WarningSet warnings) throws IllegalArgumentException {
42 throw new IllegalArgumentException("The parent of a parachute may not be null.");
44 chute = new Parachute();
45 if (isCompatible(c, Parachute.class, warnings)) {
54 public ElementHandler openElement(String element, HashMap<String, String> attributes, WarningSet warnings) {
55 return PlainTextHandler.INSTANCE;
62 public void closeElement(String element, HashMap<String, String> attributes, String content, WarningSet warnings)
64 super.closeElement(element, attributes, content, warnings);
66 if (RocksimCommonConstants.DIAMETER.equals(element)) {
67 chute.setDiameter(Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH);
68 /* Rocksim doesn't have a packed parachute radius, so we approximate it. */
70 RocketComponent parent = chute.getParent();
71 if (parent instanceof BodyTube) {
72 packed = ((BodyTube) parent).getOuterRadius() * 0.9;
74 else if (parent instanceof InnerTube) {
75 packed = ((InnerTube) parent).getInnerRadius() * 0.9;
78 packed = chute.getDiameter() * 0.025;
80 chute.setRadius(packed);
82 if (RocksimCommonConstants.SHROUD_LINE_COUNT.equals(element)) {
83 chute.setLineCount(Math.max(0, Integer.parseInt(content)));
85 if (RocksimCommonConstants.SHROUD_LINE_LEN.equals(element)) {
86 chute.setLineLength(Math.max(0, Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH));
88 if (RocksimCommonConstants.SPILL_HOLE_DIA.equals(element)) {
89 //Not supported in OpenRocket
90 double spillHoleRadius = Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_RADIUS;
91 warnings.add("Parachute spill holes are not supported. Ignoring.");
93 if (RocksimCommonConstants.SHROUD_LINE_MASS_PER_MM.equals(element)) {
94 shroudLineDensity = Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LINE_DENSITY;
96 if (RocksimCommonConstants.SHROUD_LINE_MATERIAL.equals(element)) {
97 chute.setLineMaterial(createCustomMaterial(Material.Type.LINE, content, shroudLineDensity));
99 if (RocksimCommonConstants.DRAG_COEFFICIENT.equals(element)) {
100 chute.setCD(Double.parseDouble(content));
102 if (RocksimCommonConstants.MATERIAL.equals(element)) {
103 setMaterialName(content);
106 catch (NumberFormatException nfe) {
107 warnings.add("Could not convert " + element + " value of " + content + ". It is expected to be a number.");
112 * Get the component this handler is working upon.
114 * @return a component
116 public Parachute getComponent() {