]> git.mxchange.org Git - flightgear.git/blob - src/Main/fg_props.cxx
- adjusted for no-value constructor for FGPanel
[flightgear.git] / src / Main / fg_props.cxx
1 // fg_props.cxx -- support for FlightGear properties.
2 //
3 // Written by David Megginson, started 2000.
4 //
5 // Copyright (C) 2000, 2001 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 #ifdef HAVE_CONFIG_H
24 #  include <simgear/compiler.h>
25 #endif
26
27 #include STL_IOSTREAM
28
29 #include <Autopilot/newauto.hxx>
30 #include <Aircraft/aircraft.hxx>
31 #include <Time/tmp.hxx>
32 #include <FDM/UIUCModel/uiuc_aircraftdir.h>
33 #ifndef FG_OLD_WEATHER
34 #  include <WeatherCM/FGLocalWeatherDatabase.h>
35 #else
36 #  include <Weather/weather.hxx>
37 #endif
38
39 #include "fgfs.hxx"
40 #include "fg_props.hxx"
41
42 #if !defined(SG_HAVE_NATIVE_SGI_COMPILERS)
43 SG_USING_STD(istream);
44 SG_USING_STD(ostream);
45 #endif
46
47 #define DEFAULT_AP_HEADING_LOCK FGAutopilot::FG_DG_HEADING_LOCK
48
49 static double getWindNorth ();
50 static double getWindEast ();
51 static double getWindDown ();
52
53 // Allow the view to be set from two axes (i.e. a joystick hat)
54 // This needs to be in FGViewer itself, somehow.
55 static double axisLong = 0.0;
56 static double axisLat = 0.0;
57
58 /**
59  * Utility function.
60  */
61 static inline void
62 _set_view_from_axes ()
63 {
64                                 // Take no action when hat is centered
65   if (axisLong == 0 && axisLat == 0)
66     return;
67
68   double viewDir = 0;
69
70   if (axisLong < 0) {           // Longitudinal axis forward
71     if (axisLat < 0)
72       viewDir = 45;
73     else if (axisLat > 0)
74       viewDir = 315;
75     else
76       viewDir = 0;
77   } else if (axisLong > 0) {    // Longitudinal axis backward
78     if (axisLat < 0)
79       viewDir = 135;
80     else if (axisLat > 0)
81       viewDir = 225;
82     else
83       viewDir = 180;
84   } else {                      // Longitudinal axis neutral
85     if (axisLat < 0)
86       viewDir = 90;
87     else
88       viewDir = 270;
89   }
90
91   globals->get_current_view()->set_goal_view_offset(viewDir*SGD_DEGREES_TO_RADIANS);
92 //   globals->get_current_view()->set_view_offset(viewDir*SGD_DEGREES_TO_RADIANS);
93 }
94
95 \f
96 ////////////////////////////////////////////////////////////////////////
97 // Default property bindings (not yet handled by any module).
98 ////////////////////////////////////////////////////////////////////////
99
100 /**
101  * Return the current aircraft directory (UIUC) as a string.
102  */
103 static string 
104 getAircraftDir ()
105 {
106   return aircraft_dir;
107 }
108
109
110 /**
111  * Set the current aircraft directory (UIUC).
112  */
113 static void
114 setAircraftDir (string dir)
115 {
116   if (getAircraftDir() != dir) {
117     aircraft_dir = dir;
118 //     needReinit(); FIXME!!
119   }
120 }
121
122
123 /**
124  * Get the current view offset in degrees.
125  */
126 static double
127 getViewOffset ()
128 {
129   return (globals->get_current_view()
130           ->get_view_offset() * SGD_RADIANS_TO_DEGREES);
131 }
132
133
134 static void
135 setViewOffset (double offset)
136 {
137   globals->get_current_view()->set_view_offset(offset * SGD_DEGREES_TO_RADIANS);
138 }
139
140 static double
141 getGoalViewOffset ()
142 {
143   return (globals->get_current_view()
144           ->get_goal_view_offset() * SGD_RADIANS_TO_DEGREES);
145 }
146
147 static void
148 setGoalViewOffset (double offset)
149 {
150   globals->get_current_view()
151     ->set_goal_view_offset(offset * SGD_DEGREES_TO_RADIANS);
152 }
153
154
155 /**
156  * Return the current Zulu time.
157  */
158 static string 
159 getDateString ()
160 {
161   string out;
162   char buf[64];
163   struct tm * t = globals->get_time_params()->getGmt();
164   sprintf(buf, "%.4d-%.2d-%.2dT%.2d:%.2d:%.2d",
165           t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
166           t->tm_hour, t->tm_min, t->tm_sec);
167   out = buf;
168   return out;
169 }
170
171
172 /**
173  * Set the current Zulu time.
174  */
175 static void
176 setDateString (string date_string)
177 {
178   SGTime * st = globals->get_time_params();
179   struct tm * current_time = st->getGmt();
180   struct tm new_time;
181
182                                 // Scan for basic ISO format
183                                 // YYYY-MM-DDTHH:MM:SS
184   int ret = sscanf(date_string.c_str(), "%d-%d-%dT%d:%d:%d",
185                    &(new_time.tm_year), &(new_time.tm_mon),
186                    &(new_time.tm_mday), &(new_time.tm_hour),
187                    &(new_time.tm_min), &(new_time.tm_sec));
188
189                                 // Be pretty picky about this, so
190                                 // that strange things don't happen
191                                 // if the save file has been edited
192                                 // by hand.
193   if (ret != 6) {
194     SG_LOG(SG_INPUT, SG_ALERT, "Date/time string " << date_string
195            << " not in YYYY-MM-DDTHH:MM:SS format; skipped");
196     return;
197   }
198
199                                 // OK, it looks like we got six
200                                 // values, one way or another.
201   new_time.tm_year -= 1900;
202   new_time.tm_mon -= 1;
203
204                                 // Now, tell flight gear to use
205                                 // the new time.  This was far
206                                 // too difficult, by the way.
207   long int warp =
208     mktime(&new_time) - mktime(current_time) + globals->get_warp();
209   double lon = current_aircraft.fdm_state->get_Longitude();
210   double lat = current_aircraft.fdm_state->get_Latitude();
211   globals->set_warp(warp);
212   st->update(lon, lat, warp);
213   fgUpdateSkyAndLightingParams();
214 }
215
216 /**
217  * Return the GMT as a string.
218  */
219 static string 
220 getGMTString ()
221 {
222   string out;
223   char buf[16];
224   struct tm * t = globals->get_time_params()->getGmt();
225   sprintf(buf, " %.2d:%.2d:%.2d",
226           t->tm_hour, t->tm_min, t->tm_sec);
227   out = buf;
228   return out;
229 }
230
231 /**
232  * Return the magnetic variation
233  */
234 static double
235 getMagVar ()
236 {
237   return globals->get_mag()->get_magvar() * SGD_RADIANS_TO_DEGREES;
238 }
239
240
241 /**
242  * Return the magnetic dip
243  */
244 static double
245 getMagDip ()
246 {
247   return globals->get_mag()->get_magdip() * SGD_RADIANS_TO_DEGREES;
248 }
249
250
251 /**
252  * Return the current heading in degrees.
253  */
254 static double
255 getHeadingMag ()
256 {
257   return current_aircraft.fdm_state->get_Psi() * SGD_RADIANS_TO_DEGREES - getMagVar();
258 }
259
260
261 /**
262  * Return the current engine0 rpm
263  */
264 static double
265 getRPM ()
266 {
267   if ( current_aircraft.fdm_state->get_engine(0) != NULL ) {
268       return current_aircraft.fdm_state->get_engine(0)->get_RPM();
269   } else {
270       return 0.0;
271   }
272 }
273
274
275 /**
276  * Return the current engine0 EGT.
277  */
278 static double
279 getEGT ()
280 {
281   if ( current_aircraft.fdm_state->get_engine(0) != NULL ) {
282       return current_aircraft.fdm_state->get_engine(0)->get_EGT();
283   } else {
284       return 0.0;
285   }
286 }
287
288 /**
289  * Return the current engine0 CHT.
290  */
291 static double
292 getCHT ()
293 {
294   if ( current_aircraft.fdm_state->get_engine(0) != NULL ) {
295       return current_aircraft.fdm_state->get_engine(0)->get_CHT();
296   } else {
297       return 0.0;
298   }
299 }
300
301 /**
302  * Return the current engine0 Manifold Pressure.
303  */
304 static double
305 getMP ()
306 {
307   if ( current_aircraft.fdm_state->get_engine(0) != NULL ) {
308       return current_aircraft.fdm_state->get_engine(0)->get_Manifold_Pressure();
309   } else {
310       return 0.0;
311   }
312 }
313
314
315 /**
316  * Return the current engine0 fuel flow
317  */
318 static double
319 getFuelFlow ()
320 {
321   if ( current_aircraft.fdm_state->get_engine(0) != NULL ) {
322       return current_aircraft.fdm_state->get_engine(0)->get_Fuel_Flow();
323   } else {
324       return 0.0;
325   }
326 }
327
328 /**
329  * Return the fuel level in tank 1
330  */
331 static double
332 getTank1Fuel ()
333 {
334   return current_aircraft.fdm_state->get_Tank1Fuel();
335 }
336
337 static void
338 setTank1Fuel ( double gals )
339 {
340   current_aircraft.fdm_state->set_Tank1Fuel( gals );
341 }
342
343 /**
344  * Return the fuel level in tank 2
345  */
346 static double
347 getTank2Fuel ()
348 {
349   return current_aircraft.fdm_state->get_Tank2Fuel();
350 }
351
352 static void
353 setTank2Fuel ( double gals )
354 {
355   current_aircraft.fdm_state->set_Tank2Fuel( gals );
356 }
357
358
359 /**
360  * Get the autopilot altitude lock (true=on).
361  */
362 static bool
363 getAPAltitudeLock ()
364 {
365     return current_autopilot->get_AltitudeEnabled();
366 }
367
368
369 /**
370  * Set the autopilot altitude lock (true=on).
371  */
372 static void
373 setAPAltitudeLock (bool lock)
374 {
375   current_autopilot->set_AltitudeMode(FGAutopilot::FG_ALTITUDE_LOCK);
376   current_autopilot->set_AltitudeEnabled(lock);
377 }
378
379 /**
380  * Get the autopilot target altitude in feet.
381  */
382 static double
383 getAPAltitude ()
384 {
385   return current_autopilot->get_TargetAltitude() * SG_METER_TO_FEET;
386 }
387
388
389 /**
390  * Set the autopilot target altitude in feet.
391  */
392 static void
393 setAPAltitude (double altitude)
394 {
395     current_autopilot->set_TargetAltitude( altitude * SG_FEET_TO_METER );
396 }
397
398 /**
399  * Get the autopilot altitude lock (true=on).
400  */
401 static bool
402 getAPGSLock ()
403 {
404     return current_autopilot->get_AltitudeEnabled();
405 }
406
407
408 /**
409  * Set the autopilot altitude lock (true=on).
410  */
411 static void
412 setAPGSLock (bool lock)
413 {
414   current_autopilot->set_AltitudeMode(FGAutopilot::FG_ALTITUDE_GS1);
415   current_autopilot->set_AltitudeEnabled(lock);
416 }
417
418
419 /**
420  * Get the autopilot target altitude in feet.
421  */
422 static double
423 getAPClimb ()
424 {
425   return current_autopilot->get_TargetClimbRate() * SG_METER_TO_FEET;
426 }
427
428
429 /**
430  * Set the autopilot target altitude in feet.
431  */
432 static void
433 setAPClimb (double rate)
434 {
435     current_autopilot->set_TargetClimbRate( rate * SG_FEET_TO_METER );
436 }
437
438
439 /**
440  * Get the autopilot heading lock (true=on).
441  */
442 static bool
443 getAPHeadingLock ()
444 {
445     return
446       (current_autopilot->get_HeadingEnabled() &&
447        current_autopilot->get_HeadingMode() == DEFAULT_AP_HEADING_LOCK);
448 }
449
450
451 /**
452  * Set the autopilot heading lock (true=on).
453  */
454 static void
455 setAPHeadingLock (bool lock)
456 {
457     if (lock) {
458         current_autopilot->set_HeadingMode(DEFAULT_AP_HEADING_LOCK);
459         current_autopilot->set_HeadingEnabled(true);
460     } else {
461         current_autopilot->set_HeadingEnabled(false);
462     }
463 }
464
465
466 /**
467  * Get the autopilot heading bug in degrees.
468  */
469 static double
470 getAPHeadingBug ()
471 {
472   return current_autopilot->get_DGTargetHeading();
473 }
474
475
476 /**
477  * Set the autopilot heading bug in degrees.
478  */
479 static void
480 setAPHeadingBug (double heading)
481 {
482   current_autopilot->set_DGTargetHeading( heading );
483 }
484
485
486 /**
487  * Get the autopilot wing leveler lock (true=on).
488  */
489 static bool
490 getAPWingLeveler ()
491 {
492     return
493       (current_autopilot->get_HeadingEnabled() &&
494        current_autopilot->get_HeadingMode() == FGAutopilot::FG_TC_HEADING_LOCK);
495 }
496
497
498 /**
499  * Set the autopilot wing leveler lock (true=on).
500  */
501 static void
502 setAPWingLeveler (bool lock)
503 {
504     if (lock) {
505         current_autopilot->set_HeadingMode(FGAutopilot::FG_TC_HEADING_LOCK);
506         current_autopilot->set_HeadingEnabled(true);
507     } else {
508         current_autopilot->set_HeadingEnabled(false);
509     }
510 }
511
512 /**
513  * Return true if the autopilot is locked to NAV1.
514  */
515 static bool
516 getAPNAV1Lock ()
517 {
518   return
519     (current_autopilot->get_HeadingEnabled() &&
520      current_autopilot->get_HeadingMode() == FGAutopilot::FG_HEADING_NAV1);
521 }
522
523
524 /**
525  * Set the autopilot NAV1 lock.
526  */
527 static void
528 setAPNAV1Lock (bool lock)
529 {
530   if (lock) {
531     current_autopilot->set_HeadingMode(FGAutopilot::FG_HEADING_NAV1);
532     current_autopilot->set_HeadingEnabled(true);
533   } else if (current_autopilot->get_HeadingMode() ==
534              FGAutopilot::FG_HEADING_NAV1) {
535     current_autopilot->set_HeadingEnabled(false);
536   }
537 }
538
539 /**
540  * Get the autopilot autothrottle lock.
541  */
542 static bool
543 getAPAutoThrottleLock ()
544 {
545   return current_autopilot->get_AutoThrottleEnabled();
546 }
547
548
549 /**
550  * Set the autothrottle lock.
551  */
552 static void
553 setAPAutoThrottleLock (bool lock)
554 {
555   current_autopilot->set_AutoThrottleEnabled(lock);
556 }
557
558
559 // kludge
560 static double
561 getAPRudderControl ()
562 {
563     if (getAPHeadingLock())
564         return current_autopilot->get_TargetHeading();
565     else
566         return controls.get_rudder();
567 }
568
569 // kludge
570 static void
571 setAPRudderControl (double value)
572 {
573     if (getAPHeadingLock()) {
574         SG_LOG(SG_GENERAL, SG_DEBUG, "setAPRudderControl " << value );
575         value -= current_autopilot->get_TargetHeading();
576         current_autopilot->HeadingAdjust(value < 0.0 ? -1.0 : 1.0);
577     } else {
578         controls.set_rudder(value);
579     }
580 }
581
582 // kludge
583 static double
584 getAPElevatorControl ()
585 {
586   if (getAPAltitudeLock())
587       return current_autopilot->get_TargetAltitude();
588   else
589     return controls.get_elevator();
590 }
591
592 // kludge
593 static void
594 setAPElevatorControl (double value)
595 {
596     if (getAPAltitudeLock()) {
597         SG_LOG(SG_GENERAL, SG_DEBUG, "setAPElevatorControl " << value );
598         value -= current_autopilot->get_TargetAltitude();
599         current_autopilot->AltitudeAdjust(value < 0.0 ? 100.0 : -100.0);
600     } else {
601         controls.set_elevator(value);
602     }
603 }
604
605 // kludge
606 static double
607 getAPThrottleControl ()
608 {
609   if (getAPAutoThrottleLock())
610     return 0.0;                 // always resets
611   else
612     return controls.get_throttle(0);
613 }
614
615 // kludge
616 static void
617 setAPThrottleControl (double value)
618 {
619   if (getAPAutoThrottleLock())
620     current_autopilot->AutoThrottleAdjust(value < 0.0 ? -0.01 : 0.01);
621   else
622     controls.set_throttle(0, value);
623 }
624
625
626 /**
627  * Get the current visibility (meters).
628  */
629 static double
630 getVisibility ()
631 {
632 #ifndef FG_OLD_WEATHER
633   return WeatherDatabase->getWeatherVisibility();
634 #else
635   return current_weather.get_visibility();
636 #endif
637 }
638
639
640 /**
641  * Set the current visibility (meters).
642  */
643 static void
644 setVisibility (double visibility)
645 {
646 #ifndef FG_OLD_WEATHER
647   WeatherDatabase->setWeatherVisibility(visibility);
648 #else
649   current_weather.set_visibility(visibility);
650 #endif
651 }
652
653 /**
654  * Get the current wind north velocity (feet/second).
655  */
656 static double
657 getWindNorth ()
658 {
659   return current_aircraft.fdm_state->get_V_north_airmass();
660 }
661
662
663 /**
664  * Set the current wind north velocity (feet/second).
665  */
666 static void
667 setWindNorth (double speed)
668 {
669   current_aircraft.fdm_state
670     ->set_Velocities_Local_Airmass(speed, getWindEast(), getWindDown());
671 }
672
673
674 /**
675  * Get the current wind east velocity (feet/second).
676  */
677 static double
678 getWindEast ()
679 {
680   return current_aircraft.fdm_state->get_V_east_airmass();
681 }
682
683
684 /**
685  * Set the current wind east velocity (feet/second).
686  */
687 static void
688 setWindEast (double speed)
689 {
690   cout << "Set wind-east to " << speed << endl;
691   current_aircraft.fdm_state->set_Velocities_Local_Airmass(getWindNorth(),
692                                                            speed,
693                                                            getWindDown());
694 }
695
696
697 /**
698  * Get the current wind down velocity (feet/second).
699  */
700 static double
701 getWindDown ()
702 {
703   return current_aircraft.fdm_state->get_V_down_airmass();
704 }
705
706
707 /**
708  * Set the current wind down velocity (feet/second).
709  */
710 static void
711 setWindDown (double speed)
712 {
713   current_aircraft.fdm_state->set_Velocities_Local_Airmass(getWindNorth(),
714                                                            getWindEast(),
715                                                            speed);
716 }
717
718 static double
719 getFOV ()
720 {
721   return globals->get_current_view()->get_fov();
722 }
723
724 static void
725 setFOV (double fov)
726 {
727   globals->get_current_view()->set_fov( fov );
728 }
729
730
731 static void
732 setViewAxisLong (double axis)
733 {
734   axisLong = axis;
735 }
736
737 static void
738 setViewAxisLat (double axis)
739 {
740   axisLat = axis;
741 }
742
743
744 void
745 fgInitProps ()
746 {
747                                 // Simulation
748   fgTie("/sim/aircraft-dir", getAircraftDir, setAircraftDir);
749   fgTie("/sim/view/offset", getViewOffset, setViewOffset);
750   fgTie("/sim/view/goal-offset", getGoalViewOffset, setGoalViewOffset);
751   fgTie("/sim/time/gmt", getDateString, setDateString);
752   fgTie("/sim/time/gmt-string", getGMTString);
753
754                                 // Orientation
755   fgTie("/orientation/heading-magnetic", getHeadingMag);
756
757                                 // Engine
758   fgTie("/engines/engine0/rpm", getRPM);
759   fgTie("/engines/engine0/egt", getEGT);
760   fgTie("/engines/engine0/cht", getCHT);
761   fgTie("/engines/engine0/mp", getMP);
762   fgTie("/engines/engine0/fuel-flow", getFuelFlow);
763
764   //consumables
765   fgTie("/consumables/fuel/tank1/level", getTank1Fuel, setTank1Fuel, false);
766   fgTie("/consumables/fuel/tank2/level", getTank2Fuel, setTank2Fuel, false);
767
768                                 // Autopilot
769   fgTie("/autopilot/locks/altitude", getAPAltitudeLock, setAPAltitudeLock);
770   fgTie("/autopilot/settings/altitude", getAPAltitude, setAPAltitude);
771   fgTie("/autopilot/locks/glide-slope", getAPGSLock, setAPGSLock);
772   fgTie("/autopilot/settings/climb-rate", getAPClimb, setAPClimb, false);
773   fgTie("/autopilot/locks/heading", getAPHeadingLock, setAPHeadingLock);
774   fgTie("/autopilot/settings/heading-bug", getAPHeadingBug, setAPHeadingBug,
775         false);
776   fgTie("/autopilot/locks/wing-leveler", getAPWingLeveler, setAPWingLeveler);
777   fgTie("/autopilot/locks/nav1", getAPNAV1Lock, setAPNAV1Lock);
778   fgTie("/autopilot/locks/auto-throttle",
779         getAPAutoThrottleLock, setAPAutoThrottleLock);
780   fgTie("/autopilot/control-overrides/rudder",
781         getAPRudderControl, setAPRudderControl);
782   fgTie("/autopilot/control-overrides/elevator",
783         getAPElevatorControl, setAPElevatorControl);
784   fgTie("/autopilot/control-overrides/throttle",
785         getAPThrottleControl, setAPThrottleControl);
786
787                                 // Environment
788   fgTie("/environment/visibility", getVisibility, setVisibility);
789   fgTie("/environment/wind-north", getWindNorth, setWindNorth);
790   fgTie("/environment/wind-east", getWindEast, setWindEast);
791   fgTie("/environment/wind-down", getWindDown, setWindDown);
792   fgTie("/environment/magnetic-variation", getMagVar);
793   fgTie("/environment/magnetic-dip", getMagDip);
794
795                                 // View
796   fgTie("/sim/field-of-view", getFOV, setFOV);
797   fgTie("/sim/view/axes/long", (double(*)())0, setViewAxisLong);
798   fgTie("/sim/view/axes/lat", (double(*)())0, setViewAxisLat);
799 }
800
801
802 void
803 fgUpdateProps ()
804 {
805   _set_view_from_axes();
806 }
807
808
809 \f
810 ////////////////////////////////////////////////////////////////////////
811 // Save and restore.
812 ////////////////////////////////////////////////////////////////////////
813
814
815 /**
816  * Save the current state of the simulator to a stream.
817  */
818 bool
819 fgSaveFlight (ostream &output)
820 {
821   return writeProperties(output, globals->get_props());
822 }
823
824
825 /**
826  * Restore the current state of the simulator from a stream.
827  */
828 bool
829 fgLoadFlight (istream &input)
830 {
831   SGPropertyNode props;
832   if (readProperties(input, &props)) {
833     copyProperties(&props, globals->get_props());
834                                 // When loading a flight, make it the
835                                 // new initial state.
836     globals->saveInitialState();
837   } else {
838     SG_LOG(SG_INPUT, SG_ALERT, "Error restoring flight; aborted");
839     return false;
840   }
841
842   return true;
843 }
844
845 // end of fg_props.cxx
846