diff --git a/src/Radio/antenna.cxx b/src/Radio/antenna.cxx index 22496d81e..dc6983723 100644 --- a/src/Radio/antenna.cxx +++ b/src/Radio/antenna.cxx @@ -33,19 +33,22 @@ FGRadioAntenna::FGRadioAntenna() { _mirror_y = 1; _mirror_z = 1; + _invert_ground = 0; } FGRadioAntenna::~FGRadioAntenna() { } -double FGRadioAntenna::calculate_gain(double azimuth, double theta) { +double FGRadioAntenna::calculate_gain(double azimuth, double elevation) { return 0; } - +/*** load external plot file generated by NEC4 +* +***/ void FGRadioAntenna::_load_antenna_pattern() { } diff --git a/src/Radio/antenna.hxx b/src/Radio/antenna.hxx index ec5d30253..f24c133ee 100644 --- a/src/Radio/antenna.hxx +++ b/src/Radio/antenna.hxx @@ -33,10 +33,12 @@ private: void _load_antenna_pattern(); int _mirror_y; int _mirror_z; - double _heading; + int _invert_ground; + double _heading_deg; + double _elevation_angle_deg; struct AntennaGain { double azimuth; - double elevation_angle; + double elevation; double gain; }; @@ -47,7 +49,7 @@ public: FGRadioAntenna(); ~FGRadioAntenna(); - double calculate_gain(double azimuth, double theta); + double calculate_gain(double azimuth, double elevation); }; diff --git a/src/Radio/radio.cxx b/src/Radio/radio.cxx index d5211615a..9f21a936e 100644 --- a/src/Radio/radio.cxx +++ b/src/Radio/radio.cxx @@ -63,7 +63,9 @@ FGRadioTransmission::FGRadioTransmission() { _polarization = 1; // default vertical _propagation_model = 2; - _terrain_sampling_distance = fgGetDouble("/sim/radio/sampling-distance", 90.0); // regular SRTM is 90 meters + + _root_node = fgGetNode("sim/radio", true); + _terrain_sampling_distance = _root_node->getDoubleValue("sampling-distance", 90.0); // regular SRTM is 90 meters } FGRadioTransmission::~FGRadioTransmission() @@ -145,7 +147,7 @@ void FGRadioTransmission::receiveATC(SGGeod tx_pos, double freq, string text, in /** write signal strength above threshold to the property tree * to implement a simple S-meter just divide by 3 dB per grade (VHF norm) **/ - fgSetDouble("/sim/radio/comm1-signal", signal); + _root_node->setDoubleValue("station[0]/signal", signal); } } else if ( _propagation_model == 2 ) { @@ -177,7 +179,7 @@ void FGRadioTransmission::receiveATC(SGGeod tx_pos, double freq, string text, in //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); + _root_node->setDoubleValue("station[0]/signal", signal); fgSetDouble("/sim/sound/voices/voice/volume", old_volume); } else { @@ -185,7 +187,7 @@ void FGRadioTransmission::receiveATC(SGGeod tx_pos, double freq, string text, in /** write signal strength above threshold to the property tree * to implement a simple S-meter just divide by 3 dB per grade (VHF norm) **/ - fgSetDouble("/sim/radio/comm1-signal", signal); + _root_node->setDoubleValue("station[0]/signal", signal); } } @@ -302,7 +304,10 @@ double FGRadioTransmission::ITM_calculate_attenuation(SGGeod pos, double freq, i SG_LOG(SG_GENERAL, SG_BULK, "ITM:: RX-height: " << receiver_height << " meters, TX-height: " << transmitter_height << " meters, Distance: " << distance_m << " meters"); - cerr << "ITM:: RX-height: " << receiver_height << " meters, TX-height: " << transmitter_height << " meters, Distance: " << distance_m << " meters" << endl; + //cerr << "ITM:: RX-height: " << receiver_height << " meters, TX-height: " << transmitter_height << " meters, Distance: " << distance_m << " meters" << endl; + _root_node->setDoubleValue("station[0]/rx-height", receiver_height); + _root_node->setDoubleValue("station[0]/tx-height", transmitter_height); + _root_node->setDoubleValue("station[0]/distance", distance_m); unsigned int e_size = (deque<unsigned>::size_type)max_points; @@ -373,24 +378,33 @@ double FGRadioTransmission::ITM_calculate_attenuation(SGGeod pos, double freq, i point_to_point(itm_elev, receiver_height, transmitter_height, eps_dielect, sgm_conductivity, eno, frq_mhz, radio_climate, pol, conf, rel, dbloss, strmode, p_mode, horizons, errnum); - if( fgGetBool( "/sim/radio/use-clutter-attenuation", false ) ) + if( _root_node->getBoolValue( "use-clutter-attenuation", false ) ) clutterLoss(frq_mhz, distance_m, itm_elev, materials, receiver_height, transmitter_height, p_mode, horizons, clutter_loss); } else { point_to_point(itm_elev, transmitter_height, receiver_height, eps_dielect, sgm_conductivity, eno, frq_mhz, radio_climate, pol, conf, rel, dbloss, strmode, p_mode, horizons, errnum); - if( fgGetBool( "/sim/radio/use-clutter-attenuation", false ) ) + if( _root_node->getBoolValue( "use-clutter-attenuation", false ) ) clutterLoss(frq_mhz, distance_m, itm_elev, materials, transmitter_height, receiver_height, p_mode, horizons, clutter_loss); } + + double pol_loss = 0.0; + if (_polarization == 1) { + pol_loss = polarization_loss(); + } SG_LOG(SG_GENERAL, SG_BULK, "ITM:: Link budget: " << link_budget << ", Attenuation: " << dbloss << " dBm, " << strmode << ", Error: " << errnum); - cerr << "ITM:: Link budget: " << link_budget << ", Attenuation: " << dbloss << " dBm, " << strmode << ", Error: " << errnum << endl; - - cerr << "Clutter loss: " << clutter_loss << endl; + //cerr << "ITM:: Link budget: " << link_budget << ", Attenuation: " << dbloss << " dBm, " << strmode << ", Error: " << errnum << endl; + _root_node->setDoubleValue("station[0]/link-budget", link_budget); + _root_node->setDoubleValue("station[0]/terrain-attenuation", dbloss); + _root_node->setStringValue("station[0]/prop-mode", strmode); + _root_node->setDoubleValue("station[0]/clutter-attenuation", clutter_loss); + _root_node->setDoubleValue("station[0]/polarization-attenuation", pol_loss); + //cerr << "Clutter loss: " << clutter_loss << endl; //if (errnum == 4) // if parameters are outside sane values for lrprop, the alternative method is used // return -1; - signal = link_budget - dbloss - clutter_loss; + signal = link_budget - dbloss - clutter_loss + pol_loss; return signal; } @@ -876,15 +890,25 @@ double FGRadioTransmission::polarization_loss() { double theta_deg; double roll = fgGetDouble("/orientation/roll-deg"); + if (fabs(roll) > 85.0) + roll = 85.0; double pitch = fgGetDouble("/orientation/pitch-deg"); - double theta = acos( sqrt( cos(roll) * cos(roll) + cos(pitch) * cos(pitch) )); - if (_polarization == 1) + if (fabs(pitch) > 85.0) + pitch = 85.0; + double theta = fabs( atan( sqrt( + pow(tan(roll * SGD_DEGREES_TO_RADIANS), 2) + + pow(tan(pitch * SGD_DEGREES_TO_RADIANS), 2) )) * SGD_RADIANS_TO_DEGREES); + + if (_polarization == 0) theta_deg = 90.0 - theta; else theta_deg = theta; - if (fabs(theta_deg) > 85.0) // we don't want to converge into infinity + if (theta_deg > 85.0) // we don't want to converge into infinity theta_deg = 85.0; - return 10 * log10(cos(theta_deg) * cos(theta_deg)); + + double loss = 10 * log10( pow(cos(theta_deg * SGD_DEGREES_TO_RADIANS), 2) ); + //cerr << "Polarization loss: " << loss << " dBm " << endl; + return loss; } diff --git a/src/Radio/radio.hxx b/src/Radio/radio.hxx index cafa2b386..92ce66fbc 100644 --- a/src/Radio/radio.hxx +++ b/src/Radio/radio.hxx @@ -51,7 +51,7 @@ private: double _terrain_sampling_distance; int _polarization; std::map<string, double[2]> _mat_database; - + SGPropertyNode *_root_node; int _propagation_model; /// 0 none, 1 round Earth, 2 ITM double polarization_loss(); double ITM_calculate_attenuation(SGGeod tx_pos, double freq, int ground_to_air);