1
0
Fork 0

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:
ehofman 2004-09-22 08:47:05 +00:00
parent 56f6d3b800
commit 26e6b0edcb
8 changed files with 96 additions and 49 deletions

View file

@ -27,16 +27,17 @@
#include "AIBallistic.hxx" #include "AIBallistic.hxx"
FGAIBallistic::FGAIBallistic(FGAIManager* mgr) { FGAIBallistic::FGAIBallistic(FGAIManager* mgr) {
manager = mgr; manager = mgr;
_type_str = "ballistic"; _type_str = "ballistic";
_otype = otBallistic; _otype = otBallistic;
drag_area = 0.007; drag_area = 0.007;
life_timer = 0.0; life_timer = 0.0;
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,10 +182,10 @@ 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;
} }
// end AIBallistic // end AIBallistic

View file

@ -25,12 +25,12 @@
class FGAIBallistic : public FGAIBase { class FGAIBallistic : public FGAIBase {
public: public:
FGAIBallistic(FGAIManager* mgr); FGAIBallistic(FGAIManager* mgr);
~FGAIBallistic(); ~FGAIBallistic();
bool init(); bool init();
virtual void bind(); virtual void bind();
virtual void unbind(); virtual void unbind();
@ -38,7 +38,7 @@ public:
void setAzimuth( double az ); void setAzimuth( double az );
void setElevation( double el ); void setElevation( double el );
void setRoll( double rl ); void setRoll( double rl );
void setStabilization( bool val ); void setStabilization( bool val );
void setDragArea( double a ); void setDragArea( double a );
void setLife( double seconds ); void setLife( double seconds );
@ -46,14 +46,16 @@ 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;
private: private:
double azimuth; // degrees true double azimuth; // degrees true
double elevation; // degrees double elevation; // degrees
double rotation; // degrees double rotation; // degrees
double hs; // horizontal speed (fps) double hs; // horizontal speed (fps)
bool aero_stabilized; // if true, object will point where it's going bool aero_stabilized; // if true, object will point where it's going
double drag_area; // equivalent drag area in ft2 double drag_area; // equivalent drag area in ft2
@ -63,7 +65,9 @@ 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);
}; };

View file

@ -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 ),

View file

@ -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; };

View file

@ -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

View file

@ -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

View file

@ -13,6 +13,8 @@
#include <AIModel/AIManager.hxx> #include <AIModel/AIManager.hxx>
const double SubmodelSystem::lbs_to_slugs = 0.031080950172;
SubmodelSystem::SubmodelSystem () SubmodelSystem::SubmodelSystem ()
{ {
@ -52,8 +54,8 @@ SubmodelSystem::init ()
_user_speed_down_fps_node = fgGetNode("/velocities/speed-down-fps",true); _user_speed_down_fps_node = fgGetNode("/velocities/speed-down-fps",true);
_user_speed_east_fps_node = fgGetNode("/velocities/speed-east-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"); 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_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;
@ -198,7 +204,7 @@ SubmodelSystem::transform( submodel* sm)
// get initial conditions // get initial conditions
IC.lat = _user_lat_node->getDoubleValue(); 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.alt = _user_alt_node->getDoubleValue();
IC.roll = _user_roll_node->getDoubleValue(); // rotation about x axis IC.roll = _user_roll_node->getDoubleValue(); // rotation about x axis
IC.elevation = _user_pitch_node->getDoubleValue(); // rotation about y 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[0] = sm->x_offset;
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);
@ -289,22 +297,22 @@ SubmodelSystem::transform( submodel* sm)
// re-calculate speed, elevation and azimuth // re-calculate speed, elevation and azimuth
IC.speed = sqrt( IC.total_speed_north * IC.total_speed_north + IC.speed = sqrt( IC.total_speed_north * IC.total_speed_north +
IC.total_speed_east * IC.total_speed_east + IC.total_speed_east * IC.total_speed_east +
IC.total_speed_down * IC.total_speed_down); IC.total_speed_down * IC.total_speed_down);
IC.azimuth = atan(IC.total_speed_east/IC.total_speed_north) * SG_RADIANS_TO_DEGREES; IC.azimuth = atan(IC.total_speed_east/IC.total_speed_north) * SG_RADIANS_TO_DEGREES;
// rationalise the output // rationalise the output
if (IC.total_speed_north <= 0){ if (IC.total_speed_north <= 0){
IC.azimuth = 180 + IC.azimuth; IC.azimuth = 180 + IC.azimuth;
} }
else{ else{
if(IC.total_speed_east <= 0){ if(IC.total_speed_east <= 0){
IC.azimuth = 360 + IC.azimuth; IC.azimuth = 360 + IC.azimuth;
} }
} }
IC.elevation = -atan(IC.total_speed_down/sqrt(IC.total_speed_north * IC.elevation = -atan(IC.total_speed_down/sqrt(IC.total_speed_north *
IC.total_speed_north + IC.total_speed_north +
IC.total_speed_east * IC.total_speed_east)) * SG_RADIANS_TO_DEGREES; IC.total_speed_east * IC.total_speed_east)) * SG_RADIANS_TO_DEGREES;

View file

@ -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;
@ -117,10 +124,10 @@ private:
SGPropertyNode* _user_speed_node; SGPropertyNode* _user_speed_node;
SGPropertyNode* _user_wind_from_east_node; SGPropertyNode* _user_wind_from_east_node;
SGPropertyNode* _user_wind_from_north_node; SGPropertyNode* _user_wind_from_north_node;
SGPropertyNode* _user_speed_down_fps_node; SGPropertyNode* _user_speed_down_fps_node;
SGPropertyNode* _user_speed_east_fps_node; SGPropertyNode* _user_speed_east_fps_node;
SGPropertyNode* _user_speed_north_fps_node; SGPropertyNode* _user_speed_north_fps_node;
FGAIManager* ai; FGAIManager* ai;
IC_struct IC; IC_struct IC;
@ -128,3 +135,4 @@ private:
#endif // __SYSTEMS_SUBMODEL_HXX #endif // __SYSTEMS_SUBMODEL_HXX