- Implemented a DampingMoment simulation listener example
- Added ability for simulation listeners to reserve their own data types. To support this: -- All data types can now be found from just the OpenRocketDocument (reduces some code duplication also). -- Custom expressions rebuilt after loading from file in case they use a listeners reserved type - Fixed (possibly unrelated) issue where datatypes would be deleted and re-made each step if a customexpression used a range or index subexpression
This commit is contained in:
parent
3fea838fab
commit
c9d04f5e0a
@ -1,8 +1,12 @@
|
||||
package net.sf.openrocket.document;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import net.sf.openrocket.document.events.DocumentChangeEvent;
|
||||
import net.sf.openrocket.document.events.DocumentChangeListener;
|
||||
@ -13,7 +17,10 @@ import net.sf.openrocket.rocketcomponent.ComponentChangeEvent;
|
||||
import net.sf.openrocket.rocketcomponent.ComponentChangeListener;
|
||||
import net.sf.openrocket.rocketcomponent.Configuration;
|
||||
import net.sf.openrocket.rocketcomponent.Rocket;
|
||||
import net.sf.openrocket.simulation.FlightDataType;
|
||||
import net.sf.openrocket.simulation.customexpression.CustomExpression;
|
||||
import net.sf.openrocket.simulation.exception.SimulationListenerException;
|
||||
import net.sf.openrocket.simulation.listeners.SimulationListener;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
import net.sf.openrocket.util.ArrayList;
|
||||
|
||||
@ -121,6 +128,43 @@ public class OpenRocketDocument implements ComponentChangeListener {
|
||||
return customExpressions;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a set of all the flight data types defined or available in any way in the rocket document
|
||||
*/
|
||||
public Set<FlightDataType> getFlightDataTypes(){
|
||||
Set<FlightDataType> allTypes = new LinkedHashSet<FlightDataType>();
|
||||
|
||||
// built in
|
||||
Collections.addAll(allTypes, FlightDataType.ALL_TYPES);
|
||||
|
||||
// custom expressions
|
||||
for (CustomExpression exp : customExpressions){
|
||||
allTypes.add(exp.getType());
|
||||
}
|
||||
|
||||
// simulation listeners
|
||||
for (Simulation sim : simulations){
|
||||
for (String className : sim.getSimulationListeners()) {
|
||||
SimulationListener l = null;
|
||||
try {
|
||||
Class<?> c = Class.forName(className);
|
||||
l = (SimulationListener) c.newInstance();
|
||||
|
||||
Collections.addAll(allTypes, l.getFlightDataTypes());
|
||||
//System.out.println("This document has expression datatype from "+l.getName());
|
||||
} catch (Exception e) {
|
||||
log.error("Could not instantiate listener: " + className);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// imported data
|
||||
/// not implemented yet
|
||||
|
||||
|
||||
return allTypes;
|
||||
}
|
||||
|
||||
|
||||
public Rocket getRocket() {
|
||||
return rocket;
|
||||
|
||||
@ -704,8 +704,6 @@ class OpenRocketContentHandler extends AbstractElementHandler {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
class DatatypeHandler extends AbstractElementHandler {
|
||||
private final DocumentLoadingContext context;
|
||||
private final OpenRocketContentHandler contentHandler;
|
||||
@ -1288,10 +1286,14 @@ class SimulationsHandler extends AbstractElementHandler {
|
||||
public void closeElement(String element, HashMap<String, String> attributes,
|
||||
String content, WarningSet warnings) throws SAXException {
|
||||
attributes.remove("status");
|
||||
|
||||
//Finished loading. Rebuilding custom expressions in case something has changed such as listener variable come available.
|
||||
for (CustomExpression exp : doc.getCustomExpressions()){
|
||||
exp.setExpression(exp.getExpressionString());
|
||||
}
|
||||
|
||||
super.closeElement(element, attributes, content, warnings);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
class SingleSimulationHandler extends AbstractElementHandler {
|
||||
|
||||
@ -269,8 +269,8 @@ public class FlightDataType implements Comparable<FlightDataType> {
|
||||
if (type != null) {
|
||||
// found it from symbol
|
||||
|
||||
// if name was not give (empty string), can use the one we found name
|
||||
if ( s.equals("") || s == null ){
|
||||
// if name was not given (empty string), can use the one we found
|
||||
if ( s == null || s.isEmpty()){
|
||||
s = type.getName();
|
||||
}
|
||||
if ( u == null ){
|
||||
@ -279,14 +279,19 @@ public class FlightDataType implements Comparable<FlightDataType> {
|
||||
|
||||
// if something has changed, then we need to remove the old one
|
||||
// otherwise, just return what we found
|
||||
if ( !u.equals(type.getUnitGroup()) ||
|
||||
!s.equals(type.getName())
|
||||
)
|
||||
if ( !u.equals(type.getUnitGroup()) )
|
||||
{
|
||||
oldPriority = type.priority;
|
||||
|
||||
EXISTING_TYPES.remove(type);
|
||||
log.info("Something changed with the type "+type.getName()+", removed old version.");
|
||||
log.info("Unitgroup of type "+type.getName() +
|
||||
", has changed from "+type.getUnitGroup().toString() +
|
||||
" to "+u.toString() +
|
||||
". Removing old version.");
|
||||
}
|
||||
else if (!s.equals(type.getName())) {
|
||||
oldPriority = type.priority;
|
||||
EXISTING_TYPES.remove(type);
|
||||
log.info("Name of type "+type.getName()+", has changed to "+s+". Removing old version.");
|
||||
}
|
||||
else{
|
||||
return type;
|
||||
|
||||
@ -34,11 +34,12 @@ public class CustomExpression implements Cloneable{
|
||||
private List<CustomExpression> subExpressions = new ArrayList<CustomExpression>();
|
||||
|
||||
public CustomExpression(OpenRocketDocument doc){
|
||||
this.doc = doc;
|
||||
|
||||
setName("");
|
||||
setSymbol("");
|
||||
setUnit("");
|
||||
setExpression("");
|
||||
this.doc = doc;
|
||||
}
|
||||
|
||||
public CustomExpression(OpenRocketDocument doc,
|
||||
@ -171,6 +172,7 @@ public class CustomExpression implements Cloneable{
|
||||
// get a list of all the names of all the available variables
|
||||
protected ArrayList<String> getAllNames(){
|
||||
ArrayList<String> names = new ArrayList<String>();
|
||||
/*
|
||||
for (FlightDataType type : FlightDataType.ALL_TYPES)
|
||||
names.add(type.getName());
|
||||
|
||||
@ -181,12 +183,22 @@ public class CustomExpression implements Cloneable{
|
||||
names.add(exp.getName());
|
||||
}
|
||||
}
|
||||
*/
|
||||
for (FlightDataType type : doc.getFlightDataTypes()){
|
||||
String symb = type.getName();
|
||||
if (name == null) continue;
|
||||
|
||||
if (!name.equals( this.getName() )){
|
||||
names.add(symb);
|
||||
}
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
// get a list of all the symbols of the available variables ignoring this one
|
||||
protected ArrayList<String> getAllSymbols(){
|
||||
ArrayList<String> symbols = new ArrayList<String>();
|
||||
/*
|
||||
for (FlightDataType type : FlightDataType.ALL_TYPES)
|
||||
symbols.add(type.getSymbol());
|
||||
|
||||
@ -196,6 +208,14 @@ public class CustomExpression implements Cloneable{
|
||||
symbols.add(exp.getSymbol());
|
||||
}
|
||||
}
|
||||
*/
|
||||
for (FlightDataType type : doc.getFlightDataTypes()){
|
||||
String symb = type.getSymbol();
|
||||
if (!symb.equals( this.getSymbol() )){
|
||||
symbols.add(symb);
|
||||
}
|
||||
}
|
||||
|
||||
return symbols;
|
||||
}
|
||||
|
||||
@ -305,6 +325,7 @@ public class CustomExpression implements Cloneable{
|
||||
|
||||
//// Define the available variables as empty
|
||||
// The built in data types
|
||||
/*
|
||||
for (FlightDataType type : FlightDataType.ALL_TYPES){
|
||||
builder.withVariable(new Variable(type.getSymbol()));
|
||||
}
|
||||
@ -312,12 +333,16 @@ public class CustomExpression implements Cloneable{
|
||||
for (String symb : getAllSymbols()){
|
||||
builder.withVariable(new Variable(symb));
|
||||
}
|
||||
*/
|
||||
for (FlightDataType type : doc.getFlightDataTypes()){
|
||||
builder.withVariable(new Variable(type.getSymbol()));
|
||||
}
|
||||
|
||||
// Try to build
|
||||
try {
|
||||
builder.build();
|
||||
} catch (Exception e) {
|
||||
log.user("Custom expression invalid : " + e.toString());
|
||||
log.user("Custom expression " + this.toString() + " invalid : " + e.toString());
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -341,14 +366,14 @@ public class CustomExpression implements Cloneable{
|
||||
* Builds a specified expression, log any errors and returns null in case of error.
|
||||
*/
|
||||
protected Calculable buildExpression(ExpressionBuilder b){
|
||||
Calculable calc;
|
||||
Calculable calc = null;
|
||||
try {
|
||||
calc = b.build();
|
||||
} catch (UnknownFunctionException e1) {
|
||||
log.user("Unknown function. Could not build custom expression "+name);
|
||||
log.user("Unknown function. Could not build custom expression "+this.toString());
|
||||
return null;
|
||||
} catch (UnparsableExpressionException e1) {
|
||||
log.user("Unparsable expression. Could not build custom expression "+name+". "+e1.getMessage());
|
||||
log.user("Unparsable expression. Could not build custom expression "+this.toString()+". "+e1.getMessage());
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -396,10 +421,13 @@ public class CustomExpression implements Cloneable{
|
||||
*/
|
||||
public FlightDataType getType(){
|
||||
|
||||
|
||||
UnitGroup ug = UnitGroup.SIUNITS.get(unit);
|
||||
if ( ug == null ){
|
||||
log.debug("SI unit not found for "+unit+" in expression "+toString()+". Making a new fixed unit.");
|
||||
ug = new FixedUnitGroup(unit);
|
||||
}
|
||||
//UnitGroup ug = new FixedUnitGroup(unit);
|
||||
|
||||
FlightDataType type = FlightDataType.getType(name, symbol, ug);
|
||||
|
||||
@ -442,7 +470,7 @@ public class CustomExpression implements Cloneable{
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
return "Custom expression : "+this.name.toString()+ " " + this.expression.toString();
|
||||
return "[Expression name="+this.name.toString()+ " expression=" + this.expression+" unit="+this.unit+"]";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -3,13 +3,16 @@ package net.sf.openrocket.simulation.customexpression;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import net.sf.openrocket.logging.LogHelper;
|
||||
import net.sf.openrocket.simulation.FlightDataBranch;
|
||||
import net.sf.openrocket.simulation.SimulationStatus;
|
||||
import net.sf.openrocket.simulation.exception.SimulationException;
|
||||
import net.sf.openrocket.simulation.listeners.AbstractSimulationListener;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
|
||||
public class CustomExpressionSimulationListener extends AbstractSimulationListener {
|
||||
|
||||
private static final LogHelper log = Application.getLogger();
|
||||
private final List<CustomExpression> expressions;
|
||||
|
||||
public CustomExpressionSimulationListener(List<CustomExpression> expressions) {
|
||||
@ -25,10 +28,17 @@ public class CustomExpressionSimulationListener extends AbstractSimulationListen
|
||||
// Calculate values for custom expressions
|
||||
FlightDataBranch data = status.getFlightData();
|
||||
for (CustomExpression expression : expressions ) {
|
||||
data.setValue(expression.getType(), expression.evaluateDouble(status));
|
||||
double value = expression.evaluateDouble(status);
|
||||
//log.debug("Setting value of custom expression "+expression.toString()+" = "+value);
|
||||
data.setValue(expression.getType(), value);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSystemListener(){
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -23,7 +23,6 @@ public class IndexExpression extends CustomExpression {
|
||||
setExpression(indexText);
|
||||
this.setName("");
|
||||
this.setSymbol(typeText);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -35,7 +34,10 @@ public class IndexExpression extends CustomExpression {
|
||||
}
|
||||
|
||||
// From the given datatype, get the time and function values and make an interpolator
|
||||
FlightDataType type = getType();
|
||||
|
||||
//Note: must get in a way that flight data system will figure out units. Otherwise there will be a type conflict when we get the new data.
|
||||
FlightDataType type = FlightDataType.getType(null, getSymbol(), null);
|
||||
|
||||
List<Double> data = status.getFlightData().get(type);
|
||||
List<Double> time = status.getFlightData().get(FlightDataType.TYPE_TIME);
|
||||
LinearInterpolator interp = new LinearInterpolator(time, data);
|
||||
|
||||
@ -40,7 +40,6 @@ public class RangeExpression extends CustomExpression {
|
||||
this.expression = variableType+startTime+endTime; // this is used just for generating the hash
|
||||
|
||||
log.info("New range expression, "+startTime + " to "+endTime);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@ -73,7 +72,9 @@ public class RangeExpression extends CustomExpression {
|
||||
}
|
||||
|
||||
// From the given datatype, get the time and function values and make an interpolator
|
||||
FlightDataType type = getType();
|
||||
|
||||
//Note: must get in a way that flight data system will figure out units. Otherwise there will be a type conflict when we get the new data.
|
||||
FlightDataType type = FlightDataType.getType(null, getSymbol(), null);
|
||||
|
||||
List<Double> data = status.getFlightData().get(type);
|
||||
List<Double> time = status.getFlightData().get(FlightDataType.TYPE_TIME);
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
package net.sf.openrocket.simulation.listeners;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import net.sf.openrocket.aerodynamics.AerodynamicForces;
|
||||
import net.sf.openrocket.aerodynamics.FlightConditions;
|
||||
import net.sf.openrocket.models.atmosphere.AtmosphericConditions;
|
||||
@ -8,6 +10,7 @@ import net.sf.openrocket.motor.MotorInstance;
|
||||
import net.sf.openrocket.rocketcomponent.MotorMount;
|
||||
import net.sf.openrocket.rocketcomponent.RecoveryDevice;
|
||||
import net.sf.openrocket.simulation.AccelerationData;
|
||||
import net.sf.openrocket.simulation.FlightDataType;
|
||||
import net.sf.openrocket.simulation.FlightEvent;
|
||||
import net.sf.openrocket.simulation.MassData;
|
||||
import net.sf.openrocket.simulation.SimulationStatus;
|
||||
@ -67,7 +70,13 @@ public class AbstractSimulationListener implements SimulationListener, Simulatio
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return an array of any flight data types this listener creates.
|
||||
*/
|
||||
@Override
|
||||
public FlightDataType[] getFlightDataTypes(){
|
||||
return new FlightDataType[] {};
|
||||
}
|
||||
|
||||
|
||||
//// SimulationEventListener ////
|
||||
|
||||
@ -1,9 +1,12 @@
|
||||
package net.sf.openrocket.simulation.listeners;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import net.sf.openrocket.aerodynamics.AerodynamicForces;
|
||||
import net.sf.openrocket.aerodynamics.FlightConditions;
|
||||
import net.sf.openrocket.models.atmosphere.AtmosphericConditions;
|
||||
import net.sf.openrocket.simulation.AccelerationData;
|
||||
import net.sf.openrocket.simulation.FlightDataType;
|
||||
import net.sf.openrocket.simulation.MassData;
|
||||
import net.sf.openrocket.simulation.SimulationStatus;
|
||||
import net.sf.openrocket.simulation.exception.SimulationException;
|
||||
@ -64,4 +67,5 @@ public interface SimulationComputationListener extends SimulationListener {
|
||||
|
||||
public double postSimpleThrustCalculation(SimulationStatus status, double thrust) throws SimulationException;
|
||||
|
||||
public FlightDataType[] getFlightDataTypes();
|
||||
}
|
||||
|
||||
@ -1,9 +1,12 @@
|
||||
package net.sf.openrocket.simulation.listeners;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import net.sf.openrocket.motor.MotorId;
|
||||
import net.sf.openrocket.motor.MotorInstance;
|
||||
import net.sf.openrocket.rocketcomponent.MotorMount;
|
||||
import net.sf.openrocket.rocketcomponent.RecoveryDevice;
|
||||
import net.sf.openrocket.simulation.FlightDataType;
|
||||
import net.sf.openrocket.simulation.FlightEvent;
|
||||
import net.sf.openrocket.simulation.SimulationStatus;
|
||||
import net.sf.openrocket.simulation.exception.SimulationException;
|
||||
@ -56,6 +59,10 @@ public interface SimulationEventListener {
|
||||
*/
|
||||
public boolean recoveryDeviceDeployment(SimulationStatus status, RecoveryDevice recoveryDevice)
|
||||
throws SimulationException;
|
||||
|
||||
|
||||
|
||||
public FlightDataType[] getFlightDataTypes();
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -1,5 +1,8 @@
|
||||
package net.sf.openrocket.simulation.listeners;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import net.sf.openrocket.simulation.FlightDataType;
|
||||
import net.sf.openrocket.simulation.SimulationStatus;
|
||||
import net.sf.openrocket.simulation.exception.SimulationException;
|
||||
|
||||
@ -76,4 +79,11 @@ public interface SimulationListener {
|
||||
*/
|
||||
public boolean isSystemListener();
|
||||
|
||||
|
||||
/**
|
||||
* Return a list of any flight data types this listener creates.
|
||||
*/
|
||||
public FlightDataType[] getFlightDataTypes();
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,129 @@
|
||||
package net.sf.openrocket.simulation.listeners.example;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import net.sf.openrocket.aerodynamics.AerodynamicCalculator;
|
||||
import net.sf.openrocket.aerodynamics.AerodynamicForces;
|
||||
import net.sf.openrocket.aerodynamics.FlightConditions;
|
||||
import net.sf.openrocket.motor.MotorId;
|
||||
import net.sf.openrocket.motor.MotorInstance;
|
||||
import net.sf.openrocket.motor.MotorInstanceConfiguration;
|
||||
import net.sf.openrocket.rocketcomponent.MotorMount;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
import net.sf.openrocket.simulation.FlightDataBranch;
|
||||
import net.sf.openrocket.simulation.FlightDataType;
|
||||
import net.sf.openrocket.simulation.SimulationStatus;
|
||||
import net.sf.openrocket.simulation.exception.SimulationException;
|
||||
import net.sf.openrocket.simulation.listeners.AbstractSimulationListener;
|
||||
import net.sf.openrocket.unit.UnitGroup;
|
||||
import net.sf.openrocket.util.ArrayList;
|
||||
import net.sf.openrocket.util.Coordinate;
|
||||
import net.sf.openrocket.util.PolyInterpolator;
|
||||
|
||||
public class DampingMoment extends AbstractSimulationListener {
|
||||
|
||||
private static final FlightDataType type = FlightDataType.getType("Damping moment coefficient", "Cdm", UnitGroup.UNITS_COEFFICIENT);
|
||||
private static final FlightDataType[] typeList = {type};
|
||||
|
||||
public String getName(){
|
||||
return "Damping moment listener";
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of any flight data types this listener creates.
|
||||
*/
|
||||
public FlightDataType[] getFlightDataTypes(){
|
||||
return typeList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FlightConditions postFlightConditions(SimulationStatus status, FlightConditions flightConditions) throws SimulationException {
|
||||
|
||||
// Save it as a flightdatatype
|
||||
|
||||
//status.getFlightData().setValue(type, aerodynamicPart + propulsivePart);
|
||||
status.getFlightData().setValue(type, calculate(status, flightConditions));
|
||||
|
||||
return flightConditions;
|
||||
}
|
||||
|
||||
private double calculate(SimulationStatus status, FlightConditions flightConditions){
|
||||
|
||||
// Work out the propulsive/jet damping part of the moment.
|
||||
|
||||
// dm/dt = (thrust - ma)/v
|
||||
FlightDataBranch data = status.getFlightData();
|
||||
|
||||
List<Double> mpAll = data.get(FlightDataType.TYPE_PROPELLANT_MASS);
|
||||
List<Double> time = data.get(FlightDataType.TYPE_TIME);
|
||||
if (mpAll == null || time == null){
|
||||
return Double.NaN;
|
||||
}
|
||||
|
||||
int len = mpAll.size();
|
||||
|
||||
// This isn't as accurate as I would like
|
||||
double mdot=Double.NaN;
|
||||
if (len > 2){
|
||||
// Using polynomial interpolator for derivative. Doesn't help much
|
||||
//double[] x = { time.get(len-5), time.get(len-4), time.get(len-3), time.get(len-2), time.get(len-1) };
|
||||
//double[] y = { mpAll.get(len-5), mpAll.get(len-4), mpAll.get(len-3), mpAll.get(len-2), mpAll.get(len-1) };
|
||||
//PolyInterpolator interp = new PolyInterpolator(x);
|
||||
//double[] coeff = interp.interpolator(y);
|
||||
//double dt = .01;
|
||||
//mdot = (interp.eval(x[4], coeff) - interp.eval(x[4]-dt, coeff))/dt;
|
||||
|
||||
mdot = (mpAll.get(len-1) - mpAll.get(len-2)) / (time.get(len-1) - time.get(len-2));
|
||||
}
|
||||
|
||||
double cg = data.getLast(FlightDataType.TYPE_CG_LOCATION);
|
||||
|
||||
// find the maximum distance from nose to nozzle.
|
||||
double nozzleDistance = 0;
|
||||
for (MotorId id: status.getMotorConfiguration().getMotorIDs()){
|
||||
MotorInstanceConfiguration config = status.getMotorConfiguration();
|
||||
Coordinate position = config.getMotorPosition(id);
|
||||
|
||||
double x = position.x + config.getMotorInstance(id).getParentMotor().getLength();
|
||||
if (x > nozzleDistance){
|
||||
nozzleDistance = x;
|
||||
}
|
||||
}
|
||||
|
||||
// now can get the propulsive part
|
||||
double propulsivePart = mdot * Math.pow(nozzleDistance - cg, 2);
|
||||
|
||||
// Work out the aerodynamic part of the moment.
|
||||
double aerodynamicPart = 0;
|
||||
|
||||
AerodynamicCalculator aerocalc = status.getSimulationConditions().getAerodynamicCalculator();
|
||||
|
||||
// Must go through each component ...
|
||||
Map<RocketComponent, AerodynamicForces> forces = aerocalc.getForceAnalysis(status.getConfiguration(), flightConditions, null);
|
||||
for (Map.Entry<RocketComponent, AerodynamicForces> entry : forces.entrySet()){
|
||||
|
||||
RocketComponent comp = entry.getKey();
|
||||
|
||||
if (!comp.isAerodynamic()) continue;
|
||||
|
||||
//System.out.println(comp.toString());
|
||||
|
||||
double CNa = entry.getValue().getCNa(); //?
|
||||
double Cp = entry.getValue().getCP().length();
|
||||
double z = comp.getPositionValue(); //?
|
||||
|
||||
aerodynamicPart += CNa*Math.pow(z-Cp, 2);
|
||||
}
|
||||
|
||||
double v = flightConditions.getVelocity();
|
||||
double rho = flightConditions.getAtmosphericConditions().getDensity();
|
||||
double ar = flightConditions.getRefArea();
|
||||
|
||||
aerodynamicPart = aerodynamicPart * .5 * rho * v * ar;
|
||||
|
||||
return aerodynamicPart + propulsivePart;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user