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;
|
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++;
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user