updates for 0.9.3
[debian/openrocket] / src / net / sf / openrocket / utils / MotorCompare.java
diff --git a/src/net/sf/openrocket/utils/MotorCompare.java b/src/net/sf/openrocket/utils/MotorCompare.java
new file mode 100644 (file)
index 0000000..ed6edc0
--- /dev/null
@@ -0,0 +1,288 @@
+package net.sf.openrocket.utils;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import net.sf.openrocket.file.GeneralMotorLoader;
+import net.sf.openrocket.file.MotorLoader;
+import net.sf.openrocket.rocketcomponent.Motor;
+import net.sf.openrocket.rocketcomponent.ThrustCurveMotor;
+
+public class MotorCompare {
+       
+       private static final double MAX_THRUST_MARGIN = 0.20;
+       private static final double TOTAL_IMPULSE_MARGIN = 0.10;
+       private static final double MASS_MARGIN = 0.10;
+       
+       private static final double THRUST_MARGIN = 0.15;
+       
+       private static final int DIVISIONS = 100;
+       private static final int ALLOWED_INVALID_POINTS = 15;
+       
+       private static final int MIN_POINTS = 7;
+
+       public static void main(String[] args) throws IOException {
+               final double maxThrust;
+               final double maxTime;
+               int maxDelays;
+               int maxPoints;
+               int maxCommentLen;
+
+               double min, max;
+               double diff;
+               
+               int[] goodness;
+               
+               boolean bad = false;
+               List<String> cause = new ArrayList<String>();
+               
+               MotorLoader loader = new GeneralMotorLoader();
+               List<Motor> motors = new ArrayList<Motor>();
+               List<String> files = new ArrayList<String>();
+               
+               // Load files
+               System.out.printf("Files      :");
+               for (String file: args) {
+                       System.out.printf("\t%s", file);
+                       List<Motor> m = null;
+                       try {
+                               InputStream stream = new FileInputStream(file);
+                               m = loader.load(stream, file);
+                               stream.close();
+                       } catch (IOException e) {
+                               e.printStackTrace();
+                               System.out.print("(ERR:" + e.getMessage() + ")");
+                       }
+                       if (m != null) {
+                               motors.addAll(m);
+                               for (int i=0; i<m.size(); i++)
+                                       files.add(file);
+                       }
+               }
+               System.out.println();
+               
+               if (motors.size() == 0) {
+                       System.err.println("No motors loaded.");
+                       System.out.println("ERROR: No motors loaded.\n");
+                       return;
+                       
+               }
+               
+               if (motors.size() == 1) {
+                       System.out.println("Best (ONLY): " + files.get(0));
+                       System.out.println();
+                       return;
+               }
+               
+               final int n = motors.size(); 
+               goodness = new int[n];
+               
+               
+               // Manufacturers
+               System.out.printf("Manufacture:");
+               String mfg = motors.get(0).getManufacturer();
+               for (Motor m: motors) {
+                       System.out.printf("\t%s", m.getManufacturer());
+                       if (!m.getManufacturer().equals(mfg)) {
+                               cause.add("Manufacturer");
+                               bad = true;
+                       }
+               }
+               System.out.println();
+               
+               
+               // Max. thrust
+               max = 0;
+               min = Double.MAX_VALUE;
+               System.out.printf("Max.thrust :");
+               for (Motor m: motors) {
+                       double f = m.getMaxThrust();
+                       System.out.printf("\t%.2f", f);
+                       max = Math.max(max, f);
+                       min = Math.min(min, f);
+               }
+               diff = (max-min)/min;
+               if (diff > MAX_THRUST_MARGIN) {
+                       bad = true;
+                       cause.add("Max thrust");
+               }
+               System.out.printf("\t(discrepancy %.1f%%)\n", 100.0*diff);
+               maxThrust = (min+max)/2;
+               
+               
+               // Total time
+               max = 0;
+               min = Double.MAX_VALUE;
+               System.out.printf("Total time :");
+               for (Motor m: motors) {
+                       double t = m.getTotalTime();
+                       System.out.printf("\t%.2f", t);
+                       max = Math.max(max, t);
+                       min = Math.min(min, t);
+               }
+               diff = (max-min)/min;
+               System.out.printf("\t(discrepancy %.1f%%)\n", 100.0*diff);
+               maxTime = max;
+               
+               
+               // Total impulse
+               max = 0;
+               min = Double.MAX_VALUE;
+               System.out.printf("Impulse    :");
+               for (Motor m: motors) {
+                       double f = m.getTotalImpulse();
+                       System.out.printf("\t%.2f", f);
+                       max = Math.max(max, f);
+                       min = Math.min(min, f);
+               }
+               diff = (max-min)/min;
+               if (diff > TOTAL_IMPULSE_MARGIN) {
+                       bad = true;
+                       cause.add("Total impulse");
+               }
+               System.out.printf("\t(discrepancy %.1f%%)\n", 100.0*diff);
+               
+               
+               // Initial mass
+               max = 0;
+               min = Double.MAX_VALUE;
+               System.out.printf("Init mass  :");
+               for (Motor m: motors) {
+                       double f = m.getMass(0);
+                       System.out.printf("\t%.2f", f*1000);
+                       max = Math.max(max, f);
+                       min = Math.min(min, f);
+               }
+               diff = (max-min)/min;
+               if (diff > MASS_MARGIN) {
+                       bad = true;
+                       cause.add("Initial mass");
+               }
+               System.out.printf("\t(discrepancy %.1f%%)\n", 100.0*diff);
+               
+               
+               // Empty mass
+               max = 0;
+               min = Double.MAX_VALUE;
+               System.out.printf("Empty mass :");
+               for (Motor m: motors) {
+                       double f = m.getMass(Double.POSITIVE_INFINITY);
+                       System.out.printf("\t%.2f", f*1000);
+                       max = Math.max(max, f);
+                       min = Math.min(min, f);
+               }
+               diff = (max-min)/min;
+               if (diff > MASS_MARGIN) {
+                       bad = true;
+                       cause.add("Empty mass");
+               }
+               System.out.printf("\t(discrepancy %.1f%%)\n", 100.0*diff);
+               
+               
+               // Delays
+               maxDelays = 0;
+               System.out.printf("Delays     :");
+               for (Motor m: motors) {
+                       System.out.printf("\t%d", m.getStandardDelays().length);
+                       maxDelays = Math.max(maxDelays, m.getStandardDelays().length);
+               }
+               System.out.println();
+               
+               
+               // Data points
+               maxPoints = 0;
+               System.out.printf("Points     :");
+               for (Motor m: motors) {
+                       System.out.printf("\t%d", ((ThrustCurveMotor)m).getTimePoints().length);
+                       maxPoints = Math.max(maxPoints, ((ThrustCurveMotor)m).getTimePoints().length);
+               }
+               System.out.println();
+               
+               
+               // Comment length
+               maxCommentLen = 0;
+               System.out.printf("Comment len:");
+               for (Motor m: motors) {
+                       System.out.printf("\t%d", m.getDescription().length());
+                       maxCommentLen = Math.max(maxCommentLen, m.getDescription().length());
+               }
+               System.out.println();
+               
+               
+               if (bad) {
+                       String str = "ERROR: ";
+                       for (int i=0; i<cause.size(); i++) {
+                               str += cause.get(i);
+                               if (i < cause.size()-1)
+                                       str += ", ";
+                       }
+                       str += " differs";
+                       System.out.println(str);
+                       System.out.println();
+                       return;
+               }
+               
+               // Check consistency
+               int invalidPoints = 0;
+               for (int i=0; i < DIVISIONS; i++) {
+                       double t = maxTime * i/(DIVISIONS-1);
+                       min = Double.MAX_VALUE;
+                       max = 0;
+//                     System.out.printf("%.2f:", t);
+                       for (Motor m: motors) {
+                               double f = m.getThrust(t);
+//                             System.out.printf("\t%.2f", f);
+                               min = Math.min(min, f);
+                               max = Math.max(max, f);
+                       }
+                       diff = (max-min)/maxThrust;
+//                     System.out.printf("\t(diff %.1f%%)\n", diff*100);
+                       if (diff > THRUST_MARGIN)
+                               invalidPoints++;
+               }
+               
+               if (invalidPoints > ALLOWED_INVALID_POINTS) {
+                       System.out.println("ERROR: " + invalidPoints + "/" + DIVISIONS 
+                                       + " points have thrust differing over " + (THRUST_MARGIN*100) + "%");
+                       System.out.println();
+                       return;
+               }
+               
+               
+               // Check goodness
+               for (int i=0; i<n; i++) {
+                       Motor m = motors.get(i);
+                       if (m.getStandardDelays().length == maxDelays)
+                               goodness[i] += 1000;
+                       if (((ThrustCurveMotor)m).getTimePoints().length == maxPoints)
+                               goodness[i] += 100;
+                       if (m.getDescription().length() == maxCommentLen)
+                               goodness[i] += 10;
+                       if (files.get(i).matches(".*\\.[rR][sS][eE]$"))
+                               goodness[i] += 1;
+               }
+               int best = 0;
+               for (int i=1; i<n; i++) {
+                       if (goodness[i] > goodness[best])
+                               best = i;
+               }
+               
+               
+               // Verify enough points
+               int pts = ((ThrustCurveMotor)motors.get(best)).getTimePoints().length;
+               if (pts < MIN_POINTS) {
+                       System.out.println("ERROR: Best has only " + pts + " data points");
+                       System.out.println();
+                       return;
+               }
+               
+               System.out.println("Best (" + goodness[best] + "): " + files.get(best));
+               System.out.println();
+               
+               
+       }
+       
+}