--- /dev/null
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
+\r
+ Module: FGScript.cpp\r
+ Author: Jon S. Berndt\r
+ Date started: 12/21/01\r
+ Purpose: Loads and runs JSBSim scripts.\r
+\r
+ ------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------\r
+\r
+ This program is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License as published by the Free Software\r
+ Foundation; either version 2 of the License, or (at your option) any later\r
+ version.\r
+\r
+ This program is distributed in the hope that it will be useful, but WITHOUT\r
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
+ FOR A PARTICULAR PURPOSE. See the GNU General Public License for more\r
+ details.\r
+\r
+ You should have received a copy of the GNU General Public License along with\r
+ this program; if not, write to the Free Software Foundation, Inc., 59 Temple\r
+ Place - Suite 330, Boston, MA 02111-1307, USA.\r
+\r
+ Further information about the GNU General Public License can also be found on\r
+ the world wide web at http://www.gnu.org.\r
+\r
+FUNCTIONAL DESCRIPTION\r
+--------------------------------------------------------------------------------\r
+\r
+This class wraps up the simulation scripting routines.\r
+\r
+HISTORY\r
+--------------------------------------------------------------------------------\r
+12/21/01 JSB Created\r
+\r
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
+COMMENTS, REFERENCES, and NOTES\r
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
+\r
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
+INCLUDES\r
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
+\r
+#ifdef FGFS\r
+# include <simgear/compiler.h>\r
+# include STL_IOSTREAM\r
+# include STL_ITERATOR\r
+#else\r
+# if defined(sgi) && !defined(__GNUC__)\r
+# include <iostream.h>\r
+# else\r
+# include <iostream>\r
+# endif\r
+# include <iterator>\r
+#endif\r
+\r
+#include "FGScript.h"\r
+#include "FGConfigFile.h"\r
+\r
+static const char *IdSrc = "$Id$";\r
+static const char *IdHdr = ID_FGSCRIPT;\r
+\r
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
+GLOBAL DECLARATIONS\r
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
+\r
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
+CLASS IMPLEMENTATION\r
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
+\r
+// Constructor\r
+\r
+FGScript::FGScript(FGFDMExec* fgex) : FDMExec(fgex)\r
+{\r
+ State = FDMExec->GetState();\r
+ Debug(0);\r
+}\r
+\r
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
+\r
+FGScript::~FGScript()\r
+{\r
+ Debug(1);\r
+}\r
+\r
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
+\r
+bool FGScript::LoadScript(string script)\r
+{\r
+ FGConfigFile Script(script);\r
+ string token="";\r
+ string aircraft="";\r
+ string initialize="";\r
+ bool result = false;\r
+ double dt = 0.0;\r
+ unsigned i;\r
+ struct condition *newCondition;\r
+\r
+ if (!Script.IsOpen()) return false;\r
+\r
+ Script.GetNextConfigLine();\r
+ if (Script.GetValue("runscript").length() <= 0) {\r
+ cerr << "File: " << script << " is not a script file" << endl;\r
+ delete FDMExec;\r
+ return false; \r
+ }\r
+ ScriptName = Script.GetValue("name");\r
+ Scripted = true;\r
+\r
+ if (debug_lvl > 0) cout << "Reading Script File " << ScriptName << endl;\r
+\r
+ while (Script.GetNextConfigLine() != string("EOF") && Script.GetValue() != string("/runscript")) {\r
+ token = Script.GetValue();\r
+ if (token == "use") {\r
+ if ((token = Script.GetValue("aircraft")) != string("")) {\r
+ aircraft = token;\r
+ if (debug_lvl > 0) cout << " Use aircraft: " << token << endl;\r
+ } else if ((token = Script.GetValue("initialize")) != string("")) {\r
+ initialize = token;\r
+ if (debug_lvl > 0) cout << " Use reset file: " << token << endl;\r
+ } else {\r
+ cerr << "Unknown 'use' keyword: \"" << token << "\"" << endl;\r
+ }\r
+ } else if (token == "run") {\r
+ StartTime = strtod(Script.GetValue("start").c_str(), NULL);\r
+ State->Setsim_time(StartTime);\r
+ EndTime = strtod(Script.GetValue("end").c_str(), NULL);\r
+ dt = strtod(Script.GetValue("dt").c_str(), NULL);\r
+ State->Setdt(dt);\r
+ Script.GetNextConfigLine();\r
+ token = Script.GetValue();\r
+ while (token != string("/run")) {\r
+\r
+ if (token == "when") {\r
+ Script.GetNextConfigLine();\r
+ token = Script.GetValue();\r
+ newCondition = new struct condition();\r
+ while (token != string("/when")) {\r
+ if (token == "parameter") {\r
+ newCondition->TestParam.push_back(State->GetParameterIndex(Script.GetValue("name")));\r
+ newCondition->TestValue.push_back(strtod(Script.GetValue("value").c_str(), NULL));\r
+ newCondition->Comparison.push_back(Script.GetValue("comparison"));\r
+ } else if (token == "set") {\r
+ newCondition->SetParam.push_back(State->GetParameterIndex(Script.GetValue("name")));\r
+ newCondition->SetValue.push_back(strtod(Script.GetValue("value").c_str(), NULL));\r
+ newCondition->Triggered.push_back(false);\r
+ newCondition->OriginalValue.push_back(0.0);\r
+ newCondition->newValue.push_back(0.0);\r
+ newCondition->StartTime.push_back(0.0);\r
+ newCondition->EndTime.push_back(0.0);\r
+ string tempCompare = Script.GetValue("type");\r
+ if (tempCompare == "FG_DELTA") newCondition->Type.push_back(FG_DELTA);\r
+ else if (tempCompare == "FG_BOOL") newCondition->Type.push_back(FG_BOOL);\r
+ else if (tempCompare == "FG_VALUE") newCondition->Type.push_back(FG_VALUE);\r
+ else newCondition->Type.push_back((eType)0);\r
+ tempCompare = Script.GetValue("action");\r
+ if (tempCompare == "FG_RAMP") newCondition->Action.push_back(FG_RAMP);\r
+ else if (tempCompare == "FG_STEP") newCondition->Action.push_back(FG_STEP);\r
+ else if (tempCompare == "FG_EXP") newCondition->Action.push_back(FG_EXP);\r
+ else newCondition->Action.push_back((eAction)0);\r
+ \r
+ if (Script.GetValue("persistent") == "true")\r
+ newCondition->Persistent.push_back(true);\r
+ else\r
+ newCondition->Persistent.push_back(false);\r
+ \r
+ newCondition->TC.push_back(strtod(Script.GetValue("tc").c_str(), NULL));\r
+ \r
+ } else {\r
+ cerr << "Unrecognized keyword in script file: \" [when] " << token << "\"" << endl;\r
+ }\r
+ Script.GetNextConfigLine();\r
+ token = Script.GetValue();\r
+ }\r
+ Conditions.push_back(*newCondition);\r
+ Script.GetNextConfigLine();\r
+ token = Script.GetValue();\r
+\r
+ } else {\r
+ cerr << "Error reading script file: expected \"when\", got \"" << token << "\"" << endl;\r
+ }\r
+\r
+ }\r
+ } else if (token.empty()) {\r
+ // do nothing\r
+ } else {\r
+ cerr << "Unrecognized keyword in script file: \"" << token << "\" [runscript] " << endl;\r
+ }\r
+ }\r
+\r
+ if (aircraft == "") {\r
+ cerr << "Aircraft file not loaded in script" << endl;\r
+ exit(-1);\r
+ }\r
+\r
+ Debug(4);\r
+\r
+ result = FDMExec->LoadModel("aircraft", "engine", aircraft);\r
+ if (!result) {\r
+ cerr << "Aircraft file " << aircraft << " was not found" << endl;\r
+ exit(-1);\r
+ }\r
+\r
+ FGInitialCondition IC(FDMExec);\r
+ if ( ! IC.Load("aircraft", aircraft, initialize)) {\r
+ cerr << "Initialization unsuccessful" << endl;\r
+ exit(-1);\r
+ }\r
+\r
+ return true;\r
+}\r
+\r
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
+\r
+bool FGScript::RunScript(void)\r
+{\r
+ vector <struct condition>::iterator iC = Conditions.begin();\r
+ bool truth = false;\r
+ bool WholeTruth = false;\r
+ unsigned i;\r
+\r
+ double currentTime = State->Getsim_time();\r
+ double newSetValue = 0;\r
+\r
+ if (currentTime > EndTime) return false;\r
+\r
+ while (iC < Conditions.end()) {\r
+ // determine whether the set of conditional tests for this condition equate\r
+ // to true\r
+ for (i=0; i<iC->TestValue.size(); i++) {\r
+ if (iC->Comparison[i] == "lt")\r
+ truth = State->GetParameter(iC->TestParam[i]) < iC->TestValue[i];\r
+ else if (iC->Comparison[i] == "le")\r
+ truth = State->GetParameter(iC->TestParam[i]) <= iC->TestValue[i];\r
+ else if (iC->Comparison[i] == "eq")\r
+ truth = State->GetParameter(iC->TestParam[i]) == iC->TestValue[i];\r
+ else if (iC->Comparison[i] == "ge")\r
+ truth = State->GetParameter(iC->TestParam[i]) >= iC->TestValue[i];\r
+ else if (iC->Comparison[i] == "gt")\r
+ truth = State->GetParameter(iC->TestParam[i]) > iC->TestValue[i];\r
+ else if (iC->Comparison[i] == "ne")\r
+ truth = State->GetParameter(iC->TestParam[i]) != iC->TestValue[i];\r
+ else\r
+ cerr << "Bad comparison" << endl;\r
+\r
+ if (i == 0) WholeTruth = truth;\r
+ else WholeTruth = WholeTruth && truth;\r
+\r
+ if (!truth && iC->Persistent[i] && iC->Triggered[i]) iC->Triggered[i] = false;\r
+ }\r
+\r
+ // if the conditions are true, do the setting of the desired parameters\r
+\r
+ if (WholeTruth) {\r
+ for (i=0; i<iC->SetValue.size(); i++) {\r
+ if ( ! iC->Triggered[i]) {\r
+ iC->OriginalValue[i] = State->GetParameter(iC->SetParam[i]);\r
+ switch (iC->Type[i]) {\r
+ case FG_VALUE:\r
+ iC->newValue[i] = iC->SetValue[i];\r
+ break;\r
+ case FG_DELTA:\r
+ iC->newValue[i] = iC->OriginalValue[i] + iC->SetValue[i];\r
+ break;\r
+ case FG_BOOL:\r
+ iC->newValue[i] = iC->SetValue[i];\r
+ break;\r
+ default:\r
+ cerr << "Invalid Type specified" << endl;\r
+ break;\r
+ }\r
+ iC->Triggered[i] = true;\r
+ iC->StartTime[i] = currentTime;\r
+ }\r
+\r
+ switch (iC->Action[i]) {\r
+ case FG_RAMP:\r
+ newSetValue = (currentTime - iC->StartTime[i])/(iC->TC[i])\r
+ * (iC->newValue[i] - iC->OriginalValue[i]) + iC->OriginalValue[i];\r
+ if (newSetValue > iC->newValue[i]) newSetValue = iC->newValue[i];\r
+ break;\r
+ case FG_STEP:\r
+ newSetValue = iC->newValue[i];\r
+ break;\r
+ case FG_EXP:\r
+ newSetValue = (1 - exp(-(currentTime - iC->StartTime[i])/(iC->TC[i])))\r
+ * (iC->newValue[i] - iC->OriginalValue[i]) + iC->OriginalValue[i];\r
+ break;\r
+ default:\r
+ cerr << "Invalid Action specified" << endl;\r
+ break;\r
+ }\r
+ State->SetParameter(iC->SetParam[i], newSetValue);\r
+ }\r
+ }\r
+ iC++;\r
+ }\r
+ return true;\r
+}\r
+\r
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
+// The bitmasked value choices are as follows:\r
+// unset: In this case (the default) JSBSim would only print\r
+// out the normally expected messages, essentially echoing\r
+// the config files as they are read. If the environment\r
+// variable is not set, debug_lvl is set to 1 internally\r
+// 0: This requests JSBSim not to output any messages\r
+// whatsoever.\r
+// 1: This value explicity requests the normal JSBSim\r
+// startup messages\r
+// 2: This value asks for a message to be printed out when\r
+// a class is instantiated\r
+// 4: When this value is set, a message is displayed when a\r
+// FGModel object executes its Run() method\r
+// 8: When this value is set, various runtime state variables\r
+// are printed out periodically\r
+// 16: When set various parameters are sanity checked and\r
+// a message is printed out when they go out of bounds\r
+\r
+void FGScript::Debug(int from)\r
+{\r
+ unsigned int i;\r
+\r
+ if (debug_lvl <= 0) return;\r
+\r
+ if (debug_lvl & 1) { // Standard console startup message output\r
+ if (from == 0) { // Constructor\r
+ } else if (from == 3) {\r
+ } else if (from == 4) { // print out script data\r
+ vector <struct condition>::iterator iterConditions = Conditions.begin();\r
+ int count=0;\r
+\r
+ cout << "\n Script goes from " << StartTime << " to " << EndTime\r
+ << " with dt = " << State->Getdt() << endl << endl;\r
+\r
+ while (iterConditions < Conditions.end()) {\r
+ cout << " Condition: " << count++ << endl;\r
+ cout << " if (";\r
+\r
+ for (i=0; i<iterConditions->TestValue.size(); i++) {\r
+ if (i>0) cout << " and" << endl << " ";\r
+ cout << "(" << State->paramdef[iterConditions->TestParam[i]]\r
+ << iterConditions->Comparison[i] << " "\r
+ << iterConditions->TestValue[i] << ")";\r
+ }\r
+ cout << ") then {";\r
+\r
+ for (i=0; i<iterConditions->SetValue.size(); i++) {\r
+ cout << endl << " set" << State->paramdef[iterConditions->SetParam[i]]\r
+ << "to " << iterConditions->SetValue[i];\r
+\r
+ switch (iterConditions->Type[i]) {\r
+ case FG_VALUE:\r
+ cout << " (constant";\r
+ break;\r
+ case FG_DELTA:\r
+ cout << " (delta";\r
+ break;\r
+ case FG_BOOL:\r
+ cout << " (boolean";\r
+ break;\r
+ default:\r
+ cout << " (unspecified type";\r
+ }\r
+\r
+ switch (iterConditions->Action[i]) {\r
+ case FG_RAMP:\r
+ cout << " via ramp";\r
+ break;\r
+ case FG_STEP:\r
+ cout << " via step";\r
+ break;\r
+ case FG_EXP:\r
+ cout << " via exponential approach";\r
+ break;\r
+ default:\r
+ cout << " via unspecified action";\r
+ }\r
+\r
+ if (!iterConditions->Persistent[i]) cout << endl\r
+ << " once";\r
+ else cout << endl\r
+ << " repeatedly";\r
+\r
+ if (iterConditions->Action[i] == FG_RAMP ||\r
+ iterConditions->Action[i] == FG_EXP) cout << endl\r
+ << " with time constant "\r
+ << iterConditions->TC[i];\r
+ }\r
+ cout << ")" << endl << " }" << endl << endl;\r
+\r
+ iterConditions++;\r
+ }\r
+\r
+ cout << endl;\r
+ }\r
+ }\r
+ if (debug_lvl & 2 ) { // Instantiation/Destruction notification\r
+ if (from == 0) cout << "Instantiated: FGScript" << endl;\r
+ if (from == 1) cout << "Destroyed: FGScript" << endl;\r
+ }\r
+ if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects\r
+ }\r
+ if (debug_lvl & 8 ) { // Runtime state variables\r
+ }\r
+ if (debug_lvl & 16) { // Sanity checking\r
+ }\r
+}\r
+\r
--- /dev/null
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
+ Header: FGScript.h\r
+ Author: Jon Berndt\r
+ Date started: 12/21/2001\r
+\r
+ ------------- Copyright (C) 2001 Jon S. Berndt (jsb@hal-pc.org) -------------\r
+\r
+ This program is free software; you can redistribute it and/or modify it under\r
+ the terms of the GNU General Public License as published by the Free Software\r
+ Foundation; either version 2 of the License, or (at your option) any later\r
+ version.\r
+\r
+ This program is distributed in the hope that it will be useful, but WITHOUT\r
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
+ FOR A PARTICULAR PURPOSE. See the GNU General Public License for more\r
+ details.\r
+\r
+ You should have received a copy of the GNU General Public License along with\r
+ this program; if not, write to the Free Software Foundation, Inc., 59 Temple\r
+ Place - Suite 330, Boston, MA 02111-1307, USA.\r
+\r
+ Further information about the GNU General Public License can also be found on\r
+ the world wide web at http://www.gnu.org.\r
+\r
+HISTORY\r
+--------------------------------------------------------------------------------\r
+12/21/01 JSB Created\r
+\r
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
+SENTRY\r
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
+\r
+#ifndef FGSCRIPT_HEADER_H\r
+#define FGSCRIPT_HEADER_H\r
+\r
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
+INCLUDES\r
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
+\r
+#include "FGJSBBase.h"\r
+#include "FGState.h"\r
+#include "FGFDMExec.h"\r
+#include <vector>\r
+\r
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
+DEFINITIONS\r
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
+\r
+#define ID_FGSCRIPT "$Id$"\r
+\r
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
+FORWARD DECLARATIONS\r
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
+\r
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
+COMMENTS, REFERENCES, and NOTES [use "class documentation" below for API docs]\r
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
+\r
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
+CLASS DOCUMENTATION\r
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
+\r
+/** Encapsulates the JSBSim scripting capability.\r
+ @author Jon S. Berndt\r
+ @version $Id$\r
+\r
+ <h4>Scripting support provided via FGScript.</h4>\r
+\r
+ <p>There is simple scripting support provided in the FGScript\r
+ class. Commands are specified using the <u>Simple Scripting\r
+ Directives for JSBSim</u> (SSDJ). The script file is in XML\r
+ format. A test condition (or conditions) can be set up in the\r
+ script and when the condition evaluates to true, the specified\r
+ action[s] is/are taken. A test condition can be <em>persistent</em>,\r
+ meaning that if a test condition evaluates to true, then passes\r
+ and evaluates to false, the condition is reset and may again be\r
+ triggered. When the set of tests evaluates to true for a given\r
+ condition, an item may be set to another value. This value might\r
+ be a boolean, a value, or a delta value, and the change from the\r
+ current value to the new value can be either via a step function,\r
+ a ramp, or an exponential approach. The speed of a ramp or\r
+ approach is specified via the time constant. Here is the format\r
+ of the script file:</p>\r
+\r
+ <pre><strong><?xml version="1.0"?>\r
+ <runscript name="C172-01A">\r
+\r
+ <!--\r
+ This run is for testing C172 runs\r
+ -->\r
+\r
+ <use aircraft="c172">\r
+ <use initialize="reset00">\r
+\r
+ <run start="0.0" end="4.5" dt="0.05">\r
+ <when>\r
+ <parameter name="FG_TIME" comparison="ge" value="0.25">\r
+ <parameter name="FG_TIME" comparison="le" value="0.50">\r
+ <set name="FG_AILERON_CMD" type="FG_VALUE" value="0.25"\r
+ action="FG_STEP" persistent="false" tc ="0.25">\r
+ </when>\r
+ <when>\r
+ <parameter name="FG_TIME" comparison="ge" value="0.5">\r
+ <parameter name="FG_TIME" comparison="le" value="1.5">\r
+ <set name="FG_AILERON_CMD" type="FG_DELTA" value="0.5"\r
+ action="FG_EXP" persistent="false" tc ="0.5">\r
+ </when>\r
+ <when>\r
+ <parameter name="FG_TIME" comparison="ge" value="1.5">\r
+ <parameter name="FG_TIME" comparison="le" value="2.5">\r
+ <set name="FG_RUDDER_CMD" type="FG_DELTA" value="0.5"\r
+ action="FG_RAMP" persistent="false" tc ="0.5">\r
+ </when>\r
+ </run>\r
+\r
+ </runscript></strong></pre>\r
+\r
+ <p>The first line must always be present. The second line\r
+ identifies this file as a script file, and gives a descriptive\r
+ name to the script file. Comments are next, delineated by the\r
+ <!-- and --> symbols. The aircraft and initialization files\r
+ to be used are specified in the "use" lines. Next,\r
+ comes the "run" section, where the conditions are\r
+ described in "when" clauses.</p>\r
+\r
+*/\r
+\r
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
+CLASS DECLARATION\r
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
+\r
+class FGScript : public FGJSBBase\r
+{\r
+public:\r
+ /// Default constructor\r
+ FGScript(FGFDMExec* exec);\r
+\r
+ /// Default destructor\r
+ ~FGScript();\r
+\r
+ /** Loads a script to drive JSBSim (usually in standalone mode).\r
+ The language is the Simple Script Directives for JSBSim (SSDJ).\r
+ @param script the filename (including path name, if any) for the script.\r
+ @return true if successful */\r
+ bool LoadScript(string script);\r
+\r
+ /** This function is called each pass through the executive Run() method IF\r
+ scripting is enabled. \r
+ @return false if script should exit (i.e. if time limits are violated */\r
+ bool RunScript(void);\r
+\r
+private:\r
+ enum eAction {\r
+ FG_RAMP = 1,\r
+ FG_STEP = 2,\r
+ FG_EXP = 3\r
+ };\r
+\r
+ enum eType {\r
+ FG_VALUE = 1,\r
+ FG_DELTA = 2,\r
+ FG_BOOL = 3\r
+ };\r
+\r
+ struct condition {\r
+ vector <eParam> TestParam;\r
+ vector <eParam> SetParam;\r
+ vector <double> TestValue;\r
+ vector <double> SetValue;\r
+ vector <string> Comparison;\r
+ vector <double> TC;\r
+ vector <bool> Persistent;\r
+ vector <eAction> Action;\r
+ vector <eType> Type;\r
+ vector <bool> Triggered;\r
+ vector <double> newValue;\r
+ vector <double> OriginalValue;\r
+ vector <double> StartTime;\r
+ vector <double> EndTime;\r
+\r
+ condition() {\r
+ }\r
+ };\r
+\r
+ bool Scripted;\r
+\r
+ string ScriptName;\r
+ double StartTime;\r
+ double EndTime;\r
+ vector <struct condition> Conditions;\r
+\r
+ FGFDMExec* FDMExec;\r
+ FGState* State;\r
+ void Debug(int from);\r
+};\r
+\r
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
+#endif\r
+\r