From 500086adecb383c18ee3e19421211e515238a99d Mon Sep 17 00:00:00 2001 From: adrian Date: Sun, 4 Dec 2011 21:59:38 +0200 Subject: [PATCH] Read antenna radiation pattern from file --- src/Radio/antenna.cxx | 36 +++++++++++++++++++++++++++++++----- src/Radio/antenna.hxx | 6 +++--- src/Radio/radio.cxx | 29 ++++++++++++++++++++++++----- src/Radio/radio.hxx | 4 +++- 4 files changed, 61 insertions(+), 14 deletions(-) diff --git a/src/Radio/antenna.cxx b/src/Radio/antenna.cxx index 8ebb154f0..7cfdd6285 100644 --- a/src/Radio/antenna.cxx +++ b/src/Radio/antenna.cxx @@ -32,17 +32,37 @@ using namespace std; FGRadioAntenna::FGRadioAntenna(string type) { - _mirror_y = 1; + _mirror_y = 1; // normally we want to mirror these axis because the pattern is simetric _mirror_z = 1; - _invert_ground = 0; + _invert_ground = 0; load_antenna_pattern(type); } FGRadioAntenna::~FGRadioAntenna() { + _pattern.clear(); } -double FGRadioAntenna::calculate_gain(double azimuth, double elevation) { +double FGRadioAntenna::calculate_gain(double bearing, double angle) { + + // TODO: what if the pattern is assimetric? + bearing = fabs(bearing); + if (bearing > 180) + bearing = 360 - bearing; + // for plots with 2 degrees resolution: + int azimuth = (int)floor(bearing); + azimuth += azimuth % 2; + int elevation = (int)floor(angle); + elevation += elevation % 2; + + for (unsigned int i =0; i < _pattern.size(); i++) { + AntennaGain point_gain = _pattern[i]; + + if ( (azimuth == point_gain.azimuth) && (elevation == point_gain.elevation)) { + return point_gain.gain; + } + } + return 0; } @@ -63,10 +83,16 @@ void FGRadioAntenna::load_antenna_pattern(string type) { double gain; while(!file_in.eof()) { file_in >> heading >> elevation >> gain; - cerr << "head: " << heading << " elev: " << elevation << " gain: " << gain << endl; + if( (_mirror_y == 1) && (heading > 180) ) { + continue; + } + if ( (_mirror_z == 1) && (elevation < 0) ) { + continue; + } + //cerr << "head: " << heading << " elev: " << elevation << " gain: " << gain << endl; AntennaGain datapoint; datapoint.azimuth = heading; - datapoint.elevation = elevation; + datapoint.elevation = 90.0 - fabs(elevation); datapoint.gain = gain; _pattern.push_back(datapoint); } diff --git a/src/Radio/antenna.hxx b/src/Radio/antenna.hxx index f0c3877d8..81aad2367 100644 --- a/src/Radio/antenna.hxx +++ b/src/Radio/antenna.hxx @@ -51,7 +51,7 @@ public: FGRadioAntenna(string type); ~FGRadioAntenna(); - double calculate_gain(double azimuth, double elevation); - - + double calculate_gain(double bearing, double angle); + void set_heading(double heading_deg) {_heading_deg = heading_deg ;}; + void set_elevation_angle(double elevation_angle_deg) {_elevation_angle_deg = elevation_angle_deg ;}; }; diff --git a/src/Radio/radio.cxx b/src/Radio/radio.cxx index be8dc1ef3..ff73701d5 100644 --- a/src/Radio/radio.cxx +++ b/src/Radio/radio.cxx @@ -66,6 +66,8 @@ FGRadioTransmission::FGRadioTransmission() { _root_node = fgGetNode("sim/radio", true); _terrain_sampling_distance = _root_node->getDoubleValue("sampling-distance", 90.0); // regular SRTM is 90 meters + + } FGRadioTransmission::~FGRadioTransmission() @@ -202,11 +204,8 @@ double FGRadioTransmission::ITM_calculate_attenuation(SGGeod pos, double freq, i double eps_dielect=15.0; double sgm_conductivity = 0.005; double eno = 301.0; - double frq_mhz; - if( (freq < 118.0) || (freq > 137.0) ) - frq_mhz = 125.0; // sane value, middle of bandplan - else - frq_mhz = freq; + double frq_mhz = freq; + int radio_climate = 5; // continental temperate int pol= _polarization; double conf = 0.90; // 90% of situations and time, take into account speed @@ -233,6 +232,7 @@ double FGRadioTransmission::ITM_calculate_attenuation(SGGeod pos, double freq, i double own_lat = fgGetDouble("/position/latitude-deg"); double own_lon = fgGetDouble("/position/longitude-deg"); double own_alt_ft = fgGetDouble("/position/altitude-ft"); + double own_heading = fgGetDouble("/orientation/heading-deg"); double own_alt= own_alt_ft * SG_FEET_TO_METER; @@ -257,6 +257,7 @@ double FGRadioTransmission::ITM_calculate_attenuation(SGGeod pos, double freq, i double point_distance= _terrain_sampling_distance; double course = SGGeodesy::courseRad(own_pos_c, sender_pos_c); + double reverse_course = SGGeodesy::courseRad(sender_pos_c, own_pos_c); double distance_m = SGGeodesy::distanceM(own_pos, sender_pos); double probe_distance = 0.0; /** If distance larger than this value (300 km), assume reception imposssible */ @@ -400,6 +401,22 @@ double FGRadioTransmission::ITM_calculate_attenuation(SGGeod pos, double freq, i //cerr << "Clutter loss: " << clutter_loss << endl; //if (errnum == 4) // if parameters are outside sane values for lrprop, the alternative method is used // return -1; + double sender_heading = 270.0; // due West + double tx_antenna_bearing = sender_heading - reverse_course; + double rx_antenna_bearing = own_heading - course; + double rx_elev_angle = atan((itm_elev[2] + transmitter_height - itm_elev[(int)itm_elev[0] + 2] + receiver_height) / distance_m) * SGD_RADIANS_TO_DEGREES; + double tx_elev_angle = 0.0 - rx_elev_angle; + _TX_antenna = new FGRadioAntenna("Plot2"); + _TX_antenna->set_heading(sender_heading); + _TX_antenna->set_elevation_angle(0); + double tx_pattern_gain = _TX_antenna->calculate_gain(tx_antenna_bearing, tx_elev_angle); + _RX_antenna = new FGRadioAntenna("Plot2"); + _RX_antenna->set_heading(own_heading); + _RX_antenna->set_elevation_angle(fgGetDouble("/orientation/pitch-deg")); + double rx_pattern_gain = _RX_antenna->calculate_gain(rx_antenna_bearing, rx_elev_angle); + + delete _TX_antenna; + delete _RX_antenna; signal = link_budget - dbloss - clutter_loss + pol_loss; double signal_strength_dbm = signal_strength - dbloss - clutter_loss + pol_loss; double field_strength_uV = dbm_to_microvolt(signal_strength_dbm); @@ -407,6 +424,8 @@ double FGRadioTransmission::ITM_calculate_attenuation(SGGeod pos, double freq, i _root_node->setDoubleValue("station[0]/field-strength-uV", field_strength_uV); _root_node->setDoubleValue("station[0]/signal", signal); _root_node->setDoubleValue("station[0]/tx-erp", tx_erp); + _root_node->setDoubleValue("station[0]/tx-pattern-gain", tx_pattern_gain); + _root_node->setDoubleValue("station[0]/rx-pattern-gain", rx_pattern_gain); return signal; } diff --git a/src/Radio/radio.hxx b/src/Radio/radio.hxx index 7b07d927e..77ba57bb0 100644 --- a/src/Radio/radio.hxx +++ b/src/Radio/radio.hxx @@ -28,7 +28,7 @@ #include #include - +#include "antenna.hxx" using std::string; @@ -48,6 +48,8 @@ private: double _tx_antenna_gain; double _rx_line_losses; double _tx_line_losses; + FGRadioAntenna* _TX_antenna; + FGRadioAntenna* _RX_antenna; double _terrain_sampling_distance; int _polarization; std::map _mat_database; -- 2.39.5