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