~jtaylor/ubuntu/oneiric/flightgear/fix-749249

« back to all changes in this revision

Viewing changes to src/Instrumentation/tacan.cxx

  • Committer: Bazaar Package Importer
  • Author(s): Ove Kaaven
  • Date: 2006-05-17 17:12:09 UTC
  • mfrom: (1.1.5 upstream) (3.1.1 etch)
  • Revision ID: james.westby@ubuntu.com-20060517171209-9qbwm4q1uj05vhcj
Tags: 0.9.10-2
Updated the build dependencies for xorg 7.0. Apparently the
amd64 autobuilder doesn't use Provides.

Show diffs side-by-side

added added

removed removed

Lines of Context:
3
3
//
4
4
// This file is in the Public Domain and comes with no warranty.
5
5
 
 
6
#ifdef HAVE_CONFIG_H
 
7
#  include <config.h>
 
8
#endif
 
9
 
6
10
#include <simgear/compiler.h>
7
11
#include <simgear/math/sg_geodesy.hxx>
8
12
#include <simgear/math/sg_random.h>
9
13
 
10
14
#include <Main/fg_props.hxx>
11
15
#include <Navaids/navlist.hxx>
 
16
#include <vector>
12
17
 
13
18
#include "tacan.hxx"
14
19
 
 
20
SG_USING_STD(vector);
 
21
 
15
22
 
