1 // fg_props.cxx -- support for FlightGear properties.
3 // Written by David Megginson, started 2000.
5 // Copyright (C) 2000, 2001 David Megginson - david@megginson.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.
24 # include <simgear/compiler.h>
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>
36 # include <Weather/weather.hxx>
38 #include <Objects/matlib.hxx>
41 #include "fg_props.hxx"
43 #if !defined(SG_HAVE_NATIVE_SGI_COMPILERS)
44 SG_USING_STD(istream);
45 SG_USING_STD(ostream);
48 static double getWindNorth ();
49 static double getWindEast ();
50 static double getWindDown ();
52 // Allow the view to be set from two axes (i.e. a joystick hat)
53 // This needs to be in FGViewer itself, somehow.
54 static double axisLong = 0.0;
55 static double axisLat = 0.0;
61 _set_view_from_axes ()
63 // Take no action when hat is centered
64 if ( ( axisLong < 0.01 ) &&
65 ( axisLong > -0.01 ) &&
73 /* Do all the quick and easy cases */
74 if (axisLong < 0) { // Longitudinal axis forward
75 if (axisLat == axisLong)
77 else if (axisLat == - axisLong)
79 else if (axisLat == 0)
81 } else if (axisLong > 0) { // Longitudinal axis backward
82 if (axisLat == - axisLong)
84 else if (axisLat == axisLong)
86 else if (axisLat == 0)
88 } else if (axisLong == 0) { // Longitudinal axis neutral
93 else return; /* And assertion failure maybe? */
96 /* Do all the difficult cases */
98 viewDir = SGD_RADIANS_TO_DEGREES * atan2 ( -axisLat, -axisLong );
99 if ( viewDir < -1 ) viewDir += 360;
101 // SG_LOG(SG_INPUT, SG_ALERT, "Joystick Lat=" << axisLat << " and Long="
102 // << axisLong << " gave angle=" << viewDir );
104 globals->get_current_view()->set_goal_view_offset(viewDir*SGD_DEGREES_TO_RADIANS);
105 // globals->get_current_view()->set_view_offset(viewDir*SGD_DEGREES_TO_RADIANS);
109 ////////////////////////////////////////////////////////////////////////
110 // Default property bindings (not yet handled by any module).
111 ////////////////////////////////////////////////////////////////////////
115 * Get the pause state of the sim.
120 return globals->get_freeze();
125 * Set the pause state of the sim.
128 setFreeze (bool freeze)
130 globals->set_freeze(freeze);
134 * Return the current aircraft directory (UIUC) as a string.
144 * Set the current aircraft directory (UIUC).
147 setAircraftDir (string dir)
149 if (getAircraftDir() != dir) {
151 // needReinit(); FIXME!!
157 * Get the current view offset in degrees.
162 return (globals->get_current_view()
163 ->get_view_offset() * SGD_RADIANS_TO_DEGREES);
168 setViewOffset (double offset)
170 globals->get_current_view()->set_view_offset(offset * SGD_DEGREES_TO_RADIANS);
176 return (globals->get_current_view()
177 ->get_goal_view_offset() * SGD_RADIANS_TO_DEGREES);
181 setGoalViewOffset (double offset)
183 while ( offset < 0 ) {
186 while ( offset > 360.0 ) {
189 // Snap to center if we are close
190 if ( fabs( offset ) < 1.0 ) {
194 globals->get_current_view()
195 ->set_goal_view_offset(offset * SGD_DEGREES_TO_RADIANS);
200 * Return the current Zulu time.
207 struct tm * t = globals->get_time_params()->getGmt();
208 sprintf(buf, "%.4d-%.2d-%.2dT%.2d:%.2d:%.2d",
209 t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
210 t->tm_hour, t->tm_min, t->tm_sec);
217 * Set the current Zulu time.
220 setDateString (string date_string)
222 SGTime * st = globals->get_time_params();
223 struct tm * current_time = st->getGmt();
226 // Scan for basic ISO format
227 // YYYY-MM-DDTHH:MM:SS
228 int ret = sscanf(date_string.c_str(), "%d-%d-%dT%d:%d:%d",
229 &(new_time.tm_year), &(new_time.tm_mon),
230 &(new_time.tm_mday), &(new_time.tm_hour),
231 &(new_time.tm_min), &(new_time.tm_sec));
233 // Be pretty picky about this, so
234 // that strange things don't happen
235 // if the save file has been edited
238 SG_LOG(SG_INPUT, SG_ALERT, "Date/time string " << date_string
239 << " not in YYYY-MM-DDTHH:MM:SS format; skipped");
243 // OK, it looks like we got six
244 // values, one way or another.
245 new_time.tm_year -= 1900;
246 new_time.tm_mon -= 1;
248 // Now, tell flight gear to use
249 // the new time. This was far
250 // too difficult, by the way.
252 mktime(&new_time) - mktime(current_time) + globals->get_warp();
253 double lon = current_aircraft.fdm_state->get_Longitude();
254 double lat = current_aircraft.fdm_state->get_Latitude();
255 globals->set_warp(warp);
256 st->update(lon, lat, warp);
257 fgUpdateSkyAndLightingParams();
261 * Return the GMT as a string.
268 struct tm * t = globals->get_time_params()->getGmt();
269 sprintf(buf, " %.2d:%.2d:%.2d",
270 t->tm_hour, t->tm_min, t->tm_sec);
277 * Get the texture rendering state.
282 return (material_lib.get_step() == 0);
287 * Set the texture rendering state.
290 setTextures (bool textures)
293 material_lib.set_step(0);
295 material_lib.set_step(1);
300 * Return the magnetic variation
305 return globals->get_mag()->get_magvar() * SGD_RADIANS_TO_DEGREES;
310 * Return the magnetic dip
315 return globals->get_mag()->get_magdip() * SGD_RADIANS_TO_DEGREES;
320 * Return the current heading in degrees.
325 return current_aircraft.fdm_state->get_Psi() * SGD_RADIANS_TO_DEGREES - getMagVar();
330 * Return the current engine0 rpm
335 if ( current_aircraft.fdm_state->get_engine(0) != NULL ) {
336 return current_aircraft.fdm_state->get_engine(0)->get_RPM();
344 * Return the current engine0 EGT.
349 if ( current_aircraft.fdm_state->get_engine(0) != NULL ) {
350 return current_aircraft.fdm_state->get_engine(0)->get_EGT();
357 * Return the current engine0 CHT.
362 if ( current_aircraft.fdm_state->get_engine(0) != NULL ) {
363 return current_aircraft.fdm_state->get_engine(0)->get_CHT();
370 * Return the current engine0 Manifold Pressure.
375 if ( current_aircraft.fdm_state->get_engine(0) != NULL ) {
376 return current_aircraft.fdm_state->get_engine(0)->get_Manifold_Pressure();
384 * Return the current engine0 fuel flow
389 if ( current_aircraft.fdm_state->get_engine(0) != NULL ) {
390 return current_aircraft.fdm_state->get_engine(0)->get_Fuel_Flow();
397 * Return the fuel level in tank 1
402 return current_aircraft.fdm_state->get_Tank1Fuel();
406 setTank1Fuel ( double gals )
408 current_aircraft.fdm_state->set_Tank1Fuel( gals );
412 * Return the fuel level in tank 2
417 return current_aircraft.fdm_state->get_Tank2Fuel();
421 setTank2Fuel ( double gals )
423 current_aircraft.fdm_state->set_Tank2Fuel( gals );
428 * Get the autopilot altitude lock (true=on).
433 return (current_autopilot->get_AltitudeEnabled() &&
434 current_autopilot->get_AltitudeMode()
435 == FGAutopilot::FG_ALTITUDE_LOCK);
440 * Set the autopilot altitude lock (true=on).
443 setAPAltitudeLock (bool lock)
445 current_autopilot->set_AltitudeMode(FGAutopilot::FG_ALTITUDE_LOCK);
446 current_autopilot->set_AltitudeEnabled(lock);
451 * Get the autopilot target altitude in feet.
456 return current_autopilot->get_TargetAltitude() * SG_METER_TO_FEET;
461 * Set the autopilot target altitude in feet.
464 setAPAltitude (double altitude)
466 current_autopilot->set_TargetAltitude( altitude * SG_FEET_TO_METER );
470 * Get the autopilot altitude lock (true=on).
475 return (current_autopilot->get_AltitudeEnabled() &&
476 (current_autopilot->get_AltitudeMode()
477 == FGAutopilot::FG_ALTITUDE_GS1));
482 * Set the autopilot altitude lock (true=on).
485 setAPGSLock (bool lock)
487 current_autopilot->set_AltitudeMode(FGAutopilot::FG_ALTITUDE_GS1);
488 current_autopilot->set_AltitudeEnabled(lock);
493 * Get the autopilot terrain lock (true=on).
498 return (current_autopilot->get_AltitudeEnabled() &&
499 (current_autopilot->get_AltitudeMode()
500 == FGAutopilot::FG_ALTITUDE_TERRAIN));
505 * Set the autopilot terrain lock (true=on).
508 setAPTerrainLock (bool lock)
510 current_autopilot->set_AltitudeMode(FGAutopilot::FG_ALTITUDE_TERRAIN);
511 current_autopilot->set_AltitudeEnabled(lock);
516 * Get the autopilot target altitude in feet.
521 return current_autopilot->get_TargetClimbRate() * SG_METER_TO_FEET;
526 * Set the autopilot target altitude in feet.
529 setAPClimb (double rate)
531 current_autopilot->set_TargetClimbRate( rate * SG_FEET_TO_METER );
536 * Get the autopilot heading lock (true=on).
542 (current_autopilot->get_HeadingEnabled() &&
543 current_autopilot->get_HeadingMode() == DEFAULT_AP_HEADING_LOCK);
548 * Set the autopilot heading lock (true=on).
551 setAPHeadingLock (bool lock)
554 current_autopilot->set_HeadingMode(DEFAULT_AP_HEADING_LOCK);
555 current_autopilot->set_HeadingEnabled(true);
557 current_autopilot->set_HeadingEnabled(false);
563 * Get the autopilot heading bug in degrees.
568 return current_autopilot->get_DGTargetHeading();
573 * Set the autopilot heading bug in degrees.
576 setAPHeadingBug (double heading)
578 current_autopilot->set_DGTargetHeading( heading );
583 * Get the autopilot wing leveler lock (true=on).
589 (current_autopilot->get_HeadingEnabled() &&
590 current_autopilot->get_HeadingMode() == FGAutopilot::FG_TC_HEADING_LOCK);
595 * Set the autopilot wing leveler lock (true=on).
598 setAPWingLeveler (bool lock)
601 current_autopilot->set_HeadingMode(FGAutopilot::FG_TC_HEADING_LOCK);
602 current_autopilot->set_HeadingEnabled(true);
604 current_autopilot->set_HeadingEnabled(false);
609 * Return true if the autopilot is locked to NAV1.
615 (current_autopilot->get_HeadingEnabled() &&
616 current_autopilot->get_HeadingMode() == FGAutopilot::FG_HEADING_NAV1);
621 * Set the autopilot NAV1 lock.
624 setAPNAV1Lock (bool lock)
627 current_autopilot->set_HeadingMode(FGAutopilot::FG_HEADING_NAV1);
628 current_autopilot->set_HeadingEnabled(true);
629 } else if (current_autopilot->get_HeadingMode() ==
630 FGAutopilot::FG_HEADING_NAV1) {
631 current_autopilot->set_HeadingEnabled(false);
636 * Get the autopilot autothrottle lock.
639 getAPAutoThrottleLock ()
641 return current_autopilot->get_AutoThrottleEnabled();
646 * Set the autothrottle lock.
649 setAPAutoThrottleLock (bool lock)
651 current_autopilot->set_AutoThrottleEnabled(lock);
657 getAPRudderControl ()
659 if (getAPHeadingLock())
660 return current_autopilot->get_TargetHeading();
662 return controls.get_rudder();
667 setAPRudderControl (double value)
669 if (getAPHeadingLock()) {
670 SG_LOG(SG_GENERAL, SG_DEBUG, "setAPRudderControl " << value );
671 value -= current_autopilot->get_TargetHeading();
672 current_autopilot->HeadingAdjust(value < 0.0 ? -1.0 : 1.0);
674 controls.set_rudder(value);
680 getAPElevatorControl ()
682 if (getAPAltitudeLock())
683 return current_autopilot->get_TargetAltitude();
685 return controls.get_elevator();
690 setAPElevatorControl (double value)
692 if (getAPAltitudeLock()) {
693 SG_LOG(SG_GENERAL, SG_DEBUG, "setAPElevatorControl " << value );
694 value -= current_autopilot->get_TargetAltitude();
695 current_autopilot->AltitudeAdjust(value < 0.0 ? 100.0 : -100.0);
697 controls.set_elevator(value);
703 getAPThrottleControl ()
705 if (getAPAutoThrottleLock())
706 return 0.0; // always resets
708 return controls.get_throttle(0);
713 setAPThrottleControl (double value)
715 if (getAPAutoThrottleLock())
716 current_autopilot->AutoThrottleAdjust(value < 0.0 ? -0.01 : 0.01);
718 controls.set_throttle(0, value);
723 * Get the current visibility (meters).
728 #ifndef FG_OLD_WEATHER
729 return WeatherDatabase->getWeatherVisibility();
731 return current_weather.get_visibility();
737 * Set the current visibility (meters).
740 setVisibility (double visibility)
742 #ifndef FG_OLD_WEATHER
743 WeatherDatabase->setWeatherVisibility(visibility);
745 current_weather.set_visibility(visibility);
750 * Get the current wind north velocity (feet/second).
755 return current_aircraft.fdm_state->get_V_north_airmass();
760 * Set the current wind north velocity (feet/second).
763 setWindNorth (double speed)
765 current_aircraft.fdm_state
766 ->set_Velocities_Local_Airmass(speed, getWindEast(), getWindDown());
771 * Get the current wind east velocity (feet/second).
776 return current_aircraft.fdm_state->get_V_east_airmass();
781 * Set the current wind east velocity (feet/second).
784 setWindEast (double speed)
786 cout << "Set wind-east to " << speed << endl;
787 current_aircraft.fdm_state->set_Velocities_Local_Airmass(getWindNorth(),
794 * Get the current wind down velocity (feet/second).
799 return current_aircraft.fdm_state->get_V_down_airmass();
804 * Set the current wind down velocity (feet/second).
807 setWindDown (double speed)
809 current_aircraft.fdm_state->set_Velocities_Local_Airmass(getWindNorth(),
817 return globals->get_current_view()->get_fov();
823 globals->get_current_view()->set_fov( fov );
829 return globals->get_warp();
835 globals->set_warp(warp);
841 return globals->get_warp_delta();
845 setWarpDelta (long delta)
847 globals->set_warp_delta(delta);
851 setViewAxisLong (double axis)
857 setViewAxisLat (double axis)
867 fgTie("/sim/freeze", getFreeze, setFreeze);
868 fgTie("/sim/aircraft-dir", getAircraftDir, setAircraftDir);
869 fgTie("/sim/view/offset-deg", getViewOffset, setViewOffset);
870 fgTie("/sim/view/goal-offset-deg", getGoalViewOffset, setGoalViewOffset);
871 fgTie("/sim/time/gmt", getDateString, setDateString);
872 fgTie("/sim/time/gmt-string", getGMTString);
873 fgTie("/sim/rendering/textures", getTextures, setTextures);
876 fgTie("/orientation/heading-magnetic-deg", getHeadingMag);
879 fgTie("/engines/engine[0]/rpm", getRPM);
880 fgTie("/engines/engine[0]/egt-degf", getEGT);
881 fgTie("/engines/engine[0]/cht-degf", getCHT);
882 fgTie("/engines/engine[0]/mp-osi", getMP);
883 fgTie("/engines/engine[0]/fuel-flow-gph", getFuelFlow);
886 fgTie("/consumables/fuel/tank[0]/level-gal_us", getTank1Fuel, setTank1Fuel, false);
887 fgTie("/consumables/fuel/tank[1]/level-gal_us", getTank2Fuel, setTank2Fuel, false);
890 fgTie("/autopilot/locks/altitude", getAPAltitudeLock, setAPAltitudeLock);
891 fgTie("/autopilot/settings/altitude-ft", getAPAltitude, setAPAltitude);
892 fgTie("/autopilot/locks/glide-slope", getAPGSLock, setAPGSLock);
893 fgTie("/autopilot/locks/terrain", getAPTerrainLock, setAPTerrainLock);
894 fgTie("/autopilot/settings/climb-rate-fpm", getAPClimb, setAPClimb, false);
895 fgTie("/autopilot/locks/heading", getAPHeadingLock, setAPHeadingLock);
896 fgTie("/autopilot/settings/heading-bug-deg", getAPHeadingBug, setAPHeadingBug,
898 fgTie("/autopilot/locks/wing-leveler", getAPWingLeveler, setAPWingLeveler);
899 fgTie("/autopilot/locks/nav[0]", getAPNAV1Lock, setAPNAV1Lock);
900 fgTie("/autopilot/locks/auto-throttle",
901 getAPAutoThrottleLock, setAPAutoThrottleLock);
902 fgTie("/autopilot/control-overrides/rudder",
903 getAPRudderControl, setAPRudderControl);
904 fgTie("/autopilot/control-overrides/elevator",
905 getAPElevatorControl, setAPElevatorControl);
906 fgTie("/autopilot/control-overrides/throttle",
907 getAPThrottleControl, setAPThrottleControl);
910 fgTie("/environment/visibility-m", getVisibility, setVisibility);
911 fgTie("/environment/wind-north-fps", getWindNorth, setWindNorth);
912 fgTie("/environment/wind-east-fps", getWindEast, setWindEast);
913 fgTie("/environment/wind-down-fps", getWindDown, setWindDown);
914 fgTie("/environment/magnetic-variation-deg", getMagVar);
915 fgTie("/environment/magnetic-dip-deg", getMagDip);
918 fgTie("/sim/field-of-view", getFOV, setFOV);
919 fgTie("/sim/time/warp", getWarp, setWarp, false);
920 fgTie("/sim/time/warp-delta", getWarpDelta, setWarpDelta);
921 fgTie("/sim/view/axes/long", (double(*)())0, setViewAxisLong);
922 fgTie("/sim/view/axes/lat", (double(*)())0, setViewAxisLat);
929 _set_view_from_axes();
934 ////////////////////////////////////////////////////////////////////////
936 ////////////////////////////////////////////////////////////////////////
940 * Save the current state of the simulator to a stream.
943 fgSaveFlight (ostream &output)
945 return writeProperties(output, globals->get_props());
950 * Restore the current state of the simulator from a stream.
953 fgLoadFlight (istream &input)
955 SGPropertyNode props;
956 if (readProperties(input, &props)) {
957 copyProperties(&props, globals->get_props());
958 // When loading a flight, make it the
959 // new initial state.
960 globals->saveInitialState();
962 SG_LOG(SG_INPUT, SG_ALERT, "Error restoring flight; aborted");
969 // end of fg_props.cxx