X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FCockpit%2Fmarker_beacon.cxx;h=f668f5e77e933d3dc1dd06465672268bb7dc327e;hb=d05121ef4689d2b50b3fe1848cbb0d1f5a1db877;hp=88e3e03708ca964299039485c412dbbe3a4baa4b;hpb=980012e1682fdb27c9b9ec27edea0b549d603f9d;p=flightgear.git diff --git a/src/Cockpit/marker_beacon.cxx b/src/Cockpit/marker_beacon.cxx index 88e3e0370..f668f5e77 100644 --- a/src/Cockpit/marker_beacon.cxx +++ b/src/Cockpit/marker_beacon.cxx @@ -2,7 +2,7 @@ // // Written by Curtis Olson, started April 2000. // -// Copyright (C) 2000 Curtis L. Olson - curt@flightgear.org +// Copyright (C) 2000 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 @@ -31,7 +31,7 @@ #include #include -#include +#include #include "marker_beacon.hxx" @@ -160,39 +160,96 @@ FGMarkerBeacon::update(double dt) } +static bool check_beacon_range( double lon_rad, double lat_rad, double elev_m, + FGNavRecord *b ) +{ + Point3D aircraft = sgGeodToCart( Point3D(lon_rad, lat_rad, elev_m) ); + Point3D station = Point3D( b->get_x(), b->get_y(), b->get_z() ); + // cout << " aircraft = " << aircraft << " station = " << station + // << endl; + + double d = aircraft.distance3Dsquared( station ); // meters^2 + // cout << " distance = " << d << " (" + // << FG_ILS_DEFAULT_RANGE * SG_NM_TO_METER + // * FG_ILS_DEFAULT_RANGE * SG_NM_TO_METER + // << ")" << endl; + + // cout << " range = " << sqrt(d) << endl; + + // cout << "elev = " << elev * SG_METER_TO_FEET + // << " current->get_elev() = " << current->get_elev() << endl; + double elev_ft = elev_m * SG_METER_TO_FEET; + double delev = elev_ft - b->get_elev_ft(); + + // max range is the area under r = 2.4 * alt or r^2 = 4000^2 - alt^2 + // whichever is smaller. The intersection point is 1538 ... + double maxrange2; // feet^2 + if ( delev < 1538.0 ) { + maxrange2 = 2.4 * 2.4 * delev * delev; + } else if ( delev < 4000.0 ) { + maxrange2 = 4000 * 4000 - delev * delev; + } else { + maxrange2 = 0.0; + } + maxrange2 *= SG_FEET_TO_METER * SG_FEET_TO_METER; // convert to meter^2 + // cout << "delev = " << delev << " maxrange = " << maxrange << endl; + + // match up to twice the published range so we can model + // reduced signal strength + if ( d < maxrange2 ) { + return true; + } else { + return false; + } +} + // Update current nav/adf radio stations based on current postition void FGMarkerBeacon::search() { - static FGMkrBeacon::fgMkrBeacType last_beacon = FGMkrBeacon::NOBEACON; + static fgMkrBeacType last_beacon = NOBEACON; - double lon = lon_node->getDoubleValue() * SGD_DEGREES_TO_RADIANS; - double lat = lat_node->getDoubleValue() * SGD_DEGREES_TO_RADIANS; - double elev = alt_node->getDoubleValue() * SG_FEET_TO_METER; + double lon_rad = lon_node->getDoubleValue() * SGD_DEGREES_TO_RADIANS; + double lat_rad = lat_node->getDoubleValue() * SGD_DEGREES_TO_RADIANS; + double elev_m = alt_node->getDoubleValue() * SG_FEET_TO_METER; //////////////////////////////////////////////////////////////////////// // Beacons. //////////////////////////////////////////////////////////////////////// - FGMkrBeacon::fgMkrBeacType beacon_type - = current_beacons->query( lon * SGD_RADIANS_TO_DEGREES, - lat * SGD_RADIANS_TO_DEGREES, elev ); + // get closest marker beacon + FGNavRecord *b + = globals->get_mkrlist()->findClosest( lon_rad, lat_rad, elev_m ); + + // cout << "marker beacon = " << b << " (" << b->get_type() << ")" << endl; + + fgMkrBeacType beacon_type = NOBEACON; + bool inrange = false; + if ( b != NULL ) { + if ( b->get_type() == 7 ) { + beacon_type = OUTER; + } else if ( b->get_type() == 8 ) { + beacon_type = MIDDLE; + } else if ( b->get_type() == 9 ) { + beacon_type = INNER; + } + inrange = check_beacon_range( lon_rad, lat_rad, elev_m, b ); + // cout << " inrange = " << inrange << endl; + } outer_marker = middle_marker = inner_marker = false; - if ( beacon_type == FGMkrBeacon::NOBEACON - || !has_power() || !serviceable->getBoolValue() ) + if ( b == NULL || !inrange || !has_power() || !serviceable->getBoolValue() ) { // cout << "no marker" << endl; - beacon_type = FGMkrBeacon::NOBEACON; globals->get_soundmgr()->stop( "outer-marker" ); globals->get_soundmgr()->stop( "middle-marker" ); globals->get_soundmgr()->stop( "inner-marker" ); - } else if ( beacon_type == FGMkrBeacon::OUTER ) { + } else if ( beacon_type == OUTER ) { outer_marker = true; // cout << "OUTER MARKER" << endl; - if ( last_beacon != FGMkrBeacon::OUTER ) { + if ( last_beacon != OUTER ) { if ( ! globals->get_soundmgr()->exists( "outer-marker" ) ) { - SGSimpleSound *sound = beacon.get_outer(); + SGSoundSample *sound = beacon.get_outer(); sound->set_volume( 0.3 ); globals->get_soundmgr()->add( sound, "outer-marker" ); } @@ -204,12 +261,12 @@ void FGMarkerBeacon::search() } else { globals->get_soundmgr()->stop( "outer-marker" ); } - } else if ( beacon_type == FGMkrBeacon::MIDDLE ) { + } else if ( beacon_type == MIDDLE ) { middle_marker = true; // cout << "MIDDLE MARKER" << endl; - if ( last_beacon != FGMkrBeacon::MIDDLE ) { + if ( last_beacon != MIDDLE ) { if ( ! globals->get_soundmgr()->exists( "middle-marker" ) ) { - SGSimpleSound *sound = beacon.get_middle(); + SGSoundSample *sound = beacon.get_middle(); sound->set_volume( 0.3 ); globals->get_soundmgr()->add( sound, "middle-marker" ); } @@ -221,12 +278,12 @@ void FGMarkerBeacon::search() } else { globals->get_soundmgr()->stop( "middle-marker" ); } - } else if ( beacon_type == FGMkrBeacon::INNER ) { + } else if ( beacon_type == INNER ) { inner_marker = true; // cout << "INNER MARKER" << endl; - if ( last_beacon != FGMkrBeacon::INNER ) { + if ( last_beacon != INNER ) { if ( ! globals->get_soundmgr()->exists( "inner-marker" ) ) { - SGSimpleSound *sound = beacon.get_inner(); + SGSoundSample *sound = beacon.get_inner(); sound->set_volume( 0.3 ); globals->get_soundmgr()->add( sound, "inner-marker" ); } @@ -239,5 +296,10 @@ void FGMarkerBeacon::search() globals->get_soundmgr()->stop( "inner-marker" ); } } - last_beacon = beacon_type; + + if ( inrange ) { + last_beacon = beacon_type; + } else { + last_beacon = NOBEACON; + } }