package net.sf.openrocket.simulation; import java.util.Iterator; import net.sf.openrocket.motor.MotorInstanceConfiguration; import net.sf.openrocket.rocketcomponent.Configuration; import net.sf.openrocket.rocketcomponent.FinSet; import net.sf.openrocket.rocketcomponent.Rocket; import net.sf.openrocket.rocketcomponent.RocketComponent; import net.sf.openrocket.rocketcomponent.SymmetricComponent; public class BasicTumbleStatus extends SimulationStatus { // Magic constants from techdoc.pdf private final static double cDFin = 1.42; private final static double cDBt = 0.56; // Fin efficiency. Index is number of fins. The 0th entry is arbitrary and used to // offset the indexes so finEff[1] is the coefficient for one fin from the table in techdoc.pdf private final static double[] finEff = { 0.0, 0.5, 1.0, 1.41, 1.81, 1.73, 1.90, 1.85 }; private final double drag; public BasicTumbleStatus(Configuration configuration, MotorInstanceConfiguration motorConfiguration, SimulationConditions simulationConditions) { super(configuration, motorConfiguration, simulationConditions); this.drag = computeTumbleDrag(); } public BasicTumbleStatus(SimulationStatus orig) { super(orig); if (orig instanceof BasicTumbleStatus) { this.drag = ((BasicTumbleStatus) orig).drag; } else { this.drag = computeTumbleDrag(); } } public double getTumbleDrag() { return drag; } private double computeTumbleDrag() { // Computed based on Sampo's experimentation as documented in the pdf. // compute the fin and body tube projected areas double aFins = 0.0; double aBt = 0.0; Rocket r = this.getConfiguration().getRocket(); Iterator<RocketComponent> componentIterator = r.iterator(); while (componentIterator.hasNext()) { RocketComponent component = componentIterator.next(); if (!component.isAerodynamic()) { continue; } if (component instanceof FinSet) { double finComponent = ((FinSet) component).getFinArea(); int finCount = ((FinSet) component).getFinCount(); // check bounds on finCount. if (finCount >= finEff.length) { finCount = finEff.length - 1; } aFins += finComponent * finEff[finCount]; } else if (component instanceof SymmetricComponent) { aBt += ((SymmetricComponent) component).getComponentPlanformArea(); } } return (cDFin * aFins + cDBt * aBt); } }