Read KEMT ground network from file instead of hardwiring it into the code.
This commit is contained in:
parent
38b3f48d41
commit
3447ab6e57
2 changed files with 193 additions and 328 deletions
|
@ -18,355 +18,209 @@
|
|||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
#include <simgear/misc/sg_path.hxx>
|
||||
#include <simgear/math/sg_random.h>
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
#include <simgear/misc/sgstream.hxx>
|
||||
#include <simgear/constants.h>
|
||||
#include <Main/globals.hxx>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include STL_FSTREAM
|
||||
|
||||
#include "ground.hxx"
|
||||
|
||||
FGGround::FGGround() {
|
||||
display = false;
|
||||
networkLoadOK = false;
|
||||
}
|
||||
|
||||
FGGround::~FGGround() {
|
||||
}
|
||||
|
||||
void FGGround::Init() {
|
||||
display = false;
|
||||
void FGGround::ParseRwyExits(node* np, char* es) {
|
||||
char* token;
|
||||
char estr[20];
|
||||
strcpy(estr, es);
|
||||
const char delimiters[] = "-";
|
||||
token = strtok(estr, delimiters);
|
||||
while(token != NULL) {
|
||||
int i = atoi(token);
|
||||
//cout << "token = " << token << endl;
|
||||
//cout << "rwy number = " << i << endl;
|
||||
//runways[(atoi(token))].exits.push_back(np);
|
||||
runways[i].exits.push_back(np);
|
||||
//cout << "token = " << token << '\n';
|
||||
token = strtok(NULL, delimiters);
|
||||
}
|
||||
}
|
||||
|
||||
// Build hardwired (very simplified) logical network for KEMT for now
|
||||
// Once it works we'll progress to reading KEMT data from file,
|
||||
// and finally to reading any airport with specified taxiway data from file.
|
||||
|
||||
// Load the ground logical network of the current instances airport
|
||||
// Return true if successfull.
|
||||
// TODO - currently the file is assumed to reside in the base/ATC directory.
|
||||
// This might change to something more thought out in the future.
|
||||
bool FGGround::LoadNetwork() {
|
||||
node* np;
|
||||
arc* ap;
|
||||
Gate* gp;
|
||||
|
||||
ifstream fin;
|
||||
SGPath path = globals->get_fg_root();
|
||||
//string taxiPath = "ATC/" + ident + ".taxi";
|
||||
string taxiPath = "ATC/KEMT.taxi"; // FIXME - HARDWIRED FOR TESTING
|
||||
path.append(taxiPath);
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_INFO, "Trying to read taxiway data for " << ident << "...");
|
||||
//cout << "Trying to read taxiway data for " << ident << "..." << endl;
|
||||
fin.open(path.c_str(), ios::in);
|
||||
if(!fin) {
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "Unable to open taxiway data input file " << path.c_str());
|
||||
//cout << "Unable to open taxiway data input file " << path.c_str() << endl;
|
||||
return(false);
|
||||
}
|
||||
|
||||
char ch;
|
||||
char buf[30];
|
||||
while(!fin.eof()) {
|
||||
fin >> buf;
|
||||
// Node, arc, or [End]?
|
||||
//cout << "Read in ground network element type = " << buf << endl;
|
||||
if(!strcmp(buf, "[End]")) { // TODO - maybe make this more robust to spelling errors by just looking for '['
|
||||
cout << "Done reading " << path.c_str() << endl;
|
||||
break;
|
||||
} else if(!strcmp(buf, "N")) {
|
||||
// Node
|
||||
np = new node;
|
||||
np->struct_type = NODE;
|
||||
fin >> buf;
|
||||
np->nodeID = atoi(buf);
|
||||
fin >> buf;
|
||||
np->pos.setlon(atof(buf));
|
||||
fin >> buf;
|
||||
np->pos.setlat(atof(buf));
|
||||
fin >> buf;
|
||||
np->pos.setelev(atof(buf));
|
||||
fin >> buf; // node type
|
||||
if(!strcmp(buf, "J")) {
|
||||
np->type = JUNCTION;
|
||||
} else if(!strcmp(buf, "T")) {
|
||||
np->type = TJUNCTION;
|
||||
} else if(!strcmp(buf, "H")) {
|
||||
np->type = HOLD;
|
||||
} else {
|
||||
cout << "**** ERROR ***** Unknown node type in taxi network...\n";
|
||||
delete np;
|
||||
return(false);
|
||||
}
|
||||
fin >> buf; // rwy exit information - gets parsed later - FRAGILE - will break if buf is reused.
|
||||
// Now the name
|
||||
np->name = "";
|
||||
while(1) {
|
||||
fin.unsetf(ios::skipws);
|
||||
fin >> ch;
|
||||
np->name += ch;
|
||||
if((ch == '"') || (ch == 0x0A)) {
|
||||
break;
|
||||
} // we shouldn't need the 0x0A but it makes a nice safely in case someone leaves off the "
|
||||
}
|
||||
fin.setf(ios::skipws);
|
||||
network.push_back(np);
|
||||
// FIXME - fragile - replies on buf not getting modified from exits read to here
|
||||
// see if we also need to push it onto the runway exit list
|
||||
cout << "strlen(buf) = " << strlen(buf) << endl;
|
||||
if(strlen(buf) > 2) {
|
||||
cout << "Calling ParseRwyExits for " << buf << endl;
|
||||
ParseRwyExits(np, buf);
|
||||
}
|
||||
} else if(!strcmp(buf, "A")) {
|
||||
ap = new arc;
|
||||
ap->struct_type = ARC;
|
||||
fin >> buf;
|
||||
ap->n1 = atoi(buf);
|
||||
fin >> buf;
|
||||
ap->n2 = atoi(buf);
|
||||
fin >> buf;
|
||||
if(!strcmp(buf, "R")) {
|
||||
ap->type = RUNWAY;
|
||||
} else if(!strcmp(buf, "T")) {
|
||||
ap->type = TAXIWAY;
|
||||
} else {
|
||||
cout << "**** ERROR ***** Unknown arc type in taxi network...\n";
|
||||
delete ap;
|
||||
return(false);
|
||||
}
|
||||
// directed?
|
||||
fin >> buf;
|
||||
if(!strcmp(buf, "Y")) {
|
||||
ap->directed = true;
|
||||
} else if(!strcmp(buf, "N")) {
|
||||
ap->directed = false;
|
||||
} else {
|
||||
cout << "**** ERROR ***** Unknown arc directed value in taxi network - should be Y/N !!!\n";
|
||||
delete ap;
|
||||
return(false);
|
||||
}
|
||||
// Now the name
|
||||
ap->name = "";
|
||||
while(1) {
|
||||
fin.unsetf(ios::skipws);
|
||||
fin >> ch;
|
||||
ap->name += ch;
|
||||
if((ch == '"') || (ch == 0x0A)) {
|
||||
break;
|
||||
} // we shouldn't need the 0x0A but it makes a nice safely in case someone leaves off the "
|
||||
}
|
||||
fin.setf(ios::skipws);
|
||||
network[ap->n1]->arcs.push_back(ap);
|
||||
network[ap->n2]->arcs.push_back(ap);
|
||||
} else if(!strcmp(buf, "G")) {
|
||||
gp = new Gate;
|
||||
gp->struct_type = NODE;
|
||||
gp->type = GATE;
|
||||
fin >> buf;
|
||||
gp->nodeID = atoi(buf);
|
||||
fin >> buf;
|
||||
gp->pos.setlon(atof(buf));
|
||||
fin >> buf;
|
||||
gp->pos.setlat(atof(buf));
|
||||
fin >> buf;
|
||||
gp->pos.setelev(atof(buf));
|
||||
fin >> buf; // gate type - ignore this for now
|
||||
fin >> buf; // gate heading
|
||||
gp->heading = atoi(buf);
|
||||
// Now the name
|
||||
gp->name = "";
|
||||
while(1) {
|
||||
fin.unsetf(ios::skipws);
|
||||
fin >> ch;
|
||||
gp->name += ch;
|
||||
if((ch == '"') || (ch == 0x0A)) {
|
||||
break;
|
||||
} // we shouldn't need the 0x0A but it makes a nice safely in case someone leaves off the "
|
||||
}
|
||||
fin.setf(ios::skipws);
|
||||
network.push_back(gp);
|
||||
} else {
|
||||
// Something has gone seriously pear-shaped
|
||||
cout << "********* ERROR - unknown ground network element type... aborting read of " << path.c_str() << '\n';
|
||||
return(false);
|
||||
}
|
||||
|
||||
fin >> skipeol;
|
||||
}
|
||||
return(true);
|
||||
}
|
||||
|
||||
void FGGround::Init() {
|
||||
display = false;
|
||||
|
||||
// For now we'll hardwire the threshold end
|
||||
Point3D P010(-118.037483, 34.081358, 296 * SG_FEET_TO_METER);
|
||||
double hdg = 25.32;
|
||||
ortho.Init(P010, hdg);
|
||||
|
||||
// HARDWIRED FOR TESTING - for now we'll only allow exit at each end of runway
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
// NODES
|
||||
///////////////////////////////////////////////////////
|
||||
|
||||
// node - runway01 threshold
|
||||
Point3D p1(-118.0372167, 34.08178333, 0.0);
|
||||
np = new node;
|
||||
np->struct_type = NODE;
|
||||
np->pos = p1;
|
||||
np->orthoPos = ortho.ConvertToLocal(p1);
|
||||
np->name = "rwy 01";
|
||||
np->nodeID = 0;
|
||||
np->type = JUNCTION;
|
||||
runways[1].exits.push_back(np);
|
||||
runways[19].exits.push_back(np);
|
||||
//np->max_turn_radius = ...
|
||||
network.push_back(np);
|
||||
|
||||
// node - runway19 threshold
|
||||
Point3D p2(-118.0321833, 34.09066667, 0.0);
|
||||
np = new node;
|
||||
np->struct_type = NODE;
|
||||
np->pos = p2;
|
||||
np->orthoPos = ortho.ConvertToLocal(p2);
|
||||
np->name = "rwy 19";
|
||||
np->nodeID = 1;
|
||||
np->type = JUNCTION;
|
||||
runways[1].exits.push_back(np);
|
||||
runways[19].exits.push_back(np);
|
||||
//np->max_turn_radius = ...
|
||||
network.push_back(np);
|
||||
|
||||
// node - AlphaSouth
|
||||
Point3D p3(-118.0369167, 34.08166667, 0.0);
|
||||
np = new node;
|
||||
np->struct_type = NODE;
|
||||
np->pos = p3;
|
||||
np->orthoPos = ortho.ConvertToLocal(p3);
|
||||
np->name = "";
|
||||
np->nodeID = 2;
|
||||
np->type = HOLD;
|
||||
//np->max_turn_radius = ...
|
||||
network.push_back(np);
|
||||
|
||||
// node - AlphaNorth
|
||||
Point3D p4(-118.03185, 34.0906, 0.0);
|
||||
np = new node;
|
||||
np->struct_type = NODE;
|
||||
np->pos = p4;
|
||||
np->orthoPos = ortho.ConvertToLocal(p4);
|
||||
np->name = "";
|
||||
np->nodeID = 3;
|
||||
np->type = HOLD;
|
||||
//np->max_turn_radius = ...
|
||||
network.push_back(np);
|
||||
|
||||
// node - southern turnoff to parking
|
||||
Point3D p5(-118.03515, 34.0848, 0.0);
|
||||
np = new node;
|
||||
np->struct_type = NODE;
|
||||
np->pos = p5;
|
||||
np->orthoPos = ortho.ConvertToLocal(p5);
|
||||
np->name = "";
|
||||
np->nodeID = 4;
|
||||
np->type = TJUNCTION;
|
||||
//np->max_turn_radius = ...
|
||||
network.push_back(np);
|
||||
|
||||
// node - northern turnoff to parking
|
||||
Point3D p6(-118.0349667, 34.08511667, 0.0);
|
||||
np = new node;
|
||||
np->struct_type = NODE;
|
||||
np->pos = p6;
|
||||
np->orthoPos = ortho.ConvertToLocal(p6);
|
||||
np->name = "";
|
||||
np->nodeID = 5;
|
||||
np->type = TJUNCTION;
|
||||
//np->max_turn_radius = ...
|
||||
network.push_back(np);
|
||||
|
||||
// GATES
|
||||
|
||||
// node - Turn into gate 1 (Western-most gate, ie. nearest rwy)
|
||||
Point3D p7(-118.0348333, 34.08466667, 0.0);
|
||||
np = new node;
|
||||
np->struct_type = NODE;
|
||||
np->pos = p7;
|
||||
np->orthoPos = ortho.ConvertToLocal(p7);
|
||||
np->name = "";
|
||||
np->nodeID = 6;
|
||||
np->type = TJUNCTION;
|
||||
//np->max_turn_radius = ...
|
||||
network.push_back(np);
|
||||
|
||||
// node - Gate 1
|
||||
Point3D p8(-118.0347333, 34.08483333, 0.0);
|
||||
gp = new Gate;
|
||||
gp->struct_type = NODE;
|
||||
gp->pos = p8;
|
||||
gp->orthoPos = ortho.ConvertToLocal(p8);
|
||||
gp->name = "";
|
||||
gp->nodeID = 7;
|
||||
gp->type = GATE;
|
||||
gp->heading = 10;
|
||||
//np->max_turn_radius = ...
|
||||
network.push_back(gp);
|
||||
gates[1] = *gp;
|
||||
|
||||
// node - Turn out of gate 1
|
||||
Point3D p9(-118.03465, 34.08498333, 0.0);
|
||||
np = new node;
|
||||
np->struct_type = NODE;
|
||||
np->pos = p9;
|
||||
np->orthoPos = ortho.ConvertToLocal(p9);
|
||||
np->name = "";
|
||||
np->nodeID = 8;
|
||||
np->type = TJUNCTION;
|
||||
//np->max_turn_radius = ...
|
||||
network.push_back(np);
|
||||
|
||||
// node - Turn into gate 2
|
||||
Point3D p10(-118.0346, 34.08456667, 0.0);
|
||||
np = new node;
|
||||
np->struct_type = NODE;
|
||||
np->pos = p10;
|
||||
np->orthoPos = ortho.ConvertToLocal(p10);
|
||||
np->name = "";
|
||||
np->nodeID = 9;
|
||||
np->type = TJUNCTION;
|
||||
//np->max_turn_radius = ...
|
||||
network.push_back(np);
|
||||
gates[2] = *gp;
|
||||
|
||||
// node - Gate 2
|
||||
Point3D p11(-118.0345167, 34.08473333, 0.0);
|
||||
gp = new Gate;
|
||||
gp->struct_type = NODE;
|
||||
gp->pos = p11;
|
||||
gp->orthoPos = ortho.ConvertToLocal(p11);
|
||||
gp->name = "";
|
||||
gp->nodeID = 10;
|
||||
gp->type = GATE;
|
||||
gp->heading = 10;
|
||||
//np->max_turn_radius = ...
|
||||
network.push_back(gp);
|
||||
|
||||
// node - Turn out of gate 2
|
||||
Point3D p12(-118.0344167, 34.0849, 0.0);
|
||||
np = new node;
|
||||
np->struct_type = NODE;
|
||||
np->pos = p12;
|
||||
np->orthoPos = ortho.ConvertToLocal(p12);
|
||||
np->name = "";
|
||||
np->nodeID = 11;
|
||||
np->type = TJUNCTION;
|
||||
//np->max_turn_radius = ...
|
||||
network.push_back(np);
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
// ARCS
|
||||
/////////////////////////////////////////////////////////
|
||||
|
||||
// Each arc connects two nodes
|
||||
// Eventually the nodeID of the nodes that the arc connects will be read from file
|
||||
// For now we just 'know' them !!
|
||||
|
||||
// arc - the runway - connects nodes 0 and 1
|
||||
ap = new arc;
|
||||
ap->struct_type = ARC;
|
||||
ap->name = "";
|
||||
ap->type = RUNWAY;
|
||||
ap->directed = false;
|
||||
ap->n1 = 0;
|
||||
ap->n2 = 1;
|
||||
network[0]->arcs.push_back(ap);
|
||||
network[1]->arcs.push_back(ap);
|
||||
|
||||
// arc - the exit from 01 threshold to alpha - connects nodes 0 and 2
|
||||
ap = new arc;
|
||||
ap->struct_type = ARC;
|
||||
ap->name = "";
|
||||
ap->type = TAXIWAY;
|
||||
ap->directed = false;
|
||||
ap->n1 = 0;
|
||||
ap->n2 = 2;
|
||||
network[0]->arcs.push_back(ap);
|
||||
network[2]->arcs.push_back(ap);
|
||||
|
||||
// arc - the exit from 19 threshold to alpha - connects nodes 1 and 3
|
||||
ap = new arc;
|
||||
ap->struct_type = ARC;
|
||||
ap->name = "";
|
||||
ap->type = TAXIWAY;
|
||||
ap->directed = false;
|
||||
ap->n1 = 1;
|
||||
ap->n2 = 3;
|
||||
network[1]->arcs.push_back(ap);
|
||||
network[3]->arcs.push_back(ap);
|
||||
|
||||
// arc - Alpha south - connects nodes 2 and 4
|
||||
ap = new arc;
|
||||
ap->struct_type = ARC;
|
||||
ap->name = "";
|
||||
ap->type = TAXIWAY;
|
||||
ap->directed = false;
|
||||
ap->n1 = 2;
|
||||
ap->n2 = 4;
|
||||
network[2]->arcs.push_back(ap);
|
||||
network[4]->arcs.push_back(ap);
|
||||
|
||||
// arc - Alpha middle - connects nodes 4 and 5
|
||||
ap = new arc;
|
||||
ap->struct_type = ARC;
|
||||
ap->name = "";
|
||||
ap->type = TAXIWAY;
|
||||
ap->directed = false;
|
||||
ap->n1 = 4;
|
||||
ap->n2 = 5;
|
||||
network[4]->arcs.push_back(ap);
|
||||
network[5]->arcs.push_back(ap);
|
||||
|
||||
// arc - Alpha North - connects nodes 3 and 5
|
||||
ap = new arc;
|
||||
ap->struct_type = ARC;
|
||||
ap->name = "";
|
||||
ap->type = TAXIWAY;
|
||||
ap->directed = false;
|
||||
ap->n1 = 3;
|
||||
ap->n2 = 5;
|
||||
network[3]->arcs.push_back(ap);
|
||||
network[5]->arcs.push_back(ap);
|
||||
|
||||
// arc - connects nodes 4 and 6
|
||||
ap = new arc;
|
||||
ap->struct_type = ARC;
|
||||
ap->name = "";
|
||||
ap->type = TAXIWAY;
|
||||
ap->directed = true;
|
||||
ap->n1 = 4;
|
||||
ap->n2 = 6;
|
||||
network[4]->arcs.push_back(ap);
|
||||
network[6]->arcs.push_back(ap);
|
||||
|
||||
// arc - connects nodes 6 and 9
|
||||
ap = new arc;
|
||||
ap->struct_type = ARC;
|
||||
ap->name = "";
|
||||
ap->type = TAXIWAY;
|
||||
ap->directed = true;
|
||||
ap->n1 = 6;
|
||||
ap->n2 = 9;
|
||||
network[6]->arcs.push_back(ap);
|
||||
network[9]->arcs.push_back(ap);
|
||||
|
||||
// arc - connects nodes 5 and 8
|
||||
ap = new arc;
|
||||
ap->struct_type = ARC;
|
||||
ap->name = "";
|
||||
ap->type = TAXIWAY;
|
||||
ap->directed = true;
|
||||
ap->n1 = 5;
|
||||
ap->n2 = 8;
|
||||
network[5]->arcs.push_back(ap);
|
||||
network[8]->arcs.push_back(ap);
|
||||
|
||||
// arc - connects nodes 8 and 11
|
||||
ap = new arc;
|
||||
ap->struct_type = ARC;
|
||||
ap->name = "";
|
||||
ap->type = TAXIWAY;
|
||||
ap->directed = true;
|
||||
ap->n1 = 8;
|
||||
ap->n2 = 11;
|
||||
network[8]->arcs.push_back(ap);
|
||||
network[11]->arcs.push_back(ap);
|
||||
|
||||
// arc - connects nodes 6 and 7
|
||||
ap = new arc;
|
||||
ap->struct_type = ARC;
|
||||
ap->name = "";
|
||||
ap->type = TAXIWAY;
|
||||
ap->directed = true;
|
||||
ap->n1 = 6;
|
||||
ap->n2 = 7;
|
||||
network[6]->arcs.push_back(ap);
|
||||
network[7]->arcs.push_back(ap);
|
||||
|
||||
// arc - connects nodes 7 and 8
|
||||
ap = new arc;
|
||||
ap->struct_type = ARC;
|
||||
ap->name = "";
|
||||
ap->type = TAXIWAY;
|
||||
ap->directed = true;
|
||||
ap->n1 = 7;
|
||||
ap->n2 = 8;
|
||||
network[7]->arcs.push_back(ap);
|
||||
network[8]->arcs.push_back(ap);
|
||||
|
||||
// arc - connects nodes 9 and 10
|
||||
ap = new arc;
|
||||
ap->struct_type = ARC;
|
||||
ap->name = "";
|
||||
ap->type = TAXIWAY;
|
||||
ap->directed = true;
|
||||
ap->n1 = 9;
|
||||
ap->n2 = 10;
|
||||
network[9]->arcs.push_back(ap);
|
||||
network[10]->arcs.push_back(ap);
|
||||
|
||||
// arc - connects nodes 10 and 11
|
||||
ap = new arc;
|
||||
ap->struct_type = ARC;
|
||||
ap->name = "";
|
||||
ap->type = TAXIWAY;
|
||||
ap->directed = true;
|
||||
ap->n1 = 10;
|
||||
ap->n2 = 11;
|
||||
network[10]->arcs.push_back(ap);
|
||||
network[11]->arcs.push_back(ap);
|
||||
networkLoadOK = LoadNetwork();
|
||||
}
|
||||
|
||||
void FGGround::Update() {
|
||||
|
@ -500,9 +354,11 @@ ground_network_path_type FGGround::GetPath(node* A, node* B) {
|
|||
// (might eventually be done by the AIMgr if and when lots of AI traffic is generated)
|
||||
|
||||
// Return a list of exits from a given runway
|
||||
// It is up to the calling function to check for non-zero size of returned array before use
|
||||
node_array_type FGGround::GetExits(int rwyID) {
|
||||
return(runways[rwyID].exits);
|
||||
}
|
||||
|
||||
#if 0
|
||||
void FGGround::NewArrival(plane_rec plane) {
|
||||
// What are we going to do here?
|
||||
|
|
|
@ -83,7 +83,7 @@ struct ground_network_element {
|
|||
|
||||
struct arc : public ground_network_element {
|
||||
int distance;
|
||||
char* name;
|
||||
string name;
|
||||
arc_type type;
|
||||
bool directed; //false if 2-way, true if 1-way.
|
||||
//This is a can of worms since arcs might be one way in different directions under different circumstances
|
||||
|
@ -240,6 +240,7 @@ public:
|
|||
|
||||
// Runway stuff - this might change in the future.
|
||||
// Get a list of exits from a given runway
|
||||
// It is up to the calling function to check for non-zero size of returned array before use
|
||||
node_array_type GetExits(int rwyID);
|
||||
|
||||
// Get a path from one node to another
|
||||
|
@ -297,8 +298,16 @@ private:
|
|||
// for failure modeling
|
||||
string trans_ident; // transmitted ident
|
||||
bool ground_failed; // ground failed?
|
||||
bool networkLoadOK; // Indicates whether LoadNetwork returned true or false at last attempt
|
||||
|
||||
friend istream& operator>> ( istream&, FGGround& );
|
||||
|
||||
// Load the logical ground network for this airport from file.
|
||||
// Return true if successfull.
|
||||
bool LoadNetwork();
|
||||
|
||||
// Parse a runway exit string and push the supplied node pointer onto the runway exit list
|
||||
void ParseRwyExits(node* np, char* es);
|
||||
};
|
||||
|
||||
inline istream&
|
||||
|
|
Loading…
Add table
Reference in a new issue