1
0
Fork 0

Add the latest version of JSBSim including support for a Visual Reference Point

This commit is contained in:
ehofman 2004-02-14 10:19:56 +00:00
parent 1bc3c5eca0
commit c92cb650eb
21 changed files with 238 additions and 89 deletions

View file

@ -157,12 +157,7 @@ bool FGAerodynamics::Run(void)
vForces = State->GetTs2b()*vFs;
vDXYZcg(eX) = -(Aircraft->GetXYZrp(eX)
- MassBalance->GetXYZcg(eX))*inchtoft;
vDXYZcg(eY) = (Aircraft->GetXYZrp(eY)
- MassBalance->GetXYZcg(eY))*inchtoft;
vDXYZcg(eZ) = -(Aircraft->GetXYZrp(eZ)
- MassBalance->GetXYZcg(eZ))*inchtoft;
vDXYZcg = MassBalance->StructuralToBody(Aircraft->GetXYZrp());
vMoments = vDXYZcg*vForces; // M = r X F

View file

@ -103,7 +103,7 @@ bool FGAuxiliary::Run()
tatc=RankineToCelsius(tat);
if (mach < 1) { //calculate total pressure assuming isentropic flow
pt=p*pow((1 + 0.2*machU*machU),3.5);
pt = p*pow((1 + 0.2*machU*machU),3.5);
} else {
// shock in front of pitot tube, we'll assume its normal and use
// the Rayleigh Pitot Tube Formula, i.e. the ratio of total
@ -170,8 +170,7 @@ bool FGAuxiliary::Run()
+ Propulsion->GetForces()
+ GroundReactions->GetForces();
vPilotAccel /= MassBalance->GetMass();
vToEyePt = Aircraft->GetXYZep() - MassBalance->GetXYZcg();
vToEyePt *= inchtoft;
vToEyePt = MassBalance->StructuralToBody(Aircraft->GetXYZep());
vPilotAccel += Rotation->GetPQRdot() * vToEyePt;
vPilotAccel += Rotation->GetPQR() * (Rotation->GetPQR() * vToEyePt);
} else {
@ -180,7 +179,6 @@ bool FGAuxiliary::Run()
vPilotAccelN = vPilotAccel/Inertial->gravity();
earthPosAngle += State->Getdt()*Inertial->omega();
return false;
} else {

View file

@ -111,7 +111,6 @@ FGFCS::~FGFCS()
PropAdvanceCmd.clear();
PropAdvance.clear();
unsigned int i;
for (i=0;i<APComponents.size();i++) delete APComponents[i];

View file

@ -83,9 +83,7 @@ FGColumnVector3& FGForce::GetBodyForces(void)
// needs to be done like this to convert from structural to body coords.
// CG and RP values are in inches
vDXYZ(eX) = -(vActingXYZn(eX) - fdmex->GetMassBalance()->GetXYZcg(eX))*inchtoft;
vDXYZ(eY) = (vActingXYZn(eY) - fdmex->GetMassBalance()->GetXYZcg(eY))*inchtoft;
vDXYZ(eZ) = -(vActingXYZn(eZ) - fdmex->GetMassBalance()->GetXYZcg(eZ))*inchtoft;
vDXYZ = fdmex->GetMassBalance()->StructuralToBody(vActingXYZn);
vM = vMn + vDXYZ*vFb;

View file

@ -66,9 +66,9 @@ const double FGJSBBase::fpstokts = 0.592484;
const double FGJSBBase::ktstofps = 1.68781;
const double FGJSBBase::inchtoft = 0.08333333;
const double FGJSBBase::in3tom3 = 1.638706E-5;
const double FGJSBBase::Reng = 1716.0;
double FGJSBBase::Reng = 1716.0;
const double FGJSBBase::SHRatio = 1.40;
const string FGJSBBase::needed_cfg_version = "1.60";
const string FGJSBBase::needed_cfg_version = "1.61";
const string FGJSBBase::JSBSim_version = "0.9.5";
std::queue <FGJSBBase::Message*> FGJSBBase::Messages;

View file

@ -238,7 +238,7 @@ protected:
static const double ktstofps;
static const double inchtoft;
static const double in3tom3;
static const double Reng; // Specific Gas Constant,ft^2/(sec^2*R)
static double Reng; // Specific Gas Constant,ft^2/(sec^2*R)
static const double SHRatio;
static const string needed_cfg_version;
static const string JSBSim_version;

View file

@ -115,9 +115,7 @@ FGLGear::FGLGear(FGConfigFile* AC_cfg, FGFDMExec* fdmex) : Exec(fdmex)
MaximumStrutForce = MaximumStrutTravel = 0.0;
SinkRate = GroundSpeed = 0.0;
vWhlBodyVec = (vXYZ - MassBalance->GetXYZcg()) / 12.0;
vWhlBodyVec(eX) = -vWhlBodyVec(eX);
vWhlBodyVec(eZ) = -vWhlBodyVec(eZ);
vWhlBodyVec = MassBalance->StructuralToBody(vXYZ);
vLocalGear = State->GetTb2l() * vWhlBodyVec;
@ -233,9 +231,7 @@ FGColumnVector3& FGLGear::Force(void)
if (GearDown) {
vWhlBodyVec = (vXYZ - MassBalance->GetXYZcg()) / 12.0;
vWhlBodyVec(eX) = -vWhlBodyVec(eX);
vWhlBodyVec(eZ) = -vWhlBodyVec(eZ);
vWhlBodyVec = MassBalance->StructuralToBody(vXYZ);
// vWhlBodyVec now stores the vector from the cg to this wheel
@ -403,13 +399,6 @@ FGColumnVector3& FGLGear::Force(void)
FCoeff = dynamicFCoeff*fabs(WheelSlip)/WheelSlip;
}
#if 0
// A negative force coefficient will result in a force pulling the wheel(s)
// back instead of trying to stop them from moving.
if (FCoeff < 0.0)
FCoeff = 0.0;
#endif
// Compute the vertical force on the wheel using square-law damping (per comment
// in paper AIAA-2000-4303 - see header prologue comments). We might consider
// allowing for both square and linear damping force calculation. Also need to

View file

@ -198,6 +198,39 @@ double FGMassBalance::GetPMIxz(void)
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGColumnVector3 FGMassBalance::StructuralToBody(const FGColumnVector3& r) const
{
// Under the assumption that in the structural frame the:
//
// - X-axis is directed afterwards,
// - Y-axis is directed towards the right,
// - Z-axis is directed upwards,
//
// (as documented in http://jsbsim.sourceforge.net/JSBSimCoordinates.pdf)
// we have to subtract first the center of gravity of the plane which
// is also defined in the structural frame:
//
// FGColumnVector3 cgOff = r - vXYZcg;
//
// Next, we do a change of units:
//
// cgOff *= inchtoft;
//
// And then a 180 degree rotation is done about the Y axis so that the:
//
// - X-axis is directed forward,
// - Y-axis is directed towards the right,
// - Z-axis is directed downward.
//
// This is needed because the structural and body frames are 180 degrees apart.
return FGColumnVector3(inchtoft*(vXYZcg(1)-r(1)),
inchtoft*(r(2)-vXYZcg(2)),
inchtoft*(vXYZcg(3)-r(3)));
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGMassBalance::bind(void)
{
typedef double (FGMassBalance::*PMF)(int) const;

View file

@ -84,6 +84,14 @@ public:
inline FGColumnVector3& GetXYZcg(void) {return vXYZcg;}
inline double GetXYZcg(int axis) const {return vXYZcg(axis);}
/** Conversion from the structural frame to the body frame.
* Converts the argument \parm r given in the reference frame
* coordinate system to the body frame. The units of the structural
* frame are assumed to be in inches. The unit of the result is in
* ft.
*/
FGColumnVector3 StructuralToBody(const FGColumnVector3& r) const;
inline void SetEmptyWeight(double EW) { EmptyWeight = EW;}
inline void SetBaseIxx(double bixx) { baseIxx = bixx;}
inline void SetBaseIyy(double biyy) { baseIyy = biyy;}

View file

@ -47,7 +47,6 @@ INCLUDES
# else
# include <cmath>
# endif
# include <iostream>
using std::ostream;
using std::istream;
using std::cerr;

View file

@ -184,8 +184,7 @@ bool FGPosition::Run(void)
h = Radius - SeaLevelRadius; // Geocentric
vVRPoffset = State->GetTb2l() * (vVRP - MassBalance->GetXYZcg());
vVRPoffset /= 12.0; // converted to feet
vVRPoffset = State->GetTb2l() * MassBalance->StructuralToBody(Aircraft->GetXYZvrp());
// vVRP - the vector to the Visual Reference Point - now contains the
// offset from the CG to the VRP, in units of feet, in the Local coordinate
@ -196,7 +195,7 @@ bool FGPosition::Run(void)
LongitudeVRP = vVRPoffset(eEast) / (Radius * cosLat) + Longitude;
LatitudeVRP = vVRPoffset(eNorth) / Radius + Latitude;
hVRP = vVRPoffset(eDown) + h;
hVRP = h - vVRPoffset(eDown);
/*
cout << "Lat/Lon/Alt : " << Latitude << " / " << Longitude << " / " << h << endl;
cout << "Lat/Lon/Alt VRP: " << LatitudeVRP << " / " << LongitudeVRP << " / " << hVRP << endl << endl;
@ -205,10 +204,8 @@ cout << "Lat/Lon/Alt VRP: " << LatitudeVRP << " / " << LongitudeVRP << " / " <<
hoverbcg = DistanceAGL/b;
vMac = State->GetTb2l()*Aircraft->GetXYZrp();
vMac *= inchtoft;
hoverbmac = (DistanceAGL + vMac(3))/b;
vMac = State->GetTb2l()*MassBalance->StructuralToBody(Aircraft->GetXYZrp());
hoverbmac = (DistanceAGL + vMac(3)) / b;
if (Vt > 0) {
hdot_Vt = RadiusDot/Vt;

View file

@ -131,6 +131,7 @@ double FGSimTurbine::Off(void)
OilPressure_psi = N2 * 0.62;
NozzlePosition = Seek(&NozzlePosition, 1.0, 0.8, 0.8);
EPR = Seek(&EPR, 1.0, 0.2, 0.2);
Augmentation = false;
return 0.0;
}

View file

@ -49,7 +49,7 @@ INCLUDES
# include <fstream.h>
# endif
#else
# if defined(sgi) && !defined(__GNUC__)
# if defined(sgi) && !defined(__GNUC__) && (_COMPILER_VERSION < 740)
# include <fstream.h>
# else
# include <fstream>

View file

@ -157,7 +157,6 @@ FGJSBsim::FGJSBsim( double dt )
exit(-1);
}
init_gear();
// Set initial fuel levels if provided.

View file

@ -76,10 +76,6 @@ class FGInitialCondition;
using namespace JSBSim;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
COMMENTS, REFERENCES, and NOTES [use "class documentation" below for API docs]
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DOCUMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
@ -93,10 +89,6 @@ CLASS DOCUMENTATION
@author Tony Peden (Maintained and refined)
@version $Id$
@see main in file JSBSim.cpp (use main() wrapper for standalone usage)
@see <a href="http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/jsbsim/JSBSim/JSBSim.hxx?rev=HEAD&content-type=text/vnd.viewcvs-markup">
Header File </a>
@see <a href="http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/jsbsim/JSBSim/JSBSim.cxx?rev=HEAD&content-type=text/vnd.viewcvs-markup">
Source File </a>
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

View file

@ -59,20 +59,23 @@ CLASS DOCUMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/** Models a deadband object.
Owned and Operated by the FGFCS class.
<COMPONENT NAME="Deadbeat1" TYPE="DEADBAND">
Here is the format of the deadband control specification:
<pre>
\<COMPONENT NAME="Deadbeat1" TYPE="DEADBAND">
INPUT {input}
WIDTH {deadband width}
GAIN {optional deadband gain}
MIN {minimum value}
MAX {maximum value}
OUTPUT {optional output parameter to set}
</COMPONENT>
[GAIN {optional deadband gain}]
[OUTPUT {optional output parameter to set}]
\</COMPONENT>
</pre>
The WIDTH value is the total deadband region within which an input will
produce no output. For example, say that the WIDTH value is 2.0. If the
input is between -1.0 and +1.0, the output will be zero.
@author Jon S. Berndt
@see -
*/
@version $Id$
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DECLARATION

View file

@ -118,12 +118,12 @@ FGFilter::FGFilter(FGFCS* fcs, FGConfigFile* AC_cfg) : FGFCSComponent(fcs),
cc = (2.00*C3 - dt*C2) / denom;
break;
case eOrder2:
denom = 4.0*C3 + 2.0*C5*dt + C6*dt*dt;
ca = 4.0*C1 + 2.0*C2*dt + C3*dt*dt / denom;
cb = 2.0*C3*dt*dt - 8.0*C1 / denom;
cc = 4.0*C1 - 2.0*C2*dt + C3*dt*dt / denom;
cd = 2.0*C6*dt*dt - 8.0*C4 / denom;
ce = 4.0*C3 - 2.0*C5*dt + C6*dt*dt / denom;
denom = 4.0*C4 + 2.0*C5*dt + C6*dt*dt;
ca = (4.0*C1 + 2.0*C2*dt + C3*dt*dt) / denom;
cb = (2.0*C3*dt*dt - 8.0*C1) / denom;
cc = (4.0*C1 - 2.0*C2*dt + C3*dt*dt) / denom;
cd = (2.0*C6*dt*dt - 8.0*C4) / denom;
ce = (4.0*C4 - 2.0*C5*dt + C6*dt*dt) / denom;
break;
case eWashout:
denom = 2.00 + dt*C1;

View file

@ -166,14 +166,19 @@ The corresponding filter definition is:
[TRIGGER \<property>]
\</COMPONENT>
</pre>
For the integrator, the TRIGGER features the following behavior, if the TRIGGER property value is:
For the integrator, the TRIGGER features the following behavior, if the TRIGGER
property value is:
- -1 (or simply less than zero), all previous inputs and outputs are set to 0.0
- 0, no action is taken - the output is calculated normally
- +1 (or simply greater than zero), all previous outputs (only) will be set to 0.0
@author Jon S. Berndt
@version $Id$
*/
In all the filter specifications above, an [OUTPUT] keyword is also seen. This
is so that the last component in a "string" can copy its value to the appropriate
output, such as the elevator, or speedbrake, etc.
@author Jon S. Berndt
@version $Id$
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DECLARATION

View file

@ -68,7 +68,98 @@ CLASS DOCUMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/** Encapsulates a gain component for the flight control system.
*/
The gain component merely multiplies the input by a gain. The form of the
gain component specification is:
<pre>
\<COMPONENT NAME="name" TYPE="PURE_GAIN">
INPUT \<property>
GAIN \<value>
[OUTPUT \<property>]
\</COMPONENT>
</pre>
Note: as is the case with the Summer component, the input property name may be
immediately preceded by a minus sign to invert that signal.
The scheduled gain component multiplies the input by a variable gain that is
dependent on another property (such as qbar, altitude, etc.). The lookup
mapping is in the form of a table. This kind of component might be used, for
example, in a case where aerosurface deflection must only be commanded to
acceptable settings - i.e at higher qbar the commanded elevator setting might
be attenuated. The form of the scheduled gain component specification is:
<pre>
\<COMPONENT NAME="name" TYPE="SCHEDULED_GAIN">
INPUT \<property>
[GAIN \<value>]
SCHEDULED_BY \<property>
ROWS \<number_of_rows>
\<lookup_value gain_value>
?
[OUTPUT \<property>]
\</COMPONENT>
</pre>
An overall GAIN may be supplied that is multiplicative with the scheduled gain.
Note: as is the case with the Summer component, the input property name may
be immediately preceded by a minus sign to invert that signal.
Here is an example of a scheduled gain component specification:
<pre>
\<COMPONENT NAME="Pitch Scheduled Gain 1" TYPE="SCHEDULED_GAIN">
INPUT fcs/pitch-gain-1
GAIN 0.017
SCHEDULED_BY fcs/elevator-pos-rad
ROWS 22
-0.68 -26.548
-0.595 -20.513
-0.51 -15.328
-0.425 -10.993
-0.34 -7.508
-0.255 -4.873
-0.17 -3.088
-0.085 -2.153
0 -2.068
0.085 -2.833
0.102 -3.088
0.119 -3.377
0.136 -3.7
0.153 -4.057
0.17 -4.448
0.187 -4.873
0.272 -7.508
0.357 -10.993
0.442 -15.328
0.527 -20.513
0.612 -26.548
0.697 -33.433
\</COMPONENT>
</pre>
In the example above, we see the utility of the overall GAIN value in
effecting a degrees-to-radians conversion.
The aerosurface scale component is a modified version of the simple gain
component. The normal purpose
for this component is to take control inputs that range from -1 to +1 or
from 0 to +1 and scale them to match the expected inputs to a flight control
system. For instance, the normal and expected ability of a pilot to push or
pull on a control stick is about 50 pounds. The input to the pitch channelb
lock diagram of a flight control system is in units of pounds. Yet, the
joystick control input is usually in a range from -1 to +1. The form of the
aerosurface scaling component specification is:
<pre>
\<COMPONENT NAME="name" TYPE="AEROSURFACE_SCALE">
INPUT \<property>
MIN \<value>
MAX \<value>
[GAIN \<value>]
[OUTPUT \<property>]
\</COMPONENT>
</pre>
Note: as is the case with the Summer component, the input property name may be
immediately preceded by a minus sign to invert that signal.
@author Jon S. Berndt
@version $Id$
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DECLARATION

View file

@ -69,8 +69,32 @@ CLASS DOCUMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/** Models a flight control system summing component.
The Summer component sums multiple inputs. These can be pilot control inputs,
state variables, or even floating point numbers (e.g. for a bias).
The Summer component sums two or more inputs. These can be pilot control
inputs or state variables, and a bias can also be added in using the BIAS
keyword. The form of the summer component specification is:
<pre>
\<COMPONENT NAME="name" TYPE="SUMMER">
INPUT \<property>
INPUT \<property>
[BIAS \<value>]
[?]
[CLIPTO \<min> \<max> 1]
[OUTPUT \<property>]
\</COMPONENT>
</pre>
Note that in the case of an input property the property name may be
immediately preceded by a minus sign. Here's an example of a summer
component specification:
<pre>
\<COMPONENT NAME="Roll A/P Error summer" TYPE="SUMMER">
INPUT velocities/p-rad_sec
INPUT -fcs/roll-ap-wing-leveler
INPUT fcs/roll-ap-error-integrator
CLIPTO -1 1
\</COMPONENT>
</pre>
Note that there can be only one BIAS statement per component.
@author Jon S. Berndt
@version $Id$
*/

View file

@ -62,13 +62,13 @@ CLASS DOCUMENTATION
The SWITCH component models a switch - either on/off or a multi-choice rotary
switch. The switch can represent a physical cockpit switch, or can represent a
logical switch, where several conditions might need to be satisfied before a
particular state is reached. The VALUE of the switch - the output value - is
chosen depending on the state of the switch. Each switch is comprised of two or
more TESTs. Each TEST has a VALUE associated with it. The first TEST that
evaluates to TRUE will set the output value of the switch according to the VALUE
parameter belonging to that TEST. Each TEST contains one or more CONDITIONS, which
each must be logically related (if there are more than one) given the value of
the LOGIC parameter, and which takes the form:
particular state is reached. The VALUE of the switch - the output value for the
component - is chosen depending on the state of the switch. Each switch is
comprised of two or more TESTs. Each TEST has a VALUE associated with it. The
first TEST that evaluates to TRUE will set the output value of the switch
according to the VALUE parameter belonging to that TEST. Each TEST contains one
or more CONDITIONS, which each must be logically related (if there are more than
one) given the value of the LOGIC parameter, and which takes the form:
property conditional property|value
@ -101,6 +101,24 @@ additional conditions, as well as possibly additional CONDITION_GROUPs.
...
\</COMPONENT\>
</pre>
Here's an example:
<pre>
\<COMPONENT NAME="Roll A/P Autoswitch" TYPE="SWITCH">
\<TEST LOGIC="DEFAULT" VALUE="0.0">
\</TEST>
\<TEST LOGIC="AND" VALUE="fcs/roll-ap-error-summer">
ap/attitude_hold == 1
\</TEST>
\</COMPONENT>
</pre>
The above example specifies that the default value of the component (i.e. the
output property of the component, addressed by the property, ap/roll-ap-autoswitch)
is 0.0. If or when the attitude hold switch is selected (property
ap/attitude_hold takes the value 1), the value of the switch component will be
whatever value fcs/roll-ap-error-summer is.
@author Jon S. Berndt
@version $Id$
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%