]> git.mxchange.org Git - flightgear.git/blob - src/ATC/tower.cxx
Start roughing in interactive tower control. AI planes now get the ground control...
[flightgear.git] / src / ATC / tower.cxx
1 // FGTower - a class to provide tower control at towered airports.
2 //
3 // Written by David Luff, started March 2002.
4 //
5 // Copyright (C) 2002  David C. Luff - david.luff@nottingham.ac.uk
6 //
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License as
9 // published by the Free Software Foundation; either version 2 of the
10 // License, or (at your option) any later version.
11 //
12 // This program is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 // General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21 #include <Main/globals.hxx>
22
23 #include "tower.hxx"
24 #include "ATCdisplay.hxx"
25 #include "ATCmgr.hxx"
26
27 // TowerPlaneRec
28
29 TowerPlaneRec::TowerPlaneRec() :
30 id("UNKNOWN"),
31 clearedToLand(false),
32 clearedToDepart(false),
33 longFinalReported(false),
34 longFinalAcknowledged(false),
35 finalReported(false),
36 finalAcknowledged(false)
37 {
38 }
39
40 TowerPlaneRec::TowerPlaneRec(string ID) :
41 clearedToLand(false),
42 clearedToDepart(false),
43 longFinalReported(false),
44 longFinalAcknowledged(false),
45 finalReported(false),
46 finalAcknowledged(false)
47 {
48         id = ID;
49 }
50
51 TowerPlaneRec::TowerPlaneRec(Point3D pt) :
52 id("UNKNOWN"),
53 clearedToLand(false),
54 clearedToDepart(false),
55 longFinalReported(false),
56 longFinalAcknowledged(false),
57 finalReported(false),
58 finalAcknowledged(false)
59 {
60         pos = pt;
61 }
62
63 TowerPlaneRec::TowerPlaneRec(string ID, Point3D pt) :
64 clearedToLand(false),
65 clearedToDepart(false),
66 longFinalReported(false),
67 longFinalAcknowledged(false),
68 finalReported(false),
69 finalAcknowledged(false)
70 {
71         id = ID;
72         pos = pt;
73 }
74
75
76 // FGTower
77
78 FGTower::FGTower() {
79         ATCmgr = globals->get_ATC_mgr();
80 }
81
82 FGTower::~FGTower() {
83         if(!separateGround) {
84                 delete ground;
85         }
86 }
87
88 void FGTower::Init() {
89     display = false;
90         
91         // Need some way to initialise rwyOccupied flag correctly if the user is on the runway and to know its the user.
92         // I'll punt the startup issue for now though!!!
93         rwyOccupied = false;
94         
95         // Setup the ground control at this airport
96         AirportATC a;
97         if(ATCmgr->GetAirportATCDetails(ident, &a)) {
98                 if(a.ground_freq) {             // Ground control
99                         ground = (FGGround*)ATCmgr->GetATCPointer(ident, GROUND);
100                         separateGround = true;
101                         if(ground == NULL) {
102                                 // Something has gone wrong :-(
103                                 cout << "ERROR - ground has frequency but can't get ground pointer :-(\n";
104                                 ground = new FGGround(ident);
105                                 separateGround = false;
106                                 ground->Init();
107                                 if(display) {
108                                         ground->SetDisplay();
109                                 } else {
110                                         ground->SetNoDisplay();
111                                 }
112                         }
113                 } else {
114                         // Initialise ground anyway to do the shortest path stuff!
115                         // Note that we're now responsible for updating and deleting this - NOT the ATCMgr.
116                         ground = new FGGround(ident);
117                         separateGround = false;
118                         ground->Init();
119                         if(display) {
120                                 ground->SetDisplay();
121                         } else {
122                                 ground->SetNoDisplay();
123                         }
124                 }
125         } else {
126                 //cout << "Unable to find airport details in FGTower::Init()\n";
127         }
128 }
129
130 void FGTower::Update() {
131     // Each time step, what do we need to do?
132     // We need to go through the list of outstanding requests and acknowedgements
133     // and process at least one of them.
134     // We need to go through the list of planes under our control and check if
135     // any need to be addressed.
136     // We need to check for planes not under our control coming within our 
137     // control area and address if necessary.
138
139         // TODO - a lot of the below probably doesn't need to be called every frame and should be staggered.
140         
141         // Sort the arriving planes
142
143         // Calculate the eta of each plane to the threshold.
144         // For ground traffic this is the fastest they can get there.
145         // For air traffic this is the middle approximation.
146         doThresholdETACalc();
147         
148         // Order the list of traffic as per expected threshold use and flag any conflicts
149         bool conflicts = doThresholdUseOrder();
150         
151         // sortConficts() !!!
152         
153         doCommunication();
154         
155         if(!separateGround) {
156                 // The display stuff might have to get more clever than this when not separate 
157                 // since the tower and ground might try communicating simultaneously even though
158                 // they're mean't to be the same contoller/frequency!!
159                 if(display) {
160                         ground->SetDisplay();
161                 } else {
162                         ground->SetNoDisplay();
163                 }
164                 ground->Update();
165         }
166 }
167
168 // Calculate the eta of each plane to the threshold.
169 // For ground traffic this is the fastest they can get there.
170 // For air traffic this is the middle approximation.
171 void FGTower::doThresholdETACalc() {
172         // For now we'll be very crude and hardwire expected speeds to C172-like values
173         double app_ias = 100.0;                 // Speed during straight-in approach
174         double circuit_ias = 80.0;              // Speed around circuit
175         double final_ias = 70.0;                // Speed during final approach
176
177         tower_plane_rec_list_iterator twrItr;
178
179         for(twrItr = trafficList.begin(); twrItr != trafficList.end(); twrItr++) {
180         }
181         
182 }
183
184 bool FGTower::doThresholdUseOrder() {
185         return(true);
186 }
187
188 void FGTower::doCommunication() {
189 }
190                 
191
192 void FGTower::RequestLandingClearance(string ID) {
193         cout << "Request Landing Clearance called...\n";
194 }
195 void FGTower::RequestDepartureClearance(string ID) {
196         cout << "Request Departure Clearance called...\n";
197 }       
198 //void FGTower::ReportFinal(string ID);
199 //void FGTower::ReportLongFinal(string ID);
200 //void FGTower::ReportOuterMarker(string ID);
201 //void FGTower::ReportMiddleMarker(string ID);
202 //void FGTower::ReportInnerMarker(string ID);
203 //void FGTower::ReportGoingAround(string ID);
204 void FGTower::ReportRunwayVacated(string ID) {
205         cout << "Report Runway Vacated Called...\n";
206 }