first commit

This commit is contained in:
Your Name
2022-10-20 20:29:11 +08:00
commit 4d531f8044
3238 changed files with 1387862 additions and 0 deletions
+15
View File
@@ -0,0 +1,15 @@
include(FlightGearComponent)
set(SOURCES
antenna.cxx
radio.cxx
)
set(HEADERS
antenna.hxx
radio.hxx
)
flightgear_component(Radio "${SOURCES}" "${HEADERS}")
+103
View File
@@ -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);
}
}
+73
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+1023
View File
File diff suppressed because it is too large Load Diff
+140
View File
@@ -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);
};