JSBSim Flight Dynamics Model 1.0 (23 February 2013)
An Open Source Flight Dynamics and Control Software Library in C++

FGTrimAnalysis.h

00001 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00002 
00003  Header:       FGTrimAnalysis.h
00004  Author:       Agostino De Marco
00005  Date started: Dec/14/2006
00006 
00007  ------------- Copyright (C) 2006  Agostino De Marco (agodemar@unina.it) -------
00008 
00009  This program is free software; you can redistribute it and/or modify it under
00010  the terms of the GNU Lesser General Public License as published by the Free Software
00011  Foundation; either version 2 of the License, or (at your option) any later
00012  version.
00013 
00014  This program is distributed in the hope that it will be useful, but WITHOUT
00015  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00016  FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
00017  details.
00018 
00019  You should have received a copy of the GNU Lesser General Public License along with
00020  this program; if not, write to the Free Software Foundation, Inc., 59 Temple
00021  Place - Suite 330, Boston, MA  02111-1307, USA.
00022 
00023  Further information about the GNU Lesser General Public License can also be found on
00024  the world wide web at http://www.gnu.org.
00025 
00026 
00027  HISTORY
00028 --------------------------------------------------------------------------------
00029 12/14/06   ADM   Created
00030 
00031 
00032 FUNCTIONAL DESCRIPTION
00033 --------------------------------------------------------------------------------
00034 
00035 This class takes the given set of IC's and analyzes the possible trim states
00036 of the aircraft, i.e. finds the aircraft state required to
00037 maintain a specified flight condition.  This flight condition can be
00038 steady-level, a steady turn, a pull-up or pushover.
00039 It is implemented using an iterative, direct search of a cost function minimum.
00040 
00041 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00042 SENTRY
00043 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
00044 
00045 #ifndef FGTRIMANAlYSIS_H
00046 #define FGTRIMANAlYSIS_H
00047 
00048 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00049 INCLUDES
00050 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
00051 
00052 #include "FGFDMExec.h"
00053 #include "FGJSBBase.h"
00054 #include "FGTrimAnalysisControl.h"
00055 
00056 #include "models/FGAtmosphere.h"
00057 #include "initialization/FGInitialCondition.h"
00058 #include "models/FGAircraft.h"
00059 #include "models/FGMassBalance.h"
00060 #include "models/FGGroundReactions.h"
00061 #include "models/FGInertial.h"
00062 #include "models/FGAerodynamics.h"
00063 #include "math/FGColumnVector3.h"
00064 #include "models/FGAuxiliary.h"
00065 #include "models/FGPropulsion.h"
00066 
00067 #include <vector>
00068 #include <map>
00069 #include <string>
00070 
00071 #include "math/direct_search/vec.h"
00072 
00073 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00074 DEFINITIONS
00075 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
00076 
00077 #define ID_FGTRIMANALYSIS "$Id: FGTrimAnalysis.h,v 1.8 2009/10/02 10:30:09 jberndt Exp $"
00078 
00079 #if defined(_WIN32) && !defined(__CYGWIN__)
00080   #define snprintf _snprintf
00081 #endif
00082 
00083 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00084 FORWARD DECLARATIONS
00085 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
00086 
00087 namespace JSBSim {
00088 
00089 typedef enum { taLongitudinal=0, taFull, taFullWingsLevel, taTurn, taPullup, taTurnFull,
00090                 taGround, taCustom, taNone } TrimAnalysisMode;
00091 
00092 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00093 CLASS DOCUMENTATION
00094 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
00095 
00123 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00124 CLASS DECLARATION
00125 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
00126 
00127 class FGTrimAnalysis;
00128 
00129 class Objective {
00130 public:
00133     Objective(FGFDMExec* fdmex, FGTrimAnalysis* ta, double x);
00136     ~Objective() {}
00137 
00145     void CostFunctionFull                (long vars, Vector<double> &v, double & f);
00153     void CostFunctionFullWingsLevel      (long vars, Vector<double> &v, double & f);
00161     void CostFunctionLongitudinal        (long vars, Vector<double> &v, double & f);
00169     void CostFunctionFullTurn (long vars, Vector<double> &v, double & f);
00177     void CostFunctionFullCoordinatedTurn (long vars, Vector<double> &v, double & f);
00178 
00186     void CostFunctionPullUp              (long vars, Vector<double> &v, double & f);
00187 
00200     friend void find_CostFunctionFull(long vars, Vector<double> &v, double & f,
00201                     bool & success, void* t_ptr);
00202     /* function definiation moved outside of class declaration */
00203 
00216     friend void find_CostFunctionFullWingsLevel(long vars, Vector<double> &v, double & f,
00217                     bool & success, void* t_ptr);
00218     /* function definiation moved outside of class declaration */
00219 
00232     friend void find_CostFunctionLongitudinal(long vars, Vector<double> &v, double & f,
00233                     bool & success, void* t_ptr);
00234     /* function definiation moved outside of class declaration */
00235 
00248     friend void find_CostFunctionFullCoordinatedTurn(long vars, Vector<double> &v, double & f,
00249                     bool & success, void* t_ptr);
00250     /* function definiation moved outside of class declaration */
00251 
00264     friend void find_CostFunctionFullTurn(long vars, Vector<double> &v, double & f,
00265                     bool & success, void* t_ptr);
00266     /* function definiation moved outside of class declaration */
00267 
00280     friend void find_CostFunctionPullUp(long vars, Vector<double> &v, double & f,
00281                     bool & success, void* t_ptr);
00282     /* function definiation moved outside of class declaration */
00283 
00284     void Set_x_val(double new_x);
00285     double Get_x_val() const {return _x;}
00286 
00289     typedef void (*PF)(long vars, Vector<double> &v, double & f, bool & success, void* t_ptr);
00290 
00291     map<TrimAnalysisMode,PF> mpCostFunctions; // primordial...
00292 
00293 private:
00297     void calculateDottedStates(double delta_cmd_T, double delta_cmd_E, double delta_cmd_A, double delta_cmd_R,
00298                                double phi, double theta, double psi,
00299                                TrimAnalysisMode trimMode,
00300                                double& alpha, double& beta, double& gamma,
00301                                //FGColumnVector3& vUVW, FGColumnVector3& vPQR,
00302                                FGPropagate::VehicleState& VState,
00303                                FGColumnVector3& vUVWdot, FGColumnVector3& vPQRdot );
00304 
00307     double myCostFunctionFull                  (Vector<double> & vec1);
00310     double myCostFunctionFullWingsLevel        (Vector<double> & vec1);
00313     double myCostFunctionLongitudinal          (Vector<double> & vec1);
00316     double myCostFunctionFullCoordinatedTurn   (Vector<double> & vec1);
00319     double myCostFunctionFullTurn              (Vector<double> & vec1);
00322     double myCostFunctionPullUp                (Vector<double> & vec1);
00323 
00324     double _x;
00325     FGFDMExec* FDMExec;
00326     FGTrimAnalysis* TrimAnalysis;
00327 };
00328 
00329 
00330 class FGTrimAnalysis : public FGJSBBase, public FGXMLFileRead
00331 {
00332 private:
00333   vector<FGTrimAnalysisControl*> vTrimAnalysisControls;
00334   double cost_function_value;
00335   unsigned int current_ctrl;
00336   int N, Nsub;
00337   TrimAnalysisMode mode;
00338   int DebugLevel, Debug;
00339 
00340   double dth;
00341   bool trimudot;
00342   bool gamma_fallback;
00343 
00344   bool trim_failed;
00345   unsigned int ctrl_count;
00346 
00347   FGFDMExec* fdmex;
00348   FGInitialCondition * fgic; // IC;
00349 
00350   FGAuxiliary *        Auxiliary;
00351   FGAerodynamics *     Aerodynamics;
00352   FGPropulsion *       Propulsion;
00353   FGFCS *              FCS;
00354 
00355   vector<double> vAlphaDeg, vAlphaTrimDeg; // DEG !!!
00356   vector<double> vCL, vCD, vCm;
00357   vector<double> vCLE, vCDE, vCmE;
00358   vector<vector <double> > mCL, mCD, mCm, mTa;
00359   vector<double> vThrottleCmd, vElevatorCmd;
00360   vector<double> vVn, vTn, vTa, vVnE, vTE;
00361   vector<double> vCt, vCq, vRPM;
00362   vector<vector <double> > mCt, mCq, mRPM;
00363   vector<bool> hasThrustTrim, hasCmTrim;
00364 
00365   string trim_id;
00366 
00367   // direct search stuff
00368   string search_type;
00369   double sigma_nm, alpha_nm, beta_nm, gamma_nm;
00370   double initial_step;
00371   double tolerance;
00372   string stop_criterion;
00373   int max_iterations;
00374   int total_its;
00375 
00376   // results file
00377   mutable ofstream rf; // see Stroustrup 10.2.7.2; alternative: use a cache struct
00378   string rf_name;
00379 
00380   double _u,_v,_w;
00381   double _p,_q,_r;
00382   //double uw,vw,ww;
00383   //double vnorth,veast,vdown;
00384   //double wnorth,weast,wdown;
00385   double _alpha, _beta, _theta, _phi, _psi, _psiW, _gamma, _phiW;
00386 
00387   double _stheta, _sphi, _spsi;
00388   double _ctheta, _cphi, _cpsi;
00389 
00390   double _vtIC, _hIC, _gammaIC, _rocIC, _vdownIC, _psiIC, _psigtIC, _vgIC,
00391          _vnorthIC, _veastIC, wnorthIC, _weastIC, _wdownIC;
00392 
00393   double _udot, _vdot, _wdot, _pdot, _qdot, _rdot;
00394   double _targetNlf;
00395   double _psiWdot, _phiWdot, _gammadot, _psidot, _thetadot;
00396 
00397   double C1, C2, C3, _calpha, _salpha, _cbeta, _sbeta;
00398 
00399   void setupPullup(void);
00400   void setupTurn(void);
00401   void setupTurn(double phiW); // recalculate target Nlf
00402   void setupTurnPhi(double psi, double theta); // recalculate only phi
00403 
00404   void updateRates(void);
00405 
00406   void setDebug(void);
00407 
00408   bool ensureRunning(void);
00409   bool ensureRunning(unsigned int i);
00410   bool runForAWhile(int nruns);
00411 
00412   bool populateVecAlphaDeg(double vmin, double vmax, int n);
00413   bool populateVecThrottleCmd(double vmin, double vmax, int n);
00414   bool populateVecElevatorCmd(double vmin, double vmax, int n);
00415 
00416   bool calculateAerodynamics(
00417                            double dE_cmd,
00418                            double Vt,
00419                            double alpha_deg,
00420                            double altitude,
00421                            double rho,
00422                            double S, double mac, double bw,
00423                            double& CL, double& CD, double& Cm);
00424 
00425 
00426   bool getSteadyState(int nrepeat);
00427   bool InitializeTrimControl(double default_value, Element* el,
00428                                            string unit, TaControl type);
00429 
00430 public:
00435   FGTrimAnalysis(FGFDMExec *FDMExec, TrimAnalysisMode tam=taFull );
00436 
00438   ~FGTrimAnalysis(void);
00439 
00440   friend class Objective;
00441 
00446   bool Load(string fname, bool useStoredPath = true );
00447 
00450   bool DoTrim(void);
00451 
00457   void Report(void);
00458 
00461   void TrimStats();
00462 
00468   bool SetResultsFile(string name);
00469 
00473   ofstream* GetResultsFile() const { if (rf.is_open()) return &rf; else return 0; } // const_cast<ofstream*>(&rf) (if rf is not mutable)
00474 
00478   inline void SetCostFunctionValue(double value){cost_function_value = value;}
00479 
00482   inline double GetCostFunctionValue() const { return cost_function_value;}
00483 
00490   void SetMode(TrimAnalysisMode tam);
00491 
00495   inline TrimAnalysisMode GetMode() const { return mode;};
00496 
00497   inline vector<FGTrimAnalysisControl*>* GetControls(){return &vTrimAnalysisControls;}
00498 
00505   void ClearControls(void);
00506 
00515   bool AddControl( TaControl control );
00516 
00521   bool RemoveControl( TaControl control );
00522 
00530   bool EditState( TaControl new_control, double new_initvalue, double new_step, double new_min, double new_max );
00531 
00532 
00536   inline double GetGamma() { return _gamma; }
00537 
00543   inline void SetGammaFallback(bool bb) { gamma_fallback=bb; }
00544 
00548   inline bool GetGammaFallback(void) { return gamma_fallback; }
00549 
00555   inline void SetMaxCycles(int ii) { max_iterations = ii; }
00556 
00563   inline void SetTolerance(double tt) {
00564     tolerance = tt;
00565   }
00569   inline double GetTolerance(void) {return tolerance; }
00570 
00574   inline void SetTrimFailed(bool tf) { trim_failed = tf; }
00578   inline bool GetTrimFailed(void) { return trim_failed; }
00579   inline void SetTrimSuccessfull() { trim_failed = false; }
00580 
00581 
00596   void SetState(double u0, double v0, double w0, double p0, double q0, double r0,
00597                 double alpha0, double beta0, double phi0, double theta0, double psi0, double gamma0);
00598 
00601   void SetEulerAngles(double phi0, double theta0, double psi0);
00602 
00606   double GetPhiRad  (){ return _phi;}
00610   double GetThetaRad(){ return _theta;}
00614   double GetPsiRad  (){ return _psi;}
00615 
00619   double GetPhiWRad  (){ return _phiW;}
00623   double GetGammaRad (){ return _gamma;}
00627   double GetVtFps    (){ return _vtIC;}
00628 
00632   void CalculatePhiWFromTargetNlfTurn(double nlf);
00633 
00638   FGColumnVector3 UpdateRatesTurn(double psi, double theta, double phi, double phiW);
00639 
00643   FGColumnVector3 UpdateRatesPullup(void);
00644 
00647   void SetDottedValues(double udot, double vdot, double wdot, double pdot, double qdot, double rdot);
00648 
00653   inline void SetDebug(int level) { DebugLevel = level; }
00654   inline void ClearDebug(void) { DebugLevel = 0; }
00655 
00658   inline void SetTargetNlf(double nlf) { _targetNlf=nlf; }
00659 
00663   inline double GetTargetNlf(void) { return _targetNlf; }
00664 
00665   //void eom_costf (long vars, Vector<double> &x, double & f, bool& flag, void* an_obj);
00666   //inline FGFDMExec* GetFDMExec() const { return fdmex; }
00667 
00668 };
00669 }
00670 
00671 #endif