1
0
Fork 0
This commit is contained in:
Torsten Dreyer 2011-05-26 09:51:36 +02:00
commit efb8099a39
43 changed files with 1755 additions and 432 deletions

View file

@ -583,7 +583,7 @@ if test "x$ac_cv_header_simgear_version_h" != "xyes"; then
exit
fi
AC_MSG_CHECKING([for SimGear 2.2.0 or newer])
AC_MSG_CHECKING([for SimGear 2.3.0 or newer])
AC_TRY_RUN([
#include <stdio.h>
@ -593,7 +593,7 @@ AC_TRY_RUN([
#define XSTRINGIFY(X) #X
#define MIN_MAJOR 2
#define MIN_MINOR 2
#define MIN_MINOR 3
#define MIN_MICRO 0
int main() {

View file

@ -1,7 +1,7 @@
#!/bin/sh
SDK_PATH="/Developer/SDKs/MacOSX10.5.sdk"
OSX_TARGET="10.5"
SDK_PATH="/Developer/SDKs/MacOSX10.6.sdk"
OSX_TARGET="10.6"
svn co https://macflightgear.svn.sourceforge.net/svnroot/macflightgear/trunk/FlightGearOSX macflightgear

View file

@ -2977,6 +2977,14 @@
RelativePath="..\..\..\src\Network\AV400Sim.hxx"
>
</File>
<File
RelativePath="..\..\..\src\Network\AV400WSim.cxx"
>
</File>
<File
RelativePath="..\..\..\src\Network\AV400WSim.hxx"
>
</File>
<File
RelativePath="..\..\..\src\Network\garmin.cxx"
>

View file

@ -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();

View file

@ -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;

View file

@ -100,6 +100,7 @@ void FGReplay::init()
disable_replay = fgGetNode( "/sim/replay/disable", true );
replay_master = fgGetNode( "/sim/freeze/replay-state", true );
replay_time = fgGetNode( "/sim/replay/time", true);
replay_looped = fgGetNode( "/sim/replay/looped", true);
reinit();
}
@ -194,10 +195,28 @@ void FGReplay::update( double dt )
// replay inactive, keep recording
break;
case 1:
// replay active
replay( replay_time->getDoubleValue() );
replay_time->setDoubleValue( replay_time->getDoubleValue()
+ ( dt * fgGetInt("/sim/speed-up") ) );
{
// replay active
double current_time = replay_time->getDoubleValue();
if (current_time<0.0)
{
// initialize start time
fgSetDouble( "/sim/replay/start-time", get_start_time() );
fgSetDouble( "/sim/replay/end-time", get_end_time() );
double duration = fgGetDouble( "/sim/replay/duration" );
if( duration && duration < (get_end_time() - get_start_time()) ) {
current_time = get_end_time() - duration;
} else {
current_time = get_start_time();
}
}
bool IsFinished = replay( replay_time->getDoubleValue() );
if ((IsFinished)&&(replay_looped->getBoolValue()))
current_time = -1;
else
current_time += dt * fgGetInt("/sim/speed-up");
replay_time->setDoubleValue(current_time);
}
return; // don't record the replay session
case 2:
// replay paused, no-op
@ -279,7 +298,7 @@ void FGReplay::update( double dt )
FGReplayData *lt_front = long_term.front();
if ( sim_time - lt_front->sim_time > lt_list_time ) {
//stamp("point_10");
//stamp("point_10");
while ( sim_time - lt_front->sim_time > lt_list_time ) {
lt_front = long_term.front();
recycler.push_back(lt_front);
@ -558,9 +577,10 @@ static void interpolate( double time, const replay_list_type &list ) {
/**
* Replay a saved frame based on time, interpolate from the two
* nearest saved frames.
* Returns true when replay sequence has finished, false otherwise.
*/
void FGReplay::replay( double time ) {
bool FGReplay::replay( double time ) {
// cout << "replay: " << time << " ";
// find the two frames to interpolate between
double t1, t2;
@ -571,6 +591,8 @@ void FGReplay::replay( double time ) {
if ( time > t1 ) {
// replay the most recent frame
update_fdm( (*short_term.back()) );
// replay is finished now
return true;
// cout << "first frame" << endl;
} else if ( time <= t1 && time >= t2 ) {
interpolate( time, short_term );
@ -624,7 +646,9 @@ void FGReplay::replay( double time ) {
}
} else {
// nothing to replay
return true;
}
return false;
}

View file

@ -74,7 +74,7 @@ public:
virtual void unbind();
virtual void update( double dt );
void replay( double time );
bool replay( double time );
double get_start_time();
double get_end_time();
@ -101,6 +101,7 @@ private:
SGPropertyNode_ptr disable_replay;
SGPropertyNode_ptr replay_master;
SGPropertyNode_ptr replay_time;
SGPropertyNode_ptr replay_looped;
};

View file

@ -84,11 +84,17 @@ void XMLLoader::load(FGSidStar* p) {
bool XMLLoader::findAirportData(const std::string& aICAO,
const std::string& aFileName, SGPath& aPath)
{
string fileName(aFileName);
int extPos = fileName.size() - 4;
if ((int) fileName.rfind(".xml") != extPos) {
fileName.append(".xml");
}
string_list sc = globals->get_fg_scenery();
char buffer[128];
::snprintf(buffer, 128, "%c/%c/%c/%s.%s.xml",
::snprintf(buffer, 128, "%c/%c/%c/%s.%s",
aICAO[0], aICAO[1], aICAO[2],
aICAO.c_str(), aFileName.c_str());
aICAO.c_str(), fileName.c_str());
for (string_list_iterator it = sc.begin(); it != sc.end(); ++it) {
SGPath path(*it);

View file

@ -224,6 +224,15 @@ void FGRouteMgr::init() {
void FGRouteMgr::postinit()
{
SGPath path(_pathNode->getStringValue());
if (path.exists()) {
SG_LOG(SG_AUTOPILOT, SG_INFO, "loading flight-plan from:" << path.str());
loadRoute();
}
// this code only matters for the --wp option now - perhaps the option
// should be deprecated in favour of an explicit flight-plan file?
// then the global initial waypoint list could die.
string_list *waypoints = globals->get_initial_waypoints();
if (waypoints) {
string_list::iterator it;

View file

@ -27,7 +27,6 @@
#include <simgear/constants.h>
#include <simgear/debug/logstream.hxx>
#include <simgear/scene/sky/sky.hxx>
#include <simgear/environment/visual_enviro.hxx>
#include <simgear/scene/model/particles.hxx>
#include <Main/main.hxx>
@ -122,9 +121,9 @@ FGEnvironmentMgr::bind ()
&FGClouds::get_update_event,
&FGClouds::set_update_event);
_tiedProperties.Tie("turbulence/use-cloud-turbulence", &sgEnviro,
&SGEnviro::get_turbulence_enable_state,
&SGEnviro::set_turbulence_enable_state);
// _tiedProperties.Tie("turbulence/use-cloud-turbulence", &sgEnviro,
// &SGEnviro::get_turbulence_enable_state,
// &SGEnviro::set_turbulence_enable_state);
for (int i = 0; i < MAX_CLOUD_LAYERS; i++) {
SGPropertyNode_ptr layerNode = fgGetNode("/environment/clouds",true)->getChild("layer", i, true );
@ -176,15 +175,10 @@ FGEnvironmentMgr::bind ()
&SGSky::get_3dCloudVisRange,
&SGSky::set_3dCloudVisRange);
_tiedProperties.Tie("precipitation-enable", &sgEnviro,
&SGEnviro::get_precipitation_enable_state,
&SGEnviro::set_precipitation_enable_state);
// _tiedProperties.Tie("lightning-enable", &sgEnviro,
// &SGEnviro::get_lightning_enable_state,
// &SGEnviro::set_lightning_enable_state);
_tiedProperties.Tie("lightning-enable", &sgEnviro,
&SGEnviro::get_lightning_enable_state,
&SGEnviro::set_lightning_enable_state);
sgEnviro.config(fgGetNode("/sim/rendering/precipitation"));
}
void

View file

@ -30,7 +30,7 @@
#include <simgear/constants.h>
#include <simgear/sound/soundmgr_openal.hxx>
#include <simgear/scene/sky/sky.hxx>
#include <simgear/environment/visual_enviro.hxx>
//#include <simgear/environment/visual_enviro.hxx>
#include <simgear/scene/sky/cloudfield.hxx>
#include <simgear/scene/sky/newcloud.hxx>
#include <simgear/structure/commands.hxx>
@ -47,7 +47,9 @@ extern SGSky *thesky;
FGClouds::FGClouds() :
#if 0
snd_lightning(0),
#endif
clouds_3d_enabled(false),
index(0)
{
@ -68,6 +70,7 @@ void FGClouds::set_update_event(int count) {
}
void FGClouds::Init(void) {
#if 0
if( snd_lightning == NULL ) {
snd_lightning = new SGSoundSample("Sounds/thunder.wav", SGPath());
snd_lightning->set_max_dist(7000.0f);
@ -75,8 +78,8 @@ void FGClouds::Init(void) {
SGSoundMgr *smgr = globals->get_soundmgr();
SGSampleGroup *sgr = smgr->find("weather", true);
sgr->add( snd_lightning, "thunder" );
sgEnviro.set_sampleGroup( sgr );
}
#endif
globals->get_commands()->addCommand("add-cloud", do_add_3Dcloud);
globals->get_commands()->addCommand("del-cloud", do_delete_3Dcloud);

View file

@ -45,7 +45,9 @@ private:
void buildCloudLayers(void);
int update_event;
#if 0
SGSoundSample *snd_lightning;
#endif
bool clouds_3d_enabled;
int index;

View file

@ -36,7 +36,6 @@
#include <simgear/math/SGMath.hxx>
#include <simgear/scene/sky/sky.hxx>
#include <simgear/scene/sky/cloud.hxx>
#include <simgear/environment/visual_enviro.hxx>
#include <Main/fg_props.hxx>
#include <Main/globals.hxx>
@ -93,6 +92,19 @@ void FGPrecipitationMgr::init()
fgGetNode("environment/params/precipitation-level-ft", true);
}
void FGPrecipitationMgr::bind ()
{
_tiedProperties.setRoot( fgGetNode("/sim/rendering", true ) );
_tiedProperties.Tie("precipitation-enable", precipitation.get(),
&SGPrecipitation::getEnabled,
&SGPrecipitation::setEnabled);
}
void FGPrecipitationMgr::unbind ()
{
_tiedProperties.Untie();
}
void FGPrecipitationMgr::setPrecipitationLevel(double a)
{
fgSetDouble("environment/params/precipitation-level-ft",a);
@ -206,7 +218,7 @@ void FGPrecipitationMgr::update(double dt)
setPrecipitationLevel(altitudeCloudLayer);
// Does the user enable the precipitation ?
if (!sgEnviro.get_precipitation_enable_state()) {
if (!precipitation->getEnabled() ) {
// Disable precipitations
precipitation->setRainIntensity(0);
precipitation->setSnowIntensity(0);

View file

@ -31,7 +31,7 @@
#include <simgear/structure/subsystem_mgr.hxx>
#include <simgear/environment/precipitation.hxx>
#include <simgear/props/tiedpropertylist.hxx>
class FGPrecipitationMgr : public SGSubsystem
{
@ -40,12 +40,15 @@ private:
osg::ref_ptr<osg::MatrixTransform> transform;
osg::ref_ptr<SGPrecipitation> precipitation;
float getPrecipitationAtAltitudeMax(void);
simgear::TiedPropertyList _tiedProperties;
public:
FGPrecipitationMgr();
virtual ~FGPrecipitationMgr();
// SGSubsystem methods
virtual void bind ();
virtual void unbind ();
virtual void init ();
virtual void update (double dt);

View file

@ -114,12 +114,38 @@ private:
FGJSBsim* mInterface;
};
// FG uses a squared normalized magnitude for turbulence
// this lookup table maps fg's severity levels
// none(0), light(1/3), moderate(2/3) and severe(3/3)
// to the POE table indexes 0, 3, 4 and 7
class FGTurbulenceSeverityTable : public FGTable {
public:
FGTurbulenceSeverityTable() : FGTable(4) {
*this << (0.0/9.0) << 0.0;
*this << (1.0/9.0) << 3.0;
*this << (4.0/9.0) << 4.0;
*this << (9.0/9.0) << 7.0;
}
};
/******************************************************************************/
std::map<std::string,int> FGJSBsim::TURBULENCE_TYPE_NAMES;
static FGTurbulenceSeverityTable TurbulenceSeverityTable;
FGJSBsim::FGJSBsim( double dt )
: FGInterface(dt), got_wire(false)
{
bool result;
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["ttCulp"] = FGAtmosphere::ttCulp;
TURBULENCE_TYPE_NAMES["ttMilspec"] = FGAtmosphere::ttMilspec;
TURBULENCE_TYPE_NAMES["ttTustin"] = FGAtmosphere::ttTustin;
}
// Set up the debugging level
// FIXME: this will not respond to
// runtime changes
@ -282,8 +308,10 @@ FGJSBsim::FGJSBsim( double dt )
temperature = fgGetNode("/environment/temperature-degc",true);
pressure = fgGetNode("/environment/pressure-inhg",true);
density = fgGetNode("/environment/density-slugft3",true);
ground_wind = fgGetNode("/environment/config/boundary/entry[0]/wind-speed-kt",true);
turbulence_gain = fgGetNode("/environment/turbulence/magnitude-norm",true);
turbulence_rate = fgGetNode("/environment/turbulence/rate-hz",true);
turbulence_model = fgGetNode("/environment/params/jsbsim-turbulence-model",true);
wind_from_north= fgGetNode("/environment/wind-from-north-fps",true);
wind_from_east = fgGetNode("/environment/wind-from-east-fps" ,true);
@ -331,10 +359,12 @@ void FGJSBsim::init()
9.0/5.0*(temperature->getDoubleValue()+273.15) );
Atmosphere->SetExPressure(pressure->getDoubleValue()*70.726566);
Atmosphere->SetExDensity(density->getDoubleValue());
Atmosphere->SetTurbType(FGAtmosphere::ttCulp);
Atmosphere->SetTurbGain(turbulence_gain->getDoubleValue());
Atmosphere->SetTurbRate(turbulence_rate->getDoubleValue());
// initialize to no turbulence, these values get set in the update loop
Atmosphere->SetTurbType(FGAtmosphere::ttNone);
Atmosphere->SetTurbGain(0.0);
Atmosphere->SetTurbRate(0.0);
Atmosphere->SetWindspeed20ft(0.0);
Atmosphere->SetProbabilityOfExceedence(0.0);
} else {
Atmosphere->UseInternal();
}
@ -351,14 +381,12 @@ void FGJSBsim::init()
<< ", " << fdmex->GetAtmosphere()->GetDensity() );
// deprecate egt_degf for egt-degf to have consistent naming
// TODO: raise log-level to ALERT in summer 2010,
// remove alias in fall 2010,
// remove this code in winter 2010
// TODO: remove this by end of 2011
for (unsigned int i=0; i < Propulsion->GetNumEngines(); i++) {
SGPropertyNode * node = fgGetNode("engines/engine", i, true);
SGPropertyNode * egtn = node->getNode( "egt_degf" );
if( egtn != NULL ) {
SG_LOG(SG_FLIGHT,SG_WARN,
SG_LOG(SG_FLIGHT,SG_ALERT,
"Aircraft uses deprecated node egt_degf. Please upgrade to egt-degf");
node->getNode("egt-degf", true)->alias( egtn );
}
@ -590,7 +618,6 @@ void FGJSBsim::resume()
bool FGJSBsim::copy_to_JSBsim()
{
double tmp;
unsigned int i;
// copy control positions into the JSBsim structure
@ -686,11 +713,31 @@ bool FGJSBsim::copy_to_JSBsim()
Atmosphere->SetExPressure(pressure->getDoubleValue()*70.726566);
Atmosphere->SetExDensity(density->getDoubleValue());
tmp = turbulence_gain->getDoubleValue();
//Atmosphere->SetTurbGain(tmp * tmp * 100.0);
Atmosphere->SetTurbType((FGAtmosphere::tType)TURBULENCE_TYPE_NAMES[turbulence_model->getStringValue()]);
switch( Atmosphere->GetTurbType() ) {
case FGAtmosphere::ttStandard:
case FGAtmosphere::ttCulp:
case FGAtmosphere::ttBerndt: {
double tmp = turbulence_gain->getDoubleValue();
Atmosphere->SetTurbGain(tmp * tmp * 100.0);
Atmosphere->SetTurbRate(turbulence_rate->getDoubleValue());
break;
}
case FGAtmosphere::ttMilspec:
case FGAtmosphere::ttTustin: {
// milspec turbulence: 3=light, 4=moderate, 6=severe turbulence
// turbulence_gain normalized: 0: none, 1/3: light, 2/3: moderate, 3/3: severe
double tmp = turbulence_gain->getDoubleValue();
Atmosphere->SetProbabilityOfExceedence(
SGMiscd::roundToInt(TurbulenceSeverityTable.GetValue( tmp ) )
);
Atmosphere->SetWindspeed20ft(ground_wind->getDoubleValue());
break;
}
tmp = turbulence_rate->getDoubleValue();
//Atmosphere->SetTurbRate(tmp);
default:
break;
}
Atmosphere->SetWindNED( -wind_from_north->getDoubleValue(),
-wind_from_east->getDoubleValue(),

View file

@ -271,8 +271,10 @@ private:
SGPropertyNode_ptr temperature;
SGPropertyNode_ptr pressure;
SGPropertyNode_ptr density;
SGPropertyNode_ptr ground_wind;
SGPropertyNode_ptr turbulence_gain;
SGPropertyNode_ptr turbulence_rate;
SGPropertyNode_ptr turbulence_model;
SGPropertyNode_ptr wind_from_north;
SGPropertyNode_ptr wind_from_east;
@ -280,6 +282,8 @@ private:
SGPropertyNode_ptr slaved;
static std::map<std::string,int> TURBULENCE_TYPE_NAMES;
double last_hook_tip[3];
double last_hook_root[3];
JSBSim::FGColumnVector3 hook_root_struct;

View file

@ -27,7 +27,7 @@
# include <config.h>
#endif
#include <memory>
#include <cstring>
#include <simgear/math/SGMathFwd.hxx> // for SGVec3d
#include <simgear/math/SGMisc.hxx>

View file

@ -386,6 +386,7 @@ MapWidget::MapWidget(int x, int y, int maxX, int maxY) :
_zoom = 6;
_width = maxX - x;
_height = maxY - y;
_hasPanned = false;
MapData::setFont(legendFont);
MapData::setPalette(colour);
@ -496,6 +497,7 @@ int MapWidget::checkKey (int key, int updown )
void MapWidget::pan(const SGVec2d& delta)
{
_hasPanned = true;
_projectionCenter = unproject(-delta);
}
@ -525,6 +527,12 @@ void MapWidget::draw(int dx, int dy)
fgGetDouble("/position/latitude-deg"));
_magneticHeadings = _root->getBoolValue("magnetic-headings");
if (_hasPanned)
{
_root->setBoolValue("centre-on-aircraft", false);
_hasPanned = false;
}
else
if (_root->getBoolValue("centre-on-aircraft")) {
_projectionCenter = _aircraft;
}

View file

@ -85,6 +85,7 @@ private:
double _drawRangeNm;
double _upHeading; // true heading corresponding to +ve y-axis
bool _magneticHeadings;
bool _hasPanned;
SGGeod _projectionCenter;
SGGeod _aircraft;

View file

@ -23,8 +23,8 @@
// $Id$
#include "FGMouseInput.hxx"
#include "Main/globals.hxx"
void ActivePickCallbacks::init( int b, const osgGA::GUIEventAdapter* ea )
{
// Get the list of hit callbacks. Take the first callback that
@ -33,7 +33,7 @@ void ActivePickCallbacks::init( int b, const osgGA::GUIEventAdapter* ea )
// The nearest one is the first one and the deepest
// (the most specialized one in the scenegraph) is the first.
std::vector<SGSceneryPick> pickList;
if (FGRenderer::pick(pickList, ea)) {
if (globals->get_renderer()->pick(pickList, ea)) {
std::vector<SGSceneryPick>::const_iterator i;
for (i = pickList.begin(); i != pickList.end(); ++i) {
if (i->callback->buttonPressed(b, i->info)) {

View file

@ -269,7 +269,7 @@ public:
_offset = n->getFloatValue("offset", offset);
_min = n->getFloatValue("min", min);
_max = n->getFloatValue("max", max);
_coeff = 1.0 - 1.0 / powf(10, fabsf(n->getFloatValue("damp", 0.0)));
_coeff = 1.0 - 1.0 / powf(10, fabs(n->getFloatValue("damp", 0.0)));
SGPropertyNode *p = ((SGPropertyNode *)n)->getNode("property", false);
if (p) {
const char *path = p->getStringValue();

View file

@ -89,7 +89,7 @@ void HUD::Label::draw(void)
l = _center_x - pw;
r = _center_x + pw;
bool draw_parallel = fabsf(_pointer_width - _w) > 2.0; // draw lines left and right of arrow?
bool draw_parallel = fabs(_pointer_width - _w) > 2.0; // draw lines left and right of arrow?
if (option_bottom()) {
if (draw_parallel) {
@ -115,7 +115,7 @@ void HUD::Label::draw(void)
l = _center_y - pw;
r = _center_y + pw;
draw_parallel = fabsf(_pointer_width - _h) > 2.0;
draw_parallel = fabs(_pointer_width - _h) > 2.0;
if (option_left()) {
if (draw_parallel) {

View file

@ -48,7 +48,7 @@ HUD::Ladder::Ladder(HUD *hud, const SGPropertyNode *n, float x, float y) :
_roll(n->getNode("roll-input", false)),
_width_units(int(n->getFloatValue("display-span"))),
_div_units(int(fabs(n->getFloatValue("divisions")))),
_scr_hole(fabsf(n->getFloatValue("screen-hole")) * 0.5f),
_scr_hole(fabs(n->getFloatValue("screen-hole")) * 0.5f),
_zero_bar_overlength(n->getFloatValue("zero-bar-overlength", 10)),
_dive_bar_angle(n->getBoolValue("enable-dive-bar-angle")),
_tick_length(n->getFloatValue("tick-length")),

View file

@ -534,7 +534,7 @@ void HUD::Tape::draw_horizontal(float value)
char *HUD::Tape::format_value(float v)
{
if (fabsf(v) < 1e-8) // avoid -0.0
if (fabs(v) < 1e-8) // avoid -0.0
v = 0.0f;
if (_label_fmt == INT)

View file

@ -129,12 +129,12 @@ void HUD::TurnBankIndicator::draw_scale()
int dir = bank > 0 ? 1 : -1;
if (fabsf(bank) > 25) {
if (fabs(bank) > 25) {
draw_tick(45, r, minor, dir);
draw_tick(60, r, major, dir);
}
if (fabsf(bank) > 55) {
if (fabs(bank) > 55) {
draw_tick(90, r, major, dir);
draw_tick(135, r, major, dir);
}

View file

@ -38,7 +38,6 @@
#include <simgear/constants.h>
#include <simgear/misc/sg_path.hxx>
#include <simgear/environment/visual_enviro.hxx>
#include <simgear/scene/model/model.hxx>
#include <simgear/structure/exception.hxx>
#include <simgear/misc/sg_path.hxx>
@ -137,7 +136,7 @@ wxRadarBg::init ()
SGPath tpath = globals->resolve_aircraft_path(path);
// no mipmap or else alpha will mix with pixels on the border of shapes, ruining the effect
_wxEcho = SGLoadTexture2D(tpath, false, false);
_wxEcho = SGLoadTexture2D(tpath, NULL, false, false);
_Instrument->setFloatValue("trk", 0.0);
@ -379,90 +378,99 @@ wxRadarBg::update (double delta_time_sec)
_texCoords->clear();
_textGeode->removeDrawables(0, _textGeode->getNumDrawables());
#if 0
//TODO FIXME Mask below (only used for ARC mode) isn't properly aligned, i.e.
// it assumes the a/c position at the center of the display - though it's somewhere at
// bottom part for ARC mode.
// The mask hadn't worked at all for a while (probably since the OSG port) due to
// another bug (which is fixed now). Now, the mask is disabled completely until s.o.
// adapted the coordinates below. And the mask is only really useful to limit displayed
// weather blobs (not support yet).
// Aircraft echos are already limited properly through wxradar's "limit-deg" property.
{
osg::DrawArrays *maskPSet
= static_cast<osg::DrawArrays*>(_geom->getPrimitiveSet(1));
osg::DrawArrays *trimaskPSet
= static_cast<osg::DrawArrays*>(_geom->getPrimitiveSet(2));
if (_display_mode == ARC) {
// erase what is out of sight of antenna
/*
|\ /|
| \ / |
| \ / |
---------
| |
| |
---------
*/
float xOffset = 256.0f;
float yOffset = 200.0f;
int firstQuadVert = _vertices->size();
_texCoords->push_back(osg::Vec2f(0.5f, 0.25f));
_vertices->push_back(osg::Vec2f(-xOffset, 0.0 + yOffset));
_texCoords->push_back(osg::Vec2f(1.0f, 0.25f));
_vertices->push_back(osg::Vec2f(xOffset, 0.0 + yOffset));
_texCoords->push_back(osg::Vec2f(1.0f, 0.5f));
_vertices->push_back(osg::Vec2f(xOffset, 256.0 + yOffset));
_texCoords->push_back(osg::Vec2f(0.5f, 0.5f));
_vertices->push_back(osg::Vec2f(-xOffset, 256.0 + yOffset));
maskPSet->set(osg::PrimitiveSet::QUADS, firstQuadVert, 4);
firstQuadVert += 4;
// The triangles aren't supposed to be textured, but there's
// no need to set up a different Geometry, switch modes,
// etc. I happen to know that there's a white pixel in the
// texture at 1.0, 0.0 :)
float centerY = tan(30 * SG_DEGREES_TO_RADIANS);
_vertices->push_back(osg::Vec2f(0.0, 0.0));
_vertices->push_back(osg::Vec2f(-256.0, 0.0));
_vertices->push_back(osg::Vec2f(-256.0, 256.0 * centerY));
_vertices->push_back(osg::Vec2f(0.0, 0.0));
_vertices->push_back(osg::Vec2f(256.0, 0.0));
_vertices->push_back(osg::Vec2f(256.0, 256.0 * centerY));
_vertices->push_back(osg::Vec2f(-256, 0.0));
_vertices->push_back(osg::Vec2f(256.0, 0.0));
_vertices->push_back(osg::Vec2f(-256.0, -256.0));
_vertices->push_back(osg::Vec2f(256, 0.0));
_vertices->push_back(osg::Vec2f(256.0, -256.0));
_vertices->push_back(osg::Vec2f(-256.0, -256.0));
const osg::Vec2f whiteSpot(1.0f, 0.0f);
for (int i = 0; i < 3 * 4; i++)
_texCoords->push_back(whiteSpot);
trimaskPSet->set(osg::PrimitiveSet::TRIANGLES, firstQuadVert, 3 * 4);
} else
{
maskPSet->set(osg::PrimitiveSet::QUADS, 0, 0);
trimaskPSet->set(osg::PrimitiveSet::TRIANGLES, 0, 0);
}
maskPSet->dirty();
trimaskPSet->dirty();
}
#endif
// remember index of next vertex
int vIndex = _vertices->size();
update_weather();
osg::DrawArrays *quadPSet
= static_cast<osg::DrawArrays*>(_geom->getPrimitiveSet(0));
quadPSet->set(osg::PrimitiveSet::QUADS, 0, _vertices->size());
quadPSet->dirty();
// erase what is out of sight of antenna
/*
|\ /|
| \ / |
| \ / |
---------
| |
| |
---------
*/
osg::DrawArrays *maskPSet
= static_cast<osg::DrawArrays*>(_geom->getPrimitiveSet(1));
osg::DrawArrays *trimaskPSet
= static_cast<osg::DrawArrays*>(_geom->getPrimitiveSet(2));
if (_display_mode == ARC) {
float xOffset = 256.0f;
float yOffset = 200.0f;
int firstQuadVert = _vertices->size();
_texCoords->push_back(osg::Vec2f(0.5f, 0.25f));
_vertices->push_back(osg::Vec2f(-xOffset, 0.0 + yOffset));
_texCoords->push_back(osg::Vec2f(1.0f, 0.25f));
_vertices->push_back(osg::Vec2f(xOffset, 0.0 + yOffset));
_texCoords->push_back(osg::Vec2f(1.0f, 0.5f));
_vertices->push_back(osg::Vec2f(xOffset, 256.0 + yOffset));
_texCoords->push_back(osg::Vec2f(0.5f, 0.5f));
_vertices->push_back(osg::Vec2f(-xOffset, 256.0 + yOffset));
maskPSet->set(osg::PrimitiveSet::QUADS, firstQuadVert, 4);
// The triangles aren't supposed to be textured, but there's
// no need to set up a different Geometry, switch modes,
// etc. I happen to know that there's a white pixel in the
// texture at 1.0, 0.0 :)
float centerY = tan(30 * SG_DEGREES_TO_RADIANS);
_vertices->push_back(osg::Vec2f(0.0, 0.0));
_vertices->push_back(osg::Vec2f(-256.0, 0.0));
_vertices->push_back(osg::Vec2f(-256.0, 256.0 * centerY));
_vertices->push_back(osg::Vec2f(0.0, 0.0));
_vertices->push_back(osg::Vec2f(256.0, 0.0));
_vertices->push_back(osg::Vec2f(256.0, 256.0 * centerY));
_vertices->push_back(osg::Vec2f(-256, 0.0));
_vertices->push_back(osg::Vec2f(256.0, 0.0));
_vertices->push_back(osg::Vec2f(-256.0, -256.0));
_vertices->push_back(osg::Vec2f(256, 0.0));
_vertices->push_back(osg::Vec2f(256.0, -256.0));
_vertices->push_back(osg::Vec2f(-256.0, -256.0));
const osg::Vec2f whiteSpot(1.0f, 0.0f);
for (int i = 0; i < 3 * 4; i++)
_texCoords->push_back(whiteSpot);
trimaskPSet->set(osg::PrimitiveSet::TRIANGLES, firstQuadVert + 4, 3 * 4);
} else {
maskPSet->set(osg::PrimitiveSet::QUADS, 0, 0);
trimaskPSet->set(osg::PrimitiveSet::TRIANGLES, 0, 0);
}
maskPSet->dirty();
trimaskPSet->dirty();
// draw without mask
_vertices->clear();
_texCoords->clear();
update_aircraft();
update_tacan();
update_heading_marker();
quadPSet->set(osg::PrimitiveSet::QUADS, 0, _vertices->size());
// draw all new vertices are quads
quadPSet->set(osg::PrimitiveSet::QUADS, vIndex, _vertices->size()-vIndex);
quadPSet->dirty();
}
}
@ -472,13 +480,16 @@ void
wxRadarBg::update_weather()
{
string modeButton = _Instrument->getStringValue("mode", "WX");
_radarEchoBuffer = *sgEnviro.get_radar_echo();
// FIXME: implementation of radar echoes missing
// _radarEchoBuffer = *sgEnviro.get_radar_echo();
// pretend we have a scan angle bigger then the FOV
// TODO:check real fov, enlarge if < nn, and do clipping if > mm
// const float fovFactor = 1.45f;
_Instrument->setStringValue("status", modeButton.c_str());
// FIXME: implementation of radar echoes missing
#if 0
list_of_SGWxRadarEcho *radarEcho = &_radarEchoBuffer;
list_of_SGWxRadarEcho::iterator iradarEcho, end = radarEcho->end();
const float LWClevel[] = { 0.1f, 0.5f, 2.1f };
@ -558,6 +569,7 @@ wxRadarBg::update_weather()
addQuad(_vertices, _texCoords, m, texBase);
}
}
#endif
}

View file

@ -30,7 +30,6 @@
#include <simgear/props/props.hxx>
#include <simgear/structure/subsystem_mgr.hxx>
#include <simgear/environment/visual_enviro.hxx>
#include <vector>
#include <string>
@ -148,7 +147,8 @@ private:
float _font_size;
float _font_spacing;
list_of_SGWxRadarEcho _radarEchoBuffer;
// FIXME: implementation of radar echoes missing
// list_of_SGWxRadarEcho _radarEchoBuffer;
void update_weather();
void update_aircraft();

View file

@ -33,7 +33,7 @@
#include <Scenery/scenery.hxx>
#include <Scripting/NasalSys.hxx>
#include <Sound/sample_queue.hxx>
#include <Time/sunsolver.hxx>
#include <Airports/xmlloader.hxx>
#include "fg_init.hxx"
#include "fg_io.hxx"
@ -314,6 +314,16 @@ do_resume (const SGPropertyNode * arg)
#endif
static bool
do_pause (const SGPropertyNode * arg)
{
bool paused = fgGetBool("/sim/freeze/master",true) || fgGetBool("/sim/freeze/clock",true);
fgSetBool("/sim/freeze/master",!paused);
fgSetBool("/sim/freeze/clock",!paused);
if (fgGetBool("/sim/freeze/replay-state",false))
fgSetBool("/sim/replay/disable",true);
return true;
}
/**
* Built-in command: load flight.
@ -688,85 +698,6 @@ do_set_dewpoint_degc (const SGPropertyNode * arg)
return do_set_dewpoint_sea_level_degc(dummy.get_dewpoint_sea_level_degc());
}
#endif
/**
* Update the lighting manually.
*/
static bool
do_timeofday (const SGPropertyNode * arg)
{
const string &offset_type = arg->getStringValue("timeofday", "noon");
static const SGPropertyNode *longitude
= fgGetNode("/position/longitude-deg");
static const SGPropertyNode *latitude
= fgGetNode("/position/latitude-deg");
int orig_warp = globals->get_warp();
SGTime *t = globals->get_time_params();
time_t cur_time = t->get_cur_time();
// cout << "cur_time = " << cur_time << endl;
// cout << "orig_warp = " << orig_warp << endl;
int warp = 0;
if ( offset_type == "real" ) {
warp = -orig_warp;
} else if ( offset_type == "dawn" ) {
warp = fgTimeSecondsUntilSunAngle( cur_time,
longitude->getDoubleValue()
* SGD_DEGREES_TO_RADIANS,
latitude->getDoubleValue()
* SGD_DEGREES_TO_RADIANS,
90.0, true );
} else if ( offset_type == "morning" ) {
warp = fgTimeSecondsUntilSunAngle( cur_time,
longitude->getDoubleValue()
* SGD_DEGREES_TO_RADIANS,
latitude->getDoubleValue()
* SGD_DEGREES_TO_RADIANS,
75.0, true );
} else if ( offset_type == "noon" ) {
warp = fgTimeSecondsUntilSunAngle( cur_time,
longitude->getDoubleValue()
* SGD_DEGREES_TO_RADIANS,
latitude->getDoubleValue()
* SGD_DEGREES_TO_RADIANS,
0.0, true );
} else if ( offset_type == "afternoon" ) {
warp = fgTimeSecondsUntilSunAngle( cur_time,
longitude->getDoubleValue()
* SGD_DEGREES_TO_RADIANS,
latitude->getDoubleValue()
* SGD_DEGREES_TO_RADIANS,
60.0, false );
} else if ( offset_type == "dusk" ) {
warp = fgTimeSecondsUntilSunAngle( cur_time,
longitude->getDoubleValue()
* SGD_DEGREES_TO_RADIANS,
latitude->getDoubleValue()
* SGD_DEGREES_TO_RADIANS,
90.0, false );
} else if ( offset_type == "evening" ) {
warp = fgTimeSecondsUntilSunAngle( cur_time,
longitude->getDoubleValue()
* SGD_DEGREES_TO_RADIANS,
latitude->getDoubleValue()
* SGD_DEGREES_TO_RADIANS,
100.0, false );
} else if ( offset_type == "midnight" ) {
warp = fgTimeSecondsUntilSunAngle( cur_time,
longitude->getDoubleValue()
* SGD_DEGREES_TO_RADIANS,
latitude->getDoubleValue()
* SGD_DEGREES_TO_RADIANS,
180.0, false );
}
fgSetInt("/sim/time/warp", orig_warp + warp);
return true;
}
/**
* Built-in command: toggle a bool property value.
@ -1247,17 +1178,7 @@ do_replay (const SGPropertyNode * arg)
fgSetInt( "/sim/freeze/replay-state", 1 );
fgSetBool("/sim/freeze/master", 0 );
fgSetBool("/sim/freeze/clock", 0 );
FGReplay *r = (FGReplay *)(globals->get_subsystem( "replay" ));
fgSetDouble( "/sim/replay/start-time", r->get_start_time() );
fgSetDouble( "/sim/replay/end-time", r->get_end_time() );
double duration = fgGetDouble( "/sim/replay/duration" );
if( duration && duration < (r->get_end_time() - r->get_start_time()) ) {
fgSetDouble( "/sim/replay/time", r->get_end_time() - duration );
} else {
fgSetDouble( "/sim/replay/time", r->get_start_time() );
}
fgSetDouble( "/sim/replay/time", -1 );
// cout << "start = " << r->get_start_time()
// << " end = " << r->get_end_time() << endl;
@ -1301,11 +1222,20 @@ do_load_xml_to_proptree(const SGPropertyNode * arg)
if (file.extension() != "xml")
file.concat(".xml");
if (file.isRelative()) {
file = globals->resolve_maybe_aircraft_path(file.str());
std::string icao = arg->getStringValue("icao");
if (icao.empty()) {
if (file.isRelative()) {
file = globals->resolve_maybe_aircraft_path(file.str());
}
} else {
if (!XMLLoader::findAirportData(icao, file.str(), file)) {
SG_LOG(SG_IO, SG_INFO, "loadxml: failed to find airport data for "
<< file.str() << " at ICAO:" << icao);
return false;
}
}
if (!fgValidatePath(file.c_str(), false)) {
SG_LOG(SG_IO, SG_ALERT, "loadxml: reading '" << file.str() << "' denied "
"(unauthorized access)");
@ -1442,6 +1372,7 @@ static struct {
{ "reinit", do_reinit },
{ "suspend", do_reinit },
{ "resume", do_reinit },
{ "pause", do_pause },
{ "load", do_load },
{ "save", do_save },
{ "panel-load", do_panel_load },
@ -1457,7 +1388,6 @@ static struct {
{ "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 },
{ "property-adjust", do_property_adjust },

View file

@ -46,6 +46,7 @@
#include <Network/atlas.hxx>
#include <Network/AV400.hxx>
#include <Network/AV400Sim.hxx>
#include <Network/AV400WSim.hxx>
#include <Network/garmin.hxx>
#include <Network/httpd.hxx>
#ifdef FG_JPEG_SERVER
@ -142,7 +143,13 @@ FGIO::parse_port_config( const string& config )
} else if ( protocol == "AV400Sim" ) {
FGAV400Sim *av400sim = new FGAV400Sim;
io = av400sim;
} else if ( protocol == "garmin" ) {
} else if ( protocol == "AV400WSimA" ) {
FGAV400WSimA *av400wsima = new FGAV400WSimA;
io = av400wsima;
} else if ( protocol == "AV400WSimB" ) {
FGAV400WSimB *av400wsimb = new FGAV400WSimB;
io = av400wsimb;
} else if ( protocol == "garmin" ) {
FGGarmin *garmin = new FGGarmin;
io = garmin;
} else if ( protocol == "httpd" ) {
@ -263,6 +270,17 @@ FGIO::parse_port_config( const string& config )
SGSerial *ch = new SGSerial( device, baud );
io->set_io_channel( ch );
if ( protocol == "AV400WSimB" ) {
if ( tokens.size() < 7 ) {
SG_LOG( SG_IO, SG_ALERT, "Missing second hz for AV400WSimB.");
return NULL;
}
FGAV400WSimB *fgavb = static_cast<FGAV400WSimB*>(io);
string hz2_str = tokens[6];
double hz2 = atof(hz2_str.c_str());
fgavb->set_hz2(hz2);
}
} else if ( medium == "file" ) {
// file name
if ( tokens.size() < 4) {

View file

@ -306,6 +306,7 @@ void fgWarpMouse(int x, int y)
void fgOSInit(int* argc, char** argv)
{
globals->get_renderer()->init();
WindowSystemAdapter::setWSA(new WindowSystemAdapter);
}

View file

@ -241,7 +241,8 @@ void FGGlobals::set_fg_scenery (const string &scenery)
string_list path_list = sgPathSplit( s.str() );
fg_scenery.clear();
SGPropertyNode* sim = fgGetNode("/sim", true);
for (unsigned i = 0; i < path_list.size(); i++) {
SGPath path(path_list[i]);
if (!path.exists()) {
@ -271,6 +272,12 @@ void FGGlobals::set_fg_scenery (const string &scenery)
// FG_SCENERY=A:B becomes list ["A/Terrain", "A/Objects", "",
// "B/Terrain", "B/Objects", ""]
fg_scenery.push_back("");
// make scenery dirs available to Nasal
sim->removeChild("fg-scenery", i, false);
SGPropertyNode* n = sim->getChild("fg-scenery", i, true);
n->setStringValue(path.str());
n->setAttribute(SGPropertyNode::WRITE, false);
} // of path list iteration
}

View file

@ -203,6 +203,7 @@ static void fgMainLoop( void ) {
if (globals->get_tile_mgr()->isSceneryLoaded()
&& fgGetBool("sim/fdm-initialized")) {
fgSetBool("sim/sceneryloaded",true);
fgSplashProgress("");
if (fgGetBool("/sim/sound/working")) {
globals->get_soundmgr()->activate();
}
@ -211,6 +212,7 @@ static void fgMainLoop( void ) {
}
else
{
fgSplashProgress("loading scenery");
// be nice to loader threads while waiting for initial scenery, reduce to 2fps
simgear::sleepForMSec(500);
}
@ -313,7 +315,7 @@ SGPath resolve_path(const std::string& s)
}
// This is the top level master main function that is registered as
// our idle funciton
// our idle function
// The first few passes take care of initialization things (a couple
// per pass) and once everything has been initialized fgMainLoop from
@ -347,20 +349,17 @@ static void fgIdleFunction ( void ) {
if (!guiFinishInit())
return;
idle_state++;
fgSplashProgress("reading aircraft list");
fgSplashProgress("loading aircraft list");
} else if ( idle_state == 2 ) {
idle_state++;
fgSplashProgress("reading airport & navigation data");
fgSplashProgress("loading navigation data");
} else if ( idle_state == 3 ) {
idle_state++;
fgInitNav();
fgSplashProgress("setting up scenery");
fgSplashProgress("initializing scenery system");
} else if ( idle_state == 4 ) {
idle_state++;
@ -385,14 +384,13 @@ static void fgIdleFunction ( void ) {
////////////////////////////////////////////////////////////////////
fgInitCommands();
////////////////////////////////////////////////////////////////////
// Initialize the material manager
////////////////////////////////////////////////////////////////////
globals->set_matlib( new SGMaterialLib );
simgear::SGModelLib::init(globals->get_fg_root(), globals->get_props());
simgear::SGModelLib::setPanelFunc(load_panel);
////////////////////////////////////////////////////////////////////
// Initialize the TG scenery subsystem.
////////////////////////////////////////////////////////////////////
@ -401,15 +399,12 @@ static void fgIdleFunction ( void ) {
globals->get_scenery()->bind();
globals->set_tile_mgr( new FGTileMgr );
fgSplashProgress("loading aircraft");
} else if ( idle_state == 5 ) {
idle_state++;
fgSplashProgress("generating sky elements");
fgSplashProgress("initializing sky elements");
} else if ( idle_state == 6 ) {
idle_state++;
@ -470,10 +465,8 @@ static void fgIdleFunction ( void ) {
// airport->setName( "Airport Lighting" );
// lighting->addKid( airport );
// build our custom render states
fgSplashProgress("initializing subsystems");
} else if ( idle_state == 7 ) {
idle_state++;
// Initialize audio support
@ -530,18 +523,18 @@ static void fgIdleFunction ( void ) {
fgSetPosFromAirportIDandHdg( apt, hdg );
}
}
fgSplashProgress("setting up time & renderer");
fgSplashProgress("initializing graphics engine");
} else if ( idle_state == 8 ) {
idle_state = 1000;
// setup OpenGL view parameters
globals->get_renderer()->init();
globals->get_renderer()->setupView();
globals->get_renderer()->resize( fgGetInt("/sim/startup/xsize"),
fgGetInt("/sim/startup/ysize") );
fgSplashProgress("loading scenery objects");
int session = fgGetInt("/sim/session",0);
session++;
fgSetInt("/sim/session",session);
@ -555,6 +548,10 @@ static void fgIdleFunction ( void ) {
}
}
static void fgWinResizeFunction(int width, int height)
{
globals->get_renderer()->resize(width, height);
}
static void upper_case_property(const char *name)
{
@ -644,7 +641,7 @@ int fgMainInit( int argc, char **argv ) {
fgOSInit(&argc, argv);
_bootstrap_OSInit++;
fgRegisterWindowResizeHandler( &FGRenderer::resize );
fgRegisterWindowResizeHandler( &fgWinResizeFunction );
fgRegisterIdleHandler( &fgIdleFunction );
fgRegisterDrawHandler( &FGRenderer::update );
@ -668,5 +665,3 @@ int fgMainInit( int argc, char **argv ) {
return result;
}

View file

@ -555,54 +555,6 @@ add_channel( const string& type, const string& channel_str ) {
return true;
}
// The parse wp and parse flight-plan options don't work anymore, because
// the route manager and the airport subsystems have not yet been initialized
// at this stage.
// Parse --wp=ID[@alt]
static void
parse_wp( const string& arg ) {
string_list *waypoints = globals->get_initial_waypoints();
if (!waypoints) {
waypoints = new string_list;
globals->set_initial_waypoints(waypoints);
}
waypoints->push_back(arg);
}
// Parse --flight-plan=[file]
static bool
parse_flightplan(const string& arg)
{
string_list *waypoints = globals->get_initial_waypoints();
if (!waypoints) {
waypoints = new string_list;
globals->set_initial_waypoints(waypoints);
}
sg_gzifstream in(arg.c_str());
if ( !in.is_open() )
return false;
while ( true ) {
string line;
getline( in, line, '\n' );
// catch extraneous (DOS) line ending character
if ( line[line.length() - 1] < 32 )
line = line.substr( 0, line.length()-1 );
if ( in.eof() )
break;
waypoints->push_back(line);
}
return true;
}
static int
fgOptLanguage( const char *arg )
{
@ -1067,14 +1019,12 @@ fgOptCeiling( const char *arg )
static int
fgOptWp( const char *arg )
{
parse_wp( arg );
return FG_OPTIONS_OK;
}
static int
fgOptFlightPlan( const char *arg )
{
parse_flightplan ( arg );
string_list *waypoints = globals->get_initial_waypoints();
if (!waypoints) {
waypoints = new string_list;
globals->set_initial_waypoints(waypoints);
}
waypoints->push_back(arg);
return FG_OPTIONS_OK;
}
@ -1467,6 +1417,8 @@ struct OptionDesc {
{"opengc", true, OPTION_CHANNEL, "", false, "", 0 },
{"AV400", true, OPTION_CHANNEL, "", false, "", 0 },
{"AV400Sim", true, OPTION_CHANNEL, "", false, "", 0 },
{"AV400WSimA", true, OPTION_CHANNEL, "", false, "", 0 },
{"AV400WSimB", true, OPTION_CHANNEL, "", false, "", 0 },
{"garmin", true, OPTION_CHANNEL, "", false, "", 0 },
{"nmea", true, OPTION_CHANNEL, "", false, "", 0 },
{"generic", true, OPTION_CHANNEL, "", false, "", 0 },
@ -1494,7 +1446,7 @@ struct OptionDesc {
{"turbulence", true, OPTION_FUNC, "", false, "", fgOptTurbulence },
{"ceiling", true, OPTION_FUNC, "", false, "", fgOptCeiling },
{"wp", true, OPTION_FUNC, "", false, "", fgOptWp },
{"flight-plan", true, OPTION_FUNC, "", false, "", fgOptFlightPlan },
{"flight-plan", true, OPTION_STRING, "/autopilot/route-manager/file-path", false, "", NULL },
{"config", true, OPTION_FUNC, "", false, "", fgOptConfig },
{"aircraft", true, OPTION_STRING, "/sim/aircraft", false, "", 0 },
{"vehicle", true, OPTION_STRING, "/sim/aircraft", false, "", 0 },

View file

@ -82,8 +82,6 @@
#include <simgear/screen/jpgfactory.hxx>
#endif
#include <simgear/environment/visual_enviro.hxx>
#include <Time/light.hxx>
#include <Time/light.hxx>
#include <Cockpit/panel.hxx>
@ -130,7 +128,7 @@ public:
hint->setMode(GL_DONT_CARE);
}
private:
SGSharedPtr<SGPropertyNode> mConfigNode;
SGPropertyNode_ptr mConfigNode;
};
@ -274,7 +272,7 @@ private:
class FGWireFrameModeUpdateCallback : public osg::StateAttribute::Callback {
public:
FGWireFrameModeUpdateCallback() :
mWireframe(fgGetNode("/sim/rendering/wireframe"))
mWireframe(fgGetNode("/sim/rendering/wireframe", true))
{ }
virtual void operator()(osg::StateAttribute* stateAttribute,
osg::NodeVisitor*)
@ -291,13 +289,13 @@ public:
osg::PolygonMode::FILL);
}
private:
SGSharedPtr<SGPropertyNode> mWireframe;
SGPropertyNode_ptr mWireframe;
};
class FGLightModelUpdateCallback : public osg::StateAttribute::Callback {
public:
FGLightModelUpdateCallback() :
mHighlights(fgGetNode("/sim/rendering/specular-highlight"))
mHighlights(fgGetNode("/sim/rendering/specular-highlight", true))
{ }
virtual void operator()(osg::StateAttribute* stateAttribute,
osg::NodeVisitor*)
@ -322,13 +320,13 @@ public:
}
}
private:
SGSharedPtr<SGPropertyNode> mHighlights;
SGPropertyNode_ptr mHighlights;
};
class FGFogEnableUpdateCallback : public osg::StateSet::Callback {
public:
FGFogEnableUpdateCallback() :
mFogEnabled(fgGetNode("/sim/rendering/fog"))
mFogEnabled(fgGetNode("/sim/rendering/fog", true))
{ }
virtual void operator()(osg::StateSet* stateSet, osg::NodeVisitor*)
{
@ -339,7 +337,7 @@ public:
}
}
private:
SGSharedPtr<SGPropertyNode> mFogEnabled;
SGPropertyNode_ptr mFogEnabled;
};
class FGFogUpdateCallback : public osg::StateAttribute::Callback {
@ -364,15 +362,18 @@ public:
assert(dynamic_cast<osg::Switch*>(node));
osg::Switch* sw = static_cast<osg::Switch*>(node);
double t = globals->get_sim_time_sec();
bool enabled = 0 < t;
bool enabled = scenery_enabled;
sw->setValue(0, enabled);
if (!enabled)
return;
traverse(node, nv);
}
static bool scenery_enabled;
};
bool FGScenerySwitchCallback::scenery_enabled = false;
// Sky structures
SGSky *thesky;
@ -411,10 +412,38 @@ FGRenderer::splashinit( void ) {
// visitor automatically.
mUpdateVisitor->setFrameStamp(mFrameStamp.get());
viewer->setUpdateVisitor(mUpdateVisitor.get());
fgSetDouble("/sim/startup/splash-alpha", 1.0);
}
void
FGRenderer::init( void )
{
_scenery_loaded = fgGetNode("/sim/sceneryloaded", true);
_scenery_override = fgGetNode("/sim/sceneryloaded-override", true);
_panel_hotspots = fgGetNode("/sim/panel-hotspots", true);
_virtual_cockpit = fgGetNode("/sim/virtual-cockpit", true);
_sim_delta_sec = fgGetNode("/sim/time/delta-sec", true);
_xsize = fgGetNode("/sim/startup/xsize", true);
_ysize = fgGetNode("/sim/startup/ysize", true);
_splash_alpha = fgGetNode("/sim/startup/splash-alpha", true);
_skyblend = fgGetNode("/sim/rendering/skyblend", true);
_point_sprites = fgGetNode("/sim/rendering/point-sprites", true);
_enhanced_lighting = fgGetNode("/sim/rendering/enhanced-lighting", true);
_distance_attenuation = fgGetNode("/sim/rendering/distance-attenuation", true);
_horizon_effect = fgGetNode("/sim/rendering/horizon-effect", true);
_textures = fgGetNode("/sim/rendering/textures", true);
_altitude_ft = fgGetNode("/position/altitude-ft", true);
_cloud_status = fgGetNode("/environment/clouds/status", true);
_visibility_m = fgGetNode("/environment/visibility-m", true);
}
void
FGRenderer::setupView( void )
{
osgViewer::Viewer* viewer = globals->get_renderer()->getViewer();
osg::initNotifyLevel();
@ -559,27 +588,42 @@ FGRenderer::init( void )
stateSet->setAttributeAndModes(new osg::Program, osg::StateAttribute::ON);
}
void
FGRenderer::update()
{
globals->get_renderer()->update(true);
}
// Update all Visuals (redraws anything graphics related)
void
FGRenderer::update( bool refresh_camera_settings ) {
bool scenery_loaded = fgGetBool("sim/sceneryloaded", false)
|| fgGetBool("sim/sceneryloaded-override");
if (!(_scenery_loaded->getBoolValue() ||
_scenery_override->getBoolValue()))
{
_splash_alpha->setDoubleValue(1.0);
return;
}
osgViewer::Viewer* viewer = globals->get_renderer()->getViewer();
if (!scenery_loaded) {
fgSetDouble("/sim/startup/splash-alpha", 1.0);
return;
if (_splash_alpha->getDoubleValue()>0.0)
{
// Fade out the splash screen
const double fade_time = 0.8;
const double fade_steps_per_sec = 20;
double delay_time = SGMiscd::min(fade_time/fade_steps_per_sec,
(SGTimeStamp::now() - _splash_time).toSecs());
_splash_time = SGTimeStamp::now();
double sAlpha = _splash_alpha->getDoubleValue();
sAlpha -= SGMiscd::max(0.0,delay_time/fade_time);
FGScenerySwitchCallback::scenery_enabled = (sAlpha<1.0);
_splash_alpha->setDoubleValue(sAlpha);
}
// Fade out the splash screen over the first three seconds.
double sAlpha = SGMiscd::max(0, (2.5 - globals->get_sim_time_sec()) / 2.5);
fgSetDouble("/sim/startup/splash-alpha", sAlpha);
bool skyblend = _skyblend->getBoolValue();
bool use_point_sprites = _point_sprites->getBoolValue();
bool enhanced_lighting = _enhanced_lighting->getBoolValue();
bool distance_attenuation = _distance_attenuation->getBoolValue();
bool skyblend = fgGetBool("/sim/rendering/skyblend");
bool use_point_sprites = fgGetBool("/sim/rendering/point-sprites");
bool enhanced_lighting = fgGetBool("/sim/rendering/enhanced-lighting");
bool distance_attenuation
= fgGetBool("/sim/rendering/distance-attenuation");
// OSGFIXME
SGConfigureDirectionalLights( use_point_sprites, enhanced_lighting,
distance_attenuation );
@ -588,10 +632,10 @@ FGRenderer::update( bool refresh_camera_settings ) {
// update fog params
double actual_visibility;
if (fgGetBool("/environment/clouds/status")) {
if (_cloud_status->getBoolValue()) {
actual_visibility = thesky->get_visibility();
} else {
actual_visibility = fgGetDouble("/environment/visibility-m");
actual_visibility = _visibility_m->getDoubleValue();
}
// idle_state is now 1000 meaning we've finished all our
@ -604,27 +648,27 @@ FGRenderer::update( bool refresh_camera_settings ) {
if ( refresh_camera_settings ) {
// update view port
resize( fgGetInt("/sim/startup/xsize"),
fgGetInt("/sim/startup/ysize") );
resize( _xsize->getIntValue(),
_ysize->getIntValue() );
}
osg::Camera *camera = viewer->getCamera();
if ( skyblend ) {
if ( fgGetBool("/sim/rendering/textures") ) {
if ( _textures->getBoolValue() ) {
SGVec4f clearColor(l->adj_fog_color());
camera->setClearColor(osg::Vec4(0.0, 0.0, 0.0, 1.0));
camera->setClearColor(toOsg(clearColor));
}
} else {
SGVec4f clearColor(l->sky_color());
camera->setClearColor(osg::Vec4(0.0, 0.0, 0.0, 1.0));
camera->setClearColor(toOsg(clearColor));
}
// update fog params if visibility has changed
double visibility_meters = fgGetDouble("/environment/visibility-m");
double visibility_meters = _visibility_m->getDoubleValue();
thesky->set_visibility(visibility_meters);
double altitude_m = fgGetDouble("/position/altitude-ft") * SG_FEET_TO_METER;
double altitude_m = _altitude_ft->getDoubleValue() * SG_FEET_TO_METER;
thesky->modify_vis( altitude_m, 0.0 /* time factor, now unused */);
// update the sky dome
@ -637,7 +681,7 @@ FGRenderer::update( bool refresh_camera_settings ) {
// Sun distance: 150,000,000 kilometers
double sun_horiz_eff, moon_horiz_eff;
if (fgGetBool("/sim/rendering/horizon-effect")) {
if (_horizon_effect->getBoolValue()) {
sun_horiz_eff
= 0.67 + pow(osg::clampAbove(0.5 + cos(l->get_sun_angle()),
0.0),
@ -668,7 +712,7 @@ FGRenderer::update( bool refresh_camera_settings ) {
scolor.sun_angle = l->get_sun_angle();
scolor.moon_angle = l->get_moon_angle();
double delta_time_sec = fgGetDouble("/sim/time/delta-sec");
double delta_time_sec = _sim_delta_sec->getDoubleValue();
thesky->reposition( sstate, *globals->get_ephem(), delta_time_sec );
thesky->repaint( scolor, *globals->get_ephem() );
@ -714,11 +758,10 @@ FGRenderer::update( bool refresh_camera_settings ) {
l->get_sun_angle()*SGD_RADIANS_TO_DEGREES);
mUpdateVisitor->setVisibility(actual_visibility);
simgear::GroundLightManager::instance()->update(mUpdateVisitor.get());
bool hotspots = fgGetBool("/sim/panel-hotspots");
osg::Node::NodeMask cullMask = ~simgear::LIGHTS_BITS & ~simgear::PICK_BIT;
cullMask |= simgear::GroundLightManager::instance()
->getLightNodeMask(mUpdateVisitor.get());
if (hotspots)
if (_panel_hotspots->getBoolValue())
cullMask |= simgear::PICK_BIT;
CameraGroup::getDefault()->setCameraCullMasks(cullMask);
}
@ -729,30 +772,29 @@ FGRenderer::update( bool refresh_camera_settings ) {
// Handle new window size or exposure
void
FGRenderer::resize( int width, int height ) {
int view_h;
if ( (!fgGetBool("/sim/virtual-cockpit"))
&& fgPanelVisible() && idle_state == 1000 ) {
view_h = (int)(height * (globals->get_current_panel()->getViewHeight() -
globals->get_current_panel()->getYOffset()) / 768.0);
} else {
view_h = height;
}
// the following breaks aspect-ratio of the main 3D scenery window when 2D panels are moved
// in y direction - causing issues for aircraft with 2D panels (/sim/virtual_cockpit=false).
// Disabling for now. Seems this useful for the pre-OSG time only.
// if ( (!_virtual_cockpit->getBoolValue())
// && fgPanelVisible() && idle_state == 1000 ) {
// view_h = (int)(height * (globals->get_current_panel()->getViewHeight() -
// globals->get_current_panel()->getYOffset()) / 768.0);
// }
static int lastwidth = 0;
static int lastheight = 0;
if (width != lastwidth)
fgSetInt("/sim/startup/xsize", lastwidth = width);
if (height != lastheight)
fgSetInt("/sim/startup/ysize", lastheight = height);
int curWidth = _xsize->getIntValue(),
curHeight = _ysize->getIntValue();
_xsize->setIntValue(width);
_ysize->setIntValue(height);
double aspect = height / (double) width;
// for all views
FGViewMgr *viewmgr = globals->get_viewmgr();
if (viewmgr) {
for ( int i = 0; i < viewmgr->size(); ++i ) {
viewmgr->get_view(i)->
set_aspect_ratio((float)view_h / (float)width);
}
for ( int i = 0; i < viewmgr->size(); ++i ) {
viewmgr->get_view(i)->set_aspect_ratio(aspect);
}
}
}

View file

@ -3,6 +3,8 @@
#define __FG_RENDERER_HXX 1
#include <simgear/scene/util/SGPickCallback.hxx>
#include <simgear/props/props.hxx>
#include <simgear/timing/timestamp.hxx>
#include <osg/ref_ptr>
@ -45,18 +47,20 @@ public:
void splashinit();
void init();
static void resize(int width, int height );
void setupView();
void resize(int width, int height );
// calling update( refresh_camera_settings = false ) will not
// touch window or camera settings. This is useful for the tiled
// renderer which needs to set the view frustum itself.
static void update( bool refresh_camera_settings );
inline static void update() { update( true ); }
void update( bool refresh_camera_settings);
static void update();
/** Just pick into the scene and return the pick callbacks on the way ...
*/
static bool pick( std::vector<SGSceneryPick>& pickList,
const osgGA::GUIEventAdapter* ea );
bool pick( std::vector<SGSceneryPick>& pickList,
const osgGA::GUIEventAdapter* ea );
/** Get and set the OSG Viewer object, if any.
*/
@ -76,6 +80,15 @@ public:
protected:
osg::ref_ptr<osgViewer::Viewer> viewer;
osg::ref_ptr<flightgear::FGEventHandler> eventHandler;
SGPropertyNode_ptr _scenery_loaded,_scenery_override;
SGPropertyNode_ptr _skyblend, _splash_alpha;
SGPropertyNode_ptr _point_sprites, _enhanced_lighting, _distance_attenuation;
SGPropertyNode_ptr _textures;
SGPropertyNode_ptr _cloud_status, _visibility_m;
SGPropertyNode_ptr _xsize, _ysize;
SGPropertyNode_ptr _panel_hotspots, _sim_delta_sec, _horizon_effect, _altitude_ft;
SGPropertyNode_ptr _virtual_cockpit;
SGTimeStamp _splash_time;
};
bool fgDumpSceneGraphToFile(const char* filename);

View file

@ -295,6 +295,7 @@ static osg::Node* fgCreateSplashCamera()
text->setPosition(osg::Vec3(0, -0.92, 0));
text->setAlignment(osgText::Text::CENTER_CENTER);
SGPropertyNode* prop = fgGetNode("/sim/startup/splash-progress-text", true);
prop->setStringValue("initializing");
text->setUpdateCallback(new FGSplashTextUpdateCallback(prop));
geode->addDrawable(text);

1046
src/Network/AV400WSim.cxx Normal file

File diff suppressed because it is too large Load diff

144
src/Network/AV400WSim.hxx Normal file
View file

@ -0,0 +1,144 @@
// AV400Sim.hxx -- Garmin 400 series protocal class. This AV400Sim
// protocol generates the set of "simulator" commands a garmin 400
// series gps would expect as input in simulator mode. The AV400
// protocol generates the set of commands that a garmin 400 series gps
// would emit.
//
// Written by Curtis Olson, started Januar 2009.
//
// Copyright (C) 2009 Curtis L. Olson - http://www.flightgear.org/~curt
//
// 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.
//
// $Id$
#ifndef _FG_AV400WSIM_HXX
#define _FG_AV400WSIM_HXX
#include <simgear/compiler.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include "protocol.hxx"
using std::string;
class FlightProperties;
//////////////////////////////////////////////////////////////////////////////
// Class FGAV400WSimA handles the input/output over the first serial port.
// This is very similar to the way previous Garmin non-WAAS models communicated
// but some items have been stripped out and just a minimal amount of
// info is necessary to be transmitted over this port.
class FGAV400WSimA : public FGProtocol {
char buf[ FG_MAX_MSG_SIZE ];
int length;
public:
FGAV400WSimA();
~FGAV400WSimA();
bool gen_message();
bool parse_message();
// open hailing frequencies
bool open();
// process work for this port
bool process();
// close the channel
bool close();
};
//////////////////////////////////////////////////////////////////////////////
// Class FGAV400WSimB handles the input/output over the second serial port
// which Garmin refers to as the "GPS Port". Some messages are handled on
// fixed cycle (usually 1 and 5 Hz) and some immediate responses are needed
// to certain messages upon requet by the GPS unit
class FGAV400WSimB : public FGProtocol {
char buf[ FG_MAX_MSG_SIZE ];
int length;
double hz2;
int hz2count;
int hz2cycles;
char flight_phase;
string hal;
string val;
string sbas_sel;
bool req_hostid;
bool req_raimap;
bool req_sbas;
int outputctr;
FlightProperties* fdm;
static const int SOM_SIZE = 2;
static const int DEG_TO_MILLIARCSECS = ( 60.0 * 60.0 * 1000 );
// Flight Phases
static const int PHASE_OCEANIC = 4;
static const int PHASE_ENROUTE = 5;
static const int PHASE_TERM = 6;
static const int PHASE_NONPREC = 7;
static const int PHASE_LNAVVNAV = 8;
static const int PHASE_LPVLP = 9;
public:
FGAV400WSimB();
~FGAV400WSimB();
bool gen_hostid_message();
bool gen_sbas_message();
bool gen_Wh_message();
bool gen_Wx_message();
bool gen_Wt_message();
bool gen_Wm_message();
bool gen_Wv_message();
bool verify_checksum( string message, int datachars );
string asciitize_message( string message );
string buffer_to_string();
bool parse_message();
// open hailing frequencies
bool open();
// process work for this port
bool process();
// close the channel
bool close();
inline double get_hz2() const { return hz2; }
inline void set_hz2( double t ) { hz2 = t, hz2cycles = get_hz() / hz2; }
};
#endif // _FG_AV400WSIM_HXX

View file

@ -6,6 +6,7 @@ set(SOURCES
ATC-Outputs.cxx
AV400.cxx
AV400Sim.cxx
AV400WSim.cxx
atlas.cxx
garmin.cxx
generic.cxx

View file

@ -19,6 +19,7 @@ libNetwork_a_SOURCES = \
atlas.cxx atlas.hxx \
AV400.cxx AV400.hxx \
AV400Sim.cxx AV400Sim.hxx \
AV400WSim.cxx AV400WSim.hxx \
garmin.cxx garmin.hxx \
lfsglass.cxx lfsglass.hxx lfsglass_data.hxx \
httpd.cxx httpd.hxx \
@ -43,4 +44,4 @@ INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src
if WITH_HLA
SUBDIRS = HLA
endif
endif

View file

@ -35,16 +35,32 @@
#include <simgear/structure/event_mgr.hxx>
#include <simgear/misc/sg_path.hxx>
#include <simgear/timing/lowleveltime.h>
#include <simgear/structure/commands.hxx>
#include <Main/fg_props.hxx>
#include <Main/globals.hxx>
#include <Time/sunsolver.hxx>
static bool do_timeofday (const SGPropertyNode * arg)
{
const string &offset_type = arg->getStringValue("timeofday", "noon");
int offset = arg->getIntValue("offset", 0);
TimeManager* self = (TimeManager*) globals->get_subsystem("time");
if (offset_type == "real") {
// without this, setting 'real' time is a no-op, since the current
// wrap value (orig_warp) is retained in setTimeOffset. Ick.
fgSetInt("/sim/time/warp", 0);
}
self->setTimeOffset(offset_type, offset);
return true;
}
TimeManager::TimeManager() :
_inited(false),
_impl(NULL)
{
SGCommandMgr::instance()->addCommand("timeofday", do_timeofday);
}
void TimeManager::init()
@ -345,6 +361,14 @@ void TimeManager::updateLocalTime()
}
void TimeManager::initTimeOffset()
{
int offset = fgGetInt("/sim/startup/time-offset");
string offset_type = fgGetString("/sim/startup/time-offset-type");
setTimeOffset(offset_type, offset);
}
void TimeManager::setTimeOffset(const std::string& offset_type, int offset)
{
// Handle potential user specified time offsets
int orig_warp = _warp->getIntValue();
@ -355,8 +379,6 @@ void TimeManager::initTimeOffset()
sgTimeGetGMT( fgLocaltime(&cur_time, _impl->get_zonename() ) );
// Okay, we now have several possible scenarios
int offset = fgGetInt("/sim/startup/time-offset");
string offset_type = fgGetString("/sim/startup/time-offset-type");
double lon = _longitudeDeg->getDoubleValue() * SG_DEGREES_TO_RADIANS;
double lat = _latitudeDeg->getDoubleValue() * SG_DEGREES_TO_RADIANS;
int warp = 0;
@ -394,12 +416,12 @@ void TimeManager::initTimeOffset()
warp = offset - (aircraftLocalTime - currGMT)- cur_time;
} else {
SG_LOG( SG_GENERAL, SG_ALERT,
"TimeManager::initTimeOffset: unsupported offset: " << offset_type );
"TimeManager::setTimeOffset: unsupported offset: " << offset_type );
warp = 0;
}
_warp->setIntValue( orig_warp + warp );
SG_LOG( SG_GENERAL, SG_INFO, "After fgInitTimeOffset(): warp = "
SG_LOG( SG_GENERAL, SG_INFO, "After TimeManager::setTimeOffset(): warp = "
<< _warp->getIntValue() );
}

View file

@ -43,6 +43,8 @@ public:
// SGPropertyChangeListener overrides
virtual void valueChanged(SGPropertyNode *);
void setTimeOffset(const std::string& offset_type, int offset);
private:
/**

View file

@ -1 +1 @@
2.2.0
2.3.0