1 // FGAIScenario.cxx - class for loading an AI scenario
2 // Written by David Culp, started May 2004
3 // - davidculp2@comcast.net
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.
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.
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.
21 #include <simgear/misc/sg_path.hxx>
22 #include <simgear/debug/logstream.hxx>
23 #include <simgear/structure/exception.hxx>
24 #include <simgear/constants.h>
26 # define exception c_exception
28 #include <simgear/props/props.hxx>
30 #include <Main/globals.hxx>
31 #include <Main/fg_props.hxx>
33 #include "AIScenario.hxx"
34 #include "AIFlightPlan.hxx"
37 getAllStringNodeVals(const char* name, SGPropertyNode * entry_node);
38 static list<ParkPosition>
39 getAllOffsetNodeVals(const char* name, SGPropertyNode * entry_node);
41 FGAIScenario::FGAIScenario(const string &filename)
44 SGPath path( globals->get_fg_root() );
46 // cout << "/Data/AI/" << filename << endl;
48 path.append( ("/Data/AI/" + filename + ".xml").c_str() );
50 readProperties(path.str(), &root);
52 // cout <<"path " << path.str() << endl;
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: ");
60 cout << path.str() << endl;
66 SGPropertyNode * node = root.getNode("scenario");
67 for (i = 0; i < node->nChildren(); i++) {
69 // cout << "Reading entity data entry " << i << endl;
71 SGPropertyNode * entry_node = node->getChild(i);
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->getDoubleValue("repeat", 0.0);
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;
117 if (en->flightplan != ""){
118 en->fp = new FGAIFlightPlan( en->flightplan );
120 entries.push_back( en );
123 entry_iterator = entries.begin();
124 //cout << entries.size() << " entries read." << endl;
128 FGAIScenario::~FGAIScenario()
134 FGAIModelEntity* const
135 FGAIScenario::getNextEntry( void )
137 if (entries.size() == 0) return 0;
138 if (entry_iterator != entries.end()) {
139 return *entry_iterator++;
145 int FGAIScenario::nEntries( void )
147 return entries.size();
151 getAllStringNodeVals(const char* name, SGPropertyNode * entry_node)
157 snprintf(nodename, sizeof(nodename), "%s[%d]", name, i);
158 const char* objname = entry_node->getStringValue(nodename, 0);
162 retval.push_back(string(objname));
169 static list<ParkPosition>
170 getAllOffsetNodeVals(const char* name, SGPropertyNode * entry_node)
172 list<ParkPosition> retval;
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);