heading(0),
speed(0),
altitude(0),
- radius(0) {
+ radius(0),
+ frequencyId(0),
+ allowTransmission(true) {
}
void FGTrafficRecord::setPositionAndIntentions(int pos, FGAIFlightPlan *route)
for (intVecIterator i = intentions.begin(); i != intentions.end(); i++)
{
- if (opp = net->findSegment(other.currentPos)->opposite())
+ if ((opp = net->findSegment(other.currentPos)->opposite()))
{
if ((*i) > 0)
if (opp->getIndex() == net->findSegment(*i)->getIndex())
if (other.intentions.size())
{
for (intVecIterator j = other.intentions.begin(); j != other.intentions.end(); j++)
- {
+ {
// cerr << "Current segment 1 " << (*i) << endl;
if ((*i) > 0) {
- if (opp = net->findSegment(*i)->opposite())
+ if ((opp = net->findSegment(*i)->opposite()))
{
if (opp->getIndex() ==
net->findSegment(*j)->getIndex())
instruction.setHeading(heading);
}
+bool FGTrafficRecord::pushBackAllowed() {
+ double course, az2,dist;
+ SGGeod curr(SGGeod::fromDegM(getLongitude(),
+ getLatitude(),
+ getAltitude()));
+
+ double userLatitude = fgGetDouble("/position/latitude-deg");
+ double userLongitude = fgGetDouble("/position/longitude-deg");
+ SGGeod user(SGGeod::fromDeg(userLongitude,userLatitude));
+ SGGeodesy::inverse(curr, user, course, az2, dist);
+ //cerr << "Distance to user : " << dist << endl;
+ return (dist > 250);
+
+}
+
/***************************************************************************
changeAltitude = false;
resolveCircularWait = false;
- double speed = 0;
- double heading = 0;
- double alt = 0;
+ speed = 0;
+ heading = 0;
+ alt = 0;
}
bool FGATCInstruction::hasInstruction()
string sender, receiver;
int stationFreq = 0;
int taxiFreq = 0;
+ int freqId = 0;
string atisInformation;
- //double commFreqD;
- switch (msgDir) {
- case ATC_AIR_TO_GROUND:
- sender = rec->getAircraft()->getTrafficRef()->getCallSign();
- switch (rec->getLeg()) {
- case 2:
- case 3:
- stationFreq =
- rec->getAircraft()->getTrafficRef()->getDepartureAirport()->getDynamics()->getGroundFrequency(rec->getLeg());
- taxiFreq =
- rec->getAircraft()->getTrafficRef()->getDepartureAirport()->getDynamics()->getGroundFrequency(3);
- receiver = rec->getAircraft()->getTrafficRef()->getDepartureAirport()->getName() + "-Ground";
- atisInformation = rec->getAircraft()->getTrafficRef()->getDepartureAirport()->getDynamics()->getAtisInformation();
- break;
- case 4:
- receiver = rec->getAircraft()->getTrafficRef()->getDepartureAirport()->getName() + "-Tower";
- break;
- }
- break;
- case ATC_GROUND_TO_AIR:
- receiver = rec->getAircraft()->getTrafficRef()->getCallSign();
- switch (rec->getLeg()) {
- case 2:
- case 3:
- stationFreq =
- rec->getAircraft()->getTrafficRef()->getDepartureAirport()->getDynamics()->getGroundFrequency(rec->getLeg());
- taxiFreq =
- rec->getAircraft()->getTrafficRef()->getDepartureAirport()->getDynamics()->getGroundFrequency(3);
- sender = rec->getAircraft()->getTrafficRef()->getDepartureAirport()->getName() + "-Ground";
- atisInformation = rec->getAircraft()->getTrafficRef()->getDepartureAirport()->getDynamics()->getAtisInformation();
- break;
-
- case 4:
- sender = rec->getAircraft()->getTrafficRef()->getDepartureAirport()->getName() + "-Tower";
- break;
- }
- break;
- }
string text;
string taxiFreqStr;
double heading = 0;
string transponderCode;
FGAIFlightPlan *fp;
string fltRules;
+
+ //double commFreqD;
+ sender = rec->getAircraft()->getTrafficRef()->getCallSign();
+ switch (rec->getLeg()) {
+ case 2:
+ case 3:
+ freqId = rec->getNextFrequency();
+ stationFreq =
+ rec->getAircraft()->getTrafficRef()->getDepartureAirport()->getDynamics()->getGroundFrequency(rec->getLeg()+freqId);
+ taxiFreq =
+ rec->getAircraft()->getTrafficRef()->getDepartureAirport()->getDynamics()->getGroundFrequency(3);
+ receiver = rec->getAircraft()->getTrafficRef()->getDepartureAirport()->getName() + "-Ground";
+ atisInformation = rec->getAircraft()->getTrafficRef()->getDepartureAirport()->getDynamics()->getAtisInformation();
+ break;
+ case 4:
+ receiver = rec->getAircraft()->getTrafficRef()->getDepartureAirport()->getName() + "-Tower";
+ break;
+ }
+ // Swap sender and receiver value in case of a ground to air transmission
+ if (msgDir == ATC_GROUND_TO_AIR) {
+ string tmp = sender;
+ sender = receiver;
+ receiver = tmp;
+ }
switch (msgId) {
case MSG_ANNOUNCE_ENGINE_START:
text = sender + ". Ready to Start up";
// Assign SID, if necessery (TODO)
case MSG_PERMIT_ENGINE_START:
taxiFreqStr = formatATCFrequency3_2(taxiFreq);
-
+
heading = rec->getAircraft()->getTrafficRef()->getCourse();
fltType = rec->getAircraft()->getTrafficRef()->getFlightType();
rwyClass= rec->getAircraft()->GetFlightPlan()->getRunwayClassFromTrafficType(fltType);
activeRunway + ", " + SID + ", squawk " + transponderCode + ". " +
"For push-back and taxi clearance call " + taxiFreqStr + ". " + sender;
break;
- default:
+ case MSG_ACKNOWLEDGE_SWITCH_GROUND_FREQUENCY:
+ taxiFreqStr = formatATCFrequency3_2(taxiFreq);
+ text = receiver + ". Switching to " + taxiFreqStr + ". " + sender;
+ break;
+ case MSG_REQUEST_PUSHBACK_CLEARANCE:
+ text = receiver + ". Request push-back. " + sender;
break;
+ case MSG_PERMIT_PUSHBACK_CLEARANCE:
+ text = receiver + ". Push-back approved. " + sender;
+ break;
+ case MSG_HOLD_PUSHBACK_CLEARANCE:
+ text = receiver + ". Standby. " + sender;
+ break;
+ default:
+ text = sender + ". Transmitting unknown Message";
+ break;
}
double onBoardRadioFreq0 = fgGetDouble("/instrumentation/comm[0]/frequencies/selected-mhz");
double onBoardRadioFreq1 = fgGetDouble("/instrumentation/comm[1]/frequencies/selected-mhz");
// Display ATC message only when one of the radios is tuned
// the relevant frequency.
// Note that distance attenuation is currently not yet implemented
- //cerr << "Transmitting " << text << " at " << stationFreq;
if ((onBoardRadioFreqI0 == stationFreq) || (onBoardRadioFreqI1 == stationFreq)) {
- fgSetString("/sim/messages/atc", text.c_str());
- //cerr << "Printing Message: " << endl;
+ if (rec->allowTransmissions()) {
+ fgSetString("/sim/messages/atc", text.c_str());
+ }
}
}
return string(buffer);
}
+// TODO: Set transponder codes according to real-world routes.
+// The current version just returns a random string of four octal numbers.
string FGATCController::genTransponderCode(string fltRules) {
if (fltRules == "VFR") {
return string("1200");
available = false;
}
}
+ // Note: The next two 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;
+ }
+ }
+
+
// TODO: Switch to APRON control and request pushback Clearance.
// Get Push back clearance
- if ((state == 4) && available){
+ if ((state == 5) && available){
+ if (now > startTime+160) {
+ transmit(&(*i), MSG_REQUEST_PUSHBACK_CLEARANCE, ATC_AIR_TO_GROUND);
+ i->updateState();
+ lastTransmission = now;
+ available = false;
+ }
+ }
+ if ((state == 6) && available){
+ if (now > startTime+180) {
+ if (i->pushBackAllowed()) {
+ i->allowRepeatedTransmissions();
+ transmit(&(*i), MSG_PERMIT_PUSHBACK_CLEARANCE, ATC_GROUND_TO_AIR);
+ i->updateState();
+ } else {
+ transmit(&(*i), MSG_HOLD_PUSHBACK_CLEARANCE, ATC_GROUND_TO_AIR);
+ i->suppressRepeatedTransmissions();
+ }
+ lastTransmission = now;
+ available = false;
+ }
+ }
+ if ((state == 6) && available){
i->setHoldPosition(false);
}
}