1
0
Fork 0
This commit is contained in:
Torsten Dreyer 2011-02-14 20:54:09 +01:00
commit eb68d1a927
12 changed files with 928 additions and 1250 deletions

File diff suppressed because it is too large Load diff

View file

@ -25,6 +25,7 @@
#define _CONTROLS_HXX
#include <simgear/structure/subsystem_mgr.hxx>
#include <simgear/props/tiedpropertylist.hxx>
// Define a structure containing the control parameters
@ -34,65 +35,65 @@ class FGControls : public SGSubsystem
public:
enum {
ALL_ENGINES = -1,
MAX_ENGINES = 12
ALL_ENGINES = -1,
MAX_ENGINES = 12
};
enum {
ALL_WHEELS = -1,
MAX_WHEELS = 3
ALL_WHEELS = -1,
MAX_WHEELS = 3
};
enum {
ALL_TANKS = -1,
MAX_TANKS = 8
ALL_TANKS = -1,
MAX_TANKS = 8
};
enum {
ALL_BOOSTPUMPS = -1,
MAX_BOOSTPUMPS = 2
ALL_BOOSTPUMPS = -1,
MAX_BOOSTPUMPS = 2
};
enum {
ALL_HYD_SYSTEMS = -1,
MAX_HYD_SYSTEMS = 4
ALL_HYD_SYSTEMS = -1,
MAX_HYD_SYSTEMS = 4
};
enum {
ALL_PACKS = -1,
MAX_PACKS = 4
ALL_PACKS = -1,
MAX_PACKS = 4
};
enum {
ALL_LIGHTS = -1,
MAX_LIGHTS = 4
ALL_LIGHTS = -1,
MAX_LIGHTS = 4
};
enum {
ALL_STATIONS = -1,
MAX_STATIONS = 12
ALL_STATIONS = -1,
MAX_STATIONS = 12
};
enum {
ALL_AUTOPILOTS = -1,
MAX_AUTOPILOTS = 3
ALL_AUTOPILOTS = -1,
MAX_AUTOPILOTS = 3
};
enum {
ALL_EJECTION_SEATS = -1,
MAX_EJECTION_SEATS = 10
ALL_EJECTION_SEATS = -1,
MAX_EJECTION_SEATS = 10
};
enum {
SEAT_SAFED = -1,
SEAT_ARMED = 0,
SEAT_FAIL = 1
SEAT_SAFED = -1,
SEAT_ARMED = 0,
SEAT_FAIL = 1
};
enum {
CMD_SEL_NORM = -1,
CMD_SEL_AFT = 0,
CMD_SEL_SOLO = 1
CMD_SEL_NORM = -1,
CMD_SEL_AFT = 0,
CMD_SEL_SOLO = 1
};
private:
@ -252,7 +253,7 @@ private:
SGPropertyNode_ptr auto_coordination;
simgear::TiedPropertyList _tiedProperties;
public:
FGControls();
@ -266,7 +267,7 @@ public:
// Reset function
void reset_all(void);
// Query functions
// controls/flight/
inline double get_aileron() const { return aileron; }
@ -298,7 +299,7 @@ public:
inline bool get_cutoff(int engine) const { return cutoff[engine]; }
inline double get_mixture(int engine) const { return mixture[engine]; }
inline double get_prop_advance(int engine) const {
return prop_advance[engine];
return prop_advance[engine];
}
inline int get_magnetos(int engine) const { return magnetos[engine]; }
inline int get_feed_tank(int engine) const { return feed_tank[engine]; }

View file

