Merge pull request #1312 from JoePfeiffer/fix-1207a
Rewrite tube fin and launch lug drag calculations
This commit is contained in:
commit
d0348726d3
@ -1756,6 +1756,9 @@ Warning.TUMBLE_UNDER_THRUST = Stage began to tumble under thrust.
|
|||||||
Warning.EVENT_AFTER_LANDING = Flight Event occurred after landing:
|
Warning.EVENT_AFTER_LANDING = Flight Event occurred after landing:
|
||||||
Warning.ZERO_LENGTH_BODY = Zero length bodies may not result in accurate simulations.
|
Warning.ZERO_LENGTH_BODY = Zero length bodies may not result in accurate simulations.
|
||||||
Warning.ZERO_RADIUS_BODY = Zero length bodies may not result in accurate simulations.
|
Warning.ZERO_RADIUS_BODY = Zero length bodies may not result in accurate simulations.
|
||||||
|
Warning.TUBE_STABILITY = Tube fin stability calculations may not be accurate.
|
||||||
|
Warning.TUBE_SEPARATION = Space between tube fins may not result in accurate simulations.
|
||||||
|
Warning.TUBE_OVERLAP = Overlapping tube fins may not result in accurate simulations.
|
||||||
|
|
||||||
! Scale dialog
|
! Scale dialog
|
||||||
ScaleDialog.lbl.scaleRocket = Entire rocket
|
ScaleDialog.lbl.scaleRocket = Entire rocket
|
||||||
|
@ -341,7 +341,7 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
|
|||||||
* for thickness as we go on.
|
* for thickness as we go on.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
double finFrictionCD = 0;
|
double otherFrictionCD = 0;
|
||||||
double bodyFrictionCD = 0;
|
double bodyFrictionCD = 0;
|
||||||
double maxR = 0, minX = Double.MAX_VALUE, maxX = 0;
|
double maxR = 0, minX = Double.MAX_VALUE, maxX = 0;
|
||||||
|
|
||||||
@ -407,8 +407,8 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
|
|||||||
final double componentMaxR = Math.max(s.getForeRadius(), s.getAftRadius());
|
final double componentMaxR = Math.max(s.getForeRadius(), s.getAftRadius());
|
||||||
maxR = Math.max(maxR, componentMaxR);
|
maxR = Math.max(maxR, componentMaxR);
|
||||||
|
|
||||||
} else if (c instanceof FinSet) {
|
} else {
|
||||||
finFrictionCD += componentFrictionCD;
|
otherFrictionCD += componentFrictionCD;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (map != null) {
|
if (map != null) {
|
||||||
@ -430,7 +430,7 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return finFrictionCD + correction * bodyFrictionCD;
|
return otherFrictionCD + correction * bodyFrictionCD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -585,6 +585,7 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
|
|||||||
final InstanceMap imap = configuration.getActiveInstances();
|
final InstanceMap imap = configuration.getActiveInstances();
|
||||||
for(Map.Entry<RocketComponent, ArrayList<InstanceContext>> entry: imap.entrySet() ) {
|
for(Map.Entry<RocketComponent, ArrayList<InstanceContext>> entry: imap.entrySet() ) {
|
||||||
final RocketComponent c = entry.getKey();
|
final RocketComponent c = entry.getKey();
|
||||||
|
log.debug("component " + c);
|
||||||
|
|
||||||
if (!c.isAerodynamic())
|
if (!c.isAerodynamic())
|
||||||
continue;
|
continue;
|
||||||
@ -593,7 +594,7 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
|
|||||||
final ArrayList<InstanceContext> contextList = entry.getValue();
|
final ArrayList<InstanceContext> contextList = entry.getValue();
|
||||||
for(InstanceContext context: contextList ) {
|
for(InstanceContext context: contextList ) {
|
||||||
|
|
||||||
// Pressure fore drag
|
// Pressure drag
|
||||||
double cd = calcMap.get(c).calculatePressureCD(conditions, stagnation, base,
|
double cd = calcMap.get(c).calculatePressureCD(conditions, stagnation, base,
|
||||||
warningSet);
|
warningSet);
|
||||||
total += cd;
|
total += cd;
|
||||||
|
@ -392,4 +392,7 @@ public abstract class Warning {
|
|||||||
public static final Warning ZERO_LENGTH_BODY = new Other(trans.get("Warning.ZERO_LENGTH_BODY"));
|
public static final Warning ZERO_LENGTH_BODY = new Other(trans.get("Warning.ZERO_LENGTH_BODY"));
|
||||||
public static final Warning ZERO_RADIUS_BODY = new Other(trans.get("Warning.ZERO_RADIUS_BODY"));
|
public static final Warning ZERO_RADIUS_BODY = new Other(trans.get("Warning.ZERO_RADIUS_BODY"));
|
||||||
|
|
||||||
|
public static final Warning TUBE_STABILITY = new Other(trans.get("Warning.TUBE_STABILITY"));
|
||||||
|
public static final Warning TUBE_SEPARATION = new Other(trans.get("Warning.TUBE_SEPARATION"));
|
||||||
|
public static final Warning TUBE_OVERLAP = new Other(trans.get("Warning.TUBE_OVERLAP"));
|
||||||
}
|
}
|
||||||
|
@ -8,20 +8,10 @@ import net.sf.openrocket.rocketcomponent.RocketComponent;
|
|||||||
import net.sf.openrocket.util.MathUtil;
|
import net.sf.openrocket.util.MathUtil;
|
||||||
import net.sf.openrocket.util.Transformation;
|
import net.sf.openrocket.util.Transformation;
|
||||||
|
|
||||||
public class LaunchLugCalc extends RocketComponentCalc {
|
public class LaunchLugCalc extends TubeCalc {
|
||||||
|
|
||||||
private final double CDmul;
|
|
||||||
private final double refArea;
|
|
||||||
|
|
||||||
public LaunchLugCalc(RocketComponent component) {
|
public LaunchLugCalc(RocketComponent component) {
|
||||||
super(component);
|
super(component);
|
||||||
|
|
||||||
LaunchLug lug = (LaunchLug)component;
|
|
||||||
double ld = lug.getLength() / (2*lug.getOuterRadius());
|
|
||||||
|
|
||||||
CDmul = Math.max(1.3 - ld, 1);
|
|
||||||
refArea = Math.PI * MathUtil.pow2(lug.getOuterRadius()) -
|
|
||||||
Math.PI * MathUtil.pow2(lug.getInnerRadius()) * Math.max(1 - ld, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -35,12 +25,4 @@ public class LaunchLugCalc extends RocketComponentCalc {
|
|||||||
// launch lug doesn't add enough area to worry about
|
// launch lug doesn't add enough area to worry about
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public double calculatePressureCD(FlightConditions conditions,
|
|
||||||
double stagnationCD, double baseCD, WarningSet warnings) {
|
|
||||||
|
|
||||||
return CDmul*stagnationCD * refArea / conditions.getRefArea();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,45 @@
|
|||||||
|
package net.sf.openrocket.aerodynamics.barrowman;
|
||||||
|
|
||||||
|
import net.sf.openrocket.aerodynamics.FlightConditions;
|
||||||
|
import net.sf.openrocket.aerodynamics.WarningSet;
|
||||||
|
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||||
|
import net.sf.openrocket.rocketcomponent.Tube;
|
||||||
|
import net.sf.openrocket.util.MathUtil;
|
||||||
|
|
||||||
|
public abstract class TubeCalc extends RocketComponentCalc {
|
||||||
|
|
||||||
|
private final double diameter;
|
||||||
|
private final double length;
|
||||||
|
protected double refArea;
|
||||||
|
|
||||||
|
public TubeCalc(RocketComponent component) {
|
||||||
|
super(component);
|
||||||
|
|
||||||
|
Tube tube = (Tube)component;
|
||||||
|
|
||||||
|
length = tube.getLength();
|
||||||
|
diameter = 2 * tube.getInnerRadius();
|
||||||
|
refArea = Math.PI * MathUtil.pow2(tube.getInnerRadius());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double calculatePressureCD(FlightConditions conditions,
|
||||||
|
double stagnationCD, double baseCD, WarningSet warnings) {
|
||||||
|
|
||||||
|
// calculation of pressure drop through pipe from "Atlas Copco Air Compendium", 1975,
|
||||||
|
// quoted as equation 14 in Carello, Ivanov, and Mazza, "Pressure drop in pipe
|
||||||
|
// lines for compressed air: comparison between experimental and theoretical analysis",
|
||||||
|
// Transactions on Engineering Sciences vol 18, ISSN 1743-35331998, 1998.
|
||||||
|
|
||||||
|
// Volume flow rate
|
||||||
|
final double Q = conditions.getVelocity() * refArea;
|
||||||
|
|
||||||
|
// pressure drop
|
||||||
|
final double deltap = 1.6 * 1000 * Math.pow(Q, 1.85) * Math.pow(Q, 1.85) * length /
|
||||||
|
(Math.pow(diameter, 5) * conditions.getAtmosphericConditions().getPressure());
|
||||||
|
|
||||||
|
// convert to CD and return
|
||||||
|
return deltap * refArea / conditions.getRefArea();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -10,6 +10,7 @@ import net.sf.openrocket.aerodynamics.FlightConditions;
|
|||||||
import net.sf.openrocket.aerodynamics.Warning;
|
import net.sf.openrocket.aerodynamics.Warning;
|
||||||
import net.sf.openrocket.aerodynamics.Warning.Other;
|
import net.sf.openrocket.aerodynamics.Warning.Other;
|
||||||
import net.sf.openrocket.aerodynamics.WarningSet;
|
import net.sf.openrocket.aerodynamics.WarningSet;
|
||||||
|
import net.sf.openrocket.rocketcomponent.BodyTube;
|
||||||
import net.sf.openrocket.rocketcomponent.FinSet;
|
import net.sf.openrocket.rocketcomponent.FinSet;
|
||||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||||
import net.sf.openrocket.rocketcomponent.TubeFinSet;
|
import net.sf.openrocket.rocketcomponent.TubeFinSet;
|
||||||
@ -28,14 +29,14 @@ import org.slf4j.LoggerFactory;
|
|||||||
* Uses a complete clone of FinSetCalc modelling each tube fin as 3 individual fins. It does not correctly account for
|
* Uses a complete clone of FinSetCalc modelling each tube fin as 3 individual fins. It does not correctly account for
|
||||||
* fin & tube fin interference.
|
* fin & tube fin interference.
|
||||||
*
|
*
|
||||||
* Changes to BarrowmanCalculator's calculateFrictionDrag are also probably required.
|
|
||||||
*
|
|
||||||
* @author kruland
|
* @author kruland
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class TubeFinSetCalc extends RocketComponentCalc {
|
public class TubeFinSetCalc extends TubeCalc {
|
||||||
|
|
||||||
private final static Logger logger = LoggerFactory.getLogger(FinSetCalc.class);
|
private final static Logger log = LoggerFactory.getLogger(TubeFinSetCalc.class);
|
||||||
|
|
||||||
|
final double intersticeArea;
|
||||||
|
|
||||||
private static final double STALL_ANGLE = (20 * Math.PI / 180);
|
private static final double STALL_ANGLE = (20 * Math.PI / 180);
|
||||||
|
|
||||||
@ -56,8 +57,12 @@ public class TubeFinSetCalc extends RocketComponentCalc {
|
|||||||
protected double[] chordLead = new double[DIVISIONS];
|
protected double[] chordLead = new double[DIVISIONS];
|
||||||
protected double[] chordTrail = new double[DIVISIONS];
|
protected double[] chordTrail = new double[DIVISIONS];
|
||||||
protected double[] chordLength = new double[DIVISIONS];
|
protected double[] chordLength = new double[DIVISIONS];
|
||||||
|
|
||||||
|
protected final WarningSet geometryWarnings = new WarningSet();
|
||||||
|
|
||||||
private final double[] poly = new double[6];
|
private final double[] poly = new double[6];
|
||||||
|
|
||||||
|
private final double wettedArea;
|
||||||
|
|
||||||
private final double thickness;
|
private final double thickness;
|
||||||
private final double bodyRadius;
|
private final double bodyRadius;
|
||||||
@ -73,9 +78,53 @@ public class TubeFinSetCalc extends RocketComponentCalc {
|
|||||||
throw new IllegalArgumentException("Illegal component type " + component);
|
throw new IllegalArgumentException("Illegal component type " + component);
|
||||||
}
|
}
|
||||||
|
|
||||||
TubeFinSet fin = (TubeFinSet) component;
|
final TubeFinSet tubes = (TubeFinSet) component;
|
||||||
|
final TubeFinSet fin = tubes; // keep this around while we're still leveraging FinSet
|
||||||
|
|
||||||
|
geometryWarnings.add(Warning.TUBE_STABILITY);
|
||||||
|
if (tubes.getTubeSeparation() > MathUtil.EPSILON) {
|
||||||
|
geometryWarnings.add(Warning.TUBE_SEPARATION);
|
||||||
|
} else if (tubes.getTubeSeparation() < -MathUtil.EPSILON) {
|
||||||
|
geometryWarnings.add(Warning.TUBE_OVERLAP);
|
||||||
|
}
|
||||||
|
|
||||||
|
// precompute geometry. This will be the geometry of a single tube, since BarrowmanCalculator
|
||||||
|
// iterates across them. Doesn't consider interference between them; that should only be relevant for
|
||||||
|
// fins that are either separated or overlapping.
|
||||||
|
bodyRadius = tubes.getBodyRadius();
|
||||||
|
|
||||||
|
// 1. wetted area for friction drag calculation. We don't consider the inner surface of the tube;
|
||||||
|
// that affects the pressure drop through the tube and so (indirecctly) affects the pressure drag.
|
||||||
|
|
||||||
|
// Area of the outer surface of tubes. Since roughly half
|
||||||
|
// of the area is "masked" by the interstices between the tubes and the
|
||||||
|
// body tube, only consider the other half of the area
|
||||||
|
final double outerArea = tubes.getLength() * Math.PI * tubes.getOuterRadius();
|
||||||
|
|
||||||
|
// Surface area of the portion of the body tube masked by the tube fins
|
||||||
|
final BodyTube parent = (BodyTube) tubes.getParent();
|
||||||
|
final double maskedArea = tubes.getLength() * 2.0 * Math.PI * parent.getOuterRadius();
|
||||||
|
|
||||||
|
wettedArea = outerArea - maskedArea;
|
||||||
|
log.debug("wetted area of tube fins " + wettedArea);
|
||||||
|
|
||||||
|
// 2. frontal area of interstices between tubes for pressure drag calculation.
|
||||||
|
// We'll treat them as a closed blunt object.
|
||||||
|
|
||||||
|
// area of disk passing through tube fin centers
|
||||||
|
final double tubeDiskArea = Math.PI * MathUtil.pow2(bodyRadius + tubes.getOuterRadius());
|
||||||
|
|
||||||
|
// half of combined area of tube fin interiors.
|
||||||
|
final double tubeInnerArea = tubes.getFinCount() * Math.PI * MathUtil.pow2(tubes.getInnerRadius()) / 2.0;
|
||||||
|
|
||||||
|
// body tube area
|
||||||
|
final double bodyTubeArea = Math.PI * MathUtil.pow2(bodyRadius);
|
||||||
|
|
||||||
|
// area of an interstice
|
||||||
|
intersticeArea = (tubeDiskArea - tubeInnerArea - bodyTubeArea) / tubes.getFinCount();
|
||||||
|
log.debug("interstice area " + intersticeArea);
|
||||||
|
|
||||||
thickness = fin.getThickness();
|
thickness = fin.getThickness();
|
||||||
bodyRadius = fin.getBodyRadius();
|
|
||||||
finCount = 3 * fin.getFinCount();
|
finCount = 3 * fin.getFinCount();
|
||||||
baseRotation = fin.getBaseRotation();
|
baseRotation = fin.getBaseRotation();
|
||||||
cantAngle = 0;
|
cantAngle = 0;
|
||||||
@ -94,7 +143,7 @@ public class TubeFinSetCalc extends RocketComponentCalc {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void calculateNonaxialForces(FlightConditions conditions, Transformation transform,
|
public void calculateNonaxialForces(FlightConditions conditions, Transformation transform,
|
||||||
AerodynamicForces forces, WarningSet warnings) {
|
AerodynamicForces forces, WarningSet warnings) {
|
||||||
|
|
||||||
if (span < 0.001) {
|
if (span < 0.001) {
|
||||||
forces.setCm(0);
|
forces.setCm(0);
|
||||||
@ -113,14 +162,13 @@ public class TubeFinSetCalc extends RocketComponentCalc {
|
|||||||
if( (0 < bodyRadius) && (thickness > bodyRadius / 2)){
|
if( (0 < bodyRadius) && (thickness > bodyRadius / 2)){
|
||||||
warnings.add(Warning.THICK_FIN);
|
warnings.add(Warning.THICK_FIN);
|
||||||
}
|
}
|
||||||
warnings.add(new Other("Tube fin support is experimental"));
|
|
||||||
|
|
||||||
//////// Calculate CNa. /////////
|
//////// Calculate CNa. /////////
|
||||||
|
|
||||||
// One fin without interference (both sub- and supersonic):
|
// One fin without interference (both sub- and supersonic):
|
||||||
double cna1 = calculateFinCNa1(conditions);
|
double cna1 = calculateFinCNa1(conditions);
|
||||||
|
|
||||||
// logger.debug("Component cna1 = {}", cna1);
|
// log.debug("Component cna1 = {}", cna1);
|
||||||
|
|
||||||
// Multiple fins with fin-fin interference
|
// Multiple fins with fin-fin interference
|
||||||
double cna;
|
double cna;
|
||||||
@ -141,7 +189,7 @@ public class TubeFinSetCalc extends RocketComponentCalc {
|
|||||||
cna = cna1 * finCount / 2.0;
|
cna = cna1 * finCount / 2.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// logger.debug("Component cna = {}", cna);
|
// log.debug("Component cna = {}", cna);
|
||||||
|
|
||||||
// Take into account fin-fin interference effects
|
// Take into account fin-fin interference effects
|
||||||
switch (interferenceFinCount) {
|
switch (interferenceFinCount) {
|
||||||
@ -182,7 +230,7 @@ public class TubeFinSetCalc extends RocketComponentCalc {
|
|||||||
tau = 0;
|
tau = 0;
|
||||||
cna *= 1 + tau; // Classical Barrowman
|
cna *= 1 + tau; // Classical Barrowman
|
||||||
// cna *= pow2(1 + tau); // Barrowman thesis (too optimistic??)
|
// cna *= pow2(1 + tau); // Barrowman thesis (too optimistic??)
|
||||||
// logger.debug("Component cna = {}", cna);
|
// log.debug("Component cna = {}", cna);
|
||||||
|
|
||||||
// TODO: LOW: check for fin tip mach cone interference
|
// TODO: LOW: check for fin tip mach cone interference
|
||||||
// (Barrowman thesis pdf-page 40)
|
// (Barrowman thesis pdf-page 40)
|
||||||
@ -191,9 +239,9 @@ public class TubeFinSetCalc extends RocketComponentCalc {
|
|||||||
|
|
||||||
// Calculate CP position
|
// Calculate CP position
|
||||||
double x = macLead + calculateCPPos(conditions) * macLength;
|
double x = macLead + calculateCPPos(conditions) * macLength;
|
||||||
// logger.debug("Component macLead = {}", macLead);
|
// log.debug("Component macLead = {}", macLead);
|
||||||
// logger.debug("Component macLength = {}", macLength);
|
// log.debug("Component macLength = {}", macLength);
|
||||||
// logger.debug("Component x = {}", x);
|
// log.debug("Component x = {}", x);
|
||||||
|
|
||||||
|
|
||||||
// Calculate roll forces, reduce forcing above stall angle
|
// Calculate roll forces, reduce forcing above stall angle
|
||||||
@ -352,7 +400,7 @@ public class TubeFinSetCalc extends RocketComponentCalc {
|
|||||||
double y = i * dy;
|
double y = i * dy;
|
||||||
|
|
||||||
macLength += length * length;
|
macLength += length * length;
|
||||||
logger.debug("macLength = {}, length = {}, i = {}", macLength, length, i);
|
log.debug("macLength = {}, length = {}, i = {}", macLength, length, i);
|
||||||
macSpan += y * length;
|
macSpan += y * length;
|
||||||
macLead += chordLead[i] * length;
|
macLead += chordLead[i] * length;
|
||||||
area += length;
|
area += length;
|
||||||
@ -368,7 +416,7 @@ public class TubeFinSetCalc extends RocketComponentCalc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
macLength *= dy;
|
macLength *= dy;
|
||||||
logger.debug("macLength = {}", macLength);
|
log.debug("macLength = {}", macLength);
|
||||||
macSpan *= dy;
|
macSpan *= dy;
|
||||||
macLead *= dy;
|
macLead *= dy;
|
||||||
area *= dy;
|
area *= dy;
|
||||||
@ -537,7 +585,7 @@ public class TubeFinSetCalc extends RocketComponentCalc {
|
|||||||
*/
|
*/
|
||||||
private double calculateCPPos(FlightConditions cond) {
|
private double calculateCPPos(FlightConditions cond) {
|
||||||
double m = cond.getMach();
|
double m = cond.getMach();
|
||||||
// logger.debug("m = {} ", m);
|
// log.debug("m = {} ", m);
|
||||||
if (m <= 0.5) {
|
if (m <= 0.5) {
|
||||||
// At subsonic speeds CP at quarter chord
|
// At subsonic speeds CP at quarter chord
|
||||||
return 0.25;
|
return 0.25;
|
||||||
@ -556,7 +604,7 @@ public class TubeFinSetCalc extends RocketComponentCalc {
|
|||||||
val += poly[i] * x;
|
val += poly[i] * x;
|
||||||
x *= m;
|
x *= m;
|
||||||
}
|
}
|
||||||
// logger.debug("val = {}", val);
|
// log.debug("val = {}", val);
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -586,83 +634,27 @@ public class TubeFinSetCalc extends RocketComponentCalc {
|
|||||||
poly[1] = (-31.6049 * (-0.705375 + ar) * (-0.198476 + ar)) / denom;
|
poly[1] = (-31.6049 * (-0.705375 + ar) * (-0.198476 + ar)) / denom;
|
||||||
poly[0] = (9.16049 * (-0.588838 + ar) * (-0.20624 + ar)) / denom;
|
poly[0] = (9.16049 * (-0.588838 + ar) * (-0.20624 + ar)) / denom;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
// @SuppressWarnings("null")
|
public double calculateFrictionCD(FlightConditions conditions, double componentCf, WarningSet warnings) {
|
||||||
// public static void main(String arg[]) {
|
warnings.addAll(geometryWarnings);
|
||||||
// Rocket rocket = TestRocket.makeRocket();
|
|
||||||
// FinSet finset = null;
|
final double frictionCD = componentCf * wettedArea / conditions.getRefArea();
|
||||||
//
|
log.debug("frictionCD " + frictionCD);
|
||||||
// Iterator<RocketComponent> iter = rocket.deepIterator();
|
return frictionCD;
|
||||||
// while (iter.hasNext()) {
|
}
|
||||||
// RocketComponent c = iter.next();
|
|
||||||
// if (c instanceof FinSet) {
|
|
||||||
// finset = (FinSet)c;
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// ((TrapezoidFinSet)finset).setHeight(0.10);
|
|
||||||
// ((TrapezoidFinSet)finset).setRootChord(0.10);
|
|
||||||
// ((TrapezoidFinSet)finset).setTipChord(0.10);
|
|
||||||
// ((TrapezoidFinSet)finset).setSweep(0.0);
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// FinSetCalc calc = new FinSetCalc(finset);
|
|
||||||
//
|
|
||||||
// calc.calculateFinGeometry();
|
|
||||||
// FlightConditions cond = new FlightConditions(new Configuration(rocket));
|
|
||||||
// for (double m=0; m < 3; m+=0.05) {
|
|
||||||
// cond.setMach(m);
|
|
||||||
// cond.setAOA(0.0*Math.PI/180);
|
|
||||||
// double cna = calc.calculateFinCNa1(cond);
|
|
||||||
// System.out.printf("%5.2f "+cna+"\n", m);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double calculatePressureCD(FlightConditions conditions,
|
public double calculatePressureCD(FlightConditions conditions,
|
||||||
double stagnationCD, double baseCD, WarningSet warnings) {
|
double stagnationCD, double baseCD, WarningSet warnings) {
|
||||||
|
|
||||||
double mach = conditions.getMach();
|
warnings.addAll(geometryWarnings);
|
||||||
double cd = 0;
|
final double cd = super.calculatePressureCD(conditions, stagnationCD, baseCD, warnings) +
|
||||||
|
(stagnationCD + baseCD) * intersticeArea / conditions.getRefArea();
|
||||||
// Pressure fore-drag
|
log.debug("pressure CD " + cd);
|
||||||
if (crossSection == FinSet.CrossSection.AIRFOIL ||
|
|
||||||
crossSection == FinSet.CrossSection.ROUNDED) {
|
return cd;
|
||||||
|
|
||||||
// Round leading edge
|
|
||||||
if (mach < 0.9) {
|
|
||||||
cd = Math.pow(1 - pow2(mach), -0.417) - 1;
|
|
||||||
} else if (mach < 1) {
|
|
||||||
cd = 1 - 1.785 * (mach - 0.9);
|
|
||||||
} else {
|
|
||||||
cd = 1.214 - 0.502 / pow2(mach) + 0.1095 / pow2(pow2(mach));
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (crossSection == FinSet.CrossSection.SQUARE) {
|
|
||||||
cd = stagnationCD;
|
|
||||||
} else {
|
|
||||||
throw new UnsupportedOperationException("Unsupported fin profile: " + crossSection);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Slanted leading edge
|
|
||||||
cd *= pow2(cosGammaLead);
|
|
||||||
|
|
||||||
// Trailing edge drag
|
|
||||||
if (crossSection == FinSet.CrossSection.SQUARE) {
|
|
||||||
cd += baseCD;
|
|
||||||
} else if (crossSection == FinSet.CrossSection.ROUNDED) {
|
|
||||||
cd += baseCD / 2;
|
|
||||||
}
|
|
||||||
// Airfoil assumed to have zero base drag
|
|
||||||
|
|
||||||
// Scale to correct reference area
|
|
||||||
cd *= finCount * span * thickness / conditions.getRefArea();
|
|
||||||
|
|
||||||
return cd;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int calculateInterferenceFinCount(TubeFinSet component) {
|
private static int calculateInterferenceFinCount(TubeFinSet component) {
|
||||||
RocketComponent parent = component.getParent();
|
RocketComponent parent = component.getParent();
|
||||||
@ -672,11 +664,4 @@ public class TubeFinSetCalc extends RocketComponentCalc {
|
|||||||
|
|
||||||
return 3 * component.getFinCount();
|
return 3 * component.getFinCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public double calculateFrictionCD(FlightConditions conditions, double componentCf, WarningSet warnings) {
|
|
||||||
// launch lug doesn't add enough area to worry about
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ import net.sf.openrocket.util.MathUtil;
|
|||||||
import net.sf.openrocket.util.StateChangeListener;
|
import net.sf.openrocket.util.StateChangeListener;
|
||||||
|
|
||||||
|
|
||||||
public class LaunchLug extends ExternalComponent implements AnglePositionable, BoxBounded, Coaxial, LineInstanceable, InsideColorComponent {
|
public class LaunchLug extends Tube implements AnglePositionable, BoxBounded, LineInstanceable, InsideColorComponent {
|
||||||
|
|
||||||
private static final Translator trans = Application.getTranslator();
|
private static final Translator trans = Application.getTranslator();
|
||||||
|
|
||||||
|
11
core/src/net/sf/openrocket/rocketcomponent/Tube.java
Normal file
11
core/src/net/sf/openrocket/rocketcomponent/Tube.java
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
package net.sf.openrocket.rocketcomponent;
|
||||||
|
|
||||||
|
import net.sf.openrocket.rocketcomponent.position.AxialMethod;
|
||||||
|
|
||||||
|
public abstract class Tube extends ExternalComponent implements Coaxial {
|
||||||
|
|
||||||
|
public Tube(AxialMethod relativePosition) {
|
||||||
|
super(relativePosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -17,7 +17,7 @@ import net.sf.openrocket.rocketcomponent.position.RadiusMethod;
|
|||||||
import net.sf.openrocket.startup.Application;
|
import net.sf.openrocket.startup.Application;
|
||||||
import net.sf.openrocket.util.*;
|
import net.sf.openrocket.util.*;
|
||||||
|
|
||||||
public class TubeFinSet extends ExternalComponent implements AxialPositionable, BoxBounded, RingInstanceable, InsideColorComponent {
|
public class TubeFinSet extends Tube implements AxialPositionable, BoxBounded, RingInstanceable, InsideColorComponent {
|
||||||
private static final Translator trans = Application.getTranslator();
|
private static final Translator trans = Application.getTranslator();
|
||||||
|
|
||||||
private final static double DEFAULT_RADIUS = 0.025;
|
private final static double DEFAULT_RADIUS = 0.025;
|
||||||
|
@ -124,7 +124,7 @@ public class IntegrationTest {
|
|||||||
// Compute cg+cp + altitude
|
// Compute cg+cp + altitude
|
||||||
// double cgx, double mass, double cpx, double cna)
|
// double cgx, double mass, double cpx, double cna)
|
||||||
checkCgCp(0.248, 0.0645, 0.320, 12.0);
|
checkCgCp(0.248, 0.0645, 0.320, 12.0);
|
||||||
checkAlt(48.2);
|
checkAlt(49.0);
|
||||||
|
|
||||||
// Mass modification
|
// Mass modification
|
||||||
document.addUndoPosition("Modify mass");
|
document.addUndoPosition("Modify mass");
|
||||||
@ -157,7 +157,7 @@ public class IntegrationTest {
|
|||||||
|
|
||||||
// Check cg+cp + altitude
|
// Check cg+cp + altitude
|
||||||
checkCgCp(0.163, 0.0613, 0.275, 9.95);
|
checkCgCp(0.163, 0.0613, 0.275, 9.95);
|
||||||
checkAlt(45.0);
|
checkAlt(45.6);
|
||||||
|
|
||||||
// Undo "Remove component" change
|
// Undo "Remove component" change
|
||||||
undoAction.actionPerformed(new ActionEvent(this, 0, "foo"));
|
undoAction.actionPerformed(new ActionEvent(this, 0, "foo"));
|
||||||
@ -183,7 +183,7 @@ public class IntegrationTest {
|
|||||||
|
|
||||||
// Check cg+cp + altitude
|
// Check cg+cp + altitude
|
||||||
checkCgCp(0.248, 0.0645, 0.320, 12.0);
|
checkCgCp(0.248, 0.0645, 0.320, 12.0);
|
||||||
checkAlt(48.2);
|
checkAlt(48.87);
|
||||||
|
|
||||||
// Redo "Modify mass" change
|
// Redo "Modify mass" change
|
||||||
redoAction.actionPerformed(new ActionEvent(this, 0, "foo"));
|
redoAction.actionPerformed(new ActionEvent(this, 0, "foo"));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user