258 lines
7.5 KiB
C++
258 lines
7.5 KiB
C++
|
/******************************************************************************
|
||
|
* 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 <stdlib.h>
|
||
|
#include <time.h>
|
||
|
#include <iostream>
|
||
|
#include <fstream>
|
||
|
|
||
|
|
||
|
#include <string>
|
||
|
#include <vector>
|
||
|
|
||
|
#include <plib/sg.h>
|
||
|
|
||
|
#include <simgear/compiler.h>
|
||
|
#include <simgear/math/polar3d.hxx>
|
||
|
#include <simgear/math/sg_geodesy.hxx>
|
||
|
#include <simgear/props/props.hxx>
|
||
|
#include <simgear/route/waypoint.hxx>
|
||
|
#include <simgear/structure/subsystem_mgr.hxx>
|
||
|
#include <simgear/timing/sg_time.hxx>
|
||
|
#include <simgear/xml/easyxml.hxx>
|
||
|
|
||
|
#include <AIModel/AIFlightPlan.hxx>
|
||
|
#include <AIModel/AIManager.hxx>
|
||
|
#include <Airports/simple.hxx>
|
||
|
#include <Main/fg_init.hxx> // That's pretty ugly, but I need fgFindAirportID
|
||
|
|
||
|
|
||
|
|
||
|
#include <Main/globals.hxx>
|
||
|
|
||
|
#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;
|
||
|
}
|