* AI aircraft distance to user proximity detection works again (lat/lon were inverted).
* The parking uses by the user aircraft is marked as such to prevent it being reused by an AI aicraft
* AI aircraft won't receive permission for pushback until the user aircraft is at a fair distance.
heading(0),
speed(0),
altitude(0),
- radius(0) {
+ radius(0),
+ allowTransmission(true) {
}
void FGTrafficRecord::setPositionAndIntentions(int pos, FGAIFlightPlan *route)
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);
+
+}
+
/***************************************************************************
activeRunway + ", " + SID + ", squawk " + transponderCode + ". " +
"For push-back and taxi clearance call " + taxiFreqStr + ". " + sender;
break;
- default:
+ 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");
// 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());
+ }
}
}
// TODO: Switch to APRON control and request pushback Clearance.
// Get Push back clearance
if ((state == 4) && available){
+ if (now > startTime+130) {
+ transmit(&(*i), MSG_REQUEST_PUSHBACK_CLEARANCE, ATC_AIR_TO_GROUND);
+ i->updateState();
+ lastTransmission = now;
+ available = false;
+ }
+ }
+ if ((state == 5) && available){
+ if (now > startTime+130) {
+ 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);
}
}
int currentPos;
int leg;
int state;
+ bool allowTransmission;
time_t timer;
intVec intentions;
FGATCInstruction instruction;
string getRunway() { return runway; };
//void setCallSign(string clsgn) { callsign = clsgn; };
void setAircraft(FGAIAircraft *ref) { aircraft = ref;};
- void updateState() { state++;};
+ void updateState() { state++; allowTransmission=true; };
//string getCallSign() { return callsign; };
FGAIAircraft *getAircraft() { return aircraft;};
int getTime() { return timer; };
int getLeg() { return leg; };
void setTime(time_t time) { timer = time; };
+
+ bool pushBackAllowed();
+ bool allowTransmissions() { return allowTransmission; };
+ void suppressRepeatedTransmissions () { allowTransmission=false; };
+ void allowRepeatedTransmissions () { allowTransmission=true; };
};
typedef vector<FGTrafficRecord> TrafficVector;
MSG_REQUEST_ENGINE_START,
MSG_PERMIT_ENGINE_START,
MSG_DENY_ENGINE_START,
- MSG_ACKNOWLEDGE_ENGINE_START } AtcMsgId;
+ MSG_ACKNOWLEDGE_ENGINE_START,
+ MSG_REQUEST_PUSHBACK_CLEARANCE,
+ MSG_PERMIT_PUSHBACK_CLEARANCE,
+ MSG_HOLD_PUSHBACK_CLEARANCE } AtcMsgId;
typedef enum {
ATC_AIR_TO_GROUND,
ATC_GROUND_TO_AIR } AtcMsgDir;
instruction. See below for the hold position instruction.
Note that there currently still is one flaw in the logic that needs to be addressed.
- can be situations where one aircraft is in front of the current aircraft, on a separate
+ There can be situations where one aircraft is in front of the current aircraft, on a separate
route, but really close after an intersection coming off the current route. This
aircraft is still close enough to block the current aircraft. This situation is currently
not addressed yet, but should be.
{
//cerr << "Comparing " << current->getId() << " and " << i->getId() << endl;
SGGeod other(SGGeod::fromDegM(i->getLongitude(),
- i->getLatitude(), i->getAltitude()));
+ i->getLatitude(),
+ i->getAltitude()));
SGGeodesy::inverse(curr, other, course, az2, dist);
bearing = fabs(heading-course);
if (bearing > 180)
// Finally, check UserPosition
double userLatitude = fgGetDouble("/position/latitude-deg");
double userLongitude = fgGetDouble("/position/longitude-deg");
- SGGeod user(SGGeod::fromDeg(userLatitude,userLongitude));
- SGGeodesy::inverse(user, curr, course, az2, dist);
-
+ SGGeod user(SGGeod::fromDeg(userLongitude,userLatitude));
+ SGGeodesy::inverse(curr, user, course, az2, dist);
+
bearing = fabs(heading-course);
if (bearing > 180)
- bearing = 360-bearing;
+ bearing = 360-bearing;
if ((dist < mindist) && (bearing < 60.0))
{
mindist = dist;
minbearing = bearing;
otherReasonToSlowDown = true;
}
-
- // if (closest == current) {
- // //SG_LOG(SG_GENERAL, SG_ALERT, "AI error: closest and current match");
- // //return;
- // }
- //cerr << "Distance : " << dist << " bearing : " << bearing << " heading : " << heading
- // << " course : " << course << endl;
+
current->clearSpeedAdjustment();
if (current->checkPositionAndIntentions(*closest) || otherReasonToSlowDown)
return false;
}
FGParking* parking = dcs->getParking(park_index);
+ parking->setAvailable(false);
fgApplyStartOffset(
SGGeod::fromDeg(parking->getLongitude(), parking->getLatitude()),
parking->getHeading());