updates for 0.9.3
[debian/openrocket] / src / net / sf / openrocket / utils / MotorCompare.java
1 package net.sf.openrocket.utils;
2
3 import java.io.FileInputStream;
4 import java.io.IOException;
5 import java.io.InputStream;
6 import java.util.ArrayList;
7 import java.util.List;
8
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;
14
15 public class MotorCompare {
16         
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;
20         
21         private static final double THRUST_MARGIN = 0.15;
22         
23         private static final int DIVISIONS = 100;
24         private static final int ALLOWED_INVALID_POINTS = 15;
25         
26         private static final int MIN_POINTS = 7;
27
28         public static void main(String[] args) throws IOException {
29                 final double maxThrust;
30                 final double maxTime;
31                 int maxDelays;
32                 int maxPoints;
33                 int maxCommentLen;
34
35                 double min, max;
36                 double diff;
37                 
38                 int[] goodness;
39                 
40                 boolean bad = false;
41                 List<String> cause = new ArrayList<String>();
42                 
43                 MotorLoader loader = new GeneralMotorLoader();
44                 List<Motor> motors = new ArrayList<Motor>();
45                 List<String> files = new ArrayList<String>();
46                 
47                 // Load files
48                 System.out.printf("Files      :");
49                 for (String file: args) {
50                         System.out.printf("\t%s", file);
51                         List<Motor> m = null;
52                         try {
53                                 InputStream stream = new FileInputStream(file);
54                                 m = loader.load(stream, file);
55                                 stream.close();
56                         } catch (IOException e) {
57                                 e.printStackTrace();
58                                 System.out.print("(ERR:" + e.getMessage() + ")");
59                         }
60                         if (m != null) {
61                                 motors.addAll(m);
62                                 for (int i=0; i<m.size(); i++)
63                                         files.add(file);
64                         }
65                 }
66                 System.out.println();
67                 
68                 if (motors.size() == 0) {
69                         System.err.println("No motors loaded.");
70                         System.out.println("ERROR: No motors loaded.\n");
71                         return;
72                         
73                 }
74                 
75                 if (motors.size() == 1) {
76                         System.out.println("Best (ONLY): " + files.get(0));
77                         System.out.println();
78                         return;
79                 }
80                 
81                 final int n = motors.size(); 
82                 goodness = new int[n];
83                 
84                 
85                 // Manufacturers
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");
92                                 bad = true;
93                         }
94                 }
95                 System.out.println();
96                 
97                 
98                 // Max. thrust
99                 max = 0;
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);
107                 }
108                 diff = (max-min)/min;
109                 if (diff > MAX_THRUST_MARGIN) {
110                         bad = true;
111                         cause.add("Max thrust");
112                 }
113                 System.out.printf("\t(discrepancy %.1f%%)\n", 100.0*diff);
114                 maxThrust = (min+max)/2;
115                 
116                 
117                 // Total time
118                 max = 0;
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);
126                 }
127                 diff = (max-min)/min;
128                 System.out.printf("\t(discrepancy %.1f%%)\n", 100.0*diff);
129                 maxTime = max;
130                 
131                 
132                 // Total impulse
133                 max = 0;
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);
141                 }
142                 diff = (max-min)/min;
143                 if (diff > TOTAL_IMPULSE_MARGIN) {
144                         bad = true;
145                         cause.add("Total impulse");
146                 }
147                 System.out.printf("\t(discrepancy %.1f%%)\n", 100.0*diff);
148                 
149                 
150                 // Initial mass
151                 max = 0;
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);
159                 }
160                 diff = (max-min)/min;
161                 if (diff > MASS_MARGIN) {
162                         bad = true;
163                         cause.add("Initial mass");
164                 }
165                 System.out.printf("\t(discrepancy %.1f%%)\n", 100.0*diff);
166                 
167                 
168                 // Empty mass
169                 max = 0;
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);
177                 }
178                 diff = (max-min)/min;
179                 if (diff > MASS_MARGIN) {
180                         bad = true;
181                         cause.add("Empty mass");
182                 }
183                 System.out.printf("\t(discrepancy %.1f%%)\n", 100.0*diff);
184                 
185                 
186                 // Delays
187                 maxDelays = 0;
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);
192                 }
193                 System.out.println();
194                 
195                 
196                 // Data points
197                 maxPoints = 0;
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);
202                 }
203                 System.out.println();
204                 
205                 
206                 // Comment length
207                 maxCommentLen = 0;
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());
212                 }
213                 System.out.println();
214                 
215                 
216                 if (bad) {
217                         String str = "ERROR: ";
218                         for (int i=0; i<cause.size(); i++) {
219                                 str += cause.get(i);
220                                 if (i < cause.size()-1)
221                                         str += ", ";
222                         }
223                         str += " differs";
224                         System.out.println(str);
225                         System.out.println();
226                         return;
227                 }
228                 
229                 // Check consistency
230                 int invalidPoints = 0;
231                 for (int i=0; i < DIVISIONS; i++) {
232                         double t = maxTime * i/(DIVISIONS-1);
233                         min = Double.MAX_VALUE;
234                         max = 0;
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);
241                         }
242                         diff = (max-min)/maxThrust;
243 //                      System.out.printf("\t(diff %.1f%%)\n", diff*100);
244                         if (diff > THRUST_MARGIN)
245                                 invalidPoints++;
246                 }
247                 
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();
252                         return;
253                 }
254                 
255                 
256                 // Check goodness
257                 for (int i=0; i<n; i++) {
258                         Motor m = motors.get(i);
259                         if (m.getStandardDelays().length == maxDelays)
260                                 goodness[i] += 1000;
261                         if (((ThrustCurveMotor)m).getTimePoints().length == maxPoints)
262                                 goodness[i] += 100;
263                         if (m.getDescription().length() == maxCommentLen)
264                                 goodness[i] += 10;
265                         if (files.get(i).matches(".*\\.[rR][sS][eE]$"))
266                                 goodness[i] += 1;
267                 }
268                 int best = 0;
269                 for (int i=1; i<n; i++) {
270                         if (goodness[i] > goodness[best])
271                                 best = i;
272                 }
273                 
274                 
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();
280                         return;
281                 }
282                 
283                 System.out.println("Best (" + goodness[best] + "): " + files.get(best));
284                 System.out.println();
285                 
286                 
287         }
288         
289 }