LCOV - code coverage report
Current view: top level - home/jon/JSBSim/src - FGFDMExec.cpp (source / functions) Hit Total Coverage
Test: JSBSim-Coverage-Statistics Lines: 323 512 63.1 %
Date: 2010-08-24 Functions: 19 36 52.8 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 116 308 37.7 %

           Branch data     Line data    Source code
       1                 :            : /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
       2                 :            : 
       3                 :            :  Module:       FGFDMExec.cpp
       4                 :            :  Author:       Jon S. Berndt
       5                 :            :  Date started: 11/17/98
       6                 :            :  Purpose:      Schedules and runs the model routines.
       7                 :            : 
       8                 :            :  ------------- Copyright (C) 1999  Jon S. Berndt (jon@jsbsim.org) -------------
       9                 :            : 
      10                 :            :  This program is free software; you can redistribute it and/or modify it under
      11                 :            :  the terms of the GNU Lesser General Public License as published by the Free Software
      12                 :            :  Foundation; either version 2 of the License, or (at your option) any later
      13                 :            :  version.
      14                 :            : 
      15                 :            :  This program is distributed in the hope that it will be useful, but WITHOUT
      16                 :            :  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
      17                 :            :  FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
      18                 :            :  details.
      19                 :            : 
      20                 :            :  You should have received a copy of the GNU Lesser General Public License along with
      21                 :            :  this program; if not, write to the Free Software Foundation, Inc., 59 Temple
      22                 :            :  Place - Suite 330, Boston, MA  02111-1307, USA.
      23                 :            : 
      24                 :            :  Further information about the GNU Lesser General Public License can also be found on
      25                 :            :  the world wide web at http://www.gnu.org.
      26                 :            : 
      27                 :            : FUNCTIONAL DESCRIPTION
      28                 :            : --------------------------------------------------------------------------------
      29                 :            : 
      30                 :            : This class wraps up the simulation scheduling routines.
      31                 :            : 
      32                 :            : HISTORY
      33                 :            : --------------------------------------------------------------------------------
      34                 :            : 11/17/98   JSB   Created
      35                 :            : 
      36                 :            : %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      37                 :            : COMMENTS, REFERENCES,  and NOTES
      38                 :            : %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      39                 :            : 
      40                 :            : %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      41                 :            : INCLUDES
      42                 :            : %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
      43                 :            : 
      44                 :            : #include "FGFDMExec.h"
      45                 :            : #include "models/FGAtmosphere.h"
      46                 :            : #include "models/atmosphere/FGMSIS.h"
      47                 :            : #include "models/atmosphere/FGMars.h"
      48                 :            : #include "models/FGFCS.h"
      49                 :            : #include "models/FGPropulsion.h"
      50                 :            : #include "models/FGMassBalance.h"
      51                 :            : #include "models/FGGroundReactions.h"
      52                 :            : #include "models/FGExternalReactions.h"
      53                 :            : #include "models/FGBuoyantForces.h"
      54                 :            : #include "models/FGAerodynamics.h"
      55                 :            : #include "models/FGInertial.h"
      56                 :            : #include "models/FGAircraft.h"
      57                 :            : #include "models/FGPropagate.h"
      58                 :            : #include "models/FGAuxiliary.h"
      59                 :            : #include "models/FGInput.h"
      60                 :            : #include "models/FGOutput.h"
      61                 :            : #include "initialization/FGInitialCondition.h"
      62                 :            : //#include "initialization/FGTrimAnalysis.h" // Remove until later
      63                 :            : #include "input_output/FGPropertyManager.h"
      64                 :            : #include "input_output/FGScript.h"
      65                 :            : 
      66                 :            : #include <iostream>
      67                 :            : #include <iterator>
      68                 :            : #include <cstdlib>
      69                 :            : 
      70                 :            : using namespace std;
      71                 :            : 
      72                 :            : namespace JSBSim {
      73                 :            : 
      74                 :            : static const char *IdSrc = "$Id: FGFDMExec.cpp,v 1.80 2010/08/21 22:56:10 jberndt Exp $";
      75                 :            : static const char *IdHdr = ID_FDMEXEC;
      76                 :            : 
      77                 :            : /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      78                 :            : GLOBAL DECLARATIONS
      79                 :            : %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
      80                 :            : 
      81                 :            : unsigned int FGFDMExec::FDMctr = 0;
      82                 :            : FGPropertyManager* FGFDMExec::master=0;
      83                 :            : 
      84                 :            : /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      85                 :            : CLASS IMPLEMENTATION
      86                 :            : %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
      87                 :            : 
      88                 :         52 : void checkTied ( FGPropertyManager *node )
      89                 :            : {
      90                 :        104 :   int N = node->nChildren();
      91                 :         52 :   string name;
      92                 :            : 
      93         [ +  + ]:        751 :   for (int i=0; i<N; i++) {
      94         [ +  + ]:        699 :     if (node->getChild(i)->nChildren() ) {
      95                 :         51 :       checkTied( (FGPropertyManager*)node->getChild(i) );
      96                 :            :     }
      97         [ +  + ]:        699 :     if ( node->getChild(i)->isTied() ) {
      98                 :       1302 :       name = ((FGPropertyManager*)node->getChild(i))->GetFullyQualifiedName();
      99                 :        651 :       node->Untie(name);
     100                 :            :     }
     101                 :         52 :   }
     102                 :         52 : }
     103                 :            : 
     104                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     105                 :            : // Constructor
     106                 :            : 
     107                 :          1 : FGFDMExec::FGFDMExec(FGPropertyManager* root) : Root(root)
     108                 :            : {
     109                 :            : 
     110                 :          1 :   Frame           = 0;
     111                 :          1 :   Error           = 0;
     112                 :          1 :   GroundCallback  = 0;
     113                 :          1 :   Atmosphere      = 0;
     114                 :          1 :   FCS             = 0;
     115                 :          1 :   Propulsion      = 0;
     116                 :          1 :   MassBalance     = 0;
     117                 :          1 :   Aerodynamics    = 0;
     118                 :          1 :   Inertial        = 0;
     119                 :          1 :   GroundReactions = 0;
     120                 :          1 :   ExternalReactions = 0;
     121                 :          1 :   BuoyantForces   = 0;
     122                 :          1 :   Aircraft        = 0;
     123                 :          1 :   Propagate       = 0;
     124                 :          1 :   Auxiliary       = 0;
     125                 :          1 :   Input           = 0;
     126                 :          1 :   IC              = 0;
     127                 :          1 :   Trim            = 0;
     128                 :          1 :   Script          = 0;
     129                 :            : 
     130                 :          1 :   RootDir = "";
     131                 :            : 
     132                 :          1 :   modelLoaded = false;
     133                 :          1 :   IsChild = false;
     134                 :          1 :   holding = false;
     135                 :          1 :   Terminate = false;
     136                 :            : 
     137                 :          1 :   sim_time = 0.0;
     138                 :          1 :   dT = 1.0/120.0; // a default timestep size. This is needed for when JSBSim is
     139                 :            :                   // run in standalone mode with no initialization file.
     140                 :            : 
     141                 :          1 :   IdFDM = FDMctr; // The main (parent) JSBSim instance is always the "zeroth"
     142                 :          1 :   FDMctr++;       // instance. "child" instances are loaded last.
     143                 :            : 
     144                 :            :   try {
     145                 :          1 :     char* num = getenv("JSBSIM_DEBUG");
     146 [ -  + ][ #  # ]:          1 :     if (num) debug_lvl = atoi(num); // set debug level
     147                 :            :   } catch (...) {               // if error set to 1
     148                 :            :     debug_lvl = 1;
     149                 :            :   }
     150                 :            : 
     151 [ +  - ][ #  # ]:          1 :   if (Root == 0) {
     152 [ +  - ][ #  # ]:          1 :     if (master == 0)
     153                 :          2 :       master = new FGPropertyManager;
     154                 :          1 :     Root = master;
     155                 :            :   }
     156                 :            : 
     157                 :          1 :   instance = Root->GetNode("/fdm/jsbsim",IdFDM,true);
     158                 :          1 :   Debug(0);
     159                 :            :   // this is to catch errors in binding member functions to the property tree.
     160                 :            :   try {
     161                 :          1 :     Allocate();
     162                 :          0 :   } catch ( string msg ) {
     163                 :          0 :     cout << "Caught error: " << msg << endl;
     164                 :          0 :     exit(1);
     165                 :            :   }
     166                 :            : 
     167                 :          1 :   trim_status = false;
     168                 :          1 :   ta_mode     = 99;
     169                 :            : 
     170                 :          1 :   Constructing = true;
     171                 :            :   typedef int (FGFDMExec::*iPMF)(void) const;
     172                 :            : //  instance->Tie("simulation/do_trim_analysis", this, (iPMF)0, &FGFDMExec::DoTrimAnalysis);
     173                 :          1 :   instance->Tie("simulation/do_simple_trim", this, (iPMF)0, &FGFDMExec::DoTrim);
     174                 :          1 :   instance->Tie("simulation/reset", this, (iPMF)0, &FGFDMExec::ResetToInitialConditions);
     175                 :          1 :   instance->Tie("simulation/terminate", (int *)&Terminate);
     176                 :          1 :   instance->Tie("simulation/sim-time-sec", this, &FGFDMExec::GetSimTime);
     177                 :          1 :   instance->Tie("simulation/jsbsim-debug", this, &FGFDMExec::GetDebugLevel, &FGFDMExec::SetDebugLevel);
     178                 :            : 
     179                 :          1 :   Constructing = false;
     180                 :          1 : }
     181                 :            : 
     182                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     183                 :            : 
     184                 :          1 : FGFDMExec::~FGFDMExec()
     185                 :            : {
     186                 :            :   try {
     187                 :          1 :     checkTied( instance );
     188                 :          1 :     DeAllocate();
     189 [ -  + ][ #  # ]:          1 :     if (Root == 0)  delete master;
         [ #  # ][ #  # ]
     190                 :          0 :   } catch ( string msg ) {
     191                 :          0 :     cout << "Caught error: " << msg << endl;
     192                 :            :   }
     193                 :            : 
     194 [ #  # ][ -  + ]:          1 :   for (unsigned int i=1; i<ChildFDMList.size(); i++) delete ChildFDMList[i]->exec;
         [ #  # ][ #  # ]
     195                 :          1 :   ChildFDMList.clear();
     196                 :            : 
     197                 :          1 :   PropertyCatalog.clear();
     198                 :            : 
     199                 :          1 :   FDMctr--;
     200                 :            : 
     201                 :          1 :   Debug(1);
     202                 :          2 : }
     203                 :            : 
     204                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     205                 :            : 
     206                 :          1 : bool FGFDMExec::Allocate(void)
     207                 :            : {
     208                 :          1 :   bool result=true;
     209                 :            : 
     210                 :          1 :   Atmosphere      = new FGAtmosphere(this);
     211                 :          1 :   FCS             = new FGFCS(this);
     212                 :          1 :   Propulsion      = new FGPropulsion(this);
     213                 :          1 :   MassBalance     = new FGMassBalance(this);
     214                 :          1 :   Aerodynamics    = new FGAerodynamics (this);
     215                 :          1 :   Inertial        = new FGInertial(this);
     216                 :            : 
     217                 :          1 :   GroundCallback  = new FGGroundCallback(Inertial->GetRefRadius());
     218                 :            : 
     219                 :          1 :   GroundReactions = new FGGroundReactions(this);
     220                 :          1 :   ExternalReactions = new FGExternalReactions(this);
     221                 :          1 :   BuoyantForces   = new FGBuoyantForces(this);
     222                 :          1 :   Aircraft        = new FGAircraft(this);
     223                 :          1 :   Propagate       = new FGPropagate(this);
     224                 :          1 :   Auxiliary       = new FGAuxiliary(this);
     225                 :          1 :   Input           = new FGInput(this);
     226                 :            : 
     227                 :            :   // Schedule a model. The second arg (the integer) is the pass number. For
     228                 :            :   // instance, the atmosphere model could get executed every fifth pass it is called.
     229                 :            :   
     230                 :          1 :   Schedule(Input,           1);
     231                 :          1 :   Schedule(Atmosphere,      1);
     232                 :          1 :   Schedule(FCS,             1);
     233                 :          1 :   Schedule(Propulsion,      1);
     234                 :          1 :   Schedule(MassBalance,     1);
     235                 :          1 :   Schedule(Aerodynamics,    1);
     236                 :          1 :   Schedule(Inertial,        1);
     237                 :          1 :   Schedule(GroundReactions, 1);
     238                 :          1 :   Schedule(ExternalReactions, 1);
     239                 :          1 :   Schedule(BuoyantForces,   1);
     240                 :          1 :   Schedule(Aircraft,        1);
     241                 :          1 :   Schedule(Propagate,       1);
     242                 :          1 :   Schedule(Auxiliary,       1);
     243                 :            : 
     244                 :            :   // Initialize models so they can communicate with each other
     245                 :            : 
     246                 :            :   vector <FGModel*>::iterator it;
     247         [ +  + ]:         14 :   for (it = Models.begin(); it != Models.end(); ++it) (*it)->InitModel();
     248                 :            : 
     249                 :          1 :   IC = new FGInitialCondition(this);
     250                 :            : 
     251                 :          1 :   modelLoaded = false;
     252                 :            : 
     253                 :          1 :   return result;
     254                 :            : }
     255                 :            : 
     256                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     257                 :            : 
     258                 :          1 : bool FGFDMExec::DeAllocate(void)
     259                 :            : {
     260         [ +  - ]:          1 :   delete Input;
     261         [ +  - ]:          1 :   delete Atmosphere;
     262         [ +  - ]:          1 :   delete FCS;
     263         [ +  - ]:          1 :   delete Propulsion;
     264         [ +  - ]:          1 :   delete MassBalance;
     265         [ +  - ]:          1 :   delete Aerodynamics;
     266         [ +  - ]:          1 :   delete Inertial;
     267         [ +  - ]:          1 :   delete GroundReactions;
     268         [ +  - ]:          1 :   delete ExternalReactions;
     269         [ +  - ]:          1 :   delete BuoyantForces;
     270         [ +  - ]:          1 :   delete Aircraft;
     271         [ +  - ]:          1 :   delete Propagate;
     272         [ +  - ]:          1 :   delete Auxiliary;
     273         [ +  - ]:          1 :   delete Script;
     274                 :            : 
     275 [ +  - ][ +  + ]:          2 :   for (unsigned i=0; i<Outputs.size(); i++) delete Outputs[i];
     276                 :          1 :   Outputs.clear();
     277                 :            : 
     278         [ +  - ]:          1 :   delete IC;
     279         [ -  + ]:          1 :   delete Trim;
     280                 :            : 
     281         [ +  - ]:          1 :   delete GroundCallback;
     282                 :            : 
     283                 :          1 :   Error       = 0;
     284                 :            : 
     285                 :          1 :   Input           = 0;
     286                 :          1 :   Atmosphere      = 0;
     287                 :          1 :   FCS             = 0;
     288                 :          1 :   Propulsion      = 0;
     289                 :          1 :   MassBalance     = 0;
     290                 :          1 :   Aerodynamics    = 0;
     291                 :          1 :   Inertial        = 0;
     292                 :          1 :   GroundReactions = 0;
     293                 :          1 :   ExternalReactions = 0;
     294                 :          1 :   BuoyantForces   = 0;
     295                 :          1 :   Aircraft        = 0;
     296                 :          1 :   Propagate       = 0;
     297                 :          1 :   Auxiliary       = 0;
     298                 :          1 :   Script          = 0;
     299                 :            : 
     300                 :          1 :   Models.clear();
     301                 :            : 
     302                 :          1 :   modelLoaded = false;
     303                 :          1 :   return modelLoaded;
     304                 :            : }
     305                 :            : 
     306                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     307                 :            : 
     308                 :         14 : void FGFDMExec::Schedule(FGModel* model, int rate)
     309                 :            : {
     310                 :         14 :   model->SetRate(rate);
     311                 :         14 :   Models.push_back(model);
     312                 :         14 : }
     313                 :            : 
     314                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     315                 :            : 
     316                 :      54005 : bool FGFDMExec::Run(void)
     317                 :            : {
     318                 :      54005 :   bool success=true;
     319                 :            : 
     320                 :      54005 :   Debug(2);
     321                 :            : 
     322         [ -  + ]:      54005 :   for (unsigned int i=1; i<ChildFDMList.size(); i++) {
     323                 :          0 :     ChildFDMList[i]->AssignState(Propagate); // Transfer state to the child FDM
     324                 :          0 :     ChildFDMList[i]->Run();
     325                 :            :   }
     326                 :            : 
     327                 :            :   // returns true if success, false if complete
     328 [ +  - ][ +  + ]:      54005 :   if (Script != 0 && !IntegrationSuspended()) success = Script->RunScript();
                 [ +  + ]
     329                 :            : 
     330                 :            :   vector <FGModel*>::iterator it;
     331         [ +  + ]:     810075 :   for (it = Models.begin(); it != Models.end(); ++it) (*it)->Run();
     332                 :            : 
     333                 :      54005 :   Frame++;
     334         [ +  - ]:      54005 :   if (!Holding()) IncrTime();
     335         [ -  + ]:      54005 :   if (Terminate) success = false;
     336                 :            : 
     337                 :      54005 :   return (success);
     338                 :            : }
     339                 :            : 
     340                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     341                 :            : // This call will cause the sim time to reset to 0.0
     342                 :            : 
     343                 :          1 : bool FGFDMExec::RunIC(void)
     344                 :            : {
     345                 :            :   SuspendIntegration(); // saves the integration rate, dt, then sets it to 0.0.
     346                 :          1 :   Initialize(IC);
     347                 :          1 :   Run();
     348                 :            :   ResumeIntegration(); // Restores the integration rate to what it was.
     349                 :            : 
     350                 :          1 :   return true;
     351                 :            : }
     352                 :            : 
     353                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     354                 :            : 
     355                 :          1 : void FGFDMExec::Initialize(FGInitialCondition *FGIC)
     356                 :            : {
     357                 :          1 :   Propagate->SetInitialState( FGIC );
     358                 :            : 
     359                 :          1 :   Atmosphere->Run();
     360                 :            :   Atmosphere->SetWindNED( FGIC->GetWindNFpsIC(),
     361                 :            :                           FGIC->GetWindEFpsIC(),
     362                 :          1 :                           FGIC->GetWindDFpsIC() );
     363                 :            : 
     364                 :          1 :   FGColumnVector3 vAeroUVW;
     365                 :          1 :   vAeroUVW = Propagate->GetUVW() + Propagate->GetTl2b()*Atmosphere->GetTotalWindNED();
     366                 :            : 
     367                 :            :   double alpha, beta;
     368         [ -  + ]:          1 :   if (vAeroUVW(eW) != 0.0)
     369         [ #  # ]:          0 :     alpha = vAeroUVW(eU)*vAeroUVW(eU) > 0.0 ? atan2(vAeroUVW(eW), vAeroUVW(eU)) : 0.0;
     370                 :            :   else
     371                 :          1 :     alpha = 0.0;
     372         [ -  + ]:          1 :   if (vAeroUVW(eV) != 0.0)
     373         [ #  # ]:          0 :     beta = vAeroUVW(eU)*vAeroUVW(eU)+vAeroUVW(eW)*vAeroUVW(eW) > 0.0 ? atan2(vAeroUVW(eV), (fabs(vAeroUVW(eU))/vAeroUVW(eU))*sqrt(vAeroUVW(eU)*vAeroUVW(eU) + vAeroUVW(eW)*vAeroUVW(eW))) : 0.0;
     374                 :            :   else
     375                 :          1 :     beta = 0.0;
     376                 :            : 
     377                 :          1 :   Auxiliary->SetAB(alpha, beta);
     378                 :            : 
     379                 :          1 :   double Vt = vAeroUVW.Magnitude();
     380                 :          1 :   Auxiliary->SetVt(Vt);
     381                 :            : 
     382                 :          2 :   Auxiliary->SetMach(Vt/Atmosphere->GetSoundSpeed());
     383                 :            : 
     384                 :          2 :   double qbar = 0.5*Vt*Vt*Atmosphere->GetDensity();
     385                 :          1 :   Auxiliary->Setqbar(qbar);
     386                 :          1 : }
     387                 :            : 
     388                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     389                 :            : //
     390                 :            : // A private, internal function call for Tie-ing to a property, so it needs an
     391                 :            : // argument.
     392                 :            : 
     393                 :          0 : void FGFDMExec::ResetToInitialConditions(int mode)
     394                 :            : {
     395         [ #  # ]:          0 :   if (mode == 1) {
     396         [ #  # ]:          0 :     for (unsigned int i=0; i<Outputs.size(); i++) {
     397                 :          0 :       Outputs[i]->SetStartNewFile(true); 
     398                 :            :     }
     399                 :            :   }
     400                 :            :   
     401                 :          0 :   ResetToInitialConditions();
     402                 :          0 : }
     403                 :            : 
     404                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     405                 :            : 
     406                 :          0 : void FGFDMExec::ResetToInitialConditions(void)
     407                 :            : {
     408         [ #  # ]:          0 :   if (Constructing) return;
     409                 :            : 
     410                 :            :   vector <FGModel*>::iterator it;
     411         [ #  # ]:          0 :   for (it = Models.begin(); it != Models.end(); ++it) (*it)->InitModel();
     412                 :            : 
     413                 :          0 :   RunIC();
     414         [ #  # ]:          0 :   if (Script) Script->ResetEvents();
     415                 :            : }
     416                 :            : 
     417                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     418                 :            : 
     419                 :          0 : void FGFDMExec::SetGroundCallback(FGGroundCallback* p)
     420                 :            : {
     421         [ #  # ]:          0 :   delete GroundCallback;
     422                 :          0 :   GroundCallback = p;
     423                 :          0 : }
     424                 :            : 
     425                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     426                 :            : 
     427                 :          0 : vector <string> FGFDMExec::EnumerateFDMs(void)
     428                 :            : {
     429                 :          0 :   vector <string> FDMList;
     430                 :            : 
     431                 :          0 :   FDMList.push_back(Aircraft->GetAircraftName());
     432                 :            : 
     433         [ #  # ]:          0 :   for (unsigned int i=1; i<ChildFDMList.size(); i++) {
     434                 :          0 :     FDMList.push_back(ChildFDMList[i]->exec->GetAircraft()->GetAircraftName());
     435                 :            :   }
     436                 :            : 
     437                 :          0 :   return FDMList;
     438                 :            : }
     439                 :            : 
     440                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     441                 :            : 
     442                 :          1 : bool FGFDMExec::LoadScript(string script, double deltaT)
     443                 :            : {
     444                 :            :   bool result;
     445                 :            : 
     446                 :          1 :   Script = new FGScript(this);
     447                 :          1 :   result = Script->LoadScript(RootDir + script, deltaT);
     448                 :            : 
     449                 :          1 :   return result;
     450                 :            : }
     451                 :            : 
     452                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     453                 :            : 
     454                 :            : bool FGFDMExec::LoadModel(string AircraftPath, string EnginePath, string SystemsPath,
     455                 :          0 :                 string model, bool addModelToPath)
     456                 :            : {
     457                 :          0 :   FGFDMExec::AircraftPath = RootDir + AircraftPath;
     458                 :          0 :   FGFDMExec::EnginePath = RootDir + EnginePath;
     459                 :          0 :   FGFDMExec::SystemsPath = RootDir + SystemsPath;
     460                 :            : 
     461                 :          0 :   return LoadModel(model, addModelToPath);
     462                 :            : }
     463                 :            : 
     464                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     465                 :            : 
     466                 :          1 : bool FGFDMExec::LoadModel(string model, bool addModelToPath)
     467                 :            : {
     468                 :          1 :   string token;
     469                 :          1 :   string aircraftCfgFileName;
     470                 :          1 :   Element* element = 0L;
     471                 :          1 :   bool result = false; // initialize result to false, indicating input file not yet read
     472                 :            : 
     473                 :          1 :   modelName = model; // Set the class modelName attribute
     474                 :            : 
     475 [ +  - ][ +  - ]:          1 :   if( AircraftPath.empty() || EnginePath.empty() || SystemsPath.empty()) {
         [ -  + ][ -  + ]
     476                 :          0 :     cerr << "Error: attempted to load aircraft with undefined ";
     477                 :          0 :     cerr << "aircraft, engine, and system paths" << endl;
     478                 :          0 :     return false;
     479                 :            :   }
     480                 :            : 
     481                 :          1 :   FullAircraftPath = AircraftPath;
     482         [ +  - ]:          2 :   if (addModelToPath) FullAircraftPath += "/" + model;
     483                 :          2 :   aircraftCfgFileName = FullAircraftPath + "/" + model + ".xml";
     484                 :            : 
     485         [ -  + ]:          1 :   if (modelLoaded) {
     486                 :          0 :     DeAllocate();
     487                 :          0 :     Allocate();
     488                 :            :   }
     489                 :            : 
     490                 :          1 :   int saved_debug_lvl = debug_lvl;
     491                 :            : 
     492                 :          2 :   document = LoadXMLDocument(aircraftCfgFileName); // "document" is a class member
     493         [ +  - ]:          1 :   if (document) {
     494         [ -  + ]:          1 :     if (IsChild) debug_lvl = 0;
     495                 :            : 
     496                 :          1 :     ReadPrologue(document);
     497                 :            : 
     498         [ -  + ]:          1 :     if (IsChild) debug_lvl = saved_debug_lvl;
     499                 :            : 
     500                 :            :     // Process the fileheader element in the aircraft config file. This element is OPTIONAL.
     501                 :          1 :     element = document->FindElement("fileheader");
     502         [ +  - ]:          1 :     if (element) {
     503                 :          1 :       result = ReadFileHeader(element);
     504         [ -  + ]:          1 :       if (!result) {
     505                 :          0 :         cerr << endl << "Aircraft fileheader element has problems in file " << aircraftCfgFileName << endl;
     506                 :          0 :         return result;
     507                 :            :       }
     508                 :            :     }
     509                 :            : 
     510         [ -  + ]:          1 :     if (IsChild) debug_lvl = 0;
     511                 :            : 
     512                 :            :     // Process the metrics element. This element is REQUIRED.
     513                 :          1 :     element = document->FindElement("metrics");
     514         [ +  - ]:          1 :     if (element) {
     515                 :          1 :       result = Aircraft->Load(element);
     516         [ -  + ]:          1 :       if (!result) {
     517                 :          0 :         cerr << endl << "Aircraft metrics element has problems in file " << aircraftCfgFileName << endl;
     518                 :          0 :         return result;
     519                 :            :       }
     520                 :            :     } else {
     521                 :          0 :       cerr << endl << "No metrics element was found in the aircraft config file." << endl;
     522                 :          0 :       return false;
     523                 :            :     }
     524                 :            : 
     525                 :            :     // Process the mass_balance element. This element is REQUIRED.
     526                 :          1 :     element = document->FindElement("mass_balance");
     527         [ +  - ]:          1 :     if (element) {
     528                 :          1 :       result = MassBalance->Load(element);
     529         [ -  + ]:          1 :       if (!result) {
     530                 :          0 :         cerr << endl << "Aircraft mass_balance element has problems in file " << aircraftCfgFileName << endl;
     531                 :          0 :         return result;
     532                 :            :       }
     533                 :            :     } else {
     534                 :          0 :       cerr << endl << "No mass_balance element was found in the aircraft config file." << endl;
     535                 :          0 :       return false;
     536                 :            :     }
     537                 :            : 
     538                 :            :     // Process the ground_reactions element. This element is REQUIRED.
     539                 :          1 :     element = document->FindElement("ground_reactions");
     540         [ +  - ]:          1 :     if (element) {
     541                 :          1 :       result = GroundReactions->Load(element);
     542         [ -  + ]:          1 :       if (!result) {
     543                 :          0 :         cerr << endl << "Aircraft ground_reactions element has problems in file " << aircraftCfgFileName << endl;
     544                 :          0 :         return result;
     545                 :            :       }
     546                 :            :     } else {
     547                 :          0 :       cerr << endl << "No ground_reactions element was found in the aircraft config file." << endl;
     548                 :          0 :       return false;
     549                 :            :     }
     550                 :            : 
     551                 :            :     // Process the external_reactions element. This element is OPTIONAL.
     552                 :          1 :     element = document->FindElement("external_reactions");
     553         [ -  + ]:          1 :     if (element) {
     554                 :          0 :       result = ExternalReactions->Load(element);
     555         [ #  # ]:          0 :       if (!result) {
     556                 :          0 :         cerr << endl << "Aircraft external_reactions element has problems in file " << aircraftCfgFileName << endl;
     557                 :          0 :         return result;
     558                 :            :       }
     559                 :            :     }
     560                 :            : 
     561                 :            :     // Process the buoyant_forces element. This element is OPTIONAL.
     562                 :          1 :     element = document->FindElement("buoyant_forces");
     563         [ -  + ]:          1 :     if (element) {
     564                 :          0 :       result = BuoyantForces->Load(element);
     565         [ #  # ]:          0 :       if (!result) {
     566                 :          0 :         cerr << endl << "Aircraft buoyant_forces element has problems in file " << aircraftCfgFileName << endl;
     567                 :          0 :         return result;
     568                 :            :       }
     569                 :            :     }
     570                 :            : 
     571                 :            :     // Process the propulsion element. This element is OPTIONAL.
     572                 :          1 :     element = document->FindElement("propulsion");
     573         [ +  - ]:          1 :     if (element) {
     574                 :          1 :       result = Propulsion->Load(element);
     575         [ -  + ]:          1 :       if (!result) {
     576                 :          0 :         cerr << endl << "Aircraft propulsion element has problems in file " << aircraftCfgFileName << endl;
     577                 :          0 :         return result;
     578                 :            :       }
     579                 :            :     }
     580                 :            : 
     581                 :            :     // Process the system element[s]. This element is OPTIONAL, and there may be more than one.
     582                 :          1 :     element = document->FindElement("system");
     583         [ +  + ]:          5 :     while (element) {
     584                 :          4 :       result = FCS->Load(element, FGFCS::stSystem);
     585         [ -  + ]:          4 :       if (!result) {
     586                 :          0 :         cerr << endl << "Aircraft system element has problems in file " << aircraftCfgFileName << endl;
     587                 :          0 :         return result;
     588                 :            :       }
     589                 :          4 :       element = document->FindNextElement("system");
     590                 :            :     }
     591                 :            : 
     592                 :            :     // Process the autopilot element. This element is OPTIONAL.
     593                 :          1 :     element = document->FindElement("autopilot");
     594         [ -  + ]:          1 :     if (element) {
     595                 :          0 :       result = FCS->Load(element, FGFCS::stAutoPilot);
     596         [ #  # ]:          0 :       if (!result) {
     597                 :          0 :         cerr << endl << "Aircraft autopilot element has problems in file " << aircraftCfgFileName << endl;
     598                 :          0 :         return result;
     599                 :            :       }
     600                 :            :     }
     601                 :            : 
     602                 :            :     // Process the flight_control element. This element is OPTIONAL.
     603                 :          1 :     element = document->FindElement("flight_control");
     604         [ -  + ]:          1 :     if (element) {
     605                 :          0 :       result = FCS->Load(element, FGFCS::stFCS);
     606         [ #  # ]:          0 :       if (!result) {
     607                 :          0 :         cerr << endl << "Aircraft flight_control element has problems in file " << aircraftCfgFileName << endl;
     608                 :          0 :         return result;
     609                 :            :       }
     610                 :            :     }
     611                 :            : 
     612                 :            :     // Process the aerodynamics element. This element is OPTIONAL, but almost always expected.
     613                 :          1 :     element = document->FindElement("aerodynamics");
     614         [ +  - ]:          1 :     if (element) {
     615                 :          1 :       result = Aerodynamics->Load(element);
     616         [ -  + ]:          1 :       if (!result) {
     617                 :          0 :         cerr << endl << "Aircraft aerodynamics element has problems in file " << aircraftCfgFileName << endl;
     618                 :          0 :         return result;
     619                 :            :       }
     620                 :            :     } else {
     621                 :          0 :       cerr << endl << "No expected aerodynamics element was found in the aircraft config file." << endl;
     622                 :            :     }
     623                 :            : 
     624                 :            :     // Process the input element. This element is OPTIONAL.
     625                 :          1 :     element = document->FindElement("input");
     626         [ -  + ]:          1 :     if (element) {
     627                 :          0 :       result = Input->Load(element);
     628         [ #  # ]:          0 :       if (!result) {
     629                 :          0 :         cerr << endl << "Aircraft input element has problems in file " << aircraftCfgFileName << endl;
     630                 :          0 :         return result;
     631                 :            :       }
     632                 :            :     }
     633                 :            : 
     634                 :            :     // Process the output element[s]. This element is OPTIONAL, and there may be more than one.
     635                 :          1 :     unsigned int idx=0;
     636                 :            :     typedef int (FGOutput::*iOPMF)(void) const;
     637                 :          1 :     element = document->FindElement("output");
     638         [ +  + ]:          2 :     while (element) {
     639         [ +  - ]:          3 :       if (debug_lvl > 0) cout << endl << "  Output data set: " << idx << "  ";
     640                 :          1 :       FGOutput* Output = new FGOutput(this);
     641                 :          1 :       Output->InitModel();
     642                 :          1 :       Schedule(Output, 1);
     643                 :          1 :       result = Output->Load(element);
     644         [ -  + ]:          1 :       if (!result) {
     645                 :          0 :         cerr << endl << "Aircraft output element has problems in file " << aircraftCfgFileName << endl;
     646                 :          0 :         return result;
     647                 :            :       } else {
     648                 :          1 :         Outputs.push_back(Output);
     649                 :          1 :         string outputProp = CreateIndexedPropertyName("simulation/output",idx);
     650                 :          1 :         instance->Tie(outputProp+"/log_rate_hz", Output, (iOPMF)0, &FGOutput::SetRate);
     651                 :          1 :         idx++;
     652                 :            :       }
     653                 :          1 :       element = document->FindNextElement("output");
     654                 :            :     }
     655                 :            : 
     656                 :            :     // Lastly, process the child element. This element is OPTIONAL - and NOT YET SUPPORTED.
     657                 :          1 :     element = document->FindElement("child");
     658         [ -  + ]:          1 :     if (element) {
     659                 :          0 :       result = ReadChild(element);
     660         [ #  # ]:          0 :       if (!result) {
     661                 :          0 :         cerr << endl << "Aircraft child element has problems in file " << aircraftCfgFileName << endl;
     662                 :          0 :         return result;
     663                 :            :       }
     664                 :            :     }
     665                 :            : 
     666                 :          1 :     modelLoaded = true;
     667                 :            : 
     668         [ +  - ]:          1 :     if (debug_lvl > 0) {
     669                 :          1 :       MassBalance->Run(); // Update all mass properties for the report.
     670                 :          1 :       MassBalance->GetMassPropertiesReport();
     671                 :            : 
     672                 :            :       cout << endl << fgblue << highint
     673                 :            :            << "End of vehicle configuration loading." << endl
     674                 :            :            << "-------------------------------------------------------------------------------"
     675                 :          2 :            << reset << endl;
     676                 :            :     }
     677                 :            :     
     678         [ -  + ]:          1 :     if (IsChild) debug_lvl = saved_debug_lvl;
     679                 :            : 
     680                 :            :   } else {
     681                 :            :     cerr << fgred
     682                 :            :          << "  JSBSim failed to open the configuration file: " << aircraftCfgFileName
     683                 :          0 :          << fgdef << endl;
     684                 :            :   }
     685                 :            : 
     686                 :            :   // Late bind previously undefined FCS inputs.
     687                 :            :   try {
     688                 :          1 :     FCS->LateBind();
     689                 :          0 :   } catch (string prop) {
     690                 :            :     cerr << endl << fgred << "  Could not late bind property " << prop 
     691                 :          0 :          << ". Aborting." << endl;
     692                 :          0 :     result = false;
     693                 :            :   }
     694                 :            : 
     695         [ +  - ]:          1 :   if (result) {
     696                 :            :     struct PropertyCatalogStructure masterPCS;
     697                 :            :     masterPCS.base_string = "";
     698                 :          1 :     masterPCS.node = (FGPropertyManager*)Root;
     699                 :          1 :     BuildPropertyCatalog(&masterPCS);
     700                 :            :   }
     701                 :            : 
     702                 :          1 :   return result;
     703                 :            : }
     704                 :            : 
     705                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     706                 :            : 
     707                 :         54 : void FGFDMExec::BuildPropertyCatalog(struct PropertyCatalogStructure* pcs)
     708                 :            : {
     709                 :         54 :   struct PropertyCatalogStructure* pcsNew = new struct PropertyCatalogStructure;
     710                 :         54 :   int node_idx = 0;
     711                 :            : 
     712         [ +  + ]:        753 :   for (int i=0; i<pcs->node->nChildren(); i++) {
     713                 :       1398 :     pcsNew->base_string = pcs->base_string + "/" + pcs->node->getChild(i)->getName();
     714                 :        699 :     node_idx = pcs->node->getChild(i)->getIndex();
     715         [ +  + ]:        699 :     if (node_idx != 0) {
     716                 :        352 :       pcsNew->base_string = CreateIndexedPropertyName(pcsNew->base_string, node_idx);
     717                 :            :     }
     718         [ +  + ]:        699 :     if (pcs->node->getChild(i)->nChildren() == 0) {
     719         [ +  - ]:       1292 :       if (pcsNew->base_string.substr(0,11) == string("/fdm/jsbsim")) {
     720                 :        646 :         pcsNew->base_string = pcsNew->base_string.erase(0,12);
     721                 :            :       }
     722                 :        646 :       PropertyCatalog.push_back(pcsNew->base_string);
     723                 :            :     } else {
     724                 :         53 :       pcsNew->node = (FGPropertyManager*)pcs->node->getChild(i);
     725                 :         53 :       BuildPropertyCatalog(pcsNew);
     726                 :            :     }
     727                 :            :   }
     728         [ +  - ]:        108 :   delete pcsNew;
     729                 :         54 : }
     730                 :            : 
     731                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     732                 :            : 
     733                 :          0 : string FGFDMExec::QueryPropertyCatalog(string in)
     734                 :            : {
     735                 :          0 :   string results="";
     736         [ #  # ]:          0 :   for (unsigned i=0; i<PropertyCatalog.size(); i++) {
     737         [ #  # ]:          0 :     if (PropertyCatalog[i].find(in) != string::npos) results += PropertyCatalog[i] + "\n";
     738                 :            :   }
     739         [ #  # ]:          0 :   if (results.empty()) return "No matches found\n";
     740                 :          0 :   return results;
     741                 :            : }
     742                 :            : 
     743                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     744                 :            : 
     745                 :          0 : void FGFDMExec::PrintPropertyCatalog(void)
     746                 :            : {
     747                 :            :   cout << endl;
     748                 :            :   cout << "  " << fgblue << highint << underon << "Property Catalog for "
     749                 :          0 :        << modelName << reset << endl << endl;
     750         [ #  # ]:          0 :   for (unsigned i=0; i<PropertyCatalog.size(); i++) {
     751                 :          0 :     cout << "    " << PropertyCatalog[i] << endl;
     752                 :            :   }
     753                 :          0 : }
     754                 :            : 
     755                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     756                 :            : 
     757                 :          1 : bool FGFDMExec::ReadFileHeader(Element* el)
     758                 :            : {
     759                 :          1 :   bool result = true; // true for success
     760                 :            : 
     761         [ -  + ]:          1 :   if (debug_lvl == 0) return result;
     762                 :            : 
     763         [ -  + ]:          1 :   if (IsChild) {
     764                 :          0 :     cout << endl <<highint << fgblue << "Reading child model: " << IdFDM << reset << endl << endl;
     765                 :            :   }
     766                 :            : 
     767         [ +  - ]:          1 :   if (el->FindElement("description"))
     768                 :          2 :     cout << "  Description:   " << el->FindElement("description")->GetDataLine() << endl;
     769         [ +  - ]:          1 :   if (el->FindElement("author"))
     770                 :          2 :     cout << "  Model Author:  " << el->FindElement("author")->GetDataLine() << endl;
     771         [ +  - ]:          1 :   if (el->FindElement("filecreationdate"))
     772                 :          2 :     cout << "  Creation Date: " << el->FindElement("filecreationdate")->GetDataLine() << endl;
     773         [ +  - ]:          1 :   if (el->FindElement("version"))
     774                 :          2 :     cout << "  Version:       " << el->FindElement("version")->GetDataLine() << endl;
     775                 :            : 
     776                 :          1 :   return result;
     777                 :            : }
     778                 :            : 
     779                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     780                 :            : 
     781                 :          1 : bool FGFDMExec::ReadPrologue(Element* el) // el for ReadPrologue is the document element
     782                 :            : {
     783                 :          1 :   bool result = true; // true for success
     784                 :            : 
     785         [ -  + ]:          1 :   if (!el) return false;
     786                 :            : 
     787                 :          1 :   string AircraftName = el->GetAttributeValue("name");
     788                 :          1 :   Aircraft->SetAircraftName(AircraftName);
     789                 :            : 
     790         [ +  - ]:          1 :   if (debug_lvl & 1) cout << underon << "Reading Aircraft Configuration File"
     791                 :          1 :             << underoff << ": " << highint << AircraftName << normint << endl;
     792                 :            : 
     793                 :          2 :   CFGVersion = el->GetAttributeValue("version");
     794                 :          2 :   Release    = el->GetAttributeValue("release");
     795                 :            : 
     796         [ +  - ]:          1 :   if (debug_lvl & 1)
     797                 :            :     cout << "                            Version: " << highint << CFGVersion
     798                 :          1 :                                                     << normint << endl;
     799         [ -  + ]:          1 :   if (CFGVersion != needed_cfg_version) {
     800                 :            :     cerr << endl << fgred << "YOU HAVE AN INCOMPATIBLE CFG FILE FOR THIS AIRCRAFT."
     801                 :          0 :             " RESULTS WILL BE UNPREDICTABLE !!" << endl;
     802                 :          0 :     cerr << "Current version needed is: " << needed_cfg_version << endl;
     803                 :          0 :     cerr << "         You have version: " << CFGVersion << endl << fgdef << endl;
     804                 :          0 :     return false;
     805                 :            :   }
     806                 :            : 
     807 [ +  - ][ +  - ]:          1 :   if (Release == "ALPHA" && (debug_lvl & 1)) {
                 [ +  - ]
     808                 :            :     cout << endl << endl
     809                 :            :          << highint << "This aircraft model is an " << fgred << Release
     810                 :            :          << reset << highint << " release!!!" << endl << endl << reset
     811                 :            :          << "This aircraft model may not even properly load, and probably"
     812                 :            :          << " will not fly as expected." << endl << endl
     813                 :            :          << fgred << highint << "Use this model for development purposes ONLY!!!"
     814                 :          3 :          << normint << reset << endl << endl;
     815 [ #  # ][ #  # ]:          0 :   } else if (Release == "BETA" && (debug_lvl & 1)) {
                 [ #  # ]
     816                 :            :     cout << endl << endl
     817                 :            :          << highint << "This aircraft model is a " << fgred << Release
     818                 :            :          << reset << highint << " release!!!" << endl << endl << reset
     819                 :            :          << "This aircraft model probably will not fly as expected." << endl << endl
     820                 :            :          << fgblue << highint << "Use this model for development purposes ONLY!!!"
     821                 :          0 :          << normint << reset << endl << endl;
     822 [ #  # ][ #  # ]:          0 :   } else if (Release == "PRODUCTION" && (debug_lvl & 1)) {
                 [ #  # ]
     823                 :            :     cout << endl << endl
     824                 :            :          << highint << "This aircraft model is a " << fgblue << Release
     825                 :          0 :          << reset << highint << " release." << endl << endl << reset;
     826         [ #  # ]:          0 :   } else if (debug_lvl & 1) {
     827                 :            :     cout << endl << endl
     828                 :            :          << highint << "This aircraft model is an " << fgred << Release
     829                 :            :          << reset << highint << " release!!!" << endl << endl << reset
     830                 :            :          << "This aircraft model may not even properly load, and probably"
     831                 :            :          << " will not fly as expected." << endl << endl
     832                 :            :          << fgred << highint << "Use this model for development purposes ONLY!!!"
     833                 :          0 :          << normint << reset << endl << endl;
     834                 :            :   }
     835                 :            : 
     836                 :          1 :   return result;
     837                 :            : }
     838                 :            : 
     839                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     840                 :            : 
     841                 :          0 : bool FGFDMExec::ReadChild(Element* el)
     842                 :            : {
     843                 :            :   // Add a new childData object to the child FDM list
     844                 :            :   // Populate that childData element with a new FDMExec object
     845                 :            :   // Set the IsChild flag for that FDMExec object
     846                 :            :   // Get the aircraft name
     847                 :            :   // set debug level to print out no additional data for child objects
     848                 :            :   // Load the model given the aircraft name
     849                 :            :   // reset debug level to prior setting
     850                 :            : 
     851                 :          0 :   string token;
     852                 :            : 
     853                 :          0 :   struct childData* child = new childData;
     854                 :            : 
     855                 :          0 :   child->exec = new FGFDMExec();
     856                 :          0 :   child->exec->SetChild(true);
     857                 :            : 
     858                 :          0 :   string childAircraft = el->GetAttributeValue("name");
     859                 :          0 :   string sMated = el->GetAttributeValue("mated");
     860         [ #  # ]:          0 :   if (sMated == "false") child->mated = false; // child objects are mated by default.
     861                 :          0 :   string sInternal = el->GetAttributeValue("internal");
     862         [ #  # ]:          0 :   if (sInternal == "true") child->internal = true; // child objects are external by default.
     863                 :            : 
     864                 :          0 :   child->exec->SetAircraftPath( AircraftPath );
     865                 :          0 :   child->exec->SetEnginePath( EnginePath );
     866                 :          0 :   child->exec->SetSystemsPath( SystemsPath );
     867                 :          0 :   child->exec->LoadModel(childAircraft);
     868                 :            : 
     869                 :          0 :   Element* location = el->FindElement("location");
     870         [ #  # ]:          0 :   if (location) {
     871                 :          0 :     child->Loc = location->FindElementTripletConvertTo("IN");
     872                 :            :   } else {
     873                 :          0 :     cerr << endl << highint << fgred << "  No location was found for this child object!" << reset << endl;
     874                 :          0 :     exit(-1);
     875                 :            :   }
     876                 :            :   
     877                 :          0 :   Element* orientation = el->FindElement("orient");
     878         [ #  # ]:          0 :   if (orientation) {
     879                 :          0 :     child->Orient = orientation->FindElementTripletConvertTo("RAD");
     880         [ #  # ]:          0 :   } else if (debug_lvl > 0) {
     881                 :          0 :     cerr << endl << highint << "  No orientation was found for this child object! Assuming 0,0,0." << reset << endl;
     882                 :            :   }
     883                 :            : 
     884                 :          0 :   ChildFDMList.push_back(child);
     885                 :            : 
     886                 :          0 :   return true;
     887                 :            : }
     888                 :            : 
     889                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     890                 :            : 
     891                 :         48 : FGPropertyManager* FGFDMExec::GetPropertyManager(void)
     892                 :            : {
     893                 :         48 :   return instance;
     894                 :            : }
     895                 :            : 
     896                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     897                 :            : 
     898                 :          0 : FGTrim* FGFDMExec::GetTrim(void)
     899                 :            : {
     900         [ #  # ]:          0 :   delete Trim;
     901                 :          0 :   Trim = new FGTrim(this,tNone);
     902                 :          0 :   return Trim;
     903                 :            : }
     904                 :            : 
     905                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     906                 :            : 
     907                 :          0 : void FGFDMExec::DisableOutput(void)
     908                 :            : {
     909         [ #  # ]:          0 :   for (unsigned i=0; i<Outputs.size(); i++) {
     910                 :          0 :     Outputs[i]->Disable();
     911                 :            :   }
     912                 :          0 : }
     913                 :            : 
     914                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     915                 :            : 
     916                 :          0 : void FGFDMExec::EnableOutput(void)
     917                 :            : {
     918         [ #  # ]:          0 :   for (unsigned i=0; i<Outputs.size(); i++) {
     919                 :          0 :     Outputs[i]->Enable();
     920                 :            :   }
     921                 :          0 : }
     922                 :            : 
     923                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     924                 :            : 
     925                 :          0 : bool FGFDMExec::SetOutputDirectives(string fname)
     926                 :            : {
     927                 :            :   bool result;
     928                 :            : 
     929                 :          0 :   FGOutput* Output = new FGOutput(this);
     930                 :          0 :   Output->SetDirectivesFile(RootDir + fname);
     931                 :          0 :   Output->InitModel();
     932                 :          0 :   Schedule(Output, 1);
     933                 :          0 :   result = Output->Load(0);
     934                 :            : 
     935         [ #  # ]:          0 :   if (result) {
     936                 :          0 :     Outputs.push_back(Output);
     937                 :            :     typedef int (FGOutput::*iOPMF)(void) const;
     938                 :          0 :     string outputProp = CreateIndexedPropertyName("simulation/output",Outputs.size()-1);
     939                 :          0 :     instance->Tie(outputProp+"/log_rate_hz", Output, (iOPMF)0, &FGOutput::SetRate);
     940                 :            :   }
     941                 :            : 
     942                 :          0 :   return result;
     943                 :            : }
     944                 :            : 
     945                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     946                 :            : 
     947                 :          0 : void FGFDMExec::DoTrim(int mode)
     948                 :            : {
     949                 :            :   double saved_time;
     950                 :            : 
     951         [ #  # ]:          0 :   if (Constructing) return;
     952                 :            : 
     953         [ #  # ]:          0 :   if (mode < 0 || mode > JSBSim::tNone) {
     954                 :          0 :     cerr << endl << "Illegal trimming mode!" << endl << endl;
     955                 :            :     return;
     956                 :            :   }
     957                 :          0 :   saved_time = sim_time;
     958                 :          0 :   FGTrim trim(this, (JSBSim::TrimMode)mode);
     959         [ #  # ]:          0 :   if ( !trim.DoTrim() ) cerr << endl << "Trim Failed" << endl << endl;
     960                 :          0 :   trim.Report();
     961                 :          0 :   sim_time = saved_time;
     962                 :            : }
     963                 :            : 
     964                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     965                 :            : /*
     966                 :            : void FGFDMExec::DoTrimAnalysis(int mode)
     967                 :            : {
     968                 :            :   double saved_time;
     969                 :            :   if (Constructing) return;
     970                 :            : 
     971                 :            :   if (mode < 0 || mode > JSBSim::taNone) {
     972                 :            :     cerr << endl << "Illegal trimming mode!" << endl << endl;
     973                 :            :     return;
     974                 :            :   }
     975                 :            :   saved_time = sim_time;
     976                 :            : 
     977                 :            :   FGTrimAnalysis trimAnalysis(this, (JSBSim::TrimAnalysisMode)mode);
     978                 :            : 
     979                 :            :   if ( !trimAnalysis.Load(IC->GetInitFile(), false) ) {
     980                 :            :     cerr << "A problem occurred with trim configuration file " << trimAnalysis.Load(IC->GetInitFile()) << endl;
     981                 :            :     exit(-1);
     982                 :            :   }
     983                 :            : 
     984                 :            :   bool result = trimAnalysis.DoTrim();
     985                 :            : 
     986                 :            :   if ( !result ) cerr << endl << "Trim Failed" << endl << endl;
     987                 :            : 
     988                 :            :   trimAnalysis.Report();
     989                 :            :   Setsim_time(saved_time);
     990                 :            : 
     991                 :            :   EnableOutput();
     992                 :            :   cout << "\nOutput: " << GetOutputFileName() << endl;
     993                 :            : 
     994                 :            : }
     995                 :            : */
     996                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     997                 :            : 
     998                 :          0 : void FGFDMExec::UseAtmosphereMSIS(void)
     999                 :            : {
    1000                 :          0 :   FGAtmosphere *oldAtmosphere = Atmosphere;
    1001                 :          0 :   Atmosphere = new MSIS(this);
    1002         [ #  # ]:          0 :   if (!Atmosphere->InitModel()) {
    1003                 :          0 :     cerr << fgred << "MSIS Atmosphere model init failed" << fgdef << endl;
    1004                 :          0 :     Error+=1;
    1005                 :            :   }
    1006         [ #  # ]:          0 :   delete oldAtmosphere;
    1007                 :          0 : }
    1008                 :            : 
    1009                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1010                 :            : 
    1011                 :          0 : void FGFDMExec::UseAtmosphereMars(void)
    1012                 :            : {
    1013                 :            : /*
    1014                 :            :   FGAtmosphere *oldAtmosphere = Atmosphere;
    1015                 :            :   Atmosphere = new FGMars(this);
    1016                 :            :   if (!Atmosphere->InitModel()) {
    1017                 :            :     cerr << fgred << "Mars Atmosphere model init failed" << fgdef << endl;
    1018                 :            :     Error+=1;
    1019                 :            :   }
    1020                 :            :   delete oldAtmosphere;
    1021                 :            : */
    1022                 :          0 : }
    1023                 :            : 
    1024                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1025                 :            : //    The bitmasked value choices are as follows:
    1026                 :            : //    unset: In this case (the default) JSBSim would only print
    1027                 :            : //       out the normally expected messages, essentially echoing
    1028                 :            : //       the config files as they are read. If the environment
    1029                 :            : //       variable is not set, debug_lvl is set to 1 internally
    1030                 :            : //    0: This requests JSBSim not to output any messages
    1031                 :            : //       whatsoever.
    1032                 :            : //    1: This value explicity requests the normal JSBSim
    1033                 :            : //       startup messages
    1034                 :            : //    2: This value asks for a message to be printed out when
    1035                 :            : //       a class is instantiated
    1036                 :            : //    4: When this value is set, a message is displayed when a
    1037                 :            : //       FGModel object executes its Run() method
    1038                 :            : //    8: When this value is set, various runtime state variables
    1039                 :            : //       are printed out periodically
    1040                 :            : //    16: When set various parameters are sanity checked and
    1041                 :            : //       a message is printed out when they go out of bounds
    1042                 :            : 
    1043                 :      54007 : void FGFDMExec::Debug(int from)
    1044                 :            : {
    1045         [ +  - ]:      54007 :   if (debug_lvl <= 0) return;
    1046                 :            : 
    1047 [ +  - ][ +  - ]:      54007 :   if (debug_lvl & 1 && IdFDM == 0) { // Standard console startup message output
    1048         [ +  + ]:      54007 :     if (from == 0) { // Constructor
    1049                 :            :       cout << "\n\n     " << highint << underon << "JSBSim Flight Dynamics Model v"
    1050                 :          1 :                                      << JSBSim_version << underoff << normint << endl;
    1051                 :          1 :       cout << halfint << "            [JSBSim-ML v" << needed_cfg_version << "]\n\n";
    1052                 :          1 :       cout << normint << "JSBSim startup beginning ...\n\n";
    1053         [ -  + ]:      54006 :     } else if (from == 3) {
    1054                 :          0 :       cout << "\n\nJSBSim startup complete\n\n";
    1055                 :            :     }
    1056                 :            :   }
    1057         [ -  + ]:      54007 :   if (debug_lvl & 2 ) { // Instantiation/Destruction notification
    1058         [ #  # ]:          0 :     if (from == 0) cout << "Instantiated: FGFDMExec" << endl;
    1059         [ #  # ]:          0 :     if (from == 1) cout << "Destroyed:    FGFDMExec" << endl;
    1060                 :            :   }
    1061         [ -  + ]:      54007 :   if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
    1062         [ #  # ]:          0 :     if (from == 2) {
    1063                 :            :       cout << "================== Frame: " << Frame << "  Time: "
    1064                 :          0 :            << sim_time << " dt: " << dT << endl;
    1065                 :            :     }
    1066                 :            :   }
    1067                 :      54007 :   if (debug_lvl & 8 ) { // Runtime state variables
    1068                 :            :   }
    1069                 :      54007 :   if (debug_lvl & 16) { // Sanity checking
    1070                 :            :   }
    1071         [ -  + ]:      54007 :   if (debug_lvl & 64) {
    1072         [ #  # ]:          0 :     if (from == 0) { // Constructor
    1073                 :          0 :       cout << IdSrc << endl;
    1074                 :          0 :       cout << IdHdr << endl;
    1075                 :            :     }
    1076                 :            :   }
    1077                 :            : }
    1078 [ +  + ][ +  - ]:         12 : }
    1079                 :            : 
    1080                 :            : 

Generated by: LCOV version 1.9