From 4b5a80129d17ab3b7282ce485574a02953d49bf3 Mon Sep 17 00:00:00 2001 From: ehofman Date: Mon, 16 May 2005 09:48:00 +0000 Subject: [PATCH] David Culp: 1) The AIStorm sets the properties: /environment/turbulence/magnitude-norm /environment/turbulence/rate-hz The actual turbulence effects are handled by the FDM. If the effects are deemed unrealistic, then that will have to be fixed in the FDM(s). 2) The zone of turbulence is cylindrical, and is centered at the AIStorm's lat/lon. The diameter is set with , the top with , the bottom is assumed to be at minus 1000 feet. 3) Note that the zone of turbulence may not match well with the visual model of the storm. In this case I had to x-offset the storm model by 4700 meters to match the zone of turbulence. (i.e. the storm model is 4700m off center). 4) While I was in there I also increased the speed of the lightning flashes to look more realistic. --- src/AIModel/AIBase.hxx | 6 +++--- src/AIModel/AIManager.cxx | 7 +++++-- src/AIModel/AIScenario.cxx | 3 ++- src/AIModel/AIStorm.cxx | 36 ++++++++++++++++++++++++++++++++---- src/AIModel/AIStorm.hxx | 17 ++++++++++++++++- 5 files changed, 58 insertions(+), 11 deletions(-) diff --git a/src/AIModel/AIBase.hxx b/src/AIModel/AIBase.hxx index dacd7f9ec..88c6bde7c 100644 --- a/src/AIModel/AIBase.hxx +++ b/src/AIModel/AIBase.hxx @@ -58,9 +58,9 @@ typedef struct { double azimuth; // used by ballistic objects double elevation; // used by ballistic objects double rudder; // used by ship objects - double strength; // used by thermal objects - double diameter; // used by thermal objects - double height_msl; // used by thermal objects + double strength; // used by thermal and storm objects + double diameter; // used by thermal and storm objects + double height_msl; // used by thermal and storm objects double eda; // used by ballistic objects double life; // life span in seconds double buoyancy; // acceleration in ft per sec2 diff --git a/src/AIModel/AIManager.cxx b/src/AIModel/AIManager.cxx index e0dd2aca0..d5d639292 100644 --- a/src/AIModel/AIManager.cxx +++ b/src/AIModel/AIManager.cxx @@ -137,7 +137,7 @@ void FGAIManager::update(double dt) { } ++ai_list_itr; } - wind_from_down_node->setDoubleValue( strength ); + wind_from_down_node->setDoubleValue( strength ); // for thermals } @@ -281,7 +281,10 @@ FGAIManager::createStorm( FGAIModelEntity *entity ) { ai_storm->setHeading(entity->heading); ai_storm->setSpeed(entity->speed); ai_storm->setPath(entity->path.c_str()); - ai_storm->setAltitude(entity->altitude); + ai_storm->setAltitude(entity->altitude); + ai_storm->setDiameter(entity->diameter / 6076.11549); + ai_storm->setHeight(entity->height_msl); + ai_storm->setStrengthNorm(entity->strength); ai_storm->setLongitude(entity->longitude); ai_storm->setLatitude(entity->latitude); ai_storm->init(); diff --git a/src/AIModel/AIScenario.cxx b/src/AIModel/AIScenario.cxx index f8c6e56ce..385491f08 100644 --- a/src/AIModel/AIScenario.cxx +++ b/src/AIModel/AIScenario.cxx @@ -86,7 +86,8 @@ FGAIScenario::FGAIScenario(string &filename) en->azimuth = entry_node->getDoubleValue("azimuth", 0.0); en->elevation = entry_node->getDoubleValue("elevation", 0.0); en->rudder = entry_node->getDoubleValue("rudder", 0.0); - en->strength = entry_node->getDoubleValue("strength-fps", 0.0); + en->strength = entry_node->getDoubleValue("strength-fps", 8.0); + en->strength = entry_node->getDoubleValue("strength-norm", 1.0); en->diameter = entry_node->getDoubleValue("diameter-ft", 0.0); en->height_msl = entry_node->getDoubleValue("height-msl", 5000.0); en->eda = entry_node->getDoubleValue("eda", 0.007); diff --git a/src/AIModel/AIStorm.cxx b/src/AIModel/AIStorm.cxx index 372e69e70..15d8c4fe3 100644 --- a/src/AIModel/AIStorm.cxx +++ b/src/AIModel/AIStorm.cxx @@ -56,6 +56,9 @@ FGAIStorm::FGAIStorm(FGAIManager* mgr) { subflash_array[5] = 1; subflash_array[6] = 1; subflash_array[7] = 2; + + turb_mag_node = fgGetNode("/environment/turbulence/magnitude-norm", true); + turb_rate_node = fgGetNode("/environment/turbulence/rate-hz", true); } @@ -100,10 +103,13 @@ void FGAIStorm::Run(double dt) { pos.setlat( pos.lat() + speed_north_deg_sec * dt); pos.setlon( pos.lon() + speed_east_deg_sec * dt); - // do calculations for radar // + // do calculations for weather radar display UpdateRadar(manager); - // do lightning + // ************************************************** + // * do lightning * + // ************************************************** + if (timer > random_delay) { srand((unsigned)time(0)); random_delay = delay + (rand()%3) - 1.0; @@ -118,11 +124,11 @@ void FGAIStorm::Run(double dt) { if (flashing) { if (flashed < subflashes) { timer += dt; - if (timer < 0.2) { + if (timer < 0.1) { flash_node->setBoolValue(true); } else { flash_node->setBoolValue(false); - if (timer > 0.4) { + if (timer > 0.2) { timer = 0.0; flashed++; } @@ -136,6 +142,28 @@ void FGAIStorm::Run(double dt) { else { timer += dt; } + + // *************************************************** + // * do turbulence * + // *************************************************** + + // copy user's position from the AIManager + double user_latitude = manager->get_user_latitude(); + double user_longitude = manager->get_user_longitude(); + double user_altitude = manager->get_user_altitude(); + + // calculate range to target in feet and nautical miles + double lat_range = fabs(pos.lat() - user_latitude) * ft_per_deg_lat; + double lon_range = fabs(pos.lon() - user_longitude) * ft_per_deg_lon; + double range_ft = sqrt(lat_range*lat_range + lon_range*lon_range); + range = range_ft / 6076.11549; + + if (range < (diameter * 0.5) && + user_altitude > (altitude - 1000.0) && + user_altitude < height) { + turb_mag_node->setDoubleValue(strength_norm); + turb_rate_node->setDoubleValue(0.5); + } } diff --git a/src/AIModel/AIStorm.hxx b/src/AIModel/AIStorm.hxx index 434320b55..1241a064d 100644 --- a/src/AIModel/AIStorm.hxx +++ b/src/AIModel/AIStorm.hxx @@ -39,12 +39,22 @@ public: virtual void bind(); virtual void unbind(); void update(double dt); + inline void setStrengthNorm( double s ) { strength_norm = s; }; + inline void setDiameter( double d ) { diameter = d; }; + inline void setHeight( double h ) { height = h; }; + inline double getStrengthNorm() const { return strength_norm; }; + inline double getDiameter() const { return diameter; }; + inline double getHeight() const { return height; }; private: - double dt; + double dt; + double diameter; // diameter of turbulence zone, in nm + double height; // top of turbulence zone, in feet MSL + double strength_norm; // strength of turbulence void Run(double dt); + // lightning stuff double delay; // average time (sec) between lightning flashes int subflashes; // number of subflashes per flash double random_delay; // delay +/- random number @@ -54,6 +64,11 @@ private: bool flashing; // true if currently flashing; int subflash_array[8]; int subflash_index; + + // turbulence stuff + SGPropertyNode* turb_mag_node; + SGPropertyNode* turb_rate_node; + };