AITraffic exits the runway as soon as possible (in theory; the code still needs some fine tuning).
This commit is contained in:
parent
ed30b0c9a3
commit
da3c098a4b
10 changed files with 152 additions and 17 deletions
|
@ -805,7 +805,7 @@ bool FGAIAircraft::leadPointReached(FGAIWaypoint* curr) {
|
||||||
// << lead_dist << " " << curr->name
|
// << lead_dist << " " << curr->name
|
||||||
// << " Ground target speed " << groundTargetSpeed << endl;
|
// << " Ground target speed " << groundTargetSpeed << endl;
|
||||||
double bearing = 0;
|
double bearing = 0;
|
||||||
if (speed > 50) { // don't do bearing calculations for ground traffic
|
// don't do bearing calculations for ground traffic
|
||||||
bearing = getBearing(fp->getBearing(pos.getLatitudeDeg(), pos.getLongitudeDeg(), curr));
|
bearing = getBearing(fp->getBearing(pos.getLatitudeDeg(), pos.getLongitudeDeg(), curr));
|
||||||
if (bearing < minBearing) {
|
if (bearing < minBearing) {
|
||||||
minBearing = bearing;
|
minBearing = bearing;
|
||||||
|
@ -817,8 +817,7 @@ bool FGAIAircraft::leadPointReached(FGAIWaypoint* curr) {
|
||||||
} else {
|
} else {
|
||||||
speedFraction = 1.0;
|
speedFraction = 1.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (trafficRef) {
|
if (trafficRef) {
|
||||||
//cerr << "Tracking callsign : \"" << fgGetString("/ai/track-callsign") << "\"" << endl;
|
//cerr << "Tracking callsign : \"" << fgGetString("/ai/track-callsign") << "\"" << endl;
|
||||||
/* if (trafficRef->getCallSign() == fgGetString("/ai/track-callsign")) {
|
/* if (trafficRef->getCallSign() == fgGetString("/ai/track-callsign")) {
|
||||||
|
@ -826,11 +825,14 @@ bool FGAIAircraft::leadPointReached(FGAIWaypoint* curr) {
|
||||||
<< _getAltitude() << " "<< _getLatitude() << " " << _getLongitude() << " " << dist_to_go << " " << lead_dist << " " << curr->name << " " << vs << " " << tgt_vs << " " << bearing << " " << minBearing << " " << speedFraction << endl;
|
<< _getAltitude() << " "<< _getLatitude() << " " << _getLongitude() << " " << dist_to_go << " " << lead_dist << " " << curr->name << " " << vs << " " << tgt_vs << " " << bearing << " " << minBearing << " " << speedFraction << endl;
|
||||||
}*/
|
}*/
|
||||||
}
|
}
|
||||||
if ((dist_to_go < lead_dist) || (bearing > (minBearing * 1.1))) {
|
if ((dist_to_go < lead_dist) ||
|
||||||
|
((dist_to_go > prev_dist_to_go) && (bearing > (minBearing * 1.1))) ) {
|
||||||
minBearing = 360;
|
minBearing = 360;
|
||||||
speedFraction = 1.0;
|
speedFraction = 1.0;
|
||||||
|
prev_dist_to_go = HUGE_VAL;
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
|
prev_dist_to_go = dist_to_go;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -880,6 +882,11 @@ bool FGAIAircraft::handleAirportEndPoints(FGAIWaypoint* prev, time_t now) {
|
||||||
if (prev->contains(string("Accel"))) {
|
if (prev->contains(string("Accel"))) {
|
||||||
takeOffStatus = 3;
|
takeOffStatus = 3;
|
||||||
}
|
}
|
||||||
|
//if (prev->contains(string("landing"))) {
|
||||||
|
// if (speed < _performance->vTaxi() * 2) {
|
||||||
|
// fp->shortenToFirst(2, "legend");
|
||||||
|
// }
|
||||||
|
//}
|
||||||
/*if (prev->contains(string("final"))) {
|
/*if (prev->contains(string("final"))) {
|
||||||
|
|
||||||
cerr << getCallSign() << " "
|
cerr << getCallSign() << " "
|
||||||
|
@ -1114,6 +1121,9 @@ void FGAIAircraft::updateHeading() {
|
||||||
// << hdg << ". Target " << tgt_heading << ". Diff " << fabs(sum - tgt_heading) << ". Speed " << speed << "Heading change rate : " << headingChangeRate << " bacnk sence " << bank_sense << endl;
|
// << hdg << ". Target " << tgt_heading << ". Diff " << fabs(sum - tgt_heading) << ". Speed " << speed << "Heading change rate : " << headingChangeRate << " bacnk sence " << bank_sense << endl;
|
||||||
hdg += headingChangeRate * dt * sqrt(fabs(speed) / 15);
|
hdg += headingChangeRate * dt * sqrt(fabs(speed) / 15);
|
||||||
headingError = headingDiff;
|
headingError = headingDiff;
|
||||||
|
if (fabs(headingError) < 1.0) {
|
||||||
|
hdg = tgt_heading;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (fabs(speed) > 1.0) {
|
if (fabs(speed) > 1.0) {
|
||||||
turn_radius_ft = 0.088362 * speed * speed
|
turn_radius_ft = 0.088362 * speed * speed
|
||||||
|
|
|
@ -409,9 +409,18 @@ void FGAIFlightPlan::DecrementWaypoint(bool eraseWaypoints )
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
wpt_iterator--;
|
wpt_iterator--;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FGAIFlightPlan::eraseLastWaypoint()
|
||||||
|
{
|
||||||
|
delete (waypoints.back());
|
||||||
|
waypoints.pop_back();;
|
||||||
|
wpt_iterator = waypoints.begin();
|
||||||
|
wpt_iterator++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 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, FGAIWaypoint* wp) const{
|
double FGAIFlightPlan::getDistanceToGo(double lat, double lon, FGAIWaypoint* wp) const{
|
||||||
|
@ -545,4 +554,12 @@ double FGAIFlightPlan::checkTrackLength(string wptName) {
|
||||||
trackDistance = 0; // name not found
|
trackDistance = 0; // name not found
|
||||||
}
|
}
|
||||||
return trackDistance;
|
return trackDistance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FGAIFlightPlan::shortenToFirst(unsigned int number, string name)
|
||||||
|
{
|
||||||
|
while (waypoints.size() > number + 3) {
|
||||||
|
eraseLastWaypoint();
|
||||||
|
}
|
||||||
|
(waypoints.back())->setName((waypoints.back())->getName() + name);
|
||||||
|
}
|
||||||
|
|
|
@ -164,6 +164,8 @@ public:
|
||||||
FGAIFlightPlan* getSID() { return sid; };
|
FGAIFlightPlan* getSID() { return sid; };
|
||||||
FGAIWaypoint *getWayPoint(int i) { return waypoints[i]; };
|
FGAIWaypoint *getWayPoint(int i) { return waypoints[i]; };
|
||||||
FGAIWaypoint *getLastWaypoint() { return waypoints.back(); };
|
FGAIWaypoint *getLastWaypoint() { return waypoints.back(); };
|
||||||
|
|
||||||
|
void shortenToFirst(unsigned int number, std::string name);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FGAIFlightPlan *sid;
|
FGAIFlightPlan *sid;
|
||||||
|
@ -195,6 +197,7 @@ private:
|
||||||
bool createParking(FGAIAircraft *, FGAirport *, double radius);
|
bool createParking(FGAIAircraft *, FGAirport *, double radius);
|
||||||
void deleteWaypoints();
|
void deleteWaypoints();
|
||||||
void resetWaypoints();
|
void resetWaypoints();
|
||||||
|
void eraseLastWaypoint();
|
||||||
|
|
||||||
bool createLandingTaxi(FGAIAircraft *, FGAirport *apt, double radius, const std::string& fltType, const std::string& acType, const std::string& airline);
|
bool createLandingTaxi(FGAIAircraft *, FGAirport *apt, double radius, const std::string& fltType, const std::string& acType, const std::string& airline);
|
||||||
void createDefaultLandingTaxi(FGAIAircraft *, FGAirport* aAirport);
|
void createDefaultLandingTaxi(FGAIAircraft *, FGAirport* aAirport);
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
|
|
||||||
#include <Environment/environment_mgr.hxx>
|
#include <Environment/environment_mgr.hxx>
|
||||||
#include <Environment/environment.hxx>
|
#include <Environment/environment.hxx>
|
||||||
|
#include <FDM/LaRCsim/basic_aero.h>
|
||||||
|
|
||||||
|
|
||||||
/* FGAIFlightPlan::create()
|
/* FGAIFlightPlan::create()
|
||||||
|
@ -242,7 +243,12 @@ bool FGAIFlightPlan::createTakeoffTaxi(FGAIAircraft * ac, bool firstFlight,
|
||||||
}
|
}
|
||||||
|
|
||||||
intVec ids;
|
intVec ids;
|
||||||
int runwayId = gn->findNearestNode(runwayTakeoff);
|
int runwayId = 0;
|
||||||
|
if (gn->getVersion() > 0) {
|
||||||
|
runwayId = gn->findNearestNodeOnRunway(runwayTakeoff);
|
||||||
|
} else {
|
||||||
|
runwayId = gn->findNearestNode(runwayTakeoff);
|
||||||
|
}
|
||||||
|
|
||||||
// A negative gateId indicates an overflow parking, use a
|
// A negative gateId indicates an overflow parking, use a
|
||||||
// fallback mechanism for this.
|
// fallback mechanism for this.
|
||||||
|
@ -379,7 +385,13 @@ bool FGAIFlightPlan::createLandingTaxi(FGAIAircraft * ac, FGAirport * apt,
|
||||||
}
|
}
|
||||||
|
|
||||||
intVec ids;
|
intVec ids;
|
||||||
int runwayId = gn->findNearestNode(lastWptPos);
|
int runwayId = 0;
|
||||||
|
if (gn->getVersion() == 1) {
|
||||||
|
runwayId = gn->findNearestNodeOnRunway(lastWptPos);
|
||||||
|
} else {
|
||||||
|
runwayId = gn->findNearestNode(lastWptPos);
|
||||||
|
}
|
||||||
|
//cerr << "Using network node " << runwayId << endl;
|
||||||
// A negative gateId indicates an overflow parking, use a
|
// A negative gateId indicates an overflow parking, use a
|
||||||
// fallback mechanism for this.
|
// fallback mechanism for this.
|
||||||
// Starting from gate 0 is a bit of a hack...
|
// Starting from gate 0 is a bit of a hack...
|
||||||
|
@ -878,7 +890,12 @@ bool FGAIFlightPlan::createLanding(FGAIAircraft * ac, FGAirport * apt,
|
||||||
const string & fltType)
|
const string & fltType)
|
||||||
{
|
{
|
||||||
double vTouchdown = ac->getPerformance()->vTouchdown();
|
double vTouchdown = ac->getPerformance()->vTouchdown();
|
||||||
//double vTaxi = ac->getPerformance()->vTaxi();
|
double vTaxi = ac->getPerformance()->vTaxi();
|
||||||
|
double decel = ac->getPerformance()->deceleration() * 1.5;
|
||||||
|
|
||||||
|
double vTouchdownMetric = (vTouchdown * SG_NM_TO_METER) / 3600;
|
||||||
|
double vTaxiMetric = (vTaxi * SG_NM_TO_METER) / 3600;
|
||||||
|
double decelMetric = (decel * SG_NM_TO_METER) / 3600;
|
||||||
|
|
||||||
//string rwyClass = getRunwayClassFromTrafficType(fltType);
|
//string rwyClass = getRunwayClassFromTrafficType(fltType);
|
||||||
//double heading = ac->getTrafficRef()->getCourse();
|
//double heading = ac->getTrafficRef()->getCourse();
|
||||||
|
@ -917,15 +934,50 @@ bool FGAIFlightPlan::createLanding(FGAIAircraft * ac, FGAirport * apt,
|
||||||
coord = rwy->pointOnCenterline((currentDist * (i / nPoints)));
|
coord = rwy->pointOnCenterline((currentDist * (i / nPoints)));
|
||||||
wpt = createInAir(ac, buffer, coord, currentAltitude, (vTouchdown));
|
wpt = createInAir(ac, buffer, coord, currentAltitude, (vTouchdown));
|
||||||
}*/
|
}*/
|
||||||
|
double rolloutDistance =
|
||||||
for (int i = 1; i < 10; i++) {
|
(vTouchdownMetric * vTouchdownMetric - vTaxiMetric * vTaxiMetric) / (2 * decelMetric);
|
||||||
snprintf(buffer, 12, "wpt%d", i);
|
//cerr << " touchdown speed = " << vTouchdown << ". Rollout distance " << rolloutDistance << endl;
|
||||||
|
int nPoints = 50;
|
||||||
|
for (int i = 1; i < nPoints; i++) {
|
||||||
|
snprintf(buffer, 12, "landing03%d", i);
|
||||||
|
|
||||||
coord = rwy->pointOnCenterline((rwy->lengthM() * 0.9) * (i / 10.0));
|
coord = rwy->pointOnCenterline((rolloutDistance * ((double) i / (double) nPoints)));
|
||||||
wpt = createOnGround(ac, buffer, coord, currElev, (vTouchdown / i));
|
wpt = createOnGround(ac, buffer, coord, currElev, vTaxi);
|
||||||
wpt->setCrossat(apt->getElevation());
|
wpt->setCrossat(currElev);
|
||||||
waypoints.push_back(wpt);
|
waypoints.push_back(wpt);
|
||||||
}
|
}
|
||||||
|
double mindist = 1.1 * rolloutDistance;
|
||||||
|
double maxdist = rwy->lengthM();
|
||||||
|
//cerr << "Finding nearest exit" << endl;
|
||||||
|
FGGroundNetwork *gn = apt->getDynamics()->getGroundNetwork();
|
||||||
|
if (gn) {
|
||||||
|
double min = 0;
|
||||||
|
for (int i = ceil(mindist); i < floor(maxdist); i++) {
|
||||||
|
coord = rwy->pointOnCenterline(mindist);
|
||||||
|
int nodeId = 0;
|
||||||
|
if (gn->getVersion() > 0) {
|
||||||
|
nodeId = gn->findNearestNodeOnRunway(coord);
|
||||||
|
} else {
|
||||||
|
nodeId = gn->findNearestNode(coord);
|
||||||
|
}
|
||||||
|
if (tn)
|
||||||
|
tn = gn->findNode(nodeId);
|
||||||
|
else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
double dist = SGGeodesy::distanceM(coord, tn->getGeod());
|
||||||
|
if (dist < (min + 0.75)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
min = dist;
|
||||||
|
}
|
||||||
|
if (tn) {
|
||||||
|
wpt = createOnGround(ac, buffer, tn->getGeod(), currElev, vTaxi);
|
||||||
|
waypoints.push_back(wpt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cerr << "Done. " << endl;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
//Runway Threshold
|
//Runway Threshold
|
||||||
|
|
|
@ -43,6 +43,7 @@ public:
|
||||||
inline double vRotate () { return _vRotate; };
|
inline double vRotate () { return _vRotate; };
|
||||||
inline double maximumBankAngle () { return _maxbank; };
|
inline double maximumBankAngle () { return _maxbank; };
|
||||||
inline double acceleration () { return _acceleration; };
|
inline double acceleration () { return _acceleration; };
|
||||||
|
inline double deceleration () { return _deceleration; };
|
||||||
inline double vTaxi () { return _vTaxi; };
|
inline double vTaxi () { return _vTaxi; };
|
||||||
inline double vTakeoff () { return _vTakeOff; };
|
inline double vTakeoff () { return _vTakeOff; };
|
||||||
inline double vClimb () { return _vClimb; };
|
inline double vClimb () { return _vClimb; };
|
||||||
|
|
|
@ -146,6 +146,10 @@ void FGAirportDynamicsXMLLoader::startElement (const char * name, const XMLAttr
|
||||||
|
|
||||||
void FGAirportDynamicsXMLLoader::endElement (const char * name) {
|
void FGAirportDynamicsXMLLoader::endElement (const char * name) {
|
||||||
//cout << "End element " << name << endl;
|
//cout << "End element " << name << endl;
|
||||||
|
if (name == string("version")) {
|
||||||
|
_dynamics->getGroundNetwork()->addVersion(atoi(value.c_str()));
|
||||||
|
//std::cerr << "version" << value<< std::endl;
|
||||||
|
}
|
||||||
if (name == string("AWOS")) {
|
if (name == string("AWOS")) {
|
||||||
_dynamics->addAwosFreq(atoi(value.c_str()));
|
_dynamics->addAwosFreq(atoi(value.c_str()));
|
||||||
//cerr << "Adding AWOS" << value<< endl;
|
//cerr << "Adding AWOS" << value<< endl;
|
||||||
|
|
|
@ -220,6 +220,7 @@ FGGroundNetwork::FGGroundNetwork()
|
||||||
count = 0;
|
count = 0;
|
||||||
currTraffic = activeTraffic.begin();
|
currTraffic = activeTraffic.begin();
|
||||||
group = 0;
|
group = 0;
|
||||||
|
version = 0;
|
||||||
networkInitialized = false;
|
networkInitialized = false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -452,6 +453,28 @@ int FGGroundNetwork::findNearestNode(const SGGeod & aGeod)
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int FGGroundNetwork::findNearestNodeOnRunway(const SGGeod & aGeod)
|
||||||
|
{
|
||||||
|
double minDist = HUGE_VAL;
|
||||||
|
int index = -1;
|
||||||
|
|
||||||
|
for (FGTaxiNodeVectorIterator itr = nodes.begin(); itr != nodes.end();
|
||||||
|
itr++) {
|
||||||
|
if (!((*itr)->getIsOnRunway())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
double d = SGGeodesy::distanceM(aGeod, (*itr)->getGeod());
|
||||||
|
if (d < minDist) {
|
||||||
|
minDist = d;
|
||||||
|
index = (*itr)->getIndex();
|
||||||
|
//cerr << "Minimum distance of " << minDist << " for index " << index << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int FGGroundNetwork::findNearestNode(double lat, double lon)
|
int FGGroundNetwork::findNearestNode(double lat, double lon)
|
||||||
{
|
{
|
||||||
return findNearestNode(SGGeod::fromDeg(lon, lat));
|
return findNearestNode(SGGeod::fromDeg(lon, lat));
|
||||||
|
|
|
@ -292,6 +292,7 @@ private:
|
||||||
time_t nextSave;
|
time_t nextSave;
|
||||||
//int maxDepth;
|
//int maxDepth;
|
||||||
int count;
|
int count;
|
||||||
|
int version;
|
||||||
FGTaxiNodeVector nodes;
|
FGTaxiNodeVector nodes;
|
||||||
FGTaxiNodeVector pushBackNodes;
|
FGTaxiNodeVector pushBackNodes;
|
||||||
FGTaxiSegmentVector segments;
|
FGTaxiSegmentVector segments;
|
||||||
|
@ -324,6 +325,9 @@ public:
|
||||||
void addNode (const FGTaxiNode& node);
|
void addNode (const FGTaxiNode& node);
|
||||||
void addNodes (FGParkingVec *parkings);
|
void addNodes (FGParkingVec *parkings);
|
||||||
void addSegment(const FGTaxiSegment& seg);
|
void addSegment(const FGTaxiSegment& seg);
|
||||||
|
void setVersion (int v) { version = v;};
|
||||||
|
|
||||||
|
int getVersion() { return version; };
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
bool exists() {
|
bool exists() {
|
||||||
|
@ -335,6 +339,7 @@ public:
|
||||||
|
|
||||||
int findNearestNode(double lat, double lon);
|
int findNearestNode(double lat, double lon);
|
||||||
int findNearestNode(const SGGeod& aGeod);
|
int findNearestNode(const SGGeod& aGeod);
|
||||||
|
int findNearestNodeOnRunway(const SGGeod& aGeod);
|
||||||
|
|
||||||
FGTaxiNode *findNode(unsigned idx);
|
FGTaxiNode *findNode(unsigned idx);
|
||||||
FGTaxiSegment *findSegment(unsigned idx);
|
FGTaxiSegment *findSegment(unsigned idx);
|
||||||
|
@ -365,6 +370,7 @@ public:
|
||||||
virtual void update(double dt);
|
virtual void update(double dt);
|
||||||
|
|
||||||
void saveElevationCache();
|
void saveElevationCache();
|
||||||
|
void addVersion(int v) {version = v; };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -423,7 +423,7 @@ void FGAISchedule::scheduleFlights(time_t now)
|
||||||
<< " " << arrT << ":");
|
<< " " << arrT << ":");
|
||||||
|
|
||||||
flights.push_back(flight);
|
flights.push_back(flight);
|
||||||
} while (1); //(currentDestination != startingPort);
|
} while (currentDestination != startingPort);
|
||||||
SG_LOG(SG_GENERAL, SG_BULK, " Done ");
|
SG_LOG(SG_GENERAL, SG_BULK, " Done ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -507,7 +507,8 @@ FGScheduledFlight* FGAISchedule::findAvailableFlight (const string ¤tDesti
|
||||||
}
|
}
|
||||||
if (flights.size()) {
|
if (flights.size()) {
|
||||||
time_t arrival = flights.back()->getArrivalTime();
|
time_t arrival = flights.back()->getArrivalTime();
|
||||||
if ((*i)->getDepartureTime() < (arrival+(20*60)))
|
int groundTime = groundTimeFromRadius();
|
||||||
|
if ((*i)->getDepartureTime() < (arrival+(groundTime)))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (min != 0) {
|
if (min != 0) {
|
||||||
|
@ -531,6 +532,23 @@ FGScheduledFlight* FGAISchedule::findAvailableFlight (const string ¤tDesti
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int FGAISchedule::groundTimeFromRadius()
|
||||||
|
{
|
||||||
|
if (radius < 10)
|
||||||
|
return 15 * 60;
|
||||||
|
else if (radius < 15)
|
||||||
|
return 20 * 60;
|
||||||
|
else if (radius < 20)
|
||||||
|
return 30 * 60;
|
||||||
|
else if (radius < 25)
|
||||||
|
return 50 * 60;
|
||||||
|
else if (radius < 30)
|
||||||
|
return 90 * 60;
|
||||||
|
else
|
||||||
|
return 120 * 60;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
double FGAISchedule::getSpeed()
|
double FGAISchedule::getSpeed()
|
||||||
{
|
{
|
||||||
FGScheduledFlightVecIterator i = flights.begin();
|
FGScheduledFlightVecIterator i = flights.begin();
|
||||||
|
|
|
@ -63,6 +63,7 @@ class FGAISchedule
|
||||||
bool valid;
|
bool valid;
|
||||||
|
|
||||||
void scheduleFlights(time_t now);
|
void scheduleFlights(time_t now);
|
||||||
|
int groundTimeFromRadius();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transition this schedule from distant mode to AI mode;
|
* Transition this schedule from distant mode to AI mode;
|
||||||
|
|
Loading…
Add table
Reference in a new issue