From 2c6946c3e8b446c2aa4e3f2bda6f8eb05e59c873 Mon Sep 17 00:00:00 2001 From: adrian Date: Thu, 24 Nov 2011 17:25:49 +0200 Subject: [PATCH] refactor receiveATC(), implement simple LOS routine, set comm1-signal property --- src/ATC/trafficcontrol.cxx | 2 +- src/Radio/radio.cxx | 106 ++++++++++++++++++++++++++++++++++--- src/Radio/radio.hxx | 6 ++- 3 files changed, 103 insertions(+), 11 deletions(-) diff --git a/src/ATC/trafficcontrol.cxx b/src/ATC/trafficcontrol.cxx index 2b0d20c67..cf0b16f31 100644 --- a/src/ATC/trafficcontrol.cxx +++ b/src/ATC/trafficcontrol.cxx @@ -762,7 +762,7 @@ void FGATCController::transmit(FGTrafficRecord * rec, FGAirportDynamics *parent, rec->getLatitude(), sender_alt ); } double frequency = ((double)stationFreq) / 100; - radio->receiveText(sender_pos, frequency, text, ground_to_air); + radio->receiveATC(sender_pos, frequency, text, ground_to_air); delete radio; } else { diff --git a/src/Radio/radio.cxx b/src/Radio/radio.cxx index 9b3d0320f..260894655 100644 --- a/src/Radio/radio.cxx +++ b/src/Radio/radio.cxx @@ -34,14 +34,15 @@ FGRadio::FGRadio() { - /** radio parameters (which should probably be set for each radio via constructor) */ + /** radio parameters (which should probably be set for each radio) */ + _receiver_sensitivity = -110.0; // typical AM receiver sensitivity seems to be 0.8 microVolt at 12dB SINAD /** AM transmitter power in dBm. * Note this value is calculated from the typical final transistor stage output * small aircraft have portable transmitters which operate at 36 dBm output (4 Watts) - * later store this value in aircraft description - * ATC comms usually operate high power equipment, thus making the link asymetrical; this is ignored for now + * later possibly store this value in aircraft description + * ATC comms usually operate high power equipment, thus making the link asymetrical; this is taken care of in propagation routines **/ _transmitter_power = 43.0; @@ -74,10 +75,16 @@ double FGRadio::getFrequency(int radio) { return freq; } +/*** TODO: receive multiplayer chat message and voice +***/ +void FGRadio::receiveChat(SGGeod tx_pos, double freq, string text, + int ground_to_air) { +} - -void FGRadio::receiveText(SGGeod tx_pos, double freq, string text, +/*** Receive ATC radio communication as text +***/ +void FGRadio::receiveATC(SGGeod tx_pos, double freq, string text, int ground_to_air) { /* @@ -93,7 +100,19 @@ void FGRadio::receiveText(SGGeod tx_pos, double freq, string text, fgSetString("/sim/messages/atc", text.c_str()); } else if ( _propagation_model == 1 ) { - // free space, round earth + // TODO: free space, round earth + double signal = LOS_calculate_attenuation(tx_pos, freq, ground_to_air); + if (signal <= 0.0) { + SG_LOG(SG_GENERAL, SG_BULK, "Signal below receiver minimum sensitivity: " << signal); + //cerr << "Signal below receiver minimum sensitivity: " << signal << endl; + return; + } + else { + SG_LOG(SG_GENERAL, SG_BULK, "Signal completely readable: " << signal); + //cerr << "Signal completely readable: " << signal << endl; + fgSetString("/sim/messages/atc", text.c_str()); + fgSetDouble("/sim/radio/comm1-signal", signal); + } } else if ( _propagation_model == 2 ) { // Use ITM propagation model @@ -126,12 +145,14 @@ void FGRadio::receiveText(SGGeod tx_pos, double freq, string text, //cerr << "Usable signal at limit: " << signal << endl; fgSetDouble("/sim/sound/voices/voice/volume", volume); fgSetString("/sim/messages/atc", text.c_str()); + fgSetDouble("/sim/radio/comm1-signal", signal); fgSetDouble("/sim/sound/voices/voice/volume", old_volume); } else { SG_LOG(SG_GENERAL, SG_BULK, "Signal completely readable: " << signal); //cerr << "Signal completely readable: " << signal << endl; fgSetString("/sim/messages/atc", text.c_str()); + fgSetDouble("/sim/radio/comm1-signal", signal); } } @@ -221,8 +242,8 @@ double FGRadio::ITM_calculate_attenuation(SGGeod pos, double freq, if (own_alt > 8000) { dbloss = 20 * log10(distance_m) +20 * log10(frq_mhz) -27.55; SG_LOG(SG_GENERAL, SG_BULK, - "LOS-mode:: Link budget: " << link_budget << ", Attenuation: " << dbloss << " dBm, free-space attenuation"); - //cerr << "LOS-mode:: Link budget: " << link_budget << ", Attenuation: " << dbloss << " dBm, free-space attenuation" << endl; + "ITM Free-space mode:: Link budget: " << link_budget << ", Attenuation: " << dbloss << " dBm, free-space attenuation"); + //cerr << "ITM Free-space mode:: Link budget: " << link_budget << ", Attenuation: " << dbloss << " dBm, free-space attenuation" << endl; signal = link_budget - dbloss; return signal; } @@ -338,3 +359,72 @@ double FGRadio::ITM_calculate_attenuation(SGGeod pos, double freq, return signal; } + +/*** implement simple LOS propagation model (WIP) +***/ +double FGRadio::LOS_calculate_attenuation(SGGeod pos, double freq, + int transmission_type) { + double frq_mhz; + if( (freq < 118.0) || (freq > 137.0) ) + frq_mhz = 125.0; // sane value, middle of bandplan + else + frq_mhz = freq; + double dbloss; + double tx_pow = _transmitter_power; + double ant_gain = _antenna_gain; + double signal = 0.0; + double ATC_HAAT = 30.0; + double Aircraft_HAAT = 5.0; + double sender_alt_ft,sender_alt; + double transmitter_height=0.0; + double receiver_height=0.0; + double own_lat = fgGetDouble("/position/latitude-deg"); + double own_lon = fgGetDouble("/position/longitude-deg"); + double own_alt_ft = fgGetDouble("/position/altitude-ft"); + double own_alt= own_alt_ft * SG_FEET_TO_METER; + + if(transmission_type == 1) + tx_pow = _transmitter_power + 6.0; + + if((transmission_type == 1) || (transmission_type == 3)) + ant_gain = _antenna_gain + 3.0; //pilot plane's antenna gain + ground station antenna gain + + double link_budget = tx_pow - _receiver_sensitivity + ant_gain; + + //cerr << "ITM:: pilot Lat: " << own_lat << ", Lon: " << own_lon << ", Alt: " << own_alt << endl; + + SGGeod own_pos = SGGeod::fromDegM( own_lon, own_lat, own_alt ); + + SGGeod sender_pos = pos; + + sender_alt_ft = sender_pos.getElevationFt(); + sender_alt = sender_alt_ft * SG_FEET_TO_METER; + + receiver_height = own_alt; + transmitter_height = sender_alt; + + double distance_m = SGGeodesy::distanceM(own_pos, sender_pos); + + if(transmission_type == 1) + transmitter_height += ATC_HAAT; + else + transmitter_height += Aircraft_HAAT; + + /** radio horizon calculation with wave bending k=4/3 */ + double receiver_horizon = 4.12 * sqrt(receiver_height); + double transmitter_horizon = 4.12 * sqrt(transmitter_height); + double total_horizon = receiver_horizon + transmitter_horizon; + + if (distance_m > total_horizon) { + return -1; + } + + // free-space loss (distance calculation should be changed) + dbloss = 20 * log10(distance_m) +20 * log10(frq_mhz) -27.55; + signal = link_budget - dbloss; + SG_LOG(SG_GENERAL, SG_BULK, + "LOS:: Link budget: " << link_budget << ", Attenuation: " << dbloss << " dBm "); + cerr << "LOS:: Link budget: " << link_budget << ", Attenuation: " << dbloss << " dBm " << endl; + return signal; + +} diff --git a/src/Radio/radio.hxx b/src/Radio/radio.hxx index 4b2b67c85..378cfa37b 100644 --- a/src/Radio/radio.hxx +++ b/src/Radio/radio.hxx @@ -46,6 +46,7 @@ private: int _propagation_model; /// 0 none, 1 round Earth, 2 ITM double ITM_calculate_attenuation(SGGeod tx_pos, double freq, int ground_to_air); + double LOS_calculate_attenuation(SGGeod tx_pos, double freq, int ground_to_air); public: @@ -56,8 +57,9 @@ public: void setFrequency(double freq, int radio); double getFrequency(int radio); void setTxPower(double txpower) { _transmitter_power = txpower; }; - // transmission_type: 1 for ground to air, 2 for air to air, 3 for pilot to ground, 4 for pilot to air - void receiveText(SGGeod tx_pos, double freq, string text, int transmission_type); + // 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 + void receiveATC(SGGeod tx_pos, double freq, string text, int transmission_type); + void receiveChat(SGGeod tx_pos, double freq, string text, int transmission_type); void setPropagationModel(int model) { _propagation_model = model; }; }; -- 2.39.5