]> git.mxchange.org Git - flightgear.git/blob - src/AIModel/AIScenario.cxx
3bd1d375b84c8489d3e4807b4b587f6d9258cacb
[flightgear.git] / src / AIModel / AIScenario.cxx
1 // FGAIScenario.cxx - class for loading an AI scenario
2 // Written by David Culp, started May 2004
3 // - davidculp2@comcast.net
4 //
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License as
7 // published by the Free Software Foundation; either version 2 of the
8 // License, or (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful, but
11 // WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 // General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18
19 #include <cstdio>
20
21 #include <simgear/misc/sg_path.hxx>
22 #include <simgear/debug/logstream.hxx>
23 #include <simgear/structure/exception.hxx>
24 #include <simgear/constants.h>
25 #ifdef __BORLANDC__
26 #  define exception c_exception
27 #endif
28 #include <simgear/props/props.hxx>
29
30 #include <Main/globals.hxx>
31 #include <Main/fg_props.hxx>
32
33 #include "AIScenario.hxx"
34 #include "AIFlightPlan.hxx"
35
36 static list<string>
37 getAllStringNodeVals(const char* name, SGPropertyNode * entry_node);
38 static list<ParkPosition>
39 getAllOffsetNodeVals(const char* name, SGPropertyNode * entry_node);
40
41 FGAIScenario::FGAIScenario(const string &filename)
42 {
43   int i;
44   SGPath path( globals->get_fg_root() );
45   
46 //   cout << "/Data/AI/" << filename << endl;
47   
48   path.append( ("/Data/AI/" + filename + ".xml").c_str() );
49   SGPropertyNode root;
50   readProperties(path.str(), &root);
51   
52 //   cout <<"path " << path.str() << endl;
53   
54   try {
55       readProperties(path.str(), &root);
56   } catch (const sg_exception &e) {
57       SG_LOG(SG_GENERAL, SG_ALERT,
58        "Incorrect path specified for AI scenario: ");
59        
60        cout << path.str() << endl;
61       
62       return;
63   }
64
65   entries.clear();
66   SGPropertyNode * node = root.getNode("scenario");
67   for (i = 0; i < node->nChildren(); i++) { 
68      
69 //      cout << "Reading entity data entry " << i << endl;        
70      
71      SGPropertyNode * entry_node = node->getChild(i);
72
73      FGAIModelEntity* en = new FGAIModelEntity;
74      en->callsign       = entry_node->getStringValue("callsign", "none");
75      en->m_type         = entry_node->getStringValue("type", "aircraft");
76      en->m_class        = entry_node->getStringValue("class", "jet_transport");
77      en->path           = entry_node->getStringValue("model", "Models/Geometry/glider.ac");
78      en->flightplan     = entry_node->getStringValue("flightplan", "");
79      en->repeat         = entry_node->getBoolValue("repeat", false); 
80      en->latitude       = entry_node->getDoubleValue("latitude", 0.0); 
81      en->longitude      = entry_node->getDoubleValue("longitude", 0.0); 
82      en->altitude       = entry_node->getDoubleValue("altitude", 0.0); 
83      en->speed          = entry_node->getDoubleValue("speed", 0.0); 
84      en->heading        = entry_node->getDoubleValue("heading", 0.0); 
85      en->roll           = entry_node->getDoubleValue("roll", 0.0); 
86      en->azimuth        = entry_node->getDoubleValue("azimuth", 0.0); 
87      en->elevation      = entry_node->getDoubleValue("elevation", 0.0); 
88      en->rudder         = entry_node->getFloatValue("rudder", 0.0);
89      en->strength       = entry_node->getDoubleValue("strength-fps", 8.0);
90      en->turb_strength  = entry_node->getDoubleValue("strength-norm", 1.0);  
91      en->diameter       = entry_node->getDoubleValue("diameter-ft", 0.0);
92      en->height_msl     = entry_node->getDoubleValue("height-msl", 5000.0);
93      en->eda            = entry_node->getDoubleValue("eda", 0.007);
94      en->life           = entry_node->getDoubleValue("life", 900.0);
95      en->buoyancy       = entry_node->getDoubleValue("buoyancy", 0);
96      en->wind_from_east = entry_node->getDoubleValue("wind_from_east", 0);
97      en->wind_from_north = entry_node->getDoubleValue("wind_from_north", 0);
98      en->wind            = entry_node->getBoolValue  ("wind", false);
99      en->cd              = entry_node->getDoubleValue("cd", 0.029); 
100      en->mass            = entry_node->getDoubleValue("mass", 0.007); 
101      en->radius          = entry_node->getDoubleValue("turn-radius-ft", 2000);
102      en->TACAN_channel_ID= entry_node->getStringValue("TACAN-channel-ID", "029Y");
103      en->name            = entry_node->getStringValue("name", "Nimitz");
104      en->pennant_number  = entry_node->getStringValue("pennant-number", "");
105      en->wire_objects     = getAllStringNodeVals("wire", entry_node);
106      en->catapult_objects = getAllStringNodeVals("catapult", entry_node);
107      en->solid_objects    = getAllStringNodeVals("solid", entry_node);
108      en->ppositions       = getAllOffsetNodeVals("parking-pos", entry_node);
109      en->max_lat          = entry_node->getDoubleValue("max-lat", 0);
110      en->min_lat          = entry_node->getDoubleValue("min-lat",0);
111      en->max_long          = entry_node->getDoubleValue("max-long", 0);
112      en->min_long          = entry_node->getDoubleValue("min-long", 0);
113      list<ParkPosition> flolspos = getAllOffsetNodeVals("flols-pos", entry_node);
114      en->flols_offset     = flolspos.front().offset;
115
116      en->fp             = NULL;
117      if (en->flightplan != ""){
118         en->fp = new FGAIFlightPlan( en->flightplan );
119      }
120      entries.push_back( en );
121    }
122
123   entry_iterator = entries.begin();
124   //cout << entries.size() << " entries read." << endl;
125 }
126
127
128 FGAIScenario::~FGAIScenario()
129 {
130   entries.clear();
131 }
132
133
134 FGAIModelEntity* const
135 FGAIScenario::getNextEntry( void )
136 {
137   if (entries.size() == 0) return 0;
138   if (entry_iterator != entries.end()) {
139     return *entry_iterator++;
140   } else {
141     return 0;
142   }
143 }
144
145 int FGAIScenario::nEntries( void )
146 {
147   return entries.size();
148 }
149
150 static list<string>
151 getAllStringNodeVals(const char* name, SGPropertyNode * entry_node)
152 {
153   list<string> retval;
154   int i=0;
155   do {
156     char nodename[100];
157     snprintf(nodename, sizeof(nodename), "%s[%d]", name, i);
158     const char* objname = entry_node->getStringValue(nodename, 0);
159     if (objname == 0)
160       return retval;
161
162     retval.push_back(string(objname));
163     ++i;
164   } while (1);
165
166   return retval;
167 }
168
169 static list<ParkPosition>
170 getAllOffsetNodeVals(const char* name, SGPropertyNode * entry_node)
171 {
172   list<ParkPosition> retval;
173
174   vector<SGPropertyNode_ptr>::const_iterator it;
175   vector<SGPropertyNode_ptr> children = entry_node->getChildren(name);
176   for (it = children.begin(); it != children.end(); ++it) {
177     string name = (*it)->getStringValue("name", "unnamed");
178     double offset_x = (*it)->getDoubleValue("x-offset-m", 0);
179     double offset_y = (*it)->getDoubleValue("y-offset-m", 0);
180     double offset_z = (*it)->getDoubleValue("z-offset-m", 0);
181     double hd = (*it)->getDoubleValue("heading-offset-deg", 0);
182     ParkPosition pp(name, Point3D(offset_x, offset_y, offset_z), hd);
183     retval.push_back(pp);
184   }
185
186   return retval;
187 }
188
189 // end scenario.cxx
190