]> git.mxchange.org Git - flightgear.git/blobdiff - Autopilot/autopilot.cxx
Converted fgFLIGHT to a class.
[flightgear.git] / Autopilot / autopilot.cxx
index 5803c5c6a7d890fc1610b936e198e6ee795479c5..46073ad7f821fd9e9076f6685aae65f2b0918d80 100644 (file)
 #include <assert.h>
 #include <stdlib.h>
 
-// #include <list>
-// #include <Include/fg_stl_config.h>
-
 #include <Scenery/scenery.hxx>
 
-// #ifdef NEEDNAMESPACESTD
-// using namespace std;
-// #endif
-
 #include "autopilot.hxx"
 
 #include <Include/fg_constants.h>
-#include <Debug/fg_debug.h>
-
-
-// static list < double > alt_error_queue;
+#include <Debug/logstream.hxx>
 
 
 // The below routines were copied right from hud.c ( I hate reinventing
 // They should eventually be member functions of the aircraft.
 //
 
-static double get_throttleval( void )
-{
-       fgCONTROLS *pcontrols;
-
-  pcontrols = current_aircraft.controls;
-  return pcontrols->throttle[0];     // Hack limiting to one engine
-}
-
-static double get_aileronval( void )
-{
-       fgCONTROLS *pcontrols;
-
-  pcontrols = current_aircraft.controls;
-  return pcontrols->aileron;
-}
-
-static double get_elevatorval( void )
-{
-       fgCONTROLS *pcontrols;
-
-  pcontrols = current_aircraft.controls;
-  return pcontrols->elevator;
-}
-
-static double get_elev_trimval( void )
-{
-       fgCONTROLS *pcontrols;
-
-  pcontrols = current_aircraft.controls;
-  return pcontrols->elevator_trim;
-}
-
-static double get_rudderval( void )
-{
-       fgCONTROLS *pcontrols;
-
-  pcontrols = current_aircraft.controls;
-  return pcontrols->rudder;
-}
 
 static double get_speed( void )
 {
        fgFLIGHT *f;
 
        f = current_aircraft.flight;
-       return( FG_V_equiv_kts );    // Make an explicit function call.
+       return( f->get_V_equiv_kts() );    // Make an explicit function call.
 }
 
 static double get_aoa( void )
@@ -110,7 +61,7 @@ static double get_aoa( void )
        fgFLIGHT *f;
               
        f = current_aircraft.flight;
-       return( FG_Gamma_vert_rad * RAD_TO_DEG );
+       return( f->get_Gamma_vert_rad() * RAD_TO_DEG );
 }
 
 static double fgAPget_roll( void )
@@ -118,7 +69,7 @@ static double fgAPget_roll( void )
        fgFLIGHT *f;
 
        f = current_aircraft.flight;
-       return( FG_Phi * RAD_TO_DEG );
+       return( f->get_Phi() * RAD_TO_DEG );
 }
 
 static double get_pitch( void )
@@ -126,7 +77,7 @@ static double get_pitch( void )
        fgFLIGHT *f;
               
        f = current_aircraft.flight;
-       return( FG_Theta );
+       return( f->get_Theta() );
 }
 
 double fgAPget_heading( void )
@@ -134,7 +85,7 @@ double fgAPget_heading( void )
        fgFLIGHT *f;
 
        f = current_aircraft.flight;
-       return( FG_Psi * RAD_TO_DEG );
+       return( f->get_Psi() * RAD_TO_DEG );
 }
 
 static double fgAPget_altitude( void )
@@ -143,7 +94,7 @@ static double fgAPget_altitude( void )
 
        f = current_aircraft.flight;
 
-       return( FG_Altitude * FEET_TO_METER /* -rough_elev */ );
+       return( f->get_Altitude() * FEET_TO_METER /* -rough_elev */ );
 }
 
 static double fgAPget_climb( void )
@@ -153,7 +104,7 @@ static double fgAPget_climb( void )
        f = current_aircraft.flight;
 
        // return in meters per minute
