commit
d22b0f3154
@ -392,7 +392,6 @@ public class AerodynamicForces implements Cloneable, Monitorable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public AerodynamicForces merge(AerodynamicForces other) {
|
public AerodynamicForces merge(AerodynamicForces other) {
|
||||||
|
|
||||||
this.cp = cp.average(other.getCP());
|
this.cp = cp.average(other.getCP());
|
||||||
this.CNa = CNa + other.getCNa();
|
this.CNa = CNa + other.getCNa();
|
||||||
this.CN = CN + other.getCN();
|
this.CN = CN + other.getCN();
|
||||||
|
|||||||
@ -2,6 +2,7 @@ package net.sf.openrocket.aerodynamics;
|
|||||||
|
|
||||||
import static net.sf.openrocket.util.MathUtil.pow2;
|
import static net.sf.openrocket.util.MathUtil.pow2;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
@ -17,6 +18,8 @@ import net.sf.openrocket.rocketcomponent.ExternalComponent;
|
|||||||
import net.sf.openrocket.rocketcomponent.ExternalComponent.Finish;
|
import net.sf.openrocket.rocketcomponent.ExternalComponent.Finish;
|
||||||
import net.sf.openrocket.rocketcomponent.FinSet;
|
import net.sf.openrocket.rocketcomponent.FinSet;
|
||||||
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
|
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
|
||||||
|
import net.sf.openrocket.rocketcomponent.InstanceContext;
|
||||||
|
import net.sf.openrocket.rocketcomponent.InstanceMap;
|
||||||
import net.sf.openrocket.rocketcomponent.Rocket;
|
import net.sf.openrocket.rocketcomponent.Rocket;
|
||||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||||
import net.sf.openrocket.rocketcomponent.SymmetricComponent;
|
import net.sf.openrocket.rocketcomponent.SymmetricComponent;
|
||||||
@ -24,6 +27,7 @@ import net.sf.openrocket.util.Coordinate;
|
|||||||
import net.sf.openrocket.util.MathUtil;
|
import net.sf.openrocket.util.MathUtil;
|
||||||
import net.sf.openrocket.util.PolyInterpolator;
|
import net.sf.openrocket.util.PolyInterpolator;
|
||||||
import net.sf.openrocket.util.Reflection;
|
import net.sf.openrocket.util.Reflection;
|
||||||
|
import net.sf.openrocket.util.Transformation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An aerodynamic calculator that uses the extended Barrowman method to
|
* An aerodynamic calculator that uses the extended Barrowman method to
|
||||||
@ -36,7 +40,6 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
|
|||||||
private static final String BARROWMAN_PACKAGE = "net.sf.openrocket.aerodynamics.barrowman";
|
private static final String BARROWMAN_PACKAGE = "net.sf.openrocket.aerodynamics.barrowman";
|
||||||
private static final String BARROWMAN_SUFFIX = "Calc";
|
private static final String BARROWMAN_SUFFIX = "Calc";
|
||||||
|
|
||||||
|
|
||||||
private Map<RocketComponent, RocketComponentCalc> calcMap = null;
|
private Map<RocketComponent, RocketComponentCalc> calcMap = null;
|
||||||
|
|
||||||
private double cacheDiameter = -1;
|
private double cacheDiameter = -1;
|
||||||
@ -176,65 +179,43 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
|
|||||||
warnings.add( Warning.DIAMETER_DISCONTINUITY);
|
warnings.add( Warning.DIAMETER_DISCONTINUITY);
|
||||||
}
|
}
|
||||||
|
|
||||||
AerodynamicForces total = calculateAssemblyNonAxialForces(configuration.getRocket(), configuration, conditions, calculators, warnings, "");
|
final InstanceMap imap = configuration.getActiveInstances();
|
||||||
|
|
||||||
return total;
|
|
||||||
}
|
|
||||||
|
|
||||||
private AerodynamicForces calculateAssemblyNonAxialForces( final RocketComponent component,
|
|
||||||
FlightConfiguration configuration, FlightConditions conditions,
|
|
||||||
Map<RocketComponent, AerodynamicForces> calculators, WarningSet warnings,
|
|
||||||
String indent) {
|
|
||||||
|
|
||||||
final AerodynamicForces assemblyForces= new AerodynamicForces().zero();
|
final AerodynamicForces assemblyForces= new AerodynamicForces().zero();
|
||||||
|
|
||||||
// System.err.println(String.format("%s@@ %s <%s>", indent, component.getName(), component.getClass().getSimpleName()));
|
// iterate through all components
|
||||||
|
for(Map.Entry<RocketComponent, ArrayList<InstanceContext>> entry: imap.entrySet() ) {
|
||||||
// ==== calculate child forces ====
|
final RocketComponent comp = entry.getKey();
|
||||||
for (RocketComponent child: component.getChildren()) {
|
RocketComponentCalc calcObj = calcMap.get(comp);
|
||||||
AerodynamicForces childForces = calculateAssemblyNonAxialForces( child, configuration, conditions, calculators, warnings, indent+" ");
|
|
||||||
assemblyForces.merge(childForces);
|
// System.err.println("comp=" + comp);
|
||||||
}
|
if (null != calcObj) {
|
||||||
|
// iterate across component instances
|
||||||
// calculate *this* component's forces
|
final ArrayList<InstanceContext> contextList = entry.getValue();
|
||||||
RocketComponentCalc calcObj = calcMap.get(component);
|
|
||||||
if(null != calcObj) {
|
for(InstanceContext context: contextList ) {
|
||||||
AerodynamicForces componentForces = new AerodynamicForces().zero();
|
AerodynamicForces instanceForces = new AerodynamicForces().zero();
|
||||||
calcObj.calculateNonaxialForces(conditions, componentForces, warnings);
|
|
||||||
|
calcObj.calculateNonaxialForces(conditions, context.transform, instanceForces, warnings);
|
||||||
Coordinate cp_comp = componentForces.getCP();
|
Coordinate cp_comp = instanceForces.getCP();
|
||||||
|
|
||||||
Coordinate cp_weighted = cp_comp.setWeight(cp_comp.weight);
|
Coordinate cp_abs = context.transform.transform(cp_comp);
|
||||||
Coordinate cp_absolute = component.toAbsolute(cp_weighted)[0];
|
if ((comp instanceof FinSet) && (((FinSet)comp).getFinCount() > 2))
|
||||||
if(1 < component.getInstanceCount()) {
|
cp_abs = cp_abs.setY(0.0).setZ(0.0);
|
||||||
cp_absolute = cp_absolute.setY(0.).setZ(0.);
|
|
||||||
|
instanceForces.setCP(cp_abs);
|
||||||
|
double CN_instanced = instanceForces.getCN();
|
||||||
|
instanceForces.setCm(CN_instanced * instanceForces.getCP().x / conditions.getRefLength());
|
||||||
|
// System.err.println("instanceForces=" + instanceForces);
|
||||||
|
assemblyForces.merge(instanceForces);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentForces.setCP(cp_absolute);
|
|
||||||
double CN_instanced = componentForces.getCN();
|
|
||||||
componentForces.setCm(CN_instanced * componentForces.getCP().x / conditions.getRefLength());
|
|
||||||
|
|
||||||
// if( 0.0001 < Math.abs(componentForces.getCNa())){
|
|
||||||
// final Coordinate cp = assemblyForces.getCP();
|
|
||||||
// System.err.println(String.format("%s....Component.CNa: %g @ CP: { %f, %f, %f}", indent, componentForces.getCNa(), cp.x, cp.y, cp.z));
|
|
||||||
// }
|
|
||||||
|
|
||||||
assemblyForces.merge(componentForces);
|
|
||||||
}
|
|
||||||
|
|
||||||
// if( 0.0001 < Math.abs(0 - assemblyForces.getCNa())){
|
|
||||||
// final Coordinate cp = assemblyForces.getCP();
|
|
||||||
// System.err.println(String.format("%s....Assembly.CNa: %g @ CP: { %f, %f, %f}", indent, assemblyForces.getCNa(), cp.x, cp.y, cp.z));
|
|
||||||
// }
|
|
||||||
|
|
||||||
if( component.allowsChildren() && (component.getInstanceCount() > 1)) {
|
|
||||||
return assemblyForces.multiplex(component.getInstanceCount());
|
|
||||||
}else {
|
|
||||||
return assemblyForces;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// System.err.println("assemblyForces=" + assemblyForces);
|
||||||
|
return assemblyForces;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isContinuous( final Rocket rkt){
|
public boolean isContinuous( final Rocket rkt){
|
||||||
return testIsContinuous( rkt);
|
return testIsContinuous( rkt);
|
||||||
|
|||||||
@ -16,7 +16,7 @@ import net.sf.openrocket.util.Coordinate;
|
|||||||
import net.sf.openrocket.util.LinearInterpolator;
|
import net.sf.openrocket.util.LinearInterpolator;
|
||||||
import net.sf.openrocket.util.MathUtil;
|
import net.sf.openrocket.util.MathUtil;
|
||||||
import net.sf.openrocket.util.PolyInterpolator;
|
import net.sf.openrocket.util.PolyInterpolator;
|
||||||
|
import net.sf.openrocket.util.Transformation;
|
||||||
|
|
||||||
public class FinSetCalc extends RocketComponentCalc {
|
public class FinSetCalc extends RocketComponentCalc {
|
||||||
|
|
||||||
@ -84,7 +84,7 @@ public class FinSetCalc extends RocketComponentCalc {
|
|||||||
* (normal and side forces, pitch, yaw and roll moments, CP position, CNa).
|
* (normal and side forces, pitch, yaw and roll moments, CP position, CNa).
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void calculateNonaxialForces(FlightConditions conditions,
|
public void calculateNonaxialForces(FlightConditions conditions, Transformation transform,
|
||||||
AerodynamicForces forces, WarningSet warnings) {
|
AerodynamicForces forces, WarningSet warnings) {
|
||||||
|
|
||||||
if (span < 0.001) {
|
if (span < 0.001) {
|
||||||
@ -114,21 +114,10 @@ public class FinSetCalc extends RocketComponentCalc {
|
|||||||
// Multiple fins with fin-fin interference
|
// Multiple fins with fin-fin interference
|
||||||
double cna;
|
double cna;
|
||||||
double theta = conditions.getTheta();
|
double theta = conditions.getTheta();
|
||||||
double angle = baseRotation;
|
double angle = baseRotation + transform.getXrotation();
|
||||||
|
|
||||||
// Compute basic CNa without interference effects
|
// Compute basic CNa without interference effects
|
||||||
if (finCount == 1 || finCount == 2) {
|
cna = cna1 * MathUtil.pow2(Math.sin(theta - angle));
|
||||||
// Basic CNa from geometry
|
|
||||||
double mul = 0;
|
|
||||||
for (int i = 0; i < finCount; i++) {
|
|
||||||
mul += MathUtil.pow2(Math.sin(theta - angle));
|
|
||||||
angle += 2 * Math.PI / finCount;
|
|
||||||
}
|
|
||||||
cna = cna1 * mul;
|
|
||||||
} else {
|
|
||||||
// Basic CNa assuming full efficiency
|
|
||||||
cna = cna1 * finCount / 2.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// logger.debug("Component cna = {}", cna);
|
// logger.debug("Component cna = {}", cna);
|
||||||
|
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import net.sf.openrocket.aerodynamics.WarningSet;
|
|||||||
import net.sf.openrocket.rocketcomponent.LaunchLug;
|
import net.sf.openrocket.rocketcomponent.LaunchLug;
|
||||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||||
import net.sf.openrocket.util.MathUtil;
|
import net.sf.openrocket.util.MathUtil;
|
||||||
|
import net.sf.openrocket.util.Transformation;
|
||||||
|
|
||||||
public class LaunchLugCalc extends RocketComponentCalc {
|
public class LaunchLugCalc extends RocketComponentCalc {
|
||||||
|
|
||||||
@ -24,7 +25,7 @@ public class LaunchLugCalc extends RocketComponentCalc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void calculateNonaxialForces(FlightConditions conditions,
|
public void calculateNonaxialForces(FlightConditions conditions, Transformation transform,
|
||||||
AerodynamicForces forces, WarningSet warnings) {
|
AerodynamicForces forces, WarningSet warnings) {
|
||||||
// Nothing to be done
|
// Nothing to be done
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import net.sf.openrocket.aerodynamics.AerodynamicForces;
|
|||||||
import net.sf.openrocket.aerodynamics.FlightConditions;
|
import net.sf.openrocket.aerodynamics.FlightConditions;
|
||||||
import net.sf.openrocket.aerodynamics.WarningSet;
|
import net.sf.openrocket.aerodynamics.WarningSet;
|
||||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||||
|
import net.sf.openrocket.util.Transformation;
|
||||||
|
|
||||||
public abstract class RocketComponentCalc {
|
public abstract class RocketComponentCalc {
|
||||||
|
|
||||||
@ -20,11 +21,12 @@ public abstract class RocketComponentCalc {
|
|||||||
* computed around the local origin.
|
* computed around the local origin.
|
||||||
*
|
*
|
||||||
* @param conditions the flight conditions.
|
* @param conditions the flight conditions.
|
||||||
|
* @param transform transformation from InstanceMap to get rotations rotations
|
||||||
* @param forces the object in which to store the values.
|
* @param forces the object in which to store the values.
|
||||||
* @param warnings set in which to store possible warnings.
|
* @param warnings set in which to store possible warnings.
|
||||||
*/
|
*/
|
||||||
public abstract void calculateNonaxialForces(FlightConditions conditions,
|
public abstract void calculateNonaxialForces(FlightConditions conditions, Transformation transform,
|
||||||
AerodynamicForces forces, WarningSet warnings);
|
AerodynamicForces forces, WarningSet warnings);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -16,6 +16,7 @@ import net.sf.openrocket.util.Coordinate;
|
|||||||
import net.sf.openrocket.util.LinearInterpolator;
|
import net.sf.openrocket.util.LinearInterpolator;
|
||||||
import net.sf.openrocket.util.MathUtil;
|
import net.sf.openrocket.util.MathUtil;
|
||||||
import net.sf.openrocket.util.PolyInterpolator;
|
import net.sf.openrocket.util.PolyInterpolator;
|
||||||
|
import net.sf.openrocket.util.Transformation;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -95,7 +96,7 @@ public class SymmetricComponentCalc extends RocketComponentCalc {
|
|||||||
* subsonic speeds.
|
* subsonic speeds.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void calculateNonaxialForces(FlightConditions conditions,
|
public void calculateNonaxialForces(FlightConditions conditions, Transformation transform,
|
||||||
AerodynamicForces forces, WarningSet warnings) {
|
AerodynamicForces forces, WarningSet warnings) {
|
||||||
|
|
||||||
// Pre-calculate and store the results
|
// Pre-calculate and store the results
|
||||||
|
|||||||
@ -17,6 +17,7 @@ import net.sf.openrocket.util.Coordinate;
|
|||||||
import net.sf.openrocket.util.LinearInterpolator;
|
import net.sf.openrocket.util.LinearInterpolator;
|
||||||
import net.sf.openrocket.util.MathUtil;
|
import net.sf.openrocket.util.MathUtil;
|
||||||
import net.sf.openrocket.util.PolyInterpolator;
|
import net.sf.openrocket.util.PolyInterpolator;
|
||||||
|
import net.sf.openrocket.util.Transformation;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@ -92,7 +93,7 @@ public class TubeFinSetCalc extends RocketComponentCalc {
|
|||||||
* pitch, yaw and roll moments, CP position, CNa).
|
* pitch, yaw and roll moments, CP position, CNa).
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void calculateNonaxialForces(FlightConditions conditions,
|
public void calculateNonaxialForces(FlightConditions conditions, Transformation transform,
|
||||||
AerodynamicForces forces, WarningSet warnings) {
|
AerodynamicForces forces, WarningSet warnings) {
|
||||||
|
|
||||||
if (span < 0.001) {
|
if (span < 0.001) {
|
||||||
@ -124,7 +125,7 @@ public class TubeFinSetCalc extends RocketComponentCalc {
|
|||||||
// Multiple fins with fin-fin interference
|
// Multiple fins with fin-fin interference
|
||||||
double cna;
|
double cna;
|
||||||
double theta = conditions.getTheta();
|
double theta = conditions.getTheta();
|
||||||
double angle = baseRotation;
|
double angle = baseRotation + transform.getXrotation();
|
||||||
|
|
||||||
// Compute basic CNa without interference effects
|
// Compute basic CNa without interference effects
|
||||||
if (finCount == 1 || finCount == 2) {
|
if (finCount == 1 || finCount == 2) {
|
||||||
|
|||||||
@ -331,9 +331,9 @@ public final class Coordinate implements Cloneable, Serializable {
|
|||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
if (isWeighted())
|
if (isWeighted())
|
||||||
return String.format("(%.3f,%.3f,%.3f,w=%.3f)", x, y, z, weight);
|
return String.format("(%.5f,%.5f,%.5f,w=%.5f)", x, y, z, weight);
|
||||||
else
|
else
|
||||||
return String.format("(%.3f,%.3f,%.3f)", x, y, z);
|
return String.format("(%.5f,%.5f,%.5f)", x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
// high-precision output, for use with verifying calculations
|
// high-precision output, for use with verifying calculations
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package net.sf.openrocket.util;
|
|||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
import net.sf.openrocket.appearance.Appearance;
|
import net.sf.openrocket.appearance.Appearance;
|
||||||
|
import net.sf.openrocket.file.openrocket.OpenRocketSaver;
|
||||||
import net.sf.openrocket.database.Databases;
|
import net.sf.openrocket.database.Databases;
|
||||||
import net.sf.openrocket.document.OpenRocketDocument;
|
import net.sf.openrocket.document.OpenRocketDocument;
|
||||||
import net.sf.openrocket.document.OpenRocketDocumentFactory;
|
import net.sf.openrocket.document.OpenRocketDocumentFactory;
|
||||||
@ -39,6 +40,7 @@ import net.sf.openrocket.rocketcomponent.MassComponent;
|
|||||||
import net.sf.openrocket.rocketcomponent.NoseCone;
|
import net.sf.openrocket.rocketcomponent.NoseCone;
|
||||||
import net.sf.openrocket.rocketcomponent.Parachute;
|
import net.sf.openrocket.rocketcomponent.Parachute;
|
||||||
import net.sf.openrocket.rocketcomponent.ParallelStage;
|
import net.sf.openrocket.rocketcomponent.ParallelStage;
|
||||||
|
import net.sf.openrocket.rocketcomponent.PodSet;
|
||||||
import net.sf.openrocket.rocketcomponent.RecoveryDevice;
|
import net.sf.openrocket.rocketcomponent.RecoveryDevice;
|
||||||
import net.sf.openrocket.rocketcomponent.ReferenceType;
|
import net.sf.openrocket.rocketcomponent.ReferenceType;
|
||||||
import net.sf.openrocket.rocketcomponent.Rocket;
|
import net.sf.openrocket.rocketcomponent.Rocket;
|
||||||
@ -851,6 +853,14 @@ public class TestRockets {
|
|||||||
|
|
||||||
|
|
||||||
// This function is used for unit, integration tests, DO NOT CHANGE (without updating tests).
|
// This function is used for unit, integration tests, DO NOT CHANGE (without updating tests).
|
||||||
|
// Comments starting with cp: are center of pressure calculations
|
||||||
|
// for components of the rocket. Note that a cp: without a weight
|
||||||
|
// has a weight of 0 (see for example body tubes) -- included for
|
||||||
|
// completeness.
|
||||||
|
// Instanced components (ie components on the side boosters) have
|
||||||
|
// a cp: for each instance.
|
||||||
|
// The unit tests change the number of fins on the side boosters;
|
||||||
|
// cp: comments are shown for 1-fin, 2-fin, and 3-fin cases
|
||||||
public static Rocket makeFalcon9Heavy() {
|
public static Rocket makeFalcon9Heavy() {
|
||||||
Rocket rocket = new Rocket();
|
Rocket rocket = new Rocket();
|
||||||
rocket.setName("Falcon9H Scale Rocket");
|
rocket.setName("Falcon9H Scale Rocket");
|
||||||
@ -876,10 +886,12 @@ public class TestRockets {
|
|||||||
payloadFairingNoseCone.setAftShoulderThickness( 0.001 );
|
payloadFairingNoseCone.setAftShoulderThickness( 0.001 );
|
||||||
payloadFairingNoseCone.setAftShoulderCapped( false );
|
payloadFairingNoseCone.setAftShoulderCapped( false );
|
||||||
payloadStage.addChild(payloadFairingNoseCone);
|
payloadStage.addChild(payloadFairingNoseCone);
|
||||||
|
// cp:(0.05900,0.00000,0.00000,w=2.00000)
|
||||||
|
|
||||||
BodyTube payloadBody = new BodyTube(0.132, 0.052, 0.001);
|
BodyTube payloadBody = new BodyTube(0.132, 0.052, 0.001);
|
||||||
payloadBody.setName("PL Fairing Body");
|
payloadBody.setName("PL Fairing Body");
|
||||||
payloadStage.addChild(payloadBody);
|
payloadStage.addChild(payloadBody);
|
||||||
|
// cp:(0.18400,0.00000,0.00000)
|
||||||
|
|
||||||
Transition payloadFairingTail = new Transition();
|
Transition payloadFairingTail = new Transition();
|
||||||
payloadFairingTail.setName("PL Fairing Transition");
|
payloadFairingTail.setName("PL Fairing Transition");
|
||||||
@ -888,10 +900,12 @@ public class TestRockets {
|
|||||||
payloadFairingTail.setForeRadiusAutomatic(true);
|
payloadFairingTail.setForeRadiusAutomatic(true);
|
||||||
payloadFairingTail.setAftRadiusAutomatic(true);
|
payloadFairingTail.setAftRadiusAutomatic(true);
|
||||||
payloadStage.addChild(payloadFairingTail);
|
payloadStage.addChild(payloadFairingTail);
|
||||||
|
// cp:(0.25665,0.00000,0.00000,w=-0.90366)
|
||||||
|
|
||||||
BodyTube upperStageBody= new BodyTube(0.18, 0.0385, 0.001);
|
BodyTube upperStageBody= new BodyTube(0.18, 0.0385, 0.001);
|
||||||
upperStageBody.setName("Upper Stage Body ");
|
upperStageBody.setName("Upper Stage Body ");
|
||||||
payloadStage.addChild( upperStageBody);
|
payloadStage.addChild( upperStageBody);
|
||||||
|
// cp:(0.35400,0.00000,0.00000)
|
||||||
|
|
||||||
{
|
{
|
||||||
// Parachute
|
// Parachute
|
||||||
@ -916,6 +930,7 @@ public class TestRockets {
|
|||||||
BodyTube interstage= new BodyTube(0.12, 0.0385, 0.001);
|
BodyTube interstage= new BodyTube(0.12, 0.0385, 0.001);
|
||||||
interstage.setName("Interstage");
|
interstage.setName("Interstage");
|
||||||
payloadStage.addChild( interstage);
|
payloadStage.addChild( interstage);
|
||||||
|
// cp:(0.50400,0.00000,0.00000)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ====== Core Stage ======
|
// ====== Core Stage ======
|
||||||
@ -930,6 +945,7 @@ public class TestRockets {
|
|||||||
coreBody.setName("Core Stage Body");
|
coreBody.setName("Core Stage Body");
|
||||||
coreBody.setMotorMount(true);
|
coreBody.setMotorMount(true);
|
||||||
coreStage.addChild( coreBody);
|
coreStage.addChild( coreBody);
|
||||||
|
// cp:(0.96400,0.00000,0.00000)
|
||||||
{
|
{
|
||||||
MotorConfiguration coreMotorConfig = new MotorConfiguration(coreBody, selFCID);
|
MotorConfiguration coreMotorConfig = new MotorConfiguration(coreBody, selFCID);
|
||||||
Motor mtr = TestRockets.generateMotor_M1350_75mm();
|
Motor mtr = TestRockets.generateMotor_M1350_75mm();
|
||||||
@ -961,12 +977,15 @@ public class TestRockets {
|
|||||||
boosterCone.setAftShoulderThickness( 0.001 );
|
boosterCone.setAftShoulderThickness( 0.001 );
|
||||||
boosterCone.setAftShoulderCapped( false );
|
boosterCone.setAftShoulderCapped( false );
|
||||||
boosterStage.addChild( boosterCone);
|
boosterStage.addChild( boosterCone);
|
||||||
|
// cp:(0.52400,0.07700,0.00000,w=1.09634)
|
||||||
|
// cp:(0.52400,-0.07700,0.00000,w=1.09634)
|
||||||
|
|
||||||
BodyTube boosterBody = new BodyTube(0.8, 0.0385, 0.001);
|
BodyTube boosterBody = new BodyTube(0.8, 0.0385, 0.001);
|
||||||
boosterBody.setName("Booster Body");
|
boosterBody.setName("Booster Body");
|
||||||
boosterBody.setOuterRadiusAutomatic(true);
|
boosterBody.setOuterRadiusAutomatic(true);
|
||||||
boosterStage.addChild( boosterBody);
|
boosterStage.addChild( boosterBody);
|
||||||
|
// cp:(0.96400,0.07700,0.00000)
|
||||||
|
// cp:(0.96400,-0.07700,0.00000)
|
||||||
{
|
{
|
||||||
InnerTube boosterMotorTubes = new InnerTube();
|
InnerTube boosterMotorTubes = new InnerTube();
|
||||||
boosterMotorTubes.setName("Booster Motor Tubes");
|
boosterMotorTubes.setName("Booster Motor Tubes");
|
||||||
@ -997,6 +1016,12 @@ public class TestRockets {
|
|||||||
boosterFins.setSweep(0.18);
|
boosterFins.setSweep(0.18);
|
||||||
boosterFins.setAxialMethod(AxialMethod.BOTTOM);
|
boosterFins.setAxialMethod(AxialMethod.BOTTOM);
|
||||||
boosterFins.setAxialOffset(0.0);
|
boosterFins.setAxialOffset(0.0);
|
||||||
|
// cp:(1.17873,0.10422,0.02722,w=6.07405) (1 fin case)
|
||||||
|
// cp:(1.17873,-0.10422,-0.02722,w=6.07405) (1 fin case)
|
||||||
|
// cp:(1.17873,0.10422,0.02722,w=12.14810) (2 fin case)
|
||||||
|
// cp:(1.17873,-0.10422,-0.02722,w=12.14810) (2 fin case)
|
||||||
|
// cp:(1.17873,0.00000,0.00000,w=9.11107) (3 fin case)
|
||||||
|
// cp:(1.17873,0.00000,0.00000,w=9.11107) (3 fin case)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1009,6 +1034,128 @@ public class TestRockets {
|
|||||||
|
|
||||||
return rocket;
|
return rocket;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is a simple four-fin rocket with large endplates on the
|
||||||
|
// fins, for testing CG and CP calculations with fins on pods.
|
||||||
|
// not a complete rocket (no motor mount nor recovery system)
|
||||||
|
|
||||||
|
// it's parameterized to make things easy to change, but be sure
|
||||||
|
// to adjust the unit test to match!
|
||||||
|
public static Rocket makeEndPlateRocket() {
|
||||||
|
|
||||||
|
// rocket design parameters
|
||||||
|
double radius = 0.01; // note this is diameter/2!
|
||||||
|
int finCount = 4; // also determines pod count
|
||||||
|
|
||||||
|
// nose cone
|
||||||
|
double noseThick = 0.002;
|
||||||
|
double noseLength = 0.05;
|
||||||
|
|
||||||
|
// body tube
|
||||||
|
double bodyWallThick = 0.002;
|
||||||
|
double bodyLength = 0.254;
|
||||||
|
|
||||||
|
// main body tube fins
|
||||||
|
int bodyFinCount = 4;
|
||||||
|
double bodyFinRootChord = 0.05;
|
||||||
|
double bodyFinTipChord = bodyFinRootChord;
|
||||||
|
double bodyFinHeight = 0.025;
|
||||||
|
double bodyFinSweep = 0.0;
|
||||||
|
AxialMethod bodyFinAxialMethod = AxialMethod.BOTTOM;
|
||||||
|
double bodyFinAxialOffset = 0.0;
|
||||||
|
double bodyFinThickness = 0.003;
|
||||||
|
|
||||||
|
// pods for end plates
|
||||||
|
int podSetCount = bodyFinCount;
|
||||||
|
double podSetOffset = bodyFinHeight;
|
||||||
|
AxialMethod podSetAxialMethod = bodyFinAxialMethod;
|
||||||
|
double podSetAxialOffset = 0.0;
|
||||||
|
|
||||||
|
// "phantom" tube on pods to give us somewhere to connect end
|
||||||
|
// plates
|
||||||
|
double phantomLength = bodyFinTipChord;
|
||||||
|
double phantomRadius = 0;
|
||||||
|
double phantomWallThickness = 0;
|
||||||
|
|
||||||
|
// end plates
|
||||||
|
int endPlateCount = 2;
|
||||||
|
double endPlateRootChord = bodyFinTipChord;
|
||||||
|
double endPlateTipChord = endPlateRootChord;
|
||||||
|
double endPlateSweep = 0.0;
|
||||||
|
double endPlateThickness = bodyFinThickness;
|
||||||
|
double endPlateHeight = bodyFinHeight;
|
||||||
|
double endPlateRotation = Math.PI/2.0;
|
||||||
|
AxialMethod endPlateAxialMethod = AxialMethod.BOTTOM;
|
||||||
|
double endPlateAxialOffset = 0;
|
||||||
|
|
||||||
|
// create bare rocket
|
||||||
|
Rocket rocket = new Rocket();
|
||||||
|
rocket.enableEvents();
|
||||||
|
rocket.setName("End Plate Test");
|
||||||
|
|
||||||
|
// rocket has one stage
|
||||||
|
AxialStage sustainer = new AxialStage();
|
||||||
|
rocket.addChild(sustainer);
|
||||||
|
sustainer.setName("Sustainer");
|
||||||
|
|
||||||
|
// nose cone
|
||||||
|
NoseCone noseCone = new NoseCone(Transition.Shape.OGIVE, noseLength, radius);
|
||||||
|
sustainer.addChild(noseCone);
|
||||||
|
noseCone.setName("Nose Cone");
|
||||||
|
// cp:(0.02303,0.00000,0.00000,w=2.00000)
|
||||||
|
|
||||||
|
// body tube
|
||||||
|
BodyTube bodyTube = new BodyTube(bodyLength, radius, bodyWallThick);
|
||||||
|
sustainer.addChild(bodyTube);
|
||||||
|
bodyTube.setName("Body tube");
|
||||||
|
// cp:(0.17700,0.00000,0.00000)
|
||||||
|
|
||||||
|
// Trapezoidal fin set on body tube
|
||||||
|
TrapezoidFinSet bodyFinSet = new TrapezoidFinSet(bodyFinCount, bodyFinRootChord, bodyFinTipChord, bodyFinSweep, bodyFinHeight);
|
||||||
|
bodyTube.addChild(bodyFinSet);
|
||||||
|
bodyFinSet.setName("Body Tube FinSet");
|
||||||
|
bodyFinSet.setAxialMethod(bodyFinAxialMethod);
|
||||||
|
bodyFinSet.setAxialOffset(bodyFinAxialOffset);
|
||||||
|
bodyFinSet.setThickness(bodyFinThickness);
|
||||||
|
// cp:(0.26650,0.00000,0.00000,w=15.24857)
|
||||||
|
|
||||||
|
// Pod set to put an end plate on each fin
|
||||||
|
PodSet podSet = new PodSet();
|
||||||
|
bodyTube.addChild(podSet);
|
||||||
|
podSet.setName("Pod Set");
|
||||||
|
podSet.setInstanceCount(podSetCount);
|
||||||
|
podSet.setRadiusOffset(podSetOffset);
|
||||||
|
podSet.setAxialMethod(podSetAxialMethod);
|
||||||
|
podSet.setAxialOffset(podSetAxialOffset);
|
||||||
|
|
||||||
|
// 0-diameter "body tube" to give us something to hook the
|
||||||
|
// endplates to. Note that this causes a "thick fins"
|
||||||
|
// warning.
|
||||||
|
BodyTube phantom = new BodyTube(phantomLength, phantomRadius, phantomWallThickness);
|
||||||
|
podSet.addChild(phantom);
|
||||||
|
phantom.setName("Phantom");
|
||||||
|
// cp:(0.25400,0.03540,0.00000)
|
||||||
|
// cp:(0.25400,0.00000,0.03540)
|
||||||
|
// cp:(0.25400,-0.03540,0.00000)
|
||||||
|
// cp:(0.25400,-0.00000,-0.03540)
|
||||||
|
|
||||||
|
// end plates
|
||||||
|
TrapezoidFinSet endPlate = new TrapezoidFinSet(endPlateCount, endPlateRootChord, endPlateTipChord, endPlateSweep, endPlateHeight);
|
||||||
|
phantom.addChild(endPlate);
|
||||||
|
endPlate.setName("End plates");
|
||||||
|
endPlate.setBaseRotation(endPlateRotation);
|
||||||
|
endPlate.setAxialMethod(endPlateAxialMethod);
|
||||||
|
endPlate.setAxialOffset(endPlateAxialOffset);
|
||||||
|
endPlate.setThickness(endPlateThickness);
|
||||||
|
// cp:(0.26650,0.03540,0.00000,w=0.00000)
|
||||||
|
// cp:(0.26650,0.00000,0.03540,w=11.86000)
|
||||||
|
// cp:(0.26650,-0.03540,0.00000,w=0.00000)
|
||||||
|
// cp:(0.26650,-0.00000,-0.03540,w=11.86000)
|
||||||
|
|
||||||
|
// Total cp:(0.25461,-0.00000,0.00000,w=40.96857)
|
||||||
|
|
||||||
|
return rocket;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create a new file version 1.00 rocket
|
* Create a new file version 1.00 rocket
|
||||||
@ -1406,6 +1553,7 @@ public class TestRockets {
|
|||||||
public static OpenRocketDocument makeTestRocket_v108_withBoosters() {
|
public static OpenRocketDocument makeTestRocket_v108_withBoosters() {
|
||||||
Rocket rocket = makeFalcon9Heavy();
|
Rocket rocket = makeFalcon9Heavy();
|
||||||
OpenRocketDocument document = OpenRocketDocumentFactory.createDocumentFromRocket(rocket);
|
OpenRocketDocument document = OpenRocketDocumentFactory.createDocumentFromRocket(rocket);
|
||||||
|
|
||||||
return document;
|
return document;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -374,5 +374,25 @@ public class Transformation implements java.io.Serializable {
|
|||||||
public Coordinate getTranslationVector() {
|
public Coordinate getTranslationVector() {
|
||||||
return this.translate;
|
return this.translate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate X, Y, and Z rotation angles from rotation matrices
|
||||||
|
*/
|
||||||
|
public double getXrotation() {
|
||||||
|
return Math.atan2((rotation[2][1] - rotation[1][2])/2.0,
|
||||||
|
(rotation[1][1] + rotation[2][2])/2.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getYrotation() {
|
||||||
|
return Math.atan2((rotation[0][2] - rotation[2][0])/2.0,
|
||||||
|
(rotation[0][0] + rotation[2][2])/2.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getZrotation() {
|
||||||
|
return Math.atan2((rotation[1][0] - rotation[0][1])/2.0,
|
||||||
|
(rotation[0][0] + rotation[1][1])/2.0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -86,7 +86,7 @@ public class BarrowmanCalculatorTest {
|
|||||||
|
|
||||||
assertEquals(" Estes Alpha III CNa value is incorrect:", exp_cna, cp_calc.weight, EPSILON);
|
assertEquals(" Estes Alpha III CNa value is incorrect:", exp_cna, cp_calc.weight, EPSILON);
|
||||||
assertEquals(" Estes Alpha III cp x value is incorrect:", exp_cpx, cp_calc.x, EPSILON);
|
assertEquals(" Estes Alpha III cp x value is incorrect:", exp_cpx, cp_calc.x, EPSILON);
|
||||||
assertEquals(" Estes Alpha III cp x value is incorrect:", 0.0, cp_calc.y, EPSILON);
|
assertEquals(" Estes Alpha III cp y value is incorrect:", 0.0, cp_calc.y, EPSILON);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -107,7 +107,8 @@ public class BarrowmanCalculatorTest {
|
|||||||
assertEquals(" Estes Alpha III cp x value is incorrect:", expCPx, calcCP.x, EPSILON);
|
assertEquals(" Estes Alpha III cp x value is incorrect:", expCPx, calcCP.x, EPSILON);
|
||||||
assertEquals(" Estes Alpha III CNa value is incorrect:", exp_cna, calcCP.weight, EPSILON);
|
assertEquals(" Estes Alpha III CNa value is incorrect:", exp_cna, calcCP.weight, EPSILON);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Component CP calculations resulting in expected test values are in comments in TestRockets.makeFalcon9Heavy()
|
||||||
@Test
|
@Test
|
||||||
public void testCPParallelBoosters() {
|
public void testCPParallelBoosters() {
|
||||||
final Rocket rocket = TestRockets.makeFalcon9Heavy();
|
final Rocket rocket = TestRockets.makeFalcon9Heavy();
|
||||||
@ -128,21 +129,40 @@ public class BarrowmanCalculatorTest {
|
|||||||
}{
|
}{
|
||||||
boosterFins.setFinCount(2);
|
boosterFins.setFinCount(2);
|
||||||
final Coordinate cp_2fin = calc.getCP(config, conditions, warnings);
|
final Coordinate cp_2fin = calc.getCP(config, conditions, warnings);
|
||||||
assertEquals(" Falcon 9 Heavy CNa value is incorrect:", 15.43711197, cp_2fin.weight, EPSILON);
|
assertEquals(" Falcon 9 Heavy CNa value is incorrect:", 27.585207667168696, cp_2fin.weight, EPSILON);
|
||||||
assertEquals(" Falcon 9 Heavy CP x value is incorrect:", 0.99464238, cp_2fin.x, EPSILON);
|
assertEquals(" Falcon 9 Heavy CP x value is incorrect:", 1.0757127676940474, cp_2fin.x, EPSILON);
|
||||||
assertEquals(" Falcon 9 Heavy CP y value is incorrect:", 0.0, cp_2fin.y, EPSILON);
|
assertEquals(" Falcon 9 Heavy CP y value is incorrect:", 0.0, cp_2fin.y, EPSILON);
|
||||||
assertEquals(" Falcon 9 Heavy CP z value is incorrect:", 0.0, cp_2fin.z, EPSILON);
|
assertEquals(" Falcon 9 Heavy CP z value is incorrect:", 0.0, cp_2fin.z, EPSILON);
|
||||||
}{
|
}{
|
||||||
boosterFins.setFinCount(1);
|
boosterFins.setFinCount(1);
|
||||||
final Coordinate cp_1fin = calc.getCP(config, conditions, warnings);
|
final Coordinate cp_1fin = calc.getCP(config, conditions, warnings);
|
||||||
assertEquals(" Falcon 9 Heavy CNa value is incorrect:", 9.36306412, cp_1fin.weight, EPSILON);
|
assertEquals(" Falcon 9 Heavy CNa value is incorrect:", 15.43711196967902, cp_1fin.weight, EPSILON);
|
||||||
assertEquals(" Falcon 9 Heavy CP x value is incorrect:", 0.87521867, cp_1fin.x, EPSILON);
|
assertEquals(" Falcon 9 Heavy CP x value is incorrect:", 0.99464, cp_1fin.x, EPSILON);
|
||||||
assertEquals(" Falcon 9 Heavy CP y value is incorrect:", 0f, cp_1fin.y, EPSILON);
|
assertEquals(" Falcon 9 Heavy CP y value is incorrect:", 0f, cp_1fin.y, EPSILON);
|
||||||
assertEquals(" Falcon 9 Heavy CP z value is incorrect:", 0f, cp_1fin.z, EPSILON);
|
assertEquals(" Falcon 9 Heavy CP z value is incorrect:", 0f, cp_1fin.z, EPSILON);
|
||||||
}{
|
}{
|
||||||
// absent -- 3.28901627g @[0.31469937,0.05133333,0.00000000]
|
// absent -- 3.28901627g @[0.31469937,0.05133333,0.00000000]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// test rocket with endplates on fins. Comments tracing
|
||||||
|
// calculation of CP are in TestRockets.makeEndPlateRocket().
|
||||||
|
@Test
|
||||||
|
public void testEndPlateCP() {
|
||||||
|
final Rocket rocket = TestRockets.makeEndPlateRocket();
|
||||||
|
final FlightConfiguration config = new FlightConfiguration(rocket, null);
|
||||||
|
// rocket.setFlightConfiguration(config.getId(), config);
|
||||||
|
// rocket.setSelectedConfiguration(config.getId());
|
||||||
|
final AerodynamicCalculator calc = new BarrowmanCalculator();
|
||||||
|
final FlightConditions conditions = new FlightConditions(config);
|
||||||
|
final WarningSet warnings = new WarningSet();
|
||||||
|
|
||||||
|
final Coordinate cp = calc.getCP(config, conditions, warnings);
|
||||||
|
assertEquals(" Endplate rocket cp x value is incorrect:", 0.25461, cp.x, EPSILON);
|
||||||
|
assertEquals(" Endplate rocket cp y value is incorrect:", 0.0, cp.y, EPSILON);
|
||||||
|
assertEquals(" Endplate rocket cp z value is incorrect:", 0.0, cp.z, EPSILON);
|
||||||
|
assertEquals(" Endplate rocket CNa value is incorrect:", 40.96857, cp.weight, EPSILON);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetWorstCP() {
|
public void testGetWorstCP() {
|
||||||
|
|||||||
@ -16,6 +16,7 @@ import net.sf.openrocket.rocketcomponent.Rocket;
|
|||||||
import net.sf.openrocket.rocketcomponent.TrapezoidFinSet;
|
import net.sf.openrocket.rocketcomponent.TrapezoidFinSet;
|
||||||
import net.sf.openrocket.startup.Application;
|
import net.sf.openrocket.startup.Application;
|
||||||
import net.sf.openrocket.util.TestRockets;
|
import net.sf.openrocket.util.TestRockets;
|
||||||
|
import net.sf.openrocket.util.Transformation;
|
||||||
|
|
||||||
public class FinSetCalcTest {
|
public class FinSetCalcTest {
|
||||||
protected final double EPSILON = 0.0001;
|
protected final double EPSILON = 0.0001;
|
||||||
@ -37,6 +38,27 @@ public class FinSetCalcTest {
|
|||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private AerodynamicForces sumFins(TrapezoidFinSet fins, Rocket rocket)
|
||||||
|
{
|
||||||
|
FlightConfiguration config = rocket.getSelectedConfiguration();
|
||||||
|
FlightConditions conditions = new FlightConditions(config);
|
||||||
|
WarningSet warnings = new WarningSet();
|
||||||
|
AerodynamicForces assemblyForces = new AerodynamicForces().zero();
|
||||||
|
AerodynamicForces componentForces = new AerodynamicForces();
|
||||||
|
|
||||||
|
FinSetCalc calcObj = new FinSetCalc( fins );
|
||||||
|
|
||||||
|
// Need to sum forces for fins
|
||||||
|
for (Integer i = 0; i < fins.getFinCount(); i++) {
|
||||||
|
calcObj.calculateNonaxialForces(conditions,
|
||||||
|
Transformation.rotate_x(Math.PI * i / fins.getFinCount()),
|
||||||
|
componentForces, warnings);
|
||||||
|
assemblyForces.merge(componentForces);
|
||||||
|
}
|
||||||
|
|
||||||
|
return assemblyForces;
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test3Fin() {
|
public void test3Fin() {
|
||||||
Rocket rocket = TestRockets.makeEstesAlphaIII();
|
Rocket rocket = TestRockets.makeEstesAlphaIII();
|
||||||
@ -48,18 +70,10 @@ public class FinSetCalcTest {
|
|||||||
assertEquals(" Estes Alpha III fins have wrong tip chord:", 0.03, fins.getTipChord(), EPSILON);
|
assertEquals(" Estes Alpha III fins have wrong tip chord:", 0.03, fins.getTipChord(), EPSILON);
|
||||||
assertEquals(" Estes Alpha III fins have wrong sweep: ", 0.02, fins.getSweep(), EPSILON);
|
assertEquals(" Estes Alpha III fins have wrong sweep: ", 0.02, fins.getSweep(), EPSILON);
|
||||||
assertEquals(" Estes Alpha III fins have wrong height: ", 0.05, fins.getHeight(), EPSILON);
|
assertEquals(" Estes Alpha III fins have wrong height: ", 0.05, fins.getHeight(), EPSILON);
|
||||||
|
|
||||||
FlightConfiguration config = rocket.getSelectedConfiguration();
|
// get the forces for the three fins
|
||||||
FlightConditions conditions = new FlightConditions(config);
|
AerodynamicForces forces = sumFins(fins, rocket);
|
||||||
WarningSet warnings = new WarningSet();
|
|
||||||
AerodynamicForces forces = new AerodynamicForces();
|
|
||||||
FinSetCalc calcObj = new FinSetCalc( fins );
|
|
||||||
|
|
||||||
|
|
||||||
// vvv TEST MEH! vvv
|
|
||||||
calcObj.calculateNonaxialForces(conditions, forces, warnings);
|
|
||||||
// ^^^
|
|
||||||
|
|
||||||
double exp_cna_fins = 24.146933;
|
double exp_cna_fins = 24.146933;
|
||||||
double exp_cpx_fins = 0.0193484;
|
double exp_cpx_fins = 0.0193484;
|
||||||
|
|
||||||
@ -82,17 +96,9 @@ public class FinSetCalcTest {
|
|||||||
assertEquals(" Estes Alpha III fins have wrong tip chord:", 0.03, fins.getTipChord(), EPSILON);
|
assertEquals(" Estes Alpha III fins have wrong tip chord:", 0.03, fins.getTipChord(), EPSILON);
|
||||||
assertEquals(" Estes Alpha III fins have wrong sweep: ", 0.02, fins.getSweep(), EPSILON);
|
assertEquals(" Estes Alpha III fins have wrong sweep: ", 0.02, fins.getSweep(), EPSILON);
|
||||||
assertEquals(" Estes Alpha III fins have wrong height: ", 0.05, fins.getHeight(), EPSILON);
|
assertEquals(" Estes Alpha III fins have wrong height: ", 0.05, fins.getHeight(), EPSILON);
|
||||||
|
|
||||||
FlightConfiguration config = rocket.getSelectedConfiguration();
|
// get the forces for the four fins
|
||||||
FlightConditions conditions = new FlightConditions(config);
|
AerodynamicForces forces = sumFins(fins, rocket);
|
||||||
WarningSet warnings = new WarningSet();
|
|
||||||
AerodynamicForces forces = new AerodynamicForces();
|
|
||||||
FinSetCalc calcObj = new FinSetCalc( fins );
|
|
||||||
|
|
||||||
|
|
||||||
// vvv TEST MEH! vvv
|
|
||||||
calcObj.calculateNonaxialForces(conditions, forces, warnings);
|
|
||||||
// ^^^
|
|
||||||
|
|
||||||
double exp_cna_fins = 32.195911;
|
double exp_cna_fins = 32.195911;
|
||||||
double exp_cpx_fins = 0.0193484;
|
double exp_cpx_fins = 0.0193484;
|
||||||
|
|||||||
@ -18,6 +18,7 @@ import net.sf.openrocket.rocketcomponent.Transition;
|
|||||||
import net.sf.openrocket.startup.Application;
|
import net.sf.openrocket.startup.Application;
|
||||||
import net.sf.openrocket.util.MathUtil;
|
import net.sf.openrocket.util.MathUtil;
|
||||||
import net.sf.openrocket.util.TestRockets;
|
import net.sf.openrocket.util.TestRockets;
|
||||||
|
import net.sf.openrocket.util.Transformation;
|
||||||
|
|
||||||
public class SymmetricComponentCalcTest {
|
public class SymmetricComponentCalcTest {
|
||||||
protected final double EPSILON = MathUtil.EPSILON*1000;
|
protected final double EPSILON = MathUtil.EPSILON*1000;
|
||||||
@ -52,13 +53,14 @@ public class SymmetricComponentCalcTest {
|
|||||||
|
|
||||||
FlightConfiguration config = rocket.getSelectedConfiguration();
|
FlightConfiguration config = rocket.getSelectedConfiguration();
|
||||||
FlightConditions conditions = new FlightConditions(config);
|
FlightConditions conditions = new FlightConditions(config);
|
||||||
|
Transformation transform = Transformation.IDENTITY;
|
||||||
WarningSet warnings = new WarningSet();
|
WarningSet warnings = new WarningSet();
|
||||||
AerodynamicForces forces = new AerodynamicForces();
|
AerodynamicForces forces = new AerodynamicForces();
|
||||||
SymmetricComponentCalc calcObj = new SymmetricComponentCalc( nose );
|
SymmetricComponentCalc calcObj = new SymmetricComponentCalc( nose );
|
||||||
|
|
||||||
conditions.setAOA(0.0);
|
conditions.setAOA(0.0);
|
||||||
// vvv TEST MEH! vvv
|
// vvv TEST MEH! vvv
|
||||||
calcObj.calculateNonaxialForces(conditions, forces, warnings);
|
calcObj.calculateNonaxialForces(conditions, transform, forces, warnings);
|
||||||
// ^^^
|
// ^^^
|
||||||
|
|
||||||
double cna_nose = 2;
|
double cna_nose = 2;
|
||||||
@ -82,13 +84,14 @@ public class SymmetricComponentCalcTest {
|
|||||||
|
|
||||||
FlightConfiguration config = rocket.getSelectedConfiguration();
|
FlightConfiguration config = rocket.getSelectedConfiguration();
|
||||||
FlightConditions conditions = new FlightConditions(config);
|
FlightConditions conditions = new FlightConditions(config);
|
||||||
|
Transformation transform = Transformation.IDENTITY;
|
||||||
WarningSet warnings = new WarningSet();
|
WarningSet warnings = new WarningSet();
|
||||||
AerodynamicForces forces = new AerodynamicForces();
|
AerodynamicForces forces = new AerodynamicForces();
|
||||||
SymmetricComponentCalc calcObj = new SymmetricComponentCalc( nose );
|
SymmetricComponentCalc calcObj = new SymmetricComponentCalc( nose );
|
||||||
|
|
||||||
conditions.setAOA(0.0);
|
conditions.setAOA(0.0);
|
||||||
// vvv TEST vvv
|
// vvv TEST vvv
|
||||||
calcObj.calculateNonaxialForces(conditions, forces, warnings);
|
calcObj.calculateNonaxialForces(conditions, transform, forces, warnings);
|
||||||
// ^^^ ^^^
|
// ^^^ ^^^
|
||||||
|
|
||||||
double l_nose = nose.getLength();
|
double l_nose = nose.getLength();
|
||||||
|
|||||||
@ -23,6 +23,7 @@ import net.sf.openrocket.util.Color;
|
|||||||
import net.sf.openrocket.util.Coordinate;
|
import net.sf.openrocket.util.Coordinate;
|
||||||
import net.sf.openrocket.util.LineStyle;
|
import net.sf.openrocket.util.LineStyle;
|
||||||
import net.sf.openrocket.util.BaseTestCase.BaseTestCase;
|
import net.sf.openrocket.util.BaseTestCase.BaseTestCase;
|
||||||
|
import net.sf.openrocket.util.Transformation;
|
||||||
|
|
||||||
public class FreeformFinSetTest extends BaseTestCase {
|
public class FreeformFinSetTest extends BaseTestCase {
|
||||||
|
|
||||||
@ -1203,9 +1204,10 @@ public class FreeformFinSetTest extends BaseTestCase {
|
|||||||
bt.addChild(fins);
|
bt.addChild(fins);
|
||||||
FinSetCalc calc = new FinSetCalc(fins);
|
FinSetCalc calc = new FinSetCalc(fins);
|
||||||
FlightConditions conditions = new FlightConditions(null);
|
FlightConditions conditions = new FlightConditions(null);
|
||||||
|
Transformation transform = Transformation.IDENTITY;
|
||||||
AerodynamicForces forces = new AerodynamicForces();
|
AerodynamicForces forces = new AerodynamicForces();
|
||||||
WarningSet warnings = new WarningSet();
|
WarningSet warnings = new WarningSet();
|
||||||
calc.calculateNonaxialForces(conditions, forces, warnings);
|
calc.calculateNonaxialForces(conditions, transform, forces, warnings);
|
||||||
//System.out.println(forces);
|
//System.out.println(forces);
|
||||||
assertEquals(0.023409, forces.getCP().x, 0.0001);
|
assertEquals(0.023409, forces.getCP().x, 0.0001);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user