Add unit test "testPhantomTubes" comparing a simple 3FNC rocket against the same rocket, implemented by replacing the fins by three pods, putting a 0-diameter body tube on each pod, and putting one fin on each pod.
This commit is contained in:
parent
9845decb20
commit
00abce96ff
@ -1,13 +1,16 @@
|
||||
package net.sf.openrocket.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.io.FileOutputStream;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
import net.sf.openrocket.appearance.Appearance;
|
||||
import net.sf.openrocket.file.openrocket.OpenRocketSaver;
|
||||
import net.sf.openrocket.database.Databases;
|
||||
import net.sf.openrocket.document.OpenRocketDocument;
|
||||
import net.sf.openrocket.document.OpenRocketDocumentFactory;
|
||||
import net.sf.openrocket.document.Simulation;
|
||||
import net.sf.openrocket.file.openrocket.OpenRocketSaver;
|
||||
import net.sf.openrocket.material.Material;
|
||||
import net.sf.openrocket.material.Material.Type;
|
||||
import net.sf.openrocket.motor.Manufacturer;
|
||||
@ -34,6 +37,8 @@ import net.sf.openrocket.rocketcomponent.FlightConfiguration;
|
||||
import net.sf.openrocket.rocketcomponent.FlightConfigurationId;
|
||||
import net.sf.openrocket.rocketcomponent.FreeformFinSet;
|
||||
import net.sf.openrocket.rocketcomponent.InnerTube;
|
||||
import net.sf.openrocket.rocketcomponent.InstanceContext;
|
||||
import net.sf.openrocket.rocketcomponent.InstanceMap;
|
||||
import net.sf.openrocket.rocketcomponent.InternalComponent;
|
||||
import net.sf.openrocket.rocketcomponent.LaunchLug;
|
||||
import net.sf.openrocket.rocketcomponent.MassComponent;
|
||||
@ -1629,5 +1634,84 @@ public class TestRockets {
|
||||
rocket.enableEvents();
|
||||
return rocketDoc;
|
||||
}
|
||||
|
||||
// the following two models are used in testing
|
||||
// otherwise-identical rockets, one created in the obvious way
|
||||
// using a single finset and the other creating three pods, each
|
||||
// with a single fin.
|
||||
public static final Rocket make3FNCNoPods() {
|
||||
|
||||
Rocket rocket = new Rocket();
|
||||
|
||||
rocket.enableEvents();
|
||||
|
||||
AxialStage stage = new AxialStage();
|
||||
stage.setName("Sustainer");
|
||||
rocket.addChild(stage);
|
||||
|
||||
// shape, length, radius
|
||||
NoseCone nosecone = new NoseCone(Transition.Shape.OGIVE, 0.102, 0.0125);
|
||||
stage.addChild(nosecone);
|
||||
|
||||
// length, outer radius, thickness
|
||||
BodyTube bodytube = new BodyTube(0.305, 0.0125, 0.001);
|
||||
bodytube.setName("Main Body");
|
||||
stage.addChild(bodytube);
|
||||
|
||||
// number of fins, root chord, tip chord, sweep, height
|
||||
TrapezoidFinSet trapezoidfinset = new TrapezoidFinSet(3, 0.051, 0.025, 0.038, 0.044);
|
||||
bodytube.addChild(trapezoidfinset);
|
||||
|
||||
// This is how we can dump a test rocket so we can look at it in OR to better
|
||||
// visualize it
|
||||
//
|
||||
// OpenRocketDocument doc = OpenRocketDocumentFactory.createDocumentFromRocket(rocket);
|
||||
// OpenRocketSaver saver = new OpenRocketSaver();
|
||||
// try {
|
||||
// FileOutputStream str = new FileOutputStream("3fnc.ork");
|
||||
// saver.save(str, doc, null);
|
||||
// }
|
||||
// catch (Exception e) {
|
||||
// System.err.println("exception " + e);
|
||||
// }
|
||||
|
||||
return rocket;
|
||||
}
|
||||
|
||||
// second model used to test with/without pods. In order to
|
||||
// maintain consistency between the models, we'll create the
|
||||
// no-pods first, and then modify it to make the with-pods version
|
||||
public static final Rocket make3FNCWithPods() {
|
||||
Rocket rocket = TestRockets.make3FNCNoPods();
|
||||
|
||||
// find the body and fins
|
||||
final InstanceMap imap = rocket.getSelectedConfiguration().getActiveInstances();
|
||||
for(Map.Entry<RocketComponent, ArrayList<InstanceContext>> entry: imap.entrySet() ) {
|
||||
RocketComponent c = entry.getKey();
|
||||
if (c instanceof TrapezoidFinSet) {
|
||||
final TrapezoidFinSet fins = (TrapezoidFinSet) c;
|
||||
final BodyTube body = (BodyTube) fins.getParent();
|
||||
body.removeChild(fins);
|
||||
|
||||
// create a PodSet to hook the fins to
|
||||
PodSet podset = new PodSet();
|
||||
podset.setInstanceCount(fins.getFinCount());
|
||||
|
||||
body.addChild(podset);
|
||||
|
||||
// put a phantom body tube on the pods
|
||||
BodyTube podBody = new BodyTube(fins.getRootChord(), 0);
|
||||
podBody.setName("Pod Body");
|
||||
podset.addChild(podBody);
|
||||
|
||||
// change the number of fins to 1 and put the revised
|
||||
// finset on the podbody
|
||||
fins.setFinCount(1);
|
||||
podBody.addChild(fins);
|
||||
}
|
||||
}
|
||||
|
||||
return rocket;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -231,4 +231,50 @@ public class BarrowmanCalculatorTest {
|
||||
|
||||
assertFalse(" Missed discontinuity in Falcon 9 Heavy:", calc.isContinuous( rocket));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPhantomTubes() {
|
||||
Rocket rocketNoPods = TestRockets.make3FNCNoPods();
|
||||
FlightConfiguration configNoPods = rocketNoPods.getSelectedConfiguration();
|
||||
FlightConditions conditionsNoPods = new FlightConditions(configNoPods);
|
||||
WarningSet warningsNoPods = new WarningSet();
|
||||
|
||||
Rocket rocketWithPods = TestRockets.make3FNCWithPods();
|
||||
FlightConfiguration configPods = rocketWithPods.getSelectedConfiguration();
|
||||
FlightConditions conditionsPods = new FlightConditions(configPods);
|
||||
WarningSet warningsPods = new WarningSet();
|
||||
AerodynamicCalculator calcPods = new BarrowmanCalculator();
|
||||
AerodynamicCalculator calcNoPods = new BarrowmanCalculator();
|
||||
|
||||
final AerodynamicForces forcesNoPods = calcPods.getAerodynamicForces(configNoPods, conditionsNoPods, warningsNoPods);
|
||||
final AerodynamicForces forcesPods = calcPods.getAerodynamicForces(configPods, conditionsPods, warningsPods);
|
||||
assertEquals(" 3FNC With Pods rocket CD value is incorrect:", forcesPods.getCD(), forcesNoPods.getCD(), EPSILON);
|
||||
|
||||
// The "with pods" version has no way of seeing the fins are
|
||||
// on the actual body tube rather than the phantom tubes,
|
||||
// so CD won't take fin-body interference into consideration.
|
||||
// So we'll adjust our CD in these tests. The magic numbers
|
||||
// in x and w come from temporarily disabling the
|
||||
// interference calculation in FinSetCalc and comparing
|
||||
// results with and without it
|
||||
// cpNoPods (0.34125,0.00000,0.00000,w=16.20502) -- interference disabled
|
||||
// cpNoPods (0.34797,0.00000,0.00000,w=19.34773) -- interference enabled
|
||||
|
||||
// another note: the fact that this is seen as three one-fin
|
||||
// FinSets instead of a single three-fin FinSet means the CP
|
||||
// will be off-axis (one of the fins is taken as having an
|
||||
// angle of 0 to the airstream, so it has no contribution).
|
||||
// This doesn't turn out to cause a problem in an actual
|
||||
// simulation, so we are just not testing for it. Test with
|
||||
// correction if we want some time is here but commented out
|
||||
|
||||
final Coordinate cpNoPods = calcNoPods.getCP(configNoPods, conditionsNoPods, warningsNoPods);
|
||||
final Coordinate cpPods = calcPods.getCP(configPods, conditionsPods, warningsPods);
|
||||
|
||||
assertEquals(" 3FNC With Pods rocket cp x value is incorrect:", cpPods.x, cpNoPods.x - 0.00672, EPSILON);
|
||||
// assertEquals(" 3FNC With Pods rocket cp y value is incorrect:", cpPods.y, cpNoPods.y - 0.00548, EPSILON);
|
||||
// assertEquals(" 3FNC With Pods rocket cp z value is incorrect:", cpPods.z, cpNoPods.z, EPSILON);
|
||||
assertEquals(" 3FNC With Pods rocket CNa value is incorrect:", cpPods.weight, cpNoPods.weight - 3.14271, EPSILON);
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user