Implement tumbling based on the mathematics in techdoc.pdf. Change the
conditions to transistion to tumbling to include aoa>30.
This commit is contained in:
parent
b99a704eb6
commit
526131a64c
@ -194,13 +194,17 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
||||
}
|
||||
|
||||
// Check for Tumbling
|
||||
// FIXME - need to test things like no longer stable.
|
||||
// Conditions for transision are:
|
||||
// apogee reached
|
||||
// and is not already tumbling
|
||||
// and not stable (cg > cp)
|
||||
// and aoa > 30
|
||||
|
||||
if (status.isApogeeReached() && !status.isTumbling() ) {
|
||||
int last_data_index = status.getFlightData().getLength() -1;
|
||||
double cp = status.getFlightData().get(FlightDataType.TYPE_CP_LOCATION).get(last_data_index);
|
||||
double cg = status.getFlightData().get(FlightDataType.TYPE_CG_LOCATION).get(last_data_index);
|
||||
if( cg > cp ) {
|
||||
double cp = status.getFlightData().getLast(FlightDataType.TYPE_CP_LOCATION);
|
||||
double cg = status.getFlightData().getLast(FlightDataType.TYPE_CG_LOCATION);
|
||||
double aoa = status.getFlightData().getLast(FlightDataType.TYPE_AOA);
|
||||
if( cg > cp && aoa > 30 ) {
|
||||
addEvent( new FlightEvent(FlightEvent.Type.TUMBLE,status.getSimulationTime()));
|
||||
}
|
||||
status.setTumbling(true);
|
||||
|
@ -1,42 +1,77 @@
|
||||
package net.sf.openrocket.simulation;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import net.sf.openrocket.aerodynamics.AerodynamicForces;
|
||||
import net.sf.openrocket.aerodynamics.FlightConditions;
|
||||
import net.sf.openrocket.aerodynamics.WarningSet;
|
||||
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 {
|
||||
|
||||
private double tumbleCd;
|
||||
// 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 double drag;
|
||||
|
||||
public BasicTumbleStatus(Configuration configuration,
|
||||
MotorInstanceConfiguration motorConfiguration,
|
||||
SimulationConditions simulationConditions) {
|
||||
super(configuration, motorConfiguration, simulationConditions);
|
||||
computeTumbleCd();
|
||||
computeTumbleDrag();
|
||||
}
|
||||
|
||||
public BasicTumbleStatus(SimulationStatus orig) {
|
||||
super(orig);
|
||||
if ( orig instanceof BasicTumbleStatus ) {
|
||||
this.tumbleCd = ((BasicTumbleStatus) orig).tumbleCd;
|
||||
this.drag = ((BasicTumbleStatus) orig).drag;
|
||||
}
|
||||
}
|
||||
|
||||
public double getTumbleCd( ) {
|
||||
return tumbleCd;
|
||||
public double getTumbleDrag( ) {
|
||||
return drag;
|
||||
}
|
||||
|
||||
|
||||
public void computeTumbleCd() {
|
||||
// FIXME - probably want to compute the overall CD more accurately. Perhaps average
|
||||
// CD over three AoA: 0, 90, 180. In any case, using barrowman to compute this Cd is
|
||||
// completely wrong.
|
||||
WarningSet warnings = new WarningSet();
|
||||
FlightConditions cond = new FlightConditions(this.getConfiguration());
|
||||
cond.setAOA(Math.PI);
|
||||
AerodynamicForces forces = this.getSimulationConditions().getAerodynamicCalculator().getAerodynamicForces(this.getConfiguration(), cond, warnings);
|
||||
tumbleCd = forces.getCD();
|
||||
public void 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();
|
||||
}
|
||||
}
|
||||
|
||||
drag = ( cDFin * aFins + cDBt * aBt );
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,6 @@ public class BasicTumbleStepper extends AbstractSimulationStepper {
|
||||
|
||||
@Override
|
||||
public void step(SimulationStatus status, double maxTimeStep) throws SimulationException {
|
||||
double refArea = status.getConfiguration().getReferenceArea();
|
||||
|
||||
// Get the atmospheric conditions
|
||||
AtmosphericConditions atmosphere = modelAtmosphericConditions(status);
|
||||
@ -30,11 +29,11 @@ public class BasicTumbleStepper extends AbstractSimulationStepper {
|
||||
// Get total CD
|
||||
double mach = airSpeed.length() / atmosphere.getMachSpeed();
|
||||
|
||||
double totalCD = ((BasicTumbleStatus)status).getTumbleCd();
|
||||
double tumbleDrag = ((BasicTumbleStatus)status).getTumbleDrag();
|
||||
|
||||
// Compute drag force
|
||||
double dynP = (0.5 * atmosphere.getDensity() * airSpeed.length2());
|
||||
double dragForce = totalCD * dynP * refArea;
|
||||
double dragForce = tumbleDrag * dynP;
|
||||
MassData massData = calculateMassData(status);
|
||||
double mass = massData.getCG().weight;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user