// Init en-route to destID at point pt.
// TODO - no idea what to do if pt is above planes ceiling due mountains!!
-bool FGAIGAVFRTraffic::Init(Point3D pt, string destID, const string& callsign) {
+bool FGAIGAVFRTraffic::Init(const Point3D& pt, const string& destID, const string& callsign) {
FGAILocalTraffic::Init(callsign, destID, EN_ROUTE);
// TODO FIXME - to get up and running we're going to ignore elev and get FGAIMgr to
// pass in known good values for the test location. Need to fix this!!! (or at least canonically decide who has responsibility for setting elev).
_pos.setelev(_cruise_alt);
// initially set waypoint as airport location
_wp = _destPos;
- _hdg = GetHeadingFromTo(_pos, _wp);
+ // Set the initial track
+ track = GetHeadingFromTo(_pos, _wp);
+ // And set the plane to keep following it.
+ SetTrack(GetHeadingFromTo(_pos, _wp));
_roll = 0.0;
_pitch = 0.0;
slope = 0.0;
}
// Init at srcID to fly to destID
-bool FGAIGAVFRTraffic::Init(string srcID, string destID, const string& callsign, OperatingState state) {
+bool FGAIGAVFRTraffic::Init(const string& srcID, const string& destID, const string& callsign, OperatingState state) {
_enroute = false;
FGAILocalTraffic::Init(callsign, srcID, PARKED);
return(true);
//cout << "_" << flush;
GetAirportDetails(airportID);
//cout << "L" << flush;
- // TODO FIXME TODO - need to check that tower is valid before this else if problem -> BOOM!
- freq = (double)tower->get_freq() / 100.0;
- tuned_station = tower;
+ if(_controlled) {
+ freq = (double)tower->get_freq() / 100.0;
+ tuned_station = tower;
+ } else {
+ freq = 122.8; // TODO - need to get the correct CTAF/Unicom frequency if no tower
+ tuned_station = NULL;
+ }
//cout << "freq = " << freq << endl;
GetRwyDetails(airportID);
//"@AP Tower @CS @MI miles @CD of the airport for full stop with the ATIS"
if(rwy.rwyID.size() == 3) {
patternDirection = (rwy.rwyID.substr(2,1) == "R" ? 1 : -1);
}
- pending_transmission = tower->get_name();
- pending_transmission += " Tower ";
+ if(_controlled) {
+ pending_transmission = tower->get_name();
+ pending_transmission += " Tower ";
+ } else {
+ pending_transmission = "Traffic ";
+ // TODO - find some way of getting uncontrolled airport name
+ }
pending_transmission += plane.callsign;
//char buf[10];
int dist_miles = (int)dclGetHorizontalSeparation(_pos, _destPos) / 1600;
_straightIn = true;
_incoming = true;
_wp = GetPatternApproachPos();
- _hdg = GetHeadingFromTo(_pos, _wp); // TODO - turn properly!
+ //_hdg = GetHeadingFromTo(_pos, _wp); // TODO - turn properly!
+ SetTrack(GetHeadingFromTo(_pos, _wp));
slope = atan((_wp.elev() - _pos.elev()) / dclGetHorizontalSeparation(_wp, _pos)) * DCL_RADIANS_TO_DEGREES;
double thesh_offset = 0.0;
Point3D opos = ortho.ConvertToLocal(_pos);
_downwindEntry = true;
_incoming = true;
_wp = GetPatternApproachPos();
- _hdg = GetHeadingFromTo(_pos, _wp); // TODO - turn properly!
+ SetTrack(GetHeadingFromTo(_pos, _wp));
slope = atan((_wp.elev() - _pos.elev()) / dclGetHorizontalSeparation(_wp, _pos)) * DCL_RADIANS_TO_DEGREES;
//cout << "slope = " << slope << '\n';
pending_transmission = "Report ";
if(_straightIn) {
//cout << "A " << flush;
if(fabs(orthopos.x()) < 10.0 && !_established) {
- _hdg = rwy.hdg; // MEGA MEGA HACK - FIXME!!!!!!!
+ SetTrack(rwy.hdg);
_established = true;
//cout << "Established at " << orthopos << '\n';
}
if(_entering) {
//cout << "C" << flush;
if(_turning) {
- double tgt_hdg = rwy.hdg + 180.0;
- while((tgt_hdg - _hdg) > 180.0) _hdg += 360.0;
- while((_hdg - tgt_hdg) > 180.0) _hdg -= 360.0;
- double turn_time = 60.0;
- _hdg += (360.0 / turn_time) * dt * (tgt_hdg > _hdg ? 1.0 : -1.0);
- Bank(25.0 * (tgt_hdg > _hdg ? 1.0 : -1.0));
- if(fabs(_hdg - tgt_hdg) < 2.0) {
+ if(fabs(_hdg - (rwy.hdg + 180)) < 2.0) { // TODO - use track instead of _hdg?
//cout << "Going Local...\n";
- _hdg = rwy.hdg + 180.0; // TODO - FIX THIS UGLY HACK!!!!!!!
leg = DOWNWIND;
_local = true;
_aip.setVisible(true); // HACK
if(fabs(orthopos.x() - (patternDirection == 1 ? 1000 : -1000)) < (_e45 ? 175 : 550)) { // Caution - hardwired turn clearances.
//cout << "_turning...\n";
_turning = true;
+ SetTrack(rwy.hdg + 180.0);
} // TODO - need to check for other traffic in the pattern and enter much more integilently than that!!!
} else {
//cout << "D" << flush;
slope = 0.0;
ConditionalTransmit(30);
if(_e45) {
- _hdg = (patternDirection == 1 ? rwy.hdg - 135.0 : rwy.hdg + 135.0);
+ SetTrack(patternDirection == 1 ? rwy.hdg - 135.0 : rwy.hdg + 135.0);
} else {
- _hdg = (patternDirection == 1 ? rwy.hdg + 90.0 : rwy.hdg - 90.0);
+ SetTrack(patternDirection == 1 ? rwy.hdg + 90.0 : rwy.hdg - 90.0);
}
- if(_hdg < 0.0) _hdg += 360.0;
+ //if(_hdg < 0.0) _hdg += 360.0;
_entering = true;
+ } else {
+ SetTrack(GetHeadingFromTo(_pos, _wp));
}
}
}
slope = 0.0;
}
// FIXME - lots of hackery in the next six lines!!!!
- double track = _hdg;
- double crab = 0.0;
+ //double track = _hdg;
+ double crab = 0.0; // This is a placeholder for when we take wind into account.
_hdg = track + crab;
double vel = _cruise_ias;
double dist = vel * 0.514444 * dt;
_clearedDownwindEntry = true;
break;
default:
+ SG_LOG(SG_ATC, SG_WARN, "FGAIGAVFRTraffic::RegisterTransmission(...) called with unknown code " << code);
+ FGAILocalTraffic::RegisterTransmission(code);
break;
}
}
// 12 - report base
// 13 - report final
// 14 - Contact Tower for VFR arrival
+ // 99 - Remove self
if(code < 14) {
FGAILocalTraffic::ProcessCallback(code);
} else if(code == 14) {
- tower->VFRArrivalContact(plane, this, FULL_STOP);
+ if(_controlled) {
+ tower->VFRArrivalContact(plane, this, FULL_STOP);
+ }
+ // TODO else possibly announce arrival intentions at uncontrolled airport?
+ } else if(code == 99) {
+ // Might handle this different in future - hence separated from the other codes to pass to AILocalTraffic.
+ FGAILocalTraffic::ProcessCallback(code);
}
}
// 3/ At and appropriate point on non-circuit side of rwy at take-off end for perpendicular entry to circuit overflying end-of-rwy.
Point3D FGAIGAVFRTraffic::GetPatternApproachPos() {
//cout << "\n\n";
- //cout << "PPPPPPPPPPPPPPPPPPPPPPPppppppppppppppp\n";
//cout << "Calculating pattern approach pos for " << plane.callsign << '\n';
Point3D orthopos = ortho.ConvertToLocal(_pos);
Point3D tmp;