@ -191,6 +191,7 @@ public:
NoaaMetarRealWxController( SGPropertyNode_ptr rootNode );
virtual ~NoaaMetarRealWxController();
virtual void update (bool first, double delta_time_sec);
virtual void shutdown ();
class MetarLoadRequest {
public:
@ -234,14 +235,17 @@ private:
class MetarLoadThread : public OpenThreads::Thread {
public:
MetarLoadThread( long maxAge );
virtual ~MetarLoadThread( ) { stop(); }
void requestMetar( const MetarLoadRequest & metarRequest, bool background = true );
bool hasMetar() { return _responseQueue.size() > 0; }
MetarLoadResponse getMetar() { return _responseQueue.pop(); }
virtual void run();
void stop();
private:
void fetch( const MetarLoadRequest & );
long _maxAge;
long _minRequestInterval;
volatile bool _stop;
SGBlockingQueue <MetarLoadRequest> _requestQueue;
SGBlockingQueue <MetarLoadResponse> _responseQueue;
};
@ -261,18 +265,20 @@ NoaaMetarRealWxController::NoaaMetarRealWxController( SGPropertyNode_ptr rootNod
#endif
}
NoaaMetarRealWxController::~NoaaMetarRealWxController()
void NoaaMetarRealWxController::shutdown()
{
#if defined(ENABLE_THREADS)
if( _metarLoadThread ) {
MetarLoadRequest request("");
_metarLoadThread->requestMetar(request);
_metarLoadThread->join();
delete _metarLoadThread;
_metarLoadThread = NULL;
}
#endif // ENABLE_THREADS
}
NoaaMetarRealWxController::~NoaaMetarRealWxController()
{
}
void NoaaMetarRealWxController::update( bool first, double dt )
{
_positionTimeToLive -= dt;
@ -319,7 +325,7 @@ void NoaaMetarRealWxController::update( bool first, double dt )
"NoaaMetarRealWxController::update(): spawning load request for station-id '" << stationId << "'" );
MetarLoadRequest request( stationId );
// load the metar for the neares airport in the foreground if the fdm is uninitialized
// load the metar for the nearest airport in the foreground if the fdm is uninitialized
// to make sure a metar is received
// before the automatic runway selection code runs. All subsequent calls
// run in the background
@ -348,7 +354,8 @@ void NoaaMetarRealWxController::update( bool first, double dt )
#if defined(ENABLE_THREADS)
NoaaMetarRealWxController::MetarLoadThread::MetarLoadThread( long maxAge ) :
_maxAge(maxAge),
_minRequestInterval(2000)
_minRequestInterval(2000),
_stop(false)
{
}
@ -368,24 +375,41 @@ void NoaaMetarRealWxController::MetarLoadThread::requestMetar( const MetarLoadRe
}
}
void NoaaMetarRealWxController::MetarLoadThread::stop()
{
// set stop flag and wake up the thread with an empty request
_stop = true;
MetarLoadRequest request("");
requestMetar(request);
join();
}
void NoaaMetarRealWxController::MetarLoadThread::run()
{
SGTimeStamp lastRun = SGTimeStamp::fromSec(0);
for( ;; ) {
SGTimeStamp dt = SGTimeStamp::now() - lastRun;
if( dt.getSeconds() * 1000 < _minRequestInterval )
microSleep( (_minRequestInterval - dt.getSeconds() * 1000 ) * 1000 );
lastRun = SGTimeStamp::now();
long delayMs = _minRequestInterval - dt.getSeconds() * 1000;
while (( delayMs > 0 ) && !_stop)
{
// sleep no more than 3 seconds at a time, otherwise shutdown response is too slow
long sleepMs = (delayMs>3000) ? 3000 : delayMs;
microSleep( sleepMs * 1000 );
delayMs -= sleepMs;
}
if (_stop)
break;
lastRun = SGTimeStamp::now();
const MetarLoadRequest request = _requestQueue.pop();
if( request._stationId.size() == 0 )
if (( request._stationId.size() == 0 ) || _stop)
break;
fetch( request );
}
}

View file

