X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FATC%2Ftrafficcontrol.cxx;h=a25f9195646b2f5da7915b6f010cedba82a6cfb3;hb=9fa790bcac7e535bb06cd228ae15178f1b10b26f;hp=685df21da7773ebe825f4f9d4b951e8fceedbca7;hpb=f2b354d9cbdcac4650f4837bafb147a7a306395e;p=flightgear.git diff --git a/src/ATC/trafficcontrol.cxx b/src/ATC/trafficcontrol.cxx index 685df21da..a25f91956 100644 --- a/src/ATC/trafficcontrol.cxx +++ b/src/ATC/trafficcontrol.cxx @@ -47,6 +47,8 @@ #include #include #include +#include +#include using std::sort; @@ -140,6 +142,27 @@ time_t ActiveRunway::requestTimeSlot(time_t eta) return newEta; } +void ActiveRunway::printDepartureCue() +{ + cout << "Departure cue for " << rwy << ": " << endl; + for (AircraftVecIterator atc = departureCue.begin(); atc != departureCue.end(); atc++) { + cout << " " << (*atc)->getCallSign() << " " << (*atc)->getTakeOffStatus(); + cout << " " << (*atc)->_getLatitude() << " " << (*atc)->_getLongitude() << (*atc)-> getSpeed() << " " << (*atc)->getAltitude() << endl; + } + +} + +FGAIAircraft* ActiveRunway::getFirstOfStatus(int stat) +{ + for (AircraftVecIterator atc =departureCue.begin(); atc != departureCue.end(); atc++) { + if ((*atc)->getTakeOffStatus() == stat) + return (*atc); + } + return 0; +} + + + /*************************************************************************** * FGTrafficRecord **************************************************************************/ @@ -164,14 +187,8 @@ void FGTrafficRecord::setPositionAndIntentions(int pos, if (intentions.size()) { intVecIterator i = intentions.begin(); if ((*i) != pos) { - SG_LOG(SG_GENERAL, SG_ALERT, - "Error in FGTrafficRecord::setPositionAndIntentions"); - //cerr << "Pos : " << pos << " Curr " << *(intentions.begin()) << endl; - for (intVecIterator i = intentions.begin(); - i != intentions.end(); i++) { - //cerr << (*i) << " "; - } - //cerr << endl; + SG_LOG(SG_ATC, SG_ALERT, + "Error in FGTrafficRecord::setPositionAndIntentions at " << SG_ORIGIN); } intentions.erase(i); } else { @@ -179,21 +196,11 @@ void FGTrafficRecord::setPositionAndIntentions(int pos, int size = route->getNrOfWayPoints(); //cerr << "Setting pos" << pos << " "; //cerr << "setting intentions "; - for (int i = 0; i < size; i++) { + for (int i = 2; i < size; i++) { int val = route->getRouteIndex(i); - //cerr << val<< " "; - if ((val) && (val != pos)) { - intentions.push_back(val); - //cerr << "[set] "; - } + intentions.push_back(val); } - //cerr << endl; - //while (route->next(&legNr, &routeNr)) { - //intentions.push_back(routeNr); - //} - //route->rewind(currentPos); } - //exit(1); } /** * Check if another aircraft is ahead of the current one, and on the same @@ -266,8 +273,8 @@ int FGTrafficRecord::crosses(FGGroundNetwork * net, if (intentions.size()) { for (i = intentions.begin(); i != intentions.end(); i++) { if ((*i) > 0) { - if ((currentTargetNode == - net->findSegment(*i)->getEnd()->getIndex())) { + if (currentTargetNode == + net->findSegment(*i)->getEnd()->getIndex()) { //cerr << "Current crosses at " << currentTargetNode <getCallSign() == fgGetString("/sim/multiplay/callsign")) ? true : false; }; -void FGATCController::transmit(FGTrafficRecord * rec, AtcMsgId msgId, +void FGATCController::transmit(FGTrafficRecord * rec, FGAirportDynamics *parent, AtcMsgId msgId, AtcMsgDir msgDir, bool audible) { string sender, receiver; @@ -508,6 +515,7 @@ void FGATCController::transmit(FGTrafficRecord * rec, AtcMsgId msgId, FGAIFlightPlan *fp; string fltRules; string instructionText; + int ground_to_air=0; //double commFreqD; sender = rec->getAircraft()->getTrafficRef()->getCallSign(); @@ -548,6 +556,7 @@ void FGATCController::transmit(FGTrafficRecord * rec, AtcMsgId msgId, string tmp = sender; sender = receiver; receiver = tmp; + ground_to_air=1; } switch (msgId) { case MSG_ANNOUNCE_ENGINE_START: @@ -715,10 +724,36 @@ void FGATCController::transmit(FGTrafficRecord * rec, AtcMsgId msgId, // 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 ((stationFreq > 0)&& + ((onBoardRadioFreqI0 == stationFreq)|| + (onBoardRadioFreqI1 == stationFreq))) { if (rec->allowTransmissions()) { - fgSetString("/sim/messages/atc", text.c_str()); + + if( fgGetBool( "/sim/radio/use-itm-attenuation", false ) ) { + //cerr << "Using ITM radio propagation" << endl; + FGRadioTransmission* radio = new FGRadioTransmission(); + SGGeod sender_pos; + double sender_alt_ft, sender_alt; + if(ground_to_air) { + sender_alt_ft = parent->getElevation(); + sender_alt = sender_alt_ft * SG_FEET_TO_METER; + sender_pos= SGGeod::fromDegM( parent->getLongitude(), + parent->getLatitude(), sender_alt ); + } + else { + sender_alt_ft = rec->getAltitude(); + sender_alt = sender_alt_ft * SG_FEET_TO_METER; + sender_pos= SGGeod::fromDegM( rec->getLongitude(), + rec->getLatitude(), sender_alt ); + } + double frequency = ((double)stationFreq) / 100; + radio->receiveATC(sender_pos, frequency, text, ground_to_air); + delete radio; + } + else { + fgSetString("/sim/messages/atc", text.c_str()); + } } } } else { @@ -726,6 +761,7 @@ void FGATCController::transmit(FGTrafficRecord * rec, AtcMsgId msgId, } } + string FGATCController::formatATCFrequency3_2(int freq) { char buffer[7]; @@ -844,8 +880,8 @@ void FGTowerController::updateAircraftInformation(int id, double lat, double lon } // // 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"); + SG_LOG(SG_ATC, SG_ALERT, + "AI error: updating aircraft without traffic record at " << SG_ORIGIN); } else { i->setPositionAndHeading(lat, lon, heading, speed, alt); current = i; @@ -855,7 +891,15 @@ void FGTowerController::updateAircraftInformation(int id, double lat, double lon // see if we already have a clearance record for the currently active runway // NOTE: dd. 2011-08-07: Because the active runway has been constructed in the announcePosition function, we may safely assume that is // already exists here. So, we can simplify the current code. + ActiveRunwayVecIterator rwy = activeRunways.begin(); + //if (parent->getId() == fgGetString("/sim/presets/airport-id")) { + // for (rwy = activeRunways.begin(); rwy != activeRunways.end(); rwy++) { + // rwy->printDepartureCue(); + // } + //} + + rwy = activeRunways.begin(); while (rwy != activeRunways.end()) { if (rwy->getRunwayName() == current->getRunway()) { break; @@ -878,22 +922,29 @@ void FGTowerController::updateAircraftInformation(int id, double lat, double lon } } */ // only bother with aircraft that have a takeoff status of 2, since those are essentially under tower control + FGAIAircraft* ac= rwy->getFirstAircraftInDepartureCue(); + if (ac->getTakeOffStatus() == 1) { + ac->setTakeOffStatus(2); + } if (current->getAircraft()->getTakeOffStatus() == 2) { + current -> setHoldPosition(false); + } else { current->setHoldPosition(true); - int clearanceId = rwy->getCleared(); - if (clearanceId) { - if (id == clearanceId) { - current->setHoldPosition(false); - } - } else { - if (current->getAircraft() == rwy->getFirstAircraftInDepartureCue()) { - rwy->setCleared(id); - } + } + int clearanceId = rwy->getCleared(); + if (clearanceId) { + if (id == clearanceId) { + current->setHoldPosition(false); } } else { - + if (current->getAircraft() == rwy->getFirstAircraftInDepartureCue()) { + rwy->setCleared(id); + FGAIAircraft *ac = rwy->getFirstOfStatus(1); + if (ac) + ac->setTakeOffStatus(2); + } } -} +} void FGTowerController::signOff(int id) @@ -924,13 +975,13 @@ void FGTowerController::signOff(int id) rwy->setCleared(0); rwy->updateDepartureCue(); } else { - SG_LOG(SG_GENERAL, SG_ALERT, - "AI error: Attempting to erase non-existing runway clearance record in FGTowerController::signoff"); + SG_LOG(SG_ATC, SG_ALERT, + "AI error: Attempting to erase non-existing runway clearance record in FGTowerController::signoff at " << SG_ORIGIN); } } if (i == activeTraffic.end() || (activeTraffic.size() == 0)) { - SG_LOG(SG_GENERAL, SG_ALERT, - "AI error: Aircraft without traffic record is signing off from tower"); + SG_LOG(SG_ATC, SG_ALERT, + "AI error: Aircraft without traffic record is signing off from tower at " << SG_ORIGIN); } else { i->getAircraft()->resetTakeOffStatus(); i = activeTraffic.erase(i); @@ -959,8 +1010,8 @@ bool FGTowerController::hasInstruction(int id) } } if (i == activeTraffic.end() || (activeTraffic.size() == 0)) { - SG_LOG(SG_GENERAL, SG_ALERT, - "AI error: checking ATC instruction for aircraft without traffic record"); + SG_LOG(SG_ATC, SG_ALERT, + "AI error: checking ATC instruction for aircraft without traffic record at " << SG_ORIGIN); } else { return i->hasInstruction(); } @@ -983,8 +1034,8 @@ FGATCInstruction FGTowerController::getInstruction(int id) } } if (i == activeTraffic.end() || (activeTraffic.size() == 0)) { - SG_LOG(SG_GENERAL, SG_ALERT, - "AI error: requesting ATC instruction for aircraft without traffic record"); + SG_LOG(SG_ATC, SG_ALERT, + "AI error: requesting ATC instruction for aircraft without traffic record at " << SG_ORIGIN); } else { return i->getInstruction(); } @@ -1078,8 +1129,8 @@ bool FGStartupController::hasInstruction(int id) } } if (i == activeTraffic.end() || (activeTraffic.size() == 0)) { - SG_LOG(SG_GENERAL, SG_ALERT, - "AI error: checking ATC instruction for aircraft without traffic record"); + SG_LOG(SG_ATC, SG_ALERT, + "AI error: checking ATC instruction for aircraft without traffic record at " << SG_ORIGIN); } else { return i->hasInstruction(); } @@ -1102,8 +1153,8 @@ FGATCInstruction FGStartupController::getInstruction(int id) } } if (i == activeTraffic.end() || (activeTraffic.size() == 0)) { - SG_LOG(SG_GENERAL, SG_ALERT, - "AI error: requesting ATC instruction for aircraft without traffic record"); + SG_LOG(SG_ATC, SG_ALERT, + "AI error: requesting ATC instruction for aircraft without traffic record at " << SG_ORIGIN); } else { return i->getInstruction(); } @@ -1125,8 +1176,8 @@ void FGStartupController::signOff(int id) } } if (i == activeTraffic.end() || (activeTraffic.size() == 0)) { - SG_LOG(SG_GENERAL, SG_ALERT, - "AI error: Aircraft without traffic record is signing off from tower"); + SG_LOG(SG_ATC, SG_ALERT, + "AI error: Aircraft without traffic record is signing off from tower at " << SG_ORIGIN); } else { //cerr << i->getAircraft()->getCallSign() << " signing off from startupcontroller" << endl; i = activeTraffic.erase(i); @@ -1150,13 +1201,13 @@ bool FGStartupController::checkTransmissionState(int st, time_t now, time_t star FGATCDialogNew::instance()->removeEntry(1); } else { //cerr << "creading message for " << i->getAircraft()->getCallSign() << endl; - transmit(&(*i), msgId, msgDir, false); + transmit(&(*i), &(*parent), msgId, msgDir, false); return false; } } if (now > startTime) { //cerr << "Transmitting startup msg" << endl; - transmit(&(*i), msgId, msgDir, true); + transmit(&(*i), &(*parent), msgId, msgDir, true); i->updateState(); lastTransmission = now; available = false; @@ -1186,8 +1237,8 @@ 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"); + SG_LOG(SG_ATC, SG_ALERT, + "AI error: updating aircraft without traffic record at " << SG_ORIGIN); } else { i->setPositionAndHeading(lat, lon, heading, speed, alt); current = i; @@ -1225,11 +1276,11 @@ void FGStartupController::updateAircraftInformation(int id, double lat, double l if (now > startTime + 200) { if (i->pushBackAllowed()) { i->allowRepeatedTransmissions(); - transmit(&(*i), MSG_PERMIT_PUSHBACK_CLEARANCE, + transmit(&(*i), &(*parent), MSG_PERMIT_PUSHBACK_CLEARANCE, ATC_GROUND_TO_AIR, true); i->updateState(); } else { - transmit(&(*i), MSG_HOLD_PUSHBACK_CLEARANCE, + transmit(&(*i), &(*parent), MSG_HOLD_PUSHBACK_CLEARANCE, ATC_GROUND_TO_AIR, true); i->suppressRepeatedTransmissions(); } @@ -1247,7 +1298,7 @@ static void WorldCoordinate(osg::Matrix& obj_pos, double lat, double lon, double elev, double hdg, double slope) { SGGeod geod = SGGeod::fromDegM(lon, lat, elev); - obj_pos = geod.makeZUpFrame(); + obj_pos = makeZUpFrame(geod); // hdg is not a compass heading, but a counter-clockwise rotation // around the Z axis obj_pos.preMult(osg::Matrix::rotate(hdg * SGD_DEGREES_TO_RADIANS, @@ -1276,12 +1327,13 @@ void FGStartupController::render(bool visible) if (visible) { group = new osg::Group; FGScenery * local_scenery = globals->get_scenery(); - double elevation_meters = 0.0; - double elevation_feet = 0.0; + //double elevation_meters = 0.0; + //double elevation_feet = 0.0; //for ( FGTaxiSegmentVectorIterator i = segments.begin(); i != segments.end(); i++) { double dx = 0; + time_t now = time(NULL) + fgGetLong("/sim/time/warp"); for (TrafficVectorIterator i = activeTraffic.begin(); i != activeTraffic.end(); i++) { if (i->isActive(300)) { // Handle start point @@ -1313,12 +1365,12 @@ void FGStartupController::render(bool visible) } else { elevationStart = ((i)->getAircraft()->_getAltitude() * SG_FEET_TO_METER); } - double elevationEnd = segment->getEnd()->getElevation(); + double elevationEnd = segment->getEnd()->getElevationM(parent->getElevation()*SG_FEET_TO_METER); if ((elevationEnd == 0) || (elevationEnd == parent->getElevation())) { SGGeod center2 = end; center2.setElevationM(SG_MAX_ELEVATION_M); if (local_scenery->get_elevation_m( center2, elevationEnd, NULL )) { - elevation_feet = elevationEnd * SG_METER_TO_FEET + 0.5; + //elevation_feet = elevationEnd * SG_METER_TO_FEET + 0.5; //elevation_meters += 0.5; } else { @@ -1351,7 +1403,7 @@ void FGStartupController::render(bool visible) geode->addDrawable(geometry); //osg::Node *custom_obj; SGMaterial *mat; - if (segment->hasBlock()) { + if (segment->hasBlock(now)) { mat = matlib->find("UnidirectionalTaperRed"); } else { mat = matlib->find("UnidirectionalTaperGreen"); @@ -1375,13 +1427,13 @@ void FGStartupController::render(bool visible) obj_trans->setDataVariance(osg::Object::STATIC); FGTaxiSegment *segment = parent->getGroundNetwork()->findSegment(k); - double elevationStart = segment->getStart()->getElevation(); - double elevationEnd = segment->getEnd ()->getElevation(); + double elevationStart = segment->getStart()->getElevationM(parent->getElevation()*SG_FEET_TO_METER); + double elevationEnd = segment->getEnd ()->getElevationM(parent->getElevation()*SG_FEET_TO_METER); if ((elevationStart == 0) || (elevationStart == parent->getElevation())) { SGGeod center2 = segment->getStart()->getGeod(); center2.setElevationM(SG_MAX_ELEVATION_M); if (local_scenery->get_elevation_m( center2, elevationStart, NULL )) { - elevation_feet = elevationStart * SG_METER_TO_FEET + 0.5; + //elevation_feet = elevationStart * SG_METER_TO_FEET + 0.5; //elevation_meters += 0.5; } else { @@ -1393,7 +1445,7 @@ void FGStartupController::render(bool visible) SGGeod center2 = segment->getEnd()->getGeod(); center2.setElevationM(SG_MAX_ELEVATION_M); if (local_scenery->get_elevation_m( center2, elevationEnd, NULL )) { - elevation_feet = elevationEnd * SG_METER_TO_FEET + 0.5; + //elevation_feet = elevationEnd * SG_METER_TO_FEET + 0.5; //elevation_meters += 0.5; } else { @@ -1428,7 +1480,7 @@ void FGStartupController::render(bool visible) geode->addDrawable(geometry); //osg::Node *custom_obj; SGMaterial *mat; - if (segment->hasBlock()) { + if (segment->hasBlock(now)) { mat = matlib->find("UnidirectionalTaperRed"); } else { mat = matlib->find("UnidirectionalTaperGreen"); @@ -1528,8 +1580,8 @@ void FGApproachController::updateAircraftInformation(int id, double lat, double } // // 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"); + SG_LOG(SG_ATC, SG_ALERT, + "AI error: updating aircraft without traffic record at " << SG_ORIGIN); } else { i->setPositionAndHeading(lat, lon, heading, speed, alt); current = i; @@ -1576,8 +1628,8 @@ void FGApproachController::signOff(int id) } } if (i == activeTraffic.end() || (activeTraffic.size() == 0)) { - SG_LOG(SG_GENERAL, SG_ALERT, - "AI error: Aircraft without traffic record is signing off from approach"); + SG_LOG(SG_ATC, SG_ALERT, + "AI error: Aircraft without traffic record is signing off from approach at " << SG_ORIGIN); } else { i = activeTraffic.erase(i); } @@ -1605,8 +1657,8 @@ bool FGApproachController::hasInstruction(int id) } } if (i == activeTraffic.end() || (activeTraffic.size() == 0)) { - SG_LOG(SG_GENERAL, SG_ALERT, - "AI error: checking ATC instruction for aircraft without traffic record"); + SG_LOG(SG_ATC, SG_ALERT, + "AI error: checking ATC instruction for aircraft without traffic record at " << SG_ORIGIN); } else { return i->hasInstruction(); } @@ -1629,8 +1681,8 @@ FGATCInstruction FGApproachController::getInstruction(int id) } } if (i == activeTraffic.end() || (activeTraffic.size() == 0)) { - SG_LOG(SG_GENERAL, SG_ALERT, - "AI error: requesting ATC instruction for aircraft without traffic record"); + SG_LOG(SG_ATC, SG_ALERT, + "AI error: requesting ATC instruction for aircraft without traffic record at " << SG_ORIGIN); } else { return i->getInstruction(); }