Sync'ed with JSBSim v1.1.8
- Always set useDefault to false when calling SGPropertyNode::tie() - Mass flows can now be specified using SI unit (kg/s) - Add a new property propulsion/fuel_freeze to freeze fuel consumption. - Add a new flag DONT_EXECUTE_RUN_IC that can be specified to FGFDMExec::ResetToInitialConditions. When specified, this flag avoid calling FGFDMExec::RunIC when executing FGFDMExec::ResetToInitialConditions. - Fix a bug in <linear_actuator> that resulted in erroneous output values when the input was oscillating around the zero value. - Add an assert that forbids to set the value of FGPropertyValue when the property was specified with a minus sign. - Fix the compatibility with recent versions of MinGW64 - Fix ws2tcpip.h casing for compilation on case sensitive OS. - Improve the templating of FGPropertyManager::Tie(). - Expand FGParameterValue exception message (James Turner) - TurboProp: Filters out negative powers when the propeller is not rotating
This commit is contained in:
parent
364be50967
commit
81313f4aa2
19 changed files with 124 additions and 282 deletions
|
@ -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();
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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} { }
|
||||
};
|
||||
|
||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue