diff --git a/src/Autopilot/Makefile.am b/src/Autopilot/Makefile.am index 9e38e9d69..3d0623429 100644 --- a/src/Autopilot/Makefile.am +++ b/src/Autopilot/Makefile.am @@ -1,5 +1,7 @@ noinst_LIBRARIES = libAutopilot.a -libAutopilot_a_SOURCES = autopilot.cxx autopilot.hxx +libAutopilot_a_SOURCES = \ + auto_gui.cxx auto_gui.hxx \ + newauto.cxx newauto.hxx INCLUDES += -I$(top_builddir) -I$(top_builddir)/src diff --git a/src/Autopilot/auto_gui.cxx b/src/Autopilot/auto_gui.cxx new file mode 100644 index 000000000..9379bfec4 --- /dev/null +++ b/src/Autopilot/auto_gui.cxx @@ -0,0 +1,702 @@ +// auto_gui.cxx -- autopilot gui interface +// +// Written by Norman Vine <nhv@cape.com> +// Arranged by Curt Olson <curt@flightgear.org> +// +// Copyright (C) 1998 - 2000 +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// +// $Id$ + + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <assert.h> +#include <stdlib.h> + +#include <Scenery/scenery.hxx> + +#include <simgear/constants.h> +#include <simgear/debug/logstream.hxx> +#include <simgear/math/fg_geodesy.hxx> +#include <simgear/misc/fgpath.hxx> + +#include <Airports/simple.hxx> +#include <GUI/gui.h> +#include <Main/bfi.hxx> +#include <Main/fg_init.hxx> +#include <Main/options.hxx> +#include <Time/fg_time.hxx> + +#include "auto_gui.hxx" +#include "newauto.hxx" + + +#define mySlider puSlider + +// Climb speed constants +const double min_climb = 70.0; // kts +const double best_climb = 75.0; // kts +const double ideal_climb_rate = 500.0; // fpm + +/// These statics will eventually go into the class +/// they are just here while I am experimenting -- NHV :-) +// AutoPilot Gain Adjuster members +static double MaxRollAdjust; // MaxRollAdjust = 2 * APData->MaxRoll; +static double RollOutAdjust; // RollOutAdjust = 2 * APData->RollOut; +static double MaxAileronAdjust; // MaxAileronAdjust = 2 * APData->MaxAileron; +static double RollOutSmoothAdjust; // RollOutSmoothAdjust = 2 * APData->RollOutSmooth; + +static float MaxRollValue; // 0.1 -> 1.0 +static float RollOutValue; +static float MaxAileronValue; +static float RollOutSmoothValue; + +static float TmpMaxRollValue; // for cancel operation +static float TmpRollOutValue; +static float TmpMaxAileronValue; +static float TmpRollOutSmoothValue; + +static puDialogBox *APAdjustDialog; +static puFrame *APAdjustFrame; +static puText *APAdjustDialogMessage; +static puFont APAdjustLegendFont; +static puFont APAdjustLabelFont; + +static puOneShot *APAdjustOkButton; +static puOneShot *APAdjustResetButton; +static puOneShot *APAdjustCancelButton; + +//static puButton *APAdjustDragButton; + +static puText *APAdjustMaxRollTitle; +static puText *APAdjustRollOutTitle; +static puText *APAdjustMaxAileronTitle; +static puText *APAdjustRollOutSmoothTitle; + +static puText *APAdjustMaxAileronText; +static puText *APAdjustMaxRollText; +static puText *APAdjustRollOutText; +static puText *APAdjustRollOutSmoothText; + +static mySlider *APAdjustHS0; +static mySlider *APAdjustHS1; +static mySlider *APAdjustHS2; +static mySlider *APAdjustHS3; + +static char SliderText[ 4 ][ 8 ]; + +///////// AutoPilot New Heading Dialog + +static puDialogBox *ApHeadingDialog; +static puFrame *ApHeadingDialogFrame; +static puText *ApHeadingDialogMessage; +static puInput *ApHeadingDialogInput; +static puOneShot *ApHeadingDialogOkButton; +static puOneShot *ApHeadingDialogCancelButton; + + +///////// AutoPilot New Altitude Dialog + +static puDialogBox *ApAltitudeDialog = 0; +static puFrame *ApAltitudeDialogFrame = 0; +static puText *ApAltitudeDialogMessage = 0; +static puInput *ApAltitudeDialogInput = 0; + +static puOneShot *ApAltitudeDialogOkButton = 0; +static puOneShot *ApAltitudeDialogCancelButton = 0; + + +/// The beginnings of Lock AutoPilot to target location :-) +// Needs cleaning up but works +// These statics should disapear when this is a class +static puDialogBox *TgtAptDialog = 0; +static puFrame *TgtAptDialogFrame = 0; +static puText *TgtAptDialogMessage = 0; +static puInput *TgtAptDialogInput = 0; + +static char NewTgtAirportId[16]; +static char NewTgtAirportLabel[] = "Enter New TgtAirport ID"; + +static puOneShot *TgtAptDialogOkButton = 0; +static puOneShot *TgtAptDialogCancelButton = 0; +static puOneShot *TgtAptDialogResetButton = 0; + + +// extern char *coord_format_lat(float); +// extern char *coord_format_lon(float); + +// THIS NEEDS IMPROVEMENT !!!!!!!!!!!!! +static int scan_number(char *s, double *new_value) +{ + int ret = 0; + char WordBuf[64]; + char *cptr = s; + char *WordBufPtr = WordBuf; + + if (*cptr == '+') + cptr++; + if (*cptr == '-') { + *WordBufPtr++ = *cptr++; + } + while (isdigit(*cptr) ) { + *WordBufPtr++ = *cptr++; + ret = 1; + } + if (*cptr == '.') + *WordBufPtr++ = *cptr++; // put the '.' into the string + while (isdigit(*cptr)) { + *WordBufPtr++ = *cptr++; + ret = 1; + } + if( ret == 1 ) { + *WordBufPtr = '\0'; + sscanf(WordBuf, "%lf", new_value); + } + + return(ret); +} // scan_number + + +void ApHeadingDialog_Cancel(puObject *) +{ + ApHeadingDialogInput->rejectInput(); + FG_POP_PUI_DIALOG( ApHeadingDialog ); +} + +void ApHeadingDialog_OK (puObject *me) +{ + int error = 0; + char *c; + string s; + ApHeadingDialogInput -> getValue( &c ); + + if( strlen(c) ) { + double NewHeading; + if( scan_number( c, &NewHeading ) ) + { + if ( !current_autopilot->get_HeadingEnabled() ) { + current_autopilot->set_HeadingEnabled( true ); + } + current_autopilot->HeadingSet( NewHeading ); + } else { + error = 1; + s = c; + s += " is not a valid number."; + } + } + ApHeadingDialog_Cancel(me); + if( error ) mkDialog(s.c_str()); +} + +void NewHeading(puObject *cb) +{ + // string ApHeadingLabel( "Enter New Heading" ); + // ApHeadingDialogMessage -> setLabel(ApHeadingLabel.c_str()); + ApHeadingDialogInput -> acceptInput(); + FG_PUSH_PUI_DIALOG( ApHeadingDialog ); +} + +void NewHeadingInit(void) +{ + // printf("NewHeadingInit\n"); + char NewHeadingLabel[] = "Enter New Heading"; + char *s; + + float heading = FGBFI::getHeading(); + int len = 260/2 - + (puGetStringWidth( puGetDefaultLabelFont(), NewHeadingLabel ) /2 ); + + ApHeadingDialog = new puDialogBox (150, 50); + { + ApHeadingDialogFrame = new puFrame (0, 0, 260, 150); + + ApHeadingDialogMessage = new puText (len, 110); + ApHeadingDialogMessage -> setDefaultValue (NewHeadingLabel); + ApHeadingDialogMessage -> getDefaultValue (&s); + ApHeadingDialogMessage -> setLabel (s); + + ApHeadingDialogInput = new puInput ( 50, 70, 210, 100 ); + ApHeadingDialogInput -> setValue ( heading ); + + ApHeadingDialogOkButton = new puOneShot (50, 10, 110, 50); + ApHeadingDialogOkButton -> setLegend (gui_msg_OK); + ApHeadingDialogOkButton -> makeReturnDefault (TRUE); + ApHeadingDialogOkButton -> setCallback (ApHeadingDialog_OK); + + ApHeadingDialogCancelButton = new puOneShot (140, 10, 210, 50); + ApHeadingDialogCancelButton -> setLegend (gui_msg_CANCEL); + ApHeadingDialogCancelButton -> setCallback (ApHeadingDialog_Cancel); + + } + FG_FINALIZE_PUI_DIALOG( ApHeadingDialog ); +} + +void ApAltitudeDialog_Cancel(puObject *) +{ + ApAltitudeDialogInput -> rejectInput(); + FG_POP_PUI_DIALOG( ApAltitudeDialog ); +} + +void ApAltitudeDialog_OK (puObject *me) +{ + int error = 0; + string s; + char *c; + ApAltitudeDialogInput->getValue( &c ); + + if( strlen( c ) ) { + double NewAltitude; + if( scan_number( c, &NewAltitude) ) + { + if ( !current_autopilot->get_AltitudeEnabled() ) { + current_autopilot->set_AltitudeEnabled( true ); + } + current_autopilot->AltitudeSet( NewAltitude ); + } else { + error = 1; + s = c; + s += " is not a valid number."; + } + } + ApAltitudeDialog_Cancel(me); + if( error ) mkDialog(s.c_str()); +} + +void NewAltitude(puObject *cb) +{ + ApAltitudeDialogInput -> acceptInput(); + FG_PUSH_PUI_DIALOG( ApAltitudeDialog ); +} + +void NewAltitudeInit(void) +{ + // printf("NewAltitudeInit\n"); + char NewAltitudeLabel[] = "Enter New Altitude"; + char *s; + + float alt = cur_fdm_state->get_Altitude(); + + if ( current_options.get_units() == fgOPTIONS::FG_UNITS_METERS) { + alt *= FEET_TO_METER; + } + + int len = 260/2 - + (puGetStringWidth( puGetDefaultLabelFont(), NewAltitudeLabel )/2); + + // ApAltitudeDialog = new puDialogBox (150, 50); + ApAltitudeDialog = new puDialogBox (150, 200); + { + ApAltitudeDialogFrame = new puFrame (0, 0, 260, 150); + ApAltitudeDialogMessage = new puText (len, 110); + ApAltitudeDialogMessage -> setDefaultValue (NewAltitudeLabel); + ApAltitudeDialogMessage -> getDefaultValue (&s); + ApAltitudeDialogMessage -> setLabel (s); + + ApAltitudeDialogInput = new puInput ( 50, 70, 210, 100 ); + ApAltitudeDialogInput -> setValue ( alt ); + // Uncomment the next line to have input active on startup + // ApAltitudeDialogInput -> acceptInput ( ); + // cursor at begining or end of line ? + //len = strlen(s); + // len = 0; + // ApAltitudeDialogInput -> setCursor ( len ); + // ApAltitudeDialogInput -> setSelectRegion ( 5, 9 ); + + ApAltitudeDialogOkButton = new puOneShot (50, 10, 110, 50); + ApAltitudeDialogOkButton -> setLegend (gui_msg_OK); + ApAltitudeDialogOkButton -> makeReturnDefault (TRUE); + ApAltitudeDialogOkButton -> setCallback (ApAltitudeDialog_OK); + + ApAltitudeDialogCancelButton = new puOneShot (140, 10, 210, 50); + ApAltitudeDialogCancelButton -> setLegend (gui_msg_CANCEL); + ApAltitudeDialogCancelButton -> setCallback (ApAltitudeDialog_Cancel); + + } + FG_FINALIZE_PUI_DIALOG( ApAltitudeDialog ); +} + +/////// simple AutoPilot GAIN / LIMITS ADJUSTER + +#define fgAP_CLAMP(val,min,max) ( (val) = (val) > (max) ? (max) : (val) < (min) ? (min) : (val) ) + +static void maxroll_adj( puObject *hs ) { + float val ; + + hs-> getValue ( &val ) ; + fgAP_CLAMP ( val, 0.1, 1.0 ) ; + // printf ( "maxroll_adj( %p ) %f %f\n", hs, val, MaxRollAdjust * val ) ; + current_autopilot->set_MaxRoll( MaxRollAdjust * val ); + sprintf( SliderText[ 0 ], "%05.2f", current_autopilot->get_MaxRoll() ); + APAdjustMaxRollText -> setLabel ( SliderText[ 0 ] ) ; +} + +static void rollout_adj( puObject *hs ) { + float val ; + + hs-> getValue ( &val ) ; + fgAP_CLAMP ( val, 0.1, 1.0 ) ; + // printf ( "rollout_adj( %p ) %f %f\n", hs, val, RollOutAdjust * val ) ; + current_autopilot->set_RollOut( RollOutAdjust * val ); + sprintf( SliderText[ 1 ], "%05.2f", current_autopilot->get_RollOut() ); + APAdjustRollOutText -> setLabel ( SliderText[ 1 ] ); +} + +static void maxaileron_adj( puObject *hs ) { + float val ; + + hs-> getValue ( &val ) ; + fgAP_CLAMP ( val, 0.1, 1.0 ) ; + // printf ( "maxaileron_adj( %p ) %f %f\n", hs, val, MaxAileronAdjust * val ) ; + current_autopilot->set_MaxAileron( MaxAileronAdjust * val ); + sprintf( SliderText[ 3 ], "%05.2f", current_autopilot->get_MaxAileron() ); + APAdjustMaxAileronText -> setLabel ( SliderText[ 3 ] ); +} + +static void rolloutsmooth_adj( puObject *hs ) { + float val ; + + hs -> getValue ( &val ) ; + fgAP_CLAMP ( val, 0.1, 1.0 ) ; + // printf ( "rolloutsmooth_adj( %p ) %f %f\n", hs, val, RollOutSmoothAdjust * val ) ; + current_autopilot->set_RollOutSmooth( RollOutSmoothAdjust * val ); + sprintf( SliderText[ 2 ], "%5.2f", current_autopilot->get_RollOutSmooth() ); + APAdjustRollOutSmoothText-> setLabel ( SliderText[ 2 ] ); + +} + +static void goAwayAPAdjust (puObject *) +{ + FG_POP_PUI_DIALOG( APAdjustDialog ); +} + +void cancelAPAdjust( puObject *self ) { + current_autopilot->set_MaxRoll( TmpMaxRollValue ); + current_autopilot->set_RollOut( TmpRollOutValue ); + current_autopilot->set_MaxAileron( TmpMaxAileronValue ); + current_autopilot->set_RollOutSmooth( TmpRollOutSmoothValue ); + + goAwayAPAdjust(self); +} + +void resetAPAdjust( puObject *self ) { + current_autopilot->set_MaxRoll( MaxRollAdjust / 2 ); + current_autopilot->set_RollOut( RollOutAdjust / 2 ); + current_autopilot->set_MaxAileron( MaxAileronAdjust / 2 ); + current_autopilot->set_RollOutSmooth( RollOutSmoothAdjust / 2 ); + + FG_POP_PUI_DIALOG( APAdjustDialog ); + + fgAPAdjust( self ); +} + +void fgAPAdjust( puObject * ) { + TmpMaxRollValue = current_autopilot->get_MaxRoll(); + TmpRollOutValue = current_autopilot->get_RollOut(); + TmpMaxAileronValue = current_autopilot->get_MaxAileron(); + TmpRollOutSmoothValue = current_autopilot->get_RollOutSmooth(); + + MaxRollValue = current_autopilot->get_MaxRoll() / MaxRollAdjust; + RollOutValue = current_autopilot->get_RollOut() / RollOutAdjust; + MaxAileronValue = current_autopilot->get_MaxAileron() / MaxAileronAdjust; + RollOutSmoothValue = current_autopilot->get_RollOutSmooth() + / RollOutSmoothAdjust; + + APAdjustHS0-> setValue ( MaxRollValue ) ; + APAdjustHS1-> setValue ( RollOutValue ) ; + APAdjustHS2-> setValue ( RollOutSmoothValue ) ; + APAdjustHS3-> setValue ( MaxAileronValue ) ; + + FG_PUSH_PUI_DIALOG( APAdjustDialog ); +} + +// Done once at system initialization +void fgAPAdjustInit( void ) { + + // printf("fgAPAdjustInit\n"); +#define HORIZONTAL FALSE + + int DialogX = 40; + int DialogY = 100; + int DialogWidth = 230; + + char Label[] = "AutoPilot Adjust"; + char *s; + + int labelX = (DialogWidth / 2) - + (puGetStringWidth( puGetDefaultLabelFont(), Label ) / 2); + labelX -= 30; // KLUDGEY + + int nSliders = 4; + int slider_x = 10; + int slider_y = 55; + int slider_width = 210; + int slider_title_x = 15; + int slider_value_x = 160; + float slider_delta = 0.1f; + + TmpMaxRollValue = current_autopilot->get_MaxRoll(); + TmpRollOutValue = current_autopilot->get_RollOut(); + TmpMaxAileronValue = current_autopilot->get_MaxAileron(); + TmpRollOutSmoothValue = current_autopilot->get_RollOutSmooth(); + + MaxRollValue = current_autopilot->get_MaxRoll() / MaxRollAdjust; + RollOutValue = current_autopilot->get_RollOut() / RollOutAdjust; + MaxAileronValue = current_autopilot->get_MaxAileron() / MaxAileronAdjust; + RollOutSmoothValue = current_autopilot->get_RollOutSmooth() + / RollOutSmoothAdjust; + + puGetDefaultFonts ( &APAdjustLegendFont, &APAdjustLabelFont ); + APAdjustDialog = new puDialogBox ( DialogX, DialogY ); { + int horiz_slider_height = puGetStringHeight (APAdjustLabelFont) + + puGetStringDescender (APAdjustLabelFont) + + PUSTR_TGAP + PUSTR_BGAP + 5; + + APAdjustFrame = new puFrame ( 0, 0, + DialogWidth, + 85 + nSliders * horiz_slider_height ); + + APAdjustDialogMessage = new puText ( labelX, + 52 + nSliders + * horiz_slider_height ); + APAdjustDialogMessage -> setDefaultValue ( Label ); + APAdjustDialogMessage -> getDefaultValue ( &s ); + APAdjustDialogMessage -> setLabel ( s ); + + APAdjustHS0 = new mySlider ( slider_x, slider_y, + slider_width, HORIZONTAL ) ; + APAdjustHS0-> setDelta ( slider_delta ) ; + APAdjustHS0-> setValue ( MaxRollValue ) ; + APAdjustHS0-> setCBMode ( PUSLIDER_DELTA ) ; + APAdjustHS0-> setCallback ( maxroll_adj ) ; + + sprintf( SliderText[ 0 ], "%05.2f", current_autopilot->get_MaxRoll() ); + APAdjustMaxRollTitle = new puText ( slider_title_x, slider_y ) ; + APAdjustMaxRollTitle-> setDefaultValue ( "MaxRoll" ) ; + APAdjustMaxRollTitle-> getDefaultValue ( &s ) ; + APAdjustMaxRollTitle-> setLabel ( s ) ; + APAdjustMaxRollText = new puText ( slider_value_x, slider_y ) ; + APAdjustMaxRollText-> setLabel ( SliderText[ 0 ] ) ; + + slider_y += horiz_slider_height; + + APAdjustHS1 = new mySlider ( slider_x, slider_y, slider_width, + HORIZONTAL ) ; + APAdjustHS1-> setDelta ( slider_delta ) ; + APAdjustHS1-> setValue ( RollOutValue ) ; + APAdjustHS1-> setCBMode ( PUSLIDER_DELTA ) ; + APAdjustHS1-> setCallback ( rollout_adj ) ; + + sprintf( SliderText[ 1 ], "%05.2f", current_autopilot->get_RollOut() ); + APAdjustRollOutTitle = new puText ( slider_title_x, slider_y ) ; + APAdjustRollOutTitle-> setDefaultValue ( "AdjustRollOut" ) ; + APAdjustRollOutTitle-> getDefaultValue ( &s ) ; + APAdjustRollOutTitle-> setLabel ( s ) ; + APAdjustRollOutText = new puText ( slider_value_x, slider_y ) ; + APAdjustRollOutText-> setLabel ( SliderText[ 1 ] ); + + slider_y += horiz_slider_height; + + APAdjustHS2 = new mySlider ( slider_x, slider_y, slider_width, + HORIZONTAL ) ; + APAdjustHS2-> setDelta ( slider_delta ) ; + APAdjustHS2-> setValue ( RollOutSmoothValue ) ; + APAdjustHS2-> setCBMode ( PUSLIDER_DELTA ) ; + APAdjustHS2-> setCallback ( rolloutsmooth_adj ) ; + + sprintf( SliderText[ 2 ], "%5.2f", + current_autopilot->get_RollOutSmooth() ); + APAdjustRollOutSmoothTitle = new puText ( slider_title_x, slider_y ) ; + APAdjustRollOutSmoothTitle-> setDefaultValue ( "RollOutSmooth" ) ; + APAdjustRollOutSmoothTitle-> getDefaultValue ( &s ) ; + APAdjustRollOutSmoothTitle-> setLabel ( s ) ; + APAdjustRollOutSmoothText = new puText ( slider_value_x, slider_y ) ; + APAdjustRollOutSmoothText-> setLabel ( SliderText[ 2 ] ); + + slider_y += horiz_slider_height; + + APAdjustHS3 = new mySlider ( slider_x, slider_y, slider_width, + HORIZONTAL ) ; + APAdjustHS3-> setDelta ( slider_delta ) ; + APAdjustHS3-> setValue ( MaxAileronValue ) ; + APAdjustHS3-> setCBMode ( PUSLIDER_DELTA ) ; + APAdjustHS3-> setCallback ( maxaileron_adj ) ; + + sprintf( SliderText[ 3 ], "%05.2f", + current_autopilot->get_MaxAileron() ); + APAdjustMaxAileronTitle = new puText ( slider_title_x, slider_y ) ; + APAdjustMaxAileronTitle-> setDefaultValue ( "MaxAileron" ) ; + APAdjustMaxAileronTitle-> getDefaultValue ( &s ) ; + APAdjustMaxAileronTitle-> setLabel ( s ) ; + APAdjustMaxAileronText = new puText ( slider_value_x, slider_y ) ; + APAdjustMaxAileronText-> setLabel ( SliderText[ 3 ] ); + + APAdjustOkButton = new puOneShot ( 10, 10, 60, 50 ); + APAdjustOkButton-> setLegend ( gui_msg_OK ); + APAdjustOkButton-> makeReturnDefault ( TRUE ); + APAdjustOkButton-> setCallback ( goAwayAPAdjust ); + + APAdjustCancelButton = new puOneShot ( 70, 10, 150, 50 ); + APAdjustCancelButton-> setLegend ( gui_msg_CANCEL ); + APAdjustCancelButton-> setCallback ( cancelAPAdjust ); + + APAdjustResetButton = new puOneShot ( 160, 10, 220, 50 ); + APAdjustResetButton-> setLegend ( gui_msg_RESET ); + APAdjustResetButton-> setCallback ( resetAPAdjust ); + } + FG_FINALIZE_PUI_DIALOG( APAdjustDialog ); + +#undef HORIZONTAL +} + +// Simple Dialog to input Target Airport +void TgtAptDialog_Cancel(puObject *) +{ + FG_POP_PUI_DIALOG( TgtAptDialog ); +} + +void TgtAptDialog_OK (puObject *) +{ + string TgtAptId; + + // FGTime *t = FGTime::cur_time_params; + // int PauseMode = t->getPause(); + // if(!PauseMode) + // t->togglePauseMode(); + + char *s; + TgtAptDialogInput->getValue(&s); + TgtAptId = s; + + TgtAptDialog_Cancel( NULL ); + + if ( TgtAptId.length() ) { + // set initial position from TgtAirport id + + FGPath path( current_options.get_fg_root() ); + path.append( "Airports" ); + path.append( "simple.gdbm" ); + FGAirports airports( path.c_str() ); + FGAirport a; + + FG_LOG( FG_GENERAL, FG_INFO, + "Attempting to set starting position from airport code " + << s ); + + if ( airports.search( TgtAptId, &a ) ) + { + double course, reverse, distance; + // fgAPset_tgt_airport_id( TgtAptId.c_str() ); + current_options.set_airport_id( TgtAptId.c_str() ); + sprintf( NewTgtAirportId, "%s", TgtAptId.c_str() ); + + current_autopilot->set_TargetLatitude( a.latitude ); + current_autopilot->set_TargetLongitude( a.longitude ); + current_autopilot->MakeTargetLatLonStr( + current_autopilot->get_TargetLatitude(), + current_autopilot->get_TargetLongitude() ); + + current_autopilot->set_old_lat( FGBFI::getLatitude() ); + current_autopilot->set_old_lon( FGBFI::getLongitude() ); + + // need to test for iter + if( ! geo_inverse_wgs_84( FGBFI::getAltitude() * FEET_TO_METER, + FGBFI::getLatitude(), + FGBFI::getLongitude(), + current_autopilot->get_TargetLatitude(), + current_autopilot->get_TargetLongitude(), + &course, + &reverse, + &distance ) ) { + current_autopilot->set_TargetHeading( course ); + current_autopilot->MakeTargetHeadingStr( + current_autopilot->get_TargetHeading() ); + current_autopilot->set_TargetDistance( distance ); + current_autopilot->MakeTargetDistanceStr( distance ); + // This changes the AutoPilot Heading + // following cast needed + ApHeadingDialogInput-> + setValue((float)current_autopilot->get_TargetHeading() ); + // Force this ! + current_autopilot->set_HeadingEnabled( true ); + current_autopilot->set_HeadingMode( + FGAutopilot::FG_HEADING_WAYPOINT ); + } + } else { + TgtAptId += " not in database."; + mkDialog(TgtAptId.c_str()); + } + } + // get_control_values(); + // if( PauseMode != t->getPause() ) + // t->togglePauseMode(); +} + +void TgtAptDialog_Reset(puObject *) +{ + // strncpy( NewAirportId, current_options.get_airport_id().c_str(), 16 ); + sprintf( NewTgtAirportId, "%s", current_options.get_airport_id().c_str() ); + TgtAptDialogInput->setValue ( NewTgtAirportId ); + TgtAptDialogInput->setCursor( 0 ) ; +} + +void NewTgtAirport(puObject *cb) +{ + // strncpy( NewAirportId, current_options.get_airport_id().c_str(), 16 ); + sprintf( NewTgtAirportId, "%s", current_options.get_airport_id().c_str() ); + TgtAptDialogInput->setValue( NewTgtAirportId ); + + FG_PUSH_PUI_DIALOG( TgtAptDialog ); +} + +void NewTgtAirportInit(void) +{ + FG_LOG( FG_AUTOPILOT, FG_INFO, " enter NewTgtAirportInit()" ); + // fgAPset_tgt_airport_id( current_options.get_airport_id() ); + sprintf( NewTgtAirportId, "%s", current_options.get_airport_id().c_str() ); + FG_LOG( FG_AUTOPILOT, FG_INFO, " NewTgtAirportId " << NewTgtAirportId ); + // printf(" NewTgtAirportId %s\n", NewTgtAirportId); + int len = 150 - puGetStringWidth( puGetDefaultLabelFont(), + NewTgtAirportLabel ) / 2; + + TgtAptDialog = new puDialogBox (150, 50); + { + TgtAptDialogFrame = new puFrame (0,0,350, 150); + TgtAptDialogMessage = new puText (len, 110); + TgtAptDialogMessage -> setLabel (NewTgtAirportLabel); + + TgtAptDialogInput = new puInput (50, 70, 300, 100); + TgtAptDialogInput -> setValue (NewTgtAirportId); + TgtAptDialogInput -> acceptInput(); + + TgtAptDialogOkButton = new puOneShot (50, 10, 110, 50); + TgtAptDialogOkButton -> setLegend (gui_msg_OK); + TgtAptDialogOkButton -> setCallback (TgtAptDialog_OK); + TgtAptDialogOkButton -> makeReturnDefault(TRUE); + + TgtAptDialogCancelButton = new puOneShot (140, 10, 210, 50); + TgtAptDialogCancelButton -> setLegend (gui_msg_CANCEL); + TgtAptDialogCancelButton -> setCallback (TgtAptDialog_Cancel); + + TgtAptDialogResetButton = new puOneShot (240, 10, 300, 50); + TgtAptDialogResetButton -> setLegend (gui_msg_RESET); + TgtAptDialogResetButton -> setCallback (TgtAptDialog_Reset); + } + FG_FINALIZE_PUI_DIALOG( TgtAptDialog ); + printf("leave NewTgtAirportInit()"); +} diff --git a/src/Autopilot/auto_gui.hxx b/src/Autopilot/auto_gui.hxx new file mode 100644 index 000000000..5de09364e --- /dev/null +++ b/src/Autopilot/auto_gui.hxx @@ -0,0 +1,94 @@ +// auto_gui.hxx -- autopilot gui interface +// +// Written by Norman Vine <nhv@cape.com> +// Arranged by Curt Olson <curt@flightgear.org> +// +// Copyright (C) 1998 - 2000 +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// +// $Id$ + + +#ifndef _AUTO_GUI_HXX +#define _AUTO_GUI_HXX + +#include <simgear/compiler.h> + +#include STL_STRING + +#include <string.h> + +#include <Aircraft/aircraft.hxx> +#include <FDM/flight.hxx> +#include <Controls/controls.hxx> + +FG_USING_STD(string); + + +// Defines +#define AP_CURRENT_HEADING -1 + + +// prototypes +// void fgAPToggleWayPoint( void ); +// void fgAPToggleHeading( void ); +// void fgAPToggleAltitude( void ); +// void fgAPToggleTerrainFollow( void ); +// void fgAPToggleAutoThrottle( void ); + +// bool fgAPTerrainFollowEnabled( void ); +// bool fgAPAltitudeEnabled( void ); +// bool fgAPHeadingEnabled( void ); +// bool fgAPWayPointEnabled( void ); +// bool fgAPAutoThrottleEnabled( void ); + +// void fgAPAltitudeAdjust( double inc ); +// void fgAPHeadingAdjust( double inc ); +// void fgAPAutoThrottleAdjust( double inc ); + +// void fgAPHeadingSet( double value ); + +// double fgAPget_TargetLatitude( void ); +// double fgAPget_TargetLongitude( void ); +// // double fgAPget_TargetHeading( void ); +// double fgAPget_TargetDistance( void ); +// double fgAPget_TargetAltitude( void ); + +// char *fgAPget_TargetLatitudeStr( void ); +// char *fgAPget_TargetLongitudeStr( void ); +// char *fgAPget_TargetDistanceStr( void ); +// char *fgAPget_TargetHeadingStr( void ); +// char *fgAPget_TargetAltitudeStr( void ); +// char *fgAPget_TargetLatLonStr( void ); + +//void fgAPset_tgt_airport_id( const string ); +//string fgAPget_tgt_airport_id( void ); + +// void fgAPReset(void); + +class puObject; +void fgAPAdjust( puObject * ); +void NewHeading(puObject *cb); +void NewAltitude(puObject *cb); +void NewTgtAirport(puObject *cb); + +void NewTgtAirportInit(); +void fgAPAdjustInit() ; +void NewHeadingInit(); +void NewAltitudeInit(); + + +#endif // _AUTO_GUI_HXX diff --git a/src/Autopilot/autopilot.cxx b/src/Autopilot/autopilot.cxx deleted file mode 100644 index 4d473ef2f..000000000 --- a/src/Autopilot/autopilot.cxx +++ /dev/null @@ -1,1710 +0,0 @@ -// autopilot.cxx -- autopilot subsystem -// -// Started by Jeff Goeke-Smith, started April 1998. -// -// Copyright (C) 1998 Jeff Goeke-Smith, jgoeke@voyager.net -// -// Heavy modifications and additions by Norman Vine and few by Curtis -// Olson -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, but -// WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -// -// $Id$ - - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include <assert.h> -#include <stdlib.h> - -#include <Scenery/scenery.hxx> - -#include <simgear/constants.h> -#include <simgear/debug/logstream.hxx> -#include <simgear/misc/fgpath.hxx> - -#include <Airports/simple.hxx> -#include <GUI/gui.h> -#include <Main/fg_init.hxx> -#include <Main/options.hxx> -#include <Time/fg_time.hxx> - -#include "autopilot.hxx" - - -#define mySlider puSlider - -// Climb speed constants -const double min_climb = 70.0; // kts -const double best_climb = 75.0; // kts -const double ideal_climb_rate = 500.0; // fpm - -/// These statics will eventually go into the class -/// they are just here while I am experimenting -- NHV :-) -// AutoPilot Gain Adjuster members -static double MaxRollAdjust; // MaxRollAdjust = 2 * APData->MaxRoll; -static double RollOutAdjust; // RollOutAdjust = 2 * APData->RollOut; -static double MaxAileronAdjust; // MaxAileronAdjust = 2 * APData->MaxAileron; -static double RollOutSmoothAdjust; // RollOutSmoothAdjust = 2 * APData->RollOutSmooth; - -static float MaxRollValue; // 0.1 -> 1.0 -static float RollOutValue; -static float MaxAileronValue; -static float RollOutSmoothValue; - -static float TmpMaxRollValue; // for cancel operation -static float TmpRollOutValue; -static float TmpMaxAileronValue; -static float TmpRollOutSmoothValue; - -static puDialogBox *APAdjustDialog; -static puFrame *APAdjustFrame; -static puText *APAdjustDialogMessage; -static puFont APAdjustLegendFont; -static puFont APAdjustLabelFont; - -static puOneShot *APAdjustOkButton; -static puOneShot *APAdjustResetButton; -static puOneShot *APAdjustCancelButton; - -//static puButton *APAdjustDragButton; - -static puText *APAdjustMaxRollTitle; -static puText *APAdjustRollOutTitle; -static puText *APAdjustMaxAileronTitle; -static puText *APAdjustRollOutSmoothTitle; - -static puText *APAdjustMaxAileronText; -static puText *APAdjustMaxRollText; -static puText *APAdjustRollOutText; -static puText *APAdjustRollOutSmoothText; - -static mySlider *APAdjustHS0; -static mySlider *APAdjustHS1; -static mySlider *APAdjustHS2; -static mySlider *APAdjustHS3; - -static char SliderText[ 4 ][ 8 ]; - -///////// AutoPilot New Heading Dialog - -static puDialogBox *ApHeadingDialog; -static puFrame *ApHeadingDialogFrame; -static puText *ApHeadingDialogMessage; -static puInput *ApHeadingDialogInput; -static puOneShot *ApHeadingDialogOkButton; -static puOneShot *ApHeadingDialogCancelButton; - - -///////// AutoPilot New Altitude Dialog - -static puDialogBox *ApAltitudeDialog = 0; -static puFrame *ApAltitudeDialogFrame = 0; -static puText *ApAltitudeDialogMessage = 0; -static puInput *ApAltitudeDialogInput = 0; - -static puOneShot *ApAltitudeDialogOkButton = 0; -static puOneShot *ApAltitudeDialogCancelButton = 0; - - -/// The beginnings of Lock AutoPilot to target location :-) -// Needs cleaning up but works -// These statics should disapear when this is a class -static puDialogBox *TgtAptDialog = 0; -static puFrame *TgtAptDialogFrame = 0; -static puText *TgtAptDialogMessage = 0; -static puInput *TgtAptDialogInput = 0; - -static char NewTgtAirportId[16]; -static char NewTgtAirportLabel[] = "Enter New TgtAirport ID"; - -static puOneShot *TgtAptDialogOkButton = 0; -static puOneShot *TgtAptDialogCancelButton = 0; -static puOneShot *TgtAptDialogResetButton = 0; - - -// global variable holding the AP info -// I want this gone. Data should be in aircraft structure -fgAPDataPtr APDataGlobal; - -// Local Prototype section -static double LinearExtrapolate( double x, double x1, double y1, double x2, double y2 ); -static double NormalizeDegrees( double Input ); -// End Local ProtoTypes - -extern char *coord_format_lat(float); -extern char *coord_format_lon(float); - - -static inline double get_ground_speed( void ) { - // starts in ft/s so we convert to kts - double ft_s = cur_fdm_state->get_V_ground_speed() - * current_options.get_speed_up();; - double kts = ft_s * FEET_TO_METER * 3600 * METER_TO_NM; - return kts; -} - -// The below routines were copied right from hud.c ( I hate reinventing -// the wheel more than necessary) - -// The following routines obtain information concerntin the aircraft's -// current state and return it to calling instrument display routines. -// They should eventually be member functions of the aircraft. -// -static void get_control_values( void ) { - fgAPDataPtr APData; - APData = APDataGlobal; - APData->old_aileron = controls.get_aileron(); - APData->old_elevator = controls.get_elevator(); - APData->old_elevator_trim = controls.get_elevator_trim(); - APData->old_rudder = controls.get_rudder(); -} - -static void MakeTargetHeadingStr( fgAPDataPtr APData, double bearing ) { - if( bearing < 0. ) - bearing += 360.; - else if(bearing > 360. ) - bearing -= 360.; - sprintf(APData->TargetHeadingStr, "APHeading %6.1f", bearing); -} - -static inline void MakeTargetDistanceStr( fgAPDataPtr APData, double distance ) { - double eta = distance*METER_TO_NM / get_ground_speed(); - if ( eta >= 100.0 ) { eta = 99.999; } - int major, minor; - if ( eta < (1.0/6.0) ) { - // within 10 minutes, bump up to min/secs - eta *= 60.0; - } - major = (int)eta; - minor = (int)((eta - (int)eta) * 60.0); - sprintf(APData->TargetDistanceStr, "APDistance %.2f NM ETA %d:%02d", - distance*METER_TO_NM, major, minor); - // cout << "distance = " << distance*METER_TO_NM - // << " gndsp = " << get_ground_speed() - // << " time = " << eta - // << " major = " << major - // << " minor = " << minor - // << endl; -} - -static inline void MakeTargetAltitudeStr( fgAPDataPtr APData, double altitude ) { - sprintf(APData->TargetAltitudeStr, "APAltitude %6.0f", altitude); -} - -static inline void MakeTargetLatLonStr( fgAPDataPtr APData, double lat, double lon ) { - float tmp; - tmp = APData->TargetLatitude; - sprintf( APData->TargetLatitudeStr , "%s", coord_format_lat(tmp) ); - tmp = APData->TargetLongitude; - sprintf( APData->TargetLongitudeStr, "%s", coord_format_lon(tmp) ); - - sprintf(APData->TargetLatLonStr, "%s %s", - APData->TargetLatitudeStr, - APData->TargetLongitudeStr ); -} - -static inline double get_speed( void ) { - return( cur_fdm_state->get_V_equiv_kts() ); -} - -static inline double get_aoa( void ) { - return( cur_fdm_state->get_Gamma_vert_rad() * RAD_TO_DEG ); -} - -static inline double fgAPget_latitude( void ) { - return( cur_fdm_state->get_Latitude() * RAD_TO_DEG ); -} - -static inline double fgAPget_longitude( void ) { - return( cur_fdm_state->get_Longitude() * RAD_TO_DEG ); -} - -static inline double fgAPget_roll( void ) { - return( cur_fdm_state->get_Phi() * RAD_TO_DEG ); -} - -static inline double get_pitch( void ) { - return( cur_fdm_state->get_Theta() ); -} - -double fgAPget_heading( void ) { - return( cur_fdm_state->get_Psi() * RAD_TO_DEG ); -} - -static inline double fgAPget_altitude( void ) { - return( cur_fdm_state->get_Altitude() * FEET_TO_METER ); -} - -static inline double fgAPget_climb( void ) { - // return in meters per minute - return( cur_fdm_state->get_Climb_Rate() * FEET_TO_METER * 60 ); -} - -static inline double get_sideslip( void ) { - return( cur_fdm_state->get_Beta() ); -} - -static inline double fgAPget_agl( void ) { - double agl; - - agl = cur_fdm_state->get_Altitude() * FEET_TO_METER - - scenery.cur_elev; - - return( agl ); -} - -// End of copied section. ( thanks for the wheel :-) -double fgAPget_TargetLatitude( void ) { - fgAPDataPtr APData = APDataGlobal; - return APData->TargetLatitude; -} - -double fgAPget_TargetLongitude( void ) { - fgAPDataPtr APData = APDataGlobal; - return APData->TargetLongitude; -} - -double fgAPget_TargetHeading( void ) { - fgAPDataPtr APData = APDataGlobal; - return APData->TargetHeading; -} - -double fgAPget_TargetDistance( void ) { - fgAPDataPtr APData = APDataGlobal; - return APData->TargetDistance; -} - -double fgAPget_TargetAltitude( void ) { - fgAPDataPtr APData = APDataGlobal; - return APData->TargetAltitude; -} - -char *fgAPget_TargetLatitudeStr( void ) { - fgAPDataPtr APData = APDataGlobal; - return APData->TargetLatitudeStr; -} - -char *fgAPget_TargetLongitudeStr( void ) { - fgAPDataPtr APData = APDataGlobal; - return APData->TargetLongitudeStr; -} - -char *fgAPget_TargetDistanceStr( void ) { - fgAPDataPtr APData = APDataGlobal; - return APData->TargetDistanceStr; -} - -char *fgAPget_TargetHeadingStr( void ) { - fgAPDataPtr APData = APDataGlobal; - return APData->TargetHeadingStr; -} - -char *fgAPget_TargetAltitudeStr( void ) { - fgAPDataPtr APData = APDataGlobal; - return APData->TargetAltitudeStr; -} - -char *fgAPget_TargetLatLonStr( void ) { - fgAPDataPtr APData = APDataGlobal; - return APData->TargetLatLonStr; -} - -bool fgAPWayPointEnabled( void ) -{ - fgAPDataPtr APData; - - APData = APDataGlobal; - - // heading hold enabled? - return APData->waypoint_hold; -} - - -bool fgAPHeadingEnabled( void ) -{ - fgAPDataPtr APData; - - APData = APDataGlobal; - - // heading hold enabled? - return APData->heading_hold; -} - -bool fgAPAltitudeEnabled( void ) -{ - fgAPDataPtr APData; - - APData = APDataGlobal; - - // altitude hold or terrain follow enabled? - return APData->altitude_hold; -} - -bool fgAPTerrainFollowEnabled( void ) -{ - fgAPDataPtr APData; - - APData = APDataGlobal; - - // altitude hold or terrain follow enabled? - return APData->terrain_follow ; -} - -bool fgAPAutoThrottleEnabled( void ) -{ - fgAPDataPtr APData; - - APData = APDataGlobal; - - // autothrottle enabled? - return APData->auto_throttle; -} - -void fgAPAltitudeAdjust( double inc ) -{ - // Remove at a later date - fgAPDataPtr APData = APDataGlobal; - // end section - - double target_alt, target_agl; - - if ( current_options.get_units() == fgOPTIONS::FG_UNITS_FEET ) { - target_alt = APData->TargetAltitude * METER_TO_FEET; - target_agl = APData->TargetAGL * METER_TO_FEET; - } else { - target_alt = APData->TargetAltitude; - target_agl = APData->TargetAGL; - } - - target_alt = ( int ) ( target_alt / inc ) * inc + inc; - target_agl = ( int ) ( target_agl / inc ) * inc + inc; - - if ( current_options.get_units() == fgOPTIONS::FG_UNITS_FEET ) { - target_alt *= FEET_TO_METER; - target_agl *= FEET_TO_METER; - } - - APData->TargetAltitude = target_alt; - APData->TargetAGL = target_agl; - - if ( current_options.get_units() == fgOPTIONS::FG_UNITS_FEET ) - target_alt *= METER_TO_FEET; - ApAltitudeDialogInput->setValue((float)target_alt); - MakeTargetAltitudeStr( APData, target_alt); - - get_control_values(); -} - -void fgAPAltitudeSet( double new_altitude ) { - // Remove at a later date - fgAPDataPtr APData = APDataGlobal; - // end section - double target_alt = new_altitude; - - if ( current_options.get_units() == fgOPTIONS::FG_UNITS_FEET ) - target_alt = new_altitude * FEET_TO_METER; - - if( target_alt < scenery.cur_elev ) - target_alt = scenery.cur_elev; - - APData->TargetAltitude = target_alt; - - if ( current_options.get_units() == fgOPTIONS::FG_UNITS_FEET ) - target_alt *= METER_TO_FEET; - ApAltitudeDialogInput->setValue((float)target_alt); - MakeTargetAltitudeStr( APData, target_alt); - - get_control_values(); -} - -void fgAPHeadingAdjust( double inc ) { - fgAPDataPtr APData = APDataGlobal; - - if ( APData->waypoint_hold ) - APData->waypoint_hold = false; - - double target = ( int ) ( APData->TargetHeading / inc ) * inc + inc; - - APData->TargetHeading = NormalizeDegrees( target ); - // following cast needed ambiguous plib - ApHeadingDialogInput -> setValue ((float)APData->TargetHeading ); - MakeTargetHeadingStr( APData, APData->TargetHeading ); - get_control_values(); -} - -void fgAPHeadingSet( double new_heading ) { - fgAPDataPtr APData = APDataGlobal; - - if ( APData->waypoint_hold ) - APData->waypoint_hold = false; - - new_heading = NormalizeDegrees( new_heading ); - APData->TargetHeading = new_heading; - // following cast needed ambiguous plib - ApHeadingDialogInput -> setValue ((float)APData->TargetHeading ); - MakeTargetHeadingStr( APData, APData->TargetHeading ); - get_control_values(); -} - -void fgAPAutoThrottleAdjust( double inc ) { - fgAPDataPtr APData = APDataGlobal; - - double target = ( int ) ( APData->TargetSpeed / inc ) * inc + inc; - - APData->TargetSpeed = target; -} - -// THIS NEEDS IMPROVEMENT !!!!!!!!!!!!! -static int scan_number(char *s, double *new_value) -{ - int ret = 0; - char WordBuf[64]; - char *cptr = s; - char *WordBufPtr = WordBuf; - - if (*cptr == '+') - cptr++; - if (*cptr == '-') { - *WordBufPtr++ = *cptr++; - } - while (isdigit(*cptr) ) { - *WordBufPtr++ = *cptr++; - ret = 1; - } - if (*cptr == '.') - *WordBufPtr++ = *cptr++; // put the '.' into the string - while (isdigit(*cptr)) { - *WordBufPtr++ = *cptr++; - ret = 1; - } - if( ret == 1 ) { - *WordBufPtr = '\0'; - sscanf(WordBuf, "%lf", new_value); - } - - return(ret); -} // scan_number - - -void ApHeadingDialog_Cancel(puObject *) -{ - ApHeadingDialogInput->rejectInput(); - FG_POP_PUI_DIALOG( ApHeadingDialog ); -} - -void ApHeadingDialog_OK (puObject *me) -{ - int error = 0; - char *c; - string s; - ApHeadingDialogInput -> getValue( &c ); - - if( strlen(c) ) { - double NewHeading; - if( scan_number( c, &NewHeading ) ) - { - if(!fgAPHeadingEnabled()) - fgAPToggleHeading(); - fgAPHeadingSet( NewHeading ); - } else { - error = 1; - s = c; - s += " is not a valid number."; - } - } - ApHeadingDialog_Cancel(me); - if( error ) mkDialog(s.c_str()); -} - -void NewHeading(puObject *cb) -{ - // string ApHeadingLabel( "Enter New Heading" ); - // ApHeadingDialogMessage -> setLabel(ApHeadingLabel.c_str()); - ApHeadingDialogInput -> acceptInput(); - FG_PUSH_PUI_DIALOG( ApHeadingDialog ); -} - -void NewHeadingInit(void) -{ - // printf("NewHeadingInit\n"); - char NewHeadingLabel[] = "Enter New Heading"; - char *s; - - float heading = fgAPget_heading(); - int len = 260/2 - - (puGetStringWidth( puGetDefaultLabelFont(), NewHeadingLabel ) /2 ); - - ApHeadingDialog = new puDialogBox (150, 50); - { - ApHeadingDialogFrame = new puFrame (0, 0, 260, 150); - - ApHeadingDialogMessage = new puText (len, 110); - ApHeadingDialogMessage -> setDefaultValue (NewHeadingLabel); - ApHeadingDialogMessage -> getDefaultValue (&s); - ApHeadingDialogMessage -> setLabel (s); - - ApHeadingDialogInput = new puInput ( 50, 70, 210, 100 ); - ApHeadingDialogInput -> setValue ( heading ); - - ApHeadingDialogOkButton = new puOneShot (50, 10, 110, 50); - ApHeadingDialogOkButton -> setLegend (gui_msg_OK); - ApHeadingDialogOkButton -> makeReturnDefault (TRUE); - ApHeadingDialogOkButton -> setCallback (ApHeadingDialog_OK); - - ApHeadingDialogCancelButton = new puOneShot (140, 10, 210, 50); - ApHeadingDialogCancelButton -> setLegend (gui_msg_CANCEL); - ApHeadingDialogCancelButton -> setCallback (ApHeadingDialog_Cancel); - - } - FG_FINALIZE_PUI_DIALOG( ApHeadingDialog ); -} - -void ApAltitudeDialog_Cancel(puObject *) -{ - ApAltitudeDialogInput -> rejectInput(); - FG_POP_PUI_DIALOG( ApAltitudeDialog ); -} - -void ApAltitudeDialog_OK (puObject *me) -{ - int error = 0; - string s; - char *c; - ApAltitudeDialogInput->getValue( &c ); - - if( strlen( c ) ) { - double NewAltitude; - if( scan_number( c, &NewAltitude) ) - { - if(!(fgAPAltitudeEnabled())) - fgAPToggleAltitude(); - fgAPAltitudeSet( NewAltitude ); - } else { - error = 1; - s = c; - s += " is not a valid number."; - } - } - ApAltitudeDialog_Cancel(me); - if( error ) mkDialog(s.c_str()); - get_control_values(); -} - -void NewAltitude(puObject *cb) -{ - ApAltitudeDialogInput -> acceptInput(); - FG_PUSH_PUI_DIALOG( ApAltitudeDialog ); -} - -void NewAltitudeInit(void) -{ - // printf("NewAltitudeInit\n"); - char NewAltitudeLabel[] = "Enter New Altitude"; - char *s; - - float alt = cur_fdm_state->get_Altitude(); - - if ( current_options.get_units() == fgOPTIONS::FG_UNITS_METERS) { - alt *= FEET_TO_METER; - } - - int len = 260/2 - - (puGetStringWidth( puGetDefaultLabelFont(), NewAltitudeLabel )/2); - - // ApAltitudeDialog = new puDialogBox (150, 50); - ApAltitudeDialog = new puDialogBox (150, 200); - { - ApAltitudeDialogFrame = new puFrame (0, 0, 260, 150); - ApAltitudeDialogMessage = new puText (len, 110); - ApAltitudeDialogMessage -> setDefaultValue (NewAltitudeLabel); - ApAltitudeDialogMessage -> getDefaultValue (&s); - ApAltitudeDialogMessage -> setLabel (s); - - ApAltitudeDialogInput = new puInput ( 50, 70, 210, 100 ); - ApAltitudeDialogInput -> setValue ( alt ); - // Uncomment the next line to have input active on startup - // ApAltitudeDialogInput -> acceptInput ( ); - // cursor at begining or end of line ? - //len = strlen(s); - // len = 0; - // ApAltitudeDialogInput -> setCursor ( len ); - // ApAltitudeDialogInput -> setSelectRegion ( 5, 9 ); - - ApAltitudeDialogOkButton = new puOneShot (50, 10, 110, 50); - ApAltitudeDialogOkButton -> setLegend (gui_msg_OK); - ApAltitudeDialogOkButton -> makeReturnDefault (TRUE); - ApAltitudeDialogOkButton -> setCallback (ApAltitudeDialog_OK); - - ApAltitudeDialogCancelButton = new puOneShot (140, 10, 210, 50); - ApAltitudeDialogCancelButton -> setLegend (gui_msg_CANCEL); - ApAltitudeDialogCancelButton -> setCallback (ApAltitudeDialog_Cancel); - - } - FG_FINALIZE_PUI_DIALOG( ApAltitudeDialog ); -} - -/////// simple AutoPilot GAIN / LIMITS ADJUSTER - -#define fgAP_CLAMP(val,min,max) \ -( (val) = (val) > (max) ? (max) : (val) < (min) ? (min) : (val) ) - - static void maxroll_adj( puObject *hs ) { - float val ; - fgAPDataPtr APData = APDataGlobal; - - hs-> getValue ( &val ) ; - fgAP_CLAMP ( val, 0.1, 1.0 ) ; - // printf ( "maxroll_adj( %p ) %f %f\n", hs, val, MaxRollAdjust * val ) ; - APData-> MaxRoll = MaxRollAdjust * val; - sprintf( SliderText[ 0 ], "%05.2f", APData->MaxRoll ); - APAdjustMaxRollText -> setLabel ( SliderText[ 0 ] ) ; -} - -static void rollout_adj( puObject *hs ) { - float val ; - fgAPDataPtr APData = APDataGlobal; - - hs-> getValue ( &val ) ; - fgAP_CLAMP ( val, 0.1, 1.0 ) ; - // printf ( "rollout_adj( %p ) %f %f\n", hs, val, RollOutAdjust * val ) ; - APData-> RollOut = RollOutAdjust * val; - sprintf( SliderText[ 1 ], "%05.2f", APData->RollOut ); - APAdjustRollOutText -> setLabel ( SliderText[ 1 ] ); -} - -static void maxaileron_adj( puObject *hs ) { - float val ; - fgAPDataPtr APData; - APData = APDataGlobal; - - hs-> getValue ( &val ) ; - fgAP_CLAMP ( val, 0.1, 1.0 ) ; - // printf ( "maxaileron_adj( %p ) %f %f\n", hs, val, MaxAileronAdjust * val ) ; - APData-> MaxAileron = MaxAileronAdjust * val; - sprintf( SliderText[ 3 ], "%05.2f", APData->MaxAileron ); - APAdjustMaxAileronText -> setLabel ( SliderText[ 3 ] ); -} - -static void rolloutsmooth_adj( puObject *hs ) { - float val ; - fgAPDataPtr APData = APDataGlobal; - - hs -> getValue ( &val ) ; - fgAP_CLAMP ( val, 0.1, 1.0 ) ; - // printf ( "rolloutsmooth_adj( %p ) %f %f\n", hs, val, RollOutSmoothAdjust * val ) ; - APData->RollOutSmooth = RollOutSmoothAdjust * val; - sprintf( SliderText[ 2 ], "%5.2f", APData-> RollOutSmooth ); - APAdjustRollOutSmoothText-> setLabel ( SliderText[ 2 ] ); - -} - -static void goAwayAPAdjust (puObject *) -{ - FG_POP_PUI_DIALOG( APAdjustDialog ); -} - -void cancelAPAdjust( puObject *self ) { - fgAPDataPtr APData = APDataGlobal; - - APData-> MaxRoll = TmpMaxRollValue; - APData-> RollOut = TmpRollOutValue; - APData-> MaxAileron = TmpMaxAileronValue; - APData-> RollOutSmooth = TmpRollOutSmoothValue; - - goAwayAPAdjust(self); -} - -void resetAPAdjust( puObject *self ) { - fgAPDataPtr APData = APDataGlobal; - - APData-> MaxRoll = MaxRollAdjust / 2; - APData-> RollOut = RollOutAdjust / 2; - APData-> MaxAileron = MaxAileronAdjust / 2; - APData-> RollOutSmooth = RollOutSmoothAdjust / 2; - - FG_POP_PUI_DIALOG( APAdjustDialog ); - - fgAPAdjust( self ); -} - -void fgAPAdjust( puObject * ) { - fgAPDataPtr APData = APDataGlobal; - - TmpMaxRollValue = APData-> MaxRoll; - TmpRollOutValue = APData-> RollOut; - TmpMaxAileronValue = APData-> MaxAileron; - TmpRollOutSmoothValue = APData-> RollOutSmooth; - - MaxRollValue = APData-> MaxRoll / MaxRollAdjust; - RollOutValue = APData-> RollOut / RollOutAdjust; - MaxAileronValue = APData-> MaxAileron / MaxAileronAdjust; - RollOutSmoothValue = APData-> RollOutSmooth / RollOutSmoothAdjust; - - APAdjustHS0-> setValue ( MaxRollValue ) ; - APAdjustHS1-> setValue ( RollOutValue ) ; - APAdjustHS2-> setValue ( RollOutSmoothValue ) ; - APAdjustHS3-> setValue ( MaxAileronValue ) ; - - FG_PUSH_PUI_DIALOG( APAdjustDialog ); -} - -// Done once at system initialization -void fgAPAdjustInit( void ) { - - // printf("fgAPAdjustInit\n"); -#define HORIZONTAL FALSE - - int DialogX = 40; - int DialogY = 100; - int DialogWidth = 230; - - char Label[] = "AutoPilot Adjust"; - char *s; - - fgAPDataPtr APData = APDataGlobal; - - int labelX = (DialogWidth / 2) - - (puGetStringWidth( puGetDefaultLabelFont(), Label ) / 2); - labelX -= 30; // KLUDGEY - - int nSliders = 4; - int slider_x = 10; - int slider_y = 55; - int slider_width = 210; - int slider_title_x = 15; - int slider_value_x = 160; - float slider_delta = 0.1f; - - TmpMaxRollValue = APData-> MaxRoll; - TmpRollOutValue = APData-> RollOut; - TmpMaxAileronValue = APData-> MaxAileron; - TmpRollOutSmoothValue = APData-> RollOutSmooth; - - MaxRollValue = APData-> MaxRoll / MaxRollAdjust; - RollOutValue = APData-> RollOut / RollOutAdjust; - MaxAileronValue = APData-> MaxAileron / MaxAileronAdjust; - RollOutSmoothValue = APData-> RollOutSmooth / RollOutSmoothAdjust; - - puGetDefaultFonts ( &APAdjustLegendFont, &APAdjustLabelFont ); - APAdjustDialog = new puDialogBox ( DialogX, DialogY ); { - int horiz_slider_height = puGetStringHeight (APAdjustLabelFont) + - puGetStringDescender (APAdjustLabelFont) + - PUSTR_TGAP + PUSTR_BGAP + 5; - - APAdjustFrame = new puFrame ( 0, 0, - DialogWidth, 85 + nSliders * horiz_slider_height ); - - APAdjustDialogMessage = new puText ( labelX, 52 + nSliders * horiz_slider_height ); - APAdjustDialogMessage -> setDefaultValue ( Label ); - APAdjustDialogMessage -> getDefaultValue ( &s ); - APAdjustDialogMessage -> setLabel ( s ); - - APAdjustHS0 = new mySlider ( slider_x, slider_y, slider_width, HORIZONTAL ) ; - APAdjustHS0-> setDelta ( slider_delta ) ; - APAdjustHS0-> setValue ( MaxRollValue ) ; - APAdjustHS0-> setCBMode ( PUSLIDER_DELTA ) ; - APAdjustHS0-> setCallback ( maxroll_adj ) ; - - sprintf( SliderText[ 0 ], "%05.2f", APData->MaxRoll ); - APAdjustMaxRollTitle = new puText ( slider_title_x, slider_y ) ; - APAdjustMaxRollTitle-> setDefaultValue ( "MaxRoll" ) ; - APAdjustMaxRollTitle-> getDefaultValue ( &s ) ; - APAdjustMaxRollTitle-> setLabel ( s ) ; - APAdjustMaxRollText = new puText ( slider_value_x, slider_y ) ; - APAdjustMaxRollText-> setLabel ( SliderText[ 0 ] ) ; - - slider_y += horiz_slider_height; - - APAdjustHS1 = new mySlider ( slider_x, slider_y, slider_width, HORIZONTAL ) ; - APAdjustHS1-> setDelta ( slider_delta ) ; - APAdjustHS1-> setValue ( RollOutValue ) ; - APAdjustHS1-> setCBMode ( PUSLIDER_DELTA ) ; - APAdjustHS1-> setCallback ( rollout_adj ) ; - - sprintf( SliderText[ 1 ], "%05.2f", APData->RollOut ); - APAdjustRollOutTitle = new puText ( slider_title_x, slider_y ) ; - APAdjustRollOutTitle-> setDefaultValue ( "AdjustRollOut" ) ; - APAdjustRollOutTitle-> getDefaultValue ( &s ) ; - APAdjustRollOutTitle-> setLabel ( s ) ; - APAdjustRollOutText = new puText ( slider_value_x, slider_y ) ; - APAdjustRollOutText-> setLabel ( SliderText[ 1 ] ); - - slider_y += horiz_slider_height; - - APAdjustHS2 = new mySlider ( slider_x, slider_y, slider_width, HORIZONTAL ) ; - APAdjustHS2-> setDelta ( slider_delta ) ; - APAdjustHS2-> setValue ( RollOutSmoothValue ) ; - APAdjustHS2-> setCBMode ( PUSLIDER_DELTA ) ; - APAdjustHS2-> setCallback ( rolloutsmooth_adj ) ; - - sprintf( SliderText[ 2 ], "%5.2f", APData->RollOutSmooth ); - APAdjustRollOutSmoothTitle = new puText ( slider_title_x, slider_y ) ; - APAdjustRollOutSmoothTitle-> setDefaultValue ( "RollOutSmooth" ) ; - APAdjustRollOutSmoothTitle-> getDefaultValue ( &s ) ; - APAdjustRollOutSmoothTitle-> setLabel ( s ) ; - APAdjustRollOutSmoothText = new puText ( slider_value_x, slider_y ) ; - APAdjustRollOutSmoothText-> setLabel ( SliderText[ 2 ] ); - - slider_y += horiz_slider_height; - - APAdjustHS3 = new mySlider ( slider_x, slider_y, slider_width, HORIZONTAL ) ; - APAdjustHS3-> setDelta ( slider_delta ) ; - APAdjustHS3-> setValue ( MaxAileronValue ) ; - APAdjustHS3-> setCBMode ( PUSLIDER_DELTA ) ; - APAdjustHS3-> setCallback ( maxaileron_adj ) ; - - sprintf( SliderText[ 3 ], "%05.2f", APData->MaxAileron ); - APAdjustMaxAileronTitle = new puText ( slider_title_x, slider_y ) ; - APAdjustMaxAileronTitle-> setDefaultValue ( "MaxAileron" ) ; - APAdjustMaxAileronTitle-> getDefaultValue ( &s ) ; - APAdjustMaxAileronTitle-> setLabel ( s ) ; - APAdjustMaxAileronText = new puText ( slider_value_x, slider_y ) ; - APAdjustMaxAileronText-> setLabel ( SliderText[ 3 ] ); - - APAdjustOkButton = new puOneShot ( 10, 10, 60, 50 ); - APAdjustOkButton-> setLegend ( gui_msg_OK ); - APAdjustOkButton-> makeReturnDefault ( TRUE ); - APAdjustOkButton-> setCallback ( goAwayAPAdjust ); - - APAdjustCancelButton = new puOneShot ( 70, 10, 150, 50 ); - APAdjustCancelButton-> setLegend ( gui_msg_CANCEL ); - APAdjustCancelButton-> setCallback ( cancelAPAdjust ); - - APAdjustResetButton = new puOneShot ( 160, 10, 220, 50 ); - APAdjustResetButton-> setLegend ( gui_msg_RESET ); - APAdjustResetButton-> setCallback ( resetAPAdjust ); - } - FG_FINALIZE_PUI_DIALOG( APAdjustDialog ); - -#undef HORIZONTAL -} - -// Simple Dialog to input Target Airport -void TgtAptDialog_Cancel(puObject *) -{ - FG_POP_PUI_DIALOG( TgtAptDialog ); -} - -void TgtAptDialog_OK (puObject *) -{ - fgAPDataPtr APData; - APData = APDataGlobal; - string TgtAptId; - - // FGTime *t = FGTime::cur_time_params; - // int PauseMode = t->getPause(); - // if(!PauseMode) - // t->togglePauseMode(); - - char *s; - TgtAptDialogInput->getValue(&s); - TgtAptId = s; - - TgtAptDialog_Cancel( NULL ); - - if ( TgtAptId.length() ) { - // set initial position from TgtAirport id - - FGPath path( current_options.get_fg_root() ); - path.append( "Airports" ); - path.append( "simple.gdbm" ); - FGAirports airports( path.c_str() ); - FGAirport a; - - FG_LOG( FG_GENERAL, FG_INFO, - "Attempting to set starting position from airport code " - << s ); - - if ( airports.search( TgtAptId, &a ) ) - { - double course, reverse, distance; - // fgAPset_tgt_airport_id( TgtAptId.c_str() ); - current_options.set_airport_id( TgtAptId.c_str() ); - sprintf( NewTgtAirportId, "%s", TgtAptId.c_str() ); - - APData->TargetLatitude = a.latitude; // * DEG_TO_RAD; - APData->TargetLongitude = a.longitude; // * DEG_TO_RAD; - MakeTargetLatLonStr( APData, - APData->TargetLatitude, - APData->TargetLongitude); - - APData->old_lat = fgAPget_latitude(); - APData->old_lon = fgAPget_longitude(); - - // need to test for iter - if( ! geo_inverse_wgs_84( fgAPget_altitude(), - fgAPget_latitude(), - fgAPget_longitude(), - APData->TargetLatitude, - APData->TargetLongitude, - &course, - &reverse, - &distance ) ) { - APData->TargetHeading = course; - MakeTargetHeadingStr( APData, APData->TargetHeading ); - APData->TargetDistance = distance; - MakeTargetDistanceStr( APData, distance ); - // This changes the AutoPilot Heading - // following cast needed - ApHeadingDialogInput-> - setValue((float)APData->TargetHeading); - // Force this ! - APData->waypoint_hold = true ; - APData->heading_hold = true; - } - } else { - TgtAptId += " not in database."; - mkDialog(TgtAptId.c_str()); - } - } - get_control_values(); - // if( PauseMode != t->getPause() ) - // t->togglePauseMode(); -} - -void TgtAptDialog_Reset(puObject *) -{ - // strncpy( NewAirportId, current_options.get_airport_id().c_str(), 16 ); - sprintf( NewTgtAirportId, "%s", current_options.get_airport_id().c_str() ); - TgtAptDialogInput->setValue ( NewTgtAirportId ); - TgtAptDialogInput->setCursor( 0 ) ; -} - -void NewTgtAirport(puObject *cb) -{ - // strncpy( NewAirportId, current_options.get_airport_id().c_str(), 16 ); - sprintf( NewTgtAirportId, "%s", current_options.get_airport_id().c_str() ); - TgtAptDialogInput->setValue( NewTgtAirportId ); - - FG_PUSH_PUI_DIALOG( TgtAptDialog ); -} - -void NewTgtAirportInit(void) -{ - FG_LOG( FG_AUTOPILOT, FG_INFO, " enter NewTgtAirportInit()" ); - // fgAPset_tgt_airport_id( current_options.get_airport_id() ); - sprintf( NewTgtAirportId, "%s", current_options.get_airport_id().c_str() ); - FG_LOG( FG_AUTOPILOT, FG_INFO, " NewTgtAirportId " << NewTgtAirportId ); - // printf(" NewTgtAirportId %s\n", NewTgtAirportId); - int len = 150 - puGetStringWidth( puGetDefaultLabelFont(), - NewTgtAirportLabel ) / 2; - - TgtAptDialog = new puDialogBox (150, 50); - { - TgtAptDialogFrame = new puFrame (0,0,350, 150); - TgtAptDialogMessage = new puText (len, 110); - TgtAptDialogMessage -> setLabel (NewTgtAirportLabel); - - TgtAptDialogInput = new puInput (50, 70, 300, 100); - TgtAptDialogInput -> setValue (NewTgtAirportId); - TgtAptDialogInput -> acceptInput(); - - TgtAptDialogOkButton = new puOneShot (50, 10, 110, 50); - TgtAptDialogOkButton -> setLegend (gui_msg_OK); - TgtAptDialogOkButton -> setCallback (TgtAptDialog_OK); - TgtAptDialogOkButton -> makeReturnDefault(TRUE); - - TgtAptDialogCancelButton = new puOneShot (140, 10, 210, 50); - TgtAptDialogCancelButton -> setLegend (gui_msg_CANCEL); - TgtAptDialogCancelButton -> setCallback (TgtAptDialog_Cancel); - - TgtAptDialogResetButton = new puOneShot (240, 10, 300, 50); - TgtAptDialogResetButton -> setLegend (gui_msg_RESET); - TgtAptDialogResetButton -> setCallback (TgtAptDialog_Reset); - } - FG_FINALIZE_PUI_DIALOG( TgtAptDialog ); - printf("leave NewTgtAirportInit()"); -} - - -// Finally actual guts of AutoPilot -void fgAPInit( fgAIRCRAFT *current_aircraft ) { - fgAPDataPtr APData; - - FG_LOG( FG_AUTOPILOT, FG_INFO, "Init AutoPilot Subsystem" ); - - APData = ( fgAPDataPtr ) calloc( sizeof( fgAPData ), 1 ); - - if ( APData == NULL ) { - // I couldn't get the mem. Dying - FG_LOG( FG_AUTOPILOT, FG_ALERT, "No ram for Autopilot. Dying." ); - exit( -1 ); - } - - FG_LOG( FG_AUTOPILOT, FG_INFO, " Autopilot allocated " ); - - APData->waypoint_hold = false ; // turn the target hold off - APData->heading_hold = false ; // turn the heading hold off - APData->altitude_hold = false ; // turn the altitude hold off - - // Initialize target location to startup location - // FG_LOG( FG_AUTOPILOT, FG_INFO, " Autopilot setting startup location" ); - APData->old_lat = - APData->TargetLatitude = fgAPget_latitude(); - APData->old_lon = - APData->TargetLongitude = fgAPget_longitude(); - - // FG_LOG( FG_AUTOPILOT, FG_INFO, " Autopilot setting TargetLatitudeStr" ); - MakeTargetLatLonStr( APData, APData->TargetLatitude, APData->TargetLongitude); - - APData->TargetHeading = 0.0; // default direction, due north - APData->TargetAltitude = 3000; // default altitude in meters - APData->alt_error_accum = 0.0; - - MakeTargetAltitudeStr( APData, 3000.0); - MakeTargetHeadingStr( APData, 0.0 ); - - // These eventually need to be read from current_aircaft somehow. - -#if 0 - // Original values - // the maximum roll, in Deg - APData->MaxRoll = 7; - // the deg from heading to start rolling out at, in Deg - APData->RollOut = 30; - // how far can I move the aleron from center. - APData->MaxAileron = .1; - // Smoothing distance for alerion control - APData->RollOutSmooth = 10; -#endif - - // the maximum roll, in Deg - APData->MaxRoll = 20; - - // the deg from heading to start rolling out at, in Deg - APData->RollOut = 20; - - // how far can I move the aleron from center. - APData->MaxAileron = .2; - - // Smoothing distance for alerion control - APData->RollOutSmooth = 10; - - //Remove at a later date - APDataGlobal = APData; - - // Hardwired for now should be in options - // 25% max control variablilty 0.5 / 2.0 - APData->disengage_threshold = 1.0; - -#if !defined( USING_SLIDER_CLASS ) - MaxRollAdjust = 2 * APData->MaxRoll; - RollOutAdjust = 2 * APData->RollOut; - MaxAileronAdjust = 2 * APData->MaxAileron; - RollOutSmoothAdjust = 2 * APData->RollOutSmooth; -#endif // !defined( USING_SLIDER_CLASS ) - - get_control_values(); - - // FG_LOG( FG_AUTOPILOT, FG_INFO, " calling NewTgtAirportInit" ); - NewTgtAirportInit(); - fgAPAdjustInit() ; - NewHeadingInit(); - NewAltitudeInit(); -}; - - -void fgAPReset( void ) { - fgAPDataPtr APData = APDataGlobal; - - if ( fgAPTerrainFollowEnabled() ) - fgAPToggleTerrainFollow( ); - - if ( fgAPAltitudeEnabled() ) - fgAPToggleAltitude(); - - if ( fgAPHeadingEnabled() ) - fgAPToggleHeading(); - - if ( fgAPAutoThrottleEnabled() ) - fgAPToggleAutoThrottle(); - - APData->TargetHeading = 0.0; // default direction, due north - MakeTargetHeadingStr( APData, APData->TargetHeading ); - - APData->TargetAltitude = 3000; // default altitude in meters - MakeTargetAltitudeStr( APData, 3000); - - APData->alt_error_accum = 0.0; - - - get_control_values(); - - sprintf( NewTgtAirportId, "%s", current_options.get_airport_id().c_str() ); - - APData->TargetLatitude = fgAPget_latitude(); - APData->TargetLongitude = fgAPget_longitude(); - MakeTargetLatLonStr( APData, - APData->TargetLatitude, - APData->TargetLongitude); -} - - -int fgAPRun( void ) { - // Remove the following lines when the calling funcitons start - // passing in the data pointer - - fgAPDataPtr APData; - - APData = APDataGlobal; - // end section - - // get control settings - double aileron = controls.get_aileron(); - double elevator = controls.get_elevator(); - double elevator_trim = controls.get_elevator_trim(); - double rudder = controls.get_rudder(); - - double lat = fgAPget_latitude(); - double lon = fgAPget_longitude(); - -#ifdef FG_FORCE_AUTO_DISENGAGE - // see if somebody else has changed them - if( fabs(aileron - APData->old_aileron) > APData->disengage_threshold || - fabs(elevator - APData->old_elevator) > APData->disengage_threshold || - fabs(elevator_trim - APData->old_elevator_trim) > - APData->disengage_threshold || - fabs(rudder - APData->old_rudder) > APData->disengage_threshold ) - { - // if controls changed externally turn autopilot off - APData->waypoint_hold = false ; // turn the target hold off - APData->heading_hold = false ; // turn the heading hold off - APData->altitude_hold = false ; // turn the altitude hold off - APData->terrain_follow = false; // turn the terrain_follow hold off - // APData->auto_throttle = false; // turn the auto_throttle off - - // stash this runs control settings - APData->old_aileron = aileron; - APData->old_elevator = elevator; - APData->old_elevator_trim = elevator_trim; - APData->old_rudder = rudder; - - return 0; - } -#endif - - // waypoint hold enabled? - if ( APData->waypoint_hold == true ) - { - double wp_course, wp_reverse, wp_distance; - -#ifdef DO_fgAP_CORRECTED_COURSE - // compute course made good - // this needs lots of special casing before use - double course, reverse, distance, corrected_course; - // need to test for iter - geo_inverse_wgs_84( 0, //fgAPget_altitude(), - APData->old_lat, - APData->old_lon, - lat, - lon, - &course, - &reverse, - &distance ); -#endif // DO_fgAP_CORRECTED_COURSE - - // compute course to way_point - // need to test for iter - if( ! geo_inverse_wgs_84( 0, //fgAPget_altitude(), - lat, - lon, - APData->TargetLatitude, - APData->TargetLongitude, - &wp_course, - &wp_reverse, - &wp_distance ) ) { - -#ifdef DO_fgAP_CORRECTED_COURSE - corrected_course = course - wp_course; - if( fabs(corrected_course) > 0.1 ) - printf("fgAP: course %f wp_course %f %f %f\n", - course, wp_course, fabs(corrected_course), distance ); -#endif // DO_fgAP_CORRECTED_COURSE - - if ( wp_distance > 100 ) { - // corrected_course = course - wp_course; - APData->TargetHeading = NormalizeDegrees(wp_course); - } else { - printf("APData->distance(%f) to close\n", wp_distance); - // Real Close -- set heading hold to current heading - // and Ring the arival bell !! - NewTgtAirport(NULL); - APData->waypoint_hold = false; - // use previous - APData->TargetHeading = fgAPget_heading(); - } - MakeTargetHeadingStr( APData, APData->TargetHeading ); - // Force this just in case - APData->TargetDistance = wp_distance; - MakeTargetDistanceStr( APData, wp_distance ); - // This changes the AutoPilot Heading Read Out - // following cast needed - ApHeadingDialogInput -> setValue ((float)APData->TargetHeading ); - } - APData->heading_hold = true; - } - - // heading hold enabled? - if ( APData->heading_hold == true ) { - double RelHeading; - double TargetRoll; - double RelRoll; - double AileronSet; - - RelHeading = - NormalizeDegrees( APData->TargetHeading - fgAPget_heading() ); - // figure out how far off we are from desired heading - - // Now it is time to deterime how far we should be rolled. - FG_LOG( FG_AUTOPILOT, FG_DEBUG, "RelHeading: " << RelHeading ); - - - // Check if we are further from heading than the roll out point - if ( fabs( RelHeading ) > APData->RollOut ) { - // set Target Roll to Max in desired direction - if ( RelHeading < 0 ) { - TargetRoll = 0 - APData->MaxRoll; - } else { - TargetRoll = APData->MaxRoll; - } - } else { - // We have to calculate the Target roll - - // This calculation engine thinks that the Target roll - // should be a line from (RollOut,MaxRoll) to (-RollOut, - // -MaxRoll) I hope this works well. If I get ambitious - // some day this might become a fancier curve or - // something. - - TargetRoll = LinearExtrapolate( RelHeading, -APData->RollOut, - -APData->MaxRoll, APData->RollOut, - APData->MaxRoll ); - } - - // Target Roll has now been Found. - - // Compare Target roll to Current Roll, Generate Rel Roll - - FG_LOG( FG_COCKPIT, FG_BULK, "TargetRoll: " << TargetRoll ); - - RelRoll = NormalizeDegrees( TargetRoll - fgAPget_roll() ); - - // Check if we are further from heading than the roll out smooth point - if ( fabs( RelRoll ) > APData->RollOutSmooth ) { - // set Target Roll to Max in desired direction - if ( RelRoll < 0 ) { - AileronSet = 0 - APData->MaxAileron; - } else { - AileronSet = APData->MaxAileron; - } - } else { - AileronSet = LinearExtrapolate( RelRoll, -APData->RollOutSmooth, - -APData->MaxAileron, - APData->RollOutSmooth, - APData->MaxAileron ); - } - - controls.set_aileron( AileronSet ); - controls.set_rudder( AileronSet / 2.0 ); - // controls.set_rudder( 0.0 ); - } - - // altitude hold or terrain follow enabled? - if ( APData->altitude_hold || APData->terrain_follow ) { - double speed, max_climb, error; - double prop_error, int_error; - double prop_adj, int_adj, total_adj; - - if ( APData->altitude_hold ) { - // normal altitude hold - APData->TargetClimbRate = - ( APData->TargetAltitude - fgAPget_altitude() ) * 8.0; - } else if ( APData->terrain_follow ) { - // brain dead ground hugging with no look ahead - APData->TargetClimbRate = - ( APData->TargetAGL - fgAPget_agl() ) * 16.0; - // cout << "target agl = " << APData->TargetAGL - // << " current agl = " << fgAPget_agl() - // << " target climb rate = " << APData->TargetClimbRate - // << endl; - } else { - // just try to zero out rate of climb ... - APData->TargetClimbRate = 0.0; - } - - speed = get_speed(); - - if ( speed < min_climb ) { - max_climb = 0.0; - } else if ( speed < best_climb ) { - max_climb = ((best_climb - min_climb) - (best_climb - speed)) - * ideal_climb_rate - / (best_climb - min_climb); - } else { - max_climb = ( speed - best_climb ) * 10.0 + ideal_climb_rate; - } - - // this first one could be optional if we wanted to allow - // better climb performance assuming we have the airspeed to - // support it. - if ( APData->TargetClimbRate > ideal_climb_rate ) { - APData->TargetClimbRate = ideal_climb_rate; - } - - if ( APData->TargetClimbRate > max_climb ) { - APData->TargetClimbRate = max_climb; - } - - if ( APData->TargetClimbRate < -ideal_climb_rate ) { - APData->TargetClimbRate = -ideal_climb_rate; - } - - error = fgAPget_climb() - APData->TargetClimbRate; - // cout << "climb rate = " << fgAPget_climb() - // << " error = " << error << endl; - - // accumulate the error under the curve ... this really should - // be *= delta t - APData->alt_error_accum += error; - - // calculate integral error, and adjustment amount - int_error = APData->alt_error_accum; - // printf("error = %.2f int_error = %.2f\n", error, int_error); - int_adj = int_error / 8000.0; - - // caclulate proportional error - prop_error = error; - prop_adj = prop_error / 2000.0; - - total_adj = 0.9 * prop_adj + 0.1 * int_adj; - // if ( total_adj > 0.6 ) { - // total_adj = 0.6; - // } else if ( total_adj < -0.2 ) { - // total_adj = -0.2; - // } - if ( total_adj > 1.0 ) { - total_adj = 1.0; - } else if ( total_adj < -1.0 ) { - total_adj = -1.0; - } - - controls.set_elevator( total_adj ); - } - - // auto throttle enabled? - if ( APData->auto_throttle ) { - double error; - double prop_error, int_error; - double prop_adj, int_adj, total_adj; - - error = APData->TargetSpeed - get_speed(); - - // accumulate the error under the curve ... this really should - // be *= delta t - APData->speed_error_accum += error; - if ( APData->speed_error_accum > 2000.0 ) { - APData->speed_error_accum = 2000.0; - } - else if ( APData->speed_error_accum < -2000.0 ) { - APData->speed_error_accum = -2000.0; - } - - // calculate integral error, and adjustment amount - int_error = APData->speed_error_accum; - - // printf("error = %.2f int_error = %.2f\n", error, int_error); - int_adj = int_error / 200.0; - - // caclulate proportional error - prop_error = error; - prop_adj = 0.5 + prop_error / 50.0; - - total_adj = 0.9 * prop_adj + 0.1 * int_adj; - if ( total_adj > 1.0 ) { - total_adj = 1.0; - } - else if ( total_adj < 0.0 ) { - total_adj = 0.0; - } - - controls.set_throttle( FGControls::ALL_ENGINES, total_adj ); - } - -#ifdef THIS_CODE_IS_NOT_USED - if (APData->Mode == 2) // Glide slope hold - { - double RelSlope; - double RelElevator; - - // First, calculate Relative slope and normalize it - RelSlope = NormalizeDegrees( APData->TargetSlope - get_pitch()); - - // Now calculate the elevator offset from current angle - if ( abs(RelSlope) > APData->SlopeSmooth ) - { - if ( RelSlope < 0 ) // set RelElevator to max in the correct direction - RelElevator = -APData->MaxElevator; - else - RelElevator = APData->MaxElevator; - } - - else - RelElevator = LinearExtrapolate(RelSlope,-APData->SlopeSmooth,-APData->MaxElevator,APData->SlopeSmooth,APData->MaxElevator); - - // set the elevator - fgElevMove(RelElevator); - - } -#endif // THIS_CODE_IS_NOT_USED - - // stash this runs control settings - // get_control_values(); - APData->old_aileron = controls.get_aileron(); - APData->old_elevator = controls.get_elevator(); - APData->old_elevator_trim = controls.get_elevator_trim(); - APData->old_rudder = controls.get_rudder(); - - // for cross track error - APData->old_lat = lat; - APData->old_lon = lon; - - // Ok, we are done - return 0; -} - -/* -void fgAPSetMode( int mode) -{ -//Remove the following line when the calling funcitons start passing in the data pointer -fgAPDataPtr APData; - -APData = APDataGlobal; -// end section - -fgPrintf( FG_COCKPIT, FG_INFO, "APSetMode : %d\n", mode ); - -APData->Mode = mode; // set the new mode -} -*/ -#if 0 -void fgAPset_tgt_airport_id( const string id ) { - FG_LOG( FG_AUTOPILOT, FG_INFO, "entering fgAPset_tgt_airport_id " << id ); - fgAPDataPtr APData; - APData = APDataGlobal; - APData->tgt_airport_id = id; - FG_LOG( FG_AUTOPILOT, FG_INFO, "leaving fgAPset_tgt_airport_id " - << APData->tgt_airport_id ); -}; - -string fgAPget_tgt_airport_id( void ) { - fgAPDataPtr APData = APDataGlobal; - return APData->tgt_airport_id; -}; -#endif - -void fgAPToggleHeading( void ) { - // Remove at a later date - fgAPDataPtr APData; - - APData = APDataGlobal; - // end section - - if ( APData->heading_hold || APData->waypoint_hold ) { - // turn off heading hold - APData->heading_hold = false; - APData->waypoint_hold = false; - } else { - // turn on heading hold, lock at current heading - APData->heading_hold = true; - APData->TargetHeading = fgAPget_heading(); - MakeTargetHeadingStr( APData, APData->TargetHeading ); - ApHeadingDialogInput -> setValue ((float)APData->TargetHeading ); - } - - get_control_values(); - FG_LOG( FG_COCKPIT, FG_INFO, " fgAPSetHeading: (" - << APData->heading_hold << ") " << APData->TargetHeading ); -} - -void fgAPToggleWayPoint( void ) { - // Remove at a later date - fgAPDataPtr APData; - - APData = APDataGlobal; - // end section - - if ( APData->waypoint_hold ) { - // turn off location hold - APData->waypoint_hold = false; - // set heading hold to current heading - // APData->heading_hold = true; - APData->TargetHeading = fgAPget_heading(); - } else { - double course, reverse, distance; - // turn on location hold - // turn on heading hold - APData->old_lat = fgAPget_latitude(); - APData->old_lon = fgAPget_longitude(); - - // need to test for iter - if(!geo_inverse_wgs_84( fgAPget_altitude(), - fgAPget_latitude(), - fgAPget_longitude(), - APData->TargetLatitude, - APData->TargetLongitude, - &course, - &reverse, - &distance ) ) { - APData->TargetHeading = course; - APData->TargetDistance = distance; - MakeTargetDistanceStr( APData, distance ); - } - // Force this ! - APData->waypoint_hold = true; - APData->heading_hold = true; - } - - // This changes the AutoPilot Heading - // following cast needed - ApHeadingDialogInput->setValue ((float)APData->TargetHeading ); - MakeTargetHeadingStr( APData, APData->TargetHeading ); - - get_control_values(); - - FG_LOG( FG_COCKPIT, FG_INFO, " fgAPSetLocation: ( " - << APData->waypoint_hold << " " - << APData->TargetLatitude << " " - << APData->TargetLongitude << " ) " - ); -} - - -void fgAPToggleAltitude( void ) { - // Remove at a later date - fgAPDataPtr APData; - - APData = APDataGlobal; - // end section - - if ( APData->altitude_hold ) { - // turn off altitude hold - APData->altitude_hold = false; - } else { - // turn on altitude hold, lock at current altitude - APData->altitude_hold = true; - APData->terrain_follow = false; - APData->TargetAltitude = fgAPget_altitude(); - APData->alt_error_accum = 0.0; - // alt_error_queue.erase( alt_error_queue.begin(), - // alt_error_queue.end() ); - float target_alt = APData->TargetAltitude; - if ( current_options.get_units() == fgOPTIONS::FG_UNITS_FEET ) - target_alt *= METER_TO_FEET; - - ApAltitudeDialogInput->setValue(target_alt); - MakeTargetAltitudeStr( APData, target_alt); - } - - get_control_values(); - FG_LOG( FG_COCKPIT, FG_INFO, " fgAPSetAltitude: (" - << APData->altitude_hold << ") " << APData->TargetAltitude ); -} - - -void fgAPToggleAutoThrottle ( void ) { - // Remove at a later date - fgAPDataPtr APData; - - APData = APDataGlobal; - // end section - - if ( APData->auto_throttle ) { - // turn off altitude hold - APData->auto_throttle = false; - } else { - // turn on terrain follow, lock at current agl - APData->auto_throttle = true; - APData->TargetSpeed = get_speed(); - APData->speed_error_accum = 0.0; - } - - get_control_values(); - FG_LOG( FG_COCKPIT, FG_INFO, " fgAPSetAutoThrottle: (" - << APData->auto_throttle << ") " << APData->TargetSpeed ); -} - -void fgAPToggleTerrainFollow( void ) { - // Remove at a later date - fgAPDataPtr APData; - - APData = APDataGlobal; - // end section - - if ( APData->terrain_follow ) { - // turn off altitude hold - APData->terrain_follow = false; - } else { - // turn on terrain follow, lock at current agl - APData->terrain_follow = true; - APData->altitude_hold = false; - APData->TargetAGL = fgAPget_agl(); - APData->alt_error_accum = 0.0; - } - get_control_values(); - - FG_LOG( FG_COCKPIT, FG_INFO, " fgAPSetTerrainFollow: (" - << APData->terrain_follow << ") " << APData->TargetAGL ); -} - -static double NormalizeDegrees( double Input ) { - // normalize the input to the range (-180,180] - // Input should not be greater than -360 to 360. - // Current rules send the output to an undefined state. - if ( Input > 180 ) - while(Input > 180 ) - Input -= 360; - else if ( Input <= -180 ) - while ( Input <= -180 ) - Input += 360; - return ( Input ); -}; - -static double LinearExtrapolate( double x, double x1, double y1, double x2, double y2 ) { - // This procedure extrapolates the y value for the x posistion on a line defined by x1,y1; x2,y2 - //assert(x1 != x2); // Divide by zero error. Cold abort for now - - // Could be - // static double y = 0.0; - // double dx = x2 -x1; - // if( (dx < -FG_EPSILON ) || ( dx > FG_EPSILON ) ) - // { - - double m, b, y; // the constants to find in y=mx+b - // double m, b; - - m = ( y2 - y1 ) / ( x2 - x1 ); // calculate the m - - b = y1 - m * x1; // calculate the b - - y = m * x + b; // the final calculation - - // } - - return ( y ); - -}; diff --git a/src/Autopilot/autopilot.hxx b/src/Autopilot/autopilot.hxx deleted file mode 100644 index 584d69a2a..000000000 --- a/src/Autopilot/autopilot.hxx +++ /dev/null @@ -1,155 +0,0 @@ -// autopilot.hxx -- autopilot defines and prototypes (very alpha) -// -// Written by Jeff Goeke-Smith, started April 1998. -// -// Copyright (C) 1998 Jeff Goeke-Smith - jgoeke@voyager.net -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, but -// WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -// -// $Id$ - - -#ifndef _AUTOPILOT_HXX -#define _AUTOPILOT_HXX - -#include <simgear/compiler.h> - -#include STL_STRING - -#include <string.h> - -#include <Aircraft/aircraft.hxx> -#include <FDM/flight.hxx> -#include <Controls/controls.hxx> - -FG_USING_STD(string); - - -// Structures -typedef struct { - bool waypoint_hold; // the current state of the target hold - bool heading_hold; // the current state of the heading hold - bool altitude_hold; // the current state of the altitude hold - bool terrain_follow; // the current state of the terrain follower - bool auto_throttle; // the current state of the auto throttle - - double TargetLatitude; // the latitude the AP should steer to. - double TargetLongitude; // the longitude the AP should steer to. - double TargetDistance; // the distance to Target. - double TargetHeading; // the heading the AP should steer to. - double TargetAltitude; // altitude to hold - double TargetAGL; // the terrain separation - double TargetClimbRate; // climb rate to shoot for - double TargetSpeed; // speed to shoot for - double alt_error_accum; // altitude error accumulator - double speed_error_accum; // speed error accumulator - - double TargetSlope; // the glide slope hold value - - double MaxRoll ; // the max the plane can roll for the turn - double RollOut; // when the plane should roll out - // measured from Heading - double MaxAileron; // how far to move the aleroin from center - double RollOutSmooth; // deg to use for smoothing Aileron Control - double MaxElevator; // the maximum elevator allowed - double SlopeSmooth; // smoothing angle for elevator - - // following for testing disengagement of autopilot - // apon pilot interaction with controls - double old_aileron; - double old_elevator; - double old_elevator_trim; - double old_rudder; - - // manual controls override beyond this value - double disengage_threshold; - - // For future cross track error adjust - double old_lat; - double old_lon; - - // keeping these locally to save work inside main loop - char TargetLatitudeStr[64]; - char TargetLongitudeStr[64]; - char TargetLatLonStr[64]; - char TargetDistanceStr[64]; - char TargetHeadingStr[64]; - char TargetAltitudeStr[64]; - // char jnk[32]; - // using current_options.airport_id for now - // string tgt_airport_id; // ID of initial starting airport -} fgAPData, *fgAPDataPtr ; - - -// Defines -#define AP_CURRENT_HEADING -1 - - -// prototypes -void fgAPInit( fgAIRCRAFT *current_aircraft ); -int fgAPRun( void ); - -void fgAPToggleWayPoint( void ); -void fgAPToggleHeading( void ); -void fgAPToggleAltitude( void ); -void fgAPToggleTerrainFollow( void ); -void fgAPToggleAutoThrottle( void ); - -bool fgAPTerrainFollowEnabled( void ); -bool fgAPAltitudeEnabled( void ); -bool fgAPHeadingEnabled( void ); -bool fgAPWayPointEnabled( void ); -bool fgAPAutoThrottleEnabled( void ); - -void fgAPAltitudeAdjust( double inc ); -void fgAPHeadingAdjust( double inc ); -void fgAPAutoThrottleAdjust( double inc ); - -void fgAPHeadingSet( double value ); - -double fgAPget_TargetLatitude( void ); -double fgAPget_TargetLongitude( void ); -double fgAPget_TargetHeading( void ); -double fgAPget_TargetDistance( void ); -double fgAPget_TargetAltitude( void ); - -char *fgAPget_TargetLatitudeStr( void ); -char *fgAPget_TargetLongitudeStr( void ); -char *fgAPget_TargetDistanceStr( void ); -char *fgAPget_TargetHeadingStr( void ); -char *fgAPget_TargetAltitudeStr( void ); -char *fgAPget_TargetLatLonStr( void ); - -//void fgAPset_tgt_airport_id( const string ); -//string fgAPget_tgt_airport_id( void ); - -void fgAPReset(void); - -int geo_inverse_wgs_84( double alt, - double lat1, double lon1, - double lat2, double lon2, - double *az1, double *az2, - double *s ); - -int geo_direct_wgs_84( double alt, - double lat1, double lon1, - double az1, double s, - double *lat2, double *lon2, - double *az2 ); - -class puObject; -void fgAPAdjust( puObject * ); - -#endif // _AUTOPILOT_HXX diff --git a/src/Autopilot/newauto.cxx b/src/Autopilot/newauto.cxx new file mode 100644 index 000000000..34adf9d99 --- /dev/null +++ b/src/Autopilot/newauto.cxx @@ -0,0 +1,802 @@ +// newauto.cxx -- autopilot defines and prototypes (very alpha) +// +// Started April 1998 Copyright (C) 1998 +// +// Contributions by Jeff Goeke-Smith <jgoeke@voyager.net> +// Norman Vine <nhv@cape.com> +// Curtis Olson <curt@flightgear.org> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// +// $Id$ + + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdio.h> // sprintf() + +#include <simgear/constants.h> +#include <simgear/debug/logstream.hxx> +#include <simgear/math/fg_geodesy.hxx> + +#include <Controls/controls.hxx> +#include <FDM/flight.hxx> +#include <Main/bfi.hxx> +#include <Main/options.hxx> +#include <Scenery/scenery.hxx> + +#include "newauto.hxx" + + +FGAutopilot *current_autopilot; + + +// Climb speed constants +const double min_climb = 70.0; // kts +const double best_climb = 75.0; // kts +const double ideal_climb_rate = 500.0; // fpm + +/// These statics will eventually go into the class +/// they are just here while I am experimenting -- NHV :-) +// AutoPilot Gain Adjuster members +static double MaxRollAdjust; // MaxRollAdjust = 2 * APData->MaxRoll; +static double RollOutAdjust; // RollOutAdjust = 2 * APData->RollOut; +static double MaxAileronAdjust; // MaxAileronAdjust = 2 * APData->MaxAileron; +static double RollOutSmoothAdjust; // RollOutSmoothAdjust = 2 * APData->RollOutSmooth; + +#if 0 +static float MaxRollValue; // 0.1 -> 1.0 +static float RollOutValue; +static float MaxAileronValue; +static float RollOutSmoothValue; + +static float TmpMaxRollValue; // for cancel operation +static float TmpRollOutValue; +static float TmpMaxAileronValue; +static float TmpRollOutSmoothValue; +#endif + +static char NewTgtAirportId[16]; +// static char NewTgtAirportLabel[] = "Enter New TgtAirport ID"; + +extern char *coord_format_lat(float); +extern char *coord_format_lon(float); + + +void FGAutopilot::MakeTargetLatLonStr( double lat, double lon ) { + sprintf( TargetLatitudeStr , "%s", coord_format_lat(TargetLatitude) ); + sprintf( TargetLongitudeStr, "%s", coord_format_lon(TargetLongitude) ); + sprintf( TargetLatLonStr, "%s %s", TargetLatitudeStr, TargetLongitudeStr ); +} + + +void FGAutopilot::MakeTargetAltitudeStr( double altitude ) { + sprintf( TargetAltitudeStr, "APAltitude %6.0f", altitude ); +} + + +void FGAutopilot::MakeTargetHeadingStr( double bearing ) { + if( bearing < 0. ) { + bearing += 360.; + } else if (bearing > 360. ) { + bearing -= 360.; + } + sprintf( TargetHeadingStr, "APHeading %6.1f", bearing ); +} + + +void FGAutopilot::update_old_control_values() { + old_aileron = FGBFI::getAileron(); + old_elevator = FGBFI::getElevator(); + old_elevator_trim = FGBFI::getElevatorTrim(); + old_rudder = FGBFI::getRudder(); +} + + +// Initialize autopilot subsystem +void FGAutopilot::init() { + FG_LOG( FG_AUTOPILOT, FG_INFO, "Init AutoPilot Subsystem" ); + + heading_hold = false ; // turn the heading hold off + altitude_hold = false ; // turn the altitude hold off + auto_throttle = false ; // turn the auto throttle off + + // Initialize target location to startup location + old_lat = TargetLatitude = FGBFI::getLatitude(); + old_lon = TargetLongitude = FGBFI::getLongitude(); + + MakeTargetLatLonStr( TargetLatitude, TargetLongitude); + + TargetHeading = 0.0; // default direction, due north + TargetAltitude = 3000; // default altitude in meters + alt_error_accum = 0.0; + + MakeTargetAltitudeStr( 3000.0); + MakeTargetHeadingStr( 0.0 ); + + // These eventually need to be read from current_aircaft somehow. + + // the maximum roll, in Deg + MaxRoll = 20; + + // the deg from heading to start rolling out at, in Deg + RollOut = 20; + + // how far can I move the aleron from center. + MaxAileron = .2; + + // Smoothing distance for alerion control + RollOutSmooth = 10; + + // Hardwired for now should be in options + // 25% max control variablilty 0.5 / 2.0 + disengage_threshold = 1.0; + +#if !defined( USING_SLIDER_CLASS ) + MaxRollAdjust = 2 * MaxRoll; + RollOutAdjust = 2 * RollOut; + MaxAileronAdjust = 2 * MaxAileron; + RollOutSmoothAdjust = 2 * RollOutSmooth; +#endif // !defined( USING_SLIDER_CLASS ) + + update_old_control_values(); + + // Initialize GUI components of autopilot + // NewTgtAirportInit(); + // fgAPAdjustInit() ; + // NewHeadingInit(); + // NewAltitudeInit(); +}; + + +// Reset the autopilot system +void FGAutopilot::reset() { + + heading_hold = false ; // turn the heading hold off + altitude_hold = false ; // turn the altitude hold off + auto_throttle = false ; // turn the auto throttle off + + TargetHeading = 0.0; // default direction, due north + MakeTargetHeadingStr( TargetHeading ); + + TargetAltitude = 3000; // default altitude in meters + MakeTargetAltitudeStr( TargetAltitude ); + + alt_error_accum = 0.0; + + update_old_control_values(); + + sprintf( NewTgtAirportId, "%s", current_options.get_airport_id().c_str() ); + + TargetLatitude = FGBFI::getLatitude(); + TargetLongitude = FGBFI::getLongitude(); + MakeTargetLatLonStr( TargetLatitude, TargetLongitude ); +} + + +static inline double get_speed( void ) { + return( cur_fdm_state->get_V_equiv_kts() ); +} + +static inline double get_ground_speed() { + // starts in ft/s so we convert to kts + double ft_s = cur_fdm_state->get_V_ground_speed() + * current_options.get_speed_up();; + double kts = ft_s * FEET_TO_METER * 3600 * METER_TO_NM; + + return kts; +} + + +void FGAutopilot::MakeTargetDistanceStr( double distance ) { + double eta = distance*METER_TO_NM / get_ground_speed(); + if ( eta >= 100.0 ) { eta = 99.999; } + int major, minor; + if ( eta < (1.0/6.0) ) { + // within 10 minutes, bump up to min/secs + eta *= 60.0; + } + major = (int)eta; + minor = (int)((eta - (int)eta) * 60.0); + sprintf( TargetDistanceStr, "APDistance %.2f NM ETA %d:%02d", + distance*METER_TO_NM, major, minor ); + // cout << "distance = " << distance*METER_TO_NM + // << " gndsp = " << get_ground_speed() + // << " time = " << eta + // << " major = " << major + // << " minor = " << minor + // << endl; +} + + +static double NormalizeDegrees( double Input ) { + // normalize the input to the range (-180,180] + // Input should not be greater than -360 to 360. + // Current rules send the output to an undefined state. + if ( Input > 180 ) + while(Input > 180 ) + Input -= 360; + else if ( Input <= -180 ) + while ( Input <= -180 ) + Input += 360; + return ( Input ); +}; + +static double LinearExtrapolate( double x, double x1, double y1, double x2, double y2 ) { + // This procedure extrapolates the y value for the x posistion on a line defined by x1,y1; x2,y2 + //assert(x1 != x2); // Divide by zero error. Cold abort for now + + // Could be + // static double y = 0.0; + // double dx = x2 -x1; + // if( (dx < -FG_EPSILON ) || ( dx > FG_EPSILON ) ) + // { + + double m, b, y; // the constants to find in y=mx+b + // double m, b; + + m = ( y2 - y1 ) / ( x2 - x1 ); // calculate the m + + b = y1 - m * x1; // calculate the b + + y = m * x + b; // the final calculation + + // } + + return ( y ); + +}; + + +int FGAutopilot::run() { + // Remove the following lines when the calling funcitons start + // passing in the data pointer + + // get control settings + // double aileron = FGBFI::getAileron(); + // double elevator = FGBFI::getElevator(); + // double elevator_trim = FGBFI::getElevatorTrim(); + // double rudder = FGBFI::getRudder(); + + double lat = FGBFI::getLatitude(); + double lon = FGBFI::getLongitude(); + +#ifdef FG_FORCE_AUTO_DISENGAGE + // see if somebody else has changed them + if( fabs(aileron - old_aileron) > disengage_threshold || + fabs(elevator - old_elevator) > disengage_threshold || + fabs(elevator_trim - old_elevator_trim) > + disengage_threshold || + fabs(rudder - old_rudder) > disengage_threshold ) + { + // if controls changed externally turn autopilot off + waypoint_hold = false ; // turn the target hold off + heading_hold = false ; // turn the heading hold off + altitude_hold = false ; // turn the altitude hold off + terrain_follow = false; // turn the terrain_follow hold off + // auto_throttle = false; // turn the auto_throttle off + + // stash this runs control settings + old_aileron = aileron; + old_elevator = elevator; + old_elevator_trim = elevator_trim; + old_rudder = rudder; + + return 0; + } +#endif + + // heading hold enabled? + if ( heading_hold == true ) { + + if ( heading_mode == FG_HEADING_LOCK ) { + // leave target heading alone + } else if ( heading_mode == FG_HEADING_WAYPOINT ) { + // update target heading to waypoint + + double wp_course, wp_reverse, wp_distance; + +#ifdef DO_fgAP_CORRECTED_COURSE + // compute course made good + // this needs lots of special casing before use + double course, reverse, distance, corrected_course; + // need to test for iter + geo_inverse_wgs_84( 0, //fgAPget_altitude(), + old_lat, + old_lon, + lat, + lon, + &course, + &reverse, + &distance ); +#endif // DO_fgAP_CORRECTED_COURSE + + // compute course to way_point + // need to test for iter + if( ! geo_inverse_wgs_84( 0, //fgAPget_altitude(), + lat, + lon, + TargetLatitude, + TargetLongitude, + &wp_course, + &wp_reverse, + &wp_distance ) ) { + +#ifdef DO_fgAP_CORRECTED_COURSE + corrected_course = course - wp_course; + if( fabs(corrected_course) > 0.1 ) + printf("fgAP: course %f wp_course %f %f %f\n", + course, wp_course, fabs(corrected_course), + distance ); +#endif // DO_fgAP_CORRECTED_COURSE + + if ( wp_distance > 100 ) { + // corrected_course = course - wp_course; + TargetHeading = NormalizeDegrees(wp_course); + } else { + printf("distance(%f) to close\n", wp_distance); + // Real Close -- set heading hold to current heading + // and Ring the arival bell !! + heading_mode = FG_HEADING_LOCK; + // use current heading + TargetHeading = FGBFI::getHeading(); + } + MakeTargetHeadingStr( TargetHeading ); + // Force this just in case + TargetDistance = wp_distance; + MakeTargetDistanceStr( wp_distance ); + } + } + + double RelHeading; + double TargetRoll; + double RelRoll; + double AileronSet; + + RelHeading = NormalizeDegrees( TargetHeading - FGBFI::getHeading() ); + // figure out how far off we are from desired heading + + // Now it is time to deterime how far we should be rolled. + FG_LOG( FG_AUTOPILOT, FG_DEBUG, "RelHeading: " << RelHeading ); + + + // Check if we are further from heading than the roll out point + if ( fabs( RelHeading ) > RollOut ) { + // set Target Roll to Max in desired direction + if ( RelHeading < 0 ) { + TargetRoll = 0 - MaxRoll; + } else { + TargetRoll = MaxRoll; + } + } else { + // We have to calculate the Target roll + + // This calculation engine thinks that the Target roll + // should be a line from (RollOut,MaxRoll) to (-RollOut, + // -MaxRoll) I hope this works well. If I get ambitious + // some day this might become a fancier curve or + // something. + + TargetRoll = LinearExtrapolate( RelHeading, -RollOut, + -MaxRoll, RollOut, + MaxRoll ); + } + + // Target Roll has now been Found. + + // Compare Target roll to Current Roll, Generate Rel Roll + + FG_LOG( FG_COCKPIT, FG_BULK, "TargetRoll: " << TargetRoll ); + + RelRoll = NormalizeDegrees( TargetRoll - FGBFI::getRoll() ); + + // Check if we are further from heading than the roll out smooth point + if ( fabs( RelRoll ) > RollOutSmooth ) { + // set Target Roll to Max in desired direction + if ( RelRoll < 0 ) { + AileronSet = 0 - MaxAileron; + } else { + AileronSet = MaxAileron; + } + } else { + AileronSet = LinearExtrapolate( RelRoll, -RollOutSmooth, + -MaxAileron, + RollOutSmooth, + MaxAileron ); + } + + controls.set_aileron( AileronSet ); + controls.set_rudder( AileronSet / 4.0 ); + // controls.set_rudder( 0.0 ); + } + + // altitude hold? + if ( altitude_hold ) { + double speed, max_climb, error; + double prop_error, int_error; + double prop_adj, int_adj, total_adj; + + if ( altitude_mode == FG_ALTITUDE_LOCK ) { + // normal altitude hold + // cout << "TargetAltitude = " << TargetAltitude + // << "Altitude = " << FGBFI::getAltitude() * FEET_TO_METER + // << endl; + TargetClimbRate = + ( TargetAltitude - FGBFI::getAltitude() * FEET_TO_METER ) * 8.0; + } else if ( altitude_mode == FG_ALTITUDE_TERRAIN ) { + // brain dead ground hugging with no look ahead + TargetClimbRate = + ( TargetAGL - FGBFI::getAGL()*FEET_TO_METER ) * 16.0; + // cout << "target agl = " << TargetAGL + // << " current agl = " << fgAPget_agl() + // << " target climb rate = " << TargetClimbRate + // << endl; + } else { + // just try to zero out rate of climb ... + TargetClimbRate = 0.0; + } + + speed = get_speed(); + + if ( speed < min_climb ) { + max_climb = 0.0; + } else if ( speed < best_climb ) { + max_climb = ((best_climb - min_climb) - (best_climb - speed)) + * ideal_climb_rate + / (best_climb - min_climb); + } else { + max_climb = ( speed - best_climb ) * 10.0 + ideal_climb_rate; + } + + // this first one could be optional if we wanted to allow + // better climb performance assuming we have the airspeed to + // support it. + if ( TargetClimbRate > ideal_climb_rate ) { + TargetClimbRate = ideal_climb_rate; + } + + if ( TargetClimbRate > max_climb ) { + TargetClimbRate = max_climb; + } + + if ( TargetClimbRate < -ideal_climb_rate ) { + TargetClimbRate = -ideal_climb_rate; + } + + error = FGBFI::getVerticalSpeed() * FEET_TO_METER - TargetClimbRate; + // cout << "climb rate = " << fgAPget_climb() + // << " error = " << error << endl; + + // accumulate the error under the curve ... this really should + // be *= delta t + alt_error_accum += error; + + // calculate integral error, and adjustment amount + int_error = alt_error_accum; + // printf("error = %.2f int_error = %.2f\n", error, int_error); + int_adj = int_error / 8000.0; + + // caclulate proportional error + prop_error = error; + prop_adj = prop_error / 2000.0; + + total_adj = 0.9 * prop_adj + 0.1 * int_adj; + // if ( total_adj > 0.6 ) { + // total_adj = 0.6; + // } else if ( total_adj < -0.2 ) { + // total_adj = -0.2; + // } + if ( total_adj > 1.0 ) { + total_adj = 1.0; + } else if ( total_adj < -1.0 ) { + total_adj = -1.0; + } + + controls.set_elevator( total_adj ); + } + + // auto throttle enabled? + if ( auto_throttle ) { + double error; + double prop_error, int_error; + double prop_adj, int_adj, total_adj; + + error = TargetSpeed - get_speed(); + + // accumulate the error under the curve ... this really should + // be *= delta t + speed_error_accum += error; + if ( speed_error_accum > 2000.0 ) { + speed_error_accum = 2000.0; + } + else if ( speed_error_accum < -2000.0 ) { + speed_error_accum = -2000.0; + } + + // calculate integral error, and adjustment amount + int_error = speed_error_accum; + + // printf("error = %.2f int_error = %.2f\n", error, int_error); + int_adj = int_error / 200.0; + + // caclulate proportional error + prop_error = error; + prop_adj = 0.5 + prop_error / 50.0; + + total_adj = 0.9 * prop_adj + 0.1 * int_adj; + if ( total_adj > 1.0 ) { + total_adj = 1.0; + } + else if ( total_adj < 0.0 ) { + total_adj = 0.0; + } + + controls.set_throttle( FGControls::ALL_ENGINES, total_adj ); + } + +#ifdef THIS_CODE_IS_NOT_USED + if (Mode == 2) // Glide slope hold + { + double RelSlope; + double RelElevator; + + // First, calculate Relative slope and normalize it + RelSlope = NormalizeDegrees( TargetSlope - get_pitch()); + + // Now calculate the elevator offset from current angle + if ( abs(RelSlope) > SlopeSmooth ) + { + if ( RelSlope < 0 ) // set RelElevator to max in the correct direction + RelElevator = -MaxElevator; + else + RelElevator = MaxElevator; + } + + else + RelElevator = LinearExtrapolate(RelSlope,-SlopeSmooth,-MaxElevator,SlopeSmooth,MaxElevator); + + // set the elevator + fgElevMove(RelElevator); + + } +#endif // THIS_CODE_IS_NOT_USED + + // stash this runs control settings + // update_old_control_values(); + old_aileron = controls.get_aileron(); + old_elevator = controls.get_elevator(); + old_elevator_trim = controls.get_elevator_trim(); + old_rudder = controls.get_rudder(); + + // for cross track error + old_lat = lat; + old_lon = lon; + + // Ok, we are done + return 0; +} + + +void FGAutopilot::set_HeadingMode( fgAutoHeadingMode mode ) { + heading_mode = mode; + + if ( heading_mode == FG_HEADING_LOCK ) { + // set heading hold to current heading + TargetHeading = FGBFI::getHeading(); + } else if ( heading_mode == FG_HEADING_WAYPOINT ) { + double course, reverse, distance; + // turn on location hold + // turn on heading hold + old_lat = FGBFI::getLatitude(); + old_lon = FGBFI::getLongitude(); + + // need to test for iter + if( !geo_inverse_wgs_84( FGBFI::getAltitude() * FEET_TO_METER, + FGBFI::getLatitude(), + FGBFI::getLongitude(), + TargetLatitude, + TargetLongitude, + &course, + &reverse, + &distance ) ) { + TargetHeading = course; + TargetDistance = distance; + MakeTargetDistanceStr( distance ); + } + + FG_LOG( FG_COCKPIT, FG_INFO, " fgAPSetLocation: ( " + << TargetLatitude << " " + << TargetLongitude << " ) " + ); + } + + MakeTargetHeadingStr( TargetHeading ); + update_old_control_values(); +} + + +void FGAutopilot::set_AltitudeMode( fgAutoAltitudeMode mode ) { + altitude_mode = mode; + + if ( altitude_mode == FG_ALTITUDE_LOCK ) { + // lock at current altitude + TargetAltitude = FGBFI::getAltitude() * FEET_TO_METER; + alt_error_accum = 0.0; + + MakeTargetAltitudeStr( TargetAltitude ); + } else if ( altitude_mode == FG_ALTITUDE_TERRAIN ) { + TargetAGL = FGBFI::getAGL() * FEET_TO_METER; + alt_error_accum = 0.0; + } + + update_old_control_values(); + FG_LOG( FG_COCKPIT, FG_INFO, " set_AltitudeMode():" ); +} + + +#if 0 +static inline double get_aoa( void ) { + return( cur_fdm_state->get_Gamma_vert_rad() * RAD_TO_DEG ); +} + +static inline double fgAPget_latitude( void ) { + return( cur_fdm_state->get_Latitude() * RAD_TO_DEG ); +} + +static inline double fgAPget_longitude( void ) { + return( cur_fdm_state->get_Longitude() * RAD_TO_DEG ); +} + +static inline double fgAPget_roll( void ) { + return( cur_fdm_state->get_Phi() * RAD_TO_DEG ); +} + +static inline double get_pitch( void ) { + return( cur_fdm_state->get_Theta() ); +} + +double fgAPget_heading( void ) { + return( cur_fdm_state->get_Psi() * RAD_TO_DEG ); +} + +static inline double fgAPget_altitude( void ) { + return( cur_fdm_state->get_Altitude() * FEET_TO_METER ); +} + +static inline double fgAPget_climb( void ) { + // return in meters per minute + return( cur_fdm_state->get_Climb_Rate() * FEET_TO_METER * 60 ); +} + +static inline double get_sideslip( void ) { + return( cur_fdm_state->get_Beta() ); +} + +static inline double fgAPget_agl( void ) { + double agl; + + agl = cur_fdm_state->get_Altitude() * FEET_TO_METER + - scenery.cur_elev; + + return( agl ); +} +#endif + + +void FGAutopilot::AltitudeSet( double new_altitude ) { + double target_alt = new_altitude; + + // cout << "new altitude = " << new_altitude << endl; + + if ( current_options.get_units() == fgOPTIONS::FG_UNITS_FEET ) { + target_alt = new_altitude * FEET_TO_METER; + } + + if( target_alt < scenery.cur_elev ) { + target_alt = scenery.cur_elev; + } + + TargetAltitude = target_alt; + altitude_mode = FG_ALTITUDE_LOCK; + + // cout << "TargetAltitude = " << TargetAltitude << endl; + + if ( current_options.get_units() == fgOPTIONS::FG_UNITS_FEET ) { + target_alt *= METER_TO_FEET; + } + // ApAltitudeDialogInput->setValue((float)target_alt); + MakeTargetAltitudeStr( target_alt ); + + update_old_control_values(); +} + + +void FGAutopilot::AltitudeAdjust( double inc ) +{ + double target_alt, target_agl; + + if ( current_options.get_units() == fgOPTIONS::FG_UNITS_FEET ) { + target_alt = TargetAltitude * METER_TO_FEET; + target_agl = TargetAGL * METER_TO_FEET; + } else { + target_alt = TargetAltitude; + target_agl = TargetAGL; + } + + target_alt = ( int ) ( target_alt / inc ) * inc + inc; + target_agl = ( int ) ( target_agl / inc ) * inc + inc; + + if ( current_options.get_units() == fgOPTIONS::FG_UNITS_FEET ) { + target_alt *= FEET_TO_METER; + target_agl *= FEET_TO_METER; + } + + TargetAltitude = target_alt; + TargetAGL = target_agl; + + if ( current_options.get_units() == fgOPTIONS::FG_UNITS_FEET ) + target_alt *= METER_TO_FEET; + // ApAltitudeDialogInput->setValue((float)target_alt); + MakeTargetAltitudeStr( target_alt ); + + update_old_control_values(); +} + + +void FGAutopilot::HeadingAdjust( double inc ) { + heading_mode = FG_HEADING_LOCK; + + double target = ( int ) ( TargetHeading / inc ) * inc + inc; + + TargetHeading = NormalizeDegrees( target ); + // following cast needed ambiguous plib + // ApHeadingDialogInput -> setValue ((float)TargetHeading ); + MakeTargetHeadingStr( TargetHeading ); + update_old_control_values(); +} + + +void FGAutopilot::HeadingSet( double new_heading ) { + heading_mode = FG_HEADING_LOCK; + + new_heading = NormalizeDegrees( new_heading ); + TargetHeading = new_heading; + // following cast needed ambiguous plib + // ApHeadingDialogInput -> setValue ((float)APData->TargetHeading ); + MakeTargetHeadingStr( TargetHeading ); + update_old_control_values(); +} + +void FGAutopilot::AutoThrottleAdjust( double inc ) { + double target = ( int ) ( TargetSpeed / inc ) * inc + inc; + + TargetSpeed = target; +} + + +void FGAutopilot::set_AutoThrottleEnabled( bool value ) { + auto_throttle = value; + + if ( auto_throttle = true ) { + TargetSpeed = FGBFI::getAirspeed(); + speed_error_accum = 0.0; + } + + update_old_control_values(); + FG_LOG( FG_COCKPIT, FG_INFO, " fgAPSetAutoThrottle: (" + << auto_throttle << ") " << TargetSpeed ); +} diff --git a/src/Autopilot/newauto.hxx b/src/Autopilot/newauto.hxx new file mode 100644 index 000000000..9a2db9f41 --- /dev/null +++ b/src/Autopilot/newauto.hxx @@ -0,0 +1,176 @@ +// newauto.hxx -- autopilot defines and prototypes (very alpha) +// +// Started April 1998 Copyright (C) 1998 +// +// Contributions by Jeff Goeke-Smith <jgoeke@voyager.net> +// Norman Vine <nhv@cape.com> +// Curtis Olson <curt@flightgear.org> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// +// $Id$ + + +#ifndef _NEWAUTO_HXX +#define _NEWAUTO_HXX + + +// Structures +class FGAutopilot { + +public: + + enum fgAutoHeadingMode { + FG_HEADING_LOCK = 0, + FG_HEADING_WAYPOINT = 1, + FG_HEADING_NAV1 = 2, + FG_HEADING_NAV2 = 3 + }; + + enum fgAutoAltitudeMode { + FG_ALTITUDE_LOCK = 0, + FG_ALTITUDE_TERRAIN = 1, + FG_ALTITUDE_GS1 = 2, + FG_ALTITUDE_GS2 = 3 + }; + +private: + + bool heading_hold; // the current state of the heading hold + bool altitude_hold; // the current state of the altitude hold + bool auto_throttle; // the current state of the auto throttle + + fgAutoHeadingMode heading_mode; + fgAutoAltitudeMode altitude_mode; + + double TargetLatitude; // the latitude the AP should steer to. + double TargetLongitude; // the longitude the AP should steer to. + double TargetDistance; // the distance to Target. + double TargetHeading; // the heading the AP should steer to. + double TargetAltitude; // altitude to hold + double TargetAGL; // the terrain separation + double TargetClimbRate; // climb rate to shoot for + double TargetSpeed; // speed to shoot for + double alt_error_accum; // altitude error accumulator + double speed_error_accum; // speed error accumulator + + double TargetSlope; // the glide slope hold value + + double MaxRoll ; // the max the plane can roll for the turn + double RollOut; // when the plane should roll out + // measured from Heading + double MaxAileron; // how far to move the aleroin from center + double RollOutSmooth; // deg to use for smoothing Aileron Control + double MaxElevator; // the maximum elevator allowed + double SlopeSmooth; // smoothing angle for elevator + + // following for testing disengagement of autopilot upon pilot + // interaction with controls + double old_aileron; + double old_elevator; + double old_elevator_trim; + double old_rudder; + + // manual controls override beyond this value + double disengage_threshold; + + // For future cross track error adjust + double old_lat; + double old_lon; + + // keeping these locally to save work inside main loop + char TargetLatitudeStr[64]; + char TargetLongitudeStr[64]; + char TargetLatLonStr[64]; + char TargetDistanceStr[64]; + char TargetHeadingStr[64]; + char TargetAltitudeStr[64]; + +public: + + // Initialize autopilot system + void init(); + + // Reset the autopilot system + void reset(void); + + // run an interation of the autopilot (updates control positions) + int run(); + + void AltitudeSet( double new_altitude ); + void AltitudeAdjust( double inc ); + void HeadingAdjust( double inc ); + void AutoThrottleAdjust( double inc ); + + void HeadingSet( double value ); + + inline bool get_HeadingEnabled() const { return heading_hold; } + inline void set_HeadingEnabled( bool value ) { heading_hold = value; } + inline fgAutoHeadingMode get_HeadingMode() const { return heading_mode; } + void set_HeadingMode( fgAutoHeadingMode mode ); + + inline bool get_AltitudeEnabled() const { return altitude_hold; } + inline void set_AltitudeEnabled( bool value ) { altitude_hold = value; } + inline fgAutoAltitudeMode get_AltitudeMode() const { return altitude_mode;} + void set_AltitudeMode( fgAutoAltitudeMode mode ); + + inline bool get_AutoThrottleEnabled() const { return auto_throttle; } + void set_AutoThrottleEnabled( bool value ); + + inline double get_TargetLatitude() const { return TargetLatitude; } + inline void set_TargetLatitude( double val ) { TargetLatitude = val; } + inline void set_old_lat( double val ) { old_lat = val; } + inline double get_TargetLongitude() const { return TargetLongitude; } + inline void set_TargetLongitude( double val ) { TargetLongitude = val; } + inline void set_old_lon( double val ) { old_lon = val; } + inline double get_TargetHeading() const { return TargetHeading; } + inline void set_TargetHeading( double val ) { TargetHeading = val; } + inline double get_TargetDistance() const { return TargetDistance; } + inline void set_TargetDistance( double val ) { TargetDistance = val; } + inline double get_TargetAltitude() const { return TargetAltitude; } + inline void set_TargetAltitude( double val ) { TargetAltitude = val; } + + inline char *get_TargetLatitudeStr() { return TargetLatitudeStr; } + inline char *get_TargetLongitudeStr() { return TargetLongitudeStr; } + inline char *get_TargetDistanceStr() { return TargetDistanceStr; } + inline char *get_TargetHeadingStr() { return TargetHeadingStr; } + inline char *get_TargetAltitudeStr() { return TargetAltitudeStr; } + inline char *get_TargetLatLonStr() { return TargetLatLonStr; } + + // utility functions + void MakeTargetLatLonStr( double lat, double lon ); + void MakeTargetAltitudeStr( double altitude ); + void MakeTargetHeadingStr( double bearing ); + void MakeTargetDistanceStr( double distance ); + void update_old_control_values(); + + // accessors + inline double get_MaxRoll() const { return MaxRoll; } + inline void set_MaxRoll( double val ) { MaxRoll = val; } + inline double get_RollOut() const { return RollOut; } + inline void set_RollOut( double val ) { RollOut = val; } + + inline double get_MaxAileron() const { return MaxAileron; } + inline void set_MaxAileron( double val ) { MaxAileron = val; } + inline double get_RollOutSmooth() const { return RollOutSmooth; } + inline void set_RollOutSmooth( double val ) { RollOutSmooth = val; } + +}; + + +extern FGAutopilot *current_autopilot; + + +#endif // _NEWAUTO_HXX diff --git a/src/Cockpit/hud.cxx b/src/Cockpit/hud.cxx index 0d773c8c9..cb2483355 100644 --- a/src/Cockpit/hud.cxx +++ b/src/Cockpit/hud.cxx @@ -48,6 +48,7 @@ #include <simgear/math/polar3d.hxx> #include <Aircraft/aircraft.hxx> +#include <Autopilot/newauto.hxx> #include <GUI/gui.h> #include <Main/options.hxx> #ifdef FG_NETWORK_OLK @@ -1284,30 +1285,35 @@ void fgUpdateHUD( void ) { // temporary - extern bool fgAPAltitudeEnabled( void ); - extern bool fgAPHeadingEnabled( void ); - extern bool fgAPWayPointEnabled( void ); - extern char *fgAPget_TargetDistanceStr( void ); - extern char *fgAPget_TargetHeadingStr( void ); - extern char *fgAPget_TargetAltitudeStr( void ); - extern char *fgAPget_TargetLatLonStr( void ); + // extern bool fgAPAltitudeEnabled( void ); + // extern bool fgAPHeadingEnabled( void ); + // extern bool fgAPWayPointEnabled( void ); + // extern char *fgAPget_TargetDistanceStr( void ); + // extern char *fgAPget_TargetHeadingStr( void ); + // extern char *fgAPget_TargetAltitudeStr( void ); + // extern char *fgAPget_TargetLatLonStr( void ); int apY = 480 - 80; // char scratch[128]; // HUD_TextList.add( fgText( "AUTOPILOT", 20, apY) ); // apY -= 15; - if( fgAPHeadingEnabled() ) { - HUD_TextList.add( fgText( 40, apY, fgAPget_TargetHeadingStr()) ); + if( current_autopilot->get_HeadingEnabled() ) { + HUD_TextList.add( fgText( 40, apY, + current_autopilot->get_TargetHeadingStr()) ); apY -= 15; } - if( fgAPAltitudeEnabled() ) { - HUD_TextList.add( fgText( 40, apY, fgAPget_TargetAltitudeStr()) ); + if( current_autopilot->get_AltitudeEnabled() ) { + HUD_TextList.add( fgText( 40, apY, + current_autopilot->get_TargetAltitudeStr()) ); apY -= 15; } - if( fgAPWayPointEnabled() ) { - HUD_TextList.add( fgText( 40, apY, fgAPget_TargetLatLonStr()) ); + if( current_autopilot->get_HeadingMode() == + FGAutopilot::FG_HEADING_WAYPOINT ) { + HUD_TextList.add( fgText( 40, apY, + current_autopilot->get_TargetLatLonStr()) ); apY -= 15; - HUD_TextList.add( fgText( 40, apY, fgAPget_TargetDistanceStr() ) ); + HUD_TextList.add( fgText( 40, apY, + current_autopilot->get_TargetDistanceStr() ) ); apY -= 15; } diff --git a/src/Cockpit/panel.cxx b/src/Cockpit/panel.cxx index 0774e63e0..eb9b478f7 100644 --- a/src/Cockpit/panel.cxx +++ b/src/Cockpit/panel.cxx @@ -38,7 +38,6 @@ #include <Main/views.hxx> #include <Main/bfi.hxx> #include <Objects/texload.h> -#include <Autopilot/autopilot.hxx> #include <Time/fg_time.hxx> #include "cockpit.hxx" @@ -46,8 +45,6 @@ #include "hud.hxx" #include "steam.hxx" -extern fgAPDataPtr APDataGlobal; - #define SIX_X 200 #define SIX_Y 345 #define SIX_W 128 diff --git a/src/Cockpit/steam.cxx b/src/Cockpit/steam.cxx index 0c82bd72f..e6b91ebe7 100644 --- a/src/Cockpit/steam.cxx +++ b/src/Cockpit/steam.cxx @@ -303,7 +303,7 @@ double FGSteam::get_HackVOR2_deg () { if ( current_radiostack->get_nav2_inrange() ) { r = current_radiostack->get_nav2_radial() - - current_radiostack->get_nav2_heading() + 180.0; + current_radiostack->get_nav2_heading(); // cout << "Radial = " << current_radiostack->get_nav1_radial() // << " Bearing = " << current_radiostack->get_nav1_heading() << endl; diff --git a/src/GUI/gui.cxx b/src/GUI/gui.cxx index 321e2c393..08e19fbc0 100644 --- a/src/GUI/gui.cxx +++ b/src/GUI/gui.cxx @@ -58,6 +58,8 @@ #include <Include/general.hxx> #include <Aircraft/aircraft.hxx> #include <Airports/simple.hxx> +#include <Autopilot/auto_gui.hxx> +#include <Autopilot/newauto.hxx> #include <Cockpit/panel.hxx> #include <Controls/controls.hxx> #include <FDM/flight.hxx> @@ -169,15 +171,15 @@ char *gui_msg_RESET; // "RESET" static char global_dialog_string[256]; // from autopilot.cxx -extern void NewAltitude( puObject *cb ); -extern void NewHeading( puObject *cb ); -extern void fgAPAdjust( puObject * ); -extern void NewTgtAirport( puObject *cb ); -bool fgAPTerrainFollowEnabled( void ); -bool fgAPAltitudeEnabled( void ); -bool fgAPHeadingEnabled( void ); -bool fgAPWayPointEnabled( void ); -bool fgAPAutoThrottleEnabled( void ); +// extern void NewAltitude( puObject *cb ); +// extern void NewHeading( puObject *cb ); +// extern void fgAPAdjust( puObject * ); +// extern void NewTgtAirport( puObject *cb ); +// bool fgAPTerrainFollowEnabled( void ); +// bool fgAPAltitudeEnabled( void ); +// bool fgAPHeadingEnabled( void ); +// bool fgAPWayPointEnabled( void ); +// bool fgAPAutoThrottleEnabled( void ); // from cockpit.cxx extern void fgLatLonFormatToggle( puObject *); @@ -398,20 +400,20 @@ void guiMotionFunc ( int x, int y ) offset = (_mY - y) * throttle_sensitivity; controls.move_throttle(FGControls::ALL_ENGINES, offset); } else if ( right_button() ) { - if( !fgAPHeadingEnabled() ) { + if( ! current_autopilot->get_HeadingEnabled() ) { offset = (x - _mX) * rudder_sensitivity; controls.move_rudder(offset); } - if( !fgAPAltitudeEnabled() ) { + if( ! current_autopilot->get_AltitudeEnabled() ) { offset = (_mY - y) * trim_sensitivity; controls.move_elevator_trim(offset); } } else { - if( !fgAPHeadingEnabled() ) { + if( ! current_autopilot->get_HeadingEnabled() ) { offset = (x - _mX) * aileron_sensitivity; controls.move_aileron(offset); } - if( !fgAPAltitudeEnabled() ) { + if( ! current_autopilot->get_AltitudeEnabled() ) { offset = (_mY - y) * elevator_sensitivity; controls.move_elevator(offset); } diff --git a/src/Main/bfi.cxx b/src/Main/bfi.cxx index 14b66bc9c..80dd3b95e 100644 --- a/src/Main/bfi.cxx +++ b/src/Main/bfi.cxx @@ -36,7 +36,7 @@ #include <Aircraft/aircraft.hxx> #include <Controls/controls.hxx> -#include <Autopilot/autopilot.hxx> +#include <Autopilot/newauto.hxx> #include <Scenery/scenery.hxx> #include <Time/fg_time.hxx> #include <Time/light.hxx> @@ -55,9 +55,9 @@ FG_USING_NAMESPACE(std); // FIXME: these are not part of the // published interface!!! -extern fgAPDataPtr APDataGlobal; -extern void fgAPAltitudeSet (double new_altitude); -extern void fgAPHeadingSet (double new_heading); +// extern fgAPDataPtr APDataGlobal; +// extern void fgAPAltitudeSet (double new_altitude); +// extern void fgAPHeadingSet (double new_heading); #include "bfi.hxx" @@ -671,7 +671,7 @@ FGBFI::setBrake (double brake) bool FGBFI::getAPAltitudeLock () { - return fgAPAltitudeEnabled(); + return current_autopilot->get_AltitudeEnabled(); } @@ -681,7 +681,8 @@ FGBFI::getAPAltitudeLock () void FGBFI::setAPAltitudeLock (bool lock) { - APDataGlobal->altitude_hold = lock; + current_autopilot->set_AltitudeEnabled( true ); + current_autopilot->set_AltitudeMode( FGAutopilot::FG_ALTITUDE_LOCK ); } @@ -691,7 +692,7 @@ FGBFI::setAPAltitudeLock (bool lock) double FGBFI::getAPAltitude () { - return fgAPget_TargetAltitude() * METER_TO_FEET; + return current_autopilot->get_TargetAltitude() * METER_TO_FEET; } @@ -701,7 +702,7 @@ FGBFI::getAPAltitude () void FGBFI::setAPAltitude (double altitude) { - fgAPAltitudeSet(altitude); + current_autopilot->set_TargetAltitude( altitude ); } @@ -711,7 +712,7 @@ FGBFI::setAPAltitude (double altitude) bool FGBFI::getAPHeadingLock () { - return fgAPHeadingEnabled(); + return current_autopilot->get_HeadingEnabled(); } @@ -721,7 +722,8 @@ FGBFI::getAPHeadingLock () void FGBFI::setAPHeadingLock (bool lock) { - APDataGlobal->heading_hold = lock; + current_autopilot->set_HeadingEnabled( true ); + current_autopilot->set_HeadingMode( FGAutopilot::FG_HEADING_LOCK ); } @@ -731,7 +733,7 @@ FGBFI::setAPHeadingLock (bool lock) double FGBFI::getAPHeading () { - return fgAPget_TargetHeading(); + return current_autopilot->get_TargetHeading(); } @@ -741,7 +743,7 @@ FGBFI::getAPHeading () void FGBFI::setAPHeading (double heading) { - fgAPHeadingSet(heading); + current_autopilot->set_TargetHeading( heading ); } @@ -883,7 +885,10 @@ FGBFI::setADFRotation (double rot) bool FGBFI::getGPSLock () { - return fgAPWayPointEnabled(); + return ( current_autopilot->get_HeadingEnabled() && + ( current_autopilot->get_HeadingMode() == + FGAutopilot::FG_HEADING_WAYPOINT ) + ); } @@ -893,7 +898,8 @@ FGBFI::getGPSLock () void FGBFI::setGPSLock (bool lock) { - APDataGlobal->waypoint_hold = lock; + current_autopilot->set_HeadingEnabled( true ); + current_autopilot->set_HeadingMode( FGAutopilot::FG_HEADING_WAYPOINT ); } @@ -923,7 +929,7 @@ FGBFI::setTargetAirport (const string &airportId) double FGBFI::getGPSTargetLatitude () { - return fgAPget_TargetLatitude(); + return current_autopilot->get_TargetLatitude(); } @@ -933,7 +939,7 @@ FGBFI::getGPSTargetLatitude () void FGBFI::setGPSTargetLatitude (double latitude) { - APDataGlobal->TargetLatitude = latitude; + current_autopilot->set_TargetLatitude( latitude ); } @@ -943,7 +949,7 @@ FGBFI::setGPSTargetLatitude (double latitude) double FGBFI::getGPSTargetLongitude () { - return fgAPget_TargetLongitude(); + return current_autopilot->get_TargetLongitude(); } @@ -953,7 +959,7 @@ FGBFI::getGPSTargetLongitude () void FGBFI::setGPSTargetLongitude (double longitude) { - APDataGlobal->TargetLongitude = longitude; + current_autopilot->set_TargetLongitude( longitude ); } diff --git a/src/Main/fg_init.cxx b/src/Main/fg_init.cxx index 43d48fe1a..9e34945f3 100644 --- a/src/Main/fg_init.cxx +++ b/src/Main/fg_init.cxx @@ -57,7 +57,8 @@ #include <Aircraft/aircraft.hxx> #include <Airports/simple.hxx> -#include <Autopilot/autopilot.hxx> +#include <Autopilot/auto_gui.hxx> +#include <Autopilot/newauto.hxx> #include <Cockpit/cockpit.hxx> #include <Cockpit/radiostack.hxx> #include <FDM/Balloon.h> @@ -527,8 +528,15 @@ bool fgInitSubsystems( void ) { FG_LOG( FG_GENERAL, FG_ALERT, "Error in Joystick initialization!" ); } - // Autopilot init added here, by Jeff Goeke-Smith - fgAPInit(¤t_aircraft); + // Autopilot init + current_autopilot = new FGAutopilot; + current_autopilot->init(); + + // initialize the gui parts of the autopilot + NewTgtAirportInit(); + fgAPAdjustInit() ; + NewHeadingInit(); + NewAltitudeInit(); // Initialize I/O channels #if ! defined( MACOS ) @@ -632,7 +640,7 @@ void fgReInitSubsystems( void ) } controls.reset_all(); - fgAPReset(); + current_autopilot->reset(); if( !toggle_pause ) t->togglePauseMode(); diff --git a/src/Main/keyboard.cxx b/src/Main/keyboard.cxx index 1e45b622d..60eb6a535 100644 --- a/src/Main/keyboard.cxx +++ b/src/Main/keyboard.cxx @@ -46,7 +46,7 @@ #include <simgear/misc/fgpath.hxx> #include <Aircraft/aircraft.hxx> -#include <Autopilot/autopilot.hxx> +#include <Autopilot/newauto.hxx> #include <Cockpit/hud.hxx> #include <GUI/gui.h> #include <Scenery/tilemgr.hxx> @@ -97,10 +97,18 @@ void GLUTkey(unsigned char k, int x, int y) { FG_LOG( FG_INPUT, FG_DEBUG, " SHIFTED" ); switch (k) { case 1: // Ctrl-A key - fgAPToggleAltitude(); + current_autopilot->set_AltitudeMode( + FGAutopilot::FG_ALTITUDE_LOCK ); + current_autopilot->set_AltitudeEnabled( + ! current_autopilot->get_AltitudeEnabled() + ); return; case 8: // Ctrl-H key - fgAPToggleHeading(); + current_autopilot->set_HeadingMode( + FGAutopilot::FG_HEADING_LOCK ); + current_autopilot->set_HeadingEnabled( + ! current_autopilot->get_HeadingEnabled() + ); return; case 18: // Ctrl-R key // temporary @@ -112,10 +120,16 @@ void GLUTkey(unsigned char k, int x, int y) { } return; case 19: // Ctrl-S key - fgAPToggleAutoThrottle(); + current_autopilot->set_AutoThrottleEnabled( + ! current_autopilot->get_AutoThrottleEnabled() + ); return; case 20: // Ctrl-T key - fgAPToggleTerrainFollow(); + current_autopilot->set_AltitudeMode( + FGAutopilot::FG_ALTITUDE_TERRAIN ); + current_autopilot->set_AltitudeEnabled( + ! current_autopilot->get_AltitudeEnabled() + ); return; case 21: // Ctrl-U key // add 1000' of emergency altitude. Possibly good for @@ -212,15 +226,15 @@ void GLUTkey(unsigned char k, int x, int y) { FG_LOG( FG_INPUT, FG_DEBUG, "" ); switch (k) { case 50: // numeric keypad 2 - if( fgAPAltitudeEnabled() || fgAPTerrainFollowEnabled() ) { - fgAPAltitudeAdjust( 100 ); + if ( current_autopilot->get_AltitudeEnabled() ) { + current_autopilot->AltitudeAdjust( 100 ); } else { controls.move_elevator(-0.05); } return; case 56: // numeric keypad 8 - if( fgAPAltitudeEnabled() || fgAPTerrainFollowEnabled() ) { - fgAPAltitudeAdjust( -100 ); + if ( current_autopilot->get_AltitudeEnabled() ) { + current_autopilot->AltitudeAdjust( -100 ); } else { controls.move_elevator(0.05); } @@ -238,15 +252,15 @@ void GLUTkey(unsigned char k, int x, int y) { controls.move_aileron(0.05); return; case 48: // numeric keypad Ins - if( fgAPHeadingEnabled() ) { - fgAPHeadingAdjust( -1 ); + if ( current_autopilot->get_HeadingEnabled() ) { + current_autopilot->HeadingAdjust( -1 ); } else { controls.move_rudder(-0.05); } return; case 13: // numeric keypad Enter - if( fgAPHeadingEnabled() ) { - fgAPHeadingAdjust( 1 ); + if ( current_autopilot->get_HeadingEnabled() ) { + current_autopilot->HeadingAdjust( 1 ); } else { controls.move_rudder(0.05); } @@ -257,15 +271,15 @@ void GLUTkey(unsigned char k, int x, int y) { controls.set_rudder(0.0); return; case 57: // numeric keypad 9 (Pg Up) - if( fgAPAutoThrottleEnabled() ) { - fgAPAutoThrottleAdjust( 5 ); + if ( current_autopilot->get_AutoThrottleEnabled() ) { + current_autopilot->AutoThrottleAdjust( 5 ); } else { controls.move_throttle( FGControls::ALL_ENGINES, 0.01 ); } return; case 51: // numeric keypad 3 (Pg Dn) - if( fgAPAutoThrottleEnabled() ) { - fgAPAutoThrottleAdjust( -5 ); + if ( current_autopilot->get_AutoThrottleEnabled() ) { + current_autopilot->AutoThrottleAdjust( -5 ); } else { controls.move_throttle( FGControls::ALL_ENGINES, -0.01 ); } @@ -455,7 +469,14 @@ void GLUTspecialkey(int k, int x, int y) { fgDumpSnapShot(); return; case GLUT_KEY_F6: // F6 toggles Autopilot target location - fgAPToggleWayPoint(); + if ( current_autopilot->get_HeadingMode() != + FGAutopilot::FG_HEADING_WAYPOINT ) { + current_autopilot->set_HeadingMode( + FGAutopilot::FG_HEADING_WAYPOINT ); + } else { + current_autopilot->set_HeadingMode( + FGAutopilot::FG_HEADING_LOCK ); + } return; case GLUT_KEY_F8: // F8 toggles fog ... off fastest nicest... current_options.cycle_fog(); @@ -503,15 +524,15 @@ void GLUTspecialkey(int k, int x, int y) { NewHeading( NULL ); return; case GLUT_KEY_UP: - if( fgAPAltitudeEnabled() || fgAPTerrainFollowEnabled() ) { - fgAPAltitudeAdjust( -100 ); + if ( current_autopilot->get_AltitudeEnabled() ) { + current_autopilot->AltitudeAdjust( -100 ); } else { controls.move_elevator(0.05); } return; case GLUT_KEY_DOWN: - if( fgAPAltitudeEnabled() || fgAPTerrainFollowEnabled() ) { - fgAPAltitudeAdjust( 100 ); + if ( current_autopilot->get_AltitudeEnabled() ) { + current_autopilot->AltitudeAdjust( 100 ); } else { controls.move_elevator(-0.05); } @@ -529,15 +550,15 @@ void GLUTspecialkey(int k, int x, int y) { controls.move_elevator_trim(-0.001); return; case GLUT_KEY_INSERT: // numeric keypad Ins - if( fgAPHeadingEnabled() ) { - fgAPHeadingAdjust( -1 ); + if ( current_autopilot->get_HeadingEnabled() ) { + current_autopilot->HeadingAdjust( -1 ); } else { controls.move_rudder(-0.05); } return; case 13: // numeric keypad Enter - if( fgAPHeadingEnabled() ) { - fgAPHeadingAdjust( 1 ); + if ( current_autopilot->get_HeadingEnabled() ) { + current_autopilot->HeadingAdjust( 1 ); } else { controls.move_rudder(0.05); } @@ -548,15 +569,15 @@ void GLUTspecialkey(int k, int x, int y) { controls.set_rudder(0.0); return; case GLUT_KEY_PAGE_UP: // numeric keypad 9 (Pg Up) - if( fgAPAutoThrottleEnabled() ) { - fgAPAutoThrottleAdjust( 5 ); + if ( current_autopilot->get_AutoThrottleEnabled() ) { + current_autopilot->AutoThrottleAdjust( 5 ); } else { controls.move_throttle( FGControls::ALL_ENGINES, 0.01 ); } return; case GLUT_KEY_PAGE_DOWN: // numeric keypad 3 (Pg Dn) - if( fgAPAutoThrottleEnabled() ) { - fgAPAutoThrottleAdjust( -5 ); + if ( current_autopilot->get_AutoThrottleEnabled() ) { + current_autopilot->AutoThrottleAdjust( -5 ); } else { controls.move_throttle( FGControls::ALL_ENGINES, -0.01 ); } diff --git a/src/Main/main.cxx b/src/Main/main.cxx index 503bf63b4..93131002c 100644 --- a/src/Main/main.cxx +++ b/src/Main/main.cxx @@ -76,7 +76,7 @@ #include <Aircraft/aircraft.hxx> #include <Ephemeris/ephemeris.hxx> -#include <Autopilot/autopilot.hxx> +#include <Autopilot/newauto.hxx> #include <Cockpit/cockpit.hxx> #include <Cockpit/radiostack.hxx> #include <Cockpit/steam.hxx> @@ -664,7 +664,7 @@ void fgUpdateTimeDepCalcs(int multi_loop, int remainder) { if ( !t->getPause() ) { // run Autopilot system - fgAPRun(); + current_autopilot->run(); // printf("updating flight model x %d\n", multi_loop); /* fgFDMUpdate( current_options.get_flight_model(),