]> git.mxchange.org Git - flightgear.git/blob - src/ATC/tower.cxx
Emergency fix of a possible dereference dangling pointer path uncovered by Martin...
[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 SG_USING_STD(cout);
28
29 // TowerPlaneRec
30
31 TowerPlaneRec::TowerPlaneRec() :
32 id("UNKNOWN"),
33 clearedToLand(false),
34 clearedToDepart(false),
35 longFinalReported(false),
36 longFinalAcknowledged(false),
37 finalReported(false),
38 finalAcknowledged(false)
39 {
40 }
41
42 TowerPlaneRec::TowerPlaneRec(string ID) :
43 clearedToLand(false),
44 clearedToDepart(false),
45 longFinalReported(false),
46 longFinalAcknowledged(false),
47 finalReported(false),
48 finalAcknowledged(false)
49 {
50         id = ID;
51 }
52
53 TowerPlaneRec::TowerPlaneRec(Point3D pt) :
54 id("UNKNOWN"),
55 clearedToLand(false),
56 clearedToDepart(false),
57 longFinalReported(false),
58 longFinalAcknowledged(false),
59 finalReported(false),
60 finalAcknowledged(false)
61 {
62         pos = pt;
63 }
64
65 TowerPlaneRec::TowerPlaneRec(string ID, Point3D pt) :
66 clearedToLand(false),
67 clearedToDepart(false),
68 longFinalReported(false),
69 longFinalAcknowledged(false),
70 finalReported(false),
71 finalAcknowledged(false)
72 {
73         id = ID;
74         pos = pt;
75 }
76
77
78 // FGTower
79
80 FGTower::FGTower() {
81         ATCmgr = globals->get_ATC_mgr();
82 }
83
84 FGTower::~FGTower() {
85         if(!separateGround) {
86                 delete ground;
87         }
88 }
89
90 void FGTower::Init() {
91     display = false;
92         
93         // Need some way to initialise rwyOccupied flag correctly if the user is on the runway and to know its the user.
94         // I'll punt the startup issue for now though!!!
95         rwyOccupied = false;
96         
97         // Setup the ground control at this airport
98         AirportATC a;
99         if(ATCmgr->GetAirportATCDetails(ident, &a)) {
100                 if(a.ground_freq) {             // Ground control
101                         ground = (FGGround*)ATCmgr->GetATCPointer(ident, GROUND);
102                         separateGround = true;
103                         if(ground == NULL) {
104                                 // Something has gone wrong :-(
105                                 cout << "ERROR - ground has frequency but can't get ground pointer :-(\n";
106                                 ground = new FGGround(ident);
107                                 separateGround = false;
108                                 ground->Init();
109                                 if(display) {
110                                         ground->SetDisplay();
111                                 } else {
112                                         ground->SetNoDisplay();
113                                 }
114                         }
115                 } else {
116                         // Initialise ground anyway to do the shortest path stuff!
117                         // Note that we're now responsible for updating and deleting this - NOT the ATCMgr.
118                         ground = new FGGround(ident);
119                         separateGround = false;
120                         ground->Init();
121                         if(display) {
122                                 ground->SetDisplay();
123                         } else {
124                                 ground->SetNoDisplay();
125                         }
126                 }
127         } else {
128                 cout << "Unable to find airport details for " << ident << " in FGTower::Init()\n";
129                 // Initialise ground anyway to avoid segfault later
130                 ground = new FGGround(ident);
131                 separateGround = false;
132                 ground->Init();
133                 if(display) {
134                         ground->SetDisplay();
135                 } else {
136                         ground->SetNoDisplay();
137                 }
138         }
139 }
140
141 void FGTower::Update() {
142     // Each time step, what do we need to do?
143     // We need to go through the list of outstanding requests and acknowedgements
144     // and process at least one of them.
145     // We need to go through the list of planes under our control and check if
146     // any need to be addressed.
147     // We need to check for planes not under our control coming within our 
148     // control area and address if necessary.
149
150         // TODO - a lot of the below probably doesn't need to be called every frame and should be staggered.
151         
152         // Sort the arriving planes
153
154         // Calculate the eta of each plane to the threshold.
155         // For ground traffic this is the fastest they can get there.
156         // For air traffic this is the middle approximation.
157         doThresholdETACalc();
158         
159         // Order the list of traffic as per expected threshold use and flag any conflicts
160         bool conflicts = doThresholdUseOrder();
161         
162         // sortConficts() !!!
163         
164         doCommunication();
165         
166         if(!separateGround) {
167                 // The display stuff might have to get more clever than this when not separate 
168                 // since the tower and ground might try communicating simultaneously even though
169                 // they're mean't to be the same contoller/frequency!!
170                 if(display) {
171                         ground->SetDisplay();
172                 } else {
173                         ground->SetNoDisplay();
174                 }
175                 ground->Update();
176         }
177 }
178
179 // Calculate the eta of each plane to the threshold.
180 // For ground traffic this is the fastest they can get there.
181 // For air traffic this is the middle approximation.
182 void FGTower::doThresholdETACalc() {
183         // For now we'll be very crude and hardwire expected speeds to C172-like values
184         double app_ias = 100.0;                 // Speed during straight-in approach
185         double circuit_ias = 80.0;              // Speed around circuit
186         double final_ias = 70.0;                // Speed during final approach
187
188         tower_plane_rec_list_iterator twrItr;
189
190         for(twrItr = trafficList.begin(); twrItr != trafficList.end(); twrItr++) {
191         }
192         
193 }
194
195 bool FGTower::doThresholdUseOrder() {
196         return(true);
197 }
198
199 void FGTower::doCommunication() {
200 }
201                 
202
203 void FGTower::RequestLandingClearance(string ID) {
204         cout << "Request Landing Clearance called...\n";
205 }
206 void FGTower::RequestDepartureClearance(string ID) {
207         cout << "Request Departure Clearance called...\n";
208 }       
209 //void FGTower::ReportFinal(string ID);
210 //void FGTower::ReportLongFinal(string ID);
211 //void FGTower::ReportOuterMarker(string ID);
212 //void FGTower::ReportMiddleMarker(string ID);
213 //void FGTower::ReportInnerMarker(string ID);
214 //void FGTower::ReportGoingAround(string ID);
215 void FGTower::ReportRunwayVacated(string ID) {
216         cout << "Report Runway Vacated Called...\n";
217 }