1
0
Fork 0

Sync. w/ JSBSim

External moments can now be specified in addition to external forces. This feature is needed for the AI wakes.
Headers clean up to reduce the amount of recompilation when modifying an header file.
This commit is contained in:
Bertrand Coconnier 2017-06-05 13:09:00 +02:00
parent ac89ec94a3
commit 7d80a48d94
18 changed files with 325 additions and 213 deletions

0
src/FDM/JSBSim/math/FGFunction.cpp Executable file → Normal file
View file

0
src/FDM/JSBSim/math/FGFunction.h Executable file → Normal file
View file

View file

@ -38,16 +38,16 @@ INCLUDES
#include <iostream>
#include "FGFDMExec.h"
#include "FGBuoyantForces.h"
#include "FGMassBalance.h"
#include "input_output/FGPropertyManager.h"
#include "input_output/FGXMLElement.h"
using namespace std;
namespace JSBSim {
IDENT(IdSrc,"$Id: FGBuoyantForces.cpp,v 1.30 2015/03/28 14:49:02 bcoconni Exp $");
IDENT(IdSrc,"$Id: FGBuoyantForces.cpp,v 1.31 2017/06/03 19:49:20 bcoconni Exp $");
IDENT(IdHdr,ID_BUOYANTFORCES);
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

View file

@ -48,133 +48,162 @@
</direction>
</force>
<moment name="name" frame="BODY|LOCAL|WIND">
<function> ... </function>
<direction> <!-- optional for initial direction vector -->
<x> value </x>
<y> value </y>
<z> value </z>
</direction>
</force>
</external_reactions>
*/
#include <iostream>
#include "FGFDMExec.h"
#include "FGExternalForce.h"
#include "input_output/FGXMLElement.h"
#include <iostream>
#include "math/FGPropertyValue.h"
#include "math/FGFunction.h"
using namespace std;
namespace JSBSim {
IDENT(IdSrc,"$Id: FGExternalForce.cpp,v 1.16 2014/12/18 09:56:05 andgi Exp $");
IDENT(IdSrc,"$Id: FGExternalForce.cpp,v 1.22 2017/06/04 21:06:08 bcoconni Exp $");
IDENT(IdHdr,ID_EXTERNALFORCE);
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGExternalForce::FGExternalForce(FGFDMExec *FDMExec, Element *el, int index)
: FGForce(FDMExec)
FGPropertyVector3::FGPropertyVector3(FGPropertyManager* pm,
const std::string& baseName,
const std::string& xcmp,
const std::string& ycmp,
const std::string& zcmp)
{
Element* location_element=0;
Element* direction_element=0;
Element* function_element=0;
string sFrame;
string BasePropertyName;
FGColumnVector3 location;
Magnitude_Function = 0;
magnitude = 0.0;
azimuth = 0.0;
FGPropertyManager* PropertyManager = fdmex->GetPropertyManager();
Name = el->GetAttributeValue("name");
BasePropertyName = "external_reactions/" + Name;
// The value sent to the sim through the external_forces/{force name}/magnitude
// property will be multiplied against the unit vector, which can come in
// initially in the direction vector. The frame in which the vector is defined
// is specified with the frame attribute. The vector is normalized to magnitude 1.
function_element = el->FindElement("function");
if (function_element) {
Magnitude_Function = new FGFunction(PropertyManager, function_element);
} else {
PropertyManager->Tie( BasePropertyName + "/magnitude",(FGExternalForce*)this, &FGExternalForce::GetMagnitude, &FGExternalForce::SetMagnitude);
}
data[0] = pm->CreatePropertyObject<double>(baseName + "/" + xcmp);
data[1] = pm->CreatePropertyObject<double>(baseName + "/" + ycmp);
data[2] = pm->CreatePropertyObject<double>(baseName + "/" + zcmp);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGParameter* FGExternalForce::bind(Element *el, FGPropertyManager* pm,
const string& magName, FGPropertyVector3& v)
{
// Set frame (from FGForce).
sFrame = el->GetAttributeValue("frame");
string sFrame = el->GetAttributeValue("frame");
if (sFrame.empty()) {
cerr << "No frame specified for external force, \"" << Name << "\"." << endl;
cerr << "Frame set to Body" << endl;
cerr << el->ReadFrom()
<< "No frame specified for external " << el->GetName() << ", \""
<< Name << "\"." << endl
<< "Frame set to Body" << endl;
ttype = tNone;
} else if (sFrame == "BODY") {
ttype = tNone;
} else if (sFrame == "LOCAL") {
ttype = tLocalBody;
PropertyManager->Tie( BasePropertyName + "/azimuth", (FGExternalForce*)this, &FGExternalForce::GetAzimuth, &FGExternalForce::SetAzimuth);
} else if (sFrame == "WIND") {
ttype = tWindBody;
} else {
cerr << "Invalid frame specified for external force, \"" << Name << "\"." << endl;
cerr << "Frame set to Body" << endl;
cerr << el->ReadFrom()
<< "Invalid frame specified for external " << el->GetName() << ", \""
<< Name << "\"." << endl
<< "Frame set to Body" << endl;
ttype = tNone;
}
PropertyManager->Tie( BasePropertyName + "/x", (FGExternalForce*)this, &FGExternalForce::GetX, &FGExternalForce::SetX);
PropertyManager->Tie( BasePropertyName + "/y", (FGExternalForce*)this, &FGExternalForce::GetY, &FGExternalForce::SetY);
PropertyManager->Tie( BasePropertyName + "/z", (FGExternalForce*)this, &FGExternalForce::GetZ, &FGExternalForce::SetZ);
location_element = el->FindElement("location");
if (!location_element) {
cerr << "No location element specified in force object." << endl;
} else {
location = location_element->FindElementTripletConvertTo("IN");
SetLocation(location);
}
PropertyManager->Tie( BasePropertyName + "/location-x-in", (FGExternalForce*)this, &FGExternalForce::GetLocX, &FGExternalForce::SetLocX);
PropertyManager->Tie( BasePropertyName + "/location-y-in", (FGExternalForce*)this, &FGExternalForce::GetLocY, &FGExternalForce::SetLocY);
PropertyManager->Tie( BasePropertyName + "/location-z-in", (FGExternalForce*)this, &FGExternalForce::GetLocZ, &FGExternalForce::SetLocZ);
direction_element = el->FindElement("direction");
Element* direction_element = el->FindElement("direction");
if (!direction_element) {
cerr << "No direction element specified in force object. Default is (0,0,0)." << endl;
cerr << el->ReadFrom()
<< "No direction element specified in " << el->GetName()
<< " object. Default is (0,0,0)." << endl;
} else {
vDirection = direction_element->FindElementTripletConvertTo("IN");
vDirection.Normalize();
FGColumnVector3 direction = direction_element->FindElementTripletConvertTo("IN");
direction.Normalize();
v = direction;
}
Debug(0);
// The value sent to the sim through the external_reactions/{force name}/magnitude
// property will be multiplied against the unit vector, which can come in
// initially in the direction vector. The frame in which the vector is defined
// is specified with the frame attribute. The vector is normalized to magnitude 1.
Element* function_element = el->FindElement("function");
if (function_element) {
return new FGFunction(pm, function_element);
} else {
FGPropertyNode* node = pm->GetNode(magName, true);
return new FGPropertyValue(node);
}
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// Copy constructor
FGExternalForce::FGExternalForce(const FGExternalForce& extForce) : FGForce(extForce)
void FGExternalForce::setForce(Element *el)
{
magnitude = extForce.magnitude;
Frame = extForce.Frame;
vDirection = extForce.vDirection;
Name = extForce.Name;
FGPropertyManager* PropertyManager = fdmex->GetPropertyManager();
Name = el->GetAttributeValue("name");
string BasePropertyName = "external_reactions/" + Name;
forceDirection = FGPropertyVector3(PropertyManager, BasePropertyName,
"x", "y", "z");
forceMagnitude = bind(el, PropertyManager, BasePropertyName + "/magnitude",
forceDirection);
Element* location_element = el->FindElement("location");
if (!location_element) {
cerr << el->ReadFrom()
<< "No location element specified in force object." << endl;
} else {
FGColumnVector3 location = location_element->FindElementTripletConvertTo("IN");
SetLocation(location);
}
PropertyManager->Tie( BasePropertyName + "/location-x-in", (FGForce*)this,
&FGForce::GetLocationX, &FGForce::SetLocationX);
PropertyManager->Tie( BasePropertyName + "/location-y-in", (FGForce*)this,
&FGForce::GetLocationY, &FGForce::SetLocationY);
PropertyManager->Tie( BasePropertyName + "/location-z-in", (FGForce*)this,
&FGForce::GetLocationZ, &FGForce::SetLocationZ);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGExternalForce::setMoment(Element *el)
{
FGPropertyManager* PropertyManager = fdmex->GetPropertyManager();
Name = el->GetAttributeValue("name");
string BasePropertyName = "external_reactions/" + Name;
momentDirection = FGPropertyVector3(PropertyManager, BasePropertyName,
"l", "m", "n");
momentMagnitude = bind(el, PropertyManager, BasePropertyName + "/magnitude-lbsft",
momentDirection);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGExternalForce::~FGExternalForce()
{
delete Magnitude_Function;
delete forceMagnitude;
delete momentMagnitude;
Debug(1);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGExternalForce::SetMagnitude(double mag)
{
magnitude = mag;
vFn = vDirection*mag;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
const FGColumnVector3& FGExternalForce::GetBodyForces(void)
{
if (Magnitude_Function) {
double mag = Magnitude_Function->GetValue();
SetMagnitude(mag);
}
if (forceMagnitude)
vFn = forceMagnitude->GetValue() * forceDirection;
if (momentMagnitude)
vMn = Transform() * (momentMagnitude->GetValue() * momentDirection);
return FGForce::GetBodyForces();
}
@ -204,8 +233,21 @@ void FGExternalForce::Debug(int from)
if (debug_lvl & 1) { // Standard console startup message output
if (from == 0) { // Constructor
cout << " " << Name << endl;
cout << " Frame: " << Frame << endl;
cout << " Location: (" << vXYZn(eX) << ", " << vXYZn(eY) << ", " << vXYZn(eZ) << ")" << endl;
cout << " Frame: ";
switch(ttype) {
case tNone:
cout << "BODY";
break;
case tLocalBody:
cout << "LOCAL";
break;
case tWindBody:
cout << "WIND";
break;
default:
cout << "ERROR/UNKNOWN";
}
cout << endl << " Location: (" << vXYZn(eX) << ", " << vXYZn(eY) << ", " << vXYZn(eZ) << ")" << endl;
}
}
if (debug_lvl & 2 ) { // Instantiation/Destruction notification

View file

@ -7,21 +7,21 @@
------------- Copyright (C) 2007 Jon S. Berndt (jon@jsbsim.org) -------------
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.
the terms of the GNU Lesser General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your option) any
later version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
details.
You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA.
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc., 59
Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Further information about the GNU Lesser General Public License can also be found on
the world wide web at http://www.gnu.org.
Further information about the GNU Lesser General Public License can also be
found on the world wide web at http://www.gnu.org.
HISTORY
@ -40,18 +40,16 @@ INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include <string>
#include "FGFDMExec.h"
#include "FGJSBBase.h"
#include "models/propulsion/FGForce.h"
#include "input_output/FGPropertyManager.h"
#include "math/FGColumnVector3.h"
#include "math/FGFunction.h"
#include "simgear/props/propertyObject.hxx"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_EXTERNALFORCE "$Id: FGExternalForce.h,v 1.13 2014/11/25 01:44:17 dpculp Exp $"
#define ID_EXTERNALFORCE "$Id: FGExternalForce.h,v 1.19 2017/06/04 21:06:08 bcoconni Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
@ -59,14 +57,18 @@ FORWARD DECLARATIONS
namespace JSBSim {
class FGParameter;
class Element;
class FGPropertyManager;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DOCUMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/** Encapsulates code that models an individual arbitrary force.
This class encapsulates an individual force applied at the specified
/** Encapsulates code that models an individual arbitrary force, moment or a combination thereof.
This class encapsulates an individual reaction applied at the specified
location on the vehicle, and oriented as specified in one of three frames:
- BODY frame is defined with the X axis positive forward, the Y axis
positive out the right wing, and the Z axis completing the set
positive downward out the belly of the aircraft.
@ -80,14 +82,14 @@ CLASS DOCUMENTATION
wind frame definition, which is rotated about the Y axis 180 degrees
from this WIND frame.
Much of the substance of this class is located in the FGForce base class, from
which this class is derived.
Much of the substance of this class is located in the FGForce base class,
from which this class is derived.
Here is the XML definition of a force (optional items are in []):
@code
<force name="name" frame="BODY | LOCAL | WIND">
[<function> ... </function>]
<location unit="{IN | M}">
@ -103,54 +105,124 @@ CLASS DOCUMENTATION
</force>
@endcode
The location of the force vector, in structural coordinates, can be set at
runtime through the following properties:
@code
external_reactions/{force name}/location-x-in
external_reactions/{force name}/location-y-in
external_reactions/{force name}/location-z-in
@endcode
The XML definition of a moment (optional items are in []) is a bit simpler
because you do not need to specify the location:
@code
<moment name="name" frame="BODY | LOCAL | WIND">
[<function> ... </function>]
[<direction> <!-- optional initial direction vector -->
<x> {number} </x>
<y> {number} </y>
<z> {number} </z>
</direction>]
</moment>
@endcode
The initial direction can optionally be set by specifying a unit vector
in the chosen frame (body, local, or wind). The direction is specified
at runtime through setting any/all of the following properties:
in the chosen frame (body, local, or wind).
As an example, a parachute can be defined oriented in the wind axis frame
so the drag always acts in the drag direction - opposite the positive X
axis. That does not include the effects of parachute oscillations, but
those could be handled in the calling application.
The force (or moment) direction is not actually required to be specified as
a unit vector, but prior to the force (or moment) vector being calculated,
the direction vector is normalized when initialized.
The force direction can be specified at runtime through setting any/all of
the following properties:
@code
external_reactions/{force name}/x
external_reactions/{force name}/y
external_reactions/{force name}/z
@endcode
As an example, a parachute can be defined oriented in the wind axis frame
so the drag always acts in the drag direction - opposite the positive X
axis. That does not include the effects of parachute oscillations, but
those could be handled in the calling application.
The force direction is not actually required to be specified as a unit
vector, but prior to the force vector being calculated, the direction
vector is normalized.
The location of the force vector, in structural coordinates, can be set at
runtime through the following properties:
The moment direction can be specified at runtime through setting any/all of
the following properties:
@code
external_reactions/{force name}/locx
external_reactions/{force name}/locy
external_reactions/{force name}/locz
external_reactions/{moment name}/l
external_reactions/{moment name}/m
external_reactions/{moment name}/n
@endcode
However in that case, the direction is no longer normalized.
When no <function> has been provided in the force definition, its magnitude
can be specified through the following property:
@code
external_reactions/{force name}/magnitude
@endcode
When no <function> has been provided in the moment definition, its magnitude
can be specified through the following property:
@code
external_reactions/{moment name}/magnitude-lbsft
@endcode
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DECLARATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
class FGPropertyVector3
{
public:
FGPropertyVector3(void) {}
FGPropertyVector3(FGPropertyManager* pm, const std::string& baseName,
const std::string& xcmp, const std::string& ycmp,
const std::string& zcmp);
FGPropertyVector3& operator=(const FGColumnVector3& v) {
data[0] = v(1);
data[1] = v(2);
data[2] = v(3);
return *this;
}
operator FGColumnVector3() const {
return FGColumnVector3(data[0], data[1], data[2]);
}
FGColumnVector3 operator*(double a) const {
return FGColumnVector3(a * data[0], a * data[1], a * data[2]);
}
private:
SGPropObjDouble data[3];
};
inline FGColumnVector3 operator*(double a, const FGPropertyVector3& v) {
return v*a;
}
class FGExternalForce : public FGForce
{
public:
/** Constructor.
@param FDMExec pointer to the main executive class.
*/
FGExternalForce(FGFDMExec *FDMExec);
/** Constructor.
@param FDMExec pointer to the main executive class.
@param el pointer to the XML element defining an individual force.
@param index the position of this force object in the whole list.
*/
FGExternalForce(FGFDMExec *FDMExec, Element *el, int index);
FGExternalForce(FGFDMExec *FDMExec)
: FGForce(FDMExec), forceMagnitude(NULL), momentMagnitude(NULL)
{ Debug(0); }
/** Copy Constructor
@param extForce a reference to an existing FGExternalForce object
@ -160,35 +232,18 @@ public:
/// Destructor
~FGExternalForce();
void SetMagnitude(double mag);
void SetAzimuth(double az) {azimuth = az;}
void setForce(Element* el);
void setMoment(Element* el);
const FGColumnVector3& GetBodyForces(void);
double GetMagnitude(void) const {return magnitude;}
double GetAzimuth(void) const {return azimuth;}
double GetX(void) const {return vDirection(eX);}
double GetY(void) const {return vDirection(eY);}
double GetZ(void) const {return vDirection(eZ);}
void SetX(double x) {vDirection(eX) = x;}
void SetY(double y) {vDirection(eY) = y;}
void SetZ(double z) {vDirection(eZ) = z;}
double GetLocX(void) const {return vActingXYZn(eX);}
double GetLocY(void) const {return vActingXYZn(eY);}
double GetLocZ(void) const {return vActingXYZn(eZ);}
void SetLocX(double x) {vXYZn(eX) = x; vActingXYZn(eX) = x;}
void SetLocY(double y) {vXYZn(eY) = y; vActingXYZn(eY) = y;}
void SetLocZ(double z) {vXYZn(eZ) = z; vActingXYZn(eZ) = z;}
private:
std::string Frame;
private:
FGParameter* bind(Element* el, FGPropertyManager* pm,
const std::string& baseName, FGPropertyVector3& v);
std::string Name;
FGFunction* Magnitude_Function;
FGColumnVector3 vDirection;
double magnitude;
double azimuth;
FGParameter *forceMagnitude, *momentMagnitude;
FGPropertyVector3 forceDirection, momentDirection;
void Debug(int from);
};
}
#endif

View file

@ -39,6 +39,7 @@ INCLUDES
#include <iostream>
#include <string>
#include "FGExternalForce.h"
#include "FGExternalReactions.h"
#include "input_output/FGXMLElement.h"
@ -54,7 +55,7 @@ DEFINITIONS
GLOBAL DATA
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
IDENT(IdSrc,"$Id: FGExternalReactions.cpp,v 1.19 2014/11/25 01:42:27 dpculp Exp $");
IDENT(IdSrc,"$Id: FGExternalReactions.cpp,v 1.25 2017/06/04 21:06:08 bcoconni Exp $");
IDENT(IdHdr,ID_EXTERNALREACTIONS);
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -63,8 +64,6 @@ CLASS IMPLEMENTATION
FGExternalReactions::FGExternalReactions(FGFDMExec* fdmex) : FGModel(fdmex)
{
NoneDefined = true;
Debug(0);
}
@ -80,18 +79,25 @@ bool FGExternalReactions::Load(Element* el)
// Parse force elements
int index=0;
Element* force_element = el->FindElement("force");
while (force_element) {
Forces.push_back( new FGExternalForce(FDMExec, force_element, index) );
NoneDefined = false;
index++;
Forces.push_back(new FGExternalForce(FDMExec));
Forces.back()->setForce(force_element);
force_element = el->FindNextElement("force");
}
// Parse moment elements
Element* moment_element = el->FindElement("moment");
while (moment_element) {
Forces.push_back(new FGExternalForce(FDMExec));
Forces.back()->setMoment(moment_element);
moment_element = el->FindNextElement("moment");
}
PostLoad(el, PropertyManager);
if (!NoneDefined) bind();
if (!Forces.empty()) bind();
return true;
}
@ -101,7 +107,6 @@ bool FGExternalReactions::Load(Element* el)
FGExternalReactions::~FGExternalReactions()
{
for (unsigned int i=0; i<Forces.size(); i++) delete Forces[i];
Forces.clear();
Debug(1);
}
@ -124,7 +129,7 @@ bool FGExternalReactions::Run(bool Holding)
{
if (FGModel::Run(Holding)) return true;
if (Holding) return false; // if paused don't execute
if (NoneDefined) return true;
if (Forces.empty()) return true;
RunPreFunctions();

View file

@ -40,13 +40,13 @@ INCLUDES
#include <vector>
#include "FGModel.h"
#include "FGExternalForce.h"
#include "math/FGColumnVector3.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_EXTERNALREACTIONS "$Id: FGExternalReactions.h,v 1.17 2015/02/27 20:36:47 bcoconni Exp $"
#define ID_EXTERNALREACTIONS "$Id: FGExternalReactions.h,v 1.20 2017/06/04 21:06:08 bcoconni Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
@ -55,21 +55,23 @@ FORWARD DECLARATIONS
namespace JSBSim {
class Element;
class FGExternalForce;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DOCUMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/** Manages the external and/or arbitrary forces.
/** Manages the external and/or arbitrary forces and moments.
The external reactions capability in JSBSim really should be named
"arbitrary forces", because this feature can be used to model a wide
variety of forces that act on a vehicle. Some examples include: parachutes,
catapult, arresting hook, and tow line.
"arbitrary forces and moments", because this feature can be used to model a
wide variety of forces and moments that act on a vehicle. Some examples
include: parachutes, catapult, arresting hook, and tow line.
This class acts similarly to the other "manager classes" (FGPropulsion,
FGFCS, FGGroundReactions, FGAerodynamics) because it manages collections
of constituent forces. The individual forces are implemented with the
FGExternalForce class.
This class acts similarly to the other "manager classes" (FGPropulsion,
FGFCS, FGGroundReactions, FGAerodynamics) because it manages collections of
constituent elements. The individual forces and moments are implemented with
the FGExternalForce class.
The format of the <em>optional</em> external reactions section in the config
file is as follows:
@ -80,35 +82,42 @@ CLASS DOCUMENTATION
<!-- Interface properties, a.k.a. property declarations -->
<property> ... </property>
<force name="name" frame="BODY | LOCAL | WIND" unit="unit">
<force name="name" frame="BODY | LOCAL | WIND">
...
</force>
<moment name="name" frame="BODY | LOCAL | WIND">
...
</moment>
<!-- Additional force definitions may follow -->
<force name="name" frame="BODY | LOCAL | WIND" unit="unit">
<!-- Additional force and moment definitions may follow -->
<force name="name" frame="BODY | LOCAL | WIND">
...
</force>
<moment name="name" frame="BODY | LOCAL | WIND">
...
</moment>
</external_reactions>
@endcode
See the FGExternalForce class for more information on the format of the
force specification itself.
force and moment specifications.
When force elements are encountered in the configuration file, a new instance
of the FGExternalForce class is created and a pointer to the class is pushed
onto the Forces vector.
When force or moment elements are encountered in the configuration file, a
new instance of the FGExternalForce class is created and a pointer to the
class is pushed onto the Forces vector.
This class is one of a few of the manager classes that allows properties
to be "declared". In code, these are represented by the
This class is one of a few of the manager classes that allows properties to
be "declared". In code, these are represented by the
<em>interface_properties</em> vector. Properties that have not yet been
created in an already parsed section of the configuration file and that are
used in the definition of an external force should be declared in the
external_reactions section because they will not be created automatically,
and so would cause an error, since the property cannot be found to exist.
used in the definition of an external force or moment should be declared in
the external_reactions section because they will not be created
automatically, and so would cause an error, since the property cannot be
found to exist.
See the FGExternalForce documentation for details on how forces are
actually calculated.
See the FGExternalForce documentation for details on how forces and moments
are actually calculated.
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -167,8 +176,6 @@ private:
FGColumnVector3 vTotalForces;
FGColumnVector3 vTotalMoments;
bool NoneDefined;
void bind(void);
void Debug(int from);
};

View file

@ -50,7 +50,7 @@ INCLUDES
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_GASCELL "$Id: FGGasCell.h,v 1.16 2015/03/28 14:49:02 bcoconni Exp $"
#define ID_GASCELL "$Id: FGGasCell.h,v 1.17 2017/06/03 19:49:20 bcoconni Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
@ -59,7 +59,7 @@ FORWARD DECLARATIONS
namespace JSBSim {
class FGBallonet;
class Element;
class FGMassBalance;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DOCUMENTATION

View file

@ -42,6 +42,7 @@ INCLUDES
#include <iostream>
#include <sstream>
#include "FGFDMExec.h"
#include "FGElectric.h"
#include "FGPropeller.h"
#include "input_output/FGXMLElement.h"
@ -50,7 +51,7 @@ using namespace std;
namespace JSBSim {
IDENT(IdSrc,"$Id: FGElectric.cpp,v 1.20 2015/09/27 09:54:21 bcoconni Exp $");
IDENT(IdSrc,"$Id: FGElectric.cpp,v 1.21 2017/06/03 19:49:20 bcoconni Exp $");
IDENT(IdHdr,ID_ELECTRIC);
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

View file

@ -53,7 +53,7 @@ using namespace std;
namespace JSBSim {
IDENT(IdSrc,"$Id: FGForce.cpp,v 1.19 2014/01/13 10:46:10 ehofman Exp $");
IDENT(IdSrc,"$Id: FGForce.cpp,v 1.20 2017/05/26 12:25:40 bcoconni Exp $");
IDENT(IdHdr,ID_FORCE);
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -64,14 +64,12 @@ FGForce::FGForce(FGFDMExec *FDMExec) :
{
vFn.InitMatrix();
vMn.InitMatrix();
vH.InitMatrix();
vOrient.InitMatrix();
vXYZn.InitMatrix();
vActingXYZn.InitMatrix();
vFb.InitMatrix();
vM.InitMatrix();
vDXYZ.InitMatrix();
mT.InitMatrix(1., 0., 0.,
0., 1., 0.,
@ -97,7 +95,7 @@ const 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 = fdmex->GetMassBalance()->StructuralToBody(vActingXYZn);
FGColumnVector3 vDXYZ = fdmex->GetMassBalance()->StructuralToBody(vActingXYZn);
vM = vMn + vDXYZ*vFb;

View file

@ -57,7 +57,6 @@ SENTRY
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include "FGFDMExec.h"
#include "FGJSBBase.h"
#include "math/FGMatrix33.h"
#include "math/FGColumnVector3.h"
@ -66,7 +65,7 @@ INCLUDES
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_FORCE "$Id: FGForce.h,v 1.17 2012/04/01 17:05:51 bcoconni Exp $"
#define ID_FORCE "$Id: FGForce.h,v 1.19 2017/06/03 19:49:20 bcoconni Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
@ -74,6 +73,8 @@ FORWARD DECLARATIONS
namespace JSBSim {
class FGFDMExec;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DOCUMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
@ -215,7 +216,7 @@ and vMn, the moments, can be made directly. Otherwise, the usage is similar.<br>
<br><br></p>
@author Tony Peden
@version $Id: FGForce.h,v 1.17 2012/04/01 17:05:51 bcoconni Exp $
@version $Id: FGForce.h,v 1.19 2017/06/03 19:49:20 bcoconni Exp $
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -227,12 +228,8 @@ class FGForce : public FGJSBBase
public:
/// Constructor
FGForce(FGFDMExec *FDMExec);
FGForce(const FGForce& force) {
vFn = force.vFn;
vXYZn = force.vXYZn;
ttype = force.ttype;
fdmex = force.fdmex;
}
FGForce(const FGForce& force);
/// Destructor
~FGForce();
@ -316,7 +313,6 @@ protected:
FGFDMExec *fdmex;
FGColumnVector3 vFn;
FGColumnVector3 vMn;
FGColumnVector3 vH;
FGColumnVector3 vOrient;
TransformType ttype;
FGColumnVector3 vXYZn;
@ -326,7 +322,6 @@ protected:
private:
FGColumnVector3 vFb;
FGColumnVector3 vM;
FGColumnVector3 vDXYZ;
void Debug(int from);
};

View file

@ -43,6 +43,7 @@ INCLUDES
#include <iostream>
#include <sstream>
#include "FGFDMExec.h"
#include "FGPiston.h"
#include "FGPropeller.h"
#include "input_output/FGXMLElement.h"
@ -51,7 +52,7 @@ using namespace std;
namespace JSBSim {
IDENT(IdSrc,"$Id: FGPiston.cpp,v 1.82 2016/01/02 17:42:53 bcoconni Exp $");
IDENT(IdSrc,"$Id: FGPiston.cpp,v 1.84 2017/06/03 19:49:20 bcoconni Exp $");
IDENT(IdHdr,ID_PISTON);
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

View file

@ -46,7 +46,7 @@ INCLUDES
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_PISTON "$Id: FGPiston.h,v 1.38 2016/01/02 17:42:53 bcoconni Exp $"
#define ID_PISTON "$Id: FGPiston.h,v 1.39 2017/04/29 11:16:46 ehofman Exp $"
#define FG_MAX_BOOST_SPEEDS 3
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -106,6 +106,10 @@ CLASS DOCUMENTATION
<ratedrpm3> {number} </ratedrpm3>
<ratedaltitude3 unit="{FT | M}"> {number} </ratedaltitude3>
<takeoffboost unit="{INHG | PA | ATM}"> {number} </takeoffboost>
<oil-pressure-relief-valve-psi> {number} </oil-pressure-relief-valve=psi>
<design-oil-temp-degK> {number} </design-oil-temp-degK>
<oil-pressure-rpm-max> {number} </oil-pressure-rpm-max>
<oil-viscosity-index> {number} </oil-viscosity-index>
</piston_engine>
@endcode
@ -211,7 +215,7 @@ boostspeed they refer to:
@author David Megginson (initial porting and additional code)
@author Ron Jensen (additional engine code)
@see Taylor, Charles Fayette, "The Internal Combustion Engine in Theory and Practice"
@version $Id: FGPiston.h,v 1.38 2016/01/02 17:42:53 bcoconni Exp $
@version $Id: FGPiston.h,v 1.39 2017/04/29 11:16:46 ehofman Exp $
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

View file

@ -38,6 +38,7 @@ INCLUDES
#include <iostream>
#include <sstream>
#include "FGFDMExec.h"
#include "FGPropeller.h"
#include "input_output/FGXMLElement.h"
@ -45,7 +46,7 @@ using namespace std;
namespace JSBSim {
IDENT(IdSrc,"$Id: FGPropeller.cpp,v 1.61 2017/03/22 21:27:47 bcoconni Exp $");
IDENT(IdSrc,"$Id: FGPropeller.cpp,v 1.63 2017/06/03 19:49:20 bcoconni Exp $");
IDENT(IdHdr,ID_PROPELLER);
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -146,7 +147,6 @@ FGPropeller::FGPropeller(FGFDMExec* exec, Element* prop_element, int num)
Type = ttPropeller;
RPM = 0;
vTorque.InitMatrix();
vH.InitMatrix();
D4 = Diameter*Diameter*Diameter*Diameter;
D5 = D4*Diameter;
Pitch = MinPitch;
@ -273,7 +273,7 @@ double FGPropeller::Calculate(double EnginePower)
// natural axis of the engine. The transform takes place in the base class
// FGForce::GetBodyForces() function.
vH(eX) = Ixx*omega*Sense*Sense_multiplier;
FGColumnVector3 vH(Ixx*omega*Sense*Sense_multiplier, 0.0, 0.0);
if (omega > 0.0) ExcessTorque = PowerAvailable / omega;
else ExcessTorque = PowerAvailable / 1.0;

View file

@ -41,6 +41,7 @@ INCLUDES
#include <iostream>
#include <sstream>
#include "FGFDMExec.h"
#include "FGRocket.h"
#include "FGThruster.h"
#include "input_output/FGXMLElement.h"
@ -49,7 +50,7 @@ using namespace std;
namespace JSBSim {
IDENT(IdSrc,"$Id: FGRocket.cpp,v 1.39 2015/09/27 09:54:21 bcoconni Exp $");
IDENT(IdSrc,"$Id: FGRocket.cpp,v 1.40 2017/06/03 19:49:20 bcoconni Exp $");
IDENT(IdHdr,ID_ROCKET);
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

View file

@ -38,6 +38,8 @@ INCLUDES
#include <iostream>
#include <sstream>
#include "FGFDMExec.h"
#include "input_output/FGPropertyManager.h"
#include "FGThruster.h"
#include "input_output/FGXMLElement.h"
@ -45,7 +47,7 @@ using namespace std;
namespace JSBSim {
IDENT(IdSrc,"$Id: FGThruster.cpp,v 1.22 2015/09/27 10:03:53 bcoconni Exp $");
IDENT(IdSrc,"$Id: FGThruster.cpp,v 1.23 2017/06/03 19:49:20 bcoconni Exp $");
IDENT(IdHdr,ID_THRUSTER);
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

View file

@ -42,6 +42,7 @@ INCLUDES
#include <iostream>
#include <sstream>
#include "FGFDMExec.h"
#include "math/FGFunction.h"
#include "FGTurbine.h"
#include "FGThruster.h"
@ -51,7 +52,7 @@ using namespace std;
namespace JSBSim {
IDENT(IdSrc,"$Id: FGTurbine.cpp,v 1.48 2015/12/02 04:25:23 dpculp Exp $");
IDENT(IdSrc,"$Id: FGTurbine.cpp,v 1.49 2017/06/03 19:49:20 bcoconni Exp $");
IDENT(IdHdr,ID_TURBINE);
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

0
src/FDM/JSBSim/models/propulsion/FGTurboProp.cpp Executable file → Normal file
View file