TowerPlaneRec::TowerPlaneRec() :
planePtr(NULL),
+ eta(0),
+ dist_out(0),
clearedToLand(false),
clearedToLineUp(false),
clearedToTakeOff(false),
instructedToGoAround(false),
onRwy(false),
nextOnRwy(false),
+ gearWasUp(false),
+ gearUpReported(false),
vfrArrivalReported(false),
vfrArrivalAcknowledged(false),
opType(TTT_UNKNOWN),
leg(LEG_UNKNOWN),
landingType(AIP_LT_UNKNOWN),
- gearWasUp(false),
- gearUpReported(false),
isUser(false)
{
plane.callsign = "UNKNOWN";
TowerPlaneRec::TowerPlaneRec(const PlaneRec& p) :
planePtr(NULL),
+ eta(0),
+ dist_out(0),
clearedToLand(false),
clearedToLineUp(false),
clearedToTakeOff(false),
instructedToGoAround(false),
onRwy(false),
nextOnRwy(false),
+ gearWasUp(false),
+ gearUpReported(false),
vfrArrivalReported(false),
vfrArrivalAcknowledged(false),
opType(TTT_UNKNOWN),
leg(LEG_UNKNOWN),
landingType(AIP_LT_UNKNOWN),
- gearWasUp(false),
- gearUpReported(false),
isUser(false)
{
plane = p;
TowerPlaneRec::TowerPlaneRec(const SGGeod& pt) :
planePtr(NULL),
+ eta(0),
+ dist_out(0),
clearedToLand(false),
clearedToLineUp(false),
clearedToTakeOff(false),
instructedToGoAround(false),
onRwy(false),
nextOnRwy(false),
+ gearWasUp(false),
+ gearUpReported(false),
vfrArrivalReported(false),
vfrArrivalAcknowledged(false),
opType(TTT_UNKNOWN),
leg(LEG_UNKNOWN),
landingType(AIP_LT_UNKNOWN),
- gearWasUp(false),
- gearUpReported(false),
isUser(false)
{
plane.callsign = "UNKNOWN";
TowerPlaneRec::TowerPlaneRec(const PlaneRec& p, const SGGeod& pt) :
planePtr(NULL),
+ eta(0),
+ dist_out(0),
clearedToLand(false),
clearedToLineUp(false),
clearedToTakeOff(false),
instructedToGoAround(false),
onRwy(false),
nextOnRwy(false),
+ gearWasUp(false),
+ gearUpReported(false),
vfrArrivalReported(false),
vfrArrivalAcknowledged(false),
opType(TTT_UNKNOWN),
leg(LEG_UNKNOWN),
landingType(AIP_LT_UNKNOWN),
- gearWasUp(false),
- gearUpReported(false),
isUser(false)
{
plane = p;
//cout << "Dep list, checking " << t->plane.callsign;
double distout; // meters
- if(t->isUser) distout = dclGetHorizontalSeparation(SGGeod::fromDegM(lon, lat, elev), SGGeod::fromDegM(user_lon_node->getDoubleValue(), user_lat_node->getDoubleValue(), user_elev_node->getDoubleValue()));
- else distout = dclGetHorizontalSeparation(SGGeod::fromDegM(lon, lat, elev), t->planePtr->getPos());
+ if(t->isUser) distout = dclGetHorizontalSeparation(_geod,
+ SGGeod::fromDegM(user_lon_node->getDoubleValue(), user_lat_node->getDoubleValue(), user_elev_node->getDoubleValue()));
+ else distout = dclGetHorizontalSeparation(_geod, t->planePtr->getPos());
//cout << " distout = " << distout << '\n';
if(t->isUser && !(t->clearedToTakeOff)) { // HACK - we use clearedToTakeOff to check if ATC already contacted with plane (and cleared take-off) or not
if(!OnAnyRunway(SGGeod::fromDegM(user_lon_node->getDoubleValue(), user_lat_node->getDoubleValue(), 0.0), false)) {
// Based on the airport-id and wind get the active runway
const FGAirport* apt = fgFindAirportID(ident);
- assert(apt);
+ if (!apt) {
+ SG_LOG(SG_ATC, SG_WARN, "FGTower::DoRwyDetails: unknown ICAO:" << ident);
+ return;
+ }
+
FGRunway* runway = apt->getActiveRunwayForUsage();
activeRwy = runway->ident();
}
// move to the +l end/center of the runway
//cout << "Runway center is at " << runway._lon << ", " << runway._lat << '\n';
- double tshlon, tshlat, tshr;
- double tolon, tolat, tor;
+ double tshlon = 0.0, tshlat = 0.0, tshr = 0.0;
+ double tolon = 0.0, tolat = 0.0, tor = 0.0;
rwy.length = runway->lengthM();
geo_direct_wgs_84 ( aptElev, runway->latitude(), runway->longitude(), other_way,
rwy.length / 2.0 - 25.0, &tshlat, &tshlon, &tshr );
// Only call this at startup - reading the runways database is expensive and needs to be fixed!
bool FGTower::OnAnyRunway(const SGGeod& pt, bool onGround) {
ATCData ad;
- double dist = current_commlist->FindClosest(lon, lat, elev, ad, TOWER, 7.0);
+ double dist = current_commlist->FindClosest(_geod, ad, TOWER, 7.0);
if(dist < 0.0) {
return(false);
}
t->plane.type = GA_SINGLE; // FIXME - Another assumption!
t->plane.callsign = usercall;
+ CalcETA(t);
t->vfrArrivalReported = true;
responseReqd = true;
else if ( strcmp ( tag, "@MI" ) == 0 ) {
char buf[10];
//sprintf( buf, "%3.1f", tpars.miles );
- int dist_miles = (int)dclGetHorizontalSeparation(SGGeod::fromDegM(lon, lat, elev), SGGeod::fromDegM(user_lon_node->getDoubleValue(), user_lat_node->getDoubleValue(), user_elev_node->getDoubleValue())) / 1600;
+ int dist_miles = (int)dclGetHorizontalSeparation(_geod, SGGeod::fromDegM(user_lon_node->getDoubleValue(), user_lat_node->getDoubleValue(), user_elev_node->getDoubleValue())) / 1600;
sprintf(buf, "%i", dist_miles);
strcat( &dum[0], &buf[0] );
}
}
}
else if(strcmp(tag, "@CD") == 0) { // @CD = compass direction
- double h = GetHeadingFromTo(SGGeod::fromDegM(lon, lat, elev), SGGeod::fromDegM(user_lon_node->getDoubleValue(), user_lat_node->getDoubleValue(), user_elev_node->getDoubleValue()));
+ double h = GetHeadingFromTo(_geod, SGGeod::fromDegM(user_lon_node->getDoubleValue(), user_lat_node->getDoubleValue(), user_elev_node->getDoubleValue()));
while(h < 0.0) h += 360.0;
while(h > 360.0) h -= 360.0;
if(h < 22.5 || h > 337.5) {
}
string FGTower::GetATISID() {
- int hours = fgGetInt("/sim/time/utc/hour");
- int phonetic_id = current_commlist->GetCallSign(ident, hours, 0);
- return GetPhoneticIdent(phonetic_id);
+ double tstamp = atof(fgGetString("sim/time/elapsed-sec"));
+ const int minute(60); // in SI units
+ int interval = ATIS ? 60*minute : 2*minute; // AWOS updated frequently
+ int sequence = current_commlist->GetAtisSequence(ident,
+ tstamp, interval);
+
+ return GetPhoneticLetter(sequence); // the sequence letter
}
ostream& operator << (ostream& os, tower_traffic_type ttt) {