lon_node(fgGetNode("/position/longitude-deg", true)),
lat_node(fgGetNode("/position/latitude-deg", true)),
alt_node(fgGetNode("/position/altitude-ft", true)),
- is_valid_node(NULL),
- power_btn_node(NULL),
- freq_node(NULL),
- alt_freq_node(NULL),
- sel_radial_node(NULL),
- vol_btn_node(NULL),
- ident_btn_node(NULL),
- audio_btn_node(NULL),
- backcourse_node(NULL),
- nav_serviceable_node(NULL),
- cdi_serviceable_node(NULL),
- gs_serviceable_node(NULL),
- tofrom_serviceable_node(NULL),
- dme_serviceable_node(NULL),
- fmt_freq_node(NULL),
- fmt_alt_freq_node(NULL),
- heading_node(NULL),
- radial_node(NULL),
- recip_radial_node(NULL),
- target_radial_true_node(NULL),
- target_auto_hdg_node(NULL),
- time_to_intercept(NULL),
- to_flag_node(NULL),
- from_flag_node(NULL),
- inrange_node(NULL),
- signal_quality_norm_node(NULL),
- cdi_deflection_node(NULL),
- cdi_deflection_norm_node(NULL),
- cdi_xtrack_error_node(NULL),
- cdi_xtrack_hdg_err_node(NULL),
- has_gs_node(NULL),
- loc_node(NULL),
- loc_dist_node(NULL),
- gs_deflection_node(NULL),
- gs_deflection_deg_node(NULL),
- gs_deflection_norm_node(NULL),
- gs_rate_of_climb_node(NULL),
- gs_dist_node(NULL),
- gs_inrange_node(NULL),
- nav_id_node(NULL),
- id_c1_node(NULL),
- id_c2_node(NULL),
- id_c3_node(NULL),
- id_c4_node(NULL),
- nav_slaved_to_gps_node(NULL),
- gps_cdi_deflection_node(NULL),
- gps_to_flag_node(NULL),
- gps_from_flag_node(NULL),
- gps_has_gs_node(NULL),
- gps_xtrack_error_nm_node(NULL),
play_count(0),
last_time(0),
target_radial(0.0),
_name(node->getStringValue("name", "nav")),
_num(node->getIntValue("number", 0)),
_time_before_search_sec(-1.0),
- _falseCoursesEnabled(true)
+ _sgr(NULL)
{
SGPath path( globals->get_fg_root() );
SGPath term = path;
term_tbl = new SGInterpTable( term.str() );
low_tbl = new SGInterpTable( low.str() );
high_tbl = new SGInterpTable( high.str() );
+
+
+ string branch("/instrumentation/" + _name);
+ _radio_node = fgGetNode(branch.c_str(), _num, true);
}
void
FGNavRadio::init ()
{
- morse.init();
-
- string branch;
- branch = "/instrumentation/" + _name;
+ SGSoundMgr *smgr = globals->get_soundmgr();
+ _sgr = smgr->find("avionics", true);
+ _sgr->tie_to_listener();
- SGPropertyNode *node = fgGetNode(branch.c_str(), _num, true );
+ morse.init();
+ SGPropertyNode* node = _radio_node.get();
bus_power_node =
fgGetNode(("/systems/electrical/outputs/" + _name).c_str(), true);
tofrom_serviceable_node = createServiceableProp(node, "to-from");
dme_serviceable_node = createServiceableProp(node, "dme");
- globals->get_props()->tie("sim/realism/false-radio-courses-enabled",
- SGRawValuePointer<bool>(&_falseCoursesEnabled));
-
+ falseCoursesEnabledNode =
+ fgGetNode("/sim/realism/false-radio-courses-enabled");
+ if (!falseCoursesEnabledNode) {
+ falseCoursesEnabledNode =
+ fgGetNode("/sim/realism/false-radio-courses-enabled", true);
+ falseCoursesEnabledNode->setBoolValue(true);
+ }
+
// frequencies
SGPropertyNode *subnode = node->getChild("frequencies", 0, true);
freq_node = subnode->getChild("selected-mhz", 0, true);
gs_deflection_deg_node = node->getChild("gs-needle-deflection-deg", 0, true);
gs_deflection_norm_node = node->getChild("gs-needle-deflection-norm", 0, true);
gs_rate_of_climb_node = node->getChild("gs-rate-of-climb", 0, true);
+ gs_rate_of_climb_fpm_node = node->getChild("gs-rate-of-climb-fpm", 0, true);
gs_dist_node = node->getChild("gs-distance", 0, true);
gs_inrange_node = node->getChild("gs-in-range", 0, true);
id_c3_node = node->getChild("nav-id_asc3", 0, true);
id_c4_node = node->getChild("nav-id_asc4", 0, true);
- node->tie("dme-in-range", SGRawValuePointer<bool>(&_dmeInRange));
-
// gps slaving support
nav_slaved_to_gps_node = node->getChild("slaved-to-gps", 0, true);
gps_cdi_deflection_node = fgGetNode("/instrumentation/gps/cdi-deflection", true);
void
FGNavRadio::bind ()
{
-
+ tie("dme-in-range", SGRawValuePointer<bool>(&_dmeInRange));
+ tie("operable", SGRawValueMethods<FGNavRadio, bool>(*this, &FGNavRadio::isOperable, NULL));
}
void
FGNavRadio::unbind ()
{
+ for (unsigned int t=0; t<_tiedNodes.size(); ++t) {
+ _tiedNodes[t]->untie();
+ }
+ _tiedNodes.clear();
}
if (power_btn_node->getBoolValue()
&& (bus_power_node->getDoubleValue() > 1.0)
&& nav_serviceable_node->getBoolValue() )
- {
+ {
+ _operable = true;
if (nav_slaved_to_gps_node->getBoolValue()) {
updateGPSSlaved();
} else {
gs_deflection_deg_node->setDoubleValue(0.0);
gs_deflection_norm_node->setDoubleValue(0.0);
gs_inrange_node->setBoolValue( false );
+ loc_node->setBoolValue( false );
+ has_gs_node->setBoolValue(false);
to_flag_node->setBoolValue( false );
from_flag_node->setBoolValue( false );
_dmeInRange = false;
+ _operable = false;
}
void FGNavRadio::updateReceiver(double dt)
SG_NORMALIZE_RANGE(r, -180.0, 180.0);
if ( is_loc ) {
- if (_falseCoursesEnabled) {
+ if (falseCoursesEnabledNode->getBoolValue()) {
// The factor of 30.0 gives a period of 120 which gives us 3 cycles and six
// zeros i.e. six courses: one front course, one back course, and four
// false courses. Three of the six are reverse sensing.
if (!_gs || !inrange_node->getBoolValue()) {
gs_dist_node->setDoubleValue( 0.0 );
gs_inrange_node->setBoolValue(false);
+ _gsNeedleDeflection = 0.0;
+ _gsNeedleDeflectionNorm = 0.0;
return;
}
gs_inrange_node->setBoolValue(gsInRange);
if (!gsInRange) {
+ _gsNeedleDeflection = 0.0;
+ _gsNeedleDeflectionNorm = 0.0;
return;
}
double angle = atan2(dot_v, dot_h) * SGD_RADIANS_TO_DEGREES;
double deflectionAngle = target_gs - angle;
- if (_falseCoursesEnabled) {
+ if (falseCoursesEnabledNode->getBoolValue()) {
// Construct false glideslopes. The scale factor of 1.5
// in the sawtooth gives a period of 6 degrees.
// There will be zeros at 3, 6r, 9, 12r et cetera
double gs_diff = target_gs - angle;
// convert desired vertical path angle into a climb rate
double des_angle = angle - 10 * gs_diff;
+ /* printf("target_gs=%.1f angle=%.1f gs_diff=%.1f des_angle=%.1f\n",
+ target_gs, angle, gs_diff, des_angle); */
// estimate horizontal speed towards ILS in meters per minute
double elapsedDistance = last_x - gsDist;
last_x = gsDist;
double new_vel = ( elapsedDistance / dt );
- horiz_vel = 0.75 * horiz_vel + 0.25 * new_vel;
+ horiz_vel = 0.99 * horiz_vel + 0.01 * new_vel;
+ /* printf("vel=%.1f (dist=%.1f dt=%.2f)\n", horiz_vel, elapsedDistance, dt);*/
gs_rate_of_climb_node
->setDoubleValue( -sin( des_angle * SGD_DEGREES_TO_RADIANS )
* horiz_vel * SG_METER_TO_FEET );
+ gs_rate_of_climb_fpm_node
+ ->setDoubleValue( gs_rate_of_climb_node->getDoubleValue() * 60 );
}
void FGNavRadio::updateDME(const SGVec3d& aircraft)
// play station ident via audio system if on + ident,
// otherwise turn it off
- if (!power_btn_node->getBoolValue()
+ if (!power_btn_node->getBoolValue()
|| !(bus_power_node->getDoubleValue() > 1.0)
|| !ident_btn_node->getBoolValue()
|| !audio_btn_node->getBoolValue() ) {
- globals->get_soundmgr()->stop( nav_fx_name );
- globals->get_soundmgr()->stop( dme_fx_name );
+ _sgr->stop( nav_fx_name );
+ _sgr->stop( dme_fx_name );
return;
}
- SGSoundSample *sound = globals->get_soundmgr()->find( nav_fx_name );
- double vol = vol_btn_node->getDoubleValue();
+ SGSoundSample *sound = _sgr->find( nav_fx_name );
+ double vol = vol_btn_node->getFloatValue();
SG_CLAMP_RANGE(vol, 0.0, 1.0);
if ( sound != NULL ) {
SG_LOG( SG_COCKPIT, SG_ALERT, "Can't find nav-vor-ident sound" );
}
- sound = globals->get_soundmgr()->find( dme_fx_name );
+ sound = _sgr->find( dme_fx_name );
if ( sound != NULL ) {
sound->set_volume( vol );
} else {
play_count = ++play_count % NUM_IDENT_SLOTS;
// Previous ident is out of time; if still playing, cut it off:
- globals->get_soundmgr()->stop( nav_fx_name );
- globals->get_soundmgr()->stop( dme_fx_name );
+ _sgr->stop( nav_fx_name );
+ _sgr->stop( dme_fx_name );
if (play_count == 0) { // the DME slot
if (_dmeInRange && dme_serviceable_node->getBoolValue()) {
// play DME ident
- globals->get_soundmgr()->play_once( dme_fx_name );
+ if (vol > 0.05) _sgr->play_once( dme_fx_name );
}
} else { // NAV slot
if (inrange_node->getBoolValue() && nav_serviceable_node->getBoolValue()) {
- globals->get_soundmgr()->play_once(nav_fx_name);
+ if (vol > 0.05) _sgr->play_once(nav_fx_name);
}
}
}
_gs = NULL;
_dme = NULL;
nav_id_node->setStringValue("");
- globals->get_soundmgr()->remove( nav_fx_name );
- globals->get_soundmgr()->remove( dme_fx_name );
+ loc_node->setBoolValue(false);
+ has_gs_node->setBoolValue(false);
+
+ _sgr->remove( nav_fx_name );
+ _sgr->remove( dme_fx_name );
}
is_valid_node->setBoolValue(nav != NULL);
void FGNavRadio::audioNavidChanged()
{
- if ( globals->get_soundmgr()->exists(nav_fx_name)) {
- globals->get_soundmgr()->remove(nav_fx_name);
+ if (_sgr->exists(nav_fx_name)) {
+ _sgr->remove(nav_fx_name);
}
try {
string trans_ident(_navaid->get_trans_ident());
SGSoundSample* sound = morse.make_ident(trans_ident, LO_FREQUENCY);
sound->set_volume( 0.3 );
- if (!globals->get_soundmgr()->add( sound, nav_fx_name )) {
+ if (!_sgr->add( sound, nav_fx_name )) {
SG_LOG(SG_COCKPIT, SG_WARN, "Failed to add v1-vor-ident sound");
}
- if ( globals->get_soundmgr()->exists( dme_fx_name ) ) {
- globals->get_soundmgr()->remove( dme_fx_name );
+ if ( _sgr->exists( dme_fx_name ) ) {
+ _sgr->remove( dme_fx_name );
}
sound = morse.make_ident( trans_ident, HI_FREQUENCY );
sound->set_volume( 0.3 );
- globals->get_soundmgr()->add( sound, dme_fx_name );
+ _sgr->add( sound, dme_fx_name );
int offset = (int)(sg_random() * 30.0);
play_count = offset / 4;