1
0
Fork 0

Fix bug #253, at least partially

make options
--wind=nnn@mm
--visibility
--visibility-miles
--ceiling
--turbulence
work again. These options now write properties in the
/environment/config/presets
branch. The values will be applied in the property-rules
in FGDATA/Environment/interpolator.xml
This commit is contained in:
Torsten Dreyer 2011-01-19 19:36:04 +01:00
parent bd60cd21e7
commit e86cecf470
11 changed files with 317 additions and 128 deletions

View file

@ -3413,6 +3413,14 @@
RelativePath="..\..\..\src\Environment\terrainsampler.hxx"
>
</File>
<File
RelativePath="..\..\..\src\Environment\presets.cxx"
>
</File>
<File
RelativePath="..\..\..\src\Environment\presets.hxx"
>
</File>
</Filter>
<Filter
Name="Lib_Model"

View file

@ -15,6 +15,7 @@ set(SOURCES
realwx_ctrl.cxx
ridge_lift.cxx
terrainsampler.cxx
presets.cxx
)
flightgear_component(Environment "${SOURCES}")

View file

@ -16,6 +16,7 @@ libEnvironment_a_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

View file

@ -158,10 +158,10 @@ MetarProperties::MetarProperties( SGPropertyNode_ptr rootNode ) :
_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 );
@ -218,14 +218,11 @@ void MetarProperties::set_metar( const char * metar )
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();
@ -408,4 +405,43 @@ double MetarProperties::get_magnetic_dip_deg() const
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

View file

@ -51,6 +51,14 @@ private:
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;

132
src/Environment/presets.cxx Executable file
View file

@ -0,0 +1,132 @@
// 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

94
src/Environment/presets.hxx Executable file
View file

@ -0,0 +1,94 @@
// 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

View file

@ -25,7 +25,6 @@
#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>
@ -47,6 +46,7 @@
#include "viewmgr.hxx"
#include "main.hxx"
#include <Main/viewer.hxx>
#include <Environment/presets.hxx>
using std::string;
using std::ifstream;
@ -558,6 +558,9 @@ do_tile_cache_reload (const SGPropertyNode * arg)
}
#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.
@ -684,7 +687,7 @@ do_set_dewpoint_degc (const SGPropertyNode * arg)
dummy.set_dewpoint_degc( dewpoint_degc );
return do_set_dewpoint_sea_level_degc(dummy.get_dewpoint_sea_level_degc());
}
#endif
/**
* Update the lighting manually.
*/
@ -1260,29 +1263,21 @@ do_replay (const SGPropertyNode * arg)
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
@ -1454,10 +1449,12 @@ static struct {
{ "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 },
@ -1480,8 +1477,10 @@ static struct {
{ "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 },

View file

@ -56,6 +56,7 @@
#include "util.hxx"
#include "viewmgr.hxx"
#include <Main/viewer.hxx>
#include <Environment/presets.hxx>
#include <simgear/version.h>
#include <osg/Version>
@ -994,18 +995,14 @@ fgOptViewOffset( const char *arg )
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;
}
@ -1016,7 +1013,7 @@ fgOptRandomWind( const char *arg )
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;
}
@ -1028,14 +1025,14 @@ fgOptWind( const char *arg )
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;
}
@ -1052,9 +1049,7 @@ fgOptCeiling( const char *arg )
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;
}

View file

@ -17,6 +17,9 @@
//
// $Id$
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <simgear/compiler.h>
@ -28,6 +31,8 @@
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"
@ -38,73 +43,6 @@ using std::vector;
#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)

View file

@ -26,29 +26,6 @@
#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.
*