From: Bertrand <bco...@us...> - 2017-06-04 17:40:00
|
Update of /cvsroot/jsbsim/JSBSim/src/models In directory sfp-cvs-1.v30.ch3.sourceforge.com:/tmp/cvs-serv30017/src/models Modified Files: FGExternalForce.cpp FGExternalForce.h FGExternalReactions.cpp Log Message: Prepare the code for the addition of external moments (in addition to external forces). Also created FGPropertyVector3 to mimic FGColumnVector3 except that its components are properties rather than double. The idea is to save data duplication and prevent the use of FGPropertyManager::Tie() which is unfriendly with property listeners. Index: FGExternalForce.cpp =================================================================== RCS file: /cvsroot/jsbsim/JSBSim/src/models/FGExternalForce.cpp,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -r1.20 -r1.21 *** FGExternalForce.cpp 3 Jun 2017 19:49:20 -0000 1.20 --- FGExternalForce.cpp 4 Jun 2017 17:39:57 -0000 1.21 *************** *** 69,98 **** //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ! FGExternalForce::FGExternalForce(FGFDMExec *FDMExec, Element *el) ! : FGForce(FDMExec) { ! FGPropertyManager* PropertyManager = fdmex->GetPropertyManager(); ! Name = el->GetAttributeValue("name"); ! string BasePropertyName = "external_reactions/" + Name; ! ! // 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) { ! Magnitude = new FGFunction(PropertyManager, function_element); ! } else { ! string nodeName = BasePropertyName + "/magnitude"; ! FGPropertyNode* node = PropertyManager->GetNode(nodeName, true); ! Magnitude = new FGPropertyValue(node); ! } // Set frame (from FGForce). string sFrame = el->GetAttributeValue("frame"); if (sFrame.empty()) { cerr << el->ReadFrom() ! << "No frame specified for external force, \"" << Name << "\"." << endl << "Frame set to Body" << endl; ttype = tNone; --- 69,92 ---- //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ! FGPropertyVector3::FGPropertyVector3(FGPropertyManager* pm, ! const std::string& baseName, ! const std::string& xcmp, ! const std::string& ycmp, ! const std::string& zcmp) { ! 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). string sFrame = el->GetAttributeValue("frame"); if (sFrame.empty()) { cerr << el->ReadFrom() ! << "No frame specified for external " << el->GetName() << ", \"" ! << Name << "\"." << endl << "Frame set to Body" << endl; ttype = tNone; *************** *** 105,113 **** } else { cerr << el->ReadFrom() ! << "Invalid frame specified for external force, \"" << Name << "\"." ! << endl << "Frame set to Body" << endl; ttype = tNone; } Element* location_element = el->FindElement("location"); if (!location_element) { --- 99,144 ---- } else { cerr << el->ReadFrom() ! << "Invalid frame specified for external " << el->GetName() << ", \"" ! << Name << "\"." << endl ! << "Frame set to Body" << endl; ttype = tNone; } + Element* direction_element = el->FindElement("direction"); + if (!direction_element) { + cerr << el->ReadFrom() + << "No direction element specified in " << el->GetName() + << " object. Default is (0,0,0)." << endl; + } else { + FGColumnVector3 direction = direction_element->FindElementTripletConvertTo("IN"); + direction.Normalize(); + v = direction; + } + + // 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); + } + } + + void FGExternalForce::setForce(Element *el) + { + 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) { *************** *** 124,146 **** PropertyManager->Tie( BasePropertyName + "/location-z-in", (FGForce*)this, &FGForce::GetLocationZ, &FGForce::SetLocationZ); - - Element* direction_element = el->FindElement("direction"); - if (!direction_element) { - cerr << el->ReadFrom() - << "No direction element specified in force object. Default is (0,0,0)." - << endl; - } else { - vDirection = direction_element->FindElementTripletConvertTo("IN"); - vDirection.Normalize(); - } - - PropertyManager->Tie(BasePropertyName + "/x", (FGExternalForce*)this, - &FGExternalForce::GetDirectionX, &FGExternalForce::SetDirectionX); - PropertyManager->Tie(BasePropertyName + "/y", (FGExternalForce*)this, - &FGExternalForce::GetDirectionY, &FGExternalForce::SetDirectionY); - PropertyManager->Tie(BasePropertyName + "/z", (FGExternalForce*)this, - &FGExternalForce::GetDirectionZ, &FGExternalForce::SetDirectionZ); - - Debug(0); } --- 155,158 ---- *************** *** 149,153 **** FGExternalForce::~FGExternalForce() { ! delete Magnitude; Debug(1); } --- 161,165 ---- FGExternalForce::~FGExternalForce() { ! delete forceMagnitude; Debug(1); } *************** *** 157,161 **** const FGColumnVector3& FGExternalForce::GetBodyForces(void) { ! vFn = Magnitude->GetValue() * vDirection; return FGForce::GetBodyForces(); } --- 169,173 ---- const FGColumnVector3& FGExternalForce::GetBodyForces(void) { ! vFn = forceMagnitude->GetValue() * forceDirection; return FGForce::GetBodyForces(); } Index: FGExternalForce.h =================================================================== RCS file: /cvsroot/jsbsim/JSBSim/src/models/FGExternalForce.h,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -r1.17 -r1.18 *** FGExternalForce.h 3 Jun 2017 19:49:20 -0000 1.17 --- FGExternalForce.h 4 Jun 2017 17:39:57 -0000 1.18 *************** *** 44,47 **** --- 44,48 ---- #include "models/propulsion/FGForce.h" #include "math/FGColumnVector3.h" + #include "simgear/props/propertyObject.hxx" /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *************** *** 59,62 **** --- 60,64 ---- class FGParameter; class Element; + class FGPropertyManager; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *************** *** 149,152 **** --- 151,186 ---- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ + 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 { *************** *** 156,160 **** @param el pointer to the XML element defining an individual force. */ ! FGExternalForce(FGFDMExec *FDMExec, Element *el); /** Copy Constructor --- 190,194 ---- @param el pointer to the XML element defining an individual force. */ ! FGExternalForce(FGFDMExec *FDMExec) : FGForce(FDMExec) { Debug(0); } /** Copy Constructor *************** *** 166,182 **** ~FGExternalForce(); const FGColumnVector3& GetBodyForces(void); - double GetDirectionX(void) const {return vDirection(eX);} - double GetDirectionY(void) const {return vDirection(eY);} - double GetDirectionZ(void) const {return vDirection(eZ);} - void SetDirectionX(double x) {vDirection(eX) = x;} - void SetDirectionY(double y) {vDirection(eY) = y;} - void SetDirectionZ(double z) {vDirection(eZ) = z;} private: std::string Name; ! FGParameter* Magnitude; ! FGColumnVector3 vDirection; void Debug(int from); }; --- 200,213 ---- ~FGExternalForce(); + void setForce(Element* el); const FGColumnVector3& GetBodyForces(void); private: + FGParameter* bind(Element* el, FGPropertyManager* pm, + const std::string& baseName, FGPropertyVector3& v); std::string Name; ! FGParameter* forceMagnitude; ! FGPropertyVector3 forceDirection; void Debug(int from); }; Index: FGExternalReactions.cpp =================================================================== RCS file: /cvsroot/jsbsim/JSBSim/src/models/FGExternalReactions.cpp,v retrieving revision 1.23 retrieving revision 1.24 diff -C2 -r1.23 -r1.24 *** FGExternalReactions.cpp 3 Jun 2017 19:49:20 -0000 1.23 --- FGExternalReactions.cpp 4 Jun 2017 17:39:57 -0000 1.24 *************** *** 82,86 **** Element* force_element = el->FindElement("force"); while (force_element) { ! Forces.push_back( new FGExternalForce(FDMExec, force_element) ); force_element = el->FindNextElement("force"); } --- 82,87 ---- Element* force_element = el->FindElement("force"); while (force_element) { ! Forces.push_back(new FGExternalForce(FDMExec)); ! Forces.back()->setForce(force_element); force_element = el->FindNextElement("force"); } |