From 26e6b0edcb3c5361a8cc0bb0c0d58dc518838d1c Mon Sep 17 00:00:00 2001 From: ehofman Date: Wed, 22 Sep 2004 08:47:05 +0000 Subject: [PATCH] Vivian Meazza: I have added and to the input parameters in the submodels.xml script. Raw data may be used, thus avoiding the need to guestimate . Eda remains, but should now be used to enter the proper cross-sectional area. --- src/AIModel/AIBallistic.cxx | 56 ++++++++++++++++++++++--------------- src/AIModel/AIBallistic.hxx | 18 +++++++----- src/AIModel/AIBase.cxx | 5 ++++ src/AIModel/AIBase.hxx | 9 ++++-- src/AIModel/AIManager.cxx | 3 ++ src/AIModel/AIScenario.cxx | 6 ++-- src/Systems/submodel.cxx | 32 +++++++++++++-------- src/Systems/submodel.hxx | 16 ++++++++--- 8 files changed, 96 insertions(+), 49 deletions(-) diff --git a/src/AIModel/AIBallistic.cxx b/src/AIModel/AIBallistic.cxx index bd0c8530f..d3ea25a1b 100644 --- a/src/AIModel/AIBallistic.cxx +++ b/src/AIModel/AIBallistic.cxx @@ -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 \ No newline at end of file +// end AIBallistic diff --git a/src/AIModel/AIBallistic.hxx b/src/AIModel/AIBallistic.hxx index 54f08215b..bc97ced2c 100644 --- a/src/AIModel/AIBallistic.hxx +++ b/src/AIModel/AIBallistic.hxx @@ -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); }; diff --git a/src/AIModel/AIBase.cxx b/src/AIModel/AIBase.cxx index 57a6ed5a3..057f3bc84 100644 --- a/src/AIModel/AIBase.cxx +++ b/src/AIModel/AIBase.cxx @@ -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 ), diff --git a/src/AIModel/AIBase.hxx b/src/AIModel/AIBase.hxx index 071abe788..89c798152 100644 --- a/src/AIModel/AIBase.hxx +++ b/src/AIModel/AIBase.hxx @@ -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; }; diff --git a/src/AIModel/AIManager.cxx b/src/AIModel/AIManager.cxx index 722da5aaa..b7927ef2c 100644 --- a/src/AIModel/AIManager.cxx +++ b/src/AIModel/AIManager.cxx @@ -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 diff --git a/src/AIModel/AIScenario.cxx b/src/AIModel/AIScenario.cxx index 9bc0fa7b8..2802a8152 100644 --- a/src/AIModel/AIScenario.cxx +++ b/src/AIModel/AIScenario.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 diff --git a/src/Systems/submodel.cxx b/src/Systems/submodel.cxx index d405e63d4..975ca9329 100644 --- a/src/Systems/submodel.cxx +++ b/src/Systems/submodel.cxx @@ -13,6 +13,8 @@ #include +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; diff --git a/src/Systems/submodel.hxx b/src/Systems/submodel.hxx index b7155034f..ec9dbabb9 100644 --- a/src/Systems/submodel.hxx +++ b/src/Systems/submodel.hxx @@ -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 +