Material localization support
[debian/openrocket] / core / src / net / sf / openrocket / util / TestRockets.java
1 package net.sf.openrocket.util;
2
3 import java.util.Random;
4
5 import net.sf.openrocket.database.Databases;
6 import net.sf.openrocket.material.Material;
7 import net.sf.openrocket.material.Material.Type;
8 import net.sf.openrocket.motor.Motor;
9 import net.sf.openrocket.rocketcomponent.BodyTube;
10 import net.sf.openrocket.rocketcomponent.Bulkhead;
11 import net.sf.openrocket.rocketcomponent.CenteringRing;
12 import net.sf.openrocket.rocketcomponent.ExternalComponent;
13 import net.sf.openrocket.rocketcomponent.ExternalComponent.Finish;
14 import net.sf.openrocket.rocketcomponent.FinSet.CrossSection;
15 import net.sf.openrocket.rocketcomponent.FreeformFinSet;
16 import net.sf.openrocket.rocketcomponent.IllegalFinPointException;
17 import net.sf.openrocket.rocketcomponent.InnerTube;
18 import net.sf.openrocket.rocketcomponent.InternalComponent;
19 import net.sf.openrocket.rocketcomponent.LaunchLug;
20 import net.sf.openrocket.rocketcomponent.MassComponent;
21 import net.sf.openrocket.rocketcomponent.MotorMount.IgnitionEvent;
22 import net.sf.openrocket.rocketcomponent.NoseCone;
23 import net.sf.openrocket.rocketcomponent.ReferenceType;
24 import net.sf.openrocket.rocketcomponent.Rocket;
25 import net.sf.openrocket.rocketcomponent.RocketComponent;
26 import net.sf.openrocket.rocketcomponent.RocketComponent.Position;
27 import net.sf.openrocket.rocketcomponent.Stage;
28 import net.sf.openrocket.rocketcomponent.Transition;
29 import net.sf.openrocket.rocketcomponent.Transition.Shape;
30 import net.sf.openrocket.rocketcomponent.TrapezoidFinSet;
31 import net.sf.openrocket.rocketcomponent.TubeCoupler;
32 import net.sf.openrocket.startup.Application;
33
34 public class TestRockets {
35         
36         private final String key;
37         private final Random rnd;
38         
39         
40         public TestRockets(String key) {
41                 
42                 if (key == null) {
43                         Random rnd = new Random();
44                         StringBuilder sb = new StringBuilder();
45                         for (int i = 0; i < 6; i++) {
46                                 int n = rnd.nextInt(62);
47                                 if (n < 10) {
48                                         sb.append((char) ('0' + n));
49                                 } else if (n < 36) {
50                                         sb.append((char) ('A' + n - 10));
51                                 } else {
52                                         sb.append((char) ('a' + n - 36));
53                                 }
54                         }
55                         key = sb.toString();
56                 }
57                 
58                 this.key = key;
59                 this.rnd = new Random(key.hashCode());
60                 
61         }
62         
63         
64         /**
65          * Create a new test rocket based on the value 'key'.  The rocket utilizes most of the 
66          * properties and features available.  The same key always returns the same rocket,
67          * but different key values produce slightly different rockets.  A key value of
68          * <code>null</code> generates a rocket using a random key.
69          * <p>
70          * The rocket created by this method is not fly-worthy.  It is also NOT guaranteed
71          * that later versions would produce exactly the same rocket!
72          * 
73          * @return              a rocket design.
74          */
75         public Rocket makeTestRocket() {
76                 
77                 Rocket rocket = new Rocket();
78                 setBasics(rocket);
79                 rocket.setCustomReferenceLength(rnd(0.05));
80                 rocket.setDesigner("Designer " + key);
81                 rocket.setReferenceType((ReferenceType) randomEnum(ReferenceType.class));
82                 rocket.setRevision("Rocket revision " + key);
83                 rocket.setName(key);
84                 
85                 
86                 Stage stage = new Stage();
87                 setBasics(stage);
88                 rocket.addChild(stage);
89                 
90                 
91                 NoseCone nose = new NoseCone();
92                 setBasics(stage);
93                 nose.setAftRadius(rnd(0.03));
94                 nose.setAftRadiusAutomatic(rnd.nextBoolean());
95                 nose.setAftShoulderCapped(rnd.nextBoolean());
96                 nose.setAftShoulderLength(rnd(0.02));
97                 nose.setAftShoulderRadius(rnd(0.02));
98                 nose.setAftShoulderThickness(rnd(0.002));
99                 nose.setClipped(rnd.nextBoolean());
100                 nose.setThickness(rnd(0.002));
101                 nose.setFilled(rnd.nextBoolean());
102                 nose.setForeRadius(rnd(0.1)); // Unset
103                 nose.setLength(rnd(0.15));
104                 nose.setShapeParameter(rnd(0.5));
105                 nose.setType((Shape) randomEnum(Shape.class));
106                 stage.addChild(nose);
107                 
108                 
109                 Transition shoulder = new Transition();
110                 setBasics(shoulder);
111                 shoulder.setAftRadius(rnd(0.06));
112                 shoulder.setAftRadiusAutomatic(rnd.nextBoolean());
113                 shoulder.setAftShoulderCapped(rnd.nextBoolean());
114                 shoulder.setAftShoulderLength(rnd(0.02));
115                 shoulder.setAftShoulderRadius(rnd(0.05));
116                 shoulder.setAftShoulderThickness(rnd(0.002));
117                 shoulder.setClipped(rnd.nextBoolean());
118                 shoulder.setThickness(rnd(0.002));
119                 shoulder.setFilled(rnd.nextBoolean());
120                 shoulder.setForeRadius(rnd(0.03));
121                 shoulder.setForeRadiusAutomatic(rnd.nextBoolean());
122                 shoulder.setForeShoulderCapped(rnd.nextBoolean());
123                 shoulder.setForeShoulderLength(rnd(0.02));
124                 shoulder.setForeShoulderRadius(rnd(0.02));
125                 shoulder.setForeShoulderThickness(rnd(0.002));
126                 shoulder.setLength(rnd(0.15));
127                 shoulder.setShapeParameter(rnd(0.5));
128                 shoulder.setThickness(rnd(0.003));
129                 shoulder.setType((Shape) randomEnum(Shape.class));
130                 stage.addChild(shoulder);
131                 
132                 
133                 BodyTube body = new BodyTube();
134                 setBasics(body);
135                 body.setThickness(rnd(0.002));
136                 body.setFilled(rnd.nextBoolean());
137                 body.setIgnitionDelay(rnd.nextDouble() * 3);
138                 body.setIgnitionEvent((IgnitionEvent) randomEnum(IgnitionEvent.class));
139                 body.setLength(rnd(0.3));
140                 body.setMotorMount(rnd.nextBoolean());
141                 body.setMotorOverhang(rnd.nextGaussian() * 0.03);
142                 body.setOuterRadius(rnd(0.06));
143                 body.setOuterRadiusAutomatic(rnd.nextBoolean());
144                 stage.addChild(body);
145                 
146                 
147                 Transition boattail = new Transition();
148                 setBasics(boattail);
149                 boattail.setAftRadius(rnd(0.03));
150                 boattail.setAftRadiusAutomatic(rnd.nextBoolean());
151                 boattail.setAftShoulderCapped(rnd.nextBoolean());
152                 boattail.setAftShoulderLength(rnd(0.02));
153                 boattail.setAftShoulderRadius(rnd(0.02));
154                 boattail.setAftShoulderThickness(rnd(0.002));
155                 boattail.setClipped(rnd.nextBoolean());
156                 boattail.setThickness(rnd(0.002));
157                 boattail.setFilled(rnd.nextBoolean());
158                 boattail.setForeRadius(rnd(0.06));
159                 boattail.setForeRadiusAutomatic(rnd.nextBoolean());
160                 boattail.setForeShoulderCapped(rnd.nextBoolean());
161                 boattail.setForeShoulderLength(rnd(0.02));
162                 boattail.setForeShoulderRadius(rnd(0.05));
163                 boattail.setForeShoulderThickness(rnd(0.002));
164                 boattail.setLength(rnd(0.15));
165                 boattail.setShapeParameter(rnd(0.5));
166                 boattail.setThickness(rnd(0.003));
167                 boattail.setType((Shape) randomEnum(Shape.class));
168                 stage.addChild(boattail);
169                 
170                 
171                 MassComponent mass = new MassComponent();
172                 setBasics(mass);
173                 mass.setComponentMass(rnd(0.05));
174                 mass.setLength(rnd(0.05));
175                 mass.setRadialDirection(rnd(100));
176                 mass.setRadialPosition(rnd(0.02));
177                 mass.setRadius(rnd(0.05));
178                 nose.addChild(mass);
179                 
180                 
181                 
182                 
183                 return rocket;
184         }
185         
186         
187         private void setBasics(RocketComponent c) {
188                 c.setComment(c.getComponentName() + " comment " + key);
189                 c.setName(c.getComponentName() + " name " + key);
190                 
191                 c.setCGOverridden(rnd.nextBoolean());
192                 c.setMassOverridden(rnd.nextBoolean());
193                 c.setOverrideCGX(rnd(0.2));
194                 c.setOverrideMass(rnd(0.05));
195                 c.setOverrideSubcomponents(rnd.nextBoolean());
196                 
197                 if (c.isMassive()) {
198                         // Only massive components are drawn
199                         c.setColor(randomColor());
200                         c.setLineStyle((LineStyle) randomEnum(LineStyle.class));
201                 }
202                 
203                 if (c instanceof ExternalComponent) {
204                         ExternalComponent e = (ExternalComponent) c;
205                         e.setFinish((Finish) randomEnum(Finish.class));
206                         double d = rnd(100);
207                         e.setMaterial(Databases.findMaterial(Type.BULK, "Testmat " + d, d));
208                 }
209                 
210                 if (c instanceof InternalComponent) {
211                         InternalComponent i = (InternalComponent) c;
212                         i.setRelativePosition((Position) randomEnum(Position.class));
213                         i.setPositionValue(rnd(0.3));
214                 }
215         }
216         
217         
218         
219         private double rnd(double scale) {
220                 return (rnd.nextDouble() * 0.2 + 0.9) * scale;
221         }
222         
223         private Color randomColor() {
224                 return new Color(rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256));
225         }
226         
227         private <T extends Enum<T>> Enum<T> randomEnum(Class<T> c) {
228                 Enum<T>[] values = c.getEnumConstants();
229                 if (values.length == 0)
230                         return null;
231                 
232                 return values[rnd.nextInt(values.length)];
233         }
234         
235         
236         
237         
238         
239         public Rocket makeSmallFlyable() {
240                 double noseconeLength = 0.10, noseconeRadius = 0.01;
241                 double bodytubeLength = 0.20, bodytubeRadius = 0.01, bodytubeThickness = 0.001;
242                 
243                 int finCount = 3;
244                 double finRootChord = 0.04, finTipChord = 0.05, finSweep = 0.01, finThickness = 0.003, finHeight = 0.03;
245                 
246                 
247                 Rocket rocket;
248                 Stage stage;
249                 NoseCone nosecone;
250                 BodyTube bodytube;
251                 TrapezoidFinSet finset;
252                 
253                 rocket = new Rocket();
254                 stage = new Stage();
255                 stage.setName("Stage1");
256                 
257                 nosecone = new NoseCone(Transition.Shape.ELLIPSOID, noseconeLength, noseconeRadius);
258                 bodytube = new BodyTube(bodytubeLength, bodytubeRadius, bodytubeThickness);
259                 
260                 finset = new TrapezoidFinSet(finCount, finRootChord, finTipChord, finSweep, finHeight);
261                 
262                 
263                 // Stage construction
264                 rocket.addChild(stage);
265                 
266                 
267                 // Component construction
268                 stage.addChild(nosecone);
269                 stage.addChild(bodytube);
270                 
271                 bodytube.addChild(finset);
272                 
273                 Material material = Application.getPreferences().getDefaultComponentMaterial(null, Material.Type.BULK);
274                 nosecone.setMaterial(material);
275                 bodytube.setMaterial(material);
276                 finset.setMaterial(material);
277                 
278                 String id = rocket.newMotorConfigurationID();
279                 bodytube.setMotorMount(true);
280                 
281                 Motor m = Application.getMotorSetDatabase().findMotors(null, null, "B4", Double.NaN, Double.NaN).get(0);
282                 bodytube.setMotor(id, m);
283                 bodytube.setMotorOverhang(0.005);
284                 rocket.getDefaultConfiguration().setMotorConfigurationID(id);
285                 
286                 rocket.getDefaultConfiguration().setAllStages();
287                 
288                 
289                 return rocket;
290         }
291         
292         
293         public static Rocket makeBigBlue() {
294                 Rocket rocket;
295                 Stage stage;
296                 NoseCone nosecone;
297                 BodyTube bodytube;
298                 FreeformFinSet finset;
299                 MassComponent mcomp;
300                 
301                 rocket = new Rocket();
302                 stage = new Stage();
303                 stage.setName("Stage1");
304                 
305                 nosecone = new NoseCone(Transition.Shape.ELLIPSOID, 0.105, 0.033);
306                 nosecone.setThickness(0.001);
307                 bodytube = new BodyTube(0.69, 0.033, 0.001);
308                 
309                 finset = new FreeformFinSet();
310                 try {
311                         finset.setPoints(new Coordinate[] {
312                                         new Coordinate(0, 0),
313                                         new Coordinate(0.115, 0.072),
314                                         new Coordinate(0.255, 0.072),
315                                         new Coordinate(0.255, 0.037),
316                                         new Coordinate(0.150, 0)
317                         });
318                 } catch (IllegalFinPointException e) {
319                         e.printStackTrace();
320                 }
321                 finset.setThickness(0.003);
322                 finset.setFinCount(4);
323                 
324                 finset.setCantAngle(0 * Math.PI / 180);
325                 System.err.println("Fin cant angle: " + (finset.getCantAngle() * 180 / Math.PI));
326                 
327                 mcomp = new MassComponent(0.2, 0.03, 0.045 + 0.060);
328                 mcomp.setRelativePosition(Position.TOP);
329                 mcomp.setPositionValue(0);
330                 
331                 // Stage construction
332                 rocket.addChild(stage);
333                 rocket.setPerfectFinish(false);
334                 
335                 
336                 // Component construction
337                 stage.addChild(nosecone);
338                 stage.addChild(bodytube);
339                 
340                 bodytube.addChild(finset);
341                 
342                 bodytube.addChild(mcomp);
343                 
344                 //              Material material = new Material("Test material", 500);
345                 //              nosecone.setMaterial(material);
346                 //              bodytube.setMaterial(material);
347                 //              finset.setMaterial(material);
348                 
349                 String id = rocket.newMotorConfigurationID();
350                 bodytube.setMotorMount(true);
351                 
352                 //              Motor m = Application.getMotorSetDatabase().findMotors(null, null, "F12J", Double.NaN, Double.NaN).get(0);
353                 //              bodytube.setMotor(id, m);
354                 //              bodytube.setMotorOverhang(0.005);
355                 rocket.getDefaultConfiguration().setMotorConfigurationID(id);
356                 
357                 rocket.getDefaultConfiguration().setAllStages();
358                 
359                 
360                 return rocket;
361         }
362         
363         
364         
365         public static Rocket makeIsoHaisu() {
366                 Rocket rocket;
367                 Stage stage;
368                 NoseCone nosecone;
369                 BodyTube tube1, tube2, tube3;
370                 TrapezoidFinSet finset;
371                 TrapezoidFinSet auxfinset;
372                 MassComponent mcomp;
373                 
374                 final double R = 0.07;
375                 
376                 rocket = new Rocket();
377                 stage = new Stage();
378                 stage.setName("Stage1");
379                 
380                 nosecone = new NoseCone(Transition.Shape.OGIVE, 0.53, R);
381                 nosecone.setThickness(0.005);
382                 nosecone.setMassOverridden(true);
383                 nosecone.setOverrideMass(0.588);
384                 stage.addChild(nosecone);
385                 
386                 tube1 = new BodyTube(0.505, R, 0.005);
387                 tube1.setMassOverridden(true);
388                 tube1.setOverrideMass(0.366);
389                 stage.addChild(tube1);
390                 
391                 tube2 = new BodyTube(0.605, R, 0.005);
392                 tube2.setMassOverridden(true);
393                 tube2.setOverrideMass(0.427);
394                 stage.addChild(tube2);
395                 
396                 tube3 = new BodyTube(1.065, R, 0.005);
397                 tube3.setMassOverridden(true);
398                 tube3.setOverrideMass(0.730);
399                 stage.addChild(tube3);
400                 
401                 
402                 LaunchLug lug = new LaunchLug();
403                 tube1.addChild(lug);
404                 
405                 TubeCoupler coupler = new TubeCoupler();
406                 coupler.setOuterRadiusAutomatic(true);
407                 coupler.setThickness(0.005);
408                 coupler.setLength(0.28);
409                 coupler.setMassOverridden(true);
410                 coupler.setOverrideMass(0.360);
411                 coupler.setRelativePosition(Position.BOTTOM);
412                 coupler.setPositionValue(-0.14);
413                 tube1.addChild(coupler);
414                 
415                 
416                 // Parachute
417                 MassComponent mass = new MassComponent(0.05, 0.05, 0.280);
418                 mass.setRelativePosition(Position.TOP);
419                 mass.setPositionValue(0.2);
420                 tube1.addChild(mass);
421                 
422                 // Cord
423                 mass = new MassComponent(0.05, 0.05, 0.125);
424                 mass.setRelativePosition(Position.TOP);
425                 mass.setPositionValue(0.2);
426                 tube1.addChild(mass);
427                 
428                 // Payload
429                 mass = new MassComponent(0.40, R, 1.500);
430                 mass.setRelativePosition(Position.TOP);
431                 mass.setPositionValue(0.25);
432                 tube1.addChild(mass);
433                 
434                 
435                 auxfinset = new TrapezoidFinSet();
436                 auxfinset.setName("CONTROL");
437                 auxfinset.setFinCount(2);
438                 auxfinset.setRootChord(0.05);
439                 auxfinset.setTipChord(0.05);
440                 auxfinset.setHeight(0.10);
441                 auxfinset.setSweep(0);
442                 auxfinset.setThickness(0.008);
443                 auxfinset.setCrossSection(CrossSection.AIRFOIL);
444                 auxfinset.setRelativePosition(Position.TOP);
445                 auxfinset.setPositionValue(0.28);
446                 auxfinset.setBaseRotation(Math.PI / 2);
447                 tube1.addChild(auxfinset);
448                 
449                 
450                 
451                 
452                 coupler = new TubeCoupler();
453                 coupler.setOuterRadiusAutomatic(true);
454                 coupler.setLength(0.28);
455                 coupler.setRelativePosition(Position.TOP);
456                 coupler.setPositionValue(0.47);
457                 coupler.setMassOverridden(true);
458                 coupler.setOverrideMass(0.360);
459                 tube2.addChild(coupler);
460                 
461                 
462                 
463                 // Parachute
464                 mass = new MassComponent(0.1, 0.05, 0.028);
465                 mass.setRelativePosition(Position.TOP);
466                 mass.setPositionValue(0.14);
467                 tube2.addChild(mass);
468                 
469                 Bulkhead bulk = new Bulkhead();
470                 bulk.setOuterRadiusAutomatic(true);
471                 bulk.setMassOverridden(true);
472                 bulk.setOverrideMass(0.050);
473                 bulk.setRelativePosition(Position.TOP);
474                 bulk.setPositionValue(0.27);
475                 tube2.addChild(bulk);
476                 
477                 // Chord
478                 mass = new MassComponent(0.1, 0.05, 0.125);
479                 mass.setRelativePosition(Position.TOP);
480                 mass.setPositionValue(0.19);
481                 tube2.addChild(mass);
482                 
483                 
484                 
485                 InnerTube inner = new InnerTube();
486                 inner.setOuterRadius(0.08 / 2);
487                 inner.setInnerRadius(0.0762 / 2);
488                 inner.setLength(0.86);
489                 inner.setMassOverridden(true);
490                 inner.setOverrideMass(0.388);
491                 tube3.addChild(inner);
492                 
493                 
494                 CenteringRing center = new CenteringRing();
495                 center.setInnerRadiusAutomatic(true);
496                 center.setOuterRadiusAutomatic(true);
497                 center.setLength(0.005);
498                 center.setMassOverridden(true);
499                 center.setOverrideMass(0.038);
500                 center.setRelativePosition(Position.BOTTOM);
501                 center.setPositionValue(0);
502                 tube3.addChild(center);
503                 
504                 
505                 center = new CenteringRing();
506                 center.setInnerRadiusAutomatic(true);
507                 center.setOuterRadiusAutomatic(true);
508                 center.setLength(0.005);
509                 center.setMassOverridden(true);
510                 center.setOverrideMass(0.038);
511                 center.setRelativePosition(Position.TOP);
512                 center.setPositionValue(0.28);
513                 tube3.addChild(center);
514                 
515                 
516                 center = new CenteringRing();
517                 center.setInnerRadiusAutomatic(true);
518                 center.setOuterRadiusAutomatic(true);
519                 center.setLength(0.005);
520                 center.setMassOverridden(true);
521                 center.setOverrideMass(0.038);
522                 center.setRelativePosition(Position.TOP);
523                 center.setPositionValue(0.83);
524                 tube3.addChild(center);
525                 
526                 
527                 
528                 
529                 
530                 finset = new TrapezoidFinSet();
531                 finset.setRootChord(0.495);
532                 finset.setTipChord(0.1);
533                 finset.setHeight(0.185);
534                 finset.setThickness(0.005);
535                 finset.setSweep(0.3);
536                 finset.setRelativePosition(Position.BOTTOM);
537                 finset.setPositionValue(-0.03);
538                 finset.setBaseRotation(Math.PI / 2);
539                 tube3.addChild(finset);
540                 
541                 
542                 finset.setCantAngle(0 * Math.PI / 180);
543                 System.err.println("Fin cant angle: " + (finset.getCantAngle() * 180 / Math.PI));
544                 
545                 
546                 // Stage construction
547                 rocket.addChild(stage);
548                 rocket.setPerfectFinish(false);
549                 
550                 
551                 
552                 String id = rocket.newMotorConfigurationID();
553                 tube3.setMotorMount(true);
554                 
555                 //              Motor m = Application.getMotorSetDatabase().findMotors(null, null, "L540", Double.NaN, Double.NaN).get(0);
556                 //              tube3.setMotor(id, m);
557                 //              tube3.setMotorOverhang(0.02);
558                 rocket.getDefaultConfiguration().setMotorConfigurationID(id);
559                 
560                 //              tube3.setIgnitionEvent(MotorMount.IgnitionEvent.NEVER);
561                 
562                 rocket.getDefaultConfiguration().setAllStages();
563                 
564                 
565                 return rocket;
566         }
567         
568         
569         
570 }