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.rocketcomponent.Motor;
12 import net.sf.openrocket.rocketcomponent.ThrustCurveMotor;
14 public class MotorCompare {
16 private static final double MAX_THRUST_MARGIN = 0.20;
17 private static final double TOTAL_IMPULSE_MARGIN = 0.10;
18 private static final double MASS_MARGIN = 0.10;
20 private static final double THRUST_MARGIN = 0.15;
22 private static final int DIVISIONS = 100;
23 private static final int ALLOWED_INVALID_POINTS = 15;
25 private static final int MIN_POINTS = 7;
27 public static void main(String[] args) throws IOException {
28 final double maxThrust;
40 List<String> cause = new ArrayList<String>();
42 MotorLoader loader = new GeneralMotorLoader();
43 List<Motor> motors = new ArrayList<Motor>();
44 List<String> files = new ArrayList<String>();
47 System.out.printf("Files :");
48 for (String file: args) {
49 System.out.printf("\t%s", file);
52 InputStream stream = new FileInputStream(file);
53 m = loader.load(stream, file);
55 } catch (IOException e) {
57 System.out.print("(ERR:" + e.getMessage() + ")");
61 for (int i=0; i<m.size(); i++)
67 if (motors.size() == 0) {
68 System.err.println("No motors loaded.");
69 System.out.println("ERROR: No motors loaded.\n");
74 if (motors.size() == 1) {
75 System.out.println("Best (ONLY): " + files.get(0));
80 final int n = motors.size();
81 goodness = new int[n];
85 System.out.printf("Manufacture:");
86 String mfg = motors.get(0).getManufacturer();
87 for (Motor m: motors) {
88 System.out.printf("\t%s", m.getManufacturer());
89 if (!m.getManufacturer().equals(mfg)) {
90 cause.add("Manufacturer");
99 min = Double.MAX_VALUE;
100 System.out.printf("Max.thrust :");
101 for (Motor m: motors) {
102 double f = m.getMaxThrust();
103 System.out.printf("\t%.2f", f);
104 max = Math.max(max, f);
105 min = Math.min(min, f);
107 diff = (max-min)/min;
108 if (diff > MAX_THRUST_MARGIN) {
110 cause.add("Max thrust");
112 System.out.printf("\t(discrepancy %.1f%%)\n", 100.0*diff);
113 maxThrust = (min+max)/2;
118 min = Double.MAX_VALUE;
119 System.out.printf("Total time :");
120 for (Motor m: motors) {
121 double t = m.getTotalTime();
122 System.out.printf("\t%.2f", t);
123 max = Math.max(max, t);
124 min = Math.min(min, t);
126 diff = (max-min)/min;
127 System.out.printf("\t(discrepancy %.1f%%)\n", 100.0*diff);
133 min = Double.MAX_VALUE;
134 System.out.printf("Impulse :");
135 for (Motor m: motors) {
136 double f = m.getTotalImpulse();
137 System.out.printf("\t%.2f", f);
138 max = Math.max(max, f);
139 min = Math.min(min, f);
141 diff = (max-min)/min;
142 if (diff > TOTAL_IMPULSE_MARGIN) {
144 cause.add("Total impulse");
146 System.out.printf("\t(discrepancy %.1f%%)\n", 100.0*diff);
151 min = Double.MAX_VALUE;
152 System.out.printf("Init mass :");
153 for (Motor m: motors) {
154 double f = m.getMass(0);
155 System.out.printf("\t%.2f", f*1000);
156 max = Math.max(max, f);
157 min = Math.min(min, f);
159 diff = (max-min)/min;
160 if (diff > MASS_MARGIN) {
162 cause.add("Initial mass");
164 System.out.printf("\t(discrepancy %.1f%%)\n", 100.0*diff);
169 min = Double.MAX_VALUE;
170 System.out.printf("Empty mass :");
171 for (Motor m: motors) {
172 double f = m.getMass(Double.POSITIVE_INFINITY);
173 System.out.printf("\t%.2f", f*1000);
174 max = Math.max(max, f);
175 min = Math.min(min, f);
177 diff = (max-min)/min;
178 if (diff > MASS_MARGIN) {
180 cause.add("Empty mass");
182 System.out.printf("\t(discrepancy %.1f%%)\n", 100.0*diff);
187 System.out.printf("Delays :");
188 for (Motor m: motors) {
189 System.out.printf("\t%d", m.getStandardDelays().length);
190 maxDelays = Math.max(maxDelays, m.getStandardDelays().length);
192 System.out.println();
197 System.out.printf("Points :");
198 for (Motor m: motors) {
199 System.out.printf("\t%d", ((ThrustCurveMotor)m).getTimePoints().length);
200 maxPoints = Math.max(maxPoints, ((ThrustCurveMotor)m).getTimePoints().length);
202 System.out.println();
207 System.out.printf("Comment len:");
208 for (Motor m: motors) {
209 System.out.printf("\t%d", m.getDescription().length());
210 maxCommentLen = Math.max(maxCommentLen, m.getDescription().length());
212 System.out.println();
216 String str = "ERROR: ";
217 for (int i=0; i<cause.size(); i++) {
219 if (i < cause.size()-1)
223 System.out.println(str);
224 System.out.println();
229 int invalidPoints = 0;
230 for (int i=0; i < DIVISIONS; i++) {
231 double t = maxTime * i/(DIVISIONS-1);
232 min = Double.MAX_VALUE;
234 // System.out.printf("%.2f:", t);
235 for (Motor m: motors) {
236 double f = m.getThrust(t);
237 // System.out.printf("\t%.2f", f);
238 min = Math.min(min, f);
239 max = Math.max(max, f);
241 diff = (max-min)/maxThrust;
242 // System.out.printf("\t(diff %.1f%%)\n", diff*100);
243 if (diff > THRUST_MARGIN)
247 if (invalidPoints > ALLOWED_INVALID_POINTS) {
248 System.out.println("ERROR: " + invalidPoints + "/" + DIVISIONS
249 + " points have thrust differing over " + (THRUST_MARGIN*100) + "%");
250 System.out.println();
256 for (int i=0; i<n; i++) {
257 Motor m = motors.get(i);
258 if (m.getStandardDelays().length == maxDelays)
260 if (((ThrustCurveMotor)m).getTimePoints().length == maxPoints)
262 if (m.getDescription().length() == maxCommentLen)
264 if (files.get(i).matches(".*\\.[rR][sS][eE]$"))
268 for (int i=1; i<n; i++) {
269 if (goodness[i] > goodness[best])
274 // Verify enough points
275 int pts = ((ThrustCurveMotor)motors.get(best)).getTimePoints().length;
276 if (pts < MIN_POINTS) {
277 System.out.println("ERROR: Best has only " + pts + " data points");
278 System.out.println();
282 System.out.println("Best (" + goodness[best] + "): " + files.get(best));
283 System.out.println();