X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FATC%2Ftrafficcontrol.cxx;h=dc7d8c5f30743e5e150486055a3f8d45299c13d3;hb=960f6881c993a32613e542d1475ad0d1ae97b927;hp=664929bfc764da04b97d296409f599e38637c19f;hpb=49677f512b8edaaf22c76761dbbf9c0850c79aad;p=flightgear.git diff --git a/src/ATC/trafficcontrol.cxx b/src/ATC/trafficcontrol.cxx index 664929bfc..dc7d8c5f3 100644 --- a/src/ATC/trafficcontrol.cxx +++ b/src/ATC/trafficcontrol.cxx @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -398,6 +399,10 @@ void FGTrafficRecord::setHeadingAdjustment(double heading) bool FGTrafficRecord::pushBackAllowed() { + // With the user ATC / AI integration, checking whether the user's aircraft is near no longer works, because + // this will effectively block the user's aircraft itself from receiving pushback clearance. + // So, what can we do? + /* double course, az2, dist; SGGeod curr(SGGeod::fromDegM(getLongitude(), getLatitude(), getAltitude())); @@ -408,7 +413,13 @@ bool FGTrafficRecord::pushBackAllowed() SGGeodesy::inverse(curr, user, course, az2, dist); //cerr << "Distance to user : " << dist << endl; return (dist > 250); + */ + + // In essence, we should check whether the pusbback route itself, as well as the associcated + // taxiways near the pushback point are free of traffic. + // To do so, we need to + return true; } @@ -452,8 +463,7 @@ FGATCController::FGATCController() dt_count = 0; available = true; lastTransmission = 0; - FGATCManager *mgr = (FGATCManager*) globals->get_subsystem("ATC"); - mgr->addController(this); + initialized = false; } FGATCController::~FGATCController() @@ -466,8 +476,13 @@ string FGATCController::getGateName(FGAIAircraft * ref) return ref->atGate(); } +bool FGATCController::isUserAircraft(FGAIAircraft* ac) +{ + return (ac->getCallSign() == fgGetString("/sim/multiplay/callsign")) ? true : false; +}; + void FGATCController::transmit(FGTrafficRecord * rec, AtcMsgId msgId, - AtcMsgDir msgDir) + AtcMsgDir msgDir, bool audible) { string sender, receiver; int stationFreq = 0; @@ -632,22 +647,28 @@ void FGATCController::transmit(FGTrafficRecord * rec, AtcMsgId msgId, text = text + sender + ". Transmitting unknown Message"; break; } - double onBoardRadioFreq0 = - fgGetDouble("/instrumentation/comm[0]/frequencies/selected-mhz"); - double onBoardRadioFreq1 = - fgGetDouble("/instrumentation/comm[1]/frequencies/selected-mhz"); - int onBoardRadioFreqI0 = (int) floor(onBoardRadioFreq0 * 100 + 0.5); - int onBoardRadioFreqI1 = (int) floor(onBoardRadioFreq1 * 100 + 0.5); - //cerr << "Using " << onBoardRadioFreq0 << ", " << onBoardRadioFreq1 << " and " << stationFreq << " for " << text << endl; - - // Display ATC message only when one of the radios is tuned - // the relevant frequency. - // Note that distance attenuation is currently not yet implemented - if ((onBoardRadioFreqI0 == stationFreq) - || (onBoardRadioFreqI1 == stationFreq)) { - if (rec->allowTransmissions()) { - fgSetString("/sim/messages/atc", text.c_str()); + if (audible) { + double onBoardRadioFreq0 = + fgGetDouble("/instrumentation/comm[0]/frequencies/selected-mhz"); + double onBoardRadioFreq1 = + fgGetDouble("/instrumentation/comm[1]/frequencies/selected-mhz"); + int onBoardRadioFreqI0 = (int) floor(onBoardRadioFreq0 * 100 + 0.5); + int onBoardRadioFreqI1 = (int) floor(onBoardRadioFreq1 * 100 + 0.5); + //cerr << "Using " << onBoardRadioFreq0 << ", " << onBoardRadioFreq1 << " and " << stationFreq << " for " << text << endl; + + // Display ATC message only when one of the radios is tuned + // the relevant frequency. + // Note that distance attenuation is currently not yet implemented + if ((onBoardRadioFreqI0 == stationFreq) + || (onBoardRadioFreqI1 == stationFreq)) { + if (rec->allowTransmissions()) { + fgSetString("/sim/messages/atc", text.c_str()); + } } + } else { + FGATCManager *atc = (FGATCManager*) globals->get_subsystem("atc"); + atc->getATCDialog()->addEntry(1, text); + } } @@ -672,6 +693,15 @@ string FGATCController::genTransponderCode(string fltRules) } } +void FGATCController::init() +{ + if (!initialized) { + FGATCManager *mgr = (FGATCManager*) globals->get_subsystem("ATC"); + mgr->addController(this); + initialized = true; + } +} + /*************************************************************************** * class FGTowerController * @@ -690,6 +720,7 @@ void FGTowerController::announcePosition(int id, double radius, int leg, FGAIAircraft * ref) { + init(); TrafficVectorIterator i = activeTraffic.begin(); // Search whether the current id alread has an entry // This might be faster using a map instead of a vector, but let's start by taking a safe route @@ -882,6 +913,7 @@ void FGStartupController::announcePosition(int id, double radius, int leg, FGAIAircraft * ref) { + init(); TrafficVectorIterator i = activeTraffic.begin(); // Search whether the current id alread has an entry // This might be faster using a map instead of a vector, but let's start by taking a safe route @@ -987,6 +1019,40 @@ void FGStartupController::signOff(int id) } } +bool FGStartupController::checkTransmissionState(int st, time_t now, time_t startTime, TrafficVectorIterator i, AtcMsgId msgId, + AtcMsgDir msgDir) +{ + int state = i->getState(); + if ((state == st) && available) { + if ((msgDir == ATC_AIR_TO_GROUND) && isUserAircraft(i->getAircraft())) { + + cerr << "Checking state " << st << " for " << i->getAircraft()->getCallSign() << endl; + static SGPropertyNode_ptr trans_num = globals->get_props()->getNode("/sim/atc/transmission-num", true); + int n = trans_num->getIntValue(); + if (n >= 0) { + trans_num->setIntValue(-1); + // PopupCallback(n); + cerr << "Selected transmission message" << n << endl; + FGATCManager *atc = (FGATCManager*) globals->get_subsystem("atc"); + atc->getATCDialog()->removeEntry(1); + } else { + cerr << "creading message for " << i->getAircraft()->getCallSign() << endl; + transmit(&(*i), msgId, msgDir, false); + return false; + } + } + if (now > startTime) { + //cerr << "Transmitting startup msg" << endl; + transmit(&(*i), msgId, msgDir, true); + i->updateState(); + lastTransmission = now; + available = false; + return true; + } + } + return false; +} + void FGStartupController::updateAircraftInformation(int id, double lat, double lon, double heading, double speed, double alt, double dt) @@ -1005,6 +1071,7 @@ void FGStartupController::updateAircraftInformation(int id, double lat, double l } } // // update position of the current aircraft + if (i == activeTraffic.end() || (activeTraffic.size() == 0)) { SG_LOG(SG_GENERAL, SG_ALERT, "AI error: updating aircraft without traffic record"); @@ -1015,8 +1082,10 @@ void FGStartupController::updateAircraftInformation(int id, double lat, double l setDt(getDt() + dt); int state = i->getState(); - time_t startTime = - i->getAircraft()->getTrafficRef()->getDepartureTime(); + + // The user controlled aircraft should have crased here, because it doesn't have a traffic reference. + // NOTE: if we create a traffic schedule for the user aircraft, we can use this to plan a flight. + time_t startTime = i->getAircraft()->getTrafficRef()->getDepartureTime(); time_t now = time(NULL) + fgGetLong("/sim/time/warp"); //cerr << i->getAircraft()->getTrafficRef()->getCallSign() // << " is scheduled to depart in " << startTime-now << " seconds. Available = " << available @@ -1026,91 +1095,29 @@ void FGStartupController::updateAircraftInformation(int id, double lat, double l available = true; } - if ((state == 0) && available) { - if (now > startTime) { - //cerr << "Transmitting startup msg" << endl; - transmit(&(*i), MSG_ANNOUNCE_ENGINE_START, ATC_AIR_TO_GROUND); - i->updateState(); - lastTransmission = now; - available = false; - } - } - if ((state == 1) && available) { - if (now > startTime + 60) { - transmit(&(*i), MSG_REQUEST_ENGINE_START, ATC_AIR_TO_GROUND); - i->updateState(); - lastTransmission = now; - available = false; - } - } - if ((state == 2) && available) { - if (now > startTime + 80) { - transmit(&(*i), MSG_PERMIT_ENGINE_START, ATC_GROUND_TO_AIR); - i->updateState(); - lastTransmission = now; - available = false; - } - } - if ((state == 3) && available) { - if (now > startTime + 100) { - transmit(&(*i), MSG_ACKNOWLEDGE_ENGINE_START, - ATC_AIR_TO_GROUND); - i->updateState(); - lastTransmission = now; - available = false; - } - } - // Note: The next four stages are only necessesary when Startup control is - // on a different frequency, compared to ground control - if ((state == 4) && available) { - if (now > startTime + 130) { - transmit(&(*i), MSG_ACKNOWLEDGE_SWITCH_GROUND_FREQUENCY, - ATC_AIR_TO_GROUND); - i->updateState(); - i->nextFrequency(); - lastTransmission = now; - available = false; - } - } - if ((state == 5) && available) { - if (now > startTime + 140) { - transmit(&(*i), MSG_INITIATE_CONTACT, ATC_AIR_TO_GROUND); - i->updateState(); - lastTransmission = now; - available = false; - } - } - if ((state == 6) && available) { - if (now > startTime + 150) { - transmit(&(*i), MSG_ACKNOWLEDGE_INITIATE_CONTACT, - ATC_GROUND_TO_AIR); - i->updateState(); - lastTransmission = now; - available = false; - } + checkTransmissionState(0, now, (startTime + 0 ), i, MSG_ANNOUNCE_ENGINE_START, ATC_AIR_TO_GROUND); + checkTransmissionState(1, now, (startTime + 60 ), i, MSG_REQUEST_ENGINE_START, ATC_AIR_TO_GROUND); + checkTransmissionState(2, now, (startTime + 80 ), i, MSG_PERMIT_ENGINE_START, ATC_GROUND_TO_AIR); + checkTransmissionState(3, now, (startTime + 100), i, MSG_ACKNOWLEDGE_ENGINE_START, ATC_AIR_TO_GROUND); + if (checkTransmissionState(4, now, (startTime + 130), i, MSG_ACKNOWLEDGE_SWITCH_GROUND_FREQUENCY, ATC_AIR_TO_GROUND)) { + i->nextFrequency(); } + checkTransmissionState(5, now, (startTime + 140), i, MSG_INITIATE_CONTACT, ATC_AIR_TO_GROUND); + checkTransmissionState(6, now, (startTime + 150), i, MSG_ACKNOWLEDGE_INITIATE_CONTACT, ATC_GROUND_TO_AIR); + checkTransmissionState(7, now, (startTime + 180), i, MSG_REQUEST_PUSHBACK_CLEARANCE, ATC_AIR_TO_GROUND); - // TODO: Switch to APRON control and request pushback Clearance. - // Get Push back clearance - if ((state == 7) && available) { - if (now > startTime + 180) { - transmit(&(*i), MSG_REQUEST_PUSHBACK_CLEARANCE, - ATC_AIR_TO_GROUND); - i->updateState(); - lastTransmission = now; - available = false; - } - } + + if ((state == 8) && available) { if (now > startTime + 200) { if (i->pushBackAllowed()) { i->allowRepeatedTransmissions(); transmit(&(*i), MSG_PERMIT_PUSHBACK_CLEARANCE, - ATC_GROUND_TO_AIR); + ATC_GROUND_TO_AIR, true); i->updateState(); } else { transmit(&(*i), MSG_HOLD_PUSHBACK_CLEARANCE, - ATC_GROUND_TO_AIR); + ATC_GROUND_TO_AIR, true); i->suppressRepeatedTransmissions(); } lastTransmission = now; @@ -1141,6 +1148,7 @@ void FGApproachController::announcePosition(int id, double alt, double radius, int leg, FGAIAircraft * ref) { + init(); TrafficVectorIterator i = activeTraffic.begin(); // Search whether the current id alread has an entry // This might be faster using a map instead of a vector, but let's start by taking a safe route