added exploratory code for non-axisymmetric CPs

This commit is contained in:
Daniel_M_Williams 2015-11-22 10:12:30 -05:00
parent 0972ee389a
commit e3250c9a91
8 changed files with 93 additions and 39 deletions

View File

@ -70,8 +70,18 @@ public class AerodynamicForces implements Cloneable, Monitorable {
private double yawDampingMoment = Double.NaN;
private int modID = 0;
private boolean axisymmetric = true;
public boolean isAxisymmetric(){
return this.axisymmetric;
}
public void setAxisymmetric( final boolean isSym ){
this.axisymmetric = isSym;
}
public void setComponent(RocketComponent component) {
this.component = component;
modID++;
@ -254,6 +264,7 @@ public class AerodynamicForces implements Cloneable, Monitorable {
public void zero() {
// component untouched
setAxisymmetric(true);
setCP(Coordinate.NUL);
setCNa(0);
setCN(0);

View File

@ -10,10 +10,11 @@ import java.util.Map;
import net.sf.openrocket.aerodynamics.barrowman.FinSetCalc;
import net.sf.openrocket.aerodynamics.barrowman.RocketComponentCalc;
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
import net.sf.openrocket.rocketcomponent.ExternalComponent;
import net.sf.openrocket.rocketcomponent.ExternalComponent.Finish;
import net.sf.openrocket.rocketcomponent.FinSet;
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
import net.sf.openrocket.rocketcomponent.RingInstanceable;
import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.rocketcomponent.SymmetricComponent;
import net.sf.openrocket.util.Coordinate;
@ -38,7 +39,7 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
private double cacheDiameter = -1;
private double cacheLength = -1;
public boolean debug = false;
public BarrowmanCalculator() {
@ -183,33 +184,52 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
if (!component.isAerodynamic())
continue;
// Check for discontinuities
if (component instanceof SymmetricComponent) {
SymmetricComponent sym = (SymmetricComponent) component;
// TODO:LOW: Ignores other cluster components (not clusterable)
double x = component.toAbsolute(Coordinate.NUL)[0].x;
// Check for lengthwise discontinuity
if (x > componentX + 0.0001) {
if (!MathUtil.equals(radius, 0)) {
warnings.add(Warning.DISCONTINUITY);
radius = 0;
}
}
componentX = component.toAbsolute(new Coordinate(component.getLength()))[0].x;
// Check for radius discontinuity
if (!MathUtil.equals(sym.getForeRadius(), radius)) {
warnings.add(Warning.DISCONTINUITY);
// TODO: MEDIUM: Apply correction to values to cp and to map
}
radius = sym.getAftRadius();
}
// TODO: refactor this code block to a separate method, where it will operate on each stage separately.
//
// Developer's Note:
// !! this code assumes all SymmetricComponents are along the centerline
// With the implementation of ParallelStages and Pods, this is no longer true. -Daniel Williams
//
// // Check for discontinuities
// if (component instanceof SymmetricComponent) {
// SymmetricComponent sym = (SymmetricComponent) component;
// // TODO:LOW: Ignores other cluster components (not clusterable)
// double x = component.toAbsolute(Coordinate.NUL)[0].x;
//
// // Check for lengthwise discontinuity
// if (x > componentX + 0.0001) {
// if (!MathUtil.equals(radius, 0)) {
// warnings.add(Warning.DISCONTINUITY);
// radius = 0;
// }
// }
// componentX = component.toAbsolute(new Coordinate(component.getLength()))[0].x;
//
// // Check for radius discontinuity
// if (!MathUtil.equals(sym.getForeRadius(), radius)) {
// warnings.add(Warning.DISCONTINUITY);
// // TODO: MEDIUM: Apply correction to values to cp and to map
// }
// radius = sym.getAftRadius();
// }
// Call calculation method
forces.zero();
calcMap.get(component).calculateNonaxialForces(conditions, forces, warnings);
// to account for non axi-symmetric rockets such as
if(( ! component.isAxisymmetric()) &&( component instanceof RingInstanceable )){
RingInstanceable ring = (RingInstanceable)component;
forces.setAxisymmetric(false);
total.setAxisymmetric(false);
// TODO : Implement Best-Case, Worst-Case Cp calculations.... here
double minAngle = ring.getAngularOffset(); // angle of minimum CP, MOI
double maxAngle = minAngle+Math.PI/2; // angle of maximum CP, MOI
}
int instanceCount = component.getLocations().length;
Coordinate x_cp_comp = forces.getCP();
Coordinate x_cp_weighted = x_cp_comp.setWeight(x_cp_comp.weight * instanceCount);
@ -722,5 +742,4 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
return 0;
}
}

View File

@ -114,6 +114,10 @@ public abstract class ComponentAssembly extends RocketComponent {
return false;
}
@Override
public boolean isAxisymmetric(){
return !(2 == this.getInstanceCount());
}
@Override
public void setAxialOffset(final double _pos) {

View File

@ -3,9 +3,6 @@ package net.sf.openrocket.rocketcomponent;
import java.util.ArrayList;
import java.util.Collection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.startup.Application;
import net.sf.openrocket.util.BugException;

View File

@ -6,7 +6,7 @@ public interface RingInstanceable extends Instanceable {
public double getRadialOffset();
public void setAngularOffset(final double radius);
public void setAngularOffset(final double angle);
public void setRadialOffset(final double radius);

View File

@ -279,6 +279,9 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
return (Position.AFTER == this.relativePosition);
}
public boolean isAxisymmetric(){
return true;
}
/**
* Shift the coordinates in the array corresponding to radial movement. A component

View File

@ -1,11 +1,18 @@
package net.sf.openrocket.aerodynamics;
import static org.junit.Assert.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import org.junit.BeforeClass;
import org.junit.Test;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Module;
import net.sf.openrocket.ServicesForTesting;
import net.sf.openrocket.motor.MotorInstance;
import net.sf.openrocket.plugin.PluginModule;
import net.sf.openrocket.rocketcomponent.BodyTube;
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
import net.sf.openrocket.rocketcomponent.FlightConfigurationID;
import net.sf.openrocket.rocketcomponent.InnerTube;
@ -15,13 +22,6 @@ import net.sf.openrocket.util.Coordinate;
import net.sf.openrocket.util.MathUtil;
import net.sf.openrocket.util.TestRockets;
import org.junit.BeforeClass;
import org.junit.Test;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Module;
public class BarrowmanCalculatorTest {
protected final double EPSILON = MathUtil.EPSILON;
@ -86,6 +86,26 @@ public class BarrowmanCalculatorTest {
fail("Not yet implemented");
}
@Test
public void testCPDoubleStrapOn() {
Rocket rocket = TestRockets.makeFalcon9Heavy();
FlightConfiguration config = rocket.getDefaultConfiguration();
BarrowmanCalculator calc = new BarrowmanCalculator();
FlightConditions conditions = new FlightConditions(config);
WarningSet warnings = new WarningSet();
calc.debug = true;
// calculated from OpenRocket 15.03
double expCPx = 0.225; // cm
Coordinate calcCP = calc.getCP(config, conditions, warnings);
fail("NYI");
assertEquals(" Falcon Heavy CP x value is incorrect:", expCPx, calcCP.x, EPSILON);
Coordinate expCP = new Coordinate(expCPx, 0,0,0);
assertEquals(" Falcon Heavy CP is incorrect:", expCP, calcCP);
}
@Test
public void testGetWorstCP() {
fail("Not yet implemented");

View File

@ -421,8 +421,8 @@ public class RocketFigure extends AbstractScaleFigure {
// facade for the recursive function below
private void getShapes(ArrayList<RocketComponentShape> allShapes, FlightConfiguration configuration){
for( AxialStage stage : configuration.getActiveStages()){
int stageNumber = stage.getStageNumber();
// for debug...
//int stageNumber = stage.getStageNumber();
//String activeString = ( configuration.isStageActive(stageNumber) ? "active" : "inactive");
getShapeTree( allShapes, stage, Coordinate.ZERO);