16
23
/**
17
24
 * Adjust the range.
47
54
      _transmitter_elevation_ft(0),
48
55
      _transmitter_range_nm(0),
49
56
      _transmitter_bias(0.0),
50
 
      
 
57
 
51
58
      name("tacan"),
52
59
      num(0)
53
60
{
54
 
    
 
61
 
55
62
    int i;
56
63
    for ( i = 0; i < node->nChildren(); ++i ) {
57
64
        SGPropertyNode *child = node->getChild(i);
115
122
    _time_node = node->getChild("indicated-time-min", 0, true);
116
123
    _name_node = node->getChild("name", 0, true);
117
124
    _bearing_node = node->getChild("indicated-bearing-true-deg", 0, true);
118
 
    _carrier_lat_node = fgGetNode("/ai/models/carrier/position/latitude-deg", true);
119
 
    _carrier_lon_node = fgGetNode("/ai/models/carrier/position/longitude-deg", true);
120
 
    _carrier_name_node = fgGetNode("/ai/models/carrier/name", true);
121
 
   
 
125
    SGPropertyNode *cnode = fgGetNode("/ai/models/carrier", num, true );
 
126
    _carrier_name_node = cnode->getChild("name", 0, true);
 
127
    
122
128
}
123
129
 
124
130
void
125
131
TACAN::update (double delta_time_sec)
126
 
{   
127
 
    double az2 = 0; 
 
132
{
 
133
    double az2 = 0;
128
134
    double bearing = 0;
129
 
    double distance = 0; 
130
 
    double carrier_az2= 0; 
131
 
    double carrier_bearing = 0; 
 
135
    double distance = 0;
 
136
    double carrier_az2= 0;
 
137
    double carrier_bearing = 0;
132
138
    double carrier_distance = 0;
133
139
    double frequency_mhz = 0;
134
140
    string _channel, _last_channel, _channel_1, _channel_2,_channel_3, _channel_4;
135
141
 
136
 
                                // If it's off, don't waste any time.    
137
 
    if (!_serviceable_node->getBoolValue() ||
138
 
        !_electrical_node->getBoolValue() 
139
 
        ) {
140
 
            _last_distance_nm = 0;
141
 
            _in_range_node->setBoolValue(false);
142
 
            _distance_node->setDoubleValue(0);
143
 
            _speed_node->setDoubleValue(0);
144
 
            _time_node->setDoubleValue(0);
145
 
            SG_LOG( SG_INSTR, SG_DEBUG, "skip tacan "  );
146
 
            return;
147
 
    }else{
148
 
        //SG_LOG( SG_INSTR, SG_DEBUG, "run tacan "  );
149
 
        }    
150
 
                                
 
142
                                // If it's off, don't waste any time.
 
143
    if (!_serviceable_node->getBoolValue() || !_electrical_node->getBoolValue()) {
 
144
        _last_distance_nm = 0;
 
145
        _in_range_node->setBoolValue(false);
 
146
        _distance_node->setDoubleValue(0);
 
147
        _speed_node->setDoubleValue(0);
 
148
        _time_node->setDoubleValue(0);
 
149
        SG_LOG( SG_INSTR, SG_DEBUG, "skip tacan" );
 
150
        return;
 
151
    }
 
152
 
151
153
                                // Figure out the source
152
154
    const char * source = _source_node->getStringValue();
153
 
   
 
155
 
154
156
    if (source[0] == '\0') {
155
157
        string branch;
156
158
        branch = "/instrumentation/" + name + "/frequencies/selected-channel";
157
 
      //  branch = "/instrumentation/" + _name + "/frequencies/selected-mhz";      
158
159
        _source_node->setStringValue(branch.c_str());
159
160
        source = _source_node->getStringValue();
160
 
        SG_LOG( SG_INSTR, SG_DEBUG, "source " << source  ); 
 
161
        SG_LOG( SG_INSTR, SG_DEBUG, "source " << source  );
161
162
    }
162
 
                                // Get the channel   
 
163
                                // Get the channel
163
164
    _channel_1 = fgGetString("/instrumentation/tacan/frequencies/selected-channel[1]");
164
165
    _channel_2 = fgGetString("/instrumentation/tacan/frequencies/selected-channel[2]");
165
166
    _channel_3 = fgGetString("/instrumentation/tacan/frequencies/selected-channel[3]");
167
168
    SG_LOG( SG_INSTR, SG_DEBUG, "channels " << _channel_1 << _channel_2 << _channel_3 << _channel_4);
168
169
    _channel = _channel_1 + _channel_2 + _channel_3 + _channel_4;
169
170
    SG_LOG( SG_INSTR, SG_DEBUG, "channel " << _channel );
170
 
    
 
171
 
171
172
                                // Get the frequecncy
172
173
    if (_channel != _last_channel) {
173
174
        _time_before_search_sec = 0;
175
176
        frequency_mhz = searchChannel(_channel);
176
177
        SG_LOG( SG_INSTR, SG_DEBUG, "frequency " << frequency_mhz );
177
178
        _frequency_node->setDoubleValue(frequency_mhz);
178
 
    }        
179
 
        
 
179
    }
 
180
 
180
181
                                // Get the aircraft position
181
 
     double longitude_deg = _longitude_node->getDoubleValue();
182
 
     double latitude_deg  = _latitude_node->getDoubleValue();
183
 
     double altitude_m    = _altitude_node->getDoubleValue() * SG_FEET_TO_METER;
184
 
     double longitude_rad = longitude_deg * SGD_DEGREES_TO_RADIANS;
185
 
     double latitude_rad  = latitude_deg * SGD_DEGREES_TO_RADIANS;
186
 
                                          
 
182
    double longitude_deg = _longitude_node->getDoubleValue();
 
183
    double latitude_deg  = _latitude_node->getDoubleValue();
 
184
    double altitude_m    = _altitude_node->getDoubleValue() * SG_FEET_TO_METER;
 
185
    double longitude_rad = longitude_deg * SGD_DEGREES_TO_RADIANS;
 
186
    double latitude_rad  = latitude_deg * SGD_DEGREES_TO_RADIANS;
 
187
 
187
188
                                // On timeout, scan again
188
189
    _time_before_search_sec -= delta_time_sec;
189
190
    if (_time_before_search_sec < 0 && frequency_mhz > 0)
190
 
        search(frequency_mhz, longitude_rad,
191
 
               latitude_rad, altitude_m);
 
191
        search(frequency_mhz, longitude_rad, latitude_rad, altitude_m);
192
192
 
193
193
                                 // Calculate the distance to the transmitter
194
 
                                 
195
 
     //calculate the bearing and range of the carrier from the aircraft
196
 
     SG_LOG( SG_INSTR, SG_DEBUG, "carrier_lat " << _carrier_lat);
197
 
     SG_LOG( SG_INSTR, SG_DEBUG, "carrier_lon " << _carrier_lon);
198
 
     SG_LOG( SG_INSTR, SG_DEBUG, "carrier_name " << _carrier_name);
199
 
     SG_LOG( SG_INSTR, SG_DEBUG, "carrier_valid " << _carrier_valid);
200
 
     geo_inverse_wgs_84(altitude_m,
201
 
                        latitude_deg,
202
 
                        longitude_deg,
203
 
                        _carrier_lat,
204
 
                        _carrier_lon,
205
 
                        &carrier_bearing, &carrier_az2, &carrier_distance);
206
 
                         
207
 
      
208
 
     //calculate the bearing and range of the station from the aircraft
209
 
     geo_inverse_wgs_84(altitude_m,
210
 
                        latitude_deg,
211
 
                        longitude_deg,
212
 
                        _transmitter_lat,
213
 
                        _transmitter_lon,
214
 
                        &bearing, &az2, &distance);
215
 
    
216
 
                     
217
 
     //select the nearer
218
 
     if ( carrier_distance <= distance && _carrier_valid) { 
219
 
         SG_LOG( SG_INSTR, SG_DEBUG, "carrier_distance_nm " << carrier_distance);
220
 
         SG_LOG( SG_INSTR, SG_DEBUG, "distance_nm " << distance);
221
 
         bearing = carrier_bearing;
222
 
         distance = carrier_distance;
223
 
         _transmitter_elevation_ft = _carrier_elevation_ft;
224
 
         _transmitter_range_nm = _carrier_range_nm;
225
 
         _transmitter_bias = _carrier_bias;
226
 
         _transmitter_name = _carrier_name;
227
 
         _name_node->setStringValue(_transmitter_name.c_str());
228
 
     }    
229
 
               
230
 
     double distance_nm = distance * SG_METER_TO_NM;        
231
 
     SG_LOG( SG_INSTR, SG_DEBUG, "distance_nm " << distance_nm  << " bearing " << bearing);                          
 
194
 
 
195
    //calculate the bearing and range of the carrier from the aircraft
 
196
    SG_LOG( SG_INSTR, SG_DEBUG, "carrier_lat " << _carrier_lat);
 
197
    SG_LOG( SG_INSTR, SG_DEBUG, "carrier_lon " << _carrier_lon);
 
198
    SG_LOG( SG_INSTR, SG_DEBUG, "carrier_name " << _carrier_name);
 
199
    SG_LOG( SG_INSTR, SG_DEBUG, "carrier_valid " << _carrier_valid);
 
200
    geo_inverse_wgs_84(altitude_m,
 
201
                       latitude_deg,
 
202
                       longitude_deg,
 
203
                       _carrier_lat,
 
204
                       _carrier_lon,
 
205
                       &carrier_bearing, &carrier_az2, &carrier_distance);
 
206
 
 
207
 
 
208
    //calculate the bearing and range of the station from the aircraft
 
209
    geo_inverse_wgs_84(altitude_m,
 
210
                       latitude_deg,
 
211
                       longitude_deg,
 
212
                       _transmitter_lat,
 
213
                       _transmitter_lon,
 
214
                       &bearing, &az2, &distance);
 
215
 
 
216
 
 
217
    //select the nearer
 
218
    if ( carrier_distance <= distance && _carrier_valid) {
 
219
        SG_LOG( SG_INSTR, SG_DEBUG, "carrier_distance_nm " << carrier_distance);
 
220
        SG_LOG( SG_INSTR, SG_DEBUG, "distance_nm " << distance);
 
221
        bearing = carrier_bearing;
 
222
        distance = carrier_distance;
 
223
        _transmitter_elevation_ft = _carrier_elevation_ft;
 
224
        _transmitter_range_nm = _carrier_range_nm;
 
225
        _transmitter_bias = _carrier_bias;
 
226
        _transmitter_name = _carrier_name;
 
227
        _name_node->setStringValue(_transmitter_name.c_str());
 
228
    }
 
229
 
 
230
    double distance_nm = distance * SG_METER_TO_NM;
 
231
    SG_LOG( SG_INSTR, SG_DEBUG, "distance_nm " << distance_nm  << " bearing " << bearing);
232
232
 
233
233
    /*Point3D location =
234
234
        sgGeodToCart(Point3D(longitude_rad, latitude_rad, altitude_m));
252
252
        _speed_node->setDoubleValue(speed_kt);
253
253
        _time_node->setDoubleValue(distance_nm/speed_kt*60.0);
254
254
        _bearing_node->setDoubleValue(bearing);
255
 
        
 
255
 
256
256
    } else {
257
257
        _last_distance_nm = 0;
258
258
        _in_range_node->setBoolValue(false);
261
261
        _time_node->setDoubleValue(0);
262
262
        _bearing_node->setDoubleValue(0);
263
263
    }
264
 
    
 
264
 
265
265
                                // If we can't find a valid station set everything to zero
266
 
    if (!_transmitter_valid && !_carrier_valid)
267
 
    {
 
266
    if (!_transmitter_valid && !_carrier_valid) {
268
267
        _in_range_node->setBoolValue(false);
269
268
        _distance_node->setDoubleValue(0);
270
269
        _speed_node->setDoubleValue(0);
278
277
 
279
278
void
280
279
TACAN::search (double frequency_mhz, double longitude_rad,
281
 
             double latitude_rad, double altitude_m)
282
 
{    
283
 
    
 
280
               double latitude_rad, double altitude_m)
 
281
{
 
282
 
284
283
    SG_LOG( SG_INSTR, SG_DEBUG, "tacan freq " << frequency_mhz );
285
 
     
 
284
 
286
285
    // reset search time
287
286
    _time_before_search_sec = 1.0;
288
 
    
 
287
 
289
288
    //try any carriers first
290
289
     FGNavRecord *carrier_tacan
291
290
          = globals->get_carrierlist()->findStationByFreq( frequency_mhz );
293
292
 
294
293
    if ( _carrier_valid ) {
295
294
        SG_LOG( SG_INSTR, SG_DEBUG, "carrier transmitter valid " << _carrier_valid  );
296
 
         
 
295
 
297
296
        string str1( carrier_tacan->get_name() );
298
 
        string str2 ( _carrier_name_node->getStringValue());
299
 
        SG_LOG( SG_INSTR, SG_DEBUG, "strings 1 " << str1 << " 2 " << str2 );
300
 
        unsigned int loc1= str1.find( str2, 0 );
301
 
          if( loc1 != string::npos && str2 != "" ){
302
 
              SG_LOG( SG_INSTR, SG_DEBUG, " string found" );
303
 
              _carrier_lat = _carrier_lat_node->getDoubleValue();
304
 
              _carrier_lon = _carrier_lon_node->getDoubleValue();
305
 
              _carrier_elevation_ft = carrier_tacan->get_elev_ft();
306
 
              _carrier_range_nm = carrier_tacan->get_range();
307
 
              _carrier_bias = carrier_tacan->get_multiuse();
308
 
              _carrier_name = carrier_tacan->get_name();
309
 
              }
310
 
          else{
311
 
              _carrier_valid = 0;
312
 
              SG_LOG( SG_INSTR, SG_DEBUG, " carrier transmitter invalid " << _carrier_valid );
313
 
          }    
314
 
              
315
 
              
316
 
        //_name_node->setStringValue(_transmitter_name.c_str());
317
 
        
 
297
 
 
298
        SGPropertyNode * branch = fgGetNode("ai/models", true);
 
299
        vector<SGPropertyNode_ptr> carrier = branch->getChildren("carrier");
 
300
 
 
301
        int number = carrier.size();
 
302
 
 
303
        SG_LOG( SG_INSTR, SG_DEBUG, "carrier " << number );
 
304
 
 
305
        int i;
 
306
        for ( i = 0; i < number; ++i ) {
 
307
            string str2 ( carrier[i]->getStringValue("name", ""));
 
308
            // SG_LOG( SG_INSTR, SG_DEBUG, "carrier name " << str2 );
 
309
 
 
310
            SG_LOG( SG_INSTR, SG_DEBUG, "strings 1 " << str1 << " 2 " << str2 );
 
311
            unsigned int loc1= str1.find( str2, 0 );
 
312
            if ( loc1 != string::npos && str2 != "" ) {
 
313
                SG_LOG( SG_INSTR, SG_DEBUG, " string found" );
 
314
                _carrier_lat = carrier[i]->getDoubleValue("position/latitude-deg");
 
315
                _carrier_lon = carrier[i]->getDoubleValue("position/longitude-deg");
 
316
                _carrier_elevation_ft = carrier_tacan->get_elev_ft();
 
317
                _carrier_range_nm = carrier_tacan->get_range();
 
318
                _carrier_bias = carrier_tacan->get_multiuse();
 
319
                _carrier_name = carrier_tacan->get_name();
 
320
                _carrier_valid = 1;
 
321
                SG_LOG( SG_INSTR, SG_DEBUG, " carrier transmitter valid " << _carrier_valid );
 
322
                break;
 
323
            } else {
 
324
                _carrier_valid = 0;
 
325
                SG_LOG( SG_INSTR, SG_DEBUG, " carrier transmitter invalid " << _carrier_valid );
 
326
            }
 
327
        }
 
328
 
 
329
        SG_LOG( SG_INSTR, SG_DEBUG, "name " << _carrier_name);
318
330
        SG_LOG( SG_INSTR, SG_DEBUG, "lat " << _carrier_lat << "lon " << _carrier_lon);
319
331
        SG_LOG( SG_INSTR, SG_DEBUG, "elev " << _carrier_elevation_ft);
320
 
        SG_LOG( SG_INSTR, SG_DEBUG, "name " << _carrier_name);
321
 
        
 
332
 
322
333
    } else {
323
 
         SG_LOG( SG_INSTR, SG_DEBUG, " carrier transmitter invalid " << _carrier_valid  );
324
 
     }    
325
 
    
 
334
        SG_LOG( SG_INSTR, SG_DEBUG, " carrier transmitter invalid " << _carrier_valid  );
 
335
    }
 
336
 
326
337
 
327
338
    // try the TACAN/VORTAC list next
328
339
    FGNavRecord *tacan
329
340
        = globals->get_tacanlist()->findByFreq( frequency_mhz, longitude_rad,
330
 
                                              latitude_rad, altitude_m);
 
341
                                                latitude_rad, altitude_m);
331
342
 
332
343
    _transmitter_valid = (tacan != NULL);
333
344
 
334
345
    if ( _transmitter_valid ) {
335
346
        SG_LOG( SG_INSTR, SG_DEBUG, "transmitter valid " << _transmitter_valid  );
336
 
       
 
347
 
337
348
        _transmitter_lat = tacan->get_lat();
338
349
        _transmitter_lon = tacan->get_lon();
339
350
        _transmitter_elevation_ft = tacan->get_elev_ft();
341
352
        _transmitter_bias = tacan->get_multiuse();
342
353
        _transmitter_name = tacan->get_name();
343
354
        _name_node->setStringValue(_transmitter_name.c_str());
344
 
        
 
355
 
 
356
        SG_LOG( SG_INSTR, SG_DEBUG, "name " << _transmitter_name);
345
357
        SG_LOG( SG_INSTR, SG_DEBUG, "lat " << _transmitter_lat << "lon " << _transmitter_lon);
346
358
        SG_LOG( SG_INSTR, SG_DEBUG, "elev " << _transmitter_elevation_ft);
347
 
        SG_LOG( SG_INSTR, SG_DEBUG, "name " << _transmitter_name);
348
 
        
 
359
 
349
360
    } else {
350
 
         SG_LOG( SG_INSTR, SG_DEBUG, "transmitter invalid " << _transmitter_valid  );
351
 
     }    
352
 
        
 
361
        SG_LOG( SG_INSTR, SG_DEBUG, "transmitter invalid " << _transmitter_valid  );
 
362
    }
353
363
}
354
364
 
355
365
double
356
366
TACAN::searchChannel (const string& _channel){
357
 
    
 
367
 
358
368
    double frequency_khz = 0;
359
 
    
 
369
 
360
370
    FGTACANRecord *freq
361
371
        = globals->get_channellist()->findByChannel( _channel );
362
 
    double _freq_valid = (freq != NULL); 
 
372
    double _freq_valid = (freq != NULL);
363
373
    SG_LOG( SG_INSTR, SG_DEBUG, "freq valid " << _freq_valid  );
364
374
    if ( _freq_valid ) {
365
375
        frequency_khz = freq->get_freq();
366
376
        SG_LOG( SG_INSTR, SG_DEBUG, "freq output " << frequency_khz  );
367
377
        //check sanity
368
 
        if (frequency_khz >9620 && frequency_khz <= 12130)return frequency_khz/100;
 
378
        if (frequency_khz >=9620 && frequency_khz <= 12130)
 
379
            return frequency_khz/100;
369
380
    }
370
381
    return frequency_khz = 0;
371
382
} // end TACAN::searchChannel
372
 
   
 
383
 
373
384
// end of TACAN.cxx