Remove a bunch of unneede files.
This commit is contained in:
parent
d0618685a2
commit
587fd0937e
36 changed files with 4 additions and 10866 deletions
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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
|
|
@ -203,9 +203,11 @@ string FGFunction::GetValueAsString(void) const
|
|||
|
||||
void FGFunction::bind(void)
|
||||
{
|
||||
if ( !Name.empty() ) {
|
||||
string tmp = PropertyManager->mkPropertyName(Prefix + Name, false); // Allow upper case
|
||||
PropertyManager->Tie( tmp, this, &FGFunction::GetValue);
|
||||
}
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
// The bitmasked value choices are as follows:
|
||||
|
|
Loading…
Reference in a new issue