00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <node-core.h>
00031 #include<rng.h>
00032 #include "mfullpropagation.h"
00033 #include "mphy_pktheader.h"
00034 #include "mspectralmask.h"
00035
00037 #define SIDE_NUM 20
00038 #define N_RAYS 1
00039
00040
00041 #define twopi 6.28318530718
00042 #define pi 3.14159265359
00043
00044
00045 static class MFullPropagationClass : public TclClass {
00046 public:
00047 MFullPropagationClass() : TclClass("MPropagation/FullPropagation") {}
00048 TclObject* create(int, const char*const*) {
00049 return (new MFullPropagation());
00050 }
00051 } class_mfullpropagation_class;
00052
00053
00054 void SampleTimer::expire(Event *e)
00055 {
00056 module->simulationStep();
00057 }
00058
00059 MFullPropagation::MFullPropagation()
00060 : amp_(NULL),
00061 incr_(NULL),
00062 phases_(NULL),
00063 fad_(NULL),
00064 maxDopplerShift_(6.0),
00065 xFieldWidth_(0),
00066 yFieldWidth_(0),
00067 d_(-1),
00068 A2_(NULL),
00069 N0_(4),
00070 shadowMat_(NULL),
00071 beta_(3.4),
00072 shadowSigma_(0.0),
00073 refDistance_(1.0),
00074 rayleighFading_(1),
00075 sampleTimer_(this),
00076 timeUnit_(-100),
00077 nodesNum_(0),
00078 nodesIndexArray_(NULL),
00079 debug_(0)
00080 {
00081
00082 bind("maxDopplerShift_", &maxDopplerShift_);
00083 bind("beta_", &beta_);
00084 bind("shadowSigma_", &shadowSigma_);
00085 bind("refDistance_", &refDistance_);
00086 bind("rayleighFading_", &rayleighFading_);
00087 bind("timeUnit_", &timeUnit_);
00088 bind("debug_", &debug_);
00089 bind("xFieldWidth_", &xFieldWidth_);
00090 bind("yFieldWidth_", &yFieldWidth_);
00091 }
00092
00093
00094 int MFullPropagation::command(int argc, const char*const* argv)
00095 {
00096 Tcl& tcl = Tcl::instance();
00097 if(argc==2)
00098 {
00099 if(strcasecmp(argv[1], "Init")==0)
00100 {
00101
00102 Init();
00103 return TCL_OK;
00104 }
00105 }
00106 if(argc==3)
00107 {
00108 if(strcasecmp(argv[1], "newNode")==0)
00109 {
00110
00111 Position* pos = dynamic_cast<Position*> (TclObject::lookup(argv[2]));
00112 if(!pos)
00113 {
00114 fprintf(stderr, "Error MFullPropagation::command, does not recognize the Position class instance");
00115 return TCL_ERROR;
00116 }
00117
00118 if (debug_)
00119 printf("MFullPropagation: add new simulated node (id %d, pt. %p), position (%.2f,%.2f), tot %d\n", nodesNum_, pos, pos->getX(), pos->getY(), nodesNum_+1);
00120 Position** temp = new Position*[nodesNum_+1];
00121 if (nodesNum_>0)
00122 {
00123 memcpy(temp, nodesIndexArray_, (sizeof(Position*))*nodesNum_);
00124 delete [] nodesIndexArray_;
00125 }
00126 nodesIndexArray_ = temp;
00127 nodesIndexArray_[nodesNum_++] = pos;
00128 return TCL_OK;
00129 }
00130 }
00131 return MPropagation::command(argc, argv);
00132 }
00133
00134
00135 double MFullPropagation::Gaussian()
00136 {
00137 double x1, x2, w, y1;
00138 static double y2;
00139 static int use_last = 0;
00140
00141 if (use_last)
00142 {
00143 y1 = y2;
00144 use_last = 0;
00145 }
00146 else
00147 {
00148 do
00149 {
00150
00151
00152 x1 = 2.0 * RNG::defaultrng()->uniform_double() - 1.0;
00153 x2 = 2.0 * RNG::defaultrng()->uniform_double() - 1.0;
00154 w = x1 * x1 + x2 * x2;
00155 } while ( w >= 1.0 );
00156
00157 w = sqrt( (-2.0 * log( w ) ) / w );
00158 y1 = x1 * w;
00159 y2 = x2 * w;
00160 use_last = 1;
00161 }
00162 return(y1);
00163 }
00164
00165
00166 void MFullPropagation::initialize_common(unsigned long int N0, double d, double **amp, double *incr)
00167 {
00168 unsigned long int i,N=4*N0+2;
00169
00170 int n_users = nodesNum_;
00171 int tot_bases =nodesNum_;
00172
00173 nRays_ = 1;
00174
00175 for(i=0;i<=N0;i++){
00176 incr[i]=twopi*cos(twopi*i/N)*d;
00177
00178 amp[i][0]=2*cos(pi*i/(N0+1))/sqrt(2*N0);
00179 amp[i][1]=2*sin(pi*i/(N0+1))/sqrt(2*N0+2);
00180
00181 }
00182 amp[0][0]=amp[0][0]/sqrt(2.0);
00183 amp[0][1]=amp[0][1]/sqrt(2.0);
00184 }
00185
00186
00187 void MFullPropagation::initialize_phases(unsigned long int N0, double *phases)
00188 {
00189 unsigned long int i;
00190 double temp;
00191
00192 for(i=0;i<=N0;i++){
00193
00194 temp = RNG::defaultrng()->uniform_double();
00195 phases[i]=twopi*temp;
00196 }
00197 }
00198
00199
00200 void MFullPropagation::initialize_all_phases(unsigned long int N0,double ****phases)
00201 {
00202 int n_users = nodesNum_;
00203 int tot_bases =nodesNum_;
00204 unsigned long int i,c,l;
00205
00206 for(i=0;i<n_users;i++)
00207 for(c=0;c<tot_bases;c++)
00208 for(l=0;l<nRays_;l++)
00209 initialize_phases(N0,phases[i][c][l]);
00210 }
00211
00212
00213 void MFullPropagation::oscillators(unsigned long int N0,double *phases,double *incr, double **amp,double *x)
00214 {
00215 unsigned long int i;
00216 double temp,temp0,temp1,osc;
00217
00218 temp0=0;
00219 temp1=0;
00220 for(i=0;i<=N0;i++){
00221 temp=phases[i]+incr[i];
00222 for(;temp>twopi;)temp-=twopi;
00223 phases[i]=temp;
00224 osc=cos(temp);
00225 temp0+=amp[i][0]*osc;
00226 temp1+=amp[i][1]*osc;
00227 }
00228 x[0]=temp0;
00229 x[1]=temp1;
00230 }
00231
00232
00233 void MFullPropagation::compute_fading(unsigned long int N0,double ****phases,double *incr, double **amp,double **fad,double ***A2)
00234 {
00235 int n_users = nodesNum_;
00236 int tot_bases =nodesNum_;
00237 unsigned long int i,c,l;
00238 double fading_comps[2];
00239
00240 for(i=0;i<n_users;i++)
00241 for(c=0;c<tot_bases;c++)
00242 {
00243 fad[i][c]=0.0;
00244 for(l=0;l<nRays_;l++){
00245 oscillators(N0,phases[i][c][l],incr,amp,fading_comps);
00246 A2_[i][c][l]=(pow(fading_comps[0],2.0)+pow(fading_comps[1],2.0));
00247 fad[i][c]+=A2[i][c][l];
00248 }
00249 }
00250 }
00251
00252 void MFullPropagation::ShadowInit()
00253 {
00254 unsigned int sourceX,sourceY,destX,destY;
00255
00256 shadowMat_ = (double*)malloc(SIDE_NUM*SIDE_NUM*SIDE_NUM*SIDE_NUM*sizeof(double));
00257 if(shadowMat_==NULL) {
00258 fprintf(stderr, "MFullPropagation::ShadowInit, malloc error\n");
00259 exit(1);
00260 }
00261
00262 for(sourceX=0; sourceX<SIDE_NUM; sourceX++)
00263 {
00264 for(sourceY=0; sourceY<SIDE_NUM; sourceY++)
00265 {
00266 for(destX=0; destX<SIDE_NUM; destX++)
00267 {
00268 for(destY=0; destY<SIDE_NUM; destY++)
00269 {
00270 bool flag=FALSE;
00271 unsigned int temp;
00272
00273 if(sourceX-destX<0)
00274 temp = destX - sourceX;
00275 else
00276 temp = sourceX - destX;
00277 if(temp<=3)
00278 flag=TRUE;
00279 if(sourceY-destY<0)
00280 temp = destY - sourceY;
00281 else
00282 temp= sourceY - destY;
00283 if(temp<=3)
00284 flag=TRUE;
00285
00286 if(temp==TRUE)
00287 shadowMat_[sourceX*SIDE_NUM*SIDE_NUM*SIDE_NUM+
00288 sourceY*SIDE_NUM*SIDE_NUM+destX*SIDE_NUM+destY]=
00289 0.0;
00290 else
00291 if((sourceX>destX)||
00292 ((sourceX==destX)&&(sourceY>destY))) {
00293
00294
00295
00296
00297 shadowMat_[sourceX*SIDE_NUM*SIDE_NUM*SIDE_NUM+
00298 sourceY*SIDE_NUM*SIDE_NUM+destX*SIDE_NUM+
00299 destY] = shadowMat_[destX*SIDE_NUM*SIDE_NUM*
00300 SIDE_NUM+destY*SIDE_NUM*SIDE_NUM+sourceX*
00301 SIDE_NUM+sourceY];
00302 }
00303 else {
00304
00305 shadowMat_[sourceX*SIDE_NUM*SIDE_NUM*SIDE_NUM+
00306 sourceY*SIDE_NUM*SIDE_NUM+destX*SIDE_NUM+destY]=
00307 Gaussian()*shadowSigma_;
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320 }
00321 }
00322 }
00323 }
00324 }
00325 }
00326
00327
00328
00329
00330 void MFullPropagation::FadingInit() {
00331
00332 unsigned long int n_user = nodesNum_;
00333 unsigned long int tot_bases = nodesNum_;
00334 unsigned long int n_rays = N_RAYS;
00335 unsigned long int i,c,l;
00336
00337
00338 amp_ = new double*[N0_+1];
00339 if(amp_==NULL){
00340 fprintf(stderr, "MFullPropagation::FadingInit, malloc error (amp)\n");
00341 exit(1);
00342 }
00343
00344 incr_ = new double[N0_+1];
00345 if(incr_==NULL){
00346 fprintf(stderr, "MFullPropagation::FadingInit, malloc error (incr)\n");
00347 exit(1);
00348 }
00349 for(i=0;i<=N0_;i++){
00350
00351 amp_[i] = new double[2];
00352 if(amp_[i]==NULL) {
00353 fprintf(stderr, "MFullPropagation::FadingInit, malloc error (amp[])\n");
00354 exit(1);
00355 }
00356 }
00357
00358 phases_ = new double***[n_user];
00359 if(phases_==NULL){
00360 fprintf(stderr, "MFullPropagation::FadingInit, malloc error (phases)\n");
00361 exit(1);
00362 }
00363
00364 fad_ = new double*[n_user];
00365 if(fad_==NULL) {
00366 fprintf(stderr, "MFullPropagation::FadingInit, malloc error (fad)\n");
00367 exit(1);
00368 }
00369
00370 A2_ = new double**[n_user];
00371 if(A2_==NULL){
00372 fprintf(stderr, "MFullPropagation::FadingInit, malloc error (A2)\n");
00373 exit(1);
00374 }
00375 for(i=0;i<n_user;i++){
00376
00377 phases_[i] = new double**[tot_bases];
00378 if(phases_[i]==NULL){
00379 fprintf(stderr, "MFullPropagation::FadingInit, malloc error (phases[])\n");
00380 exit(1);
00381 }
00382
00383 A2_[i] = new double*[tot_bases];
00384 if(A2_[i]==NULL){
00385 fprintf(stderr, "MFullPropagation::FadingInit, malloc error (A2[])\n");
00386 exit(1);
00387 }
00388
00389 fad_[i] = new double[tot_bases];
00390 if(fad_[i]==NULL) {
00391 fprintf(stderr, "MFullPropagation::FadingInit, malloc error (fad[])\n");
00392 exit(1);
00393 }
00394 for(c=0;c<tot_bases;c++){
00395
00396 phases_[i][c] = new double*[n_rays];
00397 if(phases_[i][c]==NULL) {
00398 fprintf(stderr, "MFullPropagation::FadingInit, malloc error (phases[][])\n");
00399 exit(1);
00400 }
00401
00402 A2_[i][c] = new double[n_rays];
00403 if(A2_[i][c]==NULL) {
00404 fprintf(stderr, "MFullPropagation::FadingInit, malloc error (A2[][])\n");
00405 exit(1);
00406 }
00407 for(l=0;l<n_rays;l++){
00408
00409 phases_[i][c][l] = new double[N0_+1];
00410 if(phases_[i][c][l]==NULL) {
00411 fprintf(stderr, "MFullPropagation::FadingInit, malloc error (phases[][][])\n");
00412 exit(1);
00413 }
00414 }
00415 }
00416 }
00417
00418
00419 d_ = maxDopplerShift_ * timeUnit_;
00420
00421
00422 initialize_common(N0_,d_,amp_,incr_);
00423 initialize_all_phases(N0_,phases_);
00424 compute_fading(N0_, phases_, incr_, amp_, fad_, A2_);
00425
00426 simulationStep();
00427 }
00428
00429
00430 void MFullPropagation::Init() {
00431
00432 if (nodesNum_<=0)
00433 {
00434 fprintf(stderr, "MFullPropagation::Init, nodes simulated must be greater than 0, define them with <newNode> TCL command\n");
00435 exit(1);
00436 }
00437 if (((xFieldWidth_<=0)||(yFieldWidth_<=0))&&(shadowSigma_==0))
00438 {
00439 fprintf(stderr, "MFullPropagation::Init, x/y field width must be greater than zero\n");
00440 exit(1);
00441 }
00442 if (beta_<0)
00443 {
00444 fprintf(stderr, "MFullPropagation::Init, beta below zero\n");
00445 exit(1);
00446 }
00447 if (refDistance_<0)
00448 {
00449 fprintf(stderr, "MFullPropagation::Init, reference distance below zero\n");
00450 exit(1);
00451 }
00452 if (shadowSigma_<0)
00453 {
00454 fprintf(stderr, "MFullPropagation::Init, shadow Sigma below zero\n");
00455 exit(1);
00456 }
00457 if ((rayleighFading_!=0)&&(rayleighFading_!=1))
00458 {
00459 fprintf(stderr, "MFullPropagation::Init, rayleighFading usage: 1 simulate fading, 0 don't simulate fading'\n");
00460 exit(1);
00461 }
00462 if (rayleighFading_==1)
00463 {
00464 if (timeUnit_==0)
00465 {
00466 fprintf(stderr, "MFullPropagation::Init, timeUnit must be different from 0\n");
00467 exit(1);
00468 }
00469 if (timeUnit_<0)
00470
00471 timeUnit_ = 1. / (maxDopplerShift_*fabs(timeUnit_));
00472 }
00473
00474
00475
00476
00477 if(shadowSigma_>0.0)
00478 ShadowInit();
00479 else
00480 shadowMat_=NULL;
00481 if(rayleighFading_==1)
00482 FadingInit();
00483 else {
00484 amp_=NULL;
00485 incr_=NULL;
00486 phases_=NULL;
00487 fad_=NULL;
00488 A2_=NULL;
00489 d_=0.0;
00490 }
00491 }
00492
00493
00494
00495 double MFullPropagation::PathLoss(double distance, double lambda)
00496 {
00497 double lossConst, att;
00498
00499 lossConst = pow((lambda)/(4*pi*refDistance_),2.0);
00500
00501 if(refDistance_ > distance)
00502 {
00503 att = lossConst;
00504 }
00505 else
00506 {
00507 att = lossConst * pow((refDistance_/distance), beta_);
00508 }
00509 return (att);
00510 }
00511
00512
00513 double MFullPropagation::Shadowing(Position* node1, Position* node2)
00514 {
00515
00516 unsigned int sourceX, sourceY, destX, destY;
00517 if(shadowMat_==NULL)
00518
00519 return(1.0);
00520 else {
00521 sourceX=(unsigned int)(node1->getX() * SIDE_NUM/xFieldWidth_);
00522 sourceY=(unsigned int)(node1->getY() * SIDE_NUM/yFieldWidth_);
00523 destX=(unsigned int)(node2->getX() * SIDE_NUM/xFieldWidth_);
00524 destY=(unsigned int)(node2->getY() * SIDE_NUM/yFieldWidth_);
00525 assert((sourceX>=0) && (sourceX<SIDE_NUM )
00526 && (sourceY>=0) && (sourceY<SIDE_NUM)
00527 && (destX>=0) && (destX<SIDE_NUM)
00528 && (destY>=0) && (destY<SIDE_NUM));
00529 double sh = shadowMat_[sourceX*SIDE_NUM*SIDE_NUM*SIDE_NUM+sourceY*SIDE_NUM*SIDE_NUM+destX*SIDE_NUM+destY];
00530 return(pow(10.0, ((double)(sh))/((double)10.0)));
00531 }
00532 }
00533
00534
00535 double MFullPropagation::Rayleigh(int txId, int rxId) {
00536
00537
00538 if(fad_==NULL)
00539 return(1.0);
00540 else
00541 return(fad_[txId][rxId]);
00542 }
00543
00544 int MFullPropagation::getSimulatedNodeId(Position* p)
00545 {
00546 for(int i=0; i<nodesNum_; i++)
00547 {
00548 if (nodesIndexArray_[i]==p) return(i);
00549 }
00550 return (-1);
00551 }
00552
00553
00554 void MFullPropagation::simulationStep()
00555 {
00556
00557 compute_fading(N0_, phases_, incr_, amp_, fad_, A2_);
00558
00559 sampleTimer_.resched(timeUnit_);
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598 }
00599
00600
00601 double MFullPropagation::getGain(Packet* p)
00602 {
00603
00604 hdr_MPhy* h = HDR_MPHY(p);
00605
00606 double pl = PathLoss(h->srcPosition->getDist(h->dstPosition), (double)(((double)3e8) / h->srcSpectralMask->getFreq()));
00607 double sh = Shadowing(h->srcPosition, h->dstPosition);
00608 int id1 = getSimulatedNodeId(h->srcPosition);
00609 int id2 = getSimulatedNodeId(h->dstPosition);
00610 if ((id1<0)||(id2<0))
00611 {
00612 fprintf(stderr, "MFullPropagation::getGain, unrecognized node, (%d,%p) or (%d,%p)\n", id1, h->srcPosition, id2, h->dstPosition);
00613
00614
00615
00616
00617 exit(1);
00618 }
00619 double fad = Rayleigh(id1, id2);
00620
00621
00622
00623 return (pl*sh*fad);
00624 }
00625