1
0
Fork 0

Document the code better;

Add some checks in the clutter function;
Use string pointers to get materials;
This commit is contained in:
adrian 2011-12-08 15:05:27 +02:00
parent 10e933dc53
commit fec3f47154
4 changed files with 104 additions and 60 deletions

View file

@ -1,6 +1,6 @@
// antenna.cxx -- implementation of FGRadioAntenna // antenna.cxx -- implementation of FGRadioAntenna
// Class to represent a virtual radio antenna properties // Class to represent a virtual radio antenna properties
// Written by Adrian Musceac, started December 2011. // Written by Adrian Musceac YO8RZZ, started December 2011.
// //
// This program is free software; you can redistribute it and/or // This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as // modify it under the terms of the GNU General Public License as
@ -34,8 +34,8 @@ FGRadioAntenna::FGRadioAntenna(string type) {
_mirror_y = 1; // normally we want to mirror these axis because the pattern is simetric _mirror_y = 1; // normally we want to mirror these axis because the pattern is simetric
_mirror_z = 1; _mirror_z = 1;
_invert_ground = 0; _invert_ground = 0; // TODO: use for inverting the antenna ground, for instance aircraft body reflection
load_antenna_pattern(type); load_NEC_antenna_pattern(type);
} }
FGRadioAntenna::~FGRadioAntenna() { FGRadioAntenna::~FGRadioAntenna() {
@ -44,9 +44,9 @@ FGRadioAntenna::~FGRadioAntenna() {
delete point_gain; delete point_gain;
} }
_pattern.clear(); _pattern.clear();
} }
// WIP
double FGRadioAntenna::calculate_gain(double bearing, double angle) { double FGRadioAntenna::calculate_gain(double bearing, double angle) {
// TODO: what if the pattern is assimetric? // TODO: what if the pattern is assimetric?
@ -58,7 +58,7 @@ double FGRadioAntenna::calculate_gain(double bearing, double angle) {
azimuth += azimuth % 2; azimuth += azimuth % 2;
int elevation = (int)floor(angle); int elevation = (int)floor(angle);
elevation += elevation % 2; elevation += elevation % 2;
cerr << "Bearing: " << bearing << " angle: " << angle << " azimuth: " << azimuth << " elevation: " << elevation << endl; //cerr << "Bearing: " << bearing << " angle: " << angle << " azimuth: " << azimuth << " elevation: " << elevation << endl;
for (unsigned i =0; i < _pattern.size(); i++) { for (unsigned i =0; i < _pattern.size(); i++) {
AntennaGain *point_gain = _pattern[i]; AntennaGain *point_gain = _pattern[i];
@ -71,13 +71,11 @@ double FGRadioAntenna::calculate_gain(double bearing, double angle) {
} }
void FGRadioAntenna::load_NEC_antenna_pattern(string type) {
/*** load external plot file generated by NEC2
***/
void FGRadioAntenna::load_antenna_pattern(string type) {
SGPath pattern_file(fgGetString("/sim/fg-home")); //SGPath pattern_file(fgGetString("/sim/fg-home"));
pattern_file.append("antennas"); SGPath pattern_file(globals->get_fg_root());
pattern_file.append("Navaids/Antennas");
pattern_file.append(type + ".txt"); pattern_file.append(type + ".txt");
if (!pattern_file.exists()) { if (!pattern_file.exists()) {
return; return;
@ -100,6 +98,4 @@ void FGRadioAntenna::load_antenna_pattern(string type) {
datapoint->gain = gain; datapoint->gain = gain;
_pattern.push_back(datapoint); _pattern.push_back(datapoint);
} }
} }

View file

@ -1,6 +1,6 @@
// antenna.hxx -- FGRadioAntenna: class to represent antenna properties // antenna.hxx -- FGRadioAntenna: class to represent antenna properties
// //
// Written by Adrian Musceac, started December 2011. // Written by Adrian Musceac YO8RZZ, started December 2011.
// //
// This program is free software; you can redistribute it and/or // This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as // modify it under the terms of the GNU General Public License as
@ -32,8 +32,16 @@ using std::string;
class FGRadioAntenna class FGRadioAntenna
{ {
private: private:
void load_antenna_pattern(string type);
int _mirror_y; /*** load external plot file generated by NEC2. needs to have a txt extension
* when naming plots, use the following scheme: type_frequencyMHz.txt
* eg: yagi_110.txt or LPDA_333.txt
* @param: name of file
* @return: none
***/
void load_NEC_antenna_pattern(string type);
int _mirror_y;
int _mirror_z; int _mirror_z;
int _invert_ground; int _invert_ground;
double _heading_deg; double _heading_deg;
@ -51,7 +59,14 @@ public:
FGRadioAntenna(string type); FGRadioAntenna(string type);
~FGRadioAntenna(); ~FGRadioAntenna();
/*** calculate far-field antenna gain on a 3D volume around it
* @param: bearing to the other station, vertical angle (some call it theta)
* @return: gain relative to maximum normalized gain. will be negative in all cases
***/
double calculate_gain(double bearing, double angle); 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 ;}; /// some convenience setters and getters (unused for now)
inline void set_heading(double heading_deg) {_heading_deg = heading_deg ;};
inline void set_elevation_angle(double elevation_angle_deg) {_elevation_angle_deg = elevation_angle_deg ;};
}; };

View file

@ -1,6 +1,6 @@
// radio.cxx -- implementation of FGRadio // radio.cxx -- implementation of FGRadio
// Class to manage radio propagation using the ITM model // Class to manage radio propagation using the ITM model
// Written by Adrian Musceac, started August 2011. // Written by Adrian Musceac YO8RZZ, started August 2011.
// //
// This program is free software; you can redistribute it and/or // This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as // modify it under the terms of the GNU General Public License as
@ -291,7 +291,7 @@ double FGRadioTransmission::ITM_calculate_attenuation(SGGeod pos, double freq, i
double delta_last = fmod(distance_m, point_distance); double delta_last = fmod(distance_m, point_distance);
deque<double> elevations; deque<double> elevations;
deque<string> materials; deque<string*> materials;
double elevation_under_pilot = 0.0; double elevation_under_pilot = 0.0;
@ -329,42 +329,48 @@ double FGRadioTransmission::ITM_calculate_attenuation(SGGeod pos, double freq, i
elevations.push_back(elevation_m); elevations.push_back(elevation_m);
if(mat) { if(mat) {
const std::vector<string> mat_names = mat->get_names(); const std::vector<string> mat_names = mat->get_names();
materials.push_back(mat_names[0]); string* name = new string(mat_names[0]);
materials.push_back(name);
} }
else { else {
materials.push_back("None"); string* no_material = new string("None");
materials.push_back(no_material);
} }
} }
else { else {
elevations.push_front(elevation_m); elevations.push_front(elevation_m);
if(mat) { if(mat) {
const std::vector<string> mat_names = mat->get_names(); const std::vector<string> mat_names = mat->get_names();
materials.push_front(mat_names[0]); string* name = new string(mat_names[0]);
materials.push_front(name);
} }
else { else {
materials.push_front("None"); string* no_material = new string("None");
materials.push_front(no_material);
} }
} }
} }
else { else {
if((transmission_type == 3) || (transmission_type == 4)) { if((transmission_type == 3) || (transmission_type == 4)) {
elevations.push_back(0.0); elevations.push_back(0.0);
materials.push_back("None"); string* no_material = new string("None");
materials.push_back(no_material);
} }
else { else {
string* no_material = new string("None");
elevations.push_front(0.0); elevations.push_front(0.0);
materials.push_front("None"); materials.push_front(no_material);
} }
} }
} }
if((transmission_type == 3) || (transmission_type == 4)) { if((transmission_type == 3) || (transmission_type == 4)) {
elevations.push_front(elevation_under_pilot); elevations.push_front(elevation_under_pilot);
if (delta_last > (point_distance / 2) ) // only add last point if it's farther than half point_distance //if (delta_last > (point_distance / 2) ) // only add last point if it's farther than half point_distance
elevations.push_back(elevation_under_sender); elevations.push_back(elevation_under_sender);
} }
else { else {
elevations.push_back(elevation_under_pilot); elevations.push_back(elevation_under_pilot);
if (delta_last > (point_distance / 2) ) //if (delta_last > (point_distance / 2) )
elevations.push_front(elevation_under_sender); elevations.push_front(elevation_under_sender);
} }
@ -452,18 +458,21 @@ double FGRadioTransmission::ITM_calculate_attenuation(SGGeod pos, double freq, i
//_root_node->setDoubleValue("station[0]/rx-pattern-gain", rx_pattern_gain); //_root_node->setDoubleValue("station[0]/rx-pattern-gain", rx_pattern_gain);
delete[] itm_elev; delete[] itm_elev;
for (unsigned i =0; i < materials.size(); i++) {
delete materials[i];
}
return signal; return signal;
} }
void FGRadioTransmission::calculate_clutter_loss(double freq, double itm_elev[], deque<string> &materials, void FGRadioTransmission::calculate_clutter_loss(double freq, double itm_elev[], deque<string*> &materials,
double transmitter_height, double receiver_height, int p_mode, double transmitter_height, double receiver_height, int p_mode,
double horizons[], double &clutter_loss) { double horizons[], double &clutter_loss) {
double distance_m = itm_elev[0] * itm_elev[1]; // only consider elevation points double distance_m = itm_elev[0] * itm_elev[1]; // only consider elevation points
unsigned mat_size = materials.size();
if (p_mode == 0) { // LOS: take each point and see how clutter height affects first Fresnel zone if (p_mode == 0) { // LOS: take each point and see how clutter height affects first Fresnel zone
int mat = 0; int mat = 0;
int j=1; int j=1;
@ -471,6 +480,9 @@ void FGRadioTransmission::calculate_clutter_loss(double freq, double itm_elev[],
double clutter_height = 0.0; // mean clutter height for a certain terrain type double clutter_height = 0.0; // mean clutter height for a certain terrain type
double clutter_density = 0.0; // percent of reflected wave double clutter_density = 0.0; // percent of reflected wave
if((unsigned)mat >= mat_size) {
break;
}
get_material_properties(materials[mat], clutter_height, clutter_density); get_material_properties(materials[mat], clutter_height, clutter_density);
double grad = fabs(itm_elev[2] + transmitter_height - itm_elev[(int)itm_elev[0] + 2] + receiver_height) / distance_m; double grad = fabs(itm_elev[2] + transmitter_height - itm_elev[(int)itm_elev[0] + 2] + receiver_height) / distance_m;
@ -522,6 +534,10 @@ void FGRadioTransmission::calculate_clutter_loss(double freq, double itm_elev[],
break; break;
double clutter_height = 0.0; // mean clutter height for a certain terrain type double clutter_height = 0.0; // mean clutter height for a certain terrain type
double clutter_density = 0.0; // percent of reflected wave double clutter_density = 0.0; // percent of reflected wave
if((unsigned)mat >= mat_size) {
break;
}
get_material_properties(materials[mat], clutter_height, clutter_density); get_material_properties(materials[mat], clutter_height, clutter_density);
double grad = fabs(itm_elev[2] + transmitter_height - itm_elev[num_points_1st + 2] + clutter_height) / distance_m; double grad = fabs(itm_elev[2] + transmitter_height - itm_elev[num_points_1st + 2] + clutter_height) / distance_m;
@ -566,6 +582,10 @@ void FGRadioTransmission::calculate_clutter_loss(double freq, double itm_elev[],
break; break;
double clutter_height = 0.0; // mean clutter height for a certain terrain type double clutter_height = 0.0; // mean clutter height for a certain terrain type
double clutter_density = 0.0; // percent of reflected wave double clutter_density = 0.0; // percent of reflected wave
if((unsigned)mat >= mat_size) {
break;
}
get_material_properties(materials[mat], clutter_height, clutter_density); get_material_properties(materials[mat], clutter_height, clutter_density);
double grad = fabs(itm_elev[last+1] + clutter_height - itm_elev[(int)itm_elev[0] + 2] + receiver_height) / distance_m; double grad = fabs(itm_elev[last+1] + clutter_height - itm_elev[(int)itm_elev[0] + 2] + receiver_height) / distance_m;
@ -618,6 +638,9 @@ void FGRadioTransmission::calculate_clutter_loss(double freq, double itm_elev[],
break; break;
double clutter_height = 0.0; // mean clutter height for a certain terrain type double clutter_height = 0.0; // mean clutter height for a certain terrain type
double clutter_density = 0.0; // percent of reflected wave double clutter_density = 0.0; // percent of reflected wave
if((unsigned)mat >= mat_size) {
break;
}
get_material_properties(materials[mat], clutter_height, clutter_density); get_material_properties(materials[mat], clutter_height, clutter_density);
double grad = fabs(itm_elev[2] + transmitter_height - itm_elev[num_points_1st + 2] + clutter_height) / distance_m; double grad = fabs(itm_elev[2] + transmitter_height - itm_elev[num_points_1st + 2] + clutter_height) / distance_m;
@ -650,6 +673,7 @@ void FGRadioTransmission::calculate_clutter_loss(double freq, double itm_elev[],
// no losses // no losses
} }
j++; j++;
mat++;
last = k; last = k;
} }
mat +=1; mat +=1;
@ -661,6 +685,9 @@ void FGRadioTransmission::calculate_clutter_loss(double freq, double itm_elev[],
break; break;
double clutter_height = 0.0; // mean clutter height for a certain terrain type double clutter_height = 0.0; // mean clutter height for a certain terrain type
double clutter_density = 0.0; // percent of reflected wave double clutter_density = 0.0; // percent of reflected wave
if((unsigned)mat >= mat_size) {
break;
}
get_material_properties(materials[mat], clutter_height, clutter_density); get_material_properties(materials[mat], clutter_height, clutter_density);
double grad = fabs(itm_elev[last+1] + clutter_height - itm_elev[num_points_1st + num_points_2nd + 2] + clutter_height) / distance_m; double grad = fabs(itm_elev[last+1] + clutter_height - itm_elev[num_points_1st + num_points_2nd + 2] + clutter_height) / distance_m;
@ -705,6 +732,9 @@ void FGRadioTransmission::calculate_clutter_loss(double freq, double itm_elev[],
break; break;
double clutter_height = 0.0; // mean clutter height for a certain terrain type double clutter_height = 0.0; // mean clutter height for a certain terrain type
double clutter_density = 0.0; // percent of reflected wave double clutter_density = 0.0; // percent of reflected wave
if((unsigned)mat >= mat_size) {
break;
}
get_material_properties(materials[mat], clutter_height, clutter_density); get_material_properties(materials[mat], clutter_height, clutter_density);
double grad = fabs(itm_elev[last2+1] + clutter_height - itm_elev[(int)itm_elev[0] + 2] + receiver_height) / distance_m; double grad = fabs(itm_elev[last2+1] + clutter_height - itm_elev[(int)itm_elev[0] + 2] + receiver_height) / distance_m;
@ -751,107 +781,110 @@ void FGRadioTransmission::calculate_clutter_loss(double freq, double itm_elev[],
} }
void FGRadioTransmission::get_material_properties(string mat_name, double &height, double &density) { void FGRadioTransmission::get_material_properties(string* mat_name, double &height, double &density) {
if(mat_name == "Landmass") { if(!mat_name)
return;
if(*mat_name == "Landmass") {
height = 15.0; height = 15.0;
density = 0.2; density = 0.2;
} }
else if(mat_name == "SomeSort") { else if(*mat_name == "SomeSort") {
height = 15.0; height = 15.0;
density = 0.2; density = 0.2;
} }
else if(mat_name == "Island") { else if(*mat_name == "Island") {
height = 15.0; height = 15.0;
density = 0.2; density = 0.2;
} }
else if(mat_name == "Default") { else if(*mat_name == "Default") {
height = 15.0; height = 15.0;
density = 0.2; density = 0.2;
} }
else if(mat_name == "EvergreenBroadCover") { else if(*mat_name == "EvergreenBroadCover") {
height = 20.0; height = 20.0;
density = 0.2; density = 0.2;
} }
else if(mat_name == "EvergreenForest") { else if(*mat_name == "EvergreenForest") {
height = 20.0; height = 20.0;
density = 0.2; density = 0.2;
} }
else if(mat_name == "DeciduousBroadCover") { else if(*mat_name == "DeciduousBroadCover") {
height = 15.0; height = 15.0;
density = 0.3; density = 0.3;
} }
else if(mat_name == "DeciduousForest") { else if(*mat_name == "DeciduousForest") {
height = 15.0; height = 15.0;
density = 0.3; density = 0.3;
} }
else if(mat_name == "MixedForestCover") { else if(*mat_name == "MixedForestCover") {
height = 20.0; height = 20.0;
density = 0.25; density = 0.25;
} }
else if(mat_name == "MixedForest") { else if(*mat_name == "MixedForest") {
height = 15.0; height = 15.0;
density = 0.25; density = 0.25;
} }
else if(mat_name == "RainForest") { else if(*mat_name == "RainForest") {
height = 25.0; height = 25.0;
density = 0.55; density = 0.55;
} }
else if(mat_name == "EvergreenNeedleCover") { else if(*mat_name == "EvergreenNeedleCover") {
height = 15.0; height = 15.0;
density = 0.2; density = 0.2;
} }
else if(mat_name == "WoodedTundraCover") { else if(*mat_name == "WoodedTundraCover") {
height = 5.0; height = 5.0;
density = 0.15; density = 0.15;
} }
else if(mat_name == "DeciduousNeedleCover") { else if(*mat_name == "DeciduousNeedleCover") {
height = 5.0; height = 5.0;
density = 0.2; density = 0.2;
} }
else if(mat_name == "ScrubCover") { else if(*mat_name == "ScrubCover") {
height = 3.0; height = 3.0;
density = 0.15; density = 0.15;
} }
else if(mat_name == "BuiltUpCover") { else if(*mat_name == "BuiltUpCover") {
height = 30.0; height = 30.0;
density = 0.7; density = 0.7;
} }
else if(mat_name == "Urban") { else if(*mat_name == "Urban") {
height = 30.0; height = 30.0;
density = 0.7; density = 0.7;
} }
else if(mat_name == "Construction") { else if(*mat_name == "Construction") {
height = 30.0; height = 30.0;
density = 0.7; density = 0.7;
} }
else if(mat_name == "Industrial") { else if(*mat_name == "Industrial") {
height = 30.0; height = 30.0;
density = 0.7; density = 0.7;
} }
else if(mat_name == "Port") { else if(*mat_name == "Port") {
height = 30.0; height = 30.0;
density = 0.7; density = 0.7;
} }
else if(mat_name == "Town") { else if(*mat_name == "Town") {
height = 10.0; height = 10.0;
density = 0.5; density = 0.5;
} }
else if(mat_name == "SubUrban") { else if(*mat_name == "SubUrban") {
height = 10.0; height = 10.0;
density = 0.5; density = 0.5;
} }
else if(mat_name == "CropWoodCover") { else if(*mat_name == "CropWoodCover") {
height = 10.0; height = 10.0;
density = 0.1; density = 0.1;
} }
else if(mat_name == "CropWood") { else if(*mat_name == "CropWood") {
height = 10.0; height = 10.0;
density = 0.1; density = 0.1;
} }
else if(mat_name == "AgroForest") { else if(*mat_name == "AgroForest") {
height = 10.0; height = 10.0;
density = 0.1; density = 0.1;
} }

View file

@ -1,6 +1,6 @@
// radio.hxx -- FGRadio: class to manage radio propagation // radio.hxx -- FGRadio: class to manage radio propagation
// //
// Written by Adrian Musceac, started August 2011. // Written by Adrian Musceac YO8RZZ, started August 2011.
// //
// This program is free software; you can redistribute it and/or // This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as // modify it under the terms of the GNU General Public License as
@ -74,7 +74,7 @@ private:
* @param: frequency, elevation data, terrain type, horizon distances, calculated loss * @param: frequency, elevation data, terrain type, horizon distances, calculated loss
* @return: none * @return: none
***/ ***/
void calculate_clutter_loss(double freq, double itm_elev[], std::deque<string> &materials, void calculate_clutter_loss(double freq, double itm_elev[], std::deque<string*> &materials,
double transmitter_height, double receiver_height, int p_mode, double transmitter_height, double receiver_height, int p_mode,
double horizons[], double &clutter_loss); double horizons[], double &clutter_loss);
@ -82,7 +82,7 @@ private:
* @param: terrain type, median clutter height, radiowave attenuation factor * @param: terrain type, median clutter height, radiowave attenuation factor
* @return: none * @return: none
***/ ***/
void get_material_properties(string mat_name, double &height, double &density); void get_material_properties(string* mat_name, double &height, double &density);
public: public: