Add component CD override logic to aerodynamic calculations.

Add unit test for CD override
This commit is contained in:
JoePfeiffer 2022-08-30 09:50:26 -06:00
parent 1a1e5b2e62
commit d076c54c9a
3 changed files with 100 additions and 38 deletions

View File

@ -1,5 +1,6 @@
package net.sf.openrocket.aerodynamics; package net.sf.openrocket.aerodynamics;
import net.sf.openrocket.rocketcomponent.Rocket;
import net.sf.openrocket.rocketcomponent.RocketComponent; import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.util.BugException; import net.sf.openrocket.util.BugException;
import net.sf.openrocket.util.Coordinate; import net.sf.openrocket.util.Coordinate;
@ -65,6 +66,8 @@ public class AerodynamicForces implements Cloneable, Monitorable {
/** Drag coefficient due to friction drag. */ /** Drag coefficient due to friction drag. */
private double frictionCD = Double.NaN; private double frictionCD = Double.NaN;
/** Drag coefficient from overrides */
private double overrideCD = Double.NaN;
private double pitchDampingMoment = Double.NaN; private double pitchDampingMoment = Double.NaN;
private double yawDampingMoment = Double.NaN; private double yawDampingMoment = Double.NaN;
@ -197,6 +200,7 @@ public class AerodynamicForces implements Cloneable, Monitorable {
public double getCD() { public double getCD() {
if (component == null) return CD; if (component == null) return CD;
if (component.isCDOverriddenByAncestor()) return 0;
if (component.isCDOverridden()) { if (component.isCDOverridden()) {
return component.getOverrideCD(); return component.getOverrideCD();
} }
@ -210,7 +214,8 @@ public class AerodynamicForces implements Cloneable, Monitorable {
public double getPressureCD() { public double getPressureCD() {
if(component == null) return pressureCD; if(component == null) return pressureCD;
if(component.isCDOverridden()) { if(component.isCDOverridden() ||
component.isCDOverriddenByAncestor()) {
return 0; return 0;
} }
return pressureCD; return pressureCD;
@ -223,8 +228,9 @@ public class AerodynamicForces implements Cloneable, Monitorable {
public double getBaseCD() { public double getBaseCD() {
if(component == null) return baseCD; if(component == null) return baseCD;
if(component.isCDOverridden()) { if(component.isCDOverridden() ||
return component.getOverrideCD(); component.isCDOverriddenByAncestor()) {
return 0;
} }
return baseCD; return baseCD;
} }
@ -236,12 +242,26 @@ public class AerodynamicForces implements Cloneable, Monitorable {
public double getFrictionCD() { public double getFrictionCD() {
if(component == null) return frictionCD; if(component == null) return frictionCD;
if(component.isCDOverridden()) { if(component.isCDOverridden() ||
component.isCDOverriddenByAncestor()) {
return 0; return 0;
} }
return frictionCD; return frictionCD;
} }
public void setOverrideCD(double overrideCD) {
this.overrideCD = overrideCD;
modID++;
}
public double getOverrideCD() {
if (component == null) return overrideCD;
if (!(component instanceof Rocket) &&
(!component.isCDOverridden() ||
component.isCDOverriddenByAncestor())) return 0;
return overrideCD;
}
public void setPitchDampingMoment(double pitchDampingMoment) { public void setPitchDampingMoment(double pitchDampingMoment) {
this.pitchDampingMoment = pitchDampingMoment; this.pitchDampingMoment = pitchDampingMoment;
modID++; modID++;

View File

@ -89,6 +89,7 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
rocketForces.setFrictionCD(calculateFrictionCD(configuration, conditions, eachMap, warnings)); rocketForces.setFrictionCD(calculateFrictionCD(configuration, conditions, eachMap, warnings));
rocketForces.setPressureCD(calculatePressureCD(configuration, conditions, eachMap, warnings)); rocketForces.setPressureCD(calculatePressureCD(configuration, conditions, eachMap, warnings));
rocketForces.setBaseCD(calculateBaseCD(configuration, conditions, eachMap, warnings)); rocketForces.setBaseCD(calculateBaseCD(configuration, conditions, eachMap, warnings));
rocketForces.setOverrideCD(calculateOverrideCD(configuration, conditions, eachMap, assemblyMap, warnings));
Map<RocketComponent, AerodynamicForces> finalMap = new LinkedHashMap<>(); Map<RocketComponent, AerodynamicForces> finalMap = new LinkedHashMap<>();
for(final RocketComponent comp : instMap.keySet()){ for(final RocketComponent comp : instMap.keySet()){
@ -118,7 +119,10 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
if (Double.isNaN(f.getFrictionCD())) if (Double.isNaN(f.getFrictionCD()))
f.setFrictionCD(0); f.setFrictionCD(0);
f.setCD(f.getBaseCD() + f.getPressureCD() + f.getFrictionCD()); if (Double.isNaN(f.getOverrideCD()))
f.setOverrideCD(0);
f.setCD(f.getBaseCD() + f.getPressureCD() + f.getFrictionCD() + f.getOverrideCD());
f.setCDaxial(calculateAxialCD(conditions, f.getCD())); f.setCDaxial(calculateAxialCD(conditions, f.getCD()));
finalMap.put(comp, f); finalMap.put(comp, f);
@ -187,8 +191,9 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
total.setFrictionCD(calculateFrictionCD(configuration, conditions, null, warnings)); total.setFrictionCD(calculateFrictionCD(configuration, conditions, null, warnings));
total.setPressureCD(calculatePressureCD(configuration, conditions, null, warnings)); total.setPressureCD(calculatePressureCD(configuration, conditions, null, warnings));
total.setBaseCD(calculateBaseCD(configuration, conditions, null, warnings)); total.setBaseCD(calculateBaseCD(configuration, conditions, null, warnings));
total.setOverrideCD(calculateOverrideCD(configuration, conditions, null, null, warnings));
total.setCD(total.getFrictionCD() + total.getPressureCD() + total.getBaseCD()); total.setCD(total.getFrictionCD() + total.getPressureCD() + total.getBaseCD() + total.getOverrideCD());
total.setCDaxial(calculateAxialCD(conditions, total.getCD())); total.setCDaxial(calculateAxialCD(conditions, total.getCD()));
@ -342,7 +347,7 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
* @return friction drag for entire rocket * @return friction drag for entire rocket
*/ */
private double calculateFrictionCD(FlightConfiguration configuration, FlightConditions conditions, private double calculateFrictionCD(FlightConfiguration configuration, FlightConditions conditions,
Map<RocketComponent, AerodynamicForces> map, WarningSet warningSet) { Map<RocketComponent, AerodynamicForces> forceMap, WarningSet warningSet) {
double mach = conditions.getMach(); double mach = conditions.getMach();
double Re = calculateReynoldsNumber(configuration, conditions); double Re = calculateReynoldsNumber(configuration, conditions);
@ -375,8 +380,8 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
continue; continue;
} }
// Handle Overriden CD for Whole Rocket if (c.isCDOverridden() ||
if(c.isCDOverridden()) { c.isCDOverriddenByAncestor()) {
continue; continue;
} }
@ -410,8 +415,8 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
} }
double componentFrictionCD = calcMap.get(c).calculateFrictionCD(conditions, componentCf, warningSet); double componentFrictionCD = calcMap.get(c).calculateFrictionCD(conditions, componentCf, warningSet);
int instanceCount = entry.getValue().size(); int instanceCount = entry.getValue().size();
if (c instanceof SymmetricComponent) { if (c instanceof SymmetricComponent) {
SymmetricComponent s = (SymmetricComponent) c; SymmetricComponent s = (SymmetricComponent) c;
@ -430,8 +435,8 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
otherFrictionCD += instanceCount * componentFrictionCD; otherFrictionCD += instanceCount * componentFrictionCD;
} }
if (map != null) { if (forceMap != null) {
map.get(c).setFrictionCD(componentFrictionCD); forceMap.get(c).setFrictionCD(componentFrictionCD);
} }
} }
@ -440,10 +445,10 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
double correction = (1 + 1.0 / (2 * fB)); double correction = (1 + 1.0 / (2 * fB));
// Correct body data in map // Correct body data in map
if (map != null) { if (forceMap != null) {
for (RocketComponent c : map.keySet()) { for (RocketComponent c : forceMap.keySet()) {
if (c instanceof SymmetricComponent) { if (c instanceof SymmetricComponent) {
map.get(c).setFrictionCD(map.get(c).getFrictionCD() * correction); forceMap.get(c).setFrictionCD(forceMap.get(c).getFrictionCD() * correction);
} }
} }
} }
@ -607,7 +612,8 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
continue; continue;
} }
if(c.isCDOverridden()) { if (c.isCDOverridden() ||
c.isCDOverriddenByAncestor()) {
continue; continue;
} }
@ -660,7 +666,7 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
* @return * @return
*/ */
private double calculateBaseCD(FlightConfiguration configuration, FlightConditions conditions, private double calculateBaseCD(FlightConfiguration configuration, FlightConditions conditions,
Map<RocketComponent, AerodynamicForces> map, WarningSet warnings) { Map<RocketComponent, AerodynamicForces> forceMap, WarningSet warnings) {
double base, total; double base, total;
@ -682,8 +688,8 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
int instanceCount = entry.getValue().size(); int instanceCount = entry.getValue().size();
if(c.isCDOverridden()) { if (c.isCDOverridden() ||
total += instanceCount * c.getOverrideCD(); c.isCDOverriddenByAncestor()) {
continue; continue;
} }
@ -699,8 +705,8 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
double area = Math.PI * (pow2(radius) - pow2(s.getForeRadius())); double area = Math.PI * (pow2(radius) - pow2(s.getForeRadius()));
double cd = base * area / conditions.getRefArea(); double cd = base * area / conditions.getRefArea();
total += instanceCount * cd; total += instanceCount * cd;
if ((map != null) && (prevComponent != null)) { if ((forceMap != null) && (prevComponent != null)) {
map.get(prevComponent).setBaseCD(cd); forceMap.get(prevComponent).setBaseCD(cd);
} }
} }
@ -712,8 +718,8 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
double area = Math.PI * pow2(s.getAftRadius()); double area = Math.PI * pow2(s.getAftRadius());
double cd = base * area / conditions.getRefArea(); double cd = base * area / conditions.getRefArea();
total += instanceCount * cd; total += instanceCount * cd;
if (map != null) { if (forceMap != null) {
map.get(s).setBaseCD(cd); forceMap.get(s).setBaseCD(cd);
} }
} }
} }
@ -798,6 +804,47 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
return -mul * cd; return -mul * cd;
} }
/**
* add together CD overrides for active components
*
* @param configuration Rocket configuration
* @param conditions Flight conditions taken into account
* @param forceMap
* @param warningSet all current warnings
* @return
*/
private double calculateOverrideCD(FlightConfiguration configuration, FlightConditions conditions,
Map<RocketComponent, AerodynamicForces> eachMap,
Map<RocketComponent, AerodynamicForces> assemblyMap,
WarningSet warningSet) {
if (calcMap == null)
buildCalcMap(configuration);
double total = 0;
final InstanceMap imap = configuration.getActiveInstances();
for(Map.Entry<RocketComponent, ArrayList<InstanceContext>> entry: imap.entrySet() ) {
final RocketComponent c = entry.getKey();
int instanceCount = entry.getValue().size();
if (!c.isAerodynamic() &&
!(c instanceof ComponentAssembly)) {
continue;
}
if (c.isCDOverridden() &&
!c.isCDOverriddenByAncestor()) {
double cd = instanceCount * c.getOverrideCD();
Map<RocketComponent, AerodynamicForces> forceMap = (c instanceof ComponentAssembly) ? assemblyMap : eachMap;
if (forceMap != null) {
forceMap.get(c).setOverrideCD(cd);
}
total += cd;
}
}
return total;
}
/** /**
* get damping moments from a rocket in a flight * get damping moments from a rocket in a flight

View File

@ -697,7 +697,6 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
* @param x the override CD to set. * @param x the override CD to set.
*/ */
public final void setOverrideCD(double x) { public final void setOverrideCD(double x) {
System.out.println("set component " + this + " override to " + x);
for (RocketComponent listener : configListeners) { for (RocketComponent listener : configListeners) {
listener.setOverrideCD(x); listener.setOverrideCD(x);
} }
@ -709,7 +708,6 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
if (isCDOverridden()) { if (isCDOverridden()) {
if (isSubcomponentsOverridden()) { if (isSubcomponentsOverridden()) {
System.out.println("override subcomponents");
overrideSubcomponentsCD(true); overrideSubcomponentsCD(true);
} }
fireComponentChangeEvent(ComponentChangeEvent.AERODYNAMIC_CHANGE); fireComponentChangeEvent(ComponentChangeEvent.AERODYNAMIC_CHANGE);
@ -737,7 +735,6 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
* @param o whether the CD is currently directly overridden * @param o whether the CD is currently directly overridden
*/ */
public final void setCDOverridden(boolean o) { public final void setCDOverridden(boolean o) {
System.out.println("setting component " + this + " cdOverridden to " + o);
for (RocketComponent listener : configListeners) { for (RocketComponent listener : configListeners) {
listener.setCDOverridden(o); listener.setCDOverridden(o);
} }
@ -793,7 +790,6 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
* @param override whether the mass and/or CG override overrides all subcomponent. * @param override whether the mass and/or CG override overrides all subcomponent.
*/ */
public void setSubcomponentsOverridden(boolean override) { public void setSubcomponentsOverridden(boolean override) {
System.out.println("component " + this + " override subcomponents " + override);
for (RocketComponent listener : configListeners) { for (RocketComponent listener : configListeners) {
listener.setSubcomponentsOverridden(override); listener.setSubcomponentsOverridden(override);
} }
@ -827,7 +823,6 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
*/ */
void overrideSubcomponentsCD(boolean override) { void overrideSubcomponentsCD(boolean override) {
for (RocketComponent c: this.children) { for (RocketComponent c: this.children) {
System.out.println("overriding CD of " + c + " override " + override);
if (c.isCDOverriddenByAncestor() != override) { if (c.isCDOverriddenByAncestor() != override) {
c.cdOverriddenByAncestor = override; c.cdOverriddenByAncestor = override;