From 22ea572da3227ffd512e11553f1b79f23abba003 Mon Sep 17 00:00:00 2001 From: Torsten Dreyer <Torsten@t3r.de> Date: Sat, 1 Jan 2011 18:56:36 +0100 Subject: [PATCH 01/48] Merge branch 'next', remote branch 'origin' into next From 455b7fe61eac01d8cae022a11ac7021014f85c3b Mon Sep 17 00:00:00 2001 From: Vivian Meazza <vivian.meazza@lineone.net> Date: Sat, 21 May 2011 17:08:36 +0100 Subject: [PATCH 02/48] Add the capability of switching slaved objects at runtime. Signed-off-by: Vivian Meazza <vivian.meazza@lineone.net> --- src/AIModel/AIBallistic.cxx | 124 ++++++++++++++++++++---------------- src/AIModel/AIBallistic.hxx | 4 +- 2 files changed, 71 insertions(+), 57 deletions(-) diff --git a/src/AIModel/AIBallistic.cxx b/src/AIModel/AIBallistic.cxx index 16b15fe1d..d31e3b46d 100644 --- a/src/AIModel/AIBallistic.cxx +++ b/src/AIModel/AIBallistic.cxx @@ -182,7 +182,7 @@ void FGAIBallistic::bind() { props->tie("sim/time/elapsed-sec", SGRawValueMethods<FGAIBallistic,double>(*this, - &FGAIBallistic::_getTime)); + &FGAIBallistic::_getTime, &FGAIBallistic::setTime)); //props->tie("mass-slug", // SGRawValueMethods<FGAIBallistic,double>(*this, // &FGAIBallistic::getMass)); @@ -586,6 +586,7 @@ void FGAIBallistic::setHt(double h, double dt, double coeff){ int FGAIBallistic::setHdg(double tgt_hdg, double dt, double coeff){ double recip = getRecip(hdg); double c = dt / (coeff + dt); + //cout << "set heading " << tgt_hdg << endl; //we need to ensure that we turn the short way to the new hdg if (tgt_hdg < recip && tgt_hdg < hdg && hdg > 180) { hdg = ((tgt_hdg + 360) * c) + (hdg * (1 - c)); @@ -626,6 +627,9 @@ void FGAIBallistic::setTgtZOffset(double z){ void FGAIBallistic::slaveToAC(double dt){ + if (invisible) + return; + double hdg, pch, rll, agl = 0; if (_pnode != 0) { @@ -652,6 +656,7 @@ void FGAIBallistic::slaveToAC(double dt){ setPitch(pch + _pitch_offset); setBank(rll + _roll_offset); setOffsetVelocity(dt, pos); + setTime(0); //update the mass (slugs) _mass = (_weight_lb + getContents()) / slugs_to_lbs; @@ -710,23 +715,13 @@ void FGAIBallistic::Run(double dt) { speed = 0.0; double speed_fps = speed * SG_KT_TO_FPS; - //double hs; // calculate vertical and horizontal speed components - if (speed == 0.0) { - hs = vs = 0.0; - } else { - vs = sin( _elevation * SG_DEGREES_TO_RADIANS ) * speed_fps; - hs = cos( _elevation * SG_DEGREES_TO_RADIANS ) * speed_fps; - } + calcVSHS(); //resolve horizontal speed into north and east components: - double speed_north_fps = cos(_azimuth / SG_RADIANS_TO_DEGREES) * hs; - double speed_east_fps = sin(_azimuth / SG_RADIANS_TO_DEGREES) * hs; - - // convert horizontal speed (fps) to degrees per second - double speed_north_deg_sec = speed_north_fps / ft_per_deg_lat; - double speed_east_deg_sec = speed_east_fps / ft_per_deg_lon; + //and convert horizontal speed (fps) to degrees per second + calcNE(); // if wind not required, set to zero if (!_wind) { @@ -755,55 +750,61 @@ void FGAIBallistic::Run(double dt) { double friction_force_speed_north_deg_sec = 0; double friction_force_speed_east_deg_sec = 0; double force_elevation_deg = 0; + double force_azimuth_deg = 0; + double force_lbs = 0; if (_external_force) { - //cout << _name << " external force" << endl; + //cout << _name << " external force " << hdg << " az " << _azimuth << endl; SGPropertyNode *n = fgGetNode(_force_path.c_str(), true); - double force_lbs = n->getChild("force-lb", 0, true)->getDoubleValue(); - force_elevation_deg = n->getChild("force-elevation-deg", 0, true)->getDoubleValue(); - double force_azimuth_deg = n->getChild("force-azimuth-deg", 0, true)->getDoubleValue(); + force_lbs = n->getChild("force-lb", 0, true)->getDoubleValue(); + force_elevation_deg = n->getChild("force-elevation-deg", 0, true)->getDoubleValue(); + force_azimuth_deg = n->getChild("force-azimuth-deg", 0, true)->getDoubleValue(); //resolve force into vertical and horizontal components: double v_force_lbs = force_lbs * sin( force_elevation_deg * SG_DEGREES_TO_RADIANS ); h_force_lbs = force_lbs * cos( force_elevation_deg * SG_DEGREES_TO_RADIANS ); //ground interaction + //we don't do this if impacts are calculated + if(!_report_impact){ - if (getHtAGL(10000)){ - double deadzone = 0.1; + if (getHtAGL(10000)){ + double deadzone = 0.1; - if (_ht_agl_ft <= (0 + _ground_offset + deadzone) && _solid){ - normal_force_lbs = (_mass * slugs_to_lbs) - v_force_lbs; + if (_ht_agl_ft <= (0 + _ground_offset + deadzone) && _solid){ + normal_force_lbs = (_mass * slugs_to_lbs) - v_force_lbs; - if ( normal_force_lbs < 0 ) - normal_force_lbs = 0; + if ( normal_force_lbs < 0 ) + normal_force_lbs = 0; - pos.setElevationFt(0 + _ground_offset); - if (vs < 0) - vs = -vs * 0.5; + pos.setElevationFt(0 + _ground_offset); + if (vs < 0) + vs = -vs * 0.5; - // calculate friction - // we assume a static Coefficient of Friction (mu) of 0.62 (wood on concrete) - double mu = 0.62; + // calculate friction + // we assume a static Coefficient of Friction (mu) of 0.62 (wood on concrete) + double mu = 0.62; - static_friction_force_lbs = mu * normal_force_lbs * _frictionFactor; + static_friction_force_lbs = mu * normal_force_lbs * _frictionFactor; - //adjust horizontal force. We assume that a speed of <= 5 fps is static - if (h_force_lbs <= static_friction_force_lbs && hs <= 5){ - h_force_lbs = hs = 0; - speed_north_fps = speed_east_fps = 0; - } else - dynamic_friction_force_lbs = (static_friction_force_lbs * 0.95); + //adjust horizontal force. We assume that a speed of <= 5 fps is static + if (h_force_lbs <= static_friction_force_lbs && hs <= 5){ + h_force_lbs = hs = 0; + _speed_north_fps = _speed_east_fps = 0; + } else + dynamic_friction_force_lbs = (static_friction_force_lbs * 0.95); - //ignore wind when on the ground for now - //TODO fix this - _wind_from_north = 0; - _wind_from_east = 0; + //ignore wind when on the ground for now + //TODO fix this + _wind_from_north = 0; + _wind_from_east = 0; + + } } - } + } //endif //acceleration = (force(lbsf)/mass(slugs)) v_force_acc_fpss = v_force_lbs/_mass; @@ -835,10 +836,10 @@ void FGAIBallistic::Run(double dt) { double wind_speed_from_east_deg_sec = _wind_from_east / ft_per_deg_lon; //recombine the horizontal velocity components - hs = sqrt(((speed_north_fps + force_speed_north_fps + friction_force_speed_north_fps) - * (speed_north_fps + force_speed_north_fps + friction_force_speed_north_fps)) - + ((speed_east_fps + force_speed_east_fps + friction_force_speed_east_fps) - * (speed_east_fps + force_speed_east_fps + friction_force_speed_east_fps))); + hs = sqrt(((_speed_north_fps + force_speed_north_fps + friction_force_speed_north_fps) + * (_speed_north_fps + force_speed_north_fps + friction_force_speed_north_fps)) + + ((_speed_east_fps + force_speed_east_fps + friction_force_speed_east_fps) + * (_speed_east_fps + force_speed_east_fps + friction_force_speed_east_fps))); if (hs <= 0.00001) hs = 0; @@ -890,8 +891,8 @@ void FGAIBallistic::Run(double dt) { // recalculate elevation and azimuth (velocity vectors) _elevation = atan2( vs, hs ) * SG_RADIANS_TO_DEGREES; - _azimuth = atan2((speed_east_fps + force_speed_east_fps + friction_force_speed_east_fps), - (speed_north_fps + force_speed_north_fps + friction_force_speed_north_fps)) + _azimuth = atan2((_speed_east_fps + force_speed_east_fps + friction_force_speed_east_fps), + (_speed_north_fps + force_speed_north_fps + friction_force_speed_north_fps)) * SG_RADIANS_TO_DEGREES; // rationalise azimuth @@ -899,7 +900,7 @@ void FGAIBallistic::Run(double dt) { _azimuth += 360; if (_aero_stabilised) { // we simulate rotational moment of inertia by using a filter - //cout<< "_aero_stabilised "<< endl; + //cout<< "_aero_stabilised " << hdg << " az " << _azimuth << endl; const double coeff = 0.9; // we assume a symetrical MI about the pitch and yaw axis @@ -941,16 +942,20 @@ double FGAIBallistic::_getTime() const { return _life_timer; } +void FGAIBallistic::setTime(double s){ + _life_timer = s; +} + void FGAIBallistic::handle_impact() { // try terrain intersection - double start = pos.getElevationM() + 10; + double start = pos.getElevationM() + 100; if(!getHtAGL(start)) return; if (_ht_agl_ft <= 0) { - SG_LOG(SG_GENERAL, SG_DEBUG, "AIBallistic: terrain impact"); + SG_LOG(SG_GENERAL, SG_DEBUG, "AIBallistic: terrain impact material" << _mat_name); report_impact(_elevation_m); _impact_reported = true; @@ -1004,7 +1009,8 @@ void FGAIBallistic::report_impact(double elevation, const FGAIBase *object) else n->setStringValue("type", "terrain"); - SG_LOG(SG_GENERAL, SG_DEBUG, "AIBallistic: object impact" << _name << " lon " <<_impact_lon); + SG_LOG(SG_GENERAL, SG_DEBUG, "AIBallistic: object impact " << _name + << " lon " <<_impact_lon << " lat " <<_impact_lat); n->setDoubleValue("longitude-deg", _impact_lon); n->setDoubleValue("latitude-deg", _impact_lat); @@ -1239,9 +1245,17 @@ void FGAIBallistic::setOffsetVelocity(double dt, SGGeod offsetpos) { calcVSHS(); //calculate the bearing of the new offset position from the old - double az1, az2, dist; - geo_inverse_wgs_84(_oldoffsetpos, offsetpos, &az1, &az2, &dist); - _azimuth = az1; + //don't do this if speed is low + //cout << "speed " << speed << endl; + if (speed > 0.1){ + double az1, az2, dist; + geo_inverse_wgs_84(_oldoffsetpos, offsetpos, &az1, &az2, &dist); + _azimuth = az1; + //cout << "offset az " << _azimuth << endl; + } else { + _azimuth = hdg; + //cout << " slow offset az " << _azimuth << endl; + } //resolve horizontal speed into north and east components: calcNE(); diff --git a/src/AIModel/AIBallistic.hxx b/src/AIModel/AIBallistic.hxx index b2b140c17..fb1b4f28d 100644 --- a/src/AIModel/AIBallistic.hxx +++ b/src/AIModel/AIBallistic.hxx @@ -96,9 +96,9 @@ public: void setParentPos(); void setOffsetPos(SGGeod pos, double heading, double pitch, double roll); void setOffsetVelocity(double dt, SGGeod pos); + void setTime(double sec); - - double _getTime() const; + double _getTime()const; double getRelBrgHitchToUser() const; double getElevHitchToUser() const; double getLoadOffset() const; From 8f3cdc940416cea0c61ddd9a202b612517874fb0 Mon Sep 17 00:00:00 2001 From: Erik Hofman <erik@ehofman.com> Date: Sun, 5 Jun 2011 10:20:16 +0200 Subject: [PATCH 03/48] Add a /rendering/scene/overcast option to color the skydome gray in case of overcast --- src/Time/light.cxx | 10 ++++++---- src/Time/light.hxx | 1 + 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/Time/light.cxx b/src/Time/light.cxx index 861c496e9..19b996153 100644 --- a/src/Time/light.cxx +++ b/src/Time/light.cxx @@ -78,6 +78,7 @@ FGLight::FGLight () _adj_sky_color(0, 0, 0, 0), _saturation(1.0), _scattering(0.8), + _overcast(0.0), _dt_total(0) { } @@ -145,6 +146,7 @@ void FGLight::bind () { // Write Only prop->tie("/rendering/scene/saturation",SGRawValuePointer<float>(&_saturation)); prop->tie("/rendering/scene/scattering",SGRawValuePointer<float>(&_scattering)); + prop->tie("/rendering/scene/overcast",SGRawValuePointer<float>(&_overcast)); // Read Only prop->tie("/sim/time/sun-angle-rad",SGRawValuePointer<double>(&_sun_angle)); @@ -178,7 +180,7 @@ void FGLight::unbind () { SGPropertyNode *prop = globals->get_props(); prop->untie("/rendering/scene/saturation"); prop->untie("/rendering/scene/scattering"); - prop->untie("/environment/relative-humidity"); + prop->untie("/rendering/scene/overcast"); prop->untie("/sim/time/sun-angle-rad"); prop->untie("/rendering/scene/ambient/red"); @@ -261,9 +263,9 @@ void FGLight::update_sky_color () { gamma_correct_rgb( _fog_color.data() ); // set sky color - _sky_color[0] = base_sky_color[0] * sky_brightness; - _sky_color[1] = base_sky_color[1] * sky_brightness; - _sky_color[2] = base_sky_color[2] * sky_brightness; + _sky_color[0] = (base_sky_color[0] + (1.0f-base_sky_color[0]) * _overcast) * sky_brightness; + _sky_color[1] = (base_sky_color[1] + (1.0f-base_sky_color[1]) * _overcast) * sky_brightness; + _sky_color[2] = (base_sky_color[2] + (1.0f-base_sky_color[2]) * _overcast) * sky_brightness; _sky_color[3] = base_sky_color[3]; gamma_correct_rgb( _sky_color.data() ); diff --git a/src/Time/light.hxx b/src/Time/light.hxx index 69987d337..1880c3dea 100644 --- a/src/Time/light.hxx +++ b/src/Time/light.hxx @@ -100,6 +100,7 @@ private: // input parameters affected by the weather system float _saturation; float _scattering; + float _overcast; double _dt_total; From afca14c3724811972fc888d8b7f3acba618ff8e1 Mon Sep 17 00:00:00 2001 From: Erik Hofman <erik@ehofman.com> Date: Sun, 5 Jun 2011 10:26:55 +0200 Subject: [PATCH 04/48] add a sanity check for the overcast property --- src/Time/light.cxx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Time/light.cxx b/src/Time/light.cxx index 19b996153..042919aee 100644 --- a/src/Time/light.cxx +++ b/src/Time/light.cxx @@ -237,6 +237,8 @@ void FGLight::update_sky_color () { else if (_saturation > 1.0) _saturation = 1.0; if (_scattering < 0.0) _scattering = 0.0; else if (_scattering > 1.0) _scattering = 1.0; + if (_overcast < 0.0) _overcast = 0.0; + else if (_overcast > 1.0) _overcast = 1.0; float ambient = _ambient_tbl->interpolate( deg ) + visibility_inv/10; float diffuse = _diffuse_tbl->interpolate( deg ); From d21924770f8d41fdfe395353e59ce92a31a3ae35 Mon Sep 17 00:00:00 2001 From: Mathias Froehlich <Mathias.Froehlich@web.de> Date: Sun, 5 Jun 2011 13:44:37 +0200 Subject: [PATCH 05/48] Avoid crashing in hla initialization failure. --- src/Network/HLA/hla.cxx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Network/HLA/hla.cxx b/src/Network/HLA/hla.cxx index de12ae2f1..cf6af5eff 100644 --- a/src/Network/HLA/hla.cxx +++ b/src/Network/HLA/hla.cxx @@ -1216,6 +1216,9 @@ FGHLA::open() bool FGHLA::process() { + if (!is_enabled()) + return false; + // First push our own data so that others can recieve ... if (get_direction() & SG_IO_OUT) { if (fgGetBool("/sim/fdm-initialized", false) && _localAircraftClass.valid()) { @@ -1245,6 +1248,9 @@ FGHLA::process() bool FGHLA::close() { + if (!is_enabled()) + return false; + if (get_direction() & SG_IO_OUT) { // Remove the local object from the rti _localAircraftInstance->deleteInstance(simgear::RTIData("gone")); From abc97adf2bf943154f849d8c542d7980538d097f Mon Sep 17 00:00:00 2001 From: Torsten Dreyer <torsten@mustang.home.t3r.de> Date: Sun, 5 Jun 2011 17:04:41 +0200 Subject: [PATCH 06/48] Initial commit to add fgpanel to cmake build system Most likely only works on OSX, other OSes will follow later --- utils/CMakeLists.txt | 4 ++++ utils/fgpanel/CMakeLists.txt | 25 +++++++++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 utils/fgpanel/CMakeLists.txt diff --git a/utils/CMakeLists.txt b/utils/CMakeLists.txt index f3caabb8b..5ba92f6f8 100644 --- a/utils/CMakeLists.txt +++ b/utils/CMakeLists.txt @@ -5,3 +5,7 @@ add_subdirectory(GPSsmooth) if (FLTK_FOUND) add_subdirectory(fgadmin) endif (FLTK_FOUND) + +if (WITH_FGPANEL) + add_subdirectory(fgpanel) +endif (WITH_FGPANEL) diff --git a/utils/fgpanel/CMakeLists.txt b/utils/fgpanel/CMakeLists.txt new file mode 100644 index 000000000..e770d76f1 --- /dev/null +++ b/utils/fgpanel/CMakeLists.txt @@ -0,0 +1,25 @@ +#FIXME: does this work in *nix/windows? +find_package(png REQUIRED) +find_package(OpenGL REQUIRED) +find_package(glut REQUIRED) + +add_executable(fgpanel main.cxx + FGGLApplication.cxx + FGPanelApplication.cxx + FGPNGTextureLoader.cxx + FGRGBTextureLoader.cxx + FGPanelProtocol.cxx + FGFontCache.cxx + panel.cxx + panel_io.cxx) + +target_link_libraries(fgpanel + ${PNG_LIBRARIES} + ${GLUT_LIBRARIES} + ${SIMGEAR_LIBRARIES} + ${OPENGL_LIBRARIES} + ${ZLIB_LIBRARIES} + ${PLIB_LIBRARIES} + ) + +install(TARGETS fgpanel RUNTIME DESTINATION bin) From 7ebc68b3c71d0ff2a629263fc12cf7d890165cc3 Mon Sep 17 00:00:00 2001 From: Torsten Dreyer <torsten@mustang.home.t3r.de> Date: Sun, 5 Jun 2011 17:10:04 +0200 Subject: [PATCH 07/48] Fix a data type mismatch --- utils/fgpanel/FGPanelApplication.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/fgpanel/FGPanelApplication.cxx b/utils/fgpanel/FGPanelApplication.cxx index 0477be7e2..b58700477 100644 --- a/utils/fgpanel/FGPanelApplication.cxx +++ b/utils/fgpanel/FGPanelApplication.cxx @@ -103,7 +103,7 @@ FGPanelApplication::FGPanelApplication( int argc, char ** argv ) : string arg = argv[i]; if( arg.find( "--prop:" ) == 0 ) { string s2 = arg.substr( 7 ); - unsigned p = s2.find( "=" ); + string::size_type p = s2.find( "=" ); if( p != string::npos ) { string propertyName = s2.substr( 0, p ); string propertyValue = s2.substr( p+1 ); From 3d36577a20606e0ece4e74504c78e6a680289cf5 Mon Sep 17 00:00:00 2001 From: Torsten Dreyer <Torsten@t3r.de> Date: Sun, 5 Jun 2011 21:08:44 +0200 Subject: [PATCH 08/48] Make cmake for fgpanel work under linux --- utils/fgpanel/CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/utils/fgpanel/CMakeLists.txt b/utils/fgpanel/CMakeLists.txt index e770d76f1..90dc2f2d9 100644 --- a/utils/fgpanel/CMakeLists.txt +++ b/utils/fgpanel/CMakeLists.txt @@ -1,7 +1,7 @@ -#FIXME: does this work in *nix/windows? -find_package(png REQUIRED) +#FIXME: does this work in windows? +find_package(PNG REQUIRED) find_package(OpenGL REQUIRED) -find_package(glut REQUIRED) +find_package(GLUT REQUIRED) add_executable(fgpanel main.cxx FGGLApplication.cxx From 2d0d434ffa0919e214537a73c599629228cf26e1 Mon Sep 17 00:00:00 2001 From: Torsten Dreyer <Torsten@t3r.de> Date: Sun, 5 Jun 2011 21:38:44 +0200 Subject: [PATCH 09/48] cmake: check for SimGear 2.3.0 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 06f3517b3..ae3117a14 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -130,7 +130,7 @@ if(ENABLE_LIBSVN) endif(ENABLE_LIBSVN) find_package(PLIB REQUIRED puaux pu js fnt) -find_package(SimGear 2.2.0 REQUIRED) +find_package(SimGear 2.3.0 REQUIRED) check_include_file(unistd.h HAVE_UNISTD_H) check_include_file(sys/time.h HAVE_SYS_TIME_H) From 8b6779aa967886142b59b14d9b0898673a4e0e7c Mon Sep 17 00:00:00 2001 From: Vivian Meazza <vivian.meazza@lineone.net> Date: Mon, 6 Jun 2011 09:32:00 +0100 Subject: [PATCH 10/48] Bugfix: set life timer to 0 on instantiation and when ballistic object dies. Signed-off-by: Vivian Meazza <vivian.meazza@lineone.net> --- src/AIModel/AIBallistic.cxx | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/AIModel/AIBallistic.cxx b/src/AIModel/AIBallistic.cxx index d31e3b46d..b3e3bceb5 100644 --- a/src/AIModel/AIBallistic.cxx +++ b/src/AIModel/AIBallistic.cxx @@ -143,6 +143,8 @@ bool FGAIBallistic::init(bool search_in_AI_path) { _elapsed_time += (sg_random() * 100); + _life_timer = 0; + props->setStringValue("material/name", ""); props->setStringValue("name", _name.c_str()); props->setStringValue("submodels/path", _path.c_str()); @@ -152,6 +154,9 @@ bool FGAIBallistic::init(bool search_in_AI_path) { props->setStringValue("contents/path", _contents_path.c_str()); } + //cout << "init: name " << _name.c_str() << " _life_timer " << _life_timer + // << endl; + //if(_parent != ""){ // setParentNode(); //} @@ -330,7 +335,7 @@ void FGAIBallistic::setLife(double seconds) { if (_random){ life = seconds * _randomness + (seconds * (1 -_randomness) * sg_random()); - //cout << "life " << life << endl; + //cout << " set life " << life << endl; } else life = seconds; } @@ -670,15 +675,23 @@ void FGAIBallistic::slaveToAC(double dt){ void FGAIBallistic::Run(double dt) { _life_timer += dt; + + //_pass += 1; + //cout<<"AIBallistic run: name " << _name.c_str() + // << " dt " << dt << " _life_timer " << _life_timer << " pass " << _pass << endl; // if life = -1 the object does not die if (_life_timer > life && life != -1){ if (_report_expiry && !_expiry_reported && !_impact_reported && !_collision_reported){ - //cout<<"AIBallistic: expiry"<< endl; + //cout<<"AIBallistic run: name " << _name.c_str() << " expiry " << " pass " << _pass <<endl; handle_expiry(); - } else + } else{ + //cout<<"AIBallistic run: name " << _name.c_str() + // << " die " << " _life_timer " << _life_timer << " pass " << _pass << endl; setDie(true); + setTime(0); + } } @@ -1010,7 +1023,7 @@ void FGAIBallistic::report_impact(double elevation, const FGAIBase *object) n->setStringValue("type", "terrain"); SG_LOG(SG_GENERAL, SG_DEBUG, "AIBallistic: object impact " << _name - << " lon " <<_impact_lon << " lat " <<_impact_lat); + << " lon " <<_impact_lon << " lat " <<_impact_lat << " sec " << _life_timer); n->setDoubleValue("longitude-deg", _impact_lon); n->setDoubleValue("latitude-deg", _impact_lat); From db7112c20b24ff2d9a2c8f3011d5f6a06fe7853e Mon Sep 17 00:00:00 2001 From: ThorstenB <brehmt@gmail.com> Date: Mon, 6 Jun 2011 19:53:21 +0200 Subject: [PATCH 11/48] Remove stray space Thanks to Vivian - make MSVC9 happy again. --- src/Main/main.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Main/main.cxx b/src/Main/main.cxx index bc17b04b0..58883a886 100644 --- a/src/Main/main.cxx +++ b/src/Main/main.cxx @@ -621,7 +621,7 @@ int fgMainInit( int argc, char **argv ) { cerr << endl << "Base package check failed:" << endl \ << " Version " << base_version << " found at: " \ << globals->get_fg_root() << endl \ - << " Version " << required_version << " is required." << endl \ + << " Version " << required_version << " is required." << endl \ << "Please upgrade/downgrade base package." << endl; #ifdef _MSC_VER cerr << "Hit a key to continue..." << endl; From c618097e83da1729e89b4aa8df6f00e7dc6be6a9 Mon Sep 17 00:00:00 2001 From: Torsten Dreyer <Torsten@t3r.de> Date: Wed, 8 Jun 2011 16:01:23 +0200 Subject: [PATCH 12/48] Make fgadmin compile under linux missing string.h for str(n)cmp --- utils/fgadmin/src/main.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/fgadmin/src/main.cxx b/utils/fgadmin/src/main.cxx index 1c743ffa1..d40a0578c 100644 --- a/utils/fgadmin/src/main.cxx +++ b/utils/fgadmin/src/main.cxx @@ -28,7 +28,7 @@ #include <string> #include <FL/Fl.H> #include <FL/filename.H> - +#include <string.h> #include "fgadmin.h" using std::string; From b7656b527583ef68f1891786c1d08477b5bbf206 Mon Sep 17 00:00:00 2001 From: Torsten Dreyer <Torsten@t3r.de> Date: Wed, 8 Jun 2011 16:02:07 +0200 Subject: [PATCH 13/48] Change SimGear library order for fgadmin --- CMakeModules/FindSimGear.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeModules/FindSimGear.cmake b/CMakeModules/FindSimGear.cmake index 88fb177a2..249afb3bc 100644 --- a/CMakeModules/FindSimGear.cmake +++ b/CMakeModules/FindSimGear.cmake @@ -135,8 +135,8 @@ if(${SIMGEAR_LIBRARIES} STREQUAL "SIMGEAR_LIBRARIES-NOTFOUND") structure props xml - debug misc + debug magvar math) From bad5fbf66aaeb52ac189258c18dedbf0d3d25904 Mon Sep 17 00:00:00 2001 From: Torsten Dreyer <Torsten@t3r.de> Date: Wed, 8 Jun 2011 20:17:40 +0200 Subject: [PATCH 14/48] Use computed gravity instead of hardcoded value --- src/AIModel/AIBallistic.cxx | 7 ++++--- src/AIModel/AIBallistic.hxx | 1 - 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/AIModel/AIBallistic.cxx b/src/AIModel/AIBallistic.cxx index b3e3bceb5..69e090e3d 100644 --- a/src/AIModel/AIBallistic.cxx +++ b/src/AIModel/AIBallistic.cxx @@ -32,6 +32,7 @@ #include "AIBallistic.hxx" #include <Main/util.hxx> +#include <Environment/gravity.hxx> using namespace simgear; @@ -51,7 +52,6 @@ _elapsed_time(0), _aero_stabilised(false), _drag_area(0.007), _life_timer(0.0), -_gravity(32.1740485564), _buoyancy(0), _wind(true), _mass(0), @@ -727,7 +727,7 @@ void FGAIBallistic::Run(double dt) { if ( speed < 0.0 ) speed = 0.0; - double speed_fps = speed * SG_KT_TO_FPS; +// double speed_fps = speed * SG_KT_TO_FPS; // calculate vertical and horizontal speed components calcVSHS(); @@ -858,7 +858,8 @@ void FGAIBallistic::Run(double dt) { hs = 0; // adjust vertical speed for acceleration of gravity, buoyancy, and vertical force - vs -= (_gravity - _buoyancy - v_force_acc_fpss - normal_force_fpss) * dt; + double gravity = Environment::Gravity::instance()->getGravity(pos); + vs -= (gravity - _buoyancy - v_force_acc_fpss - normal_force_fpss) * dt; if (vs <= 0.00001 && vs >= -0.00001) vs = 0; diff --git a/src/AIModel/AIBallistic.hxx b/src/AIModel/AIBallistic.hxx index fb1b4f28d..f798347c9 100644 --- a/src/AIModel/AIBallistic.hxx +++ b/src/AIModel/AIBallistic.hxx @@ -175,7 +175,6 @@ private: bool _aero_stabilised; // if true, object will align with trajectory double _drag_area; // equivalent drag area in ft2 double _life_timer; // seconds - double _gravity; // fps^2 double _buoyancy; // fps^2 bool _wind; // if true, local wind will be applied to object double _Cd; // drag coefficient From a8778b232c8a9ea21748798cf80945c962e41bbd Mon Sep 17 00:00:00 2001 From: ThorstenB <brehmt@gmail.com> Date: Sat, 11 Jun 2011 15:29:50 +0200 Subject: [PATCH 15/48] issue #61: built-in svn broken for automake builds Thanks to "j...@flygarna.se" --- configure.ac | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index b64b972ff..693740442 100644 --- a/configure.ac +++ b/configure.ac @@ -826,8 +826,11 @@ if test "x$with_libsvn" = "xyes"; then AC_CHECK_HEADERS([svn_client.h]) if test "x$ac_cv_header_svn_client_h" = "xyes"; then echo "TerraSync will use libsvn" - AC_SEARCH_LIBS(svn_client_checkout, svn_client-1) - AC_SEARCH_LIBS(svn_cmdline_init, svn_subr-1) + AC_SEARCH_LIBS(svn_client_checkout, svn_client-1, + [AC_DEFINE([HAVE_LIBSVN_CLIENT_1], [1], [Define to 1 if you have libsvn_client-1])], + [AC_MSG_ERROR(svn_client-1 library not found.)],) + AC_SEARCH_LIBS(svn_cmdline_init, svn_subr-1, , [AC_MSG_ERROR(svn_subr-1 library not found.)],) + AC_SEARCH_LIBS(svn_ra_initialize, svn_ra-1, , [AC_MSG_ERROR(svn_ra-1 library not found.)],) svn_LIBS=$LIBS svn_CPPFLAGS=$CPPFLAGS AC_SUBST(svn_LIBS) From 50479f47f38669211a9286b743d371172a0e1b2f Mon Sep 17 00:00:00 2001 From: ThorstenB <brehmt@gmail.com> Date: Sun, 12 Jun 2011 00:12:39 +0200 Subject: [PATCH 16/48] git ignore debug directory --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 98517f567..1ff6ff74d 100644 --- a/.gitignore +++ b/.gitignore @@ -12,5 +12,6 @@ depcomp install-sh missing INSTALL +Debug/ *.o lib*.a From ee40e8ae3f9d50a1cc140f3452991f731e55cc2e Mon Sep 17 00:00:00 2001 From: ThorstenB <brehmt@gmail.com> Date: Sun, 12 Jun 2011 00:44:07 +0200 Subject: [PATCH 17/48] Introduce terrasync subsystem. Fix tile reloading issue. --- CMakeLists.txt | 2 +- configure.ac | 8 ++++---- src/Main/CMakeLists.txt | 2 +- src/Main/Makefile.am | 5 +++-- src/Main/main.cxx | 3 +++ src/Main/options.cxx | 3 +++ src/Scenery/tilemgr.cxx | 36 ++++++++++++++++++++++++------------ src/Scenery/tilemgr.hxx | 7 +++++++ 8 files changed, 46 insertions(+), 20 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ae3117a14..293d8b41f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -55,7 +55,7 @@ option(ENABLE_YASIM "Set to ON to build FlightGear with YASIM FDM" ON) option(ENABLE_JSBSIM "Set to ON to build FlightGear with JSBSim FDM" ON) option(ENABLE_FGADMIN "Set to ON to build FlightGear with FGADMIN" ON) option(EVENT_INPUT "Set to ON to build FlightGear with event-based Input support" OFF) -option(ENABLE_LIBSVN "Set to ON to build terrasync with libsvnclient support" OFF) +option(ENABLE_LIBSVN "Set to ON to build FlightGear/terrasync with libsvnclient support" OFF) set(MSVC_3RDPARTY_ROOT NOT_FOUND CACHE PATH "Location where the third-party dependencies are extracted") diff --git a/configure.ac b/configure.ac index 693740442..179d63f51 100644 --- a/configure.ac +++ b/configure.ac @@ -819,13 +819,13 @@ dnl Check for Subversion library support # libsvn support defaults to yes save_LIBS=$LIBS save_CPPFLAGS=$CPPFLAGS -AC_ARG_WITH(libsvn, [ --without-libsvn Do not use libsvn for terrasync [default=no]], [], [with_libsvn=yes]) +AC_ARG_WITH(libsvn, [ --without-libsvn Do not use built-in subversion (libsvn) for terrasync/fgfs [default=no]], [], [with_libsvn=yes]) if test "x$with_libsvn" = "xyes"; then LIBS="`apr-1-config --link-ld`" CPPFLAGS="-I/usr/include/subversion-1 `apr-1-config --includes --cppflags`" AC_CHECK_HEADERS([svn_client.h]) if test "x$ac_cv_header_svn_client_h" = "xyes"; then - echo "TerraSync will use libsvn" + echo "Using built-in subversion (libsvn) for scenery downloads." AC_SEARCH_LIBS(svn_client_checkout, svn_client-1, [AC_DEFINE([HAVE_LIBSVN_CLIENT_1], [1], [Define to 1 if you have libsvn_client-1])], [AC_MSG_ERROR(svn_client-1 library not found.)],) @@ -836,12 +836,12 @@ if test "x$with_libsvn" = "xyes"; then AC_SUBST(svn_LIBS) AC_SUBST(svn_CPPFLAGS) else - echo "Libsvn not found. TerraSync will use command line subversion" + echo "Libsvn not found. Will use command line subversion for scenery downloads." svn_LIBS="" svn_CPPFLAGS="" fi else -echo "Libsvn explicitly disabled. TerraSync will use command line subversion" +echo "Libsvn explicitly disabled. Will use command line subversion for scenery downloads." svn_LIBS="" svn_CPPFLAGS="" fi diff --git a/src/Main/CMakeLists.txt b/src/Main/CMakeLists.txt index 954c020bc..d28d78d26 100644 --- a/src/Main/CMakeLists.txt +++ b/src/Main/CMakeLists.txt @@ -49,7 +49,7 @@ endif() target_link_libraries(fgfs ${FG_LIBS} - ${HLA_LIBRARIES} + ${HLA_LIBRARIES} ${SIMGEAR_LIBRARIES} ${OPENSCENEGRAPH_LIBRARIES} ${OPENAL_LIBRARY} diff --git a/src/Main/Makefile.am b/src/Main/Makefile.am index c4525ed8b..65d2ccd3b 100644 --- a/src/Main/Makefile.am +++ b/src/Main/Makefile.am @@ -113,7 +113,7 @@ fgfs_LDADD = \ -lsgroute -lsgsky -lsgsound -lsgephem -lsgtgdb -lsgmodel -lsgbvh \ -lsgmaterial -lsgutil -lsgtiming -lsgio -lsgscreen -lsgmath -lsgbucket \ -lsgprops -lsgdebug -lsgmagvar -lsgmisc -lsgnasal -lsgxml -lsgsound \ - -lsgserial -lsgstructure -lsgenvironment \ + -lsgserial -lsgstructure -lsgenvironment -lsgtsync\ $(fgfs_PLIB_LIBS) \ $(OSG_LIBS) \ $(thread_LIBS) \ @@ -121,7 +121,8 @@ fgfs_LDADD = \ -lz \ $(opengl_LIBS) \ $(openal_LIBS) \ - $(EVENT_LIBS) + $(EVENT_LIBS) \ + $(svn_LIBS) fgfs_LDFLAGS = $(fgfs_PLIB_FW) $(fgfs_OSG_FW) $(LDFLAGS) diff --git a/src/Main/main.cxx b/src/Main/main.cxx index 58883a886..1c4a7410f 100644 --- a/src/Main/main.cxx +++ b/src/Main/main.cxx @@ -50,6 +50,7 @@ #include <simgear/magvar/magvar.hxx> #include <simgear/math/sg_random.h> #include <simgear/io/raw_socket.hxx> +#include <simgear/scene/tsync/terrasync.hxx> #include <simgear/misc/sg_sleep.hxx> #include <Time/light.hxx> @@ -394,6 +395,8 @@ static void fgIdleFunction ( void ) { //////////////////////////////////////////////////////////////////// // Initialize the TG scenery subsystem. //////////////////////////////////////////////////////////////////// + simgear::SGTerraSync* terra_sync = new simgear::SGTerraSync(globals->get_props()); + globals->add_subsystem("terrasync", terra_sync); globals->set_scenery( new FGScenery ); globals->get_scenery()->init(); globals->get_scenery()->bind(); diff --git a/src/Main/options.cxx b/src/Main/options.cxx index 01f1e4438..342412e53 100644 --- a/src/Main/options.cxx +++ b/src/Main/options.cxx @@ -1390,6 +1390,9 @@ struct OptionDesc { {"texture-filtering", false, OPTION_INT, "/sim/rendering/filtering", 1, "", 0 }, {"disable-wireframe", false, OPTION_BOOL, "/sim/rendering/wireframe", false, "", 0 }, {"enable-wireframe", false, OPTION_BOOL, "/sim/rendering/wireframe", true, "", 0 }, + {"disable-terrasync", false, OPTION_BOOL, "/sim/terrasync/enabled", false, "", 0 }, + {"enable-terrasync", false, OPTION_BOOL, "/sim/terrasync/enabled", true, "", 0 }, + {"terrasync-dir", false, OPTION_STRING, "/sim/terrasync/scenery-dir", false, "", 0 }, {"geometry", true, OPTION_FUNC, "", false, "", fgOptGeometry }, {"bpp", true, OPTION_FUNC, "", false, "", fgOptBpp }, {"units-feet", false, OPTION_STRING, "/sim/startup/units", false, "feet", 0 }, diff --git a/src/Scenery/tilemgr.cxx b/src/Scenery/tilemgr.cxx index 7b59d60b0..efdd83856 100644 --- a/src/Scenery/tilemgr.cxx +++ b/src/Scenery/tilemgr.cxx @@ -35,6 +35,7 @@ #include <simgear/structure/exception.hxx> #include <simgear/scene/model/modellib.hxx> #include <simgear/scene/tgdb/SGReaderWriterBTGOptions.hxx> +#include <simgear/scene/tsync/terrasync.hxx> #include <Main/globals.hxx> #include <Main/fg_props.hxx> @@ -75,14 +76,20 @@ private: FGTileMgr::FGTileMgr(): state( Start ), vis( 16000 ), - _propListener(new LoaderPropertyWatcher(this)) + _propListener(new LoaderPropertyWatcher(this)), + _terra_sync(NULL) { _randomObjects = fgGetNode("/sim/rendering/random-objects", true); _randomVegetation = fgGetNode("/sim/rendering/random-vegetation", true); + _maxTileRangeM = fgGetNode("/sim/rendering/static-lod/bare", true); } -FGTileMgr::~FGTileMgr() { +FGTileMgr::~FGTileMgr() +{ + if (_terra_sync) + _terra_sync->setTileCache(NULL); + // remove all nodes we might have left behind osg::Group* group = globals->get_scenery()->get_terrain_branch(); group->removeChildren(0, group->getNumChildren()); @@ -135,7 +142,11 @@ void FGTileMgr::reinit() previous_bucket.make_bad(); current_bucket.make_bad(); longitude = latitude = -1000.0; - + + _terra_sync = (simgear::SGTerraSync*) globals->get_subsystem("terrasync"); + if (_terra_sync) + _terra_sync->setTileCache(&tile_cache); + // force an update now update(0.0); } @@ -189,10 +200,7 @@ void FGTileMgr::schedule_needed(const SGBucket& curr_bucket, double vis) SG_LOG( SG_TERRAIN, SG_ALERT, "Attempting to schedule tiles for bogus lon and lat = (" << longitude << "," << latitude << ")" ); - return; // FIXME - SG_LOG( SG_TERRAIN, SG_ALERT, - "This is a FATAL error. Exiting!" ); - exit(-1); + return; } SG_LOG( SG_TERRAIN, SG_INFO, @@ -203,8 +211,9 @@ void FGTileMgr::schedule_needed(const SGBucket& curr_bucket, double vis) // cout << "tile width = " << tile_width << " tile_height = " // << tile_height << endl; - xrange = (int)(vis / tile_width) + 1; - yrange = (int)(vis / tile_height) + 1; + double tileRangeM = min(vis,_maxTileRangeM->getDoubleValue()); + xrange = (int)(tileRangeM / tile_width) + 1; + yrange = (int)(tileRangeM / tile_height) + 1; if ( xrange < 1 ) { xrange = 1; } if ( yrange < 1 ) { yrange = 1; } @@ -309,7 +318,8 @@ void FGTileMgr::update_queues() e->prep_ssg_node(vis); if (( !e->is_loaded() )&& - ( !e->is_expired(current_time) )) + ((!e->is_expired(current_time))|| + e->is_current_view() )) { // schedule tile for loading with osg pager pager->queueRequest(e->tileFileName, @@ -322,7 +332,7 @@ void FGTileMgr::update_queues() } } else { - SG_LOG(SG_INPUT, SG_ALERT, "warning ... empty tile in cache"); + SG_LOG(SG_INPUT, SG_ALERT, "Warning: empty tile in cache!"); } tile_cache.next(); sz++; @@ -388,7 +398,7 @@ int FGTileMgr::schedule_tiles_at(const SGGeod& location, double range_m) // << current_bucket ); fgSetInt( "/environment/current-tile-id", current_bucket.gen_index() ); - // do tile load scheduling. + // do tile load scheduling. // Note that we need keep track of both viewer buckets and fdm buckets. if ( state == Running ) { SG_LOG( SG_TERRAIN, SG_DEBUG, "State == Running" ); @@ -398,6 +408,8 @@ int FGTileMgr::schedule_tiles_at(const SGGeod& location, double range_m) SG_LOG( SG_TERRAIN, SG_INFO, "FGTileMgr::update()" ); scheduled_visibility = range_m; schedule_needed(current_bucket, range_m); + if (_terra_sync) + _terra_sync->schedulePosition(latitude,longitude); } // save bucket previous_bucket = current_bucket; diff --git a/src/Scenery/tilemgr.hxx b/src/Scenery/tilemgr.hxx index 6b4a4e7ef..2c6648182 100644 --- a/src/Scenery/tilemgr.hxx +++ b/src/Scenery/tilemgr.hxx @@ -38,6 +38,11 @@ namespace osg class Node; } +namespace simgear +{ +class SGTerraSync; +} + class FGTileMgr : public SGSubsystem, public simgear::ModelLoadHelper { private: @@ -75,6 +80,7 @@ private: * tile cache */ simgear::TileCache tile_cache; + simgear::SGTerraSync* _terra_sync; // Update the various queues maintained by the tilemagr (private // internal function, do not call directly.) @@ -84,6 +90,7 @@ private: SGPropertyChangeListener* _propListener; SGPropertyNode_ptr _randomObjects; SGPropertyNode_ptr _randomVegetation; + SGPropertyNode_ptr _maxTileRangeM; public: FGTileMgr(); From 2d723d0e13723657a668d2b0075d3caabf42908c Mon Sep 17 00:00:00 2001 From: Mathias Froehlich <Mathias.Froehlich@web.de> Date: Sun, 12 Jun 2011 08:29:49 +0200 Subject: [PATCH 18/48] Fix linking with -lsgtsync with cmake. --- CMakeModules/FindSimGear.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeModules/FindSimGear.cmake b/CMakeModules/FindSimGear.cmake index 249afb3bc..b8c446bba 100644 --- a/CMakeModules/FindSimGear.cmake +++ b/CMakeModules/FindSimGear.cmake @@ -117,6 +117,7 @@ if(${SIMGEAR_LIBRARIES} STREQUAL "SIMGEAR_LIBRARIES-NOTFOUND") # linker such as GNU ld on Linux set(comps ephem + tsync environment nasal sky From d767fe169681dafa446a461cdb191684a5ef9dfa Mon Sep 17 00:00:00 2001 From: ThorstenB <brehmt@gmail.com> Date: Sun, 12 Jun 2011 13:45:10 +0200 Subject: [PATCH 19/48] Avoid compiler warning. --- src/Scenery/tilemgr.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Scenery/tilemgr.cxx b/src/Scenery/tilemgr.cxx index efdd83856..dae8cb3b5 100644 --- a/src/Scenery/tilemgr.cxx +++ b/src/Scenery/tilemgr.cxx @@ -76,8 +76,8 @@ private: FGTileMgr::FGTileMgr(): state( Start ), vis( 16000 ), - _propListener(new LoaderPropertyWatcher(this)), - _terra_sync(NULL) + _terra_sync(NULL), + _propListener(new LoaderPropertyWatcher(this)) { _randomObjects = fgGetNode("/sim/rendering/random-objects", true); _randomVegetation = fgGetNode("/sim/rendering/random-vegetation", true); From 505d4c5219bf46b4ec640f5dd903dda58ae7a09b Mon Sep 17 00:00:00 2001 From: ThorstenB <brehmt@gmail.com> Date: Sun, 12 Jun 2011 13:53:14 +0200 Subject: [PATCH 20/48] Do not reset persistent properties on sim-reset. Fixed ugly sim-reset issue: Persistent properties (USERARCHIVE attribute) are retained across sim sessions (when restarting the sim). So they should also be retained on sim-resets (without the need to first exit/restart the sim to make them really persistent). Also, avoid warning due to read-only properties. --- src/Main/globals.cxx | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/Main/globals.cxx b/src/Main/globals.cxx index b7d9b7d6d..62ae38ffa 100644 --- a/src/Main/globals.cxx +++ b/src/Main/globals.cxx @@ -364,7 +364,10 @@ FGGlobals::saveInitialState () { initial_state = new SGPropertyNode(); - if (!copyProperties(props, initial_state)) + // copy properties which are READ/WRITEable - but not USERARCHIVEd + if (!copyProperties(props, initial_state, + SGPropertyNode::READ+SGPropertyNode::WRITE, + SGPropertyNode::READ+SGPropertyNode::WRITE+SGPropertyNode::USERARCHIVE)) SG_LOG(SG_GENERAL, SG_ALERT, "Error saving initial state"); // delete various properties from the initial state, since we want to @@ -393,8 +396,10 @@ FGGlobals::restoreInitialState () "No initial state available to restore!!!"); return; } - - if ( copyProperties(initial_state, props) ) { + // restore properties which are READ/WRITEable - but not USERARCHIVEd + if ( copyProperties(initial_state, props, + SGPropertyNode::READ+SGPropertyNode::WRITE, + SGPropertyNode::READ+SGPropertyNode::WRITE+SGPropertyNode::USERARCHIVE)) { SG_LOG( SG_GENERAL, SG_INFO, "Initial state restored successfully" ); } else { SG_LOG( SG_GENERAL, SG_INFO, From 7d92bd3a1adf559c102f522b27ff789cf518edf7 Mon Sep 17 00:00:00 2001 From: ThorstenB <brehmt@gmail.com> Date: Sun, 12 Jun 2011 15:17:03 +0200 Subject: [PATCH 21/48] Martin Spott: fixed sh-like variable in CMakeLists.txt --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 293d8b41f..d2c50db06 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -65,7 +65,7 @@ else() set(FG_NDEBUG 1) endif() -if(${SP_FDMS}) +if(SP_FDMS) set(ENABLE_SP_FDM 1) endif() From 88f7c0527409263be766760e3bbca7f6fb60b418 Mon Sep 17 00:00:00 2001 From: ThorstenB <brehmt@gmail.com> Date: Sun, 12 Jun 2011 20:31:56 +0200 Subject: [PATCH 22/48] Introduce "PRESERVE" flag to protect properties on sim reset. Some specific properties need protection and shouldn't be restored to their original values on sim-reset. --- src/GUI/property_list.cxx | 8 ++++++++ src/Main/globals.cxx | 26 ++++++++++++-------------- src/Scripting/NasalSys.cxx | 4 +++- src/Scripting/nasal-props.cxx | 2 ++ 4 files changed, 25 insertions(+), 15 deletions(-) diff --git a/src/GUI/property_list.cxx b/src/GUI/property_list.cxx index 5bcb46a35..7940ca28f 100644 --- a/src/GUI/property_list.cxx +++ b/src/GUI/property_list.cxx @@ -343,6 +343,8 @@ void PropertyList::updateTextForEntry(NodeData& data) ext += 'A'; if (node->getAttribute(SGPropertyNode::USERARCHIVE)) ext += 'U'; + if (node->getAttribute(SGPropertyNode::PRESERVE)) + ext += 'P'; if (node->isTied()) ext += 'T'; @@ -357,6 +359,12 @@ void PropertyList::updateTextForEntry(NodeData& data) } line << ')'; } + else + if ((_verbose)&&(node->getAttribute(SGPropertyNode::PRESERVE))) + { + // only preserve/protection flag matters for nodes without values + line << " (P)"; + } stdString out = line.str(); if (out.size() >= PUSTRING_MAX) diff --git a/src/Main/globals.cxx b/src/Main/globals.cxx index 62ae38ffa..9ed3a6b56 100644 --- a/src/Main/globals.cxx +++ b/src/Main/globals.cxx @@ -364,21 +364,18 @@ FGGlobals::saveInitialState () { initial_state = new SGPropertyNode(); - // copy properties which are READ/WRITEable - but not USERARCHIVEd - if (!copyProperties(props, initial_state, - SGPropertyNode::READ+SGPropertyNode::WRITE, - SGPropertyNode::READ+SGPropertyNode::WRITE+SGPropertyNode::USERARCHIVE)) + // copy properties which are READ/WRITEable - but not USERARCHIVEd or PRESERVEd + int checked = SGPropertyNode::READ+SGPropertyNode::WRITE+ + SGPropertyNode::USERARCHIVE+SGPropertyNode::PRESERVE; + int expected = SGPropertyNode::READ+SGPropertyNode::WRITE; + if (!copyProperties(props, initial_state, expected, checked)) SG_LOG(SG_GENERAL, SG_ALERT, "Error saving initial state"); // delete various properties from the initial state, since we want to // preserve their values even if doing a restore - + // => Properties should now use the PRESERVE flag to protect their values + // on sim-reset. Remove some specific properties for backward compatibility. SGPropertyNode* sim = initial_state->getChild("sim"); - sim->removeChild("presets"); - SGPropertyNode* simStartup = sim->getChild("startup"); - simStartup->removeChild("xsize"); - simStartup->removeChild("ysize"); - SGPropertyNode* cameraGroupNode = sim->getNode("rendering/camera-group"); if (cameraGroupNode) { cameraGroupNode->removeChild("camera"); @@ -396,10 +393,11 @@ FGGlobals::restoreInitialState () "No initial state available to restore!!!"); return; } - // restore properties which are READ/WRITEable - but not USERARCHIVEd - if ( copyProperties(initial_state, props, - SGPropertyNode::READ+SGPropertyNode::WRITE, - SGPropertyNode::READ+SGPropertyNode::WRITE+SGPropertyNode::USERARCHIVE)) { + // copy properties which are READ/WRITEable - but not USERARCHIVEd or PRESERVEd + int checked = SGPropertyNode::READ+SGPropertyNode::WRITE+ + SGPropertyNode::USERARCHIVE+SGPropertyNode::PRESERVE; + int expected = SGPropertyNode::READ+SGPropertyNode::WRITE; + if ( copyProperties(initial_state, props, expected, checked)) { SG_LOG( SG_GENERAL, SG_INFO, "Initial state restored successfully" ); } else { SG_LOG( SG_GENERAL, SG_INFO, diff --git a/src/Scripting/NasalSys.cxx b/src/Scripting/NasalSys.cxx index af67ae368..9542c5d55 100644 --- a/src/Scripting/NasalSys.cxx +++ b/src/Scripting/NasalSys.cxx @@ -914,7 +914,9 @@ void FGNasalSys::loadPropertyScripts(SGPropertyNode* n) enable->addChangeListener(listener, false); } } - n->setBoolValue("loaded",is_loaded); + SGPropertyNode* loaded = n->getChild("loaded",0,true); + loaded->setAttribute(SGPropertyNode::PRESERVE,true); + loaded->setBoolValue(is_loaded); } // Logs a runtime error, with stack trace, to the FlightGear log stream diff --git a/src/Scripting/nasal-props.cxx b/src/Scripting/nasal-props.cxx index 214cc5c9a..15a3016f3 100644 --- a/src/Scripting/nasal-props.cxx +++ b/src/Scripting/nasal-props.cxx @@ -103,6 +103,7 @@ static naRef f_getAttribute(naContext c, naRef me, int argc, naRef* args) else if(!strcmp(a, "trace-read")) attr = SGPropertyNode::TRACE_READ; else if(!strcmp(a, "trace-write")) attr = SGPropertyNode::TRACE_WRITE; else if(!strcmp(a, "userarchive")) attr = SGPropertyNode::USERARCHIVE; + else if(!strcmp(a, "preserve")) attr = SGPropertyNode::PRESERVE; else { naRuntimeError(c, "props.getAttribute() with invalid attribute"); return naNil(); @@ -128,6 +129,7 @@ static naRef f_setAttribute(naContext c, naRef me, int argc, naRef* args) else if(!strcmp(a, "trace-read")) attr = SGPropertyNode::TRACE_READ; else if(!strcmp(a, "trace-write")) attr = SGPropertyNode::TRACE_WRITE; else if(!strcmp(a, "userarchive")) attr = SGPropertyNode::USERARCHIVE; + else if(!strcmp(a, "preserve")) attr = SGPropertyNode::PRESERVE; else { naRuntimeError(c, "props.setAttribute() with invalid attribute"); return naNil(); From 76ffb086ebf5d9f16b894229f32c770d4b345f68 Mon Sep 17 00:00:00 2001 From: ThorstenB <brehmt@gmail.com> Date: Sun, 12 Jun 2011 21:04:16 +0200 Subject: [PATCH 23/48] Betrand Coconnier: fix for issue #220 for JSBSim a/c Modifying /position/altitude-ft did not change a/c position --- src/FDM/JSBSim/JSBSim.cxx | 426 ++++++++++++++++++++------------------ src/FDM/JSBSim/JSBSim.hxx | 9 +- 2 files changed, 236 insertions(+), 199 deletions(-) diff --git a/src/FDM/JSBSim/JSBSim.cxx b/src/FDM/JSBSim/JSBSim.cxx index 54ed59872..3e6cdf7bd 100644 --- a/src/FDM/JSBSim/JSBSim.cxx +++ b/src/FDM/JSBSim/JSBSim.cxx @@ -407,6 +407,33 @@ void FGJSBsim::init() globals->get_controls()->set_mixture(i, FCS->GetMixtureCmd(i)); } } + + if ( startup_trim->getBoolValue() ) { + FGLocation cart(fgic->GetLongitudeRadIC(), fgic->GetLatitudeRadIC(), + fgic->GetSeaLevelRadiusFtIC() + fgic->GetAltitudeASLFtIC()); + double cart_pos[3], contact[3], d[3], vel[3], agl; + update_ground_cache(cart, cart_pos, 0.01); + + get_agl_ft(fdmex->GetSimTime(), cart_pos, SG_METER_TO_FEET*2, contact, + d, vel, d, &agl); + double terrain_alt = sqrt(contact[0]*contact[0] + contact[1]*contact[1] + + contact[2]*contact[2]) - fgic->GetSeaLevelRadiusFtIC(); + + SG_LOG(SG_FLIGHT, SG_INFO, "Ready to trim, terrain elevation is: " + << terrain_alt * SG_METER_TO_FEET ); + + if (fgGetBool("/sim/presets/onground")) { + FGColumnVector3 gndVelNED = cart.GetTec2l() + * FGColumnVector3(vel[0], vel[1], vel[2]); + fgic->SetVNorthFpsIC(gndVelNED(1)); + fgic->SetVEastFpsIC(gndVelNED(2)); + fgic->SetVDownFpsIC(gndVelNED(3)); + } + fgic->SetTerrainElevationFtIC( terrain_alt ); + do_trim(); + needTrim = false; + } + copy_from_JSBsim(); //update the bus SG_LOG( SG_FLIGHT, SG_INFO, " Initialized JSBSim with:" ); @@ -483,88 +510,18 @@ void FGJSBsim::update( double dt ) return; int multiloop = _calc_multiloop(dt); - - int i; - - // Compute the radius of the aircraft. That is the radius of a ball - // where all gear units are in. At the moment it is at least 10ft ... - double acrad = 10.0; - int n_gears = GroundReactions->GetNumGearUnits(); - for (i=0; i<n_gears; ++i) { - FGColumnVector3 bl = GroundReactions->GetGearUnit(i)->GetBodyLocation(); - double r = bl.Magnitude(); - if (acrad < r) - acrad = r; - } - - // Compute the potential movement of this aircraft and query for the - // ground in this area. - double groundCacheRadius = acrad + 2*dt*Propagate->GetUVW().Magnitude(); - double alt, slr, lat, lon; FGLocation cart = Auxiliary->GetLocationVRP(); - if ( needTrim && startup_trim->getBoolValue() ) { - alt = fgic->GetAltitudeASLFtIC(); - slr = fgic->GetSeaLevelRadiusFtIC(); - lat = fgic->GetLatitudeDegIC() * SGD_DEGREES_TO_RADIANS; - lon = fgic->GetLongitudeDegIC() * SGD_DEGREES_TO_RADIANS; - cart = FGLocation(lon, lat, alt+slr); - } - double cart_pos[3] = { cart(1), cart(2), cart(3) }; - double t0 = fdmex->GetSimTime(); - bool cache_ok = prepare_ground_cache_ft( t0, t0 + dt, cart_pos, - groundCacheRadius ); - if (!cache_ok) { - SG_LOG(SG_FLIGHT, SG_WARN, - "FGInterface is being called without scenery below the aircraft!"); + double cart_pos[3]; - alt = fgic->GetAltitudeASLFtIC(); - SG_LOG(SG_FLIGHT, SG_WARN, "altitude = " << alt); - - slr = fgic->GetSeaLevelRadiusFtIC(); - SG_LOG(SG_FLIGHT, SG_WARN, "sea level radius = " << slr); - - lat = fgic->GetLatitudeDegIC() * SGD_DEGREES_TO_RADIANS; - SG_LOG(SG_FLIGHT, SG_WARN, "latitude = " << lat); - - lon = fgic->GetLongitudeDegIC() * SGD_DEGREES_TO_RADIANS; - SG_LOG(SG_FLIGHT, SG_WARN, "longitude = " << lon); - //return; - } + update_ground_cache(cart, cart_pos, dt); copy_to_JSBsim(); trimmed->setBoolValue(false); - if ( needTrim ) { - if ( startup_trim->getBoolValue() ) { - double contact[3], d[3], vel[3], agl; - get_agl_ft(fdmex->GetSimTime(), cart_pos, SG_METER_TO_FEET*2, contact, - d, vel, d, &agl); - double terrain_alt = sqrt(contact[0]*contact[0] + contact[1]*contact[1] - + contact[2]*contact[2]) - fgic->GetSeaLevelRadiusFtIC(); - - SG_LOG(SG_FLIGHT, SG_INFO, - "Ready to trim, terrain elevation is: " - << terrain_alt * SG_METER_TO_FEET ); - - if (fgGetBool("/sim/presets/onground")) { - FGColumnVector3 gndVelNED = cart.GetTec2l() - * FGColumnVector3(vel[0], vel[1], vel[2]); - fgic->SetVNorthFpsIC(gndVelNED(1)); - fgic->SetVEastFpsIC(gndVelNED(2)); - fgic->SetVDownFpsIC(gndVelNED(3)); - } - fgic->SetTerrainElevationFtIC( terrain_alt ); - do_trim(); - } else { - fdmex->RunIC(); //apply any changes made through the set_ functions - } - needTrim = false; - } - - for ( i=0; i < multiloop; i++ ) { + for ( int i=0; i < multiloop; i++ ) { fdmex->Run(); - update_external_forces(fdmex->GetSimTime() + i * fdmex->GetDeltaT()); + update_external_forces(fdmex->GetSimTime() + i * fdmex->GetDeltaT()); } FGJSBBase::Message* msg; @@ -1052,186 +1009,240 @@ bool FGJSBsim::ToggleDataLogging(bool state) //Positions void FGJSBsim::set_Latitude(double lat) { - static SGConstPropertyNode_ptr altitude = fgGetNode("/position/altitude-ft"); - double alt; - double sea_level_radius_meters, lat_geoc; + static SGConstPropertyNode_ptr altitude = fgGetNode("/position/altitude-ft"); + double alt; + double sea_level_radius_meters, lat_geoc; - // In case we're not trimming - FGInterface::set_Latitude(lat); + if ( altitude->getDoubleValue() > -9990 ) + alt = altitude->getDoubleValue(); + else + alt = 0.0; - if ( altitude->getDoubleValue() > -9990 ) { - alt = altitude->getDoubleValue(); - } else { - alt = 0.0; - } + SG_LOG(SG_FLIGHT,SG_INFO,"FGJSBsim::set_Latitude: " << lat ); + SG_LOG(SG_FLIGHT,SG_INFO," cur alt (ft) = " << alt ); - update_ic(); - SG_LOG(SG_FLIGHT,SG_INFO,"FGJSBsim::set_Latitude: " << lat ); - SG_LOG(SG_FLIGHT,SG_INFO," cur alt (ft) = " << alt ); + sgGeodToGeoc( lat, alt * SG_FEET_TO_METER, + &sea_level_radius_meters, &lat_geoc ); + _set_Sea_level_radius( sea_level_radius_meters * SG_METER_TO_FEET ); - sgGeodToGeoc( lat, alt * SG_FEET_TO_METER, - &sea_level_radius_meters, &lat_geoc ); - _set_Sea_level_radius( sea_level_radius_meters * SG_METER_TO_FEET ); + if (needTrim) { fgic->SetSeaLevelRadiusFtIC( sea_level_radius_meters * SG_METER_TO_FEET ); fgic->SetLatitudeRadIC( lat_geoc ); - - if (!fdmex->Holding()) - needTrim=true; + } + else { + Propagate->SetLatitude(lat_geoc); + FGInterface::set_Latitude(lat); + } } void FGJSBsim::set_Longitude(double lon) { - SG_LOG(SG_FLIGHT,SG_INFO,"FGJSBsim::set_Longitude: " << lon ); + SG_LOG(SG_FLIGHT,SG_INFO,"FGJSBsim::set_Longitude: " << lon ); - // In case we're not trimming + if (needTrim) + fgic->SetLongitudeRadIC(lon); + else { + Propagate->SetLongitude(lon); FGInterface::set_Longitude(lon); - - update_ic(); - fgic->SetLongitudeRadIC( lon ); - - if (!fdmex->Holding()) - needTrim=true; + } } // Sets the altitude above sea level. void FGJSBsim::set_Altitude(double alt) { - static SGConstPropertyNode_ptr latitude = fgGetNode("/position/latitude-deg"); + SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::set_Altitude: " << alt ); - double sea_level_radius_meters,lat_geoc; - - SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::set_Altitude: " << alt ); - SG_LOG(SG_FLIGHT,SG_INFO, " lat (deg) = " << latitude->getDoubleValue() ); - - // In case we're not trimming - FGInterface::set_Altitude(alt); - - update_ic(); - sgGeodToGeoc( latitude->getDoubleValue() * SGD_DEGREES_TO_RADIANS, alt, - &sea_level_radius_meters, &lat_geoc); - _set_Sea_level_radius( sea_level_radius_meters * SG_METER_TO_FEET ); - fgic->SetSeaLevelRadiusFtIC( sea_level_radius_meters * SG_METER_TO_FEET ); - SG_LOG(SG_FLIGHT, SG_INFO, - "Terrain elevation: " << FGInterface::get_Runway_altitude() * SG_METER_TO_FEET ); - fgic->SetLatitudeRadIC( lat_geoc ); + if (needTrim) fgic->SetAltitudeASLFtIC(alt); - - if (!fdmex->Holding()) - needTrim=true; + else { + Propagate->SetAltitudeASL(alt); + FGInterface::set_Altitude(alt); + } } void FGJSBsim::set_V_calibrated_kts(double vc) { SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::set_V_calibrated_kts: " << vc ); - // In case we're not trimming - FGInterface::set_V_calibrated_kts(vc); - - update_ic(); + if (needTrim) fgic->SetVcalibratedKtsIC(vc); + else { + double mach = getMachFromVcas(vc); + double temp = 1.8*(temperature->getDoubleValue()+273.15); + double soundSpeed = sqrt(1.4*1716.0*temp); + FGColumnVector3 vUVW = Propagate->GetUVW(); + vUVW.Normalize(); + vUVW *= mach * soundSpeed; + Propagate->SetUVW(1, vUVW(1)); + Propagate->SetUVW(2, vUVW(2)); + Propagate->SetUVW(3, vUVW(3)); - if (!fdmex->Holding()) - needTrim=true; + FGInterface::set_V_calibrated_kts(vc); + } } void FGJSBsim::set_Mach_number(double mach) { - SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::set_Mach_number: " << mach ); + SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::set_Mach_number: " << mach ); - // In case we're not trimming - FGInterface::set_Mach_number(mach); - - update_ic(); + if (needTrim) fgic->SetMachIC(mach); + else { + double temp = 1.8*(temperature->getDoubleValue()+273.15); + double soundSpeed = sqrt(1.4*1716.0*temp); + FGColumnVector3 vUVW = Propagate->GetUVW(); + vUVW.Normalize(); + vUVW *= mach * soundSpeed; + Propagate->SetUVW(1, vUVW(1)); + Propagate->SetUVW(2, vUVW(2)); + Propagate->SetUVW(3, vUVW(3)); - if (!fdmex->Holding()) - needTrim=true; + FGInterface::set_Mach_number(mach); + } } void FGJSBsim::set_Velocities_Local( double north, double east, double down ) { - SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::set_Velocities_Local: " - << north << ", " << east << ", " << down ); + SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::set_Velocities_Local: " + << north << ", " << east << ", " << down ); - // In case we're not trimming - FGInterface::set_Velocities_Local(north, east, down); - - update_ic(); + if (needTrim) { fgic->SetVNorthFpsIC(north); fgic->SetVEastFpsIC(east); fgic->SetVDownFpsIC(down); + } + else { + FGColumnVector3 vNED(north, east, down); + FGColumnVector3 vUVW = Propagate->GetTl2b() * vNED; + Propagate->SetUVW(1, vUVW(1)); + Propagate->SetUVW(2, vUVW(2)); + Propagate->SetUVW(3, vUVW(3)); - if (!fdmex->Holding()) - needTrim=true; + FGInterface::set_Velocities_Local(north, east, down); + } } void FGJSBsim::set_Velocities_Wind_Body( double u, double v, double w) { - SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::set_Velocities_Wind_Body: " - << u << ", " << v << ", " << w ); + SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::set_Velocities_Wind_Body: " + << u << ", " << v << ", " << w ); - // In case we're not trimming - FGInterface::set_Velocities_Wind_Body(u, v, w); - - update_ic(); + if (needTrim) { fgic->SetUBodyFpsIC(u); fgic->SetVBodyFpsIC(v); fgic->SetWBodyFpsIC(w); + } + else { + Propagate->SetUVW(1, u); + Propagate->SetUVW(2, v); + Propagate->SetUVW(3, w); - if (!fdmex->Holding()) - needTrim=true; + FGInterface::set_Velocities_Wind_Body(u, v, w); + } } //Euler angles void FGJSBsim::set_Euler_Angles( double phi, double theta, double psi ) { - SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::set_Euler_Angles: " - << phi << ", " << theta << ", " << psi ); + SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::set_Euler_Angles: " + << phi << ", " << theta << ", " << psi ); - // In case we're not trimming - FGInterface::set_Euler_Angles(phi, theta, psi); - - update_ic(); + if (needTrim) { fgic->SetThetaRadIC(theta); fgic->SetPhiRadIC(phi); fgic->SetPsiRadIC(psi); + } + else { + FGQuaternion quat(phi, theta, psi); + FGMatrix33 Tl2b = quat.GetT(); + FGMatrix33 Ti2b = Tl2b*Propagate->GetTi2l(); + FGQuaternion Qi = Ti2b.GetQuaternion(); + Propagate->SetInertialOrientation(Qi); - if (!fdmex->Holding()) - needTrim=true; + FGInterface::set_Euler_Angles(phi, theta, psi); + } } //Flight Path void FGJSBsim::set_Climb_Rate( double roc) { - SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::set_Climb_Rate: " << roc ); + SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::set_Climb_Rate: " << roc ); - // In case we're not trimming - FGInterface::set_Climb_Rate(roc); - - update_ic(); - //since both climb rate and flight path angle are set in the FG - //startup sequence, something is needed to keep one from cancelling - //out the other. - if( !(fabs(roc) > 1 && fabs(fgic->GetFlightPathAngleRadIC()) < 0.01) ) { + //since both climb rate and flight path angle are set in the FG + //startup sequence, something is needed to keep one from cancelling + //out the other. + if( !(fabs(roc) > 1 && fabs(fgic->GetFlightPathAngleRadIC()) < 0.01) ) { + if (needTrim) fgic->SetClimbRateFpsIC(roc); - } + else { + FGColumnVector3 vNED = Propagate->GetVel(); + vNED(FGJSBBase::eDown) = -roc; + FGColumnVector3 vUVW = Propagate->GetTl2b() * vNED; + Propagate->SetUVW(1, vUVW(1)); + Propagate->SetUVW(2, vUVW(2)); + Propagate->SetUVW(3, vUVW(3)); - if (!fdmex->Holding()) - needTrim=true; + FGInterface::set_Climb_Rate(roc); + } + } } void FGJSBsim::set_Gamma_vert_rad( double gamma) { - SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::set_Gamma_vert_rad: " << gamma ); + SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::set_Gamma_vert_rad: " << gamma ); - update_ic(); - if( !(fabs(gamma) < 0.01 && fabs(fgic->GetClimbRateFpsIC()) > 1) ) { + if( !(fabs(gamma) < 0.01 && fabs(fgic->GetClimbRateFpsIC()) > 1) ) { + if (needTrim) fgic->SetFlightPathAngleRadIC(gamma); + else { + FGColumnVector3 vNED = Propagate->GetVel(); + double vt = vNED.Magnitude(); + vNED(FGJSBBase::eDown) = -vt * sin(gamma); + FGColumnVector3 vUVW = Propagate->GetTl2b() * vNED; + Propagate->SetUVW(1, vUVW(1)); + Propagate->SetUVW(2, vUVW(2)); + Propagate->SetUVW(3, vUVW(3)); + + FGInterface::set_Gamma_vert_rad(gamma); + } + } +} +// Reverse the VCAS formula to obtain the corresponding Mach number. For subsonic +// speeds, the reversed formula has a closed form. For supersonic speeds, the +// formula is reversed by the Newton-Raphson algorithm. + +double FGJSBsim::getMachFromVcas(double vcas) +{ + double p=pressure->getDoubleValue(); + double psl=fdmex->GetAtmosphere()->GetPressureSL(); + double rhosl=fdmex->GetAtmosphere()->GetDensitySL(); + + double pt = p + psl*(pow(1+vcas*vcas*rhosl/(7.0*psl),3.5)-1); + + if (pt/p < 1.89293) + return sqrt(5.0*(pow(pt/p, 0.2857143) -1)); // Mach < 1 + else { + // Mach >= 1 + double mach = sqrt(0.77666*pt/p); // Initial guess is based on a quadratic approximation of the Rayleigh formula + double delta = 1.; + double target = pt/(166.92158*p); + int iter = 0; + + // Find the root with Newton-Raphson. Since the differential is never zero, + // the function is monotonic and has only one root with a multiplicity of one. + // Convergence is certain. + while (delta > 1E-5 && iter < 10) { + double m2 = mach*mach; // Mach^2 + double m6 = m2*m2*m2; // Mach^6 + delta = mach*m6/pow(7.0*m2-1.0,2.5) - target; + double diff = 7.0*m6*(2.0*m2-1)/pow(7.0*m2-1.0,3.5); // Never zero when Mach >= 1 + mach -= delta/diff; + iter++; } - if (!fdmex->Holding()) - needTrim=true; + return mach; + } } void FGJSBsim::init_gear(void ) @@ -1309,18 +1320,46 @@ void FGJSBsim::do_trim(void) SG_LOG( SG_FLIGHT, SG_INFO, " Trim complete" ); } -void FGJSBsim::update_ic(void) +bool FGJSBsim::update_ground_cache(FGLocation cart, double* cart_pos, double dt) { - if ( !needTrim ) { - fgic->SetLatitudeRadIC(get_Lat_geocentric() ); - fgic->SetLongitudeRadIC( get_Longitude() ); - fgic->SetAltitudeASLFtIC( get_Altitude() ); - fgic->SetVcalibratedKtsIC( get_V_calibrated_kts() ); - fgic->SetThetaRadIC( get_Theta() ); - fgic->SetPhiRadIC( get_Phi() ); - fgic->SetPsiRadIC( get_Psi() ); - fgic->SetClimbRateFpsIC( get_Climb_Rate() ); - } + // Compute the radius of the aircraft. That is the radius of a ball + // where all gear units are in. At the moment it is at least 10ft ... + double acrad = 10.0; + int n_gears = GroundReactions->GetNumGearUnits(); + for (int i=0; i<n_gears; ++i) { + FGColumnVector3 bl = GroundReactions->GetGearUnit(i)->GetBodyLocation(); + double r = bl.Magnitude(); + if (acrad < r) + acrad = r; + } + + // Compute the potential movement of this aircraft and query for the + // ground in this area. + double groundCacheRadius = acrad + 2*dt*Propagate->GetUVW().Magnitude(); + cart_pos[0] = cart(1); + cart_pos[1] = cart(2); + cart_pos[2] = cart(3); + double t0 = fdmex->GetSimTime(); + bool cache_ok = prepare_ground_cache_ft( t0, t0 + dt, cart_pos, + groundCacheRadius ); + if (!cache_ok) { + SG_LOG(SG_FLIGHT, SG_WARN, + "FGInterface is being called without scenery below the aircraft!"); + + SG_LOG(SG_FLIGHT, SG_WARN, "altitude = " + << fgic->GetAltitudeASLFtIC()); + + SG_LOG(SG_FLIGHT, SG_WARN, "sea level radius = " + << fgic->GetSeaLevelRadiusFtIC()); + + SG_LOG(SG_FLIGHT, SG_WARN, "latitude = " + << fgic->GetLatitudeRadIC()); + + SG_LOG(SG_FLIGHT, SG_WARN, "longitude = " + << fgic->GetLongitudeRadIC()); + } + + return cache_ok; } bool @@ -1339,11 +1378,6 @@ FGJSBsim::get_agl_ft(double t, const double pt[3], double alt_off, return true; } -inline static double dot3(const FGColumnVector3& a, const FGColumnVector3& b) -{ - return a(1) * b(1) + a(2) * b(2) + a(3) * b(3); -} - inline static double sqr(double x) { return x * x; @@ -1360,7 +1394,7 @@ static double angle_diff(double a, double b) static void check_hook_solution(const FGColumnVector3& ground_normal_body, double E, double hook_length, double sin_fi_guess, double cos_fi_guess, double* sin_fis, double* cos_fis, double* fis, int* points) { FGColumnVector3 tip(-hook_length * cos_fi_guess, 0, hook_length * sin_fi_guess); - double dist = dot3(tip, ground_normal_body); + double dist = DotProduct(tip, ground_normal_body); if (fabs(dist + E) < 0.0001) { sin_fis[*points] = sin_fi_guess; cos_fis[*points] = cos_fi_guess; @@ -1419,16 +1453,16 @@ void FGJSBsim::update_external_forces(double t_off) if (got && root_agl_ft > 0 && root_agl_ft < hook_length) { FGColumnVector3 ground_normal_body = Tl2b * (Tec2l * FGColumnVector3(ground_normal[0], ground_normal[1], ground_normal[2])); FGColumnVector3 contact_body = Tl2b * Location.LocationToLocal(FGColumnVector3(contact[0], contact[1], contact[2])); - double D = -dot3(contact_body, ground_normal_body); + double D = -DotProduct(contact_body, ground_normal_body); // check hook tip agl against same ground plane - double hook_tip_agl_ft = dot3(hook_tip_body, ground_normal_body) + D; + double hook_tip_agl_ft = DotProduct(hook_tip_body, ground_normal_body) + D; if (hook_tip_agl_ft < 0) { // hook tip: hx - l cos, hy, hz + l sin // on ground: - n0 l cos + n2 l sin + E = 0 - double E = D + dot3(hook_root_body, ground_normal_body); + double E = D + DotProduct(hook_root_body, ground_normal_body); // substitue x = sin fi, cos fi = sqrt(1 - x * x) // and rearrange to get a quadratic with coeffs: @@ -1480,7 +1514,7 @@ void FGJSBsim::update_external_forces(double t_off) FGColumnVector3 wire_end2_body = Tl2b * Location.LocationToLocal(FGColumnVector3(wire_ends_ec[1][0], wire_ends_ec[1][1], wire_ends_ec[1][2])) - hook_root_body; FGColumnVector3 force_plane_normal = wire_end1_body * wire_end2_body; force_plane_normal.Normalize(); - cos_fi = dot3(force_plane_normal, FGColumnVector3(0, 0, 1)); + cos_fi = DotProduct(force_plane_normal, FGColumnVector3(0, 0, 1)); if (cos_fi < 0) cos_fi = -cos_fi; sin_fi = sqrt(1 - sqr(cos_fi)); fi = atan2(sin_fi, cos_fi) * SG_RADIANS_TO_DEGREES; diff --git a/src/FDM/JSBSim/JSBSim.hxx b/src/FDM/JSBSim/JSBSim.hxx index 14766c6f6..4e8cf1880 100644 --- a/src/FDM/JSBSim/JSBSim.hxx +++ b/src/FDM/JSBSim/JSBSim.hxx @@ -38,7 +38,6 @@ INCLUDES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ #undef MAX_ENGINES -#include "math/FGColumnVector3.h" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% DEFINITIONS @@ -69,6 +68,7 @@ class FGPropagate; class FGAuxiliary; class FGOutput; class FGInitialCondition; +class FGLocation; } // Adding it here will cause a namespace clash in FlightGear -EMH- @@ -209,10 +209,9 @@ public: /** Update the position based on inputs, positions, velocities, etc. @param dt delta time in seconds. */ void update(double dt); + bool ToggleDataLogging(bool state); bool ToggleDataLogging(void); - void do_trim(void); - void update_ic(void); bool get_agl_ft(double t, const double pt[3], double alt_off, double contact[3], double normal[3], double vel[3], @@ -292,6 +291,10 @@ private: bool crashed; + void do_trim(void); + + double getMachFromVcas(double vcas); + bool update_ground_cache(JSBSim::FGLocation cart, double* cart_pos, double dt); void init_gear(void); void update_gear(void); From ba471db64706a51fc7952d49dcc929bd8d7ee514 Mon Sep 17 00:00:00 2001 From: ThorstenB <brehmt@gmail.com> Date: Mon, 13 Jun 2011 00:44:22 +0200 Subject: [PATCH 24/48] Martin Spott: CMake DBus module, credit goes to the KDE project from whom the file was copied. --- CMakeModules/FindDBus.cmake | 72 +++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 CMakeModules/FindDBus.cmake diff --git a/CMakeModules/FindDBus.cmake b/CMakeModules/FindDBus.cmake new file mode 100644 index 000000000..f227cc297 --- /dev/null +++ b/CMakeModules/FindDBus.cmake @@ -0,0 +1,72 @@ +# - Try to find the low-level D-Bus library +# Once done this will define +# +# DBUS_FOUND - system has D-Bus +# DBUS_INCLUDE_DIR - the D-Bus include directory +# DBUS_ARCH_INCLUDE_DIR - the D-Bus architecture-specific include directory +# DBUS_LIBRARIES - the libraries needed to use D-Bus + +# Copyright (c) 2008, Kevin Kofler, <kevin.kofler@chello.at> +# modeled after FindLibArt.cmake: +# Copyright (c) 2006, Alexander Neundorf, <neundorf@kde.org> +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + +if (DBUS_INCLUDE_DIR AND DBUS_ARCH_INCLUDE_DIR AND DBUS_LIBRARIES) + + # in cache already + SET(DBUS_FOUND TRUE) + +else (DBUS_INCLUDE_DIR AND DBUS_ARCH_INCLUDE_DIR AND DBUS_LIBRARIES) + + IF (NOT WIN32) + FIND_PACKAGE(PkgConfig) + IF (PKG_CONFIG_FOUND) + # use pkg-config to get the directories and then use these values + # in the FIND_PATH() and FIND_LIBRARY() calls + pkg_check_modules(_DBUS_PC QUIET dbus-1) + ENDIF (PKG_CONFIG_FOUND) + ENDIF (NOT WIN32) + + FIND_PATH(DBUS_INCLUDE_DIR dbus/dbus.h + ${_DBUS_PC_INCLUDE_DIRS} + /usr/include + /usr/include/dbus-1.0 + /usr/local/include + ) + + FIND_PATH(DBUS_ARCH_INCLUDE_DIR dbus/dbus-arch-deps.h + ${_DBUS_PC_INCLUDE_DIRS} + /usr/lib${LIB_SUFFIX}/include + /usr/lib${LIB_SUFFIX}/dbus-1.0/include + /usr/lib64/include + /usr/lib64/dbus-1.0/include + /usr/lib/include + /usr/lib/dbus-1.0/include + ) + + FIND_LIBRARY(DBUS_LIBRARIES NAMES dbus-1 dbus + PATHS + ${_DBUS_PC_LIBDIR} + ) + + + if (DBUS_INCLUDE_DIR AND DBUS_ARCH_INCLUDE_DIR AND DBUS_LIBRARIES) + set(DBUS_FOUND TRUE) + endif (DBUS_INCLUDE_DIR AND DBUS_ARCH_INCLUDE_DIR AND DBUS_LIBRARIES) + + + if (DBUS_FOUND) + if (NOT DBus_FIND_QUIETLY) + message(STATUS "Found D-Bus: ${DBUS_LIBRARIES}") + endif (NOT DBus_FIND_QUIETLY) + else (DBUS_FOUND) + if (DBus_FIND_REQUIRED) + message(FATAL_ERROR "Could NOT find D-Bus") + endif (DBus_FIND_REQUIRED) + endif (DBUS_FOUND) + + MARK_AS_ADVANCED(DBUS_INCLUDE_DIR DBUS_ARCH_INCLUDE_DIR DBUS_LIBRARIES) + +endif (DBUS_INCLUDE_DIR AND DBUS_ARCH_INCLUDE_DIR AND DBUS_LIBRARIES) From 826784eb1825bc6f512308215034e4d0ad9917e3 Mon Sep 17 00:00:00 2001 From: ThorstenB <brehmt@gmail.com> Date: Mon, 13 Jun 2011 00:45:40 +0200 Subject: [PATCH 25/48] Martin Spott: Add CMake DBus support for event driven input. Tested on Linux only, please improve if you see fit. --- CMakeLists.txt | 1 + src/Input/CMakeLists.txt | 11 +++++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d2c50db06..fe7610f4f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -71,6 +71,7 @@ endif() if(EVENT_INPUT) message(STATUS "checking event-based Input") + find_package(DBus) IF(APPLE) elseif(CMAKE_SYSTEM_NAME MATCHES "Linux") diff --git a/src/Input/CMakeLists.txt b/src/Input/CMakeLists.txt index e0d6abd30..1a2df52d2 100644 --- a/src/Input/CMakeLists.txt +++ b/src/Input/CMakeLists.txt @@ -1,9 +1,11 @@ include(FlightGearComponent) -set(EVENT_INPUT_SOURCES - FGLinuxEventInput.cxx - FGMacOSXEventInput.cxx - ) +IF(APPLE) + set(EVENT_INPUT_SOURCES FGMacOSXEventInput.cxx) +else() + set(EVENT_INPUT_SOURCES FGLinuxEventInput.cxx) +endif() + set(SOURCES FGButton.cxx @@ -18,6 +20,7 @@ set(SOURCES if(EVENT_INPUT) list(APPEND SOURCES ${EVENT_INPUT_SOURCES}) + include_directories(${DBUS_INCLUDE_DIR} ${DBUS_ARCH_INCLUDE_DIR}) endif() set(FGJS_SOURCES From 9d7ec8f2388df1856f8a17dbeeacdf75ad21c3e8 Mon Sep 17 00:00:00 2001 From: ThorstenB <brehmt@gmail.com> Date: Mon, 13 Jun 2011 00:46:50 +0200 Subject: [PATCH 26/48] Martin Spott: Fix special FDM define for CMake. --- src/FDM/fdm_shell.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/FDM/fdm_shell.cxx b/src/FDM/fdm_shell.cxx index 8055bce5a..1aa19402d 100644 --- a/src/FDM/fdm_shell.cxx +++ b/src/FDM/fdm_shell.cxx @@ -35,7 +35,7 @@ #include <Scenery/scenery.hxx> // all the FDMs, since we are the factory method -#if ENABLE_SP_FDM +#ifdef ENABLE_SP_FDM #include <FDM/SP/ADA.hxx> #include <FDM/SP/ACMS.hxx> #include <FDM/SP/MagicCarpet.hxx> @@ -175,7 +175,7 @@ void FDMShell::createImplementation() _impl = new FGLaRCsim( dt ); } else if ( model == "jsb" ) { _impl = new FGJSBsim( dt ); -#if ENABLE_SP_FDM +#ifdef ENABLE_SP_FDM } else if ( model == "ada" ) { _impl = new FGADA( dt ); } else if ( model == "acms" ) { From 25fdbebd576e712a307ddf1ba19d9bf7cc137019 Mon Sep 17 00:00:00 2001 From: ThorstenB <brehmt@gmail.com> Date: Mon, 13 Jun 2011 00:52:43 +0200 Subject: [PATCH 27/48] Revert "issue #127: make screen shots work with OSG multi-threading" This reverts commit b4d90150c50094ac25f2e9ed7ea8302a3ef148d2. --- src/GUI/gui_funcs.cxx | 136 +----------------------------------------- 1 file changed, 3 insertions(+), 133 deletions(-) diff --git a/src/GUI/gui_funcs.cxx b/src/GUI/gui_funcs.cxx index 06459a8f6..ccbd0a550 100644 --- a/src/GUI/gui_funcs.cxx +++ b/src/GUI/gui_funcs.cxx @@ -42,7 +42,6 @@ #include <simgear/debug/logstream.hxx> #include <simgear/misc/sg_path.hxx> #include <simgear/screen/screen-dump.hxx> -#include <simgear/structure/event_mgr.hxx> #include <Cockpit/panel.hxx> #include <Main/globals.hxx> @@ -50,11 +49,8 @@ #include <Main/fg_os.hxx> #include <Main/renderer.hxx> #include <Main/viewmgr.hxx> -#include <Main/WindowSystemAdapter.hxx> -#include <Main/CameraGroup.hxx> #include <GUI/new_gui.hxx> - #ifdef _WIN32 # include <shellapi.h> #endif @@ -410,134 +406,9 @@ void fgHiResDumpWrapper () { fgHiResDump(); } -namespace -{ - using namespace flightgear; - - class GUISnapShotOperation : - public GraphicsContextOperation - { - public: - - // start new snap shot - static bool start() - { - // allow only one snapshot at a time - if (_snapShotOp.valid()) - return false; - _snapShotOp = new GUISnapShotOperation(); - /* register with graphics context so actual snap shot is done - * in the graphics context (thread) */ - osg::Camera* guiCamera = getGUICamera(CameraGroup::getDefault()); - WindowSystemAdapter* wsa = WindowSystemAdapter::getWSA(); - osg::GraphicsContext* gc = 0; - if (guiCamera) - gc = guiCamera->getGraphicsContext(); - if (gc) { - gc->add(_snapShotOp.get()); - } else { - wsa->windows[0]->gc->add(_snapShotOp.get()); - } - return true; - } - - private: - // constructor to be executed in main loop's thread - GUISnapShotOperation() : - flightgear::GraphicsContextOperation(std::string("GUI snap shot")), - _master_freeze(fgGetNode("/sim/freeze/master", true)), - _freeze(_master_freeze->getBoolValue()), - _result(false), - _mouse(fgGetMouseCursor()) - { - if (!_freeze) - _master_freeze->setBoolValue(true); - - fgSetMouseCursor(MOUSE_CURSOR_NONE); - - string dir = fgGetString("/sim/paths/screenshot-dir"); - if (dir.empty()) - dir = fgGetString("/sim/fg-current"); - - _path.set(dir + '/'); - if (_path.create_dir( 0755 )) { - SG_LOG(SG_GENERAL, SG_ALERT, "Cannot create screenshot directory '" - << dir << "'. Trying home directory."); - dir = fgGetString("/sim/fg-home"); - } - - char filename[24]; - static int count = 1; - while (count < 1000) { - snprintf(filename, 24, "fgfs-screen-%03d.png", count++); - - SGPath p(dir); - p.append(filename); - if (!p.exists()) { - _path.set(p.str()); - break; - } - } - - _xsize = fgGetInt("/sim/startup/xsize"); - _ysize = fgGetInt("/sim/startup/ysize"); - - FGRenderer *renderer = globals->get_renderer(); - renderer->resize(_xsize, _ysize); - globals->get_event_mgr()->addTask("SnapShotTimer", - this, &GUISnapShotOperation::timerExpired, - 0.1, false); - } - - // to be executed in graphics context (maybe separate thread) - void run(osg::GraphicsContext* gc) - { - _result = sg_glDumpWindow(_path.c_str(), - _xsize, - _ysize); - } - - // timer method, to be executed in main loop's thread - virtual void timerExpired() - { - if (isFinished()) - { - globals->get_event_mgr()->removeTask("SnapShotTimer"); - - fgSetString("/sim/paths/screenshot-last", _path.c_str()); - fgSetBool("/sim/signals/screenshot", _result); - - fgSetMouseCursor(_mouse); - - if ( !_freeze ) - _master_freeze->setBoolValue(false); - - _snapShotOp = 0; - } - } - - static osg::ref_ptr<GUISnapShotOperation> _snapShotOp; - SGPropertyNode_ptr _master_freeze; - bool _freeze; - bool _result; - int _mouse; - int _xsize, _ysize; - SGPath _path; - }; - -} - -osg::ref_ptr<GUISnapShotOperation> GUISnapShotOperation::_snapShotOp; // do a screen snap shot -bool fgDumpSnapShot () -{ -#if 1 - // start snap shot operation, while needs to be executed in - // graphics context - return GUISnapShotOperation::start(); -#else - // obsolete code => remove when new code is stable +bool fgDumpSnapShot () { static SGConstPropertyNode_ptr master_freeze = fgGetNode("/sim/freeze/master"); bool freeze = master_freeze->getBoolValue(); @@ -584,7 +455,7 @@ bool fgDumpSnapShot () } } - bool result = sg_glDumpWindow(path.c_str(), + int result = sg_glDumpWindow(path.c_str(), fgGetInt("/sim/startup/xsize"), fgGetInt("/sim/startup/ysize")); @@ -596,8 +467,7 @@ bool fgDumpSnapShot () if ( !freeze ) { fgSetBool("/sim/freeze/master", false); } - return result; -#endif + return result != 0; } // do an entire scenegraph dump From 702d323a3937ffef94ab909cd23fa6717afd4fc0 Mon Sep 17 00:00:00 2001 From: ThorstenB <brehmt@gmail.com> Date: Mon, 13 Jun 2011 20:31:27 +0200 Subject: [PATCH 28/48] issue #127: make screen shots work with OSG multi-threading Make sure actual snap shot is executed in graphics context. (Revert the revert :) - since the basic issue in simgear is solved now) (patch requires simgear+fgdata update!) --- src/GUI/gui_funcs.cxx | 136 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 133 insertions(+), 3 deletions(-) diff --git a/src/GUI/gui_funcs.cxx b/src/GUI/gui_funcs.cxx index ccbd0a550..06459a8f6 100644 --- a/src/GUI/gui_funcs.cxx +++ b/src/GUI/gui_funcs.cxx @@ -42,6 +42,7 @@ #include <simgear/debug/logstream.hxx> #include <simgear/misc/sg_path.hxx> #include <simgear/screen/screen-dump.hxx> +#include <simgear/structure/event_mgr.hxx> #include <Cockpit/panel.hxx> #include <Main/globals.hxx> @@ -49,8 +50,11 @@ #include <Main/fg_os.hxx> #include <Main/renderer.hxx> #include <Main/viewmgr.hxx> +#include <Main/WindowSystemAdapter.hxx> +#include <Main/CameraGroup.hxx> #include <GUI/new_gui.hxx> + #ifdef _WIN32 # include <shellapi.h> #endif @@ -406,9 +410,134 @@ void fgHiResDumpWrapper () { fgHiResDump(); } +namespace +{ + using namespace flightgear; + + class GUISnapShotOperation : + public GraphicsContextOperation + { + public: + + // start new snap shot + static bool start() + { + // allow only one snapshot at a time + if (_snapShotOp.valid()) + return false; + _snapShotOp = new GUISnapShotOperation(); + /* register with graphics context so actual snap shot is done + * in the graphics context (thread) */ + osg::Camera* guiCamera = getGUICamera(CameraGroup::getDefault()); + WindowSystemAdapter* wsa = WindowSystemAdapter::getWSA(); + osg::GraphicsContext* gc = 0; + if (guiCamera) + gc = guiCamera->getGraphicsContext(); + if (gc) { + gc->add(_snapShotOp.get()); + } else { + wsa->windows[0]->gc->add(_snapShotOp.get()); + } + return true; + } + + private: + // constructor to be executed in main loop's thread + GUISnapShotOperation() : + flightgear::GraphicsContextOperation(std::string("GUI snap shot")), + _master_freeze(fgGetNode("/sim/freeze/master", true)), + _freeze(_master_freeze->getBoolValue()), + _result(false), + _mouse(fgGetMouseCursor()) + { + if (!_freeze) + _master_freeze->setBoolValue(true); + + fgSetMouseCursor(MOUSE_CURSOR_NONE); + + string dir = fgGetString("/sim/paths/screenshot-dir"); + if (dir.empty()) + dir = fgGetString("/sim/fg-current"); + + _path.set(dir + '/'); + if (_path.create_dir( 0755 )) { + SG_LOG(SG_GENERAL, SG_ALERT, "Cannot create screenshot directory '" + << dir << "'. Trying home directory."); + dir = fgGetString("/sim/fg-home"); + } + + char filename[24]; + static int count = 1; + while (count < 1000) { + snprintf(filename, 24, "fgfs-screen-%03d.png", count++); + + SGPath p(dir); + p.append(filename); + if (!p.exists()) { + _path.set(p.str()); + break; + } + } + + _xsize = fgGetInt("/sim/startup/xsize"); + _ysize = fgGetInt("/sim/startup/ysize"); + + FGRenderer *renderer = globals->get_renderer(); + renderer->resize(_xsize, _ysize); + globals->get_event_mgr()->addTask("SnapShotTimer", + this, &GUISnapShotOperation::timerExpired, + 0.1, false); + } + + // to be executed in graphics context (maybe separate thread) + void run(osg::GraphicsContext* gc) + { + _result = sg_glDumpWindow(_path.c_str(), + _xsize, + _ysize); + } + + // timer method, to be executed in main loop's thread + virtual void timerExpired() + { + if (isFinished()) + { + globals->get_event_mgr()->removeTask("SnapShotTimer"); + + fgSetString("/sim/paths/screenshot-last", _path.c_str()); + fgSetBool("/sim/signals/screenshot", _result); + + fgSetMouseCursor(_mouse); + + if ( !_freeze ) + _master_freeze->setBoolValue(false); + + _snapShotOp = 0; + } + } + + static osg::ref_ptr<GUISnapShotOperation> _snapShotOp; + SGPropertyNode_ptr _master_freeze; + bool _freeze; + bool _result; + int _mouse; + int _xsize, _ysize; + SGPath _path; + }; + +} + +osg::ref_ptr<GUISnapShotOperation> GUISnapShotOperation::_snapShotOp; // do a screen snap shot -bool fgDumpSnapShot () { +bool fgDumpSnapShot () +{ +#if 1 + // start snap shot operation, while needs to be executed in + // graphics context + return GUISnapShotOperation::start(); +#else + // obsolete code => remove when new code is stable static SGConstPropertyNode_ptr master_freeze = fgGetNode("/sim/freeze/master"); bool freeze = master_freeze->getBoolValue(); @@ -455,7 +584,7 @@ bool fgDumpSnapShot () { } } - int result = sg_glDumpWindow(path.c_str(), + bool result = sg_glDumpWindow(path.c_str(), fgGetInt("/sim/startup/xsize"), fgGetInt("/sim/startup/ysize")); @@ -467,7 +596,8 @@ bool fgDumpSnapShot () { if ( !freeze ) { fgSetBool("/sim/freeze/master", false); } - return result != 0; + return result; +#endif } // do an entire scenegraph dump From bba9a768b327115f850d63c3e80150f36d824c26 Mon Sep 17 00:00:00 2001 From: Frederic Bouvier <fredfgfs01@free.fr> Date: Wed, 15 Jun 2011 08:27:56 +0200 Subject: [PATCH 29/48] Link built-in svn in MSVC if 32-bit target is selected --- projects/VC90/FlightGear/FlightGear.vcproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/projects/VC90/FlightGear/FlightGear.vcproj b/projects/VC90/FlightGear/FlightGear.vcproj index 084a5531f..79053ecd9 100644 --- a/projects/VC90/FlightGear/FlightGear.vcproj +++ b/projects/VC90/FlightGear/FlightGear.vcproj @@ -73,7 +73,7 @@ <Tool Name="VCLinkerTool" AdditionalOptions="/MACHINE:I386" - AdditionalDependencies="opengl32.lib glu32.lib winmm.lib wsock32.lib sg_d.lib net_d.lib pui_d.lib puaux_d.lib fnt_d.lib js_d.lib ul_d.lib zlibd.lib OpenAL32.lib ALut.lib osgd.lib osgDBd.lib osgUtild.lib osgViewerd.lib osgGAd.lib osgTextd.lib osgParticled.lib OpenThreadsd.lib libjpegd.lib" + AdditionalDependencies="opengl32.lib glu32.lib winmm.lib wsock32.lib sg_d.lib net_d.lib pui_d.lib puaux_d.lib fnt_d.lib js_d.lib ul_d.lib zlibd.lib OpenAL32.lib ALut.lib osgd.lib osgDBd.lib osgUtild.lib osgViewerd.lib osgGAd.lib osgTextd.lib osgParticled.lib OpenThreadsd.lib libjpegd.lib libsvn_client-1.lib libsvn_diff-1.lib libsvn_delta-1.lib libsvn_ra-1.lib libsvn_subr-1.lib libsvn_wc-1.lib libapr-1.lib" OutputFile="$(OutDir)\fgfs.exe" LinkIncremental="2" SuppressStartupBanner="true" @@ -249,7 +249,7 @@ <Tool Name="VCLinkerTool" AdditionalOptions="/MACHINE:I386" - AdditionalDependencies="opengl32.lib glu32.lib winmm.lib wsock32.lib sg.lib net.lib pui.lib puAux.lib fnt.lib js.lib ul.lib zlib.lib OpenAL32.lib ALut.lib osg.lib osgDB.lib osgUtil.lib osgViewer.lib osgGA.lib osgText.lib osgParticle.lib OpenThreads.lib libjpeg.lib" + AdditionalDependencies="opengl32.lib glu32.lib winmm.lib wsock32.lib sg.lib net.lib pui.lib puAux.lib fnt.lib js.lib ul.lib zlib.lib OpenAL32.lib ALut.lib osg.lib osgDB.lib osgUtil.lib osgViewer.lib osgGA.lib osgText.lib osgParticle.lib OpenThreads.lib libjpeg.lib libsvn_client-1.lib libsvn_diff-1.lib libsvn_delta-1.lib libsvn_ra-1.lib libsvn_subr-1.lib libsvn_wc-1.lib libapr-1.lib" OutputFile="$(OutDir)\fgfs.exe" LinkIncremental="1" SuppressStartupBanner="true" From ec454158fee605314172422bf0934263b5e1fe42 Mon Sep 17 00:00:00 2001 From: Erik Hofman <erik@ehofman.com> Date: Fri, 17 Jun 2011 09:26:52 +0200 Subject: [PATCH 30/48] sync with JSBSim CVS --- src/FDM/JSBSim/FGFDMExec.cpp | 99 +-- src/FDM/JSBSim/FGFDMExec.h | 11 +- src/FDM/JSBSim/FGJSBBase.cpp | 6 +- src/FDM/JSBSim/FGJSBBase.h | 8 +- src/FDM/JSBSim/JSBSim.cxx | 6 +- .../initialization/FGInitialCondition.cpp | 12 +- src/FDM/JSBSim/math/FGTable.cpp | 4 +- src/FDM/JSBSim/math/FGTable.h | 13 +- src/FDM/JSBSim/models/FGAerodynamics.cpp | 8 +- src/FDM/JSBSim/models/FGAerodynamics.h | 11 +- src/FDM/JSBSim/models/FGAircraft.cpp | 10 +- src/FDM/JSBSim/models/FGAircraft.h | 11 +- src/FDM/JSBSim/models/FGAtmosphere.cpp | 51 +- src/FDM/JSBSim/models/FGAtmosphere.h | 137 +++-- src/FDM/JSBSim/models/FGAuxiliary.cpp | 54 +- src/FDM/JSBSim/models/FGAuxiliary.h | 11 +- src/FDM/JSBSim/models/FGBuoyantForces.cpp | 10 +- src/FDM/JSBSim/models/FGBuoyantForces.h | 11 +- src/FDM/JSBSim/models/FGExternalReactions.cpp | 10 +- src/FDM/JSBSim/models/FGExternalReactions.h | 12 +- src/FDM/JSBSim/models/FGFCS.cpp | 10 +- src/FDM/JSBSim/models/FGFCS.h | 11 +- src/FDM/JSBSim/models/FGGroundReactions.cpp | 10 +- src/FDM/JSBSim/models/FGGroundReactions.h | 11 +- src/FDM/JSBSim/models/FGInertial.cpp | 10 +- src/FDM/JSBSim/models/FGInertial.h | 11 +- src/FDM/JSBSim/models/FGInput.cpp | 10 +- src/FDM/JSBSim/models/FGInput.h | 11 +- src/FDM/JSBSim/models/FGMassBalance.cpp | 10 +- src/FDM/JSBSim/models/FGMassBalance.h | 11 +- src/FDM/JSBSim/models/FGModel.cpp | 17 +- src/FDM/JSBSim/models/FGModel.h | 13 +- src/FDM/JSBSim/models/FGOutput.cpp | 10 +- src/FDM/JSBSim/models/FGOutput.h | 13 +- src/FDM/JSBSim/models/FGPropagate.cpp | 18 +- src/FDM/JSBSim/models/FGPropagate.h | 13 +- src/FDM/JSBSim/models/FGPropulsion.cpp | 12 +- src/FDM/JSBSim/models/FGPropulsion.h | 14 +- src/FDM/JSBSim/models/atmosphere/FGMSIS.cpp | 166 ++--- src/FDM/JSBSim/models/atmosphere/FGMSIS.h | 137 ++++- .../atmosphere/FGStandardAtmosphere.cpp | 568 ++++++++++++++++++ .../models/atmosphere/FGStandardAtmosphere.h | 379 ++++++++++++ .../models/flight_control/FGActuator.cpp | 9 +- .../models/flight_control/FGFCSComponent.cpp | 12 +- .../models/flight_control/FGFCSComponent.h | 7 +- .../JSBSim/models/flight_control/FGPID.cpp | 10 +- .../JSBSim/models/flight_control/FGSwitch.cpp | 3 +- .../JSBSim/models/propulsion/FGElectric.cpp | 13 +- src/FDM/JSBSim/models/propulsion/FGPiston.cpp | 22 +- src/FDM/JSBSim/models/propulsion/FGPiston.h | 207 ++++--- .../JSBSim/models/propulsion/FGPropeller.cpp | 25 +- .../JSBSim/models/propulsion/FGPropeller.h | 9 +- src/FDM/JSBSim/models/propulsion/FGTank.cpp | 10 +- src/FDM/JSBSim/models/propulsion/FGTank.h | 17 +- .../JSBSim/models/propulsion/FGTurbine.cpp | 4 +- src/FDM/JSBSim/models/propulsion/FGTurbine.h | 8 +- 56 files changed, 1748 insertions(+), 568 deletions(-) mode change 100644 => 100755 src/FDM/JSBSim/models/FGAuxiliary.cpp mode change 100644 => 100755 src/FDM/JSBSim/models/FGExternalReactions.cpp mode change 100644 => 100755 src/FDM/JSBSim/models/FGExternalReactions.h mode change 100644 => 100755 src/FDM/JSBSim/models/FGInput.h mode change 100644 => 100755 src/FDM/JSBSim/models/atmosphere/FGMSIS.cpp mode change 100644 => 100755 src/FDM/JSBSim/models/atmosphere/FGMSIS.h create mode 100644 src/FDM/JSBSim/models/atmosphere/FGStandardAtmosphere.cpp create mode 100644 src/FDM/JSBSim/models/atmosphere/FGStandardAtmosphere.h mode change 100644 => 100755 src/FDM/JSBSim/models/flight_control/FGPID.cpp diff --git a/src/FDM/JSBSim/FGFDMExec.cpp b/src/FDM/JSBSim/FGFDMExec.cpp index a3b08a49e..bcfe557f1 100644 --- a/src/FDM/JSBSim/FGFDMExec.cpp +++ b/src/FDM/JSBSim/FGFDMExec.cpp @@ -71,7 +71,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGFDMExec.cpp,v 1.91 2011/04/05 20:20:21 andgi Exp $"; +static const char *IdSrc = "$Id: FGFDMExec.cpp,v 1.95 2011/05/20 10:35:25 jberndt Exp $"; static const char *IdHdr = ID_FDMEXEC; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -228,19 +228,19 @@ bool FGFDMExec::Allocate(void) // Schedule a model. The second arg (the integer) is the pass number. For // instance, the atmosphere model could get executed every fifth pass it is called. - Schedule(Input, 1); - Schedule(Atmosphere, 1); - Schedule(FCS, 1); - Schedule(Propulsion, 1); - Schedule(MassBalance, 1); - Schedule(Aerodynamics, 1); - Schedule(Inertial, 1); - Schedule(GroundReactions, 1); - Schedule(ExternalReactions, 1); - Schedule(BuoyantForces, 1); - Schedule(Aircraft, 1); - Schedule(Propagate, 1); - Schedule(Auxiliary, 1); + Schedule(Input, 1); // Input model is Models[0] + Schedule(Atmosphere, 1); // Input model is Models[1] + Schedule(FCS, 1); // Input model is Models[2] + Schedule(Propulsion, 1); // Input model is Models[3] + Schedule(MassBalance, 1); // Input model is Models[4] + Schedule(Aerodynamics, 1); // Input model is Models[5] + Schedule(Inertial, 1); // Input model is Models[6] + Schedule(GroundReactions, 1); // Input model is Models[7] + Schedule(ExternalReactions, 1); // Input model is Models[8] + Schedule(BuoyantForces, 1); // Input model is Models[9] + Schedule(Aircraft, 1); // Input model is Models[10] + Schedule(Propagate, 1); // Input model is Models[11] + Schedule(Auxiliary, 1); // Input model is Models[12] // Initialize models so they can communicate with each other @@ -329,10 +329,9 @@ bool FGFDMExec::Run(void) if (Script != 0 && !IntegrationSuspended()) success = Script->RunScript(); vector <FGModel*>::iterator it; - for (it = Models.begin(); it != Models.end(); ++it) (*it)->Run(); + for (it = Models.begin(); it != Models.end(); ++it) (*it)->Run(holding); - Frame++; - if (!Holding()) IncrTime(); + IncrTime(); if (Terminate) success = false; return (success); @@ -359,36 +358,12 @@ void FGFDMExec::Initialize(FGInitialCondition *FGIC) Propagate->SetInitialState( FGIC ); - Atmosphere->Run(); + Atmosphere->Run(false); Atmosphere->SetWindNED( FGIC->GetWindNFpsIC(), FGIC->GetWindEFpsIC(), FGIC->GetWindDFpsIC() ); - FGColumnVector3 vAeroUVW; - - //ToDo: move this to the Auxiliary class !? - - vAeroUVW = Propagate->GetUVW() + Propagate->GetTl2b()*Atmosphere->GetTotalWindNED(); - - double alpha, beta; - if (vAeroUVW(eW) != 0.0) - alpha = vAeroUVW(eU)*vAeroUVW(eU) > 0.0 ? atan2(vAeroUVW(eW), vAeroUVW(eU)) : 0.0; - else - alpha = 0.0; - if (vAeroUVW(eV) != 0.0) - beta = vAeroUVW(eU)*vAeroUVW(eU)+vAeroUVW(eW)*vAeroUVW(eW) > 0.0 ? atan2(vAeroUVW(eV), (fabs(vAeroUVW(eU))/vAeroUVW(eU))*sqrt(vAeroUVW(eU)*vAeroUVW(eU) + vAeroUVW(eW)*vAeroUVW(eW))) : 0.0; - else - beta = 0.0; - - Auxiliary->SetAB(alpha, beta); - - double Vt = vAeroUVW.Magnitude(); - Auxiliary->SetVt(Vt); - - Auxiliary->SetMach(Vt/Atmosphere->GetSoundSpeed()); - - double qbar = 0.5*Vt*Vt*Atmosphere->GetDensity(); - Auxiliary->Setqbar(qbar); + Auxiliary->Run(false); } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -675,7 +650,7 @@ bool FGFDMExec::LoadModel(const string& model, bool addModelToPath) modelLoaded = true; if (debug_lvl > 0) { - MassBalance->Run(); // Update all mass properties for the report. + MassBalance->Run(false); // Update all mass properties for the report. MassBalance->GetMassPropertiesReport(); cout << endl << fgblue << highint @@ -968,38 +943,6 @@ void FGFDMExec::DoTrim(int mode) sim_time = saved_time; } -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -/* -void FGFDMExec::DoTrimAnalysis(int mode) -{ - double saved_time; - if (Constructing) return; - - if (mode < 0 || mode > JSBSim::taNone) { - cerr << endl << "Illegal trimming mode!" << endl << endl; - return; - } - saved_time = sim_time; - - FGTrimAnalysis trimAnalysis(this, (JSBSim::TrimAnalysisMode)mode); - - if ( !trimAnalysis.Load(IC->GetInitFile(), false) ) { - cerr << "A problem occurred with trim configuration file " << trimAnalysis.Load(IC->GetInitFile()) << endl; - exit(-1); - } - - bool result = trimAnalysis.DoTrim(); - - if ( !result ) cerr << endl << "Trim Failed" << endl << endl; - - trimAnalysis.Report(); - Setsim_time(saved_time); - - EnableOutput(); - cout << "\nOutput: " << GetOutputFileName() << endl; - -} -*/ //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% void FGFDMExec::UseAtmosphereMSIS(void) @@ -1010,6 +953,8 @@ void FGFDMExec::UseAtmosphereMSIS(void) cerr << fgred << "MSIS Atmosphere model init failed" << fgdef << endl; Error+=1; } + Models[1] = Atmosphere; // Reassign the atmosphere model that has already been scheduled + // to the new atmosphere. delete oldAtmosphere; } @@ -1024,6 +969,8 @@ void FGFDMExec::UseAtmosphereMars(void) cerr << fgred << "Mars Atmosphere model init failed" << fgdef << endl; Error+=1; } + Models[1] = Atmosphere; // Reassign the atmosphere model that has already been scheduled + // to the new atmosphere. delete oldAtmosphere; */ } diff --git a/src/FDM/JSBSim/FGFDMExec.h b/src/FDM/JSBSim/FGFDMExec.h index 5f103fe15..e745b2224 100644 --- a/src/FDM/JSBSim/FGFDMExec.h +++ b/src/FDM/JSBSim/FGFDMExec.h @@ -58,7 +58,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_FDMEXEC "$Id: FGFDMExec.h,v 1.63 2011/02/19 16:44:41 jberndt Exp $" +#define ID_FDMEXEC "$Id: FGFDMExec.h,v 1.64 2011/05/20 03:18:36 jberndt Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -181,7 +181,7 @@ CLASS DOCUMENTATION property actually maps toa function call of DoTrim(). @author Jon S. Berndt - @version $Revision: 1.63 $ + @version $Revision: 1.64 $ */ /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -432,7 +432,6 @@ public: * - tTurn * - tNone */ void DoTrim(int mode); -// void DoTrimAnalysis(int mode); /// Disables data logging to all outputs. void DisableOutput(void); @@ -522,10 +521,12 @@ public: @return the string representing the root (base) JSBSim directory. */ const string& GetRootDir(void) const {return RootDir;} - /** Increments the simulation time. + /** Increments the simulation time if not in Holding mode. The Frame counter + is also incremented. @return the new simulation time. */ double IncrTime(void) { - sim_time += dT; + if (!holding) sim_time += dT; + Frame++; return sim_time; } diff --git a/src/FDM/JSBSim/FGJSBBase.cpp b/src/FDM/JSBSim/FGJSBBase.cpp index a361a37d2..d34075e70 100644 --- a/src/FDM/JSBSim/FGJSBBase.cpp +++ b/src/FDM/JSBSim/FGJSBBase.cpp @@ -44,7 +44,7 @@ INCLUDES namespace JSBSim { -static const char *IdSrc = "$Id: FGJSBBase.cpp,v 1.29 2010/03/18 13:19:21 jberndt Exp $"; +static const char *IdSrc = "$Id: FGJSBBase.cpp,v 1.30 2011/06/13 11:47:04 jberndt Exp $"; static const char *IdHdr = ID_JSBBASE; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -89,7 +89,9 @@ const double FGJSBBase::in3tom3 = 1.638706E-5; const double FGJSBBase::m3toft3 = 1.0/(fttom*fttom*fttom); const double FGJSBBase::inhgtopa = 3386.38; const double FGJSBBase::fttom = 0.3048; -double FGJSBBase::Reng = 1716.0; +double FGJSBBase::Reng = 1716.56; // Gas constant for Air (ft-lb/slug-R) +double FGJSBBase::Rstar = 1545.348; // Universal gas constant +double FGJSBBase::Mair = 28.9645; // const double FGJSBBase::SHRatio = 1.40; // Note that definition of lbtoslug by the inverse of slugtolb and not diff --git a/src/FDM/JSBSim/FGJSBBase.h b/src/FDM/JSBSim/FGJSBBase.h index 2049a3cad..69d9f9c09 100644 --- a/src/FDM/JSBSim/FGJSBBase.h +++ b/src/FDM/JSBSim/FGJSBBase.h @@ -63,7 +63,7 @@ namespace std DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_JSBBASE "$Id: FGJSBBase.h,v 1.30 2010/07/01 23:13:19 jberndt Exp $" +#define ID_JSBBASE "$Id: FGJSBBase.h,v 1.32 2011/06/13 11:47:04 jberndt Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -79,7 +79,7 @@ CLASS DOCUMENTATION * This class provides universal constants, utility functions, messaging * functions, and enumerated constants to JSBSim. @author Jon S. Berndt - @version $Id: FGJSBBase.h,v 1.30 2010/07/01 23:13:19 jberndt Exp $ + @version $Id: FGJSBBase.h,v 1.32 2011/06/13 11:47:04 jberndt Exp $ */ /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -92,7 +92,7 @@ public: FGJSBBase() {}; /// Destructor for FGJSBBase. - ~FGJSBBase() {}; + virtual ~FGJSBBase() {}; /// JSBSim Message structure class Message { @@ -327,6 +327,8 @@ protected: static const double inhgtopa; static const double fttom; static double Reng; // Specific Gas Constant,ft^2/(sec^2*R) + static double Rstar; + static double Mair; static const double SHRatio; static const double lbtoslug; static const double slugtolb; diff --git a/src/FDM/JSBSim/JSBSim.cxx b/src/FDM/JSBSim/JSBSim.cxx index 3e6cdf7bd..3b5199599 100644 --- a/src/FDM/JSBSim/JSBSim.cxx +++ b/src/FDM/JSBSim/JSBSim.cxx @@ -140,7 +140,7 @@ FGJSBsim::FGJSBsim( double dt ) if( TURBULENCE_TYPE_NAMES.empty() ) { TURBULENCE_TYPE_NAMES["ttNone"] = FGAtmosphere::ttNone; TURBULENCE_TYPE_NAMES["ttStandard"] = FGAtmosphere::ttStandard; - TURBULENCE_TYPE_NAMES["ttBerndt"] = FGAtmosphere::ttBerndt; +// TURBULENCE_TYPE_NAMES["ttBerndt"] = FGAtmosphere::ttBerndt; TURBULENCE_TYPE_NAMES["ttCulp"] = FGAtmosphere::ttCulp; TURBULENCE_TYPE_NAMES["ttMilspec"] = FGAtmosphere::ttMilspec; TURBULENCE_TYPE_NAMES["ttTustin"] = FGAtmosphere::ttTustin; @@ -672,9 +672,9 @@ bool FGJSBsim::copy_to_JSBsim() Atmosphere->SetTurbType((FGAtmosphere::tType)TURBULENCE_TYPE_NAMES[turbulence_model->getStringValue()]); switch( Atmosphere->GetTurbType() ) { +// case FGAtmosphere::ttBerndt: case FGAtmosphere::ttStandard: - case FGAtmosphere::ttCulp: - case FGAtmosphere::ttBerndt: { + case FGAtmosphere::ttCulp: { double tmp = turbulence_gain->getDoubleValue(); Atmosphere->SetTurbGain(tmp * tmp * 100.0); Atmosphere->SetTurbRate(turbulence_rate->getDoubleValue()); diff --git a/src/FDM/JSBSim/initialization/FGInitialCondition.cpp b/src/FDM/JSBSim/initialization/FGInitialCondition.cpp index 00a3840f1..d1b65f1bc 100644 --- a/src/FDM/JSBSim/initialization/FGInitialCondition.cpp +++ b/src/FDM/JSBSim/initialization/FGInitialCondition.cpp @@ -61,7 +61,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGInitialCondition.cpp,v 1.61 2011/05/20 00:47:03 bcoconni Exp $"; +static const char *IdSrc = "$Id: FGInitialCondition.cpp,v 1.63 2011/06/13 10:30:22 bcoconni Exp $"; static const char *IdHdr = ID_INITIALCONDITION; //****************************************************************************** @@ -189,7 +189,7 @@ void FGInitialCondition::SetVequivalentKtsIC(double ve) double altitudeASL = position.GetRadius() - sea_level_radius; double rho = fdmex->GetAtmosphere()->GetDensity(altitudeASL); double rhoSL = fdmex->GetAtmosphere()->GetDensitySL(); - SetVtrueFpsIC(ve*ktstofps/sqrt(rho/rhoSL)); + SetVtrueFpsIC(ve*ktstofps*sqrt(rhoSL/rho)); lastSpeedSet = setve; } @@ -324,7 +324,7 @@ void FGInitialCondition::SetClimbRateFpsIC(double hdot) FGColumnVector3 _WIND_NED = _vt_NED - vUVW_NED; double hdot0 = -_vt_NED(eW); - if (fabs(hdot0) < vt) { + if (fabs(hdot0) < vt) { // Is this check really needed ? double scale = sqrt((vt*vt-hdot*hdot)/(vt*vt-hdot0*hdot0)); _vt_NED(eU) *= scale; _vt_NED(eV) *= scale; @@ -606,7 +606,7 @@ void FGInitialCondition::SetHeadWindKtsIC(double head) FGColumnVector3 _vWIND_NED = _vt_NED - vUVW_NED; FGColumnVector3 _vHEAD(cos(psi), sin(psi), 0.); - // Gram-Schmidt process is used to remove the existing cross wind component + // Gram-Schmidt process is used to remove the existing head wind component _vWIND_NED -= DotProduct(_vWIND_NED, _vHEAD) * _vHEAD; // which is now replaced by the new value. _vWIND_NED += head * _vHEAD; @@ -707,7 +707,7 @@ void FGInitialCondition::SetAltitudeASLFtIC(double alt) SetVtrueFpsIC(mach0 * soundSpeed); break; case setve: - SetVtrueFpsIC(ve0 * sqrt(rho/rhoSL)); + SetVtrueFpsIC(ve0 * sqrt(rhoSL/rho)); break; default: // Make the compiler stop complaining about missing enums break; @@ -1088,7 +1088,7 @@ bool FGInitialCondition::Load_v2(void) // the given orientation and knowledge of the Earth position angle. // This could be done using matrices (where in the subscript "b/a", // it is meant "b with respect to a", and where b=body frame, - // i=inertial frame, and e=ecef frame) as: + // i=inertial frame, l=local NED frame and e=ecef frame) as: // // C_b/l = C_b/e * C_e/l // diff --git a/src/FDM/JSBSim/math/FGTable.cpp b/src/FDM/JSBSim/math/FGTable.cpp index 0780739c9..08396eaae 100644 --- a/src/FDM/JSBSim/math/FGTable.cpp +++ b/src/FDM/JSBSim/math/FGTable.cpp @@ -47,7 +47,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGTable.cpp,v 1.27 2010/10/21 11:09:56 jberndt Exp $"; +static const char *IdSrc = "$Id: FGTable.cpp,v 1.28 2011/06/13 12:07:10 jberndt Exp $"; static const char *IdHdr = ID_TABLE; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -559,6 +559,8 @@ void FGTable::operator<<(istream& in_stream) //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +// Put some error handling in here if trying to access out of range row, col. + FGTable& FGTable::operator<<(const double n) { Data[rowCounter][colCounter] = n; diff --git a/src/FDM/JSBSim/math/FGTable.h b/src/FDM/JSBSim/math/FGTable.h index 3d2224981..1989de4c2 100644 --- a/src/FDM/JSBSim/math/FGTable.h +++ b/src/FDM/JSBSim/math/FGTable.h @@ -47,7 +47,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_TABLE "$Id: FGTable.h,v 1.13 2011/04/05 20:20:21 andgi Exp $" +#define ID_TABLE "$Id: FGTable.h,v 1.14 2011/06/13 11:46:08 jberndt Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -233,7 +233,7 @@ combustion_efficiency = Lookup_Combustion_Efficiency->GetValue(equivalence_ratio @endcode @author Jon S. Berndt -@version $Id: FGTable.h,v 1.13 2011/04/05 20:20:21 andgi Exp $ +@version $Id: FGTable.h,v 1.14 2011/06/13 11:46:08 jberndt Exp $ */ /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -284,12 +284,17 @@ public: FGTable& operator<<(const double n); FGTable& operator<<(const int n); - inline double GetElement(int r, int c) {return Data[r][c];} - inline double GetElement(int r, int c, int t); + inline double GetElement(int r, int c) const {return Data[r][c];} +// inline double GetElement(int r, int c, int t); + + double operator()(unsigned int r, unsigned int c) const {return GetElement(r, c);} +// double operator()(unsigned int r, unsigned int c, unsigned int t) {GetElement(r, c, t);} void SetRowIndexProperty(FGPropertyManager *node) {lookupProperty[eRow] = node;} void SetColumnIndexProperty(FGPropertyManager *node) {lookupProperty[eColumn] = node;} + unsigned int GetNumRows() const {return nRows;} + void Print(void); std::string GetName(void) const {return Name;} diff --git a/src/FDM/JSBSim/models/FGAerodynamics.cpp b/src/FDM/JSBSim/models/FGAerodynamics.cpp index 0f08c0160..4208ef626 100644 --- a/src/FDM/JSBSim/models/FGAerodynamics.cpp +++ b/src/FDM/JSBSim/models/FGAerodynamics.cpp @@ -52,7 +52,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGAerodynamics.cpp,v 1.37 2011/03/11 13:02:26 jberndt Exp $"; +static const char *IdSrc = "$Id: FGAerodynamics.cpp,v 1.38 2011/05/20 03:18:36 jberndt Exp $"; static const char *IdHdr = ID_AERODYNAMICS; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -132,11 +132,11 @@ bool FGAerodynamics::InitModel(void) } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -bool FGAerodynamics::Run(void) +bool FGAerodynamics::Run(bool Holding) { - if (FGModel::Run()) return true; - if (FDMExec->Holding()) return false; // if paused don't execute + if (FGModel::Run(Holding)) return true; + if (Holding) return false; // if paused don't execute unsigned int axis_ctr, ctr; const double alpha=FDMExec->GetAuxiliary()->Getalpha(); diff --git a/src/FDM/JSBSim/models/FGAerodynamics.h b/src/FDM/JSBSim/models/FGAerodynamics.h index c6638b411..87744e86e 100644 --- a/src/FDM/JSBSim/models/FGAerodynamics.h +++ b/src/FDM/JSBSim/models/FGAerodynamics.h @@ -52,7 +52,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_AERODYNAMICS "$Id: FGAerodynamics.h,v 1.22 2011/03/11 13:02:26 jberndt Exp $" +#define ID_AERODYNAMICS "$Id: FGAerodynamics.h,v 1.23 2011/05/20 03:18:36 jberndt Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -109,7 +109,7 @@ CLASS DOCUMENTATION Systems may NOT be combined, or a load error will occur. @author Jon S. Berndt, Tony Peden - @version $Revision: 1.22 $ + @version $Revision: 1.23 $ */ /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -129,8 +129,13 @@ public: bool InitModel(void); /** Runs the Aerodynamics model; called by the Executive + Can pass in a value indicating if the executive is directing the simulation to Hold. + @param Holding if true, the executive has been directed to hold the sim from + advancing time. Some models may ignore this flag, such as the Input + model, which may need to be active to listen on a socket for the + "Resume" command to be given. @return false if no error */ - bool Run(void); + bool Run(bool Holding); /** Loads the Aerodynamics model. The Load function for this class expects the XML parser to diff --git a/src/FDM/JSBSim/models/FGAircraft.cpp b/src/FDM/JSBSim/models/FGAircraft.cpp index e2adbe44c..7b0f3705a 100644 --- a/src/FDM/JSBSim/models/FGAircraft.cpp +++ b/src/FDM/JSBSim/models/FGAircraft.cpp @@ -67,7 +67,7 @@ DEFINITIONS GLOBAL DATA %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -static const char *IdSrc = "$Id: FGAircraft.cpp,v 1.30 2010/11/29 12:33:57 jberndt Exp $"; +static const char *IdSrc = "$Id: FGAircraft.cpp,v 1.31 2011/05/20 03:18:36 jberndt Exp $"; static const char *IdHdr = ID_AIRCRAFT; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -101,17 +101,15 @@ FGAircraft::~FGAircraft() bool FGAircraft::InitModel(void) { - if (!FGModel::InitModel()) return false; - return true; } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -bool FGAircraft::Run(void) +bool FGAircraft::Run(bool Holding) { - if (FGModel::Run()) return true; - if (FDMExec->Holding()) return false; + if (FGModel::Run(Holding)) return true; + if (Holding) return false; RunPreFunctions(); diff --git a/src/FDM/JSBSim/models/FGAircraft.h b/src/FDM/JSBSim/models/FGAircraft.h index c3060db37..684f1dd2e 100644 --- a/src/FDM/JSBSim/models/FGAircraft.h +++ b/src/FDM/JSBSim/models/FGAircraft.h @@ -49,7 +49,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_AIRCRAFT "$Id: FGAircraft.h,v 1.16 2010/11/18 12:38:06 jberndt Exp $" +#define ID_AIRCRAFT "$Id: FGAircraft.h,v 1.17 2011/05/20 03:18:36 jberndt Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -90,7 +90,7 @@ CLASS DOCUMENTATION @endcode @author Jon S. Berndt - @version $Id: FGAircraft.h,v 1.16 2010/11/18 12:38:06 jberndt Exp $ + @version $Id: FGAircraft.h,v 1.17 2011/05/20 03:18:36 jberndt Exp $ @see Cooke, Zyda, Pratt, and McGhee, "NPSNET: Flight Simulation Dynamic Modeling Using Quaternions", Presence, Vol. 1, No. 4, pp. 404-420 Naval Postgraduate School, January 1994 @@ -118,9 +118,14 @@ public: ~FGAircraft(); /** Runs the Aircraft model; called by the Executive + Can pass in a value indicating if the executive is directing the simulation to Hold. + @param Holding if true, the executive has been directed to hold the sim from + advancing time. Some models may ignore this flag, such as the Input + model, which may need to be active to listen on a socket for the + "Resume" command to be given. @see JSBSim.cpp documentation @return false if no error */ - bool Run(void); + bool Run(bool Holding); bool InitModel(void); diff --git a/src/FDM/JSBSim/models/FGAtmosphere.cpp b/src/FDM/JSBSim/models/FGAtmosphere.cpp index 992e7952e..990adb882 100644 --- a/src/FDM/JSBSim/models/FGAtmosphere.cpp +++ b/src/FDM/JSBSim/models/FGAtmosphere.cpp @@ -61,7 +61,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGAtmosphere.cpp,v 1.42 2011/02/18 12:44:16 jberndt Exp $"; +static const char *IdSrc = "$Id: FGAtmosphere.cpp,v 1.45 2011/05/20 03:18:36 jberndt Exp $"; static const char *IdHdr = ID_ATMOSPHERE; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -84,8 +84,7 @@ FGAtmosphere::FGAtmosphere(FGFDMExec* fdmex) : FGModel(fdmex) htab[7]=278385.0; //ft. MagnitudedAccelDt = MagnitudeAccel = Magnitude = 0.0; -// SetTurbType( ttCulp ); - SetTurbType( ttNone ); + SetTurbType( ttMilspec ); TurbGain = 1.0; TurbRate = 10.0; Rhythmicity = 0.1; @@ -132,8 +131,6 @@ FGAtmosphere::~FGAtmosphere() bool FGAtmosphere::InitModel(void) { - if (!FGModel::InitModel()) return false; - UseInternal(); // this is the default Calculate(h); @@ -151,10 +148,10 @@ bool FGAtmosphere::InitModel(void) //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -bool FGAtmosphere::Run(void) +bool FGAtmosphere::Run(bool Holding) { - if (FGModel::Run()) return true; - if (FDMExec->Holding()) return false; + if (FGModel::Run(Holding)) return true; + if (Holding) return false; RunPreFunctions(); @@ -483,45 +480,7 @@ void FGAtmosphere::Turbulence(void) break; } - case ttBerndt: { // This is very experimental and incomplete at the moment. - vDirectiondAccelDt(eX) = GaussianRandomNumber(); - vDirectiondAccelDt(eY) = GaussianRandomNumber(); - vDirectiondAccelDt(eZ) = GaussianRandomNumber(); -/* - MagnitudedAccelDt = GaussianRandomNumber(); - MagnitudeAccel += MagnitudedAccelDt * DeltaT; - Magnitude += MagnitudeAccel * DeltaT; -*/ - Magnitude += GaussianRandomNumber() * DeltaT; - - vDirectiondAccelDt.Normalize(); - vDirectionAccel += TurbRate * vDirectiondAccelDt * DeltaT; - vDirectionAccel.Normalize(); - vDirection += vDirectionAccel*DeltaT; - - // Diminish z-vector within two wingspans of the ground - if (HOverBMAC < 2.0) vDirection(eZ) *= HOverBMAC / 2.0; - - vDirection.Normalize(); - - vTurbulenceNED = TurbGain*Magnitude * vDirection; - vTurbulenceGrad = TurbGain*MagnitudeAccel * vDirection; - - vBodyTurbGrad = Tl2b * vTurbulenceGrad; - vTurbPQR(eP) = vBodyTurbGrad(eY) / wingspan; - if (HTailArm > 0) - vTurbPQR(eQ) = vBodyTurbGrad(eZ) / HTailArm; - else - vTurbPQR(eQ) = vBodyTurbGrad(eZ) / 10.0; - - if (VTailArm > 0) - vTurbPQR(eR) = vBodyTurbGrad(eX) / VTailArm; - else - vTurbPQR(eR) = vBodyTurbGrad(eX)/10.0; - - break; - } case ttCulp: { vTurbPQR(eP) = wind_from_clockwise; diff --git a/src/FDM/JSBSim/models/FGAtmosphere.h b/src/FDM/JSBSim/models/FGAtmosphere.h index 3dd6fa322..d2c8b5dbe 100644 --- a/src/FDM/JSBSim/models/FGAtmosphere.h +++ b/src/FDM/JSBSim/models/FGAtmosphere.h @@ -50,7 +50,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_ATMOSPHERE "$Id: FGAtmosphere.h,v 1.24 2010/11/18 12:38:06 jberndt Exp $" +#define ID_ATMOSPHERE "$Id: FGAtmosphere.h,v 1.26 2011/05/20 03:18:36 jberndt Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -64,7 +64,7 @@ CLASS DOCUMENTATION /** Models the 1976 Standard Atmosphere. @author Tony Peden, Jon Berndt - @version $Id: FGAtmosphere.h,v 1.24 2010/11/18 12:38:06 jberndt Exp $ + @version $Id: FGAtmosphere.h,v 1.26 2011/05/20 03:18:36 jberndt Exp $ @see Anderson, John D. "Introduction to Flight, Third Edition", McGraw-Hill, 1989, ISBN 0-07-001641-0 @@ -132,102 +132,107 @@ public: /// Destructor ~FGAtmosphere(); /** Runs the Atmosphere model; called by the Executive + Can pass in a value indicating if the executive is directing the simulation to Hold. + @param Holding if true, the executive has been directed to hold the sim from + advancing time. Some models may ignore this flag, such as the Input + model, which may need to be active to listen on a socket for the + "Resume" command to be given. @return false if no error */ - bool Run(void); + bool Run(bool Holding); bool InitModel(void); - enum tType {ttNone, ttStandard, ttBerndt, ttCulp, ttMilspec, ttTustin} turbType; + enum tType {ttNone, ttStandard, ttCulp, ttMilspec, ttTustin} turbType; /// Returns the temperature in degrees Rankine. - double GetTemperature(void) const {return *temperature;} + virtual double GetTemperature(void) const {return *temperature;} /** Returns the density in slugs/ft^3. <i>This function may <b>only</b> be used if Run() is called first.</i> */ - double GetDensity(void) const {return *density;} + virtual double GetDensity(void) const {return *density;} /// Returns the pressure in psf. - double GetPressure(void) const {return *pressure;} + virtual double GetPressure(void) const {return *pressure;} /// Returns the standard pressure at a specified altitude - double GetPressure(double altitude); + virtual double GetPressure(double altitude); /// Returns the standard temperature at a specified altitude - double GetTemperature(double altitude); + virtual double GetTemperature(double altitude); /// Returns the standard density at a specified altitude - double GetDensity(double altitude); + virtual double GetDensity(double altitude); /// Returns the speed of sound in ft/sec. - double GetSoundSpeed(void) const {return soundspeed;} + virtual double GetSoundSpeed(void) const {return soundspeed;} /// Returns the absolute viscosity. - double GetAbsoluteViscosity(void) const {return intViscosity;} + virtual double GetAbsoluteViscosity(void) const {return intViscosity;} /// Returns the kinematic viscosity. - double GetKinematicViscosity(void) const {return intKinematicViscosity;} + virtual double GetKinematicViscosity(void) const {return intKinematicViscosity;} /// Returns the sea level temperature in degrees Rankine. - double GetTemperatureSL(void) const { return SLtemperature; } + virtual double GetTemperatureSL(void) const { return SLtemperature; } /// Returns the sea level density in slugs/ft^3 - double GetDensitySL(void) const { return SLdensity; } + virtual double GetDensitySL(void) const { return SLdensity; } /// Returns the sea level pressure in psf. - double GetPressureSL(void) const { return SLpressure; } + virtual double GetPressureSL(void) const { return SLpressure; } /// Returns the sea level speed of sound in ft/sec. - double GetSoundSpeedSL(void) const { return SLsoundspeed; } + virtual double GetSoundSpeedSL(void) const { return SLsoundspeed; } /// Returns the ratio of at-altitude temperature over the sea level value. - double GetTemperatureRatio(void) const { return (*temperature)*rSLtemperature; } + virtual double GetTemperatureRatio(void) const { return (*temperature)*rSLtemperature; } /// Returns the ratio of at-altitude density over the sea level value. - double GetDensityRatio(void) const { return (*density)*rSLdensity; } + virtual double GetDensityRatio(void) const { return (*density)*rSLdensity; } /// Returns the ratio of at-altitude pressure over the sea level value. - double GetPressureRatio(void) const { return (*pressure)*rSLpressure; } + virtual double GetPressureRatio(void) const { return (*pressure)*rSLpressure; } /// Returns the ratio of at-altitude sound speed over the sea level value. - double GetSoundSpeedRatio(void) const { return soundspeed*rSLsoundspeed; } + virtual double GetSoundSpeedRatio(void) const { return soundspeed*rSLsoundspeed; } /// Tells the simulator to use an externally calculated atmosphere model. - void UseExternal(void); + virtual void UseExternal(void); /// Tells the simulator to use the internal atmosphere model. - void UseInternal(void); //this is the default + virtual void UseInternal(void); //this is the default /// Gets the boolean that tells if the external atmosphere model is being used. - bool External(void) { return useExternal; } + virtual bool External(void) { return useExternal; } /// Provides the external atmosphere model with an interface to set the temperature. - void SetExTemperature(double t) { exTemperature=t; } + virtual void SetExTemperature(double t) { exTemperature=t; } /// Provides the external atmosphere model with an interface to set the density. - void SetExDensity(double d) { exDensity=d; } + virtual void SetExDensity(double d) { exDensity=d; } /// Provides the external atmosphere model with an interface to set the pressure. - void SetExPressure(double p) { exPressure=p; } + virtual void SetExPressure(double p) { exPressure=p; } /// Sets the temperature deviation at sea-level in degrees Fahrenheit - void SetSLTempDev(double d) { T_dev_sl = d; } + virtual void SetSLTempDev(double d) { T_dev_sl = d; } /// Gets the temperature deviation at sea-level in degrees Fahrenheit - double GetSLTempDev(void) const { return T_dev_sl; } + virtual double GetSLTempDev(void) const { return T_dev_sl; } /// Sets the current delta-T in degrees Fahrenheit - void SetDeltaT(double d) { delta_T = d; } + virtual void SetDeltaT(double d) { delta_T = d; } /// Gets the current delta-T in degrees Fahrenheit - double GetDeltaT(void) const { return delta_T; } + virtual double GetDeltaT(void) const { return delta_T; } /// Gets the at-altitude temperature deviation in degrees Fahrenheit - double GetTempDev(void) const { return T_dev; } + virtual double GetTempDev(void) const { return T_dev; } /// Gets the density altitude in feet - double GetDensityAltitude(void) const { return density_altitude; } + virtual double GetDensityAltitude(void) const { return density_altitude; } // TOTAL WIND access functions (wind + gust + turbulence) /// Retrieves the total wind components in NED frame. - const FGColumnVector3& GetTotalWindNED(void) const { return vTotalWindNED; } + virtual const FGColumnVector3& GetTotalWindNED(void) const { return vTotalWindNED; } /// Retrieves a total wind component in NED frame. - double GetTotalWindNED(int idx) const {return vTotalWindNED(idx);} + virtual double GetTotalWindNED(int idx) const {return vTotalWindNED(idx);} // WIND access functions /// Sets the wind components in NED frame. - void SetWindNED(double wN, double wE, double wD) { vWindNED(1)=wN; vWindNED(2)=wE; vWindNED(3)=wD;} + virtual void SetWindNED(double wN, double wE, double wD) { vWindNED(1)=wN; vWindNED(2)=wE; vWindNED(3)=wD;} /// Sets a wind component in NED frame. - void SetWindNED(int idx, double wind) { vWindNED(idx)=wind;} + virtual void SetWindNED(int idx, double wind) { vWindNED(idx)=wind;} /// Retrieves the wind components in NED frame. - FGColumnVector3& GetWindNED(void) { return vWindNED; } + virtual FGColumnVector3& GetWindNED(void) { return vWindNED; } /// Retrieves a wind component in NED frame. - double GetWindNED(int idx) const {return vWindNED(idx);} + virtual double GetWindNED(int idx) const {return vWindNED(idx);} /** Retrieves the direction that the wind is coming from. The direction is defined as north=0 and increases counterclockwise. The wind heading is returned in radians.*/ - double GetWindPsi(void) const { return psiw; } + virtual double GetWindPsi(void) const { return psiw; } /** Sets the direction that the wind is coming from. The direction is defined as north=0 and increases counterclockwise to 2*pi (radians). The @@ -235,56 +240,56 @@ public: sets the vWindNED vector components based on the supplied direction. The magnitude of the wind set in the vector is preserved (assuming the vertical component is non-zero). @param dir wind direction in the horizontal plane, in radians.*/ - void SetWindPsi(double dir); + virtual void SetWindPsi(double dir); - void SetWindspeed(double speed); + virtual void SetWindspeed(double speed); - double GetWindspeed(void) const; + virtual double GetWindspeed(void) const; // GUST access functions /// Sets a gust component in NED frame. - void SetGustNED(int idx, double gust) { vGustNED(idx)=gust;} + virtual void SetGustNED(int idx, double gust) { vGustNED(idx)=gust;} /// Sets a turbulence component in NED frame. - void SetTurbNED(int idx, double turb) { vTurbulenceNED(idx)=turb;} + virtual void SetTurbNED(int idx, double turb) { vTurbulenceNED(idx)=turb;} /// Sets the gust components in NED frame. - void SetGustNED(double gN, double gE, double gD) { vGustNED(eNorth)=gN; vGustNED(eEast)=gE; vGustNED(eDown)=gD;} + virtual void SetGustNED(double gN, double gE, double gD) { vGustNED(eNorth)=gN; vGustNED(eEast)=gE; vGustNED(eDown)=gD;} /// Retrieves a gust component in NED frame. - double GetGustNED(int idx) const {return vGustNED(idx);} + virtual double GetGustNED(int idx) const {return vGustNED(idx);} /// Retrieves a turbulence component in NED frame. - double GetTurbNED(int idx) const {return vTurbulenceNED(idx);} + virtual double GetTurbNED(int idx) const {return vTurbulenceNED(idx);} /// Retrieves the gust components in NED frame. - FGColumnVector3& GetGustNED(void) {return vGustNED;} + virtual FGColumnVector3& GetGustNED(void) {return vGustNED;} /** Turbulence models available: ttNone, ttStandard, ttBerndt, ttCulp, ttMilspec, ttTustin */ - void SetTurbType(tType tt) {turbType = tt;} - tType GetTurbType() const {return turbType;} + virtual void SetTurbType(tType tt) {turbType = tt;} + virtual tType GetTurbType() const {return turbType;} - void SetTurbGain(double tg) {TurbGain = tg;} - double GetTurbGain() const {return TurbGain;} + virtual void SetTurbGain(double tg) {TurbGain = tg;} + virtual double GetTurbGain() const {return TurbGain;} - void SetTurbRate(double tr) {TurbRate = tr;} - double GetTurbRate() const {return TurbRate;} + virtual void SetTurbRate(double tr) {TurbRate = tr;} + virtual double GetTurbRate() const {return TurbRate;} - void SetRhythmicity(double r) {Rhythmicity=r;} - double GetRhythmicity() const {return Rhythmicity;} + virtual void SetRhythmicity(double r) {Rhythmicity=r;} + virtual double GetRhythmicity() const {return Rhythmicity;} - double GetTurbPQR(int idx) const {return vTurbPQR(idx);} - double GetTurbMagnitude(void) const {return Magnitude;} - const FGColumnVector3& GetTurbDirection(void) const {return vDirection;} - const FGColumnVector3& GetTurbPQR(void) const {return vTurbPQR;} + virtual double GetTurbPQR(int idx) const {return vTurbPQR(idx);} + virtual double GetTurbMagnitude(void) const {return Magnitude;} + virtual const FGColumnVector3& GetTurbDirection(void) const {return vDirection;} + virtual const FGColumnVector3& GetTurbPQR(void) const {return vTurbPQR;} - void SetWindspeed20ft(double ws) { windspeed_at_20ft = ws;} - double GetWindspeed20ft() const { return windspeed_at_20ft;} + virtual void SetWindspeed20ft(double ws) { windspeed_at_20ft = ws;} + virtual double GetWindspeed20ft() const { return windspeed_at_20ft;} /// allowable range: 0-7, 3=light, 4=moderate, 6=severe turbulence - void SetProbabilityOfExceedence( int idx) {probability_of_exceedence_index = idx;} - int GetProbabilityOfExceedence() const { return probability_of_exceedence_index;} + virtual void SetProbabilityOfExceedence( int idx) {probability_of_exceedence_index = idx;} + virtual int GetProbabilityOfExceedence() const { return probability_of_exceedence_index;} protected: double rho; @@ -338,7 +343,7 @@ protected: /// Get T, P and rho for a standard atmosphere at the given altitude. void GetStdAtmosphere(double altitude); void Turbulence(void); - void bind(void); + virtual void bind(void); void Debug(int from); }; diff --git a/src/FDM/JSBSim/models/FGAuxiliary.cpp b/src/FDM/JSBSim/models/FGAuxiliary.cpp old mode 100644 new mode 100755 index 36c1e084a..0993bc757 --- a/src/FDM/JSBSim/models/FGAuxiliary.cpp +++ b/src/FDM/JSBSim/models/FGAuxiliary.cpp @@ -59,7 +59,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGAuxiliary.cpp,v 1.47 2011/03/29 11:49:27 jberndt Exp $"; +static const char *IdSrc = "$Id: FGAuxiliary.cpp,v 1.49 2011/05/20 03:18:36 jberndt Exp $"; static const char *IdHdr = ID_AUXILIARY; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -70,13 +70,14 @@ CLASS IMPLEMENTATION FGAuxiliary::FGAuxiliary(FGFDMExec* fdmex) : FGModel(fdmex) { Name = "FGAuxiliary"; - vcas = veas = pt = tat = 0; - psl = rhosl = 1; - qbar = 0; - qbarUW = 0.0; - qbarUV = 0.0; - Re = 0.0; - Mach = 0.0; + pt = p = psl = 1.0; + rho = rhosl = 1.0; + tat = sat = 1.0; + tatc = RankineToCelsius(tat); + + vcas = veas = 0.0; + qbar = qbarUW = qbarUV = 0.0; + Mach = MachU = 0.0; alpha = beta = 0.0; adot = bdot = 0.0; gamma = Vt = Vground = 0.0; @@ -84,13 +85,19 @@ FGAuxiliary::FGAuxiliary(FGFDMExec* fdmex) : FGModel(fdmex) day_of_year = 1; seconds_in_day = 0.0; hoverbmac = hoverbcg = 0.0; - tatc = RankineToCelsius(tat); + Re = 0.0; + Nz = 0.0; + lon_relative_position = lat_relative_position = relative_position = 0.0; vPilotAccel.InitMatrix(); vPilotAccelN.InitMatrix(); vToEyePt.InitMatrix(); + vAeroUVW.InitMatrix(); vAeroPQR.InitMatrix(); + vMachUVW.InitMatrix(); + vEuler.InitMatrix(); vEulerRates.InitMatrix(); + vAircraftAccel.InitMatrix(); bind(); @@ -101,14 +108,16 @@ FGAuxiliary::FGAuxiliary(FGFDMExec* fdmex) : FGModel(fdmex) bool FGAuxiliary::InitModel(void) { - if (!FGModel::InitModel()) return false; + pt = p = FDMExec->GetAtmosphere()->GetPressure(); + rho = FDMExec->GetAtmosphere()->GetDensity(); + rhosl = FDMExec->GetAtmosphere()->GetDensitySL(); + psl = FDMExec->GetAtmosphere()->GetPressureSL(); + tat = sat = FDMExec->GetAtmosphere()->GetTemperature(); + tatc = RankineToCelsius(tat); - vcas = veas = pt = tat = 0; - psl = rhosl = 1; - qbar = 0; - qbarUW = 0.0; - qbarUV = 0.0; - Mach = 0.0; + vcas = veas = 0.0; + qbar = qbarUW = qbarUV = 0.0; + Mach = MachU = 0.0; alpha = beta = 0.0; adot = bdot = 0.0; gamma = Vt = Vground = 0.0; @@ -116,12 +125,19 @@ bool FGAuxiliary::InitModel(void) day_of_year = 1; seconds_in_day = 0.0; hoverbmac = hoverbcg = 0.0; + Re = 0.0; + Nz = 0.0; + lon_relative_position = lat_relative_position = relative_position = 0.0; vPilotAccel.InitMatrix(); vPilotAccelN.InitMatrix(); vToEyePt.InitMatrix(); + vAeroUVW.InitMatrix(); vAeroPQR.InitMatrix(); + vMachUVW.InitMatrix(); + vEuler.InitMatrix(); vEulerRates.InitMatrix(); + vAircraftAccel.InitMatrix(); return true; } @@ -135,12 +151,12 @@ FGAuxiliary::~FGAuxiliary() //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -bool FGAuxiliary::Run() +bool FGAuxiliary::Run(bool Holding) { double A,B,D; - if (FGModel::Run()) return true; // return true if error returned from base class - if (FDMExec->Holding()) return false; + if (FGModel::Run(Holding)) return true; // return true if error returned from base class + if (Holding) return false; RunPreFunctions(); diff --git a/src/FDM/JSBSim/models/FGAuxiliary.h b/src/FDM/JSBSim/models/FGAuxiliary.h index 8f7821245..3061a8cd6 100644 --- a/src/FDM/JSBSim/models/FGAuxiliary.h +++ b/src/FDM/JSBSim/models/FGAuxiliary.h @@ -47,7 +47,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_AUXILIARY "$Id: FGAuxiliary.h,v 1.19 2010/11/18 12:38:06 jberndt Exp $" +#define ID_AUXILIARY "$Id: FGAuxiliary.h,v 1.20 2011/05/20 03:18:36 jberndt Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -99,7 +99,7 @@ CLASS DOCUMENTATION The radius R is calculated below in the vector vToEyePt. @author Tony Peden, Jon Berndt - @version $Id: FGAuxiliary.h,v 1.19 2010/11/18 12:38:06 jberndt Exp $ + @version $Id: FGAuxiliary.h,v 1.20 2011/05/20 03:18:36 jberndt Exp $ */ /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -118,8 +118,13 @@ public: bool InitModel(void); /** Runs the Auxiliary routines; called by the Executive + Can pass in a value indicating if the executive is directing the simulation to Hold. + @param Holding if true, the executive has been directed to hold the sim from + advancing time. Some models may ignore this flag, such as the Input + model, which may need to be active to listen on a socket for the + "Resume" command to be given. @return false if no error */ - bool Run(void); + bool Run(bool Holding); // GET functions diff --git a/src/FDM/JSBSim/models/FGBuoyantForces.cpp b/src/FDM/JSBSim/models/FGBuoyantForces.cpp index d12777478..96fd81d67 100644 --- a/src/FDM/JSBSim/models/FGBuoyantForces.cpp +++ b/src/FDM/JSBSim/models/FGBuoyantForces.cpp @@ -45,7 +45,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGBuoyantForces.cpp,v 1.16 2011/03/23 11:58:29 jberndt Exp $"; +static const char *IdSrc = "$Id: FGBuoyantForces.cpp,v 1.17 2011/05/20 03:18:36 jberndt Exp $"; static const char *IdHdr = ID_BUOYANTFORCES; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -80,17 +80,15 @@ FGBuoyantForces::~FGBuoyantForces() bool FGBuoyantForces::InitModel(void) { - if (!FGModel::InitModel()) return false; - return true; } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -bool FGBuoyantForces::Run(void) +bool FGBuoyantForces::Run(bool Holding) { - if (FGModel::Run()) return true; - if (FDMExec->Holding()) return false; // if paused don't execute + if (FGModel::Run(Holding)) return true; + if (Holding) return false; // if paused don't execute if (NoneDefined) return true; RunPreFunctions(); diff --git a/src/FDM/JSBSim/models/FGBuoyantForces.h b/src/FDM/JSBSim/models/FGBuoyantForces.h index c27566d37..e3baab137 100644 --- a/src/FDM/JSBSim/models/FGBuoyantForces.h +++ b/src/FDM/JSBSim/models/FGBuoyantForces.h @@ -51,7 +51,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_BUOYANTFORCES "$Id: FGBuoyantForces.h,v 1.11 2010/05/07 20:38:34 andgi Exp $" +#define ID_BUOYANTFORCES "$Id: FGBuoyantForces.h,v 1.12 2011/05/20 03:18:36 jberndt Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -96,7 +96,7 @@ CLASS DOCUMENTATION See FGGasCell for the full configuration file format for gas cells. @author Anders Gidenstam, Jon S. Berndt - @version $Id: FGBuoyantForces.h,v 1.11 2010/05/07 20:38:34 andgi Exp $ + @version $Id: FGBuoyantForces.h,v 1.12 2011/05/20 03:18:36 jberndt Exp $ */ /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -116,8 +116,13 @@ public: bool InitModel(void); /** Runs the Buoyant forces model; called by the Executive + Can pass in a value indicating if the executive is directing the simulation to Hold. + @param Holding if true, the executive has been directed to hold the sim from + advancing time. Some models may ignore this flag, such as the Input + model, which may need to be active to listen on a socket for the + "Resume" command to be given. @return false if no error */ - bool Run(void); + bool Run(bool Holding); /** Loads the Buoyant forces model. The Load function for this class expects the XML parser to diff --git a/src/FDM/JSBSim/models/FGExternalReactions.cpp b/src/FDM/JSBSim/models/FGExternalReactions.cpp old mode 100644 new mode 100755 index e39f8fb07..54a219bc4 --- a/src/FDM/JSBSim/models/FGExternalReactions.cpp +++ b/src/FDM/JSBSim/models/FGExternalReactions.cpp @@ -53,7 +53,7 @@ DEFINITIONS GLOBAL DATA %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -static const char *IdSrc = "$Id: FGExternalReactions.cpp,v 1.9 2010/09/07 00:40:03 jberndt Exp $"; +static const char *IdSrc = "$Id: FGExternalReactions.cpp,v 1.10 2011/05/20 03:18:36 jberndt Exp $"; static const char *IdHdr = ID_EXTERNALREACTIONS; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -104,17 +104,15 @@ FGExternalReactions::~FGExternalReactions() bool FGExternalReactions::InitModel(void) { - if (!FGModel::InitModel()) return false; - return true; } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -bool FGExternalReactions::Run() +bool FGExternalReactions::Run(bool Holding) { - if (FGModel::Run()) return true; - if (FDMExec->Holding()) return false; // if paused don't execute + if (FGModel::Run(Holding)) return true; + if (Holding) return false; // if paused don't execute if (NoneDefined) return true; RunPreFunctions(); diff --git a/src/FDM/JSBSim/models/FGExternalReactions.h b/src/FDM/JSBSim/models/FGExternalReactions.h old mode 100644 new mode 100755 index 4b7df2d85..36666697f --- a/src/FDM/JSBSim/models/FGExternalReactions.h +++ b/src/FDM/JSBSim/models/FGExternalReactions.h @@ -46,7 +46,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_EXTERNALREACTIONS "$Id: FGExternalReactions.h,v 1.10 2010/11/18 12:38:06 jberndt Exp $" +#define ID_EXTERNALREACTIONS "$Id: FGExternalReactions.h,v 1.11 2011/05/20 03:18:36 jberndt Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -132,9 +132,13 @@ public: bool InitModel(void); /** Sum all the constituent forces for this cycle. - @return true always. - */ - bool Run(void); + Can pass in a value indicating if the executive is directing the simulation to Hold. + @param Holding if true, the executive has been directed to hold the sim from + advancing time. Some models may ignore this flag, such as the Input + model, which may need to be active to listen on a socket for the + "Resume" command to be given. + @return true always. */ + bool Run(bool Holding); /** Loads the external forces from the XML configuration file. If the external_reactions section is encountered in the vehicle configuration diff --git a/src/FDM/JSBSim/models/FGFCS.cpp b/src/FDM/JSBSim/models/FGFCS.cpp index a3b7e91bc..67c02d698 100644 --- a/src/FDM/JSBSim/models/FGFCS.cpp +++ b/src/FDM/JSBSim/models/FGFCS.cpp @@ -63,7 +63,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGFCS.cpp,v 1.73 2011/04/05 20:20:21 andgi Exp $"; +static const char *IdSrc = "$Id: FGFCS.cpp,v 1.74 2011/05/20 03:18:36 jberndt Exp $"; static const char *IdHdr = ID_FCS; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -123,8 +123,6 @@ bool FGFCS::InitModel(void) { unsigned int i; - if (!FGModel::InitModel()) return false; - for (i=0; i<ThrottlePos.size(); i++) ThrottlePos[i] = 0.0; for (i=0; i<MixturePos.size(); i++) MixturePos[i] = 0.0; for (i=0; i<ThrottleCmd.size(); i++) ThrottleCmd[i] = 0.0; @@ -191,12 +189,12 @@ bool FGFCS::InitModel(void) // actually present in the flight_control or autopilot section will override // these simple assignments. -bool FGFCS::Run(void) +bool FGFCS::Run(bool Holding) { unsigned int i; - if (FGModel::Run()) return true; // fast exit if nothing to do - if (FDMExec->Holding()) return false; + if (FGModel::Run(Holding)) return true; // fast exit if nothing to do + if (Holding) return false; RunPreFunctions(); diff --git a/src/FDM/JSBSim/models/FGFCS.h b/src/FDM/JSBSim/models/FGFCS.h index 6b97297d5..9e6736eed 100644 --- a/src/FDM/JSBSim/models/FGFCS.h +++ b/src/FDM/JSBSim/models/FGFCS.h @@ -51,7 +51,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_FCS "$Id: FGFCS.h,v 1.35 2011/04/05 20:20:21 andgi Exp $" +#define ID_FCS "$Id: FGFCS.h,v 1.36 2011/05/20 03:18:36 jberndt Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -168,7 +168,7 @@ CLASS DOCUMENTATION @property gear/tailhook-pos-norm @author Jon S. Berndt - @version $Revision: 1.35 $ + @version $Revision: 1.36 $ @see FGActuator @see FGDeadBand @see FGFCSFunction @@ -200,8 +200,13 @@ public: bool InitModel(void); /** Runs the Flight Controls model; called by the Executive + Can pass in a value indicating if the executive is directing the simulation to Hold. + @param Holding if true, the executive has been directed to hold the sim from + advancing time. Some models may ignore this flag, such as the Input + model, which may need to be active to listen on a socket for the + "Resume" command to be given. @return false if no error */ - bool Run(void); + bool Run(bool Holding); /// @name Pilot input command retrieval //@{ diff --git a/src/FDM/JSBSim/models/FGGroundReactions.cpp b/src/FDM/JSBSim/models/FGGroundReactions.cpp index 9126c9f81..7f92cec41 100644 --- a/src/FDM/JSBSim/models/FGGroundReactions.cpp +++ b/src/FDM/JSBSim/models/FGGroundReactions.cpp @@ -46,7 +46,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGGroundReactions.cpp,v 1.31 2010/11/18 12:38:06 jberndt Exp $"; +static const char *IdSrc = "$Id: FGGroundReactions.cpp,v 1.32 2011/05/20 03:18:36 jberndt Exp $"; static const char *IdHdr = ID_GROUNDREACTIONS; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -116,17 +116,15 @@ FGGroundReactions::~FGGroundReactions(void) bool FGGroundReactions::InitModel(void) { - if (!FGModel::InitModel()) return false; - return true; } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -bool FGGroundReactions::Run(void) +bool FGGroundReactions::Run(bool Holding) { - if (FGModel::Run()) return true; - if (FDMExec->Holding()) return false; + if (FGModel::Run(Holding)) return true; + if (Holding) return false; RunPreFunctions(); diff --git a/src/FDM/JSBSim/models/FGGroundReactions.h b/src/FDM/JSBSim/models/FGGroundReactions.h index 30792225d..64bfafa1b 100644 --- a/src/FDM/JSBSim/models/FGGroundReactions.h +++ b/src/FDM/JSBSim/models/FGGroundReactions.h @@ -45,7 +45,7 @@ INCLUDES #include "math/FGColumnVector3.h" #include "input_output/FGXMLElement.h" -#define ID_GROUNDREACTIONS "$Id: FGGroundReactions.h,v 1.19 2010/11/18 12:38:06 jberndt Exp $" +#define ID_GROUNDREACTIONS "$Id: FGGroundReactions.h,v 1.20 2011/05/20 03:18:36 jberndt Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -98,7 +98,14 @@ public: ~FGGroundReactions(void); bool InitModel(void); - bool Run(void); + /** Runs the Ground Reactions model; called by the Executive + Can pass in a value indicating if the executive is directing the simulation to Hold. + @param Holding if true, the executive has been directed to hold the sim from + advancing time. Some models may ignore this flag, such as the Input + model, which may need to be active to listen on a socket for the + "Resume" command to be given. + @return false if no error */ + bool Run(bool Holding); bool Load(Element* el); const FGColumnVector3& GetForces(void) const {return vForces;} double GetForces(int idx) const {return vForces(idx);} diff --git a/src/FDM/JSBSim/models/FGInertial.cpp b/src/FDM/JSBSim/models/FGInertial.cpp index 94aa291c3..93874c120 100644 --- a/src/FDM/JSBSim/models/FGInertial.cpp +++ b/src/FDM/JSBSim/models/FGInertial.cpp @@ -45,7 +45,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGInertial.cpp,v 1.20 2010/11/18 12:38:06 jberndt Exp $"; +static const char *IdSrc = "$Id: FGInertial.cpp,v 1.21 2011/05/20 03:18:36 jberndt Exp $"; static const char *IdHdr = ID_INERTIAL; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -98,8 +98,6 @@ FGInertial::~FGInertial(void) bool FGInertial::InitModel(void) { - if (!FGModel::InitModel()) return false; - earthPosAngle = 0.0; return true; @@ -107,11 +105,11 @@ bool FGInertial::InitModel(void) //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -bool FGInertial::Run(void) +bool FGInertial::Run(bool Holding) { // Fast return if we have nothing to do ... - if (FGModel::Run()) return true; - if (FDMExec->Holding()) return false; + if (FGModel::Run(Holding)) return true; + if (Holding) return false; RunPreFunctions(); diff --git a/src/FDM/JSBSim/models/FGInertial.h b/src/FDM/JSBSim/models/FGInertial.h index f4db378a2..5394d81b8 100644 --- a/src/FDM/JSBSim/models/FGInertial.h +++ b/src/FDM/JSBSim/models/FGInertial.h @@ -47,7 +47,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_INERTIAL "$Id: FGInertial.h,v 1.15 2010/01/27 04:01:09 jberndt Exp $" +#define ID_INERTIAL "$Id: FGInertial.h,v 1.16 2011/05/20 03:18:36 jberndt Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -75,7 +75,14 @@ public: bool InitModel(void); - bool Run(void); + /** Runs the Inertial model; called by the Executive + Can pass in a value indicating if the executive is directing the simulation to Hold. + @param Holding if true, the executive has been directed to hold the sim from + advancing time. Some models may ignore this flag, such as the Input + model, which may need to be active to listen on a socket for the + "Resume" command to be given. + @return false if no error */ + bool Run(bool Holding); double SLgravity(void) const {return gAccelReference;} double gravity(void) const {return gAccel;} double omega(void) const {return RotationRate;} diff --git a/src/FDM/JSBSim/models/FGInput.cpp b/src/FDM/JSBSim/models/FGInput.cpp index 51b4a3984..c1ff0b8f2 100755 --- a/src/FDM/JSBSim/models/FGInput.cpp +++ b/src/FDM/JSBSim/models/FGInput.cpp @@ -53,7 +53,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGInput.cpp,v 1.20 2010/11/18 12:38:06 jberndt Exp $"; +static const char *IdSrc = "$Id: FGInput.cpp,v 1.21 2011/05/20 03:18:36 jberndt Exp $"; static const char *IdHdr = ID_INPUT; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -83,8 +83,6 @@ FGInput::~FGInput() bool FGInput::InitModel(void) { - if (!FGModel::InitModel()) return false; - return true; } @@ -93,14 +91,14 @@ bool FGInput::InitModel(void) // This function handles accepting input commands from the socket interface. // -bool FGInput::Run(void) +bool FGInput::Run(bool Holding) { string line, token; size_t start=0, string_start=0, string_end=0; double value=0; FGPropertyManager* node=0; - if (FGModel::Run()) return true; // fast exit if nothing to do + if (FGModel::Run(Holding)) return true; // fast exit if nothing to do if (port == 0) return false; // Do nothing here if port not defined // return false if no error // This model DOES execute if "Exec->Holding" @@ -157,7 +155,7 @@ bool FGInput::Run(void) break; } if (node == 0) { - if (FDMExec->Holding()) { // if holding can query property list + if (Holding) { // if holding can query property list string query = FDMExec->QueryPropertyCatalog(argument); socket->Reply(query); } else { diff --git a/src/FDM/JSBSim/models/FGInput.h b/src/FDM/JSBSim/models/FGInput.h old mode 100644 new mode 100755 index b86a428c6..68f0e0c4a --- a/src/FDM/JSBSim/models/FGInput.h +++ b/src/FDM/JSBSim/models/FGInput.h @@ -46,7 +46,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_INPUT "$Id: FGInput.h,v 1.8 2009/10/24 22:59:30 jberndt Exp $" +#define ID_INPUT "$Id: FGInput.h,v 1.9 2011/05/20 03:18:36 jberndt Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -76,7 +76,14 @@ public: ~FGInput(); bool InitModel(void); - bool Run(void); + /** Runs the Input model; called by the Executive + Can pass in a value indicating if the executive is directing the simulation to Hold. + @param Holding if true, the executive has been directed to hold the sim from + advancing time. Some models may ignore this flag, such as the Input + model, which may need to be active to listen on a socket for the + "Resume" command to be given. + @return false if no error */ + bool Run(bool Holding); inline void Enable(void) { enabled = true; } inline void Disable(void) { enabled = false; } diff --git a/src/FDM/JSBSim/models/FGMassBalance.cpp b/src/FDM/JSBSim/models/FGMassBalance.cpp index fd067ab51..aee3cc3bb 100644 --- a/src/FDM/JSBSim/models/FGMassBalance.cpp +++ b/src/FDM/JSBSim/models/FGMassBalance.cpp @@ -51,7 +51,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGMassBalance.cpp,v 1.34 2010/11/18 12:38:06 jberndt Exp $"; +static const char *IdSrc = "$Id: FGMassBalance.cpp,v 1.35 2011/05/20 03:18:36 jberndt Exp $"; static const char *IdHdr = ID_MASSBALANCE; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -92,8 +92,6 @@ FGMassBalance::~FGMassBalance() bool FGMassBalance::InitModel(void) { - if (!FGModel::InitModel()) return false; - vLastXYZcg.InitMatrix(0.0); vDeltaXYZcg.InitMatrix(0.0); @@ -164,13 +162,13 @@ bool FGMassBalance::Load(Element* el) //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -bool FGMassBalance::Run(void) +bool FGMassBalance::Run(bool Holding) { double denom, k1, k2, k3, k4, k5, k6; double Ixx, Iyy, Izz, Ixy, Ixz, Iyz; - if (FGModel::Run()) return true; - if (FDMExec->Holding()) return false; + if (FGModel::Run(Holding)) return true; + if (Holding) return false; RunPreFunctions(); diff --git a/src/FDM/JSBSim/models/FGMassBalance.h b/src/FDM/JSBSim/models/FGMassBalance.h index c7468c5db..53279d39c 100644 --- a/src/FDM/JSBSim/models/FGMassBalance.h +++ b/src/FDM/JSBSim/models/FGMassBalance.h @@ -49,7 +49,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_MASSBALANCE "$Id: FGMassBalance.h,v 1.22 2010/11/18 12:38:06 jberndt Exp $" +#define ID_MASSBALANCE "$Id: FGMassBalance.h,v 1.23 2011/05/20 03:18:36 jberndt Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONSS @@ -116,7 +116,14 @@ public: bool Load(Element* el); bool InitModel(void); - bool Run(void); + /** Runs the Mass Balance model; called by the Executive + Can pass in a value indicating if the executive is directing the simulation to Hold. + @param Holding if true, the executive has been directed to hold the sim from + advancing time. Some models may ignore this flag, such as the Input + model, which may need to be active to listen on a socket for the + "Resume" command to be given. + @return false if no error */ + bool Run(bool Holding); double GetMass(void) const {return Mass;} double GetWeight(void) const {return Weight;} diff --git a/src/FDM/JSBSim/models/FGModel.cpp b/src/FDM/JSBSim/models/FGModel.cpp index df7ffbdd0..81961eb30 100644 --- a/src/FDM/JSBSim/models/FGModel.cpp +++ b/src/FDM/JSBSim/models/FGModel.cpp @@ -38,26 +38,15 @@ HISTORY INCLUDES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ +#include <iostream> #include "FGModel.h" #include "FGFDMExec.h" -#include "FGAtmosphere.h" -#include "FGFCS.h" -#include "FGPropulsion.h" -#include "FGMassBalance.h" -#include "FGAerodynamics.h" -#include "FGInertial.h" -#include "FGGroundReactions.h" -#include "FGExternalReactions.h" -#include "FGAircraft.h" -#include "FGPropagate.h" -#include "FGAuxiliary.h" -#include <iostream> using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGModel.cpp,v 1.17 2011/02/16 12:30:53 jberndt Exp $"; +static const char *IdSrc = "$Id: FGModel.cpp,v 1.19 2011/05/22 12:44:30 jberndt Exp $"; static const char *IdHdr = ID_MODEL; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -99,7 +88,7 @@ bool FGModel::InitModel(void) //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -bool FGModel::Run() +bool FGModel::Run(bool Holding) { if (debug_lvl & 4) cout << "Entering Run() for model " << Name << endl; diff --git a/src/FDM/JSBSim/models/FGModel.h b/src/FDM/JSBSim/models/FGModel.h index 470dc731a..eae604668 100644 --- a/src/FDM/JSBSim/models/FGModel.h +++ b/src/FDM/JSBSim/models/FGModel.h @@ -48,7 +48,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_MODEL "$Id: FGModel.h,v 1.18 2010/11/18 12:38:06 jberndt Exp $" +#define ID_MODEL "$Id: FGModel.h,v 1.19 2011/05/20 03:18:36 jberndt Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -83,10 +83,17 @@ public: std::string Name; - /** Runs the model; called by the Executive + /** Runs the model; called by the Executive. + Can pass in a value indicating if the executive is directing the simulation to Hold. + @param Holding if true, the executive has been directed to hold the sim from + advancing time. Some models may ignore this flag, such as the Input + model, which may need to be active to listen on a socket for the + "Resume" command to be given. The Holding flag is not used in the base + FGModel class. @see JSBSim.cpp documentation @return false if no error */ - virtual bool Run(void); + virtual bool Run(bool Holding); + virtual bool InitModel(void); virtual void SetRate(int tt) {rate = tt;} virtual int GetRate(void) {return rate;} diff --git a/src/FDM/JSBSim/models/FGOutput.cpp b/src/FDM/JSBSim/models/FGOutput.cpp index ab70cb2d2..3131cd6c0 100644 --- a/src/FDM/JSBSim/models/FGOutput.cpp +++ b/src/FDM/JSBSim/models/FGOutput.cpp @@ -74,7 +74,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGOutput.cpp,v 1.54 2011/03/11 13:02:26 jberndt Exp $"; +static const char *IdSrc = "$Id: FGOutput.cpp,v 1.55 2011/05/20 03:18:36 jberndt Exp $"; static const char *IdHdr = ID_OUTPUT; // (stolen from FGFS native_fdm.cxx) @@ -157,8 +157,6 @@ FGOutput::~FGOutput() bool FGOutput::InitModel(void) { - if (!FGModel::InitModel()) return false; - if (Filename.size() > 0 && StartNewFile) { ostringstream buf; string::size_type dot = BaseFilename.find_last_of('.'); @@ -178,11 +176,11 @@ bool FGOutput::InitModel(void) //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -bool FGOutput::Run(void) +bool FGOutput::Run(bool Holding) { - if (FGModel::Run()) return true; + if (FGModel::Run(Holding)) return true; - if (enabled && !FDMExec->IntegrationSuspended() && !FDMExec->Holding()) { + if (enabled && !FDMExec->IntegrationSuspended() && !Holding) { RunPreFunctions(); Print(); RunPostFunctions(); diff --git a/src/FDM/JSBSim/models/FGOutput.h b/src/FDM/JSBSim/models/FGOutput.h index e22dc1319..2640bbdcb 100644 --- a/src/FDM/JSBSim/models/FGOutput.h +++ b/src/FDM/JSBSim/models/FGOutput.h @@ -51,7 +51,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_OUTPUT "$Id: FGOutput.h,v 1.22 2011/03/11 13:02:26 jberndt Exp $" +#define ID_OUTPUT "$Id: FGOutput.h,v 1.23 2011/05/20 03:18:36 jberndt Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -124,7 +124,7 @@ CLASS DOCUMENTATION propulsion ON|OFF </pre> NOTE that Time is always output with the data. - @version $Id: FGOutput.h,v 1.22 2011/03/11 13:02:26 jberndt Exp $ + @version $Id: FGOutput.h,v 1.23 2011/05/20 03:18:36 jberndt Exp $ */ /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -138,7 +138,14 @@ public: ~FGOutput(); bool InitModel(void); - bool Run(void); + /** Runs the Output model; called by the Executive + Can pass in a value indicating if the executive is directing the simulation to Hold. + @param Holding if true, the executive has been directed to hold the sim from + advancing time. Some models may ignore this flag, such as the Input + model, which may need to be active to listen on a socket for the + "Resume" command to be given. + @return false if no error */ + bool Run(bool Holding); void Print(void); void DelimitedOutput(const std::string&); diff --git a/src/FDM/JSBSim/models/FGPropagate.cpp b/src/FDM/JSBSim/models/FGPropagate.cpp index 6202ccc1c..51bc472d2 100644 --- a/src/FDM/JSBSim/models/FGPropagate.cpp +++ b/src/FDM/JSBSim/models/FGPropagate.cpp @@ -71,7 +71,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGPropagate.cpp,v 1.86 2011/04/17 11:27:14 bcoconni Exp $"; +static const char *IdSrc = "$Id: FGPropagate.cpp,v 1.88 2011/05/20 03:18:36 jberndt Exp $"; static const char *IdHdr = ID_PROPAGATE; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -121,8 +121,6 @@ FGPropagate::~FGPropagate(void) bool FGPropagate::InitModel(void) { - if (!FGModel::InitModel()) return false; - // For initialization ONLY: SeaLevelRadius = LocalTerrainRadius = FDMExec->GetInertial()->GetRefRadius(); @@ -140,10 +138,10 @@ bool FGPropagate::InitModel(void) VState.dqInertialVelocity.resize(4, FGColumnVector3(0.0,0.0,0.0)); VState.dqQtrndot.resize(4, FGColumnVector3(0.0,0.0,0.0)); - integrator_rotational_rate = eAdamsBashforth2; - integrator_translational_rate = eTrapezoidal; - integrator_rotational_position = eAdamsBashforth2; - integrator_translational_position = eTrapezoidal; + integrator_rotational_rate = eRectEuler; + integrator_translational_rate = eAdamsBashforth2; + integrator_rotational_position = eRectEuler; + integrator_translational_position = eAdamsBashforth3; return true; } @@ -226,10 +224,10 @@ Inertial. */ -bool FGPropagate::Run(void) +bool FGPropagate::Run(bool Holding) { - if (FGModel::Run()) return true; // Fast return if we have nothing to do ... - if (FDMExec->Holding()) return false; + if (FGModel::Run(Holding)) return true; // Fast return if we have nothing to do ... + if (Holding) return false; double dt = FDMExec->GetDeltaT()*rate; // The 'stepsize' diff --git a/src/FDM/JSBSim/models/FGPropagate.h b/src/FDM/JSBSim/models/FGPropagate.h index 26b2ad73e..1afe7f641 100644 --- a/src/FDM/JSBSim/models/FGPropagate.h +++ b/src/FDM/JSBSim/models/FGPropagate.h @@ -49,7 +49,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_PROPAGATE "$Id: FGPropagate.h,v 1.58 2011/04/03 19:24:58 jberndt Exp $" +#define ID_PROPAGATE "$Id: FGPropagate.h,v 1.59 2011/05/20 03:18:36 jberndt Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -102,7 +102,7 @@ CLASS DOCUMENTATION @endcode @author Jon S. Berndt, Mathias Froehlich - @version $Id: FGPropagate.h,v 1.58 2011/04/03 19:24:58 jberndt Exp $ + @version $Id: FGPropagate.h,v 1.59 2011/05/20 03:18:36 jberndt Exp $ */ /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -177,9 +177,14 @@ public: other FGModel objects (and others). */ bool InitModel(void); - /** Runs the Propagate model; called by the Executive. + /** Runs the state propagation model; called by the Executive + Can pass in a value indicating if the executive is directing the simulation to Hold. + @param Holding if true, the executive has been directed to hold the sim from + advancing time. Some models may ignore this flag, such as the Input + model, which may need to be active to listen on a socket for the + "Resume" command to be given. @return false if no error */ - bool Run(void); + bool Run(bool Holding); const FGQuaternion& GetQuaterniondot(void) const {return vQtrndot;} diff --git a/src/FDM/JSBSim/models/FGPropulsion.cpp b/src/FDM/JSBSim/models/FGPropulsion.cpp index da82acf51..bb260f09b 100644 --- a/src/FDM/JSBSim/models/FGPropulsion.cpp +++ b/src/FDM/JSBSim/models/FGPropulsion.cpp @@ -65,7 +65,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGPropulsion.cpp,v 1.45 2011/02/13 00:42:45 jberndt Exp $"; +static const char *IdSrc = "$Id: FGPropulsion.cpp,v 1.46 2011/05/20 03:18:36 jberndt Exp $"; static const char *IdHdr = ID_PROPULSION; extern short debug_lvl; @@ -117,8 +117,6 @@ bool FGPropulsion::InitModel(void) { bool result = true; - if (!FGModel::InitModel()) return false; - for (unsigned int i=0; i<numTanks; i++) Tanks[i]->ResetToIC(); for (unsigned int i=0; i<numEngines; i++) { @@ -151,12 +149,12 @@ bool FGPropulsion::InitModel(void) //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -bool FGPropulsion::Run(void) +bool FGPropulsion::Run(bool Holding) { unsigned int i; - if (FGModel::Run()) return true; - if (FDMExec->Holding()) return false; + if (FGModel::Run(Holding)) return true; + if (Holding) return false; RunPreFunctions(); @@ -199,7 +197,7 @@ bool FGPropulsion::GetSteadyState(void) vForces.InitMatrix(); vMoments.InitMatrix(); - if (!FGModel::Run()) { + if (!FGModel::Run(false)) { FDMExec->SetTrimStatus(true); for (unsigned int i=0; i<numEngines; i++) { diff --git a/src/FDM/JSBSim/models/FGPropulsion.h b/src/FDM/JSBSim/models/FGPropulsion.h index 50dd860cd..3dacfc4fd 100644 --- a/src/FDM/JSBSim/models/FGPropulsion.h +++ b/src/FDM/JSBSim/models/FGPropulsion.h @@ -49,7 +49,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_PROPULSION "$Id: FGPropulsion.h,v 1.26 2010/11/18 12:38:06 jberndt Exp $" +#define ID_PROPULSION "$Id: FGPropulsion.h,v 1.27 2011/05/20 03:18:36 jberndt Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -91,7 +91,7 @@ CLASS DOCUMENTATION @endcode @author Jon S. Berndt - @version $Id: FGPropulsion.h,v 1.26 2010/11/18 12:38:06 jberndt Exp $ + @version $Id: FGPropulsion.h,v 1.27 2011/05/20 03:18:36 jberndt Exp $ @see FGEngine FGTank @@ -112,9 +112,13 @@ public: /** Executes the propulsion model. The initial plan for the FGPropulsion class calls for Run() to be executed, calculating the power available from the engine. - - [Note: Should we be checking the Starved flag here?] */ - bool Run(void); + Can pass in a value indicating if the executive is directing the simulation to Hold. + @param Holding if true, the executive has been directed to hold the sim from + advancing time. Some models may ignore this flag, such as the Input + model, which may need to be active to listen on a socket for the + "Resume" command to be given. + @return false if no error */ + bool Run(bool Holding); bool InitModel(void); diff --git a/src/FDM/JSBSim/models/atmosphere/FGMSIS.cpp b/src/FDM/JSBSim/models/atmosphere/FGMSIS.cpp old mode 100644 new mode 100755 index 0afaa831a..23f185f12 --- a/src/FDM/JSBSim/models/atmosphere/FGMSIS.cpp +++ b/src/FDM/JSBSim/models/atmosphere/FGMSIS.cpp @@ -66,7 +66,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGMSIS.cpp,v 1.14 2010/11/18 12:38:06 jberndt Exp $"; +static const char *IdSrc = "$Id: FGMSIS.cpp,v 1.17 2011/05/20 03:18:36 jberndt Exp $"; static const char *IdHdr = ID_MSIS; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -95,7 +95,19 @@ CLASS IMPLEMENTATION MSIS::MSIS(FGFDMExec* fdmex) : FGAtmosphere(fdmex) { Name = "MSIS"; - bind(); + + for (int i=0; i<9; i++) output.d[i] = 0.0; + for (int i=0; i<2; i++) output.t[i] = 0.0; + + dm04 = dm16 = dm28 = dm32 = dm40 = dm01 = dm14 = dfa = 0.0; + + for (int i=0; i<5; i++) meso_tn1[i] = 0.0; + for (int i=0; i<4; i++) meso_tn2[i] = 0.0; + for (int i=0; i<5; i++) meso_tn3[i] = 0.0; + for (int i=0; i<2; i++) meso_tgn1[i] = 0.0; + for (int i=0; i<2; i++) meso_tgn2[i] = 0.0; + for (int i=0; i<2; i++) meso_tgn3[i] = 0.0; + Debug(0); } @@ -110,12 +122,16 @@ MSIS::~MSIS() bool MSIS::InitModel(void) { - FGModel::InitModel(); - unsigned int i; flags.switches[0] = 0; - for (i=1;i<24;i++) flags.switches[i] = 1; + flags.sw[0] = 0; + flags.swc[0] = 0; + for (i=1;i<24;i++) { + flags.switches[i] = 1; + flags.sw[i] = 1; + flags.swc[i] = 1; + } for (i=0;i<7;i++) aph.a[i] = 100.0; @@ -124,6 +140,8 @@ bool MSIS::InitModel(void) input.f107 = 150.0; input.ap = 4.0; + UseInternal(); + SLtemperature = intTemperature = 518.0; SLpressure = intPressure = 2116.7; SLdensity = intDensity = 0.002378; @@ -132,24 +150,21 @@ bool MSIS::InitModel(void) rSLpressure = 1.0/intPressure; rSLdensity = 1.0/intDensity; rSLsoundspeed = 1.0/SLsoundspeed; - temperature = &intTemperature; - pressure = &intPressure; - density = &intDensity; - - UseInternal(); return true; } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -bool MSIS::Run(void) +bool MSIS::Run(bool Holding) { - if (FGModel::Run()) return true; - if (FDMExec->Holding()) return false; + if (FGModel::Run(Holding)) return true; + if (Holding) return false; RunPreFunctions(); + h = FDMExec->GetPropagate()->GetAltitudeASL(); + //do temp, pressure, and density first if (!useExternal) { // get sea-level values @@ -170,7 +185,7 @@ bool MSIS::Run(void) // get at-altitude values Calculate(FDMExec->GetAuxiliary()->GetDayOfYear(), FDMExec->GetAuxiliary()->GetSecondsInDay(), - FDMExec->GetPropagate()->GetAltitudeASL(), + h, FDMExec->GetPropagate()->GetLocation().GetLatitudeDeg(), FDMExec->GetPropagate()->GetLocation().GetLongitudeDeg()); intTemperature = output.t[1] * 1.8; @@ -357,7 +372,7 @@ void MSIS::splini (double *xa, double *ya, double *y2a, int n, double x, double double yi=0; int klo=0; int khi=1; - double xx, h, a, b, a2, b2; + double xx=0.0, h=0.0, a=0.0, b=0.0, a2=0.0, b2=0.0; while ((x>xa[klo]) && (khi<n)) { xx=x; if (khi<(n-1)) { @@ -472,15 +487,17 @@ double MSIS::densm(double alt, double d0, double xm, double *tz, int mn3, double *tn2, double *tgn2) { /* Calculate Temperature and Density Profiles for lower atmos. */ - double xs[10], ys[10], y2out[10]; + double xs[10] = {0,0,0,0,0,0,0,0,0,0}; + double ys[10] = {0,0,0,0,0,0,0,0,0,0}; + double y2out[10] = {0,0,0,0,0,0,0,0,0,0}; double rgas = 831.4; - double z, z1, z2, t1, t2, zg, zgdif; - double yd1, yd2; - double x, y, yi; - double expl, gamm, glb; - double densm_tmp; - int mn; - int k; + double z=0, z1=0, z2=0, t1=0, t2=0, zg=0, zgdif=0; + double yd1=0, yd2=0; + double x=0, y=0, yi=0; + double expl=0, gamm=0, glb=0; + double densm_tmp=0; + int mn=0; + int k=0; densm_tmp=d0; if (alt>zn2[0]) { if (xm==0.0) @@ -593,19 +610,19 @@ double MSIS::densu(double alt, double dlb, double tinf, double tlb, double xm, /* Calculate Temperature and Density Profiles for MSIS models * New lower thermo polynomial */ - double yd2, yd1, x=0.0, y=0.0; + double yd2=0.0, yd1=0.0, x=0.0, y=0.0; double rgas=831.4; double densu_temp=1.0; - double za, z, zg2, tt, ta=0.0; - double dta, z1=0.0, z2, t1=0.0, t2, zg, zgdif=0.0; + double za=0.0, z=0.0, zg2=0.0, tt=0.0, ta=0.0; + double dta=0.0, z1=0.0, z2=0.0, t1=0.0, t2=0.0, zg=0.0, zgdif=0.0; int mn=0; - int k; - double glb; - double expl; - double yi; - double densa; - double gamma, gamm; - double xs[5], ys[5], y2out[5]; + int k=0; + double glb=0.0; + double expl=0.0; + double yi=0.0; + double densa=0.0; + double gamma=0.0, gamm=0.0; + double xs[5]={0.0,0.0,0.0,0.0,0.0}, ys[5]={0.0,0.0,0.0,0.0,0.0}, y2out[5]={0.0,0.0,0.0,0.0,0.0}; /* joining altitudes of Bates and spline */ za=zn1[0]; if (alt>za) @@ -739,7 +756,7 @@ double MSIS::globe7(double *p, struct nrlmsise_input *input, double hr = 0.2618; double cd32, cd18, cd14, cd39; double p32, p18, p14, p39; - double df, dfa; + double df; double f1, f2; double tinf; struct ap_array *ap; @@ -957,11 +974,11 @@ double MSIS::glob7s(double *p, struct nrlmsise_input *input, /* VERSION OF GLOBE FOR LOWER ATMOSPHERE 10/26/99 */ double pset=2.0; - double t[14]; - double tt; - double cd32, cd18, cd14, cd39; - double p32, p18, p14, p39; - int i,j; + double t[14] = {0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,}; + double tt=0.0; + double cd32=0.0, cd18=0.0, cd14=0.0, cd39=0.0; + double p32=0.0, p18=0.0, p14=0.0, p39=0.0; + int i=0,j=0; double dr=1.72142E-2; double dgtr=1.74533E-2; /* confirm parameter set */ @@ -1053,23 +1070,26 @@ double MSIS::glob7s(double *p, struct nrlmsise_input *input, void MSIS::gtd7(struct nrlmsise_input *input, struct nrlmsise_flags *flags, struct nrlmsise_output *output) { - double xlat; - double xmm; + double xlat=0.0; + double xmm=0.0; int mn3 = 5; double zn3[5]={32.5,20.0,15.0,10.0,0.0}; int mn2 = 4; double zn2[4]={72.5,55.0,45.0,32.5}; - double altt; + double altt=0.0; double zmix=62.5; - double tmp; - double dm28m; - double tz; - double dmc; - double dmr; - double dz28; + double tmp=0.0; + double dm28m=0.0; + double tz=0.0; + double dmc=0.0; + double dmr=0.0; + double dz28=0.0; struct nrlmsise_output soutput; int i; + for (int i=0; i<9; i++) soutput.d[i] = 0.0; + for (int i=0; i<2; i++) soutput.t[i] = 0.0; + tselec(flags); /* Latitude variation of gravity (none for sw[2]=0) */ @@ -1186,6 +1206,8 @@ void MSIS::gtd7d(struct nrlmsise_input *input, struct nrlmsise_flags *flags, output->d[5] = 1.66E-24 * (4.0 * output->d[0] + 16.0 * output->d[1] + 28.0 * output->d[2] + 32.0 * output->d[3] + 40.0 * output->d[4] + output->d[6] + 14.0 * output->d[7] + 16.0 * output->d[8]); + if (flags->sw[0]) + output->d[5]=output->d[5]/1000; } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -1277,36 +1299,36 @@ void MSIS::gts7(struct nrlmsise_input *input, struct nrlmsise_flags *flags, * See GTD7 for more extensive comments * alt > 72.5 km! */ - double za; + double za=0.0; int i, j; - double ddum, z; + double ddum=0.0, z=0.0; double zn1[5] = {120.0, 110.0, 100.0, 90.0, 72.5}; - double tinf; + double tinf=0.0; int mn1 = 5; - double g0; - double tlb; - double s, z0, t0, tr12; - double db01, db04, db14, db16, db28, db32, db40, db48; - double zh28, zh04, zh16, zh32, zh40, zh01, zh14; - double zhm28, zhm04, zhm16, zhm32, zhm40, zhm01, zhm14; - double xmd; - double b28, b04, b16, b32, b40, b01, b14; - double tz; - double g28, g4, g16, g32, g40, g1, g14; - double zhf, xmm; - double zc04, zc16, zc32, zc40, zc01, zc14; - double hc04, hc16, hc32, hc40, hc01, hc14; - double hcc16, hcc32, hcc01, hcc14; - double zcc16, zcc32, zcc01, zcc14; - double rc16, rc32, rc01, rc14; - double rl; - double g16h, db16h, tho, zsht, zmho, zsho; + double g0=0.0; + double tlb=0.0; + double s=0.0, z0=0.0, t0=0.0, tr12=0.0; + double db01=0.0, db04=0.0, db14=0.0, db16=0.0, db28=0.0, db32=0.0, db40=0.0, db48=0.0; + double zh28=0.0, zh04=0.0, zh16=0.0, zh32=0.0, zh40=0.0, zh01=0.0, zh14=0.0; + double zhm28=0.0, zhm04=0.0, zhm16=0.0, zhm32=0.0, zhm40=0.0, zhm01=0.0, zhm14=0.0; + double xmd=0.0; + double b28=0.0, b04=0.0, b16=0.0, b32=0.0, b40=0.0, b01=0.0, b14=0.0; + double tz=0.0; + double g28=0.0, g4=0.0, g16=0.0, g32=0.0, g40=0.0, g1=0.0, g14=0.0; + double zhf=0.0, xmm=0.0; + double zc04=0.0, zc16=0.0, zc32=0.0, zc40=0.0, zc01=0.0, zc14=0.0; + double hc04=0.0, hc16=0.0, hc32=0.0, hc40=0.0, hc01=0.0, hc14=0.0; + double hcc16=0.0, hcc32=0.0, hcc01=0.0, hcc14=0.0; + double zcc16=0.0, zcc32=0.0, zcc01=0.0, zcc14=0.0; + double rc16=0.0, rc32=0.0, rc01=0.0, rc14=0.0; + double rl=0.0; + double g16h=0.0, db16h=0.0, tho=0.0, zsht=0.0, zmho=0.0, zsho=0.0; double dgtr=1.74533E-2; double dr=1.72142E-2; double alpha[9]={-0.38, 0.0, 0.0, 0.0, 0.17, 0.0, -0.38, 0.0, 0.0}; double altl[8]={200.0, 300.0, 160.0, 250.0, 240.0, 450.0, 320.0, 450.0}; - double dd; - double hc216, hcc232; + double dd=0.0; + double hc216=0.0, hcc232=0.0; za = pdl[1][15]; zn1[0] = za; for (j=0;j<9;j++) @@ -1480,7 +1502,7 @@ void MSIS::gts7(struct nrlmsise_input *input, struct nrlmsise_flags *flags, /**** AR DENSITY ****/ /* Density variation factor at Zlb */ - g40= flags->sw[20]*globe7(pd[5],input,flags); + g40= flags->sw[21]*globe7(pd[5],input,flags); /* Diffusive density at Zlb */ db40 = pdm[4][0]*exp(g40)*pd[5][0]; /* Diffusive density at Alt */ diff --git a/src/FDM/JSBSim/models/atmosphere/FGMSIS.h b/src/FDM/JSBSim/models/atmosphere/FGMSIS.h old mode 100644 new mode 100755 index 5761b1921..345a65ad5 --- a/src/FDM/JSBSim/models/atmosphere/FGMSIS.h +++ b/src/FDM/JSBSim/models/atmosphere/FGMSIS.h @@ -47,7 +47,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_MSIS "$Id: FGMSIS.h,v 1.7 2010/02/25 05:21:36 jberndt Exp $" +#define ID_MSIS "$Id: FGMSIS.h,v 1.9 2011/05/20 03:18:36 jberndt Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -75,7 +75,7 @@ CLASS DOCUMENTATION and check http://www.brodo.de/english/pub/nrlmsise/index.html for updated releases of this package. @author David Culp - @version $Id: FGMSIS.h,v 1.7 2010/02/25 05:21:36 jberndt Exp $ + @version $Id: FGMSIS.h,v 1.9 2011/05/20 03:18:36 jberndt Exp $ */ /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -87,10 +87,60 @@ struct nrlmsise_flags { double sw[24]; double swc[24]; }; +/* + * Switches: to turn on and off particular variations use these switches. + * 0 is off, 1 is on, and 2 is main effects off but cross terms on. + * + * Standard values are 0 for switch 0 and 1 for switches 1 to 23. The + * array "switches" needs to be set accordingly by the calling program. + * The arrays sw and swc are set internally. + * + * switches[i]: + * i - explanation + * ----------------- + * 0 - output in centimeters instead of meters + * 1 - F10.7 effect on mean + * 2 - time independent + * 3 - symmetrical annual + * 4 - symmetrical semiannual + * 5 - asymmetrical annual + * 6 - asymmetrical semiannual + * 7 - diurnal + * 8 - semidiurnal + * 9 - daily ap [when this is set to -1 (!) the pointer + * ap_a in struct nrlmsise_input must + * point to a struct ap_array] + * 10 - all UT/long effects + * 11 - longitudinal + * 12 - UT and mixed UT/long + * 13 - mixed AP/UT/LONG + * 14 - terdiurnal + * 15 - departures from diffusive equilibrium + * 16 - all TINF var + * 17 - all TLB var + * 18 - all TN1 var + * 19 - all S var + * 20 - all TN2 var + * 21 - all NLB var + * 22 - all TN3 var + * 23 - turbo scale height var + */ struct ap_array { double a[7]; }; +/* Array containing the following magnetic values: + * 0 : daily AP + * 1 : 3 hr AP index for current time + * 2 : 3 hr AP index for 3 hrs before current time + * 3 : 3 hr AP index for 6 hrs before current time + * 4 : 3 hr AP index for 9 hrs before current time + * 5 : Average of eight 3 hr AP indicies from 12 to 33 hrs + * prior to current time + * 6 : Average of eight 3 hr AP indicies from 36 to 57 hrs + * prior to current time + */ + struct nrlmsise_input { int year; /* year, currently ignored */ @@ -105,11 +155,71 @@ struct nrlmsise_input { double ap; /* magnetic index(daily) */ struct ap_array *ap_a; /* see above */ }; +/* + * NOTES ON INPUT VARIABLES: + * UT, Local Time, and Longitude are used independently in the + * model and are not of equal importance for every situation. + * For the most physically realistic calculation these three + * variables should be consistent (lst=sec/3600 + g_long/15). + * The Equation of Time departures from the above formula + * for apparent local time can be included if available but + * are of minor importance. + * + * f107 and f107A values used to generate the model correspond + * to the 10.7 cm radio flux at the actual distance of the Earth + * from the Sun rather than the radio flux at 1 AU. The following + * site provides both classes of values: + * ftp://ftp.ngdc.noaa.gov/STP/SOLAR_DATA/SOLAR_RADIO/FLUX/ + * + * f107, f107A, and ap effects are neither large nor well + * established below 80 km and these parameters should be set to + * 150., 150., and 4. respectively. + */ + + + +/* ------------------------------------------------------------------- */ +/* ------------------------------ OUTPUT ----------------------------- */ +/* ------------------------------------------------------------------- */ struct nrlmsise_output { double d[9]; /* densities */ double t[2]; /* temperatures */ }; +/* + * OUTPUT VARIABLES: + * d[0] - HE NUMBER DENSITY(CM-3) + * d[1] - O NUMBER DENSITY(CM-3) + * d[2] - N2 NUMBER DENSITY(CM-3) + * d[3] - O2 NUMBER DENSITY(CM-3) + * d[4] - AR NUMBER DENSITY(CM-3) + * d[5] - TOTAL MASS DENSITY(GM/CM3) [includes d[8] in td7d] + * d[6] - H NUMBER DENSITY(CM-3) + * d[7] - N NUMBER DENSITY(CM-3) + * d[8] - Anomalous oxygen NUMBER DENSITY(CM-3) + * t[0] - EXOSPHERIC TEMPERATURE + * t[1] - TEMPERATURE AT ALT + * + * + * O, H, and N are set to zero below 72.5 km + * + * t[0], Exospheric temperature, is set to global average for + * altitudes below 120 km. The 120 km gradient is left at global + * average value for altitudes below 72 km. + * + * d[5], TOTAL MASS DENSITY, is NOT the same for subroutines GTD7 + * and GTD7D + * + * SUBROUTINE GTD7 -- d[5] is the sum of the mass densities of the + * species labeled by indices 0-4 and 6-7 in output variable d. + * This includes He, O, N2, O2, Ar, H, and N but does NOT include + * anomalous oxygen (species index 8). + * + * SUBROUTINE GTD7D -- d[5] is the "effective total mass density + * for drag" and is the sum of the mass densities of all species + * in this model, INCLUDING anomalous oxygen. + */ + /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -125,8 +235,13 @@ public: /// Destructor ~MSIS(); /** Runs the MSIS-00 atmosphere model; called by the Executive + Can pass in a value indicating if the executive is directing the simulation to Hold. + @param Holding if true, the executive has been directed to hold the sim from + advancing time. Some models may ignore this flag, such as the Input + model, which may need to be active to listen on a socket for the + "Resume" command to be given. @return false if no error */ - bool Run(void); + bool Run(bool Holding); bool InitModel(void); @@ -196,9 +311,25 @@ private: double sg0(double ex, double *p, double *ap); double globe7(double *p, nrlmsise_input *input, nrlmsise_flags *flags); double glob7s(double *p, nrlmsise_input *input, nrlmsise_flags *flags); + +// GTD7 +// Neutral Atmosphere Empirical Model from the surface to lower exosphere. void gtd7(nrlmsise_input *input, nrlmsise_flags *flags, nrlmsise_output *output); + +// GTD7D +// This subroutine provides Effective Total Mass Density for output +// d[5] which includes contributions from "anomalous oxygen" which can +// affect satellite drag above 500 km. See the section "output" for +// additional details. void gtd7d(nrlmsise_input *input, nrlmsise_flags *flags, nrlmsise_output *output); + +// GHP7 +// To specify outputs at a pressure level (press) rather than at +// an altitude. void ghp7(nrlmsise_input *input, nrlmsise_flags *flags, nrlmsise_output *output, double press); + +// GTS7 +// Thermospheric portion of NRLMSISE-00 void gts7(nrlmsise_input *input, nrlmsise_flags *flags, nrlmsise_output *output); }; diff --git a/src/FDM/JSBSim/models/atmosphere/FGStandardAtmosphere.cpp b/src/FDM/JSBSim/models/atmosphere/FGStandardAtmosphere.cpp new file mode 100644 index 000000000..ab0011c7f --- /dev/null +++ b/src/FDM/JSBSim/models/atmosphere/FGStandardAtmosphere.cpp @@ -0,0 +1,568 @@ +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + Module: FGStandardAtmosphere.cpp + Author: Jon Berndt, Tony Peden + Date started: 5/2011 + Purpose: Models the 1976 U.S. Standard Atmosphere + Called by: FGFDMExec + + ------------- Copyright (C) 2011 Jon S. Berndt (jon@jsbsim.org) ------------- + + This program is free software; you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any later + version. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + details. + + You should have received a copy of the GNU Lesser General Public License along with + this program; if not, write to the Free Software Foundation, Inc., 59 Temple + Place - Suite 330, Boston, MA 02111-1307, USA. + + Further information about the GNU Lesser General Public License can also be found on + the world wide web at http://www.gnu.org. + +FUNCTIONAL DESCRIPTION +-------------------------------------------------------------------------------- + + +HISTORY +-------------------------------------------------------------------------------- + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +COMMENTS, REFERENCES, and NOTES +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +[1] Anderson, John D. "Introduction to Flight, Third Edition", McGraw-Hill, + 1989, ISBN 0-07-001641-0 + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +INCLUDES +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ + +#include <iostream> +#include <iomanip> +#include <cstdlib> +#include "FGFDMExec.h" +#include "FGStandardAtmosphere.h" + +namespace JSBSim { + +static const char *IdSrc = "$Id: FGStandardAtmosphere.cpp,v 1.9 2011/06/13 12:06:29 jberndt Exp $"; +static const char *IdHdr = ID_STANDARDATMOSPHERE; + +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +CLASS IMPLEMENTATION +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ + +FGStandardAtmosphere::FGStandardAtmosphere(FGFDMExec* fdmex) : FGModel(fdmex), + TemperatureDeltaGradient(0.0), + TemperatureBias(0.0), + PressureAltitude(0.0), // ft + DensityAltitude(0.0), // ft + SutherlandConstant(198.72), // deg Rankine + Beta(2.269690E-08) // slug/(sec ft R^0.5) +{ + Name = "FGStandardAtmosphere"; + + StdAtmosTemperatureTable = new FGTable(9); + + // This is the U.S. Standard Atmosphere table for temperature in degrees + // Rankine, based on geometric altitude. The table values are often given + // in literature relative to geopotential altitude. + // + // GeoMet Alt Temp GeoPot Alt GeoMet Alt + // (ft) (deg R) (km) (km) + // -------- -------- ---------- ---------- + *StdAtmosTemperatureTable << 0.0 << 518.67 // 0.000 0.000 + << 36151.6 << 390.0 // 11.000 11.019 + << 65823.5 << 390.0 // 20.000 20.063 + << 105518.4 << 411.6 // 32.000 32.162 + << 155347.8 << 487.2 // 47.000 47.350 + << 168677.8 << 487.2 // 51.000 51.413 + << 235570.9 << 386.4 // 71.000 71.802 + << 282152.2 << 336.5 // 84.852 86.000 + << 298556.4 << 336.5; // 91.000 - First layer in high altitude regime + + LapseRateVector.resize(StdAtmosTemperatureTable->GetNumRows()-1); + PressureBreakpointVector.resize(StdAtmosTemperatureTable->GetNumRows()); + + // Assume the altitude to fade out the gradient at is at the highest + // altitude in the table. Above that, other functions are used to + // calculate temperature. + GradientFadeoutAltitude = (*StdAtmosTemperatureTable)(StdAtmosTemperatureTable->GetNumRows(),0); + + bind(); + Debug(0); +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +FGStandardAtmosphere::~FGStandardAtmosphere() +{ + LapseRateVector.clear(); + Debug(1); +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +bool FGStandardAtmosphere::InitModel(void) +{ + PressureBreakpointVector[0] = StdSLpressure = 2116.22; // psf + TemperatureDeltaGradient = 0.0; + TemperatureBias = 0.0; + CalculateLapseRates(); + CalculatePressureBreakpoints(); + Calculate(0.0); + StdSLtemperature = SLtemperature = Temperature; + SLpressure = Pressure; + StdSLdensity = SLdensity = Density; + StdSLsoundspeed = SLsoundspeed = Soundspeed; + + rSLtemperature = 1/SLtemperature ; + rSLpressure = 1/SLpressure ; + rSLdensity = 1/SLdensity ; + rSLsoundspeed = 1/SLsoundspeed ; + +// PrintStandardAtmosphereTable(); + + return true; +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +bool FGStandardAtmosphere::Run(bool Holding) +{ + if (FGModel::Run(Holding)) return true; + if (Holding) return false; + + RunPreFunctions(); + + double altitude = FDMExec->GetPropagate()->GetAltitudeASL(); + + Calculate(altitude); + + RunPostFunctions(); + + Debug(2); + return false; +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +void FGStandardAtmosphere::Calculate(double altitude) +{ + Temperature = GetTemperature(altitude); + Pressure = GetPressure(altitude); + Density = Pressure/(Reng*Temperature); + Soundspeed = sqrt(SHRatio*Reng*(Temperature)); + + Viscosity = Beta * pow(Temperature, 1.5) / (SutherlandConstant + Temperature); + KinematicViscosity = Viscosity / Density; +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +// Get the actual pressure as modeled at a specified altitude +// These calculations are from equations 33a and 33b in the U.S. Standard Atmosphere +// document referenced in the documentation for this code. + +double FGStandardAtmosphere::GetPressure(double altitude) const +{ + unsigned int b=0; + double pressure = 0.0; + double Lmb, Exp, Tmb, deltaH, factor; + + // Iterate through the altitudes to find the current Base Altitude + // in the table. That is, if the current altitude (the argument passed in) + // is 20000 ft, then the base altitude from the table is 0.0. If the + // passed-in altitude is 40000 ft, the base altitude is 36151.6 ft (and + // the index "b" is 2 - the second entry in the table). + double testAlt = (*StdAtmosTemperatureTable)(b+1,0); + while (altitude >= testAlt) { + b++; + if (b+1 > StdAtmosTemperatureTable->GetNumRows()) break; + testAlt = (*StdAtmosTemperatureTable)(b+1,0); + } + if (b>0) b--; + + double BaseAlt = (*StdAtmosTemperatureTable)(b+1,0); + Tmb = GetTemperature(BaseAlt); + deltaH = altitude - BaseAlt; + + if (LapseRateVector[b] != 0.00) { + Lmb = LapseRateVector[b]; + Exp = Mair/(Rstar*Lmb); + factor = Tmb/(Tmb + Lmb*deltaH); + pressure = PressureBreakpointVector[b]*pow(factor, Exp); + } else { + pressure = PressureBreakpointVector[b]*exp(-Mair*deltaH/(Rstar*Tmb)); + } + + return pressure; +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +void FGStandardAtmosphere::SetSeaLevelPressure(double pressure, ePressure unit) +{ + double press = ConvertToPSF(pressure, unit); + + PressureBreakpointVector[0] = press; + CalculatePressureBreakpoints(); +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +// Get the modeled temperature at a specified altitude, including any bias or gradient +// effects. + +double FGStandardAtmosphere::GetTemperature(double altitude) const +{ + double T = StdAtmosTemperatureTable->GetValue(altitude) + TemperatureBias; + if (altitude <= GradientFadeoutAltitude) + T += TemperatureDeltaGradient * (GradientFadeoutAltitude - altitude); + + return T; +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +// Retrieves the standard temperature at a particular altitude. + +double FGStandardAtmosphere::GetStdTemperature(double altitude) const +{ + double Lk9 = 0.00658368; // deg R per foot + double Tinf = 1800.0; // Same as 1000 Kelvin + double temp = Tinf; + + if (altitude < 298556.4) { // 91 km - station 8 + + temp = StdAtmosTemperatureTable->GetValue(altitude); + + } else if (altitude < 360892.4) { // 110 km - station 9 + + temp = 473.7429 - 137.38176 * sqrt(1.0 - pow((altitude - 298556.4)/65429.462, 2.0)); + + } else if (altitude < 393700.8) { // 120 km - station 10 + + temp = 432 + Lk9 * (altitude - 360892.4); + + } else if (altitude < 3280839.9) { // 1000 km station 12 + + double lambda = 0.00001870364; + double eps = (altitude - 393700.8) * (20855531.5 + 393700.8) / (20855531.5 + altitude); + temp = Tinf - (Tinf - 648.0) * exp(-lambda*eps); + + } + + return temp; +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +double FGStandardAtmosphere::GetStdPressure(double altitude) const +{ + double press=0; + if (TemperatureBias == 0.0 && TemperatureDeltaGradient == 0.0 && PressureBreakpointVector[0] == StdSLpressure) { + press = GetPressure(altitude); + } else if (altitude <= 100000.0) { + GetStdPressure100K(altitude); + } else { + // Cannot currently retrieve the standard pressure + } + return press; +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +// This function calculates an approximation of the standard atmospheric pressure +// up to an altitude of about 100,000 ft. If the temperature and pressure are not +// altered for local conditions, the GetPressure(h) function should be used, +// as that is valid to a much higher altitude. This function is accurate to within +// a couple of psf up to 100K ft. This polynomial fit was determined using Excel. + +double FGStandardAtmosphere::GetStdPressure100K(double altitude) const +{ + // Limit this equation to input altitudes of 100000 ft. + if (altitude > 100000.0) altitude = 100000.0; + + double alt[6]; + double coef[6] = { 2116.22, + -7.583514352598E-02, + 1.045494405501E-06, + -5.881341527124E-12, + 3.482031690718E-18, + 5.683922549284E-23 }; + + alt[0] = 1; + for (int pwr=1; pwr<=5; pwr++) alt[pwr] = alt[pwr-1]*altitude; + + double press = 0.0; + for (int ctr=0; ctr<=5; ctr++) press += coef[ctr]*alt[ctr]; + return press; +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +// Get the modeled density at a specified altitude + +double FGStandardAtmosphere::GetDensity(double altitude) const +{ + return GetPressure(altitude)/(Reng * GetTemperature(altitude)); +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +// Get the standard density at a specified altitude + +double FGStandardAtmosphere::GetStdDensity(double altitude) const +{ + return GetStdPressure(altitude)/(Reng * GetStdTemperature(altitude)); +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +void FGStandardAtmosphere::SetTemperatureBias(double t, eTemperature unit) +{ + TemperatureBias = ConvertToRankine(t, unit); + CalculatePressureBreakpoints(); +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +// This function calculates a bias based on the supplied temperature for sea +// level. The bias is applied to the entire temperature profile at all altitudes. +// Internally, the Rankine scale is used for calculations, so any temperature +// supplied must be converted to that unit. + +void FGStandardAtmosphere::SetSLTemperature(double t, eTemperature unit) +{ + double targetSLtemp = ConvertToRankine(t, unit); + + TemperatureBias = targetSLtemp - GetStdTemperatureSL(); + CalculatePressureBreakpoints(); +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +// Sets a Sea Level temperature delta that is ramped out by 86 km (282,152 ft). + +void FGStandardAtmosphere::SetSLTemperatureGradedDelta(double deltemp, eTemperature unit) +{ + SetTemperatureGradedDelta(deltemp, 0.0, unit); +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +// Sets a temperature delta at the supplied altitude that is ramped out by 86 km. +// After this calculation is performed, the lapse rates and pressure breakpoints +// must be recalculated. Since we are calculating a delta here and not an actual +// temperature, we only need to be concerned about a scale factor and not +// the actual temperature itself. + +void FGStandardAtmosphere::SetTemperatureGradedDelta(double deltemp, double h, eTemperature unit) +{ + switch(unit) { + case eCelsius: + case eKelvin: + deltemp *= 9.0/5.0; // If temp delta is given in metric, scale up to English + break; + } + TemperatureDeltaGradient = deltemp/(GradientFadeoutAltitude - h); + CalculateLapseRates(); + CalculatePressureBreakpoints(); +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + void FGStandardAtmosphere::PrintStandardAtmosphereTable() +{ + std::cout << "Altitude (ft) Temp (F) Pressure (psf) Density (sl/ft3)" << std::endl; + std::cout << "------------- -------- -------------- ----------------" << std::endl; + for (int i=0; i<280000; i+=1000) { + Calculate(i); + std::cout << std::setw(12) << std::setprecision(2) << i + << " " << std::setw(9) << std::setprecision(2) << Temperature-459.67 + << " " << std::setw(13) << std::setprecision(4) << Pressure + << " " << std::setw(18) << std::setprecision(8) << Density + << std::endl; + } + + // Re-execute the Run() method to reset the calculated values + Run(false); +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +// This function calculates (or recalculates) the lapse rate over an altitude range +// where the "bh" in this case refers to the index of the base height in the +// StdAtmosTemperatureTable table. This function should be called anytime the +// temperature table is altered, such as when a gradient is applied across the +// temperature table for a range of altitudes. + +void FGStandardAtmosphere::CalculateLapseRates() +{ + for (unsigned int bh=0; bh<LapseRateVector.size(); bh++) + { + double t0 = (*StdAtmosTemperatureTable)(bh+1,1); + double t1 = (*StdAtmosTemperatureTable)(bh+2,1); + double h0 = (*StdAtmosTemperatureTable)(bh+1,0); + double h1 = (*StdAtmosTemperatureTable)(bh+2,0); + LapseRateVector[bh] = (t1 - t0) / (h1 - h0) + TemperatureDeltaGradient; + } +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +void FGStandardAtmosphere::CalculatePressureBreakpoints() +{ + for (unsigned int b=0; b<PressureBreakpointVector.size()-1; b++) { + double BaseTemp = (*StdAtmosTemperatureTable)(b+1,1); + double BaseAlt = (*StdAtmosTemperatureTable)(b+1,0); + double UpperAlt = (*StdAtmosTemperatureTable)(b+2,0); + double deltaH = UpperAlt - BaseAlt; + double Tmb = BaseTemp + + TemperatureBias + + (GradientFadeoutAltitude - BaseAlt)*TemperatureDeltaGradient; + if (LapseRateVector[b] != 0.00) { + double Lmb = LapseRateVector[b]; + double Exp = Mair/(Rstar*Lmb); + double factor = Tmb/(Tmb + Lmb*deltaH); + PressureBreakpointVector[b+1] = PressureBreakpointVector[b]*pow(factor, Exp); + } else { + PressureBreakpointVector[b+1] = PressureBreakpointVector[b]*exp(-Mair*deltaH/(Rstar*Tmb)); + } + } +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +void FGStandardAtmosphere::ResetSLTemperature() +{ + TemperatureBias = TemperatureDeltaGradient = 0.0; + CalculateLapseRates(); + CalculatePressureBreakpoints(); +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +void FGStandardAtmosphere::ResetSLPressure() +{ + PressureBreakpointVector[0] = StdSLpressure; // psf + CalculatePressureBreakpoints(); +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +double FGStandardAtmosphere::ConvertToRankine(double t, eTemperature unit) const +{ + double targetTemp=0; // in degrees Rankine + + switch(unit) { + case eFahrenheit: + targetTemp = t + 459.67; + break; + case eCelsius: + targetTemp = t*9.0/5.0 + 32.0 + 459.67; + break; + case eRankine: + targetTemp = t; + break; + case eKelvin: + targetTemp = t*9.0/5.0; + } + + return targetTemp; +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +double FGStandardAtmosphere::ConvertToPSF(double p, ePressure unit) const +{ + double targetPressure=0; // Pressure in PSF + + switch(unit) { + case ePSF: + targetPressure = p; + break; + case eMillibars: + targetPressure = p*2.08854342; + break; + case ePascals: + targetPressure = p*0.0208854342; + break; + case eInchesHg: + targetPressure = p*70.7180803; + break; + default: + throw("Undefined pressure unit given"); + } + + return targetPressure; +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +void FGStandardAtmosphere::bind(void) +{ + typedef double (FGStandardAtmosphere::*PMFi)(int) const; + typedef void (FGStandardAtmosphere::*PMF)(int, double); + PropertyManager->Tie("stdatmosphere/T-R", this, &FGStandardAtmosphere::GetTemperature); + PropertyManager->Tie("stdatmosphere/rho-slugs_ft3", this, &FGStandardAtmosphere::GetDensity); + PropertyManager->Tie("stdatmosphere/P-psf", this, &FGStandardAtmosphere::GetPressure); + PropertyManager->Tie("stdatmosphere/a-fps", this, &FGStandardAtmosphere::GetSoundSpeed); + PropertyManager->Tie("stdatmosphere/T-sl-R", this, &FGStandardAtmosphere::GetTemperatureSL); + PropertyManager->Tie("stdatmosphere/rho-sl-slugs_ft3", this, &FGStandardAtmosphere::GetDensitySL); + PropertyManager->Tie("stdatmosphere/P-sl-psf", this, &FGStandardAtmosphere::GetPressureSL); + PropertyManager->Tie("stdatmosphere/a-sl-fps", this, &FGStandardAtmosphere::GetSoundSpeedSL); + PropertyManager->Tie("stdatmosphere/theta", this, &FGStandardAtmosphere::GetTemperatureRatio); + PropertyManager->Tie("stdatmosphere/sigma", this, &FGStandardAtmosphere::GetDensityRatio); + PropertyManager->Tie("stdatmosphere/delta", this, &FGStandardAtmosphere::GetPressureRatio); + PropertyManager->Tie("stdatmosphere/a-ratio", this, &FGStandardAtmosphere::GetSoundSpeedRatio); + PropertyManager->Tie("stdatmosphere/delta-T", this, eRankine, + (PMFi)&FGStandardAtmosphere::GetTemperatureBias, + (PMF)&FGStandardAtmosphere::SetTemperatureBias); +// PropertyManager->Tie("atmosphere/density-altitude", this, &FGStandardAtmosphere::GetDensityAltitude); +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +// The bitmasked value choices are as follows: +// unset: In this case (the default) JSBSim would only print +// out the normally expected messages, essentially echoing +// the config files as they are read. If the environment +// variable is not set, debug_lvl is set to 1 internally +// 0: This requests JSBSim not to output any messages +// whatsoever. +// 1: This value explicity requests the normal JSBSim +// startup messages +// 2: This value asks for a message to be printed out when +// a class is instantiated +// 4: When this value is set, a message is displayed when a +// FGModel object executes its Run() method +// 8: When this value is set, various runtime state variables +// are printed out periodically +// 16: When set various parameters are sanity checked and +// a message is printed out when they go out of bounds + +void FGStandardAtmosphere::Debug(int from) +{ + if (debug_lvl <= 0) return; + + if (debug_lvl & 1) { // Standard console startup message output + if (from == 0) { // Constructor + } + } + if (debug_lvl & 2 ) { // Instantiation/Destruction notification + if (from == 0) std::cout << "Instantiated: FGStandardAtmosphere" << std::endl; + if (from == 1) std::cout << "Destroyed: FGStandardAtmosphere" << std::endl; + } + if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects + } + if (debug_lvl & 8 ) { // Runtime state variables + } + if (debug_lvl & 16) { // Sanity checking + } + if (debug_lvl & 128) { // + } + if (debug_lvl & 64) { + if (from == 0) { // Constructor + std::cout << IdSrc << std::endl; + std::cout << IdHdr << std::endl; + } + } +} + +} // namespace JSBSim diff --git a/src/FDM/JSBSim/models/atmosphere/FGStandardAtmosphere.h b/src/FDM/JSBSim/models/atmosphere/FGStandardAtmosphere.h new file mode 100644 index 000000000..07978941e --- /dev/null +++ b/src/FDM/JSBSim/models/atmosphere/FGStandardAtmosphere.h @@ -0,0 +1,379 @@ +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + Header: FGStandardAtmosphere.h + Author: Jon Berndt + Date started: 5/2011 + + ------------- Copyright (C) 2011 Jon S. Berndt (jon@jsbsim.org) ------------- + + This program is free software; you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any later + version. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + details. + + You should have received a copy of the GNU Lesser General Public License along with + this program; if not, write to the Free Software Foundation, Inc., 59 Temple + Place - Suite 330, Boston, MA 02111-1307, USA. + + Further information about the GNU Lesser General Public License can also be found on + the world wide web at http://www.gnu.org. + +HISTORY +-------------------------------------------------------------------------------- +5/2011 JSB Created + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +SENTRY +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ + +#ifndef FGSTANDARDATMOSPHERE_H +#define FGSTANDARDATMOSPHERE_H + +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +INCLUDES +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ + +#include <vector> +#include "models/FGModel.h" +#include "math/FGTable.h" + +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +DEFINITIONS +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ + +#define ID_STANDARDATMOSPHERE "$Id: FGStandardAtmosphere.h,v 1.9 2011/06/13 12:06:21 jberndt Exp $" + +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +FORWARD DECLARATIONS +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ + +namespace JSBSim { + +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +CLASS DOCUMENTATION +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ + +/** Models the 1976 U.S. Standard Atmosphere, with the ability to modify the + temperature and pressure. A base feature of the model is the temperature + profile that is stored as an FGTable object with this data: + +@code +GeoMet Alt Temp GeoPot Alt GeoMet Alt + (ft) (deg R) (km) (km) + --------- -------- ---------- ---------- + 0.0 518.67 // 0.000 0.000 + 36151.6 390.0 // 11.000 11.019 + 65823.5 390.0 // 20.000 20.063 + 105518.4 411.6 // 32.000 32.162 + 155347.8 487.2 // 47.000 47.350 + 168677.8 487.2 // 51.000 51.413 + 235570.9 386.4 // 71.000 71.802 + 282152.2 336.5; // 84.852 86.000 +@endcode + +The pressure is calculated at lower altitudes through the use of two equations +that are presented in the U.S. Standard Atmosphere document (see references). +Density, kinematic viscosity, speed of sound, etc., are all calculated based +on various constants and temperature and pressure. At higher altitudes (above +86 km (282152 ft) a different and more complicated method of calculating +pressure is used. +The temperature may be modified through the use of several methods. Ultimately, +these access methods allow the user to modify the sea level standard temperature, +and/or the sea level standard pressure, so that the entire profile will be +consistently and accurately calculated. + + <h2> Properties </h2> + @property atmosphere/T-R The current modeled temperature in degrees Rankine. + @property atmosphere/rho-slugs_ft3 + @property atmosphere/P-psf + @property atmosphere/a-fps + @property atmosphere/T-sl-R + @property atmosphere/rho-sl-slugs_ft3 + @property atmosphere/P-sl-psf + @property atmosphere/a-sl-fps + @property atmosphere/theta + @property atmosphere/sigma + @property atmosphere/delta + @property atmosphere/a-ratio + @property atmosphere/delta-T + @property atmosphere/T-sl-dev-F + + @author Jon Berndt + @see "U.S. Standard Atmosphere, 1976", NASA TM-X-74335 + @version $Id: FGStandardAtmosphere.h,v 1.9 2011/06/13 12:06:21 jberndt Exp $ +*/ + +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +CLASS DECLARATION +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ + +class FGStandardAtmosphere : public FGModel { +public: + + /// Enums for specifying temperature units. + enum eTemperature {eNoTempUnit=0, eFahrenheit, eCelsius, eRankine, eKelvin}; + + /// Enums for specifying pressure units. + enum ePressure {eNoPressUnit=0, ePSF, eMillibars, ePascals, eInchesHg}; + + /// Constructor + FGStandardAtmosphere(FGFDMExec*); + /// Destructor + ~FGStandardAtmosphere(); + /** Runs the standard atmosphere forces model; called by the Executive. + Can pass in a value indicating if the executive is directing the simulation to Hold. + @param Holding if true, the executive has been directed to hold the sim from + advancing time. Some models may ignore this flag, such as the Input + model, which may need to be active to listen on a socket for the + "Resume" command to be given. + @return false if no error */ + bool Run(bool Holding); + bool InitModel(void); + + // ************************************************************************* + /// @name Temperature access functions. + /// There are several ways to get the temperature, and several modeled temperature + /// values that can be retrieved. The U.S. Standard Atmosphere temperature either + /// at a specified altitude, or at sea level can be retrieved. These two temperatures + /// do NOT include the effects of any bias or delta gradient that may have been + /// supplied by the user. The modeled temperature and the modeled temperature + /// at sea level can also be retrieved. These two temperatures DO include the + /// effects of an optionally user-supplied bias or delta gradient. + // @{ + /// Returns the actual, modeled temperature at the current altitude in degrees Rankine. + /// @return Modeled temperature in degrees Rankine. + virtual double GetTemperature() const {return Temperature;} + + /// Returns the actual modeled temperature in degrees Rankine at a specified altitude. + /// @param altitude The altitude above sea level (ASL) in feet. + /// @return Modeled temperature in degrees Rankine at the specified altitude. + virtual double GetTemperature(double altitude) const; + + /// Returns the actual, modeled sea level temperature in degrees Rankine. + /// @return The modeled temperature in degrees Rankine at sea level. + virtual double GetTemperatureSL() const { return GetTemperature(0.0); } + + /// Returns the standard temperature in degrees Rankine at a specified altitude. + /// @param altitude The altitude in feet above sea level (ASL) to get the temperature at. + /// @return The STANDARD temperature in degrees Rankine at the specified altitude. + virtual double GetStdTemperature(double altitude) const; + + /// Returns the standard sea level temperature in degrees Rankine. + /// @return The STANDARD temperature at sea level in degrees Rankine. + virtual double GetStdTemperatureSL() const { return GetStdTemperature(0.0); } + + /// Returns the ratio of the at-current-altitude temperature as modeled + /// over the standard sea level value. + virtual double GetTemperatureRatio() const { return GetTemperature()*rSLtemperature; } + + /// Returns the ratio of the temperature as modeled at the supplied altitude + /// over the standard sea level value. + virtual double GetTemperatureRatio(double h) const { return GetTemperature(h)*rSLtemperature; } + + /// Returns the ratio of the standard temperature at the supplied altitude + /// over the standard sea level temperature. + virtual double GetStdTemperatureRatio(double h) const { return GetStdTemperature(h)*rSLtemperature; } + + /// Returns the temperature bias over the sea level value in degrees Rankine. + virtual double GetTemperatureBias(eTemperature to) const {return TemperatureBias;} + + /// Returns the temperature gradient to be applied on top of the standard + /// temperature gradient. + virtual double GetTemperatureDeltaGradient() { return TemperatureDeltaGradient;} + + /// Sets the Sea Level temperature, if it is to be different than the standard. + /// This function will calculate a bias - a difference - from the standard + /// atmosphere temperature and will apply that bias to the entire + /// temperature profile. This is one way to set the temperature bias. Using + /// the SetTemperatureBias function will replace the value calculated by + /// this function. + /// @param t the temperature value in the unit provided. + /// @param unit the unit of the temperature. + virtual void SetSLTemperature(double t, eTemperature unit=eFahrenheit); + + /// Sets the temperature at the supplied altitude, if it is to be different + /// than the standard temperature. + /// This function will calculate a bias - a difference - from the standard + /// atmosphere temperature at the supplied altitude and will apply that + /// calculated bias to the entire temperature profile. + /// @param t The temperature value in the unit provided. + /// @param h The altitude in feet above sea level. + /// @param unit The unit of the temperature. + virtual void SetTemperature(double t, double h, eTemperature unit=eFahrenheit) {}; + + /// Sets the temperature bias to be added to the standard temperature at all altitudes. + /// This function sets the bias - the difference - from the standard + /// atmosphere temperature. This bias applies to the entire + /// temperature profile. Another way to set the temperature bias is to use the + /// SetSLTemperature function, which replaces the value calculated by + /// this function with a calculated bias. + /// @param t the temperature value in the unit provided. + /// @param unit the unit of the temperature. + virtual void SetTemperatureBias(double t, eTemperature unit=eFahrenheit); + + /// Sets a Sea Level temperature delta that is ramped out by 86 km. + /// The value of the delta is used to calculate a delta gradient that is + /// applied to the temperature at all altitudes below 86 km (282152 ft). + /// For instance, if a temperature of 20 degrees F is supplied, the delta + /// gradient would be 20/282152 - or, about 7.09E-5 degrees/ft. At sea level, + /// the full 20 degrees would be added to the standard temperature, + /// but that 20 degree delta would be reduced by 7.09E-5 degrees for every + /// foot of altitude above sea level, so that by 86 km, there would be no + /// further delta added to the standard temperature. + /// The graded delta can be used along with the a bias to tailor the + /// temperature profile as desired. + /// @param t the sea level temperature delta value in the unit provided. + /// @param unit the unit of the temperature. + virtual void SetSLTemperatureGradedDelta(double t, eTemperature unit=eFahrenheit); + + /// Sets the temperature delta value at the supplied altitude/elevation above + /// sea level, to be added to the standard temperature and ramped out by + /// 86 km. + /// This function computes the sea level delta from the standard atmosphere + /// temperature at sea level. + /// @param t the temperature skew value in the unit provided. + /// @param unit the unit of the temperature. + virtual void SetTemperatureGradedDelta(double t, double h, eTemperature unit=eFahrenheit); + + /// This function resets the model to apply no bias or delta gradient to the + /// temperature. + /// The delta gradient and bias values are reset to 0.0, and the standard + /// temperature is used for the entire temperature profile at all altitudes. + virtual void ResetSLTemperature(); + //@} + + // ************************************************************************* + /// @name Pressure access functions. + //@{ + /// Returns the pressure in psf. + virtual double GetPressure(void) const {return Pressure;} + + /// Returns the pressure at a specified altitude in psf. + virtual double GetPressure(double altitude) const; + + /// Returns the standard pressure at a specified altitude in psf + virtual double GetStdPressure100K(double altitude) const; + + /// Returns the standard pressure at the specified altitude. + virtual double GetStdPressure(double altitude) const; + + /// Returns the sea level pressure in psf. + virtual double GetPressureSL(void) const { return SLpressure; } + + /// Returns the ratio of at-altitude pressure over the sea level value. + virtual double GetPressureRatio(void) const { return Pressure*rSLpressure; } + + /** Sets the sea level pressure for modeling an off-standard pressure + profile. This could be useful in the case where the pressure at an + airfield is known or set for a particular simulation run. + @param pressure The pressure in the units specified (PSF by default). + @param unit the unit of measure that the specified pressure is + supplied in.*/ + virtual void SetSeaLevelPressure(double pressure, ePressure unit=ePSF); + + /** Resets the sea level to the Standard sea level pressure, and recalculates + dependent parameters so that the pressure calculations are standard. */ + virtual void ResetSLPressure(); + //@} + + // ************************************************************************* + /// @name Density access functions. + //@{ + /** Returns the density in slugs/ft^3. + This function may only be used if Run() is called first. */ + virtual double GetDensity(void) const {return Density;} + + /** Returns the density in slugs/ft^3 at a given altitude in ft. */ + virtual double GetDensity(double altitude) const; + + /// Returns the standard density at a specified altitude + virtual double GetStdDensity(double altitude) const; + + /// Returns the sea level density in slugs/ft^3 + virtual double GetDensitySL(void) const { return SLdensity; } + + /// Returns the ratio of at-altitude density over the sea level value. + virtual double GetDensityRatio(void) const { return Density*rSLdensity; } + //@} + + // ************************************************************************* + /// @name Speed of sound access functions. + //@{ + /// Returns the speed of sound in ft/sec. + virtual double GetSoundSpeed(void) const {return Soundspeed;} + + /// Returns the sea level speed of sound in ft/sec. + virtual double GetSoundSpeedSL(void) const { return SLsoundspeed; } + + /// Returns the ratio of at-altitude sound speed over the sea level value. + virtual double GetSoundSpeedRatio(void) const { return Soundspeed*rSLsoundspeed; } + //@} + + // ************************************************************************* + /// @name Viscosity access functions. + //@{ + /// Returns the absolute viscosity. + virtual double GetAbsoluteViscosity(void) const {return Viscosity;} + + /// Returns the kinematic viscosity. + virtual double GetKinematicViscosity(void) const {return KinematicViscosity;} + //@} + + /* /// Gets the density altitude in feet */ +// virtual double GetDensityAltitude(void) const { return density_altitude; } + + /// Prints the U.S. Standard Atmosphere table. + virtual void PrintStandardAtmosphereTable(); + +protected: + double StdSLtemperature, StdSLdensity, StdSLpressure, StdSLsoundspeed; // Standard sea level conditions + double SLtemperature, SLdensity, SLpressure, SLsoundspeed; // Sea level conditions + double Temperature, Density, Pressure, Soundspeed; // Current actual conditions at altitude + double rSLtemperature, rSLdensity, rSLpressure, rSLsoundspeed; // Reciprocal of sea level conditions + + double PressureAltitude; + double DensityAltitude; + + double TemperatureBias; + double TemperatureDeltaGradient; + double GradientFadeoutAltitude; + + FGTable* StdAtmosTemperatureTable; + std::vector<double> LapseRateVector; + std::vector<double> PressureBreakpointVector; + + const double SutherlandConstant, Beta; + double Viscosity, KinematicViscosity; + + /// Calculate the atmosphere for the given altitude, including effects of temperature deviation. + void Calculate(double altitude); + + /// Recalculate the lapse rate vectors when the temperature profile is altered + /// in a way that would change the lapse rates, such as when a gradient is applied. + /// This function is also called to initialize the lapse rate vector. + void CalculateLapseRates(); + + /// Calculate (or recalculate) the atmospheric pressure breakpoints at the + /// altitudes in the standard temperature table. + void CalculatePressureBreakpoints(); + + // Converts to Rankine from one of several unit systems. + virtual double ConvertToRankine(double t, eTemperature unit) const; + + // Converts to PSF (pounds per square foot) from one of several unit systems. + virtual double ConvertToPSF(double t, ePressure unit=ePSF) const; + + virtual void bind(void); + void Debug(int from); +}; + +} // namespace JSBSim + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +#endif + diff --git a/src/FDM/JSBSim/models/flight_control/FGActuator.cpp b/src/FDM/JSBSim/models/flight_control/FGActuator.cpp index bfbd25920..e7ab6aa65 100644 --- a/src/FDM/JSBSim/models/flight_control/FGActuator.cpp +++ b/src/FDM/JSBSim/models/flight_control/FGActuator.cpp @@ -43,7 +43,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGActuator.cpp,v 1.17 2011/02/13 00:42:45 jberndt Exp $"; +static const char *IdSrc = "$Id: FGActuator.cpp,v 1.18 2011/05/13 17:14:47 bcoconni Exp $"; static const char *IdHdr = ID_ACTUATOR; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -125,6 +125,13 @@ bool FGActuator::Run(void ) if (fail_stuck) Output = PreviousOutput; PreviousOutput = Output; // previous value needed for "stuck" malfunction + if (fcs->GetTrimStatus()) { + PreviousHystOutput = Output; + PreviousRateLimOutput = Output; + PreviousLagInput = Output; + PreviousLagOutput = Output; + } + Clip(); if (IsOutput) SetOutput(); diff --git a/src/FDM/JSBSim/models/flight_control/FGFCSComponent.cpp b/src/FDM/JSBSim/models/flight_control/FGFCSComponent.cpp index 64a764927..2fc74bd96 100644 --- a/src/FDM/JSBSim/models/flight_control/FGFCSComponent.cpp +++ b/src/FDM/JSBSim/models/flight_control/FGFCSComponent.cpp @@ -48,7 +48,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGFCSComponent.cpp,v 1.30 2011/04/05 20:20:21 andgi Exp $"; +static const char *IdSrc = "$Id: FGFCSComponent.cpp,v 1.32 2011/06/16 03:39:38 jberndt Exp $"; static const char *IdHdr = ID_FCSCOMPONENT; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -58,7 +58,7 @@ CLASS IMPLEMENTATION FGFCSComponent::FGFCSComponent(FGFCS* _fcs, Element* element) : fcs(_fcs) { Element *input_element, *clip_el; - Input = Output = clipmin = clipmax = 0.0; + Input = Output = clipmin = clipmax = delay_time = 0.0; treenode = 0; delay = index = 0; ClipMinPropertyNode = ClipMaxPropertyNode = 0; @@ -149,18 +149,18 @@ FGFCSComponent::FGFCSComponent(FGFCS* _fcs, Element* element) : fcs(_fcs) Element* delay_elem = element->FindElement("delay"); if ( delay_elem ) { - delay = (unsigned int)delay_elem->GetDataAsNumber(); + delay_time = delay_elem->GetDataAsNumber(); string delayType = delay_elem->GetAttributeValue("type"); if (delayType.length() > 0) { if (delayType == "time") { - delay = (int)(delay / dt); + delay = (unsigned int)(delay_time / dt); } else if (delayType == "frames") { - // no op. the delay type of "frames" is assumed and is the default. + delay = (unsigned int)delay_time; } else { cerr << "Unallowed delay type" << endl; } } else { - delay = (int)(delay / dt); + delay = (unsigned int)(delay_time / dt); } output_array.resize(delay); for (int i=0; i<delay; i++) output_array[i] = 0.0; diff --git a/src/FDM/JSBSim/models/flight_control/FGFCSComponent.h b/src/FDM/JSBSim/models/flight_control/FGFCSComponent.h index 02bca98bd..d79a2e66c 100644 --- a/src/FDM/JSBSim/models/flight_control/FGFCSComponent.h +++ b/src/FDM/JSBSim/models/flight_control/FGFCSComponent.h @@ -46,7 +46,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_FCSCOMPONENT "$Id: FGFCSComponent.h,v 1.18 2011/04/05 20:20:21 andgi Exp $" +#define ID_FCSCOMPONENT "$Id: FGFCSComponent.h,v 1.20 2011/06/16 03:39:38 jberndt Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -81,7 +81,7 @@ CLASS DOCUMENTATION - FGActuator @author Jon S. Berndt - @version $Id: FGFCSComponent.h,v 1.18 2011/04/05 20:20:21 andgi Exp $ + @version $Id: FGFCSComponent.h,v 1.20 2011/06/16 03:39:38 jberndt Exp $ @see Documentation for the FGFCS class, and for the configuration file class */ @@ -120,7 +120,8 @@ protected: double Input; double Output; double clipmax, clipmin; - int delay; + double delay_time; + unsigned int delay; int index; float clipMinSign, clipMaxSign; double dt; diff --git a/src/FDM/JSBSim/models/flight_control/FGPID.cpp b/src/FDM/JSBSim/models/flight_control/FGPID.cpp old mode 100644 new mode 100755 index 6556ecdb7..da6e6c16e --- a/src/FDM/JSBSim/models/flight_control/FGPID.cpp +++ b/src/FDM/JSBSim/models/flight_control/FGPID.cpp @@ -44,7 +44,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGPID.cpp,v 1.16 2009/10/24 22:59:30 jberndt Exp $"; +static const char *IdSrc = "$Id: FGPID.cpp,v 1.19 2011/05/05 11:44:11 jberndt Exp $"; static const char *IdHdr = ID_PID; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -144,10 +144,14 @@ bool FGPID::Run(void ) if (Trigger != 0) { double test = Trigger->getDoubleValue(); - if (fabs(test) < 0.000001) I_out_delta = Ki * dt * Input; // Normal + if (fabs(test) < 0.000001) { + // I_out_delta = Ki * dt * Input; // Normal rectangular integrator + I_out_delta = Ki * dt * (1.5*Input - 0.5*Input_prev); // 2nd order Adams Bashforth integrator + } if (test < 0.0) I_out_total = 0.0; // Reset integrator to 0.0 } else { // no anti-wind-up trigger defined - I_out_delta = Ki * dt * Input; + // I_out_delta = Ki * dt * Input; + I_out_delta = Ki * dt * (1.5*Input - 0.5*Input_prev); // 2nd order Adams Bashforth integrator } I_out_total += I_out_delta; diff --git a/src/FDM/JSBSim/models/flight_control/FGSwitch.cpp b/src/FDM/JSBSim/models/flight_control/FGSwitch.cpp index cea9f583e..9d56e512e 100644 --- a/src/FDM/JSBSim/models/flight_control/FGSwitch.cpp +++ b/src/FDM/JSBSim/models/flight_control/FGSwitch.cpp @@ -69,7 +69,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGSwitch.cpp,v 1.20 2011/04/05 20:20:21 andgi Exp $"; +static const char *IdSrc = "$Id: FGSwitch.cpp,v 1.21 2011/06/16 03:39:38 jberndt Exp $"; static const char *IdHdr = ID_SWITCH; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -196,6 +196,7 @@ bool FGSwitch::Run(void ) if (!pass) Output = default_output; + if (delay != 0) Delay(); Clip(); if (IsOutput) SetOutput(); diff --git a/src/FDM/JSBSim/models/propulsion/FGElectric.cpp b/src/FDM/JSBSim/models/propulsion/FGElectric.cpp index cbcb9220a..341c02a39 100644 --- a/src/FDM/JSBSim/models/propulsion/FGElectric.cpp +++ b/src/FDM/JSBSim/models/propulsion/FGElectric.cpp @@ -42,6 +42,7 @@ INCLUDES #include "FGElectric.h" #include "models/FGPropulsion.h" #include "models/propulsion/FGThruster.h" +#include "FGPropeller.h" #include <iostream> #include <sstream> @@ -50,7 +51,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGElectric.cpp,v 1.10 2011/03/10 01:35:25 dpculp Exp $"; +static const char *IdSrc = "$Id: FGElectric.cpp,v 1.11 2011/06/06 22:35:08 jentron Exp $"; static const char *IdHdr = ID_ELECTRIC; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -71,6 +72,11 @@ FGElectric::FGElectric(FGFDMExec* exec, Element *el, int engine_number) if (el->FindElement("power")) PowerWatts = el->FindElementValueAsNumberConvertTo("power","WATTS"); + string property_name, base_property_name; + base_property_name = CreateIndexedPropertyName("propulsion/engine", EngineNumber); + property_name = base_property_name + "/power-hp"; + PropertyManager->Tie(property_name, &HP); + Debug(0); // Call Debug() routine from constructor if needed } @@ -89,6 +95,11 @@ void FGElectric::Calculate(void) Throttle = FCS->GetThrottlePos(EngineNumber); + if (Thruster->GetType() == FGThruster::ttPropeller) { + ((FGPropeller*)Thruster)->SetAdvance(FCS->GetPropAdvance(EngineNumber)); + ((FGPropeller*)Thruster)->SetFeather(FCS->GetPropFeather(EngineNumber)); + } + RPM = Thruster->GetRPM() * Thruster->GetGearRatio(); HP = PowerWatts * Throttle / hptowatts; diff --git a/src/FDM/JSBSim/models/propulsion/FGPiston.cpp b/src/FDM/JSBSim/models/propulsion/FGPiston.cpp index 7726306bf..c687b31e8 100644 --- a/src/FDM/JSBSim/models/propulsion/FGPiston.cpp +++ b/src/FDM/JSBSim/models/propulsion/FGPiston.cpp @@ -53,7 +53,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGPiston.cpp,v 1.55 2011/03/10 01:35:25 dpculp Exp $"; +static const char *IdSrc = "$Id: FGPiston.cpp,v 1.58 2011/06/13 15:23:09 jentron Exp $"; static const char *IdHdr = ID_PISTON; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -64,7 +64,7 @@ FGPiston::FGPiston(FGFDMExec* exec, Element* el, int engine_number) : FGEngine(exec, el, engine_number), R_air(287.3), // Gas constant for air J/Kg/K rho_fuel(800), // estimate - calorific_value_fuel(47.3e6), + calorific_value_fuel(47.3e6), // J/Kg Cp_air(1005), // Specific heat (constant pressure) J/Kg/K Cp_fuel(1700), standard_pressure(101320.73) @@ -100,6 +100,7 @@ FGPiston::FGPiston(FGFDMExec* exec, Element* el, int engine_number) FMEPDynamic= 18400; FMEPStatic = 46500; Cooling_Factor = 0.5144444; + StaticFriction_HP = 1.5; // These are internal program variables @@ -177,6 +178,8 @@ FGPiston::FGPiston(FGFDMExec* exec, Element* el, int engine_number) Displacement = el->FindElementValueAsNumberConvertTo("displacement","IN3"); if (el->FindElement("maxhp")) MaxHP = el->FindElementValueAsNumberConvertTo("maxhp","HP"); + if (el->FindElement("static-friction")) + StaticFriction_HP = el->FindElementValueAsNumberConvertTo("static-friction","HP"); if (el->FindElement("sparkfaildrop")) SparkFailDrop = Constrain(0, 1 - el->FindElementValueAsNumber("sparkfaildrop"), 1); if (el->FindElement("cycles")) @@ -259,7 +262,7 @@ FGPiston::FGPiston(FGFDMExec* exec, Element* el, int engine_number) pmep *= inhgtopa * volumetric_efficiency; double fmep = (FMEPDynamic * RatedMeanPistonSpeed_fps * fttom + FMEPStatic); double hp_loss = ((pmep + fmep) * displacement_SI * MaxRPM)/(Cycles*22371); - ISFC = ( 1.1*Displacement * MaxRPM * volumetric_efficiency *(MaxManifoldPressure_inHg / 29.92) ) / (9411 * (MaxHP+hp_loss)); + ISFC = ( 1.1*Displacement * MaxRPM * volumetric_efficiency *(MaxManifoldPressure_inHg / 29.92) ) / (9411 * (MaxHP+hp_loss-StaticFriction_HP)); // cout <<"FMEP: "<< fmep <<" PMEP: "<< pmep << " hp_loss: " <<hp_loss <<endl; } if ( MaxManifoldPressure_inHg > 29.9 ) { // Don't allow boosting with a bogus number @@ -314,6 +317,14 @@ FGPiston::FGPiston(FGFDMExec* exec, Element* el, int engine_number) PropertyManager->Tie(property_name, &BoostSpeed); property_name = base_property_name + "/cht-degF"; PropertyManager->Tie(property_name, this, &FGPiston::getCylinderHeadTemp_degF); + property_name = base_property_name + "/engine-rpm"; + PropertyManager->Tie(property_name, this, &FGPiston::getRPM); + property_name = base_property_name + "/oil-temperature-degF"; + PropertyManager->Tie(property_name, this, &FGPiston::getOilTemp_degF); + property_name = base_property_name + "/oil-pressure-psi"; + PropertyManager->Tie(property_name, this, &FGPiston::getOilPressure_psi); + property_name = base_property_name + "/egt-degF"; + PropertyManager->Tie(property_name, this, &FGPiston::getExhaustGasTemp_degF); // Set up and sanity-check the turbo/supercharging configuration based on the input values. if (TakeoffBoost > RatedBoost[0]) bTakeoffBoost = true; @@ -730,7 +741,7 @@ void FGPiston::doEnginePower(void) // (1/2) convert cycles, 60 minutes to seconds, 745.7 watts to hp. double pumping_hp = ((PMEP + FMEP) * displacement_SI * RPM)/(Cycles*22371); - HP = IndicatedHorsePower + pumping_hp - 1.5; //FIXME 1.5 static friction should depend on oil temp and configuration + HP = IndicatedHorsePower + pumping_hp - StaticFriction_HP; //FIXME static friction should depend on oil temp and configuration // cout << "pumping_hp " <<pumping_hp << FMEP << PMEP <<endl; PctPower = HP / MaxHP ; // cout << "Power = " << HP << " RPM = " << RPM << " Running = " << Running << " Cranking = " << Cranking << endl; @@ -756,11 +767,10 @@ void FGPiston::doEGT(void) if ((Running) && (m_dot_air > 0.0)) { // do the energy balance combustion_efficiency = Lookup_Combustion_Efficiency->GetValue(equivalence_ratio); enthalpy_exhaust = m_dot_fuel * calorific_value_fuel * - combustion_efficiency * 0.33; + combustion_efficiency * 0.30; heat_capacity_exhaust = (Cp_air * m_dot_air) + (Cp_fuel * m_dot_fuel); delta_T_exhaust = enthalpy_exhaust / heat_capacity_exhaust; ExhaustGasTemp_degK = T_amb + delta_T_exhaust; - ExhaustGasTemp_degK *= 0.444 + ((0.544 - 0.444) * PctPower); } else { // Drop towards ambient - guess an appropriate time constant for now combustion_efficiency = 0; dEGTdt = (RankineToKelvin(Atmosphere->GetTemperature()) - ExhaustGasTemp_degK) / 100.0; diff --git a/src/FDM/JSBSim/models/propulsion/FGPiston.h b/src/FDM/JSBSim/models/propulsion/FGPiston.h index a8019e5aa..4a536b5d0 100644 --- a/src/FDM/JSBSim/models/propulsion/FGPiston.h +++ b/src/FDM/JSBSim/models/propulsion/FGPiston.h @@ -46,7 +46,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_PISTON "$Id: FGPiston.h,v 1.26 2011/03/10 01:35:25 dpculp Exp $"; +#define ID_PISTON "$Id: FGPiston.h,v 1.29 2011/06/16 16:32:10 jentron Exp $"; #define FG_MAX_BOOST_SPEEDS 3 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -59,7 +59,7 @@ namespace JSBSim { CLASS DOCUMENTATION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -/** Models Dave Luff's Turbo/Supercharged Piston engine model. +/** Models a Supercharged Piston engine. Based on Dave Luff's model. <h3>Configuration File Format:</h3> @@ -67,19 +67,21 @@ CLASS DOCUMENTATION <piston_engine name="{string}"> <minmp unit="{INHG | PA | ATM}"> {number} </minmp> <maxmp unit="{INHG | PA | ATM}"> {number} </maxmp> + <idlerpm> {number} </idlerpm> + <maxrpm> {number} </maxrpm> + <maxhp unit="{HP | WATTS}"> {number} </maxhp> <displacement unit="{IN3 | LTR | CC}"> {number} </displacement> + <cycles> {number} </cycles> <bore unit="{IN | M}"> {number} </bore> <stroke unit="{IN | M}"> {number} </stroke> <cylinders> {number} </cylinders> - <cylinder-head-mass unit="{KG | LBS}"> {number} </cylinder-head-mass> <compression-ratio> {number} </compression-ratio> <sparkfaildrop> {number} </sparkfaildrop> - <maxhp unit="{HP | WATTS}"> {number} </maxhp> - <cycles> {number} </cycles> - <idlerpm> {number} </idlerpm> - <maxrpm> {number} </maxrpm> - <maxthrottle> {number} </maxthrottle> - <minthrottle> {number} </minthrottle> + <static-friction unit="{HP | WATTS}"> {number} </static-friction> + <air-intake-impedance-factor> {number} </air-intake-impedance-factor> + <ram-air-factor> {number} </ram-air-factor> + <cooling-factor> {number} </cooling-factor> + <cylinder-head-mass unit="{KG | LBS}"> {number} </cylinder-head-mass> <bsfc unit="{LBS/HP*HR | "KG/KW*HR"}"> {number} </bsfc> <volumetric-efficiency> {number} </volumetric-efficiency> <dynamic-fmep unit="{INHG | PA | ATM}"> {number} </dynamic-fmep> @@ -100,89 +102,103 @@ CLASS DOCUMENTATION <ratedrpm3> {number} </ratedrpm3> <ratedaltitude3 unit="{FT | M}"> {number} </ratedaltitude3> <takeoffboost unit="{INHG | PA | ATM}"> {number} </takeoffboost> - <air-intake-impedance-factor> {number} </air-intake-impedance-factor> - <ram-air-factor> {number} </ram-air-factor> - <cooling-factor> {number} </cooling-factor> </piston_engine> @endcode -<pre> - Additional elements are required for a supercharged engine. These can be - left off a non-supercharged engine, ie. the changes are all backward - compatible at present. +<h3>Definition of the piston engine configuration file parameters:</h3> +Basic parameters: +- \b minmp - this value is the nominal idle manifold pressure at sea-level + without boost. Along with idlerpm, it determines throttle response slope. +- \b maxmp - this value is the nominal maximum manifold pressure at sea-level + without boost. Along with maxrpm it determines the resistance of the + aircraft intake system. Overridden by air-intake-impedance-factor +- \b idlerpm - this value affects the throttle fall off and the engine stops + running if it is slowed below 80% of this value. The engine starts + running when it reaches 80% of this value. +- \b maxrpm - this value is used to calculate air-box resistance and BSFC. It + also affects oil pressure among other things. +- \b maxhp - this value is the nominal power the engine creates at maxrpm. It + will determine bsfc if that tag is not input. It also determines the + starter motor power. +- \b displacement - this value is used to determine mass air and fuel flow + which impacts engine power and cooling. +- \b cycles - Designate a 2 or 4 stroke engine. Currently only the 4 stroke + engine is supported. +- \b bore - cylinder bore is currently unused. +- \b stroke - piston stroke is used to determine the mean piston speed. Longer + strokes result in an engine that does not work as well at higher RPMs. +- \b compression-ratio - the compression ratio affects the change in volumetric + efficiency with altitude. +- \b sparkfaildrop - this is the percentage drop in horsepower for single + magneto operation. +- \b static-friction - this value is the power required to turn an engine that + is not running. Used to control and slow a windmilling propeller. Choose + a small percentage of maxhp. - - NUMBOOSTSPEEDS - zero (or not present) for a naturally-aspirated engine, +Advanced parameters +- \b bsfc - Indicated Specific Fuel Consumption. The power produced per unit of + fuel. Higher numbers give worse fuel economy. This number may need to be + lowered slightly from actual BSFC numbers because some internal engine + losses are modeled separately. Typically between 0.3 and 0.5 +- \b volumetric-efficiency - the nominal volumetric efficiency of the engine. + This is the primary way to control fuel flow Boosted engines may require + values above 1. Typical engines are 0.80 to 0.82 +- \b air-intake-impedance-factor - this number is the pressure drop across the + intake system. Increasing it reduces available manifold pressure. Also a + property for run-time adjustment. +- \b ram-air-factor - this number creates increases manifold pressure with an + increase in dynamic pressure (aircraft speed). + Also a property for run-time adjustment. + +Cooling control: +- \b cylinders - number of cylinders scales the cylinder head mass. +- \b cylinder-head-mass - the nominal mass of a cylinder head. A larger value + slows changes in engine temperature +- \b cooling-factor - this number models the efficiency of the aircraft cooling + system. Also a property for run-time adjustment. + +Supercharge parameters: +- \b numboostspeed - zero (or not present) for a naturally-aspirated engine, either 1, 2 or 3 for a boosted engine. This corresponds to the number of supercharger speeds. Merlin XII had 1 speed, Merlin 61 had 2, a late Griffon engine apparently had 3. No known engine more than 3, although - some German engines apparently had a continuously variable-speed - supercharger. + some German engines had continuously variable-speed superchargers. +- \b boostoverride - unused +- \b boostmanual - whether a multispeed supercharger will manually or + automatically shift boost speeds. On manual shifting the boost speeds is + accomplished by controlling the property propulsion/engine/boostspeed. +- \b takeoffboost - boost in psi above sea level ambient. Typically used for + takeoff, and emergency situations, generally for not more than five + minutes. This is a change in the boost control setting, not the actual + supercharger speed, and so would only give extra power below the rated altitude. + A typical takeoff boost for an early Merlin was about 12psi, compared + with a rated boost of 9psi. - - BOOSTOVERRIDE - whether the boost pressure control system (either a boost - control valve for superchargers or wastegate for turbochargers) can be - overriden by the pilot. During wartime this was commonly possible, and - known as "War Emergency Power" by the Brits. 1 or 0 in the config file. - This isn't implemented in the model yet though, there would need to be - some way of getting the boost control cutout lever position (on or off) - from FlightGear first. + When TAKEOFFBOOST is specified in the config file (and is above RATEDBOOST1), + the throttle position is interpreted as: + - 0 to 0.98 : idle manifold pressure to rated boost (where attainable) + - 0.99, 1.0 : takeoff boost (where attainable). - - BOOSTMANUAL - whether a multispeed supercharger will manually or - automatically shift boost speeds. On manual shifting the boost speeds - is accomplished by controling propulsion/engine/boostspeed +The next items are all appended with either 1, 2 or 3 depending on which +boostspeed they refer to: +- \b ratedboost[123] - the absolute rated boost above sea level ambient + (14.7 PSI, 29.92 inHg) for a given boost speed. - - The next items are all appended with either 1, 2 or 3 depending on which - boost speed they refer to, eg RATEDBOOST1. The rated values seems to have - been a common convention at the time to express the maximum continuously - available power, and the conditions to attain that power. - - - RATEDBOOST[123] - the absolute rated boost above sea level ambient for a - given boost speed, in psi. Eg the Merlin XII had a rated boost of 9psi, - giving approximately 42inHg manifold pressure up to the rated altitude. - - - RATEDALTITUDE[123] - The altitude up to which rated boost can be - maintained. Up to this altitude the boost is maintained constant for a - given throttle position by the BCV or wastegate. Beyond this altitude the - manifold pressure must drop, since the supercharger is now at maximum - unregulated output. The actual pressure multiplier of the supercharger - system is calculated at initialisation from this value. - - - RATEDPOWER[123] - The power developed at rated boost at rated altitude at - rated rpm. - - - RATEDRPM[123] - The rpm at which rated power is developed. - - - TAKEOFFBOOST - Takeoff boost in psi above ambient. Many aircraft had an - extra boost setting beyond rated boost, but not totally uncontrolled as in - the already mentioned boost-control-cutout, typically attained by pushing - the throttle past a mechanical 'gate' preventing its inadvertant use. This - was typically used for takeoff, and emergency situations, generally for - not more than five minutes. This is a change in the boost control - setting, not the actual supercharger speed, and so would only give extra - power below the rated altitude. When TAKEOFFBOOST is specified in the - config file (and is above RATEDBOOST1), then the throttle position is - interpreted as: - - - 0 to 0.98 : idle manifold pressure to rated boost (where attainable) - - 0.99, 1.0 : takeoff boost (where attainable). - - A typical takeoff boost for an earlyish Merlin was about 12psi, compared - with a rated boost of 9psi. - - It is quite possible that other boost control settings could have been used - on some aircraft, or that takeoff/extra boost could have activated by other - means than pushing the throttle full forward through a gate, but this will - suffice for now. - - Note that MAXMP is still the non-boosted max manifold pressure even for - boosted engines - effectively this is simply a measure of the pressure drop - through the fully open throttle. -</pre> +- \b ratedpower[123] - unused +- \b ratedrpm[123] - The rpm at which rated boost is developed +- \b ratedaltitude[123] - The altitude up to which the rated boost can be + maintained. Up to this altitude the boost is clipped to rated boost or + takeoffboost. Beyond this altitude the manifold pressure must drop, + since the supercharger is now at maximum unregulated output. The actual + pressure multiplier of the supercharger system is calculated at + initialization from this value. @author Jon S. Berndt (Engine framework code and framework-related mods) @author Dave Luff (engine operational code) @author David Megginson (initial porting and additional code) @author Ron Jensen (additional engine code) - @version $Id: FGPiston.h,v 1.26 2011/03/10 01:35:25 dpculp Exp $ + @see Taylor, Charles Fayette, "The Internal Combustion Engine in Theory and Practice" + @version $Id: FGPiston.h,v 1.29 2011/06/16 16:32:10 jentron Exp $ */ /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -250,7 +266,7 @@ private: const double R_air; const double rho_fuel; // kg/m^3 - const double calorific_value_fuel; // W/Kg (approximate) + const double calorific_value_fuel; // J/Kg (approximate) const double Cp_air; // J/KgK const double Cp_fuel; // J/KgK const double standard_pressure; //Pa @@ -268,6 +284,7 @@ private: double Displacement; // cubic inches double displacement_SI; // cubic meters double MaxHP; // horsepower + double StaticFriction_HP; // horsepower: amount subtracted from final engine power double SparkFailDrop; // drop of power due to spark failure double Cycles; // cycles/power stroke double IdleRPM; // revolutions per minute @@ -284,29 +301,29 @@ private: double Ram_Air_Factor; // number double StarterHP; // initial horsepower of starter motor - int BoostSpeeds; // Number of super/turbocharger boost speeds - zero implies no turbo/supercharging. - int BoostSpeed; // The current boost-speed (zero-based). - bool Boosted; // Set true for boosted engine. - int BoostManual; // The raw value read in from the config file - should be 1 or 0 - see description below. - bool bBoostManual; // Set true if pilot must manually control the boost speed. - int BoostOverride; // The raw value read in from the config file - should be 1 or 0 - see description below. - bool bBoostOverride; // Set true if pilot override of the boost regulator was fitted. + int BoostSpeeds; // Number of super/turbocharger boost speeds - zero implies no turbo/supercharging. + int BoostSpeed; // The current boost-speed (zero-based). + bool Boosted; // Set true for boosted engine. + int BoostManual; // The raw value read in from the config file - should be 1 or 0 - see description below. + bool bBoostManual; // Set true if pilot must manually control the boost speed. + int BoostOverride; // The raw value read in from the config file - should be 1 or 0 - see description below. + bool bBoostOverride; // Set true if pilot override of the boost regulator was fitted. // (Typically called 'war emergency power'). - bool bTakeoffBoost; // Set true if extra takeoff / emergency boost above rated boost could be attained. + bool bTakeoffBoost; // Set true if extra takeoff / emergency boost above rated boost could be attained. // (Typically by extra throttle movement past a mechanical 'gate'). - double TakeoffBoost; // Sea-level takeoff boost in psi. (if fitted). - double RatedBoost[FG_MAX_BOOST_SPEEDS]; // Sea-level rated boost in psi. - double RatedAltitude[FG_MAX_BOOST_SPEEDS]; // Altitude at which full boost is reached (boost regulation ends) + double TakeoffBoost; // Sea-level takeoff boost in psi. (if fitted). + double RatedBoost[FG_MAX_BOOST_SPEEDS]; // Sea-level rated boost in psi. + double RatedAltitude[FG_MAX_BOOST_SPEEDS]; // Altitude at which full boost is reached (boost regulation ends) // and at which power starts to fall with altitude [ft]. double RatedRPM[FG_MAX_BOOST_SPEEDS]; // Engine speed at which the rated power for each boost speed is delivered [rpm]. - double RatedPower[FG_MAX_BOOST_SPEEDS]; // Power at rated throttle position at rated altitude [HP]. - double BoostSwitchAltitude[FG_MAX_BOOST_SPEEDS - 1]; // Altitude at which switchover (currently assumed automatic) + double RatedPower[FG_MAX_BOOST_SPEEDS]; // Power at rated throttle position at rated altitude [HP]. + double BoostSwitchAltitude[FG_MAX_BOOST_SPEEDS - 1]; // Altitude at which switchover (currently assumed automatic) // from one boost speed to next occurs [ft]. double BoostSwitchPressure[FG_MAX_BOOST_SPEEDS - 1]; // Pressure at which boost speed switchover occurs [Pa] - double BoostMul[FG_MAX_BOOST_SPEEDS]; // Pressure multipier of unregulated supercharger - double RatedMAP[FG_MAX_BOOST_SPEEDS]; // Rated manifold absolute pressure [Pa] (BCV clamp) - double TakeoffMAP[FG_MAX_BOOST_SPEEDS]; // Takeoff setting manifold absolute pressure [Pa] (BCV clamp) - double BoostSwitchHysteresis; // Pa. + double BoostMul[FG_MAX_BOOST_SPEEDS]; // Pressure multipier of unregulated supercharger + double RatedMAP[FG_MAX_BOOST_SPEEDS]; // Rated manifold absolute pressure [Pa] (BCV clamp) + double TakeoffMAP[FG_MAX_BOOST_SPEEDS]; // Takeoff setting manifold absolute pressure [Pa] (BCV clamp) + double BoostSwitchHysteresis; // Pa. double minMAP; // Pa double maxMAP; // Pa diff --git a/src/FDM/JSBSim/models/propulsion/FGPropeller.cpp b/src/FDM/JSBSim/models/propulsion/FGPropeller.cpp index d5ed3813d..64ae65574 100644 --- a/src/FDM/JSBSim/models/propulsion/FGPropeller.cpp +++ b/src/FDM/JSBSim/models/propulsion/FGPropeller.cpp @@ -48,7 +48,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGPropeller.cpp,v 1.33 2011/03/10 01:35:25 dpculp Exp $"; +static const char *IdSrc = "$Id: FGPropeller.cpp,v 1.34 2011/06/16 14:54:06 jentron Exp $"; static const char *IdHdr = ID_PROPELLER; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -102,8 +102,7 @@ FGPropeller::FGPropeller(FGFDMExec* exec, Element* prop_element, int num) ConstantSpeed = (int)prop_element->FindElementValueAsNumber("constspeed"); if (prop_element->FindElement("reversepitch")) ReversePitch = prop_element->FindElementValueAsNumber("reversepitch"); - for (int i=0; i<2; i++) { - table_element = prop_element->FindNextElement("table"); + while(table_element = prop_element->FindNextElement("table")) { name = table_element->GetAttributeValue("name"); try { if (name == "C_THRUST") { @@ -121,6 +120,9 @@ FGPropeller::FGPropeller(FGFDMExec* exec, Element* prop_element, int num) throw("Error loading propeller table:" + name + ". " + str); } } + if( (cPower == 0) || (cThrust == 0)){ + cerr << "Propeller configuration must contain C_THRUST and C_POWER tables!" << endl; + } local_element = prop_element->GetParent()->FindElement("sense"); if (local_element) { @@ -132,7 +134,7 @@ FGPropeller::FGPropeller(FGFDMExec* exec, Element* prop_element, int num) P_Factor = local_element->GetDataAsNumber(); } if (P_Factor < 0) { - cerr << "P-Factor value in config file must be greater than zero" << endl; + cerr << "P-Factor value in propeller configuration file must be greater than zero" << endl; } if (prop_element->FindElement("ct_factor")) SetCtFactor( prop_element->FindElementValueAsNumber("ct_factor") ); @@ -424,10 +426,25 @@ void FGPropeller::Debug(int from) cout << " Maximum Pitch = " << MaxPitch << endl; cout << " Minimum RPM = " << MinRPM << endl; cout << " Maximum RPM = " << MaxRPM << endl; +// Tables are being printed elsewhere... // cout << " Thrust Coefficient: " << endl; // cThrust->Print(); // cout << " Power Coefficient: " << endl; // cPower->Print(); +// cout << " Mach Thrust Coefficient: " << endl; +// if(CtMach) +// { +// CtMach->Print(); +// } else { +// cout << " NONE" << endl; +// } +// cout << " Mach Power Coefficient: " << endl; +// if(CpMach) +// { +// CpMach->Print(); +// } else { +// cout << " NONE" << endl; +// } } } if (debug_lvl & 2 ) { // Instantiation/Destruction notification diff --git a/src/FDM/JSBSim/models/propulsion/FGPropeller.h b/src/FDM/JSBSim/models/propulsion/FGPropeller.h index 3e9c3c259..94fb454ec 100644 --- a/src/FDM/JSBSim/models/propulsion/FGPropeller.h +++ b/src/FDM/JSBSim/models/propulsion/FGPropeller.h @@ -45,7 +45,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_PROPELLER "$Id: FGPropeller.h,v 1.17 2011/03/10 01:35:25 dpculp Exp $" +#define ID_PROPELLER "$Id: FGPropeller.h,v 1.18 2011/06/06 22:39:52 jentron Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -62,6 +62,7 @@ CLASS DOCUMENTATION <h3>Configuration File Format:</h3> @code +<sense> {1 | -1} </sense> <propeller name="{string}"> <ixx> {number} </ixx> <diameter unit="IN"> {number} </diameter> @@ -73,7 +74,6 @@ CLASS DOCUMENTATION <maxrpm> {number} </maxrpm> <constspeed> {number} </constspeed> <reversepitch> {number} </reversepitch> - <sense> {1 | -1} </sense> <p_factor> {number} </p_factor> <ct_factor> {number} </ct_factor> <cp_factor> {number} </cp_factor> @@ -119,7 +119,8 @@ CLASS DOCUMENTATION \<constspeed> - 1 = constant speed mode, 0 = manual pitch mode. \<reversepitch> - Blade pitch angle for reverse. \<sense> - Direction of rotation (1=clockwise as viewed from cockpit, - -1=anti-clockwise as viewed from cockpit). + -1=anti-clockwise as viewed from cockpit). Sense is + specified in the parent tag of the propeller. \<p_factor> - P factor. \<ct_factor> - A multiplier for the coefficients of thrust. \<cp_factor> - A multiplier for the coefficients of power. @@ -141,7 +142,7 @@ CLASS DOCUMENTATION <li>Various NACA Technical Notes and Reports</li> </ul> @author Jon S. Berndt - @version $Id: FGPropeller.h,v 1.17 2011/03/10 01:35:25 dpculp Exp $ + @version $Id: FGPropeller.h,v 1.18 2011/06/06 22:39:52 jentron Exp $ @see FGEngine @see FGThruster */ diff --git a/src/FDM/JSBSim/models/propulsion/FGTank.cpp b/src/FDM/JSBSim/models/propulsion/FGTank.cpp index c9d38dab8..dbb5b37d1 100644 --- a/src/FDM/JSBSim/models/propulsion/FGTank.cpp +++ b/src/FDM/JSBSim/models/propulsion/FGTank.cpp @@ -48,7 +48,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGTank.cpp,v 1.28 2010/01/24 19:26:04 jberndt Exp $"; +static const char *IdSrc = "$Id: FGTank.cpp,v 1.29 2011/06/06 22:39:52 jentron Exp $"; static const char *IdHdr = ID_TANK; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -66,6 +66,7 @@ FGTank::FGTank(FGFDMExec* exec, Element* el, int tank_number) InitialTemperature = Temperature = -9999.0; Ixx = Iyy = Izz = 0.0; Radius = Contents = Standpipe = Length = InnerRadius = 0.0; + ExternalFlow = 0.0; InitialStandpipe = 0.0; Capacity = 0.00001; Priority = InitialPriority = 1; @@ -162,6 +163,9 @@ FGTank::FGTank(FGFDMExec* exec, Element* el, int tank_number) property_name = base_property_name + "/priority"; PropertyManager->Tie( property_name.c_str(), (FGTank*)this, &FGTank::GetPriority, &FGTank::SetPriority ); + property_name = base_property_name + "/external-flow-rate-pps"; + PropertyManager->Tie( property_name.c_str(), (FGTank*)this, &FGTank::GetExternalFlow, + &FGTank::SetExternalFlow ); if (Temperature != -9999.0) InitialTemperature = Temperature = FahrenheitToCelsius(Temperature); Area = 40.0 * pow(Capacity/1975, 0.666666667); @@ -269,6 +273,9 @@ void FGTank::SetContentsGallons(double gallons) double FGTank::Calculate(double dt) { + if(ExternalFlow < 0.) Drain( -ExternalFlow *dt); + else Fill(ExternalFlow * dt); + if (Temperature == -9999.0) return 0.0; double HeatCapacity = 900.0; // Joules/lbm/C double TempFlowFactor = 1.115; // Watts/sqft/C @@ -278,6 +285,7 @@ double FGTank::Calculate(double dt) if (fabs(Tdiff) > 0.1) { dTemp = (TempFlowFactor * Area * Tdiff * dt) / (Contents * HeatCapacity); } + return Temperature += (dTemp + dTemp); // For now, assume upper/lower the same } diff --git a/src/FDM/JSBSim/models/propulsion/FGTank.h b/src/FDM/JSBSim/models/propulsion/FGTank.h index 12e7e5fc9..4bf420a38 100644 --- a/src/FDM/JSBSim/models/propulsion/FGTank.h +++ b/src/FDM/JSBSim/models/propulsion/FGTank.h @@ -52,7 +52,7 @@ INCLUDES DEFINITIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#define ID_TANK "$Id: FGTank.h,v 1.21 2010/02/05 05:53:00 jberndt Exp $" +#define ID_TANK "$Id: FGTank.h,v 1.23 2011/06/13 15:23:09 jentron Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -100,7 +100,16 @@ CLASS DOCUMENTATION tree at <tt>propulsion/tank[i]/contents-lbs</tt>, where i is the tank number (Tanks are automatically numbered, starting at zero, in the order in which they are read in the aircraft configuration file). The latter method allows one to use a system of FCS - components to control tank contents. + components to control tank contents. + + There is also a property <tt>propulsion/tank[i]/external-flow-rate-pps</tt>. Setting + this property to a positive value causes the tank to fill at the rate specified. + Setting a negative number causes the tank to drain. The value is the rate in pounds + of fuel per second. The tank will not fill past 100% full and will not drain below 0%. + Fuel may be transfered between two tanks by setting the source tank's external flow rate + to a negative value and the destination's external flow rate to the same positive value. + Care must be taken to stop fuel flow before the source tank becomes empty to prevent + phantom fuel being created. <h3>Configuration File Format:</h3> @@ -275,6 +284,9 @@ public: double GetDensity(void) const {return Density;} void SetDensity(double d) { Density = d; } + double GetExternalFlow(void) const {return ExternalFlow;} + void SetExternalFlow(double f) { ExternalFlow = f; } + const FGColumnVector3 GetXYZ(void); const double GetXYZ(int idx); @@ -309,6 +321,7 @@ private: double Area; double Temperature, InitialTemperature; double Standpipe, InitialStandpipe; + double ExternalFlow; bool Selected; int Priority, InitialPriority; FGFDMExec* Exec; diff --git a/src/FDM/JSBSim/models/propulsion/FGTurbine.cpp b/src/FDM/JSBSim/models/propulsion/FGTurbine.cpp index d7277ba87..c4cfc3033 100644 --- a/src/FDM/JSBSim/models/propulsion/FGTurbine.cpp +++ b/src/FDM/JSBSim/models/propulsion/FGTurbine.cpp @@ -51,7 +51,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGTurbine.cpp,v 1.31 2011/03/03 12:16:26 jberndt Exp $"; +static const char *IdSrc = "$Id: FGTurbine.cpp,v 1.32 2011/06/07 00:28:03 jentron Exp $"; static const char *IdHdr = ID_TURBINE; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -360,7 +360,7 @@ double FGTurbine::Seize(void) double FGTurbine::Trim() { - double idlethrust, milthrust, thrust, tdiff; + double idlethrust, milthrust, thrust, tdiff, N2, N2norm; idlethrust = MilThrust * IdleThrustLookup->GetValue(); milthrust = (MilThrust - idlethrust) * MilThrustLookup->GetValue(); N2 = IdleN2 + ThrottlePos * N2_factor; diff --git a/src/FDM/JSBSim/models/propulsion/FGTurbine.h b/src/FDM/JSBSim/models/propulsion/FGTurbine.h index 62c6d321a..907d08dd2 100644 --- a/src/FDM/JSBSim/models/propulsion/FGTurbine.h +++ b/src/FDM/JSBSim/models/propulsion/FGTurbine.h @@ -42,7 +42,7 @@ INCLUDES #include "FGEngine.h" -#define ID_TURBINE "$Id: FGTurbine.h,v 1.19 2010/08/21 18:08:46 jberndt Exp $" +#define ID_TURBINE "$Id: FGTurbine.h,v 1.20 2011/06/07 00:28:03 jentron Exp $" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FORWARD DECLARATIONS @@ -93,6 +93,8 @@ CLASS DOCUMENTATION <atsfc> {number} </atsfc> <idlen1> {number} </idlen1> <idlen2> {number} </idlen2> + <n1spinup> {number} </n1spinup> + <n2spinup> {number} </n2spinup> <maxn1> {number} </maxn1> <maxn2> {number} </maxn2> <augmented> {0 | 1} </augmented> @@ -113,6 +115,8 @@ CLASS DOCUMENTATION atsfc - Afterburning TSFC, lbm/hr/lbf idlen1 - Fan rotor rpm (% of max) at idle idlen2 - Core rotor rpm (% of max) at idle + n1spinup - Fan rotor rpm starter acceleration (default 1.0) + n2spinup - Core rotor rpm starter acceleration (default 3.0) maxn1 - Fan rotor rpm (% of max) at full throttle maxn2 - Core rotor rpm (% of max) at full throttle augmented @@ -146,7 +150,7 @@ CLASS DOCUMENTATION /engine/direct.xml </pre> @author David P. Culp - @version "$Id: FGTurbine.h,v 1.19 2010/08/21 18:08:46 jberndt Exp $" + @version "$Id: FGTurbine.h,v 1.20 2011/06/07 00:28:03 jentron Exp $" */ /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% From 1dbc2c0f7a0c23de18e4b174e2483e6e91e8f55d Mon Sep 17 00:00:00 2001 From: Erik Hofman <erik@ehofman.com> Date: Fri, 17 Jun 2011 14:16:49 +0200 Subject: [PATCH 31/48] Fixed switch parsing and message --- src/FDM/JSBSim/models/flight_control/FGSwitch.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/FDM/JSBSim/models/flight_control/FGSwitch.cpp b/src/FDM/JSBSim/models/flight_control/FGSwitch.cpp index 9d56e512e..45b0a9921 100644 --- a/src/FDM/JSBSim/models/flight_control/FGSwitch.cpp +++ b/src/FDM/JSBSim/models/flight_control/FGSwitch.cpp @@ -69,7 +69,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGSwitch.cpp,v 1.21 2011/06/16 03:39:38 jberndt Exp $"; +static const char *IdSrc = "$Id: FGSwitch.cpp,v 1.22 2011/06/17 12:12:19 jberndt Exp $"; static const char *IdHdr = ID_SWITCH; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -119,8 +119,11 @@ FGSwitch::FGSwitch(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, element) tests.push_back(current_test); } - if (test_element->GetName() != "output" - && test_element->GetName() != "description") { // this is not an output element + string el_name = test_element->GetName(); + if ( el_name != "output" + && el_name != "description" + && el_name != "delay" ) + { value = test_element->GetAttributeValue("value"); if (value.empty()) { cerr << "No VALUE supplied for switch component: " << Name << endl; From 02eb2ac2e161a4831c33fa41db9b78679ca1adf7 Mon Sep 17 00:00:00 2001 From: Erik Hofman <erik@ehofman.com> Date: Sat, 18 Jun 2011 17:50:47 +0200 Subject: [PATCH 32/48] Improved the calcs during trimming after a suggestion from Dennis --- .../models/flight_control/FGActuator.cpp | 33 ++++++++----------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/src/FDM/JSBSim/models/flight_control/FGActuator.cpp b/src/FDM/JSBSim/models/flight_control/FGActuator.cpp index e7ab6aa65..52faac0fb 100644 --- a/src/FDM/JSBSim/models/flight_control/FGActuator.cpp +++ b/src/FDM/JSBSim/models/flight_control/FGActuator.cpp @@ -43,7 +43,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGActuator.cpp,v 1.18 2011/05/13 17:14:47 bcoconni Exp $"; +static const char *IdSrc = "$Id: FGActuator.cpp,v 1.19 2011/06/18 13:30:27 bcoconni Exp $"; static const char *IdHdr = ID_ACTUATOR; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -114,24 +114,15 @@ bool FGActuator::Run(void ) // the Input will be further processed and the eventual Output // will be overwritten from this perfect value. - if (!fcs->GetTrimStatus()) { - if (lag != 0.0) Lag(); // models actuator lag - if (rate_limit != 0) RateLimit(); // limit the actuator rate - } + if (lag != 0.0) Lag(); // models actuator lag + if (rate_limit != 0) RateLimit(); // limit the actuator rate if (deadband_width != 0.0) Deadband(); - if (!fcs->GetTrimStatus() && hysteresis_width != 0.0) Hysteresis(); + if (hysteresis_width != 0.0) Hysteresis(); if (bias != 0.0) Bias(); // models a finite bias if (fail_stuck) Output = PreviousOutput; PreviousOutput = Output; // previous value needed for "stuck" malfunction - if (fcs->GetTrimStatus()) { - PreviousHystOutput = Output; - PreviousRateLimOutput = Output; - PreviousLagInput = Output; - PreviousLagOutput = Output; - } - Clip(); if (IsOutput) SetOutput(); @@ -152,7 +143,10 @@ void FGActuator::Lag(void) // "Output" on the right side of the "=" is the current frame input // for this Lag filter double input = Output; - Output = ca * (input + PreviousLagInput) + PreviousLagOutput * cb; + + if (!fcs->GetTrimStatus()) + Output = ca * (input + PreviousLagInput) + PreviousLagOutput * cb; + PreviousLagInput = input; PreviousLagOutput = Output; } @@ -166,10 +160,11 @@ void FGActuator::Hysteresis(void) // method. double input = Output; - if (input > PreviousHystOutput) { - Output = max(PreviousHystOutput, input-0.5*hysteresis_width); - } else if (input < PreviousHystOutput) { - Output = min(PreviousHystOutput, input+0.5*hysteresis_width); + if (!fcs->GetTrimStatus()) { + if (input > PreviousHystOutput) + Output = max(PreviousHystOutput, input-0.5*hysteresis_width); + else if (input < PreviousHystOutput) + Output = min(PreviousHystOutput, input+0.5*hysteresis_width); } PreviousHystOutput = Output; @@ -183,7 +178,7 @@ void FGActuator::RateLimit(void) // is - for the purposes of this RateLimit method - really the input to the // method. double input = Output; - if (dt > 0.0) { + if (!fcs->GetTrimStatus()) { double rate = (input - PreviousRateLimOutput)/dt; if (fabs(rate) > rate_limit) { Output = PreviousRateLimOutput + (rate_limit*fabs(rate)/rate)*dt; From 033a09d7bc1f9c5edf24348ec1b1e6c0a44c1048 Mon Sep 17 00:00:00 2001 From: Frederic Bouvier <fredfgfs01@free.fr> Date: Sat, 18 Jun 2011 21:23:54 +0200 Subject: [PATCH 33/48] Bundle DDS plugin too --- package/Win-NSIS/flightgear-nightly.nsi | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package/Win-NSIS/flightgear-nightly.nsi b/package/Win-NSIS/flightgear-nightly.nsi index 78e421f11..e04e0a847 100644 --- a/package/Win-NSIS/flightgear-nightly.nsi +++ b/package/Win-NSIS/flightgear-nightly.nsi @@ -99,6 +99,7 @@ Section "" ;No components page, name is not important File ${OSGPluginsDir}\osgdb_jpeg.dll File ${OSGPluginsDir}\osgdb_rgb.dll File ${OSGPluginsDir}\osgdb_png.dll + File ${OSGPluginsDir}\osgdb_dds.dll File ${OSGPluginsDir}\osgdb_txf.dll @@ -136,4 +137,4 @@ Section "Uninstall" DeleteRegKey HKLM ${UninstallKey} SectionEnd - \ No newline at end of file + From 4d148f0b7a9ba9e769a519a6ca41cd625fae995c Mon Sep 17 00:00:00 2001 From: Frederic Bouvier <fredfgfs01@free.fr> Date: Sat, 18 Jun 2011 23:34:57 +0200 Subject: [PATCH 34/48] Update 3rdparty files for win32/x64 --- docs-mini/README.MSVC | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs-mini/README.MSVC b/docs-mini/README.MSVC index 1dcd0f759..68186886d 100644 --- a/docs-mini/README.MSVC +++ b/docs-mini/README.MSVC @@ -1,11 +1,11 @@ Use FlightGear.sln to compile fgfs executable for Win32 or x64 architectures with Visual Studio 2008. Previous versions of Visual Studio are not officially supported anymore. -Precompiled librairies and headers for compiling x64 executables with VS2008 : -ftp://ftp.ihg.uni-duisburg.de/FlightGear/Win32/MSVC/fgfs-x64-VS90-3rdParty+OSG-20110117.zip - Precompiled librairies and headers for compiling Win32 executables with VS2008 : -ftp://ftp.ihg.uni-duisburg.de/FlightGear/Win32/MSVC/fgfs-win32-VS90-3rdParty+OSG-20110117.zip +ftp://ftp.ihg.uni-duisburg.de/FlightGear/Win32/MSVC/fgfs-win32-VS90-3rdParty+OSG-20110618.zip + +Precompiled librairies and headers for compiling x64 executables with VS2008 : +ftp://ftp.ihg.uni-duisburg.de/FlightGear/Win32/MSVC/fgfs-x64-VS90-3rdParty+OSG-20110618.zip The VS2008 / v9.0 project files assume the directory layout below : From fac1525fde5f30d10c5431c5b02f85abd7589e63 Mon Sep 17 00:00:00 2001 From: Erik Hofman <erik@ehofman.com> Date: Sun, 19 Jun 2011 10:34:21 +0200 Subject: [PATCH 35/48] Removed useless divisions - As a side effect, it removes the risk of divisions by zero --- src/FDM/JSBSim/models/flight_control/FGActuator.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/FDM/JSBSim/models/flight_control/FGActuator.cpp b/src/FDM/JSBSim/models/flight_control/FGActuator.cpp index 52faac0fb..6673f0452 100644 --- a/src/FDM/JSBSim/models/flight_control/FGActuator.cpp +++ b/src/FDM/JSBSim/models/flight_control/FGActuator.cpp @@ -43,7 +43,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGActuator.cpp,v 1.19 2011/06/18 13:30:27 bcoconni Exp $"; +static const char *IdSrc = "$Id: FGActuator.cpp,v 1.20 2011/06/18 17:46:21 bcoconni Exp $"; static const char *IdHdr = ID_ACTUATOR; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -73,7 +73,7 @@ FGActuator::FGActuator(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, eleme hysteresis_width = element->FindElementValueAsNumber("hysteresis_width"); } if ( element->FindElement("rate_limit") ) { - rate_limit = element->FindElementValueAsNumber("rate_limit"); + rate_limit = fabs(element->FindElementValueAsNumber("rate_limit")); } if ( element->FindElement("bias") ) { bias = element->FindElementValueAsNumber("bias"); @@ -179,9 +179,10 @@ void FGActuator::RateLimit(void) // method. double input = Output; if (!fcs->GetTrimStatus()) { - double rate = (input - PreviousRateLimOutput)/dt; - if (fabs(rate) > rate_limit) { - Output = PreviousRateLimOutput + (rate_limit*fabs(rate)/rate)*dt; + double delta = input - PreviousRateLimOutput; + if (fabs(delta) > dt * rate_limit) { + double signed_rate_limit = delta > 0.0 ? rate_limit : -rate_limit; + Output = PreviousRateLimOutput + signed_rate_limit * dt; } } PreviousRateLimOutput = Output; From cd20c6073c8f4341d0f82070abae14b765cc8630 Mon Sep 17 00:00:00 2001 From: ThorstenB <brehmt@gmail.com> Date: Mon, 20 Jun 2011 22:50:07 +0200 Subject: [PATCH 36/48] #346 related: missing status message for property server Provide same start-up status message as for other protocols. --- src/Network/props.cxx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Network/props.cxx b/src/Network/props.cxx index 5b9eb7a1a..10befcab8 100644 --- a/src/Network/props.cxx +++ b/src/Network/props.cxx @@ -449,6 +449,7 @@ FGProps::FGProps( const vector<string>& tokens ) } else { throw FGProtocolConfigError( "FGProps: incorrect number of configuration arguments" ); } + printf( "Property server started on port %d\n", port ); } /** From c0d0b451a6a65fa01e9879f263c110b5ddc8d1a3 Mon Sep 17 00:00:00 2001 From: Frederic Bouvier <fredfgfs01@free.fr> Date: Mon, 20 Jun 2011 23:31:22 +0200 Subject: [PATCH 37/48] Bundle more OSG plugins in nightly builds[D --- package/Win-NSIS/flightgear-nightly.nsi | 3 +++ 1 file changed, 3 insertions(+) diff --git a/package/Win-NSIS/flightgear-nightly.nsi b/package/Win-NSIS/flightgear-nightly.nsi index e04e0a847..9e2d27b93 100644 --- a/package/Win-NSIS/flightgear-nightly.nsi +++ b/package/Win-NSIS/flightgear-nightly.nsi @@ -94,6 +94,7 @@ Section "" ;No components page, name is not important SetOutPath $INSTDIR\osgPlugins-${OSGVersion} File ${OSGPluginsDir}\osgdb_ac.dll File ${OSGPluginsDir}\osgdb_osg.dll + File ${OSGPluginsDir}\osgdb_osga.dll File ${OSGPluginsDir}\osgdb_3ds.dll File ${OSGPluginsDir}\osgdb_mdl.dll File ${OSGPluginsDir}\osgdb_jpeg.dll @@ -101,6 +102,8 @@ Section "" ;No components page, name is not important File ${OSGPluginsDir}\osgdb_png.dll File ${OSGPluginsDir}\osgdb_dds.dll File ${OSGPluginsDir}\osgdb_txf.dll + File ${OSGPluginsDir}\osgdb_deprecated_osg.dll + File ${OSGPluginsDir}\osgdb_deprecated_osgparticle.dll Exec '"$INSTDIR\fgrun.exe" --silent --fg-exe="$INSTDIR\fgfs.exe" --ts-exe="$INSTDIR\terrasync.exe" ' From e19c49a273f04769909dba23807ab19641fe9a46 Mon Sep 17 00:00:00 2001 From: ThorstenB <brehmt@gmail.com> Date: Wed, 22 Jun 2011 20:01:31 +0200 Subject: [PATCH 38/48] Enable parameter for new command-line option. --- src/Main/options.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Main/options.cxx b/src/Main/options.cxx index 342412e53..453e68e48 100644 --- a/src/Main/options.cxx +++ b/src/Main/options.cxx @@ -1392,7 +1392,7 @@ struct OptionDesc { {"enable-wireframe", false, OPTION_BOOL, "/sim/rendering/wireframe", true, "", 0 }, {"disable-terrasync", false, OPTION_BOOL, "/sim/terrasync/enabled", false, "", 0 }, {"enable-terrasync", false, OPTION_BOOL, "/sim/terrasync/enabled", true, "", 0 }, - {"terrasync-dir", false, OPTION_STRING, "/sim/terrasync/scenery-dir", false, "", 0 }, + {"terrasync-dir", true, OPTION_STRING, "/sim/terrasync/scenery-dir", false, "", 0 }, {"geometry", true, OPTION_FUNC, "", false, "", fgOptGeometry }, {"bpp", true, OPTION_FUNC, "", false, "", fgOptBpp }, {"units-feet", false, OPTION_STRING, "/sim/startup/units", false, "feet", 0 }, From 827ea96d7e82b6fd5f5fecbd6fda403c20606503 Mon Sep 17 00:00:00 2001 From: Mathias Froehlich <Mathias.Froehlich@web.de> Date: Wed, 22 Jun 2011 22:15:04 +0200 Subject: [PATCH 39/48] Make fgviewer at least somehow work again. --- utils/fgviewer/fgviewer.cxx | 43 +++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/utils/fgviewer/fgviewer.cxx b/utils/fgviewer/fgviewer.cxx index c7a659994..c65d8ebd6 100644 --- a/utils/fgviewer/fgviewer.cxx +++ b/utils/fgviewer/fgviewer.cxx @@ -2,9 +2,11 @@ #include <cstdlib> #include <osg/ArgumentParser> +#include <osg/Fog> #include <osgDB/ReadFile> #include <osgViewer/Viewer> #include <osgViewer/ViewerEventHandlers> +#include <osgViewer/Renderer> #include <osgGA/KeySwitchMatrixManipulator> #include <osgGA/TrackballManipulator> #include <osgGA/FlightManipulator> @@ -14,6 +16,7 @@ #include <simgear/props/props.hxx> #include <simgear/props/props_io.hxx> #include <simgear/misc/sg_path.hxx> +#include <simgear/scene/material/EffectCullVisitor.hxx> #include <simgear/scene/material/matlib.hxx> #include <simgear/scene/tgdb/SGReaderWriterBTGOptions.hxx> #include <simgear/scene/tgdb/userdata.hxx> @@ -26,8 +29,7 @@ public: virtual osg::Node *loadTileModel(const string& modelPath, bool) { try { - SGSharedPtr<SGPropertyNode> prop = new SGPropertyNode; - return simgear::SGModelLib::loadModel(modelPath, prop); + return simgear::SGModelLib::loadModel(modelPath, simgear::getPropertyRoot()); } catch (...) { std::cerr << "Error loading \"" << modelPath << "\"" << std::endl; return 0; @@ -42,7 +44,6 @@ main(int argc, char** argv) // pulled in by the linker ... // FIXME: make that more explicit clear and call an initialization function simgear::ModelRegistry::instance(); - sgUserDataInit(0); DummyLoadHelper dummyLoadHelper; simgear::TileEntry::setModelLoadHelper(&dummyLoadHelper); @@ -51,13 +52,11 @@ main(int argc, char** argv) // construct the viewer. osgViewer::Viewer viewer(arguments); - // ... for some reason, get rid of that FIXME! - viewer.setThreadingModel(osgViewer::Viewer::SingleThreaded); - + // set up the camera manipulators. osgGA::KeySwitchMatrixManipulator* keyswitchManipulator; keyswitchManipulator = new osgGA::KeySwitchMatrixManipulator; - + keyswitchManipulator->addMatrixManipulator('1', "Trackball", new osgGA::TrackballManipulator); keyswitchManipulator->addMatrixManipulator('2', "Flight", @@ -66,16 +65,30 @@ main(int argc, char** argv) new osgGA::DriveManipulator); keyswitchManipulator->addMatrixManipulator('4', "Terrain", new osgGA::TerrainManipulator); - + viewer.setCameraManipulator(keyswitchManipulator); // Usefull stats viewer.addEventHandler(new osgViewer::HelpHandler); viewer.addEventHandler(new osgViewer::StatsHandler); - // Same FIXME ... - // viewer.addEventHandler(new osgViewer::ThreadingHandler); + viewer.addEventHandler(new osgViewer::ThreadingHandler); viewer.addEventHandler(new osgViewer::LODScaleHandler); viewer.addEventHandler(new osgViewer::ScreenCaptureHandler); + viewer.addEventHandler(new osgViewer::WindowSizeHandler); + + // Sigh, we need our own cull visitor ... + osg::Camera* camera = viewer.getCamera(); + osgViewer::Renderer* renderer = static_cast<osgViewer::Renderer*>(camera->getRenderer()); + for (int j = 0; j < 2; ++j) { + osgUtil::SceneView* sceneView = renderer->getSceneView(j); + sceneView->setCullVisitor(new simgear::EffectCullVisitor); + } + // Shaders expect valid fog + osg::Fog* fog = new osg::Fog; + fog->setMode(osg::Fog::EXP2); + fog->setColor(osg::Vec4(1, 1, 1, 1)); + fog->setDensity(1e-6); + camera->getOrCreateStateSet()->setAttribute(fog); const char *fg_root_env = std::getenv("FG_ROOT"); std::string fg_root; @@ -110,6 +123,7 @@ main(int argc, char** argv) } SGSharedPtr<SGPropertyNode> props = new SGPropertyNode; + sgUserDataInit(props.get()); try { SGPath preferencesFile = fg_root; preferencesFile.append("preferences.xml"); @@ -130,14 +144,15 @@ main(int argc, char** argv) std::cerr << "Problems loading FlightGear materials.\n" << "Probably FG_ROOT is not properly set." << std::endl; } + simgear::SGModelLib::init(fg_root, props); // The file path list must be set in the registry. osgDB::Registry::instance()->getDataFilePathList() = filePathList; - + SGReaderWriterBTGOptions* btgOptions = new SGReaderWriterBTGOptions; btgOptions->getDatabasePathList() = filePathList; btgOptions->setMatlib(ml); - + // read the scene from the list of file specified command line args. osg::ref_ptr<osg::Node> loadedModel; loadedModel = osgDB::readNodeFiles(arguments, btgOptions); @@ -148,9 +163,9 @@ main(int argc, char** argv) << ": No data loaded" << std::endl; return EXIT_FAILURE; } - + // pass the loaded scene graph to the viewer. viewer.setSceneData(loadedModel.get()); - + return viewer.run(); } From 243acb61c8cae76c269c5d83d8d05de17ad1153a Mon Sep 17 00:00:00 2001 From: Frederic Bouvier <fredfgfs01@free.fr> Date: Sat, 25 Jun 2011 09:22:51 +0200 Subject: [PATCH 40/48] Fix issue #354: updateCameras reset viewport size to its initial value on OSG 3.0 --- src/Main/CameraGroup.cxx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Main/CameraGroup.cxx b/src/Main/CameraGroup.cxx index e80e0c564..a185d70dd 100644 --- a/src/Main/CameraGroup.cxx +++ b/src/Main/CameraGroup.cxx @@ -191,8 +191,10 @@ void CameraGroup::update(const osg::Vec3d& position, for (CameraList::iterator i = _cameras.begin(); i != _cameras.end(); ++i) { const CameraInfo* info = i->get(); const View::Slave& slave = _viewer->getSlave(info->slaveIndex); +#if SG_OSG_VERSION_LESS_THAN(3,0,0) // refreshes camera viewports (for now) updateCameras(info); +#endif Camera* camera = info->camera.get(); Matrix viewMatrix; if ((info->flags & VIEW_ABSOLUTE) != 0) From 523f7f4cb72823be2048f381e867b29b50664b67 Mon Sep 17 00:00:00 2001 From: Frederic Bouvier <fredfgfs01@free.fr> Date: Sat, 25 Jun 2011 10:05:38 +0200 Subject: [PATCH 41/48] Trying to fix compilation failure on Linux and Mac --- src/Main/CameraGroup.cxx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Main/CameraGroup.cxx b/src/Main/CameraGroup.cxx index a185d70dd..cb3f07d78 100644 --- a/src/Main/CameraGroup.cxx +++ b/src/Main/CameraGroup.cxx @@ -27,6 +27,7 @@ #include "WindowSystemAdapter.hxx" #include <simgear/props/props.hxx> #include <simgear/structure/OSGUtils.hxx> +#include <simgear/structure/OSGVersion.hxx> #include <simgear/scene/material/EffectCullVisitor.hxx> #include <simgear/scene/util/RenderConstants.hxx> From 029d2b00eb0dd267729bf49f2b5ca6bd80edefe9 Mon Sep 17 00:00:00 2001 From: James Turner <zakalawe@mac.com> Date: Sat, 25 Jun 2011 16:18:07 +0100 Subject: [PATCH 42/48] Tone down some log output for the release, especially related to airways/navaid loading. --- src/Airports/simple.cxx | 2 +- src/MultiPlayer/multiplaymgr.cxx | 2 +- src/Navaids/airways.cxx | 4 ++-- src/Navaids/navdb.cxx | 4 ++-- src/Navaids/navrecord.cxx | 2 +- src/Traffic/SchedFlight.cxx | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Airports/simple.cxx b/src/Airports/simple.cxx index 9df1cb254..7354db28b 100644 --- a/src/Airports/simple.cxx +++ b/src/Airports/simple.cxx @@ -442,7 +442,7 @@ void FGAirport::processThreshold(SGPropertyNode* aThreshold) // first, let's identify the current runway string id(aThreshold->getStringValue("rwy")); if (!hasRunwayWithIdent(id)) { - SG_LOG(SG_GENERAL, SG_WARN, "FGAirport::processThreshold: " + SG_LOG(SG_GENERAL, SG_DEBUG, "FGAirport::processThreshold: " "found runway not defined in the global data:" << ident() << "/" << id); return; } diff --git a/src/MultiPlayer/multiplaymgr.cxx b/src/MultiPlayer/multiplaymgr.cxx index a8f862388..40a9c438a 100644 --- a/src/MultiPlayer/multiplaymgr.cxx +++ b/src/MultiPlayer/multiplaymgr.cxx @@ -1205,7 +1205,7 @@ FGMultiplayMgr::ProcessPosMsg(const FGMultiplayMgr::MsgBuf& Msg, else { // We failed to find the property. We'll try the next packet immediately. - SG_LOG(SG_NETWORK, SG_INFO, "FGMultiplayMgr::ProcessPosMsg - " + SG_LOG(SG_NETWORK, SG_DEBUG, "FGMultiplayMgr::ProcessPosMsg - " "message from " << MsgHdr->Callsign << " has unknown property id " << id); } diff --git a/src/Navaids/airways.cxx b/src/Navaids/airways.cxx index 5bdbb2bee..8313f75b4 100644 --- a/src/Navaids/airways.cxx +++ b/src/Navaids/airways.cxx @@ -197,13 +197,13 @@ void Airway::Network::addEdge(Airway* aWay, const SGGeod& aStartPos, FGPositionedRef end = FGPositioned::findClosestWithIdent(aEndIdent, aEndPos); if (!start) { - SG_LOG(SG_GENERAL, SG_INFO, "unknown airways start pt: '" << aStartIdent << "'"); + SG_LOG(SG_GENERAL, SG_DEBUG, "unknown airways start pt: '" << aStartIdent << "'"); start = FGPositioned::createUserWaypoint(aStartIdent, aStartPos); return; } if (!end) { - SG_LOG(SG_GENERAL, SG_INFO, "unknown airways end pt: '" << aEndIdent << "'"); + SG_LOG(SG_GENERAL, SG_DEBUG, "unknown airways end pt: '" << aEndIdent << "'"); end = FGPositioned::createUserWaypoint(aEndIdent, aEndPos); return; } diff --git a/src/Navaids/navdb.cxx b/src/Navaids/navdb.cxx index 96d38c153..b1a813d61 100644 --- a/src/Navaids/navdb.cxx +++ b/src/Navaids/navdb.cxx @@ -297,12 +297,12 @@ FGRunway* getRunwayFromName(const std::string& aName) const FGAirport* apt = fgFindAirportID(parts[0]); if (!apt) { - SG_LOG(SG_GENERAL, SG_WARN, "navaid " << aName << " associated with bogus airport ID:" << parts[0]); + SG_LOG(SG_GENERAL, SG_DEBUG, "navaid " << aName << " associated with bogus airport ID:" << parts[0]); return NULL; } if (!apt->hasRunwayWithIdent(parts[1])) { - SG_LOG(SG_GENERAL, SG_WARN, "navaid " << aName << " associated with bogus runway ID:" << parts[1]); + SG_LOG(SG_GENERAL, SG_DEBUG, "navaid " << aName << " associated with bogus runway ID:" << parts[1]); return NULL; } diff --git a/src/Navaids/navrecord.cxx b/src/Navaids/navrecord.cxx index 5edc64ef1..8c01c6a10 100644 --- a/src/Navaids/navrecord.cxx +++ b/src/Navaids/navrecord.cxx @@ -61,7 +61,7 @@ FGNavRecord::FGNavRecord(Type aTy, const std::string& aIdent, // assign our own defaults, unless the range is not set for some // reason. if (range < 0.1) { - SG_LOG(SG_GENERAL, SG_WARN, "navaid " << ident() << " has no range set, using defaults"); + SG_LOG(SG_GENERAL, SG_DEBUG, "navaid " << ident() << " has no range set, using defaults"); switch (type()) { case NDB: case VOR: diff --git a/src/Traffic/SchedFlight.cxx b/src/Traffic/SchedFlight.cxx index 5575f6ee0..8b5b6ee68 100644 --- a/src/Traffic/SchedFlight.cxx +++ b/src/Traffic/SchedFlight.cxx @@ -269,13 +269,13 @@ bool FGScheduledFlight::initializeAirports() departurePort = FGAirport::findByIdent(depId); if(departurePort == NULL) { - SG_LOG( SG_GENERAL, SG_WARN, "Traffic manager could not find departure airport : " << depId); + SG_LOG( SG_GENERAL, SG_DEBUG, "Traffic manager could not find departure airport : " << depId); return false; } arrivalPort = FGAirport::findByIdent(arrId); if(arrivalPort == NULL) { - SG_LOG( SG_GENERAL, SG_WARN, "Traffic manager could not find arrival airport : " << arrId); + SG_LOG( SG_GENERAL, SG_DEBUG, "Traffic manager could not find arrival airport : " << arrId); return false; } From c19664291f3a12ab2518978d0b51a8ad52fd53b5 Mon Sep 17 00:00:00 2001 From: ThorstenB <brehmt@gmail.com> Date: Sat, 25 Jun 2011 20:44:44 +0200 Subject: [PATCH 43/48] #221, #242: Fix/work-around for AI traffic issues Move the disable-HOT feature from the MP aircraft to the a/c base class, disable HOT for all AIaircraft, since that's a fix/work-around for #242: AI aircraft respect the user a/c only when HOT is _disabled_ for them #221: AI aircraft don't stack at parking positions when HOT is disabled Also generally disables HOT for ballistic and other models (suggested by vivian), allowing it for ship/carrier models only. --- src/AIModel/AIAircraft.cxx | 8 ++++++-- src/AIModel/AIBallistic.cxx | 2 +- src/AIModel/AIBase.cxx | 6 +++++- src/AIModel/AIBase.hxx | 2 +- src/AIModel/AIMultiplayer.cxx | 6 +++--- src/AIModel/AIShip.cxx | 3 ++- src/AIModel/AIStatic.cxx | 2 +- src/AIModel/AIStorm.cxx | 4 +++- src/AIModel/AIThermal.cxx | 4 +++- 9 files changed, 25 insertions(+), 12 deletions(-) diff --git a/src/AIModel/AIAircraft.cxx b/src/AIModel/AIAircraft.cxx index d0e319705..1c904b79b 100644 --- a/src/AIModel/AIAircraft.cxx +++ b/src/AIModel/AIAircraft.cxx @@ -52,11 +52,15 @@ using std::string; static string tempReg; -FGAIAircraft::FGAIAircraft(FGAISchedule *ref) : FGAIBase(otAircraft) { +FGAIAircraft::FGAIAircraft(FGAISchedule *ref) : + /* HOT must be disabled for AI Aircraft, + * otherwise traffic detection isn't working as expected.*/ + FGAIBase(otAircraft, false) +{ trafficRef = ref; if (trafficRef) { groundOffset = trafficRef->getGroundOffset(); - setCallSign(trafficRef->getCallSign()); + setCallSign(trafficRef->getCallSign()); } else groundOffset = 0; diff --git a/src/AIModel/AIBallistic.cxx b/src/AIModel/AIBallistic.cxx index 69e090e3d..74b882821 100644 --- a/src/AIModel/AIBallistic.cxx +++ b/src/AIModel/AIBallistic.cxx @@ -40,7 +40,7 @@ const double FGAIBallistic::slugs_to_kgs = 14.5939029372; const double FGAIBallistic::slugs_to_lbs = 32.1740485564; FGAIBallistic::FGAIBallistic(object_type ot) : -FGAIBase(ot), +FGAIBase(ot, false), _height(0.0), _speed(0), _ht_agl_ft(0.0), diff --git a/src/AIModel/AIBase.cxx b/src/AIModel/AIBase.cxx index 33cb073cb..ac907c2e3 100644 --- a/src/AIModel/AIBase.cxx +++ b/src/AIModel/AIBase.cxx @@ -52,7 +52,7 @@ const double FGAIBase::lbs_to_slugs = 0.031080950172; //conversion factor using namespace simgear; -FGAIBase::FGAIBase(object_type ot) : +FGAIBase::FGAIBase(object_type ot, bool enableHot) : _max_speed(300), _name(""), _parent(""), @@ -121,6 +121,10 @@ FGAIBase::FGAIBase(object_type ot) : p = 1e5; a = 340; Mach = 0; + + // explicitly disable HOT for (most) AI models + if (!enableHot) + aip.getSceneGraph()->setNodeMask(~SG_NODEMASK_TERRAIN_BIT); } FGAIBase::~FGAIBase() { diff --git a/src/AIModel/AIBase.hxx b/src/AIModel/AIBase.hxx index 2f8362331..61351adbb 100644 --- a/src/AIModel/AIBase.hxx +++ b/src/AIModel/AIBase.hxx @@ -52,7 +52,7 @@ public: otEscort, otMultiplayer, MAX_OBJECTS }; // Needs to be last!!! - FGAIBase(object_type ot); + FGAIBase(object_type ot, bool enableHot); virtual ~FGAIBase(); virtual void readFromScenario(SGPropertyNode* scFileNode); diff --git a/src/AIModel/AIMultiplayer.cxx b/src/AIModel/AIMultiplayer.cxx index a9635c5f7..08f5afb40 100644 --- a/src/AIModel/AIMultiplayer.cxx +++ b/src/AIModel/AIMultiplayer.cxx @@ -29,18 +29,18 @@ #include "AIMultiplayer.hxx" -#include <simgear/scene/util/SGNodeMasks.hxx> // #define SG_DEBUG SG_ALERT -FGAIMultiplayer::FGAIMultiplayer() : FGAIBase(otMultiplayer) { +FGAIMultiplayer::FGAIMultiplayer() : + FGAIBase(otMultiplayer, false) +{ no_roll = false; mTimeOffsetSet = false; mAllowExtrapolation = true; mLagAdjustSystemSpeed = 10; mLastTimestamp = 0; - aip.getSceneGraph()->setNodeMask(~SG_NODEMASK_TERRAIN_BIT); lastUpdateTime = 0; } diff --git a/src/AIModel/AIShip.cxx b/src/AIModel/AIShip.cxx index 9b6a04705..b5df3d145 100644 --- a/src/AIModel/AIShip.cxx +++ b/src/AIModel/AIShip.cxx @@ -42,7 +42,8 @@ FGAIShip::FGAIShip(object_type ot) : -FGAIBase(ot), +// allow HOT to be enabled +FGAIBase(ot, true), _waiting(false), diff --git a/src/AIModel/AIStatic.cxx b/src/AIModel/AIStatic.cxx index 83be7c8d6..5ac1f4ce3 100644 --- a/src/AIModel/AIStatic.cxx +++ b/src/AIModel/AIStatic.cxx @@ -33,7 +33,7 @@ using std::string; #include "AIStatic.hxx" -FGAIStatic::FGAIStatic() : FGAIBase(otStatic) { +FGAIStatic::FGAIStatic() : FGAIBase(otStatic, false) { } diff --git a/src/AIModel/AIStorm.cxx b/src/AIModel/AIStorm.cxx index fded8012d..a4241df46 100644 --- a/src/AIModel/AIStorm.cxx +++ b/src/AIModel/AIStorm.cxx @@ -35,7 +35,9 @@ using std::string; #include "AIStorm.hxx" -FGAIStorm::FGAIStorm() : FGAIBase(otStorm) { +FGAIStorm::FGAIStorm() : + FGAIBase(otStorm, false) +{ delay = 3.6; subflashes = 1; timer = 0.0; diff --git a/src/AIModel/AIThermal.cxx b/src/AIModel/AIThermal.cxx index 172d1e68a..f47ba2356 100644 --- a/src/AIModel/AIThermal.cxx +++ b/src/AIModel/AIThermal.cxx @@ -35,7 +35,9 @@ using std::string; #include "AIThermal.hxx" -FGAIThermal::FGAIThermal() : FGAIBase(otThermal) { +FGAIThermal::FGAIThermal() : + FGAIBase(otThermal, false) +{ max_strength = 6.0; diameter = 0.5; strength = factor = 0.0; From 1ebab94710faaa5295470ad77cc44be5e8104473 Mon Sep 17 00:00:00 2001 From: ThorstenB <brehmt@gmail.com> Date: Sun, 26 Jun 2011 16:08:19 +0200 Subject: [PATCH 44/48] #358: Missing option to disable AI scenarios --ai-scenario=... can only add/enable another scenario. Introduce --disable-ai-scenarios option to disable all scenarios (can be used by external launchers, GUIs etc) Also provide error instead of debug message when a scenario cannot be loaded. --- src/AIModel/AIManager.cxx | 6 +++--- src/Main/options.cxx | 10 ++++++++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/AIModel/AIManager.cxx b/src/AIModel/AIManager.cxx index 419098112..91ef65271 100644 --- a/src/AIModel/AIManager.cxx +++ b/src/AIModel/AIManager.cxx @@ -358,9 +358,9 @@ FGAIManager::loadScenarioFile(const std::string& filename) SGPropertyNode_ptr root = new SGPropertyNode; readProperties(path.str(), root); return root; - } catch (const sg_exception &) { - SG_LOG(SG_GENERAL, SG_DEBUG, "Incorrect path specified for AI " - "scenario: \"" << path.str() << "\""); + } catch (const sg_exception &t) { + SG_LOG(SG_GENERAL, SG_ALERT, "Failed to load scenario '" + << path.str() << "': " << t.getFormattedMessage()); return 0; } } diff --git a/src/Main/options.cxx b/src/Main/options.cxx index 453e68e48..ff306e6d9 100644 --- a/src/Main/options.cxx +++ b/src/Main/options.cxx @@ -1167,6 +1167,15 @@ fgOptScenario( const char *arg ) return FG_OPTIONS_OK; } +static int +fgOptNoScenarios( const char *arg ) +{ + SGPropertyNode_ptr ai_node = fgGetNode( "/sim/ai", true ); + ai_node->removeChildren("scenario",false); + ai_node->setBoolValue( "enabled", false ); + return FG_OPTIONS_OK; +} + static int fgOptRunway( const char *arg ) { @@ -1465,6 +1474,7 @@ struct OptionDesc { {"min-status", true, OPTION_STRING, "/sim/aircraft-min-status", false, "all", 0 }, {"livery", true, OPTION_FUNC, "", false, "", fgOptLivery }, {"ai-scenario", true, OPTION_FUNC, "", false, "", fgOptScenario }, + {"disable-ai-scenarios", false, OPTION_FUNC, "", false, "", fgOptNoScenarios}, {"parking-id", true, OPTION_FUNC, "", false, "", fgOptParking }, {"version", false, OPTION_FUNC, "", false, "", fgOptVersion }, {"enable-fpe", false, OPTION_FUNC, "", false, "", fgOptFpe}, From 68dec9af2dae7a46d2ad6a6be18150035ef1299c Mon Sep 17 00:00:00 2001 From: ThorstenB <brehmt@gmail.com> Date: Sun, 26 Jun 2011 16:18:36 +0200 Subject: [PATCH 45/48] #178 related: avoid sim from freezing when FDM goes wild --- src/Instrumentation/heading_indicator_dg.cxx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Instrumentation/heading_indicator_dg.cxx b/src/Instrumentation/heading_indicator_dg.cxx index bb9c1620e..a4c478be0 100644 --- a/src/Instrumentation/heading_indicator_dg.cxx +++ b/src/Instrumentation/heading_indicator_dg.cxx @@ -153,6 +153,10 @@ HeadingIndicatorDG::update (double dt) _last_heading_deg = heading; heading += offset + align + error; + // sanity check: bail out when the FDM runs wild, to avoid + // SG_NORMALIZE_RANGE from freezing on huge/infinite numbers. + if (fabs(heading)>1e10) + return; SG_NORMALIZE_RANGE(heading, 0.0, 360.0); _heading_out_node->setDoubleValue(heading); From b2c03e4efcf6b41bfe5660ab8c9098c843b891e7 Mon Sep 17 00:00:00 2001 From: ThorstenB <brehmt@gmail.com> Date: Sun, 26 Jun 2011 19:05:28 +0200 Subject: [PATCH 46/48] #178: improve normalization issue (avoid loops altogether) thanks to Torsten --- src/Instrumentation/heading_indicator_dg.cxx | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/Instrumentation/heading_indicator_dg.cxx b/src/Instrumentation/heading_indicator_dg.cxx index a4c478be0..0c4864912 100644 --- a/src/Instrumentation/heading_indicator_dg.cxx +++ b/src/Instrumentation/heading_indicator_dg.cxx @@ -115,7 +115,7 @@ HeadingIndicatorDG::update (double dt) // Next, calculate time-based precession double offset = _offset_node->getDoubleValue(); offset -= dt * (0.25 / 60.0); // 360deg/day - SG_NORMALIZE_RANGE(offset, -360.0, 360.0); + offset = SGMiscd::normalizePeriodic(-360.0,360.0,offset); _offset_node->setDoubleValue(offset); // No magvar - set the alignment manually @@ -153,11 +153,7 @@ HeadingIndicatorDG::update (double dt) _last_heading_deg = heading; heading += offset + align + error; - // sanity check: bail out when the FDM runs wild, to avoid - // SG_NORMALIZE_RANGE from freezing on huge/infinite numbers. - if (fabs(heading)>1e10) - return; - SG_NORMALIZE_RANGE(heading, 0.0, 360.0); + heading = SGMiscd::normalizePeriodic(0.0,360.0,heading); _heading_out_node->setDoubleValue(heading); From 279fbdc8377438c8760eeb8d5b40a3d260af3915 Mon Sep 17 00:00:00 2001 From: Torsten Dreyer <Torsten@t3r.de> Date: Tue, 28 Jun 2011 12:51:00 +0200 Subject: [PATCH 47/48] Fix #357: Enabling "fixes" on map dialog crashes FG This happened for fixes with names shorter than 5 characters. range check added, which operator[] does not perform. --- src/GUI/MapWidget.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GUI/MapWidget.cxx b/src/GUI/MapWidget.cxx index e3cc5de77..b6f344497 100644 --- a/src/GUI/MapWidget.cxx +++ b/src/GUI/MapWidget.cxx @@ -917,7 +917,7 @@ public: virtual bool pass(FGPositioned* aPos) const { if (_fixes && (aPos->type() == FGPositioned::FIX)) { // ignore fixes which end in digits - expirmental - if (isdigit(aPos->ident()[3]) && isdigit(aPos->ident()[4])) { + if (aPos->ident().length() > 4 && isdigit(aPos->ident()[3]) && isdigit(aPos->ident()[4])) { return false; } } From 18eff91839ff2534ee08bac71d6e5df42e2a7b2d Mon Sep 17 00:00:00 2001 From: Erik Hofman <erik@ehofman.com> Date: Fri, 1 Jul 2011 08:21:06 +0200 Subject: [PATCH 48/48] Update to sync with JSBSim CVS, small bug fixes. --- .../JSBSim/models/flight_control/FGActuator.cpp | 17 ++++++++++------- .../models/flight_control/FGFCSComponent.cpp | 4 ++-- src/FDM/JSBSim/models/propulsion/FGTank.cpp | 4 ++-- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/FDM/JSBSim/models/flight_control/FGActuator.cpp b/src/FDM/JSBSim/models/flight_control/FGActuator.cpp index 6673f0452..9571d33f7 100644 --- a/src/FDM/JSBSim/models/flight_control/FGActuator.cpp +++ b/src/FDM/JSBSim/models/flight_control/FGActuator.cpp @@ -43,7 +43,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGActuator.cpp,v 1.20 2011/06/18 17:46:21 bcoconni Exp $"; +static const char *IdSrc = "$Id: FGActuator.cpp,v 1.21 2011/06/30 03:16:10 jentron Exp $"; static const char *IdHdr = ID_ACTUATOR; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -114,13 +114,16 @@ bool FGActuator::Run(void ) // the Input will be further processed and the eventual Output // will be overwritten from this perfect value. - if (lag != 0.0) Lag(); // models actuator lag - if (rate_limit != 0) RateLimit(); // limit the actuator rate - if (deadband_width != 0.0) Deadband(); - if (hysteresis_width != 0.0) Hysteresis(); - if (bias != 0.0) Bias(); // models a finite bias + if (fail_stuck) { + Output = PreviousOutput; + } else { + if (lag != 0.0) Lag(); // models actuator lag + if (rate_limit != 0) RateLimit(); // limit the actuator rate + if (deadband_width != 0.0) Deadband(); + if (hysteresis_width != 0.0) Hysteresis(); + if (bias != 0.0) Bias(); // models a finite bias + } - if (fail_stuck) Output = PreviousOutput; PreviousOutput = Output; // previous value needed for "stuck" malfunction Clip(); diff --git a/src/FDM/JSBSim/models/flight_control/FGFCSComponent.cpp b/src/FDM/JSBSim/models/flight_control/FGFCSComponent.cpp index 2fc74bd96..68e699adf 100644 --- a/src/FDM/JSBSim/models/flight_control/FGFCSComponent.cpp +++ b/src/FDM/JSBSim/models/flight_control/FGFCSComponent.cpp @@ -48,7 +48,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGFCSComponent.cpp,v 1.32 2011/06/16 03:39:38 jberndt Exp $"; +static const char *IdSrc = "$Id: FGFCSComponent.cpp,v 1.33 2011/06/21 04:41:54 jberndt Exp $"; static const char *IdHdr = ID_FCSCOMPONENT; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -163,7 +163,7 @@ FGFCSComponent::FGFCSComponent(FGFCS* _fcs, Element* element) : fcs(_fcs) delay = (unsigned int)(delay_time / dt); } output_array.resize(delay); - for (int i=0; i<delay; i++) output_array[i] = 0.0; + for (unsigned int i=0; i<delay; i++) output_array[i] = 0.0; } clip_el = element->FindElement("clipto"); diff --git a/src/FDM/JSBSim/models/propulsion/FGTank.cpp b/src/FDM/JSBSim/models/propulsion/FGTank.cpp index dbb5b37d1..a39fbcec3 100644 --- a/src/FDM/JSBSim/models/propulsion/FGTank.cpp +++ b/src/FDM/JSBSim/models/propulsion/FGTank.cpp @@ -48,7 +48,7 @@ using namespace std; namespace JSBSim { -static const char *IdSrc = "$Id: FGTank.cpp,v 1.29 2011/06/06 22:39:52 jentron Exp $"; +static const char *IdSrc = "$Id: FGTank.cpp,v 1.30 2011/06/21 04:41:54 jberndt Exp $"; static const char *IdHdr = ID_TANK; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -101,7 +101,7 @@ FGTank::FGTank(FGFDMExec* exec, Element* el, int tank_number) if (el->FindElement("standpipe")) InitialStandpipe = Standpipe = el->FindElementValueAsNumberConvertTo("standpipe", "LBS"); if (el->FindElement("priority")) - InitialPriority = Priority = el->FindElementValueAsNumber("priority"); + InitialPriority = Priority = (int)el->FindElementValueAsNumber("priority"); if (el->FindElement("density")) Density = el->FindElementValueAsNumberConvertTo("density", "LBS/GAL"); if (el->FindElement("type"))