1
0
Fork 0

Sync with latest JSBSim changes.

This commit is contained in:
curt 2001-11-30 17:49:37 +00:00
parent c167c60de9
commit 71a562b695
31 changed files with 774 additions and 475 deletions

View file

@ -198,7 +198,7 @@ void FGJSBsim::init() {
break;
}
stall_warning->setBoolValue(false);
stall_warning->setDoubleValue(0);
SG_LOG( SG_FLIGHT, SG_INFO, " Bank Angle: "
<< Rotation->Getphi()*RADTODEG << " deg" );
@ -382,7 +382,7 @@ bool FGJSBsim::copy_from_JSBsim() {
// Auxiliary->GetNpilot(2)/32.1739,
// Auxiliary->GetNpilot(3)/32.1739 );
_set_Nlf( Aerodynamics->GetNlf() );
_set_Nlf( Aircraft->GetNlf() );
// Velocities

56
src/FDM/JSBSim/AUTHORS Normal file
View file

@ -0,0 +1,56 @@
AUTHORS
-------
Jon S. Berndt
primary architect and coordinator
jsb@hal-pc.org
CVS access as developer (r/w)
Tony Peden
additional architecture support
trimming and aerodynamics
interface with flightgear
apeden@earthlink.net
CVS access as developer (r/w)
Additional support (programming, bug fixes, aircraft models)
by the FlightGear team and others as listed:
Curt Olson
wrote initial interface with flightgear
works flightgear/jsbsim issues
curt@flightgear.org
Norman Vine
matrix math class optimization support
general C++ suggestions, debugging, and support
nhv@cape.com
Christian Mayer
JSBSim compatibility with MSVC
mail@ChristianMayer.de
Erik Hofman
JSBSim compatibility with IRIX
erik@ehofman.com
David Megginson
ported Dave Luff's piston engine model initially to JSBSim
creation of multi-engine C-310 model and testing/debugging
general C++ suggestions, debugging, and support
david@megginson.com
Ross Golder
improvements to the build process and auto* files
ross@golder.org
Dave Luff
wrote the piston engine model used by LaRCSim and is ported to JSBSim
eazdluf@nottingham.ac.uk
Norman Princen
provided an improved gear model
nprincen@hotmail.com

View file

@ -100,7 +100,10 @@ bool FGAerodynamics::Run(void)
vFs(axis_ctr+1) += Coeff[axis_ctr][ctr]->TotalValue();
}
}
//correct signs of drag and lift to wind axes convention
//positive forward, right, down
vFs(1)*=-1; vFs(3)*=-1;
//cout << "Aircraft::vFs: " << vFs << endl;
vForces = State->GetTs2b()*vFs;
vDXYZcg(eX) = -(Aircraft->GetXYZrp(eX)
@ -198,17 +201,6 @@ string FGAerodynamics::GetCoefficientValues(void)
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
double FGAerodynamics::GetNlf(void)
{
if (fabs(Position->GetGamma()) < 1.57) {
return (vFs(eZ)/(MassBalance->GetWeight()*cos(Position->GetGamma())));
} else {
return 0.0;
}
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
double FGAerodynamics::GetLoD(void)
{
double LoD;

View file

@ -134,8 +134,6 @@ public:
coefficients */
string GetCoefficientValues(void);
/// Gets the Normal Load Factor
double GetNlf(void);
private:
typedef map<string,int> AxisIndex;

View file

@ -105,7 +105,8 @@ FGAircraft::FGAircraft(FGFDMExec* fdmex) : FGModel(fdmex),
vXYZep(3),
vDXYZcg(3),
vBodyAccel(3),
vNcg(3)
vNcg(3),
vNwcg(3)
{
Name = "FGAircraft";
alphaclmin = alphaclmax = 0;
@ -179,6 +180,9 @@ bool FGAircraft::Run(void)
vBodyAccel = vForces/MassBalance->GetMass();
vNcg = vBodyAccel/Inertial->gravity();
vNwcg = State->GetTb2s() * vNcg;
vNwcg(3) = -1*vNwcg(3) + 1;
if (alphaclmax != 0) {
if (Translation->Getalpha() > 0.85*alphaclmax) {
@ -196,6 +200,13 @@ bool FGAircraft::Run(void)
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
float FGAircraft::GetNlf(void)
{
return vNwcg(3);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGAircraft::ReadPrologue(FGConfigFile* AC_cfg)
{
string token = AC_cfg->GetValue();

View file

@ -200,7 +200,11 @@ public:
inline void SetAlphaCLMax(double tt) { alphaclmax=tt; }
inline void SetAlphaCLMin(double tt) { alphaclmin=tt; }
inline bool GetStallWarn(void) { return impending_stall; }
inline double GetStallWarn(void) { return impending_stall; }
float GetNlf(void);
inline FGColumnVector3& GetNwcg(void) { return vNwcg; }
private:
FGColumnVector3 vMoments;
@ -211,6 +215,7 @@ private:
FGColumnVector3 vDXYZcg;
FGColumnVector3 vBodyAccel;
FGColumnVector3 vNcg;
FGColumnVector3 vNwcg;
double WingArea, WingSpan, cbar, WingIncidence;
double HTailArea, VTailArea, HTailArm, VTailArm;

View file

@ -145,6 +145,7 @@ public:
inline void SetTurbGain(double tt) {TurbGain = tt;}
inline double GetTurbPQR(int idx) {return vTurbPQR(idx);}
inline FGColumnVector3& GetTurbPQR(void) {return vTurbPQR;}
private:
double rho;

View file

@ -1,322 +1,322 @@
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include "FGConfigFile.h"
#include <stdlib.h>
#include <math.h>
static const char *IdSrc = "$Id$";
static const char *IdHdr = ID_CONFIGFILE;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
FGConfigFile::FGConfigFile(string cfgFileName)
{
#if defined ( sgi ) && !defined( __GNUC__ )
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__ )
if (!cfgfile.fail() && !cfgfile.eof()) GetNextConfigLine();
#else
if (cfgfile.is_open()) GetNextConfigLine();
#endif
else Opened = false;
if (debug_lvl & 2) cout << "Instantiated: FGConfigFile" << endl;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGConfigFile::~FGConfigFile()
{
cfgfile.close();
if (debug_lvl & 2) cout << "Destroyed: FGConfigFile" << endl;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
string FGConfigFile::GetNextConfigLine(void)
{
int deblank, not_found = string::npos;
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);
} 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);
if (CurrentLine.length() == 0) GetNextConfigLine();
CurrentIndex = 0;
return CurrentLine;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
string FGConfigFile::GetValue(string val)
{
unsigned int 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__ )
if (test >= 0x20 || test == 0x09) cfgfile.putback(test);
#else
if (test >= 0x20 || test == 0x09) cfgfile.unget();
#endif
break;
}
}
}
if (cfgfile.eof()) return string("EOF");
return scratch;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
/*
FGConfigFile& FGConfigFile::operator>>(double& val)
{
unsigned int 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 (CurrentIndex >= CurrentLine.length()) GetNextConfigLine();
return *this;
}
*/
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGConfigFile& FGConfigFile::operator>>(double& val)
{
unsigned int 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 (CurrentIndex >= CurrentLine.length()) GetNextConfigLine();
return *this;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGConfigFile& FGConfigFile::operator>>(int& val)
{
unsigned int 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 (CurrentIndex >= CurrentLine.length()) GetNextConfigLine();
return *this;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGConfigFile& FGConfigFile::operator>>(eParam& val)
{
unsigned int 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 = (eParam)atoi(str.c_str());
CurrentIndex = end+1;
if (CurrentIndex >= CurrentLine.length()) GetNextConfigLine();
return *this;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGConfigFile& FGConfigFile::operator>>(string& str)
{
unsigned int 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 (CurrentIndex >= CurrentLine.length()) GetNextConfigLine();
return *this;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGConfigFile::ResetLineIndexToZero(void)
{
CurrentIndex = 0;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGConfigFile::Debug(void)
{
//TODO: Add your source code here
}
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include "FGConfigFile.h"
#include <stdlib.h>
#include <math.h>
static const char *IdSrc = "$Id$";
static const char *IdHdr = ID_CONFIGFILE;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
FGConfigFile::FGConfigFile(string cfgFileName)
{
#if defined ( sgi ) && !defined( __GNUC__ )
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__ )
if (!cfgfile.fail() && !cfgfile.eof()) GetNextConfigLine();
#else
if (cfgfile.is_open()) GetNextConfigLine();
#endif
else Opened = false;
if (debug_lvl & 2) cout << "Instantiated: FGConfigFile" << endl;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGConfigFile::~FGConfigFile()
{
cfgfile.close();
if (debug_lvl & 2) cout << "Destroyed: FGConfigFile" << endl;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
string FGConfigFile::GetNextConfigLine(void)
{
int deblank, not_found = string::npos;
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);
} 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);
if (CurrentLine.length() == 0) GetNextConfigLine();
CurrentIndex = 0;
return CurrentLine;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
string FGConfigFile::GetValue(string val)
{
unsigned int 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__ )
if (test >= 0x20 || test == 0x09) cfgfile.putback(test);
#else
if (test >= 0x20 || test == 0x09) cfgfile.unget();
#endif
break;
}
}
}
if (cfgfile.eof()) return string("EOF");
return scratch;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
/*
FGConfigFile& FGConfigFile::operator>>(double& val)
{
unsigned int 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 (CurrentIndex >= CurrentLine.length()) GetNextConfigLine();
return *this;
}
*/
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGConfigFile& FGConfigFile::operator>>(double& val)
{
unsigned int 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 (CurrentIndex >= CurrentLine.length()) GetNextConfigLine();
return *this;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGConfigFile& FGConfigFile::operator>>(int& val)
{
unsigned int 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 (CurrentIndex >= CurrentLine.length()) GetNextConfigLine();
return *this;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGConfigFile& FGConfigFile::operator>>(eParam& val)
{
unsigned int 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 = (eParam)atoi(str.c_str());
CurrentIndex = end+1;
if (CurrentIndex >= CurrentLine.length()) GetNextConfigLine();
return *this;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGConfigFile& FGConfigFile::operator>>(string& str)
{
unsigned int 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 (CurrentIndex >= CurrentLine.length()) GetNextConfigLine();
return *this;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGConfigFile::ResetLineIndexToZero(void)
{
CurrentIndex = 0;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGConfigFile::Debug(void)
{
//TODO: Add your source code here
}

View file

@ -64,7 +64,8 @@ CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
FGEngine::FGEngine(FGFDMExec* exec) {
FGEngine::FGEngine(FGFDMExec* exec)
{
FDMExec = exec;
State = FDMExec->GetState();
Atmosphere = FDMExec->GetAtmosphere();
@ -101,7 +102,8 @@ FGEngine::~FGEngine()
// This base class method removes fuel from the fuel tanks as appropriate,
// and sets the starved flag if necessary.
void FGEngine::ConsumeFuel(void) {
void FGEngine::ConsumeFuel(void)
{
double Fshortage, Oshortage;
FGTank* Tank;

View file

@ -117,15 +117,15 @@ public:
virtual double GetThrottleMax(void) { return MaxThrottle; }
double GetThrottle(void) { return Throttle; }
double GetMixture(void) { return Mixture; }
int GetMagnetos(void) { return Magnetos; }
int GetMagnetos(void) { return Magnetos; }
bool GetStarter(void) { return Starter; }
double GetThrust(void) { return Thrust; }
bool GetStarved(void) { return Starved; }
bool GetFlameout(void) { return Flameout; }
bool GetRunning(void) { return Running; }
bool GetCranking(void) { return Cranking; }
int GetType(void) { return Type; }
string GetName(void) { return Name; }
bool GetStarved(void) { return Starved; }
bool GetFlameout(void) { return Flameout; }
bool GetRunning(void) { return Running; }
bool GetCranking(void) { return Cranking; }
int GetType(void) { return Type; }
string GetName(void) { return Name; }
virtual double getManifoldPressure_inHg () const {
return ManifoldPressure_inHg;
@ -182,6 +182,9 @@ public:
/// Sets engine placement information
void SetPlacement(double x, double y, double z, double pitch, double yaw);
/// Sets the engine number
void SetEngineNumber(int nn) {EngineNumber = nn;}
virtual double GetPowerAvailable(void) {return 0.0;};
bool GetTrimMode(void) {return TrimMode;}

View file

@ -85,7 +85,7 @@ FGFCS::~FGFCS()
unsigned int i;
for(i=0;i<Components.size();i++) delete Components[i];
for (i=0;i<Components.size();i++) delete Components[i];
if (debug_lvl & 2) cout << "Destroyed: FGFCS" << endl;
}

View file

@ -67,8 +67,8 @@ const double FGJSBBase::SHRatio = 1.40;
const string FGJSBBase::needed_cfg_version = "1.55";
const string FGJSBBase::JSBSim_version = "0.9.1";
queue <struct FGJSBBase::Message*> FGJSBBase::Messages;
struct FGJSBBase::Message FGJSBBase::localMsg;
queue <FGJSBBase::Message*> FGJSBBase::Messages;
FGJSBBase::Message FGJSBBase::localMsg;
unsigned int FGJSBBase::messageId = 0;
unsigned int FGJSBBase::frame = 0;
@ -82,7 +82,7 @@ FGJSBBase::FGJSBBase()
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
struct FGJSBBase::Message* FGJSBBase::PutMessage(struct Message* msg)
FGJSBBase::Message* FGJSBBase::PutMessage(Message* msg)
{
Messages.push(msg);
return msg;
@ -90,9 +90,9 @@ struct FGJSBBase::Message* FGJSBBase::PutMessage(struct Message* msg)
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
struct FGJSBBase::Message* FGJSBBase::PutMessage(string text)
FGJSBBase::Message* FGJSBBase::PutMessage(string text)
{
struct Message *msg = new Message();
Message *msg = new Message();
msg->text = text;
msg->messageId = messageId++;
msg->subsystem = "FDM";
@ -103,9 +103,9 @@ struct FGJSBBase::Message* FGJSBBase::PutMessage(string text)
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
struct FGJSBBase::Message* FGJSBBase::PutMessage(string text, bool bVal)
FGJSBBase::Message* FGJSBBase::PutMessage(string text, bool bVal)
{
struct Message *msg = new Message();
Message *msg = new Message();
msg->text = text;
msg->messageId = messageId++;
msg->subsystem = "FDM";
@ -117,9 +117,9 @@ struct FGJSBBase::Message* FGJSBBase::PutMessage(string text, bool bVal)
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
struct FGJSBBase::Message* FGJSBBase::PutMessage(string text, int iVal)
FGJSBBase::Message* FGJSBBase::PutMessage(string text, int iVal)
{
struct Message *msg = new Message();
Message *msg = new Message();
msg->text = text;
msg->messageId = messageId++;
msg->subsystem = "FDM";
@ -131,9 +131,9 @@ struct FGJSBBase::Message* FGJSBBase::PutMessage(string text, int iVal)
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
struct FGJSBBase::Message* FGJSBBase::PutMessage(string text, double dVal)
FGJSBBase::Message* FGJSBBase::PutMessage(string text, double dVal)
{
struct Message *msg = new Message();
Message *msg = new Message();
msg->text = text;
msg->messageId = messageId++;
msg->subsystem = "FDM";
@ -145,7 +145,7 @@ struct FGJSBBase::Message* FGJSBBase::PutMessage(string text, double dVal)
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
struct FGJSBBase::Message* FGJSBBase::ReadMessage(void)
FGJSBBase::Message* FGJSBBase::ReadMessage(void)
{
if (!Messages.empty()) return Messages.front();
else return NULL;
@ -153,7 +153,7 @@ struct FGJSBBase::Message* FGJSBBase::ReadMessage(void)
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
struct FGJSBBase::Message* FGJSBBase::ProcessMessage(void)
FGJSBBase::Message* FGJSBBase::ProcessMessage(void)
{
if (!Messages.empty())
localMsg = *(Messages.front());

View file

@ -165,7 +165,7 @@ public:
virtual ~FGJSBBase() {};
/// JSBSim Message structure
struct Message {
typedef struct Msg {
unsigned int fdmId;
unsigned int messageId;
string text;
@ -174,7 +174,7 @@ public:
bool bVal;
int iVal;
double dVal;
};
} Message;
///@name JSBSim Enums.
//@{
@ -227,38 +227,38 @@ public:
/** Places a Message structure on the Message queue.
@param msg pointer to a Message structure
@return pointer to a Message structure */
struct Message* PutMessage(struct Message* msg);
Message* PutMessage(Message* msg);
/** Creates a message with the given text and places it on the queue.
@param text message text
@return pointer to a Message structure */
struct Message* PutMessage(string text);
Message* PutMessage(string text);
/** Creates a message with the given text and boolean value and places it on the queue.
@param text message text
@param bVal boolean value associated with the message
@return pointer to a Message structure */
struct Message* PutMessage(string text, bool bVal);
Message* PutMessage(string text, bool bVal);
/** Creates a message with the given text and integer value and places it on the queue.
@param text message text
@param iVal integer value associated with the message
@return pointer to a Message structure */
struct Message* PutMessage(string text, int iVal);
Message* PutMessage(string text, int iVal);
/** Creates a message with the given text and double value and places it on the queue.
@param text message text
@param dVal double value associated with the message
@return pointer to a Message structure */
struct Message* PutMessage(string text, double dVal);
Message* PutMessage(string text, double dVal);
/** Reads the message on the queue (but does not delete it).
@return pointer to a Message structure (or NULL if no mesage) */
struct Message* ReadMessage(void);
Message* ReadMessage(void);
/** Reads the message on the queue and removes it from the queue.
@return pointer to a Message structure (or NULL if no mesage) */
struct Message* ProcessMessage(void);
Message* ProcessMessage(void);
//@}
protected:
static struct Message localMsg;
static Message localMsg;
static queue <struct Message*> Messages;
static queue <Message*> Messages;
virtual void Debug(void) {};

View file

@ -148,8 +148,6 @@ void FGOutput::DelimitedOutput(string fname)
}
if (SubSystems & ssAerosurfaces) {
outstream << ", ";
outstream << "Throttle, ";
outstream << "Mixture, ";
outstream << "Aileron Cmd, ";
outstream << "Elevator Cmd, ";
outstream << "Rudder Cmd, ";
@ -224,8 +222,6 @@ void FGOutput::DelimitedOutput(string fname)
}
if (SubSystems & ssAerosurfaces) {
outstream << ", ";
outstream << FCS->GetThrottlePos(0) << ", ";
outstream << FCS->GetMixturePos(0) << ", ";
outstream << FCS->GetDaCmd() << ", ";
outstream << FCS->GetDeCmd() << ", ";
outstream << FCS->GetDrCmd() << ", ";
@ -242,7 +238,7 @@ void FGOutput::DelimitedOutput(string fname)
outstream << Translation->Getqbar() << ", ";
outstream << Translation->GetVt() << ", ";
outstream << Translation->GetUVW() << ", ";
outstream << Translation->GetvAero() << ", ";
outstream << Translation->GetvAeroUVW() << ", ";
outstream << Position->GetVel();
}
if (SubSystems & ssForces) {
@ -360,9 +356,9 @@ void FGOutput::SocketOutput(void)
socket->Append(Translation->GetUVW(eU));
socket->Append(Translation->GetUVW(eV));
socket->Append(Translation->GetUVW(eW));
socket->Append(Translation->GetvAero(eU));
socket->Append(Translation->GetvAero(eV));
socket->Append(Translation->GetvAero(eW));
socket->Append(Translation->GetvAeroUVW(eU));
socket->Append(Translation->GetvAeroUVW(eV));
socket->Append(Translation->GetvAeroUVW(eW));
socket->Append(Position->GetVn());
socket->Append(Position->GetVe());
socket->Append(Position->GetVd());

View file

@ -144,6 +144,7 @@ Notes: [TP] Make sure that -Vt <= hdot <= Vt, which, of course, should always
bool FGPosition::Run(void) {
double cosLat;
double hdot_Vt;
FGColumnVector3 vMac;
if (!FGModel::Run()) {
GetState();
@ -171,7 +172,13 @@ bool FGPosition::Run(void) {
DistanceAGL = Radius - RunwayRadius; // Geocentric
hoverb = DistanceAGL/b;
hoverbcg = DistanceAGL/b;
vMac=State->GetTb2l()*Aircraft->GetXYZrp();
vMac *= inchtoft;
hoverbmac = (DistanceAGL + vMac(3))/b;
if (Vt > 0) {
hdot_Vt = RadiusDot/Vt;
@ -209,7 +216,7 @@ void FGPosition::Seth(double tt) {
h = tt;
Radius = h + SeaLevelRadius;
DistanceAGL = Radius - RunwayRadius; // Geocentric
hoverb = DistanceAGL/b;
hoverbcg = DistanceAGL/b;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -218,7 +225,7 @@ void FGPosition::SetDistanceAGL(double tt) {
DistanceAGL=tt;
Radius = RunwayRadius + DistanceAGL;
h = Radius - SeaLevelRadius;
hoverb = DistanceAGL/b;
hoverbcg = DistanceAGL/b;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

View file

@ -105,7 +105,8 @@ public:
inline double GetGamma(void) { return gamma; }
inline void SetGamma(double tt) { gamma = tt; }
inline double GetHOverB(void) { return hoverb; }
inline double GetHOverBCG(void) { return hoverbcg; }
inline double GetHOverBMAC(void){ return hoverbmac; }
void SetvVel(const FGColumnVector3& v) { vVel = v; }
void SetLatitude(double tt) { Latitude = tt; }
void SetLongitude(double tt) { Longitude = tt; }
@ -133,7 +134,7 @@ private:
double SeaLevelRadius;
double gamma;
double Vt, Vground;
double hoverb,b;
double hoverbcg,hoverbmac,b;
double psigt;

View file

@ -50,7 +50,7 @@ FGPropeller::FGPropeller(FGFDMExec* exec, FGConfigFile* Prop_cfg) : FGThruster(e
string token;
int rows, cols;
MaxPitch = MinPitch = P_Factor = Sense = 0.0;
MaxPitch = MinPitch = P_Factor = Sense = Pitch = 0.0;
Name = Prop_cfg->GetValue("NAME");
Prop_cfg->GetNextConfigLine();
@ -138,7 +138,7 @@ FGPropeller::~FGPropeller()
double FGPropeller::Calculate(double PowerAvailable)
{
double J, C_Thrust, omega;
double Vel = (fdmex->GetTranslation()->GetvAero())(1);
double Vel = fdmex->GetTranslation()->GetvAeroUVW(eU);
double rho = fdmex->GetAtmosphere()->GetDensity();
double RPS = RPM/60.0;
double alpha, beta;
@ -194,7 +194,7 @@ double FGPropeller::GetPowerRequired(void)
double cPReq, RPS = RPM / 60.0;
double J = (fdmex->GetTranslation()->GetvAero())(1) / (Diameter * RPS);
double J = fdmex->GetTranslation()->GetvAeroUVW(eU) / (Diameter * RPS);
double rho = fdmex->GetAtmosphere()->GetDensity();
if (MaxPitch == MinPitch) { // Fixed pitch prop

View file

@ -62,14 +62,14 @@ CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
FGPropulsion::FGPropulsion(FGFDMExec* exec) : FGModel(exec)
FGPropulsion::FGPropulsion(FGFDMExec* exec) : FGModel(exec),
Forces(3),
Moments(3)
{
Name = "FGPropulsion";
numSelectedFuelTanks = numSelectedOxiTanks = 0;
numTanks = numEngines = numThrusters = 0;
numOxiTanks = numFuelTanks = 0;
Forces = new FGColumnVector3(3);
Moments = new FGColumnVector3(3);
if (debug_lvl & 2) cout << "Instantiated: " << Name << endl;
}
@ -80,8 +80,6 @@ FGPropulsion::~FGPropulsion()
{
for (unsigned int i=0; i<Engines.size(); i++) delete Engines[i];
Engines.clear();
if (Forces) delete Forces;
if (Moments) delete Moments;
if (debug_lvl & 2) cout << "Destroyed: FGPropulsion" << endl;
}
@ -92,16 +90,16 @@ bool FGPropulsion::Run(void)
double PowerAvailable;
dt = State->Getdt();
Forces->InitMatrix();
Moments->InitMatrix();
Forces.InitMatrix();
Moments.InitMatrix();
if (!FGModel::Run()) {
for (unsigned int i=0; i<numEngines; i++) {
Thrusters[i]->SetdeltaT(dt*rate);
PowerAvailable = Engines[i]->Calculate(Thrusters[i]->GetPowerRequired());
Thrusters[i]->Calculate(PowerAvailable);
*Forces += Thrusters[i]->GetBodyForces(); // sum body frame forces
*Moments += Thrusters[i]->GetMoments(); // sum body frame moments
Forces += Thrusters[i]->GetBodyForces(); // sum body frame forces
Moments += Thrusters[i]->GetMoments(); // sum body frame moments
}
return false;
} else {
@ -111,15 +109,16 @@ bool FGPropulsion::Run(void)
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
bool FGPropulsion::GetSteadyState(void) {
bool FGPropulsion::GetSteadyState(void)
{
double PowerAvailable;
double currentThrust = 0, lastThrust=-1;
dt = State->Getdt();
int steady_count,j=0;
bool steady=false;
Forces->InitMatrix();
Moments->InitMatrix();
Forces.InitMatrix();
Moments.InitMatrix();
if (!FGModel::Run()) {
for (unsigned int i=0; i<numEngines; i++) {
@ -138,8 +137,8 @@ bool FGPropulsion::GetSteadyState(void) {
}
j++;
}
*Forces += Thrusters[i]->GetBodyForces(); // sum body frame forces
*Moments += Thrusters[i]->GetMoments(); // sum body frame moments
Forces += Thrusters[i]->GetBodyForces(); // sum body frame forces
Moments += Thrusters[i]->GetMoments(); // sum body frame moments
Engines[i]->SetTrimMode(false);
}
@ -152,13 +151,14 @@ bool FGPropulsion::GetSteadyState(void) {
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
bool FGPropulsion::ICEngineStart(void) {
bool FGPropulsion::ICEngineStart(void)
{
double PowerAvailable;
int j;
dt = State->Getdt();
Forces->InitMatrix();
Moments->InitMatrix();
Forces.InitMatrix();
Moments.InitMatrix();
for (unsigned int i=0; i<numEngines; i++) {
Engines[i]->SetTrimMode(true);
@ -169,8 +169,8 @@ bool FGPropulsion::ICEngineStart(void) {
Thrusters[i]->Calculate(PowerAvailable);
j++;
}
*Forces += Thrusters[i]->GetBodyForces(); // sum body frame forces
*Moments += Thrusters[i]->GetMoments(); // sum body frame moments
Forces += Thrusters[i]->GetBodyForces(); // sum body frame forces
Moments += Thrusters[i]->GetMoments(); // sum body frame moments
Engines[i]->SetTrimMode(false);
}
return true;
@ -254,6 +254,7 @@ bool FGPropulsion::Load(FGConfigFile* AC_cfg)
}
Engines[numEngines]->SetPlacement(xLoc, yLoc, zLoc, Pitch, Yaw);
Engines[numEngines]->SetEngineNumber(numEngines);
numEngines++;
} else {
@ -406,7 +407,7 @@ string FGPropulsion::GetPropulsionValues(void)
switch(Engines[i]->GetType()) {
case FGEngine::etPiston:
PropulsionValues += (string(gcvt(((FGRocket*)Engines[i])->GetPowerAvailable(), 10, buff)));
PropulsionValues += (string(gcvt(((FGPiston*)Engines[i])->GetPowerAvailable(), 10, buff)));
break;
case FGEngine::etRocket:
PropulsionValues += (string(gcvt(((FGRocket*)Engines[i])->GetChamberPressure(), 10, buff)));

View file

@ -168,10 +168,10 @@ public:
string GetPropulsionStrings(void);
string GetPropulsionValues(void);
inline FGColumnVector3& GetForces(void) {return *Forces; }
inline double GetForces(int n) { return (*Forces)(n);}
inline FGColumnVector3& GetMoments(void) {return *Moments;}
inline double GetMoments(int n) {return (*Moments)(n);}
inline FGColumnVector3& GetForces(void) {return Forces; }
inline double GetForces(int n) { return Forces(n);}
inline FGColumnVector3& GetMoments(void) {return Moments;}
inline double GetMoments(int n) {return Moments(n);}
FGColumnVector3& GetTanksCG(void);
double GetTanksWeight(void);
@ -195,8 +195,8 @@ private:
unsigned int numTanks;
unsigned int numThrusters;
double dt;
FGColumnVector3 *Forces;
FGColumnVector3 *Moments;
FGColumnVector3 Forces;
FGColumnVector3 Moments;
FGColumnVector3 vXYZtank;
void Debug(void);
};

View file

@ -81,7 +81,8 @@ FGRotation::FGRotation(FGFDMExec* fdmex) : FGModel(fdmex),
vMoments(3),
vEuler(3),
vEulerRates(3),
vlastPQRdot(3)
vlastPQRdot(3),
vAeroPQR(3)
{
Name = "FGRotation";
cTht=cPhi=cPsi=1.0;
@ -115,6 +116,7 @@ bool FGRotation::Run(void)
vPQRdot(eR) = (N1*Ixx + L2*Ixz) / (Ixx*Izz - Ixz*Ixz);
vPQR += dt*rate*(vlastPQRdot + vPQRdot)/2.0;
vAeroPQR = vPQR + Atmosphere->GetTurbPQR();
State->IntegrateQuat(vPQR, rate);
State->CalcMatrices();

View file

@ -88,6 +88,8 @@ public:
inline FGColumnVector3& GetPQR(void) {return vPQR;}
inline double GetPQR(int axis) {return vPQR(axis);}
inline FGColumnVector3& GetAeroPQR(void) {return vAeroPQR;}
inline double GetAeroPQR(int axis) {return vAeroPQR(axis);}
inline FGColumnVector3& GetPQRdot(void) {return vPQRdot;}
inline double GetPQRdot(int idx) {return vPQRdot(idx);}
inline FGColumnVector3& GetEuler(void) {return vEuler;}
@ -111,6 +113,7 @@ public:
private:
FGColumnVector3 vPQR;
FGColumnVector3 vAeroPQR;
FGColumnVector3 vPQRdot;
FGColumnVector3 vMoments;
FGColumnVector3 vEuler;

View file

@ -76,6 +76,7 @@ CLASS IMPLEMENTATION
FGState::FGState(FGFDMExec* fdex) : mTb2l(3,3),
mTl2b(3,3),
mTs2b(3,3),
mTb2s(3,3),
vQtrn(4),
vlastQdot(4),
vQdot(4),
@ -223,12 +224,12 @@ double FGState::GetParameter(eParam val_idx) {
return Rotation->GetPQR(eP);
case FG_YAWRATE:
return Rotation->GetPQR(eR);
case FG_AEROQ:
return Rotation->GetPQR(eQ) + Atmosphere->GetTurbPQR(eQ); // add aero turbulence effects
case FG_AEROP:
return Rotation->GetPQR(eP) + Atmosphere->GetTurbPQR(eP); // add aero turbulence effects
return Rotation->GetAeroPQR(eP);
case FG_AEROQ:
return Rotation->GetAeroPQR(eQ);
case FG_AEROR:
return Rotation->GetPQR(eR) + Atmosphere->GetTurbPQR(eR); // add aero turbulence effects
return Rotation->GetAeroPQR(eR);
case FG_CL_SQRD:
if (Translation->Getqbar() > 0.00)
scratch = Aerodynamics->GetvLastFs(eLift)/(Aircraft->GetWingArea()*Translation->Getqbar());
@ -297,7 +298,7 @@ double FGState::GetParameter(eParam val_idx) {
if (ActiveEngine < 0) return FCS->GetMixturePos(0);
else return FCS->GetMixturePos(ActiveEngine);
case FG_HOVERB:
return Position->GetHOverB();
return Position->GetHOverBMAC();
case FG_PITCH_TRIM_CMD:
return FCS->GetPitchTrimCmd();
default:
@ -432,7 +433,7 @@ bool FGState::Reset(string path, string acname, string fname)
resetfile.GetNextConfigLine();
token = resetfile.GetValue();
if (token != "initialize") {
if (token != string("initialize")) {
cerr << "The reset file " << resetDef
<< " does not appear to be a reset file" << endl;
return false;
@ -440,7 +441,7 @@ bool FGState::Reset(string path, string acname, string fname)
resetfile.GetNextConfigLine();
resetfile >> token;
while (token != "/initialize" && token != "EOF") {
while (token != string("/initialize") && token != string("EOF")) {
if (token == "UBODY") resetfile >> U;
if (token == "VBODY") resetfile >> V;
if (token == "WBODY") resetfile >> W;
@ -482,7 +483,7 @@ void FGState::Initialize(double U, double V, double W,
{
double alpha, beta;
double qbar, Vt;
FGColumnVector3 vAero;
FGColumnVector3 vAeroUVW;
Position->SetLatitude(Latitude);
Position->SetLongitude(Longitude);
@ -500,14 +501,14 @@ void FGState::Initialize(double U, double V, double W,
Atmosphere->SetWindNED(wnorth, weast, wdown);
vAero = vUVW + mTl2b*Atmosphere->GetWindNED();
vAeroUVW = vUVW + mTl2b*Atmosphere->GetWindNED();
if (vAero(eW) != 0.0)
alpha = vAero(eU)*vAero(eU) > 0.0 ? atan2(vAero(eW), vAero(eU)) : 0.0;
if (vAeroUVW(eW) != 0.0)
alpha = vAeroUVW(eU)*vAeroUVW(eU) > 0.0 ? atan2(vAeroUVW(eW), vAeroUVW(eU)) : 0.0;
else
alpha = 0.0;
if (vAero(eV) != 0.0)
beta = vAero(eU)*vAero(eU)+vAero(eW)*vAero(eW) > 0.0 ? atan2(vAero(eV), (fabs(vAero(eU))/vAero(eU))*sqrt(vAero(eU)*vAero(eU) + vAero(eW)*vAero(eW))) : 0.0;
if (vAeroUVW(eV) != 0.0)
beta = vAeroUVW(eU)*vAeroUVW(eU)+vAeroUVW(eW)*vAeroUVW(eW) > 0.0 ? atan2(vAeroUVW(eV), (fabs(vAeroUVW(eU))/vAeroUVW(eU))*sqrt(vAeroUVW(eU)*vAeroUVW(eU) + vAeroUVW(eW)*vAeroUVW(eW))) : 0.0;
else
beta = 0.0;
@ -689,19 +690,46 @@ FGMatrix33& FGState::GetTs2b(void)
cb = cos(beta);
sb = sin(beta);
mTs2b(1,1) = -ca*cb;
mTs2b(1,1) = ca*cb;
mTs2b(1,2) = -ca*sb;
mTs2b(1,3) = sa;
mTs2b(2,1) = -sb;
mTs2b(1,3) = -sa;
mTs2b(2,1) = sb;
mTs2b(2,2) = cb;
mTs2b(2,3) = 0.0;
mTs2b(3,1) = -sa*cb;
mTs2b(3,1) = sa*cb;
mTs2b(3,2) = -sa*sb;
mTs2b(3,3) = -ca;
mTs2b(3,3) = ca;
return mTs2b;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGMatrix33& FGState::GetTb2s(void)
{
float alpha,beta;
float ca, cb, sa, sb;
alpha = Translation->Getalpha();
beta = Translation->Getbeta();
ca = cos(alpha);
sa = sin(alpha);
cb = cos(beta);
sb = sin(beta);
mTb2s(1,1) = ca*cb;
mTb2s(1,2) = sb;
mTb2s(1,3) = sa*cb;
mTb2s(2,1) = -ca*sb;
mTb2s(2,2) = cb;
mTb2s(2,3) = -sa*sb;
mTb2s(3,1) = -sa;
mTb2s(3,2) = 0.0;
mTb2s(3,3) = ca;
return mTb2s;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -742,7 +770,7 @@ void FGState::ReportState(void) {
Position->Gethdot()*60 );
cout << out;
snprintf(out,80, " Normal Load Factor: %4.2f g's Pitch Rate: %5.2f deg/s\n",
Aerodynamics->GetNlf(),
Aircraft->GetNlf(),
GetParameter(FG_PITCHRATE)*radtodeg );
cout << out;
snprintf(out,80, " Heading: %3.0f deg true Sideslip: %5.2f deg\n",

View file

@ -268,6 +268,11 @@ public:
@return a reference to the stability-to-body transformation matrix.
*/
FGMatrix33& GetTs2b(void);
/** Calculates and returns the body-to-stability axis transformation matrix.
@return a reference to the stability-to-body transformation matrix.
*/
FGMatrix33& GetTb2s(void);
/** Retrieves the local-to-body transformation matrix.
@return a reference to the local-to-body transformation matrix.
@ -311,6 +316,7 @@ private:
FGMatrix33 mTb2l;
FGMatrix33 mTl2b;
FGMatrix33 mTs2b;
FGMatrix33 mTb2s;
FGColumnVector4 vQtrn;
FGColumnVector4 vlastQdot;
FGColumnVector3 vUVW;

View file

@ -82,7 +82,7 @@ FGTranslation::FGTranslation(FGFDMExec* fdmex) : FGModel(fdmex),
vUVWdot(3),
vlastUVWdot(3),
mVel(3,3),
vAero(3)
vAeroUVW(3)
{
Name = "FGTranslation";
qbar = 0;
@ -122,29 +122,29 @@ bool FGTranslation::Run(void)
vUVWdot = mVel*Rotation->GetPQR() + Aircraft->GetBodyAccel();
vUVW += Tc * (vlastUVWdot + vUVWdot);
vAero = vUVW + State->GetTl2b()*Atmosphere->GetWindNED();
vAeroUVW = vUVW + State->GetTl2b()*Atmosphere->GetWindNED();
Vt = vAero.Magnitude();
Vt = vAeroUVW.Magnitude();
if ( Vt > 1) {
if (vAero(eW) != 0.0)
alpha = vAero(eU)*vAero(eU) > 0.0 ? atan2(vAero(eW), vAero(eU)) : 0.0;
if (vAero(eV) != 0.0)
beta = vAero(eU)*vAero(eU)+vAero(eW)*vAero(eW) > 0.0 ? atan2(vAero(eV),
sqrt(vAero(eU)*vAero(eU) + vAero(eW)*vAero(eW))) : 0.0;
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;
// stolen, quite shamelessly, from LaRCsim
double mUW = (vAero(eU)*vAero(eU) + vAero(eW)*vAero(eW));
double mUW = (vAeroUVW(eU)*vAeroUVW(eU) + vAeroUVW(eW)*vAeroUVW(eW));
double signU=1;
if (vAero(eU) != 0.0)
signU = vAero(eU)/fabs(vAero(eU));
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 = (vAero(eU)*vAero(eW) - vAero(eW)*vUVWdot(eU))/mUW;
bdot = (signU*mUW*vUVWdot(eV) - vAero(eV)*(vAero(eU)*vUVWdot(eU)
+ vAero(eW)*vUVWdot(eW)))/(Vt*Vt*sqrt(mUW));
adot = (vAeroUVW(eU)*vAeroUVW(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;

View file

@ -91,8 +91,8 @@ public:
inline double GetUVW (int idx) { return vUVW(idx); }
inline FGColumnVector3& GetUVWdot(void) { return vUVWdot; }
inline double GetUVWdot(int idx) { return vUVWdot(idx); }
inline FGColumnVector3& GetvAero (void) { return vAero; }
inline double GetvAero (int idx) { return vAero(idx); }
inline FGColumnVector3& GetvAeroUVW (void) { return vAeroUVW; }
inline double GetvAeroUVW (int idx) { return vAeroUVW(idx); }
inline double Getalpha(void) { return alpha; }
inline double Getbeta (void) { return beta; }
@ -121,7 +121,7 @@ private:
FGColumnVector3 vUVWdot;
FGColumnVector3 vlastUVWdot;
FGMatrix33 mVel;
FGColumnVector3 vAero;
FGColumnVector3 vAeroUVW;
double Vt, qbar, Mach;
double dt;

View file

@ -53,6 +53,7 @@ INCLUDES
#include "FGAircraft.h"
#include "FGMassBalance.h"
#include "FGAerodynamics.h"
#include "FGColumnVector3.h"
#if _MSC_VER
#pragma warning (disable : 4786 4788)
#endif
@ -70,7 +71,7 @@ FGTrim::FGTrim(FGFDMExec *FDMExec,FGInitialCondition *FGIC, TrimMode tt ) {
Tolerance=1E-3;
A_Tolerance = Tolerance / 10;
Debug=0;
Debug=0;DebugLevel=0;
fdmex=FDMExec;
fgic=FGIC;
total_its=0;
@ -79,6 +80,8 @@ FGTrim::FGTrim(FGFDMExec *FDMExec,FGInitialCondition *FGIC, TrimMode tt ) {
axis_count=0;
mode=tt;
xlo=xhi=alo=ahi;
targetNlf=1.0;
debug_axis=tAll;
switch(mode) {
case tFull:
cout << " Full Trim" << endl;
@ -102,6 +105,24 @@ FGTrim::FGTrim(FGFDMExec *FDMExec,FGInitialCondition *FGIC, TrimMode tt ) {
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tQdot,tTheta ));
//TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tPdot,tPhi ));
break;
case tPullup:
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tNlf,tAlpha ));
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tUdot,tThrottle ));
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tQdot,tPitchTrim ));
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tHmgt,tBeta ));
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tVdot,tPhi ));
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tPdot,tAileron ));
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tRdot,tRudder ));
break;
case tTurn:
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tNlf,tAlpha ));
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tUdot,tThrottle ));
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tQdot,tPitchTrim ));
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tVdot,tBeta ));
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tPdot,tAileron ));
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tRdot,tRudder ));
break;
}
//cout << "TrimAxes.size(): " << TrimAxes.size() << endl;
sub_iterations=new double[TrimAxes.size()];
@ -281,9 +302,24 @@ bool FGTrim::DoTrim(void) {
successful[current_axis]=0;
solution[current_axis]=false;
}
if(mode == tPullup ) {
cout << "Setting pitch rate and nlf... " << endl;
setupPullup();
cout << "pitch rate done ... " << endl;
TrimAxes[0]->SetStateTarget(targetNlf);
cout << "nlf done" << endl;
} else if (mode == tTurn) {
setupTurn();
TrimAxes[0]->SetStateTarget(targetNlf);
}
do {
axis_count=0;
for(current_axis=0;current_axis<TrimAxes.size();current_axis++) {
setDebug();
Nsub=0;
if(!solution[current_axis]) {
if(checkLimits()) {
@ -550,5 +586,50 @@ bool FGTrim::checkLimits(void) {
return solutionExists;
}
void FGTrim::setupPullup() {
float g,q,cgamma;
FGColumnVector3 vPQR;
g=fdmex->GetInertial()->gravity();
cgamma=cos(fgic->GetFlightPathAngleRadIC());
cout << "setPitchRateInPullup(): " << g << ", " << cgamma << ", "
<< fgic->GetVtrueFpsIC() << endl;
q=g*(targetNlf-cgamma)/fgic->GetVtrueFpsIC();
cout << targetNlf << ", " << q << endl;
vPQR.InitMatrix();
vPQR(2)=q;
cout << vPQR << endl;
fdmex->GetRotation()->SetPQR(vPQR);
cout << "setPitchRateInPullup() complete" << endl;
}
void FGTrim::setupTurn(void){
FGColumnVector3 vPQR;
float g,q,r,phi, psidot;
phi = fgic->GetRollAngleRadIC();
if( fabs(phi) > 0.01 && fabs(phi) < 1.56 ) {
targetNlf = 1 / cos(phi);
g = fdmex->GetInertial()->gravity();
psidot = g*tan(phi) / fgic->GetVtrueFpsIC();
q = psidot*sin(phi);
r = psidot*cos(phi);
vPQR(1)=0;vPQR(2)=q;vPQR(3)=r;
fdmex->GetRotation()->SetPQR(vPQR);
cout << targetNlf << ", " << vPQR*57.29577 << endl;
}
}
void FGTrim::setDebug(void) {
if(debug_axis == tAll ||
TrimAxes[current_axis]->GetStateType() == debug_axis ) {
Debug=DebugLevel;
return;
} else {
Debug=0;
return;
}
}
//YOU WERE WARNED, BUT YOU DID IT ANYWAY.

View file

@ -70,7 +70,9 @@ DEFINITIONS
#define ID_TRIM "$Id$"
typedef enum { tLongitudinal, tFull, tGround, tCustom, tNone } TrimMode;
typedef enum { tLongitudinal, tFull, tGround, tPullup,
tCustom, tNone, tTurn
} TrimMode;
#ifdef _MSC_VER
#define snprintf _snprintf
@ -148,7 +150,7 @@ private:
int current_axis;
int N, Nsub;
TrimMode mode;
int Debug;
int DebugLevel, Debug;
double Tolerance, A_Tolerance;
double wdot,udot,qdot;
double dth;
@ -164,6 +166,8 @@ private:
int axis_count;
int solutionDomain;
double xlo,xhi,alo,ahi;
double targetNlf;
int debug_axis;
FGFDMExec* fdmex;
FGInitialCondition* fgic;
@ -180,6 +184,11 @@ private:
bool findInterval(void);
bool checkLimits(void);
void setupPullup(void);
void setupTurn(void);
void setDebug(void);
public:
/** Initializes the trimming class
@ -270,10 +279,21 @@ public:
A_Tolerance = tt / 10;
}
//Debug level 1 shows results of each top-level iteration
//Debug level 2 shows level 1 & results of each per-axis iteration
inline void SetDebug(int level) { Debug = level; }
inline void ClearDebug(void) { Debug = 0; }
/**
Debug level 1 shows results of each top-level iteration
Debug level 2 shows level 1 & results of each per-axis iteration
*/
inline void SetDebug(int level) { DebugLevel = level; }
inline void ClearDebug(void) { DebugLevel = 0; }
/**
Output debug data for one of the axes
The State enum is defined in FGTrimAxis.h
*/
inline void DebugState(State state) { debug_axis=state; }
inline void SetTargetNlf(float nlf) { targetNlf=nlf; }
inline double GetTargetNlf(void) { return targetNlf; }
};

View file

@ -62,7 +62,8 @@ FGTrimAxis::FGTrimAxis(FGFDMExec* fdex, FGInitialCondition* ic, State st,
state_convert=1.0;
control_convert=1.0;
state_value=0;
switch(state) {
state_target=0;
switch(state) {
case tUdot: tolerance = DEFAULT_TOLERANCE; break;
case tVdot: tolerance = DEFAULT_TOLERANCE; break;
case tWdot: tolerance = DEFAULT_TOLERANCE; break;
@ -70,6 +71,7 @@ FGTrimAxis::FGTrimAxis(FGFDMExec* fdex, FGInitialCondition* ic, State st,
case tPdot: tolerance = DEFAULT_TOLERANCE / 10; break;
case tRdot: tolerance = DEFAULT_TOLERANCE / 10; break;
case tHmgt: tolerance = 0.01; break;
case tNlf: state_target=1.0; tolerance = 1E-5; break;
}
solver_eps=tolerance;
@ -151,13 +153,14 @@ FGTrimAxis::~FGTrimAxis()
void FGTrimAxis::getState(void) {
switch(state) {
case tUdot: state_value=fdmex->GetAircraft()->GetBodyAccel()(1); break;
case tVdot: state_value=fdmex->GetAircraft()->GetBodyAccel()(2); break;
case tWdot: state_value=fdmex->GetAircraft()->GetBodyAccel()(3); break;
case tQdot: state_value=fdmex->GetRotation()->GetPQRdot(2);break;
case tPdot: state_value=fdmex->GetRotation()->GetPQRdot(1); break;
case tRdot: state_value=fdmex->GetRotation()->GetPQRdot(3); break;
case tHmgt: state_value=computeHmgt(); break;
case tUdot: state_value=fdmex->GetTranslation()->GetUVWdot()(1)-state_target; break;
case tVdot: state_value=fdmex->GetTranslation()->GetUVWdot()(2)-state_target; break;
case tWdot: state_value=fdmex->GetTranslation()->GetUVWdot()(3)-state_target; break;
case tQdot: state_value=fdmex->GetRotation()->GetPQRdot(2)-state_target;break;
case tPdot: state_value=fdmex->GetRotation()->GetPQRdot(1)-state_target; break;
case tRdot: state_value=fdmex->GetRotation()->GetPQRdot(3)-state_target; break;
case tHmgt: state_value=computeHmgt()-state_target; break;
case tNlf: state_value=fdmex->GetAircraft()->GetNlf()-state_target; break;
}
}
@ -412,7 +415,7 @@ void FGTrimAxis::AxisReport(void) {
char out[80];
sprintf(out," %20s: %6.2f %5s: %9.2e Tolerance: %3.0e\n",
GetControlName().c_str(), GetControl()*control_convert,
GetStateName().c_str(), GetState(), GetTolerance());
GetStateName().c_str(), GetState()+state_target, GetTolerance());
cout << out;
}

View file

@ -56,7 +56,9 @@ INCLUDES
#define DEFAULT_TOLERANCE 0.001
const string StateNames[7]= { "udot","vdot","wdot","qdot","pdot","rdot","hmgt" };
const string StateNames[10]= { "all","udot","vdot","wdot","qdot","pdot","rdot",
"hmgt","nlf"
};
const string ControlNames[14]= { "Throttle","Sideslip","Angle of Attack",
"Elevator","Ailerons","Rudder",
"Altitude AGL", "Pitch Angle",
@ -69,7 +71,7 @@ const string ControlNames[14]= { "Throttle","Sideslip","Angle of Attack",
CLASS DECLARATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
enum State { tUdot,tVdot,tWdot,tQdot,tPdot,tRdot,tHmgt };
enum State { tAll,tUdot,tVdot,tWdot,tQdot,tPdot,tRdot,tHmgt,tNlf };
enum Control { tThrottle, tBeta, tAlpha, tElevator, tAileron, tRudder, tAltAGL,
tTheta, tPhi, tGamma, tPitchTrim, tRollTrim, tYawTrim, tHeading };
@ -120,6 +122,9 @@ public:
void SetThetaOnGround(double ff);
void SetPhiOnGround(double ff);
inline void SetStateTarget(float target) { state_target=target; }
inline float GetStateTarget(void) { return state_target; }
bool initTheta(void);
void AxisReport(void);
@ -132,9 +137,11 @@ private:
State state;
Control control;
double state_value;
double control_value;
float state_target;
float state_value;
float control_value;
double control_min;
double control_max;

View file

@ -152,7 +152,7 @@ int main(int argc, char** argv)
}
}
struct FGJSBBase::Message* msg;
FGJSBBase::Message* msg;
while (FDMExec->Run()) {
while (FDMExec->ReadMessage()) {
msg = FDMExec->ProcessMessage();

76
src/FDM/JSBSim/README Normal file
View file

@ -0,0 +1,76 @@
Contents
--------
1) Introduction
2) Building with autoconf/automake
3) Contact
1) Introduction
---------------
JSBSim is a multi-platform, general purpose object-oriented Flight
Dynamics Model (FDM) written in C++. Jon Berndt and Tony Peden began
about mid-1998 writing JSBSim. As of this writing it is the default
FDM for FlightGear. JSBSim can also be run in a standalone batch mode
for testing and study. More information on JSBSim can be found at the
JSBSim home page here:
http://jsbsim.sourceforge.net
The standalone version of JSBSim can be easily built from the command
line of a unix or unix-like (CygWin/Linux/Unix/IRIX, etc.) system like
this:
make -fMakefile.solo
If you are on an IRIX machine you can use the Makefile.irix makefile.
Directions are also provided below for using traditional auto* utilities
also provided with JSBSim.
2) Building with autoconf/automake
----------------------------------
Unpack the distribution tarball (if needed - CVS users will have
downloaded the code directly) using your preferred method, and change
to the working directory. For example :
$ tar xvfz JSBSim-0.1.2.tar.gz
$ cd JSBSim-0.1.2
NOTE for CVS users: If you are using JSBSim from a CVS checkout, or
snapshot, you will need to create the initial configure script. The
commands to do this have been included in the 'autogen.sh' script, so
just :
$ ./autogen.sh
If you wish to customise your version of JSBSim, use the following to
determine any build-time options you may be interested in.
$ ./configure --help
Then :
$ ./configure
This will check your system platform, compiler and other local
configuration variables needed to build JSBSim, and generates the
necessary Makefiles. Next :
$ make
Will compile the various classes, and link the library. Finally :
$ make install
Unless specified otherwise (with --prefix configure option), this will
install 'JSBSim.a' into '/usr/local/lib'.
3) Contact
----------
For more information on JSBSim contact Jon Berndt at jsbsim@hal-pc.org.