-       return( FG_Climb_Rate * FEET_TO_METER * 60 );
+       return( f->get_Climb_Rate() * FEET_TO_METER * 60 );
 }
 
 static double get_sideslip( void )
@@ -162,7 +113,7 @@ static double get_sideslip( void )
         
         f = current_aircraft.flight;
         
-        return( FG_Beta );
+        return( f->get_Beta() );
 }
 
 static double fgAPget_agl( void )
@@ -171,7 +122,7 @@ static double fgAPget_agl( void )
         double agl;
 
         f = current_aircraft.flight;
-        agl = FG_Altitude * FEET_TO_METER - scenery.cur_elev;
+        agl = f->get_Altitude() * FEET_TO_METER - scenery.cur_elev;
 
         return( agl );
 }
@@ -194,12 +145,15 @@ void fgAPInit( fgAIRCRAFT *current_aircraft )
 {
        fgAPDataPtr APData ;
 
-       fgPrintf( FG_AUTOPILOT, FG_INFO, "Init AutoPilot Subsystem\n" );
+       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
-               fgPrintf( FG_AUTOPILOT, FG_EXIT,"No ram for Autopilot. Dying.\n");
+       if (APData == NULL) {
+           // I couldn't get the mem.  Dying
+           FG_LOG( FG_AUTOPILOT, FG_ALERT, "No ram for Autopilot. Dying.");
+           exit(-1);
+       }
                
        APData->heading_hold = 0 ;     // turn the heading hold off
        APData->altitude_hold = 0 ;    // turn the altitude hold off
@@ -242,7 +196,7 @@ int fgAPRun( void )
        // figure out how far off we are from desired heading
                  
        // Now it is time to deterime how far we should be rolled.
-       fgPrintf( FG_AUTOPILOT, FG_DEBUG, "RelHeading: %f\n", RelHeading);
+       FG_LOG( FG_AUTOPILOT, FG_DEBUG, "RelHeading: " << RelHeading );
                
                
        // Check if we are further from heading than the roll out point
@@ -271,7 +225,7 @@ int fgAPRun( void )
 
        // Compare Target roll to Current Roll, Generate Rel Roll
 
-       fgPrintf( FG_COCKPIT, FG_BULK, "TargetRoll: %f\n", TargetRoll);
+       FG_LOG( FG_COCKPIT, FG_BULK, "TargetRoll: " << TargetRoll );
                
        RelRoll = NormalizeDegrees(TargetRoll - fgAPget_roll());
 
@@ -290,65 +244,105 @@ int fgAPRun( void )
                                            APData->MaxAileron );
        }
                
-       fgAileronSet(AileronSet);
-       fgRudderSet(0.0);
+       controls.set_aileron( AileronSet );
+       controls.set_rudder( 0.0 );
     }
 
