📄 fgscript.cpp
字号:
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Module: FGScript.cpp Author: Jon S. Berndt Date started: 12/21/01 Purpose: Loads and runs JSBSim scripts. ------------- Copyright (C) 1999 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.FUNCTIONAL DESCRIPTION--------------------------------------------------------------------------------This class wraps up the simulation scripting routines.HISTORY--------------------------------------------------------------------------------12/21/01 JSB Created%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%COMMENTS, REFERENCES, and NOTES%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%INCLUDES%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/#include "FGScript.h"#include <input_output/FGXMLParse.h>#include <initialization/FGTrim.h>#include <iostream>#include <iterator>namespace JSBSim {static const char *IdSrc = "$Id$";static const char *IdHdr = ID_FGSCRIPT;/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%GLOBAL DECLARATIONS%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*//*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%CLASS IMPLEMENTATION%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/// ConstructorFGScript::FGScript(FGFDMExec* fgex) : FDMExec(fgex){ State = FDMExec->GetState(); PropertyManager=FDMExec->GetPropertyManager(); Debug(0);}//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%FGScript::~FGScript(){ unsigned int i; for (i=0; i<local_properties.size(); i++) delete local_properties[i]; local_properties.clear(); for (i=0; i<Events.size(); i++) delete Events[i].Condition; Events.clear(); Debug(1);}//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%bool FGScript::LoadScript( string script ){ string aircraft="", initialize="", comparison = "", prop_name=""; string notifyPropertyName=""; Element *element=0, *run_element=0, *event_element=0; Element *condition_element=0, *set_element=0, *delay_element=0; Element *notify_element = 0L, *notify_property_element = 0L; Element *property_element = 0L; Element *output_element = 0L; Element *input_element = 0L; bool result = false; double dt = 0.0, value = 0.0; struct event *newEvent; FGCondition *newCondition; document = LoadXMLDocument(script); if (!document) { cerr << "File: " << script << " could not be loaded." << endl; return false; } // Set up input and output files if specified output_element = document->FindElement("output"); input_element = document->FindElement("input"); if (document->GetName() != string("runscript")) { cerr << "File: " << script << " is not a script file" << endl; return false; } ScriptName = document->GetAttributeValue("name"); // First, find "run" element and set delta T run_element = document->FindElement("run"); if (!run_element) { cerr << "No \"run\" element found in script." << endl; return false; } // Set sim timing StartTime = run_element->GetAttributeValueAsNumber("start"); State->Setsim_time(StartTime); EndTime = run_element->GetAttributeValueAsNumber("end"); dt = run_element->GetAttributeValueAsNumber("dt"); State->Setdt(dt); // read aircraft and initialization files element = document->FindElement("use"); if (element) { aircraft = element->GetAttributeValue("aircraft"); if (!aircraft.empty()) { result = FDMExec->LoadModel(aircraft); if (!result) return false; } else { cerr << "Aircraft must be specified in use element." << endl; return false; } initialize = element->GetAttributeValue("initialize"); if (initialize.empty()) { cerr << "Initialization file must be specified in use element." << endl; return false; } } else { cerr << "No \"use\" directives in the script file." << endl; return false; } // Now, read input spec if given. if (input_element > 0) { FDMExec->GetInput()->Load(input_element); } // Now, read output spec if given. if (output_element > 0) { string output_file = output_element->GetAttributeValue("file"); if (output_file.empty()) { cerr << "No logging directives file was specified." << endl; } else { FDMExec->SetOutputDirectives(output_file); } } // Read local property/value declarations property_element = run_element->FindElement("property"); while (property_element) { double value=0.0; if ( ! property_element->GetAttributeValue("value").empty()) value = property_element->GetAttributeValueAsNumber("value"); LocalProps *localProp = new LocalProps(value); localProp->title = property_element->GetDataLine(); local_properties.push_back(localProp); PropertyManager->Tie(localProp->title, (local_properties.back())->value); property_element = run_element->FindNextElement("property"); } // Read "events" from script event_element = run_element->FindElement("event"); while (event_element) { // event processing // Create the event structure newEvent = new struct event(); // Retrieve the event name if given newEvent->Name = event_element->GetAttributeValue("name"); // Is this event persistent? That is, does it execute repeatedly as long as the // condition is true, or does it execute as a one-shot event, only? if (event_element->GetAttributeValue("persistent") == string("true")) { newEvent->Persistent = true; } // Process the conditions condition_element = event_element->FindElement("condition"); if (condition_element != 0) { newCondition = new FGCondition(condition_element, PropertyManager); newEvent->Condition = newCondition; } else { cerr << "No condition specified in script event " << newEvent->Name << endl; return false; } // Is there a delay between the time this event is triggered, and when the event // actions are executed? delay_element = event_element->FindElement("delay"); if (delay_element) newEvent->Delay = event_element->FindElementValueAsNumber("delay"); else newEvent->Delay = 0.0; // Notify about when this event is triggered? if ((notify_element = event_element->FindElement("notify")) != 0) { newEvent->Notify = true; notify_property_element = notify_element->FindElement("property"); while (notify_property_element) { notifyPropertyName = notify_property_element->GetDataLine(); if (PropertyManager->GetNode(notifyPropertyName)) { newEvent->NotifyProperties.push_back( PropertyManager->GetNode(notifyPropertyName) ); } else { cout << endl << fgred << " Could not find the property named " << notifyPropertyName << " in script" << endl << " \"" << ScriptName << "\". This unknown property will not be " << "echoed for notification." << reset << endl; } notify_property_element = notify_element->FindNextElement("property"); } } // Read set definitions (these define the actions to be taken when the event is triggered). set_element = event_element->FindElement("set"); while (set_element) { prop_name = set_element->GetAttributeValue("name"); newEvent->SetParam.push_back( PropertyManager->GetNode(prop_name) ); //Todo - should probably do some safety checking here to make sure one or the other //of value or function is specified. if (!set_element->GetAttributeValue("value").empty()) { value = set_element->GetAttributeValueAsNumber("value"); newEvent->Functions.push_back((FGFunction*)0L); } else if (set_element->FindElement("function")) { value = 0.0; newEvent->Functions.push_back(new FGFunction(PropertyManager, set_element->FindElement("function"))); } newEvent->SetValue.push_back(value); newEvent->OriginalValue.push_back(0.0); newEvent->newValue.push_back(0.0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -