00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "UWBIRIEEE802154APathlossModel.h"
00022
00023 const bool UWBIRIEEE802154APathlossModel::implemented_CMs[] = {
00024 false,
00025 true,
00026 true,
00027 true,
00028 false,
00029 true,
00030 true,
00031 true,
00032 false,
00033 false
00034 };
00035
00036 const UWBIRIEEE802154APathlossModel::CMconfig UWBIRIEEE802154APathlossModel::CMconfigs[] = {
00037
00038 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
00039
00040
00041 { 0.000040738, 1.79, 0,
00042
00043 3, 1.12, 3, 0.047E9,
00044
00045 1.54E9, 0.15E9, 0.095,
00046
00047 22.61E-9, 0, 12.53E-9, 1.883649089,
00048
00049 0.67, 0, 0.28, 0, 0,
00050
00051 0, 0, 0},
00052
00053
00054
00055 { 0.00001349, 4.58, 0,
00056
00057 3, 1.12, 3.5, 0.12E9,
00058
00059 1.77E9, 0.15E9, 0.045,
00060
00061 26.27E-9, 0, 17.5E-9, 1.963360277,
00062
00063 0.69, 0, 0.32, 0, 0,
00064
00065 0, 0, 0},
00066
00067
00068
00069 { 0.000218776, 1.63, 1.9,
00070
00071 3, -3.5, 5.4, 0.016E9,
00072
00073 0.19E9, 2.97E9, 0.0184,
00074
00075 14.6E-9, 0, 6.4E-9, 0,
00076
00077 0.42, 0, 0.31, 0, 0,
00078
00079 0, 0, 0},
00080
00081
00082
00083 { 0.000007244, 3.07, 3.9,
00084
00085 3, -5.3, 1, 0,
00086
00087 0, 0, 0,
00088
00089 0, 0, 0, 0,
00090
00091 0.5, 0, 0.25, 0, 0,
00092
00093 15.21, 11.84, 0.86},
00094
00095
00096
00097 { 0.000046881, 1.76, 0.83,
00098
00099 3, -1.6, 13.6, 0.0048E9,
00100
00101 0.27E9, 2.41E9, 0.062,
00102
00103 31.7E-9, 0, 3.7E-9, 0,
00104
00105 0.77, 0, 0.78, 0, 0,
00106
00107 0, 0, 0},
00108
00109
00110
00111 { 0.000046881, 2.5, 2,
00112
00113 3, 0.4, 10.5, 0.0243E9,
00114
00115 0.15E9, 1.13E9, 0.062,
00116
00117 104.7E-9, 0, 9.3E-9, 0,
00118
00119 0.56, 0, 0.25, 0, 0,
00120
00121 0, 0, 0},
00122
00123
00124
00125 { 0.000012706, 1.58, 3.96,
00126
00127 3, 0, 3.31, 0.0305E9,
00128
00129 0.0225E9, 0, 0,
00130
00131 56E-9, 0, 0.92E-9, 0,
00132
00133 4.1, 0, 2.5, 0, 0,
00134
00135 0, 0, 0},
00136
00137
00138
00139 { 0.000002138, 1.2, 6,
00140
00141 3, -5.6, 4.75, 0.0709E9,
00142
00143 0, 0, 0,
00144
00145 13.47E-9, 0.926, 0.651E-9, 4.32,
00146
00147 0.36, 0, 1.13, 0, 12.99,
00148
00149 0, 0, 0},
00150
00151 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
00152 };
00153
00154 void UWBIRIEEE802154APathlossModel::filterSignal(Signal& s) {
00155
00156
00157
00158
00159
00160 txPower = s.getTransmissionPower();
00161 newTxPower = new TimeMapping<Linear>();
00162 pulsesIter = newTxPower->createIterator();
00163
00164 L = max(1, poisson(cfg.Lmean));
00165
00166 S = pow(10,(normal(0, cfg.sigma_s)/10));
00167
00168
00169 ConstMappingIterator* iter = txPower->createConstIterator();
00170
00171 while (iter->inRange()) {
00172
00173 if (iter->getValue() != 0) {
00174
00175 addEchoes(iter->getPosition().getTime() - IEEE802154A::mandatory_pulse/2);
00176 }
00177 if (!iter->hasNext()) {
00178 break;
00179 }
00180 iter->next();
00181 }
00182 delete iter;
00183 delete pulsesIter;
00184 s.setTransmissionPower(newTxPower);
00185
00186
00187
00188 Move srcMove = s.getMove();
00189 Coord srcCoord, rcvCoord;
00190 distance = 0;
00191 srcCoord = srcMove.getPositionAt(s.getSignalStart());
00192 rcvCoord = move->getPositionAt(s.getSignalStart());
00193 distance = rcvCoord.distance(srcCoord);
00194
00195
00196
00197 double attenuation = getPathloss(fc, BW);
00198 pathlosses.record(attenuation);
00199
00200
00201
00202 SimpleTimeConstMapping* attMapping = new SimpleTimeConstMapping(
00203 attenuation, s.getSignalStart(), s.getSignalStart()+s.getSignalLength());
00204
00205 s.addAttenuation(attMapping);
00206
00207 }
00208
00209 void UWBIRIEEE802154APathlossModel::addEchoes(simtime_t pulseStart) {
00210
00211 nbCalls = nbCalls + 1;
00212 double power = 0;
00213
00214 bool moreTaps = true;
00215 arg.setTime(pulseStart + IEEE802154A::mandatory_pulse/2);
00216 double pulseEnergy = txPower->getValue(arg);
00217 if(doShadowing) {
00218 pulseEnergy = pulseEnergy - S;
00219 }
00220 simtime_t tau_kl = 0;
00221 simtime_t fromClusterStart = 0;
00222
00223 clusterStart = 0;
00224 gamma_l = cfg.gamma_0;
00225 Mcluster = normal(0, cfg.sigma_cluster);
00226 Omega_l = pow(10, Mcluster / 10);
00227
00228 double tapEnergy = sqrt( Omega_l / ( cfg.gamma_0 * ( (1-cfg.Beta)*cfg.lambda_1 + cfg.Beta*cfg.lambda_2 + 1 ) ) );
00229
00230 double mfactor = 0;
00231 double mmean = 0, msigma = 0;
00232 bool firstTap = true;
00233 simtime_t echoEnd = 0;
00234 for (int cluster = 0; cluster < L; cluster++) {
00235 while (moreTaps) {
00236
00237
00238
00239 double pValueStart = newTxPower->getValue(arg);
00240 double pValueEnd = newTxPower->getValue(arg);
00241 simtime_t echoStart = pulseStart + clusterStart + tau_kl;
00242 echoEnd = pulseStart + clusterStart + tau_kl + IEEE802154A::mandatory_pulse;
00243 simtime_t echoPeak = pulseStart + clusterStart + tau_kl + IEEE802154A::mandatory_pulse/2;
00244 arg.setTime(echoEnd);
00245 newTxPower->setValue(arg, pValueEnd);
00246 arg.setTime(echoStart);
00247 newTxPower->setValue(arg, pValueStart);
00248 bool raising = true;
00249
00250 if(firstTap) {
00251 mfactor = cfg.m_0;
00252 } else {
00253 mmean = cfg.m_0 - cfg.k_m*tau_kl.dbl();
00254 msigma = cfg.var_m_0 - cfg.var_k_m*tau_kl.dbl();
00255 mfactor = normal(mmean, msigma);
00256 }
00257
00258
00259
00260
00261
00262
00263
00264
00265 double finalTapEnergy = tapEnergy * pulseEnergy;
00266
00267
00268
00269 map<simtime_t, double> intermediatePoints;
00270
00271
00272 pulsesIter->jumpTo(arg);
00273 simtime_t currentPoint = echoStart;
00274 while(currentPoint < echoEnd) {
00275 if(raising && pulsesIter->getNextPosition().getTime() < echoPeak) {
00276
00277
00278 pulsesIter->next();
00279 double oldValue = pulsesIter->getValue();
00280 currentPoint = pulsesIter->getPosition().getTime();
00281
00282 double echoValue = ((currentPoint - echoStart)/(0.5*IEEE802154A::mandatory_pulse)).dbl();
00283 echoValue = echoValue * finalTapEnergy;
00284 intermediatePoints[currentPoint] = echoValue + oldValue;
00285 } else if(raising && pulsesIter->getNextPosition().getTime() >= echoPeak) {
00286
00287 currentPoint = echoPeak;
00288 arg.setTime(currentPoint);
00289 pulsesIter->jumpTo(arg);
00290 double oldValue = pulsesIter->getValue();
00291 intermediatePoints[currentPoint] = oldValue + finalTapEnergy;
00292 raising = false;
00293 } else if(!raising && pulsesIter->getNextPosition().getTime() < echoEnd) {
00294
00295
00296 pulsesIter->next();
00297 double oldValue = pulsesIter->getValue();
00298 currentPoint = pulsesIter->getPosition().getTime();
00299
00300 double echoValue = 1 - ((currentPoint - echoPeak)/(0.5*IEEE802154A::mandatory_pulse)).dbl();
00301 echoValue = echoValue * finalTapEnergy;
00302 intermediatePoints[currentPoint] = echoValue + oldValue;
00303 } else if (!raising && pulsesIter->getNextPosition().getTime() >= echoEnd) {
00304 currentPoint = echoEnd;
00305 }
00306 }
00307
00308
00309 map<simtime_t, double>::iterator newPointsIter;
00310 newPointsIter = intermediatePoints.begin();
00311 while(newPointsIter != intermediatePoints.end()) {
00312 arg.setTime(newPointsIter->first);
00313 newTxPower->setValue(arg, newPointsIter->second);
00314 newPointsIter++;
00315 }
00316
00317 power = power + finalTapEnergy;
00318
00319
00320 double mix1 = exponential(1 / cfg.lambda_1);
00321 double mix2 = exponential(1 / cfg.lambda_2);
00322 if(mix1 == numeric_limits<double>::infinity()) {
00323 mix1 = 0;
00324 }
00325 if(mix2 == numeric_limits<double>::infinity()) {
00326 mix2 = 0;
00327 }
00328 tau_kl += mix1 * cfg.Beta + (1 - cfg.Beta) * mix2;
00329
00330 tapEnergy = gamma_l.dbl() * ((1 - cfg.Beta) * cfg.lambda_1 + cfg.Beta * cfg.lambda_2 + 1);
00331 tapEnergy = Omega_l / tapEnergy;
00332 tapEnergy = tapEnergy * exp(-tau_kl.dbl() / gamma_l.dbl());
00333 tapEnergy = sqrt(tapEnergy);
00334 if (tapEnergy < tapThreshold) {
00335 moreTaps = false;
00336 }
00337 }
00338 double nextClusterStart = exponential(1 / cfg.Lambda);
00339 if(nextClusterStart > 0.001 || nextClusterStart == numeric_limits<double>::infinity()) {
00340 moreTaps = false;
00341 } else {
00342 clusterStart = clusterStart + nextClusterStart;
00343 gamma_l = cfg.k_gamma * clusterStart + cfg.gamma_0;
00344 Mcluster = normal(0, cfg.sigma_cluster);
00345 Omega_l = pow(10, (10 * log( exp( -clusterStart.dbl() / cfg.Gamma ) ) + Mcluster) / 10);
00346
00347 if(Omega_l > 0.1) {
00348 moreTaps = true;
00349 } else {
00350 moreTaps = false;
00351 }
00352 }
00353 }
00354 arg.setTime(echoEnd);
00355 newTxPower->setValue(arg, 0);
00356 averagePower = averagePower + power;
00357 averagePowers.record( averagePower / ((double) nbCalls));
00358 }
00359
00360
00361
00362
00363
00364 double UWBIRIEEE802154APathlossModel::getPathloss(double fc, double BW) {
00365 double pathloss = 0.5;
00366 pathloss = pathloss * cfg.PL0;
00367 pathloss = pathloss * ntx * nrx;
00368 pathloss = pathloss / pow(distance/d0, cfg.n);
00369
00370
00371
00372
00373
00374
00375
00376
00377 return pathloss;
00378 }
00379
00380 double UWBIRIEEE802154APathlossModel::Rayleigh(double param) {
00381 return weibull(2, sqrt(2) * param);
00382 }
00383