1 // fg_init.cxx -- Flight Gear top level initialization routines
3 // Written by Curtis Olson, started August 1997.
5 // Copyright (C) 1997 Curtis L. Olson - curt@infoplane.com
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.
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.
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.
29 // For BC 5.01 this must be included before OpenGL includes.
30 #ifdef FG_MATH_EXCEPTION_CLASH
35 #include <simgear/xgl/xgl.h>
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.
43 # define _G_NO_EXTERN_TEMPLATES
46 #include <simgear/compiler.h>
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>
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>
87 #ifndef FG_OLD_WEATHER
88 # include <WeatherCM/FGLocalWeatherDatabase.h>
90 # include <Weather/weather.hxx>
93 #include "fg_init.hxx"
95 #include "globals.hxx"
98 #if defined(FX) && defined(XMESA)
102 FG_USING_STD(string);
104 extern const char *default_root;
107 extern void fgReshape( int width, int height );
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() );
118 // Next check home directory
119 char* envp = ::getenv( "HOME" );
120 if ( envp != NULL ) {
122 config.append( ".fgfsrc" );
123 globals->get_options()->scan_config_file_for_root( config.str() );
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);
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() );
142 // Next check home directory
143 char* envp = ::getenv( "HOME" );
144 if ( envp != NULL ) {
146 config.append( ".fgfsrc" );
147 globals->get_options()->parse_config_file( config.str() );
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 )
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 ...");
166 // find basic airport location info from airport database
167 bool fgFindAirportID( const string& id, FGAirport *a ) {
169 FGPath path( globals->get_options()->get_fg_root() );
170 path.append( "Airports" );
171 path.append( "simple.mk4" );
172 FGAirports airports( path.c_str() );
174 FG_LOG( FG_GENERAL, FG_INFO, "Searching for airport code = " << id );
176 if ( ! airports.search( id, a ) ) {
177 FG_LOG( FG_GENERAL, FG_ALERT,
178 "Failed to find " << id << " in " << path.str() );
185 FG_LOG( FG_GENERAL, FG_INFO,
186 "Position for " << id << " is ("
187 << a->longitude << ", "
188 << a->latitude << ")" );
194 // Set current_options lon/lat given an airport id
195 bool fgSetPosFromAirportID( const string& id ) {
199 FG_LOG( FG_GENERAL, FG_INFO,
200 "Attempting to set starting position from airport code " << id );
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",
207 current_properties.setDoubleValue("/position/latitude",
210 FG_LOG( FG_GENERAL, FG_INFO,
211 "Position for " << id << " is ("
212 << a.longitude << ", "
213 << a.latitude << ")" );
223 // Set current_options lon/lat given an airport id and heading (degrees)
224 bool fgSetPosFromAirportIDandHdg( const string& id, double tgt_hdg ) {
230 // set initial position from runway and heading
232 FGPath path( globals->get_options()->get_fg_root() );
233 path.append( "Airports" );
234 path.append( "runways.mk4" );
235 FGRunways runways( path.c_str() );
237 FG_LOG( FG_GENERAL, FG_INFO,
238 "Attempting to set starting position from runway code "
239 << id << " heading " << tgt_hdg );
241 // FGPath inpath( globals->get_options()->get_fg_root() );
242 // inpath.append( "Airports" );
243 // inpath.append( "apt_simple" );
244 // airports.load( inpath.c_str() );
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() );
251 if ( ! runways.search( id, &r ) ) {
252 FG_LOG( FG_GENERAL, FG_ALERT,
253 "Failed to find " << id << " in database." );
258 double min_diff = 360.0;
260 while ( r.id == id ) {
262 diff = tgt_hdg - r.heading;
263 while ( diff < -180.0 ) { diff += 360.0; }
264 while ( diff > 180.0 ) { diff -= 360.0; }
266 FG_LOG( FG_GENERAL, FG_INFO,
267 "Runway " << r.rwy_no << " heading = " << r.heading <<
268 " diff = " << diff );
269 if ( diff < min_diff ) {
276 diff = tgt_hdg - r.heading - 180.0;
277 while ( diff < -180.0 ) { diff += 360.0; }
278 while ( diff > 180.0 ) { diff -= 360.0; }
280 FG_LOG( FG_GENERAL, FG_INFO,
281 "Runway -" << r.rwy_no << " heading = " <<
283 " diff = " << diff );
284 if ( diff < min_diff ) {
293 FG_LOG( FG_GENERAL, FG_INFO, "closest runway = " << found_r.rwy_no
294 << " + " << found_dir );
300 double heading = found_r.heading + found_dir;
301 while ( heading >= 360.0 ) { heading -= 360.0; }
303 double lat2, lon2, az2;
304 double azimuth = found_r.heading + found_dir + 180.0;
305 while ( azimuth >= 360.0 ) { azimuth -= 360.0; }
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);
321 FG_LOG( FG_GENERAL, FG_INFO,
322 "Position for " << id << " is ("
324 << lat2 << ") new heading is "
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();
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 );
340 if ( scenery.cur_elev > globals->get_options()->get_altitude() - 1) {
341 globals->get_options()->set_altitude( scenery.cur_elev + 1 );
344 FG_LOG( FG_GENERAL, FG_INFO,
345 "starting altitude is = " << globals->get_options()->get_altitude() );
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 );
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);
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) << ")" );
370 // General house keeping initializations
371 bool fgInitGeneral( void ) {
374 #if defined(FX) && defined(XMESA)
375 char *mesa_win_state;
378 FG_LOG( FG_GENERAL, FG_INFO, "General Initialization" );
379 FG_LOG( FG_GENERAL, FG_INFO, "======= ==============" );
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." );
389 FG_LOG( FG_GENERAL, FG_INFO, "FG_ROOT = " << '"' << root << '"' << endl );
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;
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;
417 FG_LOG( FG_GENERAL, FG_INFO, "Initialize Subsystems");
418 FG_LOG( FG_GENERAL, FG_INFO, "========== ==========");
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() ) ) {
425 FG_LOG( FG_GENERAL, FG_ALERT, "Error loading material lib!" );
429 // Initialize the Scenery Management subsystem
430 if ( fgSceneryInit() ) {
431 // Material lib initialized ok.
433 FG_LOG( FG_GENERAL, FG_ALERT, "Error in Scenery initialization!" );
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() );
442 FG_LOG( FG_GENERAL, FG_ALERT, "Error in Tile Manager initialization!" );
446 FG_LOG( FG_GENERAL, FG_DEBUG,
447 "Current terrain elevation after tile mgr init " <<
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;
466 FG_LOG( FG_GENERAL, FG_ALERT,
467 "No flight model, can't init aircraft" );
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.
475 // set the initial position
478 // Calculate ground elevation at starting point (we didn't have
479 // tmp_abs_view_pos calculated when fgTileMgrUpdate() was called above
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
486 // now handled inside of the fgTileMgrUpdate()
489 geod_pos = Point3D( cur_fdm_state->get_Longitude(), cur_fdm_state->get_Latitude(), 0.0);
490 tmp_abs_view_pos = sgGeodToCart(geod_pos);
492 FG_LOG( FG_GENERAL, FG_DEBUG,
493 "Initial abs_view_pos = " << tmp_abs_view_pos );
495 fgTileMgrCurElev( cur_fdm_state->get_Longitude(), cur_fdm_state->get_Latitude(),
497 FG_LOG( FG_GENERAL, FG_DEBUG,
498 "Altitude after update " << scenery.cur_elev );
501 fgFDMSetGroundElevation( globals->get_options()->get_flight_model(),
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() );
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 );
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) << ")" );
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.
523 double sea_level_radius_meters;
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 );
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());
536 cur_fdm_state->set_sin_lat_geocentric(sin(lat_geoc));
537 cur_fdm_state->set_cos_lat_geocentric(cos(lat_geoc));
539 // The following section sets up the flight model EOM parameters
540 // and should really be read in from one or more files.
543 cur_fdm_state->set_Velocities_Local( globals->get_options()->get_uBody(),
544 globals->get_options()->get_vBody(),
545 globals->get_options()->get_wBody());
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 );
552 // Initial Angular Body rates
553 cur_fdm_state->set_Omega_Body( 7.206685E-05, 0.0, 9.492658E-05 );
555 cur_fdm_state->set_Earth_position_angle( 0.0 );
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 );
561 // CG position w.r.t. ref. point
562 cur_fdm_state->set_CG_Position( 0.0, 0.0, 0.0 );
564 // Initialize the event manager
565 global_events.Init();
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 );
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);
584 // Initialize the planetary subsystem
585 // global_events.Register( "fgPlanetsInit()", fgPlanetsInit,
586 // fgEVENT::FG_EVENT_READY, 600000);
588 // Initialize the sun's position
589 // global_events.Register( "fgSunInit()", fgSunInit,
590 // fgEVENT::FG_EVENT_READY, 30000 );
592 // Intialize the moon's position
593 // global_events.Register( "fgMoonInit()", fgMoonInit,
594 // fgEVENT::FG_EVENT_READY, 600000 );
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.
601 global_events.Register( "fgUpdateSunPos()", fgUpdateSunPos,
602 fgEVENT::FG_EVENT_READY, 60000);
603 global_events.Register( "fgUpdateMoonPos()", fgUpdateMoonPos,
604 fgEVENT::FG_EVENT_READY, 60000);
606 // Initialize Lighting interpolation tables
609 // update the lighting parameters (based on sun angle)
610 global_events.Register( "fgLight::Update()",
611 fgMethodCallback<fgLIGHT>( &cur_light_params,
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);
618 // Initialize the weather modeling subsystem
619 #ifndef FG_OLD_WEATHER
620 // Initialize the WeatherDatabase
621 FG_LOG(FG_GENERAL, FG_INFO, "Creating LocalWeatherDatabase");
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;
632 WeatherDatabase = FGLocalWeatherDatabase::theFGLocalWeatherDatabase;
634 // register the periodic update of the weather
635 global_events.Register( "weather update", fgUpdateWeatherDatabase,
636 fgEVENT::FG_EVENT_READY, 30000);
638 current_weather.Init();
641 // Initialize vor/ndb/ils/fix list management and query systems
642 FG_LOG(FG_GENERAL, FG_INFO, "Loading Navaids");
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 );
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 );
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 );
662 // Initialize the underlying radio stack model
663 current_radiostack = new FGRadioStack;
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 );
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 );
673 // current_radiostack->set_adf_freq( 266.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
687 current_radiostack->search( cur_fdm_state->get_Longitude(),
688 cur_fdm_state->get_Latitude(),
689 cur_fdm_state->get_Altitude() * FEET_TO_METER );
691 current_radiostack->update( cur_fdm_state->get_Longitude(),
692 cur_fdm_state->get_Latitude(),
693 cur_fdm_state->get_Altitude() * FEET_TO_METER );
695 // Search radio database once per second
696 global_events.Register( "fgRadioSearch()", fgRadioSearch,
697 fgEVENT::FG_EVENT_READY, 1000);
700 // Initialize the Cockpit subsystem
701 if( fgCockpitInit( ¤t_aircraft )) {
702 // Cockpit initialized ok.
704 FG_LOG( FG_GENERAL, FG_ALERT, "Error in Cockpit initialization!" );
708 // Initialize the flight model subsystem data structures base on
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
716 FG_LOG( FG_GENERAL, FG_ALERT, "FDM init() failed! Cannot continue." );
720 // I'm just sticking this here for now, it should probably move
722 scenery.cur_elev = cur_fdm_state->get_Runway_altitude() * FEET_TO_METER;
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 );
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
736 if ( fgJoystickInit() ) {
737 // Joystick initialized ok.
739 FG_LOG( FG_GENERAL, FG_ALERT, "Error in Joystick initialization!" );
743 current_autopilot = new FGAutopilot;
744 current_autopilot->init();
746 // initialize the gui parts of the autopilot
752 // Initialize I/O channels
753 #if ! defined( macintosh )
757 // Initialize the 2D panel.
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);
766 FG_LOG(FG_INPUT, FG_INFO, "Loaded new panel from " << panel_path);
768 // Initialize the BFI
771 FG_LOG( FG_GENERAL, FG_INFO, endl);
777 void fgReInitSubsystems( void )
779 bool freeze = globals->get_freeze();
781 globals->set_freeze( true );
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() );
788 FG_LOG( FG_GENERAL, FG_ALERT, "Error in Tile Manager initialization!" );
792 // cout << "current scenery elev = " << scenery.cur_elev << endl;
795 fgFDMSetGroundElevation( globals->get_options()->get_flight_model(),
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() );
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 );
806 double sea_level_radius_meters;
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 );
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());
819 cur_fdm_state->set_sin_lat_geocentric(sin(lat_geoc));
820 cur_fdm_state->set_cos_lat_geocentric(cos(lat_geoc));
822 // The following section sets up the flight model EOM parameters
823 // and should really be read in from one or more files.
826 cur_fdm_state->set_Velocities_Local( globals->get_options()->get_uBody(),
827 globals->get_options()->get_vBody(),
828 globals->get_options()->get_wBody());
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 );
835 // Initial Angular Body rates
836 cur_fdm_state->set_Omega_Body( 7.206685E-05, 0.0, 9.492658E-05 );
838 cur_fdm_state->set_Earth_position_angle( 0.0 );
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 );
844 // CG position w.r.t. ref. point
845 cur_fdm_state->set_CG_Position( 0.0, 0.0, 0.0 );
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 );
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());
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() );
863 scenery.cur_elev = cur_fdm_state->get_Runway_altitude() * FEET_TO_METER;
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 );
869 controls.reset_all();
870 current_autopilot->reset();
873 globals->set_freeze( false );