From 6179c26a04acfb1060d672c0bf0dc83af8c8b415 Mon Sep 17 00:00:00 2001
From: adrian <adrian@localhost.com>
Date: Fri, 2 Dec 2011 17:38:52 +0200
Subject: [PATCH] Set a couple of properties using the node /sim/radio

Also use correct the polarization calculations, using
Simgear constants for degree to radians conversions
---
 src/Radio/antenna.cxx |  7 ++++--
 src/Radio/antenna.hxx |  8 ++++---
 src/Radio/radio.cxx   | 54 +++++++++++++++++++++++++++++++------------
 src/Radio/radio.hxx   |  2 +-
 4 files changed, 50 insertions(+), 21 deletions(-)

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);