forked from ExternalVendorCode/Signal-Server
Path profile Tx height bugfix for some models
This commit is contained in:
21
CHANGELOG
21
CHANGELOG
@@ -1,5 +1,26 @@
|
|||||||
SIGNAL SERVER CHANGELOG
|
SIGNAL SERVER CHANGELOG
|
||||||
|
|
||||||
|
3.03 - 19 March 2017
|
||||||
|
Path profile bugfix for some models
|
||||||
|
Error handling for when prop loss < free space loss
|
||||||
|
|
||||||
|
3.02 - 22 Feb 2017
|
||||||
|
Gareth's error handling
|
||||||
|
|
||||||
|
3.01 - 16 Feb 2017
|
||||||
|
Image crop (Major performance improvement later on), SUI bugfix, txelev replaced
|
||||||
|
|
||||||
|
3.0 - 02 Feb 2017
|
||||||
|
Image rendering library support. Uses third party PNG lib instead of expensive PPM.
|
||||||
|
Code cleanup by a professional developer.
|
||||||
|
More errors to stderr
|
||||||
|
|
||||||
|
2.94 - 03 Oct 2016
|
||||||
|
Reduced MAXPAGES array for LIDAR to allow for uber large tiles
|
||||||
|
|
||||||
|
2.93 - 30 Sep 2016
|
||||||
|
More tiles
|
||||||
|
|
||||||
2.92 - 29 September 2016
|
2.92 - 29 September 2016
|
||||||
Overhauled LIDAR functions to read in (more) native format tiles.
|
Overhauled LIDAR functions to read in (more) native format tiles.
|
||||||
Replaced 'super tile' code with more scalable multi-tile code: currently limited to 16.
|
Replaced 'super tile' code with more scalable multi-tile code: currently limited to 16.
|
||||||
|
@@ -32,7 +32,7 @@ make
|
|||||||
|
|
||||||
## Parameters
|
## Parameters
|
||||||
```
|
```
|
||||||
Version: Signal Server 2.94 (Built for 64 DEM tiles at 1200 pixels)
|
Version: Signal Server 3.03 (Built for 100 DEM tiles at 1200 pixels)
|
||||||
License: GNU General Public License (GPL) version 2
|
License: GNU General Public License (GPL) version 2
|
||||||
|
|
||||||
Radio propagation simulator by Alex Farrant QCVS, 2E0TDW
|
Radio propagation simulator by Alex Farrant QCVS, 2E0TDW
|
||||||
|
@@ -41,7 +41,7 @@ int loadClutter(char *filename, double radius, struct site tx)
|
|||||||
|
|
||||||
if(w==2880 && h==3840){
|
if(w==2880 && h==3840){
|
||||||
cellsize=0.004167;
|
cellsize=0.004167;
|
||||||
cellsize2 = cellsize * 2;
|
cellsize2 = cellsize * 3;
|
||||||
}else{
|
}else{
|
||||||
return 0; // can't work with this yet
|
return 0; // can't work with this yet
|
||||||
}
|
}
|
||||||
@@ -107,8 +107,7 @@ int loadClutter(char *filename, double radius, struct site tx)
|
|||||||
|
|
||||||
// not in near field
|
// not in near field
|
||||||
if((lat > tx.lat+cellsize2 || lat < tx.lat-cellsize2) || (lon > tx.lon + cellsize2 || lon < tx.lon - cellsize2)){
|
if((lat > tx.lat+cellsize2 || lat < tx.lat-cellsize2) || (lon > tx.lon + cellsize2 || lon < tx.lon - cellsize2)){
|
||||||
AddElevation(lat,lon,clh,3);
|
AddElevation(lat,lon,clh,2);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -414,7 +413,7 @@ int LoadSDF_SDF(char *name)
|
|||||||
|
|
||||||
if (debug == 1) {
|
if (debug == 1) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Loading \"%s\" into page %d...",
|
"Loading \"%s\" into page %d...\n",
|
||||||
path_plus_name, indx + 1);
|
path_plus_name, indx + 1);
|
||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
}
|
}
|
||||||
|
49
main.cc
49
main.cc
@@ -1,4 +1,4 @@
|
|||||||
double version = 3.02;
|
double version = 3.03;
|
||||||
/****************************************************************************\
|
/****************************************************************************\
|
||||||
* Signal Server: Radio propagation simulator by Alex Farrant QCVS, 2E0TDW *
|
* Signal Server: Radio propagation simulator by Alex Farrant QCVS, 2E0TDW *
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
@@ -38,9 +38,9 @@ double version = 3.02;
|
|||||||
#include "models/pel.hh"
|
#include "models/pel.hh"
|
||||||
#include "image.hh"
|
#include "image.hh"
|
||||||
|
|
||||||
int MAXPAGES = 64;
|
int MAXPAGES = 10*10;
|
||||||
int ARRAYSIZE = 76810;
|
|
||||||
int IPPD = 1200;
|
int IPPD = 1200;
|
||||||
|
int ARRAYSIZE = MAXPAGES * IPPD;
|
||||||
|
|
||||||
char string[255], sdf_path[255], udt_file[255], opened = 0, gpsav =
|
char string[255], sdf_path[255], udt_file[255], opened = 0, gpsav =
|
||||||
0, ss_name[16], dashes[80];
|
0, ss_name[16], dashes[80];
|
||||||
@@ -53,7 +53,7 @@ double earthradius, max_range = 0.0, forced_erp, dpp, ppd, yppd,
|
|||||||
|
|
||||||
int ippd, mpi,
|
int ippd, mpi,
|
||||||
max_elevation = -32768, min_elevation = 32768, bzerror, contour_threshold,
|
max_elevation = -32768, min_elevation = 32768, bzerror, contour_threshold,
|
||||||
pred, pblue, pgreen, ter, multiplier = 256, debug = 0, loops = 64, jgets =
|
pred, pblue, pgreen, ter, multiplier = 256, debug = 0, loops = 100, jgets =
|
||||||
0, MAXRAD, hottest = 10, height, width;
|
0, MAXRAD, hottest = 10, height, width;
|
||||||
|
|
||||||
unsigned char got_elevation_pattern, got_azimuth_pattern, metric = 0, dbm = 0;
|
unsigned char got_elevation_pattern, got_azimuth_pattern, metric = 0, dbm = 0;
|
||||||
@@ -200,7 +200,6 @@ int OrMask(double lat, double lon, int value)
|
|||||||
x = (int)rint(ppd * (lat - dem[indx].min_north));
|
x = (int)rint(ppd * (lat - dem[indx].min_north));
|
||||||
y = mpi - (int)rint(yppd * (LonDiff(dem[indx].max_west, lon)));
|
y = mpi - (int)rint(yppd * (LonDiff(dem[indx].max_west, lon)));
|
||||||
|
|
||||||
|
|
||||||
if (x >= 0 && x <= mpi && y >= 0 && y <= mpi)
|
if (x >= 0 && x <= mpi && y >= 0 && y <= mpi)
|
||||||
found = 1;
|
found = 1;
|
||||||
else
|
else
|
||||||
@@ -234,7 +233,6 @@ int PutSignal(double lat, double lon, unsigned char signal)
|
|||||||
|
|
||||||
int x = 0, y = 0, indx;
|
int x = 0, y = 0, indx;
|
||||||
char found;
|
char found;
|
||||||
|
|
||||||
if (signal > hottest) // dBm, dBuV
|
if (signal > hottest) // dBm, dBuV
|
||||||
hottest = signal;
|
hottest = signal;
|
||||||
|
|
||||||
@@ -1713,6 +1711,12 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
}else{
|
}else{
|
||||||
// DEM first
|
// DEM first
|
||||||
|
if(debug){
|
||||||
|
fprintf(stderr,"%.4f,%.4f,%.4f,%.4f,%.4f,%.4f\n",max_north,min_west,min_north,max_west,max_lon,min_lon);
|
||||||
|
}
|
||||||
|
|
||||||
|
max_lon-=3;
|
||||||
|
|
||||||
if( (result = LoadTopoData(max_lon, min_lon, max_lat, min_lat)) != 0 ){
|
if( (result = LoadTopoData(max_lon, min_lon, max_lat, min_lat)) != 0 ){
|
||||||
// This only fails on errors loading SDF tiles
|
// This only fails on errors loading SDF tiles
|
||||||
fprintf(stderr, "Error loading topo data\n");
|
fprintf(stderr, "Error loading topo data\n");
|
||||||
@@ -1810,6 +1814,7 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
ppd=(double)ippd;
|
ppd=(double)ippd;
|
||||||
yppd=ppd;
|
yppd=ppd;
|
||||||
|
|
||||||
width = (unsigned)(ippd * ReduceAngle(max_west - min_west));
|
width = (unsigned)(ippd * ReduceAngle(max_west - min_west));
|
||||||
height = (unsigned)(ippd * ReduceAngle(max_north - min_north));
|
height = (unsigned)(ippd * ReduceAngle(max_north - min_north));
|
||||||
}
|
}
|
||||||
@@ -1863,13 +1868,26 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// CROPPING. croplat assigned in propPathLoss()
|
if(max_range<=100){
|
||||||
max_north=cropLat; // MAX(path.lat[y])
|
// CROPPING. croplat assigned in propPathLoss()
|
||||||
max_west=cropLon; // MAX(path.lon[y])
|
max_north=cropLat; // MAX(path.lat[y])
|
||||||
cropLat-=tx_site[0].lat; // angle from tx to edge
|
// Edge case #1 - EAST/WEST
|
||||||
cropLon-=tx_site[0].lon;
|
if(cropLon>357 && tx_site[0].lon < 3)
|
||||||
width=(int)((cropLon*ppd)*2);
|
cropLon=tx_site[0].lon+3;
|
||||||
height=(int)((cropLat*ppd)*2);
|
// Edge case #2 - EAST/EAST
|
||||||
|
if(cropLon>359.5 && tx_site[0].lon > 359.5)
|
||||||
|
cropLon=362;
|
||||||
|
max_west=cropLon; // MAX(path.lon[y])
|
||||||
|
cropLat-=tx_site[0].lat; // angle from tx to edge
|
||||||
|
cropLon-=tx_site[0].lon;
|
||||||
|
width=(int)((cropLon*ppd)*2);
|
||||||
|
height=(int)((cropLat*ppd)*2);
|
||||||
|
|
||||||
|
if(width>3600*10){
|
||||||
|
fprintf(stderr,"FATAL BOUNDS! max_west: %.4f cropLat: %.4f cropLon: %.4f longitude: %.5f\n",max_west,cropLat,cropLon,tx_site[0].lon);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Write bitmap
|
// Write bitmap
|
||||||
if (LR.erp == 0.0)
|
if (LR.erp == 0.0)
|
||||||
@@ -1893,7 +1911,8 @@ int main(int argc, char *argv[])
|
|||||||
if (tx_site[0].lon < -180.0){
|
if (tx_site[0].lon < -180.0){
|
||||||
tx_site[0].lon += 360;
|
tx_site[0].lon += 360;
|
||||||
}
|
}
|
||||||
if (propmodel == 2) {
|
|
||||||
|
if (propmodel == 2 || max_range > 100) {
|
||||||
// No croppping because this is LOS
|
// No croppping because this is LOS
|
||||||
fprintf(stderr, "|%.6f", max_north);
|
fprintf(stderr, "|%.6f", max_north);
|
||||||
fprintf(stderr, "|%.6f", east);
|
fprintf(stderr, "|%.6f", east);
|
||||||
@@ -1915,7 +1934,7 @@ int main(int argc, char *argv[])
|
|||||||
PlotPath(tx_site[0], tx_site[1], 1);
|
PlotPath(tx_site[0], tx_site[1], 1);
|
||||||
PathReport(tx_site[0], tx_site[1], tx_site[0].filename, 0,
|
PathReport(tx_site[0], tx_site[1], tx_site[0].filename, 0,
|
||||||
propmodel, pmenv, rxGain);
|
propmodel, pmenv, rxGain);
|
||||||
SeriesData(tx_site[1], tx_site[0], tx_site[0].filename, 1,
|
SeriesData(tx_site[0], tx_site[1], tx_site[0].filename, 1,
|
||||||
normalise);
|
normalise);
|
||||||
}
|
}
|
||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
|
@@ -336,7 +336,8 @@ void PlotPropPath(struct site source, struct site destination,
|
|||||||
Longley-Rice. This information is required for properly
|
Longley-Rice. This information is required for properly
|
||||||
integrating the antenna's elevation pattern into the
|
integrating the antenna's elevation pattern into the
|
||||||
calculation for overall path loss. */
|
calculation for overall path loss. */
|
||||||
|
if(debug)
|
||||||
|
fprintf(stderr,"four_thirds_earth %.1f source.alt %.1f path.elevation[0] %.1f\n",four_thirds_earth,source.alt,path.elevation[0]);
|
||||||
for (y = 2; (y < (path.length - 1) && path.distance[y] <= max_range);
|
for (y = 2; (y < (path.length - 1) && path.distance[y] <= max_range);
|
||||||
y++) {
|
y++) {
|
||||||
/* Process this point only if it
|
/* Process this point only if it
|
||||||
@@ -445,8 +446,6 @@ void PlotPropPath(struct site source, struct site destination,
|
|||||||
dkm = (elev[1] * elev[0]) / 1000; // km
|
dkm = (elev[1] * elev[0]) / 1000; // km
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
switch (propmodel) {
|
switch (propmodel) {
|
||||||
case 1:
|
case 1:
|
||||||
// Longley Rice ITM
|
// Longley Rice ITM
|
||||||
|
@@ -45,5 +45,6 @@ double SUIpathLoss(float f, float TxH, float RxH, float d, int mode)
|
|||||||
double Xf = 6 * log10(f / 2000);
|
double Xf = 6 * log10(f / 2000);
|
||||||
double Xh = XhCF * log10(RxH / 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;
|
||||||
}
|
}
|
||||||
|
27
outputs.cc
27
outputs.cc
@@ -491,7 +491,7 @@ int DoSigStr(char *filename, unsigned char geo, unsigned char kml,
|
|||||||
/* We should never get here, but if */
|
/* We should never get here, but if */
|
||||||
/* we do, display the region as black */
|
/* we do, display the region as black */
|
||||||
|
|
||||||
ADD_PIXEL(&ctx, 0, 0, 0);
|
ADD_PIXEL(&ctx, 255, 255, 255);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -735,7 +735,7 @@ void DoRxdPwr(char *filename, unsigned char geo, unsigned char kml,
|
|||||||
/* We should never get here, but if */
|
/* We should never get here, but if */
|
||||||
/* we do, display the region as black */
|
/* we do, display the region as black */
|
||||||
|
|
||||||
ADD_PIXEL(&ctx, 0, 0, 0);
|
ADD_PIXEL(&ctx, 255, 255, 255);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -981,7 +981,7 @@ void DoLOS(char *filename, unsigned char geo, unsigned char kml,
|
|||||||
/* We should never get here, but if */
|
/* We should never get here, but if */
|
||||||
/* we do, display the region as black */
|
/* we do, display the region as black */
|
||||||
|
|
||||||
ADD_PIXEL(&ctx, 0, 0, 0);
|
ADD_PIXEL(&ctx, 255, 255, 255);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1336,10 +1336,9 @@ void PathReport(struct site source, struct site destination, char *name,
|
|||||||
|
|
||||||
for (y = 2; y < (path.length - 1); y++) { /* path.length-1 avoids LR error */
|
for (y = 2; y < (path.length - 1); y++) { /* path.length-1 avoids LR error */
|
||||||
distance = 5280.0 * path.distance[y];
|
distance = 5280.0 * path.distance[y];
|
||||||
source_alt =
|
|
||||||
four_thirds_earth + source.alt + path.elevation[0];
|
source_alt = four_thirds_earth + source.alt + path.elevation[0];
|
||||||
dest_alt =
|
dest_alt = four_thirds_earth + destination.alt +
|
||||||
four_thirds_earth + destination.alt +
|
|
||||||
path.elevation[y];
|
path.elevation[y];
|
||||||
dest_alt2 = dest_alt * dest_alt;
|
dest_alt2 = dest_alt * dest_alt;
|
||||||
source_alt2 = source_alt * source_alt;
|
source_alt2 = source_alt * source_alt;
|
||||||
@@ -1431,14 +1430,14 @@ void PathReport(struct site source, struct site destination, char *name,
|
|||||||
case 3:
|
case 3:
|
||||||
//HATA 1, 2 & 3
|
//HATA 1, 2 & 3
|
||||||
loss =
|
loss =
|
||||||
HATApathLoss(LR.frq_mhz, source_alt * METERS_PER_FOOT,
|
HATApathLoss(LR.frq_mhz, source.alt * METERS_PER_FOOT,
|
||||||
(path.elevation[y] * METERS_PER_FOOT) +
|
(path.elevation[y] * METERS_PER_FOOT) +
|
||||||
(destination.alt * METERS_PER_FOOT), dkm, pmenv);
|
(destination.alt * METERS_PER_FOOT), dkm, pmenv);
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
// COST231-HATA
|
// COST231-HATA
|
||||||
loss =
|
loss =
|
||||||
ECC33pathLoss(LR.frq_mhz, source_alt * METERS_PER_FOOT,
|
ECC33pathLoss(LR.frq_mhz, source.alt * METERS_PER_FOOT,
|
||||||
(path.elevation[y] * METERS_PER_FOOT) +
|
(path.elevation[y] * METERS_PER_FOOT) +
|
||||||
(destination.alt * METERS_PER_FOOT), dkm, pmenv);
|
(destination.alt * METERS_PER_FOOT), dkm, pmenv);
|
||||||
break;
|
break;
|
||||||
@@ -1451,7 +1450,7 @@ void PathReport(struct site source, struct site destination, char *name,
|
|||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
loss =
|
loss =
|
||||||
COST231pathLoss(LR.frq_mhz, source_alt * METERS_PER_FOOT,
|
COST231pathLoss(LR.frq_mhz, source.alt * METERS_PER_FOOT,
|
||||||
(path.elevation[y] * METERS_PER_FOOT) +
|
(path.elevation[y] * METERS_PER_FOOT) +
|
||||||
(destination.alt * METERS_PER_FOOT), dkm,pmenv);
|
(destination.alt * METERS_PER_FOOT), dkm,pmenv);
|
||||||
break;
|
break;
|
||||||
@@ -1473,7 +1472,7 @@ void PathReport(struct site source, struct site destination, char *name,
|
|||||||
case 9:
|
case 9:
|
||||||
// Ericsson
|
// Ericsson
|
||||||
loss =
|
loss =
|
||||||
EricssonpathLoss(LR.frq_mhz, source_alt * METERS_PER_FOOT,
|
EricssonpathLoss(LR.frq_mhz, source.alt * METERS_PER_FOOT,
|
||||||
(path.elevation[y] * METERS_PER_FOOT) +
|
(path.elevation[y] * METERS_PER_FOOT) +
|
||||||
(destination.alt *
|
(destination.alt *
|
||||||
METERS_PER_FOOT), dkm,
|
METERS_PER_FOOT), dkm,
|
||||||
@@ -1535,6 +1534,11 @@ void PathReport(struct site source, struct site destination, char *name,
|
|||||||
free_space_loss);
|
free_space_loss);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if((loss*1.1) < free_space_loss){
|
||||||
|
fprintf(stderr,"Model error! Computed loss of %.1fdB is greater than free space loss of %.1fdB. Check your inuts for model %d\n",loss,free_space_loss,propmodel);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
fprintf(fd2, "Computed path loss: %.2f dB\n", loss);
|
fprintf(fd2, "Computed path loss: %.2f dB\n", loss);
|
||||||
|
|
||||||
if (free_space_loss != 0.0)
|
if (free_space_loss != 0.0)
|
||||||
@@ -1633,7 +1637,6 @@ void PathReport(struct site source, struct site destination, char *name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
ObstructionAnalysis(source, destination, LR.frq_mhz, fd2);
|
ObstructionAnalysis(source, destination, LR.frq_mhz, fd2);
|
||||||
|
|
||||||
fclose(fd2);
|
fclose(fd2);
|
||||||
|
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
|
Reference in New Issue
Block a user