INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+#define BASE
+
#include "FGJSBBase.h"
namespace JSBSim {
#include <cmath>
#include <cstdlib>
+#include "input_output/string_utilities.h"
+
using std::fabs;
using std::string;
ta=*iAxes;
if( ta->GetStateType() == state ) {
delete ta;
- TrimAxes.erase(iAxes);
+ iAxes = TrimAxes.erase(iAxes);
result=true;
continue;
}
#include "FGXMLParse.h"
#include <cstdlib>
+#include "input_output/string_utilities.h"
namespace JSBSim {
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()) {
- pos = working_string.find("\n");
- if (pos != string::npos) local_work_string = working_string.substr(0,pos);
- else local_work_string = working_string;
- current_element->AddData(local_work_string);
- working_string.erase(0, pos);
- }
+ if (!working_string.empty()) {
+ vector <string> work_strings = split(working_string, '\n');
+ for (int i=0; i<work_strings.size(); i++) current_element->AddData(work_strings[i]);
}
current_element = current_element->GetParent();
else cout << "Winsock DLL not initialized ..." << endl;
#endif
- if (address.find_first_not_of("0123456789.",0) != address.npos) {
+ if (!is_number(address)) {
if ((host = gethostbyname(address.c_str())) == NULL) {
cout << "Could not get host net address by name..." << endl;
}
cout << "Host name... " << address << ", Port... " << port << "." << 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) {
cout << "Could not get host net address by name..." << endl;
}
--- /dev/null
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ 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
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include "FGCondition.h"
+#include <vector>
namespace JSBSim {
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-//This constructor is called when there are no nested test groups inside the
+// This constructor is called when there are no nested test groups inside the
// condition
FGCondition::FGCondition(string test, FGPropertyManager* PropertyManager) :
PropertyManager(PropertyManager), isGroup(false)
{
string property1, property2, compare_string;
+ vector <string> test_strings;
InitializeConditionals();
Logic = elUndef;
conditions.clear();
- unsigned int start = 0, end = 0;
- start = test.find_first_not_of(" ");
- end = test.find_first_of(" ", start+1);
- property1 = test.substr(start,end-start);
- start = test.find_first_not_of(" ",end);
- end = test.find_first_of(" ",start+1);
- conditional = test.substr(start,end-start);
- start = test.find_first_not_of(" ",end);
- end = test.find_first_of(" ",start+1);
- property2 = test.substr(start,end-start);
+ test_strings = split(test, ' ');
+ if (test_strings.size() == 3) {
+ property1 = test_strings[0];
+ conditional = test_strings[1];
+ property2 = test_strings[2];
+ } else {
+ cerr << endl << " Conditional test is invalid: \"" << test
+ << "\" has " << test_strings.size() << " elements in the "
+ << "test condition." << endl;
+ exit(-1);
+ }
TestParam1 = PropertyManager->GetNode(property1, true);
Comparison = mComparison[conditional];
- if (property2.find_first_not_of("-.0123456789eE") == string::npos) {
+ if (is_number(property2)) {
TestValue = atof(property2.c_str());
} else {
TestParam2 = PropertyManager->GetNode(property2, true);
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+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)
{
mCacheValid = false;
@param radius distance from center of earth to vehicle in feet*/
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.
The eccentricity and flattening are calculated from the semimajor
and semiminor axis lengths */
document = element;
}
+ FGModel::Load(element); // Perform base class Load
+
DetermineAxisSystem(); // Detemine if Lift/Side/Drag, etc. is used.
Debug(2);
string element_name;
Element* element;
+ FGModel::Load(el);
+
if (el->FindElement("wingarea"))
WingArea = el->FindElementValueAsNumberConvertTo("wingarea", "FT2");
if (el->FindElement("wingspan"))
for (unsigned int i=0; i<Cells.size(); i++) delete Cells[i];
Cells.clear();
- for (unsigned int i=0; i<interface_properties.size(); i++)
- delete interface_properties[i];
- interface_properties.clear();
-
Debug(1);
}
document = element;
}
- Element *property_element = document->FindElement("property");
- 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");
- }
+ FGModel::Load(element); // Perform base class Load
gas_cell_element = document->FindElement("gas_cell");
while (gas_cell_element) {
FGColumnVector3 vGasCellXYZ;
FGColumnVector3 vXYZgasCell_arm;
- vector <double*> interface_properties;
-
bool NoneDefined;
void bind(void);
bool FGExternalReactions::Load(Element* el)
{
- Debug(2);
+ FGModel::Load(el); // Call the base class Load() function to load interface properties.
- // 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");
- }
+ Debug(2);
// Parse force elements
{
for (unsigned int i=0; i<Forces.size(); i++) delete Forces[i];
Forces.clear();
- for (unsigned int i=0; i<interface_properties.size(); i++) delete interface_properties[i];
- interface_properties.clear();
+
Debug(1);
}
unsigned int numForces;
FGColumnVector3 vTotalForces;
FGColumnVector3 vTotalMoments;
- vector <double*> interface_properties;
bool NoneDefined;
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];
APComponents.clear();
for (i=0;i<FCSComponents.size();i++) delete FCSComponents[i];
for (i=0;i<Systems.size();i++) delete Systems[i];
Systems.clear();
- for (unsigned int i=0; i<interface_properties.size(); i++) delete interface_properties[i];
- interface_properties.clear();
Debug(1);
}
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
for (i=0; i<Systems.size(); i++) Systems[i]->Run();
{
string name, file, fname="", interface_property_string, parent_name;
vector <FGFCSComponent*> *Components;
- Element *component_element, *property_element, *sensor_element;
+ Element *component_element, *sensor_element;
Element *channel_element;
Components=0;
if (document->GetName() == "flight_control") bindModel();
- // Interface properties from any autopilot, flight control, or other system are
- // 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");
- }
+ FGModel::Load(document); // Load interface properties from document
// After reading interface properties in a file, read properties in the local
// flight_control, autopilot, or system element. This allows general-purpose
// systems to be defined in a file, with overrides or initial loaded constants
// supplied in the relevant element of the aircraft configuration file.
+ Element* property_element = 0;
+
if (!fname.empty()) {
property_element = el->FindElement("property");
if (property_element && debug_lvl > 0) cout << endl << " Overriding properties" << endl << endl;
}
}
- // 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");
while (channel_element) {
FCSCompVec Systems;
FCSCompVec FCSComponents;
FCSCompVec APComponents;
- FCSCompVec sensors;
- vector <double*> interface_properties;
void bind(void);
void bindModel(void);
void bindThrottle(unsigned int);
FCS->AddGear(); // make the FCS aware of the landing gear
contact_element = el->FindNextElement("contact");
}
+
+ FGModel::Load(el); // Perform base class Load
for (unsigned int i=0; i<lGear.size();i++) lGear[i]->bind();
if (line.size() == 0) break;
// now parse individual line
- token_start = line.find_first_not_of(" ", 0);
- token_end = line.find_first_of(" ", token_start);
- token = line.substr(token_start, token_end - token_start);
+ vector <string> tokens = split(line,' ');
+
+ 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]);
+ }
+ }
+ }
- if (token == "set" || token == "SET" ) { // SET PROPERTY
+ if (command == "set") { // SET PROPERTY
- token_start = line.find_first_not_of(" ", token_end);
- token_end = line.find_first_of(" ", token_start);
- token = line.substr(token_start, token_end-token_start);
- node = PropertyManager->GetNode(token);
- if (node == 0) socket->Reply("Unknown property\n");
+ node = PropertyManager->GetNode(argument);
+ if (node == 0)
+ socket->Reply("Unknown property\n");
else {
- token_start = line.find_first_not_of(" ", token_end);
- token_end = line.find_first_of(" ", token_start);
- token = line.substr(token_start, token_end-token_start);
- value = atof(token.c_str());
+ value = atof(str_value.c_str());
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 (token_start == string::npos) {
+ if (argument.size() == 0) {
socket->Reply("No property argument supplied.\n");
break;
- } else {
- token = line.substr(token_start, line.size()-token_start);
}
try {
- node = PropertyManager->GetNode(token);
+ node = PropertyManager->GetNode(argument);
} catch(...) {
socket->Reply("Badly formed property query\n");
break;
}
if (node == 0) {
if (FDMExec->Holding()) { // if holding can query property list
- string query = FDMExec->QueryPropertyCatalog(token);
+ string query = FDMExec->QueryPropertyCatalog(argument);
socket->Reply(query);
} else {
socket->Reply("Must be in HOLD to search properties\n");
}
} 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);
}
- } else if (token == "hold" || token == "HOLD") { // PAUSE
+ } else if (command == "hold") { // PAUSE
FDMExec->Hold();
+ socket->Reply("");
- } else if (token == "resume" || token == "RESUME") { // RESUME
+ } else if (command == "resume") { // RESUME
FDMExec->Resume();
+ socket->Reply("");
- } else if (token == "quit" || token == "QUIT") { // QUIT
+ } else if (command == "quit") { // QUIT
// close the socket connection
socket->Reply("");
socket->Close();
- } else if (token == "info" || token == "INFO") { // INFO
+ } else if (command == "info") { // INFO
// get info about the sim run and/or aircraft, etc.
sprintf(buf, "%8.3f\0", State->Getsim_time());
info_string += "Simulation time: " + string(buf) + "\n";
socket->Reply(info_string);
- } else if (token == "help" || token == "HELP") { // HELP
+ } else if (command == "help") { // HELP
socket->Reply(
" JSBSim Server commands:\n\n"
string element_name = "";
double bixx, biyy, bizz, bixy, bixz, biyz;
+ FGModel::Load(el); // Perform base class Load.
+
bixx = biyy = bizz = bixy = bixz = biyz = 0.0;
if (el->FindElement("ixx"))
bixx = el->FindElementValueAsNumberConvertTo("ixx", "SLUG*FT2");
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;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+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()
{
if (debug_lvl & 4) cout << "Entering Run() for model " << Name << endl;
#include <iostream>
#include <string>
+#include <vector>
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS
/// Constructor
FGModel(FGFDMExec*);
/// Destructor
- virtual ~FGModel();
+ ~FGModel();
/** Loads this model.
@param el a pointer to the element
@return true if model is successfully loaded*/
- virtual bool Load(Element* el) {return true;}
+ virtual bool Load(Element* el);
FGModel* NextModel;
string Name;
FGPropagate* Propagate;
FGAuxiliary* Auxiliary;
FGPropertyManager* PropertyManager;
+
+ vector <double*> interface_properties;
};
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Debug(2);
+ FGModel::Load(el); // Perform base class Load.
+
Element* engine_element = el->FindElement("engine");
while (engine_element) {
engine_filename = engine_element->GetAttributeValue("file");
FGDeadBand::FGDeadBand(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, element)
{
+ string width_string;
+
+ WidthPropertyNode = 0;
+ WidthPropertySign = 1.0;
gain = 1.0;
width = 0.0;
- if (element->FindElement("width")) {
- width = element->FindElementValueAsNumber("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");
+ }
}
if (element->FindElement("gain")) {
{
Input = InputNodes[0]->getDoubleValue() * InputSigns[0];
+ if (WidthPropertyNode != 0) {
+ width = WidthPropertyNode->getDoubleValue() * WidthPropertySign;
+ }
+
if (Input < -width/2.0) {
Output = (Input + width/2.0)*gain;
} else if (Input > width/2.0) {
if (debug_lvl & 1) { // Standard console startup message output
if (from == 0) { // Constructor
cout << " INPUT: " << InputNodes[0]->getName() << endl;
- cout << " DEADBAND WIDTH: " << width << endl;
+ if (WidthPropertyNode != 0) {
+ cout << " DEADBAND WIDTH: " << WidthPropertyNode->GetName() << endl;
+ } else {
+ cout << " DEADBAND WIDTH: " << width << endl;
+ }
cout << " GAIN: " << gain << endl;
if (IsOutput) cout << " OUTPUT: " << OutputNode->getName() << endl;
}
private:
double width;
double gain;
+ FGPropertyManager* WidthPropertyNode;
+ double WidthPropertySign;
void Debug(int from);
};
clip_el = element->FindElement("clipto");
if (clip_el) {
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] == '-') {
clipMinSign = -1.0;
clip_string.erase(0,1);
clipmin = clip_el->FindElementValueAsNumber("min");
}
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] == '-') {
clipMaxSign = -1.0;
clip_string.erase(0,1);
if ( element->FindElement(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] == '-') {
PropertySign[index] = -1.0;
property_string.erase(0,1);
if ( element->FindElement("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] == '-') {
GainPropertySign = -1.0;
gain_string.erase(0,1);
else
cout << " INPUT: " << InputNodes[0]->getName() << endl;
- cout << " GAIN: " << Gain << endl;
+ if (GainPropertyNode != 0) {
+ cout << " GAIN: " << GainPropertyNode->GetName() << endl;
+ } else {
+ cout << " GAIN: " << Gain << endl;
+ }
if (IsOutput) cout << " OUTPUT: " << OutputNode->getName() << endl;
if (Type == "AEROSURFACE_SCALE") {
cout << " In/Out Mapping:" << endl;
if ( element->FindElement("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] == '-') {
KpPropertySign = -1.0;
kp_string.erase(0,1);
if ( element->FindElement("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] == '-') {
KiPropertySign = -1.0;
ki_string.erase(0,1);
if ( element->FindElement("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] == '-') {
KdPropertySign = -1.0;
kd_string.erase(0,1);
{
public:
FGSensor(FGFCS* fcs, Element* element);
- ~FGSensor();
+ virtual ~FGSensor();
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;}
cerr << "Unrecognized LOGIC token " << logic << " in switch component: " << Name << endl;
}
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
if (value.empty()) {
cerr << "No VALUE supplied for switch component: " << Name << endl;
} else {
- if (value.find_first_not_of("-.0123456789eE") == string::npos) {
- // if true (and execution falls into this block), "value" is a number.
+ if (is_number(value)) {
current_test->OutputVal = atof(value.c_str());
} else {
// "value" must be a property if execution passes to here.