]> git.mxchange.org Git - flightgear.git/blob - src/Main/bfi.cxx
FG_ to SG_ namespace changes.
[flightgear.git] / src / Main / bfi.cxx
1 // bfi.cxx - Big Friendly Interface implementation
2 //
3 // Written by David Megginson, started February, 2000.
4 //
5 // Copyright (C) 2000  David Megginson - david@megginson.com
6 //
7 // THIS CLASS IS DEPRECATED; USE THE PROPERTY MANAGER INSTEAD.
8 //
9 // This program is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU General Public License as
11 // published by the Free Software Foundation; either version 2 of the
12 // License, or (at your option) any later version.
13 //
14 // This program is distributed in the hope that it will be useful, but
15 // WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 // General Public License for more details.
18 //
19 // You should have received a copy of the GNU General Public License
20 // along with this program; if not, write to the Free Software
21 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 //
23 // $Id$
24
25 #include "fgfs.hxx"
26
27 #include <simgear/constants.h>
28 #include <simgear/debug/logstream.hxx>
29 #include <simgear/ephemeris/ephemeris.hxx>
30 #include <simgear/math/sg_types.hxx>
31 #include <simgear/misc/props.hxx>
32 #include <simgear/timing/sg_time.hxx>
33
34 #include <Aircraft/aircraft.hxx>
35 #include <FDM/UIUCModel/uiuc_aircraftdir.h>
36 #include <Controls/controls.hxx>
37 #include <Autopilot/newauto.hxx>
38 #include <Scenery/scenery.hxx>
39 #include <Time/light.hxx>
40 #include <Time/event.hxx>
41 #include <Time/sunpos.hxx>
42 #include <Time/tmp.hxx>
43 #include <Cockpit/radiostack.hxx>
44 #include <Cockpit/panel.hxx>
45 #ifndef FG_OLD_WEATHER
46 #  include <WeatherCM/FGLocalWeatherDatabase.h>
47 #else
48 #  include <Weather/weather.hxx>
49 #endif
50
51 #include "globals.hxx"
52 #include "fg_init.hxx"
53 #include "fg_props.hxx"
54
55 SG_USING_NAMESPACE(std);
56
57
58 #include "bfi.hxx"
59
60
61 \f
62 ////////////////////////////////////////////////////////////////////////
63 // Static variables.
64 ////////////////////////////////////////////////////////////////////////
65
66                                 // Yech -- not thread-safe, etc. etc.
67 static bool _needReinit = false;
68 static string _temp;
69
70 static inline void needReinit ()
71 {
72   _needReinit = true;
73 }
74
75
76 /**
77  * Reinitialize FGFS to use the new BFI settings.
78  */
79 static inline void
80 reinit ()
81 {
82                                 // Save the state of everything
83                                 // that's going to get clobbered
84                                 // when we reinit the subsystems.
85
86   FG_LOG(FG_GENERAL, FG_INFO, "Starting BFI reinit");
87
88                                 // TODO: add more AP stuff
89   bool apHeadingLock = FGBFI::getAPHeadingLock();
90   bool apAltitudeLock = FGBFI::getAPAltitudeLock();
91   double apAltitude = FGBFI::getAPAltitude();
92   bool gpsLock = FGBFI::getGPSLock();
93   // double gpsLatitude = FGBFI::getGPSTargetLatitude();
94   // double gpsLongitude = FGBFI::getGPSTargetLongitude();
95
96   fgReInitSubsystems();
97
98                                 // FIXME: this is wrong.
99                                 // All of these are scheduled events,
100                                 // and it should be possible to force
101                                 // them all to run once.
102   fgUpdateSunPos();
103   fgUpdateMoonPos();
104   cur_light_params.Update();
105   fgUpdateLocalTime();
106   fgUpdateWeatherDatabase();
107   current_radiostack->search();
108
109                                 // Restore all of the old states.
110   FGBFI::setAPHeadingLock(apHeadingLock);
111   FGBFI::setAPAltitudeLock(apAltitudeLock);
112   FGBFI::setAPAltitude(apAltitude);
113   FGBFI::setGPSLock(gpsLock);
114
115   _needReinit = false;
116
117   FG_LOG(FG_GENERAL, FG_INFO, "Ending BFI reinit");
118 }
119
120 // BEGIN: kludge
121 // Allow the view to be set from two axes (i.e. a joystick hat)
122 // This needs to be in FGViewer itself, somehow.
123 static double axisLong = 0.0;
124 static double axisLat = 0.0;
125
126 static inline void
127 _set_view_from_axes ()
128 {
129                                 // Take no action when hat is centered
130   if (axisLong == 0 && axisLat == 0)
131     return;
132
133   double viewDir = 0;
134
135   if (axisLong < 0) {           // Longitudinal axis forward
136     if (axisLat < 0)
137       viewDir = 45;
138     else if (axisLat > 0)
139       viewDir = 315;
140     else
141       viewDir = 0;
142   } else if (axisLong > 0) {    // Longitudinal axis backward
143     if (axisLat < 0)
144       viewDir = 135;
145     else if (axisLat > 0)
146       viewDir = 225;
147     else
148       viewDir = 180;
149   } else {                      // Longitudinal axis neutral
150     if (axisLat < 0)
151       viewDir = 90;
152     else
153       viewDir = 270;
154   }
155
156   globals->get_current_view()->set_goal_view_offset(viewDir*DEG_TO_RAD);
157 //   globals->get_current_view()->set_view_offset(viewDir*DEG_TO_RAD);
158 }
159
160 // END: kludge
161
162
163 \f
164 ////////////////////////////////////////////////////////////////////////
165 // Local functions
166 ////////////////////////////////////////////////////////////////////////
167
168
169 /**
170  * Initialize the BFI by binding its functions to properties.
171  *
172  * TODO: perhaps these should migrate into the individual modules
173  * (i.e. they should register themselves).
174  */
175 void
176 FGBFI::init ()
177 {
178   FG_LOG(FG_GENERAL, FG_INFO, "Starting BFI init");
179
180                                 // Simulation
181   fgTie("/sim/aircraft-dir", getAircraftDir, setAircraftDir);
182   fgTie("/sim/time/gmt", getDateString, setDateString);
183   fgTie("/sim/time/gmt-string", getGMTString);
184
185                                 // Orientation
186   fgTie("/orientation/heading-magnetic", getHeadingMag);
187
188                                 // Engine
189   fgTie("/engines/engine0/rpm", getRPM);
190   fgTie("/engines/engine0/egt", getEGT);
191   fgTie("/engines/engine0/cht", getCHT);
192   fgTie("/engines/engine0/mp", getMP);
193   fgTie("/engines/engine0/fuel-flow", getFuelFlow);
194
195   //consumables
196   fgTie("/consumables/fuel/tank1/level", getTank1Fuel, setTank1Fuel, false);
197   fgTie("/consumables/fuel/tank2/level", getTank2Fuel, setTank2Fuel, false);
198
199                                 // Autopilot
200   fgTie("/autopilot/locks/altitude", getAPAltitudeLock, setAPAltitudeLock);
201   fgTie("/autopilot/settings/altitude", getAPAltitude, setAPAltitude);
202   fgTie("/autopilot/settings/climb-rate", getAPClimb, setAPClimb, false);
203   fgTie("/autopilot/locks/heading", getAPHeadingLock, setAPHeadingLock);
204   fgTie("/autopilot/settings/heading-bug", getAPHeadingBug, setAPHeadingBug,
205         false);
206   fgTie("/autopilot/locks/wing-leveler", getAPWingLeveler, setAPWingLeveler);
207   fgTie("/autopilot/locks/nav1", getAPNAV1Lock, setAPNAV1Lock);
208
209                                 // Weather
210   fgTie("/environment/visibility", getVisibility, setVisibility);
211   fgTie("/environment/wind-north", getWindNorth, setWindNorth);
212   fgTie("/environment/wind-east", getWindEast, setWindEast);
213   fgTie("/environment/wind-down", getWindDown, setWindDown);
214
215                                 // View
216   fgTie("/sim/field-of-view", getFOV, setFOV);
217   fgTie("/sim/view/axes/long", (double(*)())0, setViewAxisLong);
218   fgTie("/sim/view/axes/lat", (double(*)())0, setViewAxisLat);
219
220   _needReinit = false;
221
222   FG_LOG(FG_GENERAL, FG_INFO, "Ending BFI init");
223 }
224
225
226 /**
227  * Reinitialize FGFS if required.
228  *
229  * Some changes (especially those in aircraft position) require that
230  * FGFS be reinitialized afterwards.  Rather than reinitialize after
231  * every change, the setter methods simply set a flag so that there
232  * can be a single reinit at the end of the frame.
233  */
234 void
235 FGBFI::update ()
236 {
237   _set_view_from_axes();
238   if (_needReinit) {
239     reinit();
240   }
241 }
242
243
244 \f
245 ////////////////////////////////////////////////////////////////////////
246 // Simulation.
247 ////////////////////////////////////////////////////////////////////////
248
249
250 /**
251  * Return the current aircraft directory (UIUC) as a string.
252  */
253 string 
254 FGBFI::getAircraftDir ()
255 {
256   return aircraft_dir;
257 }
258
259
260 /**
261  * Set the current aircraft directory (UIUC).
262  */
263 void
264 FGBFI::setAircraftDir (string dir)
265 {
266   if (getAircraftDir() != dir) {
267     aircraft_dir = dir;
268     needReinit();
269   }
270 }
271
272
273 /**
274  * Return the current Zulu time.
275  */
276 string 
277 FGBFI::getDateString ()
278 {
279   string out;
280   char buf[64];
281   struct tm * t = globals->get_time_params()->getGmt();
282   sprintf(buf, "%.4d-%.2d-%.2dT%.2d:%.2d:%.2d",
283           t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
284           t->tm_hour, t->tm_min, t->tm_sec);
285   out = buf;
286   return out;
287 }
288
289
290 /**
291  * Set the current Zulu time.
292  */
293 void
294 FGBFI::setDateString (string date_string)
295 // FGBFI::setTimeGMT (time_t time)
296 {
297   SGTime * st = globals->get_time_params();
298   struct tm * current_time = st->getGmt();
299   struct tm new_time;
300
301                                 // Scan for basic ISO format
302                                 // YYYY-MM-DDTHH:MM:SS
303   int ret = sscanf(date_string.c_str(), "%d-%d-%dT%d:%d:%d",
304                    &(new_time.tm_year), &(new_time.tm_mon),
305                    &(new_time.tm_mday), &(new_time.tm_hour),
306                    &(new_time.tm_min), &(new_time.tm_sec));
307
308                                 // Be pretty picky about this, so
309                                 // that strange things don't happen
310                                 // if the save file has been edited
311                                 // by hand.
312   if (ret != 6) {
313     FG_LOG(FG_INPUT, FG_ALERT, "Date/time string " << date_string
314            << " not in YYYY-MM-DDTHH:MM:SS format; skipped");
315     return;
316   }
317
318                                 // OK, it looks like we got six
319                                 // values, one way or another.
320   new_time.tm_year -= 1900;
321   new_time.tm_mon -= 1;
322
323                                 // Now, tell flight gear to use
324                                 // the new time.  This was far
325                                 // too difficult, by the way.
326   long int warp =
327     mktime(&new_time) - mktime(current_time) + globals->get_warp();
328   double lon = current_aircraft.fdm_state->get_Longitude();
329   double lat = current_aircraft.fdm_state->get_Latitude();
330   // double alt = current_aircraft.fdm_state->get_Altitude() * FEET_TO_METER;
331   globals->set_warp(warp);
332   st->update(lon, lat, warp);
333   fgUpdateSkyAndLightingParams();
334 }
335
336
337 /**
338  * Return the GMT as a string.
339  */
340 string 
341 FGBFI::getGMTString ()
342 {
343   string out;
344   char buf[16];
345   struct tm * t = globals->get_time_params()->getGmt();
346   sprintf(buf, " %.2d:%.2d:%.2d",
347           t->tm_hour, t->tm_min, t->tm_sec);
348   out = buf;
349   return out;
350 }
351
352
353 \f
354 ////////////////////////////////////////////////////////////////////////
355 // Position
356 ////////////////////////////////////////////////////////////////////////
357
358
359 /**
360  * Return the current latitude in degrees (negative for south).
361  */
362 double
363 FGBFI::getLatitude ()
364 {
365   return current_aircraft.fdm_state->get_Latitude() * RAD_TO_DEG;
366 }
367
368
369 /**
370  * Set the current latitude in degrees (negative for south).
371  */
372 void
373 FGBFI::setLatitude (double latitude)
374 {
375   current_aircraft.fdm_state->set_Latitude(latitude * DEG_TO_RAD);
376 }
377
378
379 /**
380  * Return the current longitude in degrees (negative for west).
381  */
382 double
383 FGBFI::getLongitude ()
384 {
385   return current_aircraft.fdm_state->get_Longitude() * RAD_TO_DEG;
386 }
387
388
389 /**
390  * Set the current longitude in degrees (negative for west).
391  */
392 void
393 FGBFI::setLongitude (double longitude)
394 {
395   current_aircraft.fdm_state->set_Longitude(longitude * DEG_TO_RAD);
396 }
397
398
399 /**
400  * Return the current altitude in feet.
401  */
402 double
403 FGBFI::getAltitude ()
404 {
405   return current_aircraft.fdm_state->get_Altitude();
406 }
407
408
409
410 /**
411  * Return the current altitude in above the terrain.
412  */
413 double
414 FGBFI::getAGL ()
415 {
416   return current_aircraft.fdm_state->get_Altitude()
417          - (scenery.cur_elev * METER_TO_FEET);
418 }
419
420
421 /**
422  * Set the current altitude in feet.
423  */
424 void
425 FGBFI::setAltitude (double altitude)
426 {
427   current_aircraft.fdm_state->set_Altitude(altitude);
428 }
429
430
431 \f
432 ////////////////////////////////////////////////////////////////////////
433 // Attitude
434 ////////////////////////////////////////////////////////////////////////
435
436
437 /**
438  * Return the current heading in degrees.
439  */
440 double
441 FGBFI::getHeading ()
442 {
443   return current_aircraft.fdm_state->get_Psi() * RAD_TO_DEG;
444 }
445
446
447 /**
448  * Return the current heading in degrees.
449  */
450 double
451 FGBFI::getHeadingMag ()
452 {
453   return current_aircraft.fdm_state->get_Psi() * RAD_TO_DEG - getMagVar();
454 }
455
456
457 /**
458  * Set the current heading in degrees.
459  */
460 void
461 FGBFI::setHeading (double heading)
462 {
463   FGInterface * fdm = current_aircraft.fdm_state;
464   fdm->set_Euler_Angles(fdm->get_Phi(), fdm->get_Theta(),
465                         heading * DEG_TO_RAD);
466 }
467
468
469 /**
470  * Return the current pitch in degrees.
471  */
472 double
473 FGBFI::getPitch ()
474 {
475   return current_aircraft.fdm_state->get_Theta() * RAD_TO_DEG;
476 }
477
478
479 /**
480  * Set the current pitch in degrees.
481  */
482 void
483 FGBFI::setPitch (double pitch)
484 {
485   FGInterface * fdm = current_aircraft.fdm_state;
486   fdm->set_Euler_Angles(fdm->get_Phi(), pitch * DEG_TO_RAD, fdm->get_Psi());
487 }
488
489
490 /**
491  * Return the current roll in degrees.
492  */
493 double
494 FGBFI::getRoll ()
495 {
496   return current_aircraft.fdm_state->get_Phi() * RAD_TO_DEG;
497 }
498
499
500 /**
501  * Set the current roll in degrees.
502  */
503 void
504 FGBFI::setRoll (double roll)
505 {
506   FGInterface * fdm = current_aircraft.fdm_state;
507   fdm->set_Euler_Angles(roll * DEG_TO_RAD, fdm->get_Theta(), fdm->get_Psi());
508 }
509
510
511 /**
512  * Return the current engine0 rpm
513  */
514 double
515 FGBFI::getRPM ()
516 {
517   if ( current_aircraft.fdm_state->get_engine(0) != NULL ) {
518       return current_aircraft.fdm_state->get_engine(0)->get_RPM();
519   } else {
520       return 0.0;
521   }
522 }
523
524
525 /**
526  * Set the current engine0 rpm
527  */
528 void
529 FGBFI::setRPM (double rpm)
530 {
531     if ( current_aircraft.fdm_state->get_engine(0) != NULL ) {
532         if (getRPM() != rpm) {
533             current_aircraft.fdm_state->get_engine(0)->set_RPM( rpm );
534         }
535     }
536 }
537
538
539 /**
540  * Return the current engine0 EGT.
541  */
542 double
543 FGBFI::getEGT ()
544 {
545   if ( current_aircraft.fdm_state->get_engine(0) != NULL ) {
546       return current_aircraft.fdm_state->get_engine(0)->get_EGT();
547   } else {
548       return 0.0;
549   }
550 }
551
552
553 /**
554  * Return the current engine0 CHT.
555  */
556 double
557 FGBFI::getCHT ()
558 {
559   if ( current_aircraft.fdm_state->get_engine(0) != NULL ) {
560       return current_aircraft.fdm_state->get_engine(0)->get_CHT();
561   } else {
562       return 0.0;
563   }
564 }
565
566
567 /**
568  * Return the current engine0 Manifold Pressure.
569  */
570 double
571 FGBFI::getMP ()
572 {
573   if ( current_aircraft.fdm_state->get_engine(0) != NULL ) {
574       return current_aircraft.fdm_state->get_engine(0)->get_Manifold_Pressure();
575   } else {
576       return 0.0;
577   }
578 }
579
580 /**
581  * Return the current engine0 fuel flow
582  */
583 double
584 FGBFI::getFuelFlow ()
585 {
586   if ( current_aircraft.fdm_state->get_engine(0) != NULL ) {
587       return current_aircraft.fdm_state->get_engine(0)->get_Fuel_Flow();
588   } else {
589       return 0.0;
590   }
591 }
592
593 ////////////////////////////////////////////////////////////////////////
594 // Consumables
595 ////////////////////////////////////////////////////////////////////////
596
597 /**
598  * Return the fuel level in tank 1
599  */
600 double
601 FGBFI::getTank1Fuel ()
602 {
603   return current_aircraft.fdm_state->get_Tank1Fuel();
604 }
605
606 void
607 FGBFI::setTank1Fuel ( double gals )
608 {
609   current_aircraft.fdm_state->set_Tank1Fuel( gals );
610 }
611
612 /**
613  * Return the fuel level in tank 2
614  */
615 double
616 FGBFI::getTank2Fuel ()
617 {
618   return current_aircraft.fdm_state->get_Tank2Fuel();
619 }
620
621 void
622 FGBFI::setTank2Fuel ( double gals )
623 {
624   current_aircraft.fdm_state->set_Tank2Fuel( gals );
625 }
626
627 \f
628 ////////////////////////////////////////////////////////////////////////
629 // Velocities
630 ////////////////////////////////////////////////////////////////////////
631
632
633 /**
634  * Return the current airspeed in knots.
635  */
636 double
637 FGBFI::getAirspeed ()
638 {
639                                 // FIXME: should we add speed-up?
640   return current_aircraft.fdm_state->get_V_calibrated_kts();
641 }
642
643
644 /**
645  * Set the calibrated airspeed in knots.
646  */
647 void
648 FGBFI::setAirspeed (double speed)
649 {
650   current_aircraft.fdm_state->set_V_calibrated_kts(speed);
651 }
652
653
654 /**
655  * Return the current sideslip (FIXME: units unknown).
656  */
657 double
658 FGBFI::getSideSlip ()
659 {
660   return current_aircraft.fdm_state->get_Beta();
661 }
662
663
664 /**
665  * Return the current climb rate in feet/minute
666  */
667 double
668 FGBFI::getVerticalSpeed ()
669 {
670                                 // What about meters?
671   return current_aircraft.fdm_state->get_Climb_Rate() * 60.0;
672 }
673
674
675 /**
676  * Get the current north velocity (units??).
677  */
678 double
679 FGBFI::getSpeedNorth ()
680 {
681   return current_aircraft.fdm_state->get_V_north();
682 }
683
684
685 // /**
686 //  * Set the current north velocity (units??).
687 //  */
688 // void
689 // FGBFI::setSpeedNorth (double speed)
690 // {
691 //   FGInterface * fdm = current_aircraft.fdm_state;
692 // //   fdm->set_Velocities_Local(speed, fdm->get_V_east(), fdm->get_V_down());
693 // }
694
695
696 /**
697  * Get the current east velocity (units??).
698  */
699 double
700 FGBFI::getSpeedEast ()
701 {
702   return current_aircraft.fdm_state->get_V_east();
703 }
704
705
706 // /**
707 //  * Set the current east velocity (units??).
708 //  */
709 // void
710 // FGBFI::setSpeedEast (double speed)
711 // {
712 //   FGInterface * fdm = current_aircraft.fdm_state;
713 // //   fdm->set_Velocities_Local(fdm->get_V_north(), speed, fdm->get_V_down());
714 // }
715
716
717 /**
718  * Get the current down velocity (units??).
719  */
720 double
721 FGBFI::getSpeedDown ()
722 {
723   return current_aircraft.fdm_state->get_V_down();
724 }
725
726
727 // /**
728 //  * Set the current down velocity (units??).
729 //  */
730 // void
731 // FGBFI::setSpeedDown (double speed)
732 // {
733 //   FGInterface * fdm = current_aircraft.fdm_state;
734 // //   fdm->set_Velocities_Local(fdm->get_V_north(), fdm->get_V_east(), speed);
735 // }
736
737
738 \f
739 ////////////////////////////////////////////////////////////////////////
740 // Controls
741 ////////////////////////////////////////////////////////////////////////
742
743 #if 0
744
745 /**
746  * Get the throttle setting, from 0.0 (none) to 1.0 (full).
747  */
748 double
749 FGBFI::getThrottle ()
750 {
751                                 // FIXME: add engine selector
752   return controls.get_throttle(0);
753 }
754
755
756 /**
757  * Set the throttle, from 0.0 (none) to 1.0 (full).
758  */
759 void
760 FGBFI::setThrottle (double throttle)
761 {
762                                 // FIXME: allow engine selection
763   controls.set_throttle(0, throttle);
764 }
765
766
767 /**
768  * Get the fuel mixture setting, from 0.0 (none) to 1.0 (full).
769  */
770 double
771 FGBFI::getMixture ()
772 {
773                                 // FIXME: add engine selector
774   return controls.get_mixture(0);
775 }
776
777
778 /**
779  * Set the fuel mixture, from 0.0 (none) to 1.0 (full).
780  */
781 void
782 FGBFI::setMixture (double mixture)
783 {
784                                 // FIXME: allow engine selection
785   controls.set_mixture(0, mixture);
786 }
787
788
789 /**
790  * Get the propellor pitch setting, from 0.0 (none) to 1.0 (full).
791  */
792 double
793 FGBFI::getPropAdvance ()
794 {
795                                 // FIXME: add engine selector
796   return controls.get_prop_advance(0);
797 }
798
799
800 /**
801  * Set the propellor pitch, from 0.0 (none) to 1.0 (full).
802  */
803 void
804 FGBFI::setPropAdvance (double pitch)
805 {
806                                 // FIXME: allow engine selection
807   controls.set_prop_advance(0, pitch);
808 }
809
810
811 /**
812  * Get the flaps setting, from 0.0 (none) to 1.0 (full).
813  */
814 double
815 FGBFI::getFlaps ()
816 {
817   return controls.get_flaps();
818 }
819
820
821 /**
822  * Set the flaps, from 0.0 (none) to 1.0 (full).
823  */
824 void
825 FGBFI::setFlaps (double flaps)
826 {
827                                 // FIXME: clamp?
828   controls.set_flaps(flaps);
829 }
830
831
832 /**
833  * Get the aileron, from -1.0 (left) to 1.0 (right).
834  */
835 double
836 FGBFI::getAileron ()
837 {
838   return controls.get_aileron();
839 }
840
841
842 /**
843  * Set the aileron, from -1.0 (left) to 1.0 (right).
844  */
845 void
846 FGBFI::setAileron (double aileron)
847 {
848                                 // FIXME: clamp?
849   controls.set_aileron(aileron);
850 }
851
852
853 /**
854  * Get the rudder setting, from -1.0 (left) to 1.0 (right).
855  */
856 double
857 FGBFI::getRudder ()
858 {
859   return controls.get_rudder();
860 }
861
862
863 /**
864  * Set the rudder, from -1.0 (left) to 1.0 (right).
865  */
866 void
867 FGBFI::setRudder (double rudder)
868 {
869                                 // FIXME: clamp?
870   controls.set_rudder(rudder);
871 }
872
873
874 /**
875  * Get the elevator setting, from -1.0 (down) to 1.0 (up).
876  */
877 double
878 FGBFI::getElevator ()
879 {
880   return controls.get_elevator();
881 }
882
883
884 /**
885  * Set the elevator, from -1.0 (down) to 1.0 (up).
886  */
887 void
888 FGBFI::setElevator (double elevator)
889 {
890                                 // FIXME: clamp?
891   controls.set_elevator(elevator);
892 }
893
894
895 /**
896  * Get the elevator trim, from -1.0 (down) to 1.0 (up).
897  */
898 double
899 FGBFI::getElevatorTrim ()
900 {
901   return controls.get_elevator_trim();
902 }
903
904
905 /**
906  * Set the elevator trim, from -1.0 (down) to 1.0 (up).
907  */
908 void
909 FGBFI::setElevatorTrim (double trim)
910 {
911                                 // FIXME: clamp?
912   controls.set_elevator_trim(trim);
913 }
914
915
916 /**
917  * Get the highest brake setting, from 0.0 (none) to 1.0 (full).
918  */
919 double
920 FGBFI::getBrakes ()
921 {
922   double b1 = getCenterBrake();
923   double b2 = getLeftBrake();
924   double b3 = getRightBrake();
925   return (b1 > b2 ? (b1 > b3 ? b1 : b3) : (b2 > b3 ? b2 : b3));
926 }
927
928
929 /**
930  * Set all brakes, from 0.0 (none) to 1.0 (full).
931  */
932 void
933 FGBFI::setBrakes (double brake)
934 {
935   setCenterBrake(brake);
936   setLeftBrake(brake);
937   setRightBrake(brake);
938 }
939
940
941 /**
942  * Get the center brake, from 0.0 (none) to 1.0 (full).
943  */
944 double
945 FGBFI::getCenterBrake ()
946 {
947   return controls.get_brake(2);
948 }
949
950
951 /**
952  * Set the center brake, from 0.0 (none) to 1.0 (full).
953  */
954 void
955 FGBFI::setCenterBrake (double brake)
956 {
957   controls.set_brake(2, brake);
958 }
959
960
961 /**
962  * Get the left brake, from 0.0 (none) to 1.0 (full).
963  */
964 double
965 FGBFI::getLeftBrake ()
966 {
967   return controls.get_brake(0);
968 }
969
970
971 /**
972  * Set the left brake, from 0.0 (none) to 1.0 (full).
973  */
974 void
975 FGBFI::setLeftBrake (double brake)
976 {
977   controls.set_brake(0, brake);
978 }
979
980
981 /**
982  * Get the right brake, from 0.0 (none) to 1.0 (full).
983  */
984 double
985 FGBFI::getRightBrake ()
986 {
987   return controls.get_brake(1);
988 }
989
990
991 /**
992  * Set the right brake, from 0.0 (none) to 1.0 (full).
993  */
994 void
995 FGBFI::setRightBrake (double brake)
996 {
997   controls.set_brake(1, brake);
998 }
999
1000
1001 #endif
1002
1003 \f
1004 ////////////////////////////////////////////////////////////////////////
1005 // Autopilot
1006 ////////////////////////////////////////////////////////////////////////
1007
1008
1009 /**
1010  * Get the autopilot altitude lock (true=on).
1011  */
1012 bool
1013 FGBFI::getAPAltitudeLock ()
1014 {
1015     return current_autopilot->get_AltitudeEnabled();
1016 }
1017
1018
1019 /**
1020  * Set the autopilot altitude lock (true=on).
1021  */
1022 void
1023 FGBFI::setAPAltitudeLock (bool lock)
1024 {
1025   current_autopilot->set_AltitudeMode(FGAutopilot::FG_ALTITUDE_LOCK);
1026   current_autopilot->set_AltitudeEnabled(lock);
1027 }
1028
1029
1030 /**
1031  * Get the autopilot target altitude in feet.
1032  */
1033 double
1034 FGBFI::getAPAltitude ()
1035 {
1036   return current_autopilot->get_TargetAltitude() * METER_TO_FEET;
1037 }
1038
1039
1040 /**
1041  * Set the autopilot target altitude in feet.
1042  */
1043 void
1044 FGBFI::setAPAltitude (double altitude)
1045 {
1046     current_autopilot->set_TargetAltitude( altitude * FEET_TO_METER );
1047 }
1048
1049
1050 /**
1051  * Get the autopilot target altitude in feet.
1052  */
1053 double
1054 FGBFI::getAPClimb ()
1055 {
1056   return current_autopilot->get_TargetClimbRate() * METER_TO_FEET;
1057 }
1058
1059
1060 /**
1061  * Set the autopilot target altitude in feet.
1062  */
1063 void
1064 FGBFI::setAPClimb (double rate)
1065 {
1066     current_autopilot->set_TargetClimbRate( rate * FEET_TO_METER );
1067 }
1068
1069
1070 /**
1071  * Get the autopilot heading lock (true=on).
1072  */
1073 bool
1074 FGBFI::getAPHeadingLock ()
1075 {
1076     return
1077       (current_autopilot->get_HeadingEnabled() &&
1078        current_autopilot->get_HeadingMode() == FGAutopilot::FG_DG_HEADING_LOCK);
1079 }
1080
1081
1082 /**
1083  * Set the autopilot heading lock (true=on).
1084  */
1085 void
1086 FGBFI::setAPHeadingLock (bool lock)
1087 {
1088     if (lock) {
1089         current_autopilot->set_HeadingMode(FGAutopilot::FG_DG_HEADING_LOCK);
1090         current_autopilot->set_HeadingEnabled(true);
1091     } else {
1092         current_autopilot->set_HeadingEnabled(false);
1093     }
1094 }
1095
1096
1097 /**
1098  * Get the autopilot heading bug in degrees.
1099  */
1100 double
1101 FGBFI::getAPHeadingBug ()
1102 {
1103   return current_autopilot->get_DGTargetHeading();
1104 }
1105
1106
1107 /**
1108  * Set the autopilot heading bug in degrees.
1109  */
1110 void
1111 FGBFI::setAPHeadingBug (double heading)
1112 {
1113   current_autopilot->set_DGTargetHeading( heading );
1114 }
1115
1116
1117 /**
1118  * Get the autopilot wing leveler lock (true=on).
1119  */
1120 bool
1121 FGBFI::getAPWingLeveler ()
1122 {
1123     return
1124       (current_autopilot->get_HeadingEnabled() &&
1125        current_autopilot->get_HeadingMode() == FGAutopilot::FG_TC_HEADING_LOCK);
1126 }
1127
1128
1129 /**
1130  * Set the autopilot wing leveler lock (true=on).
1131  */
1132 void
1133 FGBFI::setAPWingLeveler (bool lock)
1134 {
1135     if (lock) {
1136         current_autopilot->set_HeadingMode(FGAutopilot::FG_TC_HEADING_LOCK);
1137         current_autopilot->set_HeadingEnabled(true);
1138     } else {
1139         current_autopilot->set_HeadingEnabled(false);
1140     }
1141 }
1142
1143
1144 /**
1145  * Return true if the autopilot is locked to NAV1.
1146  */
1147 bool
1148 FGBFI::getAPNAV1Lock ()
1149 {
1150   return
1151     (current_autopilot->get_HeadingEnabled() &&
1152      current_autopilot->get_HeadingMode() == FGAutopilot::FG_HEADING_NAV1);
1153 }
1154
1155
1156 /**
1157  * Set the autopilot NAV1 lock.
1158  */
1159 void
1160 FGBFI::setAPNAV1Lock (bool lock)
1161 {
1162   if (lock) {
1163     current_autopilot->set_HeadingMode(FGAutopilot::FG_HEADING_NAV1);
1164     current_autopilot->set_HeadingEnabled(true);
1165   } else if (current_autopilot->get_HeadingMode() ==
1166              FGAutopilot::FG_HEADING_NAV1) {
1167     current_autopilot->set_HeadingEnabled(false);
1168   }
1169 }
1170
1171
1172 \f
1173 ////////////////////////////////////////////////////////////////////////
1174 // GPS
1175 ////////////////////////////////////////////////////////////////////////
1176
1177
1178 /**
1179  * Get the autopilot GPS lock (true=on).
1180  */
1181 bool
1182 FGBFI::getGPSLock ()
1183 {
1184   return (current_autopilot->get_HeadingEnabled() &&
1185           (current_autopilot->get_HeadingMode() ==
1186            FGAutopilot::FG_HEADING_WAYPOINT ));
1187 }
1188
1189
1190 /**
1191  * Set the autopilot GPS lock (true=on).
1192  */
1193 void
1194 FGBFI::setGPSLock (bool lock)
1195 {
1196   if (lock) {
1197     current_autopilot->set_HeadingMode(FGAutopilot::FG_HEADING_WAYPOINT);
1198     current_autopilot->set_HeadingEnabled(true);
1199   } else if (current_autopilot->get_HeadingMode() ==
1200              FGAutopilot::FG_HEADING_WAYPOINT) {
1201     current_autopilot->set_HeadingEnabled(false);
1202   }
1203 }
1204
1205
1206 /**
1207  * Get the GPS target latitude in degrees (negative for south).
1208  */
1209 double
1210 FGBFI::getGPSTargetLatitude ()
1211 {
1212     return current_autopilot->get_TargetLatitude();
1213 }
1214
1215
1216 /**
1217  * Get the GPS target longitude in degrees (negative for west).
1218  */
1219 double
1220 FGBFI::getGPSTargetLongitude ()
1221 {
1222   return current_autopilot->get_TargetLongitude();
1223 }
1224
1225 #if 0
1226 /**
1227  * Set the GPS target longitude in degrees (negative for west).
1228  */
1229 void
1230 FGBFI::setGPSTargetLongitude (double longitude)
1231 {
1232   current_autopilot->set_TargetLongitude( longitude );
1233 }
1234 #endif
1235
1236
1237 \f
1238 ////////////////////////////////////////////////////////////////////////
1239 // Weather
1240 ////////////////////////////////////////////////////////////////////////
1241
1242
1243 /**
1244  * Get the current visibility (meters).
1245  */
1246 double
1247 FGBFI::getVisibility ()
1248 {
1249 #ifndef FG_OLD_WEATHER
1250   return WeatherDatabase->getWeatherVisibility();
1251 #else
1252   return current_weather.get_visibility();
1253 #endif
1254 }
1255
1256
1257 /**
1258  * Set the current visibility (meters).
1259  */
1260 void
1261 FGBFI::setVisibility (double visibility)
1262 {
1263 #ifndef FG_OLD_WEATHER
1264   WeatherDatabase->setWeatherVisibility(visibility);
1265 #else
1266   current_weather.set_visibility(visibility);
1267 #endif
1268 }
1269
1270
1271 /**
1272  * Get the current wind north velocity (feet/second).
1273  */
1274 double
1275 FGBFI::getWindNorth ()
1276 {
1277   return current_aircraft.fdm_state->get_V_north_airmass();
1278 }
1279
1280
1281 /**
1282  * Set the current wind north velocity (feet/second).
1283  */
1284 void
1285 FGBFI::setWindNorth (double speed)
1286 {
1287   current_aircraft.fdm_state->set_Velocities_Local_Airmass(speed,
1288                                                            getWindEast(),
1289                                                            getWindDown());
1290 }
1291
1292
1293 /**
1294  * Get the current wind east velocity (feet/second).
1295  */
1296 double
1297 FGBFI::getWindEast ()
1298 {
1299   return current_aircraft.fdm_state->get_V_east_airmass();
1300 }
1301
1302
1303 /**
1304  * Set the current wind east velocity (feet/second).
1305  */
1306 void
1307 FGBFI::setWindEast (double speed)
1308 {
1309   cout << "Set wind-east to " << speed << endl;
1310   current_aircraft.fdm_state->set_Velocities_Local_Airmass(getWindNorth(),
1311                                                            speed,
1312                                                            getWindDown());
1313 }
1314
1315
1316 /**
1317  * Get the current wind down velocity (feet/second).
1318  */
1319 double
1320 FGBFI::getWindDown ()
1321 {
1322   return current_aircraft.fdm_state->get_V_down_airmass();
1323 }
1324
1325
1326 /**
1327  * Set the current wind down velocity (feet/second).
1328  */
1329 void
1330 FGBFI::setWindDown (double speed)
1331 {
1332   current_aircraft.fdm_state->set_Velocities_Local_Airmass(getWindNorth(),
1333                                                            getWindEast(),
1334                                                            speed);
1335 }
1336
1337
1338 \f
1339 ////////////////////////////////////////////////////////////////////////
1340 // View.
1341 ////////////////////////////////////////////////////////////////////////
1342
1343 double
1344 FGBFI::getFOV ()
1345 {
1346   return globals->get_current_view()->get_fov();
1347 }
1348
1349 void
1350 FGBFI::setFOV (double fov)
1351 {
1352   globals->get_current_view()->set_fov( fov );
1353 }
1354
1355 void
1356 FGBFI::setViewAxisLong (double axis)
1357 {
1358   axisLong = axis;
1359 }
1360
1361 void
1362 FGBFI::setViewAxisLat (double axis)
1363 {
1364   axisLat = axis;
1365 }
1366
1367 \f
1368 ////////////////////////////////////////////////////////////////////////
1369 // Time
1370 ////////////////////////////////////////////////////////////////////////
1371
1372 /**
1373  * Return the magnetic variation
1374  */
1375 double
1376 FGBFI::getMagVar ()
1377 {
1378   return globals->get_mag()->get_magvar() * RAD_TO_DEG;
1379 }
1380
1381
1382 /**
1383  * Return the magnetic variation
1384  */
1385 double
1386 FGBFI::getMagDip ()
1387 {
1388   return globals->get_mag()->get_magdip() * RAD_TO_DEG;
1389 }
1390
1391
1392 // end of bfi.cxx
1393