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;
import net.sf.openrocket.rocketcomponent.Rocket;
import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.util.BugException;
import net.sf.openrocket.util.Coordinate;
@ -64,7 +65,9 @@ public class AerodynamicForces implements Cloneable, Monitorable {
/** Drag coefficient due to friction drag. */
private double frictionCD = Double.NaN;
/** Drag coefficient from overrides */
private double overrideCD = Double.NaN;
private double pitchDampingMoment = Double.NaN;
private double yawDampingMoment = Double.NaN;
@ -196,8 +199,9 @@ public class AerodynamicForces implements Cloneable, Monitorable {
}
public double getCD() {
if(component == null) return CD;
if(component.isCDOverridden()) {
if (component == null) return CD;
if (component.isCDOverriddenByAncestor()) return 0;
if (component.isCDOverridden()) {
return component.getOverrideCD();
}
return CD;
@ -210,7 +214,8 @@ public class AerodynamicForces implements Cloneable, Monitorable {
public double getPressureCD() {
if(component == null) return pressureCD;
if(component.isCDOverridden()) {
if(component.isCDOverridden() ||
component.isCDOverriddenByAncestor()) {
return 0;
}
return pressureCD;
@ -223,8 +228,9 @@ public class AerodynamicForces implements Cloneable, Monitorable {
public double getBaseCD() {
if(component == null) return baseCD;
if(component.isCDOverridden()) {
return component.getOverrideCD();
if(component.isCDOverridden() ||
component.isCDOverriddenByAncestor()) {
return 0;
}
return baseCD;
}
@ -236,12 +242,26 @@ public class AerodynamicForces implements Cloneable, Monitorable {
public double getFrictionCD() {
if(component == null) return frictionCD;
if(component.isCDOverridden()) {
if(component.isCDOverridden() ||
component.isCDOverriddenByAncestor()) {
return 0;
}
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) {
this.pitchDampingMoment = pitchDampingMoment;
modID++;

View File

@ -89,6 +89,7 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
rocketForces.setFrictionCD(calculateFrictionCD(configuration, conditions, eachMap, warnings));
rocketForces.setPressureCD(calculatePressureCD(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<>();
for(final RocketComponent comp : instMap.keySet()){
@ -118,7 +119,10 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
if (Double.isNaN(f.getFrictionCD()))
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()));
finalMap.put(comp, f);
@ -187,8 +191,9 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
total.setFrictionCD(calculateFrictionCD(configuration, conditions, null, warnings));
total.setPressureCD(calculatePressureCD(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()));
@ -342,7 +347,7 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
* @return friction drag for entire rocket
*/
private double calculateFrictionCD(FlightConfiguration configuration, FlightConditions conditions,
Map<RocketComponent, AerodynamicForces> map, WarningSet warningSet) {
Map<RocketComponent, AerodynamicForces> forceMap, WarningSet warningSet) {
double mach = conditions.getMach();
double Re = calculateReynoldsNumber(configuration, conditions);
@ -375,8 +380,8 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
continue;
}
// Handle Overriden CD for Whole Rocket
if(c.isCDOverridden()) {
if (c.isCDOverridden() ||
c.isCDOverriddenByAncestor()) {
continue;
}
@ -410,8 +415,8 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
}
double componentFrictionCD = calcMap.get(c).calculateFrictionCD(conditions, componentCf, warningSet);
int instanceCount = entry.getValue().size();
if (c instanceof SymmetricComponent) {
SymmetricComponent s = (SymmetricComponent) c;
@ -430,8 +435,8 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
otherFrictionCD += instanceCount * componentFrictionCD;
}
if (map != null) {
map.get(c).setFrictionCD(componentFrictionCD);
if (forceMap != null) {
forceMap.get(c).setFrictionCD(componentFrictionCD);
}
}
@ -440,10 +445,10 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
double correction = (1 + 1.0 / (2 * fB));
// Correct body data in map
if (map != null) {
for (RocketComponent c : map.keySet()) {
if (forceMap != null) {
for (RocketComponent c : forceMap.keySet()) {
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;
}
if(c.isCDOverridden()) {
if (c.isCDOverridden() ||
c.isCDOverriddenByAncestor()) {
continue;
}
@ -616,7 +622,7 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
// Pressure drag of this component
double cd = calcMap.get(c).calculatePressureCD(conditions, stagnation, base,
warningSet);
if (forceMap != null) {
forceMap.get(c).setPressureCD(cd);
}
@ -639,13 +645,13 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
cd = stagnation * area / conditions.getRefArea();
total += instanceCount * cd;
if (forceMap != null) {
forceMap.get(c).setPressureCD(forceMap.get(c).getPressureCD() + cd);
}
if (forceMap != null) {
forceMap.get(c).setPressureCD(forceMap.get(c).getPressureCD() + cd);
}
}
}
}
return total;
}
@ -660,7 +666,7 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
* @return
*/
private double calculateBaseCD(FlightConfiguration configuration, FlightConditions conditions,
Map<RocketComponent, AerodynamicForces> map, WarningSet warnings) {
Map<RocketComponent, AerodynamicForces> forceMap, WarningSet warnings) {
double base, total;
@ -682,8 +688,8 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
int instanceCount = entry.getValue().size();
if(c.isCDOverridden()) {
total += instanceCount * c.getOverrideCD();
if (c.isCDOverridden() ||
c.isCDOverriddenByAncestor()) {
continue;
}
@ -699,8 +705,8 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
double area = Math.PI * (pow2(radius) - pow2(s.getForeRadius()));
double cd = base * area / conditions.getRefArea();
total += instanceCount * cd;
if ((map != null) && (prevComponent != null)) {
map.get(prevComponent).setBaseCD(cd);
if ((forceMap != null) && (prevComponent != null)) {
forceMap.get(prevComponent).setBaseCD(cd);
}
}
@ -712,8 +718,8 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
double area = Math.PI * pow2(s.getAftRadius());
double cd = base * area / conditions.getRefArea();
total += instanceCount * cd;
if (map != null) {
map.get(s).setBaseCD(cd);
if (forceMap != null) {
forceMap.get(s).setBaseCD(cd);
}
}
}
@ -797,9 +803,50 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
else
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
* @param configuration Rocket configuration
* @param conditions flight conditions in consideration

View File

@ -697,7 +697,6 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
* @param x the override CD to set.
*/
public final void setOverrideCD(double x) {
System.out.println("set component " + this + " override to " + x);
for (RocketComponent listener : configListeners) {
listener.setOverrideCD(x);
}
@ -709,7 +708,6 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
if (isCDOverridden()) {
if (isSubcomponentsOverridden()) {
System.out.println("override subcomponents");
overrideSubcomponentsCD(true);
}
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
*/
public final void setCDOverridden(boolean o) {
System.out.println("setting component " + this + " cdOverridden to " + o);
for (RocketComponent listener : configListeners) {
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.
*/
public void setSubcomponentsOverridden(boolean override) {
System.out.println("component " + this + " override subcomponents " + override);
for (RocketComponent listener : configListeners) {
listener.setSubcomponentsOverridden(override);
}
@ -827,7 +823,6 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
*/
void overrideSubcomponentsCD(boolean override) {
for (RocketComponent c: this.children) {
System.out.println("overriding CD of " + c + " override " + override);
if (c.isCDOverriddenByAncestor() != override) {
c.cdOverriddenByAncestor = override;