]> git.mxchange.org Git - flightgear.git/commitdiff
Read antenna radiation pattern from file
authoradrian <adrian@localhost.com>
Sun, 4 Dec 2011 19:59:38 +0000 (21:59 +0200)
committeradrian <adrian@localhost.com>
Sun, 4 Dec 2011 19:59:38 +0000 (21:59 +0200)
src/Radio/antenna.cxx
src/Radio/antenna.hxx
src/Radio/radio.cxx
src/Radio/radio.hxx

index 8ebb154f0e08ef7038a8a08a1c4766b74595e575..7cfdd6285348c56dff5939053c4b3fb588017169 100644 (file)
@@ -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);
        }
index f0c3877d8fa33d4df7b0161c4ec22c0e1f554ebb..81aad236769ea0b331d6c1c6486d7e9c43fe7ef8 100644 (file)
@@ -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 ;};
 };
index be8dc1ef339927776dbfa7fed458d41f7e8d50a6..ff73701d582c6a0a39f1273c802c6723b23cbee2 100644 (file)
@@ -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;
 
 }
index 7b07d927e9e4e4b7eef9411f9c68c88dc5a26751..77ba57bb03e5592e469dbf0a9ec561ffcc0bfc23 100644 (file)
@@ -28,7 +28,7 @@
 
 #include <simgear/math/sg_geodesy.hxx>
 #include <simgear/debug/logstream.hxx>
-
+#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<string, double[2]> _mat_database;