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
// 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
// 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_z = 1;
_invert_ground = 0;
load_antenna_pattern(type);
_invert_ground = 0; // TODO: use for inverting the antenna ground, for instance aircraft body reflection
load_NEC_antenna_pattern(type);
}
FGRadioAntenna::~FGRadioAntenna() {
@ -44,9 +44,9 @@ FGRadioAntenna::~FGRadioAntenna() {
delete point_gain;
}
_pattern.clear();
}
// WIP
double FGRadioAntenna::calculate_gain(double bearing, double angle) {
// TODO: what if the pattern is assimetric?
@ -58,7 +58,7 @@ double FGRadioAntenna::calculate_gain(double bearing, double angle) {
azimuth += azimuth % 2;
int elevation = (int)floor(angle);
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++) {
AntennaGain *point_gain = _pattern[i];
@ -71,13 +71,11 @@ double FGRadioAntenna::calculate_gain(double bearing, double angle) {
}
/*** load external plot file generated by NEC2
***/
void FGRadioAntenna::load_antenna_pattern(string type) {
void FGRadioAntenna::load_NEC_antenna_pattern(string type) {
SGPath pattern_file(fgGetString("/sim/fg-home"));
pattern_file.append("antennas");
//SGPath pattern_file(fgGetString("/sim/fg-home"));
SGPath pattern_file(globals->get_fg_root());
pattern_file.append("Navaids/Antennas");
pattern_file.append(type + ".txt");
if (!pattern_file.exists()) {
return;
@ -100,6 +98,4 @@ void FGRadioAntenna::load_antenna_pattern(string type) {
datapoint->gain = gain;
_pattern.push_back(datapoint);
}
}

View file

@ -1,6 +1,6 @@
// 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
// modify it under the terms of the GNU General Public License as
@ -32,8 +32,16 @@ using std::string;
class FGRadioAntenna
{
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 _invert_ground;
double _heading_deg;
@ -51,7 +59,14 @@ public:
FGRadioAntenna(string type);
~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);
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
// 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
// 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);
deque<double> elevations;
deque<string> materials;
deque<string*> materials;
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);
if(mat) {
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 {
materials.push_back("None");
string* no_material = new string("None");
materials.push_back(no_material);
}
}
else {
elevations.push_front(elevation_m);
if(mat) {
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 {
materials.push_front("None");
string* no_material = new string("None");
materials.push_front(no_material);
}
}
}
else {
if((transmission_type == 3) || (transmission_type == 4)) {
elevations.push_back(0.0);
materials.push_back("None");
string* no_material = new string("None");
materials.push_back(no_material);
}
else {
string* no_material = new string("None");
elevations.push_front(0.0);
materials.push_front("None");
materials.push_front(no_material);
}
}
}
if((transmission_type == 3) || (transmission_type == 4)) {
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);
}
else {
elevations.push_back(elevation_under_pilot);
if (delta_last > (point_distance / 2) )
//if (delta_last > (point_distance / 2) )
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);
delete[] itm_elev;
for (unsigned i =0; i < materials.size(); i++) {
delete materials[i];
}
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 horizons[], double &clutter_loss) {
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
int mat = 0;
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_density = 0.0; // percent of reflected wave
if((unsigned)mat >= mat_size) {
break;
}
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;
@ -522,6 +534,10 @@ void FGRadioTransmission::calculate_clutter_loss(double freq, double itm_elev[],
break;
double clutter_height = 0.0; // mean clutter height for a certain terrain type
double clutter_density = 0.0; // percent of reflected wave
if((unsigned)mat >= mat_size) {
break;
}
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;
@ -566,6 +582,10 @@ void FGRadioTransmission::calculate_clutter_loss(double freq, double itm_elev[],
break;
double clutter_height = 0.0; // mean clutter height for a certain terrain type
double clutter_density = 0.0; // percent of reflected wave
if((unsigned)mat >= mat_size) {
break;
}
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;
@ -618,6 +638,9 @@ void FGRadioTransmission::calculate_clutter_loss(double freq, double itm_elev[],
break;
double clutter_height = 0.0; // mean clutter height for a certain terrain type
double clutter_density = 0.0; // percent of reflected wave
if((unsigned)mat >= mat_size) {
break;
}
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;
@ -650,6 +673,7 @@ void FGRadioTransmission::calculate_clutter_loss(double freq, double itm_elev[],
// no losses
}
j++;
mat++;
last = k;
}
mat +=1;
@ -661,6 +685,9 @@ void FGRadioTransmission::calculate_clutter_loss(double freq, double itm_elev[],
break;
double clutter_height = 0.0; // mean clutter height for a certain terrain type
double clutter_density = 0.0; // percent of reflected wave
if((unsigned)mat >= mat_size) {
break;
}
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;
@ -705,6 +732,9 @@ void FGRadioTransmission::calculate_clutter_loss(double freq, double itm_elev[],
break;
double clutter_height = 0.0; // mean clutter height for a certain terrain type
double clutter_density = 0.0; // percent of reflected wave
if((unsigned)mat >= mat_size) {
break;
}
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;
@ -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;
density = 0.2;
}
else if(mat_name == "SomeSort") {
else if(*mat_name == "SomeSort") {
height = 15.0;
density = 0.2;
}
else if(mat_name == "Island") {
else if(*mat_name == "Island") {
height = 15.0;
density = 0.2;
}
else if(mat_name == "Default") {
else if(*mat_name == "Default") {
height = 15.0;
density = 0.2;
}
else if(mat_name == "EvergreenBroadCover") {
else if(*mat_name == "EvergreenBroadCover") {
height = 20.0;
density = 0.2;
}
else if(mat_name == "EvergreenForest") {
else if(*mat_name == "EvergreenForest") {
height = 20.0;
density = 0.2;
}
else if(mat_name == "DeciduousBroadCover") {
else if(*mat_name == "DeciduousBroadCover") {
height = 15.0;
density = 0.3;
}
else if(mat_name == "DeciduousForest") {
else if(*mat_name == "DeciduousForest") {
height = 15.0;
density = 0.3;
}
else if(mat_name == "MixedForestCover") {
else if(*mat_name == "MixedForestCover") {
height = 20.0;
density = 0.25;
}
else if(mat_name == "MixedForest") {
else if(*mat_name == "MixedForest") {
height = 15.0;
density = 0.25;
}
else if(mat_name == "RainForest") {
else if(*mat_name == "RainForest") {
height = 25.0;
density = 0.55;
}
else if(mat_name == "EvergreenNeedleCover") {
else if(*mat_name == "EvergreenNeedleCover") {
height = 15.0;
density = 0.2;
}
else if(mat_name == "WoodedTundraCover") {
else if(*mat_name == "WoodedTundraCover") {
height = 5.0;
density = 0.15;
}
else if(mat_name == "DeciduousNeedleCover") {
else if(*mat_name == "DeciduousNeedleCover") {
height = 5.0;
density = 0.2;
}
else if(mat_name == "ScrubCover") {
else if(*mat_name == "ScrubCover") {
height = 3.0;
density = 0.15;
}
else if(mat_name == "BuiltUpCover") {
else if(*mat_name == "BuiltUpCover") {
height = 30.0;
density = 0.7;
}
else if(mat_name == "Urban") {
else if(*mat_name == "Urban") {
height = 30.0;
density = 0.7;
}
else if(mat_name == "Construction") {
else if(*mat_name == "Construction") {
height = 30.0;
density = 0.7;
}
else if(mat_name == "Industrial") {
else if(*mat_name == "Industrial") {
height = 30.0;
density = 0.7;
}
else if(mat_name == "Port") {
else if(*mat_name == "Port") {
height = 30.0;
density = 0.7;
}
else if(mat_name == "Town") {
else if(*mat_name == "Town") {
height = 10.0;
density = 0.5;
}
else if(mat_name == "SubUrban") {
else if(*mat_name == "SubUrban") {
height = 10.0;
density = 0.5;
}
else if(mat_name == "CropWoodCover") {
else if(*mat_name == "CropWoodCover") {
height = 10.0;
density = 0.1;
}
else if(mat_name == "CropWood") {
else if(*mat_name == "CropWood") {
height = 10.0;
density = 0.1;
}
else if(mat_name == "AgroForest") {
else if(*mat_name == "AgroForest") {
height = 10.0;
density = 0.1;
}

View file

@ -1,6 +1,6 @@
// 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
// 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
* @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 horizons[], double &clutter_loss);
@ -82,7 +82,7 @@ private:
* @param: terrain type, median clutter height, radiowave attenuation factor
* @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: