forked from ExternalVendorCode/Signal-Server
3.04 Egli model and unit test
This commit is contained in:
@@ -27,12 +27,12 @@ Distance 1-20km
|
||||
modes 1 = URBAN, 2 = SUBURBAN, 3 = OPEN
|
||||
http://morse.colorado.edu/~tlen5510/text/classwebch3.html
|
||||
*/
|
||||
if (f < 150 || f > 2000) {
|
||||
/* if (f < 150 || f > 2000) {
|
||||
fprintf
|
||||
(stderr,"Error: COST231 Hata model frequency range 150-2000MHz\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
*/
|
||||
int C = 3; // 3dB for Urban
|
||||
float lRxH = log10(11.75 * RxH);
|
||||
float C_H = 3.2 * (lRxH * lRxH) - 4.97; // Large city (conservative)
|
||||
|
@@ -10,10 +10,11 @@ double ECC33pathLoss(float f, float TxH, float RxH, float d, int mode)
|
||||
RxH=RxH/(d*2);
|
||||
}
|
||||
|
||||
if (f < 700 || f > 3500) {
|
||||
/* if (f < 700 || f > 3500) {
|
||||
fprintf(stderr,"Error: ECC33 model frequency range 700-3500MHz\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
*/
|
||||
// MHz to GHz
|
||||
f = f / 1000;
|
||||
|
||||
|
83
models/egli.cc
Normal file
83
models/egli.cc
Normal file
@@ -0,0 +1,83 @@
|
||||
/*****************************************************************************
|
||||
* Egli VHF/UHF model for Signal Server by G6DTX *
|
||||
* April 2017 *
|
||||
* 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 any later *
|
||||
* version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will useful, but WITHOUT *
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License v3 *
|
||||
* for more details. *
|
||||
******************************************************************************
|
||||
|
||||
Frequency 30 to 1000MHz
|
||||
h1 = 1m and above
|
||||
h2 = 1m and above
|
||||
Distance 1 to 50km
|
||||
|
||||
http://people.seas.harvard.edu/~jones/es151/prop_models/propagation.html#pel
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
//static float fcmin = 30.0;
|
||||
//static float fcmax = 1000.0;
|
||||
//static float dmin = 1.0;
|
||||
//static float dmax = 50.0;
|
||||
//static float h1min = 1.0;
|
||||
//static float h2min = 1.0;
|
||||
|
||||
static __inline float _10log10f(float x)
|
||||
{
|
||||
return(4.342944f*logf(x));
|
||||
}
|
||||
|
||||
double EgliPathLoss(float f, float h1, float h2, float d)
|
||||
{
|
||||
double Lp50 = NAN;
|
||||
float C1, C2;
|
||||
|
||||
/* if ((f >= fcmin) && (f <= fcmax) &&
|
||||
(h1 >= h1min) && (h2 >= h2min))
|
||||
{*/
|
||||
if (h1 > 10.0 && h2 > 10.0)
|
||||
{
|
||||
Lp50 = 85.9;
|
||||
C1 = 2.0;
|
||||
C2 = 2.0;
|
||||
}
|
||||
else if (h1 > 10.0)
|
||||
{
|
||||
Lp50 = 76.3;
|
||||
C1 = 2.0;
|
||||
C2 = 1.0;
|
||||
}
|
||||
else if (h2 > 10.0)
|
||||
{
|
||||
Lp50 = 76.3;
|
||||
C1 = 1.0;
|
||||
C2 = 2.0;
|
||||
}
|
||||
else // both antenna heights below 10 metres
|
||||
{
|
||||
Lp50 = 66.7;
|
||||
C1 = 1.0;
|
||||
C2 = 1.0;
|
||||
} // end if
|
||||
|
||||
Lp50 += 4.0f*_10log10f(d) + 2.0f*_10log10f(f) - C1*_10log10f(h1) - C2*_10log10f(h2);
|
||||
/*}
|
||||
else
|
||||
{
|
||||
fprintf(stderr,"Parameter error: Egli path loss model f=%6.2f h1=%6.2f h2=%6.2f d=%6.2f\n", f, h1, h2, d);
|
||||
exit(EXIT_FAILURE);
|
||||
}*/
|
||||
|
||||
return(Lp50);
|
||||
|
||||
}
|
||||
|
6
models/egli.hh
Normal file
6
models/egli.hh
Normal file
@@ -0,0 +1,6 @@
|
||||
#ifndef _EGLI_HH_
|
||||
#define _EGLI_HH_
|
||||
|
||||
double EgliPathLoss(float f, float h1, float h2, float d);
|
||||
|
||||
#endif /* _EGLI_HH_ */
|
@@ -10,12 +10,12 @@ double EricssonpathLoss(float f, float TxH, float RxH, float d, int mode)
|
||||
// Urban
|
||||
double a0 = 36.2, a1 = 30.2, a2 = -12, a3 = 0.1;
|
||||
|
||||
if (f < 150 || f > 1900) {
|
||||
/* if (f < 150 || f > 1900) {
|
||||
fprintf
|
||||
(stderr,"Error: Ericsson9999 model frequency range 150-1900MHz\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
*/
|
||||
if (mode == 2) { // Suburban / Med loss
|
||||
a0 = 43.2;
|
||||
a1 = 68.93;
|
||||
@@ -25,8 +25,7 @@ double EricssonpathLoss(float f, float TxH, float RxH, float d, int mode)
|
||||
a1 = 100.6;
|
||||
}
|
||||
double g1 = 3.2 * (log10(11.75 * RxH) * log10(11.75 * RxH));
|
||||
double g2 = (44.49 * log10(f)) - 4.78 * ((log10(f) * log10(f)));
|
||||
double g2 = 44.49 * log10(f) - 4.78 * (log10(f) * log10(f));
|
||||
|
||||
return a0 + a1 * log10(d) + a2 * log10(TxH) +
|
||||
a3 * log10(TxH) * log10(d) - g1 + g2;
|
||||
return a0 + a1 * log10(d) + a2 * log10(TxH) + a3 * log10(TxH) * log10(d) - g1 + g2;
|
||||
}
|
||||
|
@@ -10,6 +10,7 @@
|
||||
#include "itwom3.0.hh"
|
||||
#include "sui.hh"
|
||||
#include "pel.hh"
|
||||
#include "egli.hh"
|
||||
#include <pthread.h>
|
||||
|
||||
#define NUM_SECTIONS 4
|
||||
@@ -304,8 +305,9 @@ void PlotPropPath(struct site source, struct site destination,
|
||||
xmtr_alt, dest_alt, xmtr_alt2, dest_alt2,
|
||||
cos_rcvr_angle, cos_test_angle = 0.0, test_alt,
|
||||
elevation = 0.0, distance = 0.0, four_thirds_earth,
|
||||
field_strength = 0.0, rxp, dBm, dkm, diffloss;
|
||||
field_strength = 0.0, rxp, dBm, diffloss;
|
||||
struct site temp;
|
||||
float dkm;
|
||||
|
||||
ReadPath(source, destination);
|
||||
|
||||
@@ -445,7 +447,6 @@ void PlotPropPath(struct site source, struct site destination,
|
||||
|
||||
dkm = (elev[1] * elev[0]) / 1000; // km
|
||||
|
||||
|
||||
switch (propmodel) {
|
||||
case 1:
|
||||
// Longley Rice ITM
|
||||
@@ -520,12 +521,14 @@ void PlotPropPath(struct site source, struct site destination,
|
||||
METERS_PER_FOOT), dkm,
|
||||
pmenv);
|
||||
break;
|
||||
|
||||
case 10:
|
||||
// Plane earth
|
||||
loss = PlaneEarthLoss(dkm, source.alt * METERS_PER_FOOT, (path.elevation[y] * METERS_PER_FOOT) + (destination.alt * METERS_PER_FOOT));
|
||||
break;
|
||||
|
||||
case 11:
|
||||
// Egli VHF/UHF
|
||||
loss = EgliPathLoss(LR.frq_mhz, source.alt * METERS_PER_FOOT, (path.elevation[y] * METERS_PER_FOOT) + (destination.alt * METERS_PER_FOOT),dkm);
|
||||
break;
|
||||
default:
|
||||
point_to_point_ITM(source.alt * METERS_PER_FOOT,
|
||||
destination.alt *
|
||||
|
@@ -2,49 +2,45 @@
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
double SUIpathLoss(float f, float TxH, float RxH, float d, int mode)
|
||||
double SUIpathLoss(double f, double TxH, double RxH, double d, int mode)
|
||||
{
|
||||
/*
|
||||
f = Frequency (MHz)
|
||||
f = Frequency (MHz) 1900 to 11000
|
||||
TxH = Transmitter height (m)
|
||||
RxH = Receiver height (m)
|
||||
d = distance (km)
|
||||
mode A1 = Hilly + trees
|
||||
mode B2 = Flat + trees OR hilly + light foliage
|
||||
mode C3 = Flat + light foliage
|
||||
mode A1 = URBAN / OBSTRUCTED
|
||||
mode B2 = SUBURBAN / PARTIALLY OBSTRUCTED
|
||||
mode C3 = RURAL / OPEN
|
||||
http://www.cl.cam.ac.uk/research/dtg/lce-pub/public/vsa23/VTC05_Empirical.pdf
|
||||
*/
|
||||
d = d * 1000; // km to m
|
||||
if (f < 1900 || f > 11000) {
|
||||
fprintf(stderr,"Error: SUI model frequency range 1.9-11GHz\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
// Terrain mode A is default
|
||||
d = d * 1000.0; // km to m
|
||||
RxH = RxH * 1000.0; // Correction factor for CPE units.
|
||||
|
||||
// Urban (A1) is default
|
||||
double a = 4.6;
|
||||
double b = 0.0075;
|
||||
double c = 12.6;
|
||||
double s = 10.6; // Optional fading value
|
||||
int XhCF = -10.8;
|
||||
double s = 0.0; // Optional fading value. Max 10.6dB
|
||||
double XhCF = -10.8;
|
||||
|
||||
if (mode == 2) {
|
||||
if (mode == 2) { // Suburban
|
||||
a = 4.0;
|
||||
b = 0.0065;
|
||||
c = 17.1;
|
||||
s = 6; // average
|
||||
}
|
||||
if (mode == 3) {
|
||||
if (mode == 3) { // Rural
|
||||
a = 3.6;
|
||||
b = 0.005;
|
||||
c = 20;
|
||||
s = 3; // Optimistic
|
||||
XhCF = -20;
|
||||
}
|
||||
double d0 = 100;
|
||||
double A = 20 * log10((4 * M_PI * d0) / (300 / f));
|
||||
double A = 20 * log10((4 * M_PI * d0) / (300.0 / f));
|
||||
double y = a - (b * TxH) + (c / TxH);
|
||||
double Xf = 6 * log10(f / 2000);
|
||||
//Correction factors
|
||||
double Xf = 6.0 * log10(f / 2000);
|
||||
double Xh = XhCF * log10(RxH / 2000);
|
||||
|
||||
//return A + (10 * y * log10(d / d0)) + Xf + Xh + s;
|
||||
return A + (10 * y) * (log10(d / d0)) + Xf + Xh + s;
|
||||
return A + (10 * y * log10(d / d0)) + Xf + Xh + s;
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
#ifndef _SUI_HH_
|
||||
#define _SUI_HH_
|
||||
|
||||
double SUIpathLoss(float f, float TxH, float RxH, float d, int mode);
|
||||
double SUIpathLoss(double f, double TxH, double RxH, double d, int mode);
|
||||
|
||||
#endif /* _SUI_HH_ */
|
||||
|
117
models/test.cc
Normal file
117
models/test.cc
Normal file
@@ -0,0 +1,117 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <sys/stat.h>
|
||||
/*
|
||||
* Propagation model test script for signal server
|
||||
* Requires gnuplot
|
||||
* Compile: gcc -Wall -o test test.cc sui.cc cost.cc ecc33.cc ericsson.cc fspl.cc egli.cc hata.cc -lm
|
||||
* Test 850Mhz: ./test 850
|
||||
*
|
||||
* 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 any later *
|
||||
* version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will 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. *
|
||||
* *
|
||||
\****************************************************************************/
|
||||
|
||||
|
||||
extern double EgliPathLoss(float f, float TxH, float RxH, float d);
|
||||
extern double SUIpathLoss(double f, double TxH, double RxH, double d, int mode);
|
||||
extern double COST231pathLoss(float f, float TxH, float RxH, float d, int mode);
|
||||
extern double ECC33pathLoss(float f, float TxH, float RxH, float d, int mode);
|
||||
extern double EricssonpathLoss(float f, float TxH, float RxH, float d, int mode);
|
||||
extern double FSPLpathLoss(float f, float d);
|
||||
extern double HATApathLoss(float f, float TxH, float RxH, float d, int mode);
|
||||
extern void point_to_point_ITM(double tht_m, double rht_m, double eps_dielect,
|
||||
double sgm_conductivity, double eno_ns_surfref,
|
||||
double frq_mhz, int radio_climate, int pol,
|
||||
double conf, double rel, double &dbloss, char *strmode,
|
||||
int &errnum);
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
double a = 0;
|
||||
double f = atof(argv[1]);
|
||||
double r = 5.0;
|
||||
float TxH = 30.0;
|
||||
float RxH = 2.0;
|
||||
|
||||
mkdir("tests", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
|
||||
|
||||
FILE * fh;
|
||||
|
||||
/*fh = fopen("tests/ITM","w");
|
||||
for(float d = 0.1; d <= r; d=d+0.2){
|
||||
point_to_point_ITM(TxH,RxH,15.0,0.005,301.0,f,5,1,0.5,0.5,a,"",errno);
|
||||
fprintf(fh,"%.1f\t%.1f\n",d,a);
|
||||
}
|
||||
fclose(fh);
|
||||
*/
|
||||
fh = fopen("tests/SUI.1","w");
|
||||
for(float d = 0.1; d <= r; d=d+0.1){
|
||||
a = SUIpathLoss(f, TxH, RxH, d,1);
|
||||
fprintf(fh,"%.1f\t%.1f\n",d,a);
|
||||
}
|
||||
fclose(fh);
|
||||
|
||||
fh = fopen("tests/COST231.1","w");
|
||||
for(float d = 0.1; d <= r; d=d+0.1){
|
||||
a = COST231pathLoss(f, TxH, RxH, d,1);
|
||||
fprintf(fh,"%.1f\t%.1f\n",d,a);
|
||||
}
|
||||
fclose(fh);
|
||||
|
||||
|
||||
fh = fopen("tests/ECC33.1","w");
|
||||
for(float d = 0.1; d <= r; d=d+0.1){
|
||||
a = ECC33pathLoss(f, TxH, RxH, d,1);
|
||||
fprintf(fh,"%.1f\t%.1f\n",d,a);
|
||||
}
|
||||
fclose(fh);
|
||||
|
||||
fh = fopen("tests/Ericsson9999.1","w");
|
||||
for(float d = 0.1; d <= r; d=d+0.1){
|
||||
a = EricssonpathLoss(f, TxH, RxH, d,1);
|
||||
fprintf(fh,"%.1f\t%.1f\n",d,a);
|
||||
}
|
||||
fclose(fh);
|
||||
|
||||
fh = fopen("tests/FSPL","w");
|
||||
for(float d = 0.1; d <= r; d=d+0.1){
|
||||
a = FSPLpathLoss(f, d);
|
||||
fprintf(fh,"%.1f\t%.1f\n",d,a);
|
||||
}
|
||||
fclose(fh);
|
||||
|
||||
fh = fopen("tests/Hata.1","w");
|
||||
for(float d = 0.1; d <= r; d=d+0.1){
|
||||
a = HATApathLoss(f, TxH, RxH, d, 1);
|
||||
fprintf(fh,"%.1f\t%.1f\n",d,a);
|
||||
}
|
||||
fclose(fh);
|
||||
|
||||
fh = fopen("tests/Egli.VHF-UHF","w");
|
||||
for(float d = 0.1; d <= r; d=d+0.1){
|
||||
a = EgliPathLoss(f, TxH, RxH, d);
|
||||
fprintf(fh,"%.1f\t%.1f\n",d,a);
|
||||
}
|
||||
fclose(fh);
|
||||
|
||||
|
||||
fh = fopen("tests/gnuplot.plt","w");
|
||||
fprintf(fh,"set terminal jpeg size 800,600\nset output '%.0fMHz_propagation_models.jpg'\nset title '%.0fMHz path loss by propagation model - CloudRF.com'\n",f,f);
|
||||
fprintf(fh,"set key right bottom box\nset style line 1\nset grid\nset xlabel 'Distance KM'\nset ylabel 'Path Loss dB'\n");
|
||||
fprintf(fh,"plot 'FSPL' with lines, 'Hata.1' with lines, 'COST231.1' with lines,'ECC33.1' with lines,'Ericsson9999.1' with lines,'SUI.1' with lines,'Egli.VHF-UHF' with lines");
|
||||
fclose(fh);
|
||||
|
||||
system("cd tests && gnuplot gnuplot.plt");
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
Reference in New Issue
Block a user