]> git.mxchange.org Git - flightgear.git/blob - src/Main/bfi.cxx
First stab at NAV1 and GS hold modes for the autopilot.
[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 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 // $Id$
22
23
24 #ifdef HAVE_CONFIG_H
25 #  include <config.h>
26 #endif
27
28 #if defined( FG_HAVE_NATIVE_SGI_COMPILERS )
29 #  include <iostream.h>
30 #else
31 #  include <iostream>
32 #endif
33
34 #include <simgear/constants.h>
35 #include <simgear/math/fg_types.hxx>
36
37 #include <Aircraft/aircraft.hxx>
38 #include <Controls/controls.hxx>
39 #include <Autopilot/newauto.hxx>
40 #include <Scenery/scenery.hxx>
41 #include <Time/fg_time.hxx>
42 #include <Time/light.hxx>
43 #include <Cockpit/radiostack.hxx>
44 #ifndef FG_OLD_WEATHER
45 #  include <WeatherCM/FGLocalWeatherDatabase.h>
46 #else
47 #  include <Weather/weather.hxx>
48 #endif
49
50 #include "options.hxx"
51 #include "save.hxx"
52 #include "fg_init.hxx"
53
54 FG_USING_NAMESPACE(std);
55
56                                 // FIXME: these are not part of the
57                                 // published interface!!!
58 // extern fgAPDataPtr APDataGlobal;
59 // extern void fgAPAltitudeSet (double new_altitude);
60 // extern void fgAPHeadingSet (double new_heading);
61
62
63 #include "bfi.hxx"
64
65
66 \f
67 ////////////////////////////////////////////////////////////////////////
68 // Static variables.
69 ////////////////////////////////////////////////////////////////////////
70
71 bool FGBFI::_needReinit = false;
72
73
74 \f
75 ////////////////////////////////////////////////////////////////////////
76 // Local functions
77 ////////////////////////////////////////////////////////////////////////
78
79
80 /**
81  * Reinitialize FGFS if required.
82  *
83  * Some changes (especially those in aircraft position) require that
84  * FGFS be reinitialized afterwards.  Rather than reinitialize after
85  * every change, the setter methods simply set a flag so that there
86  * can be a single reinit at the end of the frame.
87  */
88 void
89 FGBFI::update ()
90 {
91   if (_needReinit) {
92     reinit();
93   }
94 }
95
96
97 /**
98  * Reinitialize FGFS to use the new BFI settings.
99  */
100 void
101 FGBFI::reinit ()
102 {
103                                 // Save the state of everything
104                                 // that's going to get clobbered
105                                 // when we reinit the subsystems.
106
107                                 // TODO: add more AP stuff
108   double elevator = getElevator();
109   double aileron = getAileron();
110   double rudder = getRudder();
111   double throttle = getThrottle();
112   double elevator_trim = getElevatorTrim();
113   double flaps = getFlaps();
114   double brake = getBrake();
115   bool apHeadingLock = getAPHeadingLock();
116   double apHeading = getAPHeading();
117   bool apAltitudeLock = getAPAltitudeLock();
118   double apAltitude = getAPAltitude();
119   const string &targetAirport = getTargetAirport();
120   bool gpsLock = getGPSLock();
121   double gpsLatitude = getGPSTargetLatitude();
122   double gpsLongitude = getGPSTargetLongitude();
123
124   fgReInitSubsystems();
125   // solarSystemRebuild();
126   cur_light_params.Update();
127
128                                 // Restore all of the old states.
129   setElevator(elevator);
130   setAileron(aileron);
131   setRudder(rudder);
132   setThrottle(throttle);
133   setElevatorTrim(elevator_trim);
134   setFlaps(flaps);
135   setBrake(brake);
136   setAPHeadingLock(apHeadingLock);
137   setAPHeading(apHeading);
138   setAPAltitudeLock(apAltitudeLock);
139   setAPAltitude(apAltitude);
140   setTargetAirport(targetAirport);
141   setGPSLock(gpsLock);
142   setGPSTargetLatitude(gpsLatitude);
143   setGPSTargetLongitude(gpsLongitude);
144
145   _needReinit = false;
146 }
147
148
149 \f
150 ////////////////////////////////////////////////////////////////////////
151 // Simulation.
152 ////////////////////////////////////////////////////////////////////////
153
154
155 /**
156  * Return the flight model as an integer.
157  *
158  * TODO: use a string instead.
159  */
160 int
161 FGBFI::getFlightModel ()
162 {
163   return current_options.get_flight_model();
164 }
165
166
167 /**
168  * Set the flight model as an integer.
169  *
170  * TODO: use a string instead.
171  */
172 void
173 FGBFI::setFlightModel (int model)
174 {
175   current_options.set_flight_model(model);
176   needReinit();
177 }
178
179
180 /**
181  * Return the current Zulu time.
182  */
183 time_t
184 FGBFI::getTimeGMT ()
185 {
186                                 // FIXME: inefficient
187   return mktime(FGTime::cur_time_params->getGmt());
188 }
189
190
191 /**
192  * Set the current Zulu time.
193  */
194 void
195 FGBFI::setTimeGMT (time_t time)
196 {
197                                 // FIXME: need to update lighting
198                                 // and solar system
199   current_options.set_time_offset(time);
200   current_options.set_time_offset_type(fgOPTIONS::FG_TIME_GMT_ABSOLUTE);
201   FGTime::cur_time_params->init( cur_fdm_state->get_Longitude(),
202                                  cur_fdm_state->get_Latitude() );
203   FGTime::cur_time_params->update( cur_fdm_state->get_Longitude(),
204                                    cur_fdm_state->get_Latitude(),
205                                    cur_fdm_state->get_Altitude()
206                                    * FEET_TO_METER );
207   needReinit();
208 }
209
210
211 /**
212  * Return true if the HUD is visible.
213  */
214 bool
215 FGBFI::getHUDVisible ()
216 {
217   return current_options.get_hud_status();
218 }
219
220
221 /**
222  * Ensure that the HUD is visible or hidden.
223  */
224 void
225 FGBFI::setHUDVisible (bool visible)
226 {
227   current_options.set_hud_status(visible);
228 }
229
230
231 /**
232  * Return true if the 2D panel is visible.
233  */
234 bool
235 FGBFI::getPanelVisible ()
236 {
237   return current_options.get_panel_status();
238 }
239
240
241 /**
242  * Ensure that the 2D panel is visible or hidden.
243  */
244 void
245 FGBFI::setPanelVisible (bool visible)
246 {
247   if (current_options.get_panel_status() != visible) {
248     current_options.toggle_panel();
249   }
250 }
251
252
253 \f
254 ////////////////////////////////////////////////////////////////////////
255 // Position
256 ////////////////////////////////////////////////////////////////////////
257
258
259 /**
260  * Return the current latitude in degrees (negative for south).
261  */
262 double
263 FGBFI::getLatitude ()
264 {
265   return current_aircraft.fdm_state->get_Latitude() * RAD_TO_DEG;
266 }
267
268
269 /**
270  * Set the current latitude in degrees (negative for south).
271  */
272 void
273 FGBFI::setLatitude (double latitude)
274 {
275   current_options.set_lat(latitude);
276   needReinit();
277 }
278
279
280 /**
281  * Return the current longitude in degrees (negative for west).
282  */
283 double
284 FGBFI::getLongitude ()
285 {
286   return current_aircraft.fdm_state->get_Longitude() * RAD_TO_DEG;
287 }
288
289
290 /**
291  * Set the current longitude in degrees (negative for west).
292  */
293 void
294 FGBFI::setLongitude (double longitude)
295 {
296   current_options.set_lon(longitude);
297   needReinit();
298 }
299
300
301 /**
302  * Return the current altitude in feet.
303  */
304 double
305 FGBFI::getAltitude ()
306 {
307   return current_aircraft.fdm_state->get_Altitude();
308 }
309
310
311
312 /**
313  * Return the current altitude in above the terrain.
314  */
315 double
316 FGBFI::getAGL ()
317 {
318   return current_aircraft.fdm_state->get_Altitude()
319          - scenery.cur_elev * METER_TO_FEET;
320 }
321
322
323 /**
324  * Set the current altitude in feet.
325  */
326 void
327 FGBFI::setAltitude (double altitude)
328 {
329   current_options.set_altitude(altitude * FEET_TO_METER);
330   needReinit();
331 }
332
333
334 \f
335 ////////////////////////////////////////////////////////////////////////
336 // Attitude
337 ////////////////////////////////////////////////////////////////////////
338
339
340 /**
341  * Return the current heading in degrees.
342  */
343 double
344 FGBFI::getHeading ()
345 {
346   return current_aircraft.fdm_state->get_Psi() * RAD_TO_DEG;
347 }
348
349
350 /**
351  * Set the current heading in degrees.
352  */
353 void
354 FGBFI::setHeading (double heading)
355 {
356   current_options.set_heading(heading);
357   needReinit();
358 }
359
360
361 /**
362  * Return the current pitch in degrees.
363  */
364 double
365 FGBFI::getPitch ()
366 {
367   return current_aircraft.fdm_state->get_Theta() * RAD_TO_DEG;
368 }
369
370
371 /**
372  * Set the current pitch in degrees.
373  */
374 void
375 FGBFI::setPitch (double pitch)
376 {
377
378   current_options.set_pitch(pitch);
379   needReinit();
380 }
381
382
383 /**
384  * Return the current roll in degrees.
385  */
386 double
387 FGBFI::getRoll ()
388 {
389   return current_aircraft.fdm_state->get_Phi() * RAD_TO_DEG;
390 }
391
392
393 /**
394  * Set the current roll in degrees.
395  */
396 void
397 FGBFI::setRoll (double roll)
398 {
399   current_options.set_roll(roll);
400   needReinit();
401 }
402
403
404 \f
405 ////////////////////////////////////////////////////////////////////////
406 // Velocities
407 ////////////////////////////////////////////////////////////////////////
408
409
410 /**
411  * Return the current airspeed in knots.
412  */
413 double
414 FGBFI::getAirspeed ()
415 {
416                                 // FIXME: should we add speed-up?
417   return current_aircraft.fdm_state->get_V_calibrated_kts();
418 }
419
420
421 /**
422  * Return the current sideslip (FIXME: units unknown).
423  */
424 double
425 FGBFI::getSideSlip ()
426 {
427   return current_aircraft.fdm_state->get_Beta();
428 }
429
430
431 /**
432  * Return the current climb rate in feet/second (FIXME: verify).
433  */
434 double
435 FGBFI::getVerticalSpeed ()
436 {
437                                 // What about meters?
438   return current_aircraft.fdm_state->get_Climb_Rate() * 60.0;
439 }
440
441
442 /**
443  * Get the current north velocity (units??).
444  */
445 double
446 FGBFI::getSpeedNorth ()
447 {
448   return current_aircraft.fdm_state->get_V_north();
449 }
450
451
452 /**
453  * Set the current north velocity (units??).
454  */
455 void
456 FGBFI::setSpeedNorth (double speed)
457 {
458   current_options.set_uBody(speed);
459   needReinit();
460 }
461
462
463 /**
464  * Get the current east velocity (units??).
465  */
466 double
467 FGBFI::getSpeedEast ()
468 {
469   return current_aircraft.fdm_state->get_V_east();
470 }
471
472
473 /**
474  * Set the current east velocity (units??).
475  */
476 void
477 FGBFI::setSpeedEast (double speed)
478 {
479   current_options.set_vBody(speed);
480   needReinit();
481 }
482
483
484 /**
485  * Get the current down velocity (units??).
486  */
487 double
488 FGBFI::getSpeedDown ()
489 {
490   return current_aircraft.fdm_state->get_V_down();
491 }
492
493
494 /**
495  * Set the current down velocity (units??).
496  */
497 void
498 FGBFI::setSpeedDown (double speed)
499 {
500   current_options.set_wBody(speed);
501   needReinit();
502 }
503
504
505 \f
506 ////////////////////////////////////////////////////////////////////////
507 // Controls
508 ////////////////////////////////////////////////////////////////////////
509
510
511 /**
512  * Get the throttle setting, from 0.0 (none) to 1.0 (full).
513  */
514 double
515 FGBFI::getThrottle ()
516 {
517                                 // FIXME: add throttle selector
518   return controls.get_throttle(0);
519 }
520
521
522 /**
523  * Set the throttle, from 0.0 (none) to 1.0 (full).
524  */
525 void
526 FGBFI::setThrottle (double throttle)
527 {
528                                 // FIXME: allow throttle selection
529                                 // FIXME: clamp?
530   controls.set_throttle(0, throttle);
531 }
532
533
534 /**
535  * Get the flaps setting, from 0.0 (none) to 1.0 (full).
536  */
537 double
538 FGBFI::getFlaps ()
539 {
540   return controls.get_flaps();
541 }
542
543
544 /**
545  * Set the flaps, from 0.0 (none) to 1.0 (full).
546  */
547 void
548 FGBFI::setFlaps (double flaps)
549 {
550                                 // FIXME: clamp?
551   controls.set_flaps(flaps);
552 }
553
554
555 /**
556  * Get the aileron, from -1.0 (left) to 1.0 (right).
557  */
558 double
559 FGBFI::getAileron ()
560 {
561   return controls.get_aileron();
562 }
563
564
565 /**
566  * Set the aileron, from -1.0 (left) to 1.0 (right).
567  */
568 void
569 FGBFI::setAileron (double aileron)
570 {
571                                 // FIXME: clamp?
572   controls.set_aileron(aileron);
573 }
574
575
576 /**
577  * Get the rudder setting, from -1.0 (left) to 1.0 (right).
578  */
579 double
580 FGBFI::getRudder ()
581 {
582   return controls.get_rudder();
583 }
584
585
586 /**
587  * Set the rudder, from -1.0 (left) to 1.0 (right).
588  */
589 void
590 FGBFI::setRudder (double rudder)
591 {
592                                 // FIXME: clamp?
593   controls.set_rudder(rudder);
594 }
595
596
597 /**
598  * Get the elevator setting, from -1.0 (down) to 1.0 (up).
599  */
600 double
601 FGBFI::getElevator ()
602 {
603   return controls.get_elevator();
604 }
605
606
607 /**
608  * Set the elevator, from -1.0 (down) to 1.0 (up).
609  */
610 void
611 FGBFI::setElevator (double elevator)
612 {
613                                 // FIXME: clamp?
614   controls.set_elevator(elevator);
615 }
616
617
618 /**
619  * Get the elevator trim, from -1.0 (down) to 1.0 (up).
620  */
621 double
622 FGBFI::getElevatorTrim ()
623 {
624   return controls.get_elevator_trim();
625 }
626
627
628 /**
629  * Set the elevator trim, from -1.0 (down) to 1.0 (up).
630  */
631 void
632 FGBFI::setElevatorTrim (double trim)
633 {
634                                 // FIXME: clamp?
635   controls.set_elevator_trim(trim);
636 }
637
638
639 /**
640  * Get the brake setting, from 0.0 (none) to 1.0 (full).
641  */
642 double
643 FGBFI::getBrake ()
644 {
645                                 // FIXME: add brake selector
646   return controls.get_brake(0);
647 }
648
649
650 /**
651  * Set the brake, from 0.0 (none) to 1.0 (full).
652  */
653 void
654 FGBFI::setBrake (double brake)
655 {
656                                 // FIXME: clamp?
657                                 // FIXME: allow brake selection
658   controls.set_brake(0, brake);
659 }
660
661
662 \f
663 ////////////////////////////////////////////////////////////////////////
664 // Autopilot
665 ////////////////////////////////////////////////////////////////////////
666
667
668 /**
669  * Get the autopilot altitude lock (true=on).
670  */
671 bool
672 FGBFI::getAPAltitudeLock ()
673 {
674     return current_autopilot->get_AltitudeEnabled();
675 }
676
677
678 /**
679  * Set the autopilot altitude lock (true=on).
680  */
681 void
682 FGBFI::setAPAltitudeLock (bool lock)
683 {
684     current_autopilot->set_AltitudeEnabled( true );
685     current_autopilot->set_AltitudeMode( FGAutopilot::FG_ALTITUDE_LOCK );
686 }
687
688
689 /**
690  * Get the autopilot target altitude in feet.
691  */
692 double
693 FGBFI::getAPAltitude ()
694 {
695   return current_autopilot->get_TargetAltitude() * METER_TO_FEET;
696 }
697
698
699 /**
700  * Set the autopilot target altitude in feet.
701  */
702 void
703 FGBFI::setAPAltitude (double altitude)
704 {
705     current_autopilot->set_TargetAltitude( altitude );
706 }
707
708
709 /**
710  * Get the autopilot heading lock (true=on).
711  */
712 bool
713 FGBFI::getAPHeadingLock ()
714 {
715     return current_autopilot->get_HeadingEnabled();
716 }
717
718
719 /**
720  * Set the autopilot heading lock (true=on).
721  */
722 void
723 FGBFI::setAPHeadingLock (bool lock)
724 {
725     current_autopilot->set_HeadingEnabled( true );
726     current_autopilot->set_HeadingMode( FGAutopilot::FG_HEADING_LOCK );
727 }
728
729
730 /**
731  * Get the autopilot target heading in degrees.
732  */
733 double
734 FGBFI::getAPHeading ()
735 {
736   return current_autopilot->get_TargetHeading();
737 }
738
739
740 /**
741  * Set the autopilot target heading in degrees.
742  */
743 void
744 FGBFI::setAPHeading (double heading)
745 {
746   current_autopilot->set_TargetHeading( heading );
747 }
748
749
750 \f
751 ////////////////////////////////////////////////////////////////////////
752 // Radio navigation.
753 ////////////////////////////////////////////////////////////////////////
754
755 double
756 FGBFI::getNAV1Freq ()
757 {
758   return current_radiostack->get_nav1_freq();
759 }
760
761 double
762 FGBFI::getNAV1AltFreq ()
763 {
764   return current_radiostack->get_nav1_alt_freq();
765 }
766
767 double
768 FGBFI::getNAV1Radial ()
769 {
770   return current_radiostack->get_nav1_radial();
771 }
772
773 double
774 FGBFI::getNAV2Freq ()
775 {
776   return current_radiostack->get_nav2_freq();
777 }
778
779 double
780 FGBFI::getNAV2AltFreq ()
781 {
782   return current_radiostack->get_nav2_alt_freq();
783 }
784
785 double
786 FGBFI::getNAV2Radial ()
787 {
788   return current_radiostack->get_nav2_radial();
789 }
790
791 double
792 FGBFI::getADFFreq ()
793 {
794   return current_radiostack->get_adf_freq();
795 }
796
797 double
798 FGBFI::getADFAltFreq ()
799 {
800   return current_radiostack->get_adf_alt_freq();
801 }
802
803 double
804 FGBFI::getADFRotation ()
805 {
806   return current_radiostack->get_adf_rotation();
807 }
808
809 void
810 FGBFI::setNAV1Freq (double freq)
811 {
812   current_radiostack->set_nav1_freq(freq);
813 }
814
815 void
816 FGBFI::setNAV1AltFreq (double freq)
817 {
818   current_radiostack->set_nav1_alt_freq(freq);
819 }
820
821 void
822 FGBFI::setNAV1Radial (double radial)
823 {
824   current_radiostack->set_nav1_radial(radial);
825 }
826
827 void
828 FGBFI::setNAV2Freq (double freq)
829 {
830   current_radiostack->set_nav2_freq(freq);
831 }
832
833 void
834 FGBFI::setNAV2AltFreq (double freq)
835 {
836   current_radiostack->set_nav2_alt_freq(freq);
837 }
838
839 void
840 FGBFI::setNAV2Radial (double radial)
841 {
842   current_radiostack->set_nav2_radial(radial);
843 }
844
845 void
846 FGBFI::setADFFreq (double freq)
847 {
848   current_radiostack->set_adf_freq(freq);
849 }
850
851 void
852 FGBFI::setADFAltFreq (double freq)
853 {
854   current_radiostack->set_adf_alt_freq(freq);
855 }
856
857 void
858 FGBFI::setADFRotation (double rot)
859 {
860   current_radiostack->set_adf_rotation(rot);
861 }
862
863
864 \f
865 ////////////////////////////////////////////////////////////////////////
866 // GPS
867 ////////////////////////////////////////////////////////////////////////
868
869
870 /**
871  * Get the autopilot GPS lock (true=on).
872  */
873 bool
874 FGBFI::getGPSLock ()
875 {
876     return ( current_autopilot->get_HeadingEnabled() &&
877              ( current_autopilot->get_HeadingMode() == 
878                FGAutopilot::FG_HEADING_WAYPOINT )
879            );
880 }
881
882
883 /**
884  * Set the autopilot GPS lock (true=on).
885  */
886 void
887 FGBFI::setGPSLock (bool lock)
888 {
889     current_autopilot->set_HeadingEnabled( true );
890     current_autopilot->set_HeadingMode( FGAutopilot::FG_HEADING_WAYPOINT );
891 }
892
893
894 /**
895  * Get the GPS target airport code.
896  */
897 const string
898 FGBFI::getTargetAirport ()
899 {
900   return current_options.get_airport_id();
901 }
902
903
904 /**
905  * Set the GPS target airport code.
906  */
907 void
908 FGBFI::setTargetAirport (const string &airportId)
909 {
910   current_options.set_airport_id(airportId);
911 }
912
913
914 /**
915  * Get the GPS target latitude in degrees (negative for south).
916  */
917 double
918 FGBFI::getGPSTargetLatitude ()
919 {
920     return current_autopilot->get_TargetLatitude();
921 }
922
923
924 /**
925  * Set the GPS target latitude in degrees (negative for south).
926  */
927 void
928 FGBFI::setGPSTargetLatitude (double latitude)
929 {
930   current_autopilot->set_TargetLatitude( latitude );
931 }
932
933
934 /**
935  * Get the GPS target longitude in degrees (negative for west).
936  */
937 double
938 FGBFI::getGPSTargetLongitude ()
939 {
940   return current_autopilot->get_TargetLongitude();
941 }
942
943
944 /**
945  * Set the GPS target longitude in degrees (negative for west).
946  */
947 void
948 FGBFI::setGPSTargetLongitude (double longitude)
949 {
950   current_autopilot->set_TargetLongitude( longitude );
951 }
952
953
954 \f
955 ////////////////////////////////////////////////////////////////////////
956 // Weather
957 ////////////////////////////////////////////////////////////////////////
958
959
960 /**
961  * Get the current visible (units??).
962  */
963 double
964 FGBFI::getVisibility ()
965 {
966 #ifndef FG_OLD_WEATHER
967   return WeatherDatabase->getWeatherVisibility();
968 #else
969   return current_weather.get_visibility();
970 #endif
971 }
972
973
974 /**
975  * Set the current visibility (units??).
976  */
977 void
978 FGBFI::setVisibility (double visibility)
979 {
980 #ifndef FG_OLD_WEATHER
981   WeatherDatabase->setWeatherVisibility(visibility);
982 #else
983   current_weather.set_visibility(visibility);
984 #endif
985 }
986
987
988 \f
989 ////////////////////////////////////////////////////////////////////////
990 // Time
991 ////////////////////////////////////////////////////////////////////////
992
993 /**
994  * Return the magnetic variation
995  */
996 double
997 FGBFI::getMagVar ()
998 {
999   return FGTime::cur_time_params->getMagVar() * RAD_TO_DEG;
1000 }
1001
1002
1003 /**
1004  * Return the magnetic variation
1005  */
1006 double
1007 FGBFI::getMagDip ()
1008 {
1009   return FGTime::cur_time_params->getMagDip() * RAD_TO_DEG;
1010 }
1011
1012
1013 // end of bfi.cxx
1014