refactored file package
[debian/openrocket] / src / net / sf / openrocket / file / motor / RASPMotorLoader.java
diff --git a/src/net/sf/openrocket/file/motor/RASPMotorLoader.java b/src/net/sf/openrocket/file/motor/RASPMotorLoader.java
new file mode 100644 (file)
index 0000000..02feb9b
--- /dev/null
@@ -0,0 +1,222 @@
+package net.sf.openrocket.file.motor;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import net.sf.openrocket.file.MotorLoader;
+import net.sf.openrocket.motor.Manufacturer;
+import net.sf.openrocket.motor.Motor;
+import net.sf.openrocket.motor.MotorDigest;
+import net.sf.openrocket.motor.ThrustCurveMotor;
+import net.sf.openrocket.motor.MotorDigest.DataType;
+import net.sf.openrocket.util.Coordinate;
+
+public class RASPMotorLoader extends MotorLoader {
+
+       public static final String CHARSET_NAME = "ISO-8859-1";
+       
+       public static final Charset CHARSET = Charset.forName(CHARSET_NAME);
+       
+       
+       
+       
+       @Override
+       protected Charset getDefaultCharset() {
+               return CHARSET;
+       }
+
+       
+       /**
+        * Load a <code>Motor</code> from a RASP file specified by the <code>Reader</code>.
+        * The <code>Reader</code> is responsible for using the correct charset.
+        * <p>
+        * The CG is assumed to be located at the center of the motor casing and the mass
+        * is calculated from the thrust curve by assuming a constant exhaust velocity.
+        * 
+        * @param reader  the source of the file.
+        * @return                a list of the {@link Motor} objects defined in the file.
+        * @throws IOException  if an I/O error occurs or if the file format is illegal.
+        */
+       @Override
+       public List<Motor> load(Reader reader, String filename) throws IOException {
+               List<Motor> motors = new ArrayList<Motor>();
+               BufferedReader in = new BufferedReader(reader);
+
+               String manufacturer = "";
+               String designation = "";
+               String comment = "";
+               
+               double length = 0;
+               double diameter = 0;
+               ArrayList<Double> delays = null;
+               
+               List<Double> time = new ArrayList<Double>();
+               List<Double> thrust = new ArrayList<Double>();
+               
+               double propW = 0;
+               double totalW = 0;
+               
+               try {
+                       String line;
+                       String[] pieces, buf;
+
+                       line = in.readLine();
+                       main: while (line != null) {   // Until EOF
+
+                               manufacturer = "";
+                               designation = "";
+                               comment = "";
+                               length = 0;
+                               diameter = 0;
+                               delays = new ArrayList<Double>();
+                               propW = 0;
+                               totalW = 0;
+                               time.clear();
+                               thrust .clear();
+                       
+                               // Read comment
+                               while (line.length()==0 || line.charAt(0)==';') {
+                                       if (line.length() > 0) {
+                                               comment += line.substring(1).trim() + "\n";
+                                       }
+                                       line = in.readLine();
+                                       if (line == null)
+                                               break main;
+                               }
+                               comment = comment.trim();
+                               
+                               // Parse header line, example:
+                               // F32 24 124 5-10-15-P .0377 .0695 RV
+                               // desig diam len delays prop.w tot.w manufacturer
+                               pieces = split(line);
+                               if (pieces.length != 7) {
+                                       throw new IOException("Illegal file format.");
+                               }
+                               
+                               designation = pieces[0];
+                               diameter = Double.parseDouble(pieces[1]) / 1000.0;
+                               length = Double.parseDouble(pieces[2]) / 1000.0;
+                               
+                               if (pieces[3].equalsIgnoreCase("None")) {
+
+                               } else {
+                                       buf = split(pieces[3],"[-,]+");
+                                       for (int i=0; i < buf.length; i++) {
+                                               if (buf[i].equalsIgnoreCase("P") || 
+                                                               buf[i].equalsIgnoreCase("plugged")) {
+                                                       delays.add(Motor.PLUGGED);
+                                               } else {
+                                                       // Many RASP files have "100" as an only delay
+                                                       double d = Double.parseDouble(buf[i]);
+                                                       if (d < 99)
+                                                               delays.add(d);
+                                               }
+                                       }
+                                       Collections.sort(delays);
+                               }
+                               
+                               propW = Double.parseDouble(pieces[4]);
+                               totalW = Double.parseDouble(pieces[5]);
+                               manufacturer = pieces[6];
+                               
+                               if (propW > totalW) {
+                                       throw new IOException("Propellant weight exceeds total weight in " +
+                                                       "RASP file");
+                               }
+                               
+                               // Read the data
+                               for (line = in.readLine(); 
+                                        (line != null) && (line.length()==0 || line.charAt(0) != ';');
+                                        line = in.readLine()) {
+                                       
+                                       buf = split(line);
+                                       if (buf.length == 0) {
+                                               continue;
+                                       } else if (buf.length == 2) {
+                                               
+                                               time.add(Double.parseDouble(buf[0]));
+                                               thrust .add(Double.parseDouble(buf[1]));
+                                               
+                                       } else {
+                                               throw new IOException("Illegal file format.");
+                                       }
+                               }
+                               
+                               // Comment of EOF encountered, marks the start of the next motor
+                               if (time.size() < 2) {
+                                       throw new IOException("Illegal file format, too short thrust-curve.");
+                               }
+                               double[] delayArray = new double[delays.size()];
+                               for (int i=0; i<delays.size(); i++) {
+                                       delayArray[i] = delays.get(i);
+                               }
+                               motors.add(createRASPMotor(manufacturer, designation, comment,
+                                               length, diameter, delayArray, propW, totalW, time, thrust));
+                       }
+                       
+               } catch (NumberFormatException e) {
+                       
+                       throw new IOException("Illegal file format.");
+                       
+               } finally {
+                       
+                       in.close();
+                       
+               }
+               
+               return motors;
+       }
+       
+       
+       /**
+        * Create a motor from RASP file data.
+        * @throws IOException  if the data is illegal for a thrust curve
+        */
+       private static Motor createRASPMotor(String manufacturer, String designation,
+                       String comment, double length, double diameter, double[] delays,
+                       double propW, double totalW, List<Double> time, List<Double> thrust) 
+                       throws IOException {
+               
+               // Add zero time/thrust if necessary
+               sortLists(time, thrust);
+               finalizeThrustCurve(time, thrust);
+               List<Double> mass = calculateMass(time,thrust,totalW,propW);
+               
+               double[] timeArray = new double[time.size()];
+               double[] thrustArray = new double[time.size()];
+               Coordinate[] cgArray = new Coordinate[time.size()];
+               for (int i=0; i < time.size(); i++) {
+                       timeArray[i] = time.get(i);
+                       thrustArray[i] = thrust.get(i);
+                       cgArray[i] = new Coordinate(length/2,0,0,mass.get(i));
+               }
+               
+               designation = removeDelay(designation);
+               
+               // Create the motor digest from data available in RASP files
+               MotorDigest motorDigest = new MotorDigest();
+               motorDigest.update(DataType.TIME_ARRAY, timeArray);
+               motorDigest.update(DataType.MASS_SPECIFIC, totalW, totalW-propW);
+               motorDigest.update(DataType.FORCE_PER_TIME, thrustArray);
+               final String digest = motorDigest.getDigest();
+               
+               
+               try {
+                       
+                       return new ThrustCurveMotor(Manufacturer.getManufacturer(manufacturer), 
+                                       designation, comment, Motor.Type.UNKNOWN,
+                                       delays, diameter, length, timeArray, thrustArray, cgArray, digest);
+                       
+               } catch (IllegalArgumentException e) {
+                       
+                       // Bad data read from file.
+                       throw new IOException("Illegal file format.", e);
+                       
+               }
+       }
+}