forked from ExternalVendorCode/Signal-Server
v2.6 +multi-threading
This commit is contained in:
@@ -1,5 +1,11 @@
|
||||
SIGNAL SERVER CHANGELOG
|
||||
|
||||
2.6 - 9 June 2015
|
||||
Multithreading support added by Michael Ramnarine
|
||||
PlotPropagation() and PlotLOSMap() use four threads by default
|
||||
Feature can be disabled with -nothreads flag
|
||||
Static and global variables have been made threadsafe
|
||||
|
||||
2.5 - 27 May 2015
|
||||
Code refactored by Andrew Clayton / ac000 with header files
|
||||
New Makefile with c / c++ multi mode compilation
|
||||
|
2
Makefile
2
Makefile
@@ -4,7 +4,7 @@ CC = gcc
|
||||
CXX = g++
|
||||
CFLAGS = -Wall -O3 -s -ffast-amth
|
||||
CXXFLAGS = -Wall -O3 -s -ffast-math
|
||||
LIBS = -lm
|
||||
LIBS = -lm -lpthread
|
||||
|
||||
VPATH = models
|
||||
objects = main.o cost.o ecc33.o ericsson.o fspl.o hata.o itwom3.0.o \
|
||||
|
@@ -20,7 +20,7 @@
|
||||
* *
|
||||
\****************************************************************************/
|
||||
|
||||
-- Signal Server 2.5 --
|
||||
-- Signal Server 2.6 --
|
||||
Compiled for 64 tiles at 1200 pixels/degree
|
||||
|
||||
-d Directory containing .sdf tiles
|
||||
@@ -52,4 +52,6 @@
|
||||
-ked Knife edge diffraction (Default for ITM)
|
||||
-ng Normalise Path Profile graph
|
||||
-haf Halve 1 or 2 (optional)
|
||||
-nothreads Turn off threaded processing (optional)
|
||||
|
||||
|
||||
|
4
common.h
4
common.h
@@ -98,7 +98,7 @@ extern double clutter;
|
||||
extern double dBm;
|
||||
extern double loss;
|
||||
extern double field_strength;
|
||||
extern double *elev;
|
||||
extern __thread double *elev;
|
||||
|
||||
extern char string[];
|
||||
extern char sdf_path[];
|
||||
@@ -110,7 +110,7 @@ extern unsigned char metric;
|
||||
extern unsigned char dbm;
|
||||
|
||||
extern struct dem *dem;
|
||||
extern struct path path;
|
||||
extern __thread struct path path;
|
||||
extern struct LR LR;
|
||||
extern struct region region;
|
||||
|
||||
|
37
main.cc
37
main.cc
@@ -1,4 +1,4 @@
|
||||
double version = 2.5;
|
||||
double version = 2.6;
|
||||
/****************************************************************************\
|
||||
* Signal Server: Server optimised SPLAT! by Alex Farrant *
|
||||
******************************************************************************
|
||||
@@ -53,11 +53,11 @@ int min_north = 90, max_north = -90, min_west = 360, max_west = -1, ippd, mpi,
|
||||
|
||||
unsigned char got_elevation_pattern, got_azimuth_pattern, metric = 0, dbm = 0;
|
||||
|
||||
double *elev;
|
||||
|
||||
__thread double *elev;
|
||||
__thread struct path path;
|
||||
struct site tx_site[2];
|
||||
struct dem *dem;
|
||||
struct path path;
|
||||
|
||||
struct LR LR;
|
||||
struct region region;
|
||||
|
||||
@@ -939,7 +939,11 @@ static void free_dem(void)
|
||||
delete [] dem;
|
||||
}
|
||||
|
||||
static void free_path(void)
|
||||
void free_elev(void) {
|
||||
delete [] elev;
|
||||
}
|
||||
|
||||
void free_path(void)
|
||||
{
|
||||
delete [] path.lat;
|
||||
delete [] path.lon;
|
||||
@@ -947,6 +951,11 @@ static void free_path(void)
|
||||
delete [] path.distance;
|
||||
}
|
||||
|
||||
void alloc_elev(void)
|
||||
{
|
||||
elev = new double[ARRAYSIZE + 10];
|
||||
}
|
||||
|
||||
static void alloc_dem(void)
|
||||
{
|
||||
int i;
|
||||
@@ -965,7 +974,7 @@ static void alloc_dem(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void alloc_path(void)
|
||||
void alloc_path(void)
|
||||
{
|
||||
path.lat = new double[ARRAYSIZE];
|
||||
path.lon = new double[ARRAYSIZE];
|
||||
@@ -980,6 +989,8 @@ int main(int argc, char *argv[])
|
||||
nortRxHin, nortRxHax, propmodel, winfiles, knifeedge = 0, ppa =
|
||||
0, normalise = 0, haf = 0, pmenv = 1;
|
||||
|
||||
bool use_threads = true;
|
||||
|
||||
unsigned char LRmap = 0, txsites = 0, topomap = 0, geo = 0, kml =
|
||||
0, area_mode = 0, max_txsites, ngs = 0;
|
||||
|
||||
@@ -1047,6 +1058,7 @@ int main(int argc, char *argv[])
|
||||
" -ked Knife edge diffraction (Default for ITM)\n");
|
||||
fprintf(stdout, " -ng Normalise Path Profile graph\n");
|
||||
fprintf(stdout, " -haf Halve 1 or 2 (optional)\n");
|
||||
fprintf(stdout, " -nothreads Turn off threaded processing (optional)\n");
|
||||
|
||||
fflush(stdout);
|
||||
|
||||
@@ -1057,7 +1069,7 @@ int main(int argc, char *argv[])
|
||||
* Now we know what mode we are running in, we can allocate various
|
||||
* data structures.
|
||||
*/
|
||||
elev = new double[ARRAYSIZE + 10];
|
||||
alloc_elev();
|
||||
alloc_dem();
|
||||
alloc_path();
|
||||
|
||||
@@ -1422,6 +1434,11 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
|
||||
//Disable threads
|
||||
if (strcmp(argv[x], "-nothreads") == 0) {
|
||||
z = x + 1;
|
||||
use_threads = false;
|
||||
}
|
||||
}
|
||||
|
||||
/* ERROR DETECTION */
|
||||
@@ -1639,12 +1656,12 @@ int main(int argc, char *argv[])
|
||||
|
||||
if (ppa == 0) {
|
||||
if (propmodel == 2) {
|
||||
PlotLOSMap(tx_site[0], altitudeLR, ano_filename);
|
||||
PlotLOSMap(tx_site[0], altitudeLR, ano_filename, use_threads);
|
||||
DoLOS(mapfile, geo, kml, ngs, tx_site, txsites);
|
||||
} else {
|
||||
// 90% of effort here
|
||||
PlotPropagation(tx_site[0], altitudeLR, ano_filename,
|
||||
propmodel, knifeedge, haf, pmenv);
|
||||
propmodel, knifeedge, haf, pmenv, use_threads);
|
||||
|
||||
// Near field bugfix
|
||||
PutSignal(tx_site[0].lat, tx_site[0].lon, hottest);
|
||||
@@ -1683,7 +1700,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
fflush(stdout);
|
||||
|
||||
delete [] elev;
|
||||
free_elev();
|
||||
free_dem();
|
||||
free_path();
|
||||
|
||||
|
5
main.hh
5
main.hh
@@ -23,4 +23,9 @@ double ReadBearing(char *input);
|
||||
void ObstructionAnalysis(struct site xmtr, struct site rcvr, double f,
|
||||
FILE *outfile);
|
||||
|
||||
void free_elev(void);
|
||||
void free_path(void);
|
||||
void alloc_elev(void);
|
||||
void alloc_path(void);
|
||||
|
||||
#endif /* _MAIN_HH_ */
|
||||
|
@@ -451,7 +451,7 @@ double saalos(double d, prop_type & prop, propa_type & propa)
|
||||
double adiff(double d, prop_type & prop, propa_type & propa)
|
||||
{
|
||||
complex < double >prop_zgnd(prop.zgndreal, prop.zgndimag);
|
||||
static double wd1, xd1, afo, qk, aht, xht;
|
||||
static __thread double wd1, xd1, afo, qk, aht, xht;
|
||||
double a, q, pk, ds, th, wa, ar, wd, adiffv;
|
||||
|
||||
if (d == 0) {
|
||||
@@ -513,7 +513,7 @@ double adiff(double d, prop_type & prop, propa_type & propa)
|
||||
double adiff2(double d, prop_type & prop, propa_type & propa)
|
||||
{
|
||||
complex < double >prop_zgnd(prop.zgndreal, prop.zgndimag);
|
||||
static double wd1, xd1, qk, aht, xht, toh, toho, roh, roho, dto, dto1,
|
||||
static __thread double wd1, xd1, qk, aht, xht, toh, toho, roh, roho, dto, dto1,
|
||||
dtro, dro, dro2, drto, dtr, dhh1, dhh2, /* dhec, */ dtof, dto1f,
|
||||
drof, dro2f;
|
||||
double a, q, pk, rd, ds, dsl, /* dfdh, */ th, wa, /* ar, wd, sf1, */
|
||||
@@ -829,7 +829,7 @@ double adiff2(double d, prop_type & prop, propa_type & propa)
|
||||
|
||||
double ascat(double d, prop_type & prop, propa_type & propa)
|
||||
{
|
||||
static double ad, rr, etq, h0s;
|
||||
static __thread double ad, rr, etq, h0s;
|
||||
double h0, r1, r2, z0, ss, et, ett, th, q;
|
||||
double ascatv, temp;
|
||||
|
||||
@@ -954,7 +954,7 @@ void qlrps(double fmhz, double zsys, double en0, int ipol, double eps,
|
||||
double alos(double d, prop_type & prop, propa_type & propa)
|
||||
{
|
||||
complex < double >prop_zgnd(prop.zgndreal, prop.zgndimag);
|
||||
static double wls;
|
||||
static __thread double wls;
|
||||
complex < double >r;
|
||||
double s, sps, q;
|
||||
double alosv;
|
||||
@@ -1146,8 +1146,8 @@ void qlra(int kst[], int klimx, int mdvarx, prop_type & prop,
|
||||
void lrprop(double d, prop_type & prop, propa_type & propa)
|
||||
{
|
||||
/* PaulM_lrprop used for ITM */
|
||||
static bool wlos, wscat;
|
||||
static double dmin, xae;
|
||||
static __thread bool wlos, wscat;
|
||||
static __thread double dmin, xae;
|
||||
complex < double >prop_zgnd(prop.zgndreal, prop.zgndimag);
|
||||
double a0, a1, a2, a3, a4, a5, a6;
|
||||
double d0, d1, d2, d3, d4, d5, d6;
|
||||
@@ -1337,8 +1337,8 @@ void lrprop(double d, prop_type & prop, propa_type & propa)
|
||||
void lrprop2(double d, prop_type & prop, propa_type & propa)
|
||||
{
|
||||
/* ITWOM_lrprop2 */
|
||||
static bool wlos, wscat;
|
||||
static double dmin, xae;
|
||||
static __thread bool wlos, wscat;
|
||||
static __thread double dmin, xae;
|
||||
complex < double >prop_zgnd(prop.zgndreal, prop.zgndimag);
|
||||
double pd1;
|
||||
double a0, a1, a2, a3, a4, a5, a6, iw;
|
||||
@@ -1612,8 +1612,8 @@ double curve(double const &c1, double const &c2, double const &x1,
|
||||
double avar(double zzt, double zzl, double zzc, prop_type & prop,
|
||||
propv_type & propv)
|
||||
{
|
||||
static int kdv;
|
||||
static double dexa, de, vmd, vs0, sgl, sgtm, sgtp, sgtd, tgtd,
|
||||
static __thread int kdv;
|
||||
static __thread double dexa, de, vmd, vs0, sgl, sgtm, sgtp, sgtd, tgtd,
|
||||
gm, gp, cv1, cv2, yv1, yv2, yv3, csm1, csm2, ysm1, ysm2,
|
||||
ysm3, csp1, csp2, ysp1, ysp2, ysp3, csd1, zd, cfm1, cfm2,
|
||||
cfm3, cfp1, cfp2, cfp3;
|
||||
@@ -1650,7 +1650,7 @@ double avar(double zzt, double zzl, double zzc, prop_type & prop,
|
||||
double bfp1[7] = { 1.0, 0.93, 1.0, 0.93, 0.93, 1.0, 1.0 };
|
||||
double bfp2[7] = { 0.0, 0.31, 0.0, 0.19, 0.31, 0.0, 0.0 };
|
||||
double bfp3[7] = { 0.0, 2.00, 0.0, 1.79, 2.00, 0.0, 0.0 };
|
||||
static bool ws, w1;
|
||||
static __thread bool ws, w1;
|
||||
double rt = 7.8, rl = 24.0, avarv, q, vs, zt, zl, zc;
|
||||
double sgt, yr, temp1, temp2;
|
||||
int temp_klim = propv.klim - 1;
|
||||
@@ -1974,6 +1974,7 @@ void z1sq1(double z[], const double &x1, const double &x2, double &z0,
|
||||
xa = xb - xa;
|
||||
x = -0.5 * xa;
|
||||
xb += x;
|
||||
|
||||
a = 0.5 * (z[ja + 2] + z[jb + 2]);
|
||||
b = 0.5 * (z[ja + 2] - z[jb + 2]) * x;
|
||||
|
||||
|
442
models/los.cc
442
models/los.cc
@@ -1,8 +1,8 @@
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "../common.h"
|
||||
#include "../main.hh"
|
||||
#include "los.hh"
|
||||
#include "cost.hh"
|
||||
#include "ecc33.hh"
|
||||
#include "ericsson.hh"
|
||||
@@ -10,6 +10,154 @@
|
||||
#include "hata.hh"
|
||||
#include "itwom3.0.hh"
|
||||
#include "sui.hh"
|
||||
#include <pthread.h>
|
||||
|
||||
#define MAXPAGES 64
|
||||
#define IPPD 3600
|
||||
#define NUM_SECTIONS 4
|
||||
|
||||
namespace {
|
||||
pthread_t threads[NUM_SECTIONS];
|
||||
unsigned int thread_count = 0;
|
||||
pthread_mutex_t maskMutex;
|
||||
|
||||
bool processed[MAXPAGES][IPPD][IPPD];
|
||||
bool has_init_processed = false;
|
||||
|
||||
struct propagationRange {
|
||||
int min_west, max_west, min_north, max_north;
|
||||
double altitude;
|
||||
bool eastwest, los, use_threads;
|
||||
site source;
|
||||
unsigned char mask_value;
|
||||
FILE *fd;
|
||||
int propmodel, knifeedge, pmenv;
|
||||
};
|
||||
|
||||
void* rangePropagation(void *parameters)
|
||||
{
|
||||
propagationRange *v = (propagationRange*)parameters;
|
||||
if(v->use_threads) {
|
||||
alloc_elev();
|
||||
alloc_path();
|
||||
}
|
||||
|
||||
double minwest = dpp + (double)v->min_west;
|
||||
double lon = v->eastwest ? minwest : v->min_west;
|
||||
double lat = v->min_north;
|
||||
int y = 0;
|
||||
|
||||
do {
|
||||
if (lon >= 360.0)
|
||||
lon -= 360.0;
|
||||
|
||||
site edge;
|
||||
edge.lat = lat;
|
||||
edge.lon = lon;
|
||||
edge.alt = v->altitude;
|
||||
|
||||
if(v->los)
|
||||
PlotLOSPath(v->source, edge, v->mask_value, v->fd);
|
||||
else
|
||||
PlotPropPath(v->source, edge, v->mask_value, v->fd, v->propmodel,
|
||||
v->knifeedge, v->pmenv);
|
||||
|
||||
++y;
|
||||
if(v->eastwest)
|
||||
lon = minwest + (dpp * (double)y);
|
||||
else
|
||||
lat = (double)v->min_north + (dpp * (double)y);
|
||||
|
||||
|
||||
} while ( v->eastwest
|
||||
? (LonDiff(lon, (double)v->max_west) <= 0.0)
|
||||
: (lat < (double)v->max_north) );
|
||||
|
||||
if(v->use_threads) {
|
||||
free_elev();
|
||||
free_path();
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void init_processed()
|
||||
{
|
||||
for(int i = 0; i < MAXPAGES; i++) {
|
||||
for (int x = 0; x < ippd; x++) {
|
||||
for (int y = 0; y < ippd; y++) {
|
||||
processed[i][x][y] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool can_process(double lat, double lon)
|
||||
{
|
||||
/* Lines, text, markings, and coverage areas are stored in a
|
||||
mask that is combined with topology data when topographic
|
||||
maps are generated by ss. This function sets bits in
|
||||
the mask based on the latitude and longitude of the area
|
||||
pointed to. */
|
||||
|
||||
int x, y, indx;
|
||||
char found;
|
||||
bool rtn = false;
|
||||
|
||||
for (indx = 0, found = 0; indx < MAXPAGES && found == 0;) {
|
||||
x = (int)rint(ppd * (lat - dem[indx].min_north));
|
||||
y = mpi - (int)rint(ppd * (LonDiff(dem[indx].max_west, lon)));
|
||||
|
||||
if (x >= 0 && x <= mpi && y >= 0 && y <= mpi)
|
||||
found = 1;
|
||||
else
|
||||
indx++;
|
||||
}
|
||||
|
||||
if (found) {
|
||||
/* As long as we only set this without resetting it we can
|
||||
check outside a mutex first without worrying about race
|
||||
conditions. But we must lock the mutex before updating the
|
||||
value. */
|
||||
|
||||
if(!processed[indx][x][y]) {
|
||||
pthread_mutex_lock(&maskMutex);
|
||||
|
||||
if(!processed[indx][x][y]) {
|
||||
rtn = true;
|
||||
processed[indx][x][y] = true;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock (&maskMutex);
|
||||
}
|
||||
|
||||
}
|
||||
return rtn;
|
||||
}
|
||||
|
||||
void beginThread(void *arg)
|
||||
{
|
||||
if(!has_init_processed)
|
||||
init_processed();
|
||||
|
||||
int rc = pthread_create(&threads[thread_count], NULL, rangePropagation, arg);
|
||||
if (rc)
|
||||
printf("ERROR; return code from pthread_create() is %d\n", rc);
|
||||
else
|
||||
++thread_count;
|
||||
}
|
||||
|
||||
void finishThreads()
|
||||
{
|
||||
void* status;
|
||||
for(unsigned int i=0; i<thread_count; i++) {
|
||||
int rc = pthread_join(threads[i], &status);
|
||||
if (rc)
|
||||
printf("ERROR; return code from pthread_join() is %d\n", rc);
|
||||
}
|
||||
thread_count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Acute Angle from Rx point to an obstacle of height (opp) and
|
||||
@@ -89,7 +237,9 @@ void PlotLOSPath(struct site source, struct site destination, char mask_value,
|
||||
/* Test this point only if it hasn't been already
|
||||
tested and found to be free of obstructions. */
|
||||
|
||||
if ((GetMask(path.lat[y], path.lon[y]) & mask_value) == 0) {
|
||||
if ((GetMask(path.lat[y], path.lon[y]) & mask_value) == 0
|
||||
&& can_process(path.lat[y], path.lon[y])) {
|
||||
|
||||
distance = 5280.0 * path.distance[y];
|
||||
tx_alt = earthradius + source.alt + path.elevation[0];
|
||||
rx_alt =
|
||||
@@ -183,8 +333,12 @@ void PlotPropPath(struct site source, struct site destination,
|
||||
/* Process this point only if it
|
||||
has not already been processed. */
|
||||
|
||||
if ((GetMask(path.lat[y], path.lon[y]) & 248) !=
|
||||
(mask_value << 3)) {
|
||||
if ( (GetMask(path.lat[y], path.lon[y]) & 248) !=
|
||||
(mask_value << 3) && can_process(path.lat[y], path.lon[y])) {
|
||||
|
||||
char fd_buffer[64];
|
||||
int buffer_offset = 0;
|
||||
|
||||
distance = 5280.0 * path.distance[y];
|
||||
xmtr_alt =
|
||||
four_thirds_earth + source.alt + path.elevation[0];
|
||||
@@ -337,6 +491,7 @@ void PlotPropPath(struct site source, struct site destination,
|
||||
destination.alt *
|
||||
METERS_PER_FOOT, LR.eps_dielect,
|
||||
LR.sgm_conductivity,
|
||||
|
||||
LR.eno_ns_surfref, LR.frq_mhz,
|
||||
LR.radio_climate, LR.pol,
|
||||
LR.conf, LR.rel, loss, strmode,
|
||||
@@ -379,7 +534,8 @@ void PlotPropPath(struct site source, struct site destination,
|
||||
azimuth = (Azimuth(source, temp));
|
||||
|
||||
if (fd != NULL)
|
||||
fprintf(fd, "%.7f, %.7f, %.3f, %.3f, ",
|
||||
buffer_offset += sprintf(fd_buffer+buffer_offset,
|
||||
"%.7f, %.7f, %.3f, %.3f, ",
|
||||
path.lat[y], path.lon[y], azimuth,
|
||||
elevation);
|
||||
|
||||
@@ -388,7 +544,8 @@ void PlotPropPath(struct site source, struct site destination,
|
||||
or received power level (below), as appropriate. */
|
||||
|
||||
if (fd != NULL && LR.erp == 0.0)
|
||||
fprintf(fd, "%.2f", loss);
|
||||
buffer_offset += sprintf(fd_buffer+buffer_offset,
|
||||
"%.2f", loss);
|
||||
|
||||
/* Integrate the antenna's radiation
|
||||
pattern into the overall path loss. */
|
||||
@@ -418,7 +575,8 @@ void PlotPropPath(struct site source, struct site destination,
|
||||
dBm = 10.0 * (log10(rxp * 1000.0));
|
||||
|
||||
if (fd != NULL)
|
||||
fprintf(fd, "%.3f", dBm);
|
||||
buffer_offset += sprintf(fd_buffer+buffer_offset,
|
||||
"%.3f", dBm);
|
||||
|
||||
/* Scale roughly between 0 and 255 */
|
||||
|
||||
@@ -466,7 +624,8 @@ void PlotPropPath(struct site source, struct site destination,
|
||||
(unsigned char)ifs);
|
||||
|
||||
if (fd != NULL)
|
||||
fprintf(fd, "%.3f",
|
||||
buffer_offset += sprintf(fd_buffer+buffer_offset,
|
||||
"%.3f",
|
||||
field_strength);
|
||||
}
|
||||
}
|
||||
@@ -488,9 +647,9 @@ void PlotPropPath(struct site source, struct site destination,
|
||||
|
||||
if (fd != NULL) {
|
||||
if (block)
|
||||
fprintf(fd, " *");
|
||||
|
||||
fprintf(fd, "\n");
|
||||
buffer_offset += sprintf(fd_buffer+buffer_offset,
|
||||
" *");
|
||||
fprintf(fd, "%s\n", fd_buffer);
|
||||
}
|
||||
|
||||
/* Mark this point as having been analyzed */
|
||||
@@ -503,7 +662,8 @@ void PlotPropPath(struct site source, struct site destination,
|
||||
|
||||
}
|
||||
|
||||
void PlotLOSMap(struct site source, double altitude, char *plo_filename)
|
||||
void PlotLOSMap(struct site source, double altitude, char *plo_filename,
|
||||
bool use_threads)
|
||||
{
|
||||
/* This function performs a 360 degree sweep around the
|
||||
transmitter site (source location), and plots the
|
||||
@@ -514,10 +674,7 @@ void PlotLOSMap(struct site source, double altitude, char *plo_filename)
|
||||
of a topographic map when the WritePPM() function
|
||||
is later invoked. */
|
||||
|
||||
int x, y, z;
|
||||
struct site edge;
|
||||
double lat, lon, minwest, maxnorth, th;
|
||||
static unsigned char mask_value = 1;
|
||||
static __thread unsigned char mask_value = 1;
|
||||
FILE *fd = NULL;
|
||||
|
||||
if (plo_filename[0] != 0)
|
||||
@@ -529,64 +686,44 @@ void PlotLOSMap(struct site source, double altitude, char *plo_filename)
|
||||
max_west, min_west, max_north, min_north);
|
||||
}
|
||||
|
||||
th = ppd / loops;
|
||||
// Four sections start here
|
||||
// Process north edge east/west, east edge north/south,
|
||||
// south edge east/west, west edge north/south
|
||||
int range_min_west[] = {min_west, min_west, min_west, max_west};
|
||||
int range_min_north[] = {max_north, min_north, min_north, min_north};
|
||||
int range_max_west[] = {max_west, min_west, max_west, max_west};
|
||||
int range_max_north[] = {max_north, max_north, min_north, max_north};
|
||||
propagationRange* r[NUM_SECTIONS];
|
||||
|
||||
z = (int)(th * ReduceAngle(max_west - min_west));
|
||||
for(int i = 0; i < NUM_SECTIONS; ++i) {
|
||||
propagationRange *range = new propagationRange;
|
||||
r[i] = range;
|
||||
range->los = true;
|
||||
|
||||
minwest = dpp + (double)min_west;
|
||||
maxnorth = (double)max_north - dpp;
|
||||
range->eastwest = (range_min_west[i] == range_max_west[i] ? false : true);
|
||||
range->min_west = range_min_west[i];
|
||||
range->max_west = range_max_west[i];
|
||||
range->min_north = range_min_north[i];
|
||||
range->max_north = range_max_north[i];
|
||||
|
||||
for (lon = minwest, x = 0, y = 0;
|
||||
(LonDiff(lon, (double)max_west) <= 0.0);
|
||||
y++, lon = minwest + (dpp * (double)y)) {
|
||||
if (lon >= 360.0)
|
||||
lon -= 360.0;
|
||||
range->use_threads = use_threads;
|
||||
range->altitude = altitude;
|
||||
range->source = source;
|
||||
range->mask_value = mask_value;
|
||||
range->fd = fd;
|
||||
|
||||
edge.lat = max_north;
|
||||
edge.lon = lon;
|
||||
edge.alt = altitude;
|
||||
|
||||
PlotLOSPath(source, edge, mask_value, fd);
|
||||
}
|
||||
|
||||
z = (int)(th * (double)(max_north - min_north));
|
||||
|
||||
for (lat = maxnorth, x = 0, y = 0; lat >= (double)min_north;
|
||||
y++, lat = maxnorth - (dpp * (double)y)) {
|
||||
edge.lat = lat;
|
||||
edge.lon = min_west;
|
||||
edge.alt = altitude;
|
||||
|
||||
PlotLOSPath(source, edge, mask_value, fd);
|
||||
if(use_threads)
|
||||
beginThread(range);
|
||||
else
|
||||
rangePropagation(range);
|
||||
|
||||
}
|
||||
|
||||
z = (int)(th * ReduceAngle(max_west - min_west));
|
||||
|
||||
for (lon = minwest, x = 0, y = 0;
|
||||
(LonDiff(lon, (double)max_west) <= 0.0);
|
||||
y++, lon = minwest + (dpp * (double)y)) {
|
||||
if (lon >= 360.0)
|
||||
lon -= 360.0;
|
||||
|
||||
edge.lat = min_north;
|
||||
edge.lon = lon;
|
||||
edge.alt = altitude;
|
||||
|
||||
PlotLOSPath(source, edge, mask_value, fd);
|
||||
|
||||
}
|
||||
|
||||
z = (int)(th * (double)(max_north - min_north));
|
||||
|
||||
for (lat = (double)min_north, x = 0, y = 0; lat < (double)max_north;
|
||||
y++, lat = (double)min_north + (dpp * (double)y)) {
|
||||
edge.lat = lat;
|
||||
edge.lon = max_west;
|
||||
edge.alt = altitude;
|
||||
|
||||
PlotLOSPath(source, edge, mask_value, fd);
|
||||
if(use_threads)
|
||||
finishThreads();
|
||||
|
||||
for(int i = 0; i < NUM_SECTIONS; ++i){
|
||||
delete r[i];
|
||||
}
|
||||
|
||||
switch (mask_value) {
|
||||
@@ -603,21 +740,14 @@ void PlotLOSMap(struct site source, double altitude, char *plo_filename)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PlotPropagation(struct site source, double altitude, char *plo_filename,
|
||||
int propmodel, int knifeedge, int haf, int pmenv)
|
||||
int propmodel, int knifeedge, int haf, int pmenv, bool
|
||||
use_threads)
|
||||
{
|
||||
int y, z, count;
|
||||
struct site edge;
|
||||
double lat, lon, minwest, maxnorth, th;
|
||||
unsigned char x;
|
||||
static unsigned char mask_value = 1;
|
||||
static __thread unsigned char mask_value = 1;
|
||||
FILE *fd = NULL;
|
||||
|
||||
minwest = dpp + (double)min_west;
|
||||
maxnorth = (double)max_north - dpp;
|
||||
|
||||
count = 0;
|
||||
|
||||
if (LR.erp == 0.0 && debug)
|
||||
fprintf(stdout, "path loss");
|
||||
else {
|
||||
@@ -657,139 +787,57 @@ void PlotPropagation(struct site source, double altitude, char *plo_filename,
|
||||
max_west, min_west, max_north, min_north);
|
||||
}
|
||||
|
||||
th = ppd / loops;
|
||||
|
||||
// Four sections start here
|
||||
// Process north edge east/west, east edge north/south,
|
||||
// south edge east/west, west edge north/south
|
||||
int range_min_west[] = {min_west, min_west, min_west, max_west};
|
||||
int range_min_north[] = {max_north, min_north, min_north, min_north};
|
||||
int range_max_west[] = {max_west, min_west, max_west, max_west};
|
||||
int range_max_north[] = {max_north, max_north, min_north, max_north};
|
||||
propagationRange* r[NUM_SECTIONS];
|
||||
|
||||
//S1
|
||||
if (haf == 0 || haf == 1) {
|
||||
z = (int)(th * ReduceAngle(max_west - min_west));
|
||||
for(int i = 0; i < NUM_SECTIONS; ++i) {
|
||||
propagationRange *range = new propagationRange;
|
||||
r[i] = range;
|
||||
range->los = false;
|
||||
|
||||
for (lon = minwest, x = 0, y = 0;
|
||||
(LonDiff(lon, (double)max_west) <= 0.0);
|
||||
y++, lon = minwest + (dpp * (double)y)) {
|
||||
if (lon >= 360.0)
|
||||
lon -= 360.0;
|
||||
// Only process correct half
|
||||
if((NUM_SECTIONS - i) <= (NUM_SECTIONS / 2) && haf == 1)
|
||||
continue;
|
||||
if((NUM_SECTIONS - i) > (NUM_SECTIONS / 2) && haf == 2)
|
||||
continue;
|
||||
|
||||
edge.lat = max_north;
|
||||
edge.lon = lon;
|
||||
edge.alt = altitude;
|
||||
|
||||
PlotPropPath(source, edge, mask_value, fd, propmodel,
|
||||
knifeedge, pmenv);
|
||||
count++;
|
||||
range->eastwest = (range_min_west[i] == range_max_west[i] ? false : true);
|
||||
range->min_west = range_min_west[i];
|
||||
range->max_west = range_max_west[i];
|
||||
range->min_north = range_min_north[i];
|
||||
range->max_north = range_max_north[i];
|
||||
|
||||
if (count == z) {
|
||||
count = 0;
|
||||
range->use_threads = use_threads;
|
||||
range->altitude = altitude;
|
||||
range->source = source;
|
||||
range->mask_value = mask_value;
|
||||
range->fd = fd;
|
||||
range->propmodel = propmodel;
|
||||
range->knifeedge = knifeedge;
|
||||
range->pmenv = pmenv;
|
||||
|
||||
if (x == 3)
|
||||
x = 0;
|
||||
else
|
||||
x++;
|
||||
}
|
||||
}
|
||||
if(use_threads)
|
||||
beginThread(range);
|
||||
else
|
||||
rangePropagation(range);
|
||||
|
||||
}
|
||||
//S2
|
||||
if (haf == 0 || haf == 1) {
|
||||
count = 0;
|
||||
if (debug) {
|
||||
fprintf(stdout, "\n25%c to 50%c ", 37, 37);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
z = (int)(th * (double)(max_north - min_north));
|
||||
|
||||
for (lat = maxnorth, x = 0, y = 0; lat >= (double)min_north;
|
||||
y++, lat = maxnorth - (dpp * (double)y)) {
|
||||
edge.lat = lat;
|
||||
edge.lon = min_west;
|
||||
edge.alt = altitude;
|
||||
|
||||
PlotPropPath(source, edge, mask_value, fd, propmodel,
|
||||
knifeedge, pmenv);
|
||||
count++;
|
||||
|
||||
if (count == z) {
|
||||
count = 0;
|
||||
|
||||
if (x == 3)
|
||||
x = 0;
|
||||
else
|
||||
x++;
|
||||
}
|
||||
}
|
||||
if(use_threads)
|
||||
finishThreads();
|
||||
|
||||
for(int i = 0; i < NUM_SECTIONS; ++i){
|
||||
delete r[i];
|
||||
}
|
||||
//S3
|
||||
if (haf == 0 || haf == 2) {
|
||||
count = 0;
|
||||
if (debug) {
|
||||
fprintf(stdout, "\n50%c to 75%c ", 37, 37);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
z = (int)(th * ReduceAngle(max_west - min_west));
|
||||
|
||||
for (lon = minwest, x = 0, y = 0;
|
||||
(LonDiff(lon, (double)max_west) <= 0.0);
|
||||
y++, lon = minwest + (dpp * (double)y)) {
|
||||
if (lon >= 360.0)
|
||||
lon -= 360.0;
|
||||
|
||||
edge.lat = min_north;
|
||||
edge.lon = lon;
|
||||
edge.alt = altitude;
|
||||
|
||||
PlotPropPath(source, edge, mask_value, fd, propmodel,
|
||||
knifeedge, pmenv);
|
||||
count++;
|
||||
if (count == z) {
|
||||
count = 0;
|
||||
|
||||
if (x == 3)
|
||||
x = 0;
|
||||
else
|
||||
x++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
//S4
|
||||
if (haf == 0 || haf == 2) {
|
||||
count = 0;
|
||||
if (debug) {
|
||||
fprintf(stdout, "\n75%c to 100%c ", 37, 37);
|
||||
fflush(stdout);
|
||||
}
|
||||
z = (int)(th * (double)(max_north - min_north));
|
||||
|
||||
for (lat = (double)min_north, x = 0, y = 0;
|
||||
lat < (double)max_north;
|
||||
y++, lat = (double)min_north + (dpp * (double)y)) {
|
||||
edge.lat = lat;
|
||||
edge.lon = max_west;
|
||||
edge.alt = altitude;
|
||||
|
||||
PlotPropPath(source, edge, mask_value, fd, propmodel,
|
||||
knifeedge, pmenv);
|
||||
count++;
|
||||
|
||||
if (count == z) {
|
||||
|
||||
count = 0;
|
||||
|
||||
if (x == 3)
|
||||
x = 0;
|
||||
else
|
||||
x++;
|
||||
}
|
||||
}
|
||||
|
||||
} //S4
|
||||
|
||||
if (fd != NULL)
|
||||
if (fd != NULL)
|
||||
fclose(fd);
|
||||
|
||||
if (mask_value < 30)
|
||||
|
@@ -10,9 +10,9 @@ void PlotLOSPath(struct site source, struct site destination, char mask_value,
|
||||
void PlotPropPath(struct site source, struct site destination,
|
||||
unsigned char mask_value, FILE * fd, int propmodel,
|
||||
int knifeedge, int pmenv);
|
||||
void PlotLOSMap(struct site source, double altitude, char *plo_filename);
|
||||
void PlotLOSMap(struct site source, double altitude, char *plo_filename, bool use_threads);
|
||||
void PlotPropagation(struct site source, double altitude, char *plo_filename,
|
||||
int propmodel, int knifeedge, int haf, int pmenv);
|
||||
int propmodel, int knifeedge, int haf, int pmenv, bool use_threads);
|
||||
void PlotPath(struct site source, struct site destination, char mask_value);
|
||||
|
||||
#endif /* _LOS_HH_ */
|
||||
|
Reference in New Issue
Block a user