📄 fgforce.h
字号:
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Header: FGForce.h Author: Tony Peden Date started: 5/20/00 ------------- Copyright (C) 1999 Anthony K. Peden (apeden@earthlink.net) ------------- This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Further information about the GNU Lesser General Public License can also be found on the world wide web at http://www.gnu.org. HISTORY--------------------------------------------------------------------------------5/20/00 TP CreatedFUNCTIONAL DESCRIPTION--------------------------------------------------------------------------------The purpose of this class is to provide storage for computed forces andencapsulate all the functionality associated with transforming thoseforces from their native coord system to the body system. This includescomputing the moments due to the difference between the point of applicationand the cg.CAVEAT: if the custom transform is used for wind-to-body transforms then the user *must* always pass this class the negative of beta. This is true because sideslip angle does not follow the right hand rule i.e. it is positive for aircraft nose left sideslip. Note that use of the custom transform for this purpose shouldn't be necessary as it is already provided by SetTransform(tWindBody) and is not subject to the same restriction.%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%SENTRY%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/#ifndef FGFORCE_H#define FGFORCE_H/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%INCLUDES%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/#include <FGFDMExec.h>#include <FGJSBBase.h>#include <math/FGMatrix33.h>#include <math/FGColumnVector3.h>/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%DEFINITIONS%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/#define ID_FORCE "$Id$"/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%FORWARD DECLARATIONS%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/namespace JSBSim {/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%CLASS DOCUMENTATION%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*//** Utility class that aids in the conversion of forces between coordinate systems and calculation of moments.<br><h3>Resolution of Applied Forces into Moments and Body Axes Components</h3><br><p>All forces acting on the aircraft that cannot be considered a change in weightneed to be resolved into body axis components so that the aircraft accelerationvectors, both translational and rotational, can be computed. Furthermore, themoments produced by each force that does not act at a location corresponding tothe center of gravity also need to be computed. Unfortunately, the math requiredto do this can be a bit messy and errors are easily introduced so the classFGForce was created to provide these services in a consistent and reusablemanner.<br><br></p><h4>Basic usage</h4><p>FGForce requires that its users supply it with the location of the appliedforce vector in JSBSim structural coordinates, the sense of each axis in thatcoordinate system relative to the body system, the orientation of the vectoralso relative to body coordinates and, of course, the force vector itself. Withthis information it will compute both the body axis force components and theresulting moments. Any moments inherently produced by the native system can besupplied as well and they will be summed with those computed.</p><p>A good example for demonstrating the use of this class are the aerodynamicforces: lift, drag, and side force and the aerodynamic moments about the pitch,roll and yaw axes. These "native" forces and moments are computed and storedin the FGColumnVector objects vFs and vMoments. Their native coordinate systemis often referred to as the wind system and is defined as a right-handed systemhaving its x-axis aligned with the relative velocity vector and pointing towardsthe rear of the aircraft , the y-axis extending out the right wing, and thez-axis directed upwards. This is different than body axes; they are defined suchthat the x-axis is lies on the aircraft's roll axis and positive forward, they-axis is positive out the right wing, and the z-axis is positive downwards. Inthis instance, JSBSim already provides the needed transform and FGForce can makeuse of it by calling SetTransformType() once an object is created:</p><p><tt>FGForce fgf(FDMExec);</tt><br><tt>fgf.SetTransformType(tWindBody);</tt><br><br>This call need only be made once for each object. The available transforms aredefined in the enumerated type TransformType and are tWindBody, tLocalBody,tCustom, and tNone. The local-to-body transform, like the wind-to-body, alsomakes use of that already available in JSBSim. tNone sets FGForce to do noangular transform at all, and tCustom allows for modeling force vectors atarbitrary angles relative to the body system such as that produced by propulsionsystems. Setting up and using a custom transform is covered in more detail below.Continuing with the example, the point of application of the aerodynamic forces,the aerodynamic reference point in JSBSim, also needs to be set:</p><p><tt>fgf.SetLocation(x, y, z)</tt></p><p>where x, y, and z are in JSBSim structural coordinates.</p><p>Initialization is complete and the FGForce object is ready to do its job. Asstated above, the lift, drag, and side force are computed and stored in thevector vFs and need to be passed to FGForce:</p><p><tt>fgf.SetNativeForces(vFs);</tt> </p><p>The same applies to the aerodynamic pitching, rolling and yawing moments:</p><p><tt>fgf.SetNativeMoments(vMoments);</tt></p><p>Note that storing the native forces and moments outside of this class is notstrictly necessary, overloaded SetNativeForces() and SetNativeMoments() methodswhich each accept three doubles (rather than a vector) are provided and can berepeatedly called without incurring undue overhead. The body axes force vectorcan now be retrieved by calling:</p><p><tt>vFb=fgf.GetBodyForces();</tt></p><p>This method is where the bulk of the work gets done so calling it more thanonce for the same set of native forces and moments should probably be avoided.Note that the moment calculations are done here as well so they should beretrieved after calling the GetBodyForces() method:</p><p><tt>vM=fgf.GetMoments();</tt> </p><p>As an aside, the native moments are not needed to perform the computationscorrectly so, if the FGForce object is not being used to store them then analternate approach is to avoid the SetNativeMoments call and perform the sum</p><p><tt>vMoments+=fgf.GetMoments();</tt> <br><br>after the forces have been retrieved. </p><h4>Use of the Custom Transform Type</h4><p>In cases where the native force vector is not aligned with the body, wind, orlocal coordinate systems a custom transform type is provided. A vectorable enginenozzle will be used to demonstrate its usage. Initialization is much the same:</p><p><tt>FGForce fgf(FDMExec);</tt> <br><tt>fgf.SetTransformType(tCustom);</tt> <br><tt>fgf.SetLocation(x,y,z);</tt> </p><p>Except that here the tCustom transform type is specified and the location ofthe thrust vector is used rather than the aerodynamic reference point. Thrust istypically considered to be positive when directed aft while the body x-axis ispositive forward and, if the native system is right handed, the z-axis will bereversed as well. These differences in sense need to be specified using by thecall: </p><p><tt>fgf.SetSense(-1,1,-1);</tt></p><p>The angles are specified by calling the method: </p><p><tt>fgf.SetAnglesToBody(pitch, roll, yaw);</tt> </p><p>in which the transform matrix is computed. Note that these angles should betaken relative to the body system and not the local as the names might suggest.For an aircraft with vectorable thrust, this method will need to be calledevery time the nozzle angle changes, a fixed engine/nozzle installation, on theother hand, will require it to be be called only once.</p><p>Retrieval of the computed forces and moments is done as detailed above.</p><br><pre> <p><i>CAVEAT: If the custom system is used to compute the wind-to-body transform, then the sign of the sideslip angle must be reversed when calling SetAnglesToBody(). This is true because sideslip angle does not follow the right hand rule. Using the custom transform type this way should not be necessary, as it is already provided as a built in type (and the sign differences are correctly accounted for).</i> </p></pre><h4>Use as a Base Type</h4><p>For use as a base type, the native force and moment vector data members aredefined as protected. In this case the SetNativeForces() and SetNativeMoments()methods need not be used and, instead, the assignments to vFn, the force vector,and vMn, the moments, can be made directly. Otherwise, the usage is similar.<br><br><br></p> @author Tony Peden @version $Id$*//*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%CLASS DECLARATION%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/class FGForce : public FGJSBBase{public: /// Constructor FGForce(FGFDMExec *FDMExec); FGForce(const FGForce& force) { vFn = force.vFn; vXYZn = force.vXYZn; ttype = force.ttype; fdmex = force.fdmex; } /// Destructor ~FGForce(); enum TransformType { tNone, tWindBody, tLocalBody, tCustom }; virtual FGColumnVector3& GetBodyForces(void); inline FGColumnVector3& GetMoments(void) { return vM; } // Normal point of application, JSBsim structural coords // (inches, x +back, y +right, z +up) inline void SetLocation(double x, double y, double z) { vXYZn(eX) = x; vXYZn(eY) = y; vXYZn(eZ) = z; SetActingLocation(x, y, z); } /** Acting point of application. JSBsim structural coords used (inches, x +back, y +right, z +up). This function sets the point at which the force acts - this may not be the same as where the object resides. One area where this is true is P-Factor modeling. @param x acting location of force @param y acting location of force @param z acting location of force */ inline void SetActingLocation(double x, double y, double z) { vActingXYZn(eX) = x; vActingXYZn(eY) = y; vActingXYZn(eZ) = z; } inline void SetLocationX(double x) {vXYZn(eX) = x; vActingXYZn(eX) = x;} inline void SetLocationY(double y) {vXYZn(eY) = y; vActingXYZn(eY) = y;} inline void SetLocationZ(double z) {vXYZn(eZ) = z; vActingXYZn(eZ) = z;} inline double SetActingLocationX(double x) {vActingXYZn(eX) = x; return x;} inline double SetActingLocationY(double y) {vActingXYZn(eY) = y; return y;} inline double SetActingLocationZ(double z) {vActingXYZn(eZ) = z; return z;} inline void SetLocation(FGColumnVector3 vv) { vXYZn = vv; SetActingLocation(vv);} inline void SetActingLocation(FGColumnVector3 vv) { vActingXYZn = vv; } inline double GetLocationX( void ) { return vXYZn(eX);} inline double GetLocationY( void ) { return vXYZn(eY);} inline double GetLocationZ( void ) { return vXYZn(eZ);} inline double GetActingLocationX( void ) { return vActingXYZn(eX);} inline double GetActingLocationY( void ) { return vActingXYZn(eY);} inline double GetActingLocationZ( void ) { return vActingXYZn(eZ);} FGColumnVector3& GetLocation(void) { return vXYZn; } FGColumnVector3& GetActingLocation(void) { return vActingXYZn; } //these angles are relative to body axes, not earth!!!!! //I'm using these because pitch, roll, and yaw are easy to visualize, //there's no equivalent to roll in wind axes i.e. alpha, ? , beta //making up new names or using these is a toss-up: either way people //are going to get confused. //They are in radians. void SetAnglesToBody(double broll, double bpitch, double byaw); inline void SetAnglesToBody(FGColumnVector3 vv) { SetAnglesToBody(vv(eRoll), vv(ePitch), vv(eYaw)); } void UpdateCustomTransformMatrix(void); void SetPitch(double pitch) {vOrient(ePitch) = pitch; UpdateCustomTransformMatrix();} void SetYaw(double yaw) {vOrient(eYaw) = yaw; UpdateCustomTransformMatrix();} double GetPitch(void) const {return vOrient(ePitch);} double GetYaw(void) const {return vOrient(eYaw);} inline FGColumnVector3& GetAnglesToBody(void) {return vOrient;} inline double GetAnglesToBody(int axis) {return vOrient(axis);} inline void SetTransformType(TransformType ii) { ttype=ii; } inline TransformType GetTransformType(void) { return ttype; } FGMatrix33 Transform(void);protected: FGFDMExec *fdmex; FGColumnVector3 vFn; FGColumnVector3 vMn; FGColumnVector3 vH; FGColumnVector3 vOrient; TransformType ttype; FGColumnVector3 vXYZn; FGColumnVector3 vActingXYZn;private: FGColumnVector3 vFb; FGColumnVector3 vM; FGColumnVector3 vDXYZ; FGMatrix33 mT; void Debug(int from);};}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -