diff --git a/src/FDM/JSBSim/FGFDMExec.cpp b/src/FDM/JSBSim/FGFDMExec.cpp index 7470d4ad7..e215d7ebb 100644 --- a/src/FDM/JSBSim/FGFDMExec.cpp +++ b/src/FDM/JSBSim/FGFDMExec.cpp @@ -604,7 +604,9 @@ void FGFDMExec::ResetToInitialConditions(int mode) { if (Constructing) return; - if (mode == 1) Output->SetStartNewOutput(); + // mode flags + + if (mode & START_NEW_OUTPUT) Output->SetStartNewOutput(); InitializeModels(); @@ -613,7 +615,8 @@ void FGFDMExec::ResetToInitialConditions(int mode) else Setsim_time(0.0); - RunIC(); + if (!(mode & DONT_EXECUTE_RUN_IC)) + RunIC(); } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/src/FDM/JSBSim/FGFDMExec.h b/src/FDM/JSBSim/FGFDMExec.h index 7303d80e7..2d9d934a5 100644 --- a/src/FDM/JSBSim/FGFDMExec.h +++ b/src/FDM/JSBSim/FGFDMExec.h @@ -460,10 +460,15 @@ public: void Resume(void) {holding = false;} /// Returns true if the simulation is Holding (i.e. simulation time is not moving). bool Holding(void) {return holding;} + /// Mode flags for ResetToInitialConditions + static const int START_NEW_OUTPUT = 0x1; + static const int DONT_EXECUTE_RUN_IC = 0x2; /** Resets the initial conditions object and prepares the simulation to run - again. If mode is set to 1 the output instances will take special actions - such as closing the current output file and open a new one with a - different name. + again. If the mode's first bit is set the output instances will take special actions + such as closing the current output file and open a new one with a different name. + If the second bit is set then RunIC() won't be executed, leaving it to the caller + to call RunIC(), e.g. in case the caller wants to set some other state like control + surface deflections which would've been reset. @param mode Sets the reset mode.*/ void ResetToInitialConditions(int mode); /// Sets the debug level. diff --git a/src/FDM/JSBSim/input_output/FGPropertyManager.cpp b/src/FDM/JSBSim/input_output/FGPropertyManager.cpp index d79afdede..878e8a309 100644 --- a/src/FDM/JSBSim/input_output/FGPropertyManager.cpp +++ b/src/FDM/JSBSim/input_output/FGPropertyManager.cpp @@ -52,12 +52,10 @@ namespace JSBSim { void FGPropertyManager::Unbind(void) { - vector<SGPropertyNode_ptr>::iterator it; + for(auto& prop: tied_properties) + prop->untie(); - for (it = tied_properties.begin();it < tied_properties.end();it++) - (*it)->untie(); - - tied_properties.clear(); + tied_properties.clear(); } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -73,7 +71,7 @@ string FGPropertyManager::mkPropertyName(string name, bool lowercase) { else if( isspace(name[i]) ) name[i]='-'; } - + return name; } @@ -324,95 +322,4 @@ void FGPropertyManager::Untie (const string &name) cerr << "Failed to untie property " << name << endl << "JSBSim is not the owner of this property." << endl; } - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -void FGPropertyManager::Tie (const string &name, bool *pointer) -{ - SGPropertyNode* property = root->getNode(name.c_str(), true); - if (!property) { - cerr << "Could not get or create property " << name << endl; - return; - } - - if (!property->tie(SGRawValuePointer<bool>(pointer), false)) - cerr << "Failed to tie property " << name << " to a pointer" << endl; - else { - tied_properties.push_back(property); - if (FGJSBBase::debug_lvl & 0x20) cout << name << endl; - } -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -void FGPropertyManager::Tie (const string &name, int *pointer) -{ - SGPropertyNode* property = root->getNode(name.c_str(), true); - if (!property) { - cerr << "Could not get or create property " << name << endl; - return; - } - - if (!property->tie(SGRawValuePointer<int>(pointer), false)) - cerr << "Failed to tie property " << name << " to a pointer" << endl; - else { - tied_properties.push_back(property); - if (FGJSBBase::debug_lvl & 0x20) cout << name << endl; - } -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -void FGPropertyManager::Tie (const string &name, long *pointer) -{ - SGPropertyNode* property = root->getNode(name.c_str(), true); - if (!property) { - cerr << "Could not get or create property " << name << endl; - return; - } - - if (!property->tie(SGRawValuePointer<long>(pointer), false)) - cerr << "Failed to tie property " << name << " to a pointer" << endl; - else { - tied_properties.push_back(property); - if (FGJSBBase::debug_lvl & 0x20) cout << name << endl; - } -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -void FGPropertyManager::Tie (const string &name, float *pointer) -{ - SGPropertyNode* property = root->getNode(name.c_str(), true); - if (!property) { - cerr << "Could not get or create property " << name << endl; - return; - } - - if (!property->tie(SGRawValuePointer<float>(pointer), false)) - cerr << "Failed to tie property " << name << " to a pointer" << endl; - else { - tied_properties.push_back(property); - if (FGJSBBase::debug_lvl & 0x20) cout << name << endl; - } -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -void FGPropertyManager::Tie (const string &name, double *pointer) -{ - SGPropertyNode* property = root->getNode(name.c_str(), true); - if (!property) { - cerr << "Could not get or create property " << name << endl; - return; - } - - if (!property->tie(SGRawValuePointer<double>(pointer), false)) - cerr << "Failed to tie property " << name << " to a pointer" << endl; - else { - tied_properties.push_back(property); - if (FGJSBBase::debug_lvl & 0x20) cout << name << endl; - } -} - } // namespace JSBSim diff --git a/src/FDM/JSBSim/input_output/FGPropertyManager.h b/src/FDM/JSBSim/input_output/FGPropertyManager.h index f3e766ea1..4015f9118 100644 --- a/src/FDM/JSBSim/input_output/FGPropertyManager.h +++ b/src/FDM/JSBSim/input_output/FGPropertyManager.h @@ -424,109 +424,31 @@ class FGPropertyManager */ void Unbind (void); - // Templates cause ambiguity here - /** - * Tie a property to an external bool variable. + * Tie a property to an external variable. * * The property's value will automatically mirror the variable's * value, and vice-versa, until the property is untied. * * @param name The property name to tie (full path). * @param pointer A pointer to the variable. - * @param useDefault true if any existing property value should be - * copied to the variable; false if the variable should not - * be modified; defaults to true. */ - void - Tie (const std::string &name, bool *pointer); + template <typename T> void + Tie (const std::string &name, T *pointer) + { + SGPropertyNode* property = root->getNode(name.c_str(), true); + if (!property) { + cerr << "Could not get or create property " << name << endl; + return; + } - - /** - * Tie a property to an external int variable. - * - * The property's value will automatically mirror the variable's - * value, and vice-versa, until the property is untied. - * - * @param name The property name to tie (full path). - * @param pointer A pointer to the variable. - * @param useDefault true if any existing property value should be - * copied to the variable; false if the variable should not - * be modified; defaults to true. - */ - void - Tie (const std::string &name, int *pointer); - - - /** - * Tie a property to an external long variable. - * - * The property's value will automatically mirror the variable's - * value, and vice-versa, until the property is untied. - * - * @param name The property name to tie (full path). - * @param pointer A pointer to the variable. - * @param useDefault true if any existing property value should be - * copied to the variable; false if the variable should not - * be modified; defaults to true. - */ - void - Tie (const std::string &name, long *pointer); - - - /** - * Tie a property to an external float variable. - * - * The property's value will automatically mirror the variable's - * value, and vice-versa, until the property is untied. - * - * @param name The property name to tie (full path). - * @param pointer A pointer to the variable. - * @param useDefault true if any existing property value should be - * copied to the variable; false if the variable should not - * be modified; defaults to true. - */ - void - Tie (const std::string &name, float *pointer); - - /** - * Tie a property to an external double variable. - * - * The property's value will automatically mirror the variable's - * value, and vice-versa, until the property is untied. - * - * @param name The property name to tie (full path). - * @param pointer A pointer to the variable. - * @param useDefault true if any existing property value should be - * copied to the variable; false if the variable should not - * be modified; defaults to true. - */ - void - Tie (const std::string &name, double *pointer); - -//============================================================================ -// -// All of the following functions *must* be inlined, otherwise linker -// errors will result -// -//============================================================================ - - /* template <class V> void - Tie (const std::string &name, V (*getter)(), void (*setter)(V) = 0, - bool useDefault = true); - - template <class V> void - Tie (const std::string &name, int index, V (*getter)(int), - void (*setter)(int, V) = 0, bool useDefault = true); - - template <class T, class V> void - Tie (const std::string &name, T * obj, V (T::*getter)() const, - void (T::*setter)(V) = 0, bool useDefault = true); - - template <class T, class V> void - Tie (const std::string &name, T * obj, int index, - V (T::*getter)(int) const, void (T::*setter)(int, V) = 0, - bool useDefault = true); */ + if (!property->tie(SGRawValuePointer<T>(pointer), false)) + cerr << "Failed to tie property " << name << " to a pointer" << endl; + else { + tied_properties.push_back(property); + if (FGJSBBase::debug_lvl & 0x20) cout << name << endl; + } + } /** * Tie a property to a pair of simple functions. @@ -542,8 +464,8 @@ class FGPropertyManager * @param setter The setter function, or 0 if the value is unmodifiable. */ - template <class V> inline void - Tie (const std::string &name, V (*getter)(), void (*setter)(V) = nullptr) + template <typename T> void + Tie (const std::string &name, T (*getter)(), void (*setter)(T) = nullptr) { SGPropertyNode* property = root->getNode(name.c_str(), true); if (!property) { @@ -551,17 +473,17 @@ class FGPropertyManager return; } - if (!property->tie(SGRawValueFunctions<V>(getter, setter), false)) - std::cerr << "Failed to tie property " << name << " to functions" << std::endl; + if (!property->tie(SGRawValueFunctions<T>(getter, setter), false)) + std::cerr << "Failed to tie property " << name << " to functions" + << std::endl; else { - if (setter == 0) property->setAttribute(SGPropertyNode::WRITE, false); - if (getter == 0) property->setAttribute(SGPropertyNode::READ, false); + if (!setter) property->setAttribute(SGPropertyNode::WRITE, false); + if (!getter) property->setAttribute(SGPropertyNode::READ, false); tied_properties.push_back(property); if (FGJSBBase::debug_lvl & 0x20) std::cout << name << std::endl; } } - /** * Tie a property to a pair of indexed functions. * @@ -577,8 +499,9 @@ class FGPropertyManager * @param getter The getter function, or 0 if the value is unreadable. * @param setter The setter function, or 0 if the value is unmodifiable. */ - template <class V> inline void Tie (const std::string &name, int index, V (*getter)(int), - void (*setter)(int, V) = nullptr) + template <typename T> void + Tie (const std::string &name, int index, T (*getter)(int), + void (*setter)(int, T) = nullptr) { SGPropertyNode* property = root->getNode(name.c_str(), true); if (!property) { @@ -586,17 +509,18 @@ class FGPropertyManager return; } - if (!property->tie(SGRawValueFunctionsIndexed<V>(index, getter, setter), false)) - std::cerr << "Failed to tie property " << name << " to indexed functions" << std::endl; + if (!property->tie(SGRawValueFunctionsIndexed<T>(index, getter, setter), + false)) + std::cerr << "Failed to tie property " << name << " to indexed functions" + << std::endl; else { - if (setter == 0) property->setAttribute(SGPropertyNode::WRITE, false); - if (getter == 0) property->setAttribute(SGPropertyNode::READ, false); + if (!setter) property->setAttribute(SGPropertyNode::WRITE, false); + if (!getter) property->setAttribute(SGPropertyNode::READ, false); tied_properties.push_back(property); if (FGJSBBase::debug_lvl & 0x20) std::cout << name << std::endl; } } - /** * Tie a property to a pair of object methods. * @@ -613,9 +537,9 @@ class FGPropertyManager * @param setter The object's setter method, or 0 if the value is * unmodifiable. */ - template <class T, class V> inline void + template <class T, class V> void Tie (const std::string &name, T * obj, V (T::*getter)() const, - void (T::*setter)(V) = nullptr) + void (T::*setter)(V) = nullptr) { SGPropertyNode* property = root->getNode(name.c_str(), true); if (!property) { @@ -624,10 +548,11 @@ class FGPropertyManager } if (!property->tie(SGRawValueMethods<T,V>(*obj, getter, setter), false)) - std::cerr << "Failed to tie property " << name << " to object methods" << std::endl; + std::cerr << "Failed to tie property " << name << " to object methods" + << std::endl; else { - if (setter == 0) property->setAttribute(SGPropertyNode::WRITE, false); - if (getter == 0) property->setAttribute(SGPropertyNode::READ, false); + if (!setter) property->setAttribute(SGPropertyNode::WRITE, false); + if (!getter) property->setAttribute(SGPropertyNode::READ, false); tied_properties.push_back(property); if (FGJSBBase::debug_lvl & 0x20) std::cout << name << std::endl; } @@ -649,9 +574,9 @@ class FGPropertyManager * @param getter The getter method, or 0 if the value is unreadable. * @param setter The setter method, or 0 if the value is unmodifiable. */ - template <class T, class V> inline void + template <class T, class V> void Tie (const std::string &name, T * obj, int index, V (T::*getter)(int) const, - void (T::*setter)(int, V) = nullptr) + void (T::*setter)(int, V) = nullptr) { SGPropertyNode* property = root->getNode(name.c_str(), true); if (!property) { @@ -659,15 +584,17 @@ class FGPropertyManager return; } - if (!property->tie(SGRawValueMethodsIndexed<T,V>(*obj, index, getter, setter), false)) - std::cerr << "Failed to tie property " << name << " to indexed object methods" << std::endl; + if (!property->tie(SGRawValueMethodsIndexed<T,V>(*obj, index, getter, setter), + false)) + std::cerr << "Failed to tie property " << name + << " to indexed object methods" << std::endl; else { - if (setter == 0) property->setAttribute(SGPropertyNode::WRITE, false); - if (getter == 0) property->setAttribute(SGPropertyNode::READ, false); + if (!setter) property->setAttribute(SGPropertyNode::WRITE, false); + if (!getter) property->setAttribute(SGPropertyNode::READ, false); tied_properties.push_back(property); if (FGJSBBase::debug_lvl & 0x20) std::cout << name << std::endl; } - } + } template <class T> simgear::PropertyObject<T> CreatePropertyObject(const std::string &path) diff --git a/src/FDM/JSBSim/input_output/FGXMLElement.cpp b/src/FDM/JSBSim/input_output/FGXMLElement.cpp index 01b5a00cb..094735d8a 100644 --- a/src/FDM/JSBSim/input_output/FGXMLElement.cpp +++ b/src/FDM/JSBSim/input_output/FGXMLElement.cpp @@ -156,6 +156,7 @@ Element::Element(const string& nm) convert["PA"]["LBS/FT2"] = 1.0/convert["LBS/FT2"]["PA"]; // Mass flow convert["KG/MIN"]["LBS/MIN"] = convert["KG"]["LBS"]; + convert["KG/SEC"]["LBS/SEC"] = convert["KG"]["LBS"]; convert ["N/SEC"]["LBS/SEC"] = 0.224808943; convert ["LBS/SEC"]["N/SEC"] = 1.0/convert ["N/SEC"]["LBS/SEC"]; // Fuel Consumption diff --git a/src/FDM/JSBSim/input_output/FGfdmSocket.cpp b/src/FDM/JSBSim/input_output/FGfdmSocket.cpp index ffc30b4a9..5fddce2b3 100644 --- a/src/FDM/JSBSim/input_output/FGfdmSocket.cpp +++ b/src/FDM/JSBSim/input_output/FGfdmSocket.cpp @@ -39,7 +39,7 @@ INCLUDES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ #if defined(_MSC_VER) || defined(__MINGW32__) -#include <WS2tcpip.h> +#include <ws2tcpip.h> #elif defined(__OpenBSD__) #include <sys/types.h> #include <sys/socket.h> @@ -156,7 +156,7 @@ FGfdmSocket::FGfdmSocket(int port, int protocol) connected = false; Protocol = (ProtocolType)protocol; string ProtocolName; - + #if defined(_MSC_VER) || defined(__MINGW32__) if (!LoadWinSockDLL(debug_lvl)) return; #endif @@ -179,7 +179,7 @@ FGfdmSocket::FGfdmSocket(int port, int protocol) if (debug_lvl > 0) cout << "Creating input " << ProtocolName << " socket on port " << port << endl; - + if (sckt != -1) { memset(&scktName, 0, sizeof(struct sockaddr_in)); scktName.sin_family = AF_INET; @@ -275,15 +275,15 @@ string FGfdmSocket::Receive(void) } #endif } - + // this is for FGUDPInputSocket if (sckt >= 0 && Protocol == ptUDP) { struct sockaddr addr; socklen_t fromlen = sizeof addr; num_chars = recvfrom(sckt, buf, sizeof buf, 0, (struct sockaddr*)&addr, &fromlen); - if (num_chars != -1) data.append(buf, num_chars); + if (num_chars != -1) data.append(buf, num_chars); } - + return data; } diff --git a/src/FDM/JSBSim/math/FGFunction.h b/src/FDM/JSBSim/math/FGFunction.h index dcd9940f1..873af1e3f 100644 --- a/src/FDM/JSBSim/math/FGFunction.h +++ b/src/FDM/JSBSim/math/FGFunction.h @@ -826,7 +826,7 @@ protected: void CheckMinArguments(Element* el, unsigned int _min); void CheckMaxArguments(Element* el, unsigned int _max); void CheckOddOrEvenArguments(Element* el, OddEven odd_even); - std::string CreateOutputNode(Element* el, const string& Prefix); + std::string CreateOutputNode(Element* el, const std::string& Prefix); private: std::string Name; diff --git a/src/FDM/JSBSim/math/FGMatrix33.cpp b/src/FDM/JSBSim/math/FGMatrix33.cpp index 051aecf7f..f187d89d1 100644 --- a/src/FDM/JSBSim/math/FGMatrix33.cpp +++ b/src/FDM/JSBSim/math/FGMatrix33.cpp @@ -160,7 +160,7 @@ FGColumnVector3 FGMatrix33::GetEuler(void) const { FGColumnVector3 mEulerAngles; bool GimbalLock = false; - + if (data[6] <= -1.0) { mEulerAngles(2) = 0.5*M_PI; GimbalLock = true; @@ -176,7 +176,7 @@ FGColumnVector3 FGMatrix33::GetEuler(void) const mEulerAngles(1) = atan2(-data[5], data[4]); else mEulerAngles(1) = atan2(data[7], data[8]); - + if (GimbalLock) mEulerAngles(3) = 0.0; else { @@ -436,9 +436,9 @@ FGMatrix33 FGMatrix33::operator/(const double scalar) const Quot.data[2] = data[2] * tmp; Quot.data[5] = data[5] * tmp; Quot.data[8] = data[8] * tmp; - } else { - throw MatrixException{"Attempt to divide by zero in method FGMatrix33::operator/(const double scalar)"}; - } + } else + throw MatrixException{"Attempt to divide by zero in method FGMatrix33::operator/(const double scalar)"}; + return Quot; } @@ -457,9 +457,9 @@ FGMatrix33& FGMatrix33::operator/=(const double scalar) data[2] *= tmp; data[5] *= tmp; data[8] *= tmp; - } else { - throw MatrixException{"Attempt to divide by zero in method FGMatrix33::operator/=(const double scalar)"}; - } + } else + throw MatrixException{"Attempt to divide by zero in method FGMatrix33::operator/=(const double scalar)"}; + return *this; } diff --git a/src/FDM/JSBSim/math/FGMatrix33.h b/src/FDM/JSBSim/math/FGMatrix33.h index 85fde1ea4..0ca03e1bc 100644 --- a/src/FDM/JSBSim/math/FGMatrix33.h +++ b/src/FDM/JSBSim/math/FGMatrix33.h @@ -65,12 +65,10 @@ CLASS DOCUMENTATION DECLARATION: MatrixException %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -// changed by James to inherit std::runtime_error, so that if this -// gets thrown, we can actually catch it. class MatrixException : public std::runtime_error { public: - MatrixException(const std::string& msg) : std::runtime_error{msg} { } + MatrixException(const std::string& msg) : std::runtime_error{msg} { } }; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/src/FDM/JSBSim/math/FGParameterValue.h b/src/FDM/JSBSim/math/FGParameterValue.h index 733608ab3..cbb2ab9a4 100644 --- a/src/FDM/JSBSim/math/FGParameterValue.h +++ b/src/FDM/JSBSim/math/FGParameterValue.h @@ -71,7 +71,7 @@ public: << "The element <" << el->GetName() << "> must either contain a value number or a property name." << endl; - throw invalid_argument("Illegal argument"); + throw invalid_argument("FGParameterValue: Illegal argument defining: " + el->GetName()); } Construct(value, pm); diff --git a/src/FDM/JSBSim/math/FGPropertyValue.cpp b/src/FDM/JSBSim/math/FGPropertyValue.cpp index df1b7ea51..91473f0d3 100644 --- a/src/FDM/JSBSim/math/FGPropertyValue.cpp +++ b/src/FDM/JSBSim/math/FGPropertyValue.cpp @@ -29,8 +29,9 @@ Purpose: Stores property values INCLUDES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ +#include <assert.h> + #include "FGPropertyValue.h" -#include "input_output/FGPropertyManager.h" namespace JSBSim { @@ -80,6 +81,9 @@ double FGPropertyValue::GetValue(void) const void FGPropertyValue::SetValue(double value) { + // SetValue() ignores the Sign flag. So make sure it is never called with a + // negative sign. + assert(Sign == 1); GetNode()->setDoubleValue(value); } diff --git a/src/FDM/JSBSim/models/FGBuoyantForces.cpp b/src/FDM/JSBSim/models/FGBuoyantForces.cpp index b9474a9e7..ec1dfe729 100644 --- a/src/FDM/JSBSim/models/FGBuoyantForces.cpp +++ b/src/FDM/JSBSim/models/FGBuoyantForces.cpp @@ -241,20 +241,19 @@ string FGBuoyantForces::GetBuoyancyValues(const string& delimeter) void FGBuoyantForces::bind(void) { - typedef double (FGBuoyantForces::*PGF)(int) const; - typedef void (FGBuoyantForces::*PSF)(int, double); + using PSF = void (FGBuoyantForces::*)(int, double); PropertyManager->Tie("moments/l-buoyancy-lbsft", this, eL, - (PGF)&FGBuoyantForces::GetMoments, (PSF)nullptr); + &FGBuoyantForces::GetMoments, (PSF)nullptr); PropertyManager->Tie("moments/m-buoyancy-lbsft", this, eM, - (PGF)&FGBuoyantForces::GetMoments, (PSF)nullptr); + &FGBuoyantForces::GetMoments, (PSF)nullptr); PropertyManager->Tie("moments/n-buoyancy-lbsft", this, eN, - (PGF)&FGBuoyantForces::GetMoments, (PSF)nullptr); + &FGBuoyantForces::GetMoments, (PSF)nullptr); PropertyManager->Tie("forces/fbx-buoyancy-lbs", this, eX, - (PGF)&FGBuoyantForces::GetForces, (PSF)nullptr); + &FGBuoyantForces::GetForces, (PSF)nullptr); PropertyManager->Tie("forces/fby-buoyancy-lbs", this, eY, - (PGF)&FGBuoyantForces::GetForces, (PSF)nullptr); + &FGBuoyantForces::GetForces, (PSF)nullptr); PropertyManager->Tie("forces/fbz-buoyancy-lbs", this, eZ, - (PGF)&FGBuoyantForces::GetForces, (PSF)nullptr); + &FGBuoyantForces::GetForces, (PSF)nullptr); } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/src/FDM/JSBSim/models/FGGasCell.cpp b/src/FDM/JSBSim/models/FGGasCell.cpp index ebc19e8e4..3aecd5c05 100644 --- a/src/FDM/JSBSim/models/FGGasCell.cpp +++ b/src/FDM/JSBSim/models/FGGasCell.cpp @@ -195,7 +195,7 @@ FGGasCell::FGGasCell(FGFDMExec* exec, Element* el, unsigned int num, property_name = base_property_name + "/max_volume-ft3"; PropertyManager->Tie( property_name.c_str(), &MaxVolume); - PropertyManager->GetNode()->SetWritable( property_name); + PropertyManager->GetNode()->SetWritable( property_name, false ); property_name = base_property_name + "/temp-R"; PropertyManager->Tie( property_name.c_str(), &Temperature); property_name = base_property_name + "/pressure-psf"; @@ -623,7 +623,7 @@ FGBallonet::FGBallonet(FGFDMExec* exec, Element* el, unsigned int num, property_name = base_property_name + "/max_volume-ft3"; PropertyManager->Tie( property_name, &MaxVolume); - PropertyManager->GetNode()->SetWritable( property_name); + PropertyManager->GetNode()->SetWritable( property_name, false ); property_name = base_property_name + "/temp-R"; PropertyManager->Tie( property_name, &Temperature); diff --git a/src/FDM/JSBSim/models/FGPropulsion.cpp b/src/FDM/JSBSim/models/FGPropulsion.cpp index 6c25b3205..685498b0a 100644 --- a/src/FDM/JSBSim/models/FGPropulsion.cpp +++ b/src/FDM/JSBSim/models/FGPropulsion.cpp @@ -802,6 +802,7 @@ void FGPropulsion::bind(void) { typedef double (FGPropulsion::*PMF)(int) const; typedef int (FGPropulsion::*iPMF)(void) const; + typedef bool (FGPropulsion::*bPMF)(void) const; IsBound = true; PropertyManager->Tie("propulsion/set-running", this, (iPMF)0, &FGPropulsion::InitRunning); @@ -827,6 +828,7 @@ void FGPropulsion::bind(void) TotalOxidizerQuantity = PropertyManager->CreatePropertyObject<double>("propulsion/total-oxidizer-lbs"); refuel = PropertyManager->CreatePropertyObject<bool>("propulsion/refuel"); dump = PropertyManager->CreatePropertyObject<bool>("propulsion/fuel_dump"); + PropertyManager->Tie("propulsion/fuel_freeze", this, (bPMF)nullptr, &FGPropulsion::SetFuelFreeze); } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/src/FDM/JSBSim/models/flight_control/FGLinearActuator.cpp b/src/FDM/JSBSim/models/flight_control/FGLinearActuator.cpp index 07e8e292d..1f5223585 100644 --- a/src/FDM/JSBSim/models/flight_control/FGLinearActuator.cpp +++ b/src/FDM/JSBSim/models/flight_control/FGLinearActuator.cpp @@ -1,5 +1,5 @@ /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - * + * Module: FGLinearActuator.cpp Author: Adriano Bassignana Date started: 2019-01-03 @@ -43,11 +43,11 @@ INCLUDES using namespace std; namespace JSBSim { - + /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% CLASS IMPLEMENTATION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ - + FGLinearActuator::FGLinearActuator(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, element) { @@ -141,7 +141,7 @@ FGLinearActuator::FGLinearActuator(FGFCS* fcs, Element* element) Debug(0); } - + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FGLinearActuator::~FGLinearActuator() @@ -184,16 +184,11 @@ bool FGLinearActuator::Run(void ) } if ((versus == 0) || (versus == direction)) { inputMem = Input; - if (direction != 0) { - if (abs(inputDelta) >= (module*rate)) { - if (direction > 0) { - countSpin++; - direction = 0; - } else if (direction < 0) { - countSpin--; - direction = 0; - } - } + if (abs(inputDelta) >= (module*rate)) { + if (inputDelta < 0) + countSpin++; + else + countSpin--; } } else if ((versus != 0) && (direction != 0) && (versus != direction)) { inputLast += inputDelta; @@ -207,7 +202,7 @@ bool FGLinearActuator::Run(void ) } if (lag > 0.0) { - double input = Output; + double input = Output; Output = ca * (input + previousLagInput) + previousLagOutput * cb; previousLagInput = input; previousLagOutput = Output; diff --git a/src/FDM/JSBSim/models/flight_control/FGMagnetometer.cpp b/src/FDM/JSBSim/models/flight_control/FGMagnetometer.cpp index bee2e7b6e..14218bde0 100644 --- a/src/FDM/JSBSim/models/flight_control/FGMagnetometer.cpp +++ b/src/FDM/JSBSim/models/flight_control/FGMagnetometer.cpp @@ -75,7 +75,7 @@ FGMagnetometer::FGMagnetometer(FGFCS* fcs, Element* element) time_t rawtime; time( &rawtime ); struct tm ptm; - #ifdef _MSC_VER + #if defined(_MSC_VER) || defined(__MINGW32__) gmtime_s(&ptm, &rawtime); #else gmtime_r(&rawtime, &ptm); diff --git a/src/FDM/JSBSim/models/propulsion/FGElectric.cpp b/src/FDM/JSBSim/models/propulsion/FGElectric.cpp index f43506407..06d01a989 100644 --- a/src/FDM/JSBSim/models/propulsion/FGElectric.cpp +++ b/src/FDM/JSBSim/models/propulsion/FGElectric.cpp @@ -90,12 +90,12 @@ void FGElectric::Calculate(void) if (Thruster->GetType() == FGThruster::ttPropeller) { ((FGPropeller*)Thruster)->SetAdvance(in.PropAdvance[EngineNumber]); ((FGPropeller*)Thruster)->SetFeather(in.PropFeather[EngineNumber]); - } + } RPM = Thruster->GetRPM() * Thruster->GetGearRatio(); HP = PowerWatts * in.ThrottlePos[EngineNumber] / hptowatts; - + LoadThrusterInputs(); // Filters out negative powers when the propeller is not rotating. double power = HP * hptoftlbssec; diff --git a/src/FDM/JSBSim/models/propulsion/FGPiston.cpp b/src/FDM/JSBSim/models/propulsion/FGPiston.cpp index edcbead4a..38813b556 100644 --- a/src/FDM/JSBSim/models/propulsion/FGPiston.cpp +++ b/src/FDM/JSBSim/models/propulsion/FGPiston.cpp @@ -124,7 +124,7 @@ FGPiston::FGPiston(FGFDMExec* exec, Element* el, int engine_number, struct Input bTakeoffBoost = false; TakeoffBoost = 0.0; // Default to no extra takeoff-boost BoostLossFactor = 0.0; // Default to free boost - + int i; for (i=0; i<FG_MAX_BOOST_SPEEDS; i++) { RatedBoost[i] = 0.0; @@ -142,7 +142,7 @@ FGPiston::FGPiston(FGFDMExec* exec, Element* el, int engine_number, struct Input // Read inputs from engine data file where present. - if (el->FindElement("minmp")) + if (el->FindElement("minmp")) MinManifoldPressure_inHg = el->FindElementValueAsNumberConvertTo("minmp","INHG"); if (el->FindElement("maxmp")) MaxManifoldPressure_inHg = el->FindElementValueAsNumberConvertTo("maxmp","INHG"); @@ -309,7 +309,7 @@ FGPiston::FGPiston(FGFDMExec* exec, Element* el, int engine_number, struct Input Z_airbox = (standard_pressure *Ze / maxMAP) - Ze; // impedence of airbox } // Constant for Throttle impedence - Z_throttle=(PeakMeanPistonSpeed_fps/((IdleRPM * Stroke) / 360))*(standard_pressure/minMAP - 1) - Z_airbox; + Z_throttle=(PeakMeanPistonSpeed_fps/((IdleRPM * Stroke) / 360))*(standard_pressure/minMAP - 1) - Z_airbox; // Z_throttle=(MaxRPM/IdleRPM )*(standard_pressure/minMAP+2); // Constant for Throttle impedence // Default tables if not provided in the configuration file @@ -518,9 +518,7 @@ void FGPiston::Calculate(void) } LoadThrusterInputs(); - // Filters out negative powers. - // TODO: static_friction_HP should not be taken into account while the engine - // is not started. + // Filters out negative powers when the propeller is not rotating. double power = HP * hptoftlbssec; if (RPM <= 0.1) power = max(power, 0.0); Thruster->Calculate(power); @@ -533,7 +531,7 @@ void FGPiston::Calculate(void) double FGPiston::CalcFuelNeed(void) { FuelExpended = FuelFlowRate * in.TotalDeltaT; - if (!Starved) FuelUsedLbs += FuelExpended; + if (!Starved) FuelUsedLbs += FuelExpended; return FuelExpended; } @@ -594,7 +592,7 @@ void FGPiston::doEngineStartup(void) if ( Running ) { if (!spark || !fuel) Running = false; if (RPM < IdleRPM*0.8 ) Running = false; - } else { // !Running + } else { // !Running if ( spark && fuel) { // start the engine if revs high enough if (RPM > IdleRPM*0.8) // This allows us to in-air start Running = true; // when windmilling @@ -705,7 +703,7 @@ void FGPiston::doMAP(void) } else { BoostLossHP = 0; } - + // And set the value in American units as well ManifoldPressure_inHg = MAP / inhgtopa; } @@ -800,14 +798,14 @@ void FGPiston::doEnginePower(void) } else { // Power output when the engine is not running double torque, k_torque, rpm; // Convienience term for use in the calculations - + rpm = RPM < 1.0 ? 1.0 : RPM; if (Cranking) { if(RPM<StarterRPM) k_torque = 1.0-RPM/(StarterRPM); else k_torque = 0; torque = StarterTorque*k_torque*StarterGain; IndicatedHorsePower = torque * rpm / 5252; - } + } } // Constant is (1/2) * 60 * 745.7 diff --git a/src/FDM/JSBSim/models/propulsion/FGTurboProp.cpp b/src/FDM/JSBSim/models/propulsion/FGTurboProp.cpp index 5aba0fcd6..4cad50b40 100644 --- a/src/FDM/JSBSim/models/propulsion/FGTurboProp.cpp +++ b/src/FDM/JSBSim/models/propulsion/FGTurboProp.cpp @@ -291,7 +291,10 @@ void FGTurboProp::Calculate(void) } LoadThrusterInputs(); - Thruster->Calculate(HP * hptoftlbssec); + // Filters out negative powers when the propeller is not rotating. + double power = HP * hptoftlbssec; + if (RPM <= 0.1) power = max(power, 0.0); + Thruster->Calculate(power); RunPostFunctions(); }