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.motor.GeneralMotorLoader;
10 import net.sf.openrocket.file.motor.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.30;
19 /** Maximum allowed difference in total impulse */
20 private static final double TOTAL_IMPULSE_MARGIN = 0.20;
21 /** Maximum allowed difference in mass values */
22 private static final double MASS_MARGIN = 0.20;
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.20;
28 /** Number of invalid time points allowed */
29 private static final int ALLOWED_INVALID_POINTS = 20;
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<ThrustCurveMotor> motors = new ArrayList<ThrustCurveMotor>();
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() + ")");
68 motors.addAll((List) m);
69 for (int i = 0; i < m.size(); i++)
75 compare(motors, files);
82 public static void compare(List<ThrustCurveMotor> motors, List<String> files) {
83 final double maxThrust;
95 List<String> cause = new ArrayList<String>();
98 if (motors.size() == 0) {
99 System.err.println("No motors loaded.");
100 System.out.println("ERROR: No motors loaded.\n");
105 if (motors.size() == 1) {
106 System.out.println("Best (ONLY): " + files.get(0));
107 System.out.println();
111 final int n = motors.size();
112 goodness = new int[n];
115 for (String s : files) {
116 System.out.print("\t" + s);
118 System.out.println();
122 System.out.printf("Designation:");
123 String des = motors.get(0).getDesignation();
124 for (Motor m : motors) {
125 System.out.printf("\t%s", m.getDesignation());
126 if (!m.getDesignation().equals(des)) {
127 cause.add("Designation");
131 System.out.println();
134 System.out.printf("Manufacture:");
135 Manufacturer mfg = motors.get(0).getManufacturer();
136 for (ThrustCurveMotor m : motors) {
137 System.out.printf("\t%s", m.getManufacturer());
138 if (m.getManufacturer() != mfg) {
139 cause.add("Manufacturer");
143 System.out.println();
148 min = Double.MAX_VALUE;
149 System.out.printf("Max.thrust :");
150 for (Motor m : motors) {
151 double f = m.getMaxThrustEstimate();
152 System.out.printf("\t%.2f", f);
153 max = Math.max(max, f);
154 min = Math.min(min, f);
156 diff = (max - min) / min;
157 if (diff > MAX_THRUST_MARGIN) {
159 cause.add("Max thrust");
161 System.out.printf("\t(discrepancy %.1f%%)\n", 100.0 * diff);
162 maxThrust = (min + max) / 2;
167 min = Double.MAX_VALUE;
168 System.out.printf("Burn time :");
169 for (Motor m : motors) {
170 double t = m.getBurnTimeEstimate();
171 System.out.printf("\t%.2f", t);
172 max = Math.max(max, t);
173 min = Math.min(min, t);
175 diff = (max - min) / min;
176 System.out.printf("\t(discrepancy %.1f%%)\n", 100.0 * diff);
182 min = Double.MAX_VALUE;
183 System.out.printf("Impulse :");
184 for (Motor m : motors) {
185 double f = m.getTotalImpulseEstimate();
186 System.out.printf("\t%.2f", f);
187 max = Math.max(max, f);
188 min = Math.min(min, f);
190 diff = (max - min) / min;
191 if (diff > TOTAL_IMPULSE_MARGIN) {
193 cause.add("Total impulse");
195 System.out.printf("\t(discrepancy %.1f%%)\n", 100.0 * diff);
200 min = Double.MAX_VALUE;
201 System.out.printf("Init mass :");
202 for (Motor m : motors) {
203 double f = m.getLaunchCG().weight;
204 System.out.printf("\t%.2f", f * 1000);
205 max = Math.max(max, f);
206 min = Math.min(min, f);
208 diff = (max - min) / min;
209 if (diff > MASS_MARGIN) {
211 cause.add("Initial mass");
213 System.out.printf("\t(discrepancy %.1f%%)\n", 100.0 * diff);
218 min = Double.MAX_VALUE;
219 System.out.printf("Empty mass :");
220 for (Motor m : motors) {
221 double f = m.getEmptyCG().weight;
222 System.out.printf("\t%.2f", f * 1000);
223 max = Math.max(max, f);
224 min = Math.min(min, f);
226 diff = (max - min) / min;
227 if (diff > MASS_MARGIN) {
229 cause.add("Empty mass");
231 System.out.printf("\t(discrepancy %.1f%%)\n", 100.0 * diff);
236 System.out.printf("Delays :");
237 for (ThrustCurveMotor m : motors) {
238 System.out.printf("\t%d", m.getStandardDelays().length);
239 maxDelays = Math.max(maxDelays, m.getStandardDelays().length);
241 System.out.println();
246 System.out.printf("Points :");
247 for (Motor m : motors) {
248 System.out.printf("\t%d", ((ThrustCurveMotor) m).getTimePoints().length);
249 maxPoints = Math.max(maxPoints, ((ThrustCurveMotor) m).getTimePoints().length);
251 System.out.println();
256 System.out.printf("Comment len:");
257 for (Motor m : motors) {
258 System.out.printf("\t%d", m.getDescription().length());
259 maxCommentLen = Math.max(maxCommentLen, m.getDescription().length());
261 System.out.println();
265 String str = "ERROR: ";
266 for (int i = 0; i < cause.size(); i++) {
268 if (i < cause.size() - 1)
272 System.out.println(str);
273 System.out.println();
278 // TODO: Does not check consistency
279 // int invalidPoints = 0;
280 // for (int i = 0; i < DIVISIONS; i++) {
281 // double t = maxTime * i / (DIVISIONS - 1);
282 // min = Double.MAX_VALUE;
284 // // System.out.printf("%.2f:", t);
285 // for (Motor m : motors) {
286 // double f = m.getThrust(t);
287 // // System.out.printf("\t%.2f", f);
288 // min = Math.min(min, f);
289 // max = Math.max(max, f);
291 // diff = (max - min) / maxThrust;
292 // // System.out.printf("\t(diff %.1f%%)\n", diff*100);
293 // if (diff > THRUST_MARGIN)
297 // if (invalidPoints > ALLOWED_INVALID_POINTS) {
298 // System.out.println("ERROR: " + invalidPoints + "/" + DIVISIONS
299 // + " points have thrust differing over " + (THRUST_MARGIN * 100) + "%");
300 // System.out.println();
306 for (int i = 0; i < n; i++) {
307 ThrustCurveMotor m = motors.get(i);
308 if (m.getStandardDelays().length == maxDelays)
310 if (((ThrustCurveMotor) m).getTimePoints().length == maxPoints)
312 if (m.getDescription().length() == maxCommentLen)
314 if (files.get(i).matches(".*\\.[rR][sS][eE]$"))
318 for (int i = 1; i < n; i++) {
319 if (goodness[i] > goodness[best])
324 // Verify enough points
325 int pts = ((ThrustCurveMotor) motors.get(best)).getTimePoints().length;
326 if (pts < MIN_POINTS) {
327 System.out.println("WARNING: Best has only " + pts + " data points");
330 System.out.println("Best (" + goodness[best] + "): " + files.get(best));
331 System.out.println();