diff --git a/src/FDM/JSBSim/math/FGFunction.cpp b/src/FDM/JSBSim/math/FGFunction.cpp old mode 100755 new mode 100644 diff --git a/src/FDM/JSBSim/math/FGFunction.h b/src/FDM/JSBSim/math/FGFunction.h old mode 100755 new mode 100644 diff --git a/src/FDM/JSBSim/models/FGBuoyantForces.cpp b/src/FDM/JSBSim/models/FGBuoyantForces.cpp index 4bdb68053..51ae27f01 100644 --- a/src/FDM/JSBSim/models/FGBuoyantForces.cpp +++ b/src/FDM/JSBSim/models/FGBuoyantForces.cpp @@ -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); /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/src/FDM/JSBSim/models/FGExternalForce.cpp b/src/FDM/JSBSim/models/FGExternalForce.cpp index 37dd60135..7c5aa894c 100644 --- a/src/FDM/JSBSim/models/FGExternalForce.cpp +++ b/src/FDM/JSBSim/models/FGExternalForce.cpp @@ -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 diff --git a/src/FDM/JSBSim/models/FGExternalForce.h b/src/FDM/JSBSim/models/FGExternalForce.h index 0d7df5a59..81760543b 100644 --- a/src/FDM/JSBSim/models/FGExternalForce.h +++ b/src/FDM/JSBSim/models/FGExternalForce.h @@ -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 - diff --git a/src/FDM/JSBSim/models/FGExternalReactions.cpp b/src/FDM/JSBSim/models/FGExternalReactions.cpp index 14489904f..50304959a 100644 --- a/src/FDM/JSBSim/models/FGExternalReactions.cpp +++ b/src/FDM/JSBSim/models/FGExternalReactions.cpp @@ -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(); diff --git a/src/FDM/JSBSim/models/FGExternalReactions.h b/src/FDM/JSBSim/models/FGExternalReactions.h index f5be3578f..50766967f 100644 --- a/src/FDM/JSBSim/models/FGExternalReactions.h +++ b/src/FDM/JSBSim/models/FGExternalReactions.h @@ -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); }; diff --git a/src/FDM/JSBSim/models/FGGasCell.h b/src/FDM/JSBSim/models/FGGasCell.h index 1105c4f95..563525752 100644 --- a/src/FDM/JSBSim/models/FGGasCell.h +++ b/src/FDM/JSBSim/models/FGGasCell.h @@ -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 diff --git a/src/FDM/JSBSim/models/propulsion/FGElectric.cpp b/src/FDM/JSBSim/models/propulsion/FGElectric.cpp index 9273a97bc..ee7938291 100644 --- a/src/FDM/JSBSim/models/propulsion/FGElectric.cpp +++ b/src/FDM/JSBSim/models/propulsion/FGElectric.cpp @@ -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); /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/src/FDM/JSBSim/models/propulsion/FGForce.cpp b/src/FDM/JSBSim/models/propulsion/FGForce.cpp index a579f7773..d4e1b0395 100644 --- a/src/FDM/JSBSim/models/propulsion/FGForce.cpp +++ b/src/FDM/JSBSim/models/propulsion/FGForce.cpp @@ -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; diff --git a/src/FDM/JSBSim/models/propulsion/FGForce.h b/src/FDM/JSBSim/models/propulsion/FGForce.h index 2cd81c0e7..e432943f1 100644 --- a/src/FDM/JSBSim/models/propulsion/FGForce.h +++ b/src/FDM/JSBSim/models/propulsion/FGForce.h @@ -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); }; diff --git a/src/FDM/JSBSim/models/propulsion/FGPiston.cpp b/src/FDM/JSBSim/models/propulsion/FGPiston.cpp index 2ec5c29a0..a61c2f5fd 100644 --- a/src/FDM/JSBSim/models/propulsion/FGPiston.cpp +++ b/src/FDM/JSBSim/models/propulsion/FGPiston.cpp @@ -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); /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/src/FDM/JSBSim/models/propulsion/FGPiston.h b/src/FDM/JSBSim/models/propulsion/FGPiston.h index 97c6b7350..8c2668d3f 100644 --- a/src/FDM/JSBSim/models/propulsion/FGPiston.h +++ b/src/FDM/JSBSim/models/propulsion/FGPiston.h @@ -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 $ */ /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/src/FDM/JSBSim/models/propulsion/FGPropeller.cpp b/src/FDM/JSBSim/models/propulsion/FGPropeller.cpp index 50d9f8836..f2910efc2 100644 --- a/src/FDM/JSBSim/models/propulsion/FGPropeller.cpp +++ b/src/FDM/JSBSim/models/propulsion/FGPropeller.cpp @@ -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; diff --git a/src/FDM/JSBSim/models/propulsion/FGRocket.cpp b/src/FDM/JSBSim/models/propulsion/FGRocket.cpp index 69f72d776..b2ca883f5 100644 --- a/src/FDM/JSBSim/models/propulsion/FGRocket.cpp +++ b/src/FDM/JSBSim/models/propulsion/FGRocket.cpp @@ -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); /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/src/FDM/JSBSim/models/propulsion/FGThruster.cpp b/src/FDM/JSBSim/models/propulsion/FGThruster.cpp index b01cd6eec..1f4ddba75 100644 --- a/src/FDM/JSBSim/models/propulsion/FGThruster.cpp +++ b/src/FDM/JSBSim/models/propulsion/FGThruster.cpp @@ -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); /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/src/FDM/JSBSim/models/propulsion/FGTurbine.cpp b/src/FDM/JSBSim/models/propulsion/FGTurbine.cpp index 8b4eeac3e..796ec02cf 100644 --- a/src/FDM/JSBSim/models/propulsion/FGTurbine.cpp +++ b/src/FDM/JSBSim/models/propulsion/FGTurbine.cpp @@ -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); /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/src/FDM/JSBSim/models/propulsion/FGTurboProp.cpp b/src/FDM/JSBSim/models/propulsion/FGTurboProp.cpp old mode 100755 new mode 100644