1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7 ------------- Copyright (C) 2004 Jon S. Berndt (jon@jsbsim.org) -------------
9 This program is free software; you can redistribute it and/or modify it under
10 the terms of the GNU Lesser General Public License as published by the Free Software
11 Foundation; either version 2 of the License, or (at your option) any later
14 This program is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
19 You should have received a copy of the GNU Lesser General Public License along with
20 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21 Place - Suite 330, Boston, MA 02111-1307, USA.
23 Further information about the GNU Lesser General Public License can also be found on
24 the world wide web at http://www.gnu.org.
26 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
28 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
33 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
41 #include "FGJSBBase.h"
42 #include "math/FGColumnVector3.h"
44 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
46 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
48 #define ID_XMLELEMENT "$Id: FGXMLElement.h,v 1.20 2014/01/13 10:46:02 ehofman Exp $"
50 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
52 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
56 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
58 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
60 /** Encapsulates an XML element.
61 This class handles the creation, storage, and manipulation of XML elements.
62 This class also can convert supplied values as follows:
64 convert ["from"]["to"] = factor, so: from * factor = to
65 - convert["M"]["FT"] = 3.2808399;
66 - convert["FT"]["M"] = 1.0/convert["M"]["FT"];
67 - convert["M2"]["FT2"] = convert["M"]["FT"]*convert["M"]["FT"];
68 - convert["FT2"]["M2"] = 1.0/convert["M2"]["FT2"];
69 - convert["FT"]["IN"] = 12.0;
70 - convert["IN"]["FT"] = 1.0/convert["FT"]["IN"];
71 - convert["LBS"]["KG"] = 0.45359237;
72 - convert["KG"]["LBS"] = 1.0/convert["LBS"]["KG"];
73 - convert["SLUG*FT2"]["KG*M2"] = 1.35594;
74 - convert["KG*M2"]["SLUG*FT2"] = 1.0/convert["SLUG*FT2"]["KG*M2"];
75 - convert["RAD"]["DEG"] = 360.0/(2.0*3.1415926);
76 - convert["DEG"]["RAD"] = 1.0/convert["RAD"]["DEG"];
77 - convert["LBS/FT"]["N/M"] = 14.5939;
78 - convert["LBS/FT/SEC"]["N/M/SEC"] = 14.5939;
79 - convert["N/M"]["LBS/FT"] = 1.0/convert["LBS/FT"]["N/M"];
80 - convert["N/M/SEC"]["LBS/FT/SEC"] = 1.0/convert["LBS/FT/SEC"]["N/M/SEC"];
81 - convert["WATTS"]["HP"] = 0.001341022;
82 - convert["HP"]["WATTS"] = 1.0/convert["WATTS"]["HP"];
83 - convert["N"]["LBS"] = 0.22482;
84 - convert["LBS"]["N"] = 1.0/convert["N"]["LBS"];
85 - convert["KTS"]["FT/SEC"] = ktstofps;
86 - convert["KG/MIN"]["LBS/MIN"] = convert["KG"]["LBS"];
87 - convert["LBS/HP*HR"]["KG/KW*HR"] = 0.6083;
88 - convert["KG/KW*HR"]["LBS/HP*HR"] = 1/convert["LBS/HP*HR"]["KG/KW*HR"];
89 - convert["KG/L"]["LBS/GAL"] = 8.3454045;
91 - convert["M"]["M"] = 1.00;
92 - convert["FT"]["FT"] = 1.00;
93 - convert["IN"]["IN"] = 1.00;
94 - convert["DEG"]["DEG"] = 1.00;
95 - convert["RAD"]["RAD"] = 1.00;
96 - convert["M2"]["M2"] = 1.00;
97 - convert["FT2"]["FT2"] = 1.00;
98 - convert["KG*M2"]["KG*M2"] = 1.00;
99 - convert["SLUG*FT2"]["SLUG*FT2"] = 1.00;
100 - convert["KG"]["KG"] = 1.00;
101 - convert["LBS"]["LBS"] = 1.00;
102 - convert["LBS/FT"]["LBS/FT"] = 1.00;
103 - convert["N/M"]["N/M"] = 1.00;
104 - convert["LBS/FT/SEC"]["LBS/FT/SEC"] = 1.00;
105 - convert["N/M/SEC"]["N/M/SEC"] = 1.00;
106 - convert["PSI"]["PSI"] = 1.00;
107 - convert["INHG"]["INHG"] = 1.00;
108 - convert["HP"]["HP"] = 1.00;
109 - convert["N"]["N"] = 1.00;
110 - convert["WATTS"]["WATTS"] = 1.00;
111 - convert["KTS"]["KTS"] = 1.0;
112 - convert["FT/SEC"]["FT/SEC"] = 1.0;
113 - convert["KG/MIN"]["KG/MIN"] = 1.0;
114 - convert["LBS/MIN"]["LBS/MIN"] = 1.0;
115 - convert["LBS/HP*HR"]["LBS/HP*HR"] = 1.0;
116 - convert["KG/KW*HR"]["KG/KW*HR"] = 1.0;
117 - convert["KG/L"]["KG/L"] = 1.0;
118 - convert["LBS/GAL"]["LBS/GAL"] = 1.0;
123 - M2 = meters squared
137 - GAL = gallon (U.S. liquid)
139 @author Jon S. Berndt
140 @version $Id: FGXMLElement.h,v 1.20 2014/01/13 10:46:02 ehofman Exp $
143 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
145 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
150 @param nm the name of this element (if given)
152 Element(const std::string& nm);
156 /** Determines if an element has the supplied attribute.
157 @param key specifies the attribute key to retrieve the value of.
158 @return true or false. */
159 bool HasAttribute(const std::string& key);
161 /** Retrieves an attribute.
162 @param key specifies the attribute key to retrieve the value of.
163 @return the key value (as a string), or the empty string if no such
165 std::string GetAttributeValue(const std::string& key);
167 /** Retrieves an attribute value as a double precision real number.
168 @param key specifies the attribute key to retrieve the value of.
169 @return the key value (as a number), or the HUGE_VAL if no such
171 double GetAttributeValueAsNumber(const std::string& key);
173 /** Retrieves the element name.
174 @return the element name, or the empty string if no name has been set.*/
175 const std::string& GetName(void) const {return name;}
177 /** Gets a line of data belonging to an element.
178 @param i the index of the data line to return (0 by default).
179 @return a string representing the data line requested, or the empty string
181 std::string GetDataLine(unsigned int i=0);
183 /// Returns the number of lines of data stored
184 unsigned int GetNumDataLines(void) {return (unsigned int)data_lines.size();}
186 /// Returns the number of child elements for this element.
187 unsigned int GetNumElements(void) {return (unsigned int)children.size();}
189 /// Returns the number of named child elements for this element.
190 unsigned int GetNumElements(const std::string& element_name);
192 /** Converts the element data to a number.
193 This function attempts to convert the first (and presumably only) line of
194 data "owned" by the element into a real number. If there is not exactly one
195 line of data owned by the element, then HUGE_VAL is returned.
196 @return the numeric value of the data owned by the element.*/
197 double GetDataAsNumber(void);
199 /** Returns a pointer to the element requested by index.
200 This function also resets an internal counter to the index, so that
201 subsequent calls to GetNextElement() will return the following
202 elements sequentially, until the last element is reached. At that point,
203 GetNextElement() will return NULL.
204 @param el the index of the requested element (0 by default)
205 @return a pointer to the Element, or 0 if no valid element exists. */
206 Element* GetElement(unsigned int el=0);
208 /** Returns a pointer to the next element in the list.
209 The function GetElement() must be called first to be sure that this
210 function will return the correct element. The call to GetElement() resets
211 the internal counter to zero. Subsequent calls to GetNextElement() return
212 a pointer to subsequent elements in the list. When the final element is
213 reached, 0 is returned.
214 @return a pointer to the next Element in the sequence, or 0 if no valid
215 Element is present. */
216 Element* GetNextElement(void);
218 /** Returns a pointer to the parent of an element.
219 @return a pointer to the parent Element, or 0 if this is the top level Element. */
220 Element* GetParent(void) {return parent;}
222 /** Returns the line number at which the element has been defined.
223 @return the line number
225 int GetLineNumber(void) const { return line_number; }
227 /** Returns the name of the file in which the element has been read.
228 @return the file name
230 const std::string& GetFileName(void) const { return file_name; }
232 /** Searches for a specified element.
233 Finds the first element that matches the supplied string, or simply the first
234 element if no search string is supplied. This function call resets the internal
235 element counter to the first element.
236 @param el the search string (empty string by default).
237 @return a pointer to the first element that matches the supplied search string. */
238 Element* FindElement(const std::string& el="");
240 /** Searches for the next element as specified.
241 This function would be called after FindElement() is first called (in order to
242 reset the internal counter). If no argument is supplied (or the empty string)
243 a pointer to the very next element is returned. Otherwise, the next occurence
244 of the named element is returned. If the end of the list is reached, 0 is
246 @param el the name of the next element to find.
247 @return the pointer to the found element, or 0 if no appropriate element us
249 Element* FindNextElement(const std::string& el="");
251 /** Searches for the named element and returns the string data belonging to it.
252 This function allows the data belonging to a named element to be returned
253 as a string. If no element is found, the empty string is returned. If no
254 argument is supplied, the data string for the first element is returned.
255 @param el the name of the element being searched for (the empty string by
257 @return the data value for the named element as a string, or the empty
258 string if the element cannot be found. */
259 std::string FindElementValue(const std::string& el="");
261 /** Searches for the named element and returns the data belonging to it as a number.
262 This function allows the data belonging to a named element to be returned
263 as a double. If no element is found, HUGE_VAL is returned. If no
264 argument is supplied, the data for the first element is returned.
265 @param el the name of the element being searched for (the empty string by
267 @return the data value for the named element as a double, or HUGE_VAL if the
269 double FindElementValueAsNumber(const std::string& el="");
271 /** Searches for the named element and converts and returns the data belonging to it.
272 This function allows the data belonging to a named element to be returned
273 as a double. If no element is found, HUGE_VAL is returned. If no
274 argument is supplied, the data for the first element is returned. Additionally,
275 this function converts the value from the units specified in the config file (via
276 the UNITS="" attribute in the element definition) to the native units used by
277 JSBSim itself, as specified by the target_units parameter. The currently
278 allowable unit conversions are seen in the source file FGXMLElement.cpp.
279 Also, see above in the main documentation for this class.
280 @param el the name of the element being searched for (the empty string by
282 @param target_units the string representing the native units used by JSBSim
283 to which the value returned will be converted.
284 @return the unit-converted data value for the named element as a double,
285 or HUGE_VAL if the data is missing. */
286 double FindElementValueAsNumberConvertTo(const std::string& el, const std::string& target_units);
288 /** Searches for the named element and converts and returns the data belonging to it.
289 This function allows the data belonging to a named element to be returned
290 as a double. If no element is found, HUGE_VAL is returned. If no
291 argument is supplied, the data for the first element is returned. Additionally,
292 this function converts the value from the units specified in the supplied_units
293 parameter to the units specified in the target_units parameter. JSBSim itself,
294 as specified by the target_units parameter. The currently allowable unit
295 conversions are seen in the source file FGXMLElement.cpp. Also, see above
296 in the main documentation for this class.
297 @param el the name of the element being searched for (the empty string by
299 @param supplied_units the string representing the units of the value as
300 supplied by the config file.
301 @param target_units the string representing the native units used by JSBSim
302 to which the value returned will be converted.
303 @return the unit-converted data value for the named element as a double,
304 or HUGE_VAL if the data is missing. */
305 double FindElementValueAsNumberConvertFromTo( const std::string& el,
306 const std::string& supplied_units,
307 const std::string& target_units);
309 /** Composes a 3-element column vector for the supplied location or orientation.
310 This function processes a LOCATION or ORIENTATION construct, returning a
311 filled-out 3-element column vector containing the X, Y, Z or ROLL, PITCH,
312 YAW elements found in the supplied element. If one of the mentioned components
313 is not found, that component is set to zero and a warning message is printed.
314 All three elements should be supplied.
315 @param target_units the string representing the native units used by JSBSim
316 to which the value returned will be converted.
317 @return a column vector object built from the LOCATION or ORIENT components. */
318 FGColumnVector3 FindElementTripletConvertTo( const std::string& target_units);
320 double DisperseValue(Element *e, double val, const std::string supplied_units="", const std::string target_units="");
322 /** This function sets the value of the parent class attribute to the supplied
324 @param p pointer to the parent Element. */
325 void SetParent(Element* p) {parent = p;}
327 /** Adds a child element to the list of children stored for this element.
328 * @param el Child element to add. */
329 void AddChildElement(Element* el) {children.push_back(el);}
331 /** Stores an attribute belonging to this element.
332 * @param name The string name of the attribute.
333 * @param value The string value of the attribute. */
334 void AddAttribute(const std::string& name, const std::string& value);
336 /** Stores data belonging to this element.
337 * @param d the data to store. */
338 void AddData(std::string d);
340 /** Prints the element.
341 * Prints this element and calls the Print routine for child elements.
342 * @param d The tab level. A level corresponds to a single space. */
343 void Print(unsigned int level=0);
345 /** Set the line number at which the element has been read.
346 * @param line line number.
348 void SetLineNumber(int line) { line_number = line; }
350 /** Set the name of the file in which the element has been read.
351 * @param name file name
353 void SetFileName(const std::string& name) { file_name = name; }
355 /** Return a string that contains a description of the location where the
356 * current XML element was read from.
357 * @return a string describing the file name and line number where the
360 std::string ReadFrom(void) const;
364 std::map <std::string, std::string> attributes;
365 std::vector <std::string> data_lines;
366 std::vector <Element*> children;
368 unsigned int element_index;
369 std::string file_name;
371 typedef std::map <std::string, std::map <std::string, double> > tMapConvert;
372 static tMapConvert convert;
373 static bool converterIsInitialized;
374 double GaussianRandomNumber(void);
377 } // namespace JSBSim
379 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%