LCOV - code coverage report
Current view: top level - models - FGFCS.cpp (source / functions) Hit Total Coverage
Test: JSBSim-Coverage-Statistics Lines: 260 500 52.0 %
Date: 2010-08-24 Functions: 20 40 50.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 144 494 29.1 %

           Branch data     Line data    Source code
       1                 :            : /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
       2                 :            : 
       3                 :            :  Module:       FGFCS.cpp 
       4                 :            :  Author:       Jon Berndt
       5                 :            :  Date started: 12/12/98
       6                 :            :  Purpose:      Model the flight controls
       7                 :            :  Called by:    FDMExec
       8                 :            : 
       9                 :            :  ------------- Copyright (C) 1999  Jon S. Berndt (jon@jsbsim.org) -------------
      10                 :            : 
      11                 :            :  This program is free software; you can redistribute it and/or modify it under
      12                 :            :  the terms of the GNU Lesser General Public License as published by the Free Software
      13                 :            :  Foundation; either version 2 of the License, or (at your option) any later
      14                 :            :  version.
      15                 :            : 
      16                 :            :  This program is distributed in the hope that it will be useful, but WITHOUT
      17                 :            :  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
      18                 :            :  FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
      19                 :            :  details.
      20                 :            : 
      21                 :            :  You should have received a copy of the GNU Lesser General Public License along with
      22                 :            :  this program; if not, write to the Free Software Foundation, Inc., 59 Temple
      23                 :            :  Place - Suite 330, Boston, MA  02111-1307, USA.
      24                 :            : 
      25                 :            :  Further information about the GNU Lesser General Public License can also be found on
      26                 :            :  the world wide web at http://www.gnu.org.
      27                 :            : 
      28                 :            : FUNCTIONAL DESCRIPTION
      29                 :            : --------------------------------------------------------------------------------
      30                 :            : This class models the flight controls for a specific airplane
      31                 :            : 
      32                 :            : HISTORY
      33                 :            : --------------------------------------------------------------------------------
      34                 :            : 12/12/98   JSB   Created
      35                 :            : 
      36                 :            : %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      37                 :            : INCLUDES
      38                 :            : %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
      39                 :            : 
      40                 :            : #include "FGFCS.h"
      41                 :            : #include "FGFDMExec.h"
      42                 :            : #include "FGGroundReactions.h"
      43                 :            : #include "input_output/FGPropertyManager.h"
      44                 :            : #include <fstream>
      45                 :            : #include <sstream>
      46                 :            : #include <iomanip>
      47                 :            : 
      48                 :            : #include "models/flight_control/FGFilter.h"
      49                 :            : #include "models/flight_control/FGDeadBand.h"
      50                 :            : #include "models/flight_control/FGGain.h"
      51                 :            : #include "models/flight_control/FGPID.h"
      52                 :            : #include "models/flight_control/FGSwitch.h"
      53                 :            : #include "models/flight_control/FGSummer.h"
      54                 :            : #include "models/flight_control/FGKinemat.h"
      55                 :            : #include "models/flight_control/FGFCSFunction.h"
      56                 :            : #include "models/flight_control/FGSensor.h"
      57                 :            : #include "models/flight_control/FGActuator.h"
      58                 :            : #include "models/flight_control/FGAccelerometer.h"
      59                 :            : #include "models/flight_control/FGMagnetometer.h"
      60                 :            : #include "models/flight_control/FGGyro.h"
      61                 :            : 
      62                 :            : using namespace std;
      63                 :            : 
      64                 :            : namespace JSBSim {
      65                 :            : 
      66                 :            : static const char *IdSrc = "$Id: FGFCS.cpp,v 1.70 2010/08/21 22:56:11 jberndt Exp $";
      67                 :            : static const char *IdHdr = ID_FCS;
      68                 :            : 
      69                 :            : /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      70                 :            : CLASS IMPLEMENTATION
      71                 :            : %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
      72                 :            : 
      73                 :          1 : FGFCS::FGFCS(FGFDMExec* fdmex) : FGModel(fdmex)
      74                 :            : {
      75                 :            :   int i;
      76                 :          1 :   Name = "FGFCS";
      77                 :            : 
      78                 :          1 :   DaCmd = DeCmd = DrCmd = DsCmd = DfCmd = DsbCmd = DspCmd = 0;
      79                 :          1 :   PTrimCmd = YTrimCmd = RTrimCmd = 0.0;
      80                 :          1 :   GearCmd = GearPos = 1; // default to gear down
      81                 :          1 :   LeftBrake = RightBrake = CenterBrake = 0.0;
      82                 :          1 :   TailhookPos = WingFoldPos = 0.0; 
      83                 :            : 
      84                 :          1 :   bind();
      85 [ +  + ][ #  # ]:          5 :   for (i=0;i<NForms;i++) {
      86                 :          4 :     DePos[i] = DaLPos[i] = DaRPos[i] = DrPos[i] = 0.0;
      87                 :          4 :     DfPos[i] = DsbPos[i] = DspPos[i] = 0.0;
      88                 :            :   }
      89                 :            : 
      90                 :          1 :   Debug(0);
      91                 :          1 : }
      92                 :            : 
      93                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      94                 :            : 
      95                 :          1 : FGFCS::~FGFCS()
      96                 :            : {
      97                 :          1 :   ThrottleCmd.clear();
      98                 :          1 :   ThrottlePos.clear();
      99                 :          1 :   MixtureCmd.clear();
     100                 :          1 :   MixturePos.clear();
     101                 :          1 :   PropAdvanceCmd.clear();
     102                 :          1 :   PropAdvance.clear();
     103                 :          1 :   SteerPosDeg.clear();
     104                 :          1 :   PropFeatherCmd.clear();
     105                 :          1 :   PropFeather.clear();
     106                 :            : 
     107                 :            :   unsigned int i;
     108                 :            : 
     109 [ #  # ][ -  + ]:          1 :   for (i=0;i<APComponents.size();i++) delete APComponents[i];
         [ #  # ][ #  # ]
     110                 :          1 :   APComponents.clear();
     111 [ #  # ][ -  + ]:          1 :   for (i=0;i<FCSComponents.size();i++) delete FCSComponents[i];
         [ #  # ][ #  # ]
     112                 :          1 :   FCSComponents.clear();
     113 [ +  - ][ +  + ]:         44 :   for (i=0;i<Systems.size();i++) delete Systems[i];
         [ #  # ][ #  # ]
     114                 :          1 :   Systems.clear();
     115                 :            : 
     116                 :            : 
     117                 :          1 :   Debug(1);
     118                 :          2 : }
     119                 :            : 
     120                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     121                 :            : 
     122                 :          1 : bool FGFCS::InitModel(void)
     123                 :            : {
     124                 :            :   unsigned int i;
     125                 :            : 
     126         [ -  + ]:          1 :   if (!FGModel::InitModel()) return false;
     127                 :            : 
     128         [ -  + ]:          1 :   for (i=0; i<ThrottlePos.size(); i++) ThrottlePos[i] = 0.0;
     129         [ -  + ]:          1 :   for (i=0; i<MixturePos.size(); i++) MixturePos[i] = 0.0;
     130         [ -  + ]:          1 :   for (i=0; i<ThrottleCmd.size(); i++) ThrottleCmd[i] = 0.0;
     131         [ -  + ]:          1 :   for (i=0; i<MixtureCmd.size(); i++) MixtureCmd[i] = 0.0;
     132         [ -  + ]:          1 :   for (i=0; i<PropAdvance.size(); i++) PropAdvance[i] = 0.0;
     133         [ -  + ]:          1 :   for (i=0; i<PropFeather.size(); i++) PropFeather[i] = 0.0;
     134                 :            : 
     135                 :          1 :   DaCmd = DeCmd = DrCmd = DsCmd = DfCmd = DsbCmd = DspCmd = 0;
     136                 :          1 :   PTrimCmd = YTrimCmd = RTrimCmd = 0.0;
     137                 :          1 :   TailhookPos = WingFoldPos = 0.0;
     138                 :            : 
     139         [ +  + ]:          5 :   for (i=0;i<NForms;i++) {
     140                 :          4 :     DePos[i] = DaLPos[i] = DaRPos[i] = DrPos[i] = 0.0;
     141                 :          4 :     DfPos[i] = DsbPos[i] = DspPos[i] = 0.0;
     142                 :            :   }
     143                 :            : 
     144         [ -  + ]:          1 :   for (unsigned int i=0; i<Systems.size(); i++) {
     145 [ #  # ][ #  # ]:          0 :     if (Systems[i]->GetType() == "LAG" ||
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     146                 :            :         Systems[i]->GetType() == "LEAD_LAG" ||
     147                 :            :         Systems[i]->GetType() == "WASHOUT" ||
     148                 :            :         Systems[i]->GetType() == "SECOND_ORDER_FILTER" ||
     149                 :            :         Systems[i]->GetType() == "INTEGRATOR")
     150                 :            :     {
     151                 :          0 :       ((FGFilter*)Systems[i])->ResetPastStates();
     152         [ #  # ]:          0 :     } else if (Systems[i]->GetType() == "PID" ) {
     153                 :          0 :       ((FGPID*)Systems[i])->ResetPastStates();
     154                 :            :     }
     155                 :            :   }
     156                 :            : 
     157         [ -  + ]:          1 :   for (unsigned int i=0; i<FCSComponents.size(); i++) {
     158 [ #  # ][ #  # ]:          0 :     if (FCSComponents[i]->GetType() == "LAG" ||
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     159                 :            :         FCSComponents[i]->GetType() == "LEAD_LAG" ||
     160                 :            :         FCSComponents[i]->GetType() == "WASHOUT" ||
     161                 :            :         FCSComponents[i]->GetType() == "SECOND_ORDER_FILTER" ||
     162                 :            :         FCSComponents[i]->GetType() == "INTEGRATOR")
     163                 :            :     {
     164                 :          0 :       ((FGFilter*)FCSComponents[i])->ResetPastStates();
     165         [ #  # ]:          0 :     } else if (FCSComponents[i]->GetType() == "PID" ) {
     166                 :          0 :       ((FGPID*)FCSComponents[i])->ResetPastStates();
     167                 :            :     }
     168                 :            :   }
     169                 :            : 
     170         [ -  + ]:          1 :   for (unsigned int i=0; i<APComponents.size(); i++) {
     171 [ #  # ][ #  # ]:          0 :     if (APComponents[i]->GetType() == "LAG" ||
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     172                 :            :         APComponents[i]->GetType() == "LEAD_LAG" ||
     173                 :            :         APComponents[i]->GetType() == "WASHOUT" ||
     174                 :            :         APComponents[i]->GetType() == "SECOND_ORDER_FILTER" ||
     175                 :            :         APComponents[i]->GetType() == "INTEGRATOR")
     176                 :            :     {
     177                 :          0 :       ((FGFilter*)APComponents[i])->ResetPastStates();
     178         [ #  # ]:          0 :     } else if (APComponents[i]->GetType() == "PID" ) {
     179                 :          0 :       ((FGPID*)APComponents[i])->ResetPastStates();
     180                 :            :     }
     181                 :            :   }
     182                 :            : 
     183                 :          1 :   return true;
     184                 :            : }
     185                 :            :   
     186                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     187                 :            : 
     188                 :          1 : void FGFCS::LateBind(void)
     189                 :            : {
     190                 :            :   int i;
     191                 :            : 
     192         [ +  + ]:         44 :   for (i=0; i<Systems.size(); i++) Systems[i]->LateBind();
     193         [ -  + ]:          1 :   for (i=0; i<APComponents.size(); i++) APComponents[i]->LateBind();
     194         [ -  + ]:          1 :   for (i=0; i<FCSComponents.size(); i++) FCSComponents[i]->LateBind();
     195                 :          1 : }
     196                 :            : 
     197                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     198                 :            : // Notes: In this logic the default engine commands are set. This is simply a
     199                 :            : // sort of safe-mode method in case the user has not defined control laws for
     200                 :            : // throttle, mixture, and prop-advance. The throttle, mixture, and prop advance
     201                 :            : // positions are set equal to the respective commands. Any control logic that is
     202                 :            : // actually present in the flight_control or autopilot section will override
     203                 :            : // these simple assignments.
     204                 :            : 
     205                 :      54005 : bool FGFCS::Run(void)
     206                 :            : {
     207                 :            :   unsigned int i;
     208                 :            : 
     209         [ -  + ]:      54005 :   if (FGModel::Run()) return true; // fast exit if nothing to do
     210         [ -  + ]:      54005 :   if (FDMExec->Holding()) return false;
     211                 :            : 
     212                 :      54005 :   RunPreFunctions();
     213                 :            : 
     214         [ +  + ]:     702065 :   for (i=0; i<ThrottlePos.size(); i++) ThrottlePos[i] = ThrottleCmd[i];
     215         [ +  + ]:     702065 :   for (i=0; i<MixturePos.size(); i++) MixturePos[i] = MixtureCmd[i];
     216         [ +  + ]:     702065 :   for (i=0; i<PropAdvance.size(); i++) PropAdvance[i] = PropAdvanceCmd[i];
     217         [ +  + ]:     702065 :   for (i=0; i<PropFeather.size(); i++) PropFeather[i] = PropFeatherCmd[i];
     218                 :            : 
     219                 :            :   // Set the default steering angle
     220         [ -  + ]:      54005 :   for (i=0; i<SteerPosDeg.size(); i++) {
     221                 :          0 :     FGLGear* gear = GroundReactions->GetGearUnit(i);
     222                 :          0 :     SteerPosDeg[i] = gear->GetDefaultSteerAngle( GetDsCmd() );
     223                 :            :   }
     224                 :            : 
     225                 :            :   // Execute Systems in order
     226         [ +  + ]:    2376220 :   for (i=0; i<Systems.size(); i++) Systems[i]->Run();
     227                 :            : 
     228                 :            :   // Execute Autopilot
     229         [ -  + ]:      54005 :   for (i=0; i<APComponents.size(); i++) APComponents[i]->Run();
     230                 :            : 
     231                 :            :   // Execute Flight Control System
     232         [ -  + ]:      54005 :   for (i=0; i<FCSComponents.size(); i++) FCSComponents[i]->Run();
     233                 :            : 
     234                 :      54005 :   RunPostFunctions();
     235                 :            : 
     236                 :      54005 :   return false;
     237                 :            : }
     238                 :            : 
     239                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     240                 :            : 
     241                 :          0 : void FGFCS::SetDaLPos( int form , double pos )
     242                 :            : {
     243   [ #  #  #  # ]:          0 :   switch(form) {
     244                 :            :   case ofRad:
     245                 :          0 :     DaLPos[ofRad] = pos;
     246                 :          0 :     DaLPos[ofDeg] = pos*radtodeg;
     247                 :          0 :     break;
     248                 :            :   case ofDeg:
     249                 :          0 :     DaLPos[ofRad] = pos*degtorad;
     250                 :          0 :     DaLPos[ofDeg] = pos;
     251                 :          0 :     break;
     252                 :            :   case ofNorm:
     253                 :          0 :     DaLPos[ofNorm] = pos;
     254                 :            :   }
     255                 :          0 :   DaLPos[ofMag] = fabs(DaLPos[ofRad]);
     256                 :          0 : }
     257                 :            : 
     258                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     259                 :            : 
     260                 :          0 : void FGFCS::SetDaRPos( int form , double pos )
     261                 :            : {
     262   [ #  #  #  # ]:          0 :   switch(form) {
     263                 :            :   case ofRad:
     264                 :          0 :     DaRPos[ofRad] = pos;
     265                 :          0 :     DaRPos[ofDeg] = pos*radtodeg;
     266                 :          0 :     break;
     267                 :            :   case ofDeg:
     268                 :          0 :     DaRPos[ofRad] = pos*degtorad;
     269                 :          0 :     DaRPos[ofDeg] = pos;
     270                 :          0 :     break;
     271                 :            :   case ofNorm:
     272                 :          0 :     DaRPos[ofNorm] = pos;
     273                 :            :   }
     274                 :          0 :   DaRPos[ofMag] = fabs(DaRPos[ofRad]);
     275                 :          0 : }
     276                 :            : 
     277                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     278                 :            : 
     279                 :          0 : void FGFCS::SetDePos( int form , double pos )
     280                 :            : {
     281   [ #  #  #  # ]:          0 :   switch(form) {
     282                 :            :   case ofRad:
     283                 :          0 :     DePos[ofRad] = pos;
     284                 :          0 :     DePos[ofDeg] = pos*radtodeg;
     285                 :          0 :     break;
     286                 :            :   case ofDeg:
     287                 :          0 :     DePos[ofRad] = pos*degtorad;
     288                 :          0 :     DePos[ofDeg] = pos;
     289                 :          0 :     break;
     290                 :            :   case ofNorm:
     291                 :          0 :     DePos[ofNorm] = pos;
     292                 :            :   }
     293                 :          0 :   DePos[ofMag] = fabs(DePos[ofRad]);
     294                 :          0 : }
     295                 :            : 
     296                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     297                 :            : 
     298                 :          0 : void FGFCS::SetDrPos( int form , double pos )
     299                 :            : {
     300   [ #  #  #  # ]:          0 :   switch(form) {
     301                 :            :   case ofRad:
     302                 :          0 :     DrPos[ofRad] = pos;
     303                 :          0 :     DrPos[ofDeg] = pos*radtodeg;
     304                 :          0 :     break;
     305                 :            :   case ofDeg:
     306                 :          0 :     DrPos[ofRad] = pos*degtorad;
     307                 :          0 :     DrPos[ofDeg] = pos;
     308                 :          0 :     break;
     309                 :            :   case ofNorm:
     310                 :          0 :     DrPos[ofNorm] = pos;
     311                 :            :   }
     312                 :          0 :   DrPos[ofMag] = fabs(DrPos[ofRad]);
     313                 :          0 : }
     314                 :            : 
     315                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     316                 :            : 
     317                 :          0 : void FGFCS::SetDfPos( int form , double pos )
     318                 :            : {
     319   [ #  #  #  # ]:          0 :   switch(form) {
     320                 :            :   case ofRad:
     321                 :          0 :     DfPos[ofRad] = pos;
     322                 :          0 :     DfPos[ofDeg] = pos*radtodeg;
     323                 :          0 :     break;
     324                 :            :   case ofDeg:
     325                 :          0 :     DfPos[ofRad] = pos*degtorad;
     326                 :          0 :     DfPos[ofDeg] = pos;
     327                 :          0 :     break;
     328                 :            :   case ofNorm:
     329                 :          0 :     DfPos[ofNorm] = pos;
     330                 :            :   }
     331                 :          0 :   DfPos[ofMag] = fabs(DfPos[ofRad]);
     332                 :          0 : }
     333                 :            : 
     334                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     335                 :            : 
     336                 :          0 : void FGFCS::SetDsbPos( int form , double pos )
     337                 :            : {
     338   [ #  #  #  # ]:          0 :   switch(form) {
     339                 :            :   case ofRad:
     340                 :          0 :     DsbPos[ofRad] = pos;
     341                 :          0 :     DsbPos[ofDeg] = pos*radtodeg;
     342                 :          0 :     break;
     343                 :            :   case ofDeg:
     344                 :          0 :     DsbPos[ofRad] = pos*degtorad;
     345                 :          0 :     DsbPos[ofDeg] = pos;
     346                 :          0 :     break;
     347                 :            :   case ofNorm:
     348                 :          0 :     DsbPos[ofNorm] = pos;
     349                 :            :   }
     350                 :          0 :   DsbPos[ofMag] = fabs(DsbPos[ofRad]);
     351                 :          0 : }
     352                 :            : 
     353                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     354                 :            : 
     355                 :          0 : void FGFCS::SetDspPos( int form , double pos )
     356                 :            : {
     357   [ #  #  #  # ]:          0 :   switch(form) {
     358                 :            :   case ofRad:
     359                 :          0 :     DspPos[ofRad] = pos;
     360                 :          0 :     DspPos[ofDeg] = pos*radtodeg;
     361                 :          0 :     break;
     362                 :            :   case ofDeg:
     363                 :          0 :     DspPos[ofRad] = pos*degtorad;
     364                 :          0 :     DspPos[ofDeg] = pos;
     365                 :          0 :     break;
     366                 :            :   case ofNorm:
     367                 :          0 :     DspPos[ofNorm] = pos;
     368                 :            :   }
     369                 :          0 :   DspPos[ofMag] = fabs(DspPos[ofRad]);
     370                 :          0 : }
     371                 :            : 
     372                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     373                 :            : 
     374                 :     213136 : void FGFCS::SetThrottleCmd(int engineNum, double setting)
     375                 :            : {
     376                 :            :   unsigned int ctr;
     377                 :            : 
     378         [ +  - ]:     213136 :   if (engineNum < (int)ThrottlePos.size()) {
     379         [ -  + ]:     213136 :     if (engineNum < 0) {
     380         [ #  # ]:          0 :       for (ctr=0;ctr<ThrottleCmd.size();ctr++) ThrottleCmd[ctr] = setting;
     381                 :            :     } else {
     382                 :     213136 :       ThrottleCmd[engineNum] = setting;
     383                 :            :     }
     384                 :            :   } else {
     385                 :            :     cerr << "Throttle " << engineNum << " does not exist! " << ThrottleCmd.size()
     386                 :            :          << " engines exist, but attempted throttle command is for engine "
     387                 :          0 :          << engineNum << endl;
     388                 :            :   }
     389                 :     213136 : }
     390                 :            : 
     391                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     392                 :            : 
     393                 :          0 : void FGFCS::SetThrottlePos(int engineNum, double setting)
     394                 :            : {
     395                 :            :   unsigned int ctr;
     396                 :            : 
     397         [ #  # ]:          0 :   if (engineNum < (int)ThrottlePos.size()) {
     398         [ #  # ]:          0 :     if (engineNum < 0) {
     399         [ #  # ]:          0 :       for (ctr=0;ctr<ThrottlePos.size();ctr++) ThrottlePos[ctr] = setting;
     400                 :            :     } else {
     401                 :          0 :       ThrottlePos[engineNum] = setting;
     402                 :            :     }
     403                 :            :   } else {
     404                 :            :     cerr << "Throttle " << engineNum << " does not exist! " << ThrottlePos.size()
     405                 :            :          << " engines exist, but attempted throttle position setting is for engine "
     406                 :          0 :          << engineNum << endl;
     407                 :            :   }
     408                 :          0 : }
     409                 :            : 
     410                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     411                 :            : 
     412                 :      54074 : double FGFCS::GetThrottleCmd(int engineNum) const
     413                 :            : {
     414         [ +  - ]:      54074 :   if (engineNum < (int)ThrottlePos.size()) {
     415         [ -  + ]:      54074 :     if (engineNum < 0) {
     416                 :          0 :        cerr << "Cannot get throttle value for ALL engines" << endl;
     417                 :            :     } else {
     418                 :      54074 :       return ThrottleCmd[engineNum];
     419                 :            :     }
     420                 :            :   } else {
     421                 :            :     cerr << "Throttle " << engineNum << " does not exist! " << ThrottleCmd.size()
     422                 :            :          << " engines exist, but throttle setting for engine " << engineNum
     423                 :          0 :          << " is selected" << endl;
     424                 :            :   }
     425                 :      54074 :   return 0.0;
     426                 :            : }
     427                 :            : 
     428                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     429                 :            : 
     430                 :     648072 : double FGFCS::GetThrottlePos(int engineNum) const
     431                 :            : {
     432         [ +  - ]:     648072 :   if (engineNum < (int)ThrottlePos.size()) {
     433         [ -  + ]:     648072 :     if (engineNum < 0) {
     434                 :          0 :        cerr << "Cannot get throttle value for ALL engines" << endl;
     435                 :            :     } else {
     436                 :     648072 :       return ThrottlePos[engineNum];
     437                 :            :     }
     438                 :            :   } else {
     439                 :            :     cerr << "Throttle " << engineNum << " does not exist! " << ThrottlePos.size()
     440                 :            :          << " engines exist, but attempted throttle position setting is for engine "
     441                 :          0 :          << engineNum << endl;
     442                 :            :   }
     443                 :     648072 :   return 0.0;
     444                 :            : }
     445                 :            : 
     446                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     447                 :            : 
     448                 :          0 : void FGFCS::SetMixtureCmd(int engineNum, double setting)
     449                 :            : {
     450                 :            :   unsigned int ctr;
     451                 :            : 
     452         [ #  # ]:          0 :   if (engineNum < (int)ThrottlePos.size()) {
     453         [ #  # ]:          0 :     if (engineNum < 0) {
     454         [ #  # ]:          0 :       for (ctr=0;ctr<MixtureCmd.size();ctr++) MixtureCmd[ctr] = setting;
     455                 :            :     } else {
     456                 :          0 :       MixtureCmd[engineNum] = setting;
     457                 :            :     }
     458                 :            :   }
     459                 :          0 : }
     460                 :            : 
     461                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     462                 :            : 
     463                 :          0 : void FGFCS::SetMixturePos(int engineNum, double setting)
     464                 :            : {
     465                 :            :   unsigned int ctr;
     466                 :            : 
     467         [ #  # ]:          0 :   if (engineNum < (int)ThrottlePos.size()) {
     468         [ #  # ]:          0 :     if (engineNum < 0) {
     469         [ #  # ]:          0 :       for (ctr=0;ctr<MixtureCmd.size();ctr++) MixturePos[ctr] = MixtureCmd[ctr];
     470                 :            :     } else {
     471                 :          0 :       MixturePos[engineNum] = setting;
     472                 :            :     }
     473                 :            :   }
     474                 :          0 : }
     475                 :            : 
     476                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     477                 :            : 
     478                 :          0 : void FGFCS::SetPropAdvanceCmd(int engineNum, double setting)
     479                 :            : {
     480                 :            :   unsigned int ctr;
     481                 :            : 
     482         [ #  # ]:          0 :   if (engineNum < (int)ThrottlePos.size()) {
     483         [ #  # ]:          0 :     if (engineNum < 0) {
     484         [ #  # ]:          0 :       for (ctr=0;ctr<PropAdvanceCmd.size();ctr++) PropAdvanceCmd[ctr] = setting;
     485                 :            :     } else {
     486                 :          0 :       PropAdvanceCmd[engineNum] = setting;
     487                 :            :     }
     488                 :            :   }
     489                 :          0 : }
     490                 :            : 
     491                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     492                 :            : 
     493                 :          0 : void FGFCS::SetPropAdvance(int engineNum, double setting)
     494                 :            : {
     495                 :            :   unsigned int ctr;
     496                 :            : 
     497         [ #  # ]:          0 :   if (engineNum < (int)ThrottlePos.size()) {
     498         [ #  # ]:          0 :     if (engineNum < 0) {
     499         [ #  # ]:          0 :       for (ctr=0;ctr<PropAdvanceCmd.size();ctr++) PropAdvance[ctr] = PropAdvanceCmd[ctr];
     500                 :            :     } else {
     501                 :          0 :       PropAdvance[engineNum] = setting;
     502                 :            :     }
     503                 :            :   }
     504                 :          0 : }
     505                 :            : 
     506                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     507                 :            : 
     508                 :          0 : void FGFCS::SetFeatherCmd(int engineNum, bool setting)
     509                 :            : {
     510                 :            :   unsigned int ctr;
     511                 :            : 
     512         [ #  # ]:          0 :   if (engineNum < (int)ThrottlePos.size()) {
     513         [ #  # ]:          0 :     if (engineNum < 0) {
     514         [ #  # ]:          0 :       for (ctr=0;ctr<PropFeatherCmd.size();ctr++) PropFeatherCmd[ctr] = setting;
     515                 :            :     } else {
     516                 :          0 :       PropFeatherCmd[engineNum] = setting;
     517                 :            :     }
     518                 :            :   }
     519                 :          0 : }
     520                 :            : 
     521                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     522                 :            : 
     523                 :          0 : void FGFCS::SetPropFeather(int engineNum, bool setting)
     524                 :            : {
     525                 :            :   unsigned int ctr;
     526                 :            : 
     527         [ #  # ]:          0 :   if (engineNum < (int)ThrottlePos.size()) {
     528         [ #  # ]:          0 :     if (engineNum < 0) {
     529         [ #  # ]:          0 :       for (ctr=0;ctr<PropFeatherCmd.size();ctr++) PropFeather[ctr] = PropFeatherCmd[ctr];
     530                 :            :     } else {
     531                 :          0 :       PropFeather[engineNum] = setting;
     532                 :            :     }
     533                 :            :   }
     534                 :          0 : }
     535                 :            : 
     536                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     537                 :            : 
     538                 :          4 : bool FGFCS::Load(Element* el, SystemType systype)
     539                 :            : {
     540                 :          4 :   string name, file, fname="", interface_property_string, parent_name;
     541                 :            :   vector <FGFCSComponent*> *Components;
     542                 :            :   Element *component_element;
     543                 :            :   Element *channel_element;
     544                 :            : 
     545                 :          4 :   Components=0;
     546                 :            : 
     547                 :            : // ToDo: The handling of name and file attributes could be improved, here,
     548                 :            : //       considering that a name can be in the external file, as well.
     549                 :            : 
     550                 :          8 :   name = el->GetAttributeValue("name");
     551                 :            : 
     552 [ +  - ][ +  - ]:          8 :   if (name.empty() || !el->GetAttributeValue("file").empty()) {
         [ +  - ][ #  # ]
         [ #  # ][ +  - ]
         [ #  # ][ +  - ]
                 [ +  - ]
     553                 :          8 :     fname = el->GetAttributeValue("file");
     554         [ +  - ]:          4 :     if (systype == stSystem) {
     555                 :          8 :       file = FindSystemFullPathname(fname);
     556                 :            :     } else { 
     557                 :          0 :       file = FDMExec->GetFullAircraftPath() + "/" + fname + ".xml";
     558                 :            :     }
     559         [ -  + ]:          4 :     if (fname.empty()) {
     560                 :          0 :       cerr << "FCS, Autopilot, or system does not appear to be defined inline nor in a file" << endl;
     561                 :          0 :       return false;
     562                 :            :     } else {
     563                 :          8 :       document = LoadXMLDocument(file);
     564         [ -  + ]:          4 :       if (!document) {
     565                 :          0 :         cerr << "Error loading file " << file << endl;
     566                 :          0 :         return false;
     567                 :            :       }
     568                 :          8 :       name = document->GetAttributeValue("name");
     569                 :            :     }
     570                 :            :   } else {
     571                 :          0 :     document = el;
     572                 :            :   }
     573                 :            : 
     574         [ -  + ]:          4 :   if (document->GetName() == "autopilot") {
     575                 :          0 :     Components = &APComponents;
     576                 :          0 :     Name = "Autopilot: " + document->GetAttributeValue("name");
     577         [ -  + ]:          4 :   } else if (document->GetName() == "flight_control") {
     578                 :          0 :     Components = &FCSComponents;
     579                 :          0 :     Name = "FCS: " + document->GetAttributeValue("name");
     580         [ +  - ]:          4 :   } else if (document->GetName() == "system") {
     581                 :          4 :     Components = &Systems;
     582                 :          8 :     Name = "System: " + document->GetAttributeValue("name");
     583                 :            :   }
     584                 :          4 :   Debug(2);
     585                 :            : 
     586         [ -  + ]:          4 :   if (document->GetName() == "flight_control") bindModel();
     587                 :            : 
     588                 :          4 :   FGModel::Load(document); // Load interface properties from document
     589                 :            : 
     590                 :            :   // After reading interface properties in a file, read properties in the local
     591                 :            :   // flight_control, autopilot, or system element. This allows general-purpose
     592                 :            :   // systems to be defined in a file, with overrides or initial loaded constants
     593                 :            :   // supplied in the relevant element of the aircraft configuration file.
     594                 :            : 
     595                 :          4 :   Element* property_element = 0;
     596                 :            : 
     597         [ +  - ]:          4 :   if (!fname.empty()) {
     598                 :          4 :     property_element = el->FindElement("property");
     599 [ -  + ][ #  # ]:          4 :     if (property_element && debug_lvl > 0) cout << endl << "    Overriding properties" << endl << endl;
     600         [ -  + ]:          4 :     while (property_element) {
     601                 :          0 :       double value=0.0;
     602         [ #  # ]:          0 :       if ( ! property_element->GetAttributeValue("value").empty())
     603                 :          0 :         value = property_element->GetAttributeValueAsNumber("value");
     604                 :            : 
     605                 :          0 :       interface_property_string = property_element->GetDataLine();
     606         [ #  # ]:          0 :       if (PropertyManager->HasNode(interface_property_string)) {
     607                 :          0 :         FGPropertyManager* node = PropertyManager->GetNode(interface_property_string);
     608         [ #  # ]:          0 :         if (debug_lvl > 0)
     609                 :            :           cout << "      " << "Overriding value for property " << interface_property_string
     610                 :          0 :                << " (old value: " << node->getDoubleValue() << "  new value: " << value << ")" << endl;
     611                 :          0 :         node->setDoubleValue(value);
     612                 :            :       } else {
     613                 :          0 :         interface_properties.push_back(new double(value));
     614                 :          0 :         PropertyManager->Tie(interface_property_string, interface_properties.back());
     615         [ #  # ]:          0 :         if (debug_lvl > 0)
     616                 :          0 :           cout << "      " << interface_property_string << " (initial value: " << value << ")" << endl;
     617                 :            :       }
     618                 :            :       
     619                 :          0 :       property_element = el->FindNextElement("property");
     620                 :            :     }
     621                 :            :   }
     622                 :            : 
     623                 :          4 :   channel_element = document->FindElement("channel");
     624         [ +  + ]:         18 :   while (channel_element) {
     625                 :            :   
     626         [ +  - ]:         14 :     if (debug_lvl > 0)
     627                 :            :       cout << endl << highint << fgblue << "    Channel " 
     628                 :         42 :          << normint << channel_element->GetAttributeValue("name") << reset << endl;
     629                 :            :   
     630                 :         14 :     component_element = channel_element->GetElement();
     631         [ +  + ]:         57 :     while (component_element) {
     632                 :            :       try {
     633 [ +  + ][ +  - ]:        246 :         if ((component_element->GetName() == string("lag_filter")) ||
         [ +  - ][ +  - ]
         [ -  + ][ +  + ]
         [ #  # ][ #  # ]
         [ +  + ][ #  # ]
         [ +  + ][ #  # ]
         [ +  + ][ #  # ]
         [ +  + ][ #  # ]
         [ +  + ][ #  # ]
         [ +  + ][ #  # ]
         [ +  + ][ #  # ]
         [ +  - ][ #  # ]
         [ +  - ][ +  + ]
     634                 :            :             (component_element->GetName() == string("lead_lag_filter")) ||
     635                 :            :             (component_element->GetName() == string("washout_filter")) ||
     636                 :            :             (component_element->GetName() == string("second_order_filter")) ||
     637                 :            :             (component_element->GetName() == string("integrator")) )
     638                 :            :         {
     639                 :          3 :           Components->push_back(new FGFilter(this, component_element));
     640 [ +  + ][ +  - ]:        146 :         } else if ((component_element->GetName() == string("pure_gain")) ||
         [ -  + ][ +  + ]
         [ #  # ][ #  # ]
         [ +  + ][ #  # ]
         [ +  + ][ #  # ]
         [ +  + ][ #  # ]
         [ +  - ][ #  # ]
         [ +  - ][ +  + ]
     641                 :            :                    (component_element->GetName() == string("scheduled_gain")) ||
     642                 :            :                    (component_element->GetName() == string("aerosurface_scale")))
     643                 :            :         {
     644                 :          7 :           Components->push_back(new FGGain(this, component_element));
     645         [ +  + ]:         33 :         } else if (component_element->GetName() == string("summer")) {
     646                 :          4 :           Components->push_back(new FGSummer(this, component_element));
     647         [ -  + ]:         29 :         } else if (component_element->GetName() == string("deadband")) {
     648                 :          0 :           Components->push_back(new FGDeadBand(this, component_element));
     649         [ +  + ]:         29 :         } else if (component_element->GetName() == string("switch")) {
     650                 :         14 :           Components->push_back(new FGSwitch(this, component_element));
     651         [ -  + ]:         15 :         } else if (component_element->GetName() == string("kinematic")) {
     652                 :          0 :           Components->push_back(new FGKinemat(this, component_element));
     653         [ +  + ]:         15 :         } else if (component_element->GetName() == string("fcs_function")) {
     654                 :          4 :           Components->push_back(new FGFCSFunction(this, component_element));
     655         [ +  + ]:         11 :         } else if (component_element->GetName() == string("pid")) {
     656                 :          7 :           Components->push_back(new FGPID(this, component_element));
     657         [ +  - ]:          4 :         } else if (component_element->GetName() == string("actuator")) {
     658                 :          4 :           Components->push_back(new FGActuator(this, component_element));
     659         [ #  # ]:          0 :         } else if (component_element->GetName() == string("sensor")) {
     660                 :          0 :           Components->push_back(new FGSensor(this, component_element));
     661         [ #  # ]:          0 :         } else if (component_element->GetName() == string("accelerometer")) {
     662                 :          0 :           Components->push_back(new FGAccelerometer(this, component_element));
     663         [ #  # ]:          0 :         } else if (component_element->GetName() == string("magnetometer")) {
     664                 :          0 :           Components->push_back(new FGMagnetometer(this, component_element));
     665         [ #  # ]:          0 :         } else if (component_element->GetName() == string("gyro")) {
     666                 :          0 :           Components->push_back(new FGGyro(this, component_element));
     667                 :            :         } else {
     668                 :          0 :           cerr << "Unknown FCS component: " << component_element->GetName() << endl;
     669                 :            :         }
     670                 :          0 :       } catch(string s) {
     671                 :          0 :         cerr << highint << fgred << endl << "  " << s << endl;
     672                 :          0 :         cerr << reset << endl;
     673                 :          0 :         return false;
     674                 :            :       }
     675                 :         43 :       component_element = channel_element->GetNextElement();
     676                 :            :     }
     677                 :         14 :     channel_element = document->FindNextElement("channel");
     678                 :            :   }
     679                 :            : 
     680                 :          4 :   ResetParser();
     681                 :            : 
     682                 :          4 :   return true;
     683                 :            : }
     684                 :            : 
     685                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     686                 :            : 
     687                 :          0 : double FGFCS::GetBrake(FGLGear::BrakeGroup bg)
     688                 :            : {
     689   [ #  #  #  # ]:          0 :   switch (bg) {
     690                 :            :   case FGLGear::bgLeft:
     691                 :          0 :     return LeftBrake;
     692                 :            :   case FGLGear::bgRight:
     693                 :          0 :     return RightBrake;
     694                 :            :   case FGLGear::bgCenter:
     695                 :          0 :     return CenterBrake;
     696                 :            :   default:
     697                 :          0 :     cerr << "GetBrake asked to return a bogus brake value" << endl;
     698                 :            :   }
     699                 :          0 :   return 0.0;
     700                 :            : }
     701                 :            : 
     702                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     703                 :            : 
     704                 :          4 : string FGFCS::FindSystemFullPathname(const string& sysfilename)
     705                 :            : {
     706                 :          4 :   string fullpath, localpath;
     707                 :          4 :   string system_filename = sysfilename;
     708                 :          4 :   string systemPath = FDMExec->GetSystemsPath();
     709                 :          4 :   string aircraftPath = FDMExec->GetFullAircraftPath();
     710                 :          4 :   ifstream system_file;
     711                 :            : 
     712                 :          8 :   fullpath = systemPath + "/";
     713                 :          8 :   localpath = aircraftPath + "/Systems/";
     714                 :            : 
     715 [ +  - ][ -  + ]:          8 :   if (system_filename.length() <=4 || system_filename.substr(system_filename.length()-4, 4) != ".xml") {
         [ +  - ][ #  # ]
                 [ -  + ]
     716                 :          0 :     system_filename.append(".xml");
     717                 :            :   }
     718                 :            : 
     719                 :          4 :   system_file.open(string(localpath + system_filename).c_str());
     720         [ -  + ]:          4 :   if ( !system_file.is_open()) {
     721                 :          0 :     system_file.open(string(fullpath + system_filename).c_str());
     722         [ #  # ]:          0 :       if ( !system_file.is_open()) {
     723                 :            :         cerr << " Could not open system file: " << system_filename << " in path "
     724                 :          0 :              << fullpath << " or " << localpath << endl;
     725                 :          0 :         return string("");
     726                 :            :       } else {
     727                 :          0 :         return string(fullpath + system_filename);
     728                 :            :       }
     729                 :            :   }
     730                 :          4 :   return string(localpath + system_filename);
     731                 :            : }
     732                 :            : 
     733                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     734                 :            : 
     735                 :          0 : ifstream* FGFCS::FindSystemFile(const string& sysfilename)
     736                 :            : {
     737                 :          0 :   string fullpath, localpath;
     738                 :          0 :   string system_filename = sysfilename;
     739                 :          0 :   string systemPath = FDMExec->GetSystemsPath();
     740                 :          0 :   string aircraftPath = FDMExec->GetFullAircraftPath();
     741                 :          0 :   ifstream* system_file = new ifstream();
     742                 :            : 
     743                 :          0 :   fullpath = systemPath + "/";
     744                 :          0 :   localpath = aircraftPath + "/Systems/";
     745                 :            : 
     746         [ #  # ]:          0 :   if (system_filename.substr(system_filename.length()-4, 4) != ".xml") {
     747                 :          0 :     system_filename.append(".xml");
     748                 :            :   }
     749                 :            : 
     750                 :          0 :   system_file->open(string(localpath + system_filename).c_str());
     751         [ #  # ]:          0 :   if ( !system_file->is_open()) {
     752                 :          0 :     system_file->open(string(fullpath + system_filename).c_str());
     753         [ #  # ]:          0 :       if ( !system_file->is_open()) {
     754                 :            :         cerr << " Could not open system file: " << system_filename << " in path "
     755                 :          0 :              << fullpath << " or " << localpath << endl;
     756                 :            :       }
     757                 :            :   }
     758                 :          0 :   return system_file;
     759                 :            : }
     760                 :            : 
     761                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     762                 :            : 
     763                 :          1 : string FGFCS::GetComponentStrings(const string& delimiter)
     764                 :            : {
     765                 :            :   unsigned int comp;
     766                 :          1 :   string CompStrings = "";
     767                 :          1 :   bool firstime = true;
     768                 :          1 :   int total_count=0;
     769                 :            : 
     770         [ +  + ]:         44 :   for (unsigned int i=0; i<Systems.size(); i++) {
     771         [ +  + ]:         43 :     if (firstime) firstime = false;
     772                 :         42 :     else          CompStrings += delimiter;
     773                 :            : 
     774                 :         43 :     CompStrings += Systems[i]->GetName();
     775                 :         43 :     total_count++;
     776                 :            :   }
     777                 :            : 
     778         [ -  + ]:          1 :   for (comp = 0; comp < APComponents.size(); comp++)
     779                 :            :   {
     780         [ #  # ]:          0 :     if (firstime) firstime = false;
     781                 :          0 :     else          CompStrings += delimiter;
     782                 :            : 
     783                 :          0 :     CompStrings += APComponents[comp]->GetName();
     784                 :          0 :     total_count++;
     785                 :            :   }
     786                 :            : 
     787         [ -  + ]:          1 :   for (comp = 0; comp < FCSComponents.size(); comp++) {
     788         [ #  # ]:          0 :     if (firstime) firstime = false;
     789                 :          0 :     else          CompStrings += delimiter;
     790                 :            : 
     791                 :          0 :     CompStrings += FCSComponents[comp]->GetName();
     792                 :          0 :     total_count++;
     793                 :            :   }
     794                 :            : 
     795                 :          1 :   return CompStrings;
     796                 :            : }
     797                 :            : 
     798                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     799                 :            : 
     800                 :       4909 : string FGFCS::GetComponentValues(const string& delimiter)
     801                 :            : {
     802                 :       4909 :   std::ostringstream buf;
     803                 :            : 
     804                 :            :   unsigned int comp;
     805                 :       4909 :   bool firstime = true;
     806                 :       4909 :   int total_count=0;
     807                 :            : 
     808         [ +  + ]:     215996 :   for (unsigned int i=0; i<Systems.size(); i++) {
     809         [ +  + ]:     211087 :     if (firstime) firstime = false;
     810                 :     206178 :     else          buf << delimiter;
     811                 :            : 
     812                 :     633261 :     buf << setprecision(9) << Systems[i]->GetOutput();
     813                 :     211087 :     total_count++;
     814                 :            :   }
     815                 :            : 
     816         [ -  + ]:       4909 :   for (comp = 0; comp < APComponents.size(); comp++) {
     817         [ #  # ]:          0 :     if (firstime) firstime = false;
     818                 :          0 :     else          buf << delimiter;
     819                 :            : 
     820                 :          0 :     buf << setprecision(9) << APComponents[comp]->GetOutput();
     821                 :          0 :     total_count++;
     822                 :            :   }
     823                 :            : 
     824         [ -  + ]:       4909 :   for (comp = 0; comp < FCSComponents.size(); comp++) {
     825         [ #  # ]:          0 :     if (firstime) firstime = false;
     826                 :          0 :     else          buf << delimiter;
     827                 :            : 
     828                 :          0 :     buf << setprecision(9) << FCSComponents[comp]->GetOutput();
     829                 :          0 :     total_count++;
     830                 :            :   }
     831                 :            : 
     832                 :       4909 :   return buf.str();
     833                 :            : }
     834                 :            : 
     835                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     836                 :            : 
     837                 :         12 : void FGFCS::AddThrottle(void)
     838                 :            : {
     839                 :         12 :   ThrottleCmd.push_back(0.0);
     840                 :         12 :   ThrottlePos.push_back(0.0);
     841                 :         12 :   MixtureCmd.push_back(0.0);     // assume throttle and mixture are coupled
     842                 :         12 :   MixturePos.push_back(0.0);
     843                 :         12 :   PropAdvanceCmd.push_back(0.0); // assume throttle and prop pitch are coupled
     844                 :         12 :   PropAdvance.push_back(0.0);
     845                 :         12 :   PropFeatherCmd.push_back(false);
     846                 :         12 :   PropFeather.push_back(false);
     847                 :            : 
     848                 :         24 :   unsigned int num = (unsigned int)ThrottleCmd.size()-1;
     849                 :         12 :   bindThrottle(num);
     850                 :         12 : }
     851                 :            : 
     852                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     853                 :            : 
     854                 :          0 : void FGFCS::AddGear(void)
     855                 :            : {
     856                 :          0 :   SteerPosDeg.push_back(0.0);
     857                 :          0 : }
     858                 :            : 
     859                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     860                 :            : 
     861                 :         43 : double FGFCS::GetDt(void)
     862                 :            : {
     863                 :         43 :   return FDMExec->GetDeltaT()*rate;
     864                 :            : }
     865                 :            : 
     866                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     867                 :            : 
     868                 :          1 : void FGFCS::bind(void)
     869                 :            : {
     870                 :          1 :   PropertyManager->Tie("fcs/aileron-cmd-norm", this, &FGFCS::GetDaCmd, &FGFCS::SetDaCmd);
     871                 :          1 :   PropertyManager->Tie("fcs/elevator-cmd-norm", this, &FGFCS::GetDeCmd, &FGFCS::SetDeCmd);
     872                 :          1 :   PropertyManager->Tie("fcs/rudder-cmd-norm", this, &FGFCS::GetDrCmd, &FGFCS::SetDrCmd);
     873                 :          1 :   PropertyManager->Tie("fcs/flap-cmd-norm", this, &FGFCS::GetDfCmd, &FGFCS::SetDfCmd);
     874                 :          1 :   PropertyManager->Tie("fcs/speedbrake-cmd-norm", this, &FGFCS::GetDsbCmd, &FGFCS::SetDsbCmd);
     875                 :          1 :   PropertyManager->Tie("fcs/spoiler-cmd-norm", this, &FGFCS::GetDspCmd, &FGFCS::SetDspCmd);
     876                 :          1 :   PropertyManager->Tie("fcs/pitch-trim-cmd-norm", this, &FGFCS::GetPitchTrimCmd, &FGFCS::SetPitchTrimCmd);
     877                 :          1 :   PropertyManager->Tie("fcs/roll-trim-cmd-norm", this, &FGFCS::GetRollTrimCmd, &FGFCS::SetRollTrimCmd);
     878                 :          1 :   PropertyManager->Tie("fcs/yaw-trim-cmd-norm", this, &FGFCS::GetYawTrimCmd, &FGFCS::SetYawTrimCmd);
     879                 :            : 
     880                 :          1 :   PropertyManager->Tie("fcs/left-aileron-pos-rad", this, ofRad, &FGFCS::GetDaLPos, &FGFCS::SetDaLPos);
     881                 :          1 :   PropertyManager->Tie("fcs/left-aileron-pos-deg", this, ofDeg, &FGFCS::GetDaLPos, &FGFCS::SetDaLPos);
     882                 :          1 :   PropertyManager->Tie("fcs/left-aileron-pos-norm", this, ofNorm, &FGFCS::GetDaLPos, &FGFCS::SetDaLPos);
     883                 :          1 :   PropertyManager->Tie("fcs/mag-left-aileron-pos-rad", this, ofMag, &FGFCS::GetDaLPos);
     884                 :            : 
     885                 :          1 :   PropertyManager->Tie("fcs/right-aileron-pos-rad", this, ofRad, &FGFCS::GetDaRPos, &FGFCS::SetDaRPos);
     886                 :          1 :   PropertyManager->Tie("fcs/right-aileron-pos-deg", this, ofDeg, &FGFCS::GetDaRPos, &FGFCS::SetDaRPos);
     887                 :          1 :   PropertyManager->Tie("fcs/right-aileron-pos-norm", this, ofNorm, &FGFCS::GetDaRPos, &FGFCS::SetDaRPos);
     888                 :          1 :   PropertyManager->Tie("fcs/mag-right-aileron-pos-rad", this, ofMag, &FGFCS::GetDaRPos);
     889                 :            : 
     890                 :          1 :   PropertyManager->Tie("fcs/elevator-pos-rad", this, ofRad, &FGFCS::GetDePos, &FGFCS::SetDePos);
     891                 :          1 :   PropertyManager->Tie("fcs/elevator-pos-deg", this, ofDeg, &FGFCS::GetDePos, &FGFCS::SetDePos);
     892                 :          1 :   PropertyManager->Tie("fcs/elevator-pos-norm", this, ofNorm, &FGFCS::GetDePos, &FGFCS::SetDePos);
     893                 :          1 :   PropertyManager->Tie("fcs/mag-elevator-pos-rad", this, ofMag, &FGFCS::GetDePos);
     894                 :            : 
     895                 :          1 :   PropertyManager->Tie("fcs/rudder-pos-rad", this,ofRad, &FGFCS::GetDrPos, &FGFCS::SetDrPos);
     896                 :          1 :   PropertyManager->Tie("fcs/rudder-pos-deg", this,ofDeg, &FGFCS::GetDrPos, &FGFCS::SetDrPos);
     897                 :          1 :   PropertyManager->Tie("fcs/rudder-pos-norm", this,ofNorm, &FGFCS::GetDrPos, &FGFCS::SetDrPos);
     898                 :          1 :   PropertyManager->Tie("fcs/mag-rudder-pos-rad", this,ofMag, &FGFCS::GetDrPos);
     899                 :            : 
     900                 :          1 :   PropertyManager->Tie("fcs/flap-pos-rad", this,ofRad, &FGFCS::GetDfPos, &FGFCS::SetDfPos);
     901                 :          1 :   PropertyManager->Tie("fcs/flap-pos-deg", this,ofDeg, &FGFCS::GetDfPos, &FGFCS::SetDfPos);
     902                 :          1 :   PropertyManager->Tie("fcs/flap-pos-norm", this,ofNorm, &FGFCS::GetDfPos, &FGFCS::SetDfPos);
     903                 :            : 
     904                 :          1 :   PropertyManager->Tie("fcs/speedbrake-pos-rad", this,ofRad, &FGFCS::GetDsbPos, &FGFCS::SetDsbPos);
     905                 :          1 :   PropertyManager->Tie("fcs/speedbrake-pos-deg", this,ofDeg, &FGFCS::GetDsbPos, &FGFCS::SetDsbPos);
     906                 :          1 :   PropertyManager->Tie("fcs/speedbrake-pos-norm", this,ofNorm, &FGFCS::GetDsbPos, &FGFCS::SetDsbPos);
     907                 :          1 :   PropertyManager->Tie("fcs/mag-speedbrake-pos-rad", this,ofMag, &FGFCS::GetDsbPos);
     908                 :            : 
     909                 :          1 :   PropertyManager->Tie("fcs/spoiler-pos-rad", this, ofRad, &FGFCS::GetDspPos, &FGFCS::SetDspPos);
     910                 :          1 :   PropertyManager->Tie("fcs/spoiler-pos-deg", this, ofDeg, &FGFCS::GetDspPos, &FGFCS::SetDspPos);
     911                 :          1 :   PropertyManager->Tie("fcs/spoiler-pos-norm", this, ofNorm, &FGFCS::GetDspPos, &FGFCS::SetDspPos);
     912                 :          1 :   PropertyManager->Tie("fcs/mag-spoiler-pos-rad", this, ofMag, &FGFCS::GetDspPos);
     913                 :            : 
     914                 :          1 :   PropertyManager->Tie("gear/gear-pos-norm", this, &FGFCS::GetGearPos, &FGFCS::SetGearPos);
     915                 :          1 :   PropertyManager->Tie("gear/gear-cmd-norm", this, &FGFCS::GetGearCmd, &FGFCS::SetGearCmd);
     916                 :          1 :   PropertyManager->Tie("fcs/left-brake-cmd-norm", this, &FGFCS::GetLBrake, &FGFCS::SetLBrake);
     917                 :          1 :   PropertyManager->Tie("fcs/right-brake-cmd-norm", this, &FGFCS::GetRBrake, &FGFCS::SetRBrake);
     918                 :          1 :   PropertyManager->Tie("fcs/center-brake-cmd-norm", this, &FGFCS::GetCBrake, &FGFCS::SetCBrake);
     919                 :          1 :   PropertyManager->Tie("fcs/steer-cmd-norm", this, &FGFCS::GetDsCmd, &FGFCS::SetDsCmd);
     920                 :            : 
     921                 :          1 :   PropertyManager->Tie("gear/tailhook-pos-norm", this, &FGFCS::GetTailhookPos, &FGFCS::SetTailhookPos);
     922                 :          1 :   PropertyManager->Tie("fcs/wing-fold-pos-norm", this, &FGFCS::GetWingFoldPos, &FGFCS::SetWingFoldPos);
     923                 :          1 : }
     924                 :            : 
     925                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     926                 :            : // Technically, this function should probably bind propulsion type specific controls
     927                 :            : // rather than mixture and prop-advance.
     928                 :            : 
     929                 :         12 : void FGFCS::bindThrottle(unsigned int num)
     930                 :            : {
     931                 :         12 :   string tmp;
     932                 :            : 
     933                 :         24 :   tmp = CreateIndexedPropertyName("fcs/throttle-cmd-norm", num);
     934                 :            :   PropertyManager->Tie( tmp.c_str(), this, num, &FGFCS::GetThrottleCmd,
     935                 :         12 :                                         &FGFCS::SetThrottleCmd);
     936                 :         24 :   tmp = CreateIndexedPropertyName("fcs/throttle-pos-norm", num);
     937                 :            :   PropertyManager->Tie( tmp.c_str(), this, num, &FGFCS::GetThrottlePos,
     938                 :         12 :                                         &FGFCS::SetThrottlePos);
     939                 :         24 :   tmp = CreateIndexedPropertyName("fcs/mixture-cmd-norm", num);
     940                 :            :   PropertyManager->Tie( tmp.c_str(), this, num, &FGFCS::GetMixtureCmd,
     941                 :         12 :                                         &FGFCS::SetMixtureCmd);
     942                 :         24 :   tmp = CreateIndexedPropertyName("fcs/mixture-pos-norm", num);
     943                 :            :   PropertyManager->Tie( tmp.c_str(), this, num, &FGFCS::GetMixturePos,
     944                 :         12 :                                         &FGFCS::SetMixturePos);
     945                 :         24 :   tmp = CreateIndexedPropertyName("fcs/advance-cmd-norm", num);
     946                 :            :   PropertyManager->Tie( tmp.c_str(), this, num, &FGFCS::GetPropAdvanceCmd,
     947                 :         12 :                                         &FGFCS::SetPropAdvanceCmd);
     948                 :         24 :   tmp = CreateIndexedPropertyName("fcs/advance-pos-norm", num);
     949                 :            :   PropertyManager->Tie( tmp.c_str(), this, num, &FGFCS::GetPropAdvance,
     950                 :         12 :                                         &FGFCS::SetPropAdvance);
     951                 :         24 :   tmp = CreateIndexedPropertyName("fcs/feather-cmd-norm", num);
     952                 :            :   PropertyManager->Tie( tmp.c_str(), this, num, &FGFCS::GetFeatherCmd,
     953                 :         12 :                                         &FGFCS::SetFeatherCmd);
     954                 :         24 :   tmp = CreateIndexedPropertyName("fcs/feather-pos-norm", num);
     955                 :            :   PropertyManager->Tie( tmp.c_str(), this, num, &FGFCS::GetPropFeather,
     956                 :         12 :                                         &FGFCS::SetPropFeather);
     957                 :         12 : }
     958                 :            : 
     959                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     960                 :            : 
     961                 :          0 : void FGFCS::bindModel(void)
     962                 :            : {
     963                 :            :   unsigned int i;
     964                 :          0 :   string tmp;
     965                 :            : 
     966         [ #  # ]:          0 :   for (i=0; i<SteerPosDeg.size(); i++) {
     967         [ #  # ]:          0 :     if (GroundReactions->GetGearUnit(i)->GetSteerable()) {
     968                 :          0 :       tmp = CreateIndexedPropertyName("fcs/steer-pos-deg", i);
     969                 :          0 :       PropertyManager->Tie( tmp.c_str(), this, i, &FGFCS::GetSteerPosDeg, &FGFCS::SetSteerPosDeg);
     970                 :            :     }
     971                 :          0 :   }
     972                 :          0 : }
     973                 :            : 
     974                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     975                 :            : //    The bitmasked value choices are as follows:
     976                 :            : //    unset: In this case (the default) JSBSim would only print
     977                 :            : //       out the normally expected messages, essentially echoing
     978                 :            : //       the config files as they are read. If the environment
     979                 :            : //       variable is not set, debug_lvl is set to 1 internally
     980                 :            : //    0: This requests JSBSim not to output any messages
     981                 :            : //       whatsoever.
     982                 :            : //    1: This value explicity requests the normal JSBSim
     983                 :            : //       startup messages
     984                 :            : //    2: This value asks for a message to be printed out when
     985                 :            : //       a class is instantiated
     986                 :            : //    4: When this value is set, a message is displayed when a
     987                 :            : //       FGModel object executes its Run() method
     988                 :            : //    8: When this value is set, various runtime state variables
     989                 :            : //       are printed out periodically
     990                 :            : //    16: When set various parameters are sanity checked and
     991                 :            : //       a message is printed out when they go out of bounds
     992                 :            : 
     993                 :          6 : void FGFCS::Debug(int from)
     994                 :            : {
     995         [ +  - ]:          6 :   if (debug_lvl <= 0) return;
     996                 :            : 
     997         [ +  - ]:          6 :   if (debug_lvl & 1) { // Standard console startup message output
     998         [ +  + ]:          6 :     if (from == 2) { // Loader
     999                 :          4 :       cout << endl << "  " << Name << endl;
    1000                 :            :     }
    1001                 :            :   }
    1002         [ -  + ]:          6 :   if (debug_lvl & 2 ) { // Instantiation/Destruction notification
    1003         [ #  # ]:          0 :     if (from == 0) cout << "Instantiated: FGFCS" << endl;
    1004         [ #  # ]:          0 :     if (from == 1) cout << "Destroyed:    FGFCS" << endl;
    1005                 :            :   }
    1006                 :          6 :   if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
    1007                 :            :   }
    1008                 :          6 :   if (debug_lvl & 8 ) { // Runtime state variables
    1009                 :            :   }
    1010                 :          6 :   if (debug_lvl & 16) { // Sanity checking
    1011                 :            :   }
    1012         [ -  + ]:          6 :   if (debug_lvl & 64) {
    1013         [ #  # ]:          0 :     if (from == 0) { // Constructor
    1014                 :          0 :       cout << IdSrc << endl;
    1015                 :          0 :       cout << IdHdr << endl;
    1016                 :            :     }
    1017                 :            :   }
    1018                 :            : }
    1019                 :            : 
    1020 [ +  + ][ +  - ]:         12 : }

Generated by: LCOV version 1.9