57 MakeDoubleChecker<double> ()) |
57 MakeDoubleChecker<double> ()) |
58 |
58 |
59 .AddAttribute ("RooftopLevel", |
59 .AddAttribute ("RooftopLevel", |
60 " The height of the rooftop [m].", |
60 " The height of the rooftop [m].", |
61 DoubleValue (30.0), |
61 DoubleValue (30.0), |
62 MakeDoubleAccessor (&BuildingsPropagationLossModel::m_rooftopThreshold), |
62 MakeDoubleAccessor (&BuildingsPropagationLossModel::m_rooftopHeight), |
63 MakeDoubleChecker<double> ()) |
63 MakeDoubleChecker<double> ()) |
64 |
64 |
65 .AddAttribute ("MinDistance", |
65 .AddAttribute ("MinDistance", |
66 "The distance under which the propagation model refuses to give results (m) ", |
66 "The distance under which the propagation model refuses to give results (m) ", |
67 DoubleValue (0.5), |
67 DoubleValue (0.5), |
189 |
189 |
190 return (loss); |
190 return (loss); |
191 } |
191 } |
192 |
192 |
193 |
193 |
|
194 |
194 double |
195 double |
195 BuildingsPropagationLossModel::ItuR1411 (Ptr<BuildingsMobilityModel> a, Ptr<BuildingsMobilityModel> b) const |
196 BuildingsPropagationLossModel::ItuR1411 (Ptr<BuildingsMobilityModel> a, Ptr<BuildingsMobilityModel> b) const |
|
197 { |
|
198 return (ItuR1411Los (a,b)); |
|
199 } |
|
200 |
|
201 |
|
202 double |
|
203 BuildingsPropagationLossModel::ItuR1411Los (Ptr<BuildingsMobilityModel> a, Ptr<BuildingsMobilityModel> b) const |
196 { |
204 { |
197 double dist = a->GetDistanceFrom (b); |
205 double dist = a->GetDistanceFrom (b); |
198 double lossLow = 0.0; |
206 double lossLow = 0.0; |
199 double lossUp = 0.0; |
207 double lossUp = 0.0; |
200 double pi = 3.141592653589793; |
208 double pi = 3.141592653589793; |
201 double Lbp = 20*log10(m_lambda*m_lambda/(8*pi*a->GetPosition ().z*b->GetPosition ().z)); |
209 double Lbp = 20*log10(m_lambda*m_lambda/(8*pi*a->GetPosition ().z*b->GetPosition ().z)); |
202 double Rbp = (4 * a->GetPosition ().z * b->GetPosition ().z) / m_lambda; |
210 double Rbp = (4 * a->GetPosition ().z * b->GetPosition ().z) / m_lambda; |
203 // NS_LOG_INFO (this << " Lbp " << Lbp << " Rbp " << Rbp); |
211 // NS_LOG_INFO (this << " Lbp " << Lbp << " Rbp " << Rbp); |
204 if (dist <= Rbp) |
212 if (dist <= Rbp) |
205 { |
213 { |
206 lossLow = Lbp + 20*log10(dist/Rbp); |
214 lossLow = Lbp + 20*log10(dist/Rbp); |
207 lossUp = Lbp + 20 + 25*log10(dist/Rbp); |
215 lossUp = Lbp + 20 + 25*log10(dist/Rbp); |
208 } |
216 } |
209 else |
217 else |
210 { |
218 { |
211 lossLow = Lbp + 40*log10(dist/Rbp); |
219 lossLow = Lbp + 40*log10(dist/Rbp); |
212 lossUp = Lbp + 20 + 40*log10(dist/Rbp); |
220 lossUp = Lbp + 20 + 40*log10(dist/Rbp); |
213 } |
221 } |
214 |
222 |
215 double loss = (lossUp + lossLow) / 2; |
223 double loss = (lossUp + lossLow) / 2; |
216 |
224 |
217 return (loss); |
225 return (loss); |
|
226 } |
|
227 |
|
228 double |
|
229 BuildingsPropagationLossModel::ItuR1411Nlos (Ptr<BuildingsMobilityModel> a, Ptr<BuildingsMobilityModel> b) const |
|
230 { |
|
231 if ((a->GetPosition ().z>m_rooftopHeight) || (b->GetPosition ().z>m_rooftopHeight)) |
|
232 { |
|
233 return (ItuR1411NlosOverRooftop (a,b)); |
|
234 } |
|
235 else |
|
236 { |
|
237 return (ItuR1411NlosStreetCanyons (a,b)); |
|
238 } |
|
239 } |
|
240 |
|
241 double |
|
242 BuildingsPropagationLossModel::ItuR1411NlosOverRooftop (Ptr<BuildingsMobilityModel> a, Ptr<BuildingsMobilityModel> b) const |
|
243 { |
|
244 double Lori = 0.0; |
|
245 if ((m_streetsOrientation>=0)&&(m_streetsOrientation<35)) |
|
246 { |
|
247 Lori = -10.0 + 0.354*m_streetsOrientation; |
|
248 } |
|
249 else if ((m_streetsOrientation>=35)&&(m_streetsOrientation<55)) |
|
250 { |
|
251 Lori = 2.5 + 0.075*m_streetsOrientation; |
|
252 } |
|
253 else if ((m_streetsOrientation>=55)&&(m_streetsOrientation<90)) |
|
254 { |
|
255 Lori = 2.5 + 0.075*m_streetsOrientation; |
|
256 } |
|
257 else |
|
258 { |
|
259 NS_LOG_ERROR (this << " Street Orientation must be in [0,90]"); |
|
260 } |
|
261 |
|
262 double Lrts = -8.2 -10*log10(m_streetsWidth) + 20*log10(m_rooftopHeight - b->GetPosition ().z) + Lori; |
|
263 double distance = a->GetDistanceFrom (b); |
|
264 double Dhb = a->GetPosition ().z - m_rooftopHeight; |
|
265 double ds = (m_lambda * distance * distance) / (Dhb * Dhb); |
|
266 double Lmsd = 0.0; |
|
267 double pi = 3.141592653589793; |
|
268 if (ds < m_buildingsExtend) |
|
269 { |
|
270 double Lbsh = 0.0; |
|
271 double ka = 0.0; |
|
272 double kd = 0.0; |
|
273 double kf = 0.0; |
|
274 if ((a->GetPosition ().z > m_rooftopHeight) || (b->GetPosition ().z > m_rooftopHeight)) |
|
275 { |
|
276 Lbsh = -18*log10(1+Dhb); |
|
277 ka = 54.0; |
|
278 kd = 18.0; |
|
279 } |
|
280 else |
|
281 { |
|
282 Lbsh = 0; |
|
283 kd = 18.0 - 15*Dhb/a->GetPosition ().z; |
|
284 if (distance <500) |
|
285 { |
|
286 ka = 54.0 - 1.6*Dhb*distance/1000; |
|
287 } |
|
288 else |
|
289 { |
|
290 ka = 54.0 - 0.8*Dhb; |
|
291 } |
|
292 } |
|
293 if ((m_environment==Urban)&&(m_citySize==Large)) |
|
294 { |
|
295 kf = 0.7*(m_frequency/925.0 -1); |
|
296 } |
|
297 else |
|
298 { |
|
299 kf = 1.5*(m_frequency/925.0 -1); |
|
300 } |
|
301 Lmsd = Lbsh + ka + kd*log10(distance/1000.0) + kf*log10(m_frequency) -9.0*log10(m_buildingSeparation); // CHECK last d (it's "b" in ITU) |
|
302 } |
|
303 else |
|
304 { |
|
305 double theta = atan (Dhb/m_buildingSeparation); |
|
306 double rho = sqrt(Dhb*Dhb+m_buildingSeparation*m_buildingSeparation); |
|
307 double hb = a->GetPosition ().z; |
|
308 double Qm = 0.0; |
|
309 if ((hb > m_rooftopHeight -1.0) && (hb < m_rooftopHeight + 1.0)) |
|
310 { |
|
311 Qm = m_buildingSeparation / distance; |
|
312 } |
|
313 else if (hb > m_rooftopHeight) |
|
314 { |
|
315 Qm = 2.35*pow(Dhb/distance*sqrt(m_buildingSeparation/m_lambda), 0.9); |
|
316 } |
|
317 else |
|
318 { |
|
319 Qm = m_buildingSeparation/(2*pi*distance)*sqrt(m_lambda/rho)*(1/theta-(1/(2*pi+theta))); |
|
320 } |
|
321 |
|
322 Lmsd = -10*log10(Qm*Qm); |
|
323 } |
|
324 double Lbf = 32.4 + 20*log10(distance/1000) + 20*log10(m_frequency); |
|
325 |
|
326 double loss = 0.0; |
|
327 if (Lrts + Lmsd > 0) |
|
328 { |
|
329 loss = Lbf + Lrts + Lmsd; |
|
330 } |
|
331 else |
|
332 { |
|
333 loss = Lbf; |
|
334 } |
|
335 return (loss); |
|
336 } |
|
337 |
|
338 double |
|
339 BuildingsPropagationLossModel::ItuR1411NlosStreetCanyons (Ptr<BuildingsMobilityModel> a, Ptr<BuildingsMobilityModel> b) const |
|
340 { |
|
341 |
|
342 return (0.0); |
218 } |
343 } |
219 |
344 |
220 |
345 |
221 double |
346 double |
222 BuildingsPropagationLossModel::ItuR1238 (Ptr<BuildingsMobilityModel> a, Ptr<BuildingsMobilityModel> b) const |
347 BuildingsPropagationLossModel::ItuR1238 (Ptr<BuildingsMobilityModel> a, Ptr<BuildingsMobilityModel> b) const |
225 int n = abs (a->GetFloorNumber () - b->GetFloorNumber ()); |
350 int n = abs (a->GetFloorNumber () - b->GetFloorNumber ()); |
226 NS_LOG_INFO (this << " A floor " << (uint16_t)a->GetFloorNumber () << " B floor " << (uint16_t)b->GetFloorNumber () << " n " << n); |
351 NS_LOG_INFO (this << " A floor " << (uint16_t)a->GetFloorNumber () << " B floor " << (uint16_t)b->GetFloorNumber () << " n " << n); |
227 double Lf = 0.0; |
352 double Lf = 0.0; |
228 Ptr<Building> aBuilding = a->GetBuilding (); |
353 Ptr<Building> aBuilding = a->GetBuilding (); |
229 if (aBuilding->GetBuildingType () == Building::Residential) |
354 if (aBuilding->GetBuildingType () == Building::Residential) |
230 { |
355 { |
231 N = 28; |
356 N = 28; |
232 Lf = 4 * n; |
357 Lf = 4 * n; |
233 } |
358 } |
234 else if (aBuilding->GetBuildingType () == Building::Office) |
359 else if (aBuilding->GetBuildingType () == Building::Office) |
235 { |
360 { |
236 N = 30; |
361 N = 30; |
237 Lf = 15 + (4 * (n-1)); |
362 Lf = 15 + (4 * (n-1)); |
238 } |
363 } |
239 else if (aBuilding->GetBuildingType () == Building::Commercial) |
364 else if (aBuilding->GetBuildingType () == Building::Commercial) |
240 { |
365 { |
241 N = 22; |
366 N = 22; |
242 Lf = 6 + (3 * (n-1)); |
367 Lf = 6 + (3 * (n-1)); |
243 } |
368 } |
244 else |
369 else |
245 { |
370 { |
246 NS_LOG_ERROR (this << " Unkwnon Wall Type"); |
371 NS_LOG_ERROR (this << " Unkwnon Wall Type"); |
247 } |
372 } |
248 |
373 |
249 double loss = 20*log10(m_frequency) + N*log10(a->GetDistanceFrom (b)) + Lf - 28.0; |
374 double loss = 20*log10(m_frequency) + N*log10(a->GetDistanceFrom (b)) + Lf - 28.0; |
250 |
375 |
251 return (loss); |
376 return (loss); |
252 } |
377 } |
253 |
378 |
293 // get the BuildingsMobilityModel pointers |
418 // get the BuildingsMobilityModel pointers |
294 Ptr<BuildingsMobilityModel> a1 = DynamicCast<BuildingsMobilityModel> (a); |
419 Ptr<BuildingsMobilityModel> a1 = DynamicCast<BuildingsMobilityModel> (a); |
295 Ptr<BuildingsMobilityModel> b1 = DynamicCast<BuildingsMobilityModel> (b); |
420 Ptr<BuildingsMobilityModel> b1 = DynamicCast<BuildingsMobilityModel> (b); |
296 |
421 |
297 double loss = 0.0; |
422 double loss = 0.0; |
298 NS_LOG_INFO (this << " rooftop " << m_rooftopThreshold); |
423 NS_LOG_INFO (this << " rooftop " << m_rooftopHeight); |
299 |
424 |
300 if (a1->IsOutdoor ()) |
425 if (a1->IsOutdoor ()) |
301 { |
426 { |
302 if (b1->IsOutdoor ()) |
427 if (b1->IsOutdoor ()) |
303 { |
428 { |
304 if (distance > 1000) |
429 if (distance > 1000) |
305 { |
430 { |
306 if ((a1->GetPosition ().z > m_rooftopThreshold) |
431 if ((a1->GetPosition ().z > m_rooftopHeight) |
307 || (b1->GetPosition ().z > m_rooftopThreshold)) |
432 || (b1->GetPosition ().z > m_rooftopHeight)) |
308 { |
433 { |
309 // Over the rooftop tranmission -> Okumura Hata |
434 // Over the rooftop tranmission -> Okumura Hata |
310 loss = OkumuraHata (a1, b1); |
435 loss = OkumuraHata (a1, b1); |
311 NS_LOG_INFO (this << " O-O (>1000): Over the rooftop -> OH : " << loss); |
436 NS_LOG_INFO (this << " O-O (>1000): Over the rooftop -> OH : " << loss); |
312 } |
437 } |