-    // altitude hold enabled?
-    if ( APData->altitude_hold == 1 ) {
-       double error, size;
+    // altitude hold or terrain follow enabled?
+    if ( (APData->altitude_hold == 1) || (APData->terrain_follow == 1) ) {
+       double speed, max_climb, error;
        double prop_error, int_error;
        double prop_adj, int_adj, total_adj;
 
-       // normal altitude hold
-       APData->TargetClimbRate = 
-           (APData->TargetAltitude - fgAPget_altitude()) * 12.0;
+       if (APData->altitude_hold == 1) {
+           // normal altitude hold
+           APData->TargetClimbRate = 
+               (APData->TargetAltitude - fgAPget_altitude()) * 8.0;
+       } else if (APData->terrain_follow == 1) {
+           // brain dead ground hugging with no look ahead
+           APData->TargetClimbRate = 
+               ( APData->TargetAGL - fgAPget_agl() ) * 16.0;
+       } else {
+           // just try to zero out rate of climb ...
+           APData->TargetClimbRate = 0.0;
+       }
 
-       // brain dead ground hugging with no look ahead
-       // APData->TargetClimbRate = ( 500 - fgAPget_agl() ) * 12.0;
+       speed = get_speed();
 
-       // just try to zero out rate of climb ...
-       // APData->TargetClimbRate = 0.0;
+       if ( speed < 90.0 ) {
+           max_climb = 0.0;
+       } else if ( speed < 100.0 ) {
+           max_climb = (speed - 90.0) * 20;
+       } else {
+           max_climb = ( speed - 100.0 ) * 4.0 + 200.0;
+       }
 
-       if ( APData->TargetClimbRate > 200.0 ) {
-           APData->TargetClimbRate = 200.0;
+       if ( APData->TargetClimbRate > max_climb ) {
+           APData->TargetClimbRate = max_climb;
        }
-       if ( APData->TargetClimbRate < -200.0 ) {
-           APData->TargetClimbRate = -200.0;
+
+       if ( APData->TargetClimbRate < -400.0 ) {
+           APData->TargetClimbRate = -400.0;
        }
 
        error = fgAPget_climb() - APData->TargetClimbRate;
 
-       // push current error onto queue and add into accumulator
-       // alt_error_queue.push_back(error);
+       // accumulate the error under the curve ... this really should
+       // be *= delta t
        APData->alt_error_accum += error;
 
-       // if queue size larger than 60 ... pop front and subtract
-       // from accumulator
-       // size = alt_error_queue.size();
-       // if ( size > 300 ) {
-           // APData->alt_error_accum -= alt_error_queue.front();
-           // alt_error_queue.pop_front();
-           // size--;
-       // }
-
        // 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 / 1500.0;
+       // 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.5 ) { total_adj =  0.5; }
-       if ( total_adj < -0.3 ) { total_adj = -0.3; }
+       if ( total_adj >  0.6 ) { total_adj =  0.6; }
+       if ( total_adj < -0.2 ) { total_adj = -0.2; }
 
-       fgElevSet( total_adj );
+       controls.set_elevator( total_adj );
     }
 
-    /*
+    // auto throttle enabled?
+    if ( APData->auto_throttle == 1 ) {
+       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;
+       }
+       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; }
+       if ( total_adj < 0.0 ) { total_adj = 0.0; }
+
+       controls.set_throttle( fgCONTROLS::FG_ALL_ENGINES, total_adj );
+    }
+
+     /*
     if (APData->Mode == 2) // Glide slope hold
     {
        double RelSlope;
@@ -412,9 +406,8 @@ void fgAPToggleHeading( void )
        APData->TargetHeading = fgAPget_heading();
     }
 
-    fgPrintf( FG_COCKPIT, FG_INFO, " fgAPSetHeading: (%d) %.2f\n",
-             APData->heading_hold,
-             APData->TargetHeading);
+    FG_LOG( FG_COCKPIT, FG_INFO, " fgAPSetHeading: (" 
+           << APData->heading_hold << ") " << APData->TargetHeading );
 }
                 
 
@@ -432,18 +425,63 @@ void fgAPToggleAltitude( void )
     } else {
        // turn on altitude hold, lock at current altitude
        APData->altitude_hold = 1;
+       APData->terrain_follow = 0;
        APData->TargetAltitude = fgAPget_altitude();
        APData->alt_error_accum = 0.0;
        // alt_error_queue.erase( alt_error_queue.begin(), 
        //                        alt_error_queue.end() );
     }
 
-    fgPrintf( FG_COCKPIT, FG_INFO, " fgAPSetAltitude: (%d) %.2f\n",
-             APData->altitude_hold,
-             APData->TargetAltitude);
+    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 = 0;
+    } else {
+       // turn on terrain follow, lock at current agl
+       APData->auto_throttle = 1;
+       APData->TargetSpeed = get_speed();
+       APData->speed_error_accum = 0.0;
+    }
+
+    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 = 0;
+    } else {
+       // turn on terrain follow, lock at current agl
+       APData->terrain_follow = 1;
+       APData->altitude_hold = 0;
+       APData->TargetAGL = fgAPget_agl();
+       APData->alt_error_accum = 0.0;
+    }
+
+    FG_LOG( FG_COCKPIT, FG_INFO, " fgAPSetTerrainFollow: ("
+           << APData->terrain_follow << ") " << APData->TargetAGL );
+}
+
 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