25
25
#include <simgear/constants.h>
26
26
#include <simgear/compiler.h>
27
#include <simgear/props/props.hxx>
27
28
#include <simgear/misc/sgstream.hxx>
28
29
#include <simgear/math/sg_geodesy.hxx>
29
30
#include <simgear/debug/logstream.hxx>
31
#include <simgear/structure/SGSharedPtr.hxx>
36
36
#include "ATCVoice.hxx"
40
// Convert a frequency in MHz to tens of kHz
41
// so we can use it e.g. as an index into commlist_freq
43
// If freq > 1000 assume it's already in tens of KHz;
44
// otherwise assume MHz.
46
// Note: 122.375 must be rounded DOWN to 12237
47
// in order to be consistent with apt.dat et cetera.
48
inline int kHz10(double freq)
50
if (freq > 1000.) return int(freq);
51
return int(freq*100.0 + 0.25);
61
73
// Possible types of ATC type that the radios may be tuned to.
62
74
// INVALID implies not tuned in to anything.
83
INVALID /* must be last element; see ATC_NUM_TYPES */
73
const int ATC_NUM_TYPES = 7;
86
const int ATC_NUM_TYPES = 1 + INVALID;
75
88
// DCL - new experimental ATC data store
78
// I've deliberately used float instead of double here to keep the size down - we'll be storing thousands of these in memory.
79
// In fact, we could probably ditch x, y and z and generate on the fly as needed.
80
// On the other hand, we'll probably end up reading this data directly from the DAFIF eventually anyway!!
84
93
unsigned short int freq;
86
94
unsigned short int range;
155
165
// Set the core ATC data
156
166
void SetData(ATCData* d);
158
inline double get_lon() const { return lon; }
159
inline void set_lon(const double ln) {lon = ln;}
160
inline double get_lat() const { return lat; }
161
inline void set_lat(const double lt) {lat = lt;}
162
inline double get_elev() const { return elev; }
163
inline void set_elev(const double ev) {elev = ev;}
164
inline double get_x() const { return x; }
165
inline void set_x(const double ecs) {x = ecs;}
166
inline double get_y() const { return y; }
167
inline void set_y(const double why) {y = why;}
168
inline double get_z() const { return z; }
169
inline void set_z(const double zed) {z = zed;}
170
168
inline int get_freq() const { return freq; }
171
169
inline void set_freq(const int fq) {freq = fq;}
172
170
inline int get_range() const { return range; }
182
180
// Outputs the transmission either on screen or as audio depending on user preference
183
181
// The refname is a string to identify this sample to the sound manager
184
182
// The repeating flag indicates whether the message should be repeated continuously or played once.
185
void Render(std::string& msg, const std::string& refname = "", bool repeating = false);
183
void Render(std::string& msg, const float volume = 1.0,
184
const std::string& refname = "", bool repeating = false);
187
186
// Cease rendering all transmission from this station.
188
187
// Requires the sound manager refname if audio, else "".
189
188
void NoRender(const std::string& refname);
191
190
// Transmit a message when channel becomes free of other dialog
192
void Transmit(int callback_code = 0);
191
void Transmit(int callback_code = 0);
194
193
// Transmit a message if channel becomes free within timeout (seconds). timeout of zero implies no limit
195
194
void ConditionalTransmit(double timeout, int callback_code = 0);
200
199
virtual void ProcessCallback(int code);
202
double lon, lat, elev;
204
std::map<std::string,int> active_on;
206
std::string ident; // Code of the airport its at.
207
std::string name; // Name transmitted in the broadcast.
207
std::string ident; // Code of the airport its at.
208
std::string name; // Name transmitted in the broadcast.
210
211
// Rendering related stuff
211
bool _voice; // Flag - true if we are using voice
212
bool _playing; // Indicates a message in progress
213
bool _voiceOK; // Flag - true if at least one voice has loaded OK
212
bool _voice; // Flag - true if we are using voice
213
bool _playing; // Indicates a message in progress
214
bool _voiceOK; // Flag - true if at least one voice has loaded OK
214
215
FGATCVoice* _vPtr;
216
std::string pending_transmission; // derived classes set this string before calling Transmit(...)
217
bool freqClear; // Flag to indicate if the frequency is clear of ongoing dialog
218
bool receiving; // Flag to indicate we are receiving a transmission
219
bool responseReqd; // Flag to indicate we should be responding to a request/report
217
SGSharedPtr<SGSampleGroup> _sgr; // default sample group;
220
bool freqClear; // Flag to indicate if the frequency is clear of ongoing dialog
221
bool receiving; // Flag to indicate we are receiving a transmission
224
double responseTime; // Time to take from end of request transmission to beginning of response
225
// The idea is that this will be slightly random.
227
bool respond; // Flag to indicate now is the time to respond - ie set following the count down of the response timer.
228
std::string responseID; // ID of the plane to respond to
220
229
bool runResponseCounter; // Flag to indicate the response counter should be run
221
double responseTime; // Time to take from end of request transmission to beginning of response
222
// The idea is that this will be slightly random.
223
double responseCounter; // counter to implement the above
224
std::string responseID; // ID of the plane to respond to
225
bool respond; // Flag to indicate now is the time to respond - ie set following the count down of the response timer.
230
double responseCounter; // counter to implement the above
226
231
// Derived classes only need monitor this flag, and use the response ID, as long as they call FGATC::Update(...)
227
232
bool _runReleaseCounter; // A timer for releasing the frequency after giving the message enough time to display
233
bool responseReqd; // Flag to indicate we should be responding to a request/report
228
234
double _releaseTime;
229
235
double _releaseCounter;
231
bool _display; // Flag to indicate whether we should be outputting to the ATC display.
232
bool _displaying; // Flag to indicate whether we are outputting to the ATC display.
237
bool _display; // Flag to indicate whether we should be outputting to the ATC display.
238
std::string pending_transmission; // derived classes set this string before calling Transmit(...)
235
241
// Transmission timing stuff.
238
245
int _callback_code; // A callback code to be notified and processed by the derived classes
239
246
// A value of zero indicates no callback required
240
247
bool _transmit; // we are to transmit
241
248
bool _transmitting; // we are transmitting
243
250
double _max_count;
252
SGPropertyNode_ptr _volume;
253
SGPropertyNode_ptr _enabled;
254
SGPropertyNode_ptr _atc_external;
255
SGPropertyNode_ptr _internal;
247
operator >> ( std::istream& fin, ATCData& a )
270
return fin >> skipeol;
272
SG_LOG(SG_GENERAL, SG_ALERT, "Warning - unknown type \'" << tp << "\' found whilst reading ATC frequency data!\n");
274
return fin >> skipeol;
277
fin >> a.lat >> a.lon >> a.elev >> f >> a.range
282
if(ch != '"') a.name += ch;
285
fin.unsetf(std::ios::skipws);
287
if((ch == '"') || (ch == 0x0A)) {
289
} // we shouldn't need the 0x0A but it makes a nice safely in case someone leaves off the "
292
fin.setf(std::ios::skipws);
293
//cout << "Comm name = " << a.name << '\n';
295
a.freq = (int)(f*100.0 + 0.5);
297
// cout << a.ident << endl;
299
// generate cartesian coordinates
300
Point3D geod( a.lon * SGD_DEGREES_TO_RADIANS, a.lat * SGD_DEGREES_TO_RADIANS, a.elev );
301
Point3D cart = sgGeodToCart( geod );
306
return fin >> skipeol;
258
std::istream& operator>> ( std::istream& fin, ATCData& a );
310
260
#endif // _FG_ATC_HXX