Add component CD override logic to aerodynamic calculations.
Add unit test for CD override
This commit is contained in:
parent
1a1e5b2e62
commit
d076c54c9a
@ -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++;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user