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