break;
}
- stall_warning->setBoolValue(false);
+ stall_warning->setDoubleValue(0);
SG_LOG( SG_FLIGHT, SG_INFO, " Bank Angle: "
<< Rotation->Getphi()*RADTODEG << " deg" );
// Auxiliary->GetNpilot(2)/32.1739,
// Auxiliary->GetNpilot(3)/32.1739 );
- _set_Nlf( Aerodynamics->GetNlf() );
+ _set_Nlf( Aircraft->GetNlf() );
// Velocities
--- /dev/null
+AUTHORS\r
+-------\r
+\r
+Jon S. Berndt\r
+primary architect and coordinator\r
+jsb@hal-pc.org\r
+CVS access as developer (r/w)\r
+\r
+\r
+Tony Peden\r
+additional architecture support\r
+trimming and aerodynamics\r
+interface with flightgear\r
+apeden@earthlink.net\r
+CVS access as developer (r/w)\r
+\r
+\r
+Additional support (programming, bug fixes, aircraft models)\r
+by the FlightGear team and others as listed:\r
+\r
+Curt Olson\r
+wrote initial interface with flightgear\r
+works flightgear/jsbsim issues\r
+curt@flightgear.org\r
+\r
+Norman Vine\r
+matrix math class optimization support\r
+general C++ suggestions, debugging, and support\r
+nhv@cape.com\r
+\r
+Christian Mayer\r
+JSBSim compatibility with MSVC\r
+mail@ChristianMayer.de\r
+\r
+Erik Hofman\r
+JSBSim compatibility with IRIX\r
+erik@ehofman.com\r
+\r
+David Megginson\r
+ported Dave Luff's piston engine model initially to JSBSim\r
+creation of multi-engine C-310 model and testing/debugging\r
+general C++ suggestions, debugging, and support\r
+david@megginson.com\r
+\r
+Ross Golder\r
+improvements to the build process and auto* files\r
+ross@golder.org\r
+\r
+Dave Luff\r
+wrote the piston engine model used by LaRCSim and is ported to JSBSim\r
+eazdluf@nottingham.ac.uk\r
+\r
+Norman Princen\r
+provided an improved gear model\r
+nprincen@hotmail.com\r
+\r
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)
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-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;
coefficients */
string GetCoefficientValues(void);
- /// Gets the Normal Load Factor
- double GetNlf(void);
private:
typedef map<string,int> AxisIndex;
vXYZep(3),
vDXYZcg(3),
vBodyAccel(3),
- vNcg(3)
+ vNcg(3),
+ vNwcg(3)
{
Name = "FGAircraft";
alphaclmin = alphaclmax = 0;
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) {
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+float FGAircraft::GetNlf(void)
+{
+ return vNwcg(3);
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
void FGAircraft::ReadPrologue(FGConfigFile* AC_cfg)
{
string token = AC_cfg->GetValue();
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;
FGColumnVector3 vDXYZcg;
FGColumnVector3 vBodyAccel;
FGColumnVector3 vNcg;
+ FGColumnVector3 vNwcg;
double WingArea, WingSpan, cbar, WingIncidence;
double HTailArea, VTailArea, HTailArm, VTailArm;
inline void SetTurbGain(double tt) {TurbGain = tt;}
inline double GetTurbPQR(int idx) {return vTurbPQR(idx);}
+ inline FGColumnVector3& GetTurbPQR(void) {return vTurbPQR;}
private:
double rho;
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-\r
- Header: FGConfigFile.h\r
- Author: Jon Berndt\r
- Date started: 03/29/00\r
- Purpose: Config file read-in class\r
- Called by: FGAircraft\r
-\r
-FUNCTIONAL DESCRIPTION\r
---------------------------------------------------------------------------------\r
-\r
-HISTORY\r
---------------------------------------------------------------------------------\r
-03/16/2000 JSB Created\r
-\r
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-INCLUDES\r
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
-\r
-#include "FGConfigFile.h"\r
-#include <stdlib.h>\r
-#include <math.h>\r
-\r
-static const char *IdSrc = "$Id$";\r
-static const char *IdHdr = ID_CONFIGFILE;\r
-\r
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-CLASS IMPLEMENTATION\r
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
-\r
-FGConfigFile::FGConfigFile(string cfgFileName)\r
-{\r
-#if defined ( sgi ) && !defined( __GNUC__ )\r
- cfgfile.open(cfgFileName.c_str(), ios::in );\r
-#else\r
- cfgfile.open(cfgFileName.c_str(), ios::in | ios::binary );\r
-#endif\r
- CommentsOn = false;\r
- CurrentIndex = 0;\r
- Opened = true;\r
-#if defined ( sgi ) && !defined( __GNUC__ )\r
- if (!cfgfile.fail() && !cfgfile.eof()) GetNextConfigLine();\r
-#else\r
- if (cfgfile.is_open()) GetNextConfigLine();\r
-#endif\r
- else Opened = false;\r
-\r
- if (debug_lvl & 2) cout << "Instantiated: FGConfigFile" << endl;\r
-}\r
-\r
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-\r
-FGConfigFile::~FGConfigFile()\r
-{\r
- cfgfile.close();\r
- if (debug_lvl & 2) cout << "Destroyed: FGConfigFile" << endl;\r
-}\r
-\r
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-\r
-string FGConfigFile::GetNextConfigLine(void)\r
-{\r
- int deblank, not_found = string::npos;\r
- int comment_starts_at;\r
- int comment_ends_at;\r
- int comment_length;\r
- int line_length;\r
- bool start_comment, end_comment;\r
- string CommentStringTemp;\r
-\r
- do {\r
- CurrentLine = GetLine();\r
- line_length = CurrentLine.length();\r
- comment_starts_at = CurrentLine.find("<!--");\r
- \r
- if (comment_starts_at >= 0) start_comment = true;\r
- else start_comment = false;\r
- \r
- comment_ends_at = CurrentLine.find("-->");\r
- \r
- if (comment_ends_at >= 0) end_comment = true;\r
- else end_comment = false;\r
-\r
- if (!start_comment && !end_comment) { // command comment\r
- if (CommentsOn) CommentStringTemp = CurrentLine;\r
- CommentString += CommentStringTemp + "\r\n";\r
- } else if (start_comment && comment_ends_at > comment_starts_at) { // <!-- ... -->\r
- CommentsOn = false;\r
- comment_length = comment_ends_at + 2 - comment_starts_at + 1;\r
- LineComment = CurrentLine.substr(comment_starts_at+4, comment_length-4-3);\r
- CurrentLine.erase(comment_starts_at, comment_length);\r
- } else if ( start_comment && !end_comment) { // <!-- ...\r
- CommentsOn = true;\r
- comment_length = line_length - comment_starts_at;\r
- CommentStringTemp = CurrentLine.substr(comment_starts_at+4, comment_length-4);\r
- CommentString = CommentStringTemp + "\r\n";\r
- CurrentLine.erase(comment_starts_at, comment_length);\r
- } else if (!start_comment && end_comment) { // ... -->\r
- CommentsOn = false;\r
- comment_length = comment_ends_at + 2 + 1;\r
- CommentStringTemp = CurrentLine.substr(0, comment_length-4);\r
- CommentString += CommentStringTemp + "\r\n";\r
- CurrentLine.erase(0, comment_length);\r
- } else if (start_comment && comment_ends_at < comment_starts_at) { // --> command <!--\r
- cerr << "Old comment ends and new one starts - bad JSBSim config file form." << endl;\r
- CommentsOn = false;\r
- comment_length = comment_ends_at + 2 + 1;\r
- CommentStringTemp = CurrentLine.substr(0, comment_length-4);\r
- CommentString += CommentStringTemp + "\r\n";\r
- CurrentLine.erase(0, comment_length);\r
- }\r
- \r
- } while (CommentsOn);\r
-\r
- if (CurrentLine.length() == 0) GetNextConfigLine();\r
- CurrentIndex = 0;\r
- return CurrentLine;\r
-}\r
-\r
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-\r
-string FGConfigFile::GetValue(string val)\r
-{\r
- unsigned int pos, p1, p2, ptest;\r
-\r
- if (val == "") { // this call is to return the tag value\r
- pos = CurrentLine.find("<");\r
- if (pos != CurrentLine.npos) { // beginning brace found "<"\r
- p1 = CurrentLine.find_first_not_of(" ",pos+1);\r
- if (p1 != CurrentLine.npos) { // found first character of tag\r
- p2 = CurrentLine.find_first_of(" >",p1+1);\r
- if (p2 == CurrentLine.npos) p2 = p1+1;\r
- return CurrentLine.substr(p1,p2-p1);\r
- }\r
- } else { // beginning brace "<" not found; this is a regular data line\r
- pos = CurrentLine.find_first_not_of(" ");\r
- if (pos != CurrentLine.npos) { // first character in line found\r
- p2 = CurrentLine.find_first_of(" ",pos+1);\r
- if (p2 != CurrentLine.npos) {\r
- return CurrentLine.substr(pos,p2-pos);\r
- } else {\r
- return CurrentLine.substr(pos,CurrentLine.length()-pos);\r
- }\r
- }\r
- }\r
- } else { // return a value for a specific tag\r
- pos = CurrentLine.find(val);\r
- if (pos != CurrentLine.npos) {\r
- pos = CurrentLine.find("=",pos);\r
- if (pos != CurrentLine.npos) {\r
- ptest = CurrentLine.find_first_not_of(" ",pos+1);\r
- if (ptest != CurrentLine.npos) {\r
- p1 = ptest + 1;\r
- if (CurrentLine[ptest] == '"') { // quoted\r
- p2 = CurrentLine.find_first_of("\"",p1);\r
- } else { // not quoted\r
- p2 = CurrentLine.find_first_of(" ",p1);\r
- }\r
- if (p2 != CurrentLine.npos) {\r
- return CurrentLine.substr(p1,p2-p1);\r
- }\r
- }\r
- } else { // "=" not found\r
- pos = CurrentLine.find(val);\r
- pos = CurrentLine.find_first_of(" ",pos+1);\r
- ptest = CurrentLine.find_first_not_of(" ",pos+1);\r
- if (ptest != CurrentLine.npos) {\r
- if (CurrentLine[ptest] == '"') { // quoted\r
- p1 = ptest + 1;\r
- p2 = CurrentLine.find_first_of("\"",p1);\r
- } else { // not quoted\r
- p1 = ptest;\r
- p2 = CurrentLine.find_first_of(" ",p1);\r
- }\r
- if (p2 != CurrentLine.npos) {\r
- return CurrentLine.substr(p1,p2-p1);\r
- } else {\r
- p2 = CurrentLine.length();\r
- return CurrentLine.substr(p1,p2-p1);\r
- }\r
- }\r
- }\r
- }\r
- }\r
-\r
- return string("");\r
-}\r
-\r
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-\r
-string FGConfigFile::GetValue(void)\r
-{\r
- return GetValue("");\r
-}\r
-\r
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-\r
-string FGConfigFile::GetLine(void)\r
-{\r
- string scratch = "";\r
- int test;\r
-\r
- while ((test = cfgfile.get()) != EOF) {\r
- if (test >= 0x20 || test == 0x09) {\r
- if (test == 0x09) {\r
- scratch += (char)0x20;\r
- } else {\r
- scratch += (char)test;\r
- }\r
- } else {\r
- if ((test = cfgfile.get()) != EOF) { // get *next* character\r
-#if defined ( sgi ) && !defined( __GNUC__ )\r
- if (test >= 0x20 || test == 0x09) cfgfile.putback(test);\r
-#else\r
- if (test >= 0x20 || test == 0x09) cfgfile.unget();\r
-#endif\r
- break;\r
- }\r
- }\r
- }\r
- if (cfgfile.eof()) return string("EOF");\r
- return scratch;\r
-}\r
-\r
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-/*\r
-FGConfigFile& FGConfigFile::operator>>(double& val)\r
-{\r
- unsigned int pos, end;\r
-\r
- pos = CurrentLine.find_first_not_of(", ",CurrentIndex);\r
- if (pos == CurrentLine.npos) pos = CurrentLine.length();\r
- end = CurrentLine.find_first_of(", ",pos+1);\r
- if (end == CurrentLine.npos) end = CurrentLine.length();\r
- string str = CurrentLine.substr(pos, end - pos);\r
- val = strtod(str.c_str(),NULL);\r
- CurrentIndex = end+1;\r
- if (CurrentIndex >= CurrentLine.length()) GetNextConfigLine();\r
- return *this;\r
-}\r
-*/\r
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-\r
-FGConfigFile& FGConfigFile::operator>>(double& val)\r
-{\r
- unsigned int pos, end;\r
-\r
- pos = CurrentLine.find_first_not_of(", ",CurrentIndex);\r
- if (pos == CurrentLine.npos) pos = CurrentLine.length();\r
- end = CurrentLine.find_first_of(", ",pos+1);\r
- if (end == CurrentLine.npos) end = CurrentLine.length();\r
- string str = CurrentLine.substr(pos, end - pos);\r
- val = strtod(str.c_str(),NULL);\r
- CurrentIndex = end+1;\r
- if (CurrentIndex >= CurrentLine.length()) GetNextConfigLine();\r
- return *this;\r
-}\r
-\r
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-\r
-FGConfigFile& FGConfigFile::operator>>(int& val)\r
-{\r
- unsigned int pos, end;\r
-\r
- pos = CurrentLine.find_first_not_of(", ",CurrentIndex);\r
- if (pos == CurrentLine.npos) pos = CurrentLine.length();\r
- end = CurrentLine.find_first_of(", ",pos+1);\r
- if (end == CurrentLine.npos) end = CurrentLine.length();\r
- string str = CurrentLine.substr(pos, end - pos);\r
- val = atoi(str.c_str());\r
- CurrentIndex = end+1;\r
- if (CurrentIndex >= CurrentLine.length()) GetNextConfigLine();\r
- return *this;\r
-}\r
-\r
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-\r
-FGConfigFile& FGConfigFile::operator>>(eParam& val)\r
-{\r
- unsigned int pos, end;\r
-\r
- pos = CurrentLine.find_first_not_of(", ",CurrentIndex);\r
- if (pos == CurrentLine.npos) pos = CurrentLine.length();\r
- end = CurrentLine.find_first_of(", ",pos+1);\r
- if (end == CurrentLine.npos) end = CurrentLine.length();\r
- string str = CurrentLine.substr(pos, end - pos);\r
- val = (eParam)atoi(str.c_str());\r
- CurrentIndex = end+1;\r
- if (CurrentIndex >= CurrentLine.length()) GetNextConfigLine();\r
- return *this;\r
-}\r
-\r
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-\r
-FGConfigFile& FGConfigFile::operator>>(string& str)\r
-{\r
- unsigned int pos, end;\r
-\r
- pos = CurrentLine.find_first_not_of(", ",CurrentIndex);\r
- if (pos == CurrentLine.npos) pos = CurrentLine.length();\r
- end = CurrentLine.find_first_of(", ",pos+1);\r
- if (end == CurrentLine.npos) end = CurrentLine.length();\r
- str = CurrentLine.substr(pos, end - pos);\r
- CurrentIndex = end+1;\r
- if (CurrentIndex >= CurrentLine.length()) GetNextConfigLine();\r
- return *this;\r
-}\r
-\r
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-\r
-void FGConfigFile::ResetLineIndexToZero(void)\r
-{\r
- CurrentIndex = 0;\r
-}\r
-\r
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-\r
-void FGConfigFile::Debug(void)\r
-{\r
- //TODO: Add your source code here\r
-}\r
-\r
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ 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
+}
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-FGEngine::FGEngine(FGFDMExec* exec) {
+FGEngine::FGEngine(FGFDMExec* exec)
+{
FDMExec = exec;
State = FDMExec->GetState();
Atmosphere = FDMExec->GetAtmosphere();
// 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;
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;
/// 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;}
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;
}
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;
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-struct FGJSBBase::Message* FGJSBBase::PutMessage(struct Message* msg)
+FGJSBBase::Message* FGJSBBase::PutMessage(Message* msg)
{
Messages.push(msg);
return 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";
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-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";
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-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";
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-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";
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-struct FGJSBBase::Message* FGJSBBase::ReadMessage(void)
+FGJSBBase::Message* FGJSBBase::ReadMessage(void)
{
if (!Messages.empty()) return Messages.front();
else return NULL;
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-struct FGJSBBase::Message* FGJSBBase::ProcessMessage(void)
+FGJSBBase::Message* FGJSBBase::ProcessMessage(void)
{
if (!Messages.empty())
localMsg = *(Messages.front());
virtual ~FGJSBBase() {};
/// JSBSim Message structure
- struct Message {
+ typedef struct Msg {
unsigned int fdmId;
unsigned int messageId;
string text;
bool bVal;
int iVal;
double dVal;
- };
+ } Message;
///@name JSBSim Enums.
//@{
/** 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) {};
}
if (SubSystems & ssAerosurfaces) {
outstream << ", ";
- outstream << "Throttle, ";
- outstream << "Mixture, ";
outstream << "Aileron Cmd, ";
outstream << "Elevator Cmd, ";
outstream << "Rudder Cmd, ";
}
if (SubSystems & ssAerosurfaces) {
outstream << ", ";
- outstream << FCS->GetThrottlePos(0) << ", ";
- outstream << FCS->GetMixturePos(0) << ", ";
outstream << FCS->GetDaCmd() << ", ";
outstream << FCS->GetDeCmd() << ", ";
outstream << FCS->GetDrCmd() << ", ";
outstream << Translation->Getqbar() << ", ";
outstream << Translation->GetVt() << ", ";
outstream << Translation->GetUVW() << ", ";
- outstream << Translation->GetvAero() << ", ";
+ outstream << Translation->GetvAeroUVW() << ", ";
outstream << Position->GetVel();
}
if (SubSystems & ssForces) {
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());
bool FGPosition::Run(void) {
double cosLat;
double hdot_Vt;
+ FGColumnVector3 vMac;
if (!FGModel::Run()) {
GetState();
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;
h = tt;
Radius = h + SeaLevelRadius;
DistanceAGL = Radius - RunwayRadius; // Geocentric
- hoverb = DistanceAGL/b;
+ hoverbcg = DistanceAGL/b;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DistanceAGL=tt;
Radius = RunwayRadius + DistanceAGL;
h = Radius - SeaLevelRadius;
- hoverb = DistanceAGL/b;
+ hoverbcg = DistanceAGL/b;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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; }
double SeaLevelRadius;
double gamma;
double Vt, Vground;
- double hoverb,b;
+ double hoverbcg,hoverbmac,b;
double psigt;
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();
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;
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
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-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;
}
{
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;
}
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 {
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-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++) {
}
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);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-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);
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;
}
Engines[numEngines]->SetPlacement(xLoc, yLoc, zLoc, Pitch, Yaw);
+ Engines[numEngines]->SetEngineNumber(numEngines);
numEngines++;
} else {
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)));
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);
unsigned int numTanks;
unsigned int numThrusters;
double dt;
- FGColumnVector3 *Forces;
- FGColumnVector3 *Moments;
+ FGColumnVector3 Forces;
+ FGColumnVector3 Moments;
FGColumnVector3 vXYZtank;
void Debug(void);
};
vMoments(3),
vEuler(3),
vEulerRates(3),
- vlastPQRdot(3)
+ vlastPQRdot(3),
+ vAeroPQR(3)
{
Name = "FGRotation";
cTht=cPhi=cPsi=1.0;
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();
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;}
private:
FGColumnVector3 vPQR;
+ FGColumnVector3 vAeroPQR;
FGColumnVector3 vPQRdot;
FGColumnVector3 vMoments;
FGColumnVector3 vEuler;
FGState::FGState(FGFDMExec* fdex) : mTb2l(3,3),
mTl2b(3,3),
mTs2b(3,3),
+ mTb2s(3,3),
vQtrn(4),
vlastQdot(4),
vQdot(4),
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());
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:
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;
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;
{
double alpha, beta;
double qbar, Vt;
- FGColumnVector3 vAero;
+ FGColumnVector3 vAeroUVW;
Position->SetLatitude(Latitude);
Position->SetLongitude(Longitude);
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;
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;
+}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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",
@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.
FGMatrix33 mTb2l;
FGMatrix33 mTl2b;
FGMatrix33 mTs2b;
+ FGMatrix33 mTb2s;
FGColumnVector4 vQtrn;
FGColumnVector4 vlastQdot;
FGColumnVector3 vUVW;
vUVWdot(3),
vlastUVWdot(3),
mVel(3,3),
- vAero(3)
+ vAeroUVW(3)
{
Name = "FGTranslation";
qbar = 0;
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;
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; }
FGColumnVector3 vUVWdot;
FGColumnVector3 vlastUVWdot;
FGMatrix33 mVel;
- FGColumnVector3 vAero;
+ FGColumnVector3 vAeroUVW;
double Vt, qbar, Mach;
double dt;
#include "FGAircraft.h"
#include "FGMassBalance.h"
#include "FGAerodynamics.h"
+#include "FGColumnVector3.h"
#if _MSC_VER
#pragma warning (disable : 4786 4788)
#endif
Tolerance=1E-3;
A_Tolerance = Tolerance / 10;
- Debug=0;
+ Debug=0;DebugLevel=0;
fdmex=FDMExec;
fgic=FGIC;
total_its=0;
axis_count=0;
mode=tt;
xlo=xhi=alo=ahi;
+ targetNlf=1.0;
+ debug_axis=tAll;
switch(mode) {
case tFull:
cout << " Full Trim" << endl;
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()];
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()) {
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.
#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
int current_axis;
int N, Nsub;
TrimMode mode;
- int Debug;
+ int DebugLevel, Debug;
double Tolerance, A_Tolerance;
double wdot,udot,qdot;
double dth;
int axis_count;
int solutionDomain;
double xlo,xhi,alo,ahi;
+ double targetNlf;
+ int debug_axis;
FGFDMExec* fdmex;
FGInitialCondition* fgic;
bool findInterval(void);
bool checkLimits(void);
+
+ void setupPullup(void);
+ void setupTurn(void);
+
+ void setDebug(void);
public:
/** Initializes the trimming class
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; }
};
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;
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;
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;
}
}
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;
}
#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",
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 };
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);
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;
}
}
- struct FGJSBBase::Message* msg;
+ FGJSBBase::Message* msg;\r
while (FDMExec->Run()) {
while (FDMExec->ReadMessage()) {
msg = FDMExec->ProcessMessage();
--- /dev/null
+Contents\r
+--------\r
+\r
+1) Introduction\r
+2) Building with autoconf/automake\r
+3) Contact\r
+\r
+\r
+1) Introduction\r
+---------------\r
+\r
+JSBSim is a multi-platform, general purpose object-oriented Flight\r
+Dynamics Model (FDM) written in C++. Jon Berndt and Tony Peden began\r
+about mid-1998 writing JSBSim. As of this writing it is the default\r
+FDM for FlightGear. JSBSim can also be run in a standalone batch mode\r
+for testing and study. More information on JSBSim can be found at the\r
+JSBSim home page here:\r
+\r
+http://jsbsim.sourceforge.net\r
+\r
+The standalone version of JSBSim can be easily built from the command\r
+line of a unix or unix-like (CygWin/Linux/Unix/IRIX, etc.) system like\r
+this:\r
+\r
+make -fMakefile.solo\r
+\r
+If you are on an IRIX machine you can use the Makefile.irix makefile.\r
+Directions are also provided below for using traditional auto* utilities\r
+also provided with JSBSim.\r
+\r
+\r
+2) Building with autoconf/automake\r
+----------------------------------\r
+\r
+Unpack the distribution tarball (if needed - CVS users will have\r
+downloaded the code directly) using your preferred method, and change\r
+to the working directory. For example :\r
+\r
+$ tar xvfz JSBSim-0.1.2.tar.gz\r
+$ cd JSBSim-0.1.2\r
+\r
+NOTE for CVS users: If you are using JSBSim from a CVS checkout, or\r
+snapshot, you will need to create the initial configure script. The\r
+commands to do this have been included in the 'autogen.sh' script, so\r
+just :\r
+\r
+$ ./autogen.sh\r
+\r
+If you wish to customise your version of JSBSim, use the following to\r
+determine any build-time options you may be interested in.\r
+\r
+$ ./configure --help\r
+\r
+Then :\r
+\r
+$ ./configure\r
+\r
+This will check your system platform, compiler and other local\r
+configuration variables needed to build JSBSim, and generates the\r
+necessary Makefiles. Next :\r
+\r
+$ make\r
+\r
+Will compile the various classes, and link the library. Finally :\r
+\r
+$ make install\r
+\r
+Unless specified otherwise (with --prefix configure option), this will\r
+install 'JSBSim.a' into '/usr/local/lib'.\r
+\r
+\r
+3) Contact\r
+----------\r
+\r
+For more information on JSBSim contact Jon Berndt at jsbsim@hal-pc.org.\r
+\r