Vivian Meazza:
I have added <Cd> and <weight> to the input parameters in the submodels.xml script. Raw data may be used, thus avoiding the need to guestimate <eda>. Eda remains, but should now be used to enter the proper cross-sectional area.
This commit is contained in:
parent
56f6d3b800
commit
26e6b0edcb
8 changed files with 96 additions and 49 deletions
|
@ -27,16 +27,17 @@
|
|||
#include "AIBallistic.hxx"
|
||||
|
||||
|
||||
|
||||
FGAIBallistic::FGAIBallistic(FGAIManager* mgr) {
|
||||
manager = mgr;
|
||||
_type_str = "ballistic";
|
||||
_otype = otBallistic;
|
||||
drag_area = 0.007;
|
||||
life_timer = 0.0;
|
||||
gravity = 32;
|
||||
// buoyancy = 64;
|
||||
gravity = 32;
|
||||
// buoyancy = 64;
|
||||
no_roll = false;
|
||||
}
|
||||
}
|
||||
|
||||
FGAIBallistic::~FGAIBallistic() {
|
||||
}
|
||||
|
@ -111,8 +112,16 @@ void FGAIBallistic::setWind_from_north(double fps) {
|
|||
void FGAIBallistic::setWind(bool val) {
|
||||
wind = val;
|
||||
}
|
||||
void FGAIBallistic::Run(double dt) {
|
||||
|
||||
void FGAIBallistic::setCd(double c) {
|
||||
Cd = c;
|
||||
}
|
||||
|
||||
void FGAIBallistic::setWeight(double w) {
|
||||
weight = w;
|
||||
}
|
||||
|
||||
void FGAIBallistic::Run(double dt) {
|
||||
life_timer += dt;
|
||||
if (life_timer > life) setDie(true);
|
||||
|
||||
|
@ -120,12 +129,22 @@ void FGAIBallistic::Run(double dt) {
|
|||
double speed_east_deg_sec;
|
||||
double wind_speed_from_north_deg_sec;
|
||||
double wind_speed_from_east_deg_sec;
|
||||
double mass;
|
||||
|
||||
// the two drag calculations below assume sea-level density,
|
||||
// mass of 0.03 slugs, drag coeff of 0.295
|
||||
// adjust speed due to drag
|
||||
speed -= 0.0116918 * drag_area * speed * speed * dt;
|
||||
// the drag calculations below assume sea-level density,
|
||||
// rho = 0.023780 slugs/ft3
|
||||
// calculate mass
|
||||
mass = weight * lbs_to_slugs;
|
||||
|
||||
// drag = Cd * 0.5 * rho * speed * speed * drag_area;
|
||||
// acceleration = drag/mass;
|
||||
// adjust speed by drag
|
||||
speed -= (Cd * 0.5 * rho * speed * speed * drag_area/mass) * dt;
|
||||
|
||||
// don't let speed become negative
|
||||
if ( speed < 0.0 ) speed = 0.0;
|
||||
|
||||
// calculate vertical and horizontal speed components
|
||||
vs = sin( pitch * SG_DEGREES_TO_RADIANS ) * speed;
|
||||
hs = cos( pitch * SG_DEGREES_TO_RADIANS ) * speed;
|
||||
|
||||
|
@ -133,28 +152,21 @@ void FGAIBallistic::Run(double dt) {
|
|||
speed_north_deg_sec = cos(hdg / SG_RADIANS_TO_DEGREES) * hs / ft_per_deg_lat;
|
||||
speed_east_deg_sec = sin(hdg / SG_RADIANS_TO_DEGREES) * hs / ft_per_deg_lon;
|
||||
|
||||
// convert wind speed (fps) to degrees per second
|
||||
|
||||
// if wind not required, set to zero
|
||||
if (!wind){
|
||||
wind_from_north = 0;
|
||||
wind_from_east = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// convert wind speed (fps) to degrees per second
|
||||
wind_speed_from_north_deg_sec = wind_from_north / ft_per_deg_lat;
|
||||
wind_speed_from_east_deg_sec = wind_from_east / ft_per_deg_lon;
|
||||
|
||||
|
||||
// set new position
|
||||
// pos.setlat( pos.lat() + (speed_north_deg_sec * dt) );
|
||||
// pos.setlon( pos.lon() + (speed_east_deg_sec * dt) );
|
||||
|
||||
|
||||
// set new position
|
||||
|
||||
pos.setlat( pos.lat() + (speed_north_deg_sec - wind_speed_from_north_deg_sec) * dt );
|
||||
pos.setlon( pos.lon() + (speed_east_deg_sec - wind_speed_from_east_deg_sec) * dt );
|
||||
|
||||
// adjust vertical speed for acceleration of gravity
|
||||
// adjust vertical speed for acceleration of gravity and buoyancy
|
||||
vs -= (gravity - buoyancy) * dt;
|
||||
|
||||
// adjust altitude (feet)
|
||||
|
@ -170,10 +182,10 @@ void FGAIBallistic::Run(double dt) {
|
|||
// set destruction flag if altitude less than sea level -1000
|
||||
if (altitude < -1000.0) setDie(true);
|
||||
|
||||
}
|
||||
} // end Run
|
||||
|
||||
double FGAIBallistic::_getTime() const {
|
||||
return life_timer;
|
||||
}
|
||||
|
||||
// end AIBallistic
|
||||
// end AIBallistic
|
||||
|
|
|
@ -25,12 +25,12 @@
|
|||
|
||||
|
||||
class FGAIBallistic : public FGAIBase {
|
||||
|
||||
|
||||
public:
|
||||
|
||||
|
||||
FGAIBallistic(FGAIManager* mgr);
|
||||
~FGAIBallistic();
|
||||
|
||||
|
||||
bool init();
|
||||
virtual void bind();
|
||||
virtual void unbind();
|
||||
|
@ -38,7 +38,7 @@ public:
|
|||
|
||||
void setAzimuth( double az );
|
||||
void setElevation( double el );
|
||||
void setRoll( double rl );
|
||||
void setRoll( double rl );
|
||||
void setStabilization( bool val );
|
||||
void setDragArea( double a );
|
||||
void setLife( double seconds );
|
||||
|
@ -46,14 +46,16 @@ public:
|
|||
void setWind_from_east( double fps );
|
||||
void setWind_from_north( double fps );
|
||||
void setWind( bool val );
|
||||
void setCd( double c );
|
||||
void setWeight( double w );
|
||||
|
||||
double _getTime() const;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
double azimuth; // degrees true
|
||||
double elevation; // degrees
|
||||
double rotation; // degrees
|
||||
double rotation; // degrees
|
||||
double hs; // horizontal speed (fps)
|
||||
bool aero_stabilized; // if true, object will point where it's going
|
||||
double drag_area; // equivalent drag area in ft2
|
||||
|
@ -63,7 +65,9 @@ private:
|
|||
double wind_from_east; // fps
|
||||
double wind_from_north; // fps
|
||||
bool wind; // if true, local wind will be applied to object
|
||||
|
||||
double Cd; // drag coefficient
|
||||
double weight; // lbs
|
||||
|
||||
void Run(double dt);
|
||||
};
|
||||
|
||||
|
|
|
@ -43,6 +43,11 @@
|
|||
#include "AIBase.hxx"
|
||||
#include "AIManager.hxx"
|
||||
|
||||
|
||||
const double FGAIBase::rho = 0.023780; // sea level air density slugs/ft3
|
||||
const double FGAIBase::lbs_to_slugs = 0.031080950172; //conversion factor
|
||||
|
||||
|
||||
FGAIBase::FGAIBase()
|
||||
: fp( NULL ),
|
||||
model( NULL ),
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// FGAIBase - abstract base class for AI objects
|
||||
// FGAIBase.hxx - abstract base class for AI objects
|
||||
// Written by David Culp, started Nov 2003, based on
|
||||
// David Luff's FGAIEntity class.
|
||||
// - davidculp2@comcast.net
|
||||
|
@ -62,7 +62,9 @@ typedef struct {
|
|||
double buoyancy; // acceleration in ft per sec2
|
||||
double wind_from_east; // in feet per second
|
||||
double wind_from_north; // in feet per second
|
||||
bool wind;
|
||||
double cd; // coefficient of drag
|
||||
bool wind; // if true, model reacts to parent wind
|
||||
double weight; // in lbs
|
||||
} FGAIModelEntity;
|
||||
|
||||
|
||||
|
@ -177,6 +179,9 @@ public:
|
|||
double _getY_shift() const;
|
||||
double _getRotation() const;
|
||||
|
||||
static const double rho;
|
||||
static const double lbs_to_slugs;
|
||||
|
||||
int _getID() const;
|
||||
|
||||
inline double _getRange() { return range; };
|
||||
|
|
|
@ -203,6 +203,8 @@ FGAIManager::createBallistic( FGAIModelEntity *entity ) {
|
|||
ai_ballistic->setWind_from_north(entity->wind_from_north);
|
||||
ai_ballistic->setWind(entity->wind);
|
||||
ai_ballistic->setRoll(entity->roll);
|
||||
ai_ballistic->setCd(entity->cd);
|
||||
ai_ballistic->setWeight(entity->weight);
|
||||
ai_ballistic->init();
|
||||
ai_ballistic->bind();
|
||||
return ai_ballistic;
|
||||
|
@ -316,3 +318,4 @@ void FGAIManager::processScenario( string filename ) {
|
|||
delete s;
|
||||
}
|
||||
|
||||
//end AIManager.cxx
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// FGAIScenario - class for loading an AI scenario
|
||||
// FGAIScenario.cxx - class for loading an AI scenario
|
||||
// Written by David Culp, started May 2004
|
||||
// - davidculp2@comcast.net
|
||||
//
|
||||
|
@ -78,6 +78,8 @@ FGAIScenario::FGAIScenario(string filename)
|
|||
en->wind_from_east = entry_node->getDoubleValue("wind_from_east", 0);
|
||||
en->wind_from_north = entry_node->getDoubleValue("wind_from_north", 0);
|
||||
en->wind = entry_node->getBoolValue("wind", false);
|
||||
en->cd = entry_node->getDoubleValue ("cd", 0.029);
|
||||
en->weight = entry_node->getDoubleValue ("weight", 0.030);
|
||||
en->fp = NULL;
|
||||
}
|
||||
|
||||
|
@ -108,4 +110,4 @@ int FGAIScenario::nEntries( void )
|
|||
return entries.size();
|
||||
}
|
||||
|
||||
|
||||
// end scenario.cxx
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
#include <AIModel/AIManager.hxx>
|
||||
|
||||
|
||||
const double SubmodelSystem::lbs_to_slugs = 0.031080950172;
|
||||
|
||||
SubmodelSystem::SubmodelSystem ()
|
||||
{
|
||||
|
||||
|
@ -52,8 +54,8 @@ SubmodelSystem::init ()
|
|||
|
||||
_user_speed_down_fps_node = fgGetNode("/velocities/speed-down-fps",true);
|
||||
_user_speed_east_fps_node = fgGetNode("/velocities/speed-east-fps",true);
|
||||
_user_speed_north_fps_node = fgGetNode("/velocities/speed-north-fps",true);
|
||||
|
||||
_user_speed_north_fps_node = fgGetNode("/velocities/speed-north-fps",true);
|
||||
|
||||
ai = (FGAIManager*)globals->get_subsystem("ai_model");
|
||||
|
||||
|
||||
|
@ -124,6 +126,8 @@ SubmodelSystem::release (submodel* sm, double dt)
|
|||
entity.wind_from_east = IC.wind_from_east;
|
||||
entity.wind_from_north = IC.wind_from_north;
|
||||
entity.wind = sm->wind;
|
||||
entity.cd = sm->cd;
|
||||
entity.weight = sm->weight;
|
||||
ai->createBallistic( &entity );
|
||||
|
||||
if (sm->count > 0) (sm->count)--;
|
||||
|
@ -161,7 +165,7 @@ SubmodelSystem::load ()
|
|||
sm->trigger = fgGetNode(entry_node->getStringValue("trigger", "none"), true);
|
||||
sm->name = entry_node->getStringValue("name", "none_defined");
|
||||
sm->model = entry_node->getStringValue("model", "Models/Geometry/rocket.ac");
|
||||
sm->speed = entry_node->getDoubleValue("speed", 0.0);
|
||||
sm->speed = entry_node->getDoubleValue("speed", 2329.4 );
|
||||
sm->repeat = entry_node->getBoolValue ("repeat", false);
|
||||
sm->delay = entry_node->getDoubleValue("delay", 0.25);
|
||||
sm->count = entry_node->getIntValue ("count", 1);
|
||||
|
@ -171,11 +175,13 @@ SubmodelSystem::load ()
|
|||
sm->z_offset = entry_node->getDoubleValue("z-offset", 0.0);
|
||||
sm->yaw_offset = entry_node->getDoubleValue("yaw-offset", 0.0);
|
||||
sm->pitch_offset = entry_node->getDoubleValue("pitch-offset", 0.0);
|
||||
sm->drag_area = entry_node->getDoubleValue("eda", 0.007);
|
||||
sm->drag_area = entry_node->getDoubleValue("eda", 0.034);
|
||||
sm->life = entry_node->getDoubleValue("life", 900.0);
|
||||
sm->buoyancy = entry_node->getDoubleValue("buoyancy", 0);
|
||||
sm->wind = entry_node->getBoolValue ("wind", false);
|
||||
sm->first_time = false;
|
||||
sm->cd = entry_node->getDoubleValue("cd", 0.295);
|
||||
sm->weight = entry_node->getDoubleValue("weight", 0.25);
|
||||
|
||||
sm->trigger->setBoolValue(false);
|
||||
sm->timer = sm->delay;
|
||||
|
@ -198,7 +204,7 @@ SubmodelSystem::transform( submodel* sm)
|
|||
// get initial conditions
|
||||
|
||||
IC.lat = _user_lat_node->getDoubleValue();
|
||||
IC.lon = _user_lon_node->getDoubleValue();
|
||||
IC.lon = _user_lon_node->getDoubleValue();
|
||||
IC.alt = _user_alt_node->getDoubleValue();
|
||||
IC.roll = _user_roll_node->getDoubleValue(); // rotation about x axis
|
||||
IC.elevation = _user_pitch_node->getDoubleValue(); // rotation about y axis
|
||||
|
@ -216,7 +222,9 @@ SubmodelSystem::transform( submodel* sm)
|
|||
in[0] = sm->x_offset;
|
||||
in[1] = sm->y_offset;
|
||||
in[2] = sm->z_offset;
|
||||
|
||||
|
||||
IC.mass = sm->weight * lbs_to_slugs;
|
||||
|
||||
// pre-process the trig functions
|
||||
|
||||
cosRx = cos(-IC.roll * SG_DEGREES_TO_RADIANS);
|
||||
|
@ -289,22 +297,22 @@ SubmodelSystem::transform( submodel* sm)
|
|||
// re-calculate speed, elevation and azimuth
|
||||
|
||||
IC.speed = sqrt( IC.total_speed_north * IC.total_speed_north +
|
||||
IC.total_speed_east * IC.total_speed_east +
|
||||
IC.total_speed_down * IC.total_speed_down);
|
||||
|
||||
IC.total_speed_east * IC.total_speed_east +
|
||||
IC.total_speed_down * IC.total_speed_down);
|
||||
|
||||
IC.azimuth = atan(IC.total_speed_east/IC.total_speed_north) * SG_RADIANS_TO_DEGREES;
|
||||
|
||||
// rationalise the output
|
||||
|
||||
if (IC.total_speed_north <= 0){
|
||||
IC.azimuth = 180 + IC.azimuth;
|
||||
}
|
||||
}
|
||||
else{
|
||||
if(IC.total_speed_east <= 0){
|
||||
IC.azimuth = 360 + IC.azimuth;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
IC.elevation = -atan(IC.total_speed_down/sqrt(IC.total_speed_north *
|
||||
IC.total_speed_north +
|
||||
IC.total_speed_east * IC.total_speed_east)) * SG_RADIANS_TO_DEGREES;
|
||||
|
|
|
@ -29,6 +29,7 @@ public:
|
|||
typedef struct {
|
||||
SGPropertyNode* trigger;
|
||||
SGPropertyNode* prop;
|
||||
|
||||
string name;
|
||||
string model;
|
||||
double speed;
|
||||
|
@ -47,6 +48,9 @@ public:
|
|||
double buoyancy;
|
||||
bool wind;
|
||||
bool first_time;
|
||||
double cd;
|
||||
double weight;
|
||||
// double mass;
|
||||
} submodel;
|
||||
|
||||
typedef struct {
|
||||
|
@ -65,6 +69,7 @@ public:
|
|||
double total_speed_down;
|
||||
double total_speed_east;
|
||||
double total_speed_north;
|
||||
double mass;
|
||||
} IC_struct;
|
||||
|
||||
SubmodelSystem ();
|
||||
|
@ -105,6 +110,8 @@ private:
|
|||
double x_offset, y_offset, z_offset;
|
||||
double pitch_offset, yaw_offset;
|
||||
|
||||
static const double lbs_to_slugs; //conversion factor
|
||||
|
||||
SGPropertyNode* _serviceable_node;
|
||||
SGPropertyNode* _user_lat_node;
|
||||
SGPropertyNode* _user_lon_node;
|
||||
|
@ -117,10 +124,10 @@ private:
|
|||
SGPropertyNode* _user_speed_node;
|
||||
SGPropertyNode* _user_wind_from_east_node;
|
||||
SGPropertyNode* _user_wind_from_north_node;
|
||||
SGPropertyNode* _user_speed_down_fps_node;
|
||||
SGPropertyNode* _user_speed_east_fps_node;
|
||||
SGPropertyNode* _user_speed_north_fps_node;
|
||||
|
||||
SGPropertyNode* _user_speed_down_fps_node;
|
||||
SGPropertyNode* _user_speed_east_fps_node;
|
||||
SGPropertyNode* _user_speed_north_fps_node;
|
||||
|
||||
FGAIManager* ai;
|
||||
IC_struct IC;
|
||||
|
||||
|
@ -128,3 +135,4 @@ private:
|
|||
|
||||
#endif // __SYSTEMS_SUBMODEL_HXX
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue