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,8 +203,10 @@ string FGFunction::GetValueAsString(void) const
|
||||||
|
|
||||||
void FGFunction::bind(void)
|
void FGFunction::bind(void)
|
||||||
{
|
{
|
||||||
string tmp = PropertyManager->mkPropertyName(Prefix + Name, false); // Allow upper case
|
if ( !Name.empty() ) {
|
||||||
PropertyManager->Tie( tmp, this, &FGFunction::GetValue);
|
string tmp = PropertyManager->mkPropertyName(Prefix + Name, false); // Allow upper case
|
||||||
|
PropertyManager->Tie( tmp, this, &FGFunction::GetValue);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
Loading…
Add table
Reference in a new issue