1 // radio.hxx -- FGRadio: class to manage radio propagation
2 //
3 // Written by Adrian Musceac YO8RZZ, started August 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 #ifndef __cplusplus
21 # error This library requires C++
22 #endif
23 
24 #include <simgear/compiler.h>
25 #include <simgear/structure/subsystem_mgr.hxx>
26 #include <deque>
27 #include <Main/fg_props.hxx>
28 
29 #include <simgear/math/sg_geodesy.hxx>
30 #include <simgear/debug/logstream.hxx>
31 #include "antenna.hxx"
32 
33 using std::string;
34 
35 
36 class FGRadioTransmission
37 {
38 private:
39 
40 	double _receiver_sensitivity;
41 	double _transmitter_power;
42 	double _tx_antenna_height;
43 	double _rx_antenna_height;
44 	double _rx_antenna_gain;
45 	double _tx_antenna_gain;
46 	double _rx_line_losses;
47 	double _tx_line_losses;
48 
49 	double _terrain_sampling_distance;
50 	int _polarization;
51 	std::map<string, double[2]> _mat_database;
52 	SGPropertyNode *_root_node;
53 	int _propagation_model; /// 0 none, 1 round Earth, 2 ITM
54 	double polarization_loss();
55 
56 
57 /***  Implement radio attenuation
58 *	  based on the Longley-Rice propagation model
59 *	ground_to_air: 0 for air to ground 1 for ground to air, 2 for air to air, 3 for pilot to ground, 4 for pilot to air
60 *	@param: transmitter position, frequency, flag to indicate if the transmission is from a ground station
61 *	@return: signal level above receiver treshhold sensitivity
62 ***/
63 	double ITM_calculate_attenuation(SGGeod tx_pos, double freq, int ground_to_air);
64 
65 /*** a simple alternative LOS propagation model (WIP)
66 *	@param: transmitter position, frequency, flag to indicate if the transmission is from a ground station
67 *	@return: signal level above receiver treshhold sensitivity
68 ***/
69 	double LOS_calculate_attenuation(SGGeod tx_pos, double freq, int ground_to_air);
70 
71 /*** Calculate losses due to vegetation and urban clutter (WIP)
72 *	 We are only worried about clutter loss, terrain influence
73 *	 on the first Fresnel zone is calculated in the ITM functions
74 *	@param: frequency, elevation data, terrain type, horizon distances, calculated loss
75 *	@return: none
76 ***/
77 	void calculate_clutter_loss(double freq, double itm_elev[], std::deque<string*> &materials,
78 			double transmitter_height, double receiver_height, int p_mode,
79 			double horizons[], double &clutter_loss);
80 
81 /*** 	Temporary material properties database
82 *		@param: terrain type, median clutter height, radiowave attenuation factor
83 *		@return: none
84 ***/
85 	void get_material_properties(string* mat_name, double &height, double &density);
86 
87 
88 public:
89 
90     FGRadioTransmission();
91     ~FGRadioTransmission();
92 
93     /// a couple of setters and getters for convenience, call after initializing
94     /// frequency is in MHz, sensitivity in dBm, antenna gain and losses in dB, transmitter power in dBm
95     /// polarization can be: 0 horizontal, 1 vertical
96     void setFrequency(double freq, int radio);
97     double getFrequency(int radio);
setTxPower(double txpower)98     inline void setTxPower(double txpower) { _transmitter_power = txpower; };
setRxSensitivity(double sensitivity)99     inline void setRxSensitivity(double sensitivity) { _receiver_sensitivity = sensitivity; };
setTxAntennaHeight(double tx_antenna_height)100     inline void setTxAntennaHeight(double tx_antenna_height) { _tx_antenna_height = tx_antenna_height; };
setRxAntennaHeight(double rx_antenna_height)101     inline void setRxAntennaHeight(double rx_antenna_height) { _rx_antenna_height = rx_antenna_height; };
setTxAntennaGain(double tx_antenna_gain)102     inline void setTxAntennaGain(double tx_antenna_gain) { _tx_antenna_gain = tx_antenna_gain; };
setRxAntennaGain(double rx_antenna_gain)103     inline void setRxAntennaGain(double rx_antenna_gain) { _rx_antenna_gain = rx_antenna_gain; };
setTxLineLosses(double tx_line_losses)104     inline void setTxLineLosses(double tx_line_losses) { _tx_line_losses = tx_line_losses; };
setRxLineLosses(double rx_line_losses)105     inline void setRxLineLosses(double rx_line_losses) { _rx_line_losses = rx_line_losses; };
setPropagationModel(int model)106     inline void setPropagationModel(int model) { _propagation_model = model; };
setPolarization(int polarization)107     inline void setPolarization(int polarization) { _polarization = polarization; };
108 
109     /// static convenience functions for unit conversions
110     static double watt_to_dbm(double power_watt);
111     static double dbm_to_watt(double dbm);
112     static double dbm_to_microvolt(double dbm);
113 
114 
115 /*** Receive ATC radio communication as text
116 *	transmission_type: 0 for air to ground 1 for ground to air, 2 for air to air, 3 for pilot to ground, 4 for pilot to air
117 *	@param: transmitter position, frequency, ATC text, flag to indicate whether the transmission comes from an ATC groundstation
118 *	@return: none
119 ***/
120     void receiveATC(SGGeod tx_pos, double freq, string text, int transmission_type);
121 
122 /*** TODO: receive multiplayer chat message and voice
123 *	@param: transmitter position, frequency, ATC text, flag to indicate whether the transmission comes from an ATC groundstation
124 *	@return: none
125 ***/
126     void receiveChat(SGGeod tx_pos, double freq, string text, int transmission_type);
127 
128 /*** TODO: receive navaid
129 *	@param: transmitter position, frequency, flag
130 *	@return: signal level above receiver treshhold sensitivity
131 ***/
132     double receiveNav(SGGeod tx_pos, double freq, int transmission_type);
133 
134 /*** Call this function to receive an arbitrary signal
135 *	for instance via the Nasal radioTransmission() function
136 *	returns the signal value above receiver sensitivity treshhold
137 *	@param: transmitter position, object heading in degrees (for antenna), object pitch angle in degrees
138 *	@return: signal level above receiver treshhold sensitivity
139 ***/
140     double receiveBeacon(SGGeod &tx_pos, double heading, double pitch);
141 };
142 
143 
144