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