RelativePath="..\..\..\src\Environment\terrainsampler.hxx"\r
>\r
</File>\r
+ <File\r
+ RelativePath="..\..\..\src\Environment\presets.cxx"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\..\..\src\Environment\presets.hxx"\r
+ >\r
+ </File>\r
</Filter>\r
<Filter\r
Name="Lib_Model"\r
realwx_ctrl.cxx
ridge_lift.cxx
terrainsampler.cxx
+ presets.cxx
)
-flightgear_component(Environment "${SOURCES}")
\ No newline at end of file
+flightgear_component(Environment "${SOURCES}")
precipitation_mgr.cxx precipitation_mgr.hxx \
ridge_lift.cxx ridge_lift.hxx \
ephemeris.cxx ephemeris.hxx \
- terrainsampler.cxx terrainsampler.cxx
+ terrainsampler.cxx terrainsampler.cxx \
+ presets.cxx presets.cxx
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src
_tiedProperties.Tie("max-visibility-m", &_max_visibility );
_tiedProperties.Tie("base-wind-range-from", &_base_wind_range_from );
_tiedProperties.Tie("base-wind-range-to", &_base_wind_range_to );
- _tiedProperties.Tie("base-wind-speed-kt", &_wind_speed );
- _tiedProperties.Tie("base-wind-dir-deg", &_base_wind_dir );
- _tiedProperties.Tie("base-wind-from-north-fps", &_wind_from_north_fps );
- _tiedProperties.Tie("base-wind-from-east-fps", &_wind_from_east_fps );
+ _tiedProperties.Tie("base-wind-speed-kt", this, &MetarProperties::get_wind_speed, &MetarProperties::set_wind_speed );
+ _tiedProperties.Tie("base-wind-dir-deg", this, &MetarProperties::get_base_wind_dir, &MetarProperties::set_base_wind_dir );
+ _tiedProperties.Tie("base-wind-from-north-fps", this, &MetarProperties::get_wind_from_north_fps, &MetarProperties::set_wind_from_north_fps );
+ _tiedProperties.Tie("base-wind-from-east-fps",this, &MetarProperties::get_wind_from_east_fps, &MetarProperties::set_wind_from_east_fps );
_tiedProperties.Tie("gust-wind-speed-kt", &_gusts );
_tiedProperties.Tie("temperature-degc", &_temperature );
_tiedProperties.Tie("dewpoint-degc", &_dewpoint );
vis->setDoubleValue("max-m", v);
}
- _base_wind_dir = m->getWindDir();
+ set_base_wind_dir(m->getWindDir());
_base_wind_range_from = m->getWindRangeFrom();
_base_wind_range_to = m->getWindRangeTo();
- _wind_speed = m->getWindSpeed_kt();
+ set_wind_speed(m->getWindSpeed_kt());
- double speed_fps = _wind_speed * SG_NM_TO_METER * SG_METER_TO_FEET / 3600.0;
- _wind_from_north_fps = speed_fps * cos((double)_base_wind_dir * SGD_DEGREES_TO_RADIANS);
- _wind_from_east_fps = speed_fps * sin((double)_base_wind_dir * SGD_DEGREES_TO_RADIANS);
_gusts = m->getGustSpeed_kt();
_temperature = m->getTemperature_C();
_dewpoint = m->getDewpoint_C();
return _magneticVariation->get_dip_deg( _station_longitude, _station_latitude, _station_elevation );
}
+static inline void calc_wind_hs( double north_fps, double east_fps, int & heading_deg, double & speed_kt )
+{
+ speed_kt = sqrt((north_fps)*(north_fps)+(east_fps)*(east_fps)) * 3600.0 / (SG_NM_TO_METER * SG_METER_TO_FEET);
+ heading_deg = SGMiscd::roundToInt(
+ SGMiscd::normalizeAngle2( atan2( east_fps, north_fps ) ) * SGD_RADIANS_TO_DEGREES );
+}
+
+void MetarProperties::set_wind_from_north_fps( double value )
+{
+ _wind_from_north_fps = value;
+ calc_wind_hs( _wind_from_north_fps, _wind_from_east_fps, _base_wind_dir, _wind_speed );
+}
+
+void MetarProperties::set_wind_from_east_fps( double value )
+{
+ _wind_from_east_fps = value;
+ calc_wind_hs( _wind_from_north_fps, _wind_from_east_fps, _base_wind_dir, _wind_speed );
+}
+
+static inline void calc_wind_ne( double heading_deg, double speed_kt, double & north_fps, double & east_fps )
+{
+ double speed_fps = speed_kt * SG_NM_TO_METER * SG_METER_TO_FEET / 3600.0;
+ north_fps = speed_fps * cos(heading_deg * SGD_DEGREES_TO_RADIANS);
+ east_fps = speed_fps * sin(heading_deg * SGD_DEGREES_TO_RADIANS);
+}
+
+void MetarProperties::set_base_wind_dir( double value )
+{
+ _base_wind_dir = value;
+ calc_wind_ne( (double)_base_wind_dir, _wind_speed, _wind_from_north_fps, _wind_from_east_fps );
+}
+
+void MetarProperties::set_wind_speed( double value )
+{
+ _wind_speed = value;
+ calc_wind_ne( (double)_base_wind_dir, _wind_speed, _wind_from_north_fps, _wind_from_east_fps );
+}
+
+
} // namespace Environment
const char * get_decoded() const { return _decoded.c_str(); }
double get_magnetic_variation_deg() const;
double get_magnetic_dip_deg() const;
+ double get_wind_from_north_fps() const { return _wind_from_north_fps; }
+ double get_wind_from_east_fps() const { return _wind_from_east_fps; }
+ double get_base_wind_dir() const { return _base_wind_dir; }
+ double get_wind_speed() const { return _wind_speed; }
+ void set_wind_from_north_fps( double value );
+ void set_wind_from_east_fps( double value );
+ void set_base_wind_dir( double value );
+ void set_wind_speed( double value );
SGPropertyNode_ptr _rootNode;
SGPropertyNode_ptr _metarValidNode;
--- /dev/null
+// presets.cxx -- Wrap environment presets
+//
+// Written by Torsten Dreyer, January 2011
+//
+// Copyright (C) 2010 Torsten Dreyer Torsten(at)t3r(dot)de
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU 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
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include "presets.hxx"
+
+#include <simgear/math/SGMisc.hxx>
+#include <Main/fg_props.hxx>
+
+namespace Environment {
+namespace Presets {
+
+PresetBase::PresetBase( const char * overrideNodePath )
+ : _overrideNodePath( overrideNodePath )
+{
+}
+
+void PresetBase::setOverride( bool value )
+{
+ /*
+ Don't initialize node in constructor because the class is used as a singleton
+ and created as a static variable in the initialization sequence when globals()
+ is not yet initialized and returns null.
+ */
+ if( _overrideNode == NULL )
+ _overrideNode = fgGetNode( _overrideNodePath.c_str(), true );
+ _overrideNode->setBoolValue( value );
+}
+
+
+Wind::Wind() :
+ PresetBase("/environment/config/presets/wind-override")
+{
+}
+
+
+void Wind::preset( double min_hdg, double max_hdg, double speed_kt, double gust_kt )
+{
+ // see: PresetBase::setOverride()
+
+ //TODO: handle variable wind and gusts
+ if( _fromNorthNode == NULL )
+ _fromNorthNode = fgGetNode("/environment/config/presets/wind-from-north-fps", true );
+
+ if( _fromEastNode == NULL )
+ _fromEastNode = fgGetNode("/environment/config/presets/wind-from-east-fps", true );
+
+ double avgHeading_rad =
+ SGMiscd::normalizeAngle2(
+ (SGMiscd::normalizeAngle(min_hdg*SG_DEGREES_TO_RADIANS) +
+ SGMiscd::normalizeAngle(max_hdg*SG_DEGREES_TO_RADIANS))/2);
+
+ double speed_fps = speed_kt * SG_NM_TO_METER * SG_METER_TO_FEET / 3600.0;
+ _fromNorthNode->setDoubleValue( speed_fps * cos(avgHeading_rad) );
+ _fromEastNode->setDoubleValue( speed_fps * sin(avgHeading_rad) );
+ setOverride( true );
+}
+
+Visibility::Visibility() :
+ PresetBase("/environment/config/presets/visibility-m-override")
+{
+}
+
+void Visibility::preset( double visibility_m )
+{
+ // see: PresetBase::setOverride()
+ if( _visibilityNode == NULL )
+ _visibilityNode = fgGetNode("/environment/config/presets/visibility-m", true );
+
+ _visibilityNode->setDoubleValue(visibility_m );
+ setOverride( true );
+}
+
+Turbulence::Turbulence() :
+ PresetBase("/environment/config/presets/turbulence-magnitude-norm-override")
+{
+}
+
+
+void Turbulence::preset(double magnitude_norm)
+{
+ // see: PresetBase::setOverride()
+ if( _magnitudeNode == NULL )
+ _magnitudeNode = fgGetNode("/environment/config/presets/turbulence-magnitude-norm", true );
+
+ _magnitudeNode->setDoubleValue( magnitude_norm );
+ setOverride( true );
+}
+
+Ceiling::Ceiling() :
+ PresetBase("/environment/config/presets/ceiling-override")
+{
+}
+
+
+void Ceiling::preset( double elevation, double thickness )
+{
+ // see: PresetBase::setOverride()
+ if( _elevationNode == NULL )
+ _elevationNode = fgGetNode("/environment/config/presets/ceiling-elevation-ft", true);
+
+ if( _thicknessNode == NULL )
+ _thicknessNode = fgGetNode("/environment/config/presets/ceiling-elevation-ft", true);
+
+ _elevationNode->setDoubleValue( elevation );
+ _thicknessNode->setDoubleValue( thickness );
+ setOverride( true );
+}
+
+} // namespace Presets
+} // namespace Environment
+
--- /dev/null
+// presets.hxx -- Wrap environment presets
+//
+// Written by Torsten Dreyer, January 2011
+//
+// Copyright (C) 2010 Torsten Dreyer Torsten(at)t3r(dot)de
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU 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
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifndef __ENVIRONMENT_PRESETS_HXX
+#define __ENVIRONMENT_PRESETS_HXX
+
+#include <simgear/structure/Singleton.hxx>
+#include <simgear/props/props.hxx>
+
+namespace Environment {
+
+/**
+ * @brief A wrapper for presets of environment properties
+ * mainly set from the command line with --wind=270@10,
+ * visibility=1600 etc.
+ */
+namespace Presets {
+
+class PresetBase {
+public:
+ PresetBase( const char * overrideNodePath );
+ virtual void disablePreset() { setOverride(false); }
+protected:
+ void setOverride( bool value );
+private:
+ std::string _overrideNodePath;
+ SGPropertyNode_ptr _overrideNode;
+};
+
+class Ceiling : public PresetBase {
+public:
+ Ceiling();
+ void preset( double elevation, double thickness );
+private:
+ SGPropertyNode_ptr _elevationNode;
+ SGPropertyNode_ptr _thicknessNode;
+};
+
+typedef simgear::Singleton<Ceiling> CeilingSingleton;
+
+class Turbulence : public PresetBase {
+public:
+ Turbulence();
+ void preset( double magnitude_norm );
+private:
+ SGPropertyNode_ptr _magnitudeNode;
+};
+
+typedef simgear::Singleton<Turbulence> TurbulenceSingleton;
+
+class Wind : public PresetBase {
+public:
+ Wind();
+ void preset( double min_hdg, double max_hdg, double speed, double gust );
+private:
+ SGPropertyNode_ptr _fromNorthNode;
+ SGPropertyNode_ptr _fromEastNode;
+};
+
+typedef simgear::Singleton<Wind> WindSingleton;
+
+class Visibility : public PresetBase {
+public:
+ Visibility();
+ void preset( double visibility_m );
+private:
+ SGPropertyNode_ptr _visibilityNode;
+};
+
+typedef simgear::Singleton<Visibility> VisibilitySingleton;
+
+} // namespace Presets
+
+} // namespace Environment
+
+#endif //__ENVIRONMENT_PRESETS_HXX
#include <Cockpit/panel.hxx>
#include <Cockpit/panel_io.hxx>
-#include <Environment/environment.hxx>
#include <FDM/flight.hxx>
#include <GUI/gui.h>
#include <GUI/new_gui.hxx>
#include "viewmgr.hxx"
#include "main.hxx"
#include <Main/viewer.hxx>
+#include <Environment/presets.hxx>
using std::string;
using std::ifstream;
}
+#if 0
+These do_set_(some-environment-parameters) are deprecated and no longer
+useful/functional - Torsten Dreyer, January 2011
/**
* Set the sea level outside air temperature and assigning that to all
* boundary and aloft environment layers.
dummy.set_dewpoint_degc( dewpoint_degc );
return do_set_dewpoint_sea_level_degc(dummy.get_dewpoint_sea_level_degc());
}
-
+#endif
/**
* Update the lighting manually.
*/
return true;
}
-
+/*
static bool
do_decrease_visibility (const SGPropertyNode * arg)
{
- double new_value = fgGetDouble("/environment/visibility-m") * 0.9;
- fgSetDouble("/environment/visibility-m", new_value);
- fgDefaultWeatherValue("visibility-m", new_value);
- globals->get_subsystem("environment")->reinit();
-
+ Environment::Presets::VisibilitySingleton::instance()->adjust( 0.9 );
return true;
}
static bool
do_increase_visibility (const SGPropertyNode * arg)
{
- double new_value = fgGetDouble("/environment/visibility-m") * 1.1;
- fgSetDouble("/environment/visibility-m", new_value);
- fgDefaultWeatherValue("visibility-m", new_value);
- globals->get_subsystem("environment")->reinit();
-
+ Environment::Presets::VisibilitySingleton::instance()->adjust( 1.1 );
return true;
}
-
+*/
/**
* An fgcommand to allow loading of xml files via nasal,
* the xml file's structure will be made available within
{ "screen-capture", do_screen_capture },
{ "hires-screen-capture", do_hires_screen_capture },
{ "tile-cache-reload", do_tile_cache_reload },
+ /*
{ "set-sea-level-air-temp-degc", do_set_sea_level_degc },
{ "set-outside-air-temp-degc", do_set_oat_degc },
{ "set-dewpoint-sea-level-air-temp-degc", do_set_dewpoint_sea_level_degc },
{ "set-dewpoint-temp-degc", do_set_dewpoint_degc },
+ */
{ "timeofday", do_timeofday },
{ "property-toggle", do_property_toggle },
{ "property-assign", do_property_assign },
{ "presets-commit", do_presets_commit },
{ "log-level", do_log_level },
{ "replay", do_replay },
+ /*
{ "decrease-visibility", do_decrease_visibility },
{ "increase-visibility", do_increase_visibility },
+ */
{ "loadxml", do_load_xml_to_proptree},
{ "savexml", do_save_xml_from_proptree },
{ "press-cockpit-button", do_press_cockpit_button },
#include "util.hxx"
#include "viewmgr.hxx"
#include <Main/viewer.hxx>
+#include <Environment/presets.hxx>
#include <simgear/version.h>
#include <osg/Version>
static int
fgOptVisibilityMeters( const char *arg )
{
- double visibility = atof( arg );
- fgDefaultWeatherValue("visibility-m", visibility);
- fgSetDouble("/environment/visibility-m", visibility);
+ Environment::Presets::VisibilitySingleton::instance()->preset( atof( arg ) );
return FG_OPTIONS_OK;
}
static int
fgOptVisibilityMiles( const char *arg )
{
- double visibility = atof( arg ) * 5280.0 * SG_FEET_TO_METER;
- fgDefaultWeatherValue("visibility-m", visibility);
- fgSetDouble("/environment/visibility-m", visibility);
+ Environment::Presets::VisibilitySingleton::instance()->preset( atof( arg ) * 5280.0 * SG_FEET_TO_METER );
return FG_OPTIONS_OK;
}
double max_hdg = min_hdg + (20 - sqrt(sg_random() * 400));
double speed = sg_random() * sg_random() * 40;
double gust = speed + (10 - sqrt(sg_random() * 100));
- fgSetupWind(min_hdg, max_hdg, speed, gust);
+ Environment::Presets::WindSingleton::instance()->preset(min_hdg, max_hdg, speed, gust);
return FG_OPTIONS_OK;
}
SG_LOG( SG_GENERAL, SG_ALERT, "bad wind value " << arg );
return FG_OPTIONS_ERROR;
}
- fgSetupWind(min_hdg, max_hdg, speed, gust);
+ Environment::Presets::WindSingleton::instance()->preset(min_hdg, max_hdg, speed, gust);
return FG_OPTIONS_OK;
}
static int
fgOptTurbulence( const char *arg )
{
- fgDefaultWeatherValue("turbulence/magnitude-norm", atof(arg));
+ Environment::Presets::TurbulenceSingleton::instance()->preset( atof(arg) );
return FG_OPTIONS_OK;
}
elevation = atof(spec.substr(0, pos).c_str());
thickness = atof(spec.substr(pos + 1).c_str());
}
- fgSetDouble("/environment/clouds/layer[0]/elevation-ft", elevation);
- fgSetDouble("/environment/clouds/layer[0]/thickness-ft", thickness);
- fgSetString("/environment/clouds/layer[0]/coverage", "overcast");
+ Environment::Presets::CeilingSingleton::instance()->preset( elevation, thickness );
return FG_OPTIONS_OK;
}
//
// $Id$
-
+#ifdef HAVE_CONFIG_H\r
+# include <config.h>\r
+#endif\r
+\r
#include <simgear/compiler.h>
#include <math.h>
using std::vector;
#include <simgear/debug/logstream.hxx>
+#include <simgear/math/SGLimits.hxx>
+#include <simgear/math/SGMisc.hxx>
#include "fg_io.hxx"
#include "fg_props.hxx"
#include "osgDB/Registry"
#endif
-void
-fgDefaultWeatherValue (const char * propname, double value)
-{
- unsigned int i;
-
- SGPropertyNode * branch = fgGetNode("/environment/config/boundary", true);
- vector<SGPropertyNode_ptr> entries = branch->getChildren("entry");
- for (i = 0; i < entries.size(); i++) {
- entries[i]->setDoubleValue(propname, value);
- }
-
- branch = fgGetNode("/environment/config/aloft", true);
- entries = branch->getChildren("entry");
- for (i = 0; i < entries.size(); i++) {
- entries[i]->setDoubleValue(propname, value);
- }
-}
-
-
-void
-fgSetupWind (double min_hdg, double max_hdg, double speed, double gust)
-{
- // Initialize to a reasonable state
- fgDefaultWeatherValue("wind-from-heading-deg", min_hdg);
- fgDefaultWeatherValue("wind-speed-kt", speed);
-
- SG_LOG(SG_GENERAL, SG_INFO, "WIND: " << min_hdg << '@' <<
- speed << " knots" << endl);
-
- // Now, add some variety to the layers
- min_hdg += 10;
- if (min_hdg > 360)
- min_hdg -= 360;
- speed *= 1.1;
- fgSetDouble("/environment/config/boundary/entry[1]/wind-from-heading-deg",
- min_hdg);
- fgSetDouble("/environment/config/boundary/entry[1]/wind-speed-kt",
- speed);
-
- min_hdg += 20;
- if (min_hdg > 360)
- min_hdg -= 360;
- speed *= 1.1;
- fgSetDouble("/environment/config/aloft/entry[0]/wind-from-heading-deg",
- min_hdg);
- fgSetDouble("/environment/config/aloft/entry[0]/wind-speed-kt",
- speed);
-
- min_hdg += 10;
- if (min_hdg > 360)
- min_hdg -= 360;
- speed *= 1.1;
- fgSetDouble("/environment/config/aloft/entry[1]/wind-from-heading-deg",
- min_hdg);
- fgSetDouble("/environment/config/aloft/entry[1]/wind-speed-kt",
- speed);
-
- min_hdg += 10;
- if (min_hdg > 360)
- min_hdg -= 360;
- speed *= 1.1;
- fgSetDouble("/environment/config/aloft/entry[2]/wind-from-heading-deg",
- min_hdg);
- fgSetDouble("/environment/config/aloft/entry[2]/wind-speed-kt",
- speed);
-}
-
// Originally written by Alex Perry.
double
fgGetLowPass (double current, double target, double timeratio)
#endif
-/**
- * Initialize a single value through all existing weather levels.
- *
- * This function is useful mainly from the command-line.
- *
- * @param propname The name of the subproperty to initialized.
- * @param value The initial value.
- */
-extern void fgDefaultWeatherValue (const char * propname, double value);
-
-
-/**
- * Set up a plausible wind layout, boundary and aloft,
- * based on just a few parameters.
- *
- * @param min_hdg Minimal wind heading
- * @param max_hdg Maximal wind heading
- * @param speed Windspeed in knots
- * @param gust Wind gust variation in knots
- */
-extern void fgSetupWind (double min_hdg, double max_hdg,
- double speed, double gust);
-
/**
* Move a value towards a target.
*