first commit
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
include(FlightGearComponent)
|
||||
|
||||
set(SOURCES
|
||||
antenna.cxx
|
||||
radio.cxx
|
||||
)
|
||||
|
||||
set(HEADERS
|
||||
antenna.hxx
|
||||
radio.hxx
|
||||
)
|
||||
|
||||
|
||||
flightgear_component(Radio "${SOURCES}" "${HEADERS}")
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
// antenna.cxx -- implementation of FGRadioAntenna
|
||||
// Class to represent a virtual radio antenna properties
|
||||
// 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
|
||||
// published by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
#include <stdlib.h>
|
||||
#include <fstream>
|
||||
#include <Scenery/scenery.hxx>
|
||||
#include <simgear/io/iostreams/sgstream.hxx>
|
||||
|
||||
#include "antenna.hxx"
|
||||
|
||||
using namespace std;
|
||||
|
||||
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; // TODO: use for inverting the antenna ground, for instance aircraft body reflection
|
||||
load_NEC_antenna_pattern(type);
|
||||
}
|
||||
|
||||
FGRadioAntenna::~FGRadioAntenna() {
|
||||
for (unsigned i =0; i < _pattern.size(); i++) {
|
||||
AntennaGain *point_gain = _pattern[i];
|
||||
delete point_gain;
|
||||
}
|
||||
_pattern.clear();
|
||||
}
|
||||
|
||||
// WIP
|
||||
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;
|
||||
//cerr << "Bearing: " << bearing << " angle: " << angle << " azimuth: " << azimuth << " elevation: " << elevation << endl;
|
||||
for (unsigned 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;
|
||||
}
|
||||
|
||||
|
||||
void FGRadioAntenna::load_NEC_antenna_pattern(string type) {
|
||||
|
||||
//SGPath pattern_file(globals->get_fg_home());
|
||||
SGPath pattern_file(globals->get_fg_root());
|
||||
pattern_file.append("Navaids/Antennas");
|
||||
pattern_file.append(type + ".txt");
|
||||
if (!pattern_file.exists()) {
|
||||
return;
|
||||
}
|
||||
sg_ifstream file_in(pattern_file);
|
||||
int heading, elevation;
|
||||
double gain;
|
||||
while(!file_in.eof()) {
|
||||
file_in >> heading >> elevation >> gain;
|
||||
if( (_mirror_y == 1) && (heading > 180) ) {
|
||||
continue;
|
||||
}
|
||||
if ( (_mirror_z == 1) && (elevation < 0) ) {
|
||||
continue;
|
||||
}
|
||||
//cerr << "head: " << heading << " elev: " << elevation << " gain: " << gain << endl;
|
||||
AntennaGain *datapoint = new AntennaGain;
|
||||
datapoint->azimuth = heading;
|
||||
datapoint->elevation = 90.0 - abs(elevation);
|
||||
datapoint->gain = gain;
|
||||
_pattern.push_back(datapoint);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
// antenna.hxx -- FGRadioAntenna: class to represent antenna properties
|
||||
//
|
||||
// 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
|
||||
// published by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __cplusplus
|
||||
# error This library requires C++
|
||||
#endif
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
#include <simgear/structure/subsystem_mgr.hxx>
|
||||
#include <Main/fg_props.hxx>
|
||||
|
||||
#include <simgear/math/sg_geodesy.hxx>
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
|
||||
|
||||
class FGRadioAntenna
|
||||
{
|
||||
private:
|
||||
|
||||
/*** 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(std::string type);
|
||||
|
||||
int _mirror_y;
|
||||
int _mirror_z;
|
||||
int _invert_ground;
|
||||
double _heading_deg;
|
||||
double _elevation_angle_deg;
|
||||
struct AntennaGain {
|
||||
double azimuth;
|
||||
double elevation;
|
||||
double gain;
|
||||
};
|
||||
SGPath _pattern_file;
|
||||
typedef std::vector<AntennaGain*> AntennaPattern;
|
||||
AntennaPattern _pattern;
|
||||
|
||||
public:
|
||||
|
||||
FGRadioAntenna(std::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);
|
||||
|
||||
/// 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 ;};
|
||||
};
|
||||
+1868
File diff suppressed because it is too large
Load Diff
+1023
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,140 @@
|
||||
// radio.hxx -- FGRadio: class to manage radio propagation
|
||||
//
|
||||
// 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
|
||||
// published by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __cplusplus
|
||||
# error This library requires C++
|
||||
#endif
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
#include <simgear/structure/subsystem_mgr.hxx>
|
||||
#include <deque>
|
||||
#include <Main/fg_props.hxx>
|
||||
|
||||
#include <simgear/math/sg_geodesy.hxx>
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
#include "antenna.hxx"
|
||||
|
||||
|
||||
class FGRadioTransmission
|
||||
{
|
||||
private:
|
||||
|
||||
double _receiver_sensitivity;
|
||||
double _transmitter_power;
|
||||
double _tx_antenna_height;
|
||||
double _rx_antenna_height;
|
||||
double _rx_antenna_gain;
|
||||
double _tx_antenna_gain;
|
||||
double _rx_line_losses;
|
||||
double _tx_line_losses;
|
||||
|
||||
double _terrain_sampling_distance;
|
||||
int _polarization;
|
||||
std::map<std::string, double[2]> _mat_database;
|
||||
SGPropertyNode *_root_node;
|
||||
int _propagation_model; /// 0 none, 1 round Earth, 2 ITM
|
||||
double polarization_loss();
|
||||
|
||||
|
||||
/*** Implement radio attenuation
|
||||
* based on the Longley-Rice propagation model
|
||||
* ground_to_air: 0 for air to ground 1 for ground to air, 2 for air to air, 3 for pilot to ground, 4 for pilot to air
|
||||
* @param: transmitter position, frequency, flag to indicate if the transmission is from a ground station
|
||||
* @return: signal level above receiver treshhold sensitivity
|
||||
***/
|
||||
double ITM_calculate_attenuation(SGGeod tx_pos, double freq, int ground_to_air);
|
||||
|
||||
/*** a simple alternative LOS propagation model (WIP)
|
||||
* @param: transmitter position, frequency, flag to indicate if the transmission is from a ground station
|
||||
* @return: signal level above receiver treshhold sensitivity
|
||||
***/
|
||||
double LOS_calculate_attenuation(SGGeod tx_pos, double freq, int ground_to_air);
|
||||
|
||||
/*** Calculate losses due to vegetation and urban clutter (WIP)
|
||||
* We are only worried about clutter loss, terrain influence
|
||||
* on the first Fresnel zone is calculated in the ITM functions
|
||||
* @param: frequency, elevation data, terrain type, horizon distances, calculated loss
|
||||
* @return: none
|
||||
***/
|
||||
void calculate_clutter_loss(double freq, double itm_elev[], std::deque<std::string*> &materials,
|
||||
double transmitter_height, double receiver_height, int p_mode,
|
||||
double horizons[], double &clutter_loss);
|
||||
|
||||
/*** Temporary material properties database
|
||||
* @param: terrain type, median clutter height, radiowave attenuation factor
|
||||
* @return: none
|
||||
***/
|
||||
void get_material_properties(std::string* mat_name, double &height, double &density);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
FGRadioTransmission();
|
||||
~FGRadioTransmission();
|
||||
|
||||
/// a couple of setters and getters for convenience, call after initializing
|
||||
/// frequency is in MHz, sensitivity in dBm, antenna gain and losses in dB, transmitter power in dBm
|
||||
/// polarization can be: 0 horizontal, 1 vertical
|
||||
void setFrequency(double freq, int radio);
|
||||
double getFrequency(int radio);
|
||||
inline void setTxPower(double txpower) { _transmitter_power = txpower; };
|
||||
inline void setRxSensitivity(double sensitivity) { _receiver_sensitivity = sensitivity; };
|
||||
inline void setTxAntennaHeight(double tx_antenna_height) { _tx_antenna_height = tx_antenna_height; };
|
||||
inline void setRxAntennaHeight(double rx_antenna_height) { _rx_antenna_height = rx_antenna_height; };
|
||||
inline void setTxAntennaGain(double tx_antenna_gain) { _tx_antenna_gain = tx_antenna_gain; };
|
||||
inline void setRxAntennaGain(double rx_antenna_gain) { _rx_antenna_gain = rx_antenna_gain; };
|
||||
inline void setTxLineLosses(double tx_line_losses) { _tx_line_losses = tx_line_losses; };
|
||||
inline void setRxLineLosses(double rx_line_losses) { _rx_line_losses = rx_line_losses; };
|
||||
inline void setPropagationModel(int model) { _propagation_model = model; };
|
||||
inline void setPolarization(int polarization) { _polarization = polarization; };
|
||||
|
||||
/// static convenience functions for unit conversions
|
||||
static double watt_to_dbm(double power_watt);
|
||||
static double dbm_to_watt(double dbm);
|
||||
static double dbm_to_microvolt(double dbm);
|
||||
|
||||
|
||||
/*** Receive ATC radio communication as text
|
||||
* transmission_type: 0 for air to ground 1 for ground to air, 2 for air to air, 3 for pilot to ground, 4 for pilot to air
|
||||
* @param: transmitter position, frequency, ATC text, flag to indicate whether the transmission comes from an ATC groundstation
|
||||
* @return: none
|
||||
***/
|
||||
void receiveATC(SGGeod tx_pos, double freq, std::string text, int transmission_type);
|
||||
|
||||
/*** TODO: receive multiplayer chat message and voice
|
||||
* @param: transmitter position, frequency, ATC text, flag to indicate whether the transmission comes from an ATC groundstation
|
||||
* @return: none
|
||||
***/
|
||||
void receiveChat(SGGeod tx_pos, double freq, std::string text, int transmission_type);
|
||||
|
||||
/*** TODO: receive navaid
|
||||
* @param: transmitter position, frequency, flag
|
||||
* @return: signal level above receiver treshhold sensitivity
|
||||
***/
|
||||
double receiveNav(SGGeod tx_pos, double freq, int transmission_type);
|
||||
|
||||
/*** Call this function to receive an arbitrary signal
|
||||
* for instance via the Nasal radioTransmission() function
|
||||
* returns the signal value above receiver sensitivity treshhold
|
||||
* @param: transmitter position, object heading in degrees (for antenna), object pitch angle in degrees
|
||||
* @return: signal level above receiver treshhold sensitivity
|
||||
***/
|
||||
double receiveBeacon(SGGeod &tx_pos, double heading, double pitch);
|
||||
};
|
||||
Reference in New Issue
Block a user