FGAIFlightPlan::FGAIFlightPlan(string filename)
{
int i;
+ start_time = 0;
SGPath path( globals->get_fg_root() );
path.append( ("/Data/AI/FlightPlans/" + filename).c_str() );
SGPropertyNode root;
// as setting speeds and altitude computed by the
// traffic manager.
FGAIFlightPlan::FGAIFlightPlan(FGAIModelEntity *entity,
- double course,
+ double course,
+ time_t start,
FGAirport *dep,
FGAirport *arr)
{
+ start_time = start;
bool useInitialWayPoint = true;
bool useCurrentWayPoint = false;
SGPath path( globals->get_fg_root() );
path.append( "/Data/AI/FlightPlans" );
path.append( entity->path );
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;
+ }
try {
readProperties(path.str(), &root);
(*i)->altitude);
double crse, crsDiff;
double dist;
- first.CourseAndDistance(curr, &crse, &dist);
+ curr.CourseAndDistance(first, &crse, &dist);
dist *= SG_METER_TO_NM;
// 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;
+ // << "Course = " << course
+ // << "crse = " << crse << endl;
}
else
useCurrentWayPoint = true;
{
if ((dist > 100.0) && (useInitialWayPoint))
{
- //waypoints.push_back(init_waypoint);
+ //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
*/
void FGAIFlightPlan::create(FGAirport *dep, FGAirport *arr, double alt, double speed)
{
- double wind_speed;
+double wind_speed;
double wind_heading;
FGRunway rwy;
+ double lat, lon, az;
+ double lat2, lon2, az2;
+ int direction;
//waypoints.push_back(wpt);
// Create the outbound taxi leg, for now simplified as a
// Direct route from the airport center point to the start
// of the runway.
///////////////////////////////////////////////////////////
- //cerr << "Cruise Alt << " << alt << endl;
+ //cerr << "Cruise Alt << " << alt << endl;
+ // Temporary code to add some small random variation to aircraft parking positions;
+ direction = (rand() % 360);
+geo_direct_wgs_84 ( 0, dep->_latitude, dep->_longitude, direction,
+ 100,
+ &lat2, &lon2, &az2 );
waypoint *wpt = new waypoint;
- wpt->name = dep->id; //wpt_node->getStringValue("name", "END");
- wpt->latitude = dep->latitude;
- wpt->longitude = dep->longitude;
- wpt->altitude = dep->elevation + 19; // probably need to add some model height to it
+ wpt->name = dep->_id; //wpt_node->getStringValue("name", "END");
+ wpt->latitude = lat2;
+ wpt->longitude = lon2;
+ wpt->altitude = dep->_elevation + 19; // probably need to add some model height to it
wpt->speed = 15;
wpt->crossat = -10000;
wpt->gear_down = true;
wpt->flaps_down= true;
wpt->finished = false;
+ wpt->on_ground = true;
waypoints.push_back(wpt);
// Get the current active runway, based on code from David Luff
FGEnvironment
stationweather = ((FGEnvironmentMgr *) globals->get_subsystem("environment"))
- ->getEnvironment(dep->latitude, dep->longitude, dep->elevation);
+ ->getEnvironment(dep->_latitude, dep->_longitude, dep->_elevation);
wind_speed = stationweather.get_wind_speed_kt();
wind_heading = stationweather.get_wind_from_heading_deg();
// which is consistent with Flightgear's initial setup.
}
- string rwy_no = globals->get_runways()->search(dep->id, int(wind_heading));
- if (!(globals->get_runways()->search(dep->id, (int) wind_heading, &rwy )))
+ string rwy_no = globals->get_runways()->search(dep->_id, int(wind_heading));
+ if (!(globals->get_runways()->search(dep->_id, (int) wind_heading, &rwy )))
{
- cout << "Failed to find runway for " << dep->id << endl;
+ cout << "Failed to find runway for " << dep->_id << endl;
// Hmm, how do we handle a potential error like this?
exit(1);
}
- double lat, lon, az;
- double lat2, lon2, az2;
- double heading = rwy.heading;
+
+ double heading = rwy._heading;
double azimuth = heading + 180.0;
while ( azimuth >= 360.0 ) { azimuth -= 360.0; }
- geo_direct_wgs_84 ( 0, rwy.lat, rwy.lon, azimuth,
- rwy.length * SG_FEET_TO_METER * 0.5 - 5.0,
+ geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, azimuth,
+ rwy._length * SG_FEET_TO_METER * 0.5 - 5.0,
&lat2, &lon2, &az2 );
//Add the runway startpoint;
wpt = new waypoint;
- wpt->name = rwy.id;
+ wpt->name = rwy._id;
wpt->latitude = lat2;
wpt->longitude = lon2;
- wpt->altitude = dep->elevation + 19;
+ wpt->altitude = dep->_elevation + 19;
wpt->speed = 15;
wpt->crossat = -10000;
wpt->gear_down = true;
//Next: The point on the runway where we begin to accelerate to take-off speed
//100 meters down the runway seems to work. Shorter distances cause problems with
// the turn with larger aircraft
- geo_direct_wgs_84 ( 0, rwy.lat, rwy.lon, azimuth,
- rwy.length * SG_FEET_TO_METER * 0.5 - 105.0,
+ geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, azimuth,
+ rwy._length * SG_FEET_TO_METER * 0.5 - 105.0,
&lat2, &lon2, &az2 );
wpt = new waypoint;
wpt->name = "accel";
wpt->latitude = lat2;
wpt->longitude = lon2;
- wpt->altitude = dep->elevation + 19;
+ wpt->altitude = dep->_elevation + 19;
wpt->speed = speed;
wpt->crossat = -10000;
wpt->gear_down = true;
//Beginning of Decent
stationweather = ((FGEnvironmentMgr *)globals->get_subsystem("environment"))
- ->getEnvironment(arr->latitude, arr->longitude, arr->elevation);
+ ->getEnvironment(arr->_latitude, arr->_longitude, arr->_elevation);
wind_speed = stationweather.get_wind_speed_kt();
wind_heading = stationweather.get_wind_from_heading_deg();
// which is consistent with Flightgear's initial setup.
}
- rwy_no = globals->get_runways()->search(arr->id, int(wind_heading));
- //cout << "Using runway # " << rwy_no << " for departure at " << dep->id << endl;
+ rwy_no = globals->get_runways()->search(arr->_id, int(wind_heading));
+ //cout << "Using runway # " << rwy_no << " for departure at " << dep->_id << endl;
- if (!(globals->get_runways()->search(arr->id, (int) wind_heading, &rwy )))
+ if (!(globals->get_runways()->search(arr->_id, (int) wind_heading, &rwy )))
{
- cout << "Failed to find runway for " << arr->id << endl;
+ cout << "Failed to find runway for " << arr->_id << endl;
// Hmm, how do we handle a potential error like this?
exit(1);
}
//cerr << "Done" << endl;
- heading = rwy.heading;
+ heading = rwy._heading;
azimuth = heading + 180.0;
while ( azimuth >= 360.0 ) { azimuth -= 360.0; }
- geo_direct_wgs_84 ( 0, rwy.lat, rwy.lon, azimuth,
+ geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, azimuth,
100000,
&lat2, &lon2, &az2 );
wpt = new waypoint;
waypoints.push_back(wpt);
// Ten thousand ft. Slowing down to 240 kts
- geo_direct_wgs_84 ( 0, rwy.lat, rwy.lon, azimuth,
+ geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, azimuth,
20*SG_NM_TO_METER,
&lat2, &lon2, &az2 );
wpt = new waypoint;
wpt->name = "Dec 10000ft"; //wpt_node->getStringValue("name", "END");
wpt->latitude = lat2;
wpt->longitude = lon2;
- wpt->altitude = arr->elevation + 19;
+ wpt->altitude = arr->_elevation + 19;
wpt->speed = 240;
wpt->crossat = 10000;
wpt->gear_down = false;
waypoints.push_back(wpt);
// Three thousand ft. Slowing down to 160 kts
- geo_direct_wgs_84 ( 0, rwy.lat, rwy.lon, azimuth,
+ geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, azimuth,
8*SG_NM_TO_METER,
&lat2, &lon2, &az2 );
wpt = new waypoint;
wpt->name = "DEC 3000ft"; //wpt_node->getStringValue("name", "END");
wpt->latitude = lat2;
wpt->longitude = lon2;
- wpt->altitude = arr->elevation + 19;
+ wpt->altitude = arr->_elevation + 19;
wpt->speed = 160;
wpt->crossat = 3000;
wpt->gear_down = true;
wpt->on_ground = false;
waypoints.push_back(wpt);
//Runway Threshold
- geo_direct_wgs_84 ( 0, rwy.lat, rwy.lon, azimuth,
- rwy.length*0.45,
+ geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, azimuth,
+ rwy._length*0.45 * SG_FEET_TO_METER,
&lat2, &lon2, &az2 );
wpt = new waypoint;
wpt->name = "Threshold"; //wpt_node->getStringValue("name", "END");
wpt->latitude = lat2;
wpt->longitude = lon2;
- wpt->altitude = arr->elevation + 19;
+ wpt->altitude = arr->_elevation + 19;
wpt->speed = 15;
- wpt->crossat = arr->elevation + 19;
+ wpt->crossat = arr->_elevation + 19;
wpt->gear_down = true;
wpt->flaps_down= true;
wpt->finished = false;
waypoints.push_back(wpt);
//Full stop at the runway centerpoint
- geo_direct_wgs_84 ( 0, rwy.lat, rwy.lon, azimuth,
- rwy.length*0.45,
+ geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, azimuth,
+ rwy._length*0.45,
&lat2, &lon2, &az2 );
wpt = new waypoint;
wpt->name = "Center"; //wpt_node->getStringValue("name", "END");
- wpt->latitude = rwy.lat;
- wpt->longitude = rwy.lon;
- wpt->altitude = arr->elevation + 19;
+ wpt->latitude = rwy._lat;
+ wpt->longitude = rwy._lon;
+ wpt->altitude = arr->_elevation + 19;
wpt->speed = 15;
wpt->crossat = -10000;
wpt->gear_down = true;
wpt->flaps_down= true;
wpt->finished = false;
- wpt->on_ground = false;
+ wpt->on_ground = true;
waypoints.push_back(wpt);
+direction = (rand() % 360);
+geo_direct_wgs_84 ( 0, arr->_latitude, arr->_longitude, direction,
+ 100,
+ &lat2, &lon2, &az2 );
+
// Add the final destination waypoint
wpt = new waypoint;
- wpt->name = arr->id; //wpt_node->getStringValue("name", "END");
- wpt->latitude = arr->latitude;
- wpt->longitude = arr->longitude;
- wpt->altitude = arr->elevation+19;
+ wpt->name = arr->_id; //wpt_node->getStringValue("name", "END");
+ wpt->latitude = lat2;
+ wpt->longitude = lon2;
+ wpt->altitude = arr->_elevation+19;
wpt->speed = 15;
wpt->crossat = -10000;
wpt->gear_down = true;
wpt->flaps_down= true;
wpt->finished = false;
- wpt->on_ground = false;
+ wpt->on_ground = true;
waypoints.push_back(wpt);
// And finally one more named "END"
wpt = new waypoint;
wpt->name = "END"; //wpt_node->getStringValue("name", "END");
- wpt->latitude = arr->latitude;
- wpt->longitude = arr->longitude;
+ wpt->latitude = lat2;
+ wpt->longitude = lon2;
wpt->altitude = 19;
wpt->speed = 15;
wpt->crossat = -10000;
// And finally one more named "EOF"
wpt = new waypoint;
wpt->name = "EOF"; //wpt_node->getStringValue("name", "END");
- wpt->latitude = arr->latitude;
- wpt->longitude = arr->longitude;
+ wpt->latitude = lat2;
+ wpt->longitude = lon2;
wpt->altitude = 19;
wpt->speed = 15;
wpt->crossat = -10000;
wpt->gear_down = true;
wpt->flaps_down= true;
wpt->finished = true;
- wpt->finished = true;
+ wpt->on_ground = true;
waypoints.push_back(wpt);
}