]> git.mxchange.org Git - flightgear.git/blobdiff - src/ATC/approach.cxx
Modified Files:
[flightgear.git] / src / ATC / approach.cxx
index a0c77b46a13a15a13330b12d8bc295845030c8b2..a0c2c504d973fbbe848a67efc767153eda315663 100644 (file)
 //
 // 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
 
 #include "approach.hxx"
 #include "transmission.hxx"
 #include "ATCDialog.hxx"
 
 #include <Airports/runways.hxx>
+#include <simgear/constants.h>
+#include <simgear/math/polar3d.hxx>
 #include <simgear/misc/sg_path.hxx>
 
-#ifdef FG_WEATHERCM
-# include <WeatherCM/FGLocalWeatherDatabase.h>
-#else
-# include <Environment/environment_mgr.hxx>
-# include <Environment/environment.hxx>
-#endif
+#include <Environment/environment_mgr.hxx>
+#include <Environment/environment.hxx>
 
 
 #include <GUI/gui.h>
 
 //Constructor
 FGApproach::FGApproach(){
-  comm1_node = fgGetNode("/radios/comm[0]/frequencies/selected-mhz", true);
-  comm2_node = fgGetNode("/radios/comm[1]/frequencies/selected-mhz", true);
+  comm1_node = fgGetNode("/instrumentation/comm[0]/frequencies/selected-mhz", true);
+  comm2_node = fgGetNode("/instrumentation/comm[1]/frequencies/selected-mhz", true);
+  
+  _type = APPROACH;
 
   num_planes = 0;
   lon_node   = fgGetNode("/position/longitude-deg", true);
@@ -48,7 +52,7 @@ FGApproach::FGApproach(){
   elev_node  = fgGetNode("/position/altitude-ft", true);
   hdg_node   = fgGetNode("/orientation/heading-deg", true);
   speed_node = fgGetNode("/velocities/airspeed-kt", true);
-  etime_node = fgGetNode("/sim/time/elapsed-ms", true);
+  etime_node = fgGetNode("/sim/time/elapsed-sec", true);
 
   first = true;
   active_runway = "";
@@ -74,7 +78,6 @@ FGApproach::~FGApproach(){
 }
 
 void FGApproach::Init() {
-  display    = false;
 }
 
 
@@ -82,12 +85,12 @@ void FGApproach::Init() {
 // ============================================================================
 // the main update function
 // ============================================================================
-void FGApproach::Update() {
+void FGApproach::Update(double dt) {
        
        const int max_trans = 20;
        FGTransmission tmissions[max_trans];
        int    wpn;
-       int    station = 1;
+       atc_type station = APPROACH;
        TransCode code;
        TransPar TPar;
        int    i,j;
@@ -111,11 +114,13 @@ void FGApproach::Update() {
        
        for (i=0; i<num_planes; i++) {
                if ( planes[i].ident == "Player") { 
-                       station = 1;
+                       station = APPROACH;
                        tpars.station = name;
                        tpars.callsign = "Player";
                        tpars.airport = ident;
                        
+                       //cout << "ident = " << ident << " name = " << name << '\n';
+                       
                        int num_trans = 0;
                        // is the frequency of the station tuned in?
                        if ( freq == (int)(comm1_freq*100.0 + 0.5) ) {
@@ -123,15 +128,18 @@ void FGApproach::Update() {
                                // loop over all transmissions for station
                                for ( j=0; j<=num_trans-1; j++ ) {
                                        code = tmissions[j].get_code();
+                                       //cout << "code is " << code.c1 << "  " << code.c2 << "  " << code.c3 << '\n';
                                        // select proper transmissions
-                                       if ( ( code.c2 == -1 && planes[i].lmc.c3 == 0 ) || 
-                                               ( code.c1 == 0  && code.c2 == planes[i].lmc.c2 ) ) {
-                                               mentry = current_transmissionlist->gen_text(station, code, tpars, false);
-                                               transm = current_transmissionlist->gen_text(station, code, tpars, true);
-                                               // is the transmission already registered?
-                                               if (!current_atcdialog->trans_reg( ident, transm )) {
-                                                       current_atcdialog->add_entry( ident, transm, mentry );
-                                               }
+                                       if(code.c3 != 2) {    // DCL - hack to prevent request crossing airspace being displayed since this isn't implemented yet.
+                                           if ( ( code.c2 == -1 && planes[i].lmc.c3 == 0 ) || 
+                                                   ( code.c1 == 0  && code.c2 == planes[i].lmc.c2 ) ) {
+                                                   mentry = current_transmissionlist->gen_text(station, code, tpars, false);
+                                                   transm = current_transmissionlist->gen_text(station, code, tpars, true);
+                                                   // is the transmission already registered?
+                                                   if (!current_atcdialog->trans_reg( ident, transm, APPROACH )) {
+                                                           current_atcdialog->add_entry( ident, transm, mentry, APPROACH, 0 );
+                                                   }
+                                           }
                                        }
                                }
                        }
@@ -139,10 +147,12 @@ void FGApproach::Update() {
        }
        
        for ( i=0; i<num_planes; i++ ) {
-               
-               if ( planes[i].ident == TPar.callsign && name == TPar.airport && TPar.station == "approach" ) {
-                       
-                       if ( TPar.request && TPar.intention == "landing" && ident == TPar.intid) {
+               //cout << "TPar.airport = " << TPar.airport << " TPar.station = " << TPar.station << " TPar.callsign = " << TPar.callsign << '\n';
+               //if ( planes[i].ident == TPar.callsign && name == TPar.airport && TPar.station == "approach" ) {
+                       //if ( TPar.request && TPar.intention == "landing" && ident == TPar.intid) {
+                       if(planes[i].ident == "Player" && fgGetBool("/sim/atc/opt0")) {
+                               //cout << "Landing requested\n";
+                               fgSetBool("/sim/atc/opt0", false);
                                planes[i].wpn = 0; 
                                // ===========================
                                // === calculate waypoints ===
@@ -168,14 +178,16 @@ void FGApproach::Update() {
                                else tpars.VDir = 2;
                                tpars.alt = planes[i].aalt;
                                message = current_transmissionlist->gen_text(station, code, tpars, true );
-                               globals->get_ATC_display()->RegisterSingleMessage( message, 0 );
+                               //cout << message << '\n';
+                               set_message(message);
                                planes[i].lmc = code;
                                planes[i].tlm = etime_node->getDoubleValue();
                                planes[i].on_crs = true;
                                planes[i].contact = 1;
                        }
-               }
+               //}
                
+               //if(1) {
                if ( planes[i].contact == 1 ) {
                        // =========================
                        // === update parameters ===
@@ -193,12 +205,13 @@ void FGApproach::Update() {
                        adif = angle_diff_deg( planes[i].hdg, planes[i].wpts[wpn][4] ) 
                        * SGD_DEGREES_TO_RADIANS;
                        datp = 2*sin(fabs(adif)/2.0)*sin(fabs(adif)/2.0) *
-                       planes[i].spd/3600. * planes[i].turn_rate + 
-                       planes[i].spd/3600. * 3.0;
+                              planes[i].spd/3600. * planes[i].turn_rate + 
+                              planes[i].spd/3600. * 3.0;
                        //cout << adif/SGD_DEGREES_TO_RADIANS << " " 
                        //     << datp << " " << planes[i].dnc << " " << planes[i].dcc <<endl;
                        if ( fabs(planes[i].dnc) < datp ) {
                        //if ( fabs(planes[i].dnc) < 0.3 && planes[i].dnwp < 1.0 ) {
+                               //cout << "Reached next waypoint!\n";
                                planes[i].wpn -= 1;
                                wpn = planes[i].wpn-1;
                                planes[i].ahdg = planes[i].wpts[wpn][4];
@@ -222,8 +235,9 @@ void FGApproach::Update() {
                                        else tpars.VDir = 2;
                                        tpars.alt = planes[i].aalt;
                                        message = current_transmissionlist->gen_text(station, code, tpars, true );
-                                       globals->get_ATC_display()->RegisterSingleMessage( message, 0 );
-                                       
+                                       //cout << "Approach transmitting...\n";
+                                       //cout << message << endl;
+                                       set_message(message);
                                }
                                else {
                                        code.c1 = 1;
@@ -231,7 +245,9 @@ void FGApproach::Update() {
                                        code.c3 = 0;
                                        tpars.runway = active_runway;
                                        message = current_transmissionlist->gen_text(station, code, tpars, true);
-                                       globals->get_ATC_display()->RegisterSingleMessage( message, 0 );
+                                       //cout << "Approach transmitting 2 ...\n";
+                                       //cout << message << endl;
+                                       set_message(message);
                                }
                                planes[i].lmc = code;
                                planes[i].tlm = etime_node->getDoubleValue();
@@ -244,8 +260,8 @@ void FGApproach::Update() {
                        // === come off course ? ===
                        // =========================
                        if ( fabs(planes[i].dcc) > 1.0 && 
-                               ( !planes[i].wp_change || 
-                       etime_node->getDoubleValue() - planes[i].tlm > tbm ) ) {
+                          ( !planes[i].wp_change || etime_node->getDoubleValue() - planes[i].tlm > tbm ) ) {
+                               //cout << "Off course!\n";
                                if ( planes[i].on_crs ) {
                                        if ( planes[i].dcc < 0) {
                                                planes[i].ahdg += 30.0;
@@ -262,8 +278,8 @@ void FGApproach::Update() {
                                //     << planes[i].tlm << endl;
                                // generate the message
                                if ( planes[i].on_crs || 
-                                       ( fabs(angle_diff_deg( planes[i].hdg, planes[i].ahdg )) >  30.0  && 
-                               etime_node->getDoubleValue() - planes[i].tlm > tbm) ) {
+                                  ( fabs(angle_diff_deg( planes[i].hdg, planes[i].ahdg )) >  30.0  && 
+                                   etime_node->getDoubleValue() - planes[i].tlm > tbm) ) {
                                        // generate the message
                                        code.c1 = 1;
                                        code.c2 = 4;
@@ -276,7 +292,9 @@ void FGApproach::Update() {
                                        else            tpars.tdir = 2;
                                        tpars.heading = planes[i].ahdg;
                                        message = current_transmissionlist->gen_text(station, code, tpars, true);
-                                       globals->get_ATC_display()->RegisterSingleMessage( message, 0 );
+                                       //cout << "Approach transmitting 3 ...\n";
+                                       //cout << message << '\n';
+                                       set_message(message);
                                        planes[i].lmc = code;
                                        planes[i].tlm = etime_node->getDoubleValue();
                                }
@@ -284,9 +302,10 @@ void FGApproach::Update() {
                                planes[i].on_crs = false;
                        }
                        else if ( !planes[i].on_crs ) {
+                               //cout << "Off course 2!\n";
                                wpn = planes[i].wpn-1;
                                adif = angle_diff_deg( planes[i].hdg, planes[i].wpts[wpn][4] ) 
-                               * SGD_DEGREES_TO_RADIANS;
+                                      * SGD_DEGREES_TO_RADIANS;
                                datp = 2*sin(fabs(adif)/2.0)*sin(fabs(adif)/2.0) *
                                planes[i].spd/3600. * planes[i].turn_rate + 
                                planes[i].spd/3600. * 3.0;
@@ -303,7 +322,9 @@ void FGApproach::Update() {
                                        else            tpars.tdir = 2;
                                        tpars.heading = planes[i].ahdg;
                                        message = current_transmissionlist->gen_text(station, code, tpars, true);
-                                       globals->get_ATC_display()->RegisterSingleMessage( message, 0 );
+                                       //cout << "Approach transmitting 4 ...\n";
+                                       //cout << message << '\n';
+                                       set_message(message);
                                        planes[i].lmc = code;
                                        planes[i].tlm = etime_node->getDoubleValue();
                                        
@@ -319,7 +340,7 @@ void FGApproach::Update() {
                        // ===================================================================
                        if ( planes[i].wpn == 2 && planes[i].dnwp < planes[i].spd/60.*2.0 ) {
                                
-                               double freq = 121.95;
+                               double freq = 121.95;   // Hardwired - FIXME
                                // generate message
                                code.c1 = 1;
                                code.c2 = 5;
@@ -328,7 +349,9 @@ void FGApproach::Update() {
                                tpars.callsign = "Player";
                                tpars.freq    = freq;
                                message = current_transmissionlist->gen_text(station, code, tpars, true);
-                               globals->get_ATC_display()->RegisterSingleMessage( message, 0 );
+                               //cout << "Approach transmitting 5 ...\n";
+                               //cout << message << '\n';
+                               set_message(message);
                                planes[i].lmc = code;
                                planes[i].tlm = etime_node->getDoubleValue();
                                
@@ -336,7 +359,6 @@ void FGApproach::Update() {
                        }
                }
        }
-       
 }
 
 
@@ -386,13 +408,13 @@ void FGApproach::calc_wp( const int &i ) {
        int wpn = planes[i].wpn;
        // waypoint 0: Threshold of active runway
        calc_gc_course_dist(Point3D(lon*SGD_DEGREES_TO_RADIANS, lat*SGD_DEGREES_TO_RADIANS, 0.0),
-       Point3D(active_rw_lon*SGD_DEGREES_TO_RADIANS,active_rw_lat*SGD_DEGREES_TO_RADIANS, 0.0 ),
-       &course, &d);
+                           Point3D(active_rw_lon*SGD_DEGREES_TO_RADIANS,active_rw_lat*SGD_DEGREES_TO_RADIANS, 0.0 ),
+                           &course, &d);
        double d1 = active_rw_hdg+180.0;
        if ( d1 > 360.0 ) d1 -=360.0;
        calc_cd_head_dist(360.0-course*SGD_RADIANS_TO_DEGREES, d/SG_NM_TO_METER, 
-       d1, active_rw_len/SG_NM_TO_METER/2.
-       &planes[i].wpts[wpn][0], &planes[i].wpts[wpn][1]);
+                         d1, active_rw_len/SG_NM_TO_METER/2.0
+                         &planes[i].wpts[wpn][0], &planes[i].wpts[wpn][1]);
        planes[i].wpts[wpn][2] = elev;
        planes[i].wpts[wpn][4] = 0.0;
        planes[i].wpts[wpn][5] = 0.0;
@@ -402,20 +424,18 @@ void FGApproach::calc_wp( const int &i ) {
        // horizontal navigation
        // ======================
        // waypoint 1: point for turning onto final
-       calc_cd_head_dist(planes[i].wpts[wpn-1][0], planes[i].wpts[wpn-1][1] , 
-       d1, lfl,
-       &planes[i].wpts[wpn][0], &planes[i].wpts[wpn][1]);
+       calc_cd_head_dist(planes[i].wpts[wpn-1][0], planes[i].wpts[wpn-1][1], d1, lfl,
+                         &planes[i].wpts[wpn][0], &planes[i].wpts[wpn][1]);
        calc_hd_course_dist(planes[i].wpts[wpn][0],   planes[i].wpts[wpn][1],
-       planes[i].wpts[wpn-1][0], planes[i].wpts[wpn-1][1],
-       &course, &d);
+                           planes[i].wpts[wpn-1][0], planes[i].wpts[wpn-1][1],
+                           &course, &d);
        planes[i].wpts[wpn][4] = course;
        planes[i].wpts[wpn][5] = d;
        wpn += 1;
        
        // calculate course and distance from plane position to waypoint 1
-       calc_hd_course_dist(planes[i].brg, planes[i].dist,
-       planes[i].wpts[1][0], planes[i].wpts[1][1],
-       &course, &d);
+       calc_hd_course_dist(planes[i].brg, planes[i].dist, planes[i].wpts[1][0], 
+                           planes[i].wpts[1][1], &course, &d);
        // check if airport is not between plane and waypoint 1 and
        // DCA to airport on course to waypoint 1 is larger than 10 miles
        double zero = 0.0;
@@ -424,23 +444,22 @@ void FGApproach::calc_wp( const int &i ) {
                // check if turning angle at waypoint 1 would be > max_ta
                if ( fabs(angle_diff_deg( planes[i].wpts[1][4], course )) > max_ta ) {
                        cd = calc_psl_dist(planes[i].brg, planes[i].dist,
-                       planes[i].wpts[1][0], planes[i].wpts[1][1],
-                       planes[i].wpts[1][4]);
+                            planes[i].wpts[1][0], planes[i].wpts[1][1],
+                            planes[i].wpts[1][4]);
                        a1 = atan2(cd,planes[i].wpts[1][1]);
                        planes[i].wpts[wpn][0] = planes[i].wpts[1][0] - a1/SGD_DEGREES_TO_RADIANS;
                        if ( planes[i].wpts[wpn][0] < 0.0)   planes[i].wpts[wpn][0] += 360.0;   
                        if ( planes[i].wpts[wpn][0] > 360.0) planes[i].wpts[wpn][0] -= 360.0;   
                        planes[i].wpts[wpn][1] = fabs(cd) / sin(fabs(a1));
                        calc_hd_course_dist(planes[i].wpts[wpn][0],   planes[i].wpts[wpn][1],
-                       planes[i].wpts[wpn-1][0], planes[i].wpts[wpn-1][1],
-                       &course, &d);
+                                           planes[i].wpts[wpn-1][0], planes[i].wpts[wpn-1][1],
+                                           &course, &d);
                        planes[i].wpts[wpn][4] = course;
                        planes[i].wpts[wpn][5] = d;
                        wpn += 1;
                        
-                       calc_hd_course_dist(planes[i].brg, planes[i].dist,
-                       planes[i].wpts[wpn-1][0], planes[i].wpts[wpn-1][1],
-                       &course, &d);
+                       calc_hd_course_dist(planes[i].brg, planes[i].dist, planes[i].wpts[wpn-1][0], 
+                                           planes[i].wpts[wpn-1][1], &course, &d);
                }
        } else {
                double leg = 10.0;
@@ -452,15 +471,15 @@ void FGApproach::calc_wp( const int &i ) {
                
                planes[i].wpts[wpn][1] = sqrt( planes[i].wpts[1][1]*planes[i].wpts[1][1] + leg*leg );
                calc_hd_course_dist(planes[i].wpts[wpn][0],   planes[i].wpts[wpn][1],
-               planes[i].wpts[wpn-1][0], planes[i].wpts[wpn-1][1],
-               &course, &d);
+                                   planes[i].wpts[wpn-1][0], planes[i].wpts[wpn-1][1],
+                                   &course, &d);
                planes[i].wpts[wpn][4] = course;
                planes[i].wpts[wpn][5] = d;
                wpn += 1;
                
                calc_hd_course_dist(planes[i].brg, planes[i].dist,
-               planes[i].wpts[wpn-1][0], planes[i].wpts[wpn-1][1],
-               &course, &d);
+                                   planes[i].wpts[wpn-1][0], planes[i].wpts[wpn-1][1],
+                                   &course, &d);
        }
        
        planes[i].wpts[wpn][0] = planes[i].brg;
@@ -489,7 +508,7 @@ void FGApproach::calc_wp( const int &i ) {
                double dalt = planes[i].alt - planes[i].wpts[j-1][2];
                if ( dalt > 0 ) {
                        alt = planes[i].wpts[j-1][2] + 
-                       (planes[i].wpts[j][5] / planes[i].spd) * 60.0 * planes[i].desc_rate;
+                             (planes[i].wpts[j][5] / planes[i].spd) * 60.0 * planes[i].desc_rate;
                        planes[i].wpts[j][2] = round_alt( false, alt );
                        if ( planes[i].wpts[j][2] > planes[i].alt ) 
                                planes[i].wpts[j][2] = round_alt( false, planes[i].alt );
@@ -504,7 +523,7 @@ void FGApproach::calc_wp( const int &i ) {
                cout << "Waypoint " << j << endl;
                cout << "------------------" << endl;
                cout << planes[i].wpts[j][0] << "   " << planes[i].wpts[j][1]
-               << "   " << planes[i].wpts[j][2] << "   " << planes[i].wpts[j][5]; 
+                    << "   " << planes[i].wpts[j][2] << "   " << planes[i].wpts[j][5]; 
                cout << endl << endl;
        }
        
@@ -534,50 +553,21 @@ double FGApproach::round_alt( const bool hl, double alt ) {
 // get active runway
 // ============================================================================
 void FGApproach::get_active_runway() {
+       //cout << "Entering FGApproach::get_active_runway()\n";
 
-#ifdef FG_WEATHERCM
-  sgVec3 position = { lat, lon, elev };
-  FGPhysicalProperty stationweather = WeatherDatabase->get(position);
-#else
   FGEnvironment stationweather =
-    globals->get_environment_mgr()->getEnvironment(lat, lon, elev);
-#endif
+      ((FGEnvironmentMgr *)globals->get_subsystem("environment"))
+        ->getEnvironment(lat, lon, elev);
 
-  SGPath path( globals->get_fg_root() );
-  path.append( "Airports" );
-  path.append( "runways.mk4" );
-  FGRunways runways( path.c_str() );
-  
-#ifdef FG_WEATHERCM
-  //Set the heading to into the wind
-  double wind_x = stationweather.Wind[0];
-  double wind_y = stationweather.Wind[1];
-  
-  double speed = sqrt( wind_x*wind_x + wind_y*wind_y ) * SG_METER_TO_NM / (60.0*60.0);
-  double hdg;
-  
-  //If no wind use 270degrees
-  if(speed == 0) {
-    hdg = 270;
-  } else {
-    // //normalize the wind to get the direction
-    //wind_x /= speed; wind_y /= speed;
-    
-    hdg = - atan2 ( wind_x, wind_y ) * SG_RADIANS_TO_DEGREES ;
-    if (hdg < 0.0)
-      hdg += 360.0;
-  }
-#else
   double hdg = stationweather.get_wind_from_heading_deg();
-#endif
   
   FGRunway runway;
-  if ( runways.search( ident, int(hdg), &runway) ) {
-    active_runway = runway.rwy_no;
-    active_rw_hdg = runway.heading;
-    active_rw_lon = runway.lon;
-    active_rw_lat = runway.lat;
-    active_rw_len = runway.length;
+  if ( globals->get_runways()->search( ident, int(hdg), &runway) ) {
+    active_runway = runway._rwy_no;
+    active_rw_hdg = runway._heading;
+    active_rw_lon = runway._lon;
+    active_rw_lat = runway._lat;
+    active_rw_len = runway._length;
     //cout << "Active runway is: " << active_runway << "  heading = " 
     // << active_rw_hdg 
     // << " lon = " << active_rw_lon 
@@ -621,12 +611,12 @@ void FGApproach::update_plane_dat() {
 // =======================================================================
 // Add plane to Approach list
 // =======================================================================
-void FGApproach::AddPlane(string pid) {
+void FGApproach::AddPlane(const string& pid) {
 
   int i;
   for ( i=0; i<num_planes; i++) {
     if ( planes[i].ident == pid) {
-      //cout << "Plane already registered: " << ident << " " << num_planes << endl;
+      //cout << "Plane already registered: " << planes[i].ident << ' ' << ident << ' ' << num_planes << endl;
       return;
     }
   }
@@ -664,8 +654,8 @@ double FGApproach::calc_psl_dist(const double &h1, const double &d1,
   x3 *= sqrt(val2);
   y3 *= sqrt(val2);
   double da = fabs(atan2(y3,x3) - atan2(y1-y2,x1-x2));
-  if ( da > SGD_PI ) da -= 2*SGD_PI;
-  if ( fabs(da) > SGD_PI/2.) {
+  if ( da > SGD_PI ) da -= SGD_2PI;
+  if ( fabs(da) > SGD_PI_2) {
     //if ( x3*(x1-x2) < 0.0 && y3*(y1-y2) < 0.0) {
     x3 *= -1.0;
     y3 *= -1.0;
@@ -675,7 +665,7 @@ double FGApproach::calc_psl_dist(const double &h1, const double &d1,
   double dis2   = y1-y2-y3;
   dis = sqrt(dis);
   da = atan2(dis2,dis1);
-  if ( da < 0.0 ) da  += 2*SGD_PI;
+  if ( da < 0.0 ) da  += SGD_2PI;
   if ( da < a3 )  dis *= -1.0;
   //cout << dis1 << " " << dis2 << " " << da*SGD_RADIANS_TO_DEGREES << " " << h3
   //     << " " << sqrt(dis1*dis1 + dis2*dis2) << " " << dis << endl;
@@ -703,7 +693,7 @@ void FGApproach::calc_cd_head_dist(const double &h1, const double &d1,
   *d2 = sqrt((x1+x2)*(x1+x2) + (y1+y2)*(y1+y2));
   *h2 = atan2( (y1+y2), (x1+x2) ) * SGD_RADIANS_TO_DEGREES;
   if ( *h2 < 0 ) *h2 = *h2+360;
-  }
+}
 
 
 
@@ -761,3 +751,11 @@ int FGApproach::RemovePlane() {
 
   return num_planes;
 }
+
+
+void FGApproach::set_message(const string &msg)
+{
+  fgSetString("/sim/messages/approach", msg.c_str());
+  globals->get_ATC_display()->RegisterSingleMessage( msg, 0 );
+}
+