added exploratory code for non-axisymmetric CPs
This commit is contained in:
parent
0972ee389a
commit
e3250c9a91
@ -71,6 +71,16 @@ public class AerodynamicForces implements Cloneable, Monitorable {
|
|||||||
|
|
||||||
private int modID = 0;
|
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) {
|
public void setComponent(RocketComponent component) {
|
||||||
this.component = component;
|
this.component = component;
|
||||||
@ -254,6 +264,7 @@ public class AerodynamicForces implements Cloneable, Monitorable {
|
|||||||
public void zero() {
|
public void zero() {
|
||||||
// component untouched
|
// component untouched
|
||||||
|
|
||||||
|
setAxisymmetric(true);
|
||||||
setCP(Coordinate.NUL);
|
setCP(Coordinate.NUL);
|
||||||
setCNa(0);
|
setCNa(0);
|
||||||
setCN(0);
|
setCN(0);
|
||||||
|
@ -10,10 +10,11 @@ import java.util.Map;
|
|||||||
|
|
||||||
import net.sf.openrocket.aerodynamics.barrowman.FinSetCalc;
|
import net.sf.openrocket.aerodynamics.barrowman.FinSetCalc;
|
||||||
import net.sf.openrocket.aerodynamics.barrowman.RocketComponentCalc;
|
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;
|
||||||
import net.sf.openrocket.rocketcomponent.ExternalComponent.Finish;
|
import net.sf.openrocket.rocketcomponent.ExternalComponent.Finish;
|
||||||
import net.sf.openrocket.rocketcomponent.FinSet;
|
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.RocketComponent;
|
||||||
import net.sf.openrocket.rocketcomponent.SymmetricComponent;
|
import net.sf.openrocket.rocketcomponent.SymmetricComponent;
|
||||||
import net.sf.openrocket.util.Coordinate;
|
import net.sf.openrocket.util.Coordinate;
|
||||||
@ -38,7 +39,7 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
|
|||||||
private double cacheDiameter = -1;
|
private double cacheDiameter = -1;
|
||||||
private double cacheLength = -1;
|
private double cacheLength = -1;
|
||||||
|
|
||||||
|
public boolean debug = false;
|
||||||
|
|
||||||
public BarrowmanCalculator() {
|
public BarrowmanCalculator() {
|
||||||
|
|
||||||
@ -183,33 +184,52 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
|
|||||||
if (!component.isAerodynamic())
|
if (!component.isAerodynamic())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Check for discontinuities
|
// TODO: refactor this code block to a separate method, where it will operate on each stage separately.
|
||||||
if (component instanceof SymmetricComponent) {
|
//
|
||||||
SymmetricComponent sym = (SymmetricComponent) component;
|
// Developer's Note:
|
||||||
// TODO:LOW: Ignores other cluster components (not clusterable)
|
// !! this code assumes all SymmetricComponents are along the centerline
|
||||||
double x = component.toAbsolute(Coordinate.NUL)[0].x;
|
// With the implementation of ParallelStages and Pods, this is no longer true. -Daniel Williams
|
||||||
|
//
|
||||||
// Check for lengthwise discontinuity
|
// // Check for discontinuities
|
||||||
if (x > componentX + 0.0001) {
|
// if (component instanceof SymmetricComponent) {
|
||||||
if (!MathUtil.equals(radius, 0)) {
|
// SymmetricComponent sym = (SymmetricComponent) component;
|
||||||
warnings.add(Warning.DISCONTINUITY);
|
// // TODO:LOW: Ignores other cluster components (not clusterable)
|
||||||
radius = 0;
|
// double x = component.toAbsolute(Coordinate.NUL)[0].x;
|
||||||
}
|
//
|
||||||
}
|
// // Check for lengthwise discontinuity
|
||||||
componentX = component.toAbsolute(new Coordinate(component.getLength()))[0].x;
|
// if (x > componentX + 0.0001) {
|
||||||
|
// if (!MathUtil.equals(radius, 0)) {
|
||||||
// Check for radius discontinuity
|
// warnings.add(Warning.DISCONTINUITY);
|
||||||
if (!MathUtil.equals(sym.getForeRadius(), radius)) {
|
// radius = 0;
|
||||||
warnings.add(Warning.DISCONTINUITY);
|
// }
|
||||||
// TODO: MEDIUM: Apply correction to values to cp and to map
|
// }
|
||||||
}
|
// componentX = component.toAbsolute(new Coordinate(component.getLength()))[0].x;
|
||||||
radius = sym.getAftRadius();
|
//
|
||||||
}
|
// // 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
|
// Call calculation method
|
||||||
forces.zero();
|
forces.zero();
|
||||||
calcMap.get(component).calculateNonaxialForces(conditions, forces, warnings);
|
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;
|
int instanceCount = component.getLocations().length;
|
||||||
Coordinate x_cp_comp = forces.getCP();
|
Coordinate x_cp_comp = forces.getCP();
|
||||||
Coordinate x_cp_weighted = x_cp_comp.setWeight(x_cp_comp.weight * instanceCount);
|
Coordinate x_cp_weighted = x_cp_comp.setWeight(x_cp_comp.weight * instanceCount);
|
||||||
@ -722,5 +742,4 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -114,6 +114,10 @@ public abstract class ComponentAssembly extends RocketComponent {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAxisymmetric(){
|
||||||
|
return !(2 == this.getInstanceCount());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setAxialOffset(final double _pos) {
|
public void setAxialOffset(final double _pos) {
|
||||||
|
@ -3,9 +3,6 @@ package net.sf.openrocket.rocketcomponent;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import net.sf.openrocket.l10n.Translator;
|
import net.sf.openrocket.l10n.Translator;
|
||||||
import net.sf.openrocket.startup.Application;
|
import net.sf.openrocket.startup.Application;
|
||||||
import net.sf.openrocket.util.BugException;
|
import net.sf.openrocket.util.BugException;
|
||||||
|
@ -6,7 +6,7 @@ public interface RingInstanceable extends Instanceable {
|
|||||||
|
|
||||||
public double getRadialOffset();
|
public double getRadialOffset();
|
||||||
|
|
||||||
public void setAngularOffset(final double radius);
|
public void setAngularOffset(final double angle);
|
||||||
|
|
||||||
public void setRadialOffset(final double radius);
|
public void setRadialOffset(final double radius);
|
||||||
|
|
||||||
|
@ -279,6 +279,9 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
|
|||||||
return (Position.AFTER == this.relativePosition);
|
return (Position.AFTER == this.relativePosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isAxisymmetric(){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shift the coordinates in the array corresponding to radial movement. A component
|
* Shift the coordinates in the array corresponding to radial movement. A component
|
||||||
|
@ -1,11 +1,18 @@
|
|||||||
package net.sf.openrocket.aerodynamics;
|
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.ServicesForTesting;
|
||||||
import net.sf.openrocket.motor.MotorInstance;
|
import net.sf.openrocket.motor.MotorInstance;
|
||||||
import net.sf.openrocket.plugin.PluginModule;
|
import net.sf.openrocket.plugin.PluginModule;
|
||||||
import net.sf.openrocket.rocketcomponent.BodyTube;
|
|
||||||
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
|
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
|
||||||
import net.sf.openrocket.rocketcomponent.FlightConfigurationID;
|
import net.sf.openrocket.rocketcomponent.FlightConfigurationID;
|
||||||
import net.sf.openrocket.rocketcomponent.InnerTube;
|
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.MathUtil;
|
||||||
import net.sf.openrocket.util.TestRockets;
|
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 {
|
public class BarrowmanCalculatorTest {
|
||||||
protected final double EPSILON = MathUtil.EPSILON;
|
protected final double EPSILON = MathUtil.EPSILON;
|
||||||
|
|
||||||
@ -86,6 +86,26 @@ public class BarrowmanCalculatorTest {
|
|||||||
fail("Not yet implemented");
|
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
|
@Test
|
||||||
public void testGetWorstCP() {
|
public void testGetWorstCP() {
|
||||||
fail("Not yet implemented");
|
fail("Not yet implemented");
|
||||||
|
@ -421,8 +421,8 @@ public class RocketFigure extends AbstractScaleFigure {
|
|||||||
// facade for the recursive function below
|
// facade for the recursive function below
|
||||||
private void getShapes(ArrayList<RocketComponentShape> allShapes, FlightConfiguration configuration){
|
private void getShapes(ArrayList<RocketComponentShape> allShapes, FlightConfiguration configuration){
|
||||||
for( AxialStage stage : configuration.getActiveStages()){
|
for( AxialStage stage : configuration.getActiveStages()){
|
||||||
int stageNumber = stage.getStageNumber();
|
|
||||||
// for debug...
|
// for debug...
|
||||||
|
//int stageNumber = stage.getStageNumber();
|
||||||
//String activeString = ( configuration.isStageActive(stageNumber) ? "active" : "inactive");
|
//String activeString = ( configuration.isStageActive(stageNumber) ? "active" : "inactive");
|
||||||
|
|
||||||
getShapeTree( allShapes, stage, Coordinate.ZERO);
|
getShapeTree( allShapes, stage, Coordinate.ZERO);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user