1 package net.sf.openrocket.utils;
3 import java.io.FileInputStream;
4 import java.io.IOException;
5 import java.io.InputStream;
6 import java.util.ArrayList;
9 import net.sf.openrocket.file.GeneralMotorLoader;
10 import net.sf.openrocket.file.MotorLoader;
11 import net.sf.openrocket.motor.Manufacturer;
12 import net.sf.openrocket.motor.Motor;
13 import net.sf.openrocket.motor.ThrustCurveMotor;
15 public class MotorCompare {
17 /** Maximum allowed difference in maximum thrust */
18 private static final double MAX_THRUST_MARGIN = 0.20;
19 /** Maximum allowed difference in total impulse */
20 private static final double TOTAL_IMPULSE_MARGIN = 0.10;
21 /** Maximum allowed difference in mass values */
22 private static final double MASS_MARGIN = 0.10;
24 /** Number of time points in thrust curve to compare */
25 private static final int DIVISIONS = 100;
26 /** Maximum difference in thrust for a time point to be considered invalid */
27 private static final double THRUST_MARGIN = 0.15;
28 /** Number of invalid time points allowed */
29 private static final int ALLOWED_INVALID_POINTS = 15;
31 /** Minimum number of thrust curve points allowed (incl. start and end points) */
32 private static final int MIN_POINTS = 7;
35 public static void main(String[] args) throws IOException {
36 final double maxThrust;
48 List<String> cause = new ArrayList<String>();
50 MotorLoader loader = new GeneralMotorLoader();
51 List<Motor> motors = new ArrayList<Motor>();
52 List<String> files = new ArrayList<String>();
55 System.out.printf("Files :");
56 for (String file: args) {
57 System.out.printf("\t%s", file);
60 InputStream stream = new FileInputStream(file);
61 m = loader.load(stream, file);
63 } catch (IOException e) {
65 System.out.print("(ERR:" + e.getMessage() + ")");
69 for (int i=0; i<m.size(); i++)
75 if (motors.size() == 0) {
76 System.err.println("No motors loaded.");
77 System.out.println("ERROR: No motors loaded.\n");
82 if (motors.size() == 1) {
83 System.out.println("Best (ONLY): " + files.get(0));
88 final int n = motors.size();
89 goodness = new int[n];
93 System.out.printf("Manufacture:");
94 Manufacturer mfg = motors.get(0).getManufacturer();
95 for (Motor m: motors) {
96 System.out.printf("\t%s", m.getManufacturer());
97 if (m.getManufacturer() != mfg) {
98 cause.add("Manufacturer");
102 System.out.println();
107 min = Double.MAX_VALUE;
108 System.out.printf("Max.thrust :");
109 for (Motor m: motors) {
110 double f = m.getMaxThrust();
111 System.out.printf("\t%.2f", f);
112 max = Math.max(max, f);
113 min = Math.min(min, f);
115 diff = (max-min)/min;
116 if (diff > MAX_THRUST_MARGIN) {
118 cause.add("Max thrust");
120 System.out.printf("\t(discrepancy %.1f%%)\n", 100.0*diff);
121 maxThrust = (min+max)/2;
126 min = Double.MAX_VALUE;
127 System.out.printf("Total time :");
128 for (Motor m: motors) {
129 double t = m.getTotalTime();
130 System.out.printf("\t%.2f", t);
131 max = Math.max(max, t);
132 min = Math.min(min, t);
134 diff = (max-min)/min;
135 System.out.printf("\t(discrepancy %.1f%%)\n", 100.0*diff);
141 min = Double.MAX_VALUE;
142 System.out.printf("Impulse :");
143 for (Motor m: motors) {
144 double f = m.getTotalImpulse();
145 System.out.printf("\t%.2f", f);
146 max = Math.max(max, f);
147 min = Math.min(min, f);
149 diff = (max-min)/min;
150 if (diff > TOTAL_IMPULSE_MARGIN) {
152 cause.add("Total impulse");
154 System.out.printf("\t(discrepancy %.1f%%)\n", 100.0*diff);
159 min = Double.MAX_VALUE;
160 System.out.printf("Init mass :");
161 for (Motor m: motors) {
162 double f = m.getMass(0);
163 System.out.printf("\t%.2f", f*1000);
164 max = Math.max(max, f);
165 min = Math.min(min, f);
167 diff = (max-min)/min;
168 if (diff > MASS_MARGIN) {
170 cause.add("Initial mass");
172 System.out.printf("\t(discrepancy %.1f%%)\n", 100.0*diff);
177 min = Double.MAX_VALUE;
178 System.out.printf("Empty mass :");
179 for (Motor m: motors) {
180 double f = m.getMass(Double.POSITIVE_INFINITY);
181 System.out.printf("\t%.2f", f*1000);
182 max = Math.max(max, f);
183 min = Math.min(min, f);
185 diff = (max-min)/min;
186 if (diff > MASS_MARGIN) {
188 cause.add("Empty mass");
190 System.out.printf("\t(discrepancy %.1f%%)\n", 100.0*diff);
195 System.out.printf("Delays :");
196 for (Motor m: motors) {
197 System.out.printf("\t%d", m.getStandardDelays().length);
198 maxDelays = Math.max(maxDelays, m.getStandardDelays().length);
200 System.out.println();
205 System.out.printf("Points :");
206 for (Motor m: motors) {
207 System.out.printf("\t%d", ((ThrustCurveMotor)m).getTimePoints().length);
208 maxPoints = Math.max(maxPoints, ((ThrustCurveMotor)m).getTimePoints().length);
210 System.out.println();
215 System.out.printf("Comment len:");
216 for (Motor m: motors) {
217 System.out.printf("\t%d", m.getDescription().length());
218 maxCommentLen = Math.max(maxCommentLen, m.getDescription().length());
220 System.out.println();
224 String str = "ERROR: ";
225 for (int i=0; i<cause.size(); i++) {
227 if (i < cause.size()-1)
231 System.out.println(str);
232 System.out.println();
237 int invalidPoints = 0;
238 for (int i=0; i < DIVISIONS; i++) {
239 double t = maxTime * i/(DIVISIONS-1);
240 min = Double.MAX_VALUE;
242 // System.out.printf("%.2f:", t);
243 for (Motor m: motors) {
244 double f = m.getThrust(t);
245 // System.out.printf("\t%.2f", f);
246 min = Math.min(min, f);
247 max = Math.max(max, f);
249 diff = (max-min)/maxThrust;
250 // System.out.printf("\t(diff %.1f%%)\n", diff*100);
251 if (diff > THRUST_MARGIN)
255 if (invalidPoints > ALLOWED_INVALID_POINTS) {
256 System.out.println("ERROR: " + invalidPoints + "/" + DIVISIONS
257 + " points have thrust differing over " + (THRUST_MARGIN*100) + "%");
258 System.out.println();
264 for (int i=0; i<n; i++) {
265 Motor m = motors.get(i);
266 if (m.getStandardDelays().length == maxDelays)
268 if (((ThrustCurveMotor)m).getTimePoints().length == maxPoints)
270 if (m.getDescription().length() == maxCommentLen)
272 if (files.get(i).matches(".*\\.[rR][sS][eE]$"))
276 for (int i=1; i<n; i++) {
277 if (goodness[i] > goodness[best])
282 // Verify enough points
283 int pts = ((ThrustCurveMotor)motors.get(best)).getTimePoints().length;
284 if (pts < MIN_POINTS) {
285 System.out.println("ERROR: Best has only " + pts + " data points");
286 System.out.println();
290 System.out.println("Best (" + goodness[best] + "): " + files.get(best));
291 System.out.println();