1 /******************************************************************************
3 * Written by Durk Talsma, started May 5, 2004.
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 **************************************************************************/
22 /* This a prototype version of a top-level flight plan manager for Flightgear.
23 * It parses the fgtraffic.txt file and determine for a specific time/date,
24 * where each aircraft listed in this file is at the current time.
26 * I'm currently assuming the following simplifications:
27 * 1) The earth is a perfect sphere
28 * 2) Each aircraft flies a perfect great circle route.
29 * 3) Each aircraft flies at a constant speed (with infinite accelerations and
31 * 4) Each aircraft leaves at exactly the departure time.
32 * 5) Each aircraft arrives at exactly the specified arrival time.
35 * - Check the code for known portability issues
36 * - Find an alternative for the depricated Point3D class
38 *****************************************************************************/
50 #include <simgear/compiler.h>
51 #include <simgear/math/polar3d.hxx>
52 #include <simgear/math/sg_geodesy.hxx>
53 #include <simgear/props/props.hxx>
54 #include <simgear/route/waypoint.hxx>
55 #include <simgear/structure/subsystem_mgr.hxx>
56 #include <simgear/timing/sg_time.hxx>
57 #include <simgear/xml/easyxml.hxx>
59 #include <AIModel/AIFlightPlan.hxx>
60 #include <AIModel/AIManager.hxx>
61 #include <Airports/simple.hxx>
62 #include <Main/fg_init.hxx> // That's pretty ugly, but I need fgFindAirportID
66 #include <Main/globals.hxx>
68 #include "SchedFlight.hxx"
71 /******************************************************************************
72 * FGScheduledFlight stuff
73 *****************************************************************************/
75 FGScheduledFlight::FGScheduledFlight()
79 FGScheduledFlight::FGScheduledFlight(const FGScheduledFlight &other)
81 callsign = other.callsign;
82 fltRules = other.fltRules;
83 departurePort = other.departurePort;
84 departureTime = other.departureTime;
85 cruiseAltitude = other.cruiseAltitude;
86 arrivalPort = other.arrivalPort;
87 arrivalTime = other.arrivalTime;
88 repeatPeriod = other.repeatPeriod;
89 initialized = other.initialized;
92 FGScheduledFlight::FGScheduledFlight(string cs,
103 departurePort.id = depPrt;
104 arrivalPort.id = arrPrt;
105 //departureTime = processTimeString(deptime);
106 //arrivalTime = processTimeString(arrtime);
107 cruiseAltitude = cruiseAlt;
109 // Process the repeat period string
110 if (rep.find("WEEK",0) != string::npos)
112 repeatPeriod = 7*24*60*60; // in seconds
114 else if (rep.find("Hr", 0) != string::npos)
116 repeatPeriod = 60*60*atoi(rep.substr(0,2).c_str());
120 cerr << "Unknown repeat period" << endl;
124 // What we still need to do is preprocess the departure and
126 departureTime = processTimeString(deptime);
127 arrivalTime = processTimeString(arrtime);
128 if (departureTime > arrivalTime)
130 departureTime -= repeatPeriod;
136 FGScheduledFlight:: ~FGScheduledFlight()
140 time_t FGScheduledFlight::processTimeString(string theTime)
143 int timeOffsetInDays;
150 SGTime* currTimeDate = globals->get_time_params();
152 string timeCopy = theTime;
155 // okay first split theTime string into
156 // weekday, hour, minute, second;
157 // Check if a week day is specified
158 if (timeCopy.find("/",0) != string::npos)
160 weekday = atoi(timeCopy.substr(0,1).c_str());
161 timeOffsetInDays = weekday - currTimeDate->getGmt()->tm_wday;
162 timeCopy = timeCopy.substr(2,timeCopy.length());
166 timeOffsetInDays = 0;
168 targetHour = atoi(timeCopy.substr(0,2).c_str());
169 targetMinute = atoi(timeCopy.substr(3,5).c_str());
170 targetSecond = atoi(timeCopy.substr(6,8).c_str());
171 targetTimeDate.tm_year = currTimeDate->getGmt()->tm_year;
172 targetTimeDate.tm_mon = currTimeDate->getGmt()->tm_mon;
173 targetTimeDate.tm_mday = currTimeDate->getGmt()->tm_mday;
174 targetTimeDate.tm_hour = targetHour;
175 targetTimeDate.tm_min = targetMinute;
176 targetTimeDate.tm_sec = targetSecond;
178 time_t processedTime = sgTimeGetGMT(&targetTimeDate);
179 processedTime += timeOffsetInDays*24*60*60;
180 if (processedTime < currTimeDate->get_cur_time())
182 processedTime += repeatPeriod;
184 //tm *temp = currTimeDate->getGmt();
186 //sgTimeFormatTime(&targetTimeDate, buffer);
187 //cout << "Scheduled Time " << buffer << endl;
188 //cout << "Time :" << time(NULL) << " SGTime : " << sgTimeGetGMT(temp) << endl;
189 return processedTime;
192 void FGScheduledFlight::update()
194 departureTime += repeatPeriod;
195 arrivalTime += repeatPeriod;
198 void FGScheduledFlight::adjustTime(time_t now)
200 //cerr << "1: Adjusting schedule please wait: " << now
201 // << " " << arrivalTime << " " << arrivalTime+repeatPeriod << endl;
202 // Make sure that the arrival time is in between
203 // the current time and the next repeat period.
204 while ((arrivalTime < now) || (arrivalTime > now+repeatPeriod))
206 if (arrivalTime < now)
208 departureTime += repeatPeriod;
209 arrivalTime += repeatPeriod;
211 else if (arrivalTime > now+repeatPeriod)
213 departureTime -= repeatPeriod;
214 arrivalTime -= repeatPeriod;
216 // cerr << "2: Adjusting schedule please wait: " << now
217 // << " " << arrivalTime << " " << arrivalTime+repeatPeriod << endl;
222 FGAirport *FGScheduledFlight::getDepartureAirport()
226 initializeAirports();
228 return &departurePort;
230 FGAirport * FGScheduledFlight::getArrivalAirport ()
234 initializeAirports();
239 // Upon the first time of requesting airport information
240 // for this scheduled flight, these data need to be
241 // looked up in the main FlightGear database.
242 // Missing or bogus Airport codes are currently ignored,
243 // but we should improve that. The best idea is probably to cancel
244 // this flight entirely by removing it from the schedule, if one
245 // of the airports cannot be found.
246 void FGScheduledFlight::initializeAirports()
248 if(!(fgFindAirportID(arrivalPort.id, &arrivalPort )))
250 //cerr << ": Could not find " << arrivalPort.id << endl;
252 if(!(fgFindAirportID(departurePort.id, &departurePort)))
254 //cerr << ": Could not find " << departurePort.id << endl;