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,6 +27,7 @@
|
||||||
#include "AIBallistic.hxx"
|
#include "AIBallistic.hxx"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
FGAIBallistic::FGAIBallistic(FGAIManager* mgr) {
|
FGAIBallistic::FGAIBallistic(FGAIManager* mgr) {
|
||||||
manager = mgr;
|
manager = mgr;
|
||||||
_type_str = "ballistic";
|
_type_str = "ballistic";
|
||||||
|
@ -36,7 +37,7 @@ FGAIBallistic::FGAIBallistic(FGAIManager* mgr) {
|
||||||
gravity = 32;
|
gravity = 32;
|
||||||
// buoyancy = 64;
|
// buoyancy = 64;
|
||||||
no_roll = false;
|
no_roll = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
FGAIBallistic::~FGAIBallistic() {
|
FGAIBallistic::~FGAIBallistic() {
|
||||||
}
|
}
|
||||||
|
@ -111,8 +112,16 @@ void FGAIBallistic::setWind_from_north(double fps) {
|
||||||
void FGAIBallistic::setWind(bool val) {
|
void FGAIBallistic::setWind(bool val) {
|
||||||
wind = 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;
|
life_timer += dt;
|
||||||
if (life_timer > life) setDie(true);
|
if (life_timer > life) setDie(true);
|
||||||
|
|
||||||
|
@ -120,12 +129,22 @@ void FGAIBallistic::Run(double dt) {
|
||||||
double speed_east_deg_sec;
|
double speed_east_deg_sec;
|
||||||
double wind_speed_from_north_deg_sec;
|
double wind_speed_from_north_deg_sec;
|
||||||
double wind_speed_from_east_deg_sec;
|
double wind_speed_from_east_deg_sec;
|
||||||
|
double mass;
|
||||||
|
|
||||||
// the two drag calculations below assume sea-level density,
|
// the drag calculations below assume sea-level density,
|
||||||
// mass of 0.03 slugs, drag coeff of 0.295
|
// rho = 0.023780 slugs/ft3
|
||||||
// adjust speed due to drag
|
// calculate mass
|
||||||
speed -= 0.0116918 * drag_area * speed * speed * dt;
|
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;
|
if ( speed < 0.0 ) speed = 0.0;
|
||||||
|
|
||||||
|
// calculate vertical and horizontal speed components
|
||||||
vs = sin( pitch * SG_DEGREES_TO_RADIANS ) * speed;
|
vs = sin( pitch * SG_DEGREES_TO_RADIANS ) * speed;
|
||||||
hs = cos( 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_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;
|
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){
|
if (!wind){
|
||||||
wind_from_north = 0;
|
wind_from_north = 0;
|
||||||
wind_from_east = 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_north_deg_sec = wind_from_north / ft_per_deg_lat;
|
||||||
wind_speed_from_east_deg_sec = wind_from_east / ft_per_deg_lon;
|
wind_speed_from_east_deg_sec = wind_from_east / ft_per_deg_lon;
|
||||||
|
|
||||||
|
|
||||||
// set new position
|
// 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.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 );
|
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;
|
vs -= (gravity - buoyancy) * dt;
|
||||||
|
|
||||||
// adjust altitude (feet)
|
// adjust altitude (feet)
|
||||||
|
@ -170,7 +182,7 @@ void FGAIBallistic::Run(double dt) {
|
||||||
// set destruction flag if altitude less than sea level -1000
|
// set destruction flag if altitude less than sea level -1000
|
||||||
if (altitude < -1000.0) setDie(true);
|
if (altitude < -1000.0) setDie(true);
|
||||||
|
|
||||||
}
|
} // end Run
|
||||||
|
|
||||||
double FGAIBallistic::_getTime() const {
|
double FGAIBallistic::_getTime() const {
|
||||||
return life_timer;
|
return life_timer;
|
||||||
|
|
|
@ -46,6 +46,8 @@ public:
|
||||||
void setWind_from_east( double fps );
|
void setWind_from_east( double fps );
|
||||||
void setWind_from_north( double fps );
|
void setWind_from_north( double fps );
|
||||||
void setWind( bool val );
|
void setWind( bool val );
|
||||||
|
void setCd( double c );
|
||||||
|
void setWeight( double w );
|
||||||
|
|
||||||
double _getTime() const;
|
double _getTime() const;
|
||||||
|
|
||||||
|
@ -63,6 +65,8 @@ private:
|
||||||
double wind_from_east; // fps
|
double wind_from_east; // fps
|
||||||
double wind_from_north; // fps
|
double wind_from_north; // fps
|
||||||
bool wind; // if true, local wind will be applied to object
|
bool wind; // if true, local wind will be applied to object
|
||||||
|
double Cd; // drag coefficient
|
||||||
|
double weight; // lbs
|
||||||
|
|
||||||
void Run(double dt);
|
void Run(double dt);
|
||||||
};
|
};
|
||||||
|
|
|
@ -43,6 +43,11 @@
|
||||||
#include "AIBase.hxx"
|
#include "AIBase.hxx"
|
||||||
#include "AIManager.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()
|
FGAIBase::FGAIBase()
|
||||||
: fp( NULL ),
|
: fp( NULL ),
|
||||||
model( 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
|
// Written by David Culp, started Nov 2003, based on
|
||||||
// David Luff's FGAIEntity class.
|
// David Luff's FGAIEntity class.
|
||||||
// - davidculp2@comcast.net
|
// - davidculp2@comcast.net
|
||||||
|
@ -62,7 +62,9 @@ typedef struct {
|
||||||
double buoyancy; // acceleration in ft per sec2
|
double buoyancy; // acceleration in ft per sec2
|
||||||
double wind_from_east; // in feet per second
|
double wind_from_east; // in feet per second
|
||||||
double wind_from_north; // 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;
|
} FGAIModelEntity;
|
||||||
|
|
||||||
|
|
||||||
|
@ -177,6 +179,9 @@ public:
|
||||||
double _getY_shift() const;
|
double _getY_shift() const;
|
||||||
double _getRotation() const;
|
double _getRotation() const;
|
||||||
|
|
||||||
|
static const double rho;
|
||||||
|
static const double lbs_to_slugs;
|
||||||
|
|
||||||
int _getID() const;
|
int _getID() const;
|
||||||
|
|
||||||
inline double _getRange() { return range; };
|
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_from_north(entity->wind_from_north);
|
||||||
ai_ballistic->setWind(entity->wind);
|
ai_ballistic->setWind(entity->wind);
|
||||||
ai_ballistic->setRoll(entity->roll);
|
ai_ballistic->setRoll(entity->roll);
|
||||||
|
ai_ballistic->setCd(entity->cd);
|
||||||
|
ai_ballistic->setWeight(entity->weight);
|
||||||
ai_ballistic->init();
|
ai_ballistic->init();
|
||||||
ai_ballistic->bind();
|
ai_ballistic->bind();
|
||||||
return ai_ballistic;
|
return ai_ballistic;
|
||||||
|
@ -316,3 +318,4 @@ void FGAIManager::processScenario( string filename ) {
|
||||||
delete s;
|
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
|
// Written by David Culp, started May 2004
|
||||||
// - davidculp2@comcast.net
|
// - 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_east = entry_node->getDoubleValue("wind_from_east", 0);
|
||||||
en->wind_from_north = entry_node->getDoubleValue("wind_from_north", 0);
|
en->wind_from_north = entry_node->getDoubleValue("wind_from_north", 0);
|
||||||
en->wind = entry_node->getBoolValue("wind", false);
|
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;
|
en->fp = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,4 +110,4 @@ int FGAIScenario::nEntries( void )
|
||||||
return entries.size();
|
return entries.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// end scenario.cxx
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
#include <AIModel/AIManager.hxx>
|
#include <AIModel/AIManager.hxx>
|
||||||
|
|
||||||
|
|
||||||
|
const double SubmodelSystem::lbs_to_slugs = 0.031080950172;
|
||||||
|
|
||||||
SubmodelSystem::SubmodelSystem ()
|
SubmodelSystem::SubmodelSystem ()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -124,6 +126,8 @@ SubmodelSystem::release (submodel* sm, double dt)
|
||||||
entity.wind_from_east = IC.wind_from_east;
|
entity.wind_from_east = IC.wind_from_east;
|
||||||
entity.wind_from_north = IC.wind_from_north;
|
entity.wind_from_north = IC.wind_from_north;
|
||||||
entity.wind = sm->wind;
|
entity.wind = sm->wind;
|
||||||
|
entity.cd = sm->cd;
|
||||||
|
entity.weight = sm->weight;
|
||||||
ai->createBallistic( &entity );
|
ai->createBallistic( &entity );
|
||||||
|
|
||||||
if (sm->count > 0) (sm->count)--;
|
if (sm->count > 0) (sm->count)--;
|
||||||
|
@ -161,7 +165,7 @@ SubmodelSystem::load ()
|
||||||
sm->trigger = fgGetNode(entry_node->getStringValue("trigger", "none"), true);
|
sm->trigger = fgGetNode(entry_node->getStringValue("trigger", "none"), true);
|
||||||
sm->name = entry_node->getStringValue("name", "none_defined");
|
sm->name = entry_node->getStringValue("name", "none_defined");
|
||||||
sm->model = entry_node->getStringValue("model", "Models/Geometry/rocket.ac");
|
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->repeat = entry_node->getBoolValue ("repeat", false);
|
||||||
sm->delay = entry_node->getDoubleValue("delay", 0.25);
|
sm->delay = entry_node->getDoubleValue("delay", 0.25);
|
||||||
sm->count = entry_node->getIntValue ("count", 1);
|
sm->count = entry_node->getIntValue ("count", 1);
|
||||||
|
@ -171,11 +175,13 @@ SubmodelSystem::load ()
|
||||||
sm->z_offset = entry_node->getDoubleValue("z-offset", 0.0);
|
sm->z_offset = entry_node->getDoubleValue("z-offset", 0.0);
|
||||||
sm->yaw_offset = entry_node->getDoubleValue("yaw-offset", 0.0);
|
sm->yaw_offset = entry_node->getDoubleValue("yaw-offset", 0.0);
|
||||||
sm->pitch_offset = entry_node->getDoubleValue("pitch-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->life = entry_node->getDoubleValue("life", 900.0);
|
||||||
sm->buoyancy = entry_node->getDoubleValue("buoyancy", 0);
|
sm->buoyancy = entry_node->getDoubleValue("buoyancy", 0);
|
||||||
sm->wind = entry_node->getBoolValue ("wind", false);
|
sm->wind = entry_node->getBoolValue ("wind", false);
|
||||||
sm->first_time = 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->trigger->setBoolValue(false);
|
||||||
sm->timer = sm->delay;
|
sm->timer = sm->delay;
|
||||||
|
@ -217,6 +223,8 @@ SubmodelSystem::transform( submodel* sm)
|
||||||
in[1] = sm->y_offset;
|
in[1] = sm->y_offset;
|
||||||
in[2] = sm->z_offset;
|
in[2] = sm->z_offset;
|
||||||
|
|
||||||
|
IC.mass = sm->weight * lbs_to_slugs;
|
||||||
|
|
||||||
// pre-process the trig functions
|
// pre-process the trig functions
|
||||||
|
|
||||||
cosRx = cos(-IC.roll * SG_DEGREES_TO_RADIANS);
|
cosRx = cos(-IC.roll * SG_DEGREES_TO_RADIANS);
|
||||||
|
|
|
@ -29,6 +29,7 @@ public:
|
||||||
typedef struct {
|
typedef struct {
|
||||||
SGPropertyNode* trigger;
|
SGPropertyNode* trigger;
|
||||||
SGPropertyNode* prop;
|
SGPropertyNode* prop;
|
||||||
|
|
||||||
string name;
|
string name;
|
||||||
string model;
|
string model;
|
||||||
double speed;
|
double speed;
|
||||||
|
@ -47,6 +48,9 @@ public:
|
||||||
double buoyancy;
|
double buoyancy;
|
||||||
bool wind;
|
bool wind;
|
||||||
bool first_time;
|
bool first_time;
|
||||||
|
double cd;
|
||||||
|
double weight;
|
||||||
|
// double mass;
|
||||||
} submodel;
|
} submodel;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -65,6 +69,7 @@ public:
|
||||||
double total_speed_down;
|
double total_speed_down;
|
||||||
double total_speed_east;
|
double total_speed_east;
|
||||||
double total_speed_north;
|
double total_speed_north;
|
||||||
|
double mass;
|
||||||
} IC_struct;
|
} IC_struct;
|
||||||
|
|
||||||
SubmodelSystem ();
|
SubmodelSystem ();
|
||||||
|
@ -105,6 +110,8 @@ private:
|
||||||
double x_offset, y_offset, z_offset;
|
double x_offset, y_offset, z_offset;
|
||||||
double pitch_offset, yaw_offset;
|
double pitch_offset, yaw_offset;
|
||||||
|
|
||||||
|
static const double lbs_to_slugs; //conversion factor
|
||||||
|
|
||||||
SGPropertyNode* _serviceable_node;
|
SGPropertyNode* _serviceable_node;
|
||||||
SGPropertyNode* _user_lat_node;
|
SGPropertyNode* _user_lat_node;
|
||||||
SGPropertyNode* _user_lon_node;
|
SGPropertyNode* _user_lon_node;
|
||||||
|
@ -128,3 +135,4 @@ private:
|
||||||
|
|
||||||
#endif // __SYSTEMS_SUBMODEL_HXX
|
#endif // __SYSTEMS_SUBMODEL_HXX
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue