1
0
Fork 0

Added a new startup option. By giving the command line option --parkpos=AVAILABLE you can -in principle- let FlightGear decide what the most optimal parking location is. This option does require a few properties to be set that are also needed for future ATC use. Hence, they are listed under /sim/ATC, but could move to a different location if desired.

/sim/ATC/radius should be a nummeric estimate of the size of your aircraft. A small aircraft fits into a large parking, but a large aircraft does not fit into a small parking space. Because the AI part of radius is also used for slightly different purposes (prioritizing gate assignmments, the given valuem may deviate slightly from the real aircraft size. See http:/wiki.flightgear.org/Aircraft.radii for an overview of currently used values for the redius property.
/sim/ATC/flight-type can be any one of "ga", "cargo", "gate", "mil-fighter", "mil-cargo", or "vtol". See http://wiki.flightgear.org/Interactive_traffic#A_technical_perspective for more information.
optionally, the property /sim/ATC/airline can be set set to a three letter icao airline code. By way of illustration, I will commit a number of startup preset files setting these properties shortly.

Also did some more finetuning to the traffic mananger routing algorithm can be any one of "ga", "cargo", "gate", "mil-fighter", "mil-cargo", or "vtol". See http://wiki.flightgear.org/Interactive_traffic#A_technical_perspective for more information.
optionally, the property /sim/ATC/airline can be set set to a three letter icao airline code. By way of illustration, I will commit a number of startup preset files setting these properties shortly.

Also did some more finetuning to the traffic mananger routing algorithm.
This commit is contained in:
Durk Talsma 2011-09-17 16:51:00 +02:00
parent 67c604a722
commit db816deb90
4 changed files with 52 additions and 18 deletions

View file

@ -111,7 +111,7 @@ void FGATCManager::init() {
if (park_index < 0) {
SG_LOG( SG_GENERAL, SG_ALERT,
"Failed to find parking position " << parking <<
" at airport " << airport );
" at airport " << airport << "at " << SG_ORIGIN);
}
if (parking.empty() || (park_index < 0)) {
controller = apt->getDynamics()->getTowerController();

View file

@ -901,18 +901,38 @@ static bool fgSetPosFromAirportIDandParkpos( const string& id, const string& par
FGAirportDynamics* dcs = apt->getDynamics();
if (!dcs) {
SG_LOG( SG_GENERAL, SG_ALERT,
"Failed to find parking position " << parkpos <<
" at airport " << id );
"Airport " << id << "does not appear to have parking information available");
return false;
}
int park_index = dcs->getNrOfParkings() - 1;
while (park_index >= 0 && dcs->getParkingName(park_index) != parkpos) park_index--;
if (park_index < 0) {
SG_LOG( SG_GENERAL, SG_ALERT,
"Failed to find parking position " << parkpos <<
" at airport " << id );
return false;
bool succes;
double radius = fgGetDouble("/sim/atc/acradius");
//cerr << "Using radius " << radius << endl;
//cerr << "Checking parkpos comparison " << (bool) (parkpos == string("AVAILABLE")) << endl;
if ((parkpos == string("AVAILABLE")) && (radius > 0)) {
double lat, lon, heading;
string fltType = fgGetString("/sim/atc/flight-type");
string airline = fgGetString("/sim/atc/airline" );
string acType; // Currently not used by findAvailable parking, so safe to leave empty.
succes = dcs->getAvailableParking(&lat, &lon, &heading, &park_index, radius, fltType, acType, airline);
if (succes) {
fgGetString("/sim/presets/parkpos");
fgSetString("/sim/presets/parkpos", dcs->getParking(park_index)->getName());
} else {
SG_LOG( SG_GENERAL, SG_ALERT,
"Failed to find a suitable parking at airport " << id );
return false;
}
} else {
//cerr << "We shouldn't get here when AVAILABLE" << endl;
while (park_index >= 0 && dcs->getParkingName(park_index) != parkpos) park_index--;
if (park_index < 0) {
SG_LOG( SG_GENERAL, SG_ALERT,
"Failed to find parking position " << parkpos <<
" at airport " << id );
return false;
}
}
FGParking* parking = dcs->getParking(park_index);
parking->setAvailable(false);

View file

@ -201,7 +201,7 @@ bool FGAISchedule::update(time_t now, const SGVec3d& userCart)
if (!valid) {
return false;
}
scheduleFlights();
scheduleFlights(now);
if (flights.empty()) { // No flights available for this aircraft
valid = false;
return false;
@ -369,17 +369,24 @@ void FGAISchedule::setHeading()
courseToDest = SGGeodesy::courseDeg((*flights.begin())->getDepartureAirport()->geod(), (*flights.begin())->getArrivalAirport()->geod());
}
void FGAISchedule::scheduleFlights()
void FGAISchedule::scheduleFlights(time_t now)
{
string startingPort;
if (!flights.empty()) {
return;
}
// change back to bulk
string startingPort;
string userPort = fgGetString("/sim/presets/airport-id");
SG_LOG(SG_GENERAL, SG_BULK, "Scheduling Flights for : " << modelPath << " " << registration << " " << homePort);
FGScheduledFlight *flight = NULL;
do {
flight = findAvailableFlight(currentDestination, flightIdentifier);
if (currentDestination.empty()) {
flight = findAvailableFlight(userPort, flightIdentifier, now, (now+6400));
if (!flight)
flight = findAvailableFlight(currentDestination, flightIdentifier);
} else {
flight = findAvailableFlight(currentDestination, flightIdentifier);
}
if (!flight) {
break;
}
@ -389,11 +396,12 @@ void FGAISchedule::scheduleFlights()
currentDestination = flight->getArrivalAirport()->getId();
//cerr << "Current destination " << currentDestination << endl;
if (!initialized) {
string departurePort = flight->getDepartureAirport()->getId();
//cerr << "Scheduled " << registration << " " << score << " for Flight "
// << flight-> getCallSign() << " from " << departurePort << " to " << currentDestination << endl;
if (fgGetString("/sim/presets/airport-id") == departurePort) {
if (userPort == departurePort) {
hits++;
}
//runCount++;
@ -452,7 +460,8 @@ bool FGAISchedule::next()
}
FGScheduledFlight* FGAISchedule::findAvailableFlight (const string &currentDestination,
const string &req)
const string &req,
time_t min, time_t max)
{
time_t now = time(NULL) + fgGetLong("/sim/time/warp");
@ -501,6 +510,11 @@ FGScheduledFlight* FGAISchedule::findAvailableFlight (const string &currentDesti
if ((*i)->getDepartureTime() < (arrival+(20*60)))
continue;
}
if (min != 0) {
time_t dep = (*i)->getDepartureTime();
if ((dep < min) || (dep > max))
continue;
}
// So, if we actually get here, we have a winner
//cerr << "found flight: " << req << " : " << currentDestination << " : " <<

View file

@ -62,7 +62,7 @@ class FGAISchedule
bool initialized;
bool valid;
void scheduleFlights();
void scheduleFlights(time_t now);
/**
* Transition this schedule from distant mode to AI mode;
@ -122,7 +122,7 @@ class FGAISchedule
void setHeading ();
void assign (FGScheduledFlight *ref) { flights.push_back(ref); };
void setFlightType (string val ) { flightType = val; };
FGScheduledFlight*findAvailableFlight (const string &currentDestination, const string &req);
FGScheduledFlight*findAvailableFlight (const string &currentDestination, const string &req, time_t min=0, time_t max=0);
// used to sort in decending order of score: I've probably found a better way to
// decending order sorting, but still need to test that.
bool operator< (const FGAISchedule &other) const;