Merge branch 'durk-atc' into next
This commit is contained in:
commit
cfa08438ae
19 changed files with 799 additions and 632 deletions
|
@ -65,9 +65,10 @@ FGAIAircraft::FGAIAircraft(FGAISchedule *ref) :
|
|||
else
|
||||
groundOffset = 0;
|
||||
|
||||
fp = 0;
|
||||
controller = 0;
|
||||
prevController = 0;
|
||||
fp = 0;
|
||||
controller = 0;
|
||||
prevController = 0;
|
||||
towerController = 0;
|
||||
dt_count = 0;
|
||||
dt_elev_count = 0;
|
||||
use_perf_vs = true;
|
||||
|
@ -92,6 +93,7 @@ FGAIAircraft::FGAIAircraft(FGAISchedule *ref) :
|
|||
|
||||
_performance = 0; //TODO initialize to JET_TRANSPORT from PerformanceDB
|
||||
dt = 0;
|
||||
takeOffStatus = 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -249,11 +251,11 @@ void FGAIAircraft::SetFlightPlan(FGAIFlightPlan *f) {
|
|||
void FGAIAircraft::ProcessFlightPlan( double dt, time_t now ) {
|
||||
|
||||
// the one behind you
|
||||
FGAIFlightPlan::waypoint* prev = 0;
|
||||
FGAIWaypoint* prev = 0;
|
||||
// the one ahead
|
||||
FGAIFlightPlan::waypoint* curr = 0;
|
||||
FGAIWaypoint* curr = 0;
|
||||
// the next plus 1
|
||||
FGAIFlightPlan::waypoint* next = 0;
|
||||
FGAIWaypoint* next = 0;
|
||||
|
||||
prev = fp->getPreviousWaypoint();
|
||||
curr = fp->getCurrentWaypoint();
|
||||
|
@ -300,7 +302,7 @@ void FGAIAircraft::ProcessFlightPlan( double dt, time_t now ) {
|
|||
<< endl;
|
||||
} */
|
||||
} else {
|
||||
if (curr->finished) //end of the flight plan
|
||||
if (curr->isFinished()) //end of the flight plan
|
||||
{
|
||||
if (fp->getRepeat())
|
||||
fp->restart();
|
||||
|
@ -348,22 +350,22 @@ void FGAIAircraft::ProcessFlightPlan( double dt, time_t now ) {
|
|||
fp->setLeadDistance(tgt_speed, tgt_heading, curr, next);
|
||||
}
|
||||
|
||||
if (!(prev->on_ground)) // only update the tgt altitude from flightplan if not on the ground
|
||||
if (!(prev->getOn_ground())) // only update the tgt altitude from flightplan if not on the ground
|
||||
{
|
||||
tgt_altitude_ft = prev->altitude;
|
||||
if (curr->crossat > -1000.0) {
|
||||
tgt_altitude_ft = prev->getAltitude();
|
||||
if (curr->getCrossat() > -1000.0) {
|
||||
use_perf_vs = false;
|
||||
tgt_vs = (curr->crossat - altitude_ft) / (fp->getDistanceToGo(pos.getLatitudeDeg(), pos.getLongitudeDeg(), curr)
|
||||
tgt_vs = (curr->getCrossat() - altitude_ft) / (fp->getDistanceToGo(pos.getLatitudeDeg(), pos.getLongitudeDeg(), curr)
|
||||
/ 6076.0 / speed*60.0);
|
||||
checkTcas();
|
||||
tgt_altitude_ft = curr->crossat;
|
||||
tgt_altitude_ft = curr->getCrossat();
|
||||
} else {
|
||||
use_perf_vs = true;
|
||||
}
|
||||
}
|
||||
AccelTo(prev->speed);
|
||||
AccelTo(prev->getSpeed());
|
||||
hdg_lock = alt_lock = true;
|
||||
no_roll = prev->on_ground;
|
||||
no_roll = prev->getOn_ground();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -407,16 +409,18 @@ const char * FGAIAircraft::_getTransponderCode() const {
|
|||
return transponderCode.c_str();
|
||||
}
|
||||
|
||||
// NOTE: Check whether the new (delayed leg increment code has any effect on this code.
|
||||
// Probably not, because it should only be executed after we have already passed the leg incrementing waypoint.
|
||||
|
||||
bool FGAIAircraft::loadNextLeg(double distance) {
|
||||
|
||||
int leg;
|
||||
if ((leg = fp->getLeg()) == 10) {
|
||||
if ((leg = fp->getLeg()) == 9) {
|
||||
if (!trafficRef->next()) {
|
||||
return false;
|
||||
}
|
||||
setCallSign(trafficRef->getCallSign());
|
||||
leg = 1;
|
||||
leg = 0;
|
||||
fp->setLeg(leg);
|
||||
}
|
||||
|
||||
|
@ -431,7 +435,7 @@ bool FGAIAircraft::loadNextLeg(double distance) {
|
|||
fp->create (this,
|
||||
dep,
|
||||
arr,
|
||||
leg,
|
||||
leg+1,
|
||||
cruiseAlt,
|
||||
trafficRef->getSpeed(),
|
||||
_getLatitude(),
|
||||
|
@ -508,29 +512,31 @@ void FGAIAircraft::announcePositionToController() {
|
|||
|
||||
// Note that leg has been incremented after creating the current leg, so we should use
|
||||
// leg numbers here that are one higher than the number that is used to create the leg
|
||||
//
|
||||
// NOTE: As of July, 30, 2011, the post-creation leg updating is no longer happening.
|
||||
// Leg numbers are updated only once the aircraft passes the last waypoint created for that legm so I should probably just use
|
||||
// the original leg numbers here!
|
||||
switch (leg) {
|
||||
case 2: // Startup and Push back
|
||||
case 1: // Startup and Push back
|
||||
if (trafficRef->getDepartureAirport()->getDynamics())
|
||||
controller = trafficRef->getDepartureAirport()->getDynamics()->getStartupController();
|
||||
break;
|
||||
case 3: // Taxiing to runway
|
||||
case 2: // Taxiing to runway
|
||||
if (trafficRef->getDepartureAirport()->getDynamics()->getGroundNetwork()->exists())
|
||||
controller = trafficRef->getDepartureAirport()->getDynamics()->getGroundNetwork();
|
||||
break;
|
||||
case 4: //Take off tower controller
|
||||
case 3: //Take off tower controller
|
||||
if (trafficRef->getDepartureAirport()->getDynamics()) {
|
||||
controller = trafficRef->getDepartureAirport()->getDynamics()->getTowerController();
|
||||
} else {
|
||||
cerr << "Error: Could not find Dynamics at airport : " << trafficRef->getDepartureAirport()->getId() << endl;
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
case 6:
|
||||
if (trafficRef->getDepartureAirport()->getDynamics()) {
|
||||
controller = trafficRef->getArrivalAirport()->getDynamics()->getApproachController();
|
||||
}
|
||||
break;
|
||||
case 9: // Taxiing for parking
|
||||
case 8: // Taxiing for parking
|
||||
if (trafficRef->getArrivalAirport()->getDynamics()->getGroundNetwork()->exists())
|
||||
controller = trafficRef->getArrivalAirport()->getDynamics()->getGroundNetwork();
|
||||
break;
|
||||
|
@ -544,13 +550,33 @@ void FGAIAircraft::announcePositionToController() {
|
|||
}
|
||||
prevController = controller;
|
||||
if (controller) {
|
||||
controller->announcePosition(getID(), fp, fp->getCurrentWaypoint()->routeIndex,
|
||||
controller->announcePosition(getID(), fp, fp->getCurrentWaypoint()->getRouteIndex(),
|
||||
_getLatitude(), _getLongitude(), hdg, speed, altitude_ft,
|
||||
trafficRef->getRadius(), leg, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FGAIAircraft::scheduleForATCTowerDepartureControl(int state) {
|
||||
if (!takeOffStatus) {
|
||||
int leg = fp->getLeg();
|
||||
if (trafficRef) {
|
||||
if (trafficRef->getDepartureAirport()->getDynamics()) {
|
||||
towerController = trafficRef->getDepartureAirport()->getDynamics()->getTowerController();
|
||||
} else {
|
||||
cerr << "Error: Could not find Dynamics at airport : " << trafficRef->getDepartureAirport()->getId() << endl;
|
||||
}
|
||||
if (towerController) {
|
||||
towerController->announcePosition(getID(), fp, fp->getCurrentWaypoint()->getRouteIndex(),
|
||||
_getLatitude(), _getLongitude(), hdg, speed, altitude_ft,
|
||||
trafficRef->getRadius(), leg, this);
|
||||
//cerr << "Scheduling " << trafficRef->getCallSign() << " for takeoff " << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
takeOffStatus = state;
|
||||
}
|
||||
|
||||
// Process ATC instructions and report back
|
||||
|
||||
void FGAIAircraft::processATC(FGATCInstruction instruction) {
|
||||
|
@ -587,7 +613,7 @@ void FGAIAircraft::processATC(FGATCInstruction instruction) {
|
|||
//cerr << trafficRef->getCallSign() << " Changing Speed " << endl;
|
||||
AccelTo(instruction.getSpeed());
|
||||
} else {
|
||||
if (fp) AccelTo(fp->getPreviousWaypoint()->speed);
|
||||
if (fp) AccelTo(fp->getPreviousWaypoint()->getSpeed());
|
||||
}
|
||||
}
|
||||
if (instruction.getChangeHeading ()) {
|
||||
|
@ -612,9 +638,9 @@ void FGAIAircraft::handleFirstWaypoint() {
|
|||
eraseWaypoints = false;
|
||||
}
|
||||
|
||||
FGAIFlightPlan::waypoint* prev = 0; // the one behind you
|
||||
FGAIFlightPlan::waypoint* curr = 0; // the one ahead
|
||||
FGAIFlightPlan::waypoint* next = 0;// the next plus 1
|
||||
FGAIWaypoint* prev = 0; // the one behind you
|
||||
FGAIWaypoint* curr = 0; // the one ahead
|
||||
FGAIWaypoint* next = 0;// the next plus 1
|
||||
|
||||
spinCounter = 0;
|
||||
tempReg = "";
|
||||
|
@ -631,15 +657,15 @@ void FGAIAircraft::handleFirstWaypoint() {
|
|||
curr = fp->getCurrentWaypoint(); //second waypoint
|
||||
next = fp->getNextWaypoint(); //third waypoint (might not exist!)
|
||||
|
||||
setLatitude(prev->latitude);
|
||||
setLongitude(prev->longitude);
|
||||
setSpeed(prev->speed);
|
||||
setAltitude(prev->altitude);
|
||||
setLatitude(prev->getLatitude());
|
||||
setLongitude(prev->getLongitude());
|
||||
setSpeed(prev->getSpeed());
|
||||
setAltitude(prev->getAltitude());
|
||||
|
||||
if (prev->speed > 0.0)
|
||||
setHeading(fp->getBearing(prev->latitude, prev->longitude, curr));
|
||||
if (prev->getSpeed() > 0.0)
|
||||
setHeading(fp->getBearing(prev->getLatitude(), prev->getLongitude(), curr));
|
||||
else
|
||||
setHeading(fp->getBearing(curr->latitude, curr->longitude, prev));
|
||||
setHeading(fp->getBearing(curr->getLatitude(), curr->getLongitude(), prev));
|
||||
|
||||
// If next doesn't exist, as in incrementally created flightplans for
|
||||
// AI/Trafficmanager created plans,
|
||||
|
@ -647,20 +673,20 @@ void FGAIAircraft::handleFirstWaypoint() {
|
|||
if (next)
|
||||
fp->setLeadDistance(speed, hdg, curr, next);
|
||||
|
||||
if (curr->crossat > -1000.0) //use a calculated descent/climb rate
|
||||
if (curr->getCrossat() > -1000.0) //use a calculated descent/climb rate
|
||||
{
|
||||
use_perf_vs = false;
|
||||
tgt_vs = (curr->crossat - prev->altitude)
|
||||
tgt_vs = (curr->getCrossat() - prev->getAltitude())
|
||||
/ (fp->getDistanceToGo(pos.getLatitudeDeg(), pos.getLongitudeDeg(), curr)
|
||||
/ 6076.0 / prev->speed*60.0);
|
||||
/ 6076.0 / prev->getSpeed()*60.0);
|
||||
checkTcas();
|
||||
tgt_altitude_ft = curr->crossat;
|
||||
tgt_altitude_ft = curr->getCrossat();
|
||||
} else {
|
||||
use_perf_vs = true;
|
||||
tgt_altitude_ft = prev->altitude;
|
||||
tgt_altitude_ft = prev->getAltitude();
|
||||
}
|
||||
alt_lock = hdg_lock = true;
|
||||
no_roll = prev->on_ground;
|
||||
no_roll = prev->getOn_ground();
|
||||
if (no_roll) {
|
||||
Transform(); // make sure aip is initialized.
|
||||
getGroundElev(60.1); // make sure it's executed first time around, so force a large dt value
|
||||
|
@ -693,19 +719,19 @@ bool FGAIAircraft::fpExecutable(time_t now) {
|
|||
* @param curr
|
||||
* @return
|
||||
*/
|
||||
bool FGAIAircraft::leadPointReached(FGAIFlightPlan::waypoint* curr) {
|
||||
bool FGAIAircraft::leadPointReached(FGAIWaypoint* curr) {
|
||||
double dist_to_go = fp->getDistanceToGo(pos.getLatitudeDeg(), pos.getLongitudeDeg(), curr);
|
||||
|
||||
//cerr << "2" << endl;
|
||||
double lead_dist = fp->getLeadDistance();
|
||||
// experimental: Use fabs, because speed can be negative (I hope) during push_back.
|
||||
if ((dist_to_go < fabs(10.0* speed)) && (speed < 0) && (tgt_speed < 0) && fp->getCurrentWaypoint()->name == string("PushBackPoint")) {
|
||||
if ((dist_to_go < fabs(10.0* speed)) && (speed < 0) && (tgt_speed < 0) && fp->getCurrentWaypoint()->contains("PushBackPoint")) {
|
||||
tgt_speed = -(dist_to_go / 10.0);
|
||||
if (tgt_speed > -0.5) {
|
||||
tgt_speed = -0.5;
|
||||
}
|
||||
if (fp->getPreviousWaypoint()->speed < tgt_speed) {
|
||||
fp->getPreviousWaypoint()->speed = tgt_speed;
|
||||
if (fp->getPreviousWaypoint()->getSpeed() < tgt_speed) {
|
||||
fp->getPreviousWaypoint()->setSpeed(tgt_speed);
|
||||
}
|
||||
}
|
||||
if (lead_dist < fabs(2*speed)) {
|
||||
|
@ -768,7 +794,7 @@ bool FGAIAircraft::aiTrafficVisible() {
|
|||
*/
|
||||
|
||||
//TODO the trafficRef is the right place for the method
|
||||
bool FGAIAircraft::handleAirportEndPoints(FGAIFlightPlan::waypoint* prev, time_t now) {
|
||||
bool FGAIAircraft::handleAirportEndPoints(FGAIWaypoint* prev, time_t now) {
|
||||
// prepare routing from one airport to another
|
||||
FGAirport * dep = trafficRef->getDepartureAirport();
|
||||
FGAirport * arr = trafficRef->getArrivalAirport();
|
||||
|
@ -779,21 +805,29 @@ bool FGAIAircraft::handleAirportEndPoints(FGAIFlightPlan::waypoint* prev, time_t
|
|||
// This waypoint marks the fact that the aircraft has passed the initial taxi
|
||||
// departure waypoint, so it can release the parking.
|
||||
//cerr << trafficRef->getCallSign() << " has passed waypoint " << prev->name << " at speed " << speed << endl;
|
||||
if (prev->name == "PushBackPoint") {
|
||||
//cerr << "Passing waypoint : " << prev->getName() << endl;
|
||||
if (prev->contains("PushBackPoint")) {
|
||||
dep->getDynamics()->releaseParking(fp->getGate());
|
||||
AccelTo(0.0);
|
||||
setTaxiClearanceRequest(true);
|
||||
//setTaxiClearanceRequest(true);
|
||||
}
|
||||
if (prev->contains("legend")) {
|
||||
fp->incrementLeg();
|
||||
}
|
||||
if (prev->contains(string("DepartureHold"))) {
|
||||
//cerr << "Passing point DepartureHold" << endl;
|
||||
scheduleForATCTowerDepartureControl(2);
|
||||
}
|
||||
|
||||
// This is the last taxi waypoint, and marks the the end of the flight plan
|
||||
// so, the schedule should update and wait for the next departure time.
|
||||
if (prev->name == "END") {
|
||||
if (prev->contains("END")) {
|
||||
time_t nextDeparture = trafficRef->getDepartureTime();
|
||||
// make sure to wait at least 20 minutes at parking to prevent "nervous" taxi behavior
|
||||
if (nextDeparture < (now+1200)) {
|
||||
nextDeparture = now + 1200;
|
||||
}
|
||||
fp->setTime(nextDeparture); // should be "next departure"
|
||||
fp->setTime(nextDeparture);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -805,7 +839,7 @@ bool FGAIAircraft::handleAirportEndPoints(FGAIFlightPlan::waypoint* prev, time_t
|
|||
*
|
||||
* @param curr
|
||||
*/
|
||||
void FGAIAircraft::controlHeading(FGAIFlightPlan::waypoint* curr) {
|
||||
void FGAIAircraft::controlHeading(FGAIWaypoint* curr) {
|
||||
double calc_bearing = fp->getBearing(pos.getLatitudeDeg(), pos.getLongitudeDeg(), curr);
|
||||
//cerr << "Bearing = " << calc_bearing << endl;
|
||||
if (speed < 0) {
|
||||
|
@ -824,8 +858,8 @@ void FGAIAircraft::controlHeading(FGAIFlightPlan::waypoint* curr) {
|
|||
cerr << "calc_bearing is not a finite number : "
|
||||
<< "Speed " << speed
|
||||
<< "pos : " << pos.getLatitudeDeg() << ", " << pos.getLongitudeDeg()
|
||||
<< "waypoint " << curr->latitude << ", " << curr->longitude << endl;
|
||||
cerr << "waypoint name " << curr->name;
|
||||
<< "waypoint " << curr->getLatitude() << ", " << curr->getLongitude() << endl;
|
||||
cerr << "waypoint name " << curr->getName();
|
||||
exit(1); // FIXME
|
||||
}
|
||||
}
|
||||
|
@ -838,7 +872,7 @@ void FGAIAircraft::controlHeading(FGAIFlightPlan::waypoint* curr) {
|
|||
* @param curr
|
||||
* @param next
|
||||
*/
|
||||
void FGAIAircraft::controlSpeed(FGAIFlightPlan::waypoint* curr, FGAIFlightPlan::waypoint* next) {
|
||||
void FGAIAircraft::controlSpeed(FGAIWaypoint* curr, FGAIWaypoint* next) {
|
||||
double speed_diff = speed - prevSpeed;
|
||||
|
||||
if (fabs(speed_diff) > 10) {
|
||||
|
@ -1168,8 +1202,8 @@ void FGAIAircraft::updateSecondaryTargetValues() {
|
|||
|
||||
|
||||
bool FGAIAircraft::reachedEndOfCruise(double &distance) {
|
||||
FGAIFlightPlan::waypoint* curr = fp->getCurrentWaypoint();
|
||||
if (curr->name == "BOD") {
|
||||
FGAIWaypoint* curr = fp->getCurrentWaypoint();
|
||||
if (curr->getName() == string("BOD")) {
|
||||
double dist = fp->getDistanceToGo(pos.getLatitudeDeg(), pos.getLongitudeDeg(), curr);
|
||||
double descentSpeed = (getPerformance()->vDescent() * SG_NM_TO_METER) / 3600.0; // convert from kts to meter/s
|
||||
double descentRate = (getPerformance()->descentRate() * SG_FEET_TO_METER) / 60.0; // convert from feet/min to meter/s
|
||||
|
@ -1205,22 +1239,22 @@ bool FGAIAircraft::reachedEndOfCruise(double &distance) {
|
|||
void FGAIAircraft::resetPositionFromFlightPlan()
|
||||
{
|
||||
// the one behind you
|
||||
FGAIFlightPlan::waypoint* prev = 0;
|
||||
FGAIWaypoint* prev = 0;
|
||||
// the one ahead
|
||||
FGAIFlightPlan::waypoint* curr = 0;
|
||||
FGAIWaypoint* curr = 0;
|
||||
// the next plus 1
|
||||
FGAIFlightPlan::waypoint* next = 0;
|
||||
FGAIWaypoint* next = 0;
|
||||
|
||||
prev = fp->getPreviousWaypoint();
|
||||
curr = fp->getCurrentWaypoint();
|
||||
next = fp->getNextWaypoint();
|
||||
|
||||
setLatitude(prev->latitude);
|
||||
setLongitude(prev->longitude);
|
||||
setLatitude(prev->getLatitude());
|
||||
setLongitude(prev->getLongitude());
|
||||
double tgt_heading = fp->getBearing(curr, next);
|
||||
setHeading(tgt_heading);
|
||||
setAltitude(prev->altitude);
|
||||
setSpeed(prev->speed);
|
||||
setAltitude(prev->getAltitude());
|
||||
setSpeed(prev->getSpeed());
|
||||
}
|
||||
|
||||
double FGAIAircraft::getBearing(double crse)
|
||||
|
@ -1232,7 +1266,7 @@ double FGAIAircraft::getBearing(double crse)
|
|||
}
|
||||
|
||||
time_t FGAIAircraft::checkForArrivalTime(string wptName) {
|
||||
FGAIFlightPlan::waypoint* curr = 0;
|
||||
FGAIWaypoint* curr = 0;
|
||||
curr = fp->getCurrentWaypoint();
|
||||
|
||||
double tracklength = fp->checkTrackLength(wptName);
|
||||
|
|
|
@ -77,6 +77,11 @@ public:
|
|||
bool getTaxiClearanceRequest() { return needsTaxiClearance; };
|
||||
FGAISchedule * getTrafficRef() { return trafficRef; };
|
||||
void setTrafficRef(FGAISchedule *ref) { trafficRef = ref; };
|
||||
void resetTakeOffStatus() { takeOffStatus = 0;};
|
||||
void setTakeOffStatus(int status) { takeOffStatus = status; };
|
||||
void scheduleForATCTowerDepartureControl(int state);
|
||||
|
||||
//inline bool isScheduledForTakeoff() { return scheduledForTakeoff; };
|
||||
|
||||
virtual const char* getTypeString(void) const { return "aircraft"; }
|
||||
|
||||
|
@ -95,6 +100,8 @@ public:
|
|||
inline double airspeed() const { return props->getFloatValue("velocities/airspeed-kt");};
|
||||
std::string atGate();
|
||||
|
||||
int getTakeOffStatus() { return takeOffStatus; };
|
||||
|
||||
void checkTcas();
|
||||
|
||||
FGATCController * getATCController() { return controller; };
|
||||
|
@ -104,7 +111,9 @@ protected:
|
|||
|
||||
private:
|
||||
FGAISchedule *trafficRef;
|
||||
FGATCController *controller, *prevController;
|
||||
FGATCController *controller,
|
||||
*prevController,
|
||||
*towerController; // Only needed to make a pre-announcement
|
||||
|
||||
bool hdg_lock;
|
||||
bool alt_lock;
|
||||
|
@ -126,13 +135,13 @@ private:
|
|||
//subclasses to override specific behaviour
|
||||
bool fpExecutable(time_t now);
|
||||
void handleFirstWaypoint(void);
|
||||
bool leadPointReached(FGAIFlightPlan::waypoint* curr);
|
||||
bool handleAirportEndPoints(FGAIFlightPlan::waypoint* prev, time_t now);
|
||||
bool leadPointReached(FGAIWaypoint* curr);
|
||||
bool handleAirportEndPoints(FGAIWaypoint* prev, time_t now);
|
||||
bool reachedEndOfCruise(double&);
|
||||
bool aiTrafficVisible(void);
|
||||
void controlHeading(FGAIFlightPlan::waypoint* curr);
|
||||
void controlSpeed(FGAIFlightPlan::waypoint* curr,
|
||||
FGAIFlightPlan::waypoint* next);
|
||||
void controlHeading(FGAIWaypoint* curr);
|
||||
void controlSpeed(FGAIWaypoint* curr,
|
||||
FGAIWaypoint* next);
|
||||
|
||||
void updatePrimaryTargetValues(bool& flightplanActive, bool& aiOutOfSight);
|
||||
|
||||
|
@ -147,6 +156,7 @@ private:
|
|||
void checkVisibility();
|
||||
inline bool isStationary() { return ((fabs(speed)<=0.0001)&&(fabs(tgt_speed)<=0.0001));}
|
||||
inline bool needGroundElevation() { if (!isStationary()) _needsGroundElevation=true;return _needsGroundElevation;}
|
||||
|
||||
|
||||
double sign(double x);
|
||||
|
||||
|
@ -167,6 +177,7 @@ private:
|
|||
bool reachedWaypoint;
|
||||
bool needsTaxiClearance;
|
||||
bool _needsGroundElevation;
|
||||
int takeOffStatus; // 1 = joined departure cue; 2 = Passed DepartureHold waypoint; handover control to tower; 0 = any other state.
|
||||
time_t timeElapsed;
|
||||
|
||||
PerformanceData* _performance; // the performance data for this aircraft
|
||||
|
|
|
@ -46,6 +46,29 @@
|
|||
|
||||
using std::cerr;
|
||||
|
||||
FGAIWaypoint::FGAIWaypoint() {
|
||||
latitude = 0;
|
||||
longitude = 0;
|
||||
altitude = 0;
|
||||
speed = 0;
|
||||
crossat = 0;
|
||||
finished = 0;
|
||||
gear_down = 0;
|
||||
flaps_down = 0;
|
||||
on_ground = 0;
|
||||
routeIndex = 0;
|
||||
time_sec = 0;
|
||||
trackLength = 0;
|
||||
}
|
||||
|
||||
bool FGAIWaypoint::contains(string target) {
|
||||
size_t found = name.find(target);
|
||||
if (found == string::npos)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
FGAIFlightPlan::FGAIFlightPlan()
|
||||
{
|
||||
rwy = 0;
|
||||
|
@ -88,22 +111,22 @@ FGAIFlightPlan::FGAIFlightPlan(const string& filename)
|
|||
SGPropertyNode * node = root.getNode("flightplan");
|
||||
for (i = 0; i < node->nChildren(); i++) {
|
||||
//cout << "Reading waypoint " << i << endl;
|
||||
waypoint* wpt = new waypoint;
|
||||
FGAIWaypoint* wpt = new FGAIWaypoint;
|
||||
SGPropertyNode * wpt_node = node->getChild(i);
|
||||
wpt->name = wpt_node->getStringValue("name", "END");
|
||||
wpt->latitude = wpt_node->getDoubleValue("lat", 0);
|
||||
wpt->longitude = wpt_node->getDoubleValue("lon", 0);
|
||||
wpt->altitude = wpt_node->getDoubleValue("alt", 0);
|
||||
wpt->speed = wpt_node->getDoubleValue("ktas", 0);
|
||||
wpt->crossat = wpt_node->getDoubleValue("crossat", -10000);
|
||||
wpt->gear_down = wpt_node->getBoolValue("gear-down", false);
|
||||
wpt->flaps_down= wpt_node->getBoolValue("flaps-down", false);
|
||||
wpt->on_ground = wpt_node->getBoolValue("on-ground", false);
|
||||
wpt->time_sec = wpt_node->getDoubleValue("time-sec", 0);
|
||||
wpt->time = wpt_node->getStringValue("time", "");
|
||||
wpt->setName (wpt_node->getStringValue("name", "END" ));
|
||||
wpt->setLatitude (wpt_node->getDoubleValue("lat", 0 ));
|
||||
wpt->setLongitude (wpt_node->getDoubleValue("lon", 0 ));
|
||||
wpt->setAltitude (wpt_node->getDoubleValue("alt", 0 ));
|
||||
wpt->setSpeed (wpt_node->getDoubleValue("ktas", 0 ));
|
||||
wpt->setCrossat (wpt_node->getDoubleValue("crossat", -10000 ));
|
||||
wpt->setGear_down (wpt_node->getBoolValue("gear-down", false ));
|
||||
wpt->setFlaps_down (wpt_node->getBoolValue("flaps-down", false ));
|
||||
wpt->setOn_ground (wpt_node->getBoolValue("on-ground", false ));
|
||||
wpt->setTime_sec (wpt_node->getDoubleValue("time-sec", 0 ));
|
||||
wpt->setTime (wpt_node->getStringValue("time", "" ));
|
||||
|
||||
if (wpt->name == "END") wpt->finished = true;
|
||||
else wpt->finished = false;
|
||||
if (wpt->getName() == "END") wpt->setFinished(true);
|
||||
else wpt->setFinished(false);
|
||||
|
||||
waypoints.push_back( wpt );
|
||||
}
|
||||
|
@ -173,20 +196,19 @@ FGAIFlightPlan::FGAIFlightPlan(FGAIAircraft *ac,
|
|||
//waypoints.push_back( init_waypoint );
|
||||
for (int i = 0; i < node->nChildren(); i++) {
|
||||
//cout << "Reading waypoint " << i << endl;
|
||||
waypoint* wpt = new waypoint;
|
||||
FGAIWaypoint* wpt = new FGAIWaypoint;
|
||||
SGPropertyNode * wpt_node = node->getChild(i);
|
||||
wpt->name = wpt_node->getStringValue("name", "END");
|
||||
wpt->latitude = wpt_node->getDoubleValue("lat", 0);
|
||||
wpt->longitude = wpt_node->getDoubleValue("lon", 0);
|
||||
wpt->altitude = wpt_node->getDoubleValue("alt", 0);
|
||||
wpt->speed = wpt_node->getDoubleValue("ktas", 0);
|
||||
//wpt->speed = speed;
|
||||
wpt->crossat = wpt_node->getDoubleValue("crossat", -10000);
|
||||
wpt->gear_down = wpt_node->getBoolValue("gear-down", false);
|
||||
wpt->flaps_down= wpt_node->getBoolValue("flaps-down", false);
|
||||
wpt->setName (wpt_node->getStringValue("name", "END" ));
|
||||
wpt->setLatitude (wpt_node->getDoubleValue("lat", 0 ));
|
||||
wpt->setLongitude (wpt_node->getDoubleValue("lon", 0 ));
|
||||
wpt->setAltitude (wpt_node->getDoubleValue("alt", 0 ));
|
||||
wpt->setSpeed (wpt_node->getDoubleValue("ktas", 0 ));
|
||||
wpt->setCrossat (wpt_node->getDoubleValue("crossat", -10000 ));
|
||||
wpt->setGear_down (wpt_node->getBoolValue("gear-down", false ));
|
||||
wpt->setFlaps_down (wpt_node->getBoolValue("flaps-down", false ));
|
||||
|
||||
if (wpt->name == "END") wpt->finished = true;
|
||||
else wpt->finished = false;
|
||||
if (wpt->getName() == "END") wpt->setFinished(true);
|
||||
else wpt->setFinished(false);
|
||||
waypoints.push_back(wpt);
|
||||
} // of node loop
|
||||
wpt_iterator = waypoints.begin();
|
||||
|
@ -204,8 +226,10 @@ FGAIFlightPlan::FGAIFlightPlan(FGAIAircraft *ac,
|
|||
|
||||
if ((timeDiff > 60) && (timeDiff < 1200))
|
||||
leg = 2;
|
||||
else if ((timeDiff >= 1200) && (timeDiff < 1500))
|
||||
else if ((timeDiff >= 1200) && (timeDiff < 1500)) {
|
||||
leg = 3;
|
||||
ac->setTakeOffStatus(2);
|
||||
}
|
||||
else if ((timeDiff >= 1500) && (timeDiff < 2000))
|
||||
leg = 4;
|
||||
else if (timeDiff >= 2000)
|
||||
|
@ -324,8 +348,7 @@ FGAIFlightPlan::~FGAIFlightPlan()
|
|||
}
|
||||
|
||||
|
||||
FGAIFlightPlan::waypoint* const
|
||||
FGAIFlightPlan::getPreviousWaypoint( void ) const
|
||||
FGAIWaypoint* const FGAIFlightPlan::getPreviousWaypoint( void ) const
|
||||
{
|
||||
if (wpt_iterator == waypoints.begin()) {
|
||||
return 0;
|
||||
|
@ -335,14 +358,12 @@ FGAIFlightPlan::getPreviousWaypoint( void ) const
|
|||
}
|
||||
}
|
||||
|
||||
FGAIFlightPlan::waypoint* const
|
||||
FGAIFlightPlan::getCurrentWaypoint( void ) const
|
||||
FGAIWaypoint* const FGAIFlightPlan::getCurrentWaypoint( void ) const
|
||||
{
|
||||
return *wpt_iterator;
|
||||
}
|
||||
|
||||
FGAIFlightPlan::waypoint* const
|
||||
FGAIFlightPlan::getNextWaypoint( void ) const
|
||||
FGAIWaypoint* const FGAIFlightPlan::getNextWaypoint( void ) const
|
||||
{
|
||||
wpt_vector_iterator i = waypoints.end();
|
||||
i--; // end() points to one element after the last one.
|
||||
|
@ -394,14 +415,14 @@ void FGAIFlightPlan::DecrementWaypoint(bool eraseWaypoints )
|
|||
|
||||
|
||||
// gives distance in feet from a position to a waypoint
|
||||
double FGAIFlightPlan::getDistanceToGo(double lat, double lon, waypoint* wp) const{
|
||||
double FGAIFlightPlan::getDistanceToGo(double lat, double lon, FGAIWaypoint* wp) const{
|
||||
return SGGeodesy::distanceM(SGGeod::fromDeg(lon, lat),
|
||||
SGGeod::fromDeg(wp->longitude, wp->latitude));
|
||||
SGGeod::fromDeg(wp->getLongitude(), wp->getLatitude()));
|
||||
}
|
||||
|
||||
// sets distance in feet from a lead point to the current waypoint
|
||||
void FGAIFlightPlan::setLeadDistance(double speed, double bearing,
|
||||
waypoint* current, waypoint* next){
|
||||
FGAIWaypoint* current, FGAIWaypoint* next){
|
||||
double turn_radius;
|
||||
// Handle Ground steering
|
||||
// At a turn rate of 30 degrees per second, it takes 12 seconds to do a full 360 degree turn
|
||||
|
@ -444,14 +465,14 @@ void FGAIFlightPlan::setLeadDistance(double distance_ft){
|
|||
}
|
||||
|
||||
|
||||
double FGAIFlightPlan::getBearing(waypoint* first, waypoint* second) const{
|
||||
return getBearing(first->latitude, first->longitude, second);
|
||||
double FGAIFlightPlan::getBearing(FGAIWaypoint* first, FGAIWaypoint* second) const{
|
||||
return getBearing(first->getLatitude(), first->getLongitude(), second);
|
||||
}
|
||||
|
||||
|
||||
double FGAIFlightPlan::getBearing(double lat, double lon, waypoint* wp) const{
|
||||
double FGAIFlightPlan::getBearing(double lat, double lon, FGAIWaypoint* wp) const{
|
||||
return SGGeodesy::courseDeg(SGGeod::fromDeg(lon, lat),
|
||||
SGGeod::fromDeg(wp->longitude, wp->latitude));
|
||||
SGGeod::fromDeg(wp->getLongitude(), wp->getLatitude()));
|
||||
}
|
||||
|
||||
void FGAIFlightPlan::deleteWaypoints()
|
||||
|
@ -469,19 +490,19 @@ void FGAIFlightPlan::resetWaypoints()
|
|||
return;
|
||||
else
|
||||
{
|
||||
waypoint *wpt = new waypoint;
|
||||
FGAIWaypoint *wpt = new FGAIWaypoint;
|
||||
wpt_vector_iterator i = waypoints.end();
|
||||
i--;
|
||||
wpt->name = (*i)->name;
|
||||
wpt->latitude = (*i)->latitude;
|
||||
wpt->longitude = (*i)->longitude;
|
||||
wpt->altitude = (*i)->altitude;
|
||||
wpt->speed = (*i)->speed;
|
||||
wpt->crossat = (*i)->crossat;
|
||||
wpt->gear_down = (*i)->gear_down;
|
||||
wpt->flaps_down= (*i)->flaps_down;
|
||||
wpt->finished = false;
|
||||
wpt->on_ground = (*i)->on_ground;
|
||||
wpt->setName ( (*i)->getName() );
|
||||
wpt->setLatitude ( (*i)->getLatitude() );
|
||||
wpt->setLongitude ( (*i)->getLongitude() );
|
||||
wpt->setAltitude ( (*i)->getAltitude() );
|
||||
wpt->setSpeed ( (*i)->getSpeed() );
|
||||
wpt->setCrossat ( (*i)->getCrossat() );
|
||||
wpt->setGear_down ( (*i)->getGear_down() );
|
||||
wpt->setFlaps_down ( (*i)->getFlaps_down() );
|
||||
wpt->setFinished ( false );
|
||||
wpt->setOn_ground ( (*i)->getOn_ground() );
|
||||
//cerr << "Recycling waypoint " << wpt->name << endl;
|
||||
deleteWaypoints();
|
||||
waypoints.push_back(wpt);
|
||||
|
@ -504,7 +525,7 @@ void FGAIFlightPlan::deleteTaxiRoute()
|
|||
|
||||
int FGAIFlightPlan::getRouteIndex(int i) {
|
||||
if ((i > 0) && (i < (int)waypoints.size())) {
|
||||
return waypoints[i]->routeIndex;
|
||||
return waypoints[i]->getRouteIndex();
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
|
@ -517,8 +538,8 @@ double FGAIFlightPlan::checkTrackLength(string wptName) {
|
|||
wpt_vector_iterator wptvec = waypoints.begin();
|
||||
wptvec++;
|
||||
wptvec++;
|
||||
while ((wptvec != waypoints.end()) && ((*wptvec)->name != wptName)) {
|
||||
trackDistance += (*wptvec)->trackLength;
|
||||
while ((wptvec != waypoints.end()) && (!((*wptvec)->contains(wptName)))) {
|
||||
trackDistance += (*wptvec)->getTrackLength();
|
||||
wptvec++;
|
||||
}
|
||||
if (wptvec == waypoints.end()) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// // FGAIFlightPlan - class for loading and storing AI flight plans
|
||||
// FGAIFlightPlan - class for loading and storing AI flight plans
|
||||
// Written by David Culp, started May 2004
|
||||
// - davidculp2@comcast.net
|
||||
//
|
||||
|
@ -30,11 +30,8 @@ class FGAIAircraft;
|
|||
class FGAirport;
|
||||
class SGGeod;
|
||||
|
||||
class FGAIFlightPlan {
|
||||
|
||||
public:
|
||||
|
||||
typedef struct {
|
||||
class FGAIWaypoint {
|
||||
private:
|
||||
std::string name;
|
||||
double latitude;
|
||||
double longitude;
|
||||
|
@ -47,10 +44,52 @@ public:
|
|||
bool on_ground;
|
||||
int routeIndex; // For AI/ATC purposes;
|
||||
double time_sec;
|
||||
double trackLength; // distance from previous waypoint (for AI purposes);
|
||||
double trackLength; // distance from previous FGAIWaypoint (for AI purposes);
|
||||
std::string time;
|
||||
|
||||
} waypoint;
|
||||
public:
|
||||
FGAIWaypoint();
|
||||
~FGAIWaypoint() {};
|
||||
void setName (std::string nam) { name = nam; };
|
||||
void setLatitude (double lat) { latitude = lat; };
|
||||
void setLongitude (double lon) { longitude = lon; };
|
||||
void setAltitude (double alt) { altitude = alt; };
|
||||
void setSpeed (double spd) { speed = spd; };
|
||||
void setCrossat (double val) { crossat = val; };
|
||||
void setFinished (bool fin) { finished = fin; };
|
||||
void setGear_down (bool grd) { gear_down = grd; };
|
||||
void setFlaps_down (bool fld) { flaps_down = fld; };
|
||||
void setOn_ground (bool grn) { on_ground = grn; };
|
||||
void setRouteIndex (int rte) { routeIndex = rte; };
|
||||
void setTime_sec (double ts ) { time_sec = ts; };
|
||||
void setTrackLength (double tl ) { trackLength = tl; };
|
||||
void setTime (std::string tme) { time = tme; };
|
||||
|
||||
bool contains(std::string name);
|
||||
|
||||
std::string getName () { return name; };
|
||||
double getLatitude () { return latitude; };
|
||||
double getLongitude () { return longitude; };
|
||||
double getAltitude () { return altitude; };
|
||||
double getSpeed () { return speed; };
|
||||
|
||||
double getCrossat () { return crossat; };
|
||||
bool getGear_down () { return gear_down; };
|
||||
bool getFlaps_down () { return flaps_down; };
|
||||
bool getOn_ground () { return on_ground; };
|
||||
int getRouteIndex () { return routeIndex; };
|
||||
bool isFinished () { return finished; };
|
||||
double getTime_sec () { return time_sec; };
|
||||
double getTrackLength() { return trackLength; };
|
||||
std::string getTime () { return time; };
|
||||
|
||||
};
|
||||
|
||||
|
||||
class FGAIFlightPlan {
|
||||
|
||||
public:
|
||||
|
||||
FGAIFlightPlan();
|
||||
FGAIFlightPlan(const std::string& filename);
|
||||
FGAIFlightPlan(FGAIAircraft *,
|
||||
|
@ -70,19 +109,20 @@ public:
|
|||
const std::string& airline);
|
||||
~FGAIFlightPlan();
|
||||
|
||||
waypoint* const getPreviousWaypoint( void ) const;
|
||||
waypoint* const getCurrentWaypoint( void ) const;
|
||||
waypoint* const getNextWaypoint( void ) const;
|
||||
FGAIWaypoint* const getPreviousWaypoint( void ) const;
|
||||
FGAIWaypoint* const getCurrentWaypoint( void ) const;
|
||||
FGAIWaypoint* const getNextWaypoint( void ) const;
|
||||
void IncrementWaypoint( bool erase );
|
||||
void DecrementWaypoint( bool erase );
|
||||
|
||||
double getDistanceToGo(double lat, double lon, waypoint* wp) const;
|
||||
double getDistanceToGo(double lat, double lon, FGAIWaypoint* wp) const;
|
||||
int getLeg () const { return leg;};
|
||||
void setLeadDistance(double speed, double bearing, waypoint* current, waypoint* next);
|
||||
|
||||
void setLeadDistance(double speed, double bearing, FGAIWaypoint* current, FGAIWaypoint* next);
|
||||
void setLeadDistance(double distance_ft);
|
||||
double getLeadDistance( void ) const {return lead_distance;}
|
||||
double getBearing(waypoint* previous, waypoint* next) const;
|
||||
double getBearing(double lat, double lon, waypoint* next) const;
|
||||
double getBearing(FGAIWaypoint* previous, FGAIWaypoint* next) const;
|
||||
double getBearing(double lat, double lon, FGAIWaypoint* next) const;
|
||||
double checkTrackLength(std::string wptName);
|
||||
time_t getStartTime() const { return start_time; }
|
||||
time_t getArrivalTime() const { return arrivalTime; }
|
||||
|
@ -110,21 +150,25 @@ public:
|
|||
std::string getRunway() { return activeRunway; }
|
||||
bool isActive(time_t time) {return time >= this->getStartTime();}
|
||||
|
||||
void incrementLeg() { leg++;};
|
||||
|
||||
void setRunway(std::string rwy) { activeRunway = rwy; };
|
||||
std::string getRunwayClassFromTrafficType(std::string fltType);
|
||||
|
||||
void addWaypoint(waypoint* wpt) { waypoints.push_back(wpt); };
|
||||
void addWaypoint(FGAIWaypoint* wpt) { waypoints.push_back(wpt); };
|
||||
|
||||
void setName(std::string n) { name = n; };
|
||||
std::string getName() { return name; };
|
||||
|
||||
void setSID(FGAIFlightPlan* fp) { sid = fp;};
|
||||
FGAIFlightPlan* getSID() { return sid; };
|
||||
FGAIWaypoint *getWayPoint(int i) { return waypoints[i]; };
|
||||
FGAIWaypoint *getLastWaypoint() { return waypoints.back(); };
|
||||
|
||||
private:
|
||||
FGRunway* rwy;
|
||||
FGAIFlightPlan *sid;
|
||||
typedef std::vector <waypoint*> wpt_vector_type;
|
||||
typedef std::vector <FGAIWaypoint*> wpt_vector_type;
|
||||
typedef wpt_vector_type::const_iterator wpt_vector_iterator;
|
||||
|
||||
|
||||
|
@ -160,10 +204,10 @@ private:
|
|||
|
||||
double getTurnRadius(double, bool);
|
||||
|
||||
waypoint* createOnGround(FGAIAircraft *, const std::string& aName, const SGGeod& aPos, double aElev, double aSpeed);
|
||||
waypoint* createInAir(FGAIAircraft *, const std::string& aName, const SGGeod& aPos, double aElev, double aSpeed);
|
||||
waypoint* cloneWithPos(FGAIAircraft *, waypoint* aWpt, const std::string& aName, const SGGeod& aPos);
|
||||
waypoint* clone(waypoint* aWpt);
|
||||
FGAIWaypoint* createOnGround(FGAIAircraft *, const std::string& aName, const SGGeod& aPos, double aElev, double aSpeed);
|
||||
FGAIWaypoint* createInAir(FGAIAircraft *, const std::string& aName, const SGGeod& aPos, double aElev, double aSpeed);
|
||||
FGAIWaypoint* cloneWithPos(FGAIAircraft *, FGAIWaypoint* aWpt, const std::string& aName, const SGGeod& aPos);
|
||||
FGAIWaypoint* clone(FGAIWaypoint* aWpt);
|
||||
|
||||
|
||||
//void createCruiseFallback(bool, FGAirport*, FGAirport*, double, double, double, double);
|
||||
|
@ -172,6 +216,6 @@ private:
|
|||
wpt_vector_iterator getFirstWayPoint() { return waypoints.begin(); };
|
||||
wpt_vector_iterator getLastWayPoint() { return waypoints.end(); };
|
||||
bool isValidPlan() { return isValid; };
|
||||
};
|
||||
};
|
||||
|
||||
#endif // _FG_AIFLIGHTPLAN_HXX
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
# include <config.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include "AIFlightPlan.hxx"
|
||||
#include <simgear/math/sg_geodesy.hxx>
|
||||
#include <simgear/props/props.hxx>
|
||||
|
@ -96,92 +97,81 @@ bool FGAIFlightPlan::create(FGAIAircraft * ac, FGAirport * dep,
|
|||
" this is probably an internal program error");
|
||||
}
|
||||
wpt_iterator = waypoints.begin() + currWpt;
|
||||
leg++;
|
||||
//don't increment leg right away, but only once we pass the actual last waypoint that was created.
|
||||
// to do so, mark the last waypoint with a special status flag
|
||||
if (retVal) {
|
||||
waypoints.back()->setName( waypoints.back()->getName() + string("legend"));
|
||||
// "It's pronounced Leg-end" (Roger Glover (Deep Purple): come Hell or High Water DvD, 1993)
|
||||
}
|
||||
|
||||
|
||||
//leg++;
|
||||
return retVal;
|
||||
}
|
||||
|
||||
FGAIFlightPlan::waypoint *
|
||||
FGAIFlightPlan::createOnGround(FGAIAircraft * ac,
|
||||
FGAIWaypoint * FGAIFlightPlan::createOnGround(FGAIAircraft * ac,
|
||||
const std::string & aName,
|
||||
const SGGeod & aPos, double aElev,
|
||||
double aSpeed)
|
||||
{
|
||||
waypoint *wpt = new waypoint;
|
||||
wpt->name = aName;
|
||||
wpt->longitude = aPos.getLongitudeDeg();
|
||||
wpt->latitude = aPos.getLatitudeDeg();
|
||||
wpt->altitude = aElev;
|
||||
wpt->speed = aSpeed;
|
||||
wpt->crossat = -10000.1;
|
||||
wpt->gear_down = true;
|
||||
wpt->flaps_down = true;
|
||||
wpt->finished = false;
|
||||
wpt->on_ground = true;
|
||||
wpt->routeIndex = 0;
|
||||
FGAIWaypoint *wpt = new FGAIWaypoint;
|
||||
wpt->setName (aName );
|
||||
wpt->setLongitude (aPos.getLongitudeDeg() );
|
||||
wpt->setLatitude (aPos.getLatitudeDeg() );
|
||||
wpt->setAltitude (aElev );
|
||||
wpt->setSpeed (aSpeed );
|
||||
wpt->setCrossat (-10000.1 );
|
||||
wpt->setGear_down (true );
|
||||
wpt->setFlaps_down (true );
|
||||
wpt->setFinished (false );
|
||||
wpt->setOn_ground (true );
|
||||
wpt->setRouteIndex (0 );
|
||||
return wpt;
|
||||
}
|
||||
|
||||
FGAIFlightPlan::waypoint *
|
||||
FGAIFlightPlan::createInAir(FGAIAircraft * ac,
|
||||
FGAIWaypoint * FGAIFlightPlan::createInAir(FGAIAircraft * ac,
|
||||
const std::string & aName,
|
||||
const SGGeod & aPos, double aElev,
|
||||
double aSpeed)
|
||||
{
|
||||
waypoint *wpt = new waypoint;
|
||||
wpt->name = aName;
|
||||
wpt->longitude = aPos.getLongitudeDeg();
|
||||
wpt->latitude = aPos.getLatitudeDeg();
|
||||
wpt->altitude = aElev;
|
||||
wpt->speed = aSpeed;
|
||||
wpt->crossat = -10000.1;
|
||||
wpt->gear_down = false;
|
||||
wpt->flaps_down = false;
|
||||
wpt->finished = false;
|
||||
wpt->on_ground = false;
|
||||
wpt->routeIndex = 0;
|
||||
FGAIWaypoint * wpt = createOnGround(ac, aName, aPos, aElev, aSpeed);
|
||||
wpt->setGear_down (false );
|
||||
wpt->setFlaps_down (false );
|
||||
wpt->setOn_ground (false );
|
||||
return wpt;
|
||||
}
|
||||
|
||||
FGAIFlightPlan::waypoint *
|
||||
FGAIFlightPlan::cloneWithPos(FGAIAircraft * ac, waypoint * aWpt,
|
||||
FGAIWaypoint * FGAIFlightPlan::clone(FGAIWaypoint * aWpt)
|
||||
{
|
||||
FGAIWaypoint *wpt = new FGAIWaypoint;
|
||||
wpt->setName ( aWpt->getName () );
|
||||
wpt->setLongitude ( aWpt->getLongitude() );
|
||||
wpt->setLatitude ( aWpt->getLatitude() );
|
||||
wpt->setAltitude ( aWpt->getAltitude() );
|
||||
wpt->setSpeed ( aWpt->getSpeed() );
|
||||
wpt->setCrossat ( aWpt->getCrossat() );
|
||||
wpt->setGear_down ( aWpt->getGear_down() );
|
||||
wpt->setFlaps_down ( aWpt->getFlaps_down() );
|
||||
wpt->setFinished ( aWpt->isFinished() );
|
||||
wpt->setOn_ground ( aWpt->getOn_ground() );
|
||||
wpt->setRouteIndex ( 0 );
|
||||
|
||||
return wpt;
|
||||
}
|
||||
|
||||
|
||||
FGAIWaypoint * FGAIFlightPlan::cloneWithPos(FGAIAircraft * ac, FGAIWaypoint * aWpt,
|
||||
const std::string & aName,
|
||||
const SGGeod & aPos)
|
||||
{
|
||||
waypoint *wpt = new waypoint;
|
||||
wpt->name = aName;
|
||||
wpt->longitude = aPos.getLongitudeDeg();
|
||||
wpt->latitude = aPos.getLatitudeDeg();
|
||||
|
||||
wpt->altitude = aWpt->altitude;
|
||||
wpt->speed = aWpt->speed;
|
||||
wpt->crossat = aWpt->crossat;
|
||||
wpt->gear_down = aWpt->gear_down;
|
||||
wpt->flaps_down = aWpt->flaps_down;
|
||||
wpt->finished = aWpt->finished;
|
||||
wpt->on_ground = aWpt->on_ground;
|
||||
wpt->routeIndex = 0;
|
||||
FGAIWaypoint *wpt = clone(aWpt);
|
||||
wpt->setName ( aName );
|
||||
wpt->setLongitude ( aPos.getLongitudeDeg () );
|
||||
wpt->setLatitude ( aPos.getLatitudeDeg () );
|
||||
|
||||
return wpt;
|
||||
}
|
||||
|
||||
FGAIFlightPlan::waypoint * FGAIFlightPlan::clone(waypoint * aWpt)
|
||||
{
|
||||
waypoint *wpt = new waypoint;
|
||||
wpt->name = aWpt->name;
|
||||
wpt->longitude = aWpt->longitude;
|
||||
wpt->latitude = aWpt->latitude;
|
||||
|
||||
wpt->altitude = aWpt->altitude;
|
||||
wpt->speed = aWpt->speed;
|
||||
wpt->crossat = aWpt->crossat;
|
||||
wpt->gear_down = aWpt->gear_down;
|
||||
wpt->flaps_down = aWpt->flaps_down;
|
||||
wpt->finished = aWpt->finished;
|
||||
wpt->on_ground = aWpt->on_ground;
|
||||
wpt->routeIndex = 0;
|
||||
|
||||
return wpt;
|
||||
}
|
||||
|
||||
|
||||
void FGAIFlightPlan::createDefaultTakeoffTaxi(FGAIAircraft * ac,
|
||||
|
@ -191,7 +181,7 @@ void FGAIFlightPlan::createDefaultTakeoffTaxi(FGAIAircraft * ac,
|
|||
SGGeod runwayTakeoff = aRunway->pointOnCenterline(5.0);
|
||||
double airportElev = aAirport->getElevation();
|
||||
|
||||
waypoint *wpt;
|
||||
FGAIWaypoint *wpt;
|
||||
wpt =
|
||||
createOnGround(ac, "Airport Center", aAirport->geod(), airportElev,
|
||||
ac->getPerformance()->vTaxi());
|
||||
|
@ -304,17 +294,30 @@ bool FGAIFlightPlan::createTakeoffTaxi(FGAIAircraft * ac, bool firstFlight,
|
|||
|
||||
// push each node on the taxi route as a waypoint
|
||||
int route;
|
||||
//cerr << "Building taxi route" << endl;
|
||||
while (taxiRoute->next(&node, &route)) {
|
||||
char buffer[10];
|
||||
snprintf(buffer, 10, "%d", node);
|
||||
FGTaxiNode *tn =
|
||||
apt->getDynamics()->getGroundNetwork()->findNode(node);
|
||||
waypoint *wpt =
|
||||
FGAIWaypoint *wpt =
|
||||
createOnGround(ac, buffer, tn->getGeod(), apt->getElevation(),
|
||||
ac->getPerformance()->vTaxi());
|
||||
wpt->routeIndex = route;
|
||||
wpt->setRouteIndex(route);
|
||||
//cerr << "Nodes left " << taxiRoute->nodesLeft() << " ";
|
||||
if (taxiRoute->nodesLeft() == 1) {
|
||||
// Note that we actually have hold points in the ground network, but this is just an initial test.
|
||||
//cerr << "Setting departurehold point: " << endl;
|
||||
wpt->setName( wpt->getName() + string("DepartureHold"));
|
||||
}
|
||||
waypoints.push_back(wpt);
|
||||
}
|
||||
// Acceleration point, 105 meters into the runway,
|
||||
SGGeod accelPoint = rwy->pointOnCenterline(105.0);
|
||||
FGAIWaypoint *wpt = createOnGround(ac, "accel", accelPoint, apt->getElevation(), ac->getPerformance()->vRotate());
|
||||
waypoints.push_back(wpt);
|
||||
|
||||
//cerr << "[done]" << endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -322,11 +325,11 @@ void FGAIFlightPlan::createDefaultLandingTaxi(FGAIAircraft * ac,
|
|||
FGAirport * aAirport)
|
||||
{
|
||||
SGGeod lastWptPos =
|
||||
SGGeod::fromDeg(waypoints.back()->longitude,
|
||||
waypoints.back()->latitude);
|
||||
SGGeod::fromDeg(waypoints.back()->getLongitude(),
|
||||
waypoints.back()->getLatitude());
|
||||
double airportElev = aAirport->getElevation();
|
||||
|
||||
waypoint *wpt;
|
||||
FGAIWaypoint *wpt;
|
||||
wpt =
|
||||
createOnGround(ac, "Runway Exit", lastWptPos, airportElev,
|
||||
ac->getPerformance()->vTaxi());
|
||||
|
@ -356,8 +359,8 @@ bool FGAIFlightPlan::createLandingTaxi(FGAIAircraft * ac, FGAirport * apt,
|
|||
acType, airline);
|
||||
|
||||
SGGeod lastWptPos =
|
||||
SGGeod::fromDeg(waypoints.back()->longitude,
|
||||
waypoints.back()->latitude);
|
||||
SGGeod::fromDeg(waypoints.back()->getLongitude(),
|
||||
waypoints.back()->getLatitude());
|
||||
FGGroundNetwork *gn = apt->getDynamics()->getGroundNetwork();
|
||||
|
||||
// Find a route from runway end to parking/gate.
|
||||
|
@ -396,10 +399,10 @@ bool FGAIFlightPlan::createLandingTaxi(FGAIAircraft * ac, FGAirport * apt,
|
|||
char buffer[10];
|
||||
snprintf(buffer, 10, "%d", node);
|
||||
FGTaxiNode *tn = gn->findNode(node);
|
||||
waypoint *wpt =
|
||||
FGAIWaypoint *wpt =
|
||||
createOnGround(ac, buffer, tn->getGeod(), apt->getElevation(),
|
||||
ac->getPerformance()->vTaxi());
|
||||
wpt->routeIndex = route;
|
||||
wpt->setRouteIndex(route);
|
||||
waypoints.push_back(wpt);
|
||||
}
|
||||
return true;
|
||||
|
@ -441,7 +444,7 @@ bool FGAIFlightPlan::createTakeOff(FGAIAircraft * ac, bool firstFlight,
|
|||
(vRotateMetric * vRotateMetric -
|
||||
vTaxiMetric * vTaxiMetric) / (2 * accelMetric);
|
||||
//cerr << "Using " << accelDistance << " " << accelMetric << " " << vRotateMetric << endl;
|
||||
waypoint *wpt;
|
||||
FGAIWaypoint *wpt;
|
||||
// Get the current active runway, based on code from David Luff
|
||||
// This should actually be unified and extended to include
|
||||
// Preferential runway use schema's
|
||||
|
@ -458,17 +461,13 @@ bool FGAIFlightPlan::createTakeOff(FGAIAircraft * ac, bool firstFlight,
|
|||
|
||||
|
||||
double airportElev = apt->getElevation();
|
||||
// Acceleration point, 105 meters into the runway,
|
||||
SGGeod accelPoint = rwy->pointOnCenterline(105.0);
|
||||
wpt = createOnGround(ac, "accel", accelPoint, airportElev, vRotate);
|
||||
waypoints.push_back(wpt);
|
||||
|
||||
|
||||
|
||||
accelDistance =
|
||||
(vTakeoffMetric * vTakeoffMetric -
|
||||
vTaxiMetric * vTaxiMetric) / (2 * accelMetric);
|
||||
//cerr << "Using " << accelDistance << " " << accelMetric << " " << vTakeoffMetric << endl;
|
||||
accelPoint = rwy->pointOnCenterline(105.0 + accelDistance);
|
||||
SGGeod accelPoint = rwy->pointOnCenterline(105.0 + accelDistance);
|
||||
wpt = createOnGround(ac, "rotate", accelPoint, airportElev, vTakeoff);
|
||||
waypoints.push_back(wpt);
|
||||
|
||||
|
@ -480,18 +479,18 @@ bool FGAIFlightPlan::createTakeOff(FGAIAircraft * ac, bool firstFlight,
|
|||
wpt =
|
||||
createOnGround(ac, "rotate", accelPoint, airportElev + 1000,
|
||||
vTakeoff * 1.1);
|
||||
wpt->on_ground = false;
|
||||
wpt->setOn_ground(false);
|
||||
waypoints.push_back(wpt);
|
||||
|
||||
wpt = cloneWithPos(ac, wpt, "3000 ft", rwy->end());
|
||||
wpt->altitude = airportElev + 3000;
|
||||
wpt->setAltitude(airportElev + 3000);
|
||||
waypoints.push_back(wpt);
|
||||
|
||||
// Finally, add two more waypoints, so that aircraft will remain under
|
||||
// Tower control until they have reached the 3000 ft climb point
|
||||
SGGeod pt = rwy->pointOnCenterline(5000 + rwy->lengthM() * 0.5);
|
||||
wpt = cloneWithPos(ac, wpt, "5000 ft", pt);
|
||||
wpt->altitude = airportElev + 5000;
|
||||
wpt->setAltitude(airportElev + 5000);
|
||||
waypoints.push_back(wpt);
|
||||
return true;
|
||||
}
|
||||
|
@ -504,7 +503,7 @@ bool FGAIFlightPlan::createClimb(FGAIAircraft * ac, bool firstFlight,
|
|||
FGAirport * apt, double speed, double alt,
|
||||
const string & fltType)
|
||||
{
|
||||
waypoint *wpt;
|
||||
FGAIWaypoint *wpt;
|
||||
// bool planLoaded = false;
|
||||
string fPLName;
|
||||
double vClimb = ac->getPerformance()->vClimb();
|
||||
|
@ -525,13 +524,13 @@ bool FGAIFlightPlan::createClimb(FGAIAircraft * ac, bool firstFlight,
|
|||
} else {
|
||||
SGGeod climb1 = rwy->pointOnCenterline(10 * SG_NM_TO_METER);
|
||||
wpt = createInAir(ac, "10000ft climb", climb1, vClimb, 10000);
|
||||
wpt->gear_down = true;
|
||||
wpt->flaps_down = true;
|
||||
wpt->setGear_down(true);
|
||||
wpt->setFlaps_down(true);
|
||||
waypoints.push_back(wpt);
|
||||
|
||||
SGGeod climb2 = rwy->pointOnCenterline(20 * SG_NM_TO_METER);
|
||||
wpt = cloneWithPos(ac, wpt, "18000ft climb", climb2);
|
||||
wpt->altitude = 18000;
|
||||
wpt->setAltitude(18000);
|
||||
waypoints.push_back(wpt);
|
||||
}
|
||||
return true;
|
||||
|
@ -551,7 +550,7 @@ bool FGAIFlightPlan::createDescent(FGAIAircraft * ac, FGAirport * apt,
|
|||
double requiredDistance)
|
||||
{
|
||||
bool reposition = false;
|
||||
waypoint *wpt;
|
||||
FGAIWaypoint *wpt;
|
||||
double vDescent = ac->getPerformance()->vDescent();
|
||||
double vApproach = ac->getPerformance()->vApproach();
|
||||
|
||||
|
@ -729,8 +728,8 @@ bool FGAIFlightPlan::createDescent(FGAIAircraft * ac, FGAirport * apt,
|
|||
SGGeodesy::direct(origin, azimuth, currentDist, result, dummyAz2);
|
||||
snprintf(buffer, 16, "descent%03d", i);
|
||||
wpt = createInAir(ac, buffer, result, currentAltitude, vDescent);
|
||||
wpt->crossat = currentAltitude;
|
||||
wpt->trackLength = (newDistance / nPoints);
|
||||
wpt->setCrossat(currentAltitude);
|
||||
wpt->setTrackLength((newDistance / nPoints));
|
||||
waypoints.push_back(wpt);
|
||||
//cerr << "Track Length : " << wpt->trackLength;
|
||||
//cerr << " Position : " << result.getLatitudeDeg() << " " << result.getLongitudeDeg() << " " << currentAltitude << endl;
|
||||
|
@ -772,8 +771,8 @@ bool FGAIFlightPlan::createDescent(FGAIAircraft * ac, FGAirport * apt,
|
|||
initialTurnRadius, result, dummyAz2);
|
||||
snprintf(buffer, 16, "turn%03d", i);
|
||||
wpt = createInAir(ac, buffer, result, currentAltitude, vDescent);
|
||||
wpt->crossat = currentAltitude;
|
||||
wpt->trackLength = trackLength;
|
||||
wpt->setCrossat(currentAltitude);
|
||||
wpt->setTrackLength(trackLength);
|
||||
//cerr << "Track Length : " << wpt->trackLength;
|
||||
waypoints.push_back(wpt);
|
||||
//cerr << " Position : " << result.getLatitudeDeg() << " " << result.getLongitudeDeg() << " " << currentAltitude << endl;
|
||||
|
@ -791,11 +790,11 @@ bool FGAIFlightPlan::createDescent(FGAIAircraft * ac, FGAirport * apt,
|
|||
snprintf(buffer, 16, "final%03d", i);
|
||||
result = rwy->pointOnCenterline((-distanceOut) + currentDist);
|
||||
wpt = createInAir(ac, buffer, result, currentAltitude, vApproach);
|
||||
wpt->crossat = currentAltitude;
|
||||
wpt->trackLength = (distanceOut / nPoints);
|
||||
wpt->setCrossat(currentAltitude);
|
||||
wpt->setTrackLength((distanceOut / nPoints));
|
||||
// account for the extra distance due to an extended downwind leg
|
||||
if (i == 1) {
|
||||
wpt->trackLength += distanceCovered;
|
||||
wpt->setTrackLength(wpt->getTrackLength() + distanceCovered);
|
||||
}
|
||||
//cerr << "Track Length : " << wpt->trackLength;
|
||||
waypoints.push_back(wpt);
|
||||
|
@ -831,6 +830,7 @@ bool FGAIFlightPlan::createDescent(FGAIAircraft * ac, FGAirport * apt,
|
|||
//cerr << "Repositioning to waypoint " << (*waypoints.begin())->name << endl;
|
||||
ac->resetPositionFromFlightPlan();
|
||||
}
|
||||
waypoints[1]->setName( (waypoints[1]->getName() + string("legend")));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -852,7 +852,7 @@ bool FGAIFlightPlan::createLanding(FGAIAircraft * ac, FGAirport * apt,
|
|||
//rwy = apt->getRunwayByIdent(activeRunway);
|
||||
|
||||
|
||||
waypoint *wpt;
|
||||
FGAIWaypoint *wpt;
|
||||
double aptElev = apt->getElevation();
|
||||
|
||||
SGGeod coord;
|
||||
|
@ -861,7 +861,7 @@ bool FGAIFlightPlan::createLanding(FGAIAircraft * ac, FGAirport * apt,
|
|||
snprintf(buffer, 12, "wpt%d", i);
|
||||
coord = rwy->pointOnCenterline(rwy->lengthM() * (i / 10.0));
|
||||
wpt = createOnGround(ac, buffer, coord, aptElev, (vTouchdown / i));
|
||||
wpt->crossat = apt->getElevation();
|
||||
wpt->setCrossat(apt->getElevation());
|
||||
waypoints.push_back(wpt);
|
||||
}
|
||||
|
||||
|
@ -890,7 +890,7 @@ bool FGAIFlightPlan::createLanding(FGAIAircraft * ac, FGAirport * apt,
|
|||
bool FGAIFlightPlan::createParking(FGAIAircraft * ac, FGAirport * apt,
|
||||
double radius)
|
||||
{
|
||||
waypoint *wpt;
|
||||
FGAIWaypoint *wpt;
|
||||
double aptElev = apt->getElevation();
|
||||
double lat = 0.0, lat2 = 0.0;
|
||||
double lon = 0.0, lon2 = 0.0;
|
||||
|
|
|
@ -292,7 +292,7 @@ bool FGAIFlightPlan::createCruise(FGAIAircraft *ac, bool firstFlight, FGAirport
|
|||
double alt, const string& fltType)
|
||||
{
|
||||
double vCruise = ac->getPerformance()->vCruise();
|
||||
waypoint *wpt;
|
||||
FGAIWaypoint *wpt;
|
||||
wpt = createInAir(ac, "Cruise", SGGeod::fromDeg(longitude, latitude), alt, vCruise);
|
||||
waypoints.push_back(wpt);
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/******************************************************************************
|
||||
/****************************************************************************
|
||||
* AIFlightPlanCreatePushBack.cxx
|
||||
* Written by Durk Talsma, started August 1, 2007.
|
||||
*
|
||||
|
@ -74,22 +74,10 @@ bool FGAIFlightPlan::createPushBack(FGAIAircraft *ac,
|
|||
return false;
|
||||
char buffer[10];
|
||||
snprintf (buffer, 10, "%d", gateId);
|
||||
SGGeod coord = coord.fromDeg(lon, lat);
|
||||
//FGTaxiNode *tn = dep->getDynamics()->getGroundNetwork()->findNode(node);
|
||||
waypoint *wpt;
|
||||
wpt = new waypoint;
|
||||
wpt->name = string(buffer); // fixme: should be the name of the taxiway
|
||||
wpt->latitude = lat;
|
||||
wpt->longitude = lon;
|
||||
// Elevation is currently disregarded when on_ground is true
|
||||
// because the AIModel obtains a periodic ground elevation estimate.
|
||||
wpt->altitude = dep->getElevation();
|
||||
wpt->speed = vTaxiBackward;
|
||||
wpt->crossat = -10000;
|
||||
wpt->gear_down = true;
|
||||
wpt->flaps_down= true;
|
||||
wpt->finished = false;
|
||||
wpt->on_ground = true;
|
||||
wpt->routeIndex = -1;
|
||||
FGAIWaypoint *wpt = createOnGround(ac, string(buffer), coord, dep->getElevation(), vTaxiBackward);
|
||||
wpt->setRouteIndex(-1);
|
||||
waypoints.push_back(wpt);
|
||||
}
|
||||
//cerr << "Success : GateId = " << gateId << endl;
|
||||
|
@ -119,7 +107,7 @@ bool FGAIFlightPlan::createPushBack(FGAIAircraft *ac,
|
|||
|
||||
|
||||
pushBackRoute = parking->getPushBackRoute();
|
||||
if ((pushBackNode > 0) && (pushBackRoute == 0)) {
|
||||
if ((pushBackNode > 0) && (pushBackRoute == 0)) { // Load the already established route for this gate
|
||||
int node, rte;
|
||||
FGTaxiRoute route;
|
||||
//cerr << "Creating push-back for " << gateId << " (" << parking->getName() << ") using push-back point " << pushBackNode << endl;
|
||||
|
@ -134,7 +122,6 @@ bool FGAIFlightPlan::createPushBack(FGAIAircraft *ac,
|
|||
SG_LOG(SG_GENERAL, SG_WARN, "Using " << pushBackNode);
|
||||
}
|
||||
pushBackRoute->first();
|
||||
waypoint *wpt;
|
||||
while(pushBackRoute->next(&node, &rte))
|
||||
{
|
||||
//FGTaxiNode *tn = apt->getDynamics()->getGroundNetwork()->findSegment(node)->getEnd();
|
||||
|
@ -142,122 +129,20 @@ bool FGAIFlightPlan::createPushBack(FGAIAircraft *ac,
|
|||
snprintf (buffer, 10, "%d", node);
|
||||
FGTaxiNode *tn = dep->getDynamics()->getGroundNetwork()->findNode(node);
|
||||
//ids.pop_back();
|
||||
wpt = new waypoint;
|
||||
wpt->name = string(buffer); // fixme: should be the name of the taxiway
|
||||
wpt->latitude = tn->getLatitude();
|
||||
wpt->longitude = tn->getLongitude();
|
||||
// Elevation is currently disregarded when on_ground is true
|
||||
// because the AIModel obtains a periodic ground elevation estimate.
|
||||
wpt->altitude = dep->getElevation();
|
||||
wpt->speed = vTaxiBackward;
|
||||
wpt->crossat = -10000;
|
||||
wpt->gear_down = true;
|
||||
wpt->flaps_down= true;
|
||||
wpt->finished = false;
|
||||
wpt->on_ground = true;
|
||||
wpt->routeIndex = rte;
|
||||
//wpt = new waypoint;
|
||||
SGGeod coord = coord.fromDeg(tn->getLongitude(), tn->getLatitude());
|
||||
FGAIWaypoint *wpt = createOnGround(ac, string(buffer), coord, dep->getElevation(), vTaxiBackward);
|
||||
|
||||
wpt->setRouteIndex(rte);
|
||||
waypoints.push_back(wpt);
|
||||
}
|
||||
// some special considerations for the last point:
|
||||
wpt->name = string("PushBackPoint");
|
||||
wpt->speed = vTaxi;
|
||||
//for (wpt_vector_iterator i = waypoints.begin(); i != waypoints.end(); i++) {
|
||||
// cerr << "Waypoint Name: " << (*i)->name << endl;
|
||||
//}
|
||||
} else {
|
||||
/*
|
||||
string rwyClass = getRunwayClassFromTrafficType(fltType);
|
||||
|
||||
// Only set this if it hasn't been set by ATC already.
|
||||
if (activeRunway.empty()) {
|
||||
//cerr << "Getting runway for " << ac->getTrafficRef()->getCallSign() << " at " << apt->getId() << endl;
|
||||
double depHeading = ac->getTrafficRef()->getCourse();
|
||||
dep->getDynamics()->getActiveRunway(rwyClass, 1, activeRunway,
|
||||
depHeading);
|
||||
}
|
||||
rwy = dep->getRunwayByIdent(activeRunway);
|
||||
SGGeod runwayTakeoff = rwy->pointOnCenterline(5.0);
|
||||
|
||||
FGGroundNetwork *gn = dep->getDynamics()->getGroundNetwork();
|
||||
if (!gn->exists()) {
|
||||
createDefaultTakeoffTaxi(ac, dep, rwy);
|
||||
return true;
|
||||
}
|
||||
int runwayId = gn->findNearestNode(runwayTakeoff);
|
||||
int node = 0;
|
||||
// Find out which node to start from
|
||||
FGParking *park = dep->getDynamics()->getParking(gateId);
|
||||
if (park) {
|
||||
node = park->getPushBackPoint();
|
||||
}
|
||||
|
||||
if (node == -1) {
|
||||
node = gateId;
|
||||
}
|
||||
// HAndle case where parking doens't have a node
|
||||
if ((node == 0) && park) {
|
||||
if (firstFlight) {
|
||||
node = gateId;
|
||||
} else {
|
||||
node = gateId;
|
||||
}
|
||||
}
|
||||
//delete taxiRoute;
|
||||
//taxiRoute = new FGTaxiRoute;
|
||||
FGTaxiRoute tr = gn->findShortestRoute(node, runwayId);
|
||||
int route;
|
||||
FGTaxiNode *tn;
|
||||
waypoint *wpt;
|
||||
int nr = 0;
|
||||
cerr << "Creating taxiroute from gate: " << gateId << " at " << dep->getId() << endl;
|
||||
while (tr.next(&node, &route) && (nr++ < 3)) {
|
||||
char buffer[10];
|
||||
snprintf(buffer, 10, "%d", node);
|
||||
tn = dep->getDynamics()->getGroundNetwork()->findNode(node);
|
||||
wpt = createOnGround(ac, buffer, tn->getGeod(), dep->getElevation(),
|
||||
vTaxiReduced);
|
||||
wpt->routeIndex = route;
|
||||
waypoints.push_back(wpt);
|
||||
}
|
||||
wpt->name = "PushBackPoint";
|
||||
lastNodeVisited = tn->getIndex();
|
||||
//FGTaxiNode *firstNode = findNode(gateId);
|
||||
//FGTaxiNode *lastNode = findNode(runwayId);
|
||||
//cerr << "Creating direct forward departure route fragment" << endl;
|
||||
*/
|
||||
waypoints.back()->setName(string("PushBackPoint"));
|
||||
waypoints.back()->setSpeed(vTaxi);
|
||||
ac->setTaxiClearanceRequest(true);
|
||||
} else { // In case of a push forward departure...
|
||||
ac->setTaxiClearanceRequest(false);
|
||||
double lat2 = 0.0, lon2 = 0.0, az2 = 0.0;
|
||||
waypoint *wpt;
|
||||
geo_direct_wgs_84 ( 0, lat, lon, heading,
|
||||
2, &lat2, &lon2, &az2 );
|
||||
wpt = new waypoint;
|
||||
wpt->name = "park2";
|
||||
wpt->latitude = lat2;
|
||||
wpt->longitude = lon2;
|
||||
wpt->altitude = dep->getElevation();
|
||||
wpt->speed = vTaxiReduced;
|
||||
wpt->crossat = -10000;
|
||||
wpt->gear_down = true;
|
||||
wpt->flaps_down= true;
|
||||
wpt->finished = false;
|
||||
wpt->on_ground = true;
|
||||
wpt->routeIndex = 0;
|
||||
waypoints.push_back(wpt);
|
||||
|
||||
geo_direct_wgs_84 ( 0, lat, lon, heading,
|
||||
4, &lat2, &lon2, &az2 );
|
||||
wpt = new waypoint;
|
||||
wpt->name = "name";
|
||||
wpt->latitude = lat2;
|
||||
wpt->longitude = lon2;
|
||||
wpt->altitude = dep->getElevation();
|
||||
wpt->speed = vTaxiReduced;
|
||||
wpt->crossat = -10000;
|
||||
wpt->gear_down = true;
|
||||
wpt->flaps_down= true;
|
||||
wpt->finished = false;
|
||||
wpt->on_ground = true;
|
||||
wpt->routeIndex = 0;
|
||||
waypoints.push_back(wpt);
|
||||
|
||||
//cerr << "Creating final push forward point for gate " << gateId << endl;
|
||||
FGTaxiNode *tn = dep->getDynamics()->getGroundNetwork()->findNode(gateId);
|
||||
|
@ -273,21 +158,27 @@ bool FGAIFlightPlan::createPushBack(FGAIAircraft *ac,
|
|||
SG_LOG(SG_GENERAL, SG_ALERT, "No valid taxinode found");
|
||||
exit(1);
|
||||
}
|
||||
wpt = new waypoint;
|
||||
wpt->name = "PushBackPoint";
|
||||
wpt->latitude = tn->getLatitude();
|
||||
wpt->longitude = tn->getLongitude();
|
||||
wpt->altitude = dep->getElevation();
|
||||
wpt->speed = vTaxiReduced;
|
||||
wpt->crossat = -10000;
|
||||
wpt->gear_down = true;
|
||||
wpt->flaps_down= true;
|
||||
wpt->finished = false;
|
||||
wpt->on_ground = true;
|
||||
wpt->routeIndex = (*ts)->getIndex();
|
||||
waypoints.push_back(wpt);
|
||||
}
|
||||
double distance = (*ts)->getLength();
|
||||
//cerr << "Length of push forward route = " << distance << " and heading is " << heading << endl;
|
||||
lat2 = tn->getLatitude();
|
||||
lon2 = tn->getLongitude();
|
||||
|
||||
for (int i = 1; i < 10; i++) {
|
||||
geo_direct_wgs_84 ( 0, lat, lon, heading,
|
||||
((i / 10.0) * distance), &lat2, &lon2, &az2 );
|
||||
char buffer[16];
|
||||
snprintf(buffer, 16, "pushback-%02d", i);
|
||||
SGGeod coord = coord.fromDeg(lon2, lat2);
|
||||
//cerr << i << endl;
|
||||
FGAIWaypoint *wpt = createOnGround(ac, string(buffer), coord, dep->getElevation(), vTaxiReduced);
|
||||
|
||||
wpt->setRouteIndex((*ts)->getIndex());
|
||||
waypoints.push_back(wpt);
|
||||
}
|
||||
// cerr << "Done " << endl;
|
||||
waypoints.back()->setName(string("PushBackPoint"));
|
||||
// cerr << "Done assinging new name" << endl;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -321,51 +212,26 @@ void FGAIFlightPlan::createPushBackFallBack(FGAIAircraft *ac, bool firstFlight,
|
|||
|
||||
heading += 180.0;
|
||||
if (heading > 360)
|
||||
heading -= 360;
|
||||
waypoint *wpt = new waypoint;
|
||||
wpt->name = "park";
|
||||
wpt->latitude = lat;
|
||||
wpt->longitude = lon;
|
||||
wpt->altitude = dep->getElevation();
|
||||
wpt->speed = vTaxiBackward;
|
||||
wpt->crossat = -10000;
|
||||
wpt->gear_down = true;
|
||||
wpt->flaps_down= true;
|
||||
wpt->finished = false;
|
||||
wpt->on_ground = true;
|
||||
heading -= 360;
|
||||
|
||||
SGGeod coord = coord.fromDeg(lon, lat);
|
||||
FGAIWaypoint *wpt = createOnGround(ac, string("park"), coord, dep->getElevation(), vTaxiBackward);
|
||||
|
||||
waypoints.push_back(wpt);
|
||||
|
||||
geo_direct_wgs_84 ( 0, lat, lon, heading,
|
||||
10,
|
||||
&lat2, &lon2, &az2 );
|
||||
wpt = new waypoint;
|
||||
wpt->name = "park2";
|
||||
wpt->latitude = lat2;
|
||||
wpt->longitude = lon2;
|
||||
wpt->altitude = dep->getElevation();
|
||||
wpt->speed = vTaxiBackward;
|
||||
wpt->crossat = -10000;
|
||||
wpt->gear_down = true;
|
||||
wpt->flaps_down= true;
|
||||
wpt->finished = false;
|
||||
wpt->on_ground = true;
|
||||
wpt->routeIndex = 0;
|
||||
coord = coord.fromDeg(lon2, lat2);
|
||||
wpt = createOnGround(ac, string("park2"), coord, dep->getElevation(), vTaxiBackward);
|
||||
|
||||
waypoints.push_back(wpt);
|
||||
|
||||
geo_direct_wgs_84 ( 0, lat, lon, heading,
|
||||
2.2*radius,
|
||||
&lat2, &lon2, &az2 );
|
||||
wpt = new waypoint;
|
||||
wpt->name = "taxiStart";
|
||||
wpt->latitude = lat2;
|
||||
wpt->longitude = lon2;
|
||||
wpt->altitude = dep->getElevation();
|
||||
wpt->speed = vTaxiReduced;
|
||||
wpt->crossat = -10000;
|
||||
wpt->gear_down = true;
|
||||
wpt->flaps_down= true;
|
||||
wpt->finished = false;
|
||||
wpt->on_ground = true;
|
||||
wpt->routeIndex = 0;
|
||||
coord = coord.fromDeg(lon2, lat2);
|
||||
wpt = createOnGround(ac, string("taxiStart"), coord, dep->getElevation(), vTaxiReduced);
|
||||
waypoints.push_back(wpt);
|
||||
|
||||
}
|
||||
|
|
|
@ -280,7 +280,7 @@ bool FGAIGroundVehicle::getPitch() {
|
|||
|
||||
} else {
|
||||
|
||||
if (prev->altitude == 0 || curr->altitude == 0) return false;
|
||||
if (prev->getAltitude() == 0 || curr->getAltitude() == 0) return false;
|
||||
|
||||
static double distance;
|
||||
static double d_alt;
|
||||
|
@ -289,20 +289,20 @@ bool FGAIGroundVehicle::getPitch() {
|
|||
|
||||
if (_new_waypoint){
|
||||
//cout << "new waypoint, calculating pitch " << endl;
|
||||
curr_alt = curr->altitude;
|
||||
prev_alt = prev->altitude;
|
||||
curr_alt = curr->getAltitude();
|
||||
prev_alt = prev->getAltitude();
|
||||
//cout << "prev_alt" <<prev_alt << endl;
|
||||
d_alt = (curr_alt - prev_alt) * SG_METER_TO_FEET;
|
||||
//_elevation = prev->altitude;
|
||||
distance = SGGeodesy::distanceM(SGGeod::fromDeg(prev->longitude, prev->latitude),
|
||||
SGGeod::fromDeg(curr->longitude, curr->latitude));
|
||||
distance = SGGeodesy::distanceM(SGGeod::fromDeg(prev->getLongitude(), prev->getLatitude()),
|
||||
SGGeod::fromDeg(curr->getLongitude(), curr->getLatitude()));
|
||||
_pitch = atan2(d_alt, distance * SG_METER_TO_FEET) * SG_RADIANS_TO_DEGREES;
|
||||
//cout << "new waypoint, calculating pitch " << _pitch <<
|
||||
// " " << _pitch_offset << " " << _elevation <<endl;
|
||||
}
|
||||
|
||||
double distance_to_go = SGGeodesy::distanceM(SGGeod::fromDeg(pos.getLongitudeDeg(), pos.getLatitudeDeg()),
|
||||
SGGeod::fromDeg(curr->longitude, curr->latitude));
|
||||
SGGeod::fromDeg(curr->getLongitude(), curr->getLatitude()));
|
||||
|
||||
/*cout << "tunnel " << _tunnel
|
||||
<< " distance prev & curr " << prev->name << " " << curr->name << " " << distance * SG_METER_TO_FEET
|
||||
|
@ -385,13 +385,13 @@ void FGAIGroundVehicle::AdvanceFP(){
|
|||
double count = 0;
|
||||
string parent_next_name =_selected_ac->getStringValue("waypoint/name-next");
|
||||
|
||||
while(fp->getNextWaypoint() != 0 && fp->getNextWaypoint()->name != "END" && count < 5){
|
||||
while(fp->getNextWaypoint() != 0 && fp->getNextWaypoint()->getName() != "END" && count < 5){
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "AIGroundVeh1cle: " << _name
|
||||
<<" advancing waypoint to: " << parent_next_name);
|
||||
|
||||
if (fp->getNextWaypoint()->name == parent_next_name){
|
||||
if (fp->getNextWaypoint()->getName() == parent_next_name){
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "AIGroundVeh1cle: " << _name
|
||||
<< " not setting waypoint already at: " << fp->getNextWaypoint()->name);
|
||||
<< " not setting waypoint already at: " << fp->getNextWaypoint()->getName());
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -400,9 +400,9 @@ void FGAIGroundVehicle::AdvanceFP(){
|
|||
curr = fp->getCurrentWaypoint();
|
||||
next = fp->getNextWaypoint();
|
||||
|
||||
if (fp->getNextWaypoint()->name == parent_next_name){
|
||||
if (fp->getNextWaypoint()->getName() == parent_next_name){
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "AIGroundVeh1cle: " << _name
|
||||
<< " waypoint set to: " << fp->getNextWaypoint()->name);
|
||||
<< " waypoint set to: " << fp->getNextWaypoint()->getName());
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -410,15 +410,15 @@ void FGAIGroundVehicle::AdvanceFP(){
|
|||
|
||||
}// end while loop
|
||||
|
||||
while(fp->getPreviousWaypoint() != 0 && fp->getPreviousWaypoint()->name != "END"
|
||||
while(fp->getPreviousWaypoint() != 0 && fp->getPreviousWaypoint()->getName() != "END"
|
||||
&& count > -10){
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "AIGroundVeh1cle: " << _name
|
||||
<< " retreating waypoint to: " << parent_next_name
|
||||
<< " at: " << fp->getNextWaypoint()->name);
|
||||
<< " at: " << fp->getNextWaypoint()->getName());
|
||||
|
||||
if (fp->getNextWaypoint()->name == parent_next_name){
|
||||
if (fp->getNextWaypoint()->getName() == parent_next_name){
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "AIGroundVeh1cle: " << _name
|
||||
<< " not setting waypoint already at:" << fp->getNextWaypoint()->name );
|
||||
<< " not setting waypoint already at:" << fp->getNextWaypoint()->getName() );
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -427,9 +427,9 @@ void FGAIGroundVehicle::AdvanceFP(){
|
|||
curr = fp->getCurrentWaypoint();
|
||||
next = fp->getNextWaypoint();
|
||||
|
||||
if (fp->getNextWaypoint()->name == parent_next_name){
|
||||
if (fp->getNextWaypoint()->getName() == parent_next_name){
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "AIGroundVeh1cle: " << _name
|
||||
<< " waypoint set to: " << fp->getNextWaypoint()->name);
|
||||
<< " waypoint set to: " << fp->getNextWaypoint()->getName());
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -488,7 +488,7 @@ void FGAIGroundVehicle::RunGroundVehicle(double dt){
|
|||
}
|
||||
|
||||
if(_parent == ""){
|
||||
AccelTo(prev->speed);
|
||||
AccelTo(prev->getSpeed());
|
||||
_dt_count = 0;
|
||||
return;
|
||||
}
|
||||
|
@ -499,7 +499,7 @@ void FGAIGroundVehicle::RunGroundVehicle(double dt){
|
|||
bool parent_waiting = _selected_ac->getBoolValue("waypoint/waiting");
|
||||
//bool parent_restart = _selected_ac->getBoolValue("controls/restart");
|
||||
|
||||
if (parent_next_name == "END" && fp->getNextWaypoint()->name != "END" ){
|
||||
if (parent_next_name == "END" && fp->getNextWaypoint()->getName() != "END" ){
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "AIGroundVeh1cle: " << _name
|
||||
<< " setting END: getting new waypoints ");
|
||||
AdvanceFP();
|
||||
|
@ -513,7 +513,7 @@ void FGAIGroundVehicle::RunGroundVehicle(double dt){
|
|||
AdvanceFP();
|
||||
setWPNames();
|
||||
_waiting = true;
|
||||
} else if (parent_next_name != "WAIT" && fp->getNextWaypoint()->name == "WAIT"){
|
||||
} else if (parent_next_name != "WAIT" && fp->getNextWaypoint()->getName() == "WAIT"){
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "AIGroundVeh1cle: " << _name
|
||||
<< " wait done: getting new waypoints ");
|
||||
_waiting = false;
|
||||
|
@ -521,8 +521,8 @@ void FGAIGroundVehicle::RunGroundVehicle(double dt){
|
|||
fp->IncrementWaypoint(false);
|
||||
next = fp->getNextWaypoint();
|
||||
|
||||
if (next->name == "WAITUNTIL" || next->name == "WAIT"
|
||||
|| next->name == "END"){
|
||||
if (next->getName() == "WAITUNTIL" || next->getName() == "WAIT"
|
||||
|| next->getName() == "END"){
|
||||
} else {
|
||||
prev = curr;
|
||||
fp->IncrementWaypoint(false);
|
||||
|
|
|
@ -572,25 +572,25 @@ void FGAIShip::setTunnel(bool t) {
|
|||
void FGAIShip::setWPNames() {
|
||||
|
||||
if (prev != 0)
|
||||
setPrevName(prev->name);
|
||||
setPrevName(prev->getName());
|
||||
else
|
||||
setPrevName("");
|
||||
|
||||
if (curr != 0)
|
||||
setCurrName(curr->name);
|
||||
setCurrName(curr->getName());
|
||||
else{
|
||||
setCurrName("");
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "AIShip: current wp name error" );
|
||||
}
|
||||
|
||||
if (next != 0)
|
||||
setNextName(next->name);
|
||||
setNextName(next->getName());
|
||||
else
|
||||
setNextName("");
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "AIShip: prev wp name " << prev->name);
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "AIShip: current wp name " << curr->name);
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "AIShip: next wp name " << next->name);
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "AIShip: prev wp name " << prev->getName());
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "AIShip: current wp name " << curr->getName());
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "AIShip: next wp name " << next->getName());
|
||||
|
||||
}
|
||||
|
||||
|
@ -647,7 +647,7 @@ void FGAIShip::ProcessFlightPlan(double dt) {
|
|||
// check to see if we've reached the point for our next turn
|
||||
// if the range to the waypoint is less than the calculated turn
|
||||
// radius we can start the turn to the next leg
|
||||
_wp_range = getRange(pos.getLatitudeDeg(), pos.getLongitudeDeg(), curr->latitude, curr->longitude);
|
||||
_wp_range = getRange(pos.getLatitudeDeg(), pos.getLongitudeDeg(), curr->getLatitude(), curr->getLongitude());
|
||||
_range_rate = (_wp_range - _old_range) / _dt_count;
|
||||
double sp_turn_radius_nm = _sp_turn_radius_ft / 6076.1155;
|
||||
// we need to try to identify a _missed waypoint
|
||||
|
@ -687,8 +687,8 @@ void FGAIShip::ProcessFlightPlan(double dt) {
|
|||
fp->IncrementWaypoint(false);
|
||||
next = fp->getNextWaypoint();
|
||||
|
||||
if (next->name == "WAITUNTIL" || next->name == "WAIT"
|
||||
|| next->name == "END" || next->name == "TUNNEL")
|
||||
if (next->getName() == "WAITUNTIL" || next->getName() == "WAIT"
|
||||
|| next->getName() == "END" || next->getName() == "TUNNEL")
|
||||
return;
|
||||
|
||||
prev = curr;
|
||||
|
@ -705,13 +705,13 @@ void FGAIShip::ProcessFlightPlan(double dt) {
|
|||
curr = fp->getCurrentWaypoint();
|
||||
next = fp->getNextWaypoint();
|
||||
setWPNames();
|
||||
_wp_range = getRange(pos.getLatitudeDeg(), pos.getLongitudeDeg(), curr->latitude, curr->longitude);
|
||||
_wp_range = getRange(pos.getLatitudeDeg(), pos.getLongitudeDeg(), curr->getLatitude(), curr->getLongitude());
|
||||
_old_range = _wp_range;
|
||||
_range_rate = 0;
|
||||
_new_waypoint = true;
|
||||
_missed_count = 0;
|
||||
_lead_angle = 0;
|
||||
AccelTo(prev->speed);
|
||||
AccelTo(prev->getSpeed());
|
||||
} else if (_restart){
|
||||
SG_LOG(SG_GENERAL, SG_INFO, "AIShip: " << _name << " Flightplan restarting ");
|
||||
_missed_count = 0;
|
||||
|
@ -725,7 +725,7 @@ void FGAIShip::ProcessFlightPlan(double dt) {
|
|||
|
||||
} else if (_next_name == "WAIT") {
|
||||
|
||||
if (_wait_count < next->time_sec) {
|
||||
if (_wait_count < next->getTime_sec()) {
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "AIShip: " << _name << " waiting ");
|
||||
setSpeed(0);
|
||||
_waiting = true;
|
||||
|
@ -741,8 +741,8 @@ void FGAIShip::ProcessFlightPlan(double dt) {
|
|||
fp->IncrementWaypoint(false);
|
||||
next = fp->getNextWaypoint();
|
||||
|
||||
if (next->name == "WAITUNTIL" || next->name == "WAIT"
|
||||
|| next->name == "END" || next->name == "TUNNEL")
|
||||
if (next->getName() == "WAITUNTIL" || next->getName() == "WAIT"
|
||||
|| next->getName() == "END" || next->getName() == "TUNNEL")
|
||||
return;
|
||||
|
||||
prev = curr;
|
||||
|
@ -753,12 +753,12 @@ void FGAIShip::ProcessFlightPlan(double dt) {
|
|||
|
||||
} else if (_next_name == "WAITUNTIL") {
|
||||
time_sec = getDaySeconds();
|
||||
until_time_sec = processTimeString(next->time);
|
||||
_until_time = next->time;
|
||||
setUntilTime(next->time);
|
||||
until_time_sec = processTimeString(next->getTime());
|
||||
_until_time = next->getTime();
|
||||
setUntilTime(next->getTime());
|
||||
if (until_time_sec > time_sec) {
|
||||
SG_LOG(SG_GENERAL, SG_INFO, "AIShip: " << _name << " "
|
||||
<< curr->name << " waiting until: "
|
||||
<< curr->getName() << " waiting until: "
|
||||
<< _until_time << " " << until_time_sec << " now " << time_sec );
|
||||
setSpeed(0);
|
||||
_lead_angle = 0;
|
||||
|
@ -770,12 +770,12 @@ void FGAIShip::ProcessFlightPlan(double dt) {
|
|||
setUntilTime("");
|
||||
fp->IncrementWaypoint(false);
|
||||
|
||||
while (next->name == "WAITUNTIL") {
|
||||
while (next->getName() == "WAITUNTIL") {
|
||||
fp->IncrementWaypoint(false);
|
||||
next = fp->getNextWaypoint();
|
||||
}
|
||||
|
||||
if (next->name == "WAIT")
|
||||
if (next->getName() == "WAIT")
|
||||
return;
|
||||
|
||||
prev = curr;
|
||||
|
@ -799,23 +799,23 @@ void FGAIShip::ProcessFlightPlan(double dt) {
|
|||
_missed_count = 0;
|
||||
_range_rate = 0;
|
||||
_lead_angle = 0;
|
||||
_wp_range = getRange(pos.getLatitudeDeg(), pos.getLongitudeDeg(), curr->latitude, curr->longitude);
|
||||
_wp_range = getRange(pos.getLatitudeDeg(), pos.getLongitudeDeg(), curr->getLatitude(), curr->getLongitude());
|
||||
_old_range = _wp_range;
|
||||
setWPPos();
|
||||
object_type type = getType();
|
||||
|
||||
if (type != 10)
|
||||
AccelTo(prev->speed);
|
||||
AccelTo(prev->getSpeed());
|
||||
|
||||
_curr_alt = curr->altitude;
|
||||
_prev_alt = prev->altitude;
|
||||
_curr_alt = curr->getAltitude();
|
||||
_prev_alt = prev->getAltitude();
|
||||
|
||||
} else {
|
||||
_new_waypoint = false;
|
||||
}
|
||||
|
||||
// now revise the required course for the next way point
|
||||
_course = getCourse(pos.getLatitudeDeg(), pos.getLongitudeDeg(), curr->latitude, curr->longitude);
|
||||
_course = getCourse(pos.getLatitudeDeg(), pos.getLongitudeDeg(), curr->getLatitude(), curr->getLongitude());
|
||||
|
||||
if (finite(_course))
|
||||
TurnTo(_course);
|
||||
|
@ -840,7 +840,7 @@ bool FGAIShip::initFlightPlan() {
|
|||
curr = fp->getCurrentWaypoint(); //second waypoint
|
||||
next = fp->getNextWaypoint(); //third waypoint (might not exist!)
|
||||
|
||||
while (curr->name == "WAIT" || curr->name == "WAITUNTIL") { // don't wait when initialising
|
||||
while (curr->getName() == "WAIT" || curr->getName() == "WAITUNTIL") { // don't wait when initialising
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "AIShip: " << _name << " re-initializing waypoints ");
|
||||
fp->IncrementWaypoint(false);
|
||||
curr = fp->getCurrentWaypoint();
|
||||
|
@ -874,14 +874,14 @@ bool FGAIShip::initFlightPlan() {
|
|||
}
|
||||
|
||||
} else {
|
||||
setLatitude(prev->latitude);
|
||||
setLongitude(prev->longitude);
|
||||
setSpeed(prev->speed);
|
||||
setLatitude(prev->getLatitude());
|
||||
setLongitude(prev->getLongitude());
|
||||
setSpeed(prev->getSpeed());
|
||||
}
|
||||
|
||||
setWPNames();
|
||||
setHeading(getCourse(prev->latitude, prev->longitude, curr->latitude, curr->longitude));
|
||||
_wp_range = getRange(prev->latitude, prev->longitude, curr->latitude, curr->longitude);
|
||||
setHeading(getCourse(prev->getLatitude(), prev->getLongitude(), curr->getLatitude(), curr->getLongitude()));
|
||||
_wp_range = getRange(prev->getLatitude(), prev->getLongitude(), curr->getLatitude(), curr->getLongitude());
|
||||
_old_range = _wp_range;
|
||||
_range_rate = 0;
|
||||
_hdg_lock = true;
|
||||
|
@ -941,7 +941,7 @@ bool FGAIShip::advanceFlightPlan (double start_sec, double day_sec) {
|
|||
|
||||
while ( elapsed_sec < day_sec ) {
|
||||
|
||||
if (next->name == "END" || fp->getNextWaypoint() == 0) {
|
||||
if (next->getName() == "END" || fp->getNextWaypoint() == 0) {
|
||||
|
||||
if (_repeat ) {
|
||||
//cout << _name << ": " << "restarting flightplan" << endl;
|
||||
|
@ -954,11 +954,11 @@ bool FGAIShip::advanceFlightPlan (double start_sec, double day_sec) {
|
|||
return false;
|
||||
}
|
||||
|
||||
} else if (next->name == "WAIT") {
|
||||
} else if (next->getName() == "WAIT") {
|
||||
//cout << _name << ": begin WAIT: " << prev->name << " ";
|
||||
//cout << curr->name << " " << next->name << endl;
|
||||
|
||||
elapsed_sec += next->time_sec;
|
||||
elapsed_sec += next->getTime_sec();
|
||||
|
||||
if ( elapsed_sec >= day_sec)
|
||||
continue;
|
||||
|
@ -966,16 +966,16 @@ bool FGAIShip::advanceFlightPlan (double start_sec, double day_sec) {
|
|||
fp->IncrementWaypoint(false);
|
||||
next = fp->getNextWaypoint();
|
||||
|
||||
if (next->name != "WAITUNTIL" && next->name != "WAIT"
|
||||
&& next->name != "END") {
|
||||
if (next->getName() != "WAITUNTIL" && next->getName() != "WAIT"
|
||||
&& next->getName() != "END") {
|
||||
prev = curr;
|
||||
fp->IncrementWaypoint(false);
|
||||
curr = fp->getCurrentWaypoint();
|
||||
next = fp->getNextWaypoint();
|
||||
}
|
||||
|
||||
} else if (next->name == "WAITUNTIL") {
|
||||
double until_sec = processTimeString(next->time);
|
||||
} else if (next->getName() == "WAITUNTIL") {
|
||||
double until_sec = processTimeString(next->getTime());
|
||||
|
||||
if (until_sec > _start_sec && start_sec < 0)
|
||||
until_sec -= _day;
|
||||
|
@ -989,7 +989,7 @@ bool FGAIShip::advanceFlightPlan (double start_sec, double day_sec) {
|
|||
fp->IncrementWaypoint(false);
|
||||
next = fp->getNextWaypoint();
|
||||
|
||||
if (next->name != "WAITUNTIL" && next->name != "WAIT") {
|
||||
if (next->getName() != "WAITUNTIL" && next->getName() != "WAIT") {
|
||||
prev = curr;
|
||||
fp->IncrementWaypoint(false);
|
||||
curr = fp->getCurrentWaypoint();
|
||||
|
@ -1000,8 +1000,8 @@ bool FGAIShip::advanceFlightPlan (double start_sec, double day_sec) {
|
|||
//cout << prev->name << " " << curr->name << " " << next->name << endl;
|
||||
|
||||
} else {
|
||||
distance_nm = getRange(prev->latitude, prev->longitude, curr->latitude, curr->longitude);
|
||||
elapsed_sec += distance_nm * 60 * 60 / prev->speed;
|
||||
distance_nm = getRange(prev->getLatitude(), prev->getLongitude(), curr->getLatitude(), curr->getLongitude());
|
||||
elapsed_sec += distance_nm * 60 * 60 / prev->getSpeed();
|
||||
|
||||
if (elapsed_sec >= day_sec)
|
||||
continue;
|
||||
|
@ -1026,31 +1026,31 @@ bool FGAIShip::advanceFlightPlan (double start_sec, double day_sec) {
|
|||
|
||||
//cout << " time diff " << time_diff << endl;
|
||||
|
||||
if (next->name == "WAIT" ){
|
||||
if (next->getName() == "WAIT" ){
|
||||
setSpeed(0);
|
||||
lat = curr->latitude;
|
||||
lon = curr->longitude;
|
||||
lat = curr->getLatitude();
|
||||
lon = curr->getLongitude();
|
||||
_wait_count= time_diff;
|
||||
_waiting = true;
|
||||
} else if (next->name == "WAITUNTIL") {
|
||||
} else if (next->getName() == "WAITUNTIL") {
|
||||
setSpeed(0);
|
||||
lat = curr->latitude;
|
||||
lon = curr->longitude;
|
||||
lat = curr->getLatitude();
|
||||
lon = curr->getLongitude();
|
||||
_waiting = true;
|
||||
} else {
|
||||
setSpeed(prev->speed);
|
||||
setSpeed(prev->getSpeed());
|
||||
distance_nm = speed * time_diff / (60 * 60);
|
||||
double brg = getCourse(curr->latitude, curr->longitude, prev->latitude, prev->longitude);
|
||||
double brg = getCourse(curr->getLatitude(), curr->getLongitude(), prev->getLatitude(), prev->getLongitude());
|
||||
|
||||
//cout << " brg " << brg << " from " << curr->name << " to " << prev->name << " "
|
||||
// << " lat " << curr->latitude << " lon " << curr->longitude
|
||||
// << " distance m " << distance_nm * SG_NM_TO_METER << endl;
|
||||
|
||||
lat = geo_direct_wgs_84 (curr->latitude, curr->longitude, brg,
|
||||
lat = geo_direct_wgs_84 (curr->getLatitude(), curr->getLongitude(), brg,
|
||||
distance_nm * SG_NM_TO_METER, &lat, &lon, &recip );
|
||||
lon = geo_direct_wgs_84 (curr->latitude, curr->longitude, brg,
|
||||
lon = geo_direct_wgs_84 (curr->getLatitude(), curr->getLongitude(), brg,
|
||||
distance_nm * SG_NM_TO_METER, &lat, &lon, &recip );
|
||||
recip = geo_direct_wgs_84 (curr->latitude, curr->longitude, brg,
|
||||
recip = geo_direct_wgs_84 (curr->getLatitude(), curr->getLongitude(), brg,
|
||||
distance_nm * SG_NM_TO_METER, &lat, &lon, &recip );
|
||||
}
|
||||
|
||||
|
@ -1062,18 +1062,18 @@ bool FGAIShip::advanceFlightPlan (double start_sec, double day_sec) {
|
|||
|
||||
void FGAIShip::setWPPos() {
|
||||
|
||||
if (curr->name == "END" || curr->name == "WAIT"
|
||||
|| curr->name == "WAITUNTIL" || curr->name == "TUNNEL"){
|
||||
if (curr->getName() == "END" || curr->getName() == "WAIT"
|
||||
|| curr->getName() == "WAITUNTIL" || curr->getName() == "TUNNEL"){
|
||||
//cout << curr->name << " returning" << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
double elevation_m = 0;
|
||||
wppos.setLatitudeDeg(curr->latitude);
|
||||
wppos.setLongitudeDeg(curr->longitude);
|
||||
wppos.setLatitudeDeg(curr->getLatitude());
|
||||
wppos.setLongitudeDeg(curr->getLongitude());
|
||||
wppos.setElevationM(0);
|
||||
|
||||
if (curr->on_ground){
|
||||
if (curr->getOn_ground()){
|
||||
|
||||
if (globals->get_scenery()->get_elevation_m(SGGeod::fromGeodM(wppos, 3000),
|
||||
elevation_m, &_material, 0)){
|
||||
|
@ -1083,20 +1083,20 @@ void FGAIShip::setWPPos() {
|
|||
//cout << curr->name << " setting measured elev " << elevation_m << endl;
|
||||
|
||||
} else {
|
||||
wppos.setElevationM(curr->altitude);
|
||||
wppos.setElevationM(curr->getAltitude());
|
||||
//cout << curr->name << " setting FP elev " << elevation_m << endl;
|
||||
}
|
||||
|
||||
curr->altitude = wppos.getElevationM();
|
||||
curr->setAltitude(wppos.getElevationM());
|
||||
|
||||
}
|
||||
|
||||
void FGAIShip::setXTrackError() {
|
||||
|
||||
double course = getCourse(prev->latitude, prev->longitude,
|
||||
curr->latitude, curr->longitude);
|
||||
double course = getCourse(prev->getLatitude(), prev->getLongitude(),
|
||||
curr->getLatitude(), curr->getLongitude());
|
||||
double brg = getCourse(pos.getLatitudeDeg(), pos.getLongitudeDeg(),
|
||||
curr->latitude, curr->longitude);
|
||||
curr->getLatitude(), curr->getLongitude());
|
||||
double xtrack_error_nm = sin((course - brg)* SG_DEGREES_TO_RADIANS) * _wp_range;
|
||||
double factor = -0.0045 * speed + 1;
|
||||
double limit = _lead_angle_limit * factor;
|
||||
|
|
|
@ -81,9 +81,9 @@ public:
|
|||
double _missed_range, _tow_angle, _wait_count, _missed_count,_wp_range;
|
||||
double _dt_count, _next_run;
|
||||
|
||||
FGAIFlightPlan::waypoint* prev; // the one behind you
|
||||
FGAIFlightPlan::waypoint* curr; // the one ahead
|
||||
FGAIFlightPlan::waypoint* next; // the next plus 1
|
||||
FGAIWaypoint* prev; // the one behind you
|
||||
FGAIWaypoint* curr; // the one ahead
|
||||
FGAIWaypoint* next; // the next plus 1
|
||||
|
||||
protected:
|
||||
|
||||
|
|
|
@ -34,6 +34,8 @@
|
|||
|
||||
|
||||
FGATCManager::FGATCManager() {
|
||||
controller = 0;
|
||||
prevController = 0;
|
||||
networkVisible = false;
|
||||
}
|
||||
|
||||
|
@ -115,16 +117,17 @@ void FGATCManager::init() {
|
|||
int stationFreq = apt->getDynamics()->getTowerFrequency(2);
|
||||
//cerr << "Setting radio frequency to in airfrequency: " << stationFreq << endl;
|
||||
fgSetDouble("/instrumentation/comm[0]/frequencies/selected-mhz", ((double) stationFreq / 100.0));
|
||||
leg = 4;
|
||||
leg = 3;
|
||||
string fltType = "ga";
|
||||
fp->setRunway(runway);
|
||||
fp->createTakeOff(&ai_ac, false, apt, 0, fltType);
|
||||
ai_ac.setTakeOffStatus(2);
|
||||
} else {
|
||||
controller = apt->getDynamics()->getStartupController();
|
||||
int stationFreq = apt->getDynamics()->getGroundFrequency(2);
|
||||
int stationFreq = apt->getDynamics()->getGroundFrequency(1);
|
||||
//cerr << "Setting radio frequency to : " << stationFreq << endl;
|
||||
fgSetDouble("/instrumentation/comm[0]/frequencies/selected-mhz", ((double) stationFreq / 100.0));
|
||||
leg = 2;
|
||||
leg = 1;
|
||||
//double, lat, lon, head; // Unused variables;
|
||||
//int getId = apt->getDynamics()->getParking(gateId, &lat, &lon, &head);
|
||||
FGParking* parking = dcs->getParking(park_index);
|
||||
|
@ -142,7 +145,9 @@ void FGATCManager::init() {
|
|||
fltType,
|
||||
aircraftType,
|
||||
airline);
|
||||
}
|
||||
|
||||
}
|
||||
fp->getLastWaypoint()->setName( fp->getLastWaypoint()->getName() + string("legend"));
|
||||
} else {
|
||||
controller = 0;
|
||||
}
|
||||
|
@ -155,7 +160,7 @@ void FGATCManager::init() {
|
|||
ai_ac.SetFlightPlan(fp);
|
||||
}
|
||||
if (controller) {
|
||||
controller->announcePosition(ai_ac.getID(), fp, fp->getCurrentWaypoint()->routeIndex,
|
||||
controller->announcePosition(ai_ac.getID(), fp, fp->getCurrentWaypoint()->getRouteIndex(),
|
||||
ai_ac._getLatitude(), ai_ac._getLongitude(), heading, speed, altitude,
|
||||
aircraftRadius, leg, &ai_ac);
|
||||
|
||||
|
@ -180,20 +185,23 @@ void FGATCManager::update ( double time ) {
|
|||
FGAIFlightPlan *fp = ai_ac.GetFlightPlan();
|
||||
|
||||
/* test code : find out how the routing develops */
|
||||
//if (fp) {
|
||||
// int size = fp->getNrOfWayPoints();
|
||||
if (fp) {
|
||||
int size = fp->getNrOfWayPoints();
|
||||
// //cerr << "Setting pos" << pos << " ";
|
||||
// //cerr << "setting intentions " ;
|
||||
// for (int i = 0; i < size; i++) {
|
||||
for (int i = 0; i < size; i++) {
|
||||
// int val = fp->getRouteIndex(i);
|
||||
// cerr << val << " ";
|
||||
//cerr << fp->getWayPoint(i)->getName() << " ";
|
||||
//if ((val) && (val != pos)) {
|
||||
//intentions.push_back(val);
|
||||
//cerr << "[done ] " << endl;
|
||||
//}
|
||||
// }
|
||||
//}
|
||||
}
|
||||
}
|
||||
//cerr << "[done ] " << endl;
|
||||
if (fp) {
|
||||
//cerr << "Currently at leg : " << fp->getLeg() << endl;
|
||||
}
|
||||
double longitude = fgGetDouble("/position/longitude-deg");
|
||||
double latitude = fgGetDouble("/position/latitude-deg");
|
||||
double heading = fgGetDouble("/orientation/heading-deg");
|
||||
|
@ -208,9 +216,10 @@ void FGATCManager::update ( double time ) {
|
|||
controller = ai_ac.getATCController();
|
||||
currentATCDialog->update(time);
|
||||
if (controller) {
|
||||
|
||||
//cerr << "name of previous waypoint : " << fp->getPreviousWaypoint()->getName() << endl;
|
||||
|
||||
//cerr << "Running FGATCManager::update()" << endl;
|
||||
//cerr << "Currently under control of " << controller->getName() << endl;
|
||||
controller->updateAircraftInformation(ai_ac.getID(),
|
||||
latitude,
|
||||
longitude,
|
||||
|
@ -227,9 +236,13 @@ void FGATCManager::update ( double time ) {
|
|||
networkVisible = !networkVisible;
|
||||
trans_num->setIntValue(-1);
|
||||
}
|
||||
if ((controller != prevController) && (prevController)) {
|
||||
prevController->render(false);
|
||||
}
|
||||
controller->render(networkVisible);
|
||||
|
||||
//cerr << "Adding groundnetWork to the scenegraph::update" << endl;
|
||||
prevController = controller;
|
||||
}
|
||||
//globals->get_scenery()->get_scene_graph()->addChild(node);
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ class FGATCManager : public SGSubsystem
|
|||
private:
|
||||
AtcVec activeStations;
|
||||
FGAIAircraft ai_ac;
|
||||
FGATCController *controller; // The ATC controller that is responsible for the user's aircraft.
|
||||
FGATCController *controller, *prevController; // The ATC controller that is responsible for the user's aircraft.
|
||||
//FGATCDialogNew dialog; // note that this variable should really replace the ugly global "currentATCDialog();
|
||||
bool networkVisible;
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
FGATCDialogNew *currentATCDialog;
|
||||
|
||||
static bool doATCDialog(const SGPropertyNode* arg) {
|
||||
cerr << "Running doATCDialog" << endl;
|
||||
//cerr << "Running doATCDialog" << endl;
|
||||
currentATCDialog->PopupDialog();
|
||||
return(true);
|
||||
}
|
||||
|
|
|
@ -86,7 +86,7 @@ time_t ActiveRunway::requestTimeSlot(time_t eta)
|
|||
}
|
||||
} else {
|
||||
if ((((*j) - (*i)) > (separation * 2))) { // found a potential slot
|
||||
// now check whether this slow is usable:
|
||||
// now check whether this slot is usable:
|
||||
// 1) eta should fall between the two points
|
||||
// i.e. eta > i AND eta < j
|
||||
//
|
||||
|
@ -193,6 +193,11 @@ void FGTrafficRecord::setPositionAndIntentions(int pos,
|
|||
}
|
||||
//exit(1);
|
||||
}
|
||||
/**
|
||||
* Check if another aircraft is ahead of the current one, and on the same
|
||||
* return true / false is the is/isn't the case.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
bool FGTrafficRecord::checkPositionAndIntentions(FGTrafficRecord & other)
|
||||
{
|
||||
|
@ -497,10 +502,12 @@ void FGATCController::transmit(FGTrafficRecord * rec, AtcMsgId msgId,
|
|||
string sender, receiver;
|
||||
int stationFreq = 0;
|
||||
int taxiFreq = 0;
|
||||
int towerFreq = 0;
|
||||
int freqId = 0;
|
||||
string atisInformation;
|
||||
string text;
|
||||
string taxiFreqStr;
|
||||
string towerFreqStr;
|
||||
double heading = 0;
|
||||
string activeRunway;
|
||||
string fltType;
|
||||
|
@ -509,20 +516,29 @@ void FGATCController::transmit(FGTrafficRecord * rec, AtcMsgId msgId,
|
|||
string transponderCode;
|
||||
FGAIFlightPlan *fp;
|
||||
string fltRules;
|
||||
string instructionText;
|
||||
|
||||
//double commFreqD;
|
||||
sender = rec->getAircraft()->getTrafficRef()->getCallSign();
|
||||
if (rec->getAircraft()->getTaxiClearanceRequest()) {
|
||||
instructionText = "push-back and taxi";
|
||||
} else {
|
||||
instructionText = "taxi";
|
||||
}
|
||||
//cerr << "transmitting for: " << sender << "Leg = " << rec->getLeg() << endl;
|
||||
switch (rec->getLeg()) {
|
||||
case 1:
|
||||
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);
|
||||
getDynamics()->getGroundFrequency(2);
|
||||
towerFreq =
|
||||
rec->getAircraft()->getTrafficRef()->getDepartureAirport()->
|
||||
getDynamics()->getTowerFrequency(2);
|
||||
receiver =
|
||||
rec->getAircraft()->getTrafficRef()->getDepartureAirport()->
|
||||
getName() + "-Ground";
|
||||
|
@ -530,7 +546,7 @@ void FGATCController::transmit(FGTrafficRecord * rec, AtcMsgId msgId,
|
|||
rec->getAircraft()->getTrafficRef()->getDepartureAirport()->
|
||||
getDynamics()->getAtisSequence();
|
||||
break;
|
||||
case 4:
|
||||
case 3:
|
||||
receiver =
|
||||
rec->getAircraft()->getTrafficRef()->getDepartureAirport()->
|
||||
getName() + "-Tower";
|
||||
|
@ -588,7 +604,7 @@ void FGATCController::transmit(FGTrafficRecord * rec, AtcMsgId msgId,
|
|||
receiver + ". Start-up approved. " + atisInformation +
|
||||
" correct, runway " + activeRunway + ", " + SID + ", squawk " +
|
||||
transponderCode + ". " +
|
||||
"For push-back and taxi clearance call " + taxiFreqStr + ". " +
|
||||
"For "+ instructionText + " clearance call " + taxiFreqStr + ". " +
|
||||
sender + " control.";
|
||||
break;
|
||||
case MSG_DENY_ENGINE_START:
|
||||
|
@ -606,11 +622,12 @@ void FGATCController::transmit(FGTrafficRecord * rec, AtcMsgId msgId,
|
|||
taxiFreqStr = formatATCFrequency3_2(taxiFreq);
|
||||
activeRunway = rec->getAircraft()->GetFlightPlan()->getRunway();
|
||||
transponderCode = rec->getAircraft()->GetTransponderCode();
|
||||
|
||||
text =
|
||||
receiver + ". Start-up approved. " + atisInformation +
|
||||
" correct, runway " + activeRunway + ", " + SID + ", squawk " +
|
||||
transponderCode + ". " +
|
||||
"For push-back and taxi clearance call " + taxiFreqStr + ". " +
|
||||
"For " + instructionText + " clearance call " + taxiFreqStr + ". " +
|
||||
sender;
|
||||
break;
|
||||
case MSG_ACKNOWLEDGE_SWITCH_GROUND_FREQUENCY:
|
||||
|
@ -624,10 +641,18 @@ void FGATCController::transmit(FGTrafficRecord * rec, AtcMsgId msgId,
|
|||
text = receiver + ". Roger. " + sender;
|
||||
break;
|
||||
case MSG_REQUEST_PUSHBACK_CLEARANCE:
|
||||
text = receiver + ". Request push-back. " + sender;
|
||||
if (rec->getAircraft()->getTaxiClearanceRequest()) {
|
||||
text = receiver + ". Request push-back. " + sender;
|
||||
} else {
|
||||
text = receiver + ". Request Taxi clearance. " + sender;
|
||||
}
|
||||
break;
|
||||
case MSG_PERMIT_PUSHBACK_CLEARANCE:
|
||||
text = receiver + ". Push-back approved. " + sender;
|
||||
if (rec->getAircraft()->getTaxiClearanceRequest()) {
|
||||
text = receiver + ". Push-back approved. " + sender;
|
||||
} else {
|
||||
text = receiver + ". Cleared to Taxi." + sender;
|
||||
}
|
||||
break;
|
||||
case MSG_HOLD_PUSHBACK_CLEARANCE:
|
||||
text = receiver + ". Standby. " + sender;
|
||||
|
@ -653,7 +678,37 @@ void FGATCController::transmit(FGTrafficRecord * rec, AtcMsgId msgId,
|
|||
case MSG_ACKNOWLEDGE_RESUME_TAXI:
|
||||
text = receiver + ". Continuing Taxi. " + sender;
|
||||
break;
|
||||
case MSG_REPORT_RUNWAY_HOLD_SHORT:
|
||||
activeRunway = rec->getAircraft()->GetFlightPlan()->getRunway();
|
||||
//activeRunway = "test";
|
||||
text = receiver + ". Holding short runway "
|
||||
+ activeRunway
|
||||
+ ". " + sender;
|
||||
//text = "test1";
|
||||
//cerr << "1 Currently at leg " << rec->getLeg() << endl;
|
||||
break;
|
||||
case MSG_ACKNOWLEDGE_REPORT_RUNWAY_HOLD_SHORT:
|
||||
activeRunway = rec->getAircraft()->GetFlightPlan()->getRunway();
|
||||
text = receiver + "Roger. Holding short runway "
|
||||
// + activeRunway
|
||||
+ ". " + sender;
|
||||
//text = "test2";
|
||||
//cerr << "2 Currently at leg " << rec->getLeg() << endl;
|
||||
break;
|
||||
case MSG_SWITCH_TOWER_FREQUENCY:
|
||||
towerFreqStr = formatATCFrequency3_2(towerFreq);
|
||||
text = receiver + "Contact Tower at " + towerFreqStr + ". " + sender;
|
||||
//text = "test3";
|
||||
//cerr << "3 Currently at leg " << rec->getLeg() << endl;
|
||||
break;
|
||||
case MSG_ACKNOWLEDGE_SWITCH_TOWER_FREQUENCY:
|
||||
towerFreqStr = formatATCFrequency3_2(towerFreq);
|
||||
text = receiver + "Roger, switching to tower at " + towerFreqStr + ". " + sender;
|
||||
//text = "test4";
|
||||
//cerr << "4 Currently at leg " << rec->getLeg() << endl;
|
||||
break;
|
||||
default:
|
||||
//text = "test3";
|
||||
text = text + sender + ". Transmitting unknown Message";
|
||||
break;
|
||||
}
|
||||
|
@ -716,9 +771,10 @@ void FGATCController::init()
|
|||
* class FGTowerController
|
||||
*
|
||||
**************************************************************************/
|
||||
FGTowerController::FGTowerController():
|
||||
FGTowerController::FGTowerController(FGAirportDynamics *par) :
|
||||
FGATCController()
|
||||
{
|
||||
parent = par;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -752,8 +808,29 @@ void FGTowerController::announcePosition(int id,
|
|||
rec.setRunway(intendedRoute->getRunway());
|
||||
rec.setLeg(leg);
|
||||
//rec.setCallSign(callsign);
|
||||
rec.setRadius(radius);
|
||||
rec.setAircraft(ref);
|
||||
activeTraffic.push_back(rec);
|
||||
// Don't just schedule the aircraft for the tower controller, also assign if to the correct active runway.
|
||||
ActiveRunwayVecIterator rwy = activeRunways.begin();
|
||||
if (activeRunways.size()) {
|
||||
while (rwy != activeRunways.end()) {
|
||||
if (rwy->getRunwayName() == intendedRoute->getRunway()) {
|
||||
break;
|
||||
}
|
||||
rwy++;
|
||||
}
|
||||
}
|
||||
if (rwy == activeRunways.end()) {
|
||||
ActiveRunway aRwy(intendedRoute->getRunway(), id);
|
||||
aRwy.addToDepartureCue(ref);
|
||||
activeRunways.push_back(aRwy);
|
||||
rwy = (activeRunways.end()-1);
|
||||
} else {
|
||||
rwy->addToDepartureCue(ref);
|
||||
}
|
||||
|
||||
//cerr << ref->getTrafficRef()->getCallSign() << " You are number " << rwy->getDepartureCueSize() << " for takeoff " << endl;
|
||||
} else {
|
||||
i->setPositionAndHeading(lat, lon, heading, speed, alt);
|
||||
}
|
||||
|
@ -786,29 +863,43 @@ void FGTowerController::updateAircraftInformation(int id, double lat, double lon
|
|||
}
|
||||
setDt(getDt() + dt);
|
||||
|
||||
// // see if we already have a clearance record for the currently active runway
|
||||
// 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();
|
||||
// again, a map might be more efficient here
|
||||
if (activeRunways.size()) {
|
||||
//while ((rwy->getRunwayName() != current->getRunway()) && (rwy != activeRunways.end())) {
|
||||
while (rwy != activeRunways.end()) {
|
||||
if (rwy->getRunwayName() == current->getRunway()) {
|
||||
break;
|
||||
}
|
||||
rwy++;
|
||||
while (rwy != activeRunways.end()) {
|
||||
if (rwy->getRunwayName() == current->getRunway()) {
|
||||
break;
|
||||
}
|
||||
rwy++;
|
||||
}
|
||||
if (rwy == activeRunways.end()) {
|
||||
ActiveRunway aRwy(current->getRunway(), id);
|
||||
activeRunways.push_back(aRwy); // Since there are no clearance records for this runway yet
|
||||
current->setHoldPosition(false); // Clear the current aircraft to continue
|
||||
} else {
|
||||
// Okay, we have a clearance record for this runway, so check
|
||||
// whether the clearence ID matches that of the current aircraft
|
||||
if (id == rwy->getCleared()) {
|
||||
current->setHoldPosition(false);
|
||||
|
||||
// only bother running the following code if the current aircraft is the
|
||||
// first in line for depature
|
||||
/* if (current->getAircraft() == rwy->getFirstAircraftInDepartureCue()) {
|
||||
if (rwy->getCleared()) {
|
||||
if (id == rwy->getCleared()) {
|
||||
current->setHoldPosition(false);
|
||||
} else {
|
||||
current->setHoldPosition(true);
|
||||
}
|
||||
} else {
|
||||
current->setHoldPosition(true);
|
||||
// For now. At later stages, this will probably be the place to check for inbound traffc.
|
||||
rwy->setCleared(id);
|
||||
}
|
||||
} */
|
||||
// only bother with aircraft that have a takeoff status of 2, since those are essentially under tower control
|
||||
if (current->getAircraft()->getTakeOffStatus() == 2) {
|
||||
current->setHoldPosition(true);
|
||||
int clearanceId = rwy->getCleared();
|
||||
if (clearanceId) {
|
||||
if (id == clearanceId) {
|
||||
current->setHoldPosition(false);
|
||||
}
|
||||
} else {
|
||||
if (current->getAircraft() == rwy->getFirstAircraftInDepartureCue()) {
|
||||
rwy->setCleared(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -839,7 +930,8 @@ void FGTowerController::signOff(int id)
|
|||
rwy++;
|
||||
}
|
||||
if (rwy != activeRunways.end()) {
|
||||
rwy = activeRunways.erase(rwy);
|
||||
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");
|
||||
|
@ -849,6 +941,7 @@ void FGTowerController::signOff(int id)
|
|||
SG_LOG(SG_GENERAL, SG_ALERT,
|
||||
"AI error: Aircraft without traffic record is signing off from tower");
|
||||
} else {
|
||||
i->getAircraft()->resetTakeOffStatus();
|
||||
i = activeTraffic.erase(i);
|
||||
//cerr << "Signing off from tower controller" << endl;
|
||||
}
|
||||
|
@ -911,6 +1004,11 @@ void FGTowerController::render(bool visible) {
|
|||
//cerr << "FGTowerController::render function not yet implemented" << endl;
|
||||
}
|
||||
|
||||
string FGTowerController::getName() {
|
||||
return string(parent->getId() + "-tower");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* class FGStartupController
|
||||
|
@ -1273,13 +1371,19 @@ void FGStartupController::render(bool visible)
|
|||
}
|
||||
}
|
||||
|
||||
string FGStartupController::getName() {
|
||||
return string(parent->getId() + "-startup");
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* class FGApproachController
|
||||
*
|
||||
**************************************************************************/
|
||||
FGApproachController::FGApproachController():
|
||||
FGApproachController::FGApproachController(FGAirportDynamics *par):
|
||||
FGATCController()
|
||||
{
|
||||
parent = par;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -1467,3 +1571,9 @@ ActiveRunway *FGApproachController::getRunway(string name)
|
|||
void FGApproachController::render(bool visible) {
|
||||
//cerr << "FGApproachController::render function not yet implemented" << endl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
string FGApproachController::getName() {
|
||||
return string(parent->getId() + "-approach");
|
||||
}
|
||||
|
|
|
@ -197,6 +197,8 @@ typedef vector<FGTrafficRecord>::iterator TrafficVectorIterator;
|
|||
typedef vector<time_t> TimeVector;
|
||||
typedef vector<time_t>::iterator TimeVectorIterator;
|
||||
|
||||
typedef vector<FGAIAircraft*> AircraftVec;
|
||||
typedef vector<FGAIAircraft*>::iterator AircraftVecIterator;
|
||||
|
||||
/***********************************************************************
|
||||
* Active runway, a utility class to keep track of which aircraft has
|
||||
|
@ -209,6 +211,8 @@ private:
|
|||
int currentlyCleared;
|
||||
double distanceToFinal;
|
||||
TimeVector estimatedArrivalTimes;
|
||||
AircraftVec departureCue;
|
||||
|
||||
public:
|
||||
ActiveRunway(string r, int cc) { rwy = r; currentlyCleared = cc; distanceToFinal = 6.0 * SG_NM_TO_METER; };
|
||||
|
||||
|
@ -218,7 +222,13 @@ public:
|
|||
//time_t getEstApproachTime() { return estimatedArrival; };
|
||||
|
||||
//void setEstApproachTime(time_t time) { estimatedArrival = time; };
|
||||
void addToDepartureCue(FGAIAircraft *ac) { departureCue.push_back(ac); };
|
||||
void setCleared(int number) { currentlyCleared = number; };
|
||||
time_t requestTimeSlot(time_t eta);
|
||||
|
||||
int getDepartureCueSize() { return departureCue.size(); };
|
||||
FGAIAircraft* getFirstAircraftInDepartureCue() { return departureCue.size() ? *(departureCue.begin()) : NULL; };
|
||||
void updateDepartureCue() { departureCue.erase(departureCue.begin()); }
|
||||
};
|
||||
|
||||
typedef vector<ActiveRunway> ActiveRunwayVec;
|
||||
|
@ -263,7 +273,13 @@ public:
|
|||
MSG_HOLD_POSITION,
|
||||
MSG_ACKNOWLEDGE_HOLD_POSITION,
|
||||
MSG_RESUME_TAXI,
|
||||
MSG_ACKNOWLEDGE_RESUME_TAXI } AtcMsgId;
|
||||
MSG_ACKNOWLEDGE_RESUME_TAXI,
|
||||
MSG_REPORT_RUNWAY_HOLD_SHORT,
|
||||
MSG_ACKNOWLEDGE_REPORT_RUNWAY_HOLD_SHORT,
|
||||
MSG_SWITCH_TOWER_FREQUENCY,
|
||||
MSG_ACKNOWLEDGE_SWITCH_TOWER_FREQUENCY
|
||||
} AtcMsgId;
|
||||
|
||||
typedef enum {
|
||||
ATC_AIR_TO_GROUND,
|
||||
ATC_GROUND_TO_AIR } AtcMsgDir;
|
||||
|
@ -286,6 +302,8 @@ public:
|
|||
void transmit(FGTrafficRecord *rec, AtcMsgId msgId, AtcMsgDir msgDir, bool audible);
|
||||
string getGateName(FGAIAircraft *aircraft);
|
||||
virtual void render(bool) = 0;
|
||||
virtual string getName() = 0;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
|
@ -300,9 +318,10 @@ class FGTowerController : public FGATCController
|
|||
private:
|
||||
TrafficVector activeTraffic;
|
||||
ActiveRunwayVec activeRunways;
|
||||
FGAirportDynamics *parent;
|
||||
|
||||
public:
|
||||
FGTowerController();
|
||||
FGTowerController(FGAirportDynamics *parent);
|
||||
virtual ~FGTowerController() {};
|
||||
virtual void announcePosition(int id, FGAIFlightPlan *intendedRoute, int currentRoute,
|
||||
double lat, double lon,
|
||||
|
@ -315,6 +334,7 @@ public:
|
|||
virtual FGATCInstruction getInstruction(int id);
|
||||
|
||||
virtual void render(bool);
|
||||
virtual string getName();
|
||||
bool hasActiveTraffic() { return activeTraffic.size() != 0; };
|
||||
TrafficVector &getActiveTraffic() { return activeTraffic; };
|
||||
};
|
||||
|
@ -329,7 +349,7 @@ class FGStartupController : public FGATCController
|
|||
private:
|
||||
TrafficVector activeTraffic;
|
||||
//ActiveRunwayVec activeRunways;
|
||||
FGAirportDynamics *parent;
|
||||
FGAirportDynamics *parent;
|
||||
|
||||
public:
|
||||
FGStartupController(FGAirportDynamics *parent);
|
||||
|
@ -345,6 +365,7 @@ public:
|
|||
virtual FGATCInstruction getInstruction(int id);
|
||||
|
||||
virtual void render(bool);
|
||||
virtual string getName();
|
||||
|
||||
bool hasActiveTraffic() { return activeTraffic.size() != 0; };
|
||||
TrafficVector &getActiveTraffic() { return activeTraffic; };
|
||||
|
@ -363,10 +384,11 @@ class FGApproachController : public FGATCController
|
|||
private:
|
||||
TrafficVector activeTraffic;
|
||||
ActiveRunwayVec activeRunways;
|
||||
FGAirportDynamics *parent;
|
||||
|
||||
public:
|
||||
FGApproachController();
|
||||
virtual ~FGApproachController() {};
|
||||
FGApproachController(FGAirportDynamics * parent);
|
||||
virtual ~FGApproachController() { };
|
||||
virtual void announcePosition(int id, FGAIFlightPlan *intendedRoute, int currentRoute,
|
||||
double lat, double lon,
|
||||
double hdg, double spd, double alt, double radius, int leg,
|
||||
|
@ -378,6 +400,7 @@ public:
|
|||
virtual FGATCInstruction getInstruction(int id);
|
||||
|
||||
virtual void render(bool);
|
||||
virtual string getName();
|
||||
|
||||
ActiveRunway* getRunway(string name);
|
||||
|
||||
|
|
|
@ -51,9 +51,12 @@ using std::random_shuffle;
|
|||
|
||||
FGAirportDynamics::FGAirportDynamics(FGAirport * ap):
|
||||
_ap(ap), rwyPrefs(ap), SIDs(ap),
|
||||
startupController (this),
|
||||
towerController (this),
|
||||
approachController (this),
|
||||
atisSequenceIndex(-1),
|
||||
atisSequenceTimeStamp(0.0),
|
||||
startupController(this)
|
||||
atisSequenceTimeStamp(0.0)
|
||||
|
||||
{
|
||||
lastUpdate = 0;
|
||||
}
|
||||
|
@ -493,25 +496,24 @@ const string & FGAirportDynamics::getId() const
|
|||
int FGAirportDynamics::getGroundFrequency(unsigned leg)
|
||||
{
|
||||
//return freqGround.size() ? freqGround[0] : 0; };
|
||||
//cerr << "Getting frequency for : " << leg << endl;
|
||||
int groundFreq = 0;
|
||||
if (leg < 2) {
|
||||
if (leg < 1) {
|
||||
SG_LOG(SG_ATC, SG_ALERT,
|
||||
"Leg value is smaller than two at " << SG_ORIGIN);
|
||||
"Leg value is smaller than one at " << SG_ORIGIN);
|
||||
}
|
||||
if (freqGround.size() == 0) {
|
||||
return 0;
|
||||
}
|
||||
if ((freqGround.size() > leg - 1) && (leg > 1)) {
|
||||
groundFreq = freqGround[leg - 1];
|
||||
}
|
||||
if ((freqGround.size() < leg - 1) && (leg > 1)) {
|
||||
|
||||
if ((freqGround.size() < leg) && (leg > 0)) {
|
||||
groundFreq =
|
||||
(freqGround.size() <
|
||||
(leg - 1)) ? freqGround[freqGround.size() -
|
||||
1] : freqGround[leg - 2];
|
||||
1] : freqGround[leg - 1];
|
||||
}
|
||||
if ((freqGround.size() >= leg - 1) && (leg > 1)) {
|
||||
groundFreq = freqGround[leg - 2];
|
||||
if ((freqGround.size() >= leg) && (leg > 0)) {
|
||||
groundFreq = freqGround[leg - 1];
|
||||
}
|
||||
return groundFreq;
|
||||
}
|
||||
|
|
|
@ -46,6 +46,8 @@
|
|||
#include <AIModel/AIAircraft.hxx>
|
||||
#include <AIModel/AIFlightPlan.hxx>
|
||||
|
||||
#include <ATC/atc_mgr.hxx>
|
||||
|
||||
#include <Scenery/scenery.hxx>
|
||||
|
||||
#include "groundnetwork.hxx"
|
||||
|
@ -171,6 +173,7 @@ bool FGTaxiRoute::next(int *nde, int *rte)
|
|||
return true;
|
||||
};
|
||||
|
||||
|
||||
void FGTaxiRoute::rewind(int route)
|
||||
{
|
||||
int currPoint;
|
||||
|
@ -510,6 +513,7 @@ void FGGroundNetwork::announcePosition(int id,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void FGGroundNetwork::signOff(int id)
|
||||
{
|
||||
TrafficVectorIterator i = activeTraffic.begin();
|
||||
|
@ -531,28 +535,40 @@ void FGGroundNetwork::signOff(int id)
|
|||
i = activeTraffic.erase(i);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The ground network can deal with the following states:
|
||||
* 0 = Normal; no action required
|
||||
* 1 = "Acknowledge "Hold position
|
||||
* 2 = "Acknowledge "Resume taxi".
|
||||
* 3 = "Issue TaxiClearance"
|
||||
* 4 = Acknowledge Taxi Clearance"
|
||||
* 5 = Post acknowlegde taxiclearance: Start taxiing
|
||||
* 6 = Report runway
|
||||
* 7 = Acknowledge report runway
|
||||
* 8 = Switch tower frequency
|
||||
* 9 = Acknowledge switch tower frequency
|
||||
*************************************************************************************************************************/
|
||||
bool FGGroundNetwork::checkTransmissionState(int minState, int maxState, TrafficVectorIterator i, time_t now, AtcMsgId msgId,
|
||||
AtcMsgDir msgDir)
|
||||
{
|
||||
int state = i->getState();
|
||||
if ((state >= minState) && (state <= maxState) && available) {
|
||||
if ((msgDir == ATC_AIR_TO_GROUND) && isUserAircraft(i->getAircraft())) {
|
||||
|
||||
//cerr << "Checking state " << state << " for " << i->getAircraft()->getCallSign() << endl;
|
||||
static SGPropertyNode_ptr trans_num = globals->get_props()->getNode("/sim/atc/transmission-num", true);
|
||||
int n = trans_num->getIntValue();
|
||||
if (n == 0) {
|
||||
trans_num->setIntValue(-1);
|
||||
// PopupCallback(n);
|
||||
cerr << "Selected transmission message " << n << endl;
|
||||
//cerr << "Selected transmission message " << n << endl;
|
||||
FGATCManager *atc = (FGATCManager*) globals->get_subsystem("atc");
|
||||
atc->getATCDialog()->removeEntry(1);
|
||||
} else {
|
||||
//cerr << "creating message for " << i->getAircraft()->getCallSign() << endl;
|
||||
transmit(&(*i), msgId, msgDir, false);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
//cerr << "Transmitting startup msg" << endl;
|
||||
transmit(&(*i), msgId, msgDir, true);
|
||||
i->updateState();
|
||||
lastTransmission = now;
|
||||
|
@ -631,12 +647,11 @@ void FGGroundNetwork::updateAircraftInformation(int id, double lat, double lon,
|
|||
if ((state == 5) && available) {
|
||||
current->setState(0);
|
||||
current->getAircraft()->setTaxiClearanceRequest(false);
|
||||
current->setHoldPosition(true);
|
||||
current->setHoldPosition(false);
|
||||
available = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -720,6 +735,10 @@ void FGGroundNetwork::checkSpeedAdjustment(int id, double lat,
|
|||
if (bearing > 180)
|
||||
bearing = 360 - bearing;
|
||||
if ((dist < mindist) && (bearing < 60.0)) {
|
||||
//cerr << "Current aircraft " << current->getAircraft()->getTrafficRef()->getCallSign()
|
||||
// << " is closest to " << i->getAircraft()->getTrafficRef()->getCallSign()
|
||||
// << ", which has status " << i->getAircraft()->isScheduledForTakeoff()
|
||||
// << endl;
|
||||
mindist = dist;
|
||||
closest = i;
|
||||
minbearing = bearing;
|
||||
|
@ -728,6 +747,8 @@ void FGGroundNetwork::checkSpeedAdjustment(int id, double lat,
|
|||
}
|
||||
}
|
||||
// Finally, check UserPosition
|
||||
// Note, as of 2011-08-01, this should no longer be necessecary.
|
||||
/*
|
||||
double userLatitude = fgGetDouble("/position/latitude-deg");
|
||||
double userLongitude = fgGetDouble("/position/longitude-deg");
|
||||
SGGeod user(SGGeod::fromDeg(userLongitude, userLatitude));
|
||||
|
@ -742,7 +763,7 @@ void FGGroundNetwork::checkSpeedAdjustment(int id, double lat,
|
|||
minbearing = bearing;
|
||||
otherReasonToSlowDown = true;
|
||||
}
|
||||
|
||||
*/
|
||||
current->clearSpeedAdjustment();
|
||||
|
||||
if (current->checkPositionAndIntentions(*closest)
|
||||
|
@ -755,11 +776,18 @@ void FGGroundNetwork::checkSpeedAdjustment(int id, double lat,
|
|||
return;
|
||||
else
|
||||
current->setWaitsForId(closest->getId());
|
||||
if (closest->getId() != current->getId())
|
||||
if (closest->getId() != current->getId()) {
|
||||
current->setSpeedAdjustment(closest->getSpeed() *
|
||||
(mindist / 100));
|
||||
else
|
||||
if (
|
||||
closest->getAircraft()->getTakeOffStatus() &&
|
||||
(current->getAircraft()->getTrafficRef()->getDepartureAirport() == closest->getAircraft()->getTrafficRef()->getDepartureAirport()) &&
|
||||
(current->getAircraft()->GetFlightPlan()->getRunway() == closest->getAircraft()->GetFlightPlan()->getRunway())
|
||||
)
|
||||
current->getAircraft()->scheduleForATCTowerDepartureControl(1);
|
||||
} else {
|
||||
current->setSpeedAdjustment(0); // This can only happen when the user aircraft is the one closest
|
||||
}
|
||||
if (mindist < maxAllowableDistance) {
|
||||
//double newSpeed = (maxAllowableDistance-mindist);
|
||||
//current->setSpeedAdjustment(newSpeed);
|
||||
|
@ -860,8 +888,10 @@ void FGGroundNetwork::checkHoldPosition(int id, double lat,
|
|||
//(!(current->getSpeedAdjustment())))
|
||||
|
||||
{
|
||||
current->setHoldPosition(true);
|
||||
current->setWaitsForId(i->getId());
|
||||
if (!(isUserAircraft(i->getAircraft()))) { // test code. Don't wait for the user, let the user wait for you.
|
||||
current->setHoldPosition(true);
|
||||
current->setWaitsForId(i->getId());
|
||||
}
|
||||
//cerr << "Hold check 5: " << current->getCallSign() <<" Setting Hold Position: distance to node (" << node << ") "
|
||||
// << dist << " meters. Waiting for " << i->getCallSign();
|
||||
//if (opposing)
|
||||
|
@ -879,31 +909,37 @@ void FGGroundNetwork::checkHoldPosition(int id, double lat,
|
|||
}
|
||||
}
|
||||
bool currStatus = current->hasHoldPosition();
|
||||
|
||||
current->setHoldPosition(origStatus);
|
||||
// Either a Hold Position or a resume taxi transmission has been issued
|
||||
time_t now = time(NULL) + fgGetLong("/sim/time/warp");
|
||||
if ((now - lastTransmission) > 2) {
|
||||
available = true;
|
||||
}
|
||||
if ((origStatus != currStatus) && available) {
|
||||
//cerr << "Issueing hold short instrudtion " << currStatus << " " << available << endl;
|
||||
if (currStatus == true) { // No has a hold short instruction
|
||||
transmit(&(*current), MSG_HOLD_POSITION, ATC_GROUND_TO_AIR, true);
|
||||
//cerr << "Transmittin hold short instrudtion " << currStatus << " " << available << endl;
|
||||
current->setState(1);
|
||||
} else {
|
||||
transmit(&(*current), MSG_RESUME_TAXI, ATC_GROUND_TO_AIR, true);
|
||||
//cerr << "Transmittig resume instrudtion " << currStatus << " " << available << endl;
|
||||
current->setState(2);
|
||||
if (current->getState() == 0) {
|
||||
if ((origStatus != currStatus) && available) {
|
||||
//cerr << "Issueing hold short instrudtion " << currStatus << " " << available << endl;
|
||||
if (currStatus == true) { // No has a hold short instruction
|
||||
transmit(&(*current), MSG_HOLD_POSITION, ATC_GROUND_TO_AIR, true);
|
||||
//cerr << "Transmittin hold short instrudtion " << currStatus << " " << available << endl;
|
||||
current->setState(1);
|
||||
} else {
|
||||
transmit(&(*current), MSG_RESUME_TAXI, ATC_GROUND_TO_AIR, true);
|
||||
//cerr << "Transmittig resume instrudtion " << currStatus << " " << available << endl;
|
||||
current->setState(2);
|
||||
}
|
||||
lastTransmission = now;
|
||||
available = false;
|
||||
// Don't act on the changed instruction until the transmission is confirmed
|
||||
// So set back to original status
|
||||
//cerr << "Current state " << current->getState() << endl;
|
||||
}
|
||||
lastTransmission = now;
|
||||
available = false;
|
||||
// Don't act on the changed instruction until the transmission is confirmed
|
||||
// So set back to original status
|
||||
current->setHoldPosition(origStatus);
|
||||
//cerr << "Current state " << current->getState() << endl;
|
||||
} else {
|
||||
|
||||
}
|
||||
// 6 = Report runway
|
||||
// 7 = Acknowledge report runway
|
||||
// 8 = Switch tower frequency
|
||||
//9 = Acknowledge switch tower frequency
|
||||
|
||||
//int state = current->getState();
|
||||
if (checkTransmissionState(1,1, current, now, MSG_ACKNOWLEDGE_HOLD_POSITION, ATC_AIR_TO_GROUND)) {
|
||||
current->setState(0);
|
||||
|
@ -913,24 +949,22 @@ void FGGroundNetwork::checkHoldPosition(int id, double lat,
|
|||
current->setState(0);
|
||||
current->setHoldPosition(false);
|
||||
}
|
||||
|
||||
/*if ((state == 1) && (available)) {
|
||||
//cerr << "ACKNOWLEDGE HOLD" << endl;
|
||||
transmit(&(*current), MSG_ACKNOWLEDGE_HOLD_POSITION, ATC_AIR_TO_GROUND, true);
|
||||
current->setState(0);
|
||||
current->setHoldPosition(true);
|
||||
lastTransmission = now;
|
||||
available = false;
|
||||
|
||||
if (current->getAircraft()->getTakeOffStatus() && (current->getState() == 0)) {
|
||||
//cerr << "Scheduling " << current->getAircraft()->getCallSign() << " for hold short" << endl;
|
||||
current->setState(6);
|
||||
}
|
||||
if (checkTransmissionState(6,6, current, now, MSG_REPORT_RUNWAY_HOLD_SHORT, ATC_AIR_TO_GROUND)) {
|
||||
}
|
||||
if ((state == 2) && (available)) {
|
||||
//cerr << "ACKNOWLEDGE RESUME" << endl;
|
||||
transmit(&(*current), MSG_ACKNOWLEDGE_RESUME_TAXI, ATC_AIR_TO_GROUND, true);
|
||||
current->setState(0);
|
||||
current->setHoldPosition(false);
|
||||
lastTransmission = now;
|
||||
available = false;
|
||||
}*/
|
||||
if (checkTransmissionState(7,7, current, now, MSG_ACKNOWLEDGE_REPORT_RUNWAY_HOLD_SHORT, ATC_GROUND_TO_AIR)) {
|
||||
}
|
||||
if (checkTransmissionState(8,8, current, now, MSG_SWITCH_TOWER_FREQUENCY, ATC_GROUND_TO_AIR)) {
|
||||
}
|
||||
if (checkTransmissionState(9,9, current, now, MSG_ACKNOWLEDGE_SWITCH_TOWER_FREQUENCY, ATC_AIR_TO_GROUND)) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
//current->setState(0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1208,4 +1242,8 @@ void FGGroundNetwork::render(bool visible)
|
|||
}
|
||||
globals->get_scenery()->get_scene_graph()->addChild(group);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string FGGroundNetwork::getName() {
|
||||
return string(parent->getId() + "-ground");
|
||||
}
|
||||
|
|
|
@ -212,6 +212,8 @@ public:
|
|||
|
||||
void first() { currNode = nodes.begin(); currRoute = routes.begin(); };
|
||||
int size() { return nodes.size(); };
|
||||
int nodesLeft() { return nodes.end() - currNode; };
|
||||
|
||||
// int getDepth() { return depth; };
|
||||
};
|
||||
|
||||
|
@ -288,6 +290,7 @@ public:
|
|||
AtcMsgDir msgDir);
|
||||
bool checkForCircularWaits(int id);
|
||||
virtual void render(bool);
|
||||
virtual string getName();
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -73,23 +73,25 @@ void FGSidStar::load(SGPath filename) {
|
|||
fp->setName(name);
|
||||
SGPropertyNode * wpts_node = fpl_node->getNode("wpts");
|
||||
for (int j = 0; j < wpts_node->nChildren(); j++) {
|
||||
FGAIFlightPlan::waypoint* wpt = new FGAIFlightPlan::waypoint;
|
||||
FGAIWaypoint* wpt = new FGAIWaypoint;
|
||||
SGPropertyNode * wpt_node = wpts_node->getChild(j);
|
||||
//cerr << "Reading waypoint " << j << wpt_node->getStringValue("name", "END") << endl;
|
||||
wpt->name = wpt_node->getStringValue("name", "END");
|
||||
wpt->latitude = wpt_node->getDoubleValue("lat", 0);
|
||||
wpt->longitude = wpt_node->getDoubleValue("lon", 0);
|
||||
wpt->altitude = wpt_node->getDoubleValue("alt", 0);
|
||||
wpt->speed = wpt_node->getDoubleValue("ktas", 0);
|
||||
wpt->crossat = wpt_node->getDoubleValue("crossat", -10000);
|
||||
wpt->gear_down = wpt_node->getBoolValue("gear-down", false);
|
||||
wpt->flaps_down= wpt_node->getBoolValue("flaps-down", false);
|
||||
wpt->on_ground = wpt_node->getBoolValue("on-ground", false);
|
||||
wpt->time_sec = wpt_node->getDoubleValue("time-sec", 0);
|
||||
wpt->time = wpt_node->getStringValue("time", "");
|
||||
wpt->setName (wpt_node->getStringValue("name", "END"));
|
||||
wpt->setLatitude (wpt_node->getDoubleValue("lat", 0));
|
||||
wpt->setLongitude (wpt_node->getDoubleValue("lon", 0));
|
||||
wpt->setAltitude (wpt_node->getDoubleValue("alt", 0));
|
||||
wpt->setSpeed (wpt_node->getDoubleValue("ktas", 0));
|
||||
wpt->setCrossat (wpt_node->getDoubleValue("crossat", -10000));
|
||||
wpt->setGear_down (wpt_node->getBoolValue("gear-down", false));
|
||||
wpt->setFlaps_down (wpt_node->getBoolValue("flaps-down", false));
|
||||
wpt->setOn_ground (wpt_node->getBoolValue("on-ground", false));
|
||||
wpt->setTime_sec (wpt_node->getDoubleValue("time-sec", 0));
|
||||
wpt->setTime (wpt_node->getStringValue("time", ""));
|
||||
|
||||
if (wpt->name == "END") wpt->finished = true;
|
||||
else wpt->finished = false;
|
||||
if (wpt->contains("END"))
|
||||
wpt->setFinished(true);
|
||||
else
|
||||
wpt->setFinished(false);
|
||||
|
||||
//
|
||||
fp->addWaypoint( wpt );
|
||||
|
|
Loading…
Reference in a new issue