1
0
Fork 0

Remove a bunch of unneede files.

This commit is contained in:
ehofman 2006-01-13 09:49:09 +00:00
parent d0618685a2
commit 587fd0937e
36 changed files with 4 additions and 10866 deletions

View file

@ -1,430 +0,0 @@
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Module: FGAerodynamics.cpp
Author: Jon S. Berndt
Date started: 09/13/00
Purpose: Encapsulates the aerodynamic forces (gear and collision)
------------- Copyright (C) 2000 Jon S. Berndt (jsb@hal-pc.org) -------------
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU 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 General Public License for more
details.
You should have received a copy of the GNU 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 General Public License can also be found on
the world wide web at http://www.gnu.org.
FUNCTIONAL DESCRIPTION
--------------------------------------------------------------------------------
HISTORY
--------------------------------------------------------------------------------
09/13/00 JSB Created
04/22/01 JSB Moved code into here from FGAircraft
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "FGAerodynamics.h"
#include "FGPropagate.h"
#include "FGAircraft.h"
#include "FGState.h"
#include "FGMassBalance.h"
#include "FGFactorGroup.h"
#include "FGPropertyManager.h"
namespace JSBSim {
static const char *IdSrc = "$Id$";
static const char *IdHdr = ID_AERODYNAMICS;
const unsigned NAxes=6;
const char* AxisNames[] = { "drag", "side", "lift", "roll",
"pitch","yaw" };
const char* AxisNamesUpper[] = { "DRAG", "SIDE", "LIFT", "ROLL",
"PITCH","YAW" };
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
FGAerodynamics::FGAerodynamics(FGFDMExec* FDMExec) : FGModel(FDMExec)
{
Name = "FGAerodynamics";
AxisIdx["DRAG"] = 0;
AxisIdx["SIDE"] = 1;
AxisIdx["LIFT"] = 2;
AxisIdx["ROLL"] = 3;
AxisIdx["PITCH"] = 4;
AxisIdx["YAW"] = 5;
Coeff = new CoeffArray[6];
impending_stall = stall_hyst = 0.0;
alphaclmin = alphaclmax = 0.0;
alphahystmin = alphahystmax = 0.0;
clsq = lod = 0.0;
alphaw = 0.0;
bi2vel = ci2vel = 0.0;
bind();
Debug(0);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGAerodynamics::~FGAerodynamics()
{
unsigned int i,j;
unbind();
for (i=0; i<6; i++) {
for (j=0; j<Coeff[i].size(); j++) {
delete Coeff[i][j];
}
}
delete[] Coeff;
Debug(1);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
bool FGAerodynamics::Run(void)
{
unsigned int axis_ctr,ctr;
double alpha, twovel;
if (!FGModel::Run()) {
twovel = 2*Auxiliary->GetVt();
if (twovel != 0) {
bi2vel = Aircraft->GetWingSpan() / twovel;
ci2vel = Aircraft->Getcbar() / twovel;
}
alphaw = Auxiliary->Getalpha() + Aircraft->GetWingIncidence();
alpha = Auxiliary->Getalpha();
if (alphaclmax != 0) {
if (alpha > 0.85*alphaclmax) {
impending_stall = 10*(alpha/alphaclmax - 0.85);
} else {
impending_stall = 0;
}
}
if (alphahystmax != 0.0 && alphahystmin != 0.0) {
if (alpha > alphahystmax) {
stall_hyst = 1;
} else if (alpha < alphahystmin) {
stall_hyst = 0;
}
}
vLastFs = vFs;
vFs.InitMatrix();
for (axis_ctr = 0; axis_ctr < 3; axis_ctr++) {
for (ctr=0; ctr < Coeff[axis_ctr].size(); ctr++) {
vFs(axis_ctr+1) += Coeff[axis_ctr][ctr]->TotalValue();
}
}
//correct signs of drag and lift to wind axes convention
//positive forward, right, down
if ( Auxiliary->Getqbar() > 0) {
clsq = vFs(eLift) / (Aircraft->GetWingArea()*Auxiliary->Getqbar());
clsq *= clsq;
}
if ( vFs(eDrag) > 0) {
lod = vFs(eLift) / vFs(eDrag);
}
//correct signs of drag and lift to wind axes convention
//positive forward, right, down
vFs(eDrag)*=-1; vFs(eLift)*=-1;
vForces = State->GetTs2b()*vFs;
vDXYZcg = MassBalance->StructuralToBody(Aircraft->GetXYZrp());
vMoments = vDXYZcg*vForces; // M = r X F
for (axis_ctr = 0; axis_ctr < 3; axis_ctr++) {
for (ctr = 0; ctr < Coeff[axis_ctr+3].size(); ctr++) {
vMoments(axis_ctr+1) += Coeff[axis_ctr+3][ctr]->TotalValue();
}
}
return false;
} else {
return true;
}
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
bool FGAerodynamics::Load(FGConfigFile* AC_cfg)
{
string parameter, axis, scratch;
AC_cfg->GetNextConfigLine();
while ((parameter = AC_cfg->GetValue()) != string("/AERODYNAMICS")) {
if (parameter == "AXIS") {
CoeffArray ca;
axis = AC_cfg->GetValue("NAME");
AC_cfg->GetNextConfigLine();
while ((parameter = AC_cfg->GetValue()) != string("/AXIS")) {
if ( parameter == "COEFFICIENT" ) {
ca.push_back( new FGCoefficient(FDMExec) );
ca.back()->Load(AC_cfg);
} else if ( parameter == "GROUP" ) {
ca.push_back( new FGFactorGroup(FDMExec) );
ca.back()->Load(AC_cfg);
}
}
Coeff[AxisIdx[axis]] = ca;
AC_cfg->GetNextConfigLine();
} else if (parameter == "AC_ALPHALIMITS") {
*AC_cfg >> scratch >> alphaclmin >> alphaclmax;
if (debug_lvl > 0) cout << " Maximum Alpha: " << alphaclmax
<< " Minimum Alpha: " << alphaclmin
<< endl;
} else if (parameter == "AC_HYSTLIMITS") {
*AC_cfg >> scratch >> alphahystmin >> alphahystmax;
if (debug_lvl > 0) cout << " Hysteresis Start: " << alphahystmax
<< " Hysteresis End: " << alphahystmin
<< endl;
}
}
bindModel();
return true;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
string FGAerodynamics::GetCoefficientStrings(string delimeter)
{
string CoeffStrings = "";
bool firstime = true;
unsigned int axis, sd;
for (axis = 0; axis < 6; axis++) {
for (sd = 0; sd < Coeff[axis].size(); sd++) {
if (firstime) {
firstime = false;
} else {
CoeffStrings += delimeter;
}
CoeffStrings += Coeff[axis][sd]->GetCoefficientName();
}
}
return CoeffStrings;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
string FGAerodynamics::GetCoefficientValues(string delimeter)
{
string SDValues = "";
bool firstime = true;
for (unsigned int axis = 0; axis < 6; axis++) {
for (unsigned int sd = 0; sd < Coeff[axis].size(); sd++) {
if (firstime) {
firstime = false;
} else {
SDValues += delimeter;
}
SDValues += Coeff[axis][sd]->GetSDstring();
}
}
return SDValues;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGAerodynamics::bind(void)
{
typedef double (FGAerodynamics::*PMF)(int) const;
PropertyManager->Tie("forces/fbx-aero-lbs", this,1,
(PMF)&FGAerodynamics::GetForces);
PropertyManager->Tie("forces/fby-aero-lbs", this,2,
(PMF)&FGAerodynamics::GetForces);
PropertyManager->Tie("forces/fbz-aero-lbs", this,3,
(PMF)&FGAerodynamics::GetForces);
PropertyManager->Tie("moments/l-aero-lbsft", this,1,
(PMF)&FGAerodynamics::GetMoments);
PropertyManager->Tie("moments/m-aero-lbsft", this,2,
(PMF)&FGAerodynamics::GetMoments);
PropertyManager->Tie("moments/n-aero-lbsft", this,3,
(PMF)&FGAerodynamics::GetMoments);
PropertyManager->Tie("forces/fwx-aero-lbs", this,1,
(PMF)&FGAerodynamics::GetvFs);
PropertyManager->Tie("forces/fwy-aero-lbs", this,2,
(PMF)&FGAerodynamics::GetvFs);
PropertyManager->Tie("forces/fwz-aero-lbs", this,3,
(PMF)&FGAerodynamics::GetvFs);
PropertyManager->Tie("forces/lod-norm", this,
&FGAerodynamics::GetLoD);
PropertyManager->Tie("aero/cl-squared-norm", this,
&FGAerodynamics::GetClSquared);
PropertyManager->Tie("aero/alpha-max-deg", this,
&FGAerodynamics::GetAlphaCLMax,
&FGAerodynamics::SetAlphaCLMax,
true);
PropertyManager->Tie("aero/alpha-min-deg", this,
&FGAerodynamics::GetAlphaCLMin,
&FGAerodynamics::SetAlphaCLMin,
true);
PropertyManager->Tie("aero/bi2vel", this,
&FGAerodynamics::GetBI2Vel);
PropertyManager->Tie("aero/ci2vel", this,
&FGAerodynamics::GetCI2Vel);
PropertyManager->Tie("aero/alpha-wing-rad", this,
&FGAerodynamics::GetAlphaW);
PropertyManager->Tie("systems/stall-warn-norm", this,
&FGAerodynamics::GetStallWarn);
PropertyManager->Tie("aero/stall-hyst-norm", this,
&FGAerodynamics::GetHysteresisParm);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGAerodynamics::bindModel(void)
{
unsigned i,j;
FGPropertyManager* node;
string axis_node_name;
node = PropertyManager->GetNode("aero/buildup",true);
for (i=0;i<NAxes;i++) {
node = node->GetNode( string(AxisNames[i]),true );
for (j=0; j < Coeff[i].size(); j++) {
Coeff[i][j]->bind(node);
}
node = (FGPropertyManager*)node->getParent();
}
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGAerodynamics::unbind(void)
{
unsigned i,j;
PropertyManager->Untie("forces/fbx-aero-lbs");
PropertyManager->Untie("forces/fby-aero-lbs");
PropertyManager->Untie("forces/fbz-aero-lbs");
PropertyManager->Untie("moments/l-aero-lbsft");
PropertyManager->Untie("moments/m-aero-lbsft");
PropertyManager->Untie("moments/n-aero-lbsft");
PropertyManager->Untie("forces/fwx-aero-lbs");
PropertyManager->Untie("forces/fwy-aero-lbs");
PropertyManager->Untie("forces/fwz-aero-lbs");
PropertyManager->Untie("forces/lod-norm");
PropertyManager->Untie("aero/cl-squared-norm");
PropertyManager->Untie("aero/alpha-max-deg");
PropertyManager->Untie("aero/alpha-min-deg");
PropertyManager->Untie("aero/bi2vel");
PropertyManager->Untie("aero/ci2vel");
PropertyManager->Untie("aero/alpha-wing-rad");
PropertyManager->Untie("aero/stall-hyst-norm");
PropertyManager->Untie("systems/stall-warn-norm");
for ( i=0; i<NAxes; i++ ) {
for ( j=0; j < Coeff[i].size(); j++ ) {
Coeff[i][j]->unbind();
}
}
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGAerodynamics::convert(void)
{
for (int axis=0; axis<6; axis++) {
if (Coeff[axis].size()>0) {
cout << endl << " <axis name=\"" << AxisNamesUpper[axis] << "\">" << endl;
for (int c=0; c<Coeff[axis].size(); c++) {
Coeff[axis][c]->convert();
}
cout << " </axis>" << endl;
}
}
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// The bitmasked value choices are as follows:
// unset: In this case (the default) JSBSim would only print
// out the normally expected messages, essentially echoing
// the config files as they are read. If the environment
// variable is not set, debug_lvl is set to 1 internally
// 0: This requests JSBSim not to output any messages
// whatsoever.
// 1: This value explicity requests the normal JSBSim
// startup messages
// 2: This value asks for a message to be printed out when
// a class is instantiated
// 4: When this value is set, a message is displayed when a
// FGModel object executes its Run() method
// 8: When this value is set, various runtime state variables
// are printed out periodically
// 16: When set various parameters are sanity checked and
// a message is printed out when they go out of bounds
void FGAerodynamics::Debug(int from)
{
if (debug_lvl <= 0) return;
if (debug_lvl & 1) { // Standard console startup message output
if (from == 0) { // Constructor
}
}
if (debug_lvl & 2 ) { // Instantiation/Destruction notification
if (from == 0) cout << "Instantiated: FGAerodynamics" << endl;
if (from == 1) cout << "Destroyed: FGAerodynamics" << endl;
}
if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
}
if (debug_lvl & 8 ) { // Runtime state variables
}
if (debug_lvl & 16) { // Sanity checking
}
if (debug_lvl & 64) {
if (from == 0) { // Constructor
cout << IdSrc << endl;
cout << IdHdr << endl;
}
}
}
} // namespace JSBSim

View file

@ -1,199 +0,0 @@
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Header: FGAerodynamics.h
Author: Jon S. Berndt
Date started: 09/13/00
------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU 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 General Public License for more
details.
You should have received a copy of the GNU 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 General Public License can also be found on
the world wide web at http://www.gnu.org.
HISTORY
--------------------------------------------------------------------------------
09/13/00 JSB Created
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
SENTRY
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#ifndef FGAERODYNAMICS_H
#define FGAERODYNAMICS_H
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#ifdef FGFS
# include <simgear/compiler.h>
# ifdef SG_HAVE_STD_INCLUDES
# include <vector>
# include <map>
# else
# include <vector.h>
# include <map.h>
# endif
#else
# include <vector>
# include <map>
#endif
#include "FGModel.h"
#include "FGConfigFile.h"
#include "FGCoefficient.h"
#include "FGColumnVector3.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_AERODYNAMICS "$Id$"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
namespace JSBSim {
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DOCUMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/** Encapsulates the aerodynamic calculations.
This class owns and contains the list of coefficients that define the
aerodynamic properties of this aircraft. Here also, such unique phenomena
as ground effect and maximum lift curve tailoff are handled.
@config
<pre>
\<AERODYNAMICS>
\<AXIS NAME="{LIFT|DRAG|SIDE|ROLL|PITCH|YAW}">
{Coefficient definitions}
\</AXIS>
{Additional axis definitions}
\</AERODYNAMICS> </pre>
@author Jon S. Berndt, Tony Peden
$Id$
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DECLARATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
class FGAerodynamics : public FGModel {
public:
/** Constructor
@param Executive a pointer to the parent executive object */
FGAerodynamics(FGFDMExec* Executive);
/// Destructor
~FGAerodynamics();
/** Runs the Aerodynamics model; called by the Executive
@return false if no error */
bool Run(void);
/** Loads the Aerodynamics model.
The Load function for this class expects the configuration file to
have found the AERODYNAMICS keyword in the configution file and to
have set that line to the current line.
@param AC_cfg pointer to the current configuration file.
@return true if successful */
bool Load(FGConfigFile* AC_cfg);
/** Gets the total aerodynamic force vector.
@return a force vector reference. */
FGColumnVector3& GetForces(void) {return vForces;}
/** Gets the aerodynamic force for an axis.
@param n Axis index. This could be 0, 1, or 2, or one of the
axis enums: eX, eY, eZ.
@return the force acting on an axis */
double GetForces(int n) const {return vForces(n);}
/** Gets the total aerodynamic moment vector.
@return a moment vector reference. */
FGColumnVector3& GetMoments(void) {return vMoments;}
/** Gets the aerodynamic moment for an axis.
@return the moment about a single axis (as described also in the
similar call to GetForces(int n).*/
double GetMoments(int n) const {return vMoments(n);}
FGColumnVector3& GetvLastFs(void) { return vLastFs; }
double GetvLastFs(int axis) const { return vLastFs(axis); }
FGColumnVector3& GetvFs(void) { return vFs; }
double GetvFs(int axis) const { return vFs(axis); }
inline double GetLoD(void) const { return lod; }
inline double GetClSquared(void) const { return clsq; }
inline double GetAlphaCLMax(void) const { return alphaclmax; }
inline double GetAlphaCLMin(void) const { return alphaclmin; }
inline double GetAlphaHystMax(void) const { return alphahystmax; }
inline double GetAlphaHystMin(void) const { return alphahystmin; }
inline double GetHysteresisParm(void) const { return stall_hyst; }
inline double GetStallWarn(void) const { return impending_stall; }
double GetAlphaW(void) const { return alphaw; }
double GetBI2Vel(void) const { return bi2vel; }
double GetCI2Vel(void) const { return ci2vel; }
inline void SetAlphaCLMax(double tt) { alphaclmax=tt; }
inline void SetAlphaCLMin(double tt) { alphaclmin=tt; }
/** Gets the strings for the current set of coefficients.
@param delimeter either a tab or comma string depending on output type
@return a string containing the descriptive names for all coefficients */
string GetCoefficientStrings(string delimeter);
/** Gets the coefficient values.
@param delimeter either a tab or comma string depending on output type
@return a string containing the numeric values for the current set of
coefficients */
string GetCoefficientValues(string delimeter);
void bind(void);
void bindModel(void);
void unbind(void);
void convert(void);
private:
typedef map<string,int> AxisIndex;
AxisIndex AxisIdx;
typedef vector<FGCoefficient*> CoeffArray;
CoeffArray* Coeff;
FGColumnVector3 vFs;
FGColumnVector3 vForces;
FGColumnVector3 vMoments;
FGColumnVector3 vLastFs;
FGColumnVector3 vDXYZcg;
double alphaclmax, alphaclmin;
double alphahystmax, alphahystmin;
double impending_stall, stall_hyst;
double bi2vel, ci2vel,alphaw;
double clsq,lod;
typedef double (FGAerodynamics::*PMF)(int) const;
void Debug(int from);
};
} // namespace JSBSim
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#endif

View file

@ -1,399 +0,0 @@
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Module: FGAircraft.cpp
Author: Jon S. Berndt
Date started: 12/12/98
Purpose: Encapsulates an aircraft
Called by: FGFDMExec
------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU 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 General Public License for more
details.
You should have received a copy of the GNU 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 General Public License can also be found on
the world wide web at http://www.gnu.org.
FUNCTIONAL DESCRIPTION
--------------------------------------------------------------------------------
Models the aircraft reactions and forces. This class is instantiated by the
FGFDMExec class and scheduled as an FDM entry.
HISTORY
--------------------------------------------------------------------------------
12/12/98 JSB Created
04/03/99 JSB Changed Aero() method to correct body axis force calculation
from wind vector. Fix provided by Tony Peden.
05/03/99 JSB Changed (for the better?) the way configurations are read in.
9/17/99 TP Combined force and moment functions. Added aero reference
point to config file. Added calculations for moments due to
difference in cg and aero reference point
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
COMMENTS, REFERENCES, and NOTES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <sys/stat.h>
#include <sys/types.h>
#ifdef FGFS
# ifndef __BORLANDC__
# include <simgear/compiler.h>
# endif
# ifdef SG_HAVE_STD_INCLUDES
# include <cmath>
# else
# include <math.h>
# endif
#else
# if defined (sgi) && !defined(__GNUC__)
# include <math.h>
# else
# include <cmath>
# endif
#endif
#include "FGAircraft.h"
#include "FGMassBalance.h"
#include "FGInertial.h"
#include "FGGroundReactions.h"
#include "FGAerodynamics.h"
#include "FGState.h"
#include "FGFDMExec.h"
#include "FGPropagate.h"
#include "FGPropertyManager.h"
namespace JSBSim {
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
GLOBAL DATA
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
static const char *IdSrc = "$Id$";
static const char *IdHdr = ID_AIRCRAFT;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
FGAircraft::FGAircraft(FGFDMExec* fdmex) : FGModel(fdmex)
{
Name = "FGAircraft";
WingSpan = 0.0;
HTailArea = VTailArea = 0.0;
HTailArm = VTailArm = 0.0;
lbarh = lbarv = 0.0;
vbarh = vbarv = 0.0;
WingIncidence = 0.0;
bind();
Debug(0);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGAircraft::~FGAircraft()
{
unbind();
Debug(1);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
bool FGAircraft::Run(void)
{
if (!FGModel::Run()) { // if false then execute this Run()
vForces.InitMatrix();
vForces += Aerodynamics->GetForces();
vForces += Propulsion->GetForces();
vForces += GroundReactions->GetForces();
vMoments.InitMatrix();
vMoments += Aerodynamics->GetMoments();
vMoments += Propulsion->GetMoments();
vMoments += GroundReactions->GetMoments();
vBodyAccel = vForces/MassBalance->GetMass();
vNcg = vBodyAccel/Inertial->gravity();
vNwcg = State->GetTb2s() * vNcg;
vNwcg(3) = -1*vNwcg(3) + 1;
return false;
} else { // skip Run() execution this time
return true;
}
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
double FGAircraft::GetNlf(void)
{
return -1*Aerodynamics->GetvFs(3)/MassBalance->GetWeight();
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
bool FGAircraft::Load(FGConfigFile* AC_cfg)
{
string token = "";
string parameter;
double EW, bixx, biyy, bizz, bixy, bixz, biyz;
double pmWt, pmX, pmY, pmZ;
FGColumnVector3 vbaseXYZcg;
bixx = biyy = bizz = bixy = bixz = biyz = 0.0;
AC_cfg->GetNextConfigLine();
while ((token = AC_cfg->GetValue()) != string("/METRICS")) {
*AC_cfg >> parameter;
if (parameter == "AC_WINGAREA") {
*AC_cfg >> WingArea;
if (debug_lvl > 0) cout << " WingArea: " << WingArea << endl;
} else if (parameter == "AC_WINGSPAN") {
*AC_cfg >> WingSpan;
if (debug_lvl > 0) cout << " WingSpan: " << WingSpan << endl;
} else if (parameter == "AC_WINGINCIDENCE") {
*AC_cfg >> WingIncidence;
if (debug_lvl > 0) cout << " Incidence: " << WingIncidence << endl;
} else if (parameter == "AC_CHORD") {
*AC_cfg >> cbar;
if (debug_lvl > 0) cout << " Chord: " << cbar << endl;
} else if (parameter == "AC_HTAILAREA") {
*AC_cfg >> HTailArea;
if (debug_lvl > 0) cout << " H. Tail Area: " << HTailArea << endl;
} else if (parameter == "AC_HTAILARM") {
*AC_cfg >> HTailArm;
if (debug_lvl > 0) cout << " H. Tail Arm: " << HTailArm << endl;
} else if (parameter == "AC_VTAILAREA") {
*AC_cfg >> VTailArea;
if (debug_lvl > 0) cout << " V. Tail Area: " << VTailArea << endl;
} else if (parameter == "AC_VTAILARM") {
*AC_cfg >> VTailArm;
if (debug_lvl > 0) cout << " V. Tail Arm: " << VTailArm << endl;
} else if (parameter == "AC_IXX") {
*AC_cfg >> bixx;
if (debug_lvl > 0) cout << " baseIxx: " << bixx << " slug-ft2" << endl;
} else if (parameter == "AC_IYY") {
*AC_cfg >> biyy;
if (debug_lvl > 0) cout << " baseIyy: " << biyy << " slug-ft2" << endl;
} else if (parameter == "AC_IZZ") {
*AC_cfg >> bizz;
if (debug_lvl > 0) cout << " baseIzz: " << bizz << " slug-ft2" << endl;
} else if (parameter == "AC_IXY") {
*AC_cfg >> bixy;
if (debug_lvl > 0) cout << " baseIxy: " << bixy << " slug-ft2" << endl;
} else if (parameter == "AC_IXZ") {
*AC_cfg >> bixz;
if (debug_lvl > 0) cout << " baseIxz: " << bixz << " slug-ft2" << endl;
} else if (parameter == "AC_IYZ") {
*AC_cfg >> biyz;
if (debug_lvl > 0) cout << " baseIyz: " << biyz << " slug-ft2" << endl;
} else if (parameter == "AC_EMPTYWT") {
*AC_cfg >> EW;
MassBalance->SetEmptyWeight(EW);
if (debug_lvl > 0) cout << " EmptyWeight: " << EW << " lbm" << endl;
} else if (parameter == "AC_CGLOC") {
*AC_cfg >> vbaseXYZcg(eX) >> vbaseXYZcg(eY) >> vbaseXYZcg(eZ);
MassBalance->SetBaseCG(vbaseXYZcg);
if (debug_lvl > 0) cout << " CG (x, y, z): " << vbaseXYZcg << endl;
} else if (parameter == "AC_EYEPTLOC") {
*AC_cfg >> vXYZep(eX) >> vXYZep(eY) >> vXYZep(eZ);
if (debug_lvl > 0) cout << " Eyepoint (x, y, z): " << vXYZep << endl;
} else if (parameter == "AC_AERORP") {
*AC_cfg >> vXYZrp(eX) >> vXYZrp(eY) >> vXYZrp(eZ);
if (debug_lvl > 0) cout << " Ref Pt (x, y, z): " << vXYZrp << endl;
} else if (parameter == "AC_VRP") {
*AC_cfg >> vXYZvrp(eX) >> vXYZvrp(eY) >> vXYZvrp(eZ);
if (debug_lvl > 0) cout << " Visual Ref Pt (x, y, z): " << vXYZvrp << endl;
} else if (parameter == "AC_POINTMASS") {
*AC_cfg >> pmWt >> pmX >> pmY >> pmZ;
MassBalance->AddPointMass(pmWt, pmX, pmY, pmZ);
if (debug_lvl > 0) cout << " Point Mass Object: " << pmWt << " lbs. at "
<< "X, Y, Z (in.): " << pmX << " " << pmY << " " << pmZ
<< endl;
}
}
MassBalance->SetAircraftBaseInertias(FGMatrix33( bixx, -bixy, -bixz,
-bixy, biyy, -biyz,
-bixz, -biyz, bizz ));
// calculate some derived parameters
if (cbar != 0.0) {
lbarh = HTailArm/cbar;
lbarv = VTailArm/cbar;
if (WingArea != 0.0) {
vbarh = HTailArm*HTailArea / (cbar*WingArea);
vbarv = VTailArm*VTailArea / (cbar*WingArea);
}
}
return true;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGAircraft::bind(void)
{
typedef double (FGAircraft::*PMF)(int) const;
PropertyManager->Tie("metrics/Sw-sqft", this,
&FGAircraft::GetWingArea);
PropertyManager->Tie("metrics/bw-ft", this,
&FGAircraft::GetWingSpan);
PropertyManager->Tie("metrics/cbarw-ft", this,
&FGAircraft::Getcbar);
PropertyManager->Tie("metrics/iw-deg", this,
&FGAircraft::GetWingIncidence);
PropertyManager->Tie("metrics/Sh-sqft", this,
&FGAircraft::GetHTailArea);
PropertyManager->Tie("metrics/lh-ft", this,
&FGAircraft::GetHTailArm);
PropertyManager->Tie("metrics/Sv-sqft", this,
&FGAircraft::GetVTailArea);
PropertyManager->Tie("metrics/lv-ft", this,
&FGAircraft::GetVTailArm);
PropertyManager->Tie("metrics/lh-norm", this,
&FGAircraft::Getlbarh);
PropertyManager->Tie("metrics/lv-norm", this,
&FGAircraft::Getlbarv);
PropertyManager->Tie("metrics/vbarh-norm", this,
&FGAircraft::Getvbarh);
PropertyManager->Tie("metrics/vbarv-norm", this,
&FGAircraft::Getvbarv);
PropertyManager->Tie("moments/l-total-lbsft", this,1,
(PMF)&FGAircraft::GetMoments);
PropertyManager->Tie("moments/m-total-lbsft", this,2,
(PMF)&FGAircraft::GetMoments);
PropertyManager->Tie("moments/n-total-lbsft", this,3,
(PMF)&FGAircraft::GetMoments);
PropertyManager->Tie("forces/fbx-total-lbs", this,1,
(PMF)&FGAircraft::GetForces);
PropertyManager->Tie("forces/fby-total-lbs", this,2,
(PMF)&FGAircraft::GetForces);
PropertyManager->Tie("forces/fbz-total-lbs", this,3,
(PMF)&FGAircraft::GetForces);
PropertyManager->Tie("metrics/aero-rp-x-in", this,1,
(PMF)&FGAircraft::GetXYZrp);
PropertyManager->Tie("metrics/aero-rp-y-in", this,2,
(PMF)&FGAircraft::GetXYZrp);
PropertyManager->Tie("metrics/aero-rp-z-in", this,3,
(PMF)&FGAircraft::GetXYZrp);
PropertyManager->Tie("metrics/eyepoint-x-in", this,1,
(PMF)&FGAircraft::GetXYZep);
PropertyManager->Tie("metrics/eyepoint-y-in", this,2,
(PMF)&FGAircraft::GetXYZep);
PropertyManager->Tie("metrics/eyepoint-z-in", this,3,
(PMF)&FGAircraft::GetXYZep);
PropertyManager->Tie("metrics/visualrefpoint-x-in", this,1,
(PMF)&FGAircraft::GetXYZvrp);
PropertyManager->Tie("metrics/visualrefpoint-y-in", this,2,
(PMF)&FGAircraft::GetXYZvrp);
PropertyManager->Tie("metrics/visualrefpoint-z-in", this,3,
(PMF)&FGAircraft::GetXYZvrp);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGAircraft::unbind(void)
{
PropertyManager->Untie("metrics/Sw-sqft");
PropertyManager->Untie("metrics/bw-ft");
PropertyManager->Untie("metrics/cbarw-ft");
PropertyManager->Untie("metrics/iw-deg");
PropertyManager->Untie("metrics/Sh-sqft");
PropertyManager->Untie("metrics/lh-ft");
PropertyManager->Untie("metrics/Sv-sqft");
PropertyManager->Untie("metrics/lv-ft");
PropertyManager->Untie("metrics/lh-norm");
PropertyManager->Untie("metrics/lv-norm");
PropertyManager->Untie("metrics/vbarh-norm");
PropertyManager->Untie("metrics/vbarv-norm");
PropertyManager->Untie("moments/l-total-lbsft");
PropertyManager->Untie("moments/m-total-lbsft");
PropertyManager->Untie("moments/n-total-lbsft");
PropertyManager->Untie("forces/fbx-total-lbs");
PropertyManager->Untie("forces/fby-total-lbs");
PropertyManager->Untie("forces/fbz-total-lbs");
PropertyManager->Untie("metrics/aero-rp-x-in");
PropertyManager->Untie("metrics/aero-rp-y-in");
PropertyManager->Untie("metrics/aero-rp-z-in");
PropertyManager->Untie("metrics/eyepoint-x-in");
PropertyManager->Untie("metrics/eyepoint-y-in");
PropertyManager->Untie("metrics/eyepoint-z-in");
PropertyManager->Untie("metrics/visualrefpoint-x-in");
PropertyManager->Untie("metrics/visualrefpoint-y-in");
PropertyManager->Untie("metrics/visualrefpoint-z-in");
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// The bitmasked value choices are as follows:
// unset: In this case (the default) JSBSim would only print
// out the normally expected messages, essentially echoing
// the config files as they are read. If the environment
// variable is not set, debug_lvl is set to 1 internally
// 0: This requests JSBSim not to output any messages
// whatsoever.
// 1: This value explicity requests the normal JSBSim
// startup messages
// 2: This value asks for a message to be printed out when
// a class is instantiated
// 4: When this value is set, a message is displayed when a
// FGModel object executes its Run() method
// 8: When this value is set, various runtime state variables
// are printed out periodically
// 16: When set various parameters are sanity checked and
// a message is printed out when they go out of bounds
void FGAircraft::Debug(int from)
{
if (debug_lvl <= 0) return;
if (debug_lvl & 1) { // Standard console startup message output
if (from == 0) { // Constructor
}
}
if (debug_lvl & 2 ) { // Instantiation/Destruction notification
if (from == 0) cout << "Instantiated: FGAircraft" << endl;
if (from == 1) cout << "Destroyed: FGAircraft" << endl;
}
if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
}
if (debug_lvl & 8 ) { // Runtime state variables
}
if (debug_lvl & 16) { // Sanity checking
}
if (debug_lvl & 64) {
if (from == 0) { // Constructor
cout << IdSrc << endl;
cout << IdHdr << endl;
}
}
}
} // namespace JSBSim

View file

@ -1,184 +0,0 @@
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Header: FGAircraft.h
Author: Jon S. Berndt
Date started: 12/12/98
------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU 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 General Public License for more
details.
You should have received a copy of the GNU 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 General Public License can also be found on
the world wide web at http://www.gnu.org.
HISTORY
--------------------------------------------------------------------------------
12/12/98 JSB Created
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
SENTRY
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#ifndef FGAIRCRAFT_H
#define FGAIRCRAFT_H
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#ifdef FGFS
# include <simgear/compiler.h>
# ifdef SG_HAVE_STD_INCLUDES
# include <vector>
# include <iterator>
# else
# include <vector.h>
# include <iterator.h>
# endif
#else
# include <vector>
# include <iterator>
#endif
#include "FGModel.h"
#include "FGConfigFile.h"
#include "FGColumnVector3.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_AIRCRAFT "$Id$"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
namespace JSBSim {
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DOCUMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/** Encapsulates an Aircraft and its systems.
Owns all the parts (other classes) which make up this aircraft. This includes
the Engines, Tanks, Propellers, Nozzles, Aerodynamic and Mass properties,
landing gear, etc. These constituent parts may actually run as separate
JSBSim models themselves, but the responsibility for initializing them and
for retrieving their force and moment contributions falls to FGAircraft.
@author Jon S. Berndt
@version $Id$
@see Cooke, Zyda, Pratt, and McGhee, "NPSNET: Flight Simulation Dynamic Modeling
Using Quaternions", Presence, Vol. 1, No. 4, pp. 404-420 Naval Postgraduate
School, January 1994
@see D. M. Henderson, "Euler Angles, Quaternions, and Transformation Matrices",
JSC 12960, July 1977
@see Richard E. McFarland, "A Standard Kinematic Model for Flight Simulation at
NASA-Ames", NASA CR-2497, January 1975
@see Barnes W. McCormick, "Aerodynamics, Aeronautics, and Flight Mechanics",
Wiley & Sons, 1979 ISBN 0-471-03032-5
@see Bernard Etkin, "Dynamics of Flight, Stability and Control", Wiley & Sons,
1982 ISBN 0-471-08936-2
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DECLARATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
class FGAircraft : public FGModel {
public:
/** Constructor
@param Executive a pointer to the parent executive object */
FGAircraft(FGFDMExec *Executive);
/// Destructor
~FGAircraft();
/** Runs the Aircraft model; called by the Executive
@see JSBSim.cpp documentation
@return false if no error */
bool Run(void);
/** Loads the aircraft.
The executive calls this method to load the aircraft into JSBSim.
@param AC_cfg a pointer to the config file instance
@return true if successful */
bool Load(FGConfigFile* AC_cfg);
/** Gets the aircraft name
@return the name of the aircraft as a string type */
inline string GetAircraftName(void) { return AircraftName; }
/// Gets the wing area
double GetWingArea(void) const { return WingArea; }
/// Gets the wing span
double GetWingSpan(void) const { return WingSpan; }
/// Gets the average wing chord
double Getcbar(void) const { return cbar; }
inline double GetWingIncidence(void) const { return WingIncidence; }
inline double GetHTailArea(void) const { return HTailArea; }
inline double GetHTailArm(void) const { return HTailArm; }
inline double GetVTailArea(void) const { return VTailArea; }
inline double GetVTailArm(void) const { return VTailArm; }
inline double Getlbarh(void) const { return lbarh; } // HTailArm / cbar
inline double Getlbarv(void) const { return lbarv; } // VTailArm / cbar
inline double Getvbarh(void) const { return vbarh; } // H. Tail Volume
inline double Getvbarv(void) const { return vbarv; } // V. Tail Volume
inline FGColumnVector3& GetMoments(void) { return vMoments; }
inline double GetMoments(int idx) const { return vMoments(idx); }
inline FGColumnVector3& GetForces(void) { return vForces; }
inline double GetForces(int idx) const { return vForces(idx); }
inline FGColumnVector3& GetBodyAccel(void) { return vBodyAccel; }
inline double GetBodyAccel(int idx) { return vBodyAccel(idx); }
inline FGColumnVector3& GetNcg (void) { return vNcg; }
inline double GetNcg(int idx) { return vNcg(idx); }
inline FGColumnVector3& GetXYZrp(void) { return vXYZrp; }
inline FGColumnVector3& GetXYZvrp(void) { return vXYZvrp; }
inline FGColumnVector3& GetXYZep(void) { return vXYZep; }
inline double GetXYZrp(int idx) const { return vXYZrp(idx); }
inline double GetXYZvrp(int idx) const { return vXYZvrp(idx); }
inline double GetXYZep(int idx) const { return vXYZep(idx); }
inline void SetAircraftName(string name) {AircraftName = name;}
double GetNlf(void);
inline FGColumnVector3& GetNwcg(void) { return vNwcg; }
void bind(void);
void unbind(void);
private:
FGColumnVector3 vMoments;
FGColumnVector3 vForces;
FGColumnVector3 vXYZrp;
FGColumnVector3 vXYZvrp;
FGColumnVector3 vXYZep;
FGColumnVector3 vDXYZcg;
FGColumnVector3 vBodyAccel;
FGColumnVector3 vNcg;
FGColumnVector3 vNwcg;
double WingArea, WingSpan, cbar, WingIncidence;
double HTailArea, VTailArea, HTailArm, VTailArm;
double lbarh,lbarv,vbarh,vbarv;
string AircraftName;
void Debug(int from);
};
} // namespace JSBSim
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#endif

View file

@ -1,541 +0,0 @@
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Module: FGAtmosphere.cpp
Author: Jon Berndt
Implementation of 1959 Standard Atmosphere added by Tony Peden
Date started: 11/24/98
Purpose: Models the atmosphere
Called by: FGSimExec
------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU 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 General Public License for more
details.
You should have received a copy of the GNU 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 General Public License can also be found on
the world wide web at http://www.gnu.org.
FUNCTIONAL DESCRIPTION
--------------------------------------------------------------------------------
Models the atmosphere. The equation used below was determined by a third order
curve fit using Excel. The data is from the ICAO atmosphere model.
HISTORY
--------------------------------------------------------------------------------
11/24/98 JSB Created
07/23/99 TP Added implementation of 1959 Standard Atmosphere
Moved calculation of Mach number to FGPropagate
Later updated to '76 model
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
COMMENTS, REFERENCES, and NOTES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
[1] Anderson, John D. "Introduction to Flight, Third Edition", McGraw-Hill,
1989, ISBN 0-07-001641-0
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include "FGAtmosphere.h"
#include "FGState.h"
#include "FGFDMExec.h"
#include "FGAircraft.h"
#include "FGPropagate.h"
#include "FGInertial.h"
#include "FGPropertyManager.h"
namespace JSBSim {
static const char *IdSrc = "$Id$";
static const char *IdHdr = ID_ATMOSPHERE;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
FGAtmosphere::FGAtmosphere(FGFDMExec* fdmex) : FGModel(fdmex)
{
Name = "FGAtmosphere";
lastIndex = 0;
h = 0.0;
psiw = 0.0;
htab[0]=0;
htab[1]=36089.239;
htab[2]=65616.798;
htab[3]=104986.878;
htab[4]=154199.475;
htab[5]=170603.675;
htab[6]=200131.234;
htab[7]=259186.352; //ft.
MagnitudedAccelDt = MagnitudeAccel = Magnitude = 0.0;
// turbType = ttNone;
turbType = ttStandard;
// turbType = ttBerndt;
TurbGain = 0.0;
TurbRate = 1.0;
T_dev_sl = T_dev = delta_T = 0.0;
bind();
Debug(0);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGAtmosphere::~FGAtmosphere()
{
unbind();
Debug(1);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
bool FGAtmosphere::InitModel(void)
{
FGModel::InitModel();
Calculate(h);
SLtemperature = intTemperature;
SLpressure = intPressure;
SLdensity = intDensity;
SLsoundspeed = sqrt(SHRatio*Reng*intTemperature);
rSLtemperature = 1.0/intTemperature;
rSLpressure = 1.0/intPressure;
rSLdensity = 1.0/intDensity;
rSLsoundspeed = 1.0/SLsoundspeed;
temperature=&intTemperature;
pressure=&intPressure;
density=&intDensity;
useExternal=false;
return true;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
bool FGAtmosphere::Run(void)
{
if (!FGModel::Run()) { // if false then execute this Run()
//do temp, pressure, and density first
if (!useExternal) {
h = Propagate->Geth();
Calculate(h);
}
if (turbType != ttNone) {
Turbulence();
vWindNED += vTurbulence;
}
if (vWindNED(1) != 0.0) psiw = atan2( vWindNED(2), vWindNED(1) );
if (psiw < 0) psiw += 2*M_PI;
soundspeed = sqrt(SHRatio*Reng*(*temperature));
Debug(2);
return false;
} else { // skip Run() execution this time
return true;
}
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//
// See reference 1
void FGAtmosphere::Calculate(double altitude)
{
double slope, reftemp, refpress;
int i = 0;
i = lastIndex;
if (altitude < htab[lastIndex]) {
if (altitude <= 0) {
i = 0;
altitude=0;
} else {
i = lastIndex-1;
while (htab[i] > altitude) i--;
}
} else if (altitude > htab[lastIndex+1]) {
if (altitude >= htab[7]) {
i = 7;
altitude = htab[7];
} else {
i = lastIndex+1;
while (htab[i+1] < altitude) i++;
}
}
switch(i) {
case 1: // 36089 ft.
slope = 0;
reftemp = 389.97;
refpress = 472.452;
//refdens = 0.000706032;
break;
case 2: // 65616 ft.
slope = 0.00054864;
reftemp = 389.97;
refpress = 114.636;
//refdens = 0.000171306;
break;
case 3: // 104986 ft.
slope = 0.00153619;
reftemp = 411.57;
refpress = 8.36364;
//refdens = 1.18422e-05;
break;
case 4: // 154199 ft.
slope = 0;
reftemp = 487.17;
refpress = 0.334882;
//refdens = 4.00585e-7;
break;
case 5: // 170603 ft.
slope = -0.00109728;
reftemp = 487.17;
refpress = 0.683084;
//refdens = 8.17102e-7;
break;
case 6: // 200131 ft.
slope = -0.00219456;
reftemp = 454.17;
refpress = 0.00684986;
//refdens = 8.77702e-9;
break;
case 7: // 259186 ft.
slope = 0;
reftemp = 325.17;
refpress = 0.000122276;
//refdens = 2.19541e-10;
break;
case 0:
default: // sea level
slope = -0.00356616; // R/ft.
reftemp = 518.67; // R
refpress = 2116.22; // psf
//refdens = 0.00237767; // slugs/cubic ft.
break;
}
T_dev = 0.0;
if (delta_T != 0.0) {
T_dev = delta_T;
} else {
if ((h < 36089.239) && (T_dev_sl != 0.0)) {
T_dev = T_dev_sl * ( 1.0 - (h/36089.239));
}
}
density_altitude = h + T_dev * 66.7;
reftemp+=T_dev;
if (slope == 0) {
intTemperature = reftemp;
intPressure = refpress*exp(-Inertial->SLgravity()/(reftemp*Reng)*(altitude-htab[i]));
//intDensity = refdens*exp(-Inertial->SLgravity()/(reftemp*Reng)*(altitude-htab[i]));
intDensity = intPressure/(Reng*intTemperature);
} else {
intTemperature = reftemp+slope*(altitude-htab[i]);
intPressure = refpress*pow(intTemperature/reftemp,-Inertial->SLgravity()/(slope*Reng));
//intDensity = refdens*pow(intTemperature/reftemp,-(Inertial->SLgravity()/(slope*Reng)+1));
intDensity = intPressure/(Reng*intTemperature);
}
lastIndex=i;
//cout << "Atmosphere: h=" << altitude << " rho= " << intDensity << endl;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// Return the pressure at an arbitrary altitude and then restore the internal state
double FGAtmosphere::GetPressure(double alt) {
Calculate(alt);
double p = *pressure;
// Reset the internal atmospheric state
Run();
return(p);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// square a value, but preserve the original sign
static inline double square_signed (double value)
{
if (value < 0)
return value * value * -1;
else
return value * value;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGAtmosphere::Turbulence(void)
{
switch (turbType) {
case ttStandard: {
vDirectiondAccelDt(eX) = 1 - 2.0*(double(rand())/double(RAND_MAX));
vDirectiondAccelDt(eY) = 1 - 2.0*(double(rand())/double(RAND_MAX));
vDirectiondAccelDt(eZ) = 1 - 2.0*(double(rand())/double(RAND_MAX));
MagnitudedAccelDt = 1 - 2.0*(double(rand())/double(RAND_MAX)) - Magnitude;
// Scale the magnitude so that it moves
// away from the peaks
MagnitudedAccelDt = ((MagnitudedAccelDt - Magnitude) /
(1 + fabs(Magnitude)));
MagnitudeAccel += MagnitudedAccelDt*rate*TurbRate*State->Getdt();
Magnitude += MagnitudeAccel*rate*State->Getdt();
vDirectiondAccelDt.Normalize();
// deemphasise non-vertical forces
vDirectiondAccelDt(eX) = square_signed(vDirectiondAccelDt(eX));
vDirectiondAccelDt(eY) = square_signed(vDirectiondAccelDt(eY));
vDirectionAccel += vDirectiondAccelDt*rate*TurbRate*State->Getdt();
vDirectionAccel.Normalize();
vDirection += vDirectionAccel*rate*State->Getdt();
vDirection.Normalize();
// Diminish turbulence within three wingspans
// of the ground
vTurbulence = TurbGain * Magnitude * vDirection;
double HOverBMAC = Auxiliary->GetHOverBMAC();
if (HOverBMAC < 3.0)
vTurbulence *= (HOverBMAC / 3.0) * (HOverBMAC / 3.0);
vTurbulenceGrad = TurbGain*MagnitudeAccel * vDirection;
vBodyTurbGrad = Propagate->GetTl2b()*vTurbulenceGrad;
if (Aircraft->GetWingSpan() > 0) {
vTurbPQR(eP) = vBodyTurbGrad(eY)/Aircraft->GetWingSpan();
} else {
vTurbPQR(eP) = vBodyTurbGrad(eY)/30.0;
}
// if (Aircraft->GetHTailArm() != 0.0)
// vTurbPQR(eQ) = vBodyTurbGrad(eZ)/Aircraft->GetHTailArm();
// else
// vTurbPQR(eQ) = vBodyTurbGrad(eZ)/10.0;
if (Aircraft->GetVTailArm() > 0)
vTurbPQR(eR) = vBodyTurbGrad(eX)/Aircraft->GetVTailArm();
else
vTurbPQR(eR) = vBodyTurbGrad(eX)/10.0;
// Clear the horizontal forces
// actually felt by the plane, now
// that we've used them to calculate
// moments.
vTurbulence(eX) = 0.0;
vTurbulence(eY) = 0.0;
break;
}
case ttBerndt: {
vDirectiondAccelDt(eX) = 1 - 2.0*(double(rand())/double(RAND_MAX));
vDirectiondAccelDt(eY) = 1 - 2.0*(double(rand())/double(RAND_MAX));
vDirectiondAccelDt(eZ) = 1 - 2.0*(double(rand())/double(RAND_MAX));
MagnitudedAccelDt = 1 - 2.0*(double(rand())/double(RAND_MAX)) - Magnitude;
MagnitudeAccel += MagnitudedAccelDt*rate*State->Getdt();
Magnitude += MagnitudeAccel*rate*State->Getdt();
vDirectiondAccelDt.Normalize();
vDirectionAccel += vDirectiondAccelDt*rate*State->Getdt();
vDirectionAccel.Normalize();
vDirection += vDirectionAccel*rate*State->Getdt();
// Diminish z-vector within two wingspans
// of the ground
double HOverBMAC = Auxiliary->GetHOverBMAC();
if (HOverBMAC < 2.0)
vDirection(eZ) *= HOverBMAC / 2.0;
vDirection.Normalize();
vTurbulence = TurbGain*Magnitude * vDirection;
vTurbulenceGrad = TurbGain*MagnitudeAccel * vDirection;
vBodyTurbGrad = Propagate->GetTl2b()*vTurbulenceGrad;
vTurbPQR(eP) = vBodyTurbGrad(eY)/Aircraft->GetWingSpan();
if (Aircraft->GetHTailArm() > 0)
vTurbPQR(eQ) = vBodyTurbGrad(eZ)/Aircraft->GetHTailArm();
else
vTurbPQR(eQ) = vBodyTurbGrad(eZ)/10.0;
if (Aircraft->GetVTailArm() > 0)
vTurbPQR(eR) = vBodyTurbGrad(eX)/Aircraft->GetVTailArm();
else
vTurbPQR(eR) = vBodyTurbGrad(eX)/10.0;
break;
}
default:
break;
}
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGAtmosphere::UseExternal(void) {
temperature=&exTemperature;
pressure=&exPressure;
density=&exDensity;
useExternal=true;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGAtmosphere::UseInternal(void) {
temperature=&intTemperature;
pressure=&intPressure;
density=&intDensity;
useExternal=false;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGAtmosphere::bind(void)
{
typedef double (FGAtmosphere::*PMF)(int) const;
PropertyManager->Tie("atmosphere/T-R", this,
&FGAtmosphere::GetTemperature);
PropertyManager->Tie("atmosphere/rho-slugs_ft3", this,
&FGAtmosphere::GetDensity);
// PropertyManager->Tie("atmosphere/P-psf", this,
// &FGAtmosphere::GetPressure);
PropertyManager->Tie("atmosphere/a-fps", this,
&FGAtmosphere::GetSoundSpeed);
PropertyManager->Tie("atmosphere/T-sl-R", this,
&FGAtmosphere::GetTemperatureSL);
PropertyManager->Tie("atmosphere/rho-sl-slugs_ft3", this,
&FGAtmosphere::GetDensitySL);
PropertyManager->Tie("atmosphere/P-sl-psf", this,
&FGAtmosphere::GetPressureSL);
PropertyManager->Tie("atmosphere/a-sl-fps", this,
&FGAtmosphere::GetSoundSpeedSL);
PropertyManager->Tie("atmosphere/theta-norm", this,
&FGAtmosphere::GetTemperatureRatio);
PropertyManager->Tie("atmosphere/sigma-norm", this,
&FGAtmosphere::GetDensityRatio);
PropertyManager->Tie("atmosphere/delta-norm", this,
&FGAtmosphere::GetPressureRatio);
PropertyManager->Tie("atmosphere/a-norm", this,
&FGAtmosphere::GetSoundSpeedRatio);
PropertyManager->Tie("atmosphere/psiw-rad", this,
&FGAtmosphere::GetWindPsi);
PropertyManager->Tie("atmosphere/delta-T", this,
&FGAtmosphere::GetDeltaT, &FGAtmosphere::SetDeltaT);
PropertyManager->Tie("atmosphere/T-sl-dev-F", this,
&FGAtmosphere::GetSLTempDev, &FGAtmosphere::SetSLTempDev);
PropertyManager->Tie("atmosphere/density-altitude", this,
&FGAtmosphere::GetDensityAltitude);
PropertyManager->Tie("atmosphere/p-turb-rad_sec", this,1,
(PMF)&FGAtmosphere::GetTurbPQR);
PropertyManager->Tie("atmosphere/q-turb-rad_sec", this,2,
(PMF)&FGAtmosphere::GetTurbPQR);
PropertyManager->Tie("atmosphere/r-turb-rad_sec", this,3,
(PMF)&FGAtmosphere::GetTurbPQR);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGAtmosphere::unbind(void)
{
PropertyManager->Untie("atmosphere/T-R");
PropertyManager->Untie("atmosphere/rho-slugs_ft3");
// PropertyManager->Untie("atmosphere/P-psf");
PropertyManager->Untie("atmosphere/a-fps");
PropertyManager->Untie("atmosphere/T-sl-R");
PropertyManager->Untie("atmosphere/rho-sl-slugs_ft3");
PropertyManager->Untie("atmosphere/P-sl-psf");
PropertyManager->Untie("atmosphere/a-sl-fps");
PropertyManager->Untie("atmosphere/delta-T");
PropertyManager->Untie("atmosphere/T-sl-dev-F");
PropertyManager->Untie("atmosphere/density-altitude");
PropertyManager->Untie("atmosphere/theta-norm");
PropertyManager->Untie("atmosphere/sigma-norm");
PropertyManager->Untie("atmosphere/delta-norm");
PropertyManager->Untie("atmosphere/a-norm");
PropertyManager->Untie("atmosphere/psiw-rad");
PropertyManager->Untie("atmosphere/p-turb-rad_sec");
PropertyManager->Untie("atmosphere/q-turb-rad_sec");
PropertyManager->Untie("atmosphere/r-turb-rad_sec");
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// The bitmasked value choices are as follows:
// unset: In this case (the default) JSBSim would only print
// out the normally expected messages, essentially echoing
// the config files as they are read. If the environment
// variable is not set, debug_lvl is set to 1 internally
// 0: This requests JSBSim not to output any messages
// whatsoever.
// 1: This value explicity requests the normal JSBSim
// startup messages
// 2: This value asks for a message to be printed out when
// a class is instantiated
// 4: When this value is set, a message is displayed when a
// FGModel object executes its Run() method
// 8: When this value is set, various runtime state variables
// are printed out periodically
// 16: When set various parameters are sanity checked and
// a message is printed out when they go out of bounds
void FGAtmosphere::Debug(int from)
{
if (debug_lvl <= 0) return;
if (debug_lvl & 1) { // Standard console startup message output
if (from == 0) { // Constructor
}
}
if (debug_lvl & 2 ) { // Instantiation/Destruction notification
if (from == 0) cout << "Instantiated: FGAtmosphere" << endl;
if (from == 1) cout << "Destroyed: FGAtmosphere" << endl;
}
if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
}
if (debug_lvl & 8 ) { // Runtime state variables
}
if (debug_lvl & 16) { // Sanity checking
}
if (debug_lvl & 32) { // Turbulence
if (frame == 0 && from == 2) {
cout << "vTurbulence(X), vTurbulence(Y), vTurbulence(Z), "
<< "vTurbulenceGrad(X), vTurbulenceGrad(Y), vTurbulenceGrad(Z), "
<< "vDirection(X), vDirection(Y), vDirection(Z), "
<< "Magnitude, "
<< "vTurbPQR(P), vTurbPQR(Q), vTurbPQR(R), " << endl;
} else if (from == 2) {
cout << vTurbulence << ", " << vTurbulenceGrad << ", " << vDirection << ", " << Magnitude << ", " << vTurbPQR << endl;
}
}
if (debug_lvl & 64) {
if (from == 0) { // Constructor
cout << IdSrc << endl;
cout << IdHdr << endl;
}
}
}
} // namespace JSBSim

View file

@ -1,205 +0,0 @@
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Header: FGAtmosphere.h
Author: Jon Berndt
Implementation of 1959 Standard Atmosphere added by Tony Peden
Date started: 11/24/98
------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU 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 General Public License for more
details.
You should have received a copy of the GNU 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 General Public License can also be found on
the world wide web at http://www.gnu.org.
HISTORY
--------------------------------------------------------------------------------
11/24/98 JSB Created
07/23/99 TP Added implementation of 1959 Standard Atmosphere
Moved calculation of Mach number to FGPropagate
Updated to '76 model
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
SENTRY
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#ifndef FGAtmosphere_H
#define FGAtmosphere_H
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include "FGModel.h"
#include "FGColumnVector3.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_ATMOSPHERE "$Id$"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
namespace JSBSim {
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DOCUMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/** Models the standard atmosphere.
@author Tony Peden, Jon Berndt
@version $Id$
@see Anderson, John D. "Introduction to Flight, Third Edition", McGraw-Hill,
1989, ISBN 0-07-001641-0
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DECLARATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
class FGAtmosphere : public FGModel {
public:
/// Constructor
FGAtmosphere(FGFDMExec*);
/// Destructor
~FGAtmosphere();
/** Runs the Atmosphere model; called by the Executive
@return false if no error */
bool Run(void);
bool InitModel(void);
/// Returns the temperature in degrees Rankine.
inline double GetTemperature(void) const {return *temperature;}
/** Returns the density in slugs/ft^3.
<i>This function may <b>only</b> be used if Run() is called first.</i> */
inline double GetDensity(void) const {return *density;}
/// Returns the pressure in psf.
inline double GetPressure(void) const {return *pressure;}
/// Returns the pressure at an arbitrary altitude in psf
double GetPressure(double alt);
/// Returns the speed of sound in ft/sec.
inline double GetSoundSpeed(void) const {return soundspeed;}
/// Returns the sea level temperature in degrees Rankine.
inline double GetTemperatureSL(void) const { return SLtemperature; }
/// Returns the sea level density in slugs/ft^3
inline double GetDensitySL(void) const { return SLdensity; }
/// Returns the sea level pressure in psf.
inline double GetPressureSL(void) const { return SLpressure; }
/// Returns the sea level speed of sound in ft/sec.
inline double GetSoundSpeedSL(void) const { return SLsoundspeed; }
/// Returns the ratio of at-altitude temperature over the sea level value.
inline double GetTemperatureRatio(void) const { return (*temperature)*rSLtemperature; }
/// Returns the ratio of at-altitude density over the sea level value.
inline double GetDensityRatio(void) const { return (*density)*rSLdensity; }
/// Returns the ratio of at-altitude pressure over the sea level value.
inline double GetPressureRatio(void) const { return (*pressure)*rSLpressure; }
/// Returns the ratio of at-altitude sound speed over the sea level value.
inline double GetSoundSpeedRatio(void) const { return soundspeed*rSLsoundspeed; }
/// Tells the simulator to use an externally calculated atmosphere model.
void UseExternal(void);
/// Tells the simulator to use the internal atmosphere model.
void UseInternal(void); //this is the default
/// Gets the boolean that tells if the external atmosphere model is being used.
bool External(void) { return useExternal; }
/// Provides the external atmosphere model with an interface to set the temperature.
inline void SetExTemperature(double t) { exTemperature=t; }
/// Provides the external atmosphere model with an interface to set the density.
inline void SetExDensity(double d) { exDensity=d; }
/// Provides the external atmosphere model with an interface to set the pressure.
inline void SetExPressure(double p) { exPressure=p; }
/// Sets the temperature deviation at sea-level in degrees Fahrenheit
inline void SetSLTempDev(double d) { T_dev_sl = d; }
/// Gets the temperature deviation at sea-level in degrees Fahrenheit
inline double GetSLTempDev(void) const { return T_dev_sl; }
/// Sets the current delta-T in degrees Fahrenheit
inline void SetDeltaT(double d) { delta_T = d; }
/// Gets the current delta-T in degrees Fahrenheit
inline double GetDeltaT(void) const { return delta_T; }
/// Gets the at-altitude temperature deviation in degrees Fahrenheit
inline double GetTempDev(void) const { return T_dev; }
/// Gets the density altitude in feet
inline double GetDensityAltitude(void) const { return density_altitude; }
/// Sets the wind components in NED frame.
inline void SetWindNED(double wN, double wE, double wD) { vWindNED(1)=wN; vWindNED(2)=wE; vWindNED(3)=wD;}
/// Retrieves the wind components in NED frame.
inline FGColumnVector3& GetWindNED(void) { return vWindNED; }
/** Retrieves the wind direction. The direction is defined as north=0 and
increases counterclockwise. The wind heading is returned in radians.*/
inline double GetWindPsi(void) const { return psiw; }
inline void SetTurbGain(double tt) {TurbGain = tt;}
inline void SetTurbRate(double tt) {TurbRate = tt;}
inline double GetTurbPQR(int idx) const {return vTurbPQR(idx);}
inline FGColumnVector3& GetTurbPQR(void) {return vTurbPQR;}
void bind(void);
void unbind(void);
protected:
double rho;
enum tType {ttStandard, ttBerndt, ttNone} turbType;
int lastIndex;
double h;
double htab[8];
double SLtemperature,SLdensity,SLpressure,SLsoundspeed;
double rSLtemperature,rSLdensity,rSLpressure,rSLsoundspeed; //reciprocals
double *temperature,*density,*pressure;
double soundspeed;
bool useExternal;
double exTemperature,exDensity,exPressure;
double intTemperature, intDensity, intPressure;
double T_dev_sl, T_dev, delta_T, density_altitude;
double MagnitudedAccelDt, MagnitudeAccel, Magnitude;
double TurbGain;
double TurbRate;
FGColumnVector3 vDirectiondAccelDt;
FGColumnVector3 vDirectionAccel;
FGColumnVector3 vDirection;
FGColumnVector3 vTurbulence;
FGColumnVector3 vTurbulenceGrad;
FGColumnVector3 vBodyTurbGrad;
FGColumnVector3 vTurbPQR;
FGColumnVector3 vWindNED;
double psiw;
void Calculate(double altitude);
void Turbulence(void);
void Debug(int from);
};
} // namespace JSBSim
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#endif

View file

@ -1,420 +0,0 @@
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Module: FGAuxiliary.cpp
Author: Tony Peden, Jon Berndt
Date started: 01/26/99
Purpose: Calculates additional parameters needed by the visual system, etc.
Called by: FGSimExec
------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU 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 General Public License for more
details.
You should have received a copy of the GNU 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 General Public License can also be found on
the world wide web at http://www.gnu.org.
FUNCTIONAL DESCRIPTION
--------------------------------------------------------------------------------
This class calculates various auxiliary parameters.
REFERENCES
Anderson, John D. "Introduction to Flight", 3rd Edition, McGraw-Hill, 1989
pgs. 112-126
HISTORY
--------------------------------------------------------------------------------
01/26/99 JSB Created
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include "FGAuxiliary.h"
#include "FGAerodynamics.h"
#include "FGPropagate.h"
#include "FGAtmosphere.h"
#include "FGState.h"
#include "FGFDMExec.h"
#include "FGAircraft.h"
#include "FGInertial.h"
#include "FGPropertyManager.h"
namespace JSBSim {
static const char *IdSrc = "$Id$";
static const char *IdHdr = ID_AUXILIARY;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
FGAuxiliary::FGAuxiliary(FGFDMExec* fdmex) : FGModel(fdmex)
{
Name = "FGAuxiliary";
vcas = veas = pt = tat = 0;
psl = rhosl = 1;
earthPosAngle = 0.0;
qbar = 0;
qbarUW = 0.0;
qbarUV = 0.0;
Mach = 0.0;
alpha = beta = 0.0;
adot = bdot = 0.0;
gamma = Vt = Vground = 0.0;
psigt = 0.0;
day_of_year = 1;
seconds_in_day = 0.0;
hoverbmac = hoverbcg = 0.0;
vPilotAccel.InitMatrix();
vPilotAccelN.InitMatrix();
vToEyePt.InitMatrix();
vAeroPQR.InitMatrix();
vEulerRates.InitMatrix();
bind();
Debug(0);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGAuxiliary::~FGAuxiliary()
{
unbind();
Debug(1);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
bool FGAuxiliary::Run()
{
double A,B,D, hdot_Vt;
const FGColumnVector3& vPQR = Propagate->GetPQR();
const FGColumnVector3& vUVW = Propagate->GetUVW();
const FGColumnVector3& vUVWdot = Propagate->GetUVWdot();
const FGColumnVector3& vVel = Propagate->GetVel();
if (!FGModel::Run())
{
p = Atmosphere->GetPressure();
rhosl = Atmosphere->GetDensitySL();
psl = Atmosphere->GetPressureSL();
sat = Atmosphere->GetTemperature();
// Rotation
double cTht = Propagate->GetCosEuler(eTht);
double cPhi = Propagate->GetCosEuler(ePhi);
double sPhi = Propagate->GetSinEuler(ePhi);
vEulerRates(eTht) = vPQR(eQ)*cPhi - vPQR(eR)*sPhi;
if (cTht != 0.0) {
vEulerRates(ePsi) = (vPQR(eQ)*sPhi + vPQR(eR)*cPhi)/cTht;
vEulerRates(ePhi) = vPQR(eP) + vEulerRates(ePsi)*sPhi;
}
vAeroPQR = vPQR + Atmosphere->GetTurbPQR();
// Translation
vAeroUVW = vUVW + Propagate->GetTl2b()*Atmosphere->GetWindNED();
Vt = vAeroUVW.Magnitude();
if ( Vt > 0.05) {
if (vAeroUVW(eW) != 0.0)
alpha = vAeroUVW(eU)*vAeroUVW(eU) > 0.0 ? atan2(vAeroUVW(eW), vAeroUVW(eU)) : 0.0;
if (vAeroUVW(eV) != 0.0)
beta = vAeroUVW(eU)*vAeroUVW(eU)+vAeroUVW(eW)*vAeroUVW(eW) > 0.0 ? atan2(vAeroUVW(eV),
sqrt(vAeroUVW(eU)*vAeroUVW(eU) + vAeroUVW(eW)*vAeroUVW(eW))) : 0.0;
double mUW = (vAeroUVW(eU)*vAeroUVW(eU) + vAeroUVW(eW)*vAeroUVW(eW));
double signU=1;
if (vAeroUVW(eU) != 0.0)
signU = vAeroUVW(eU)/fabs(vAeroUVW(eU));
if ( (mUW == 0.0) || (Vt == 0.0) ) {
adot = 0.0;
bdot = 0.0;
} else {
adot = (vAeroUVW(eU)*vUVWdot(eW) - vAeroUVW(eW)*vUVWdot(eU))/mUW;
bdot = (signU*mUW*vUVWdot(eV) - vAeroUVW(eV)*(vAeroUVW(eU)*vUVWdot(eU)
+ vAeroUVW(eW)*vUVWdot(eW)))/(Vt*Vt*sqrt(mUW));
}
} else {
alpha = beta = adot = bdot = 0;
}
qbar = 0.5*Atmosphere->GetDensity()*Vt*Vt;
qbarUW = 0.5*Atmosphere->GetDensity()*(vAeroUVW(eU)*vAeroUVW(eU) + vAeroUVW(eW)*vAeroUVW(eW));
qbarUV = 0.5*Atmosphere->GetDensity()*(vAeroUVW(eU)*vAeroUVW(eU) + vAeroUVW(eV)*vAeroUVW(eV));
Mach = Vt / Atmosphere->GetSoundSpeed();
MachU = vMachUVW(eU) = vAeroUVW(eU) / Atmosphere->GetSoundSpeed();
vMachUVW(eV) = vAeroUVW(eV) / Atmosphere->GetSoundSpeed();
vMachUVW(eW) = vAeroUVW(eW) / Atmosphere->GetSoundSpeed();
// Position
Vground = sqrt( vVel(eNorth)*vVel(eNorth) + vVel(eEast)*vVel(eEast) );
if (vVel(eNorth) == 0) psigt = 0;
else psigt = atan2(vVel(eEast), vVel(eNorth));
if (psigt < 0.0) psigt += 2*M_PI;
if (Vt != 0) {
hdot_Vt = -vVel(eDown)/Vt;
if (fabs(hdot_Vt) <= 1) gamma = asin(hdot_Vt);
} else {
gamma = 0.0;
}
tat = sat*(1 + 0.2*Mach*Mach); // Total Temperature, isentropic flow
tatc = RankineToCelsius(tat);
if (MachU < 1) { // Calculate total pressure assuming isentropic flow
pt = p*pow((1 + 0.2*MachU*MachU),3.5);
} else {
// Use Rayleigh pitot tube formula for normal shock in front of pitot tube
B = 5.76*MachU*MachU/(5.6*MachU*MachU - 0.8);
D = (2.8*MachU*MachU-0.4)*0.4167;
pt = p*pow(B,3.5)*D;
}
A = pow(((pt-p)/psl+1),0.28571);
if (MachU > 0.0) {
vcas = sqrt(7*psl/rhosl*(A-1));
veas = sqrt(2*qbar/rhosl);
} else {
vcas = veas = 0.0;
}
vPilotAccel.InitMatrix();
if ( Vt > 1.0 ) {
vPilotAccel = Aerodynamics->GetForces()
+ Propulsion->GetForces()
+ GroundReactions->GetForces();
vPilotAccel /= MassBalance->GetMass();
vToEyePt = MassBalance->StructuralToBody(Aircraft->GetXYZep());
vPilotAccel += Propagate->GetPQRdot() * vToEyePt;
vPilotAccel += vPQR * (vPQR * vToEyePt);
} else {
vPilotAccel = Propagate->GetTl2b() * FGColumnVector3( 0.0, 0.0, Inertial->gravity() );
}
vPilotAccelN = vPilotAccel/Inertial->gravity();
earthPosAngle += State->Getdt()*Inertial->omega();
// VRP computation
const FGLocation& vLocation = Propagate->GetLocation();
FGColumnVector3 vrpStructural = Aircraft->GetXYZvrp();
FGColumnVector3 vrpBody = MassBalance->StructuralToBody( vrpStructural );
FGColumnVector3 vrpLocal = Propagate->GetTb2l() * vrpBody;
vLocationVRP = vLocation.LocalToLocation( vrpLocal );
// Recompute some derived values now that we know the dependent parameters values ...
hoverbcg = Propagate->GetDistanceAGL() / Aircraft->GetWingSpan();
FGColumnVector3 vMac = Propagate->GetTb2l()*MassBalance->StructuralToBody(Aircraft->GetXYZrp());
hoverbmac = (Propagate->GetDistanceAGL() + vMac(3)) / Aircraft->GetWingSpan();
return false;
} else {
return true;
}
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
double FGAuxiliary::GetHeadWind(void)
{
double psiw,vw;
psiw = Atmosphere->GetWindPsi();
vw = Atmosphere->GetWindNED().Magnitude();
return vw*cos(psiw - Propagate->GetEuler(ePsi));
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
double FGAuxiliary::GetCrossWind(void)
{
double psiw,vw;
psiw = Atmosphere->GetWindPsi();
vw = Atmosphere->GetWindNED().Magnitude();
return vw*sin(psiw - Propagate->GetEuler(ePsi));
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGAuxiliary::bind(void)
{
typedef double (FGAuxiliary::*PMF)(int) const;
typedef double (FGAuxiliary::*PF)(void) const;
PropertyManager->Tie("velocities/vc-fps", this, &FGAuxiliary::GetVcalibratedFPS);
PropertyManager->Tie("velocities/vc-kts", this, &FGAuxiliary::GetVcalibratedKTS);
PropertyManager->Tie("velocities/ve-fps", this, &FGAuxiliary::GetVequivalentFPS);
PropertyManager->Tie("velocities/ve-kts", this, &FGAuxiliary::GetVequivalentKTS);
PropertyManager->Tie("velocities/machU", this, &FGAuxiliary::GetMachU);
PropertyManager->Tie("velocities/tat-r", this, &FGAuxiliary::GetTotalTemperature);
PropertyManager->Tie("velocities/tat-c", this, &FGAuxiliary::GetTAT_C);
PropertyManager->Tie("velocities/pt-lbs_sqft", this, &FGAuxiliary::GetTotalPressure);
PropertyManager->Tie("velocities/p-aero-rad_sec", this, eX, (PMF)&FGAuxiliary::GetAeroPQR);
PropertyManager->Tie("velocities/q-aero-rad_sec", this, eY, (PMF)&FGAuxiliary::GetAeroPQR);
PropertyManager->Tie("velocities/r-aero-rad_sec", this, eZ, (PMF)&FGAuxiliary::GetAeroPQR);
PropertyManager->Tie("velocities/phidot-rad_sec", this, ePhi, (PMF)&FGAuxiliary::GetEulerRates);
PropertyManager->Tie("velocities/thetadot-rad_sec", this, eTht, (PMF)&FGAuxiliary::GetEulerRates);
PropertyManager->Tie("velocities/psidot-rad_sec", this, ePsi, (PMF)&FGAuxiliary::GetEulerRates);
PropertyManager->Tie("velocities/u-aero-fps", this, eU, (PMF)&FGAuxiliary::GetAeroUVW);
PropertyManager->Tie("velocities/v-aero-fps", this, eV, (PMF)&FGAuxiliary::GetAeroUVW);
PropertyManager->Tie("velocities/w-aero-fps", this, eW, (PMF)&FGAuxiliary::GetAeroUVW);
PropertyManager->Tie("velocities/vt-fps", this, &FGAuxiliary::GetVt, &FGAuxiliary::SetVt, true);
PropertyManager->Tie("velocities/mach-norm", this, &FGAuxiliary::GetMach, &FGAuxiliary::SetMach, true);
PropertyManager->Tie("velocities/vg-fps", this, &FGAuxiliary::GetVground);
PropertyManager->Tie("accelerations/a-pilot-x-ft_sec2", this, eX, (PMF)&FGAuxiliary::GetPilotAccel);
PropertyManager->Tie("accelerations/a-pilot-y-ft_sec2", this, eY, (PMF)&FGAuxiliary::GetPilotAccel);
PropertyManager->Tie("accelerations/a-pilot-z-ft_sec2", this, eZ, (PMF)&FGAuxiliary::GetPilotAccel);
PropertyManager->Tie("accelerations/n-pilot-x-norm", this, eX, (PMF)&FGAuxiliary::GetNpilot);
PropertyManager->Tie("accelerations/n-pilot-y-norm", this, eY, (PMF)&FGAuxiliary::GetNpilot);
PropertyManager->Tie("accelerations/n-pilot-z-norm", this, eZ, (PMF)&FGAuxiliary::GetNpilot);
PropertyManager->Tie("position/epa-rad", this, &FGAuxiliary::GetEarthPositionAngle);
/* PropertyManager->Tie("atmosphere/headwind-fps", this, &FGAuxiliary::GetHeadWind, true);
PropertyManager->Tie("atmosphere/crosswind-fps", this, &FGAuxiliary::GetCrossWind, true); */
PropertyManager->Tie("aero/alpha-rad", this, (PF)&FGAuxiliary::Getalpha, &FGAuxiliary::Setalpha, true);
PropertyManager->Tie("aero/beta-rad", this, (PF)&FGAuxiliary::Getbeta, &FGAuxiliary::Setbeta, true);
PropertyManager->Tie("aero/mag-beta-rad", this, (PF)&FGAuxiliary::GetMagBeta);
PropertyManager->Tie("aero/alpha-deg", this, inDegrees, (PMF)&FGAuxiliary::Getalpha);
PropertyManager->Tie("aero/beta-deg", this, inDegrees, (PMF)&FGAuxiliary::Getbeta);
PropertyManager->Tie("aero/mag-beta-deg", this, inDegrees, (PMF)&FGAuxiliary::GetMagBeta);
PropertyManager->Tie("aero/qbar-psf", this, &FGAuxiliary::Getqbar, &FGAuxiliary::Setqbar, true);
PropertyManager->Tie("aero/qbarUW-psf", this, &FGAuxiliary::GetqbarUW, &FGAuxiliary::SetqbarUW, true);
PropertyManager->Tie("aero/qbarUV-psf", this, &FGAuxiliary::GetqbarUV, &FGAuxiliary::SetqbarUV, true);
PropertyManager->Tie("aero/alphadot-rad_sec", this, (PF)&FGAuxiliary::Getadot, &FGAuxiliary::Setadot, true);
PropertyManager->Tie("aero/betadot-rad_sec", this, (PF)&FGAuxiliary::Getbdot, &FGAuxiliary::Setbdot, true);
PropertyManager->Tie("aero/alphadot-deg_sec", this, inDegrees, (PMF)&FGAuxiliary::Getadot);
PropertyManager->Tie("aero/betadot-deg_sec", this, inDegrees, (PMF)&FGAuxiliary::Getbdot);
PropertyManager->Tie("aero/h_b-cg-ft", this, &FGAuxiliary::GetHOverBCG);
PropertyManager->Tie("aero/h_b-mac-ft", this, &FGAuxiliary::GetHOverBMAC);
PropertyManager->Tie("flight-path/gamma-rad", this, &FGAuxiliary::GetGamma, &FGAuxiliary::SetGamma);
PropertyManager->Tie("flight-path/psi-gt-rad", this, &FGAuxiliary::GetGroundTrack);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGAuxiliary::unbind(void)
{
PropertyManager->Untie("velocities/vc-fps");
PropertyManager->Untie("velocities/vc-kts");
PropertyManager->Untie("velocities/ve-fps");
PropertyManager->Untie("velocities/ve-kts");
PropertyManager->Untie("velocities/machU");
PropertyManager->Untie("velocities/tat-r");
PropertyManager->Untie("velocities/tat-c");
PropertyManager->Untie("velocities/p-aero-rad_sec");
PropertyManager->Untie("velocities/q-aero-rad_sec");
PropertyManager->Untie("velocities/r-aero-rad_sec");
PropertyManager->Untie("velocities/pt-lbs_sqft");
PropertyManager->Untie("velocities/phidot-rad_sec");
PropertyManager->Untie("velocities/thetadot-rad_sec");
PropertyManager->Untie("velocities/psidot-rad_sec");
PropertyManager->Untie("velocities/u-aero-fps");
PropertyManager->Untie("velocities/v-aero-fps");
PropertyManager->Untie("velocities/w-aero-fps");
PropertyManager->Untie("velocities/vt-fps");
PropertyManager->Untie("velocities/mach-norm");
PropertyManager->Untie("velocities/vg-fps");
PropertyManager->Untie("accelerations/a-pilot-x-ft_sec2");
PropertyManager->Untie("accelerations/a-pilot-y-ft_sec2");
PropertyManager->Untie("accelerations/a-pilot-z-ft_sec2");
PropertyManager->Untie("accelerations/n-pilot-x-norm");
PropertyManager->Untie("accelerations/n-pilot-y-norm");
PropertyManager->Untie("accelerations/n-pilot-z-norm");
PropertyManager->Untie("position/epa-rad");
/* PropertyManager->Untie("atmosphere/headwind-fps");
PropertyManager->Untie("atmosphere/crosswind-fps"); */
PropertyManager->Untie("aero/qbar-psf");
PropertyManager->Untie("aero/qbarUW-psf");
PropertyManager->Untie("aero/qbarUV-psf");
PropertyManager->Untie("aero/alpha-rad");
PropertyManager->Untie("aero/beta-rad");
PropertyManager->Untie("aero/alpha-deg");
PropertyManager->Untie("aero/beta-deg");
PropertyManager->Untie("aero/alphadot-rad_sec");
PropertyManager->Untie("aero/betadot-rad_sec");
PropertyManager->Untie("aero/mag-beta-rad");
PropertyManager->Untie("aero/alphadot-deg_sec");
PropertyManager->Untie("aero/betadot-deg_sec");
PropertyManager->Untie("aero/mag-beta-deg");
PropertyManager->Untie("aero/h_b-cg-ft");
PropertyManager->Untie("aero/h_b-mac-ft");
PropertyManager->Untie("flight-path/gamma-rad");
PropertyManager->Untie("flight-path/psi-gt-rad");
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// The bitmasked value choices are as follows:
// unset: In this case (the default) JSBSim would only print
// out the normally expected messages, essentially echoing
// the config files as they are read. If the environment
// variable is not set, debug_lvl is set to 1 internally
// 0: This requests JSBSim not to output any messages
// whatsoever.
// 1: This value explicity requests the normal JSBSim
// startup messages
// 2: This value asks for a message to be printed out when
// a class is instantiated
// 4: When this value is set, a message is displayed when a
// FGModel object executes its Run() method
// 8: When this value is set, various runtime state variables
// are printed out periodically
// 16: When set various parameters are sanity checked and
// a message is printed out when they go out of bounds
void FGAuxiliary::Debug(int from)
{
if (debug_lvl <= 0) return;
if (debug_lvl & 1) { // Standard console startup message output
if (from == 0) { // Constructor
}
}
if (debug_lvl & 2 ) { // Instantiation/Destruction notification
if (from == 0) cout << "Instantiated: FGAuxiliary" << endl;
if (from == 1) cout << "Destroyed: FGAuxiliary" << endl;
}
if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
}
if (debug_lvl & 8 ) { // Runtime state variables
}
if (debug_lvl & 16) { // Sanity checking
if (Mach > 100 || Mach < 0.00)
cout << "FGPropagate::Mach is out of bounds: " << Mach << endl;
if (qbar > 1e6 || qbar < 0.00)
cout << "FGPropagate::qbar is out of bounds: " << qbar << endl;
}
if (debug_lvl & 64) {
if (from == 0) { // Constructor
cout << IdSrc << endl;
cout << IdHdr << endl;
}
}
}
} // namespace JSBSim

View file

@ -1,245 +0,0 @@
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Header: FGAuxiliary.h
Author: Jon Berndt
Date started: 01/26/99
------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU 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 General Public License for more
details.
You should have received a copy of the GNU 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 General Public License can also be found on
the world wide web at http://www.gnu.org.
HISTORY
--------------------------------------------------------------------------------
11/22/98 JSB Created
1/1/00 TP Added calcs and getters for VTAS, VCAS, VEAS, Vground, in knots
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
SENTRY
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#ifndef FGAUXILIARY_H
#define FGAUXILIARY_H
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include "FGModel.h"
#include "FGColumnVector3.h"
#include "FGLocation.h"
#include "FGPropagate.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_AUXILIARY "$Id$"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
namespace JSBSim {
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DOCUMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/** Encapsulates various uncategorized scheduled functions.
Pilot sensed accelerations are calculated here. This is used
for the coordinated turn ball instrument. Motion base platforms sometimes
use the derivative of pilot sensed accelerations as the driving parameter,
rather than straight accelerations.
The theory behind pilot-sensed calculations is presented:
For purposes of discussion and calculation, assume for a minute that the
pilot is in space and motionless in inertial space. She will feel
no accelerations. If the aircraft begins to accelerate along any axis or
axes (without rotating), the pilot will sense those accelerations. If
any rotational moment is applied, the pilot will sense an acceleration
due to that motion in the amount:
[wdot X R] + [w X (w X R)]
Term I Term II
where:
wdot = omegadot, the rotational acceleration rate vector
w = omega, the rotational rate vector
R = the vector from the aircraft CG to the pilot eyepoint
The sum total of these two terms plus the acceleration of the aircraft
body axis gives the acceleration the pilot senses in inertial space.
In the presence of a large body such as a planet, a gravity field also
provides an accelerating attraction. This acceleration can be transformed
from the reference frame of the planet so as to be expressed in the frame
of reference of the aircraft. This gravity field accelerating attraction
is felt by the pilot as a force on her tushie as she sits in her aircraft
on the runway awaiting takeoff clearance.
In JSBSim the acceleration of the body frame in inertial space is given
by the F = ma relation. If the vForces vector is divided by the aircraft
mass, the acceleration vector is calculated. The term wdot is equivalent
to the JSBSim vPQRdot vector, and the w parameter is equivalent to vPQR.
The radius R is calculated below in the vector vToEyePt.
@author Tony Peden, Jon Berndt
@version $Id$
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DECLARATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
class FGAuxiliary : public FGModel {
public:
/** Constructor
@param Executive a pointer to the parent executive object */
FGAuxiliary(FGFDMExec* Executive);
/// Destructor
~FGAuxiliary();
/** Runs the Auxiliary routines; called by the Executive
@return false if no error */
bool Run(void);
// GET functions
// Atmospheric parameters GET functions
double GetVcalibratedFPS(void) const { return vcas; }
double GetVcalibratedKTS(void) const { return vcas*fpstokts; }
double GetVequivalentFPS(void) const { return veas; }
double GetVequivalentKTS(void) const { return veas*fpstokts; }
// total pressure above is freestream total pressure for subsonic only
// for supersonic it is the 1D total pressure behind a normal shock
double GetTotalPressure(void) const { return pt; }
double GetTotalTemperature(void) const { return tat; }
double GetTAT_C(void) const { return tatc; }
double GetPilotAccel(int idx) const { return vPilotAccel(idx); }
double GetNpilot(int idx) const { return vPilotAccelN(idx); }
double GetAeroPQR(int axis) const { return vAeroPQR(axis); }
double GetEulerRates(int axis) const { return vEulerRates(axis); }
const FGColumnVector3& GetPilotAccel (void) const { return vPilotAccel; }
const FGColumnVector3& GetNpilot (void) const { return vPilotAccelN; }
const FGColumnVector3& GetAeroPQR (void) const { return vAeroPQR; }
const FGColumnVector3& GetEulerRates (void) const { return vEulerRates; }
const FGColumnVector3& GetAeroUVW (void) const { return vAeroUVW; }
const FGLocation& GetLocationVRP(void) const { return vLocationVRP; }
double GethVRP(void) const { return vLocationVRP.GetRadius() - Propagate->GetSeaLevelRadius(); }
double GetAeroUVW (int idx) const { return vAeroUVW(idx); }
double Getalpha (void) const { return alpha; }
double Getbeta (void) const { return beta; }
double Getadot (void) const { return adot; }
double Getbdot (void) const { return bdot; }
double GetMagBeta (void) const { return fabs(beta); }
double Getalpha (int unit) const { if (unit == inDegrees) return alpha*radtodeg;
else cerr << "Bad units" << endl; return 0.0;}
double Getbeta (int unit) const { if (unit == inDegrees) return beta*radtodeg;
else cerr << "Bad units" << endl; return 0.0;}
double Getadot (int unit) const { if (unit == inDegrees) return adot*radtodeg;
else cerr << "Bad units" << endl; return 0.0;}
double Getbdot (int unit) const { if (unit == inDegrees) return bdot*radtodeg;
else cerr << "Bad units" << endl; return 0.0;}
double GetMagBeta (int unit) const { if (unit == inDegrees) return fabs(beta)*radtodeg;
else cerr << "Bad units" << endl; return 0.0;}
double Getqbar (void) const { return qbar; }
double GetqbarUW (void) const { return qbarUW; }
double GetqbarUV (void) const { return qbarUV; }
double GetVt (void) const { return Vt; }
double GetVground (void) const { return Vground; }
double GetMach (void) const { return Mach; }
double GetMachU (void) const { return MachU; }
double GetHOverBCG(void) const { return hoverbcg; }
double GetHOverBMAC(void) const { return hoverbmac; }
double GetGamma(void) const { return gamma; }
double GetGroundTrack(void) const { return psigt; }
double GetEarthPositionAngle(void) const { return earthPosAngle; }
double GetHeadWind(void);
double GetCrossWind(void);
// SET functions
void SetAeroUVW(FGColumnVector3 tt) { vAeroUVW = tt; }
void Setalpha (double tt) { alpha = tt; }
void Setbeta (double tt) { beta = tt; }
void Setqbar (double tt) { qbar = tt; }
void SetqbarUW (double tt) { qbarUW = tt; }
void SetqbarUV (double tt) { qbarUV = tt; }
void SetVt (double tt) { Vt = tt; }
void SetMach (double tt) { Mach=tt; }
void Setadot (double tt) { adot = tt; }
void Setbdot (double tt) { bdot = tt; }
void SetAB (double t1, double t2) { alpha=t1; beta=t2; }
void SetGamma (double tt) { gamma = tt; }
// Time routines, SET and GET functions
void SetDayOfYear (int doy) { day_of_year = doy; }
void SetSecondsInDay (double sid) { seconds_in_day = sid; }
int GetDayOfYear (void) const { return day_of_year; }
double GetSecondsInDay (void) const { return seconds_in_day; }
void bind(void);
void unbind(void);
private:
double vcas, veas;
double rhosl, rho, p, psl, pt, tat, sat, tatc; // Don't add a getter for pt!
FGColumnVector3 vPilotAccel;
FGColumnVector3 vPilotAccelN;
FGColumnVector3 vToEyePt;
FGColumnVector3 vAeroPQR;
FGColumnVector3 vAeroUVW;
FGColumnVector3 vEuler;
FGColumnVector3 vEulerRates;
FGColumnVector3 vMachUVW;
FGLocation vLocationVRP;
double Vt, Vground, Mach, MachU;
double qbar, qbarUW, qbarUV;
double alpha, beta;
double adot,bdot;
double psigt, gamma;
double seconds_in_day; // seconds since current GMT day began
int day_of_year; // GMT day, 1 .. 366
double earthPosAngle;
double hoverbcg, hoverbmac;
void Debug(int from);
};
} // namespace JSBSim
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#endif

View file

@ -1,522 +0,0 @@
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Module: FGCoefficient.cpp
Author: Jon S. Berndt
Date started: 12/28/98
Purpose: Encapsulates the stability derivative class FGCoefficient;
Called by: FGAircraft
------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU 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 General Public License for more
details.
You should have received a copy of the GNU 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 General Public License can also be found on
the world wide web at http://www.gnu.org.
FUNCTIONAL DESCRIPTION
--------------------------------------------------------------------------------
This class models the stability derivative coefficient lookup tables or
equations. Note that the coefficients need not be calculated each delta-t.
Note that the values in a row which index into the table must be the same value
for each column of data, so the first column of numbers for each altitude are
seen to be equal, and there are the same number of values for each altitude.
See the header file FGCoefficient.h for the values of the identifiers.
HISTORY
--------------------------------------------------------------------------------
12/28/98 JSB Created
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdio.h>
#include "FGCoefficient.h"
#include "FGState.h"
#include "FGFDMExec.h"
#include "FGPropertyManager.h"
#ifndef FGFS
# if defined(sgi) && !defined(__GNUC__) && (_COMPILER_VERSION < 740)
# include <iomanip.h>
# else
# include <iomanip>
# endif
#else
# include STL_IOMANIP
#endif
namespace JSBSim {
static const char *IdSrc = "$Id$";
static const char *IdHdr = ID_COEFFICIENT;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
FGCoefficient::FGCoefficient( FGFDMExec* fdex )
{
FDMExec = fdex;
State = FDMExec->GetState();
Table = 0;
IsFactor = false;
PropertyManager = FDMExec->GetPropertyManager();
Table = (FGTable*)0L;
LookupR = LookupC = 0;
numInstances = 0;
rows = columns = tables = 0;
StaticValue = 0.0;
totalValue = 0.0;
bias = 0.0;
gain = 1.0;
SD = 0.0;
filename.erase();
description.erase();
name.erase();
method.erase();
multparms.erase();
multparmsRow.erase();
multparmsCol.erase();
Debug(0);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGCoefficient::~FGCoefficient()
{
if (Table) delete Table;
Debug(1);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
bool FGCoefficient::Load(FGConfigFile *AC_cfg)
{
int start, end, n;
string mult;
if (AC_cfg) {
name = AC_cfg->GetValue("NAME");
method = AC_cfg->GetValue("TYPE");
AC_cfg->GetNextConfigLine();
*AC_cfg >> description;
if (method == "EQUATION") type = EQUATION;
else if (method == "TABLE") type = TABLE;
else if (method == "TABLE3D") type = TABLE3D;
else if (method == "VECTOR") type = VECTOR;
else if (method == "VALUE") type = VALUE;
else type = UNKNOWN;
if (type == VECTOR || type == TABLE || type == TABLE3D) {
if (type == TABLE3D) {
*AC_cfg >> rows >> columns >> tables;
Table = new FGTable(rows, columns, tables);
*AC_cfg >> multparmsRow >> multparmsCol >> multparmsTable;
LookupR = PropertyManager->GetNode( multparmsRow );
LookupC = PropertyManager->GetNode( multparmsCol );
LookupT = PropertyManager->GetNode( multparmsTable );
} else if (type == TABLE) {
*AC_cfg >> rows >> columns;
Table = new FGTable(rows, columns);
*AC_cfg >> multparmsRow >> multparmsCol;
LookupR = PropertyManager->GetNode( multparmsRow );
LookupC = PropertyManager->GetNode( multparmsCol );
} else {
*AC_cfg >> rows;
Table = new FGTable(rows);
*AC_cfg >> multparmsRow;
LookupR = PropertyManager->GetNode( multparmsRow );
}
}
// Here, read in the line of the form:
// {property1} | {property2} | {property3}
// where each non-dimensionalizing property for this coefficient is
// separated by a | character
string line=AC_cfg->GetCurrentLine();
unsigned j=0;
char tmp[255];
for(unsigned i=0;i<line.length(); i++ ) {
if( !isspace(line[i]) ) {
tmp[j]=line[i];
j++;
}
}
tmp[j]='\0'; multparms=tmp;
end = multparms.length();
n = multparms.find("|");
if (n == string::npos) n = end;
start = 0;
if (multparms != string("none")) {
while (n < end && n != string::npos) {
n -= start;
mult = multparms.substr(start,n);
multipliers.push_back( resolveSymbol( mult ) );
start += n+1;
n = multparms.find("|",start);
}
mult = multparms.substr(start,n);
multipliers.push_back( resolveSymbol( mult ) );
// End of non-dimensionalizing parameter read-in
}
AC_cfg->GetNextConfigLine();
if (type == VALUE) {
*AC_cfg >> StaticValue;
} else if (type == VECTOR || type == TABLE || type == TABLE3D) {
*Table << *AC_cfg;
} else {
cerr << "Unimplemented coefficient type: " << type << endl;
}
AC_cfg->GetNextConfigLine();
FGCoefficient::Debug(2);
return true;
} else {
return false;
}
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
double FGCoefficient::Value(double rVal, double cVal, double tVal)
{
double Value;
unsigned int midx;
SD = Value = gain*Table->GetValue(rVal, cVal, tVal) + bias;
for (midx=0; midx < multipliers.size(); midx++) {
Value *= multipliers[midx]->getDoubleValue();
}
return Value;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
double FGCoefficient::Value(double rVal, double cVal)
{
double Value;
unsigned int midx;
SD = Value = gain*Table->GetValue(rVal, cVal) + bias;
for (midx=0; midx < multipliers.size(); midx++) {
Value *= multipliers[midx]->getDoubleValue();
}
return Value;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
double FGCoefficient::Value(double Val)
{
double Value;
SD = Value = gain*Table->GetValue(Val) + bias;
for (unsigned int midx=0; midx < multipliers.size(); midx++)
Value *= multipliers[midx]->getDoubleValue();
return Value;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
double FGCoefficient::Value(void)
{
double Value;
SD = Value = gain*StaticValue + bias;
for (unsigned int midx=0; midx < multipliers.size(); midx++)
Value *= multipliers[midx]->getDoubleValue();
return Value;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
double FGCoefficient::TotalValue(void)
{
switch(type) {
case UNKNOWN:
totalValue = -1;
break;
case VALUE:
totalValue = Value();
break;
case VECTOR:
totalValue = Value( LookupR->getDoubleValue() );
break;
case TABLE:
totalValue = Value( LookupR->getDoubleValue(),
LookupC->getDoubleValue() );
break;
case TABLE3D:
totalValue = Value( LookupR->getDoubleValue(),
LookupC->getDoubleValue(),
LookupT->getDoubleValue() );
break;
case EQUATION:
totalValue = 0.0;
break;
}
return totalValue;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGCoefficient::DisplayCoeffFactors(void)
{
unsigned int i;
cout << " Non-Dimensionalized by: ";
if (multipliers.size() == 0) {
cout << "none" << endl;
} else {
for (i=0; i<multipliers.size(); i++)
cout << multipliers[i]->getName() << " ";
}
cout << endl;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
string FGCoefficient::GetSDstring(void)
{
char buffer[20];
string value;
sprintf(buffer,"%9.6f",SD);
value = string(buffer);
return value;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGCoefficient::bind(FGPropertyManager *parent)
{
string mult;
unsigned i;
node = parent->GetNode(name,true);
node->SetString("description",description);
if (LookupR) node->SetString("row-parm",LookupR->getName() );
if (LookupC) node->SetString("column-parm",LookupC->getName() );
mult="";
if (multipliers.size() == 0)
mult="none";
for (i=0; i<multipliers.size(); i++) {
mult += multipliers[i]->getName();
if ( i < multipliers.size()-1 ) mult += " ";
}
node->SetString("multipliers",mult);
node->Tie("SD-norm",this,&FGCoefficient::GetSD );
node->Tie("value-lbs",this,&FGCoefficient::GetValue );
node->Tie("bias", this, &FGCoefficient::getBias,
&FGCoefficient::setBias );
node->Tie("gain", this, &FGCoefficient::getGain,
&FGCoefficient::setGain );
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGCoefficient::unbind(void)
{
node->Untie("SD-norm");
node->Untie("value-lbs");
node->Untie("bias");
node->Untie("gain");
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGPropertyManager* FGCoefficient::resolveSymbol(string name)
{
FGPropertyManager* tmpn;
tmpn = PropertyManager->GetNode(name,false);
if ( !tmpn ) {
cerr << "Coefficient multipliers cannot create properties, check spelling?" << endl;
exit(1);
}
return tmpn;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGCoefficient::convert(string prop)
{
if (IsFactor)
cout << " <function name=\"aero/function/" << name << "\">" << endl;
else
cout << " <function name=\"aero/coefficient/" << name << "\">" << endl;
cout << " <description>" << description << "</description>" << endl;
cout << " <product>" << endl;
for (int i=0; i<multipliers.size(); i++)
cout << " <property>" << (multipliers[i]->GetFullyQualifiedName()).substr(12) << "</property>" << endl;
if (!prop.empty())
cout << " <property>aero/function/" << prop << "</property>" << endl;
switch (type) {
case VALUE:
cout << " <value>" << StaticValue << "</value>" << endl;
break;
case VECTOR:
cout << " <table>" << endl;
cout << " <independentVar>" << (LookupR->GetFullyQualifiedName()).substr(12) << "</independentVar>" << endl;
cout << " <tableData>" << endl;
Table->Print(30);
cout << " </tableData>" << endl;
cout << " </table>" << endl;
break;
case TABLE:
cout << " <table>" << endl;
cout << " <independentVar lookup=\"row\">" << (LookupR->GetFullyQualifiedName()).substr(12) << "</independentVar>" << endl;
cout << " <independentVar lookup=\"column\">" << (LookupC->GetFullyQualifiedName()).substr(12) << "</independentVar>" << endl;
cout << " <tableData>" << endl;
Table->Print(30);
cout << " </tableData>" << endl;
cout << " </table>" << endl;
break;
case TABLE3D:
cout << " <table>" << endl;
cout << " <independentVar lookup=\"row\">" << (LookupR->GetFullyQualifiedName()).substr(12) << "</independentVar>" << endl;
cout << " <independentVar lookup=\"column\">" << (LookupC->GetFullyQualifiedName()).substr(12) << "</independentVar>" << endl;
cout << " <independentVar lookup=\"table\">" << (LookupT->GetFullyQualifiedName()).substr(12) << "</independentVar>" << endl;
cout << " <tableData>" << endl;
Table->Print(30);
cout << " </tableData>" << endl;
cout << " </table>" << endl;
break;
}
cout << " </product>" << endl;
cout << " </function>" << endl;
if (IsFactor) {
cout << " === MOVE THE ABOVE FACTOR " << name << " OUTSIDE OF AND BEFORE ANY <AXIS> DEFINITION ===" << endl;
for (int i=0; i<sum.size(); i++) {
sum[i]->convert(name);
}
}
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// The bitmasked value choices are as follows:
// unset: In this case (the default) JSBSim would only print
// out the normally expected messages, essentially echoing
// the config files as they are read. If the environment
// variable is not set, debug_lvl is set to 1 internally
// 0: This requests JSBSim not to output any messages
// whatsoever.
// 1: This value explicity requests the normal JSBSim
// startup messages
// 2: This value asks for a message to be printed out when
// a class is instantiated
// 4: When this value is set, a message is displayed when a
// FGModel object executes its Run() method
// 8: When this value is set, various runtime state variables
// are printed out periodically
// 16: When set various parameters are sanity checked and
// a message is printed out when they go out of bounds
void FGCoefficient::Debug(int from)
{
if (debug_lvl <= 0) return;
if (debug_lvl & 1) { // Standard console startup message output
if (from == 2) { // Loading
cout << "\n " << highint << underon << name << underoff << normint << endl;
cout << " " << description << endl;
cout << " " << method << endl;
if (type == VECTOR || type == TABLE || type == TABLE3D) {
cout << " Rows: " << rows << " indexed by: " << LookupR->getName() << endl;
if (type == TABLE || type == TABLE3D) {
cout << " Cols: " << columns << " indexed by: " << LookupC->getName() << endl;
if (type == TABLE3D) {
cout << " Tables: " << tables << " indexed by: " << LookupT->getName() << endl;
}
}
Table->Print();
} else if (type == VALUE) {
cout << " Value = " << StaticValue << endl;
}
DisplayCoeffFactors();
}
}
if (debug_lvl & 2 ) { // Instantiation/Destruction notification
if (from == 0) cout << "Instantiated: FGCoefficient" << endl;
if (from == 1) cout << "Destroyed: FGCoefficient" << endl;
}
if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
}
if (debug_lvl & 8 ) { // Runtime state variables
}
if (debug_lvl & 16) { // Sanity checking
}
if (debug_lvl & 64) {
if (from == 0) { // Constructor
cout << IdSrc << endl;
cout << IdHdr << endl;
}
}
}
} // namespace JSBSim

View file

@ -1,206 +0,0 @@
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Header: FGCoefficient.h
Author: Jon Berndt
Date started: 12/28/98
------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU 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 General Public License for more
details.
You should have received a copy of the GNU 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 General Public License can also be found on
the world wide web at http://www.gnu.org.
HISTORY
--------------------------------------------------------------------------------
12/28/98 JSB Created
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
SENTRY
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#ifndef FGCOEFFICIENT_H
#define FGCOEFFICIENT_H
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#ifdef FGFS
# include <simgear/compiler.h>
#endif
#include <vector>
#include <string>
#include "FGConfigFile.h"
#include "FGTable.h"
#include "FGJSBBase.h"
#include "FGPropertyManager.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_COEFFICIENT "$Id$"
using std::vector;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
namespace JSBSim {
class FGFDMExec;
class FGState;
class FGAtmosphere;
class FGFCS;
class FGAircraft;
class FGPropagate;
class FGAuxiliary;
class FGOutput;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DOCUMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/** This class models the aero coefficient and stability derivative coefficient
lookup table, value, vector, or equation (equation not modeled, yet).
Each coefficient for an axis is stored in that axes' vector of coefficients.
Each FDM execution frame the Run() method of the FGAerodynamics model
is called and the coefficient values are calculated.
@author Jon S. Berndt
@version $Id$
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DECLARATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
class FGCoefficient : public FGJSBBase
{
public:
/** Constructor.
@param exec a pointer to the FGFDMExec instance. */
FGCoefficient(FGFDMExec* exec);
/// Destructor.
virtual ~FGCoefficient();
/** Loads the stability derivative/aero coefficient data from the config file
as directed by the FGAerodynamics instance.
@param AC_cfg a pointer to the current config file instance. */
virtual bool Load(FGConfigFile* AC_cfg);
typedef vector <FGPropertyManager*> MultVec;
enum Type {UNKNOWN, VALUE, VECTOR, TABLE, TABLE3D, EQUATION};
/** Returns the value for this coefficient.
Each instance of FGCoefficient stores a value for the "type" of coefficient
it is, one of: VALUE, VECTOR, TABLE, or EQUATION. This TotalValue function
is called when the value for a coefficient needs to be known. When it is called,
depending on what type of coefficient is represented by the FGCoefficient
instance, TotalValue() directs the appropriate Value() function to be called.
The type of coefficient represented is determined when the config file is read.
The coefficient definition includes the "type" specifier.
@return the current value of the coefficient represented by this instance of
FGCoefficient. */
virtual double TotalValue(void);
/** Returns the value for this coefficient.
TotalValue is stored each time TotalValue() is called. This function returns
the stored value but does not calculate it anew. This is valuable for merely
printing out the value.
@return the most recently calculated and stored value of the coefficient
represented by this instance of FGCoefficient. */
virtual inline double GetValue(void) const { return totalValue; }
/// Returns the name of this coefficient.
virtual inline string Getname(void) const {return name;}
/// Returns the value of the coefficient only - before it is re-dimensionalized.
virtual inline double GetSD(void) const { return SD;}
/** Outputs coefficient information.
Non-dimensionalizing parameter descriptions are output
for each aero coefficient defined. */
virtual void DisplayCoeffFactors(void);
/// Returns the name of the coefficient.
virtual inline string GetCoefficientName(void) { return name; }
/// Returns the stability derivative or coefficient value as a string.
virtual string GetSDstring(void);
inline void setBias(double b) { bias=b; }
inline void setGain(double g) { gain=g; };
inline double getBias(void) const { return bias; }
inline double getGain(void) const { return gain; }
virtual void bind(FGPropertyManager *parent);
virtual void unbind(void);
void convert(string prop="");
protected:
FGFDMExec* FDMExec;
bool IsFactor;
typedef vector<FGCoefficient*> CoeffArray;
CoeffArray sum;
private:
int numInstances;
string description;
string name;
string filename;
string method;
string multparms;
string multparmsRow;
string multparmsCol;
string multparmsTable;
double Value(double, double, double);
double Value(double, double);
double Value(double);
double Value(void);
double StaticValue;
double totalValue;
double bias,gain;
FGPropertyManager *LookupR, *LookupC, *LookupT;
FGPropertyManager *node; // must be private!!
MultVec multipliers;
int rows, columns, tables;
Type type;
double SD; // Actual stability derivative (or other coefficient) value
FGTable *Table;
FGState* State;
FGAtmosphere* Atmosphere;
FGFCS* FCS;
FGAircraft* Aircraft;
FGPropagate* Propagate;
FGAuxiliary* Auxiliary;
FGOutput* Output;
FGPropertyManager* PropertyManager;
FGPropertyManager* resolveSymbol(string name);
virtual void Debug(int from);
};
} // using namespace JSBSim
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#endif

View file

@ -1,159 +0,0 @@
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Module: FGColumnVector3.cpp
Author: Originally by Tony Peden [formatted here (and broken??) by JSB]
Date started: 1998
Purpose: FGColumnVector3 class
Called by: Various
FUNCTIONAL DESCRIPTION
--------------------------------------------------------------------------------
HISTORY
--------------------------------------------------------------------------------
??/??/?? TP Created
03/16/2000 JSB Added exception throwing
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "FGColumnVector3.h"
#include <cstdio>
namespace JSBSim {
static const char *IdSrc = "$Id$";
static const char *IdHdr = ID_COLUMNVECTOR3;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
FGColumnVector3::FGColumnVector3(void)
{
data[0] = data[1] = data[2] = 0.0;
Debug(0);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
string FGColumnVector3::Dump(string delimeter) const
{
char buffer[256];
sprintf(buffer, "%f%s%f%s%f", Entry(1), delimeter.c_str(), Entry(2), delimeter.c_str(), Entry(3));
return string(buffer);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGColumnVector3 FGColumnVector3::operator/(const double scalar) const
{
if (scalar != 0.0)
return operator*( 1.0/scalar );
cerr << "Attempt to divide by zero in method "
"FGColumnVector3::operator/(const double scalar), "
"object " << this << endl;
return FGColumnVector3();
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGColumnVector3& FGColumnVector3::operator/=(const double scalar)
{
if (scalar != 0.0)
operator*=( 1.0/scalar );
else
cerr << "Attempt to divide by zero in method "
"FGColumnVector3::operator/=(const double scalar), "
"object " << this << endl;
return *this;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
double FGColumnVector3::Magnitude(void) const
{
if (Entry(1) == 0.0 && Entry(2) == 0.0 && Entry(3) == 0.0)
return 0.0;
else
return sqrt( Entry(1)*Entry(1) + Entry(2)*Entry(2) + Entry(3)*Entry(3) );
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGColumnVector3& FGColumnVector3::Normalize(void)
{
double Mag = Magnitude();
if (Mag != 0.0)
operator*=( 1.0/Mag );
return *this;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGColumnVector3 FGColumnVector3::multElementWise(const FGColumnVector3& V) const
{
return FGColumnVector3(Entry(1) * V(1), Entry(2) * V(2), Entry(3) * V(3));
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
ostream& operator<<(ostream& os, const FGColumnVector3& col)
{
os << col(1) << " , " << col(2) << " , " << col(3);
return os;
}
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
// The bitmasked value choices are as follows:
// unset: In this case (the default) JSBSim would only print
// out the normally expected messages, essentially echoing
// the config files as they are read. If the environment
// variable is not set, debug_lvl is set to 1 internally
// 0: This requests JSBSim not to output any messages
// whatsoever.
// 1: This value explicity requests the normal JSBSim
// startup messages
// 2: This value asks for a message to be printed out when
// a class is instantiated
// 4: When this value is set, a message is displayed when a
// FGModel object executes its Run() method
// 8: When this value is set, various runtime state variables
// are printed out periodically
// 16: When set various parameters are sanity checked and
// a message is printed out when they go out of bounds
void FGColumnVector3::Debug(int from)
{
if (debug_lvl <= 0) return;
if (debug_lvl & 1) { // Standard console startup message output
}
if (debug_lvl & 2 ) { // Instantiation/Destruction notification
if (from == 0) cout << "Instantiated: FGColumnVector3" << endl;
if (from == 1) cout << "Destroyed: FGColumnVector3" << endl;
}
if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
}
if (debug_lvl & 8 ) { // Runtime state variables
}
if (debug_lvl & 16) { // Sanity checking
}
if (debug_lvl & 64) {
if (from == 0) { // Constructor
cout << IdSrc << endl;
cout << IdHdr << endl;
}
}
}
} // namespace JSBSim

View file

@ -1,307 +0,0 @@
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Header: FGColumnVector3.h
Author: Originally by Tony Peden [formatted and adapted here by Jon Berndt]
Date started: Unknown
HISTORY
--------------------------------------------------------------------------------
??/??/???? ?? Initial version and more.
03/06/2004 MF Rework, document and do much inlineing.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
SENTRY
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#ifndef FGCOLUMNVECTOR3_H
#define FGCOLUMNVECTOR3_H
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include <stdlib.h>
#ifdef FGFS
# include <math.h>
# include <simgear/compiler.h>
# include STL_STRING
# include STL_FSTREAM
# include STL_IOSTREAM
SG_USING_STD(string);
SG_USING_STD(ostream);
SG_USING_STD(istream);
SG_USING_STD(cerr);
SG_USING_STD(cout);
SG_USING_STD(endl);
// SG_USING_STD(sqrt);
#else
# include <string>
# if defined(sgi) && !defined(__GNUC__) && (_COMPILER_VERSION < 740)
# include <fstream.h>
# include <iostream.h>
# include <math.h>
# else
# include <fstream>
# include <iostream>
# if defined(sgi) && !defined(__GNUC__)
# include <math.h>
# else
# include <cmath>
# endif
using std::ostream;
using std::istream;
using std::cerr;
using std::cout;
using std::endl;
using std::sqrt;
# endif
using std::string;
#endif
#include "FGJSBBase.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_COLUMNVECTOR3 "$Id$"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
namespace JSBSim {
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DOCUMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/** This class implements a 3 dimensional vector.
@author Jon S. Berndt, Tony Peden, et. al.
@version $Id$
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DECLARATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
class FGColumnVector3 : public FGJSBBase
{
public:
/** Default initializer.
Create a zero vector. */
FGColumnVector3(void);
/** Initialization by given values.
@param X value of the x-conponent.
@param Y value of the y-conponent.
@param Z value of the z-conponent.
Create a vector from the doubles given in the arguments. */
FGColumnVector3(double X, double Y, double Z) {
data[0] = X;
data[1] = Y;
data[2] = Z;
Debug(0);
}
/** Copy constructor.
@param v Vector which is used for initialization.
Create copy of the vector given in the argument. */
FGColumnVector3(const FGColumnVector3& v) {
data[0] = v.data[0];
data[1] = v.data[1];
data[2] = v.data[2];
Debug(0);
}
/// Destructor.
~FGColumnVector3(void) { Debug(1); }
/** Read access the entries of the vector.
@param idx the component index.
Return the value of the matrix entry at the given index.
Indices are counted starting with 1.
Note that the index given in the argument is unchecked. */
double operator()(unsigned int idx) const { return Entry(idx); }
/** Write access the entries of the vector.
@param idx the component index.
Return a reference to the vector entry at the given index.
Indices are counted starting with 1.
Note that the index given in the argument is unchecked. */
double& operator()(unsigned int idx) { return Entry(idx); }
/** Read access the entries of the vector.
@param idx the component index.
Return the value of the matrix entry at the given index.
Indices are counted starting with 1.
This function is just a shortcut for the @ref double
operator()(unsigned int idx) const function. It is
used internally to access the elements in a more convenient way.
Note that the index given in the argument is unchecked. */
double Entry(unsigned int idx) const { return data[idx-1]; }
/** Write access the entries of the vector.
@param idx the component index.
Return a reference to the vector entry at the given index.
Indices are counted starting with 1.
This function is just a shortcut for the @ref double&
operator()(unsigned int idx) function. It is
used internally to access the elements in a more convenient way.
Note that the index given in the argument is unchecked. */
double& Entry(unsigned int idx) { return data[idx-1]; }
/** Prints the contents of the vector
@param delimeter the item separator (tab or comma)
@return a string with the delimeter-separated contents of the vector */
string Dump(string delimeter) const;
/** Assignment operator.
@param b source vector.
Copy the content of the vector given in the argument into *this. */
FGColumnVector3& operator=(const FGColumnVector3& b) {
data[0] = b.data[0];
data[1] = b.data[1];
data[2] = b.data[2];
return *this;
}
/** Comparison operator.
@param b other vector.
Returns true if both vectors are exactly the same. */
bool operator==(const FGColumnVector3& b) const {
return data[0] == b.data[0] && data[1] == b.data[1] && data[2] == b.data[2];
}
/** Comparison operator.
@param b other vector.
Returns false if both vectors are exactly the same. */
bool operator!=(const FGColumnVector3& b) const { return ! operator==(b); }
/** Multiplication by a scalar.
@param scalar scalar value to multiply the vector with.
@return The resulting vector from the multiplication with that scalar.
Multiply the vector with the scalar given in the argument. */
FGColumnVector3 operator*(const double scalar) const {
return FGColumnVector3(scalar*Entry(1), scalar*Entry(2), scalar*Entry(3));
}
/** Multiply by 1/scalar.
@param scalar scalar value to devide the vector through.
@return The resulting vector from the division through that scalar.
Multiply the vector with the 1/scalar given in the argument. */
FGColumnVector3 operator/(const double scalar) const;
/** Cross product multiplication.
@param v vector to multiply with.
@return The resulting vector from the cross product multiplication.
Compute and return the cross product of the current vector with
the given argument. */
FGColumnVector3 operator*(const FGColumnVector3& V) const {
return FGColumnVector3( Entry(2) * V(3) - Entry(3) * V(2),
Entry(3) * V(1) - Entry(1) * V(3),
Entry(1) * V(2) - Entry(2) * V(1) );
}
/// Addition operator.
FGColumnVector3 operator+(const FGColumnVector3& B) const {
return FGColumnVector3( Entry(1) + B(1), Entry(2) + B(2), Entry(3) + B(3) );
}
/// Subtraction operator.
FGColumnVector3 operator-(const FGColumnVector3& B) const {
return FGColumnVector3( Entry(1) - B(1), Entry(2) - B(2), Entry(3) - B(3) );
}
/// Subtract an other vector.
FGColumnVector3& operator-=(const FGColumnVector3 &B) {
Entry(1) -= B(1);
Entry(2) -= B(2);
Entry(3) -= B(3);
return *this;
}
/// Add an other vector.
FGColumnVector3& operator+=(const FGColumnVector3 &B) {
Entry(1) += B(1);
Entry(2) += B(2);
Entry(3) += B(3);
return *this;
}
/// Scale by a scalar.
FGColumnVector3& operator*=(const double scalar) {
Entry(1) *= scalar;
Entry(2) *= scalar;
Entry(3) *= scalar;
return *this;
}
/// Scale by a 1/scalar.
FGColumnVector3& operator/=(const double scalar);
void InitMatrix(void) { data[0] = data[1] = data[2] = 0.0; }
void InitMatrix(double a) { data[0] = data[1] = data[2] = a; }
void InitMatrix(double a, double b, double c) {
data[0]=a; data[1]=b; data[2]=c;
}
/** Length of the vector.
Compute and return the euclidean norm of this vector. */
double Magnitude(void) const;
/** Length of the vector in a coordinate axis plane.
Compute and return the euclidean norm of this vector projected into
the coordinate axis plane idx1-idx2. */
double Magnitude(int idx1, int idx2) const {
return sqrt( Entry(idx1)*Entry(idx1) + Entry(idx2)*Entry(idx2) );
}
/** Normalize.
Normalize the vector to have the Magnitude() == 1.0. If the vector
is equal to zero it is left untouched. */
FGColumnVector3& Normalize(void);
// ??? Is this something sensible ??
FGColumnVector3 multElementWise(const FGColumnVector3& V) const;
// little trick here.
struct AssignRef {
AssignRef(FGColumnVector3& r, int i) : Ref(r), idx(i) {}
AssignRef operator<<(const double ff) {
Ref.Entry(idx) = ff;
return AssignRef(Ref, idx+1);
}
FGColumnVector3& Ref;
int idx;
};
AssignRef operator<<(const double ff) {
Entry(1) = ff;
return AssignRef(*this, 2);
}
private:
double data[3];
void Debug(int from);
};
/** Scalar multiplication.
@param scalar scalar value to multiply with.
@param A Vector to multiply.
Multiply the Vector with a scalar value.*/
inline FGColumnVector3 operator*(double scalar, const FGColumnVector3& A) {
// use already defined operation.
return A*scalar;
}
/** Write vector to a stream.
@param os Stream to write to.
@param M Matrix to write.
Write the matrix to a stream.*/
ostream& operator<<(ostream& os, const FGColumnVector3& col);
} // namespace JSBSim
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#endif

View file

@ -1,354 +0,0 @@
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Header: FGConfigFile.h
Author: Jon Berndt
Date started: 03/29/00
Purpose: Config file read-in class
Called by: FGAircraft
FUNCTIONAL DESCRIPTION
--------------------------------------------------------------------------------
HISTORY
--------------------------------------------------------------------------------
03/16/2000 JSB Created
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "FGConfigFile.h"
#include <stdlib.h>
#include <math.h>
namespace JSBSim {
static const char *IdSrc = "$Id$";
static const char *IdHdr = ID_CONFIGFILE;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
FGConfigFile::FGConfigFile(string cfgFileName)
{
#if defined ( sgi ) && !defined( __GNUC__ ) && (_COMPILER_VERSION < 740)
cfgfile.open(cfgFileName.c_str(), ios::in );
#else
cfgfile.open(cfgFileName.c_str(), ios::in | ios::binary );
#endif
CommentsOn = false;
CurrentIndex = 0;
Opened = true;
#if defined ( sgi ) && !defined( __GNUC__ ) && (_COMPILER_VERSION < 740)
if (!cfgfile.fail() && !cfgfile.eof()) GetNextConfigLine();
#else
if (cfgfile.is_open()) GetNextConfigLine();
#endif
else Opened = false;
Debug(0);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGConfigFile::~FGConfigFile()
{
cfgfile.close();
Debug(1);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
string FGConfigFile::GetNextConfigLine(void)
{
int comment_starts_at;
int comment_ends_at;
int comment_length;
int line_length;
bool start_comment, end_comment;
string CommentStringTemp;
do {
CurrentLine = GetLine();
line_length = CurrentLine.length();
comment_starts_at = CurrentLine.find("<!--");
if (comment_starts_at >= 0) start_comment = true;
else start_comment = false;
comment_ends_at = CurrentLine.find("-->");
if (comment_ends_at >= 0) end_comment = true;
else end_comment = false;
if (!start_comment && !end_comment) { // command comment
if (CommentsOn) CommentStringTemp = CurrentLine;
CommentString += CommentStringTemp + "\r\n";
} else if (start_comment && comment_ends_at > comment_starts_at) { // <!-- ... -->
CommentsOn = false;
comment_length = comment_ends_at + 2 - comment_starts_at + 1;
LineComment = CurrentLine.substr(comment_starts_at+4, comment_length-4-3);
CurrentLine.erase(comment_starts_at, comment_length);
if (CurrentLine.find_first_not_of(" ") == string::npos) {
CurrentLine.erase();
}
} else if ( start_comment && !end_comment) { // <!-- ...
CommentsOn = true;
comment_length = line_length - comment_starts_at;
CommentStringTemp = CurrentLine.substr(comment_starts_at+4, comment_length-4);
CommentString = CommentStringTemp + "\r\n";
CurrentLine.erase(comment_starts_at, comment_length);
} else if (!start_comment && end_comment) { // ... -->
CommentsOn = false;
comment_length = comment_ends_at + 2 + 1;
CommentStringTemp = CurrentLine.substr(0, comment_length-4);
CommentString += CommentStringTemp + "\r\n";
CurrentLine.erase(0, comment_length);
} else if (start_comment && comment_ends_at < comment_starts_at) { // --> command <!--
cerr << "Old comment ends and new one starts - bad JSBSim config file form." << endl;
CommentsOn = false;
comment_length = comment_ends_at + 2 + 1;
CommentStringTemp = CurrentLine.substr(0, comment_length-4);
CommentString += CommentStringTemp + "\r\n";
CurrentLine.erase(0, comment_length);
}
} while (CommentsOn);
CurrentIndex = 0;
if (CurrentLine.length() == 0) {
GetNextConfigLine();
}
return CurrentLine;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
string FGConfigFile::GetValue(string val)
{
string::size_type pos, p1, p2, ptest;
if (val == "") { // this call is to return the tag value
pos = CurrentLine.find("<");
if (pos != CurrentLine.npos) { // beginning brace found "<"
p1 = CurrentLine.find_first_not_of(" ",pos+1);
if (p1 != CurrentLine.npos) { // found first character of tag
p2 = CurrentLine.find_first_of(" >",p1+1);
if (p2 == CurrentLine.npos) p2 = p1+1;
return CurrentLine.substr(p1,p2-p1);
}
} else { // beginning brace "<" not found; this is a regular data line
pos = CurrentLine.find_first_not_of(" ");
if (pos != CurrentLine.npos) { // first character in line found
p2 = CurrentLine.find_first_of(" ",pos+1);
if (p2 != CurrentLine.npos) {
return CurrentLine.substr(pos,p2-pos);
} else {
return CurrentLine.substr(pos,CurrentLine.length()-pos);
}
}
}
} else { // return a value for a specific tag
pos = CurrentLine.find(val);
if (pos != CurrentLine.npos) {
pos = CurrentLine.find("=",pos);
if (pos != CurrentLine.npos) {
ptest = CurrentLine.find_first_not_of(" ",pos+1);
if (ptest != CurrentLine.npos) {
p1 = ptest + 1;
if (CurrentLine[ptest] == '"') { // quoted
p2 = CurrentLine.find_first_of("\"",p1);
} else { // not quoted
p2 = CurrentLine.find_first_of(" ",p1);
}
if (p2 != CurrentLine.npos) {
return CurrentLine.substr(p1,p2-p1);
}
}
} else { // "=" not found
pos = CurrentLine.find(val);
pos = CurrentLine.find_first_of(" ",pos+1);
ptest = CurrentLine.find_first_not_of(" ",pos+1);
if (ptest != CurrentLine.npos) {
if (CurrentLine[ptest] == '"') { // quoted
p1 = ptest + 1;
p2 = CurrentLine.find_first_of("\"",p1);
} else { // not quoted
p1 = ptest;
p2 = CurrentLine.find_first_of(" ",p1);
}
if (p2 != CurrentLine.npos) {
return CurrentLine.substr(p1,p2-p1);
} else {
p2 = CurrentLine.length();
return CurrentLine.substr(p1,p2-p1);
}
}
}
}
}
return string("");
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
string FGConfigFile::GetValue(void)
{
return GetValue("");
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
string FGConfigFile::GetLine(void)
{
string scratch = "";
int test;
while ((test = cfgfile.get()) != EOF) {
if (test >= 0x20 || test == 0x09) {
if (test == 0x09) {
scratch += (char)0x20;
} else {
scratch += (char)test;
}
} else {
if ((test = cfgfile.get()) != EOF) { // get *next* character
#if defined ( sgi ) && !defined( __GNUC__ ) && (_COMPILER_VERSION < 740) || defined (_MSC_VER)
if (test >= 0x20 || test == 0x09) cfgfile.putback(test);
#else
if (test >= 0x20 || test == 0x09) cfgfile.unget();
#endif
break;
}
}
}
int index = scratch.find_last_not_of(" ");
if (index != string::npos && index < (scratch.size()-1)) {
scratch = scratch.substr(0,index+1);
}
if (cfgfile.eof() && scratch.empty()) return string("EOF");
return scratch;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGConfigFile& FGConfigFile::operator>>(double& val)
{
string::size_type pos, end;
pos = CurrentLine.find_first_not_of(", ",CurrentIndex);
if (pos == CurrentLine.npos) pos = CurrentLine.length();
end = CurrentLine.find_first_of(", ",pos+1);
if (end == CurrentLine.npos) end = CurrentLine.length();
string str = CurrentLine.substr(pos, end - pos);
val = strtod(str.c_str(),NULL);
CurrentIndex = end+1;
if (end == pos) {
GetNextConfigLine();
*this >> val;
} else {
if (CurrentIndex >= CurrentLine.length()) GetNextConfigLine();
}
return *this;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGConfigFile& FGConfigFile::operator>>(int& val)
{
string::size_type pos, end;
pos = CurrentLine.find_first_not_of(", ",CurrentIndex);
if (pos == CurrentLine.npos) pos = CurrentLine.length();
end = CurrentLine.find_first_of(", ",pos+1);
if (end == CurrentLine.npos) end = CurrentLine.length();
string str = CurrentLine.substr(pos, end - pos);
val = atoi(str.c_str());
CurrentIndex = end+1;
if (end == pos) {
GetNextConfigLine();
*this >> val;
} else {
if (CurrentIndex >= CurrentLine.length()) GetNextConfigLine();
}
return *this;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGConfigFile& FGConfigFile::operator>>(string& str)
{
string::size_type pos, end;
pos = CurrentLine.find_first_not_of(", ",CurrentIndex);
if (pos == CurrentLine.npos) pos = CurrentLine.length();
end = CurrentLine.find_first_of(", ",pos+1);
if (end == CurrentLine.npos) end = CurrentLine.length();
str = CurrentLine.substr(pos, end - pos);
CurrentIndex = end+1;
if (end == pos) {
GetNextConfigLine();
*this >> str;
} else {
if (CurrentIndex >= CurrentLine.length()) GetNextConfigLine();
}
return *this;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGConfigFile::ResetLineIndexToZero(void)
{
CurrentIndex = 0;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// The bitmasked value choices are as follows:
// unset: In this case (the default) JSBSim would only print
// out the normally expected messages, essentially echoing
// the config files as they are read. If the environment
// variable is not set, debug_lvl is set to 1 internally
// 0: This requests JSBSim not to output any messages
// whatsoever.
// 1: This value explicity requests the normal JSBSim
// startup messages
// 2: This value asks for a message to be printed out when
// a class is instantiated
// 4: When this value is set, a message is displayed when a
// FGModel object executes its Run() method
// 8: When this value is set, various runtime state variables
// are printed out periodically
// 16: When set various parameters are sanity checked and
// a message is printed out when they go out of bounds
void FGConfigFile::Debug(int from)
{
if (debug_lvl <= 0) return;
if (debug_lvl & 1) { // Standard console startup message output
}
if (debug_lvl & 2 ) { // Instantiation/Destruction notification
if (from == 0) cout << "Instantiated: FGConfigFile" << endl;
if (from == 1) cout << "Destroyed: FGConfigFile" << endl;
}
if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
}
if (debug_lvl & 8 ) { // Runtime state variables
}
if (debug_lvl & 16) { // Sanity checking
}
if (debug_lvl & 64) {
if (from == 0) { // Constructor
cout << IdSrc << endl;
cout << IdHdr << endl;
}
}
}
}

View file

@ -1,147 +0,0 @@
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Header: FGConfigFile.h
Author: Jon Berndt
Date started: 03/29/00
------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU 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 General Public License for more
details.
You should have received a copy of the GNU 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 General Public License can also be found on
the world wide web at http://www.gnu.org.
HISTORY
--------------------------------------------------------------------------------
03/29/00 JSB Created
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
SENTRY
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#ifndef FGCONFIGFILE_H
#define FGCONFIGFILE_H
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#ifdef FGFS
# include <simgear/compiler.h>
# include STL_STRING
# include STL_FSTREAM
# include STL_IOSTREAM
SG_USING_STD(string);
SG_USING_STD(ostream);
SG_USING_STD(istream);
SG_USING_STD(ifstream);
SG_USING_STD(cerr);
SG_USING_STD(endl);
SG_USING_STD(ios);
SG_USING_STD(cout);
#else
# include <string>
# if defined(sgi) && !defined(__GNUC__) && (_COMPILER_VERSION < 740)
# include <fstream.h>
# include <iostream.h>
# else
# include <fstream>
# include <iostream>
using std::ostream;
using std::istream;
using std::ios;
using std::cerr;
using std::cout;
using std::ifstream;
using std::endl;
# endif
using std::string;
#endif
#include "FGJSBBase.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_CONFIGFILE "$Id$"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
namespace JSBSim {
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DOCUMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/** Encapsulates reading a JSBSim config file.
JSBSim config files are in XML format.
@author Jon S. Berndt
@version $Id$
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DECLARATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
class FGConfigFile : public FGJSBBase
{
public:
/** Constructor
@param Filename the name of the config file to be read. */
FGConfigFile(string Filename);
/// Destructor
~FGConfigFile();
/** Returns the next line from the currently open config file.
Comments are bypassed and ignored.
@return the next valid line from the config file OR "EOF" if end of file is
reached.*/
string GetNextConfigLine(void);
string GetCurrentLine(void) { return CurrentLine; }
/** Returns the value of the tag supplied.
@param tag the tag for the value that is desired.
@return tthe value of the tag supplied.*/
string GetValue(string tag);
string GetValue(void);
string GetCommentString(void) {return CommentString;}
string GetLineComment(void) {return LineComment;}
bool IsOpen(void) {return Opened;}
FGConfigFile& operator>>(double&);
FGConfigFile& operator>>(int&);
FGConfigFile& operator>>(string&);
void ResetLineIndexToZero(void);
private:
ifstream cfgfile;
string CurrentLine;
string CommentString;
string LineComment;
bool CommentsOn;
bool Opened;
unsigned int CurrentIndex;
string GetLine(void);
void Debug(int from);
};
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#endif

View file

@ -1,171 +0,0 @@
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Module: FGElectric.cpp
Author: David Culp
Date started: 04/07/2004
Purpose: This module models an electric motor
--------- Copyright (C) 2004 David Culp (davidculp2@comcast.net) -------------
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU 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 General Public License for more
details.
You should have received a copy of the GNU 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 General Public License can also be found on
the world wide web at http://www.gnu.org.
FUNCTIONAL DESCRIPTION
--------------------------------------------------------------------------------
This class descends from the FGEngine class and models an electric motor based on
parameters given in the engine config file for this class
HISTORY
--------------------------------------------------------------------------------
04/07/2004 DPC Created
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "FGElectric.h"
#include "FGPropulsion.h"
namespace JSBSim {
static const char *IdSrc = "$Id$";
static const char *IdHdr = ID_ELECTRIC;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
FGElectric::FGElectric(FGFDMExec* exec, FGConfigFile* Eng_cfg, int engine_number)
: FGEngine(exec, engine_number)
{
string token;
Type = etElectric;
PowerWatts = 745.7;
hptowatts = 745.7;
dt = State->Getdt();
Name = Eng_cfg->GetValue("NAME");
Eng_cfg->GetNextConfigLine();
while (Eng_cfg->GetValue() != string("/FG_ELECTRIC")) {
*Eng_cfg >> token;
if (token == "POWER_WATTS") *Eng_cfg >> PowerWatts;
else cerr << "Unhandled token in Engine config file: " << token << endl;
}
Debug(0); // Call Debug() routine from constructor if needed
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGElectric::~FGElectric()
{
Debug(1); // Call Debug() routine from constructor if needed
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
double FGElectric::Calculate(void)
{
Throttle = FCS->GetThrottlePos(EngineNumber);
RPM = Thruster->GetRPM() * Thruster->GetGearRatio();
HP = PowerWatts * Throttle / hptowatts;
PowerAvailable = (HP * hptoftlbssec) - Thruster->GetPowerRequired();
return Thrust = Thruster->Calculate(PowerAvailable);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
string FGElectric::GetEngineLabels(string delimeter)
{
return ""; // currently no labels are returned for this engine
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
string FGElectric::GetEngineValues(string delimeter)
{
return ""; // currently no values are returned for this engine
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//
// The bitmasked value choices are as follows:
// unset: In this case (the default) JSBSim would only print
// out the normally expected messages, essentially echoing
// the config files as they are read. If the environment
// variable is not set, debug_lvl is set to 1 internally
// 0: This requests JSBSim not to output any messages
// whatsoever.
// 1: This value explicity requests the normal JSBSim
// startup messages
// 2: This value asks for a message to be printed out when
// a class is instantiated
// 4: When this value is set, a message is displayed when a
// FGModel object executes its Run() method
// 8: When this value is set, various runtime state variables
// are printed out periodically
// 16: When set various parameters are sanity checked and
// a message is printed out when they go out of bounds
void FGElectric::Debug(int from)
{
if (debug_lvl <= 0) return;
if (debug_lvl & 1) { // Standard console startup message output
if (from == 0) { // Constructor
cout << "\n Engine Name: " << Name << endl;
cout << " Power Watts: " << PowerWatts << endl;
}
}
if (debug_lvl & 2 ) { // Instantiation/Destruction notification
if (from == 0) cout << "Instantiated: FGElectric" << endl;
if (from == 1) cout << "Destroyed: FGElectric" << endl;
}
if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
}
if (debug_lvl & 8 ) { // Runtime state variables
}
if (debug_lvl & 16) { // Sanity checking
}
if (debug_lvl & 64) {
if (from == 0) { // Constructor
cout << IdSrc << endl;
cout << IdHdr << endl;
}
}
}
double
FGElectric::CalcFuelNeed(void)
{
return 0;
}
} // namespace JSBSim

View file

@ -1,107 +0,0 @@
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Header: FGElectric.h
Author: David Culp
Date started: 04/07/2004
----- Copyright (C) 2004 David P. Culp (davidculp2@comcast.net) --------------
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU 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 General Public License for more
details.
You should have received a copy of the GNU 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 General Public License can also be found on
the world wide web at http://www.gnu.org.
HISTORY
--------------------------------------------------------------------------------
04/07/2004 DPC Created
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
SENTRY
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#ifndef FGELECTRIC_H
#define FGELECTRIC_H
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include "FGEngine.h"
#include "FGConfigFile.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_ELECTRIC "$Id$";
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
namespace JSBSim {
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DOCUMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/** Models and electric motor.
FGElectric models an electric motor based on the configuration file
POWER_WATTS parameter. The throttle controls motor output linearly from
zero to POWER_WATTS. This power value (converted internally to horsepower)
is then used by FGPropeller to apply torque to the propeller.
@author David Culp
@version "$Id$"
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DECLARATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
class FGElectric : public FGEngine
{
public:
/// Constructor
FGElectric(FGFDMExec* exec, FGConfigFile* Eng_cfg, int engine_number);
/// Destructor
~FGElectric();
double Calculate(void);
double GetPowerAvailable(void) {return PowerAvailable;}
double CalcFuelNeed(void);
double getRPM(void) {return RPM;}
string GetEngineLabels(string delimeter);
string GetEngineValues(string delimeter);
private:
double BrakeHorsePower;
double PowerAvailable;
// timestep
double dt;
// constants
double hptowatts;
double PowerWatts; // maximum engine power
double RPM; // revolutions per minute
double HP;
void Debug(int from);
};
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#endif

View file

@ -1,349 +0,0 @@
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Module: FGEngine.cpp
Author: Jon Berndt
Date started: 01/21/99
Called by: FGAircraft
------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU 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 General Public License for more
details.
You should have received a copy of the GNU 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 General Public License can also be found on
the world wide web at http://www.gnu.org.
FUNCTIONAL DESCRIPTION
--------------------------------------------------------------------------------
See header file.
HISTORY
--------------------------------------------------------------------------------
01/21/99 JSB Created
09/03/99 JSB Changed Rocket thrust equation to correct -= Thrust instead of
+= Thrust (thanks to Tony Peden)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#ifdef FGFS
# include <simgear/compiler.h>
# ifdef SG_HAVE_STD_INCLUDES
# include <fstream>
# else
# include <fstream.h>
# endif
#else
# if defined(sgi) && !defined(__GNUC__) && (_COMPILER_VERSION < 740)
# include <fstream.h>
# else
# include <fstream>
# endif
#endif
#include "FGEngine.h"
#include "FGTank.h"
#include "FGPropeller.h"
#include "FGNozzle.h"
namespace JSBSim {
static const char *IdSrc = "$Id$";
static const char *IdHdr = ID_ENGINE;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
FGEngine::FGEngine(FGFDMExec* exec, int engine_number) : EngineNumber(engine_number)
{
Name = "";
Type = etUnknown;
X = Y = Z = 0.0;
EnginePitch = EngineYaw = 0.0;
SLFuelFlowMax = SLOxiFlowMax = 0.0;
MaxThrottle = 1.0;
MinThrottle = 0.0;
Thrust = 0.0;
Throttle = 0.0;
Mixture = 1.0;
Starter = false;
FuelNeed = OxidizerNeed = 0.0;
Starved = Running = Cranking = false;
PctPower = 0.0;
TrimMode = false;
FuelFlow_gph = 0.0;
FuelFlow_pph = 0.0;
FuelFreeze = false;
FDMExec = exec;
State = FDMExec->GetState();
Atmosphere = FDMExec->GetAtmosphere();
FCS = FDMExec->GetFCS();
Propulsion = FDMExec->GetPropulsion();
Aircraft = FDMExec->GetAircraft();
Propagate = FDMExec->GetPropagate();
Auxiliary = FDMExec->GetAuxiliary();
Output = FDMExec->GetOutput();
PropertyManager = FDMExec->GetPropertyManager();
char property_name[80];
snprintf(property_name, 80, "propulsion/engine[%u]/thrust", EngineNumber);
PropertyManager->Tie( property_name, &Thrust);
Debug(0);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGEngine::~FGEngine()
{
if (Thruster) delete Thruster;
char property_name[80];
snprintf(property_name, 80, "propulsion/engine[%u]/thrust", EngineNumber);
PropertyManager->Untie( property_name);
Debug(1);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// This base class function should be called from within the
// derived class' Calculate() function before any other calculations are done.
// This base class method removes fuel from the fuel tanks as appropriate,
// and sets the starved flag if necessary.
void FGEngine::ConsumeFuel(void)
{
if (FuelFreeze) return;
unsigned int i;
double Fshortage, Oshortage, TanksWithFuel, TanksWithOxidizer;
FGTank* Tank;
bool haveOxTanks = false;
if (TrimMode) return;
Fshortage = Oshortage = TanksWithFuel = TanksWithOxidizer = 0.0;
// count how many assigned tanks have fuel or oxidizer
for (i=0; i<SourceTanks.size(); i++) {
Tank = Propulsion->GetTank(SourceTanks[i]);
if (Tank->GetType() == FGTank::ttFUEL){
if (Tank->GetContents() > 0.0) {
++TanksWithFuel;
}
} else if (Tank->GetType() == FGTank::ttOXIDIZER) {
haveOxTanks = true;
if (Tank->GetContents() > 0.0) {
++TanksWithOxidizer;
}
}
}
if (!TanksWithFuel || (haveOxTanks && !TanksWithOxidizer)) return;
for (i=0; i<SourceTanks.size(); i++) {
Tank = Propulsion->GetTank(SourceTanks[i]);
if (Tank->GetType() == FGTank::ttFUEL) {
Fshortage += Tank->Drain(CalcFuelNeed()/TanksWithFuel);
} else if (Tank->GetType() == FGTank::ttOXIDIZER) {
Oshortage += Tank->Drain(CalcOxidizerNeed()/TanksWithOxidizer);
}
}
if (Fshortage < 0.00 || Oshortage < 0.00) Starved = true;
else Starved = false;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
double FGEngine::CalcFuelNeed(void)
{
FuelNeed = SLFuelFlowMax*PctPower*State->Getdt()*Propulsion->GetRate();
return FuelNeed;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
double FGEngine::CalcOxidizerNeed(void)
{
OxidizerNeed = SLOxiFlowMax*PctPower*State->Getdt()*Propulsion->GetRate();
return OxidizerNeed;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGEngine::SetPlacement(double x, double y, double z, double pitch, double yaw)
{
X = x;
Y = y;
Z = z;
EnginePitch = pitch;
EngineYaw = yaw;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGEngine::AddFeedTank(int tkID)
{
SourceTanks.push_back(tkID);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGColumnVector3& FGEngine::GetBodyForces(void)
{
return Thruster->GetBodyForces();
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGColumnVector3& FGEngine::GetMoments(void)
{
return Thruster->GetMoments();
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
bool FGEngine::LoadThruster(FGConfigFile* AC_cfg)
{
string token, fullpath, localpath;
string thrType, engineFileName;
FGConfigFile* Cfg_ptr = 0;
double xLoc, yLoc, zLoc, Pitch, Yaw;
double P_Factor = 0, Sense = 0.0;
string enginePath = FDMExec->GetEnginePath();
string aircraftPath = FDMExec->GetAircraftPath();
thrusterFileName = AC_cfg->GetValue("FILE");
# ifndef macintosh
fullpath = enginePath + "/";
localpath = aircraftPath + "/" + "/Engines/";
# else
fullpath = enginePath + ";";
localpath = aircraftPath + ";" + ";Engines;";
# endif
// Look in the Aircraft/Engines directory first
FGConfigFile Local_Thruster_cfg(localpath + thrusterFileName + ".xml");
FGConfigFile Thruster_cfg(fullpath + thrusterFileName + ".xml");
if (Local_Thruster_cfg.IsOpen()) {
Cfg_ptr = &Local_Thruster_cfg;
if (debug_lvl > 0) cout << "\n Reading thruster from file: " << localpath
+ thrusterFileName + ".xml"<< endl;
} else {
if (Thruster_cfg.IsOpen()) {
Cfg_ptr = &Thruster_cfg;
if (debug_lvl > 0) cout << "\n Reading thruster from file: " << fullpath
+ thrusterFileName + ".xml"<< endl;
}
}
if (Cfg_ptr) {
Cfg_ptr->GetNextConfigLine();
thrType = Cfg_ptr->GetValue();
if (thrType == "FG_PROPELLER") {
Thruster = new FGPropeller(FDMExec, Cfg_ptr, EngineNumber);
} else if (thrType == "FG_NOZZLE") {
Thruster = new FGNozzle(FDMExec, Cfg_ptr, EngineNumber);
} else if (thrType == "FG_DIRECT") {
Thruster = new FGThruster( FDMExec, Cfg_ptr, EngineNumber);
}
AC_cfg->GetNextConfigLine();
while ((token = AC_cfg->GetValue()) != string("/AC_THRUSTER")) {
*AC_cfg >> token;
if (token == "XLOC") *AC_cfg >> xLoc;
else if (token == "YLOC") *AC_cfg >> yLoc;
else if (token == "ZLOC") *AC_cfg >> zLoc;
else if (token == "PITCH") *AC_cfg >> Pitch;
else if (token == "YAW") *AC_cfg >> Yaw;
else if (token == "P_FACTOR") *AC_cfg >> P_Factor;
else if (token == "SENSE") *AC_cfg >> Sense;
else cerr << "Unknown identifier: " << token << " in engine file: "
<< engineFileName << endl;
}
Thruster->SetLocation(xLoc, yLoc, zLoc);
Thruster->SetAnglesToBody(0, Pitch, Yaw);
if (thrType == "FG_PROPELLER" && P_Factor > 0.001) {
((FGPropeller*)Thruster)->SetPFactor(P_Factor);
if (debug_lvl > 0) cout << " P-Factor: " << P_Factor << endl;
((FGPropeller*)Thruster)->SetSense(fabs(Sense)/Sense);
if (debug_lvl > 0) cout << " Sense: " << Sense << endl;
}
Thruster->SetdeltaT(State->Getdt() * Propulsion->GetRate());
return true;
} else {
cerr << "Could not read thruster config file: " << fullpath
+ thrusterFileName + ".xml" << endl;
return false;
}
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// The bitmasked value choices are as follows:
// unset: In this case (the default) JSBSim would only print
// out the normally expected messages, essentially echoing
// the config files as they are read. If the environment
// variable is not set, debug_lvl is set to 1 internally
// 0: This requests JSBSim not to output any messages
// whatsoever.
// 1: This value explicity requests the normal JSBSim
// startup messages
// 2: This value asks for a message to be printed out when
// a class is instantiated
// 4: When this value is set, a message is displayed when a
// FGModel object executes its Run() method
// 8: When this value is set, various runtime state variables
// are printed out periodically
// 16: When set various parameters are sanity checked and
// a message is printed out when they go out of bounds
void FGEngine::Debug(int from)
{
if (debug_lvl <= 0) return;
if (debug_lvl & 1) { // Standard console startup message output
if (from == 0) { // Constructor
}
}
if (debug_lvl & 2 ) { // Instantiation/Destruction notification
if (from == 0) cout << "Instantiated: FGEngine" << endl;
if (from == 1) cout << "Destroyed: FGEngine" << endl;
}
if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
}
if (debug_lvl & 8 ) { // Runtime state variables
}
if (debug_lvl & 16) { // Sanity checking
}
if (debug_lvl & 64) {
if (from == 0) { // Constructor
cout << IdSrc << endl;
cout << IdHdr << endl;
}
}
}
}

View file

@ -1,252 +0,0 @@
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Header: FGEngine.h
Author: Jon S. Berndt
Date started: 01/21/99
------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU 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 General Public License for more
details.
You should have received a copy of the GNU 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 General Public License can also be found on
the world wide web at http://www.gnu.org.
FUNCTIONAL DESCRIPTION
--------------------------------------------------------------------------------
Based on Flightgear code, which is based on LaRCSim. This class simulates
a generic engine.
HISTORY
--------------------------------------------------------------------------------
01/21/99 JSB Created
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
SENTRY
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#ifndef FGENGINE_H
#define FGENGINE_H
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#ifdef FGFS
# include <simgear/compiler.h>
# include STL_STRING
SG_USING_STD(string);
# ifdef SG_HAVE_STD_INCLUDES
# include <vector>
# else
# include <vector.h>
# endif
#else
# include <vector>
# include <string>
#endif
#include "FGJSBBase.h"
#include "FGThruster.h"
#include "FGPropertyManager.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_ENGINE "$Id$"
using std::string;
using std::vector;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
namespace JSBSim {
class FGFDMExec;
class FGState;
class FGAtmosphere;
class FGFCS;
class FGAircraft;
class FGPropagate;
class FGPropulsion;
class FGAuxiliary;
class FGOutput;
class FGThruster;
class FGConfigFile;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DOCUMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/** Base class for all engines.
This base class contains methods and members common to all engines, such as
logic to drain fuel from the appropriate tank, etc.
@author Jon S. Berndt
@version $Id$
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DECLARATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
class FGEngine : public FGJSBBase
{
public:
FGEngine(FGFDMExec* exec, int engine_number);
virtual ~FGEngine();
enum EngineType {etUnknown, etRocket, etPiston, etTurbine, etElectric};
EngineType GetType(void) { return Type; }
virtual string GetName(void) { return Name; }
string GetThrusterFileName(void) {return thrusterFileName;}
void SetEngineFileName(string eng) {engineFileName = eng;}
string GetEngineFileName(void) {return engineFileName;}
// Engine controls
virtual double GetThrottleMin(void) { return MinThrottle; }
virtual double GetThrottleMax(void) { return MaxThrottle; }
virtual double GetThrottle(void) { return Throttle; }
virtual double GetMixture(void) { return Mixture; }
virtual bool GetStarter(void) { return Starter; }
virtual double getFuelFlow_gph () const {return FuelFlow_gph;}
virtual double getFuelFlow_pph () const {return FuelFlow_pph;}
virtual double GetThrust(void) { return Thrust; }
virtual bool GetStarved(void) { return Starved; }
virtual bool GetRunning(void) { return Running; }
virtual bool GetCranking(void) { return Cranking; }
virtual void SetStarved(bool tt) { Starved = tt; }
virtual void SetStarved(void) { Starved = true; }
virtual void SetRunning(bool bb) { Running=bb; }
virtual void SetName(string name) { Name = name; }
virtual void AddFeedTank(int tkID);
virtual void SetFuelFreeze(bool f) { FuelFreeze = f; }
virtual void SetStarter(bool s) { Starter = s; }
/** Calculates the thrust of the engine, and other engine functions.
@return Thrust in pounds */
virtual double Calculate(void) {return 0.0;}
/** Reduces the fuel in the active tanks by the amount required.
This function should be called from within the
derived class' Calculate() function before any other calculations are
done. This base class method removes fuel from the fuel tanks as
appropriate, and sets the starved flag if necessary. */
virtual void ConsumeFuel(void);
/** The fuel need is calculated based on power levels and flow rate for that
power level. It is also turned from a rate into an actual amount (pounds)
by multiplying it by the delta T and the rate.
@return Total fuel requirement for this engine in pounds. */
virtual double CalcFuelNeed(void);
/** The oxidizer need is calculated based on power levels and flow rate for that
power level. It is also turned from a rate into an actual amount (pounds)
by multiplying it by the delta T and the rate.
@return Total oxidizer requirement for this engine in pounds. */
virtual double CalcOxidizerNeed(void);
/// Sets engine placement information
virtual void SetPlacement(double x, double y, double z, double pitch, double yaw);
double GetPlacementX(void) const {return X;}
double GetPlacementY(void) const {return Y;}
double GetPlacementZ(void) const {return Z;}
double GetPitch(void) const {return EnginePitch;}
double GetYaw(void) const {return EngineYaw;}
virtual double GetPowerAvailable(void) {return 0.0;};
virtual bool GetTrimMode(void) {return TrimMode;}
virtual void SetTrimMode(bool state) {TrimMode = state;}
virtual FGColumnVector3& GetBodyForces(void);
virtual FGColumnVector3& GetMoments(void);
bool LoadThruster(FGConfigFile* AC_cfg);
FGThruster* GetThruster(void) {return Thruster;}
virtual string GetEngineLabels(string delimeter) = 0;
virtual string GetEngineValues(string delimeter) = 0;
int GetNumSourceTanks(void) {return SourceTanks.size();}
int GetSourceTank(int t) {return SourceTanks[t];}
protected:
FGPropertyManager* PropertyManager;
string Name;
string thrusterFileName;
string engineFileName;
const int EngineNumber;
EngineType Type;
double X, Y, Z;
double EnginePitch;
double EngineYaw;
double SLFuelFlowMax;
double SLOxiFlowMax;
double MaxThrottle;
double MinThrottle;
double Thrust;
double Throttle;
double Mixture;
double FuelNeed;
double OxidizerNeed;
double PctPower;
bool Starter;
bool Starved;
bool Running;
bool Cranking;
bool TrimMode;
bool FuelFreeze;
double FuelFlow_gph;
double FuelFlow_pph;
FGFDMExec* FDMExec;
FGState* State;
FGAtmosphere* Atmosphere;
FGFCS* FCS;
FGPropulsion* Propulsion;
FGAircraft* Aircraft;
FGPropagate* Propagate;
FGAuxiliary* Auxiliary;
FGOutput* Output;
FGThruster* Thruster;
vector <int> SourceTanks;
void Debug(int from);
};
}
#include "FGState.h"
#include "FGFDMExec.h"
#include "FGAtmosphere.h"
#include "FGFCS.h"
#include "FGAircraft.h"
#include "FGPropagate.h"
#include "FGPropulsion.h"
#include "FGAuxiliary.h"
#include "FGOutput.h"
#include "FGThruster.h"
#include "FGConfigFile.h"
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#endif

View file

@ -1,890 +0,0 @@
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Module: FGFCS.cpp
Author: Jon Berndt
Date started: 12/12/98
Purpose: Model the flight controls
Called by: FDMExec
------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU 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 General Public License for more
details.
You should have received a copy of the GNU 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 General Public License can also be found on
the world wide web at http://www.gnu.org.
FUNCTIONAL DESCRIPTION
--------------------------------------------------------------------------------
This class models the flight controls for a specific airplane
HISTORY
--------------------------------------------------------------------------------
12/12/98 JSB Created
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "FGFCS.h"
#include "FGFDMExec.h"
#include "FGPropertyManager.h"
#include "filtersjb/FGFilter.h"
#include "filtersjb/FGDeadBand.h"
#include "filtersjb/FGGain.h"
#include "filtersjb/FGGradient.h"
#include "filtersjb/FGSwitch.h"
#include "filtersjb/FGSummer.h"
#include "filtersjb/FGKinemat.h"
namespace JSBSim {
static const char *IdSrc = "$Id$";
static const char *IdHdr = ID_FCS;
#if defined(WIN32) && !defined(__CYGWIN__)
#define snprintf _snprintf
#endif
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
FGFCS::FGFCS(FGFDMExec* fdmex) : FGModel(fdmex)
{
int i;
Name = "FGFCS";
DaCmd = DeCmd = DrCmd = DfCmd = DsbCmd = DspCmd = 0.0;
AP_DaCmd = AP_DeCmd = AP_DrCmd = AP_ThrottleCmd = 0.0;
PTrimCmd = YTrimCmd = RTrimCmd = 0.0;
GearCmd = GearPos = 1; // default to gear down
LeftBrake = RightBrake = CenterBrake = 0.0;
APAttitudeSetPt = APAltitudeSetPt = APHeadingSetPt = APAirspeedSetPt = 0.0;
DoNormalize=true;
bind();
for (i=0;i<=NForms;i++) {
DePos[i] = DaLPos[i] = DaRPos[i] = DrPos[i] = 0.0;
DfPos[i] = DsbPos[i] = DspPos[i] = 0.0;
}
for (i=0;i<NNorm;i++) { ToNormalize[i]=-1;}
Debug(0);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGFCS::~FGFCS()
{
unbind( PropertyManager->GetNode("fcs") );
unbind( PropertyManager->GetNode("ap") );
PropertyManager->Untie( "gear/gear-cmd-norm" );
PropertyManager->Untie( "gear/gear-pos-norm" );
ThrottleCmd.clear();
ThrottlePos.clear();
MixtureCmd.clear();
MixturePos.clear();
PropAdvanceCmd.clear();
PropAdvance.clear();
SteerPosDeg.clear();
unsigned int i;
for (i=0;i<APComponents.size();i++) delete APComponents[i];
for (i=0;i<FCSComponents.size();i++) delete FCSComponents[i];
Debug(1);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
bool FGFCS::Run(void)
{
unsigned int i;
if (FGModel::Run()) return true; // fast exit if nothing to do
// Set the default engine commands
for (i=0; i<ThrottlePos.size(); i++) ThrottlePos[i] = ThrottleCmd[i];
for (i=0; i<MixturePos.size(); i++) MixturePos[i] = MixtureCmd[i];
for (i=0; i<PropAdvance.size(); i++) PropAdvance[i] = PropAdvanceCmd[i];
// Set the default steering angle
for (i=0; i<SteerPosDeg.size(); i++) {
FGLGear* gear = GroundReactions->GetGearUnit(i);
SteerPosDeg[i] = gear->GetDefaultSteerAngle( GetDsCmd() );
}
for (i=0; i<APComponents.size(); i++) APComponents[i]->Run(); // cycle AP components
for (i=0; i<FCSComponents.size(); i++) FCSComponents[i]->Run(); // cycle FCS components
if (DoNormalize) Normalize();
return false;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGFCS::SetThrottleCmd(int engineNum, double setting)
{
unsigned int ctr;
if (engineNum < (int)ThrottlePos.size()) {
if (engineNum < 0) {
for (ctr=0;ctr<ThrottleCmd.size();ctr++) ThrottleCmd[ctr] = setting;
} else {
ThrottleCmd[engineNum] = setting;
}
} else {
cerr << "Throttle " << engineNum << " does not exist! " << ThrottleCmd.size()
<< " engines exist, but attempted throttle command is for engine "
<< engineNum << endl;
}
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGFCS::SetThrottlePos(int engineNum, double setting)
{
unsigned int ctr;
if (engineNum < (int)ThrottlePos.size()) {
if (engineNum < 0) {
for (ctr=0;ctr<ThrottlePos.size();ctr++) ThrottlePos[ctr] = setting;
} else {
ThrottlePos[engineNum] = setting;
}
} else {
cerr << "Throttle " << engineNum << " does not exist! " << ThrottlePos.size()
<< " engines exist, but attempted throttle position setting is for engine "
<< engineNum << endl;
}
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
double FGFCS::GetThrottleCmd(int engineNum) const
{
if (engineNum < (int)ThrottlePos.size()) {
if (engineNum < 0) {
cerr << "Cannot get throttle value for ALL engines" << endl;
} else {
return ThrottleCmd[engineNum];
}
} else {
cerr << "Throttle " << engineNum << " does not exist! " << ThrottleCmd.size()
<< " engines exist, but throttle setting for engine " << engineNum
<< " is selected" << endl;
}
return 0.0;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
double FGFCS::GetThrottlePos(int engineNum) const
{
if (engineNum < (int)ThrottlePos.size()) {
if (engineNum < 0) {
cerr << "Cannot get throttle value for ALL engines" << endl;
} else {
return ThrottlePos[engineNum];
}
} else {
cerr << "Throttle " << engineNum << " does not exist! " << ThrottlePos.size()
<< " engines exist, but attempted throttle position setting is for engine "
<< engineNum << endl;
}
return 0.0;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGFCS::SetMixtureCmd(int engineNum, double setting)
{
unsigned int ctr;
if (engineNum < (int)ThrottlePos.size()) {
if (engineNum < 0) {
for (ctr=0;ctr<MixtureCmd.size();ctr++) MixtureCmd[ctr] = setting;
} else {
MixtureCmd[engineNum] = setting;
}
}
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGFCS::SetMixturePos(int engineNum, double setting)
{
unsigned int ctr;
if (engineNum < (int)ThrottlePos.size()) {
if (engineNum < 0) {
for (ctr=0;ctr<=MixtureCmd.size();ctr++) MixturePos[ctr] = MixtureCmd[ctr];
} else {
MixturePos[engineNum] = setting;
}
}
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGFCS::SetPropAdvanceCmd(int engineNum, double setting)
{
unsigned int ctr;
if (engineNum < (int)ThrottlePos.size()) {
if (engineNum < 0) {
for (ctr=0;ctr<PropAdvanceCmd.size();ctr++) PropAdvanceCmd[ctr] = setting;
} else {
PropAdvanceCmd[engineNum] = setting;
}
}
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGFCS::SetPropAdvance(int engineNum, double setting)
{
unsigned int ctr;
if (engineNum < (int)ThrottlePos.size()) {
if (engineNum < 0) {
for (ctr=0;ctr<=PropAdvanceCmd.size();ctr++) PropAdvance[ctr] = PropAdvanceCmd[ctr];
} else {
PropAdvance[engineNum] = setting;
}
}
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
bool FGFCS::Load(FGConfigFile* AC_cfg)
{
string token, delimiter;
string name, file, fname;
unsigned i;
vector <FGFCSComponent*> *Components;
FGConfigFile *FCS_cfg;
Components=0;
// Determine if the FCS/Autopilot is defined inline in the aircraft configuration
// file or in a separate file. Set up the config file class as appropriate.
delimiter = AC_cfg->GetValue();
name = AC_cfg->GetValue("NAME");
fname = AC_cfg->GetValue("FILE");
if ( AC_cfg->GetValue("NORMALIZE") == "FALSE") {
DoNormalize = false;
cout << " Automatic Control Surface Normalization Disabled" << endl;
}
# ifndef macintosh
// file = "control/" + fname + ".xml";
file = FDMExec->GetAircraftPath() + "/" + FDMExec->GetModelName() + "/" + fname + ".xml";
# else
// file = "control;" + fname + ".xml";
file = FDMExec->GetAircraftPath() + ";" + FDMExec->GetModelName() + ";" + fname + ".xml";
# endif
if (name.empty()) {
name = fname;
if (file.empty()) {
cerr << "FCS/Autopilot does not appear to be defined inline nor in a file" << endl;
} else {
FCS_cfg = new FGConfigFile(file);
if (!FCS_cfg->IsOpen()) {
cerr << "Could not open " << delimiter << " file: " << file << endl;
return false;
} else {
AC_cfg = FCS_cfg; // set local config file object pointer to FCS config
// file object pointer
}
}
} else {
AC_cfg->GetNextConfigLine();
}
if (delimiter == "AUTOPILOT") {
Components = &APComponents;
Name = "Autopilot: " + name;
} else if (delimiter == "FLIGHT_CONTROL") {
Components = &FCSComponents;
Name = "FCS: " + name;
} else {
cerr << endl << "Unknown FCS delimiter" << endl << endl;
}
if (debug_lvl > 0) cout << " Control System Name: " << Name << endl;
while ((token = AC_cfg->GetValue()) != string("/" + delimiter)) {
if (token == "COMPONENT") {
token = AC_cfg->GetValue("TYPE");
if (debug_lvl > 0) cout << endl << " Loading Component \""
<< AC_cfg->GetValue("NAME")
<< "\" of type: " << token << endl;
if ((token == "LAG_FILTER") ||
(token == "LEAD_LAG_FILTER") ||
(token == "SECOND_ORDER_FILTER") ||
(token == "WASHOUT_FILTER") ||
(token == "INTEGRATOR") ) {
Components->push_back(new FGFilter(this, AC_cfg));
} else if ((token == "PURE_GAIN") ||
(token == "SCHEDULED_GAIN") ||
(token == "AEROSURFACE_SCALE") ) {
Components->push_back(new FGGain(this, AC_cfg));
} else if (token == "SUMMER") {
Components->push_back(new FGSummer(this, AC_cfg));
} else if (token == "DEADBAND") {
Components->push_back(new FGDeadBand(this, AC_cfg));
} else if (token == "GRADIENT") {
Components->push_back(new FGGradient(this, AC_cfg));
} else if (token == "SWITCH") {
Components->push_back(new FGSwitch(this, AC_cfg));
} else if (token == "KINEMAT") {
Components->push_back(new FGKinemat(this, AC_cfg));
} else {
cerr << "Unknown token [" << token << "] in FCS portion of config file" << endl;
return false;
}
if (AC_cfg->GetNextConfigLine() == "EOF") break;
}
}
//collect information for normalizing control surfaces
string nodeName;
for (i=0; i<Components->size(); i++) {
if ( (((*Components)[i])->GetType() == "AEROSURFACE_SCALE"
|| ((*Components)[i])->GetType() == "KINEMAT")
&& ((*Components)[i])->GetOutputNode() ) {
nodeName = ((*Components)[i])->GetOutputNode()->GetName();
if ( nodeName == "elevator-pos-rad" ) {
ToNormalize[iDe]=i;
} else if ( nodeName == "left-aileron-pos-rad"
|| nodeName == "aileron-pos-rad" ) {
ToNormalize[iDaL]=i;
} else if ( nodeName == "right-aileron-pos-rad" ) {
ToNormalize[iDaR]=i;
} else if ( nodeName == "rudder-pos-rad" ) {
ToNormalize[iDr]=i;
} else if ( nodeName == "speedbrake-pos-rad" ) {
ToNormalize[iDsb]=i;
} else if ( nodeName == "spoiler-pos-rad" ) {
ToNormalize[iDsp]=i;
} else if ( nodeName == "flap-pos-deg" ) {
ToNormalize[iDf]=i;
}
}
}
if (delimiter == "FLIGHT_CONTROL") bindModel();
return true;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
double FGFCS::GetBrake(FGLGear::BrakeGroup bg)
{
switch (bg) {
case FGLGear::bgLeft:
return LeftBrake;
case FGLGear::bgRight:
return RightBrake;
case FGLGear::bgCenter:
return CenterBrake;
default:
cerr << "GetBrake asked to return a bogus brake value" << endl;
}
return 0.0;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
string FGFCS::GetComponentStrings(string delimeter)
{
unsigned int comp;
string CompStrings = "";
bool firstime = true;
for (comp = 0; comp < FCSComponents.size(); comp++) {
if (firstime) firstime = false;
else CompStrings += delimeter;
CompStrings += FCSComponents[comp]->GetName();
}
for (comp = 0; comp < APComponents.size(); comp++)
{
CompStrings += delimeter;
CompStrings += APComponents[comp]->GetName();
}
return CompStrings;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
string FGFCS::GetComponentValues(string delimeter)
{
unsigned int comp;
string CompValues = "";
char buffer[12];
bool firstime = true;
for (comp = 0; comp < FCSComponents.size(); comp++) {
if (firstime) firstime = false;
else CompValues += delimeter;
sprintf(buffer, "%9.6f", FCSComponents[comp]->GetOutput());
CompValues += string(buffer);
}
for (comp = 0; comp < APComponents.size(); comp++) {
sprintf(buffer, "%s%9.6f", delimeter.c_str(), APComponents[comp]->GetOutput());
CompValues += string(buffer);
}
return CompValues;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGFCS::AddThrottle(void)
{
ThrottleCmd.push_back(0.0);
ThrottlePos.push_back(0.0);
MixtureCmd.push_back(0.0); // assume throttle and mixture are coupled
MixturePos.push_back(0.0);
PropAdvanceCmd.push_back(0.0); // assume throttle and prop pitch are coupled
PropAdvance.push_back(0.0);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGFCS::AddGear(void)
{
SteerPosDeg.push_back(0.0);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGFCS::Normalize(void) {
//not all of these are guaranteed to be defined for every model
//those that are have an index >=0 in the ToNormalize array
//ToNormalize is filled in Load()
if ( ToNormalize[iDe] > -1 ) {
DePos[ofNorm] = FCSComponents[ToNormalize[iDe]]->GetOutputPct();
}
if ( ToNormalize[iDaL] > -1 ) {
DaLPos[ofNorm] = FCSComponents[ToNormalize[iDaL]]->GetOutputPct();
}
if ( ToNormalize[iDaR] > -1 ) {
DaRPos[ofNorm] = FCSComponents[ToNormalize[iDaR]]->GetOutputPct();
}
if ( ToNormalize[iDr] > -1 ) {
DrPos[ofNorm] = FCSComponents[ToNormalize[iDr]]->GetOutputPct();
}
if ( ToNormalize[iDsb] > -1 ) {
DsbPos[ofNorm] = FCSComponents[ToNormalize[iDsb]]->GetOutputPct();
}
if ( ToNormalize[iDsp] > -1 ) {
DspPos[ofNorm] = FCSComponents[ToNormalize[iDsp]]->GetOutputPct();
}
if ( ToNormalize[iDf] > -1 ) {
DfPos[ofNorm] = FCSComponents[ToNormalize[iDf]]->GetOutputPct();
}
DePos[ofMag] = fabs(DePos[ofRad]);
DaLPos[ofMag] = fabs(DaLPos[ofRad]);
DaRPos[ofMag] = fabs(DaRPos[ofRad]);
DrPos[ofMag] = fabs(DrPos[ofRad]);
DsbPos[ofMag] = fabs(DsbPos[ofRad]);
DspPos[ofMag] = fabs(DspPos[ofRad]);
DfPos[ofMag] = fabs(DfPos[ofRad]);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGFCS::bind(void)
{
PropertyManager->Tie("fcs/aileron-cmd-norm", this,
&FGFCS::GetDaCmd,
&FGFCS::SetDaCmd,
true);
PropertyManager->Tie("fcs/elevator-cmd-norm", this,
&FGFCS::GetDeCmd,
&FGFCS::SetDeCmd,
true);
PropertyManager->Tie("fcs/rudder-cmd-norm", this,
&FGFCS::GetDrCmd,
&FGFCS::SetDrCmd,
true);
PropertyManager->Tie("fcs/steer-cmd-norm", this,
&FGFCS::GetDsCmd,
&FGFCS::SetDsCmd,
true);
PropertyManager->Tie("fcs/flap-cmd-norm", this,
&FGFCS::GetDfCmd,
&FGFCS::SetDfCmd,
true);
PropertyManager->Tie("fcs/speedbrake-cmd-norm", this,
&FGFCS::GetDsbCmd,
&FGFCS::SetDsbCmd,
true);
PropertyManager->Tie("fcs/spoiler-cmd-norm", this,
&FGFCS::GetDspCmd,
&FGFCS::SetDspCmd,
true);
PropertyManager->Tie("fcs/pitch-trim-cmd-norm", this,
&FGFCS::GetPitchTrimCmd,
&FGFCS::SetPitchTrimCmd,
true);
PropertyManager->Tie("fcs/roll-trim-cmd-norm", this,
&FGFCS::GetRollTrimCmd,
&FGFCS::SetRollTrimCmd,
true);
PropertyManager->Tie("fcs/yaw-trim-cmd-norm", this,
&FGFCS::GetYawTrimCmd,
&FGFCS::SetYawTrimCmd,
true);
PropertyManager->Tie("gear/gear-cmd-norm", this,
&FGFCS::GetGearCmd,
&FGFCS::SetGearCmd,
true);
PropertyManager->Tie("fcs/left-aileron-pos-rad", this,ofRad,
&FGFCS::GetDaLPos,
&FGFCS::SetDaLPos,
true);
PropertyManager->Tie("fcs/left-aileron-pos-norm", this,ofNorm,
&FGFCS::GetDaLPos,
&FGFCS::SetDaLPos,
true);
PropertyManager->Tie("fcs/mag-left-aileron-pos-rad", this,ofMag,
&FGFCS::GetDaLPos,
&FGFCS::SetDaLPos,
true);
PropertyManager->Tie("fcs/right-aileron-pos-rad", this,ofRad,
&FGFCS::GetDaRPos,
&FGFCS::SetDaRPos,
true);
PropertyManager->Tie("fcs/right-aileron-pos-norm", this,ofNorm,
&FGFCS::GetDaRPos,
&FGFCS::SetDaRPos,
true);
PropertyManager->Tie("fcs/mag-right-aileron-pos-rad", this,ofMag,
&FGFCS::GetDaRPos,
&FGFCS::SetDaRPos,
true);
PropertyManager->Tie("fcs/elevator-pos-rad", this, ofRad,
&FGFCS::GetDePos,
&FGFCS::SetDePos,
true );
PropertyManager->Tie("fcs/elevator-pos-norm", this,ofNorm,
&FGFCS::GetDePos,
&FGFCS::SetDePos,
true );
PropertyManager->Tie("fcs/mag-elevator-pos-rad", this,ofMag,
&FGFCS::GetDePos,
&FGFCS::SetDePos,
true );
PropertyManager->Tie("fcs/rudder-pos-rad", this,ofRad,
&FGFCS::GetDrPos,
&FGFCS::SetDrPos,
true);
PropertyManager->Tie("fcs/rudder-pos-norm", this,ofNorm,
&FGFCS::GetDrPos,
&FGFCS::SetDrPos,
true);
PropertyManager->Tie("fcs/mag-rudder-pos-rad", this,ofMag,
&FGFCS::GetDrPos,
&FGFCS::SetDrPos,
true);
PropertyManager->Tie("fcs/flap-pos-deg", this,ofRad,
&FGFCS::GetDfPos,
&FGFCS::SetDfPos,
true);
PropertyManager->Tie("fcs/flap-pos-norm", this,ofNorm,
&FGFCS::GetDfPos,
&FGFCS::SetDfPos,
true);
PropertyManager->Tie("fcs/speedbrake-pos-rad", this,ofRad,
&FGFCS::GetDsbPos,
&FGFCS::SetDsbPos,
true);
PropertyManager->Tie("fcs/speedbrake-pos-norm", this,ofNorm,
&FGFCS::GetDsbPos,
&FGFCS::SetDsbPos,
true);
PropertyManager->Tie("fcs/mag-speedbrake-pos-rad", this,ofMag,
&FGFCS::GetDsbPos,
&FGFCS::SetDsbPos,
true);
PropertyManager->Tie("fcs/spoiler-pos-rad", this,ofRad,
&FGFCS::GetDspPos,
&FGFCS::SetDspPos,
true);
PropertyManager->Tie("fcs/spoiler-pos-norm", this,ofNorm,
&FGFCS::GetDspPos,
&FGFCS::SetDspPos,
true);
PropertyManager->Tie("fcs/mag-spoiler-pos-rad", this,ofMag,
&FGFCS::GetDspPos,
&FGFCS::SetDspPos,
true);
PropertyManager->Tie("gear/gear-pos-norm", this,
&FGFCS::GetGearPos,
&FGFCS::SetGearPos,
true);
PropertyManager->Tie("ap/elevator_cmd", this,
&FGFCS::GetAPDeCmd,
&FGFCS::SetAPDeCmd,
true);
PropertyManager->Tie("ap/aileron_cmd", this,
&FGFCS::GetAPDaCmd,
&FGFCS::SetAPDaCmd,
true);
PropertyManager->Tie("ap/rudder_cmd", this,
&FGFCS::GetAPDrCmd,
&FGFCS::SetAPDrCmd,
true);
PropertyManager->Tie("ap/throttle_cmd", this,
&FGFCS::GetAPThrottleCmd,
&FGFCS::SetAPThrottleCmd,
true);
PropertyManager->Tie("ap/attitude_setpoint", this,
&FGFCS::GetAPAttitudeSetPt,
&FGFCS::SetAPAttitudeSetPt,
true);
PropertyManager->Tie("ap/altitude_setpoint", this,
&FGFCS::GetAPAltitudeSetPt,
&FGFCS::SetAPAltitudeSetPt,
true);
PropertyManager->Tie("ap/heading_setpoint", this,
&FGFCS::GetAPHeadingSetPt,
&FGFCS::SetAPHeadingSetPt,
true);
PropertyManager->Tie("ap/airspeed_setpoint", this,
&FGFCS::GetAPAirspeedSetPt,
&FGFCS::SetAPAirspeedSetPt,
true);
PropertyManager->Tie("ap/acquire_attitude", this,
&FGFCS::GetAPAcquireAttitude,
&FGFCS::SetAPAcquireAttitude,
true);
PropertyManager->Tie("ap/acquire_altitude", this,
&FGFCS::GetAPAcquireAltitude,
&FGFCS::SetAPAcquireAltitude,
true);
PropertyManager->Tie("ap/acquire_heading", this,
&FGFCS::GetAPAcquireHeading,
&FGFCS::SetAPAcquireHeading,
true);
PropertyManager->Tie("ap/acquire_airspeed", this,
&FGFCS::GetAPAcquireAirspeed,
&FGFCS::SetAPAcquireAirspeed,
true);
PropertyManager->Tie("ap/attitude_hold", this,
&FGFCS::GetAPAttitudeHold,
&FGFCS::SetAPAttitudeHold,
true);
PropertyManager->Tie("ap/altitude_hold", this,
&FGFCS::GetAPAltitudeHold,
&FGFCS::SetAPAltitudeHold,
true);
PropertyManager->Tie("ap/heading_hold", this,
&FGFCS::GetAPHeadingHold,
&FGFCS::SetAPHeadingHold,
true);
PropertyManager->Tie("ap/airspeed_hold", this,
&FGFCS::GetAPAirspeedHold,
&FGFCS::SetAPAirspeedHold,
true);
PropertyManager->Tie("ap/wingslevel_hold", this,
&FGFCS::GetAPWingsLevelHold,
&FGFCS::SetAPWingsLevelHold,
true);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGFCS::bindModel(void)
{
unsigned i;
char tmp[80];
for (i=0; i<ThrottleCmd.size(); i++) {
snprintf(tmp,80,"fcs/throttle-cmd-norm[%u]",i);
PropertyManager->Tie( tmp,this,i,
&FGFCS::GetThrottleCmd,
&FGFCS::SetThrottleCmd,
true );
snprintf(tmp,80,"fcs/throttle-pos-norm[%u]",i);
PropertyManager->Tie( tmp,this,i,
&FGFCS::GetThrottlePos,
&FGFCS::SetThrottlePos,
true );
if ( MixtureCmd.size() > i ) {
snprintf(tmp,80,"fcs/mixture-cmd-norm[%u]",i);
PropertyManager->Tie( tmp,this,i,
&FGFCS::GetMixtureCmd,
&FGFCS::SetMixtureCmd,
true );
snprintf(tmp,80,"fcs/mixture-pos-norm[%u]",i);
PropertyManager->Tie( tmp,this,i,
&FGFCS::GetMixturePos,
&FGFCS::SetMixturePos,
true );
}
if ( PropAdvanceCmd.size() > i ) {
snprintf(tmp,80,"fcs/advance-cmd-norm[%u]",i);
PropertyManager->Tie( tmp,this,i,
&FGFCS::GetPropAdvanceCmd,
&FGFCS::SetPropAdvanceCmd,
true );
snprintf(tmp,80,"fcs/advance-pos-norm[%u]",i);
PropertyManager->Tie( tmp,this,i,
&FGFCS::GetPropAdvance,
&FGFCS::SetPropAdvance,
true );
}
}
for (i=0; i<SteerPosDeg.size(); i++) {
if (GroundReactions->GetGearUnit(i)->GetSteerable()) {
snprintf(tmp,80,"fcs/steer-pos-deg[%u]",i);
PropertyManager->Tie( tmp, this, i,
&FGFCS::GetSteerPosDeg,
&FGFCS::SetSteerPosDeg,
true );
}
}
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGFCS::unbind(FGPropertyManager *node)
{
int N = node->nChildren();
for(int i=0;i<N;i++) {
if(node->getChild(i)->nChildren() ) {
unbind( (FGPropertyManager*)node->getChild(i) );
} else if( node->getChild(i)->isTied() ) {
node->getChild(i)->untie();
}
}
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGFCS::convert(void)
{
for (int i=0; i<FCSComponents.size(); i++) {
FCSComponents[i]->convert();
}
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// The bitmasked value choices are as follows:
// unset: In this case (the default) JSBSim would only print
// out the normally expected messages, essentially echoing
// the config files as they are read. If the environment
// variable is not set, debug_lvl is set to 1 internally
// 0: This requests JSBSim not to output any messages
// whatsoever.
// 1: This value explicity requests the normal JSBSim
// startup messages
// 2: This value asks for a message to be printed out when
// a class is instantiated
// 4: When this value is set, a message is displayed when a
// FGModel object executes its Run() method
// 8: When this value is set, various runtime state variables
// are printed out periodically
// 16: When set various parameters are sanity checked and
// a message is printed out when they go out of bounds
void FGFCS::Debug(int from)
{
if (debug_lvl <= 0) return;
if (debug_lvl & 1) { // Standard console startup message output
if (from == 0) { // Constructor
}
}
if (debug_lvl & 2 ) { // Instantiation/Destruction notification
if (from == 0) cout << "Instantiated: FGFCS" << endl;
if (from == 1) cout << "Destroyed: FGFCS" << endl;
}
if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
}
if (debug_lvl & 8 ) { // Runtime state variables
}
if (debug_lvl & 16) { // Sanity checking
}
if (debug_lvl & 64) {
if (from == 0) { // Constructor
cout << IdSrc << endl;
cout << IdHdr << endl;
}
}
}
}

View file

@ -1,651 +0,0 @@
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Header: FGGFCS.h
Author: Jon S. Berndt
Date started: 12/12/98
------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU 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 General Public License for more
details.
You should have received a copy of the GNU 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 General Public License can also be found on
the world wide web at http://www.gnu.org.
HISTORY
--------------------------------------------------------------------------------
12/12/98 JSB Created
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
SENTRY
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#ifndef FGFCS_H
#define FGFCS_H
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#ifdef FGFS
# include <simgear/compiler.h>
# ifdef SG_HAVE_STD_INCLUDES
# include <vector>
# else
# include <vector.h>
# endif
#else
# include <vector>
#endif
#include <string>
#include "filtersjb/FGFCSComponent.h"
#include "FGModel.h"
#include "FGLGear.h"
#include "FGConfigFile.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_FCS "$Id$"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
namespace JSBSim {
typedef enum { iDe=0, iDaL, iDaR, iDr, iDsb, iDsp, iDf, NNorm } FcIdx;
typedef enum { ofRad=0, ofNorm, ofMag , NForms} OutputForm;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DOCUMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/** Encapsulates the Flight Control System (FCS) functionality.
This class owns and contains the list of FGFCSComponents
that define the control system for this aircraft. The config file for the
aircraft contains a description of the control path that starts at an input
or command and ends at an effector, e.g. an aerosurface. The FCS components
which comprise the control laws for an axis are defined sequentially in
the configuration file. For instance, for the X-15:
<pre>
\<FLIGHT_CONTROL NAME="X-15 SAS">
\<COMPONENT NAME="Pitch Trim Sum" TYPE="SUMMER">
INPUT fcs/elevator-cmd-norm
INPUT fcs/pitch-trim-cmd-norm
CLIPTO -1 1
\</COMPONENT>
\<COMPONENT NAME="Pitch Command Scale" TYPE="AEROSURFACE_SCALE">
INPUT fcs/pitch-trim-sum
MIN -50
MAX 50
\</COMPONENT>
\<COMPONENT NAME="Pitch Gain 1" TYPE="PURE_GAIN">
INPUT fcs/pitch-command-scale
GAIN -0.36
\</COMPONENT>
... etc.
</pre>
In the above case we can see the first few components of the pitch channel
defined. The input to the first component, as can be seen in the "Pitch trim
sum" component, is really the sum of two parameters: elevator command (from
the stick - a pilot input), and pitch trim. The type of this component is
"Summer".
The next component created is an aerosurface scale component - a type of
gain (see the LoadFCS() method for insight on how the various types of
components map into the actual component classes). This continues until the
final component for an axis when the
OUTPUT keyword specifies where the output is supposed to go. See the
individual components for more information on how they are mechanized.
Another option for the flight controls portion of the config file is that in
addition to using the "NAME" attribute in,
<pre>
\<FLIGHT_CONTROL NAME="X-15 SAS">
</pre>
one can also supply a filename:
<pre>
\<FLIGHT_CONTROL NAME="X-15 SAS" FILE="X15.xml">
\</FLIGHT_CONTROL>
</pre>
In this case, the FCS would be read in from another file.
@author Jon S. Berndt
@version $Id$
@see FGFCSComponent
@see FGConfigFile
@see FGGain
@see FGSummer
@see FGSwitch
@see FGGradient
@see FGFilter
@see FGDeadBand
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DECLARATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
class FGFCS : public FGModel {
public:
/** Constructor
@param Executive a pointer to the parent executive object */
FGFCS(FGFDMExec*);
/// Destructor
~FGFCS();
/** Runs the Flight Controls model; called by the Executive
@return false if no error */
bool Run(void);
/// @name Pilot input command retrieval
//@{
/** Gets the aileron command.
@return aileron command in percent */
inline double GetDaCmd(void) const { return DaCmd; }
/** Gets the elevator command.
@return elevator command in percent */
inline double GetDeCmd(void) const { return DeCmd; }
/** Gets the rudder command.
@return rudder command in percent */
inline double GetDrCmd(void) const { return DrCmd; }
/** Gets the steering command.
@return steering command in percent */
inline double GetDsCmd(void) const { return DsCmd; }
/** Gets the flaps command.
@return flaps command in percent */
inline double GetDfCmd(void) const { return DfCmd; }
/** Gets the speedbrake command.
@return speedbrake command in percent */
inline double GetDsbCmd(void) const { return DsbCmd; }
/** Gets the spoiler command.
@return spoiler command in percent */
inline double GetDspCmd(void) const { return DspCmd; }
/** Gets the throttle command.
@param engine engine ID number
@return throttle command in percent ( 0 - 100) for the given engine */
double GetThrottleCmd(int engine) const;
/** Gets the mixture command.
@param engine engine ID number
@return mixture command in percent ( 0 - 100) for the given engine */
inline double GetMixtureCmd(int engine) const { return MixtureCmd[engine]; }
/** Gets the prop pitch command.
@param engine engine ID number
@return pitch command in percent ( 0.0 - 1.0) for the given engine */
inline double GetPropAdvanceCmd(int engine) const { return PropAdvanceCmd[engine]; }
/** Gets the pitch trim command.
@return pitch trim command in percent */
inline double GetPitchTrimCmd(void) const { return PTrimCmd; }
/** Gets the rudder trim command.
@return rudder trim command in percent */
inline double GetYawTrimCmd(void) const { return YTrimCmd; }
/** Gets the aileron trim command.
@return aileron trim command in percent */
inline double GetRollTrimCmd(void) const { return RTrimCmd; }
/** Get the gear extend/retract command. 0 commands gear up, 1 down.
defaults to down.
@return the current value of the gear extend/retract command*/
inline double GetGearCmd(void) const { return GearCmd; }
//@}
/// @name AUTOPilot -> FCS effectors command retrieval
//@{
/** Gets the AUTOPilot aileron command.
@return aileron command in radians */
inline double GetAPDaCmd(void) const { return AP_DaCmd; }
/** Gets the AUTOPilot elevator command.
@return elevator command in radians */
inline double GetAPDeCmd(void) const { return AP_DeCmd; }
/** Gets the AUTOPilot rudder command.
@return rudder command in radians */
inline double GetAPDrCmd(void) const { return AP_DrCmd; }
/** Gets the AUTOPilot throttle (all engines) command.
@return throttle command in percent */
inline double GetAPThrottleCmd(void) const { return AP_ThrottleCmd; }
//@}
/// @name AUTOPilot setpoint retrieval
//@{
/** Gets the autopilot pitch attitude setpoint
@return Pitch attitude setpoint in radians */
inline double GetAPAttitudeSetPt(void) const {return APAttitudeSetPt;}
/** Gets the autopilot altitude setpoint
@return Altitude setpoint in feet */
inline double GetAPAltitudeSetPt(void) const {return APAltitudeSetPt;}
/** Gets the autopilot heading setpoint
@return Heading setpoint in radians */
inline double GetAPHeadingSetPt(void) const {return APHeadingSetPt;}
/** Gets the autopilot airspeed setpoint
@return Airspeed setpoint in fps */
inline double GetAPAirspeedSetPt(void) const {return APAirspeedSetPt;}
//@}
/// @name AUTOPilot setpoint setting
//@{
/// Sets the autopilot pitch attitude setpoint
inline void SetAPAttitudeSetPt(double set) {APAttitudeSetPt = set;}
/// Sets the autopilot altitude setpoint
inline void SetAPAltitudeSetPt(double set) {APAltitudeSetPt = set;}
/// Sets the autopilot heading setpoint
inline void SetAPHeadingSetPt(double set) {APHeadingSetPt = set;}
/// Sets the autopilot airspeed setpoint
inline void SetAPAirspeedSetPt(double set) {APAirspeedSetPt = set;}
//@}
/// @name AUTOPilot mode setting
//@{
/** Turns on/off the attitude-seeking autopilot.
@param set true turns the mode on, false turns it off **/
inline void SetAPAcquireAttitude(bool set) {APAcquireAttitude = set;}
/** Turns on/off the altitude-seeking autopilot.
@param set true turns the mode on, false turns it off **/
inline void SetAPAcquireAltitude(bool set) {APAcquireAltitude = set;}
/** Turns on/off the heading-seeking autopilot.
@param set true turns the mode on, false turns it off **/
inline void SetAPAcquireHeading(bool set) {APAcquireHeading = set;}
/** Turns on/off the airspeed-seeking autopilot.
@param set true turns the mode on, false turns it off **/
inline void SetAPAcquireAirspeed(bool set) {APAcquireAirspeed = set;}
/** Turns on/off the attitude-holding autopilot.
@param set true turns the mode on, false turns it off **/
inline void SetAPAttitudeHold(bool set) {APAttitudeHold = set;}
/** Turns on/off the altitude-holding autopilot.
@param set true turns the mode on, false turns it off **/
inline void SetAPAltitudeHold(bool set) {APAltitudeHold = set;}
/** Turns on/off the heading-holding autopilot.
@param set true turns the mode on, false turns it off **/
inline void SetAPHeadingHold(bool set) {APHeadingHold = set;}
/** Turns on/off the airspeed-holding autopilot.
@param set true turns the mode on, false turns it off **/
inline void SetAPAirspeedHold(bool set) {APAirspeedHold = set;}
/** Turns on/off the wing-leveler autopilot.
@param set true turns the mode on, false turns it off **/
inline void SetAPWingsLevelHold(bool set) {APWingsLevelHold = set;}
//@}
/// @name AUTOPilot mode retrieval
//@{
/** Retrieves the on/off mode of the autopilot AcquireAttitude mode
@return true if on, false if off */
inline bool GetAPAcquireAttitude(void) const {return APAcquireAttitude;}
/** Retrieves the on/off mode of the autopilot AcquireAltitude mode
@return true if on, false if off */
inline bool GetAPAcquireAltitude(void) const {return APAcquireAltitude;}
/** Retrieves the on/off mode of the autopilot AcquireHeading mode
@return true if on, false if off */
inline bool GetAPAcquireHeading(void) const {return APAcquireHeading;}
/** Retrieves the on/off mode of the autopilot AcquireAirspeed mode
@return true if on, false if off */
inline bool GetAPAcquireAirspeed(void) const {return APAcquireAirspeed;}
/** Retrieves the on/off mode of the autopilot AttitudeHold mode
@return true if on, false if off */
inline bool GetAPAttitudeHold(void) const {return APAttitudeHold;}
/** Retrieves the on/off mode of the autopilot AltitudeHold mode
@return true if on, false if off */
inline bool GetAPAltitudeHold(void) const {return APAltitudeHold;}
/** Retrieves the on/off mode of the autopilot HeadingHold mode
@return true if on, false if off */
inline bool GetAPHeadingHold(void) const {return APHeadingHold;}
/** Retrieves the on/off mode of the autopilot AirspeedHold mode
@return true if on, false if off */
inline bool GetAPAirspeedHold(void) const {return APAirspeedHold;}
/** Retrieves the on/off mode of the autopilot WingsLevelHold mode
@return true if on, false if off */
inline bool GetAPWingsLevelHold(void) const {return APWingsLevelHold;}
//@}
/// @name Aerosurface position retrieval
//@{
/** Gets the left aileron position.
@return aileron position in radians */
inline double GetDaLPos( int form = ofRad )
const { return DaLPos[form]; }
/// @name Aerosurface position retrieval
//@{
/** Gets the right aileron position.
@return aileron position in radians */
inline double GetDaRPos( int form = ofRad )
const { return DaRPos[form]; }
/** Gets the elevator position.
@return elevator position in radians */
inline double GetDePos( int form = ofRad )
const { return DePos[form]; }
/** Gets the rudder position.
@return rudder position in radians */
inline double GetDrPos( int form = ofRad )
const { return DrPos[form]; }
/** Gets the speedbrake position.
@return speedbrake position in radians */
inline double GetDsbPos( int form = ofRad )
const { return DsbPos[form]; }
/** Gets the spoiler position.
@return spoiler position in radians */
inline double GetDspPos( int form = ofRad )
const { return DspPos[form]; }
/** Gets the flaps position.
@return flaps position in radians */
inline double GetDfPos( int form = ofRad )
const { return DfPos[form]; }
/** Gets the throttle position.
@param engine engine ID number
@return throttle position for the given engine in percent ( 0 - 100)*/
double GetThrottlePos(int engine) const;
/** Gets the mixture position.
@param engine engine ID number
@return mixture position for the given engine in percent ( 0 - 100)*/
inline double GetMixturePos(int engine) const { return MixturePos[engine]; }
/** Gets the steering position.
@return steering position in degrees */
double GetSteerPosDeg(int gear) const { return SteerPosDeg[gear]; }
/** Gets the gear position (0 up, 1 down), defaults to down
@return gear position (0 up, 1 down) */
inline double GetGearPos(void) const { return GearPos; }
/** Gets the prop pitch position.
@param engine engine ID number
@return prop pitch position for the given engine in percent ( 0.0-1.0)*/
inline double GetPropAdvance(int engine) const { return PropAdvance[engine]; }
//@}
/** Retrieves the State object pointer.
This is used by the FGFCS-owned components.
@return pointer to the State object */
inline FGState* GetState(void) { return State; }
/** Retrieves all component names for inclusion in output stream
@param delimeter either a tab or comma string depending on output type
@return a string containing the descriptive names for all components */
string GetComponentStrings(string delimeter);
/** Retrieves all component outputs for inclusion in output stream
@param delimeter either a tab or comma string depending on output type
@return a string containing the numeric values for the current set of
component outputs */
string GetComponentValues(string delimeter);
/// @name Pilot input command setting
//@{
/** Sets the aileron command
@param cmd aileron command in percent*/
inline void SetDaCmd( double cmd ) { DaCmd = cmd; }
/** Sets the elevator command
@param cmd elevator command in percent*/
inline void SetDeCmd(double cmd ) { DeCmd = cmd; }
/** Sets the rudder command
@param cmd rudder command in percent*/
inline void SetDrCmd(double cmd) { DrCmd = cmd; }
/** Sets the steering command
@param cmd steering command in percent*/
inline void SetDsCmd(double cmd) { DsCmd = cmd; }
/** Sets the flaps command
@param cmd flaps command in percent*/
inline void SetDfCmd(double cmd) { DfCmd = cmd; }
/** Sets the speedbrake command
@param cmd speedbrake command in percent*/
inline void SetDsbCmd(double cmd) { DsbCmd = cmd; }
/** Sets the spoilers command
@param cmd spoilers command in percent*/
inline void SetDspCmd(double cmd) { DspCmd = cmd; }
/** Sets the pitch trim command
@param cmd pitch trim command in percent*/
inline void SetPitchTrimCmd(double cmd) { PTrimCmd = cmd; }
/** Sets the rudder trim command
@param cmd rudder trim command in percent*/
inline void SetYawTrimCmd(double cmd) { YTrimCmd = cmd; }
/** Sets the aileron trim command
@param cmd aileron trim command in percent*/
inline void SetRollTrimCmd(double cmd) { RTrimCmd = cmd; }
/** Sets the throttle command for the specified engine
@param engine engine ID number
@param cmd throttle command in percent (0 - 100)*/
void SetThrottleCmd(int engine, double cmd);
/** Sets the mixture command for the specified engine
@param engine engine ID number
@param cmd mixture command in percent (0 - 100)*/
void SetMixtureCmd(int engine, double cmd);
/** Set the gear extend/retract command, defaults to down
@param gear command 0 for up, 1 for down */
void SetGearCmd(double gearcmd) { GearCmd = gearcmd; }
/** Sets the propeller pitch command for the specified engine
@param engine engine ID number
@param cmd mixture command in percent (0.0 - 1.0)*/
void SetPropAdvanceCmd(int engine, double cmd);
//@}
/// @name AUTOPilot -> FCS effector command setting
//@{
/** Sets the AUTOPilot aileron command
@param cmd AUTOPilot aileron command in radians*/
inline void SetAPDaCmd( double cmd ) { AP_DaCmd = cmd; }
/** Sets the AUTOPilot elevator command
@param cmd AUTOPilot elevator command in radians*/
inline void SetAPDeCmd(double cmd ) { AP_DeCmd = cmd; }
/** Sets the AUTOPilot rudder command
@param cmd AUTOPilot rudder command in radians*/
inline void SetAPDrCmd(double cmd) { AP_DrCmd = cmd; }
/** Sets the AUTOPilot throttle command
@param cmd AUTOPilot throttle command in percent*/
inline void SetAPThrottleCmd(double cmd) { AP_ThrottleCmd = cmd; }
//@}
/// @name Aerosurface position setting
//@{
/** Sets the left aileron position
@param cmd left aileron position in radians*/
inline void SetDaLPos( int form , double pos )
{ DaLPos[form] = pos; }
/** Sets the right aileron position
@param cmd right aileron position in radians*/
inline void SetDaRPos( int form , double pos )
{ DaRPos[form] = pos; }
/** Sets the elevator position
@param cmd elevator position in radians*/
inline void SetDePos( int form , double pos )
{ DePos[form] = pos; }
/** Sets the rudder position
@param cmd rudder position in radians*/
inline void SetDrPos( int form , double pos )
{ DrPos[form] = pos; }
/** Sets the flaps position
@param cmd flaps position in radians*/
inline void SetDfPos( int form , double pos )
{ DfPos[form] = pos; }
/** Sets the speedbrake position
@param cmd speedbrake position in radians*/
inline void SetDsbPos( int form , double pos )
{ DsbPos[form] = pos; }
/** Sets the spoiler position
@param cmd spoiler position in radians*/
inline void SetDspPos( int form , double pos )
{ DspPos[form] = pos; }
/** Sets the actual throttle setting for the specified engine
@param engine engine ID number
@param cmd throttle setting in percent (0 - 100)*/
void SetThrottlePos(int engine, double cmd);
/** Sets the actual mixture setting for the specified engine
@param engine engine ID number
@param cmd mixture setting in percent (0 - 100)*/
void SetMixturePos(int engine, double cmd);
/** Sets the steering position
@param cmd steering position in degrees*/
void SetSteerPosDeg(int gear, double pos) { SteerPosDeg[gear] = pos; }
/** Set the gear extend/retract position, defaults to down
@param gear position 0 up, 1 down */
void SetGearPos(double gearpos) { GearPos = gearpos; }
/** Sets the actual prop pitch setting for the specified engine
@param engine engine ID number
@param cmd prop pitch setting in percent (0.0 - 1.0)*/
void SetPropAdvance(int engine, double cmd);
//@}
/// @name Landing Gear brakes
//@{
/** Sets the left brake group
@param cmd brake setting in percent (0.0 - 1.0) */
void SetLBrake(double cmd) {LeftBrake = cmd;}
/** Sets the right brake group
@param cmd brake setting in percent (0.0 - 1.0) */
void SetRBrake(double cmd) {RightBrake = cmd;}
/** Sets the center brake group
@param cmd brake setting in percent (0.0 - 1.0) */
void SetCBrake(double cmd) {CenterBrake = cmd;}
/** Gets the brake for a specified group.
@param bg which brakegroup to retrieve the command for
@return the brake setting for the supplied brake group argument */
double GetBrake(FGLGear::BrakeGroup bg);
//@}
/** Loads the Flight Control System.
The FGAircraft instance is actually responsible for reading the config file
and calling the various Loadxx() methods of the other systems, passing in
the config file instance pointer. LoadFCS() is called from FGAircraft.
@param AC_cfg pointer to the config file instance
@return true if succesful */
bool Load(FGConfigFile* AC_cfg);
void AddThrottle(void);
void AddGear(void);
FGPropertyManager* GetPropertyManager(void) { return PropertyManager; }
void convert(void);
void bind(void);
void bindModel(void);
void unbind(FGPropertyManager *node);
private:
double DaCmd, DeCmd, DrCmd, DsCmd, DfCmd, DsbCmd, DspCmd;
double AP_DaCmd, AP_DeCmd, AP_DrCmd, AP_ThrottleCmd;
double DePos[NForms], DaLPos[NForms], DaRPos[NForms], DrPos[NForms];
double DfPos[NForms], DsbPos[NForms], DspPos[NForms];
double PTrimCmd, YTrimCmd, RTrimCmd;
vector <double> ThrottleCmd;
vector <double> ThrottlePos;
vector <double> MixtureCmd;
vector <double> MixturePos;
vector <double> PropAdvanceCmd;
vector <double> PropAdvance;
vector <double> SteerPosDeg;
double LeftBrake, RightBrake, CenterBrake; // Brake settings
double GearCmd,GearPos;
double APAttitudeSetPt, APAltitudeSetPt, APHeadingSetPt, APAirspeedSetPt;
bool APAcquireAttitude, APAcquireAltitude, APAcquireHeading, APAcquireAirspeed;
bool APAttitudeHold, APAltitudeHold, APHeadingHold, APAirspeedHold, APWingsLevelHold;
bool DoNormalize;
void Normalize(void);
vector <FGFCSComponent*> FCSComponents;
vector <FGFCSComponent*> APComponents;
int ToNormalize[NNorm];
void Debug(int from);
};
}
#endif

View file

@ -1,210 +0,0 @@
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Module: FGFactorGroup.cpp
Author: Tony Peden
Date started: 7/21/01
Purpose: Encapsulates coefficients in the mathematical construct:
factor*(coeff1 + coeff2 + coeff3 + ... + coeffn)
Called by: FGAerodynamics
------------- Copyright (C) 2001 Tony Peden (apeden@earthlink.net) -----------
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU 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 General Public License for more
details.
You should have received a copy of the GNU 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 General Public License can also be found on
the world wide web at http://www.gnu.org.
FUNCTIONAL DESCRIPTION
--------------------------------------------------------------------------------
This class models the stability derivative coefficient lookup tables or
equations. Note that the coefficients need not be calculated each delta-t.
Note that the values in a row which index into the table must be the same value
for each column of data, so the first column of numbers for each altitude are
seen to be equal, and there are the same number of values for each altitude.
See the header file FGFactorGroup.h for the values of the identifiers.
HISTORY
--------------------------------------------------------------------------------
7/21/01 TP Created
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "FGCoefficient.h"
#include "FGFactorGroup.h"
#include "FGState.h"
#include "FGFDMExec.h"
#ifndef FGFS
# if defined(sgi) && !defined(__GNUC__) && (_COMPILER_VERSION < 740)
# include <iomanip.h>
# else
# include <iomanip>
# endif
#else
# include STL_IOMANIP
#endif
namespace JSBSim {
static const char *IdSrc = "$Id$";
static const char *IdHdr = ID_FACTORGROUP;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
FGFactorGroup::FGFactorGroup( FGFDMExec* fdmex ) : FGCoefficient( fdmex)
{
FDMExec = fdmex;
totalValue = 0;
IsFactor = true;
Debug(0);
}
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
FGFactorGroup::~FGFactorGroup()
{
for (unsigned int i=0; i<sum.size(); i++) delete sum[i];
Debug(1);
}
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
bool FGFactorGroup::Load(FGConfigFile *AC_cfg)
{
string token;
if (AC_cfg) {
name = AC_cfg->GetValue("NAME");
AC_cfg->GetNextConfigLine();
*AC_cfg >> description;
token = AC_cfg->GetValue();
if (token == "FACTOR") {
FGCoefficient::Load(AC_cfg);
}
token = AC_cfg->GetValue();
while (token != string("/GROUP") ) {
sum.push_back( new FGCoefficient(FDMExec) );
sum.back()->Load(AC_cfg);
token = AC_cfg->GetValue();
}
AC_cfg->GetNextConfigLine();
return true;
} else {
return false;
}
}
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
double FGFactorGroup::TotalValue(void)
{
unsigned int i;
SDtotal = 0.0;
totalValue = 0.0;
for (i=0; i<sum.size(); i++) {
totalValue += sum[i]->TotalValue();
SDtotal += sum[i]->GetSD();
}
totalValue *= FGCoefficient::TotalValue();
SDtotal *= FGCoefficient::GetSD();
Debug(2);
return totalValue;
}
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
void FGFactorGroup::bind(FGPropertyManager* parent)
{
unsigned i;
node=parent->GetNode(name,true);
node->SetString("description",description);
FGCoefficient::bind(node);
for (i=0; i < sum.size(); i++) {
sum[i]->bind(node);
}
node=(FGPropertyManager*)node->getParent();
}
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
void FGFactorGroup::unbind(void)
{
unsigned i;
FGCoefficient::unbind();
for (i=0; i < sum.size(); i++) {
sum[i]->unbind();
}
}
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
// The bitmasked value choices are as follows:
// unset: In this case (the default) JSBSim would only print
// out the normally expected messages, essentially echoing
// the config files as they are read. If the environment
// variable is not set, debug_lvl is set to 1 internally
// 0: This requests JSBSim not to output any messages
// whatsoever.
// 1: This value explicity requests the normal JSBSim
// startup messages
// 2: This value asks for a message to be printed out when
// a class is instantiated
// 4: When this value is set, a message is displayed when a
// FGModel object executes its Run() method
// 8: When this value is set, various runtime state variables
// are printed out periodically
// 16: When set various parameters are sanity checked and
// a message is printed out when they go out of bounds
void FGFactorGroup::Debug(int from)
{
if (debug_lvl <= 0) return;
if (debug_lvl & 1) { // Standard console startup message output
}
if (debug_lvl & 2 ) { // Instantiation/Destruction notification
if (from == 0) cout << "Instantiated: FGFactorGroup" << endl;
if (from == 1) cout << "Destroyed: FGFactorGroup" << endl;
}
if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
}
if (debug_lvl & 8 ) { // Runtime state variables
if (from == 2) {
cout << "FGCoefficient::GetSD(): " << FGCoefficient::GetSD() << endl;
cout << "FGFactorGroup::SDtotal: " << SDtotal << endl;
}
}
if (debug_lvl & 16) { // Sanity checking
}
if (debug_lvl & 64) {
if (from == 0) { // Constructor
cout << IdSrc << endl;
cout << IdHdr << endl;
}
}
}
}

View file

@ -1,115 +0,0 @@
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Header: FGFactorGroup.h
Author: Tony Peden
Date started: 7/14/01
------------- Copyright (C) 2001 Tony Peden (apeden@earthlink.net ------------
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU 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 General Public License for more
details.
You should have received a copy of the GNU 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 General Public License can also be found on
the world wide web at http://www.gnu.org.
HISTORY
--------------------------------------------------------------------------------
12/28/98 JSB Created
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
SENTRY
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#ifndef FGFACTORGROUP_H
#define FGFACTORGROUP_H
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#ifdef FGFS
# include <simgear/compiler.h>
#endif
#include <vector>
#include <string>
#include "FGConfigFile.h"
#include "FGTable.h"
#include "FGCoefficient.h"
#include "FGAerodynamics.h"
#include "FGFactorGroup.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_FACTORGROUP "$Id$"
using std::vector;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
namespace JSBSim {
class FGFDMExec;
class FGState;
class FGAtmosphere;
class FGFCS;
class FGAircraft;
class FGPropagate;
class FGAuxiliary;
class FGOutput;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DOCUMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/** This class encapsulates the functionality needed to manage a factor group
i.e. factor*(coeff1 + coeff2 + coeff3)
@author Tony Peden
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DECLARATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
class FGFactorGroup: public FGCoefficient
{
public:
FGFactorGroup(FGFDMExec* fdmex);
~FGFactorGroup();
bool Load(FGConfigFile *AC_cfg);
double TotalValue(void);
inline double GetValue(void) const { return totalValue; }
inline double GetSD(void) { return SDtotal; }
inline double GetFactorSD(void) { return FGCoefficient::GetSD(); }
void bind(FGPropertyManager* parent);
void unbind(void);
private:
// typedef vector<FGCoefficient*> CoeffArray;
// CoeffArray sum;
double SDtotal;
double totalValue;
string description;
string name;
FGPropertyManager *node;
void Debug(int from);
};
}
#endif

View file

@ -1,180 +0,0 @@
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Source: FGForce.cpp
Author: Tony Peden
Date started: 6/10/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 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 General Public License for more
details.
You should have received a copy of the GNU 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 General Public License can also be found on
the world wide web at http://www.gnu.org.
HISTORY
--------------------------------------------------------------------------------
6/10/00 TP Created
FUNCTIONAL DESCRIPTION
--------------------------------------------------------------------------------
The purpose of this class is to provide storage for computed forces and
encapsulate all the functionality associated with transforming those
forces from their native coord system to the body system. This includes
computing the moments due to the difference between the point of application
and the cg.
*/
#include "FGFDMExec.h"
#include "FGAircraft.h"
#include "FGPropagate.h"
#include "FGMassBalance.h"
#include "FGState.h"
#include "FGForce.h"
namespace JSBSim {
static const char *IdSrc = "$Id$";
static const char *IdHdr = ID_FORCE;
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGForce::FGForce(FGFDMExec *FDMExec) :
ttype(tNone),
fdmex(FDMExec)
{
mT(1,1) = 1; //identity matrix
mT(2,2) = 1;
mT(3,3) = 1;
vSense.InitMatrix(1);
Debug(0);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGForce::~FGForce()
{
Debug(1);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGColumnVector3& FGForce::GetBodyForces(void)
{
vFb = Transform()*(vFn.multElementWise(vSense));
// Find the distance from this vector's acting location to the cg; this
// needs to be done like this to convert from structural to body coords.
// CG and RP values are in inches
vDXYZ = fdmex->GetMassBalance()->StructuralToBody(vActingXYZn);
vM = vMn + vDXYZ*vFb;
return vFb;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGMatrix33 FGForce::Transform(void)
{
switch(ttype) {
case tWindBody:
return fdmex->GetState()->GetTs2b();
case tLocalBody:
return fdmex->GetPropagate()->GetTl2b();
case tCustom:
case tNone:
return mT;
default:
cout << "Unrecognized tranform requested from FGForce::Transform()" << endl;
exit(1);
}
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGForce::SetAnglesToBody(double broll, double bpitch, double byaw)
{
if (ttype == tCustom) {
double cp,sp,cr,sr,cy,sy;
cp=cos(bpitch); sp=sin(bpitch);
cr=cos(broll); sr=sin(broll);
cy=cos(byaw); sy=sin(byaw);
mT(1,1)=cp*cy;
mT(1,2)=cp*sy;
mT(1,3)=-1*sp;
mT(2,1)=sr*sp*cy-cr*sy;
mT(2,2)=sr*sp*sy+cr*cy;
mT(2,3)=sr*cp;
mT(3,1)=cr*sp*cy+sr*sy;
mT(3,2)=cr*sp*sy-sr*cy;
mT(3,3)=cr*cp;
}
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// The bitmasked value choices are as follows:
// unset: In this case (the default) JSBSim would only print
// out the normally expected messages, essentially echoing
// the config files as they are read. If the environment
// variable is not set, debug_lvl is set to 1 internally
// 0: This requests JSBSim not to output any messages
// whatsoever.
// 1: This value explicity requests the normal JSBSim
// startup messages
// 2: This value asks for a message to be printed out when
// a class is instantiated
// 4: When this value is set, a message is displayed when a
// FGModel object executes its Run() method
// 8: When this value is set, various runtime state variables
// are printed out periodically
// 16: When set various parameters are sanity checked and
// a message is printed out when they go out of bounds
void FGForce::Debug(int from)
{
if (debug_lvl <= 0) return;
if (debug_lvl & 1) { // Standard console startup message output
if (from == 0) { // Constructor
}
}
if (debug_lvl & 2 ) { // Instantiation/Destruction notification
if (from == 0) cout << "Instantiated: FGForce" << endl;
if (from == 1) cout << "Destroyed: FGForce" << endl;
}
if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
}
if (debug_lvl & 8 ) { // Runtime state variables
}
if (debug_lvl & 16) { // Sanity checking
}
if (debug_lvl & 64) {
if (from == 0) { // Constructor
cout << IdSrc << endl;
cout << IdHdr << endl;
}
}
}
}

View file

@ -1,338 +0,0 @@
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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 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 General Public License for more
details.
You should have received a copy of the GNU 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 General Public License can also be found on
the world wide web at http://www.gnu.org.
HISTORY
--------------------------------------------------------------------------------
5/20/00 TP Created
FUNCTIONAL DESCRIPTION
--------------------------------------------------------------------------------
The purpose of this class is to provide storage for computed forces and
encapsulate all the functionality associated with transforming those
forces from their native coord system to the body system. This includes
computing the moments due to the difference between the point of application
and 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 "FGMatrix33.h"
#include "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 weight
need to be resolved into body axis components so that the aircraft acceleration
vectors, both translational and rotational, can be computed. Furthermore, the
moments produced by each force that does not act at a location corresponding to
the center of gravity also need to be computed. Unfortunately, the math required
to do this can be a bit messy and errors are easily introduced so the class
FGForce was created to provide these services in a consistent and reusable
manner.<br><br></p>
<h4>Basic usage</h4>
<p>FGForce requires that its users supply it with the location of the applied
force vector in JSBSim structural coordinates, the sense of each axis in that
coordinate system relative to the body system, the orientation of the vector
also relative to body coordinates and, of course, the force vector itself. With
this information it will compute both the body axis force components and the
resulting moments. Any moments inherently produced by the native system can be
supplied as well and they will be summed with those computed.</p>
<p>A good example for demonstrating the use of this class are the aerodynamic
forces: lift, drag, and side force and the aerodynamic moments about the pitch,
roll and yaw axes. These "native" forces and moments are computed and stored
in the FGColumnVector objects vFs and vMoments. Their native coordinate system
is often referred to as the wind system and is defined as a right-handed system
having its x-axis aligned with the relative velocity vector and pointing towards
the rear of the aircraft , the y-axis extending out the right wing, and the
z-axis directed upwards. This is different than body axes; they are defined such
that the x-axis is lies on the aircraft's roll axis and positive forward, the
y-axis is positive out the right wing, and the z-axis is positive downwards. In
this instance, JSBSim already provides the needed transform and FGForce can make
use 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 are
defined in the enumerated type TransformType and are tWindBody, tLocalBody,
tCustom, and tNone. The local-to-body transform, like the wind-to-body, also
makes use of that already available in JSBSim. tNone sets FGForce to do no
angular transform at all, and tCustom allows for modeling force vectors at
arbitrary angles relative to the body system such as that produced by propulsion
systems. 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. As
stated above, the lift, drag, and side force are computed and stored in the
vector 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 not
strictly necessary, overloaded SetNativeForces() and SetNativeMoments() methods
which each accept three doubles (rather than a vector) are provided and can be
repeatedly called without incurring undue overhead. The body axes force vector
can 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 than
once 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 not be
retrieved 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 computations
correctly so, if the FGForce object is not being used to store them then an
alternate 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, or
local coordinate systems a custom transform type is provided. A vectorable engine
nozzle 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 of
the thrust vector is used rather than the aerodynamic reference point. Thrust is
typically considered to be positive when directed aft while the body x-axis is
positive forward and, if the native system is right handed, the z-axis will be
reversed as well. These differences in sense need to be specified using by the
call: </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 be
taken 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 called
every time the nozzle angle changes, a fixed engine/nozzle installation, on the
other 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>
<blockquote>
<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>
<br></p>
</blockquote>
<h4>Use as a Base Type</h4>
<p>For use as a base type, the native force and moment vector data members are
defined 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);
/// Destructor
~FGForce();
enum TransformType { tNone, tWindBody, tLocalBody, tCustom } ttype;
inline void SetNativeForces(double Fnx, double Fny, double Fnz) {
vFn(1)=Fnx;
vFn(2)=Fny;
vFn(3)=Fnz;
}
inline void SetNativeForces(FGColumnVector3 vv) { vFn = vv; };
inline void SetNativeMoments(double Ln,double Mn, double Nn) {
vMn(1)=Ln;
vMn(2)=Mn;
vMn(3)=Nn;
}
inline void SetNativeMoments(FGColumnVector3 vv) { vMn = vv; }
inline FGColumnVector3& GetNativeForces(void) { return vFn; }
inline FGColumnVector3& GetNativeMoments(void) { return vMn; }
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));
}
inline void SetSense(double x, double y, double z) { vSense(eX)=x, vSense(eY)=y, vSense(eZ)=z; }
inline void SetSense(FGColumnVector3 vv) { vSense=vv; }
inline FGColumnVector3& GetSense(void) { return vSense; }
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;
private:
FGColumnVector3 vFb;
FGColumnVector3 vM;
FGColumnVector3 vXYZn;
FGColumnVector3 vActingXYZn;
FGColumnVector3 vDXYZ;
FGColumnVector3 vSense;
FGMatrix33 mT;
void Debug(int from);
};
}
#endif

View file

@ -1,78 +0,0 @@
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Header: FGGroundCallback.cpp
Author: Mathias Froehlich
Date started: 05/21/04
------ Copyright (C) 2004 Mathias Froehlich (Mathias.Froehlich@web.de) -------
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU 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 General Public License for more
details.
You should have received a copy of the GNU 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 General Public License can also be found on
the world wide web at http://www.gnu.org.
HISTORY
-------------------------------------------------------------------------------
05/21/00 MF Created
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
SENTRY
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "FGColumnVector3.h"
#include "FGLocation.h"
#include "FGGroundCallback.h"
namespace JSBSim {
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGGroundCallback::FGGroundCallback()
{
mReferenceRadius = 20925650;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGGroundCallback::~FGGroundCallback()
{
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
double FGGroundCallback::GetAltitude(const FGLocation& l) const
{
return l.GetRadius() - mReferenceRadius;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
double FGGroundCallback::GetAGLevel(double t, const FGLocation& l,
FGLocation& cont, FGColumnVector3& n,
FGColumnVector3& v) const
{
v = FGColumnVector3(0.0, 0.0, 0.0);
n = (-1/FGColumnVector3(l).Magnitude())*FGColumnVector3(l);
double r = l.GetRadius();
double agl = GetAltitude(l);
cont = ((r-agl)/r)*FGColumnVector3(l);
return agl;
}
}

View file

@ -1,88 +0,0 @@
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Header: FGGroundCallback.h
Author: Mathias Froehlich
Date started: 05/21/04
------ Copyright (C) 2004 Mathias Froehlich (Mathias.Froehlich@web.de) -------
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU 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 General Public License for more
details.
You should have received a copy of the GNU 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 General Public License can also be found on
the world wide web at http://www.gnu.org.
HISTORY
-------------------------------------------------------------------------------
05/21/00 MF Created
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
SENTRY
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#ifndef FGGROUNDCALLBACK_H
#define FGGROUNDCALLBACK_H
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include "FGColumnVector3.h"
#include "FGLocation.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_GROUNDCALLBACK "$Id$"
namespace JSBSim {
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DOCUMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/** This class provides callback slots to get ground specific data like
ground elevation and such.
There is a default implementation, which returns values for a
ball formed earth.
@author Mathias Froehlich
@version $Id$
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DECLARATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
class FGGroundCallback
: public FGJSBBase {
public:
FGGroundCallback();
virtual ~FGGroundCallback();
/** Compute the altitude above sealevel. */
virtual double GetAltitude(const FGLocation& l) const;
/** Compute the altitude above ground. Defaults to sealevel altitude. */
virtual double GetAGLevel(double t, const FGLocation& l, FGLocation& cont,
FGColumnVector3& n, FGColumnVector3& v) const;
private:
/// Reference radius.
double mReferenceRadius;
};
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#endif

View file

@ -1,272 +0,0 @@
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Module: FGGroundReactions.cpp
Author: Jon S. Berndt
Date started: 09/13/00
Purpose: Encapsulates the ground reaction forces (gear and collision)
------------- Copyright (C) 2000 Jon S. Berndt (jsb@hal-pc.org) -------------
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU 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 General Public License for more
details.
You should have received a copy of the GNU 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 General Public License can also be found on
the world wide web at http://www.gnu.org.
FUNCTIONAL DESCRIPTION
--------------------------------------------------------------------------------
HISTORY
--------------------------------------------------------------------------------
09/13/00 JSB Created
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <sstream>
#include <iomanip>
#include "FGGroundReactions.h"
#include "FGPropertyManager.h"
namespace JSBSim {
static const char *IdSrc = "$Id$";
static const char *IdHdr = ID_GROUNDREACTIONS;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
FGGroundReactions::FGGroundReactions(FGFDMExec* fgex) : FGModel(fgex)
{
Name = "FGGroundReactions";
bind();
Debug(0);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGGroundReactions::~FGGroundReactions(void)
{
unbind();
Debug(1);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
bool FGGroundReactions::Run(void)
{
if (!FGModel::Run()) {
vForces.InitMatrix();
vMoments.InitMatrix();
// Only execute gear force code below 300 feet
if ( Propagate->GetDistanceAGL() < 300.0 ) {
vector <FGLGear>::iterator iGear = lGear.begin();
// Sum forces and moments for all gear, here.
// Some optimizations may be made here - or rather in the gear code itself.
// The gear ::Run() method is called several times - once for each gear.
// Perhaps there is some commonality for things which only need to be
// calculated once.
while (iGear != lGear.end()) {
vForces += iGear->Force();
vMoments += iGear->Moment();
iGear++;
}
} else {
// Crash Routine
}
return false;
} else {
return true;
}
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
bool FGGroundReactions::Load(FGConfigFile* AC_cfg)
{
string token;
AC_cfg->GetNextConfigLine();
while ((token = AC_cfg->GetValue()) != string("/UNDERCARRIAGE")) {
string type;
*AC_cfg >> type;
if (type == "AC_GEAR") {
int num = lGear.size();
lGear.push_back(FGLGear(AC_cfg, FDMExec, num));
FCS->AddGear();
} else {
cerr << "Unknown undercarriage type \"" << type << "\"" << endl;
}
}
return true;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
string FGGroundReactions::GetGroundReactionStrings(string delimeter)
{
std::ostringstream buf;
for (unsigned int i=0;i<lGear.size();i++) {
string name = lGear[i].GetName();
buf << name << "_WOW" << delimeter
<< name << "_stroke" << delimeter
<< name << "_strokeVel" << delimeter
<< name << "_CompressForce" << delimeter
<< name << "_WhlSideForce" << delimeter
<< name << "_WhlVelVecX" << delimeter
<< name << "_WhlVelVecY" << delimeter
<< name << "_WhlRollForce" << delimeter
<< name << "_BodyXForce" << delimeter
<< name << "_BodyYForce" << delimeter
<< name << "_WhlSlipDegrees" << delimeter;
}
buf << "TotalGearForce_X" << delimeter
<< "TotalGearForce_Y" << delimeter
<< "TotalGearForce_Z" << delimeter
<< "TotalGearMoment_L" << delimeter
<< "TotalGearMoment_M" << delimeter
<< "TotalGearMoment_N";
return buf.str();
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
string FGGroundReactions::GetGroundReactionValues(string delimeter)
{
std::ostringstream buf;
for (unsigned int i=0;i<lGear.size();i++) {
FGLGear& gear = lGear[i];
buf << (gear.GetWOW() ? "1, " : "0, ")
<< setprecision(5) << gear.GetCompLen() << delimeter
<< setprecision(6) << gear.GetCompVel() << delimeter
<< setprecision(10) << gear.GetCompForce() << delimeter
<< setprecision(6) << gear.GetWheelVel(eX) << delimeter
<< gear.GetWheelVel(eY) << delimeter
<< gear.GetWheelSideForce() << delimeter
<< gear.GetWheelRollForce() << delimeter
<< gear.GetBodyXForce() << delimeter
<< gear.GetBodyYForce() << delimeter
<< gear.GetWheelSlipAngle() << delimeter;
}
buf << vForces(eX) << delimeter
<< vForces(eY) << delimeter
<< vForces(eZ) << delimeter
<< vMoments(eX) << delimeter
<< vMoments(eY) << delimeter
<< vMoments(eZ);
return buf.str();
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGGroundReactions::bind(void)
{
typedef double (FGGroundReactions::*PMF)(int) const;
PropertyManager->Tie("gear/num-units", this,
&FGGroundReactions::GetNumGearUnits);
PropertyManager->Tie("moments/l-gear-lbsft", this,1,
(PMF)&FGGroundReactions::GetMoments);
PropertyManager->Tie("moments/m-gear-lbsft", this,2,
(PMF)&FGGroundReactions::GetMoments);
PropertyManager->Tie("moments/n-gear-lbsft", this,3,
(PMF)&FGGroundReactions::GetMoments);
PropertyManager->Tie("forces/fbx-gear-lbs", this,1,
(PMF)&FGGroundReactions::GetForces);
PropertyManager->Tie("forces/fby-gear-lbs", this,2,
(PMF)&FGGroundReactions::GetForces);
PropertyManager->Tie("forces/fbz-gear-lbs", this,3,
(PMF)&FGGroundReactions::GetForces);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGGroundReactions::unbind(void)
{
PropertyManager->Untie("gear/num-units");
PropertyManager->Untie("moments/l-gear-lbsft");
PropertyManager->Untie("moments/m-gear-lbsft");
PropertyManager->Untie("moments/n-gear-lbsft");
PropertyManager->Untie("forces/fbx-gear-lbs");
PropertyManager->Untie("forces/fby-gear-lbs");
PropertyManager->Untie("forces/fbz-gear-lbs");
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// The bitmasked value choices are as follows:
// unset: In this case (the default) JSBSim would only print
// out the normally expected messages, essentially echoing
// the config files as they are read. If the environment
// variable is not set, debug_lvl is set to 1 internally
// 0: This requests JSBSim not to output any messages
// whatsoever.
// 1: This value explicity requests the normal JSBSim
// startup messages
// 2: This value asks for a message to be printed out when
// a class is instantiated
// 4: When this value is set, a message is displayed when a
// FGModel object executes its Run() method
// 8: When this value is set, various runtime state variables
// are printed out periodically
// 16: When set various parameters are sanity checked and
// a message is printed out when they go out of bounds
void FGGroundReactions::Debug(int from)
{
if (debug_lvl <= 0) return;
if (debug_lvl & 1) { // Standard console startup message output
if (from == 0) { // Constructor
}
}
if (debug_lvl & 2 ) { // Instantiation/Destruction notification
if (from == 0) cout << "Instantiated: FGGroundReactions" << endl;
if (from == 1) cout << "Destroyed: FGGroundReactions" << endl;
}
if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
}
if (debug_lvl & 8 ) { // Runtime state variables
}
if (debug_lvl & 16) { // Sanity checking
}
if (debug_lvl & 64) {
if (from == 0) { // Constructor
cout << IdSrc << endl;
cout << IdHdr << endl;
}
}
}
}

View file

@ -1,113 +0,0 @@
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Header: FGGroundReactions.h
Author: Jon S. Berndt
Date started: 09/13/00
------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU 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 General Public License for more
details.
You should have received a copy of the GNU 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 General Public License can also be found on
the world wide web at http://www.gnu.org.
HISTORY
--------------------------------------------------------------------------------
09/13/00 JSB Created
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
SENTRY
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#ifndef FGGROUNDREACTIONS_H
#define FGGROUNDREACTIONS_H
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#ifdef FGFS
# include <simgear/compiler.h>
# ifdef SG_HAVE_STD_INCLUDES
# include <vector>
# else
# include <vector.h>
# endif
#else
# include <vector>
#endif
#include "FGModel.h"
#include "FGConfigFile.h"
#include "FGLGear.h"
#include "FGColumnVector3.h"
#define ID_GROUNDREACTIONS "$Id$"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
namespace JSBSim {
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DOCUMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/** Manages ground reactions modeling.
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DECLARATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
class FGGroundReactions : public FGModel
{
public:
FGGroundReactions(FGFDMExec*);
~FGGroundReactions(void);
bool Run(void);
bool Load(FGConfigFile* AC_cfg);
FGColumnVector3& GetForces(void) {return vForces;}
double GetForces(int idx) const {return vForces(idx);}
FGColumnVector3& GetMoments(void) {return vMoments;}
double GetMoments(int idx) const {return vMoments(idx);}
string GetGroundReactionStrings(string delimeter);
string GetGroundReactionValues(string delimeter);
inline int GetNumGearUnits(void) const { return lGear.size(); }
/** Gets a gear instance
@param gear index of gear instance
@return a pointer to the FGLGear instance of the gear unit requested */
inline FGLGear* GetGearUnit(int gear) { return &(lGear[gear]); }
void bind(void);
void unbind(void);
private:
vector <FGLGear> lGear;
FGColumnVector3 vForces;
FGColumnVector3 vMoments;
FGColumnVector3 vMaxStaticGrip;
FGColumnVector3 vMaxMomentResist;
void Debug(int from);
};
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#endif

View file

@ -1,145 +0,0 @@
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Module: FGInertial.cpp
Author: Jon S. Berndt
Date started: 09/13/00
Purpose: Encapsulates the inertial frame forces (coriolis and centrifugal)
------------- Copyright (C) 2000 Jon S. Berndt (jsb@hal-pc.org) -------------
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU 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 General Public License for more
details.
You should have received a copy of the GNU 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 General Public License can also be found on
the world wide web at http://www.gnu.org.
FUNCTIONAL DESCRIPTION
--------------------------------------------------------------------------------
HISTORY
--------------------------------------------------------------------------------
09/13/00 JSB Created
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "FGInertial.h"
#include "FGPropagate.h"
#include "FGState.h"
#include "FGMassBalance.h"
namespace JSBSim {
static const char *IdSrc = "$Id$";
static const char *IdHdr = ID_INERTIAL;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
FGInertial::FGInertial(FGFDMExec* fgex) : FGModel(fgex)
{
Name = "FGInertial";
// Defaults
RotationRate = 0.00007272205217;
GM = 14.06252720E15;
RadiusReference = 20925650.00;
gAccelReference = GM/(RadiusReference*RadiusReference);
gAccel = GM/(RadiusReference*RadiusReference);
Debug(0);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGInertial::~FGInertial(void)
{
Debug(1);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
bool FGInertial::Run(void)
{
// Fast return if we have nothing to do ...
if (FGModel::Run()) return true;
// Gravitation accel
double r = Propagate->GetRadius();
gAccel = GetGAccel(r);
return false;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
bool FGInertial::LoadInertial(FGConfigFile* AC_cfg)
{
return true;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// The bitmasked value choices are as follows:
// unset: In this case (the default) JSBSim would only print
// out the normally expected messages, essentially echoing
// the config files as they are read. If the environment
// variable is not set, debug_lvl is set to 1 internally
// 0: This requests JSBSim not to output any messages
// whatsoever.
// 1: This value explicity requests the normal JSBSim
// startup messages
// 2: This value asks for a message to be printed out when
// a class is instantiated
// 4: When this value is set, a message is displayed when a
// FGModel object executes its Run() method
// 8: When this value is set, various runtime state variables
// are printed out periodically
// 16: When set various parameters are sanity checked and
// a message is printed out when they go out of bounds
void FGInertial::Debug(int from)
{
if (debug_lvl <= 0) return;
if (debug_lvl & 1) { // Standard console startup message output
if (from == 0) { // Constructor
}
}
if (debug_lvl & 2 ) { // Instantiation/Destruction notification
if (from == 0) cout << "Instantiated: FGInertial" << endl;
if (from == 1) cout << "Destroyed: FGInertial" << endl;
}
if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
}
if (debug_lvl & 8 ) { // Runtime state variables
}
if (debug_lvl & 16) { // Sanity checking
}
if (debug_lvl & 64) {
if (from == 0) { // Constructor
cout << IdSrc << endl;
cout << IdHdr << endl;
}
}
}
}

View file

@ -1,103 +0,0 @@
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Header: FGInertial.h
Author: Jon S. Berndt
Date started: 09/13/00
------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU 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 General Public License for more
details.
You should have received a copy of the GNU 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 General Public License can also be found on
the world wide web at http://www.gnu.org.
HISTORY
--------------------------------------------------------------------------------
09/13/00 JSB Created
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
SENTRY
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#ifndef FGINERTIAL_H
#define FGINERTIAL_H
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#ifdef FGFS
# include <simgear/compiler.h>
# ifdef SG_HAVE_STD_INCLUDES
# include <vector>
# else
# include <vector.h>
# endif
#else
# include <vector>
#endif
#include "FGModel.h"
#include "FGConfigFile.h"
#include "FGColumnVector3.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_INERTIAL "$Id$"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
namespace JSBSim {
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DOCUMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/** Models inertial forces (e.g. centripetal and coriolis accelerations).
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DECLARATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
class FGInertial : public FGModel {
public:
FGInertial(FGFDMExec*);
~FGInertial(void);
bool Run(void);
bool LoadInertial(FGConfigFile* AC_cfg);
double SLgravity(void) const {return gAccelReference;}
double gravity(void) const {return gAccel;}
double omega(void) const {return RotationRate;}
double GetGAccel(double r) const { return GM/(r*r); }
double RefRadius(void) const {return RadiusReference;}
private:
double gAccel;
double gAccelReference;
double RadiusReference;
double RotationRate;
double GM;
void Debug(int from);
};
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#endif

File diff suppressed because it is too large Load diff

View file

@ -1,302 +0,0 @@
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Header: FGInitialCondition.h
Author: Tony Peden
Date started: 7/1/99
------------- 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 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 General Public License for more
details.
You should have received a copy of the GNU 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 General Public License can also be found on
the world wide web at http://www.gnu.org.
HISTORY
--------------------------------------------------------------------------------
7/1/99 TP Created
FUNCTIONAL DESCRIPTION
--------------------------------------------------------------------------------
The purpose of this class is to take a set of initial conditions and provide
a kinematically consistent set of body axis velocity components, euler
angles, and altitude. This class does not attempt to trim the model i.e.
the sim will most likely start in a very dynamic state (unless, of course,
you have chosen your IC's wisely) even after setting it up with this class.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
SENTRY
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#ifndef FGINITIALCONDITION_H
#define FGINITIALCONDITION_H
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include "FGFDMExec.h"
#include "FGJSBBase.h"
#include "FGColumnVector3.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_INITIALCONDITION "$Id$"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
namespace JSBSim {
typedef enum { setvt, setvc, setve, setmach, setuvw, setned, setvg } speedset;
typedef enum { setwned, setwmd, setwhc } windset;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DOCUMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/** Takes a set of initial conditions and provide a kinematically consistent set
of body axis velocity components, euler angles, and altitude. This class
does not attempt to trim the model i.e. the sim will most likely start in a
very dynamic state (unless, of course, you have chosen your IC's wisely)
even after setting it up with this class.
USAGE NOTES
With a valid object of FGFDMExec and an aircraft model loaded
FGInitialCondition fgic=new FGInitialCondition(FDMExec);
fgic->SetVcalibratedKtsIC()
fgic->SetAltitudeFtIC();
//to directly into Run
FDMExec->GetState()->Initialize(fgic)
delete fgic;
FDMExec->Run()
//or to loop the sim w/o integrating
FDMExec->RunIC(fgic)
Speed:
Since vc, ve, vt, and mach all represent speed, the remaining
three are recalculated each time one of them is set (using the
current altitude). The most recent speed set is remembered so
that if and when altitude is reset, the last set speed is used
to recalculate the remaining three. Setting any of the body
components forces a recalculation of vt and vt then becomes the
most recent speed set.
Alpha,Gamma, and Theta:
This class assumes that it will be used to set up the sim for a
steady, zero pitch rate condition. Since any two of those angles
specifies the third gamma (flight path angle) is favored when setting
alpha and theta and alpha is favored when setting gamma. i.e.
- set alpha : recalculate theta using gamma as currently set
- set theta : recalculate alpha using gamma as currently set
- set gamma : recalculate theta using alpha as currently set
The idea being that gamma is most interesting to pilots (since it
is indicative of climb rate).
Setting climb rate is, for the purpose of this discussion,
considered equivalent to setting gamma.
@author Tony Peden
@version "$Id$"
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DECLARATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
class FGInitialCondition : public FGJSBBase
{
public:
/// Constructor
FGInitialCondition(FGFDMExec *fdmex);
/// Destructor
~FGInitialCondition();
void SetVcalibratedKtsIC(double tt);
void SetVequivalentKtsIC(double tt);
inline void SetVtrueKtsIC(double tt) { SetVtrueFpsIC(tt*ktstofps); }
inline void SetVgroundKtsIC(double tt) { SetVgroundFpsIC(tt*ktstofps); }
void SetMachIC(double tt);
inline void SetAlphaDegIC(double tt) { SetAlphaRadIC(tt*degtorad); }
inline void SetBetaDegIC(double tt) { SetBetaRadIC(tt*degtorad);}
inline void SetPitchAngleDegIC(double tt) { SetPitchAngleRadIC(tt*degtorad); }
inline void SetRollAngleDegIC(double tt) { SetRollAngleRadIC(tt*degtorad);}
inline void SetTrueHeadingDegIC(double tt){ SetTrueHeadingRadIC(tt*degtorad); }
void SetClimbRateFpmIC(double tt);
inline void SetFlightPathAngleDegIC(double tt) { SetFlightPathAngleRadIC(tt*degtorad); }
void SetAltitudeFtIC(double tt);
void SetAltitudeAGLFtIC(double tt);
void SetSeaLevelRadiusFtIC(double tt);
void SetTerrainAltitudeFtIC(double tt);
inline void SetLatitudeDegIC(double tt) { latitude=tt*degtorad; }
inline void SetLongitudeDegIC(double tt) { longitude=tt*degtorad; }
inline double GetVcalibratedKtsIC(void) const { return vc*fpstokts; }
inline double GetVequivalentKtsIC(void) const { return ve*fpstokts; }
inline double GetVgroundKtsIC(void) const { return vg*fpstokts; }
inline double GetVtrueKtsIC(void) const { return vt*fpstokts; }
inline double GetMachIC(void) const { return mach; }
inline double GetClimbRateFpmIC(void) const { return hdot*60; }
inline double GetFlightPathAngleDegIC(void)const { return gamma*radtodeg; }
inline double GetAlphaDegIC(void) const { return alpha*radtodeg; }
inline double GetBetaDegIC(void) const { return beta*radtodeg; }
inline double GetPitchAngleDegIC(void) const { return theta*radtodeg; }
inline double GetRollAngleDegIC(void) const { return phi*radtodeg; }
inline double GetHeadingDegIC(void) const { return psi*radtodeg; }
inline double GetLatitudeDegIC(void) const { return latitude*radtodeg; }
inline double GetLongitudeDegIC(void) const { return longitude*radtodeg; }
inline double GetAltitudeFtIC(void) const { return altitude; }
inline double GetAltitudeAGLFtIC(void) const { return altitude - terrain_altitude; }
inline double GetSeaLevelRadiusFtIC(void) const { return sea_level_radius; }
inline double GetTerrainAltitudeFtIC(void) const { return terrain_altitude; }
void SetVgroundFpsIC(double tt);
void SetVtrueFpsIC(double tt);
void SetUBodyFpsIC(double tt);
void SetVBodyFpsIC(double tt);
void SetWBodyFpsIC(double tt);
void SetVnorthFpsIC(double tt);
void SetVeastFpsIC(double tt);
void SetVdownFpsIC(double tt);
void SetPRadpsIC(double tt) { p = tt; }
void SetQRadpsIC(double tt) { q = tt; }
void SetRRadpsIC(double tt) { r = tt; }
void SetWindNEDFpsIC(double wN, double wE, double wD);
void SetWindMagKtsIC(double mag);
void SetWindDirDegIC(double dir);
void SetHeadWindKtsIC(double head);
void SetCrossWindKtsIC(double cross);// positive from left
void SetWindDownKtsIC(double wD);
void SetClimbRateFpsIC(double tt);
inline double GetVgroundFpsIC(void) const { return vg; }
inline double GetVtrueFpsIC(void) const { return vt; }
inline double GetWindUFpsIC(void) const { return uw; }
inline double GetWindVFpsIC(void) const { return vw; }
inline double GetWindWFpsIC(void) const { return ww; }
inline double GetWindNFpsIC(void) const { return wnorth; }
inline double GetWindEFpsIC(void) const { return weast; }
inline double GetWindDFpsIC(void) const { return wdown; }
inline double GetWindFpsIC(void) const { return sqrt(wnorth*wnorth + weast*weast); }
double GetWindDirDegIC(void);
inline double GetClimbRateFpsIC(void) const { return hdot; }
double GetUBodyFpsIC(void) const;
double GetVBodyFpsIC(void) const;
double GetWBodyFpsIC(void) const;
double GetPRadpsIC() const { return p; }
double GetQRadpsIC() const { return q; }
double GetRRadpsIC() const { return r; }
void SetFlightPathAngleRadIC(double tt);
void SetAlphaRadIC(double tt);
void SetPitchAngleRadIC(double tt);
void SetBetaRadIC(double tt);
void SetRollAngleRadIC(double tt);
void SetTrueHeadingRadIC(double tt);
inline void SetLatitudeRadIC(double tt) { latitude=tt; }
inline void SetLongitudeRadIC(double tt) { longitude=tt; }
inline double GetFlightPathAngleRadIC(void) const { return gamma; }
inline double GetAlphaRadIC(void) const { return alpha; }
inline double GetPitchAngleRadIC(void) const { return theta; }
inline double GetBetaRadIC(void) const { return beta; }
inline double GetRollAngleRadIC(void) const { return phi; }
inline double GetHeadingRadIC(void) const { return psi; }
inline double GetLatitudeRadIC(void) const { return latitude; }
inline double GetLongitudeRadIC(void) const { return longitude; }
inline double GetThetaRadIC(void) const { return theta; }
inline double GetPhiRadIC(void) const { return phi; }
inline double GetPsiRadIC(void) const { return psi; }
inline speedset GetSpeedSet(void) { return lastSpeedSet; }
inline windset GetWindSet(void) { return lastWindSet; }
bool Load(string rstname, bool useStoredPath = true );
void bind(void);
void unbind(void);
private:
double vt,vc,ve,vg;
double mach;
double altitude,hdot;
double latitude,longitude;
double u,v,w;
double p,q,r;
double uw,vw,ww;
double vnorth,veast,vdown;
double wnorth,weast,wdown;
double whead, wcross, wdir, wmag;
double sea_level_radius;
double terrain_altitude;
double radius_to_vehicle;
double alpha, beta, theta, phi, psi, gamma;
double salpha,sbeta,stheta,sphi,spsi,sgamma;
double calpha,cbeta,ctheta,cphi,cpsi,cgamma;
double xlo, xhi,xmin,xmax;
typedef double (FGInitialCondition::*fp)(double x);
fp sfunc;
speedset lastSpeedSet;
windset lastWindSet;
FGFDMExec *fdmex;
FGPropertyManager *PropertyManager;
bool getAlpha(void);
bool getTheta(void);
bool getMachFromVcas(double *Mach,double vcas);
double GammaEqOfTheta(double Theta);
double GammaEqOfAlpha(double Alpha);
double calcVcas(double Mach);
void calcUVWfromNED(void);
void calcWindUVW(void);
bool findInterval(double x,double guess);
bool solve(double *y, double x);
void Debug(int from);
};
}
#endif

View file

@ -1,596 +0,0 @@
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Module: FGLGear.cpp
Author: Jon S. Berndt
Norman H. Princen
Date started: 11/18/99
Purpose: Encapsulates the landing gear elements
Called by: FGAircraft
------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU 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 General Public License for more
details.
You should have received a copy of the GNU 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 General Public License can also be found on
the world wide web at http://www.gnu.org.
FUNCTIONAL DESCRIPTION
--------------------------------------------------------------------------------
HISTORY
--------------------------------------------------------------------------------
11/18/99 JSB Created
01/30/01 NHP Extended gear model to properly simulate steering and braking
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include "FGLGear.h"
namespace JSBSim {
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
GLOBAL DATA
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
static const char *IdSrc = "$Id$";
static const char *IdHdr = ID_LGEAR;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
FGLGear::FGLGear(FGConfigFile* AC_cfg, FGFDMExec* fdmex, int number) : Exec(fdmex)
{
GearNumber = number;
*AC_cfg >> name >> vXYZ(1) >> vXYZ(2) >> vXYZ(3)
>> kSpring >> bDamp>> dynamicFCoeff >> staticFCoeff
>> rollingFCoeff >> sSteerType >> sBrakeGroup
>> maxSteerAngle >> sRetractable;
if (sBrakeGroup == "LEFT" ) eBrakeGrp = bgLeft;
else if (sBrakeGroup == "RIGHT" ) eBrakeGrp = bgRight;
else if (sBrakeGroup == "CENTER") eBrakeGrp = bgCenter;
else if (sBrakeGroup == "NOSE" ) eBrakeGrp = bgNose;
else if (sBrakeGroup == "TAIL" ) eBrakeGrp = bgTail;
else if (sBrakeGroup == "NONE" ) eBrakeGrp = bgNone;
else {
cerr << "Improper braking group specification in config file: "
<< sBrakeGroup << " is undefined." << endl;
}
if (sSteerType == "STEERABLE") eSteerType = stSteer;
else if (sSteerType == "FIXED" ) eSteerType = stFixed;
else if (sSteerType == "CASTERED" ) eSteerType = stCaster;
else {
cerr << "Improper steering type specification in config file: "
<< sSteerType << " is undefined." << endl;
}
if ( sRetractable == "RETRACT" ) {
isRetractable = true;
} else {
isRetractable = false;
}
GearUp = false;
GearDown = true;
Servicable = true;
// Add some AI here to determine if gear is located properly according to its
// brake group type ??
State = Exec->GetState();
Aircraft = Exec->GetAircraft();
Propagate = Exec->GetPropagate();
Auxiliary = Exec->GetAuxiliary();
FCS = Exec->GetFCS();
MassBalance = Exec->GetMassBalance();
WOW = lastWOW = true; // should the value be initialized to true?
ReportEnable = true;
FirstContact = false;
StartedGroundRun = false;
TakeoffReported = LandingReported = false;
LandingDistanceTraveled = TakeoffDistanceTraveled = TakeoffDistanceTraveled50ft = 0.0;
MaximumStrutForce = MaximumStrutTravel = 0.0;
SideForce = RollingForce = 0.0;
SinkRate = GroundSpeed = 0.0;
vWhlBodyVec = MassBalance->StructuralToBody(vXYZ);
vLocalGear = Propagate->GetTb2l() * vWhlBodyVec;
compressLength = 0.0;
compressSpeed = 0.0;
brakePct = 0.0;
maxCompLen = 0.0;
WheelSlip = lastWheelSlip = 0.0;
compressLength = 0.0;
compressSpeed = 0.0;
brakePct = 0.0;
maxCompLen = 0.0;
TirePressureNorm = 1.0;
Debug(0);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGLGear::FGLGear(const FGLGear& lgear)
{
GearNumber = lgear.GearNumber;
State = lgear.State;
Aircraft = lgear.Aircraft;
Propagate = lgear.Propagate;
Auxiliary = lgear.Auxiliary;
Exec = lgear.Exec;
FCS = lgear.FCS;
MassBalance = lgear.MassBalance;
vXYZ = lgear.vXYZ;
vMoment = lgear.vMoment;
vWhlBodyVec = lgear.vWhlBodyVec;
vLocalGear = lgear.vLocalGear;
WOW = lgear.WOW;
lastWOW = lgear.lastWOW;
ReportEnable = lgear.ReportEnable;
FirstContact = lgear.FirstContact;
StartedGroundRun = lgear.StartedGroundRun;
LandingDistanceTraveled = lgear.LandingDistanceTraveled;
TakeoffDistanceTraveled = lgear.TakeoffDistanceTraveled;
TakeoffDistanceTraveled50ft = lgear.TakeoffDistanceTraveled50ft;
MaximumStrutForce = lgear.MaximumStrutForce;
MaximumStrutTravel = lgear.MaximumStrutTravel;
SideForce = lgear.SideForce;
RollingForce = lgear.RollingForce;
kSpring = lgear.kSpring;
bDamp = lgear.bDamp;
compressLength = lgear.compressLength;
compressSpeed = lgear.compressSpeed;
staticFCoeff = lgear.staticFCoeff;
dynamicFCoeff = lgear.dynamicFCoeff;
rollingFCoeff = lgear.rollingFCoeff;
brakePct = lgear.brakePct;
maxCompLen = lgear.maxCompLen;
SinkRate = lgear.SinkRate;
GroundSpeed = lgear.GroundSpeed;
LandingReported = lgear.LandingReported;
TakeoffReported = lgear.TakeoffReported;
name = lgear.name;
sSteerType = lgear.sSteerType;
sRetractable = lgear.sRetractable;
eSteerType = lgear.eSteerType;
sBrakeGroup = lgear.sBrakeGroup;
eBrakeGrp = lgear.eBrakeGrp;
maxSteerAngle = lgear.maxSteerAngle;
isRetractable = lgear.isRetractable;
GearUp = lgear.GearUp;
GearDown = lgear.GearDown;
WheelSlip = lgear.WheelSlip;
lastWheelSlip = lgear.lastWheelSlip;
TirePressureNorm = lgear.TirePressureNorm;
Servicable = lgear.Servicable;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGLGear::~FGLGear()
{
Debug(1);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGColumnVector3& FGLGear::Force(void)
{
double SinWheel, CosWheel;
double deltaT = State->Getdt()*Exec->GetGroundReactions()->GetRate();
vForce.InitMatrix();
vMoment.InitMatrix();
if (isRetractable) {
if (FCS->GetGearPos() < 0.01) {
GearUp = true;
GearDown = false;
} else if (FCS->GetGearPos() > 0.99) {
GearDown = true;
GearUp = false;
} else {
GearUp = false;
GearDown = false;
}
} else {
GearUp = false;
GearDown = true;
}
// Compute the steering angle in any case.
// Will make shure that animations will look right.
switch (eSteerType) {
case stSteer:
SteerAngle = degtorad * FCS->GetSteerPosDeg(GearNumber);
break;
case stFixed:
SteerAngle = 0.0;
break;
case stCaster:
// Note to Jon: This is not correct for castering gear. I'll fix it later.
SteerAngle = 0.0;
break;
default:
cerr << "Improper steering type membership detected for this gear." << endl;
break;
}
if (GearDown) {
double t = Exec->GetState()->Getsim_time();
vWhlBodyVec = MassBalance->StructuralToBody(vXYZ);
// vWhlBodyVec now stores the vector from the cg to this wheel
vLocalGear = Propagate->GetTb2l() * vWhlBodyVec;
// vLocalGear now stores the vector from the cg to the wheel in local coords.
FGColumnVector3 normal, cvel;
FGLocation contact;
FGLocation gearLoc = Propagate->GetLocation().LocalToLocation(vLocalGear);
compressLength = - Exec->GetGroundCallback()->GetAGLevel(t, gearLoc, contact, normal, cvel);
// The compression length is currently measured in the Z-axis, only, at this time.
// It should be measured along the strut axis. If the local-frame gear position
// "hangs down" below the CG greater than the altitude, then the compressLength
// will be positive - i.e. the gear will have made contact.
if (compressLength > 0.00) {
WOW = true; // Weight-On-Wheels is true
// The next equation should really use the vector to the contact patch of the tire
// including the strut compression and not vWhlBodyVec. Will fix this later.
// As it stands, now, the following equation takes the aircraft body-frame
// rotational rate and calculates the cross-product with the vector from the CG
// to the wheel, thus producing the instantaneous velocity vector of the tire
// in Body coords. The frame is also converted to local coordinates. When the
// aircraft local-frame velocity is added to this quantity, the total velocity of
// the wheel in local frame is then known. Subsequently, the compression speed
// (used for calculating damping force) is found by taking the Z-component of the
// wheel velocity.
vWhlVelVec = Propagate->GetTb2l() * (Propagate->GetPQR() * vWhlBodyVec);
vWhlVelVec += Propagate->GetVel() - cvel;
compressSpeed = vWhlVelVec(eZ);
// If this is the first time the wheel has made contact, remember some values
// for later printout.
if (!FirstContact) {
FirstContact = true;
SinkRate = compressSpeed;
GroundSpeed = Propagate->GetVel().Magnitude();
TakeoffReported = false;
}
// If the takeoff run is starting, initialize.
if ((Propagate->GetVel().Magnitude() > 0.1) &&
(FCS->GetBrake(bgLeft) == 0) &&
(FCS->GetBrake(bgRight) == 0) &&
(FCS->GetThrottlePos(0) == 1) && !StartedGroundRun)
{
TakeoffDistanceTraveled = 0;
TakeoffDistanceTraveled50ft = 0;
StartedGroundRun = true;
}
// The following needs work regarding friction coefficients and braking and
// steering The BrakeFCoeff formula assumes that an anti-skid system is used.
// It also assumes that we won't be turning and braking at the same time.
// Will fix this later.
// [JSB] The braking force coefficients include normal rolling coefficient +
// a percentage of the static friction coefficient based on braking applied.
switch (eBrakeGrp) {
case bgLeft:
BrakeFCoeff = ( rollingFCoeff*(1.0 - FCS->GetBrake(bgLeft)) +
staticFCoeff*FCS->GetBrake(bgLeft) );
break;
case bgRight:
BrakeFCoeff = ( rollingFCoeff*(1.0 - FCS->GetBrake(bgRight)) +
staticFCoeff*FCS->GetBrake(bgRight) );
break;
case bgCenter:
BrakeFCoeff = ( rollingFCoeff*(1.0 - FCS->GetBrake(bgCenter)) +
staticFCoeff*FCS->GetBrake(bgCenter) );
break;
case bgNose:
BrakeFCoeff = ( rollingFCoeff*(1.0 - FCS->GetBrake(bgCenter)) +
staticFCoeff*FCS->GetBrake(bgCenter) );
break;
case bgTail:
BrakeFCoeff = ( rollingFCoeff*(1.0 - FCS->GetBrake(bgCenter)) +
staticFCoeff*FCS->GetBrake(bgCenter) );
break;
case bgNone:
BrakeFCoeff = rollingFCoeff;
break;
default:
cerr << "Improper brake group membership detected for this gear." << endl;
break;
}
// Transform the wheel velocities from the local axis system to the wheel axis system.
// For now, steering angle is assumed to happen in the Local Z axis,
// not the strut axis as it should be. Will fix this later.
SinWheel = sin(Propagate->GetEuler(ePsi) + SteerAngle);
CosWheel = cos(Propagate->GetEuler(ePsi) + SteerAngle);
RollingWhlVel = vWhlVelVec(eX)*CosWheel + vWhlVelVec(eY)*SinWheel;
SideWhlVel = vWhlVelVec(eY)*CosWheel - vWhlVelVec(eX)*SinWheel;
// Calculate tire slip angle.
if (RollingWhlVel == 0.0 && SideWhlVel == 0.0) {
WheelSlip = 0.0;
} else if (fabs(RollingWhlVel) < 1.0) {
WheelSlip = 0.05*radtodeg*atan2(SideWhlVel, fabs(RollingWhlVel)) + 0.95*WheelSlip;
} else {
WheelSlip = radtodeg*atan2(SideWhlVel, fabs(RollingWhlVel));
}
/*
double maxdeltaSlip = 0.5*deltaT;
if (RollingWhlVel == 0.0 && SideWhlVel == 0.0) {
WheelSlip = 0.0;
} else if (RollingWhlVel < 1.0) {
WheelSlip = radtodeg*atan2(SideWhlVel, RollingWhlVel);
deltaSlip = WheelSlip - lastWheelSlip;
if (fabs(deltaSlip) > maxdeltaSlip) {
if (WheelSlip > lastWheelSlip) {
WheelSlip = lastWheelSlip + maxdeltaSlip;
} else if (WheelSlip < lastWheelSlip) {
WheelSlip = lastWheelSlip - maxdeltaSlip;
}
}
} else {
WheelSlip = radtodeg*atan2(SideWhlVel, RollingWhlVel);
}
if ((WheelSlip < 0.0 && lastWheelSlip > 0.0) ||
(WheelSlip > 0.0 && lastWheelSlip < 0.0))
{
WheelSlip = 0.0;
}
*/
lastWheelSlip = WheelSlip;
// Compute the sideforce coefficients using similar assumptions to LaRCSim for now.
// Allow a maximum of 10 degrees tire slip angle before wheel slides. At that point,
// transition from static to dynamic friction. There are more complicated formulations
// of this that avoid the discrete jump (similar to Pacejka). Will fix this later.
if (fabs(WheelSlip) <= 20.0) {
FCoeff = staticFCoeff*WheelSlip/20.0;
} else if (fabs(WheelSlip) <= 40.0) {
// FCoeff = dynamicFCoeff*fabs(WheelSlip)/WheelSlip;
FCoeff = (dynamicFCoeff*(fabs(WheelSlip) - 20.0)/20.0 +
staticFCoeff*(40.0 - fabs(WheelSlip))/20.0)*fabs(WheelSlip)/WheelSlip;
} else {
FCoeff = dynamicFCoeff*fabs(WheelSlip)/WheelSlip;
}
// Compute the vertical force on the wheel using square-law damping (per comment
// in paper AIAA-2000-4303 - see header prologue comments). We might consider
// allowing for both square and linear damping force calculation. Also need to
// possibly give a "rebound damping factor" that differs from the compression
// case.
vLocalForce(eZ) = min(-compressLength * kSpring
- compressSpeed * bDamp, (double)0.0);
MaximumStrutForce = max(MaximumStrutForce, fabs(vLocalForce(eZ)));
MaximumStrutTravel = max(MaximumStrutTravel, fabs(compressLength));
// Compute the forces in the wheel ground plane.
RollingForce = 0;
if (fabs(RollingWhlVel) > 1E-3) {
double badPresResis = (1.0 - TirePressureNorm) * 30;
RollingForce = (badPresResis * min(fabs(RollingWhlVel), 1.0)
+ vLocalForce(eZ) * BrakeFCoeff)
* fabs(RollingWhlVel)/RollingWhlVel;
}
SideForce = vLocalForce(eZ) * FCoeff;
// Transform these forces back to the local reference frame.
vLocalForce(eX) = RollingForce*CosWheel - SideForce*SinWheel;
vLocalForce(eY) = SideForce*CosWheel + RollingForce*SinWheel;
// Note to Jon: At this point the forces will be too big when the airplane is
// stopped or rolling to a stop. We need to make sure that the gear forces just
// balance out the non-gear forces when the airplane is stopped. That way the
// airplane won't start to accelerate until the non-gear/ forces are larger than
// the gear forces. I think that the proper fix should go into FGAircraft::FMGear.
// This routine would only compute the local strut forces and return them to
// FMGear. All of the gear forces would get adjusted in FMGear using the total
// non-gear forces. Then the gear moments would be calculated. If strange things
// start happening to the airplane during testing as it rolls to a stop, then we
// need to implement this change. I ran out of time to do it now but have the
// equations.
// Transform the forces back to the body frame and compute the moment.
vForce = Propagate->GetTl2b() * vLocalForce;
vMoment = vWhlBodyVec * vForce;
} else { // Gear is NOT compressed
WOW = false;
// Return to neutral position between 1.0 and 0.8 gear pos.
SteerAngle *= max(FCS->GetGearPos()-0.8, 0.0)/0.2;
if (Propagate->GetDistanceAGL() > 200.0) {
FirstContact = false;
StartedGroundRun = false;
LandingReported = false;
LandingDistanceTraveled = 0.0;
MaximumStrutForce = MaximumStrutTravel = 0.0;
}
compressLength = 0.0; // reset compressLength to zero for data output validity
}
if (FirstContact) LandingDistanceTraveled += Auxiliary->GetVground()*deltaT;
if (StartedGroundRun) {
TakeoffDistanceTraveled50ft += Auxiliary->GetVground()*deltaT;
if (WOW) TakeoffDistanceTraveled += Auxiliary->GetVground()*deltaT;
}
if (ReportEnable && Auxiliary->GetVground() <= 0.05 && !LandingReported) {
if (debug_lvl > 0) Report(erLand);
}
if (ReportEnable && !TakeoffReported &&
(vLocalGear(eZ) - Propagate->GetDistanceAGL()) < -50.0)
{
if (debug_lvl > 0) Report(erTakeoff);
}
if (lastWOW != WOW) {
PutMessage("GEAR_CONTACT: " + name, WOW);
}
lastWOW = WOW;
// Crash detection logic (really out-of-bounds detection)
if (compressLength > 500.0 ||
vForce.Magnitude() > 100000000.0 ||
vMoment.Magnitude() > 5000000000.0 ||
SinkRate > 1.4666*30)
{
PutMessage("Crash Detected: Simulation FREEZE.");
Exec->Freeze();
}
}
return vForce;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGLGear::Report(ReportType repType)
{
switch(repType) {
case erLand:
cout << endl << "Touchdown report for " << name << endl;
cout << " Sink rate at contact: " << SinkRate << " fps, "
<< SinkRate*0.3048 << " mps" << endl;
cout << " Contact ground speed: " << GroundSpeed*.5925 << " knots, "
<< GroundSpeed*0.3048 << " mps" << endl;
cout << " Maximum contact force: " << MaximumStrutForce << " lbs, "
<< MaximumStrutForce*4.448 << " Newtons" << endl;
cout << " Maximum strut travel: " << MaximumStrutTravel*12.0 << " inches, "
<< MaximumStrutTravel*30.48 << " cm" << endl;
cout << " Distance traveled: " << LandingDistanceTraveled << " ft, "
<< LandingDistanceTraveled*0.3048 << " meters" << endl;
LandingReported = true;
break;
case erTakeoff:
cout << endl << "Takeoff report for " << name << endl;
cout << " Distance traveled: " << TakeoffDistanceTraveled
<< " ft, " << TakeoffDistanceTraveled*0.3048 << " meters" << endl;
cout << " Distance traveled (over 50'): " << TakeoffDistanceTraveled50ft
<< " ft, " << TakeoffDistanceTraveled50ft*0.3048 << " meters" << endl;
TakeoffReported = true;
break;
}
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// The bitmasked value choices are as follows:
// unset: In this case (the default) JSBSim would only print
// out the normally expected messages, essentially echoing
// the config files as they are read. If the environment
// variable is not set, debug_lvl is set to 1 internally
// 0: This requests JSBSim not to output any messages
// whatsoever.
// 1: This value explicity requests the normal JSBSim
// startup messages
// 2: This value asks for a message to be printed out when
// a class is instantiated
// 4: When this value is set, a message is displayed when a
// FGModel object executes its Run() method
// 8: When this value is set, various runtime state variables
// are printed out periodically
// 16: When set various parameters are sanity checked and
// a message is printed out when they go out of bounds
void FGLGear::Debug(int from)
{
if (debug_lvl <= 0) return;
if (debug_lvl & 1) { // Standard console startup message output
if (from == 0) { // Constructor
cout << " Name: " << name << endl;
cout << " Location: " << vXYZ << endl;
cout << " Spring Constant: " << kSpring << endl;
cout << " Damping Constant: " << bDamp << endl;
cout << " Dynamic Friction: " << dynamicFCoeff << endl;
cout << " Static Friction: " << staticFCoeff << endl;
cout << " Rolling Friction: " << rollingFCoeff << endl;
cout << " Steering Type: " << sSteerType << endl;
cout << " Grouping: " << sBrakeGroup << endl;
cout << " Max Steer Angle: " << maxSteerAngle << endl;
cout << " Retractable: " << sRetractable << endl;
}
}
if (debug_lvl & 2 ) { // Instantiation/Destruction notification
if (from == 0) cout << "Instantiated: FGLGear" << endl;
if (from == 1) cout << "Destroyed: FGLGear" << endl;
}
if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
}
if (debug_lvl & 8 ) { // Runtime state variables
}
if (debug_lvl & 16) { // Sanity checking
}
if (debug_lvl & 64) {
if (from == 0) { // Constructor
cout << IdSrc << endl;
cout << IdHdr << endl;
}
}
}
} // namespace JSBSim

View file

@ -1,329 +0,0 @@
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Header: FGLGear.h
Author: Jon S. Berndt
Date started: 11/18/99
------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU 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 General Public License for more
details.
You should have received a copy of the GNU 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 General Public License can also be found on
the world wide web at http://www.gnu.org.
HISTORY
--------------------------------------------------------------------------------
11/18/99 JSB Created
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
SENTRY
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#ifndef FGLGEAR_H
#define FGLGEAR_H
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#ifdef FGFS
# include <simgear/compiler.h>
#endif
#include "FGJSBBase.h"
#include "FGFDMExec.h"
#include "FGConfigFile.h"
#include "FGColumnVector3.h"
#include <string>
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_LGEAR "$Id$"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
namespace JSBSim {
class FGAircraft;
class FGPropagate;
class FGFCS;
class FGState;
class FGMassBalance;
class FGAuxiliary;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DOCUMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/** Landing gear model.
Calculates forces and moments due to landing gear reactions. This is done in
several steps, and is dependent on what kind of gear is being modeled. Here
are the parameters that can be specified in the config file for modeling
landing gear:
<p>
<b><u>Physical Characteristics</u></b><br>
<ol>
<li>X, Y, Z location, in inches in structural coordinate frame</li>
<li>Spring constant, in lbs/ft</li>
<li>Damping coefficient, in lbs/ft/sec</li>
<li>Dynamic Friction Coefficient</li>
<li>Static Friction Coefficient</li>
</ol></p><p>
<b><u>Operational Properties</b></u><br>
<ol>
<li>Name</li>
<li>Steerability attribute {one of STEERABLE | FIXED | CASTERED}</li>
<li>Brake Group Membership {one of LEFT | CENTER | RIGHT | NOSE | TAIL | NONE}</li>
<li>Max Steer Angle, in degrees</li>
</ol></p>
<p>
<b><u>Algorithm and Approach to Modeling</u></b><br>
<ol>
<li>Find the location of the uncompressed landing gear relative to the CG of
the aircraft. Remember, the structural coordinate frame that the aircraft is
defined in is: X positive towards the tail, Y positive out the right side, Z
positive upwards. The locations of the various parts are given in inches in
the config file.</li>
<li>The vector giving the location of the gear (relative to the cg) is
rotated 180 degrees about the Y axis to put the coordinates in body frame (X
positive forwards, Y positive out the right side, Z positive downwards, with
the origin at the cg). The lengths are also now given in feet.</li>
<li>The new gear location is now transformed to the local coordinate frame
using the body-to-local matrix. (Mb2l).</li>
<li>Knowing the location of the center of gravity relative to the ground
(height above ground level or AGL) now enables gear deflection to be
calculated. The gear compression value is the local frame gear Z location
value minus the height AGL. [Currently, we make the assumption that the gear
is oriented - and the deflection occurs in - the Z axis only. Additionally,
the vector to the landing gear is currently not modified - which would
(correctly) move the point of contact to the actual compressed-gear point of
contact. Eventually, articulated gear may be modeled, but initially an
effort must be made to model a generic system.] As an example, say the
aircraft left main gear location (in local coordinates) is Z = 3 feet
(positive) and the height AGL is 2 feet. This tells us that the gear is
compressed 1 foot.</li>
<li>If the gear is compressed, a Weight-On-Wheels (WOW) flag is set.</li>
<li>With the compression length calculated, the compression velocity may now
be calculated. This will be used to determine the damping force in the
strut. The aircraft rotational rate is multiplied by the vector to the wheel
to get a wheel velocity in body frame. That velocity vector is then
transformed into the local coordinate frame.</li>
<li>The aircraft cg velocity in the local frame is added to the
just-calculated wheel velocity (due to rotation) to get a total wheel
velocity in the local frame.</li>
<li>The compression speed is the Z-component of the vector.</li>
<li>With the wheel velocity vector no longer needed, it is normalized and
multiplied by a -1 to reverse it. This will be used in the friction force
calculation.</li>
<li>Since the friction force takes place solely in the runway plane, the Z
coordinate of the normalized wheel velocity vector is set to zero.</li>
<li>The gear deflection force (the force on the aircraft acting along the
local frame Z axis) is now calculated given the spring and damper
coefficients, and the gear deflection speed and stroke length. Keep in mind
that gear forces always act in the negative direction (in both local and
body frames), and are not capable of generating a force in the positive
sense (one that would attract the aircraft to the ground). So, the gear
forces are always negative - they are limited to values of zero or less. The
gear force is simply the negative of the sum of the spring compression
length times the spring coefficient and the gear velocity times the damping
coefficient.</li>
<li>The lateral/directional force acting on the aircraft through the landing
gear (along the local frame X and Y axes) is calculated next. First, the
friction coefficient is multiplied by the recently calculated Z-force. This
is the friction force. It must be given direction in addition to magnitude.
We want the components in the local frame X and Y axes. From step 9, above,
the conditioned wheel velocity vector is taken and the X and Y parts are
multiplied by the friction force to get the X and Y components of friction.
</li>
<li>The wheel force in local frame is next converted to body frame.</li>
<li>The moment due to the gear force is calculated by multiplying r x F
(radius to wheel crossed into the wheel force). Both of these operands are
in body frame.</li>
</ol>
@author Jon S. Berndt
@version $Id$
@see Richard E. McFarland, "A Standard Kinematic Model for Flight Simulation at
NASA-Ames", NASA CR-2497, January 1975
@see Barnes W. McCormick, "Aerodynamics, Aeronautics, and Flight Mechanics",
Wiley & Sons, 1979 ISBN 0-471-03032-5
@see W. A. Ragsdale, "A Generic Landing Gear Dynamics Model for LASRS++",
AIAA-2000-4303
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DECLARATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
class FGLGear : public FGJSBBase
{
public:
/// Brake grouping enumerators
enum BrakeGroup {bgNone=0, bgLeft, bgRight, bgCenter, bgNose, bgTail };
/// Steering group membership enumerators
enum SteerType {stSteer, stFixed, stCaster};
/// Report type enumerators
enum ReportType {erNone=0, erTakeoff, erLand};
/** Constructor
@param Executive a pointer to the parent executive object
@param File a pointer to the config file instance */
FGLGear(FGConfigFile* File, FGFDMExec* Executive, int number);
/** Constructor
@param lgear a reference to an existing FGLGear object */
FGLGear(const FGLGear& lgear);
/// Destructor
~FGLGear();
/// The Force vector for this gear
FGColumnVector3& Force(void);
/// The Moment vector for this gear
FGColumnVector3& Moment(void) {return vMoment;}
/// Gets the location of the gear in Body axes
FGColumnVector3& GetBodyLocation(void) { return vWhlBodyVec; }
double GetBodyLocation(int idx) { return vWhlBodyVec(idx); }
FGColumnVector3& GetLocalGear(void) { return vLocalGear; }
double GetLocalGear(int idx) { return vLocalGear(idx); }
/// Gets the name of the gear
inline string GetName(void) {return name; }
/// Gets the Weight On Wheels flag value
inline bool GetWOW(void) {return WOW; }
/// Gets the current compressed length of the gear in feet
inline double GetCompLen(void) {return compressLength;}
/// Gets the current gear compression velocity in ft/sec
inline double GetCompVel(void) {return compressSpeed; }
/// Gets the gear compression force in pounds
inline double GetCompForce(void) {return Force()(3); }
inline double GetBrakeFCoeff(void) {return BrakeFCoeff;}
inline double GetXYZ(int i) {return vXYZ(i);}
/// Gets the current normalized tire pressure
inline double GetTirePressure(void) { return TirePressureNorm; }
/// Sets the new normalized tire pressure
inline void SetTirePressure(double p) { TirePressureNorm = p; }
/// Sets the brake value in percent (0 - 100)
inline void SetBrake(double bp) {brakePct = bp;}
/** Set the console touchdown reporting feature
@param flag true turns on touchdown reporting, false turns it off */
inline void SetReport(bool flag) { ReportEnable = flag; }
/** Get the console touchdown reporting feature
@return true if reporting is turned on */
inline bool GetReport(void) { return ReportEnable; }
double GetSteerNorm(void) const { return radtodeg/maxSteerAngle*SteerAngle; }
double GetDefaultSteerAngle(double cmd) const { return cmd*maxSteerAngle; }
double GetstaticFCoeff(void) { return staticFCoeff; }
double GetdynamicFCoeff(void) { return dynamicFCoeff; }
double GetrollingFCoeff(void) { return rollingFCoeff; }
inline int GetBrakeGroup(void) { return (int)eBrakeGrp; }
inline int GetSteerType(void) { return (int)eSteerType; }
bool GetSteerable(void) const { return eSteerType != stFixed; }
inline bool GetRetractable(void) const { return isRetractable; }
inline bool GetGearUnitUp(void) const { return GearUp; }
inline bool GetGearUnitDown(void) const { return GearDown; }
inline double GetWheelSideForce(void) const { return SideForce; }
inline double GetWheelRollForce(void) const { return RollingForce; }
inline double GetBodyXForce(void) const { return vLocalForce(eX); }
inline double GetBodyYForce(void) const { return vLocalForce(eY); }
inline double GetWheelSlipAngle(void) const { return WheelSlip; }
double GetWheelVel(int axis) const { return vWhlVelVec(axis);}
double GetkSpring(void) const { return kSpring; }
double GetbDamp(void) const { return bDamp; }
double GetmaxSteerAngle(void) const { return maxSteerAngle; }
string GetsBrakeGroup(void) const { return sBrakeGroup; }
string GetsRetractable(void) const { return sRetractable; }
string GetsSteerType(void) const { return sSteerType; }
private:
int GearNumber;
FGColumnVector3 vXYZ;
FGColumnVector3 vMoment;
FGColumnVector3 vWhlBodyVec;
FGColumnVector3 vLocalGear;
FGColumnVector3 vForce;
FGColumnVector3 vLocalForce;
FGColumnVector3 vWhlVelVec; // Velocity of this wheel (Local)
double SteerAngle;
double kSpring;
double bDamp;
double compressLength;
double compressSpeed;
double staticFCoeff, dynamicFCoeff, rollingFCoeff;
double brakePct;
double BrakeFCoeff;
double maxCompLen;
double SinkRate;
double GroundSpeed;
double TakeoffDistanceTraveled;
double TakeoffDistanceTraveled50ft;
double LandingDistanceTraveled;
double MaximumStrutForce;
double MaximumStrutTravel;
double SideWhlVel, RollingWhlVel;
double RollingForce, SideForce, FCoeff;
double WheelSlip;
double lastWheelSlip;
double TirePressureNorm;
bool WOW;
bool lastWOW;
bool FirstContact;
bool StartedGroundRun;
bool LandingReported;
bool TakeoffReported;
bool ReportEnable;
bool isRetractable;
bool GearUp, GearDown;
bool Servicable;
string name;
string sSteerType;
string sBrakeGroup;
string sRetractable;
BrakeGroup eBrakeGrp;
SteerType eSteerType;
double maxSteerAngle;
FGFDMExec* Exec;
FGState* State;
FGAircraft* Aircraft;
FGPropagate* Propagate;
FGAuxiliary* Auxiliary;
FGFCS* FCS;
FGMassBalance* MassBalance;
void Report(ReportType rt);
void Debug(int from);
};
}
#include "FGAircraft.h"
#include "FGPropagate.h"
#include "FGAuxiliary.h"
#include "FGFCS.h"
#include "FGMassBalance.h"
#include "FGState.h"
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#endif

View file

@ -1,221 +0,0 @@
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Module: FGLocation.cpp
Author: Jon S. Berndt
Date started: 04/04/2004
Purpose: Store an arbitrary location on the globe
------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) ------------------
------- (C) 2004 Mathias Froehlich (Mathias.Froehlich@web.de) ----
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU 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 General Public License for more
details.
You should have received a copy of the GNU 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 General Public License can also be found on
the world wide web at http://www.gnu.org.
FUNCTIONAL DESCRIPTION
------------------------------------------------------------------------------
This class encapsulates an arbitrary position in the globe with its accessors.
It has vector properties, so you can add multiply ....
HISTORY
------------------------------------------------------------------------------
04/04/2004 MF Created
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#ifdef FGFS
# include <simgear/compiler.h>
# ifdef SG_HAVE_STD_INCLUDES
# include <cmath>
# else
# include <math.h>
# endif
#else
# if defined(sgi) && !defined(__GNUC__)
# include <math.h>
# else
# include <cmath>
# endif
#endif
#include "FGLocation.h"
#include "FGPropertyManager.h"
namespace JSBSim {
static const char *IdSrc = "$Id$";
static const char *IdHdr = ID_LOCATION;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
FGLocation::FGLocation(double lon, double lat, double radius)
{
mCacheValid = false;
double sinLat = sin(lat);
double cosLat = cos(lat);
double sinLon = sin(lon);
double cosLon = cos(lon);
mECLoc = FGColumnVector3( radius*cosLat*cosLon,
radius*cosLat*sinLon,
radius*sinLat );
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGLocation::SetLongitude(double longitude)
{
double rtmp = mECLoc.Magnitude(eX, eY);
// Check if we have zero radius.
// If so set it to 1, so that we can set a position
if (0.0 == mECLoc.Magnitude())
rtmp = 1.0;
// Fast return if we are on the north or south pole ...
if (rtmp == 0.0)
return;
mCacheValid = false;
mECLoc(eX) = rtmp*cos(longitude);
mECLoc(eY) = rtmp*sin(longitude);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGLocation::SetLatitude(double latitude)
{
mCacheValid = false;
double r = mECLoc.Magnitude();
if (r == 0.0) {
mECLoc(eX) = 1.0;
r = 1.0;
}
double rtmp = mECLoc.Magnitude(eX, eY);
if (rtmp != 0.0) {
double fac = r/rtmp*cos(latitude);
mECLoc(eX) *= fac;
mECLoc(eY) *= fac;
} else {
mECLoc(eX) = r*cos(latitude);
mECLoc(eY) = 0.0;
}
mECLoc(eZ) = r*sin(latitude);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGLocation::SetRadius(double radius)
{
mCacheValid = false;
double rold = mECLoc.Magnitude();
if (rold == 0.0)
mECLoc(eX) = radius;
else
mECLoc *= radius/rold;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGLocation::ComputeDerivedUnconditional(void) const
{
// The radius is just the Euclidean norm of the vector.
mRadius = mECLoc.Magnitude();
// The distance of the location to the y-axis, which is the axis
// through the poles.
double rxy = sqrt(mECLoc(eX)*mECLoc(eX) + mECLoc(eY)*mECLoc(eY));
// Compute the sin/cos values of the longitude
double sinLon, cosLon;
if (rxy == 0.0) {
sinLon = 0.0;
cosLon = 1.0;
} else {
sinLon = mECLoc(eY)/rxy;
cosLon = mECLoc(eX)/rxy;
}
// Compute the sin/cos values of the latitude
double sinLat, cosLat;
if (mRadius == 0.0) {
sinLat = 0.0;
cosLat = 1.0;
} else {
sinLat = mECLoc(eZ)/mRadius;
cosLat = rxy/mRadius;
}
// Compute the longitude and latitude itself
if ( mECLoc( eX ) == 0.0 && mECLoc( eY ) == 0.0 )
mLon = 0.0;
else
mLon = atan2( mECLoc( eY ), mECLoc( eX ) );
if ( rxy == 0.0 && mECLoc( eZ ) == 0.0 )
mLat = 0.0;
else
mLat = atan2( mECLoc(eZ), rxy );
// Compute the transform matrices from and to the earth centered frame.
// see Durham Chapter 4, problem 1, page 52
mTec2l = FGMatrix33( -cosLon*sinLat, -sinLon*sinLat, cosLat,
-sinLon , cosLon , 0.0 ,
-cosLon*cosLat, -sinLon*cosLat, -sinLat );
mTl2ec = mTec2l.Transposed();
// Mark the cached values as valid
mCacheValid = true;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGLocation::bind(FGPropertyManager* PropertyManager, const string& prefix) const
{
PropertyManager->Tie(prefix + "lat-gc-rad", (FGLocation*)this,
&FGLocation::GetLatitude);
PropertyManager->Tie(prefix + "lat-gc-deg", (FGLocation*)this,
&FGLocation::GetLatitudeDeg);
PropertyManager->Tie(prefix + "long-gc-rad", (FGLocation*)this,
&FGLocation::GetLongitude);
PropertyManager->Tie(prefix + "long-gc-deg", (FGLocation*)this,
&FGLocation::GetLongitudeDeg);
PropertyManager->Tie(prefix + "radius-ft", (FGLocation*)this,
&FGLocation::GetRadius);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGLocation::unbind(FGPropertyManager* PropertyManager, const string& prefix) const
{
PropertyManager->Untie(prefix + "lat-gc-rad");
PropertyManager->Untie(prefix + "lat-gc-deg");
PropertyManager->Untie(prefix + "long-gc-rad");
PropertyManager->Untie(prefix + "long-gc-deg");
PropertyManager->Untie(prefix + "radius-ft");
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
} // namespace JSBSim

View file

@ -203,8 +203,10 @@ string FGFunction::GetValueAsString(void) const
void FGFunction::bind(void)
{
string tmp = PropertyManager->mkPropertyName(Prefix + Name, false); // Allow upper case
PropertyManager->Tie( tmp, this, &FGFunction::GetValue);
if ( !Name.empty() ) {
string tmp = PropertyManager->mkPropertyName(Prefix + Name, false); // Allow upper case
PropertyManager->Tie( tmp, this, &FGFunction::GetValue);
}
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%