LCOV - code coverage report
Current view: top level - models/flight_control - FGActuator.cpp (source / functions) Hit Total Coverage
Test: JSBSim-Coverage-Statistics Lines: 94 108 87.0 %
Date: 2010-08-24 Functions: 10 16 62.5 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 41 90 45.6 %

           Branch data     Line data    Source code
       1                 :            : /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
       2                 :            : 
       3                 :            :  Module:       FGActuator.cpp
       4                 :            :  Author:       Jon Berndt
       5                 :            :  Date started: 21 February 2006
       6                 :            : 
       7                 :            :  ------------- Copyright (C) 2007 Jon S. Berndt (jon@jsbsim.org) -------------
       8                 :            : 
       9                 :            :  This program is free software; you can redistribute it and/or modify it under
      10                 :            :  the terms of the GNU Lesser General Public License as published by the Free Software
      11                 :            :  Foundation; either version 2 of the License, or (at your option) any later
      12                 :            :  version.
      13                 :            : 
      14                 :            :  This program is distributed in the hope that it will be useful, but WITHOUT
      15                 :            :  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
      16                 :            :  FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
      17                 :            :  details.
      18                 :            : 
      19                 :            :  You should have received a copy of the GNU Lesser General Public License along with
      20                 :            :  this program; if not, write to the Free Software Foundation, Inc., 59 Temple
      21                 :            :  Place - Suite 330, Boston, MA  02111-1307, USA.
      22                 :            : 
      23                 :            :  Further information about the GNU Lesser General Public License can also be found on
      24                 :            :  the world wide web at http://www.gnu.org.
      25                 :            : 
      26                 :            : FUNCTIONAL DESCRIPTION
      27                 :            : --------------------------------------------------------------------------------
      28                 :            : 
      29                 :            : HISTORY
      30                 :            : --------------------------------------------------------------------------------
      31                 :            : 
      32                 :            : %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      33                 :            : COMMENTS, REFERENCES,  and NOTES
      34                 :            : %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      35                 :            : 
      36                 :            : %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      37                 :            : INCLUDES
      38                 :            : %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
      39                 :            : 
      40                 :            : #include "FGActuator.h"
      41                 :            : 
      42                 :            : using namespace std;
      43                 :            : 
      44                 :            : namespace JSBSim {
      45                 :            : 
      46                 :            : static const char *IdSrc = "$Id: FGActuator.cpp,v 1.15 2010/08/21 22:56:11 jberndt Exp $";
      47                 :            : static const char *IdHdr = ID_ACTUATOR;
      48                 :            : 
      49                 :            : /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      50                 :            : CLASS IMPLEMENTATION
      51                 :            : %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
      52                 :            : 
      53                 :            : 
      54                 :          4 : FGActuator::FGActuator(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, element)
      55                 :            : {
      56                 :            :   double denom;
      57                 :            : 
      58                 :            :   // inputs are read from the base class constructor
      59                 :            : 
      60                 :          4 :   PreviousOutput = 0.0;
      61                 :          4 :   PreviousHystOutput = 0.0;
      62                 :          4 :   PreviousRateLimOutput = 0.0;
      63                 :          4 :   PreviousLagInput = PreviousLagOutput = 0.0;
      64                 :          4 :   bias = lag = hysteresis_width = deadband_width = 0.0;
      65                 :          4 :   rate_limit = 0.0; // no limit
      66                 :          4 :   fail_zero = fail_hardover = fail_stuck = false;
      67                 :          4 :   ca = cb = 0.0;
      68                 :            : 
      69 [ -  + ][ #  # ]:          4 :   if ( element->FindElement("deadband_width") ) {
      70                 :          0 :     deadband_width = element->FindElementValueAsNumber("deadband_width");
      71                 :            :   }
      72 [ +  - ][ #  # ]:          4 :   if ( element->FindElement("hysteresis_width") ) {
      73                 :          4 :     hysteresis_width = element->FindElementValueAsNumber("hysteresis_width");
      74                 :            :   }
      75 [ +  - ][ #  # ]:          4 :   if ( element->FindElement("rate_limit") ) {
      76                 :          4 :     rate_limit = element->FindElementValueAsNumber("rate_limit");
      77                 :            :   }
      78 [ +  - ][ #  # ]:          4 :   if ( element->FindElement("bias") ) {
      79                 :          4 :     bias = element->FindElementValueAsNumber("bias");
      80                 :            :   }
      81 [ +  - ][ #  # ]:          4 :   if ( element->FindElement("lag") ) {
      82                 :          4 :     lag = element->FindElementValueAsNumber("lag");
      83                 :          4 :     denom = 2.00 + dt*lag;
      84                 :          4 :     ca = dt*lag / denom;
      85                 :          4 :     cb = (2.00 - dt*lag) / denom;
      86                 :            :   }
      87                 :            : 
      88                 :          4 :   FGFCSComponent::bind();
      89                 :          4 :   bind();
      90                 :            : 
      91                 :          4 :   Debug(0);
      92                 :          4 : }
      93                 :            : 
      94                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      95                 :            : 
      96                 :          4 : FGActuator::~FGActuator()
      97                 :            : {
      98                 :          4 :   Debug(1);
      99 [ +  - ][ #  # ]:          4 : }
                 [ #  # ]
     100                 :            : 
     101                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     102                 :            : 
     103                 :     216020 : bool FGActuator::Run(void )
     104                 :            : {
     105                 :     216020 :   Input = InputNodes[0]->getDoubleValue() * InputSigns[0];
     106                 :            : 
     107         [ -  + ]:     216020 :   if (fail_zero) Input = 0;
     108         [ -  + ]:     216020 :   if (fail_hardover) Input =  clipmax*sign(Input);
     109                 :            : 
     110                 :     216020 :   Output = Input; // Perfect actuator. At this point, if no failures are present
     111                 :            :                   // and no subsequent lag, limiting, etc. is done, the output
     112                 :            :                   // is simply the input. If any further processing is done
     113                 :            :                   // (below) such as lag, rate limiting, hysteresis, etc., then
     114                 :            :                   // the Input will be further processed and the eventual Output
     115                 :            :                   // will be overwritten from this perfect value.
     116                 :            : 
     117         [ +  - ]:     216020 :   if (lag != 0.0)              Lag();        // models actuator lag
     118         [ +  - ]:     216020 :   if (rate_limit != 0)         RateLimit();  // limit the actuator rate
     119         [ -  + ]:     216020 :   if (deadband_width != 0.0)   Deadband();
     120         [ +  - ]:     216020 :   if (hysteresis_width != 0.0) Hysteresis();
     121         [ +  - ]:     216020 :   if (bias != 0.0)             Bias();       // models a finite bias
     122                 :            : 
     123         [ -  + ]:     216020 :   if (fail_stuck) Output = PreviousOutput;
     124                 :     216020 :   PreviousOutput = Output; // previous value needed for "stuck" malfunction
     125                 :            : 
     126                 :     216020 :   Clip();
     127         [ +  - ]:     216020 :   if (IsOutput) SetOutput();
     128                 :            : 
     129                 :     216020 :   return true;
     130                 :            : }
     131                 :            : 
     132                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     133                 :            : 
     134                 :          0 : void FGActuator::Bias(void)
     135                 :            : {
     136                 :     216020 :   Output += bias;
     137                 :          0 : }
     138                 :            : 
     139                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     140                 :            : 
     141                 :          0 : void FGActuator::Lag(void)
     142                 :            : {
     143                 :            :   // "Output" on the right side of the "=" is the current frame input
     144                 :            :   // for this Lag filter
     145                 :     216020 :   double input = Output;
     146                 :     216020 :   Output = ca * (input + PreviousLagInput) + PreviousLagOutput * cb;
     147                 :     216020 :   PreviousLagInput = input;
     148                 :     216020 :   PreviousLagOutput = Output;
     149                 :          0 : }
     150                 :            : 
     151                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     152                 :            : 
     153                 :     216020 : void FGActuator::Hysteresis(void)
     154                 :            : {
     155                 :            :   // Note: this function acts cumulatively on the "Output" parameter. So, "Output"
     156                 :            :   // is - for the purposes of this Hysteresis method - really the input to the
     157                 :            :   // method.
     158                 :     216020 :   double input = Output;
     159                 :            :   
     160         [ +  + ]:     216020 :   if (input > PreviousHystOutput) {
     161                 :     120340 :     Output = max(PreviousHystOutput, input-0.5*hysteresis_width);
     162         [ +  + ]:      95680 :   } else if (input < PreviousHystOutput) {
     163                 :      79545 :     Output = min(PreviousHystOutput, input+0.5*hysteresis_width);
     164                 :            :   }
     165                 :            : 
     166                 :     216020 :   PreviousHystOutput = Output;
     167                 :     216020 : }
     168                 :            : 
     169                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     170                 :            : 
     171                 :     216020 : void FGActuator::RateLimit(void)
     172                 :            : {
     173                 :            :   // Note: this function acts cumulatively on the "Output" parameter. So, "Output"
     174                 :            :   // is - for the purposes of this RateLimit method - really the input to the
     175                 :            :   // method.
     176                 :     216020 :   double input = Output;
     177         [ +  - ]:     216020 :   if (dt > 0.0) {
     178                 :     216020 :     double rate = (input - PreviousRateLimOutput)/dt;
     179         [ +  + ]:     216020 :     if (fabs(rate) > rate_limit) {
     180                 :        105 :       Output = PreviousRateLimOutput + (rate_limit*fabs(rate)/rate)*dt;
     181                 :            :     }
     182                 :            :   }
     183                 :     216020 :   PreviousRateLimOutput = Output;
     184                 :     216020 : }
     185                 :            : 
     186                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     187                 :            : 
     188                 :          0 : void FGActuator::Deadband(void)
     189                 :            : {
     190                 :          0 : }
     191                 :            : 
     192                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     193                 :            : 
     194                 :          4 : void FGActuator::bind(void)
     195                 :            : {
     196                 :          4 :   string tmp = Name;
     197         [ -  + ]:          4 :   if (Name.find("/") == string::npos) {
     198                 :          0 :     tmp = "fcs/" + PropertyManager->mkPropertyName(Name, true);
     199                 :            :   }
     200                 :          4 :   const string tmp_zero = tmp + "/malfunction/fail_zero";
     201                 :          4 :   const string tmp_hardover = tmp + "/malfunction/fail_hardover";
     202                 :          4 :   const string tmp_stuck = tmp + "/malfunction/fail_stuck";
     203                 :            : 
     204                 :          4 :   PropertyManager->Tie( tmp_zero, this, &FGActuator::GetFailZero, &FGActuator::SetFailZero);
     205                 :          4 :   PropertyManager->Tie( tmp_hardover, this, &FGActuator::GetFailHardover, &FGActuator::SetFailHardover);
     206                 :          4 :   PropertyManager->Tie( tmp_stuck, this, &FGActuator::GetFailStuck, &FGActuator::SetFailStuck);
     207                 :          4 : }
     208                 :            : 
     209                 :            : //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     210                 :            : //    The bitmasked value choices are as follows:
     211                 :            : //    unset: In this case (the default) JSBSim would only print
     212                 :            : //       out the normally expected messages, essentially echoing
     213                 :            : //       the config files as they are read. If the environment
     214                 :            : //       variable is not set, debug_lvl is set to 1 internally
     215                 :            : //    0: This requests JSBSim not to output any messages
     216                 :            : //       whatsoever.
     217                 :            : //    1: This value explicity requests the normal JSBSim
     218                 :            : //       startup messages
     219                 :            : //    2: This value asks for a message to be printed out when
     220                 :            : //       a class is instantiated
     221                 :            : //    4: When this value is set, a message is displayed when a
     222                 :            : //       FGModel object executes its Run() method
     223                 :            : //    8: When this value is set, various runtime state variables
     224                 :            : //       are printed out periodically
     225                 :            : //    16: When set various parameters are sanity checked and
     226                 :            : //       a message is printed out when they go out of bounds
     227                 :            : 
     228                 :          8 : void FGActuator::Debug(int from)
     229                 :            : {
     230         [ +  - ]:          8 :   if (debug_lvl <= 0) return;
     231                 :            : 
     232         [ +  - ]:          8 :   if (debug_lvl & 1) { // Standard console startup message output
     233         [ +  + ]:          8 :     if (from == 0) { // Constructor
     234         [ -  + ]:          4 :       if (InputSigns[0] < 0)
     235                 :          0 :         cout << "      INPUT: -" << InputNames[0] << endl;
     236                 :            :       else
     237                 :          4 :         cout << "      INPUT: " << InputNames[0] << endl;
     238                 :            : 
     239         [ +  - ]:          4 :       if (IsOutput) {
     240         [ +  + ]:         16 :         for (unsigned int i=0; i<OutputNodes.size(); i++)
     241                 :         12 :           cout << "      OUTPUT: " << OutputNodes[i]->getName() << endl;
     242                 :            :       }
     243         [ +  - ]:          4 :       if (bias != 0.0) cout << "      Bias: " << bias << endl;
     244         [ +  - ]:          4 :       if (rate_limit != 0) cout << "      Rate limit: " << rate_limit << endl;
     245         [ +  - ]:          4 :       if (lag != 0) cout << "      Actuator lag: " << lag << endl;
     246         [ +  - ]:          4 :       if (hysteresis_width != 0) cout << "      Hysteresis width: " << hysteresis_width << endl;
     247         [ -  + ]:          4 :       if (deadband_width != 0) cout << "      Deadband width: " << deadband_width << endl;
     248                 :            :     }
     249                 :            :   }
     250         [ -  + ]:          8 :   if (debug_lvl & 2 ) { // Instantiation/Destruction notification
     251         [ #  # ]:          0 :     if (from == 0) cout << "Instantiated: FGActuator" << endl;
     252         [ #  # ]:          0 :     if (from == 1) cout << "Destroyed:    FGActuator" << endl;
     253                 :            :   }
     254                 :          8 :   if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
     255                 :            :   }
     256                 :          8 :   if (debug_lvl & 8 ) { // Runtime state variables
     257                 :            :   }
     258                 :          8 :   if (debug_lvl & 16) { // Sanity checking
     259                 :            :   }
     260         [ -  + ]:          8 :   if (debug_lvl & 64) {
     261         [ #  # ]:          0 :     if (from == 0) { // Constructor
     262                 :          0 :       cout << IdSrc << endl;
     263                 :          0 :       cout << IdHdr << endl;
     264                 :            :     }
     265                 :            :   }
     266                 :            : }
     267 [ +  + ][ +  - ]:         12 : }

Generated by: LCOV version 1.9