latest changes for JSBSim (1.0 prerelease)
This commit is contained in:
parent
21a8522160
commit
cb435814c1
31 changed files with 332 additions and 176 deletions
|
@ -35,6 +35,8 @@ HISTORY
|
||||||
INCLUDES
|
INCLUDES
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#define BASE
|
||||||
|
|
||||||
#include "FGJSBBase.h"
|
#include "FGJSBBase.h"
|
||||||
|
|
||||||
namespace JSBSim {
|
namespace JSBSim {
|
||||||
|
|
|
@ -45,6 +45,8 @@ INCLUDES
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
|
#include "input_output/string_utilities.h"
|
||||||
|
|
||||||
using std::fabs;
|
using std::fabs;
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
|
|
|
@ -184,7 +184,7 @@ bool FGTrim::RemoveState( State state ) {
|
||||||
ta=*iAxes;
|
ta=*iAxes;
|
||||||
if( ta->GetStateType() == state ) {
|
if( ta->GetStateType() == state ) {
|
||||||
delete ta;
|
delete ta;
|
||||||
TrimAxes.erase(iAxes);
|
iAxes = TrimAxes.erase(iAxes);
|
||||||
result=true;
|
result=true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@ INCLUDES
|
||||||
|
|
||||||
#include "FGXMLParse.h"
|
#include "FGXMLParse.h"
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
#include "input_output/string_utilities.h"
|
||||||
|
|
||||||
namespace JSBSim {
|
namespace JSBSim {
|
||||||
|
|
||||||
|
@ -114,26 +115,9 @@ void FGXMLParse::startElement (const char * name, const XMLAttributes &atts)
|
||||||
|
|
||||||
void FGXMLParse::endElement (const char * name)
|
void FGXMLParse::endElement (const char * name)
|
||||||
{
|
{
|
||||||
string local_work_string;
|
|
||||||
|
|
||||||
while (!working_string.empty()) {
|
|
||||||
// clear leading newlines and spaces
|
|
||||||
string::size_type pos = working_string.find_first_not_of( " \n");
|
|
||||||
if (pos > 0)
|
|
||||||
working_string.erase(0, pos);
|
|
||||||
|
|
||||||
// remove spaces (only) from end of string
|
|
||||||
pos = working_string.find_last_not_of( " ");
|
|
||||||
if (pos != string::npos)
|
|
||||||
working_string.erase( ++pos);
|
|
||||||
|
|
||||||
if (!working_string.empty()) {
|
if (!working_string.empty()) {
|
||||||
pos = working_string.find("\n");
|
vector <string> work_strings = split(working_string, '\n');
|
||||||
if (pos != string::npos) local_work_string = working_string.substr(0,pos);
|
for (int i=0; i<work_strings.size(); i++) current_element->AddData(work_strings[i]);
|
||||||
else local_work_string = working_string;
|
|
||||||
current_element->AddData(local_work_string);
|
|
||||||
working_string.erase(0, pos);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
current_element = current_element->GetParent();
|
current_element = current_element->GetParent();
|
||||||
|
|
|
@ -63,7 +63,7 @@ FGfdmSocket::FGfdmSocket(string address, int port, int protocol)
|
||||||
else cout << "Winsock DLL not initialized ..." << endl;
|
else cout << "Winsock DLL not initialized ..." << endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (address.find_first_not_of("0123456789.",0) != address.npos) {
|
if (!is_number(address)) {
|
||||||
if ((host = gethostbyname(address.c_str())) == NULL) {
|
if ((host = gethostbyname(address.c_str())) == NULL) {
|
||||||
cout << "Could not get host net address by name..." << endl;
|
cout << "Could not get host net address by name..." << endl;
|
||||||
}
|
}
|
||||||
|
@ -121,7 +121,7 @@ FGfdmSocket::FGfdmSocket(string address, int port)
|
||||||
cout << "Host name... " << address << ", Port... " << port << "." << endl;
|
cout << "Host name... " << address << ", Port... " << port << "." << endl;
|
||||||
cout << "Host name... (char) " << address.c_str() << "." << endl;
|
cout << "Host name... (char) " << address.c_str() << "." << endl;
|
||||||
|
|
||||||
if (address.find_first_not_of("0123456789.",0) != address.npos) {
|
if (!is_number(address)) {
|
||||||
if ((host = gethostbyname(address.c_str())) == NULL) {
|
if ((host = gethostbyname(address.c_str())) == NULL) {
|
||||||
cout << "Could not get host net address by name..." << endl;
|
cout << "Could not get host net address by name..." << endl;
|
||||||
}
|
}
|
||||||
|
|
144
src/FDM/JSBSim/input_output/string_utilities.h
Normal file
144
src/FDM/JSBSim/input_output/string_utilities.h
Normal file
|
@ -0,0 +1,144 @@
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
Header: string_utilities.h
|
||||||
|
Author: Jon S. Berndt
|
||||||
|
Date started: 06/01/09
|
||||||
|
|
||||||
|
------------- Copyright (C) 2009 Jon S. Berndt (jsb@hal-pc.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.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
Further information about the GNU Lesser General Public License can also be found on
|
||||||
|
the world wide web at http://www.gnu.org.
|
||||||
|
|
||||||
|
HISTORY
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
06/01/09 JSB Created
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
SENTRY
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#ifndef STRINGUTILS_H
|
||||||
|
#define STRINGUTILS_H
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
INCLUDES
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
DEFINITIONS
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#define ID_STRINGUTILS "$Id$"
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
FORWARD DECLARATIONS
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
CLASS DOCUMENTATION
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
|
||||||
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
CLASS DECLARATION
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
#if !defined(BASE)
|
||||||
|
extern string& trim_left(string& str);
|
||||||
|
extern string& trim_right(string& str);
|
||||||
|
extern string& trim(string& str);
|
||||||
|
extern string& to_upper(string& str);
|
||||||
|
extern string& to_lower(string& str);
|
||||||
|
extern bool is_number(string& str);
|
||||||
|
vector <string> split(string str, char d);
|
||||||
|
#else
|
||||||
|
|
||||||
|
string& trim_left(string& str)
|
||||||
|
{
|
||||||
|
while ( !isgraph(str[0]) ) {
|
||||||
|
str = str.erase(0,1);
|
||||||
|
if (str.size() == 0) break;
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
string& trim_right(string& str)
|
||||||
|
{
|
||||||
|
while (!isgraph(str[str.size()-1])) {
|
||||||
|
str = str.erase(str.size()-1,1);
|
||||||
|
if (str.size() == 0) break;
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
string& trim(string& str)
|
||||||
|
{
|
||||||
|
if (str.size() == 0) return str;
|
||||||
|
string temp_str = trim_right(str);
|
||||||
|
return str = trim_left(temp_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
string& to_upper(string& str)
|
||||||
|
{
|
||||||
|
for (int i=0; i<str.size(); i++) str[i] = toupper(str[i]);
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
string& to_lower(string& str)
|
||||||
|
{
|
||||||
|
for (int i=0; i<str.size(); i++) str[i] = tolower(str[i]);
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_number(string& str)
|
||||||
|
{
|
||||||
|
return (str.find_first_not_of("+-.0123456789Ee") == string::npos);
|
||||||
|
}
|
||||||
|
|
||||||
|
vector <string> split(string str, char d)
|
||||||
|
{
|
||||||
|
vector <string> str_array;
|
||||||
|
int index=0;
|
||||||
|
string temp = "";
|
||||||
|
|
||||||
|
trim(str);
|
||||||
|
index = str.find(d);
|
||||||
|
while (index != string::npos) {
|
||||||
|
temp = str.substr(0,index);
|
||||||
|
trim(temp);
|
||||||
|
if (temp.size() > 0) str_array.push_back(temp);
|
||||||
|
str = str.erase(0,index+1);
|
||||||
|
index = str.find(d);
|
||||||
|
}
|
||||||
|
if (str.size() > 0) {
|
||||||
|
temp = trim(str);
|
||||||
|
if (temp.size() > 0) str_array.push_back(temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
return str_array;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
#endif
|
|
@ -35,6 +35,7 @@ INCLUDES
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
#include "FGCondition.h"
|
#include "FGCondition.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace JSBSim {
|
namespace JSBSim {
|
||||||
|
|
||||||
|
@ -94,6 +95,7 @@ FGCondition::FGCondition(string test, FGPropertyManager* PropertyManager) :
|
||||||
PropertyManager(PropertyManager), isGroup(false)
|
PropertyManager(PropertyManager), isGroup(false)
|
||||||
{
|
{
|
||||||
string property1, property2, compare_string;
|
string property1, property2, compare_string;
|
||||||
|
vector <string> test_strings;
|
||||||
|
|
||||||
InitializeConditionals();
|
InitializeConditionals();
|
||||||
|
|
||||||
|
@ -103,20 +105,21 @@ FGCondition::FGCondition(string test, FGPropertyManager* PropertyManager) :
|
||||||
Logic = elUndef;
|
Logic = elUndef;
|
||||||
conditions.clear();
|
conditions.clear();
|
||||||
|
|
||||||
unsigned int start = 0, end = 0;
|
test_strings = split(test, ' ');
|
||||||
start = test.find_first_not_of(" ");
|
if (test_strings.size() == 3) {
|
||||||
end = test.find_first_of(" ", start+1);
|
property1 = test_strings[0];
|
||||||
property1 = test.substr(start,end-start);
|
conditional = test_strings[1];
|
||||||
start = test.find_first_not_of(" ",end);
|
property2 = test_strings[2];
|
||||||
end = test.find_first_of(" ",start+1);
|
} else {
|
||||||
conditional = test.substr(start,end-start);
|
cerr << endl << " Conditional test is invalid: \"" << test
|
||||||
start = test.find_first_not_of(" ",end);
|
<< "\" has " << test_strings.size() << " elements in the "
|
||||||
end = test.find_first_of(" ",start+1);
|
<< "test condition." << endl;
|
||||||
property2 = test.substr(start,end-start);
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
TestParam1 = PropertyManager->GetNode(property1, true);
|
TestParam1 = PropertyManager->GetNode(property1, true);
|
||||||
Comparison = mComparison[conditional];
|
Comparison = mComparison[conditional];
|
||||||
if (property2.find_first_not_of("-.0123456789eE") == string::npos) {
|
if (is_number(property2)) {
|
||||||
TestValue = atof(property2.c_str());
|
TestValue = atof(property2.c_str());
|
||||||
} else {
|
} else {
|
||||||
TestParam2 = PropertyManager->GetNode(property2, true);
|
TestParam2 = PropertyManager->GetNode(property2, true);
|
||||||
|
|
|
@ -168,6 +168,26 @@ void FGLocation::SetPosition(double lon, double lat, double radius)
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGLocation::SetPositionGeodetic(double lon, double lat, double height)
|
||||||
|
{
|
||||||
|
mCacheValid = false;
|
||||||
|
|
||||||
|
mGeodLat = lat;
|
||||||
|
mLon = lon;
|
||||||
|
GeodeticAltitude = height;
|
||||||
|
|
||||||
|
initial_longitude = mLon;
|
||||||
|
|
||||||
|
double RN = a / sqrt(1.0 - e2*sin(mGeodLat)*sin(mGeodLat));
|
||||||
|
|
||||||
|
mECLoc(eX) = (RN + GeodeticAltitude)*cos(mGeodLat)*cos(mLon);
|
||||||
|
mECLoc(eY) = (RN + GeodeticAltitude)*cos(mGeodLat)*sin(mLon);
|
||||||
|
mECLoc(eZ) = ((1 - e2)*RN + GeodeticAltitude)*sin(mGeodLat);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
void FGLocation::SetEllipse(double semimajor, double semiminor)
|
void FGLocation::SetEllipse(double semimajor, double semiminor)
|
||||||
{
|
{
|
||||||
mCacheValid = false;
|
mCacheValid = false;
|
||||||
|
|
|
@ -233,6 +233,12 @@ public:
|
||||||
@param radius distance from center of earth to vehicle in feet*/
|
@param radius distance from center of earth to vehicle in feet*/
|
||||||
void SetPosition(double lon, double lat, double radius);
|
void SetPosition(double lon, double lat, double radius);
|
||||||
|
|
||||||
|
/** Sets the longitude, latitude and the distance above the reference ellipsoid.
|
||||||
|
@param lon longitude in radians
|
||||||
|
@param lat GEODETIC latitude in radians
|
||||||
|
@param height distance above the reference ellipsoid to vehicle in feet*/
|
||||||
|
void SetPositionGeodetic(double lon, double lat, double height);
|
||||||
|
|
||||||
/** Sets the semimajor and semiminor axis lengths for this planet.
|
/** Sets the semimajor and semiminor axis lengths for this planet.
|
||||||
The eccentricity and flattening are calculated from the semimajor
|
The eccentricity and flattening are calculated from the semimajor
|
||||||
and semiminor axis lengths */
|
and semiminor axis lengths */
|
||||||
|
|
|
@ -318,6 +318,8 @@ bool FGAerodynamics::Load(Element *element)
|
||||||
document = element;
|
document = element;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FGModel::Load(element); // Perform base class Load
|
||||||
|
|
||||||
DetermineAxisSystem(); // Detemine if Lift/Side/Drag, etc. is used.
|
DetermineAxisSystem(); // Detemine if Lift/Side/Drag, etc. is used.
|
||||||
|
|
||||||
Debug(2);
|
Debug(2);
|
||||||
|
|
|
@ -152,6 +152,8 @@ bool FGAircraft::Load(Element* el)
|
||||||
string element_name;
|
string element_name;
|
||||||
Element* element;
|
Element* element;
|
||||||
|
|
||||||
|
FGModel::Load(el);
|
||||||
|
|
||||||
if (el->FindElement("wingarea"))
|
if (el->FindElement("wingarea"))
|
||||||
WingArea = el->FindElementValueAsNumberConvertTo("wingarea", "FT2");
|
WingArea = el->FindElementValueAsNumberConvertTo("wingarea", "FT2");
|
||||||
if (el->FindElement("wingspan"))
|
if (el->FindElement("wingspan"))
|
||||||
|
|
|
@ -72,10 +72,6 @@ FGBuoyantForces::~FGBuoyantForces()
|
||||||
for (unsigned int i=0; i<Cells.size(); i++) delete Cells[i];
|
for (unsigned int i=0; i<Cells.size(); i++) delete Cells[i];
|
||||||
Cells.clear();
|
Cells.clear();
|
||||||
|
|
||||||
for (unsigned int i=0; i<interface_properties.size(); i++)
|
|
||||||
delete interface_properties[i];
|
|
||||||
interface_properties.clear();
|
|
||||||
|
|
||||||
Debug(1);
|
Debug(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,28 +123,7 @@ bool FGBuoyantForces::Load(Element *element)
|
||||||
document = element;
|
document = element;
|
||||||
}
|
}
|
||||||
|
|
||||||
Element *property_element = document->FindElement("property");
|
FGModel::Load(element); // Perform base class Load
|
||||||
if (property_element)
|
|
||||||
cout << endl << " Declared properties" << endl << endl;
|
|
||||||
while (property_element) {
|
|
||||||
string interface_property_string = property_element->GetDataLine();
|
|
||||||
|
|
||||||
if (PropertyManager->HasNode(interface_property_string)) {
|
|
||||||
cout << " Property " << interface_property_string <<
|
|
||||||
" is already defined." << endl;
|
|
||||||
} else {
|
|
||||||
double value=0.0;
|
|
||||||
if ( ! property_element->GetAttributeValue("value").empty())
|
|
||||||
value = property_element->GetAttributeValueAsNumber("value");
|
|
||||||
interface_properties.push_back(new double(value));
|
|
||||||
interface_property_string = property_element->GetDataLine();
|
|
||||||
PropertyManager->Tie(interface_property_string,
|
|
||||||
interface_properties.back());
|
|
||||||
cout << " " << interface_property_string <<
|
|
||||||
" (initial value: " << value << ")" << endl;
|
|
||||||
}
|
|
||||||
property_element = document->FindNextElement("property");
|
|
||||||
}
|
|
||||||
|
|
||||||
gas_cell_element = document->FindElement("gas_cell");
|
gas_cell_element = document->FindElement("gas_cell");
|
||||||
while (gas_cell_element) {
|
while (gas_cell_element) {
|
||||||
|
|
|
@ -169,8 +169,6 @@ private:
|
||||||
FGColumnVector3 vGasCellXYZ;
|
FGColumnVector3 vGasCellXYZ;
|
||||||
FGColumnVector3 vXYZgasCell_arm;
|
FGColumnVector3 vXYZgasCell_arm;
|
||||||
|
|
||||||
vector <double*> interface_properties;
|
|
||||||
|
|
||||||
bool NoneDefined;
|
bool NoneDefined;
|
||||||
|
|
||||||
void bind(void);
|
void bind(void);
|
||||||
|
|
|
@ -66,27 +66,10 @@ FGExternalReactions::FGExternalReactions(FGFDMExec* fdmex) : FGModel(fdmex)
|
||||||
|
|
||||||
bool FGExternalReactions::Load(Element* el)
|
bool FGExternalReactions::Load(Element* el)
|
||||||
{
|
{
|
||||||
|
FGModel::Load(el); // Call the base class Load() function to load interface properties.
|
||||||
|
|
||||||
Debug(2);
|
Debug(2);
|
||||||
|
|
||||||
// Interface properties are all stored in the interface properties array.
|
|
||||||
// ToDo: Interface properties should not be created if they already exist.
|
|
||||||
// A check should be done prior to creation. This ought to make it easier
|
|
||||||
// to work with FlightGear, where some properties used in definitions may
|
|
||||||
// already have been created, but would not be seen when JSBSim is run
|
|
||||||
// in standalone mode.
|
|
||||||
|
|
||||||
Element* property_element;
|
|
||||||
property_element = el->FindElement("property");
|
|
||||||
while (property_element) {
|
|
||||||
double value=0.0;
|
|
||||||
if ( ! property_element->GetAttributeValue("value").empty())
|
|
||||||
value = property_element->GetAttributeValueAsNumber("value");
|
|
||||||
interface_properties.push_back(new double(value));
|
|
||||||
string interface_property_string = property_element->GetDataLine();
|
|
||||||
PropertyManager->Tie(interface_property_string, interface_properties.back());
|
|
||||||
property_element = el->FindNextElement("property");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse force elements
|
// Parse force elements
|
||||||
|
|
||||||
int index=0;
|
int index=0;
|
||||||
|
@ -107,8 +90,7 @@ FGExternalReactions::~FGExternalReactions()
|
||||||
{
|
{
|
||||||
for (unsigned int i=0; i<Forces.size(); i++) delete Forces[i];
|
for (unsigned int i=0; i<Forces.size(); i++) delete Forces[i];
|
||||||
Forces.clear();
|
Forces.clear();
|
||||||
for (unsigned int i=0; i<interface_properties.size(); i++) delete interface_properties[i];
|
|
||||||
interface_properties.clear();
|
|
||||||
Debug(1);
|
Debug(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -158,7 +158,6 @@ private:
|
||||||
unsigned int numForces;
|
unsigned int numForces;
|
||||||
FGColumnVector3 vTotalForces;
|
FGColumnVector3 vTotalForces;
|
||||||
FGColumnVector3 vTotalMoments;
|
FGColumnVector3 vTotalMoments;
|
||||||
vector <double*> interface_properties;
|
|
||||||
|
|
||||||
bool NoneDefined;
|
bool NoneDefined;
|
||||||
|
|
||||||
|
|
|
@ -101,8 +101,6 @@ FGFCS::~FGFCS()
|
||||||
|
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
for (i=0;i<sensors.size();i++) delete sensors[i];
|
|
||||||
sensors.clear();
|
|
||||||
for (i=0;i<APComponents.size();i++) delete APComponents[i];
|
for (i=0;i<APComponents.size();i++) delete APComponents[i];
|
||||||
APComponents.clear();
|
APComponents.clear();
|
||||||
for (i=0;i<FCSComponents.size();i++) delete FCSComponents[i];
|
for (i=0;i<FCSComponents.size();i++) delete FCSComponents[i];
|
||||||
|
@ -110,8 +108,6 @@ FGFCS::~FGFCS()
|
||||||
for (i=0;i<Systems.size();i++) delete Systems[i];
|
for (i=0;i<Systems.size();i++) delete Systems[i];
|
||||||
Systems.clear();
|
Systems.clear();
|
||||||
|
|
||||||
for (unsigned int i=0; i<interface_properties.size(); i++) delete interface_properties[i];
|
|
||||||
interface_properties.clear();
|
|
||||||
|
|
||||||
Debug(1);
|
Debug(1);
|
||||||
}
|
}
|
||||||
|
@ -208,10 +204,6 @@ bool FGFCS::Run(void)
|
||||||
SteerPosDeg[i] = gear->GetDefaultSteerAngle( GetDsCmd() );
|
SteerPosDeg[i] = gear->GetDefaultSteerAngle( GetDsCmd() );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cycle through the sensor, systems, autopilot, and flight control components
|
|
||||||
// Execute Sensors
|
|
||||||
for (i=0; i<sensors.size(); i++) sensors[i]->Run();
|
|
||||||
|
|
||||||
// Execute Systems in order
|
// Execute Systems in order
|
||||||
for (i=0; i<Systems.size(); i++) Systems[i]->Run();
|
for (i=0; i<Systems.size(); i++) Systems[i]->Run();
|
||||||
|
|
||||||
|
@ -527,7 +519,7 @@ bool FGFCS::Load(Element* el, SystemType systype)
|
||||||
{
|
{
|
||||||
string name, file, fname="", interface_property_string, parent_name;
|
string name, file, fname="", interface_property_string, parent_name;
|
||||||
vector <FGFCSComponent*> *Components;
|
vector <FGFCSComponent*> *Components;
|
||||||
Element *component_element, *property_element, *sensor_element;
|
Element *component_element, *sensor_element;
|
||||||
Element *channel_element;
|
Element *channel_element;
|
||||||
|
|
||||||
Components=0;
|
Components=0;
|
||||||
|
@ -575,33 +567,15 @@ bool FGFCS::Load(Element* el, SystemType systype)
|
||||||
|
|
||||||
if (document->GetName() == "flight_control") bindModel();
|
if (document->GetName() == "flight_control") bindModel();
|
||||||
|
|
||||||
// Interface properties from any autopilot, flight control, or other system are
|
FGModel::Load(document); // Load interface properties from document
|
||||||
// all stored in the interface properties array.
|
|
||||||
|
|
||||||
property_element = document->FindElement("property");
|
|
||||||
if (property_element && debug_lvl > 0) cout << endl << " Declared properties" << endl << endl;
|
|
||||||
while (property_element) {
|
|
||||||
interface_property_string = property_element->GetDataLine();
|
|
||||||
if (PropertyManager->HasNode(interface_property_string)) {
|
|
||||||
cerr << " Property " << interface_property_string << " is already defined." << endl;
|
|
||||||
} else {
|
|
||||||
double value=0.0;
|
|
||||||
if ( ! property_element->GetAttributeValue("value").empty())
|
|
||||||
value = property_element->GetAttributeValueAsNumber("value");
|
|
||||||
interface_properties.push_back(new double(value));
|
|
||||||
interface_property_string = property_element->GetDataLine();
|
|
||||||
PropertyManager->Tie(interface_property_string, interface_properties.back());
|
|
||||||
if (debug_lvl > 0)
|
|
||||||
cout << " " << interface_property_string << " (initial value: " << value << ")" << endl;
|
|
||||||
}
|
|
||||||
property_element = document->FindNextElement("property");
|
|
||||||
}
|
|
||||||
|
|
||||||
// After reading interface properties in a file, read properties in the local
|
// After reading interface properties in a file, read properties in the local
|
||||||
// flight_control, autopilot, or system element. This allows general-purpose
|
// flight_control, autopilot, or system element. This allows general-purpose
|
||||||
// systems to be defined in a file, with overrides or initial loaded constants
|
// systems to be defined in a file, with overrides or initial loaded constants
|
||||||
// supplied in the relevant element of the aircraft configuration file.
|
// supplied in the relevant element of the aircraft configuration file.
|
||||||
|
|
||||||
|
Element* property_element = 0;
|
||||||
|
|
||||||
if (!fname.empty()) {
|
if (!fname.empty()) {
|
||||||
property_element = el->FindElement("property");
|
property_element = el->FindElement("property");
|
||||||
if (property_element && debug_lvl > 0) cout << endl << " Overriding properties" << endl << endl;
|
if (property_element && debug_lvl > 0) cout << endl << " Overriding properties" << endl << endl;
|
||||||
|
@ -628,22 +602,6 @@ bool FGFCS::Load(Element* el, SystemType systype)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Any sensor elements that are outside of a channel (in either the autopilot
|
|
||||||
// or the flight_control, or even any possible "system") are placed into the global
|
|
||||||
// "sensors" array, and are executed prior to any autopilot, flight control, or
|
|
||||||
// system.
|
|
||||||
|
|
||||||
sensor_element = document->FindElement("sensor");
|
|
||||||
while (sensor_element) {
|
|
||||||
try {
|
|
||||||
sensors.push_back(new FGSensor(this, sensor_element));
|
|
||||||
} catch (string s) {
|
|
||||||
cerr << highint << fgred << endl << " " << s << endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
sensor_element = document->FindNextElement("sensor");
|
|
||||||
}
|
|
||||||
|
|
||||||
channel_element = document->FindElement("channel");
|
channel_element = document->FindElement("channel");
|
||||||
while (channel_element) {
|
while (channel_element) {
|
||||||
|
|
||||||
|
|
|
@ -568,8 +568,6 @@ private:
|
||||||
FCSCompVec Systems;
|
FCSCompVec Systems;
|
||||||
FCSCompVec FCSComponents;
|
FCSCompVec FCSComponents;
|
||||||
FCSCompVec APComponents;
|
FCSCompVec APComponents;
|
||||||
FCSCompVec sensors;
|
|
||||||
vector <double*> interface_properties;
|
|
||||||
void bind(void);
|
void bind(void);
|
||||||
void bindModel(void);
|
void bindModel(void);
|
||||||
void bindThrottle(unsigned int);
|
void bindThrottle(unsigned int);
|
||||||
|
|
|
@ -131,6 +131,8 @@ bool FGGroundReactions::Load(Element* el)
|
||||||
contact_element = el->FindNextElement("contact");
|
contact_element = el->FindNextElement("contact");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FGModel::Load(el); // Perform base class Load
|
||||||
|
|
||||||
for (unsigned int i=0; i<lGear.size();i++) lGear[i]->bind();
|
for (unsigned int i=0; i<lGear.size();i++) lGear[i]->bind();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -114,67 +114,71 @@ bool FGInput::Run(void)
|
||||||
if (line.size() == 0) break;
|
if (line.size() == 0) break;
|
||||||
|
|
||||||
// now parse individual line
|
// now parse individual line
|
||||||
token_start = line.find_first_not_of(" ", 0);
|
vector <string> tokens = split(line,' ');
|
||||||
token_end = line.find_first_of(" ", token_start);
|
|
||||||
token = line.substr(token_start, token_end - token_start);
|
|
||||||
|
|
||||||
if (token == "set" || token == "SET" ) { // SET PROPERTY
|
string command="", argument="", str_value="";
|
||||||
|
if (tokens.size() > 0) {
|
||||||
|
command = to_lower(tokens[0]);
|
||||||
|
if (tokens.size() > 1) {
|
||||||
|
argument = trim(tokens[1]);
|
||||||
|
if (tokens.size() > 2) {
|
||||||
|
str_value = trim(tokens[2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
token_start = line.find_first_not_of(" ", token_end);
|
if (command == "set") { // SET PROPERTY
|
||||||
token_end = line.find_first_of(" ", token_start);
|
|
||||||
token = line.substr(token_start, token_end-token_start);
|
node = PropertyManager->GetNode(argument);
|
||||||
node = PropertyManager->GetNode(token);
|
if (node == 0)
|
||||||
if (node == 0) socket->Reply("Unknown property\n");
|
socket->Reply("Unknown property\n");
|
||||||
else {
|
else {
|
||||||
token_start = line.find_first_not_of(" ", token_end);
|
value = atof(str_value.c_str());
|
||||||
token_end = line.find_first_of(" ", token_start);
|
|
||||||
token = line.substr(token_start, token_end-token_start);
|
|
||||||
value = atof(token.c_str());
|
|
||||||
node->setDoubleValue(value);
|
node->setDoubleValue(value);
|
||||||
}
|
}
|
||||||
|
socket->Reply("");
|
||||||
|
|
||||||
} else if (token == "get" || token == "GET") { // GET PROPERTY
|
} else if (command == "get") { // GET PROPERTY
|
||||||
|
|
||||||
token_start = line.find_first_not_of(" ", token_end);
|
if (argument.size() == 0) {
|
||||||
if (token_start == string::npos) {
|
|
||||||
socket->Reply("No property argument supplied.\n");
|
socket->Reply("No property argument supplied.\n");
|
||||||
break;
|
break;
|
||||||
} else {
|
|
||||||
token = line.substr(token_start, line.size()-token_start);
|
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
node = PropertyManager->GetNode(token);
|
node = PropertyManager->GetNode(argument);
|
||||||
} catch(...) {
|
} catch(...) {
|
||||||
socket->Reply("Badly formed property query\n");
|
socket->Reply("Badly formed property query\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (node == 0) {
|
if (node == 0) {
|
||||||
if (FDMExec->Holding()) { // if holding can query property list
|
if (FDMExec->Holding()) { // if holding can query property list
|
||||||
string query = FDMExec->QueryPropertyCatalog(token);
|
string query = FDMExec->QueryPropertyCatalog(argument);
|
||||||
socket->Reply(query);
|
socket->Reply(query);
|
||||||
} else {
|
} else {
|
||||||
socket->Reply("Must be in HOLD to search properties\n");
|
socket->Reply("Must be in HOLD to search properties\n");
|
||||||
}
|
}
|
||||||
} else if (node > 0) {
|
} else if (node > 0) {
|
||||||
sprintf(buf, "%s = %12.6f\n", token.c_str(), node->getDoubleValue());
|
sprintf(buf, "%s = %12.6f\n", argument.c_str(), node->getDoubleValue());
|
||||||
socket->Reply(buf);
|
socket->Reply(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (token == "hold" || token == "HOLD") { // PAUSE
|
} else if (command == "hold") { // PAUSE
|
||||||
|
|
||||||
FDMExec->Hold();
|
FDMExec->Hold();
|
||||||
|
socket->Reply("");
|
||||||
|
|
||||||
} else if (token == "resume" || token == "RESUME") { // RESUME
|
} else if (command == "resume") { // RESUME
|
||||||
|
|
||||||
FDMExec->Resume();
|
FDMExec->Resume();
|
||||||
|
socket->Reply("");
|
||||||
|
|
||||||
} else if (token == "quit" || token == "QUIT") { // QUIT
|
} else if (command == "quit") { // QUIT
|
||||||
|
|
||||||
// close the socket connection
|
// close the socket connection
|
||||||
socket->Reply("");
|
socket->Reply("");
|
||||||
socket->Close();
|
socket->Close();
|
||||||
|
|
||||||
} else if (token == "info" || token == "INFO") { // INFO
|
} else if (command == "info") { // INFO
|
||||||
|
|
||||||
// get info about the sim run and/or aircraft, etc.
|
// get info about the sim run and/or aircraft, etc.
|
||||||
sprintf(buf, "%8.3f\0", State->Getsim_time());
|
sprintf(buf, "%8.3f\0", State->Getsim_time());
|
||||||
|
@ -184,7 +188,7 @@ bool FGInput::Run(void)
|
||||||
info_string += "Simulation time: " + string(buf) + "\n";
|
info_string += "Simulation time: " + string(buf) + "\n";
|
||||||
socket->Reply(info_string);
|
socket->Reply(info_string);
|
||||||
|
|
||||||
} else if (token == "help" || token == "HELP") { // HELP
|
} else if (command == "help") { // HELP
|
||||||
|
|
||||||
socket->Reply(
|
socket->Reply(
|
||||||
" JSBSim Server commands:\n\n"
|
" JSBSim Server commands:\n\n"
|
||||||
|
|
|
@ -96,6 +96,8 @@ bool FGMassBalance::Load(Element* el)
|
||||||
string element_name = "";
|
string element_name = "";
|
||||||
double bixx, biyy, bizz, bixy, bixz, biyz;
|
double bixx, biyy, bizz, bixy, bixz, biyz;
|
||||||
|
|
||||||
|
FGModel::Load(el); // Perform base class Load.
|
||||||
|
|
||||||
bixx = biyy = bizz = bixy = bixz = biyz = 0.0;
|
bixx = biyy = bizz = bixy = bixz = biyz = 0.0;
|
||||||
if (el->FindElement("ixx"))
|
if (el->FindElement("ixx"))
|
||||||
bixx = el->FindElementValueAsNumberConvertTo("ixx", "SLUG*FT2");
|
bixx = el->FindElementValueAsNumberConvertTo("ixx", "SLUG*FT2");
|
||||||
|
|
|
@ -99,6 +99,9 @@ FGModel::FGModel(FGFDMExec* fdmex)
|
||||||
|
|
||||||
FGModel::~FGModel()
|
FGModel::~FGModel()
|
||||||
{
|
{
|
||||||
|
for (unsigned int i=0; i<interface_properties.size(); i++) delete interface_properties[i];
|
||||||
|
interface_properties.clear();
|
||||||
|
|
||||||
if (debug_lvl & 2) cout << "Destroyed: FGModel" << endl;
|
if (debug_lvl & 2) cout << "Destroyed: FGModel" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,6 +140,35 @@ bool FGModel::InitModel(void)
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
bool FGModel::Load(Element* el)
|
||||||
|
{
|
||||||
|
// Interface properties are all stored in the interface properties array.
|
||||||
|
|
||||||
|
string interface_property_string = "";
|
||||||
|
|
||||||
|
Element *property_element = el->FindElement("property");
|
||||||
|
if (property_element && debug_lvl > 0) cout << endl << " Declared properties" << endl << endl;
|
||||||
|
while (property_element) {
|
||||||
|
interface_property_string = property_element->GetDataLine();
|
||||||
|
if (PropertyManager->HasNode(interface_property_string)) {
|
||||||
|
cerr << " Property " << interface_property_string << " is already defined." << endl;
|
||||||
|
} else {
|
||||||
|
double value=0.0;
|
||||||
|
if ( ! property_element->GetAttributeValue("value").empty())
|
||||||
|
value = property_element->GetAttributeValueAsNumber("value");
|
||||||
|
interface_properties.push_back(new double(value));
|
||||||
|
PropertyManager->Tie(interface_property_string, interface_properties.back());
|
||||||
|
if (debug_lvl > 0)
|
||||||
|
cout << " " << interface_property_string << " (initial value: " << value << ")" << endl;
|
||||||
|
}
|
||||||
|
property_element = el->FindNextElement("property");
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
bool FGModel::Run()
|
bool FGModel::Run()
|
||||||
{
|
{
|
||||||
if (debug_lvl & 4) cout << "Entering Run() for model " << Name << endl;
|
if (debug_lvl & 4) cout << "Entering Run() for model " << Name << endl;
|
||||||
|
|
|
@ -44,6 +44,7 @@ INCLUDES
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
DEFINITIONS
|
DEFINITIONS
|
||||||
|
@ -93,12 +94,12 @@ public:
|
||||||
/// Constructor
|
/// Constructor
|
||||||
FGModel(FGFDMExec*);
|
FGModel(FGFDMExec*);
|
||||||
/// Destructor
|
/// Destructor
|
||||||
virtual ~FGModel();
|
~FGModel();
|
||||||
|
|
||||||
/** Loads this model.
|
/** Loads this model.
|
||||||
@param el a pointer to the element
|
@param el a pointer to the element
|
||||||
@return true if model is successfully loaded*/
|
@return true if model is successfully loaded*/
|
||||||
virtual bool Load(Element* el) {return true;}
|
virtual bool Load(Element* el);
|
||||||
|
|
||||||
FGModel* NextModel;
|
FGModel* NextModel;
|
||||||
string Name;
|
string Name;
|
||||||
|
@ -135,6 +136,8 @@ protected:
|
||||||
FGPropagate* Propagate;
|
FGPropagate* Propagate;
|
||||||
FGAuxiliary* Auxiliary;
|
FGAuxiliary* Auxiliary;
|
||||||
FGPropertyManager* PropertyManager;
|
FGPropertyManager* PropertyManager;
|
||||||
|
|
||||||
|
vector <double*> interface_properties;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
|
@ -253,6 +253,8 @@ bool FGPropulsion::Load(Element* el)
|
||||||
|
|
||||||
Debug(2);
|
Debug(2);
|
||||||
|
|
||||||
|
FGModel::Load(el); // Perform base class Load.
|
||||||
|
|
||||||
Element* engine_element = el->FindElement("engine");
|
Element* engine_element = el->FindElement("engine");
|
||||||
while (engine_element) {
|
while (engine_element) {
|
||||||
engine_filename = engine_element->GetAttributeValue("file");
|
engine_filename = engine_element->GetAttributeValue("file");
|
||||||
|
|
|
@ -52,12 +52,25 @@ CLASS IMPLEMENTATION
|
||||||
|
|
||||||
FGDeadBand::FGDeadBand(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, element)
|
FGDeadBand::FGDeadBand(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, element)
|
||||||
{
|
{
|
||||||
|
string width_string;
|
||||||
|
|
||||||
|
WidthPropertyNode = 0;
|
||||||
|
WidthPropertySign = 1.0;
|
||||||
gain = 1.0;
|
gain = 1.0;
|
||||||
width = 0.0;
|
width = 0.0;
|
||||||
|
|
||||||
if ( element->FindElement("width") ) {
|
if ( element->FindElement("width") ) {
|
||||||
|
width_string = element->FindElementValue("width");
|
||||||
|
if (!is_number(width_string)) { // property
|
||||||
|
if (width_string[0] == '-') {
|
||||||
|
WidthPropertySign = -1.0;
|
||||||
|
width_string.erase(0,1);
|
||||||
|
}
|
||||||
|
WidthPropertyNode = PropertyManager->GetNode(width_string);
|
||||||
|
} else {
|
||||||
width = element->FindElementValueAsNumber("width");
|
width = element->FindElementValueAsNumber("width");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (element->FindElement("gain")) {
|
if (element->FindElement("gain")) {
|
||||||
gain = element->FindElementValueAsNumber("gain");
|
gain = element->FindElementValueAsNumber("gain");
|
||||||
|
@ -80,6 +93,10 @@ bool FGDeadBand::Run(void )
|
||||||
{
|
{
|
||||||
Input = InputNodes[0]->getDoubleValue() * InputSigns[0];
|
Input = InputNodes[0]->getDoubleValue() * InputSigns[0];
|
||||||
|
|
||||||
|
if (WidthPropertyNode != 0) {
|
||||||
|
width = WidthPropertyNode->getDoubleValue() * WidthPropertySign;
|
||||||
|
}
|
||||||
|
|
||||||
if (Input < -width/2.0) {
|
if (Input < -width/2.0) {
|
||||||
Output = (Input + width/2.0)*gain;
|
Output = (Input + width/2.0)*gain;
|
||||||
} else if (Input > width/2.0) {
|
} else if (Input > width/2.0) {
|
||||||
|
@ -121,7 +138,11 @@ void FGDeadBand::Debug(int from)
|
||||||
if (debug_lvl & 1) { // Standard console startup message output
|
if (debug_lvl & 1) { // Standard console startup message output
|
||||||
if (from == 0) { // Constructor
|
if (from == 0) { // Constructor
|
||||||
cout << " INPUT: " << InputNodes[0]->getName() << endl;
|
cout << " INPUT: " << InputNodes[0]->getName() << endl;
|
||||||
|
if (WidthPropertyNode != 0) {
|
||||||
|
cout << " DEADBAND WIDTH: " << WidthPropertyNode->GetName() << endl;
|
||||||
|
} else {
|
||||||
cout << " DEADBAND WIDTH: " << width << endl;
|
cout << " DEADBAND WIDTH: " << width << endl;
|
||||||
|
}
|
||||||
cout << " GAIN: " << gain << endl;
|
cout << " GAIN: " << gain << endl;
|
||||||
if (IsOutput) cout << " OUTPUT: " << OutputNode->getName() << endl;
|
if (IsOutput) cout << " OUTPUT: " << OutputNode->getName() << endl;
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,6 +97,8 @@ public:
|
||||||
private:
|
private:
|
||||||
double width;
|
double width;
|
||||||
double gain;
|
double gain;
|
||||||
|
FGPropertyManager* WidthPropertyNode;
|
||||||
|
double WidthPropertySign;
|
||||||
|
|
||||||
void Debug(int from);
|
void Debug(int from);
|
||||||
};
|
};
|
||||||
|
|
|
@ -133,7 +133,7 @@ FGFCSComponent::FGFCSComponent(FGFCS* _fcs, Element* element) : fcs(_fcs)
|
||||||
clip_el = element->FindElement("clipto");
|
clip_el = element->FindElement("clipto");
|
||||||
if (clip_el) {
|
if (clip_el) {
|
||||||
clip_string = clip_el->FindElementValue("min");
|
clip_string = clip_el->FindElementValue("min");
|
||||||
if (clip_string.find_first_not_of("+-.0123456789") != string::npos) { // it's a property
|
if (!is_number(clip_string)) { // it's a property
|
||||||
if (clip_string[0] == '-') {
|
if (clip_string[0] == '-') {
|
||||||
clipMinSign = -1.0;
|
clipMinSign = -1.0;
|
||||||
clip_string.erase(0,1);
|
clip_string.erase(0,1);
|
||||||
|
@ -143,7 +143,7 @@ FGFCSComponent::FGFCSComponent(FGFCS* _fcs, Element* element) : fcs(_fcs)
|
||||||
clipmin = clip_el->FindElementValueAsNumber("min");
|
clipmin = clip_el->FindElementValueAsNumber("min");
|
||||||
}
|
}
|
||||||
clip_string = clip_el->FindElementValue("max");
|
clip_string = clip_el->FindElementValue("max");
|
||||||
if (clip_string.find_first_not_of("+-.0123456789") != string::npos) { // it's a property
|
if (!is_number(clip_string)) { // it's a property
|
||||||
if (clip_string[0] == '-') {
|
if (clip_string[0] == '-') {
|
||||||
clipMaxSign = -1.0;
|
clipMaxSign = -1.0;
|
||||||
clip_string.erase(0,1);
|
clip_string.erase(0,1);
|
||||||
|
|
|
@ -105,7 +105,7 @@ void FGFilter::ReadFilterCoefficients(Element* element, int index)
|
||||||
|
|
||||||
if ( element->FindElement(coefficient) ) {
|
if ( element->FindElement(coefficient) ) {
|
||||||
property_string = element->FindElementValue(coefficient);
|
property_string = element->FindElementValue(coefficient);
|
||||||
if (property_string.find_first_not_of("+-.0123456789Ee") != string::npos) { // property
|
if (!is_number(property_string)) { // property
|
||||||
if (property_string[0] == '-') {
|
if (property_string[0] == '-') {
|
||||||
PropertySign[index] = -1.0;
|
PropertySign[index] = -1.0;
|
||||||
property_string.erase(0,1);
|
property_string.erase(0,1);
|
||||||
|
|
|
@ -70,7 +70,7 @@ FGGain::FGGain(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, element)
|
||||||
|
|
||||||
if ( element->FindElement("gain") ) {
|
if ( element->FindElement("gain") ) {
|
||||||
gain_string = element->FindElementValue("gain");
|
gain_string = element->FindElementValue("gain");
|
||||||
if (gain_string.find_first_not_of("+-.0123456789Ee") != string::npos) { // property
|
if (!is_number(gain_string)) { // property
|
||||||
if (gain_string[0] == '-') {
|
if (gain_string[0] == '-') {
|
||||||
GainPropertySign = -1.0;
|
GainPropertySign = -1.0;
|
||||||
gain_string.erase(0,1);
|
gain_string.erase(0,1);
|
||||||
|
@ -207,7 +207,11 @@ void FGGain::Debug(int from)
|
||||||
else
|
else
|
||||||
cout << " INPUT: " << InputNodes[0]->getName() << endl;
|
cout << " INPUT: " << InputNodes[0]->getName() << endl;
|
||||||
|
|
||||||
|
if (GainPropertyNode != 0) {
|
||||||
|
cout << " GAIN: " << GainPropertyNode->GetName() << endl;
|
||||||
|
} else {
|
||||||
cout << " GAIN: " << Gain << endl;
|
cout << " GAIN: " << Gain << endl;
|
||||||
|
}
|
||||||
if (IsOutput) cout << " OUTPUT: " << OutputNode->getName() << endl;
|
if (IsOutput) cout << " OUTPUT: " << OutputNode->getName() << endl;
|
||||||
if (Type == "AEROSURFACE_SCALE") {
|
if (Type == "AEROSURFACE_SCALE") {
|
||||||
cout << " In/Out Mapping:" << endl;
|
cout << " In/Out Mapping:" << endl;
|
||||||
|
|
|
@ -64,7 +64,7 @@ FGPID::FGPID(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, element)
|
||||||
|
|
||||||
if ( element->FindElement("kp") ) {
|
if ( element->FindElement("kp") ) {
|
||||||
kp_string = element->FindElementValue("kp");
|
kp_string = element->FindElementValue("kp");
|
||||||
if (kp_string.find_first_not_of("+-.0123456789Ee") != string::npos) { // property
|
if (!is_number(kp_string)) { // property
|
||||||
if (kp_string[0] == '-') {
|
if (kp_string[0] == '-') {
|
||||||
KpPropertySign = -1.0;
|
KpPropertySign = -1.0;
|
||||||
kp_string.erase(0,1);
|
kp_string.erase(0,1);
|
||||||
|
@ -77,7 +77,7 @@ FGPID::FGPID(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, element)
|
||||||
|
|
||||||
if ( element->FindElement("ki") ) {
|
if ( element->FindElement("ki") ) {
|
||||||
ki_string = element->FindElementValue("ki");
|
ki_string = element->FindElementValue("ki");
|
||||||
if (ki_string.find_first_not_of("+-.0123456789Ee") != string::npos) { // property
|
if (!is_number(ki_string)) { // property
|
||||||
if (ki_string[0] == '-') {
|
if (ki_string[0] == '-') {
|
||||||
KiPropertySign = -1.0;
|
KiPropertySign = -1.0;
|
||||||
ki_string.erase(0,1);
|
ki_string.erase(0,1);
|
||||||
|
@ -90,7 +90,7 @@ FGPID::FGPID(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, element)
|
||||||
|
|
||||||
if ( element->FindElement("kd") ) {
|
if ( element->FindElement("kd") ) {
|
||||||
kd_string = element->FindElementValue("kd");
|
kd_string = element->FindElementValue("kd");
|
||||||
if (kd_string.find_first_not_of("+-.0123456789Ee") != string::npos) { // property
|
if (!is_number(kd_string)) { // property
|
||||||
if (kd_string[0] == '-') {
|
if (kd_string[0] == '-') {
|
||||||
KdPropertySign = -1.0;
|
KdPropertySign = -1.0;
|
||||||
kd_string.erase(0,1);
|
kd_string.erase(0,1);
|
||||||
|
|
|
@ -119,7 +119,7 @@ class FGSensor : public FGFCSComponent
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FGSensor(FGFCS* fcs, Element* element);
|
FGSensor(FGFCS* fcs, Element* element);
|
||||||
~FGSensor();
|
virtual ~FGSensor();
|
||||||
|
|
||||||
void SetFailLow(double val) {if (val > 0.0) fail_low = true; else fail_low = false;}
|
void SetFailLow(double val) {if (val > 0.0) fail_low = true; else fail_low = false;}
|
||||||
void SetFailHigh(double val) {if (val > 0.0) fail_high = true; else fail_high = false;}
|
void SetFailHigh(double val) {if (val > 0.0) fail_high = true; else fail_high = false;}
|
||||||
|
|
|
@ -97,7 +97,17 @@ FGSwitch::FGSwitch(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, element)
|
||||||
cerr << "Unrecognized LOGIC token " << logic << " in switch component: " << Name << endl;
|
cerr << "Unrecognized LOGIC token " << logic << " in switch component: " << Name << endl;
|
||||||
}
|
}
|
||||||
for (unsigned int i=0; i<test_element->GetNumDataLines(); i++) {
|
for (unsigned int i=0; i<test_element->GetNumDataLines(); i++) {
|
||||||
current_test->conditions.push_back(new FGCondition(test_element->GetDataLine(i), PropertyManager));
|
string input_data = test_element->GetDataLine(i);
|
||||||
|
while (input_data[0] <= 32) {
|
||||||
|
input_data = input_data.erase(0,1);
|
||||||
|
if (input_data.size() <= 1) break;
|
||||||
|
}
|
||||||
|
if (input_data.size() <= 1) {
|
||||||
|
// Make sure there are no bad data lines that consist solely of whitespace
|
||||||
|
cerr << fgred << " Bad data line in switch component: " << Name << reset << endl;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
current_test->conditions.push_back(new FGCondition(input_data, PropertyManager));
|
||||||
}
|
}
|
||||||
|
|
||||||
condition_element = test_element->GetElement(); // retrieve condition groups
|
condition_element = test_element->GetElement(); // retrieve condition groups
|
||||||
|
@ -115,8 +125,7 @@ FGSwitch::FGSwitch(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, element)
|
||||||
if (value.empty()) {
|
if (value.empty()) {
|
||||||
cerr << "No VALUE supplied for switch component: " << Name << endl;
|
cerr << "No VALUE supplied for switch component: " << Name << endl;
|
||||||
} else {
|
} else {
|
||||||
if (value.find_first_not_of("-.0123456789eE") == string::npos) {
|
if (is_number(value)) {
|
||||||
// if true (and execution falls into this block), "value" is a number.
|
|
||||||
current_test->OutputVal = atof(value.c_str());
|
current_test->OutputVal = atof(value.c_str());
|
||||||
} else {
|
} else {
|
||||||
// "value" must be a property if execution passes to here.
|
// "value" must be a property if execution passes to here.
|
||||||
|
|
Loading…
Reference in a new issue