From 85df309a3beed294b98aa86e9241d166a2a4fddb Mon Sep 17 00:00:00 2001 From: ehofman Date: Sun, 7 Nov 2004 14:46:21 +0000 Subject: [PATCH] David Culp: Here are files to get automated contrails working. I've set up contrails for the 737, using my simple, untextured contrail model. Vivian has made another contrail model, but I'm still trying to get his to work. I'm hoping others will try to make contrail models also. Here's some code that defines a top to thermals. When the top of a thermal is reached the strength is phased-out linearly over the next 100 feet of altitude. At first I tried just capping the thermal at the top, but the change in thermal strength was too fast for the FDM to handle well. Included is a new version of the thermal scenario that includes a top (height-msl) to the thermal. The default value is 5000 feet. --- src/AIModel/AIBase.hxx | 1 + src/AIModel/AIScenario.cxx | 1 + src/AIModel/AIThermal.cxx | 13 ++++++++++++- src/AIModel/AIThermal.hxx | 3 +++ src/AIModel/submodel.cxx | 12 +++++++++++- src/AIModel/submodel.hxx | 4 ++++ 6 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/AIModel/AIBase.hxx b/src/AIModel/AIBase.hxx index daf0caedb..941ac87fa 100644 --- a/src/AIModel/AIBase.hxx +++ b/src/AIModel/AIBase.hxx @@ -57,6 +57,7 @@ typedef struct { 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 eda; // used by ballistic objects double life; // life span in seconds double buoyancy; // acceleration in ft per sec2 diff --git a/src/AIModel/AIScenario.cxx b/src/AIModel/AIScenario.cxx index 9742db92c..b4db6abfd 100644 --- a/src/AIModel/AIScenario.cxx +++ b/src/AIModel/AIScenario.cxx @@ -74,6 +74,7 @@ FGAIScenario::FGAIScenario(string &filename) en->rudder = entry_node->getDoubleValue("rudder", 0.0); en->strength = entry_node->getDoubleValue("strength-fps", 0.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); en->life = entry_node->getDoubleValue("life", 900.0); en->buoyancy = entry_node->getDoubleValue("buoyancy", 0); diff --git a/src/AIModel/AIThermal.cxx b/src/AIModel/AIThermal.cxx index a8fd777b2..c3d2def1c 100644 --- a/src/AIModel/AIThermal.cxx +++ b/src/AIModel/AIThermal.cxx @@ -80,7 +80,7 @@ void FGAIThermal::Run(double dt) { // copy values from the AIManager double user_latitude = manager->get_user_latitude(); double user_longitude = manager->get_user_longitude(); - // double user_altitude = manager->get_user_altitude(); + 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; @@ -96,5 +96,16 @@ void FGAIThermal::Run(double dt) { } else { strength = 0.0; } + + // Stop lift at the top of the thermal (smoothly) + if (user_altitude > (height + 100.0)) { + strength = 0.0; + } + else if (user_altitude < height) { + // do nothing + } + else { + strength -= (strength * (user_altitude - height) * 0.01); + } } diff --git a/src/AIModel/AIThermal.hxx b/src/AIModel/AIThermal.hxx index be772c733..b3fee71bc 100644 --- a/src/AIModel/AIThermal.hxx +++ b/src/AIModel/AIThermal.hxx @@ -42,8 +42,10 @@ public: inline void setMaxStrength( double s ) { max_strength = s; }; inline void setDiameter( double d ) { diameter = d; }; + inline void setHeight( double h ) { height = h; }; inline double getStrength() const { return strength; }; inline double getDiameter() const { return diameter; }; + inline double getHeight() const { return height; }; private: @@ -52,6 +54,7 @@ private: double max_strength; double strength; double diameter; + double height; double factor; }; diff --git a/src/AIModel/submodel.cxx b/src/AIModel/submodel.cxx index e11e0b7c8..0e2dd4299 100644 --- a/src/AIModel/submodel.cxx +++ b/src/AIModel/submodel.cxx @@ -26,6 +26,7 @@ FGSubmodelMgr::FGSubmodelMgr () out[0] = out[1] = out[2] = 0; in[3] = out[3] = 1; string contents_node; + contrail_altitude = 30000.0; } FGSubmodelMgr::~FGSubmodelMgr () @@ -57,8 +58,12 @@ FGSubmodelMgr::init () _user_speed_east_fps_node = fgGetNode("/velocities/speed-east-fps",true); _user_speed_north_fps_node = fgGetNode("/velocities/speed-north-fps",true); - ai = (FGAIManager*)globals->get_subsystem("ai_model"); + _contrail_altitude_node = fgGetNode("/environment/params/contrail-altitude", true); + contrail_altitude = _contrail_altitude_node->getDoubleValue(); + _contrail_trigger = fgGetNode("ai/submodels/contrails", true); + _contrail_trigger->setBoolValue(false); + ai = (FGAIManager*)globals->get_subsystem("ai_model"); } @@ -82,6 +87,11 @@ FGSubmodelMgr::update (double dt) { if (!(_serviceable_node->getBoolValue())) return; int i=-1; + + if (_user_alt_node->getDoubleValue() > contrail_altitude) { + _contrail_trigger->setBoolValue(true); + } + submodel_iterator = submodels.begin(); while(submodel_iterator != submodels.end()) { i++; diff --git a/src/AIModel/submodel.hxx b/src/AIModel/submodel.hxx index e02233a0a..7c733d48e 100644 --- a/src/AIModel/submodel.hxx +++ b/src/AIModel/submodel.hxx @@ -114,6 +114,8 @@ private: static const double lbs_to_slugs; //conversion factor + double contrail_altitude; + SGPropertyNode* _serviceable_node; SGPropertyNode* _user_lat_node; SGPropertyNode* _user_lon_node; @@ -129,6 +131,8 @@ private: SGPropertyNode* _user_speed_down_fps_node; SGPropertyNode* _user_speed_east_fps_node; SGPropertyNode* _user_speed_north_fps_node; + SGPropertyNode* _contrail_altitude_node; + SGPropertyNode* _contrail_trigger; FGAIManager* ai; IC_struct IC; -- 2.39.5