1 // antenna.cxx -- implementation of FGRadioAntenna
2 // Class to represent a virtual radio antenna properties
3 // Written by Adrian Musceac YO8RZZ, started December 2011.
4 //
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License as
7 // published by the Free Software Foundation; either version 2 of the
8 // License, or (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful, but
11 // WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 // General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18 
19 
20 #ifdef HAVE_CONFIG_H
21 #  include <config.h>
22 #endif
23 
24 #include <cmath>
25 #include <iostream>
26 #include <stdlib.h>
27 #include <fstream>
28 #include <Scenery/scenery.hxx>
29 #include <simgear/io/iostreams/sgstream.hxx>
30 
31 #include "antenna.hxx"
32 
33 using namespace std;
34 
FGRadioAntenna(string type)35 FGRadioAntenna::FGRadioAntenna(string type) {
36 
37 	_mirror_y = 1;	// normally we want to mirror these axis because the pattern is simetric
38 	_mirror_z = 1;
39 	_invert_ground = 0;		// TODO: use for inverting the antenna ground, for instance aircraft body reflection
40 	load_NEC_antenna_pattern(type);
41 }
42 
~FGRadioAntenna()43 FGRadioAntenna::~FGRadioAntenna() {
44 	for (unsigned i =0; i < _pattern.size(); i++) {
45 		AntennaGain *point_gain = _pattern[i];
46 		delete point_gain;
47 	}
48 	_pattern.clear();
49 }
50 
51 // WIP
calculate_gain(double bearing,double angle)52 double FGRadioAntenna::calculate_gain(double bearing, double angle) {
53 
54 	// TODO: what if the pattern is assimetric?
55 	bearing = fabs(bearing);
56 	if (bearing > 180)
57 		bearing = 360 - bearing;
58 	// for plots with 2 degrees resolution:
59 	int azimuth = (int)floor(bearing);
60 	azimuth += azimuth % 2;
61 	int elevation = (int)floor(angle);
62 	elevation += elevation % 2;
63 	//cerr << "Bearing: " << bearing << " angle: " << angle << " azimuth: " << azimuth << " elevation: " << elevation << endl;
64 	for (unsigned i =0; i < _pattern.size(); i++) {
65 		AntennaGain *point_gain = _pattern[i];
66 
67 		if ( (azimuth == point_gain->azimuth) && (elevation == point_gain->elevation)) {
68 			return point_gain->gain;
69 		}
70 	}
71 
72 	return 0;
73 }
74 
75 
load_NEC_antenna_pattern(string type)76 void FGRadioAntenna::load_NEC_antenna_pattern(string type) {
77 
78 	//SGPath pattern_file(globals->get_fg_home());
79 	SGPath pattern_file(globals->get_fg_root());
80 	pattern_file.append("Navaids/Antennas");
81 	pattern_file.append(type + ".txt");
82 	if (!pattern_file.exists()) {
83 		return;
84 	}
85 	sg_ifstream file_in(pattern_file);
86 	int heading, elevation;
87 	double gain;
88 	while(!file_in.eof()) {
89 		file_in >> heading >> elevation >> gain;
90 		if( (_mirror_y == 1) && (heading > 180) ) {
91 			continue;
92 		}
93 		if ( (_mirror_z == 1) && (elevation < 0) ) {
94 			continue;
95 		}
96 		//cerr << "head: " << heading << " elev: " << elevation << " gain: " << gain << endl;
97 		AntennaGain *datapoint = new AntennaGain;
98 		datapoint->azimuth = heading;
99 		datapoint->elevation = 90.0 - abs(elevation);
100 		datapoint->gain = gain;
101 		_pattern.push_back(datapoint);
102 	}
103 }
104