]> git.mxchange.org Git - flightgear.git/blob - src/Main/fg_init.cxx
630afbe8345be6e9d3d7ba51b50cd2ae2027cd89
[flightgear.git] / src / Main / fg_init.cxx
1 // fg_init.cxx -- Flight Gear top level initialization routines
2 //
3 // Written by Curtis Olson, started August 1997.
4 //
5 // Copyright (C) 1997  Curtis L. Olson  - curt@infoplane.com
6 //
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License as
9 // published by the Free Software Foundation; either version 2 of the
10 // License, or (at your option) any later version.
11 //
12 // This program is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 // General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 //
21 //
22 // $Id$
23
24
25 #ifdef HAVE_CONFIG_H
26 #  include <config.h>
27 #endif
28
29 // For BC 5.01 this must be included before OpenGL includes.
30 #ifdef FG_MATH_EXCEPTION_CLASH
31 #  include <math.h>
32 #endif
33
34 #include <GL/glut.h>
35 #include <simgear/xgl/xgl.h>
36
37 #include <stdio.h>
38 #include <stdlib.h>
39
40 // work around a stdc++ lib bug in some versions of linux, but doesn't
41 // seem to hurt to have this here for all versions of Linux.
42 #ifdef linux
43 #  define _G_NO_EXTERN_TEMPLATES
44 #endif
45
46 #include <simgear/compiler.h>
47
48 #include STL_STRING
49
50 #include <simgear/constants.h>
51 #include <simgear/debug/logstream.hxx>
52 #include <simgear/math/point3d.hxx>
53 #include <simgear/math/polar3d.hxx>
54 #include <simgear/math/sg_geodesy.hxx>
55 #include <simgear/misc/fgpath.hxx>
56 #include <simgear/timing/sg_time.hxx>
57
58 #include <Aircraft/aircraft.hxx>
59 #include <Airports/runways.hxx>
60 #include <Airports/simple.hxx>
61 #include <Autopilot/auto_gui.hxx>
62 #include <Autopilot/newauto.hxx>
63 #include <Cockpit/cockpit.hxx>
64 #include <Cockpit/radiostack.hxx>
65 #include <Cockpit/panel.hxx>
66 #include <Cockpit/panel_io.hxx>
67 #include <FDM/ADA.hxx>
68 #include <FDM/Balloon.h>
69 #include <FDM/External.hxx>
70 #include <FDM/JSBSim.hxx>
71 #include <FDM/LaRCsim.hxx>
72 #include <FDM/MagicCarpet.hxx>
73 #include <Include/general.hxx>
74 #include <Joystick/joystick.hxx>
75 #include <Objects/matlib.hxx>
76 #include <Navaids/fixlist.hxx>
77 #include <Navaids/ilslist.hxx>
78 #include <Navaids/navlist.hxx>
79 #include <Scenery/scenery.hxx>
80 #include <Scenery/tilemgr.hxx>
81 #include <Time/event.hxx>
82 #include <Time/light.hxx>
83 #include <Time/sunpos.hxx>
84 #include <Time/moonpos.hxx>
85 #include <Time/tmp.hxx>
86
87 #ifndef FG_OLD_WEATHER
88 #  include <WeatherCM/FGLocalWeatherDatabase.h>
89 #else
90 #  include <Weather/weather.hxx>
91 #endif
92
93 #include "fg_init.hxx"
94 #include "fg_io.hxx"
95 #include "globals.hxx"
96 #include "bfi.hxx"
97
98 #if defined(FX) && defined(XMESA)
99 #include <GL/xmesa.h>
100 #endif
101
102 FG_USING_STD(string);
103
104 extern const char *default_root;
105
106 // from main.cxx
107 extern void fgReshape( int width, int height );
108
109
110 // Read in configuration (file and command line) and just set fg_root
111 bool fgInitFGRoot ( int argc, char **argv ) {
112     // Attempt to locate and parse a config file
113     // First check fg_root
114     FGPath config( globals->get_options()->get_fg_root() );
115     config.append( "system.fgfsrc" );
116     globals->get_options()->scan_config_file_for_root( config.str() );
117
118     // Next check home directory
119     char* envp = ::getenv( "HOME" );
120     if ( envp != NULL ) {
121         config.set( envp );
122         config.append( ".fgfsrc" );
123         globals->get_options()->scan_config_file_for_root( config.str() );
124     }
125
126     // Parse remaining command line options
127     // These will override anything specified in a config file
128     globals->get_options()->scan_command_line_for_root(argc, argv);
129
130     return true;
131 }
132
133
134 // Read in configuration (file and command line)
135 bool fgInitConfig ( int argc, char **argv ) {
136     // Attempt to locate and parse a config file
137     // First check fg_root
138     FGPath config( globals->get_options()->get_fg_root() );
139     config.append( "system.fgfsrc" );
140     globals->get_options()->parse_config_file( config.str() );
141
142     // Next check home directory
143     char* envp = ::getenv( "HOME" );
144     if ( envp != NULL ) {
145         config.set( envp );
146         config.append( ".fgfsrc" );
147         globals->get_options()->parse_config_file( config.str() );
148     }
149
150     // Parse remaining command line options
151     // These will override anything specified in a config file
152     if ( globals->get_options()->parse_command_line(argc, argv) !=
153          FGOptions::FG_OPTIONS_OK )
154     {
155         // Something must have gone horribly wrong with the command
156         // line parsing or maybe the user just requested help ... :-)
157         globals->get_options()->usage();
158         FG_LOG( FG_GENERAL, FG_ALERT, "\nExiting ...");
159         return false;
160     }
161
162     return true;
163 }
164
165
166 // find basic airport location info from airport database
167 bool fgFindAirportID( const string& id, FGAirport *a ) {
168     if ( id.length() ) {
169         FGPath path( globals->get_options()->get_fg_root() );
170         path.append( "Airports" );
171         path.append( "simple.mk4" );
172         FGAirports airports( path.c_str() );
173
174         FG_LOG( FG_GENERAL, FG_INFO, "Searching for airport code = " << id );
175
176         if ( ! airports.search( id, a ) ) {
177             FG_LOG( FG_GENERAL, FG_ALERT,
178                     "Failed to find " << id << " in " << path.str() );
179             return false;
180         }
181     } else {
182         return false;
183     }
184
185     FG_LOG( FG_GENERAL, FG_INFO,
186             "Position for " << id << " is ("
187             << a->longitude << ", "
188             << a->latitude << ")" );
189
190     return true;
191 }
192
193
194 // Set current_options lon/lat given an airport id
195 bool fgSetPosFromAirportID( const string& id ) {
196     FGAirport a;
197     double lon, lat;
198
199     FG_LOG( FG_GENERAL, FG_INFO,
200             "Attempting to set starting position from airport code " << id );
201
202     if ( fgFindAirportID( id, &a ) ) {
203         globals->get_options()->set_lon( a.longitude );
204         globals->get_options()->set_lat( a.latitude );
205         current_properties.setDoubleValue("/position/longitude",
206                                           a.longitude);
207         current_properties.setDoubleValue("/position/latitude",
208                                           a.latitude);
209
210         FG_LOG( FG_GENERAL, FG_INFO,
211                 "Position for " << id << " is ("
212                 << a.longitude << ", "
213                 << a.latitude << ")" );
214
215         return true;
216     } else {
217         return false;
218     }
219
220 }
221
222
223 // Set current_options lon/lat given an airport id and heading (degrees)
224 bool fgSetPosFromAirportIDandHdg( const string& id, double tgt_hdg ) {
225     FGRunway r;
226     FGRunway found_r;
227     double found_dir;
228
229     if ( id.length() ) {
230         // set initial position from runway and heading
231
232         FGPath path( globals->get_options()->get_fg_root() );
233         path.append( "Airports" );
234         path.append( "runways.mk4" );
235         FGRunways runways( path.c_str() );
236
237         FG_LOG( FG_GENERAL, FG_INFO,
238                 "Attempting to set starting position from runway code "
239                 << id << " heading " << tgt_hdg );
240
241         // FGPath inpath( globals->get_options()->get_fg_root() );
242         // inpath.append( "Airports" );
243         // inpath.append( "apt_simple" );
244         // airports.load( inpath.c_str() );
245
246         // FGPath outpath( globals->get_options()->get_fg_root() );
247         // outpath.append( "Airports" );
248         // outpath.append( "simple.gdbm" );
249         // airports.dump_gdbm( outpath.c_str() );
250
251         if ( ! runways.search( id, &r ) ) {
252             FG_LOG( FG_GENERAL, FG_ALERT,
253                     "Failed to find " << id << " in database." );
254             return false;
255         }
256
257         double diff;
258         double min_diff = 360.0;
259
260         while ( r.id == id ) {
261             // forward direction
262             diff = tgt_hdg - r.heading;
263             while ( diff < -180.0 ) { diff += 360.0; }
264             while ( diff >  180.0 ) { diff -= 360.0; }
265             diff = fabs(diff);
266             FG_LOG( FG_GENERAL, FG_INFO,
267                     "Runway " << r.rwy_no << " heading = " << r.heading <<
268                     " diff = " << diff );
269             if ( diff < min_diff ) {
270                 min_diff = diff;
271                 found_r = r;
272                 found_dir = 0;
273             }
274
275             // reverse direction
276             diff = tgt_hdg - r.heading - 180.0;
277             while ( diff < -180.0 ) { diff += 360.0; }
278             while ( diff >  180.0 ) { diff -= 360.0; }
279             diff = fabs(diff);
280             FG_LOG( FG_GENERAL, FG_INFO,
281                     "Runway -" << r.rwy_no << " heading = " <<
282                     r.heading + 180.0 <<
283                     " diff = " << diff );
284             if ( diff < min_diff ) {
285                 min_diff = diff;
286                 found_r = r;
287                 found_dir = 180.0;
288             }
289
290             runways.next( &r );
291         }
292
293         FG_LOG( FG_GENERAL, FG_INFO, "closest runway = " << found_r.rwy_no
294                 << " + " << found_dir );
295
296     } else {
297         return false;
298     }
299
300     double heading = found_r.heading + found_dir;
301     while ( heading >= 360.0 ) { heading -= 360.0; }
302
303     double lat2, lon2, az2;
304     double azimuth = found_r.heading + found_dir + 180.0;
305     while ( azimuth >= 360.0 ) { azimuth -= 360.0; }
306
307     FG_LOG( FG_GENERAL, FG_INFO,
308             "runway =  " << found_r.lon << ", " << found_r.lat
309             << " length = " << found_r.length * FEET_TO_METER * 0.5 
310             << " heading = " << azimuth );
311     geo_direct_wgs_84 ( 0, found_r.lat, found_r.lon, 
312                         azimuth, found_r.length * FEET_TO_METER * 0.5 - 5.0,
313                         &lat2, &lon2, &az2 );
314     globals->get_options()->set_lon( lon2 );
315     globals->get_options()->set_lat( lat2 );
316     globals->get_options()->set_heading( heading );
317     current_properties.setDoubleValue("/position/longitude", lon2);
318     current_properties.setDoubleValue("/position/latitude", lat2);
319     current_properties.setDoubleValue("/orientation/heading", heading);
320
321     FG_LOG( FG_GENERAL, FG_INFO,
322             "Position for " << id << " is ("
323             << lon2 << ", "
324             << lat2 << ") new heading is "
325             << heading );
326
327     return true;
328 }
329
330
331 // Set initial position and orientation
332 bool fgInitPosition( void ) {
333     FGInterface *f = current_aircraft.fdm_state;
334     string id = globals->get_options()->get_airport_id();
335
336     // set initial position from default or command line coordinates
337     f->set_Longitude( globals->get_options()->get_lon() * DEG_TO_RAD );
338     f->set_Latitude( globals->get_options()->get_lat() * DEG_TO_RAD );
339
340     if ( scenery.cur_elev > globals->get_options()->get_altitude() - 1) {
341         globals->get_options()->set_altitude( scenery.cur_elev + 1 );
342     }
343
344     FG_LOG( FG_GENERAL, FG_INFO,
345             "starting altitude is = " << globals->get_options()->get_altitude() );
346
347     f->set_Altitude( globals->get_options()->get_altitude() * METER_TO_FEET );
348     fgFDMSetGroundElevation( globals->get_options()->get_flight_model(),
349                              f->get_Altitude() * FEET_TO_METER );
350
351 #if 0
352     current_properties.setDoubleValue("/position/longitude",
353                                       f->get_Longitude() * RAD_TO_DEG);
354     current_properties.setDoubleValue("/position/latitude",
355                                       f->get_Latitude() * RAD_TO_DEG);
356     current_properties.setDoubleValue("/position/altitude",
357                                       f->get_Altitude() * RAD_TO_DEG);
358 #endif
359
360     FG_LOG( FG_GENERAL, FG_INFO,
361             "Initial position is: ("
362             << (f->get_Longitude() * RAD_TO_DEG) << ", "
363             << (f->get_Latitude() * RAD_TO_DEG) << ", "
364             << (f->get_Altitude() * FEET_TO_METER) << ")" );
365
366     return true;
367 }
368
369
370 // General house keeping initializations
371 bool fgInitGeneral( void ) {
372     string root;
373
374 #if defined(FX) && defined(XMESA)
375     char *mesa_win_state;
376 #endif
377
378     FG_LOG( FG_GENERAL, FG_INFO, "General Initialization" );
379     FG_LOG( FG_GENERAL, FG_INFO, "======= ==============" );
380
381     root = globals->get_options()->get_fg_root();
382     if ( ! root.length() ) {
383         // No root path set? Then bail ...
384         FG_LOG( FG_GENERAL, FG_ALERT,
385                 "Cannot continue without environment variable FG_ROOT"
386                 << "being defined." );
387         exit(-1);
388     }
389     FG_LOG( FG_GENERAL, FG_INFO, "FG_ROOT = " << '"' << root << '"' << endl );
390
391 #if defined(FX) && defined(XMESA)
392     // initialize full screen flag
393     global_fullscreen = false;
394     if ( strstr ( general.get_glRenderer(), "Glide" ) ) {
395         // Test for the MESA_GLX_FX env variable
396         if ( (mesa_win_state = getenv( "MESA_GLX_FX" )) != NULL) {
397             // test if we are fullscreen mesa/glide
398             if ( (mesa_win_state[0] == 'f') ||
399                  (mesa_win_state[0] == 'F') ) {
400                 global_fullscreen = true;
401             }
402         }
403     }
404 #endif
405
406     return true;
407 }
408
409
410 // This is the top level init routine which calls all the other
411 // initialization routines.  If you are adding a subsystem to flight
412 // gear, its initialization call should located in this routine.
413 // Returns non-zero if a problem encountered.
414 bool fgInitSubsystems( void ) {
415     fgLIGHT *l = &cur_light_params;
416
417     FG_LOG( FG_GENERAL, FG_INFO, "Initialize Subsystems");
418     FG_LOG( FG_GENERAL, FG_INFO, "========== ==========");
419
420     // Initialize the material property lib
421     FGPath mpath( globals->get_options()->get_fg_root() );
422     mpath.append( "materials" );
423     if ( material_lib.load( mpath.str() ) ) {
424     } else {
425         FG_LOG( FG_GENERAL, FG_ALERT, "Error loading material lib!" );
426         exit(-1);
427     }
428
429     // Initialize the Scenery Management subsystem
430     if ( fgSceneryInit() ) {
431         // Material lib initialized ok.
432     } else {
433         FG_LOG( FG_GENERAL, FG_ALERT, "Error in Scenery initialization!" );
434         exit(-1);
435     }
436
437     if ( global_tile_mgr.init() ) {
438         // Load the local scenery data
439         global_tile_mgr.update( globals->get_options()->get_lon(),
440                                 globals->get_options()->get_lat() );
441     } else {
442         FG_LOG( FG_GENERAL, FG_ALERT, "Error in Tile Manager initialization!" );
443         exit(-1);
444     }
445
446     FG_LOG( FG_GENERAL, FG_DEBUG,
447             "Current terrain elevation after tile mgr init " <<
448             scenery.cur_elev );
449
450     if ( globals->get_options()->get_flight_model() == FGInterface::FG_LARCSIM ) {
451         cur_fdm_state = new FGLaRCsim;
452     } else if ( globals->get_options()->get_flight_model() == FGInterface::FG_JSBSIM ) {
453         cur_fdm_state = new FGJSBsim;
454     } else if ( globals->get_options()->get_flight_model() == FGInterface::FG_ADA ) {
455         cur_fdm_state = new FGADA;
456     } else if ( globals->get_options()->get_flight_model() == 
457                 FGInterface::FG_BALLOONSIM ) {
458         cur_fdm_state = new FGBalloonSim;
459     } else if ( globals->get_options()->get_flight_model() == 
460                 FGInterface::FG_MAGICCARPET ) {
461         cur_fdm_state = new FGMagicCarpet;
462     } else if ( globals->get_options()->get_flight_model() == 
463                 FGInterface::FG_EXTERNAL ) {
464         cur_fdm_state = new FGExternal;
465     } else {
466         FG_LOG( FG_GENERAL, FG_ALERT,
467                 "No flight model, can't init aircraft" );
468         exit(-1);
469     }
470
471     // allocates structures so must happen before any of the flight
472     // model or control parameters are set
473     fgAircraftInit();   // In the future this might not be the case.
474
475     // set the initial position
476     fgInitPosition();
477
478     // Calculate ground elevation at starting point (we didn't have
479     // tmp_abs_view_pos calculated when fgTileMgrUpdate() was called above
480     //
481     // calculalate a cartesian point somewhere along the line between
482     // the center of the earth and our view position.  Doesn't have to
483     // be the exact elevation (this is good because we don't know it
484     // yet :-)
485
486     // now handled inside of the fgTileMgrUpdate()
487
488     /*
489     geod_pos = Point3D( cur_fdm_state->get_Longitude(), cur_fdm_state->get_Latitude(), 0.0);
490     tmp_abs_view_pos = sgGeodToCart(geod_pos);
491
492     FG_LOG( FG_GENERAL, FG_DEBUG,
493             "Initial abs_view_pos = " << tmp_abs_view_pos );
494     scenery.cur_elev =
495         fgTileMgrCurElev( cur_fdm_state->get_Longitude(), cur_fdm_state->get_Latitude(),
496                           tmp_abs_view_pos );
497     FG_LOG( FG_GENERAL, FG_DEBUG,
498             "Altitude after update " << scenery.cur_elev );
499     */
500
501     fgFDMSetGroundElevation( globals->get_options()->get_flight_model(),
502                              scenery.cur_elev );
503
504     // Reset our altitude if we are below ground
505     FG_LOG( FG_GENERAL, FG_DEBUG, "Current altitude = " << cur_fdm_state->get_Altitude() );
506     FG_LOG( FG_GENERAL, FG_DEBUG, "Current runway altitude = " <<
507             cur_fdm_state->get_Runway_altitude() );
508
509     if ( cur_fdm_state->get_Altitude() < cur_fdm_state->get_Runway_altitude() + 3.758099) {
510         cur_fdm_state->set_Altitude( cur_fdm_state->get_Runway_altitude() + 3.758099 );
511     }
512
513     FG_LOG( FG_GENERAL, FG_INFO,
514             "Updated position (after elevation adj): ("
515             << (cur_fdm_state->get_Latitude() * RAD_TO_DEG) << ", "
516             << (cur_fdm_state->get_Longitude() * RAD_TO_DEG) << ", "
517             << (cur_fdm_state->get_Altitude() * FEET_TO_METER) << ")" );
518
519     // We need to calculate a few more values here that would normally
520     // be calculated by the FDM so that the current_view.UpdateViewMath()
521     // routine doesn't get hosed.
522
523     double sea_level_radius_meters;
524     double lat_geoc;
525     // Set the FG variables first
526     sgGeodToGeoc( cur_fdm_state->get_Latitude(), cur_fdm_state->get_Altitude(),
527                   &sea_level_radius_meters, &lat_geoc);
528     cur_fdm_state->set_Geocentric_Position( lat_geoc, cur_fdm_state->get_Longitude(),
529                                 cur_fdm_state->get_Altitude() +
530                                 (sea_level_radius_meters * METER_TO_FEET) );
531     cur_fdm_state->set_Sea_level_radius( sea_level_radius_meters * METER_TO_FEET );
532
533     cur_fdm_state->set_sin_cos_longitude(cur_fdm_state->get_Longitude());
534     cur_fdm_state->set_sin_cos_latitude(cur_fdm_state->get_Latitude());
535         
536     cur_fdm_state->set_sin_lat_geocentric(sin(lat_geoc));
537     cur_fdm_state->set_cos_lat_geocentric(cos(lat_geoc));
538
539     // The following section sets up the flight model EOM parameters
540     // and should really be read in from one or more files.
541
542     // Initial Velocity
543     cur_fdm_state->set_Velocities_Local( globals->get_options()->get_uBody(),
544                              globals->get_options()->get_vBody(),
545                              globals->get_options()->get_wBody());
546
547     // Initial Orientation
548     cur_fdm_state->set_Euler_Angles( globals->get_options()->get_roll() * DEG_TO_RAD,
549                          globals->get_options()->get_pitch() * DEG_TO_RAD,
550                          globals->get_options()->get_heading() * DEG_TO_RAD );
551
552     // Initial Angular Body rates
553     cur_fdm_state->set_Omega_Body( 7.206685E-05, 0.0, 9.492658E-05 );
554
555     cur_fdm_state->set_Earth_position_angle( 0.0 );
556
557     // Mass properties and geometry values
558     cur_fdm_state->set_Inertias( 8.547270E+01,
559                      1.048000E+03, 3.000000E+03, 3.530000E+03, 0.000000E+00 );
560
561     // CG position w.r.t. ref. point
562     cur_fdm_state->set_CG_Position( 0.0, 0.0, 0.0 );
563
564     // Initialize the event manager
565     global_events.Init();
566
567     // Output event stats every 60 seconds
568     global_events.Register( "fgEVENT_MGR::PrintStats()",
569                             fgMethodCallback<fgEVENT_MGR>( &global_events,
570                                                    &fgEVENT_MGR::PrintStats),
571                             fgEVENT::FG_EVENT_READY, 60000 );
572
573     // Initialize view parameters
574     FG_LOG( FG_GENERAL, FG_DEBUG, "Before current_view.init()");
575     globals->get_current_view()->Init();
576     globals->get_pilot_view()->Init();
577     FG_LOG( FG_GENERAL, FG_DEBUG, "After current_view.init()");
578     globals->get_current_view()->UpdateViewMath(*cur_fdm_state);
579     globals->get_pilot_view()->UpdateViewMath(*cur_fdm_state);
580     FG_LOG( FG_GENERAL, FG_DEBUG, "  abs_view_pos = "
581             << globals->get_current_view()->get_abs_view_pos());
582     // current_view.UpdateWorldToEye(f);
583
584     // Initialize the planetary subsystem
585     // global_events.Register( "fgPlanetsInit()", fgPlanetsInit,
586     //                      fgEVENT::FG_EVENT_READY, 600000);
587
588     // Initialize the sun's position
589     // global_events.Register( "fgSunInit()", fgSunInit,
590     //                      fgEVENT::FG_EVENT_READY, 30000 );
591
592     // Intialize the moon's position
593     // global_events.Register( "fgMoonInit()", fgMoonInit,
594     //                      fgEVENT::FG_EVENT_READY, 600000 );
595
596     // fgUpdateSunPos() needs a few position and view parameters set
597     // so it can calculate local relative sun angle and a few other
598     // things for correctly orienting the sky.
599     fgUpdateSunPos();
600     fgUpdateMoonPos();
601     global_events.Register( "fgUpdateSunPos()", fgUpdateSunPos,
602                             fgEVENT::FG_EVENT_READY, 60000);
603     global_events.Register( "fgUpdateMoonPos()", fgUpdateMoonPos,
604                             fgEVENT::FG_EVENT_READY, 60000);
605
606     // Initialize Lighting interpolation tables
607     l->Init();
608
609     // update the lighting parameters (based on sun angle)
610     global_events.Register( "fgLight::Update()",
611                             fgMethodCallback<fgLIGHT>( &cur_light_params,
612                                                        &fgLIGHT::Update),
613                             fgEVENT::FG_EVENT_READY, 30000 );
614     // update the current timezone each 30 minutes
615     global_events.Register( "fgUpdateLocalTime()", fgUpdateLocalTime,
616                             fgEVENT::FG_EVENT_READY, 1800000);
617
618     // Initialize the weather modeling subsystem
619 #ifndef FG_OLD_WEATHER
620     // Initialize the WeatherDatabase
621     FG_LOG(FG_GENERAL, FG_INFO, "Creating LocalWeatherDatabase");
622     sgVec3 position;
623     sgSetVec3( position, current_aircraft.fdm_state->get_Latitude(),
624                current_aircraft.fdm_state->get_Longitude(),
625                current_aircraft.fdm_state->get_Altitude() * FEET_TO_METER );
626     FGLocalWeatherDatabase::theFGLocalWeatherDatabase = 
627         new FGLocalWeatherDatabase( position, globals->get_options()->get_fg_root() );
628     // cout << theFGLocalWeatherDatabase << endl;
629     // cout << "visibility = " 
630     //      << theFGLocalWeatherDatabase->getWeatherVisibility() << endl;
631
632     WeatherDatabase = FGLocalWeatherDatabase::theFGLocalWeatherDatabase;
633      
634     // register the periodic update of the weather
635     global_events.Register( "weather update", fgUpdateWeatherDatabase,
636                             fgEVENT::FG_EVENT_READY, 30000);
637 #else
638     current_weather.Init();
639 #endif
640
641     // Initialize vor/ndb/ils/fix list management and query systems
642     FG_LOG(FG_GENERAL, FG_INFO, "Loading Navaids");
643
644     FG_LOG(FG_GENERAL, FG_INFO, "  VOR/NDB");
645     current_navlist = new FGNavList;
646     FGPath p_nav( globals->get_options()->get_fg_root() );
647     p_nav.append( "Navaids/default.nav" );
648     current_navlist->init( p_nav );
649
650     FG_LOG(FG_GENERAL, FG_INFO, "  ILS");
651     current_ilslist = new FGILSList;
652     FGPath p_ils( globals->get_options()->get_fg_root() );
653     p_ils.append( "Navaids/default.ils" );
654     current_ilslist->init( p_ils );
655
656     FG_LOG(FG_GENERAL, FG_INFO, "  Fixes");
657     current_fixlist = new FGFixList;
658     FGPath p_fix( globals->get_options()->get_fg_root() );
659     p_fix.append( "Navaids/default.fix" );
660     current_fixlist->init( p_fix );
661
662     // Initialize the underlying radio stack model
663     current_radiostack = new FGRadioStack;
664
665 //     current_radiostack->set_nav1_freq( 117.30 );
666 //     current_radiostack->set_nav1_alt_freq( 110.30 );
667 //     current_radiostack->set_nav1_sel_radial( 119.0 );
668
669 //     current_radiostack->set_nav2_freq( 111.80 );
670 //     current_radiostack->set_nav2_alt_freq( 115.70 );
671 //     current_radiostack->set_nav2_sel_radial( 029.0 );
672
673 //     current_radiostack->set_adf_freq( 266.0 );
674
675 #if 0
676     // This block of settings are Alex's defaults for San Diego
677     current_radiostack->set_nav1_freq( 111.70 );
678     current_radiostack->set_nav1_alt_freq( 115.30 );
679     current_radiostack->set_nav1_sel_radial( 280.0 );
680     current_radiostack->set_nav2_freq( 117.80 );
681     current_radiostack->set_nav2_alt_freq( 114.00 );
682     current_radiostack->set_nav2_sel_radial( 68.0 );
683     current_radiostack->set_adf_freq( 210.0 );
684     // End of Alex's custom settings
685 #endif
686
687     current_radiostack->search( cur_fdm_state->get_Longitude(),
688                                 cur_fdm_state->get_Latitude(),
689                                 cur_fdm_state->get_Altitude() * FEET_TO_METER );
690
691     current_radiostack->update( cur_fdm_state->get_Longitude(),
692                                 cur_fdm_state->get_Latitude(),
693                                 cur_fdm_state->get_Altitude() * FEET_TO_METER );
694
695     // Search radio database once per second
696     global_events.Register( "fgRadioSearch()", fgRadioSearch,
697                             fgEVENT::FG_EVENT_READY, 1000);
698
699
700     // Initialize the Cockpit subsystem
701     if( fgCockpitInit( &current_aircraft )) {
702         // Cockpit initialized ok.
703     } else {
704         FG_LOG( FG_GENERAL, FG_ALERT, "Error in Cockpit initialization!" );
705         exit(-1);
706     }
707
708     // Initialize the flight model subsystem data structures base on
709     // above values
710
711     // fgFDMInit( globals->get_options()->get_flight_model(), cur_fdm_state,
712     //            1.0 / globals->get_options()->get_model_hz() );
713     if ( cur_fdm_state->init( 1.0 / globals->get_options()->get_model_hz() ) ) {
714         // fdm init successful
715     } else {
716         FG_LOG( FG_GENERAL, FG_ALERT, "FDM init() failed!  Cannot continue." );
717         exit(-1);
718     }
719
720     // I'm just sticking this here for now, it should probably move
721     // eventually
722     scenery.cur_elev = cur_fdm_state->get_Runway_altitude() * FEET_TO_METER;
723
724     if ( cur_fdm_state->get_Altitude() < cur_fdm_state->get_Runway_altitude() + 3.758099) {
725         cur_fdm_state->set_Altitude( cur_fdm_state->get_Runway_altitude() + 3.758099 );
726     }
727
728     FG_LOG( FG_GENERAL, FG_INFO,
729             "Updated position (after elevation adj): ("
730             << (cur_fdm_state->get_Latitude() * RAD_TO_DEG) << ", "
731             << (cur_fdm_state->get_Longitude() * RAD_TO_DEG) << ", "
732             << (cur_fdm_state->get_Altitude() * FEET_TO_METER) << ")" );
733     // end of thing that I just stuck in that I should probably move
734
735     // Joystick support
736     if ( fgJoystickInit() ) {
737         // Joystick initialized ok.
738     } else {
739         FG_LOG( FG_GENERAL, FG_ALERT, "Error in Joystick initialization!" );
740     }
741
742     // Autopilot init
743     current_autopilot = new FGAutopilot;
744     current_autopilot->init();
745
746     // initialize the gui parts of the autopilot
747     NewTgtAirportInit();
748     fgAPAdjustInit() ;
749     NewHeadingInit();
750     NewAltitudeInit();
751
752     // Initialize I/O channels
753 #if ! defined( macintosh )
754     fgIOInit();
755 #endif
756
757     // Initialize the 2D panel.
758     string panel_path =
759         current_properties.getStringValue("/sim/panel/path",
760                                           "Panels/Default/default.xml");
761     current_panel = fgReadPanel(panel_path);
762     if (current_panel == 0) {
763         FG_LOG(FG_INPUT, FG_ALERT,
764                "Error reading new panel from " << panel_path);
765     }
766     FG_LOG(FG_INPUT, FG_INFO, "Loaded new panel from " << panel_path);
767
768     // Initialize the BFI
769     FGBFI::init();
770
771     FG_LOG( FG_GENERAL, FG_INFO, endl);
772
773     return true;
774 }
775
776
777 void fgReInitSubsystems( void )
778 {
779     bool freeze = globals->get_freeze();
780     if( !freeze )
781         globals->set_freeze( true );
782     
783     if( global_tile_mgr.init() ) {
784         // Load the local scenery data
785         global_tile_mgr.update( globals->get_options()->get_lon(),
786                                 globals->get_options()->get_lat() );
787     } else {
788         FG_LOG( FG_GENERAL, FG_ALERT, "Error in Tile Manager initialization!" );
789                 exit(-1);
790     }
791
792     // cout << "current scenery elev = " << scenery.cur_elev << endl;
793
794     fgInitPosition();
795     fgFDMSetGroundElevation( globals->get_options()->get_flight_model(), 
796                              scenery.cur_elev );
797
798     // Reset our altitude if we are below ground
799     FG_LOG( FG_GENERAL, FG_DEBUG, "Current altitude = " << cur_fdm_state->get_Altitude() );
800     FG_LOG( FG_GENERAL, FG_DEBUG, "Current runway altitude = " << 
801             cur_fdm_state->get_Runway_altitude() );
802
803     if ( cur_fdm_state->get_Altitude() < cur_fdm_state->get_Runway_altitude() + 3.758099) {
804         cur_fdm_state->set_Altitude( cur_fdm_state->get_Runway_altitude() + 3.758099 );
805     }
806     double sea_level_radius_meters;
807     double lat_geoc;
808     // Set the FG variables first
809     sgGeodToGeoc( cur_fdm_state->get_Latitude(), cur_fdm_state->get_Altitude(), 
810                   &sea_level_radius_meters, &lat_geoc);
811     cur_fdm_state->set_Geocentric_Position( lat_geoc, cur_fdm_state->get_Longitude(), 
812                                 cur_fdm_state->get_Altitude() + 
813                                 (sea_level_radius_meters * METER_TO_FEET) );
814     cur_fdm_state->set_Sea_level_radius( sea_level_radius_meters * METER_TO_FEET );
815         
816     cur_fdm_state->set_sin_cos_longitude(cur_fdm_state->get_Longitude());
817     cur_fdm_state->set_sin_cos_latitude(cur_fdm_state->get_Latitude());
818         
819     cur_fdm_state->set_sin_lat_geocentric(sin(lat_geoc));
820     cur_fdm_state->set_cos_lat_geocentric(cos(lat_geoc));
821
822     // The following section sets up the flight model EOM parameters
823     // and should really be read in from one or more files.
824
825     // Initial Velocity
826     cur_fdm_state->set_Velocities_Local( globals->get_options()->get_uBody(),
827                              globals->get_options()->get_vBody(),
828                              globals->get_options()->get_wBody());
829
830     // Initial Orientation
831     cur_fdm_state->set_Euler_Angles( globals->get_options()->get_roll() * DEG_TO_RAD,
832                          globals->get_options()->get_pitch() * DEG_TO_RAD,
833                          globals->get_options()->get_heading() * DEG_TO_RAD );
834
835     // Initial Angular Body rates
836     cur_fdm_state->set_Omega_Body( 7.206685E-05, 0.0, 9.492658E-05 );
837
838     cur_fdm_state->set_Earth_position_angle( 0.0 );
839
840     // Mass properties and geometry values
841     cur_fdm_state->set_Inertias( 8.547270E+01, 
842                      1.048000E+03, 3.000000E+03, 3.530000E+03, 0.000000E+00 );
843
844     // CG position w.r.t. ref. point
845     cur_fdm_state->set_CG_Position( 0.0, 0.0, 0.0 );
846
847     // Initialize view parameters
848     globals->get_current_view()->set_view_offset( 0.0 );
849     globals->get_current_view()->set_goal_view_offset( 0.0 );
850     globals->get_pilot_view()->set_view_offset( 0.0 );
851     globals->get_pilot_view()->set_goal_view_offset( 0.0 );
852
853     FG_LOG( FG_GENERAL, FG_DEBUG, "After current_view.init()");
854     globals->get_current_view()->UpdateViewMath(*cur_fdm_state);
855     globals->get_pilot_view()->UpdateViewMath(*cur_fdm_state);
856     FG_LOG( FG_GENERAL, FG_DEBUG, "  abs_view_pos = "
857             << globals->get_current_view()->get_abs_view_pos());
858
859     // fgFDMInit( globals->get_options()->get_flight_model(), cur_fdm_state, 
860     //            1.0 / globals->get_options()->get_model_hz() );
861     cur_fdm_state->init( 1.0 / globals->get_options()->get_model_hz() );
862
863     scenery.cur_elev = cur_fdm_state->get_Runway_altitude() * FEET_TO_METER;
864
865     if ( cur_fdm_state->get_Altitude() < cur_fdm_state->get_Runway_altitude() + 3.758099) {
866         cur_fdm_state->set_Altitude( cur_fdm_state->get_Runway_altitude() + 3.758099 );
867     }
868
869     controls.reset_all();
870     current_autopilot->reset();
871
872     if( !freeze )
873         globals->set_freeze( false );
874 }