+// This is a modified version of the constructor,
+// Which not only reads the waypoints from a
+// Flight plan file, but also adds the current
+// Position computed by the traffic manager, as well
+// as setting speeds and altitude computed by the
+// traffic manager.
+FGAIFlightPlan::FGAIFlightPlan(FGAIAircraft *ac,
+ const std::string& p,
+ double course,
+ time_t start,
+ FGAirport *dep,
+ FGAirport *arr,
+ bool firstLeg,
+ double radius,
+ double alt,
+ double lat,
+ double lon,
+ double speed,
+ const string& fltType,
+ const string& acType,
+ const string& airline)
+{
+ sid = 0;
+ repeat = false;
+ leg = 10;
+ gateId=0;
+ taxiRoute = 0;
+ start_time = start;
+ bool useInitialWayPoint = true;
+ bool useCurrentWayPoint = false;
+ SGPath path( globals->get_fg_root() );
+ path.append( "/AI/FlightPlans" );
+ path.append( p );
+
+ SGPropertyNode root;
+
+ // This is a bit of a hack:
+ // Normally the value of course will be used to evaluate whether
+ // or not a waypoint will be used for midair initialization of
+ // an AI aircraft. However, if a course value of 999 will be passed
+ // when an update request is received, which will by definition always be
+ // on the ground and should include all waypoints.
+ if (course == 999)
+ {
+ useInitialWayPoint = false;
+ useCurrentWayPoint = true;
+ }
+
+ if (path.exists())
+ {
+ try
+ {
+ readProperties(path.str(), &root);
+
+ SGPropertyNode * node = root.getNode("flightplan");
+
+ //waypoints.push_back( init_waypoint );
+ for (int i = 0; i < node->nChildren(); i++) {
+ //cout << "Reading waypoint " << i << endl;
+ waypoint* wpt = new waypoint;
+ SGPropertyNode * wpt_node = node->getChild(i);
+ wpt->name = wpt_node->getStringValue("name", "END");
+ wpt->latitude = wpt_node->getDoubleValue("lat", 0);
+ wpt->longitude = wpt_node->getDoubleValue("lon", 0);
+ wpt->altitude = wpt_node->getDoubleValue("alt", 0);
+ wpt->speed = wpt_node->getDoubleValue("ktas", 0);
+ //wpt->speed = speed;
+ wpt->crossat = wpt_node->getDoubleValue("crossat", -10000);
+ wpt->gear_down = wpt_node->getBoolValue("gear-down", false);
+ wpt->flaps_down= wpt_node->getBoolValue("flaps-down", false);
+
+ if (wpt->name == "END") wpt->finished = true;
+ else wpt->finished = false;
+ waypoints.push_back(wpt);
+ } // of node loop
+ } catch (const sg_exception &e) {
+ SG_LOG(SG_GENERAL, SG_WARN, "Error reading AI flight plan: " <<
+ e.getMessage() << " from " << e.getOrigin());
+ }
+ } else {
+ // cout << path.str() << endl;
+ // cout << "Trying to create this plan dynamically" << endl;
+ // cout << "Route from " << dep->id << " to " << arr->id << endl;
+ time_t now = time(NULL) + fgGetLong("/sim/time/warp");
+ time_t timeDiff = now-start;
+ leg = 1;
+ /*
+ if ((timeDiff > 300) && (timeDiff < 1200))
+ leg = 2;
+ else if ((timeDiff >= 1200) && (timeDiff < 1500))
+ leg = 3;
+ else if ((timeDiff >= 1500) && (timeDiff < 2000))
+ leg = 4;
+ else if (timeDiff >= 2000)
+ leg = 5;
+ */
+ if (timeDiff >= 2000)
+ leg = 5;
+
+ SG_LOG(SG_GENERAL, SG_INFO, "Route from " << dep->getId() << " to " << arr->getId() << ". Set leg to : " << leg << " " << ac->getTrafficRef()->getCallSign());
+ wpt_iterator = waypoints.begin();
+ create(ac, dep,arr, leg, alt, speed, lat, lon,
+ firstLeg, radius, fltType, acType, airline);
+ wpt_iterator = waypoints.begin();
+ //cerr << "after create: " << (*wpt_iterator)->name << endl;
+ //leg++;
+ // Now that we have dynamically created a flight plan,
+ // we need to add some code that pops any waypoints already past.
+ //return;
+ }
+ /*
+ waypoint* init_waypoint = new waypoint;
+ init_waypoint->name = string("initial position");
+ init_waypoint->latitude = entity->latitude;
+ init_waypoint->longitude = entity->longitude;
+ init_waypoint->altitude = entity->altitude;
+ init_waypoint->speed = entity->speed;
+ init_waypoint->crossat = - 10000;
+ init_waypoint->gear_down = false;
+ init_waypoint->flaps_down = false;
+ init_waypoint->finished = false;
+
+ wpt_vector_iterator i = waypoints.begin();
+ while (i != waypoints.end())
+ {
+ //cerr << "Checking status of each waypoint: " << (*i)->name << endl;
+ SGWayPoint first(init_waypoint->longitude,
+ init_waypoint->latitude,
+ init_waypoint->altitude);
+ SGWayPoint curr ((*i)->longitude,
+ (*i)->latitude,
+ (*i)->altitude);
+ double crse, crsDiff;
+ double dist;
+ curr.CourseAndDistance(first, &crse, &dist);
+
+ dist *= SG_METER_TO_NM;
+
+ // We're only interested in the absolute value of crsDiff
+ // wich should fall in the 0-180 deg range.
+ crsDiff = fabs(crse-course);
+ if (crsDiff > 180)
+ crsDiff = 360-crsDiff;
+ // These are the three conditions that we consider including
+ // in our flight plan:
+ // 1) current waypoint is less then 100 miles away OR
+ // 2) curren waypoint is ahead of us, at any distance
+
+ if ((dist > 20.0) && (crsDiff > 90.0) && ((*i)->name != string ("EOF")))
+ {
+ //useWpt = false;
+ // Once we start including waypoints, we have to continue, even though
+ // one of the following way point would suffice.
+ // so once is the useWpt flag is set to true, we cannot reset it to false.
+ //cerr << "Discarding waypoint: " << (*i)->name
+ // << ": Course difference = " << crsDiff
+ // << "Course = " << course
+ // << "crse = " << crse << endl;
+ }
+ else
+ useCurrentWayPoint = true;
+
+ if (useCurrentWayPoint)
+ {
+ if ((dist > 100.0) && (useInitialWayPoint))
+ {
+ //waypoints.push_back(init_waypoint);;
+ waypoints.insert(i, init_waypoint);
+ //cerr << "Using waypoint : " << init_waypoint->name << endl;
+ }
+ //if (useInitialWayPoint)
+ // {
+ // (*i)->speed = dist; // A hack
+ // }
+ //waypoints.push_back( wpt );
+ //cerr << "Using waypoint : " << (*i)->name
+ // << ": course diff : " << crsDiff
+ // << "Course = " << course
+ // << "crse = " << crse << endl
+ // << "distance : " << dist << endl;
+ useInitialWayPoint = false;
+ i++;
+ }
+ else
+ {
+ //delete wpt;
+ delete *(i);
+ i = waypoints.erase(i);
+ }
+
+ }
+ */
+ //for (i = waypoints.begin(); i != waypoints.end(); i++)
+ // cerr << "Using waypoint : " << (*i)->name << endl;
+ //wpt_iterator = waypoints.begin();
+ //cout << waypoints.size() << " waypoints read." << endl;
+}
+
+
+
+