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 private static final double MAX_THRUST_MARGIN = 0.20;
18 private static final double TOTAL_IMPULSE_MARGIN = 0.10;
19 private static final double MASS_MARGIN = 0.10;
21 private static final double THRUST_MARGIN = 0.15;
23 private static final int DIVISIONS = 100;
24 private static final int ALLOWED_INVALID_POINTS = 15;
26 private static final int MIN_POINTS = 7;
28 public static void main(String[] args) throws IOException {
29 final double maxThrust;
41 List<String> cause = new ArrayList<String>();
43 MotorLoader loader = new GeneralMotorLoader();
44 List<Motor> motors = new ArrayList<Motor>();
45 List<String> files = new ArrayList<String>();
48 System.out.printf("Files :");
49 for (String file: args) {
50 System.out.printf("\t%s", file);
53 InputStream stream = new FileInputStream(file);
54 m = loader.load(stream, file);
56 } catch (IOException e) {
58 System.out.print("(ERR:" + e.getMessage() + ")");
62 for (int i=0; i<m.size(); i++)
68 if (motors.size() == 0) {
69 System.err.println("No motors loaded.");
70 System.out.println("ERROR: No motors loaded.\n");
75 if (motors.size() == 1) {
76 System.out.println("Best (ONLY): " + files.get(0));
81 final int n = motors.size();
82 goodness = new int[n];
86 System.out.printf("Manufacture:");
87 Manufacturer mfg = motors.get(0).getManufacturer();
88 for (Motor m: motors) {
89 System.out.printf("\t%s", m.getManufacturer());
90 if (m.getManufacturer() != mfg) {
91 cause.add("Manufacturer");
100 min = Double.MAX_VALUE;
101 System.out.printf("Max.thrust :");
102 for (Motor m: motors) {
103 double f = m.getMaxThrust();
104 System.out.printf("\t%.2f", f);
105 max = Math.max(max, f);
106 min = Math.min(min, f);
108 diff = (max-min)/min;
109 if (diff > MAX_THRUST_MARGIN) {
111 cause.add("Max thrust");
113 System.out.printf("\t(discrepancy %.1f%%)\n", 100.0*diff);
114 maxThrust = (min+max)/2;
119 min = Double.MAX_VALUE;
120 System.out.printf("Total time :");
121 for (Motor m: motors) {
122 double t = m.getTotalTime();
123 System.out.printf("\t%.2f", t);
124 max = Math.max(max, t);
125 min = Math.min(min, t);
127 diff = (max-min)/min;
128 System.out.printf("\t(discrepancy %.1f%%)\n", 100.0*diff);
134 min = Double.MAX_VALUE;
135 System.out.printf("Impulse :");
136 for (Motor m: motors) {
137 double f = m.getTotalImpulse();
138 System.out.printf("\t%.2f", f);
139 max = Math.max(max, f);
140 min = Math.min(min, f);
142 diff = (max-min)/min;
143 if (diff > TOTAL_IMPULSE_MARGIN) {
145 cause.add("Total impulse");
147 System.out.printf("\t(discrepancy %.1f%%)\n", 100.0*diff);
152 min = Double.MAX_VALUE;
153 System.out.printf("Init mass :");
154 for (Motor m: motors) {
155 double f = m.getMass(0);
156 System.out.printf("\t%.2f", f*1000);
157 max = Math.max(max, f);
158 min = Math.min(min, f);
160 diff = (max-min)/min;
161 if (diff > MASS_MARGIN) {
163 cause.add("Initial mass");
165 System.out.printf("\t(discrepancy %.1f%%)\n", 100.0*diff);
170 min = Double.MAX_VALUE;
171 System.out.printf("Empty mass :");
172 for (Motor m: motors) {
173 double f = m.getMass(Double.POSITIVE_INFINITY);
174 System.out.printf("\t%.2f", f*1000);
175 max = Math.max(max, f);
176 min = Math.min(min, f);
178 diff = (max-min)/min;
179 if (diff > MASS_MARGIN) {
181 cause.add("Empty mass");
183 System.out.printf("\t(discrepancy %.1f%%)\n", 100.0*diff);
188 System.out.printf("Delays :");
189 for (Motor m: motors) {
190 System.out.printf("\t%d", m.getStandardDelays().length);
191 maxDelays = Math.max(maxDelays, m.getStandardDelays().length);
193 System.out.println();
198 System.out.printf("Points :");
199 for (Motor m: motors) {
200 System.out.printf("\t%d", ((ThrustCurveMotor)m).getTimePoints().length);
201 maxPoints = Math.max(maxPoints, ((ThrustCurveMotor)m).getTimePoints().length);
203 System.out.println();
208 System.out.printf("Comment len:");
209 for (Motor m: motors) {
210 System.out.printf("\t%d", m.getDescription().length());
211 maxCommentLen = Math.max(maxCommentLen, m.getDescription().length());
213 System.out.println();
217 String str = "ERROR: ";
218 for (int i=0; i<cause.size(); i++) {
220 if (i < cause.size()-1)
224 System.out.println(str);
225 System.out.println();
230 int invalidPoints = 0;
231 for (int i=0; i < DIVISIONS; i++) {
232 double t = maxTime * i/(DIVISIONS-1);
233 min = Double.MAX_VALUE;
235 // System.out.printf("%.2f:", t);
236 for (Motor m: motors) {
237 double f = m.getThrust(t);
238 // System.out.printf("\t%.2f", f);
239 min = Math.min(min, f);
240 max = Math.max(max, f);
242 diff = (max-min)/maxThrust;
243 // System.out.printf("\t(diff %.1f%%)\n", diff*100);
244 if (diff > THRUST_MARGIN)
248 if (invalidPoints > ALLOWED_INVALID_POINTS) {
249 System.out.println("ERROR: " + invalidPoints + "/" + DIVISIONS
250 + " points have thrust differing over " + (THRUST_MARGIN*100) + "%");
251 System.out.println();
257 for (int i=0; i<n; i++) {
258 Motor m = motors.get(i);
259 if (m.getStandardDelays().length == maxDelays)
261 if (((ThrustCurveMotor)m).getTimePoints().length == maxPoints)
263 if (m.getDescription().length() == maxCommentLen)
265 if (files.get(i).matches(".*\\.[rR][sS][eE]$"))
269 for (int i=1; i<n; i++) {
270 if (goodness[i] > goodness[best])
275 // Verify enough points
276 int pts = ((ThrustCurveMotor)motors.get(best)).getTimePoints().length;
277 if (pts < MIN_POINTS) {
278 System.out.println("ERROR: Best has only " + pts + " data points");
279 System.out.println();
283 System.out.println("Best (" + goodness[best] + "): " + files.get(best));
284 System.out.println();