LCOV - code coverage report
Current view: top level - models/propulsion - FGForce.h (source / functions) Hit Total Coverage
Test: JSBSim-Coverage-Statistics Lines: 13 26 50.0 %
Date: 2010-08-24 Functions: 4 7 57.1 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
       2                 :            : 
       3                 :            :  Header:       FGForce.h
       4                 :            :  Author:       Tony Peden
       5                 :            :  Date started: 5/20/00
       6                 :            : 
       7                 :            :  ------------- Copyright (C) 1999  Anthony K. Peden (apeden@earthlink.net) -------------
       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                 :            : 
      27                 :            :  HISTORY
      28                 :            : --------------------------------------------------------------------------------
      29                 :            : 5/20/00  TP   Created
      30                 :            : 
      31                 :            : 
      32                 :            : FUNCTIONAL DESCRIPTION
      33                 :            : --------------------------------------------------------------------------------
      34                 :            : 
      35                 :            : The purpose of this class is to provide storage for computed forces and
      36                 :            : encapsulate all the functionality associated with transforming those
      37                 :            : forces from their native coord system to the body system.  This includes
      38                 :            : computing the moments due to the difference between the point of application
      39                 :            : and the cg.
      40                 :            : 
      41                 :            : CAVEAT:  if the custom transform is used for wind-to-body transforms then the
      42                 :            :          user *must* always pass this class the negative of beta. This is true
      43                 :            :          because sideslip angle does not follow the right hand rule i.e. it is
      44                 :            :          positive for aircraft nose left sideslip.  Note that use of the custom
      45                 :            :          transform for this purpose shouldn't be necessary as it is already
      46                 :            :          provided by SetTransform(tWindBody) and is not subject to the same
      47                 :            :          restriction.
      48                 :            : 
      49                 :            : %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      50                 :            : SENTRY
      51                 :            : %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
      52                 :            : 
      53                 :            : #ifndef FGFORCE_H
      54                 :            : #define FGFORCE_H
      55                 :            : 
      56                 :            : /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      57                 :            : INCLUDES
      58                 :            : %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
      59                 :            : 
      60                 :            : #include "FGFDMExec.h"
      61                 :            : #include "FGJSBBase.h"
      62                 :            : #include "math/FGMatrix33.h"
      63                 :            : #include "math/FGColumnVector3.h"
      64                 :            : 
      65                 :            : /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      66                 :            : DEFINITIONS
      67                 :            : %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
      68                 :            : 
      69                 :            : #define ID_FORCE "$Id: FGForce.h,v 1.13 2009/10/05 04:48:03 jberndt Exp $"
      70                 :            : 
      71                 :            : /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      72                 :            : FORWARD DECLARATIONS
      73                 :            : %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
      74                 :            : 
      75                 :            : namespace JSBSim {
      76                 :            : 
      77                 :            : /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      78                 :            : CLASS DOCUMENTATION
      79                 :            : %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
      80                 :            : 
      81                 :            : /** Utility class that aids in the conversion of forces between coordinate systems
      82                 :            :     and calculation of moments.
      83                 :            : <br><h3>Resolution of Applied Forces into Moments and Body Axes Components</h3>
      84                 :            : <br><p>
      85                 :            : All forces acting on the aircraft that cannot be considered a change in weight
      86                 :            : need to be resolved into body axis components so that the aircraft acceleration
      87                 :            : vectors, both translational and rotational, can be computed. Furthermore, the
      88                 :            : moments produced by each force that does not act at a location corresponding to
      89                 :            : the center of gravity also need to be computed. Unfortunately, the math required
      90                 :            : to do this can be a bit messy and errors are easily introduced so the class
      91                 :            : FGForce was created to provide these services in a consistent and reusable
      92                 :            : manner.<br><br></p>
      93                 :            : 
      94                 :            : <h4>Basic usage</h4>
      95                 :            : 
      96                 :            : <p>FGForce requires that its users supply it with the location of the applied
      97                 :            : force vector in JSBSim structural coordinates, the sense of each axis in that
      98                 :            : coordinate system relative to the body system, the orientation of the vector
      99                 :            : also relative to body coordinates and, of course, the force vector itself. With
     100                 :            : this information it will compute both the body axis force components and the
     101                 :            : resulting moments. Any moments inherently produced by the native system can be
     102                 :            : supplied as well and they will be summed with those computed.</p>
     103                 :            : 
     104                 :            : <p>A good example for demonstrating the use of this class are the aerodynamic
     105                 :            : forces: lift, drag, and side force and the aerodynamic moments about the pitch,
     106                 :            : roll and yaw axes. These "native" forces and moments are computed and stored
     107                 :            : in the FGColumnVector objects vFs and vMoments. Their native coordinate system
     108                 :            : is often referred to as the wind system and is defined as a right-handed system
     109                 :            : having its x-axis aligned with the relative velocity vector and pointing towards
     110                 :            : the rear of the aircraft , the y-axis extending out the right wing, and the
     111                 :            : z-axis directed upwards. This is different than body axes; they are defined such
     112                 :            : that the x-axis is lies on the aircraft's roll axis and positive forward, the
     113                 :            : y-axis is positive out the right wing, and the z-axis is positive downwards. In
     114                 :            : this instance, JSBSim already provides the needed transform and FGForce can make
     115                 :            : use of it by calling SetTransformType() once an object is created:</p>
     116                 :            : 
     117                 :            : <p><tt>FGForce fgf(FDMExec);</tt><br>
     118                 :            : <tt>fgf.SetTransformType(tWindBody);</tt><br><br>
     119                 :            : 
     120                 :            : This call need only be made once for each object. The available transforms are
     121                 :            : defined in the enumerated type TransformType and are tWindBody, tLocalBody,
     122                 :            : tCustom, and tNone. The local-to-body transform, like the wind-to-body, also
     123                 :            : makes use of that already available in JSBSim. tNone sets FGForce to do no
     124                 :            : angular transform at all, and tCustom allows for modeling force vectors at
     125                 :            : arbitrary angles relative to the body system such as that produced by propulsion
     126                 :            : systems. Setting up and using a custom transform is covered in more detail below.
     127                 :            : Continuing with the example, the point of application of the aerodynamic forces,
     128                 :            : the aerodynamic reference point in JSBSim, also needs to be set:</p>
     129                 :            : <p><tt>
     130                 :            : fgf.SetLocation(x, y, z)</tt></p>
     131                 :            : 
     132                 :            : <p>where x, y, and z are in JSBSim structural coordinates.</p>
     133                 :            : 
     134                 :            : <p>Initialization is complete and the FGForce object is ready to do its job. As
     135                 :            : stated above, the lift, drag, and side force are computed and stored in the
     136                 :            : vector vFs and need to be passed to FGForce:</p>
     137                 :            : 
     138                 :            : <p><tt>fgf.SetNativeForces(vFs);</tt> </p>
     139                 :            : 
     140                 :            : <p>The same applies to the aerodynamic pitching, rolling and yawing moments:</p>
     141                 :            : 
     142                 :            : <p><tt>fgf.SetNativeMoments(vMoments);</tt></p>
     143                 :            : 
     144                 :            : <p>Note that storing the native forces and moments outside of this class is not
     145                 :            : strictly necessary, overloaded SetNativeForces() and SetNativeMoments() methods
     146                 :            : which each accept three doubles (rather than a vector) are provided and can be
     147                 :            : repeatedly called without incurring undue overhead. The body axes force vector
     148                 :            : can now be retrieved by calling:</p>
     149                 :            : 
     150                 :            : <p><tt>vFb=fgf.GetBodyForces();</tt></p>
     151                 :            : 
     152                 :            : <p>This method is where the bulk of the work gets done so calling it more than
     153                 :            : once for the same set of native forces and moments should probably be avoided.
     154                 :            : Note that the moment calculations are done here as well so they should be
     155                 :            : retrieved after calling the GetBodyForces() method:</p>
     156                 :            : 
     157                 :            : <p><tt>vM=fgf.GetMoments();</tt> </p>
     158                 :            : 
     159                 :            : <p>As an aside, the native moments are not needed to perform the computations
     160                 :            : correctly so, if the FGForce object is not being used to store them then an
     161                 :            : alternate approach is to avoid the SetNativeMoments call and perform the sum</p>
     162                 :            : 
     163                 :            : <p><tt>vMoments+=fgf.GetMoments();</tt> <br><br>
     164                 :            : 
     165                 :            : after the forces have been retrieved. </p>
     166                 :            : 
     167                 :            : <h4>Use of the Custom Transform Type</h4>
     168                 :            : 
     169                 :            : <p>In cases where the native force vector is not aligned with the body, wind, or
     170                 :            : local coordinate systems a custom transform type is provided. A vectorable engine
     171                 :            : nozzle will be used to demonstrate its usage. Initialization is much the same:</p>
     172                 :            : 
     173                 :            : <p><tt>FGForce fgf(FDMExec);</tt> <br>
     174                 :            : <tt>fgf.SetTransformType(tCustom);</tt> <br>
     175                 :            : <tt>fgf.SetLocation(x,y,z);</tt> </p>
     176                 :            : 
     177                 :            : <p>Except that here the tCustom transform type is specified and the location of
     178                 :            : the thrust vector is used rather than the aerodynamic reference point. Thrust is
     179                 :            : typically considered to be positive when directed aft while the body x-axis is
     180                 :            : positive forward and, if the native system is right handed, the z-axis will be
     181                 :            : reversed as well. These differences in sense need to be specified using by the
     182                 :            : call: </p>
     183                 :            : 
     184                 :            : <p><tt>fgf.SetSense(-1,1,-1);</tt></p>
     185                 :            : 
     186                 :            : <p>The angles are specified by calling the method: </p>
     187                 :            : 
     188                 :            : <p><tt>fgf.SetAnglesToBody(pitch, roll, yaw);</tt> </p>
     189                 :            : 
     190                 :            : <p>in which the transform matrix is computed. Note that these angles should be
     191                 :            : taken relative to the body system and not the local as the names might suggest.
     192                 :            : For an aircraft with vectorable thrust, this method will need to be called
     193                 :            : every time the nozzle angle changes, a fixed engine/nozzle installation, on the
     194                 :            : other hand, will require it to be be called only once.</p>
     195                 :            : 
     196                 :            : <p>Retrieval of the computed forces and moments is done as detailed above.</p>
     197                 :            : <br>
     198                 :            : <pre>
     199                 :            :     <p><i>CAVEAT: If the custom system is used to compute
     200                 :            :     the wind-to-body transform, then the sign of the sideslip
     201                 :            :     angle must be reversed when calling SetAnglesToBody().
     202                 :            :     This is true because sideslip angle does not follow the right
     203                 :            :     hand rule. Using the custom transform type this way
     204                 :            :     should not be necessary, as it is already provided as a built
     205                 :            :     in type (and the sign differences are correctly accounted for).</i>
     206                 :            :     </p>
     207                 :            : </pre>
     208                 :            : 
     209                 :            : <h4>Use as a Base Type</h4>
     210                 :            : 
     211                 :            : <p>For use as a base type, the native force and moment vector data members are
     212                 :            : defined as protected. In this case the SetNativeForces() and SetNativeMoments()
     213                 :            : methods need not be used and, instead, the assignments to vFn, the force vector,
     214                 :            : and vMn, the moments, can be made directly. Otherwise, the usage is similar.<br>
     215                 :            : <br><br></p>
     216                 :            : 
     217                 :            :     @author Tony Peden
     218                 :            :     @version $Id: FGForce.h,v 1.13 2009/10/05 04:48:03 jberndt Exp $
     219                 :            : */
     220                 :            : 
     221                 :            : /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     222                 :            : CLASS DECLARATION
     223                 :            : %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
     224                 :            : 
     225                 :            : class FGForce : public FGJSBBase
     226                 :            : {
     227                 :            : public:
     228                 :            :   /// Constructor
     229                 :            :   FGForce(FGFDMExec *FDMExec);
     230                 :          0 :   FGForce(const FGForce& force) {
     231                 :          0 :     vFn = force.vFn;
     232                 :          0 :     vXYZn = force.vXYZn;
     233                 :          0 :     ttype = force.ttype;
     234                 :          0 :     fdmex = force.fdmex;
     235                 :          0 :   }
     236                 :            :   /// Destructor
     237                 :            :   ~FGForce();
     238                 :            : 
     239                 :            :   enum TransformType { tNone, tWindBody, tLocalBody, tCustom };
     240                 :            : 
     241                 :            :   virtual FGColumnVector3& GetBodyForces(void);
     242                 :            : 
     243                 :          0 :   inline double GetBodyXForce(void) const { return vFb(eX); }
     244                 :          0 :   inline double GetBodyYForce(void) const { return vFb(eY); }
     245                 :            :   inline double GetBodyZForce(void) const { return vFb(eZ); }
     246                 :     648060 :   inline FGColumnVector3& GetMoments(void) { return vM; }
     247                 :            : 
     248                 :            :   // Normal point of application, JSBsim structural coords
     249                 :            :   // (inches, x +back, y +right, z +up)
     250                 :            :   inline void SetLocation(double x, double y, double z) {
     251                 :            :     vXYZn(eX) = x;
     252                 :            :     vXYZn(eY) = y;
     253                 :            :     vXYZn(eZ) = z;
     254                 :            :     SetActingLocation(x, y, z);
     255                 :            :   }
     256                 :            : 
     257                 :            :   /** Acting point of application.
     258                 :            :       JSBsim structural coords used (inches, x +back, y +right, z +up).
     259                 :            :       This function sets the point at which the force acts - this may
     260                 :            :       not be the same as where the object resides. One area where this
     261                 :            :       is true is P-Factor modeling.
     262                 :            :       @param x acting location of force
     263                 :            :       @param y acting location of force
     264                 :            :       @param z acting location of force    */
     265                 :            :   inline void SetActingLocation(double x, double y, double z) {
     266                 :            :     vActingXYZn(eX) = x;
     267                 :            :     vActingXYZn(eY) = y;
     268                 :            :     vActingXYZn(eZ) = z;
     269                 :            :   }
     270                 :            :   inline void SetLocationX(double x) {vXYZn(eX) = x; vActingXYZn(eX) = x;}
     271                 :            :   inline void SetLocationY(double y) {vXYZn(eY) = y; vActingXYZn(eY) = y;}
     272                 :          0 :   inline void SetLocationZ(double z) {vXYZn(eZ) = z; vActingXYZn(eZ) = z;}
     273                 :            :   inline double SetActingLocationX(double x) {vActingXYZn(eX) = x; return x;}
     274                 :          0 :   inline double SetActingLocationY(double y) {vActingXYZn(eY) = y; return y;}
     275                 :          0 :   inline double SetActingLocationZ(double z) {vActingXYZn(eZ) = z; return z;}
     276                 :         12 :   inline void SetLocation(FGColumnVector3 vv) { vXYZn = vv; SetActingLocation(vv);}
     277                 :         12 :   inline void SetActingLocation(FGColumnVector3 vv) { vActingXYZn = vv; }
     278                 :            : 
     279                 :         24 :   inline double GetLocationX( void ) const { return vXYZn(eX);}
     280                 :         24 :   inline double GetLocationY( void ) const { return vXYZn(eY);}
     281                 :         24 :   inline double GetLocationZ( void ) const { return vXYZn(eZ);}
     282                 :            :   inline double GetActingLocationX( void ) const { return vActingXYZn(eX);}
     283                 :          0 :   inline double GetActingLocationY( void ) const { return vActingXYZn(eY);}
     284                 :          0 :   inline double GetActingLocationZ( void ) const { return vActingXYZn(eZ);}
     285                 :            :   FGColumnVector3& GetLocation(void) { return vXYZn; }
     286                 :            :   FGColumnVector3& GetActingLocation(void) { return vActingXYZn; }
     287                 :            : 
     288                 :            :   //these angles are relative to body axes, not earth!!!!!
     289                 :            :   //I'm using these because pitch, roll, and yaw are easy to visualize,
     290                 :            :   //there's no equivalent to roll in wind axes i.e. alpha, ? , beta
     291                 :            :   //making up new names or using these is a toss-up: either way people
     292                 :            :   //are going to get confused.
     293                 :            :   //They are in radians.
     294                 :            : 
     295                 :            :   void SetAnglesToBody(double broll, double bpitch, double byaw);
     296                 :            :   inline void  SetAnglesToBody(FGColumnVector3 vv) {
     297                 :         12 :     SetAnglesToBody(vv(eRoll), vv(ePitch), vv(eYaw));
     298                 :            :   }
     299                 :            : 
     300                 :            :   void UpdateCustomTransformMatrix(void);
     301                 :     324030 :   void SetPitch(double pitch) {vOrient(ePitch) = pitch; UpdateCustomTransformMatrix();}
     302                 :     324030 :   void SetYaw(double yaw) {vOrient(eYaw) = yaw; UpdateCustomTransformMatrix();}
     303                 :            : 
     304                 :         12 :   double GetPitch(void) const {return vOrient(ePitch);}
     305                 :         12 :   double GetYaw(void) const {return vOrient(eYaw);}
     306                 :            : 
     307                 :            :   inline FGColumnVector3& GetAnglesToBody(void) {return vOrient;}
     308                 :         48 :   inline double GetAnglesToBody(int axis) const {return vOrient(axis);}
     309                 :            : 
     310                 :         12 :   inline void SetTransformType(TransformType ii) { ttype=ii; }
     311                 :            :   inline TransformType GetTransformType(void) const { return ttype; }
     312                 :            : 
     313                 :            :   FGMatrix33 Transform(void);
     314                 :            : 
     315                 :            : protected:
     316                 :            :   FGFDMExec *fdmex;
     317                 :            :   FGColumnVector3 vFn;
     318                 :            :   FGColumnVector3 vMn;
     319                 :            :   FGColumnVector3 vH;
     320                 :            :   FGColumnVector3 vOrient;
     321                 :            :   TransformType ttype;
     322                 :            :   FGColumnVector3 vXYZn;
     323                 :            :   FGColumnVector3 vActingXYZn;
     324                 :            : 
     325                 :            : private:
     326                 :            :   FGColumnVector3 vFb;
     327                 :            :   FGColumnVector3 vM;
     328                 :            :   FGColumnVector3 vDXYZ;
     329                 :            : 
     330                 :            :   FGMatrix33 mT;
     331                 :            : 
     332                 :            :   void Debug(int from);
     333                 :            : };
     334                 :            : }
     335                 :            : #endif
     336                 :            : 

Generated by: LCOV version 1.9