@ -103,42 +103,20 @@ void FGRidgeLift::init(void)
void FGRidgeLift::bind() {
string prop;
_tiedProperties.setRoot( fgGetNode("/environment/ridge-lift",true));
for( int i = 0; i < 5; i++ ) {
prop = CreateIndexedPropertyName("/environment/ridge-lift/probe-elev-m", i );
fgTie( prop.c_str(), this, i, &FGRidgeLift::get_probe_elev_m); // read-only
prop = CreateIndexedPropertyName("/environment/ridge-lift/probe-lat-deg", i );
fgTie( prop.c_str(), this, i, &FGRidgeLift::get_probe_lat_deg); // read-only
prop = CreateIndexedPropertyName("/environment/ridge-lift/probe-lon-deg", i );
fgTie( prop.c_str(), this, i, &FGRidgeLift::get_probe_lon_deg); // read-only
_tiedProperties.Tie( "probe-elev-m", i, this, i, &FGRidgeLift::get_probe_elev_m );
_tiedProperties.Tie( "probe-lat-deg", i, this, i, &FGRidgeLift::get_probe_lat_deg );
_tiedProperties.Tie( "probe-lon-deg", i, this, i, &FGRidgeLift::get_probe_lon_deg );
}
for( int i = 0; i < 4; i++ ) {
prop = CreateIndexedPropertyName("/environment/ridge-lift/slope", i );
fgTie( prop.c_str(), this, i, &FGRidgeLift::get_slope); // read-only
_tiedProperties.Tie( "slope", i, this, i, &FGRidgeLift::get_slope );
}
}
void FGRidgeLift::unbind() {
string prop;
for( int i = 0; i < 5; i++ ) {
prop = CreateIndexedPropertyName("/environment/ridge-lift/probe-elev-m", i );
fgUntie( prop.c_str() );
prop = CreateIndexedPropertyName("/environment/ridge-lift/probe-lat-deg", i );
fgUntie( prop.c_str() );
prop = CreateIndexedPropertyName("/environment/ridge-lift/probe-lon-deg", i );
fgUntie( prop.c_str() );
}
for( int i = 0; i < 4; i++ ) {
prop = CreateIndexedPropertyName("/environment/ridge-lift/slope", i );
fgUntie( prop.c_str() );
}
_tiedProperties.Untie();
}
void FGRidgeLift::update(double dt) {

View file

@ -36,6 +36,7 @@
#include <string>
using std::string;
#include <simgear/props/tiedpropertylist.hxx>
class FGRidgeLift : public SGSubsystem {
public:
@ -80,6 +81,7 @@ private:
SGPropertyNode_ptr _user_latitude_node;
SGPropertyNode_ptr _ground_elev_node;
simgear::TiedPropertyList _tiedProperties;
};
#endif // _FG_RidgeLift_HXX

View file

@ -26,6 +26,7 @@
#include "TankProperties.hxx"
#include <simgear/math/SGMath.hxx>
#include <simgear/sg_inlines.h>
#include <Main/fg_props.hxx>
static const double LBS_PER_KG = 2.20462262;
@ -38,12 +39,14 @@ static const double M3_PER_IMPGAL = 1.0/IMPGAL_PER_M3;
TankProperties::TankProperties(SGPropertyNode_ptr rootNode ) :
_content_kg(0.0),
_density_kgpm3(0.0),
_capacity_m3(0.0)
_capacity_m3(0.0),
_unusable_m3(0.0)
{
_tiedProperties.setRoot( rootNode );
_tiedProperties.Tie("level-kg", this, &TankProperties::getContent_kg, &TankProperties::setContent_kg );
_tiedProperties.Tie("density-kgpm3", this, &TankProperties::getDensity_kgpm3, &TankProperties::setDensity_kgpm3 );
_tiedProperties.Tie("capacity-m3", this, &TankProperties::getCapacity_m3, &TankProperties::setCapacity_m3 );
_tiedProperties.Tie("unusable-m3", this, &TankProperties::getUnusable_m3, &TankProperties::setUnusable_m3 );
_tiedProperties.Tie("level-m3", this, &TankProperties::getContent_m3, &TankProperties::setContent_m3 );
_tiedProperties.Tie("level-norm", this, &TankProperties::getContent_norm, &TankProperties::setContent_norm );
@ -51,8 +54,14 @@ TankProperties::TankProperties(SGPropertyNode_ptr rootNode ) :
_tiedProperties.Tie("level-lbs", this, &TankProperties::getContent_lbs, &TankProperties::setContent_lbs );
_tiedProperties.Tie("level-gal_us", this, &TankProperties::getContent_gal_us, &TankProperties::setContent_gal_us );
_tiedProperties.Tie("level-gal_imp", this, &TankProperties::getContent_gal_imp, &TankProperties::setContent_gal_imp );
_tiedProperties.Tie("capacity-gal_us", this, &TankProperties::getCapacity_gal_us, &TankProperties::setCapacity_gal_us );
_tiedProperties.Tie("unusable-gal_us", this, &TankProperties::getUnusable_gal_us, &TankProperties::setUnusable_gal_us );
_tiedProperties.Tie("capacity-gal_imp", this, &TankProperties::getCapacity_gal_imp, &TankProperties::setCapacity_gal_imp );
_tiedProperties.Tie("unusable-gal_imp", this, &TankProperties::getUnusable_gal_imp, &TankProperties::setUnusable_gal_imp );
_tiedProperties.Tie("empty", this, &TankProperties::getEmpty );
}
TankProperties::~TankProperties()
@ -66,7 +75,7 @@ double TankProperties::getContent_kg() const
void TankProperties::setContent_kg( double value )
{
_content_kg = value;
_content_kg = SG_MAX2<double>(value, 0.0);
}
double TankProperties::getDensity_kgpm3() const
@ -76,7 +85,7 @@ double TankProperties::getDensity_kgpm3() const
void TankProperties::setDensity_kgpm3( double value )
{
_density_kgpm3 = value;
_density_kgpm3 = SG_MAX2<double>(value, 0.0);
}
double TankProperties::getDensity_ppg() const
@ -86,7 +95,7 @@ double TankProperties::getDensity_ppg() const
void TankProperties::setDensity_ppg( double value )
{
_density_kgpm3 = value * KG_PER_LBS / M3_PER_USGAL;
_density_kgpm3 = SG_MAX2<double>(value * KG_PER_LBS / M3_PER_USGAL, 0.0);
}
double TankProperties::getContent_lbs() const
@ -96,7 +105,7 @@ double TankProperties::getContent_lbs() const
void TankProperties::setContent_lbs( double value )
{
_content_kg = value * KG_PER_LBS;
_content_kg = SG_MAX2<double>(value * KG_PER_LBS, 0.0);
}
double TankProperties::getContent_m3() const
@ -106,7 +115,8 @@ double TankProperties::getContent_m3() const
void TankProperties::setContent_m3( double value )
{
_content_kg = value * _density_kgpm3;
// ugly hack to allow setting of a volumetric content without having the density
_content_kg = SG_MAX2<double>(value * (_density_kgpm3>0.0?_density_kgpm3:755.0), 0.0);
}
double TankProperties::getContent_gal_us() const
@ -136,7 +146,7 @@ double TankProperties::getCapacity_m3() const
void TankProperties::setCapacity_m3( double value )
{
_capacity_m3 = value;
_capacity_m3 = SG_MAX2<double>(value, 0.0);
}
double TankProperties::getCapacity_gal_us() const
@ -146,7 +156,7 @@ double TankProperties::getCapacity_gal_us() const
void TankProperties::setCapacity_gal_us( double value )
{
_capacity_m3 = value * M3_PER_USGAL;
_capacity_m3 = SG_MAX2<double>(value * M3_PER_USGAL, 0.0);
}
double TankProperties::getCapacity_gal_imp() const
@ -156,7 +166,38 @@ double TankProperties::getCapacity_gal_imp() const
void TankProperties::setCapacity_gal_imp( double value )
{
_capacity_m3 = value * M3_PER_IMPGAL;
_capacity_m3 = SG_MAX2<double>(value * M3_PER_IMPGAL, 0.0);
}
double TankProperties::getUnusable_m3() const
{
return _unusable_m3;
}
void TankProperties::setUnusable_m3( double value )
{
_unusable_m3 = SG_MAX2<double>(value, 0.0);
}
double TankProperties::getUnusable_gal_us() const
{
return _unusable_m3 * USGAL_PER_M3;
}
void TankProperties::setUnusable_gal_us( double value )
{
_unusable_m3 = SG_MAX2<double>(value * M3_PER_USGAL, 0.0);
}
double TankProperties::getUnusable_gal_imp() const
{
return _unusable_m3 * IMPGAL_PER_M3;
}
void TankProperties::setUnusable_gal_imp( double value )
{
_unusable_m3 = SG_MAX2<double>(value * M3_PER_IMPGAL, 0.0);
}
double TankProperties::getContent_norm() const
@ -169,12 +210,19 @@ void TankProperties::setContent_norm( double value )
setContent_m3(_capacity_m3 * value);
}
bool TankProperties::getEmpty() const
{
return getContent_m3() <= _unusable_m3;
}
TankPropertiesList::TankPropertiesList( SGPropertyNode_ptr rootNode )
{
// we don't have a global rule how many tanks we support, so I assume eight.
// Because hard coded values suck, make it settable by a property
size_type n = rootNode->getIntValue( "numtanks", 8 );
for( size_type i = 0; i < n; i++ ) {
// Because hard coded values suck, make it settable by a property.
// If tanks were configured, use that number
int n = rootNode->getChildren("tank").size();
if( n == 0 ) n = rootNode->getIntValue( "numtanks", 8 );
for( int i = 0; i < n; i++ ) {
push_back( new TankProperties( rootNode->getChild( "tank", i, true ) ) );
}

View file

@ -64,15 +64,27 @@ public:
double getCapacity_gal_imp() const;
void setCapacity_gal_imp( double value );
double getUnusable_m3() const;
void setUnusable_m3( double value );
double getUnusable_gal_us() const;
void setUnusable_gal_us( double value );
double getUnusable_gal_imp() const;
void setUnusable_gal_imp( double value );
double getContent_norm() const;
void setContent_norm( double value );
bool getEmpty() const;
protected:
simgear::TiedPropertyList _tiedProperties;
double _content_kg;
double _density_kgpm3;
double _capacity_m3;
double _unusable_m3;
};
class TankPropertiesList : std::vector<SGSharedPtr<TankProperties> > {

View file

@ -247,7 +247,7 @@ do_reinit (const SGPropertyNode * arg)
if (subsystem == 0) {
result = false;
SG_LOG( SG_GENERAL, SG_ALERT,
"Subsystem " << name << "not found" );
"Subsystem " << name << " not found" );
} else {
subsystem->reinit();
}
@ -280,7 +280,7 @@ do_suspend (const SGPropertyNode * arg)
SGSubsystem * subsystem = globals->get_subsystem(name);
if (subsystem == 0) {
result = false;
SG_LOG(SG_GENERAL, SG_ALERT, "Subsystem " << name << "not found");
SG_LOG(SG_GENERAL, SG_ALERT, "Subsystem " << name << " not found");
} else {
subsystem->suspend();
}
@ -304,7 +304,7 @@ do_resume (const SGPropertyNode * arg)
SGSubsystem * subsystem = globals->get_subsystem(name);
if (subsystem == 0) {
result = false;
SG_LOG(SG_GENERAL, SG_ALERT, "Subsystem " << name << "not found");
SG_LOG(SG_GENERAL, SG_ALERT, "Subsystem " << name << " not found");
} else {
subsystem->resume();
}

View file

@ -1557,8 +1557,7 @@ void fgReInitSubsystems()
globals->get_viewmgr()->reinit();
globals->get_subsystem("time")->reinit();
globals->get_subsystem("tile-manager")->reinit();
// setup state to end re-init
fgSetBool("/sim/signals/reinit", false);
if ( !freeze ) {

View file

@ -52,10 +52,33 @@ using simgear::SGModelLib;
using simgear::TileEntry;
using simgear::TileCache;
// helper: listen to property changes affecting tile loading
class LoaderPropertyWatcher : public SGPropertyChangeListener
{
public:
LoaderPropertyWatcher(FGTileMgr* pTileMgr) :
_pTileMgr(pTileMgr)
{
}
virtual void valueChanged(SGPropertyNode*)
{
_pTileMgr->configChanged();
}
private:
FGTileMgr* _pTileMgr;
};
FGTileMgr::FGTileMgr():
state( Start ),
vis( 16000 )
vis( 16000 ),
_propListener(new LoaderPropertyWatcher(this))
{
_randomObjects = fgGetNode("/sim/rendering/random-objects", true);
_randomVegetation = fgGetNode("/sim/rendering/random-vegetation", true);
}
@ -63,6 +86,8 @@ FGTileMgr::~FGTileMgr() {
// remove all nodes we might have left behind
osg::Group* group = globals->get_scenery()->get_terrain_branch();
group->removeChildren(0, group->getNumChildren());
delete _propListener;
_propListener = NULL;
}
@ -72,8 +97,11 @@ void FGTileMgr::init() {
_options = new SGReaderWriterBTGOptions;
_options->setMatlib(globals->get_matlib());
_options->setUseRandomObjects(fgGetBool("/sim/rendering/random-objects", true));
_options->setUseRandomVegetation(fgGetBool("/sim/rendering/random-vegetation", true));
_randomObjects.get()->addChangeListener(_propListener, false);
_randomVegetation.get()->addChangeListener(_propListener, false);
configChanged();
osgDB::FilePathList &fp = _options->getDatabasePathList();
const string_list &sc = globals->get_fg_scenery();
fp.clear();
@ -89,6 +117,9 @@ void FGTileMgr::init() {
void FGTileMgr::reinit()
{
// remove all old scenery nodes from scenegraph and clear cache
osg::Group* group = globals->get_scenery()->get_terrain_branch();
group->removeChildren(0, group->getNumChildren());
tile_cache.init();
state = Inited;
@ -101,6 +132,11 @@ void FGTileMgr::reinit()
update(0.0);
}
void FGTileMgr::configChanged()
{
_options->setUseRandomObjects(_randomObjects.get()->getBoolValue());
_options->setUseRandomVegetation(_randomVegetation.get()->getBoolValue());
}
/* schedule a tile for loading, keep request for given amount of time.
* Returns true if tile is already loaded. */

View file

@ -81,6 +81,9 @@ private:
void update_queues();
SGPropertyNode* _visibilityMeters;
SGPropertyChangeListener* _propListener;
SGPropertyNode_ptr _randomObjects;
SGPropertyNode_ptr _randomVegetation;
public:
FGTileMgr();
@ -93,6 +96,9 @@ public:
virtual void update(double dt);
// update loader configuration options
void configChanged();
int schedule_tiles_at(const SGGeod& location, double rangeM);

View file

@ -290,7 +290,7 @@ void sync_tree(const char* dir) {
#if defined(_MSC_VER) || defined(__MINGW32__)
typedef void (__cdecl * sighandler_t)(int);
#elif defined( __APPLE__ )
#elif defined( __APPLE__ ) || defined (__FreeBSD__)
typedef sig_t sighandler_t;
#endif