/****************************************************************************** * SchedFlight.cxx * Written by Durk Talsma, started May 5, 2004. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * **************************************************************************/ /* This a prototype version of a top-level flight plan manager for Flightgear. * It parses the fgtraffic.txt file and determine for a specific time/date, * where each aircraft listed in this file is at the current time. * * I'm currently assuming the following simplifications: * 1) The earth is a perfect sphere * 2) Each aircraft flies a perfect great circle route. * 3) Each aircraft flies at a constant speed (with infinite accelerations and * decelerations) * 4) Each aircraft leaves at exactly the departure time. * 5) Each aircraft arrives at exactly the specified arrival time. * * TODO: * - Check the code for known portability issues * - Find an alternative for the depricated Point3D class * *****************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include
// That's pretty ugly, but I need fgFindAirportID #include
#include "SchedFlight.hxx" /****************************************************************************** * FGScheduledFlight stuff *****************************************************************************/ FGScheduledFlight::FGScheduledFlight() { } FGScheduledFlight::FGScheduledFlight(const FGScheduledFlight &other) { callsign = other.callsign; fltRules = other.fltRules; departurePort = other.departurePort; departureTime = other.departureTime; cruiseAltitude = other.cruiseAltitude; arrivalPort = other.arrivalPort; arrivalTime = other.arrivalTime; repeatPeriod = other.repeatPeriod; initialized = other.initialized; } FGScheduledFlight::FGScheduledFlight(string cs, string fr, string depPrt, string arrPrt, int cruiseAlt, string deptime, string arrtime, string rep) { callsign = cs; fltRules = fr; departurePort.id = depPrt; arrivalPort.id = arrPrt; //departureTime = processTimeString(deptime); //arrivalTime = processTimeString(arrtime); cruiseAltitude = cruiseAlt; // Process the repeat period string if (rep.find("WEEK",0) != string::npos) { repeatPeriod = 7*24*60*60; // in seconds } else if (rep.find("Hr", 0) != string::npos) { repeatPeriod = 60*60*atoi(rep.substr(0,2).c_str()); } else { cerr << "Unknown repeat period" << endl; exit(1); } // What we still need to do is preprocess the departure and // arrival times. departureTime = processTimeString(deptime); arrivalTime = processTimeString(arrtime); if (departureTime > arrivalTime) { departureTime -= repeatPeriod; } initialized = false; } FGScheduledFlight:: ~FGScheduledFlight() { } time_t FGScheduledFlight::processTimeString(string theTime) { int weekday; int timeOffsetInDays; int targetDate; int targetHour; int targetMinute; int targetSecond; tm targetTimeDate; SGTime* currTimeDate = globals->get_time_params(); string timeCopy = theTime; // okay first split theTime string into // weekday, hour, minute, second; // Check if a week day is specified if (timeCopy.find("/",0) != string::npos) { weekday = atoi(timeCopy.substr(0,1).c_str()); timeOffsetInDays = weekday - currTimeDate->getGmt()->tm_wday; timeCopy = timeCopy.substr(2,timeCopy.length()); } else { timeOffsetInDays = 0; } targetHour = atoi(timeCopy.substr(0,2).c_str()); targetMinute = atoi(timeCopy.substr(3,5).c_str()); targetSecond = atoi(timeCopy.substr(6,8).c_str()); targetTimeDate.tm_year = currTimeDate->getGmt()->tm_year; targetTimeDate.tm_mon = currTimeDate->getGmt()->tm_mon; targetTimeDate.tm_mday = currTimeDate->getGmt()->tm_mday; targetTimeDate.tm_hour = targetHour; targetTimeDate.tm_min = targetMinute; targetTimeDate.tm_sec = targetSecond; time_t processedTime = sgTimeGetGMT(&targetTimeDate); processedTime += timeOffsetInDays*24*60*60; if (processedTime < currTimeDate->get_cur_time()) { processedTime += repeatPeriod; } //tm *temp = currTimeDate->getGmt(); //char buffer[512]; //sgTimeFormatTime(&targetTimeDate, buffer); //cout << "Scheduled Time " << buffer << endl; //cout << "Time :" << time(NULL) << " SGTime : " << sgTimeGetGMT(temp) << endl; return processedTime; } void FGScheduledFlight::update() { departureTime += repeatPeriod; arrivalTime += repeatPeriod; } void FGScheduledFlight::adjustTime(time_t now) { //cerr << "1: Adjusting schedule please wait: " << now // << " " << arrivalTime << " " << arrivalTime+repeatPeriod << endl; // Make sure that the arrival time is in between // the current time and the next repeat period. while ((arrivalTime < now) || (arrivalTime > now+repeatPeriod)) { if (arrivalTime < now) { departureTime += repeatPeriod; arrivalTime += repeatPeriod; } else if (arrivalTime > now+repeatPeriod) { departureTime -= repeatPeriod; arrivalTime -= repeatPeriod; } // cerr << "2: Adjusting schedule please wait: " << now // << " " << arrivalTime << " " << arrivalTime+repeatPeriod << endl; } } FGAirport *FGScheduledFlight::getDepartureAirport() { if (!(initialized)) { initializeAirports(); } return &departurePort; } FGAirport * FGScheduledFlight::getArrivalAirport () { if (!(initialized)) { initializeAirports(); } return &arrivalPort; } // Upon the first time of requesting airport information // for this scheduled flight, these data need to be // looked up in the main FlightGear database. // Missing or bogus Airport codes are currently ignored, // but we should improve that. The best idea is probably to cancel // this flight entirely by removing it from the schedule, if one // of the airports cannot be found. void FGScheduledFlight::initializeAirports() { if(!(fgFindAirportID(arrivalPort.id, &arrivalPort ))) { //cerr << ": Could not find " << arrivalPort.id << endl; } if(!(fgFindAirportID(departurePort.id, &departurePort))) { //cerr << ": Could not find " << departurePort.id << endl; } initialized = true; }