24#include "ns3/double.h"
25#include "ns3/geocentric-constant-position-mobility-model.h"
26#include "ns3/integer.h"
28#include "ns3/mobility-model.h"
30#include "ns3/phased-array-model.h"
31#include "ns3/pointer.h"
32#include "ns3/string.h"
33#include <ns3/simulator.h>
47static constexpr double DEG2RAD = M_PI / 180.0;
52 0.0447, -0.0447, 0.1413, -0.1413, 0.2492, -0.2492, 0.3715, -0.3715, 0.5129, -0.5129,
53 0.6797, -0.6797, 0.8844, -0.8844, 1.1481, -1.1481, 1.5195, -1.5195, 2.1551, -2.1551,
65 {1, 0, 0, 0, 0, 0, 0},
66 {0, 1, 0, 0, 0, 0, 0},
67 {-0.5, 0, 0.866025, 0, 0, 0, 0},
68 {0, 0, 0, 1, 0, 0, 0},
69 {0, 0, 0, 0, 1, 0, 0},
70 {0.01, 0, -0.0519615, 0.73, -0.2, 0.651383, 0},
71 {-0.17, -0.02, 0.21362, -0.14, 0.24, 0.142773, 0.909661},
85 {-0.5, 0.866025, 0, 0, 0, 0},
86 {0.6, -0.11547, 0.791623, 0, 0, 0},
88 {-0.04, -0.138564, 0.540662, -0.18, 0.809003, 0},
89 {-0.25, -0.606218, -0.240013, 0.26, -0.231685, 0.625392},
104 {0, 0, -0.7, 0.714143, 0, 0},
105 {0, 0, 0.66, -0.123225, 0.741091, 0},
106 {0, 0, 0.47, 0.152631, -0.393194, 0.775373},
118 {1, 0, 0, 0, 0, 0, 0},
119 {0, 1, 0, 0, 0, 0, 0},
120 {-0.4, -0.4, 0.824621, 0, 0, 0, 0},
121 {-0.5, 0, 0.242536, 0.83137, 0, 0, 0},
122 {-0.5, -0.2, 0.630593, -0.484671, 0.278293, 0, 0},
123 {0, 0, -0.242536, 0.672172, 0.642214, 0.27735, 0},
124 {-0.8, 0, -0.388057, -0.367926, 0.238537, -3.58949e-15, 0.130931},
138 {-0.4, 0.916515, 0, 0, 0, 0},
139 {-0.6, 0.174574, 0.78072, 0, 0, 0},
140 {0, 0.654654, 0.365963, 0.661438, 0, 0},
141 {0, -0.545545, 0.762422, 0.118114, 0.327327, 0},
142 {-0.4, -0.174574, -0.396459, 0.392138, 0.49099, 0.507445},
155 {-0.5, 0.866025, 0, 0, 0, 0},
156 {0.2, 0.57735, 0.791623, 0, 0, 0},
157 {0, 0.46188, -0.336861, 0.820482, 0, 0},
158 {0, -0.69282, 0.252646, 0.493742, 0.460857, 0},
159 {0, -0.23094, 0.16843, 0.808554, -0.220827, 0.464515},
172 {1, 0, 0, 0, 0, 0, 0},
173 {0.5, 0.866025, 0, 0, 0, 0, 0},
174 {-0.4, -0.57735, 0.711805, 0, 0, 0, 0},
175 {-0.5, 0.057735, 0.468293, 0.726201, 0, 0, 0},
176 {-0.4, -0.11547, 0.805464, -0.23482, 0.350363, 0, 0},
177 {0, 0, 0, 0.688514, 0.461454, 0.559471, 0},
178 {0, 0, 0.280976, 0.231921, -0.490509, 0.11916, 0.782603},
192 {-0.7, 0.714143, 0, 0, 0, 0},
194 {-0.4, 0.168034, 0, 0.90098, 0, 0},
195 {0, -0.70014, 0.5, 0.130577, 0.4927, 0},
196 {0, 0, 0.5, 0.221981, -0.566238, 0.616522},
209 {-0.5, 0.866025, 0, 0, 0, 0},
210 {0.2, 0.57735, 0.791623, 0, 0, 0},
211 {0, 0.46188, -0.336861, 0.820482, 0, 0},
212 {0, -0.69282, 0.252646, 0.493742, 0.460857, 0},
213 {0, -0.23094, 0.16843, 0.808554, -0.220827, 0.464515},
225 {1, 0, 0, 0, 0, 0, 0},
226 {0.5, 0.866025, 0, 0, 0, 0, 0},
227 {-0.8, -0.11547, 0.588784, 0, 0, 0, 0},
228 {-0.4, 0.23094, 0.520847, 0.717903, 0, 0, 0},
229 {-0.5, 0.288675, 0.73598, -0.348236, 0.0610847, 0, 0},
230 {0.2, -0.11547, 0.418943, 0.541106, 0.219905, 0.655744, 0},
231 {0.3, -0.057735, 0.73598, -0.348236, 0.0610847, -0.304997, 0.383375},
245 {-0.5, 0.866025, 0, 0, 0, 0},
246 {0, 0.46188, 0.886942, 0, 0, 0},
247 {-0.4, -0.23094, 0.120263, 0.878751, 0, 0},
248 {0, -0.311769, 0.55697, -0.249198, 0.728344, 0},
249 {0, -0.069282, 0.295397, 0.430696, 0.468462, 0.709214},
261 {1, 0, 0, 0, 0, 0, 0},
262 {0, 1, 0, 0, 0, 0, 0},
263 {-0.4, -0.4, 0.824621, 0, 0, 0, 0},
264 {-0.5, 0, 0.242536, 0.83137, 0, 0, 0},
265 {-0.5, -0.2, 0.630593, -0.484671, 0.278293, 0, 0},
266 {0, 0, -0.242536, 0.672172, 0.642214, 0.27735, 0},
267 {-0.8, 0, -0.388057, -0.367926, 0.238537, -4.09997e-15, 0.130931},
280 {-0.4, 0.916515, 0, 0, 0, 0},
281 {-0.6, 0.174574, 0.78072, 0, 0, 0},
282 {0, 0.654654, 0.365963, 0.661438, 0, 0},
283 {0, -0.545545, 0.762422, 0.118114, 0.327327, 0},
284 {-0.4, -0.174574, -0.396459, 0.392138, 0.49099, 0.507445},
296 {1, 0, 0, 0, 0, 0, 0},
297 {0, 1, 0, 0, 0, 0, 0},
298 {-0.4, -0.4, 0.824621, 0, 0, 0, 0},
299 {-0.5, 0, 0.242536, 0.83137, 0, 0, 0},
300 {-0.5, -0.2, 0.630593, -0.484671, 0.278293, 0, 0},
301 {0, 0, -0.242536, 0.672172, 0.642214, 0.27735, 0},
302 {-0.8, 0, -0.388057, -0.367926, 0.238537, -4.09997e-15, 0.130931},
319 {-0.21, 0.977701, 0, 0, 0, 0},
320 {-0.48, 0.459445, 0.747335, 0, 0, 0},
321 {-0.05, 0.377927, 0.28416, 0.879729, 0, 0},
322 {-0.02, 0.691213, 0.258017, 0.073265, 0.670734, 0},
323 {-0.31, -0.00521632, -0.115615, 0.0788023, 0.00218104, 0.940368},
328 {-0.25, 0.968246, 0, 0, 0, 0},
329 {-0.52, 0.35115, 0.778648, 0, 0, 0},
330 {-0.04, 0.371806, 0.345008, 0.860889, 0, 0},
331 {0, 0.743613, 0.281102, 0.0424415, 0.605161, 0},
332 {-0.32, 0.0206559, -0.0689057, 0.154832, 0.061865, 0.929852},
337 {-0.21, 0.977701, 0, 0, 0, 0},
338 {-0.52, 0.450853, 0.725487, 0, 0, 0},
339 {-0.04, 0.288023, 0.260989, 0.920504, 0, 0},
340 {0.01, 0.697657, 0.386856, 0.0418183, 0.601472, 0},
341 {-0.33, 0.0416283, -0.0694268, 0.166137, 0.139937, 0.915075},
346 {-0.26, 0.965609, 0, 0, 0, 0},
347 {-0.53, 0.395813, 0.749955, 0, 0, 0},
348 {-0.04, 0.299914, 0.320139, 0.897754, 0, 0},
349 {0.01, 0.696556, 0.372815, 0.0580784, 0.610202, 0},
350 {-0.33, 0.0457742, -0.0173584, 0.154417, 0.129332, 0.920941},
355 {-0.25, 0.968246, 0, 0, 0, 0},
356 {-0.57, 0.420864, 0.705672, 0, 0, 0},
357 {-0.03, 0.229797, 0.235501, 0.943839, 0, 0},
358 {0.03, 0.679063, 0.384466, 0.0681379, 0.6209, 0},
359 {-0.41, -0.147173, -0.229228, 0.270707, 0.293002, 0.773668},
364 {-0.2, 0.979796, 0, 0, 0, 0},
365 {-0.53, 0.473568, 0.703444, 0, 0, 0},
366 {-0.05, 0.204124, 0.109225, 0.971547, 0, 0},
367 {0.03, 0.68994, 0.411073, 0.0676935, 0.591202, 0},
368 {-0.4, -0.224537, -0.292371, 0.275609, 0.301835, 0.732828},
373 {-0.19, 0.981784, 0, 0, 0, 0},
374 {-0.5, 0.524555, 0.689088, 0, 0, 0},
375 {-0.03, 0.228462, 0.18163, 0.955989, 0, 0},
376 {-0.02, 0.637818, 0.428725, 0.00608114, 0.639489, 0},
377 {-0.36, -0.18171, -0.282523, 0.106726, 0.123808, 0.854894},
382 {-0.2, 0.979796, 0, 0, 0, 0},
383 {-0.49, 0.502145, 0.712566, 0, 0, 0},
384 {-0.01, 0.232702, 0.151916, 0.960558, 0, 0},
385 {-0.05, 0.612372, 0.376106, 0.0206792, 0.693265, 0},
386 {-0.37, -0.320475, -0.365405, -0.00376264, 0.0364343, 0.790907},
391 {-0.19, 0.981784, 0, 0, 0, 0},
392 {-0.38, 0.58852, 0.713613, 0, 0, 0},
393 {-0.03, 0.360874, 0.12082, 0.924269, 0, 0},
394 {-0.12, 0.526796, 0.34244, 0.0594196, 0.766348, 0},
395 {-0.33, -0.257389, -0.24372, -0.257035, -0.176521, 0.817451},
408 {1, 0, 0, 0, 0, 0, 0},
409 {0, 1, 0, 0, 0, 0, 0},
410 {-0.4, -0.4, 0.824621, 0, 0, 0, 0},
411 {-0.5, 0, 0.242536, 0.83137, 0, 0, 0},
412 {-0.5, -0.2, 0.630593, -0.484671, 0.278293, 0, 0},
413 {0, 0, -0.242536, 0.672172, 0.642214, 0.27735, 0},
414 {-0.8, 0, -0.388057, -0.367926, 0.238537, -4.09997e-15, 0.130931},
427 {-0.4, 0.916515, 0, 0, 0, 0},
428 {-0.6, 0.174574, 0.78072, 0, 0, 0},
429 {0, 0.654654, 0.365963, 0.661438, 0, 0},
430 {0, -0.545545, 0.762422, 0.118114, 0.327327, 0},
431 {-0.4, -0.174574, -0.396459, 0.392138, 0.49099, 0.507445},
443 {1, 0, 0, 0, 0, 0, 0},
444 {0, 1, 0, 0, 0, 0, 0},
445 {-0.5, 0, 0.866025, 0, 0, 0, 0},
446 {0, 0, 0, 1, 0, 0, 0},
447 {0, 0, 0, 0, 1, 0, 0},
448 {0.01, 0, -0.0519615, 0.73, -0.2, 0.651383, 0},
449 {-0.17, -0.02, 0.21362, -0.14, 0.24, 0.142773, 0.909661},
466 {-0.36, 0.932952, 0, 0, 0, 0},
467 {0.45, 0.516639, 0.728412, 0, 0, 0},
468 {0.02, 0.329277, 0.371881, 0.867687, 0, 0},
469 {-0.06, 0.59853, 0.436258, -0.0324062, 0.668424, 0},
470 {-0.07, 0.0373009, 0.305087, -0.0280496, -0.225204, 0.921481},
475 {-0.39, 0.920815, 0, 0, 0, 0},
476 {0.52, 0.426579, 0.740021, 0, 0, 0},
477 {0, 0.347518, -0.0381664, 0.936896, 0, 0},
478 {-0.04, 0.710675, 0.172483, 0.116993, 0.670748, 0},
479 {-0.17, -0.0394216, 0.115154, 0.243458, -0.0702635, 0.944498},
484 {-0.41, 0.912086, 0, 0, 0, 0},
485 {0.54, 0.49491, 0.680782, 0, 0, 0},
486 {0, 0.350844, -0.152231, 0.923977, 0, 0},
487 {-0.04, 0.694672, 0.0702137, 0.0832998, 0.709903, 0},
488 {-0.19, -0.0854087, 0.0805978, 0.283811, -0.137441, 0.922318},
493 {-0.37, 0.929032, 0, 0, 0, 0},
494 {0.53, 0.480177, 0.698949, 0, 0, 0},
495 {0.01, 0.434538, 0.00864797, 0.900556, 0, 0},
496 {-0.05, 0.765851, -0.0303947, 0.0421641, 0.63896, 0},
497 {-0.17, -0.16458, 0.0989022, 0.158081, -0.150425, 0.941602},
502 {-0.4, 0.916515, 0, 0, 0, 0},
503 {0.55, 0.403703, 0.731111, 0, 0, 0},
504 {0.02, 0.499719, -0.0721341, 0.862947, 0, 0},
505 {-0.06, 0.835775, -0.156481, 0.0373835, 0.521534, 0},
506 {-0.19, -0.301141, 0.145082, 0.144564, -0.0238067, 0.911427},
511 {-0.41, 0.912086, 0, 0, 0, 0},
512 {0.56, 0.339442, 0.755764, 0, 0, 0},
513 {0.02, 0.436582, -0.0256617, 0.899076, 0, 0},
514 {-0.07, 0.856608, -0.12116, 0.0715303, 0.491453, 0},
515 {-0.2, -0.331109, 0.15136, 0.036082, 0.031313, 0.908391},
520 {-0.4, 0.916515, 0, 0, 0, 0},
521 {0.56, 0.386246, 0.732949, 0, 0, 0},
522 {0.04, 0.573913, -0.0601289, 0.815726, 0, 0},
523 {-0.11, 0.813953, -0.0720183, 0.0281118, 0.565158, 0},
524 {-0.19, -0.432071, 0.236423, -0.0247788, -0.0557206, 0.847113},
529 {-0.46, 0.887919, 0, 0, 0, 0},
530 {0.58, 0.469412, 0.665772, 0, 0, 0},
531 {0.01, 0.309262, -0.286842, 0.90663, 0, 0},
532 {-0.05, 0.762457, -0.268721, -0.0467443, 0.584605, 0},
533 {-0.23, -0.580909, 0.399665, 0.0403629, 0.326208, 0.584698},
538 {-0.3, 0.953939, 0, 0, 0, 0},
539 {0.47, 0.81871, 0.329868, 0, 0, 0},
540 {0.06, 0.0712834, -0.595875, 0.797654, 0, 0},
541 {-0.1, 0.408831, -0.0233859, 0.0412736, 0.905873, 0},
542 {-0.13, -0.407783, 0.439436, -0.0768289, -0.212875, 0.756631},
561 {-0.36, 0.932952, 0, 0, 0, 0},
562 {0.45, 0.527358, 0.72069, 0, 0, 0},
563 {0.02, 0.350715, 0.355282, 0.866241, 0, 0},
564 {-0.07, 0.562515, 0.478504, 0.0162932, 0.670406, 0},
565 {-0.06, 0.0411597, 0.270982, 0.0121094, -0.159927, 0.946336},
570 {-0.38, 0.924986, 0, 0, 0, 0},
571 {0.52, 0.473088, 0.711188, 0, 0, 0},
572 {0, 0.367573, -0.0617198, 0.927944, 0, 0},
573 {-0.04, 0.68628, 0.149228, 0.115257, 0.701332, 0},
574 {-0.16, -0.0441088, 0.118207, 0.251641, -0.0752458, 0.943131},
579 {-0.42, 0.907524, 0, 0, 0, 0},
580 {0.54, 0.48131, 0.690464, 0, 0, 0},
581 {0, 0.363627, -0.137613, 0.921324, 0, 0},
582 {-0.04, 0.686704, 0.117433, 0.104693, 0.708581, 0},
583 {-0.19, -0.0438556, 0.0922685, 0.269877, -0.136292, 0.928469},
588 {-0.36, 0.932952, 0, 0, 0, 0},
589 {0.53, 0.483197, 0.696865, 0, 0, 0},
590 {0.01, 0.464761, -0.0285153, 0.88492, 0, 0},
591 {-0.05, 0.763169, 0.140255, 0.0562856, 0.626286, 0},
592 {-0.16, -0.126051, 0.0942905, 0.195354, -0.217188, 0.92967},
597 {-0.39, 0.920815, 0, 0, 0, 0},
598 {0.55, 0.406705, 0.729446, 0, 0, 0},
599 {0.01, 0.503793, -0.123923, 0.854831, 0, 0},
600 {-0.06, 0.821664, -0.207246, 0.0245302, 0.526988, 0},
601 {-0.19, -0.254231, 0.10679, 0.190931, -0.0665276, 0.920316},
606 {-0.42, 0.907524, 0, 0, 0, 0},
607 {0.56, 0.391395, 0.730213, 0, 0, 0},
608 {0.02, 0.427978, -0.0393147, 0.902712, 0, 0},
609 {-0.06, 0.820694, -0.119986, 0.105509, 0.545281, 0},
610 {-0.2, -0.279882, 0.180145, 0.0563477, -0.0121631, 0.919723},
615 {-0.36, 0.932952, 0, 0, 0, 0},
616 {0.54, 0.519212, 0.662434, 0, 0, 0},
617 {0.04, 0.412025, -0.0234416, 0.909992, 0, 0},
618 {-0.09, 0.758452, -0.0682296, 0.0214276, 0.64151, 0},
619 {-0.17, -0.387158, 0.306169, -0.0291255, -0.109344, 0.845378},
624 {-0.44, 0.897998, 0, 0, 0, 0},
625 {0.57, 0.43519, 0.696928, 0, 0, 0},
626 {0.01, 0.316705, -0.248988, 0.915207, 0, 0},
627 {-0.06, 0.805793, -0.296262, -0.0419182, 0.507514, 0},
628 {-0.22, -0.497551, 0.289742, 0.0785823, 0.328773, 0.711214},
633 {-0.27, 0.96286, 0, 0, 0, 0},
634 {0.46, 0.741748, 0.488067, 0, 0, 0},
635 {0.04, 0.0735309, -0.374828, 0.923308, 0, 0},
636 {-0.08, 0.517624, 0.128779, 0.0795063, 0.838308, 0},
637 {-0.11, -0.321646, 0.0802763, -0.131981, -0.193429, 0.907285},
678 -7.12, 0.8, -3.06, 0.48, 0.94, 0.7, 0.82, 0.03, -2.52, 0.5, 4.4,
679 3.3, 2.5, 24.4, 3.8, 3.0, 20.0, 3.9, 0.0, 11.0, 7.0, 3.0,
683 -7.28, 0.67, -2.68, 0.36, 0.87, 0.66, 0.5, 0.09, -2.29, 0.53, 9.0,
684 6.6, 2.5, 23.6, 4.7, 3.0, 20.0, 3.9, 0.0, 11.0, 7.0, 3.0,
688 -7.45, 0.68, -2.51, 0.38, 0.92, 0.68, 0.82, 0.05, -2.19, 0.58, 9.3,
689 6.1, 2.5, 23.2, 4.6, 3.0, 20.0, 3.9, 0.0, 11.0, 7.0, 3.0,
693 -7.73, 0.66, -2.4, 0.32, 0.79, 0.64, 1.23, 0.03, -2.24, 0.51, 7.9,
694 4.0, 2.5, 22.6, 4.9, 3.0, 20.0, 3.9, 0.0, 11.0, 7.0, 3.0,
698 -7.91, 0.62, -2.31, 0.33, 0.72, 0.63, 1.43, 0.06, -2.3, 0.46, 7.4,
699 3.0, 2.5, 21.8, 5.7, 3.0, 20.0, 3.9, 0.0, 11.0, 7.0, 3.0,
703 -8.14, 0.51, -2.2, 0.39, 0.6, 0.54, 1.56, 0.05, -2.48, 0.35, 7.0,
704 2.6, 2.5, 20.5, 6.9, 3.0, 20.0, 3.9, 0.0, 11.0, 7.0, 3.0,
708 -8.23, 0.45, -2.0, 0.4, 0.55, 0.52, 1.66, 0.05, -2.64, 0.31, 6.9,
709 2.2, 2.5, 19.3, 8.1, 3.0, 20.0, 3.9, 0.0, 11.0, 7.0, 3.0,
713 -8.28, 0.31, -1.64, 0.32, 0.71, 0.53, 1.73, 0.02, -2.68, 0.39, 6.5,
714 2.1, 2.5, 17.4, 10.3, 3.0, 20.0, 3.9, 0.0, 11.0, 7.0, 3.0,
718 -8.36, 0.08, -0.63, 0.53, 0.81, 0.62, 1.79, 0.01, -2.61, 0.28, 6.8,
719 1.9, 2.5, 12.3, 15.2, 3.0, 20.0, 3.9, 0.0, 11.0, 7.0, 3.0,
726 -7.43, 0.9, -3.43, 0.54, 0.65, 0.82, 0.82, 0.05, -2.75, 0.55, 6.1,
727 2.6, 2.5, 24.7, 2.1, 3.0, 20.0, 1.6, 0.0, 11.0, 7.0, 3.0,
731 -7.62, 0.78, -3.06, 0.41, 0.53, 0.78, 0.47, 0.11, -2.64, 0.64, 13.7,
732 6.8, 2.5, 24.4, 2.8, 3.0, 20.0, 1.6, 0.0, 11.0, 7.0, 3.0,
736 -7.76, 0.8, -2.91, 0.42, 0.6, 0.83, 0.8, 0.05, -2.49, 0.69, 12.9,
737 6.0, 2.5, 24.4, 2.7, 3.0, 20.0, 1.6, 0.0, 11.0, 7.0, 3.0,
741 -8.02, 0.72, -2.81, 0.34, 0.43, 0.78, 1.23, 0.04, -2.51, 0.57, 10.3,
742 3.3, 2.5, 24.2, 2.7, 3.0, 20.0, 1.6, 0.0, 11.0, 7.0, 3.0,
746 -8.13, 0.61, -2.74, 0.34, 0.36, 0.77, 1.42, 0.1, -2.54, 0.5, 9.2,
747 2.2, 2.5, 23.9, 3.1, 3.0, 20.0, 1.6, 0.0, 11.0, 7.0, 3.0,
751 -8.3, 0.47, -2.72, 0.7, 0.16, 0.84, 1.56, 0.06, -2.71, 0.37, 8.4,
752 1.9, 2.5, 23.3, 3.9, 3.0, 20.0, 1.6, 0.0, 11.0, 7.0, 3.0,
756 -8.34, 0.39, -2.46, 0.4, 0.18, 0.64, 1.65, 0.07, -2.85, 0.31, 8.0,
757 1.5, 2.5, 22.6, 4.8, 3.0, 20.0, 1.6, 0.0, 11.0, 7.0, 3.0,
761 -8.39, 0.26, -2.3, 0.78, 0.24, 0.81, 1.73, 0.02, -3.01, 0.45, 7.4,
762 1.6, 2.5, 21.2, 6.8, 3.0, 20.0, 1.6, 0.0, 11.0, 7.0, 3.0,
766 -8.45, 0.01, -1.11, 0.51, 0.36, 0.65, 1.79, 0.01, -3.08, 0.27, 7.6,
767 1.3, 2.5, 17.6, 12.7, 3.0, 20.0, 1.6, 0.0, 11.0, 7.0, 3.0,
780 -6.84, 0.82, -2.08, 0.87, 1.0, 1.6, 1.0, 0.63, -2.08, 0.58,
781 2.3, 23.8, 4.4, 4.0, 20.0, 3.9, 0.0, 15.0, 7.0, 3.0,
785 -6.81, 0.61, -1.68, 0.73, 1.44, 0.87, 0.94, 0.65, -1.66, 0.5,
786 2.3, 21.9, 6.3, 4.0, 20.0, 3.9, 0.0, 15.0, 7.0, 3.0,
790 -6.94, 0.49, -1.46, 0.53, 1.54, 0.64, 1.15, 0.42, -1.48, 0.4,
791 2.3, 19.7, 8.1, 4.0, 20.0, 3.9, 0.0, 15.0, 7.0, 3.0,
795 -7.14, 0.49, -1.43, 0.5, 1.53, 0.56, 1.35, 0.28, -1.46, 0.37,
796 2.3, 18.1, 9.3, 4.0, 20.0, 3.9, 0.0, 15.0, 7.0, 3.0,
800 -7.34, 0.51, -1.44, 0.58, 1.48, 0.54, 1.44, 0.25, -1.53, 0.47,
801 2.3, 16.3, 11.5, 4.0, 20.0, 3.9, 0.0, 15.0, 7.0, 3.0,
805 -7.53, 0.47, -1.33, 0.49, 1.39, 0.68, 1.56, 0.16, -1.61, 0.43,
806 2.3, 14.0, 13.3, 4.0, 20.0, 3.9, 0.0, 15.0, 7.0, 3.0,
810 -7.67, 0.44, -1.31, 0.65, 1.42, 0.55, 1.64, 0.18, -1.77, 0.5,
811 2.3, 12.1, 14.9, 4.0, 20.0, 3.9, 0.0, 15.0, 7.0, 3.0,
815 -7.82, 0.42, -1.11, 0.69, 1.38, 0.6, 1.7, 0.09, -1.9, 0.42,
816 2.3, 8.7, 17.0, 4.0, 20.0, 3.9, 0.0, 15.0, 7.0, 3.0,
820 -7.84, 0.55, -0.11, 0.53, 1.23, 0.6, 1.7, 0.17, -1.99, 0.5,
821 2.3, 6.4, 12.3, 4.0, 20.0, 3.9, 0.0, 15.0, 7.0, 3.0,
828 -6.86, 0.81, -2.12, 0.94, 1.02, 1.44, 1.01, 0.56, -2.11, 0.59,
829 2.3, 23.7, 4.5, 4.0, 20.0, 3.9, 0.0, 15.0, 7.0, 3.0,
833 -6.84, 0.61, -1.74, 0.79, 1.44, 0.77, 0.96, 0.55, -1.69, 0.51,
834 2.3, 21.8, 6.3, 4.0, 20.0, 3.9, 0.0, 15.0, 7.0, 3.0,
838 -7.0, 0.56, -1.56, 0.66, 1.48, 0.7, 1.13, 0.43, -1.52, 0.46,
839 2.3, 19.6, 8.2, 4.0, 20.0, 3.9, 0.0, 15.0, 7.0, 3.0,
843 -7.21, 0.56, -1.54, 0.63, 1.46, 0.6, 1.3, 0.37, -1.51, 0.43,
844 2.3, 18.0, 9.4, 4.0, 20.0, 3.9, 0.0, 15.0, 7.0, 3.0,
848 -7.42, 0.57, -1.45, 0.56, 1.4, 0.59, 1.4, 0.32, -1.54, 0.45,
849 2.3, 16.3, 11.5, 4.0, 20.0, 3.9, 0.0, 15.0, 7.0, 3.0,
853 -7.86, 0.55, -1.64, 0.78, 0.97, 1.27, 1.41, 0.45, -1.84, 0.63,
854 2.3, 15.9, 12.4, 4.0, 20.0, 3.9, 0.0, 15.0, 7.0, 3.0,
858 -7.76, 0.47, -1.37, 0.56, 1.33, 0.56, 1.63, 0.17, -1.86, 0.51,
859 2.3, 12.3, 15.0, 4.0, 20.0, 3.9, 0.0, 15.0, 7.0, 3.0,
863 -8.07, 0.42, -1.29, 0.76, 1.12, 1.04, 1.68, 0.14, -2.16, 0.74,
864 2.3, 10.5, 15.7, 4.0, 20.0, 3.9, 0.0, 15.0, 7.0, 3.0,
868 -7.95, 0.59, -0.41, 0.59, 1.04, 0.63, 1.7, 0.17, -2.21, 0.61,
869 2.3, 10.5, 15.7, 4.0, 20.0, 3.9, 0.0, 15.0, 7.0, 3.0,
877static const std::map<std::string, std::map<int, std::vector<float>>>
m_NTNUrbanLOS{
882 -7.97, 1.0, -2.6, 0.79, 0.18, 0.74, -0.63, 2.6, -2.54, 2.62, 31.83,
883 13.84, 2.5, 8.0, 4.0, 4.0, 20.0, 3.9, 0.09, 12.55, 1.25, 3.0,
887 -8.12, 0.83, -2.48, 0.8, 0.42, 0.9, -0.15, 3.31, -2.67, 2.96, 18.78,
888 13.78, 2.5, 8.0, 4.0, 3.0, 20.0, 3.9, 0.09, 12.76, 3.23, 3.0,
892 -8.21, 0.68, -2.44, 0.91, 0.41, 1.3, 0.54, 1.1, -2.03, 0.86, 10.49,
893 10.42, 2.5, 8.0, 4.0, 3.0, 20.0, 3.9, 0.12, 14.36, 4.39, 3.0,
897 -8.31, 0.48, -2.6, 1.02, 0.18, 1.69, 0.35, 1.59, -2.28, 1.19, 7.46,
898 8.01, 2.5, 8.0, 4.0, 3.0, 20.0, 3.9, 0.16, 16.42, 5.72, 3.0,
902 -8.37, 0.38, -2.71, 1.17, -0.07, 2.04, 0.27, 1.62, -2.48, 1.4, 6.52,
903 8.27, 2.5, 8.0, 4.0, 3.0, 20.0, 3.9, 0.2, 17.13, 6.17, 3.0,
907 -8.39, 0.24, -2.76, 1.17, -0.43, 2.54, 0.26, 0.97, -2.56, 0.85, 5.47,
908 7.26, 2.5, 8.0, 4.0, 3.0, 20.0, 3.9, 0.28, 19.01, 7.36, 3.0,
912 -8.38, 0.18, -2.78, 1.2, -0.64, 2.47, -0.12, 1.99, -2.96, 1.61, 4.54,
913 5.53, 2.5, 8.0, 4.0, 3.0, 20.0, 3.9, 0.44, 19.31, 7.3, 3.0,
917 -8.35, 0.13, -2.65, 1.45, -0.91, 2.69, -0.21, 1.82, -3.08, 1.49, 4.03,
918 4.49, 2.5, 8.0, 4.0, 3.0, 20.0, 3.9, 0.9, 22.39, 7.7, 3.0,
922 -8.34, 0.09, -2.27, 1.85, -0.54, 1.66, -0.07, 1.43, -3.0, 1.09, 3.68,
923 3.14, 2.5, 8.0, 4.0, 3.0, 20.0, 3.9, 2.87, 27.8, 9.25, 3.0,
930 -8.52, 0.92, -3.18, 0.79, -0.4, 0.77, -0.67, 2.22, -2.61, 2.41, 40.18,
931 16.99, 2.5, 8.0, 4.0, 4.0, 20.0, 1.6, 0.09, 11.8, 1.14, 3.0,
935 -8.59, 0.79, -3.05, 0.87, -0.15, 0.97, -0.34, 3.04, -2.82, 2.59, 23.62,
936 18.96, 2.5, 8.0, 4.0, 3.0, 20.0, 1.6, 0.09, 11.6, 2.78, 3.0,
940 -8.51, 0.65, -2.98, 1.04, -0.18, 1.58, 0.07, 1.33, -2.48, 1.02, 12.48,
941 14.23, 2.5, 8.0, 4.0, 3.0, 20.0, 1.6, 0.11, 13.05, 3.87, 3.0,
945 -8.49, 0.48, -3.11, 1.06, -0.31, 1.69, -0.08, 1.45, -2.76, 1.27, 8.56,
946 11.06, 2.5, 8.0, 4.0, 3.0, 20.0, 1.6, 0.15, 14.56, 4.94, 3.0,
950 -8.48, 0.46, -3.19, 1.12, -0.58, 2.13, -0.21, 1.62, -2.93, 1.38, 7.42,
951 11.21, 2.5, 8.0, 4.0, 3.0, 20.0, 1.6, 0.18, 15.35, 5.41, 3.0,
955 -8.44, 0.34, -3.25, 1.14, -0.9, 2.51, -0.25, 1.06, -3.05, 0.96, 5.97,
956 9.47, 2.5, 8.0, 4.0, 3.0, 20.0, 1.6, 0.27, 16.97, 6.31, 3.0,
960 -8.4, 0.27, -3.33, 1.25, -1.16, 2.47, -0.61, 1.88, -3.45, 1.51, 4.88,
961 7.24, 2.5, 8.0, 4.0, 3.0, 20.0, 1.6, 0.42, 17.96, 6.66, 3.0,
965 -8.37, 0.19, -3.22, 1.35, -1.48, 2.61, -0.79, 1.87, -3.66, 1.49, 4.22,
966 5.79, 2.5, 8.0, 4.0, 3.0, 20.0, 1.6, 0.86, 20.68, 7.31, 3.0,
970 -8.35, 0.14, -2.83, 1.62, -1.14, 1.7, -0.58, 1.19, -3.56, 0.89, 3.81,
971 4.25, 2.5, 8.0, 4.0, 3.0, 20.0, 1.6, 2.55, 25.08, 9.23, 3.0,
979static const std::map<std::string, std::map<int, std::vector<float>>>
m_NTNUrbanNLOS{
984 -7.24, 1.26, -1.58, 0.89, 0.13, 2.99, -1.13, 2.66, -2.87, 2.76, 0.0,
985 0.0, 2.3, 7.0, 3.0, 3.0, 20.0, 1.6, 0.08, 14.72, 1.57, 3.0,
989 -7.7, 0.99, -1.67, 0.89, 0.19, 3.12, 0.49, 2.03, -2.68, 2.76, 0.0,
990 0.0, 2.3, 7.0, 3.0, 3.0, 20.0, 1.6, 0.1, 14.62, 4.3, 3.0,
994 -7.82, 0.86, -1.84, 1.3, 0.44, 2.69, 0.95, 1.54, -2.12, 1.54, 0.0,
995 0.0, 2.3, 7.0, 3.0, 3.0, 20.0, 1.6, 0.14, 16.4, 6.64, 3.0,
999 -8.04, 0.75, -2.02, 1.15, 0.48, 2.45, 1.15, 1.02, -2.27, 1.77, 0.0,
1000 0.0, 2.3, 7.0, 3.0, 3.0, 20.0, 1.6, 0.22, 17.86, 9.21, 3.0,
1004 -8.08, 0.77, -2.06, 1.23, 0.56, 2.17, 1.14, 1.61, -2.5, 2.36, 0.0,
1005 0.0, 2.3, 7.0, 3.0, 3.0, 20.0, 1.6, 0.31, 19.74, 10.32, 3.0,
1009 -8.1, 0.76, -1.99, 1.02, 0.55, 1.93, 1.13, 1.84, -2.47, 2.33, 0.0,
1010 0.0, 2.3, 7.0, 3.0, 3.0, 20.0, 1.6, 0.49, 19.73, 10.3, 3.0,
1014 -8.16, 0.73, -2.19, 1.78, 0.48, 1.72, 1.16, 1.81, -2.83, 2.84, 0.0,
1015 0.0, 2.3, 7.0, 3.0, 2.0, 20.0, 1.6, 0.97, 20.5, 10.2, 3.0,
1019 -8.03, 0.79, -1.88, 1.55, 0.53, 1.51, 1.28, 1.35, -2.82, 2.87, 0.0,
1020 0.0, 2.3, 7.0, 3.0, 2.0, 20.0, 1.6, 1.52, 26.16, 12.27, 3.0,
1024 -8.33, 0.7, -2.0, 1.4, 0.32, 1.2, 1.42, 0.6, -4.55, 4.27, 0.0,
1025 0.0, 2.3, 7.0, 3.0, 2.0, 20.0, 1.6, 5.36, 25.83, 12.75, 3.0,
1032 -7.24, 1.26, -1.58, 0.89, 0.13, 2.99, -1.13, 2.66, -2.87, 2.76, 0.0,
1033 0.0, 2.3, 7.0, 3.0, 3.0, 20.0, 1.6, 0.08, 14.72, 1.57, 3.0,
1037 -7.7, 0.99, -1.67, 0.89, 0.19, 3.12, 0.49, 2.03, -2.68, 2.76, 0.0,
1038 0.0, 2.3, 7.0, 3.0, 3.0, 20.0, 1.6, 0.1, 14.62, 4.3, 3.0,
1042 -7.82, 0.86, -1.84, 1.3, 0.44, 2.69, 0.95, 1.54, -2.12, 1.54, 0.0,
1043 0.0, 2.3, 7.0, 3.0, 3.0, 20.0, 1.6, 0.14, 16.4, 6.64, 3.0,
1047 -8.04, 0.75, -2.02, 1.15, 0.48, 2.45, 1.15, 1.02, -2.27, 1.77, 0.0,
1048 0.0, 2.3, 7.0, 3.0, 3.0, 20.0, 1.6, 0.22, 17.86, 9.21, 3.0,
1052 -8.08, 0.77, -2.06, 1.23, 0.56, 2.17, 1.14, 1.61, -2.5, 2.36, 0.0,
1053 0.0, 2.3, 7.0, 3.0, 3.0, 20.0, 1.6, 0.31, 19.74, 10.32, 3.0,
1057 -8.1, 0.76, -1.99, 1.02, 0.55, 1.93, 1.13, 1.84, -2.47, 2.33, 0.0,
1058 0.0, 2.3, 7.0, 3.0, 3.0, 20.0, 1.6, 0.49, 19.73, 10.3, 3.0,
1062 -8.16, 0.73, -2.19, 1.78, 0.48, 1.72, 1.16, 1.81, -2.83, 2.84, 0.0,
1063 0.0, 2.3, 7.0, 3.0, 2.0, 20.0, 1.6, 0.97, 20.5, 10.2, 3.0,
1067 -8.03, 0.79, -1.88, 1.55, 0.53, 1.51, 1.28, 1.35, -2.82, 2.87, 0.0,
1068 0.0, 2.3, 7.0, 3.0, 2.0, 20.0, 1.6, 1.52, 26.16, 12.27, 3.0,
1072 -8.33, 0.7, -2.0, 1.4, 0.32, 1.2, 1.42, 0.6, -4.55, 4.27, 0.0,
1073 0.0, 2.3, 7.0, 3.0, 2.0, 20.0, 1.6, 5.36, 25.83, 12.75, 3.0,
1086 -8.16, 0.99, -3.57, 1.62, 0.05, 1.84, -1.78, 0.62, -1.06, 0.96, 11.4,
1087 6.26, 2.2, 21.3, 7.6, 3.0, 20.0, 1.6, 0.0, 11.0, 7.0, 3.0,
1091 -8.56, 0.96, -3.8, 1.74, -0.38, 1.94, -1.84, 0.81, -1.21, 0.95, 19.45,
1092 10.32, 3.36, 21.0, 8.9, 3.0, 20.0, 1.6, 0.0, 11.0, 7.0, 3.0,
1096 -8.72, 0.79, -3.77, 1.72, -0.56, 1.75, -1.67, 0.57, -1.28, 0.49, 20.8,
1097 16.34, 3.5, 21.2, 8.5, 3.0, 20.0, 1.6, 0.0, 11.0, 7.0, 3.0,
1101 -8.71, 0.81, -3.57, 1.6, -0.59, 1.82, -1.59, 0.86, -1.32, 0.79, 21.2,
1102 15.63, 2.81, 21.1, 8.4, 3.0, 20.0, 1.6, 0.0, 11.0, 7.0, 3.0,
1106 -8.72, 1.12, -3.42, 1.49, -0.58, 1.87, -1.55, 1.05, -1.39, 0.97, 21.6,
1107 14.22, 2.39, 20.7, 9.2, 3.0, 20.0, 1.6, 0.0, 11.0, 7.0, 3.0,
1111 -8.66, 1.23, -3.27, 1.43, -0.55, 1.92, -1.51, 1.23, -1.36, 1.17, 19.75,
1112 14.19, 2.73, 20.6, 9.8, 3.0, 20.0, 1.6, 0.0, 11.0, 7.0, 3.0,
1116 -8.38, 0.55, -3.08, 1.36, -0.28, 1.16, -1.27, 0.54, -1.08, 0.62, 12.0,
1117 5.7, 2.07, 20.3, 10.8, 2.0, 20.0, 1.6, 0.0, 11.0, 7.0, 3.0,
1121 -8.34, 0.63, -2.75, 1.26, -0.17, 1.09, -1.28, 0.67, -1.31, 0.76, 12.85,
1122 9.91, 2.04, 19.8, 12.2, 2.0, 20.0, 1.6, 0.0, 11.0, 7.0, 3.0,
1126 -8.34, 0.63, -2.75, 1.26, -0.17, 1.09, -1.28, 0.67, -1.31, 0.76, 12.85,
1127 9.91, 2.04, 19.1, 13.0, 2.0, 20.0, 1.6, 0.0, 11.0, 7.0, 3.0,
1134 -8.07, 0.46, -3.55, 0.48, 0.89, 0.67, 0.63, 0.35, -3.37, 0.28, 8.9,
1135 4.4, 2.5, 23.2, 5.0, 3.0, 20.0, 1.6, 0.0, 11.0, 7.0, 3.0,
1139 -8.61, 0.45, -3.69, 0.41, 0.31, 0.78, 0.76, 0.3, -3.28, 0.27, 14.0,
1140 4.6, 2.5, 23.6, 4.5, 3.0, 20.0, 1.6, 0.0, 11.0, 7.0, 3.0,
1144 -8.72, 0.28, -3.59, 0.41, 0.02, 0.75, 1.11, 0.28, -3.04, 0.26, 11.3,
1145 3.7, 2.5, 23.5, 4.7, 3.0, 20.0, 1.6, 0.0, 11.0, 7.0, 3.0,
1149 -8.63, 0.17, -3.38, 0.35, -0.1, 0.65, 1.37, 0.23, -2.88, 0.21, 9.0,
1150 3.5, 2.5, 23.4, 5.2, 3.0, 20.0, 1.6, 0.0, 11.0, 7.0, 3.0,
1154 -8.54, 0.14, -3.23, 0.35, -0.19, 0.55, 1.53, 0.23, -2.83, 0.18, 7.5,
1155 3.0, 2.5, 23.2, 5.7, 3.0, 20.0, 1.6, 0.0, 11.0, 7.0, 3.0,
1159 -8.48, 0.15, -3.19, 0.43, -0.54, 0.96, 1.65, 0.17, -2.86, 0.17, 6.6,
1160 2.6, 2.5, 23.3, 5.9, 3.0, 20.0, 1.6, 0.0, 11.0, 7.0, 3.0,
1164 -8.42, 0.09, -2.83, 0.33, -0.24, 0.43, 1.74, 0.11, -2.95, 0.1, 5.9,
1165 1.7, 2.5, 23.4, 6.2, 2.0, 20.0, 1.6, 0.0, 11.0, 7.0, 3.0,
1169 -8.39, 0.05, -2.66, 0.44, -0.52, 0.93, 1.82, 0.05, -3.21, 0.07, 5.5,
1170 0.7, 2.5, 23.2, 7.0, 2.0, 20.0, 1.6, 0.0, 11.0, 7.0, 3.0,
1174 -8.37, 0.02, -1.22, 0.31, -0.15, 0.44, 1.87, 0.02, -3.49, 0.24, 5.4,
1175 0.3, 2.5, 23.1, 7.6, 2.0, 20.0, 1.6, 0.0, 11.0, 7.0, 3.0,
1188 -7.43, 0.5, -2.89, 0.41, 1.49, 0.4, 0.81, 0.36, -3.09, 0.32, 0.0,
1189 0.0, 2.3, 22.5, 5.0, 4.0, 20.0, 1.6, 0.0, 15.0, 7.0, 3.0,
1193 -7.63, 0.61, -2.76, 0.41, 1.24, 0.82, 1.06, 0.41, -2.93, 0.47, 0.0,
1194 0.0, 2.3, 19.4, 8.5, 4.0, 20.0, 1.6, 0.0, 15.0, 7.0, 3.0,
1198 -7.86, 0.56, -2.64, 0.41, 1.06, 0.71, 1.12, 0.4, -2.91, 0.46, 0.0,
1199 0.0, 2.3, 15.5, 10.0, 4.0, 20.0, 1.6, 0.0, 15.0, 7.0, 3.0,
1203 -7.96, 0.58, -2.41, 0.52, 0.91, 0.55, 1.14, 0.39, -2.78, 0.54, 0.0,
1204 0.0, 2.3, 13.9, 10.6, 4.0, 20.0, 1.6, 0.0, 15.0, 7.0, 3.0,
1208 -7.98, 0.59, -2.42, 0.7, 0.98, 0.58, 1.29, 0.35, -2.7, 0.45, 0.0,
1209 0.0, 2.3, 11.7, 10.0, 4.0, 20.0, 1.6, 0.0, 15.0, 7.0, 3.0,
1213 -8.45, 0.47, -2.53, 0.5, 0.49, 1.37, 1.38, 0.36, -3.03, 0.36, 0.0,
1214 0.0, 2.3, 9.8, 9.1, 3.0, 20.0, 1.6, 0.0, 15.0, 7.0, 3.0,
1218 -8.21, 0.36, -2.35, 0.58, 0.73, 0.49, 1.36, 0.29, -2.9, 0.42, 0.0,
1219 0.0, 2.3, 10.3, 9.1, 3.0, 20.0, 1.6, 0.0, 15.0, 7.0, 3.0,
1223 -8.69, 0.29, -2.31, 0.73, -0.04, 1.48, 1.38, 0.2, -3.2, 0.3, 0.0,
1224 0.0, 2.3, 15.6, 9.1, 3.0, 20.0, 1.6, 0.0, 15.0, 7.0, 3.0,
1228 -8.69, 0.29, -2.31, 0.73, -0.04, 1.48, 1.38, 0.2, -3.2, 0.3, 0.0,
1229 0.0, 2.3, 15.6, 9.1, 3.0, 20.0, 1.6, 0.0, 15.0, 7.0, 3.0,
1236 -7.43, 0.5, -2.89, 0.41, 1.49, 0.4, 0.81, 0.36, -3.09, 0.32, 0.0,
1237 0.0, 2.3, 22.5, 5.0, 4.0, 20.0, 1.6, 0.0, 15.0, 7.0, 3.0,
1241 -7.63, 0.61, -2.76, 0.41, 1.24, 0.82, 1.06, 0.41, -2.93, 0.47, 0.0,
1242 0.0, 2.3, 19.4, 8.5, 4.0, 20.0, 1.6, 0.0, 15.0, 7.0, 3.0,
1246 -7.86, 0.56, -2.64, 0.41, 1.06, 0.71, 1.12, 0.4, -2.91, 0.46, 0.0,
1247 0.0, 2.3, 15.5, 10.0, 4.0, 20.0, 1.6, 0.0, 15.0, 7.0, 3.0,
1251 -7.96, 0.58, -2.41, 0.52, 0.91, 0.55, 1.14, 0.39, -2.78, 0.54, 0.0,
1252 0.0, 2.3, 13.9, 10.6, 4.0, 20.0, 1.6, 0.0, 15.0, 7.0, 3.0,
1256 -7.98, 0.59, -2.42, 0.7, 0.98, 0.58, 1.29, 0.35, -2.7, 0.45, 0.0,
1257 0.0, 2.3, 11.7, 10.0, 4.0, 20.0, 1.6, 0.0, 15.0, 7.0, 3.0,
1261 -8.45, 0.47, -2.53, 0.5, 0.49, 1.37, 1.38, 0.36, -3.03, 0.36, 0.0,
1262 0.0, 2.3, 9.8, 9.1, 3.0, 20.0, 1.6, 0.0, 15.0, 7.0, 3.0,
1266 -8.21, 0.36, -2.35, 0.58, 0.73, 0.49, 1.36, 0.29, -2.9, 0.42, 0.0,
1267 0.0, 2.3, 10.3, 9.1, 3.0, 20.0, 1.6, 0.0, 15.0, 7.0, 3.0,
1271 -8.69, 0.29, -2.31, 0.73, -0.04, 1.48, 1.38, 0.2, -3.2, 0.3, 0.0,
1272 0.0, 2.3, 15.6, 9.1, 3.0, 20.0, 1.6, 0.0, 15.0, 7.0, 3.0,
1276 -8.69, 0.29, -2.31, 0.73, -0.04, 1.48, 1.38, 0.2, -3.2, 0.3, 0.0,
1277 0.0, 2.3, 15.6, 9.1, 3.0, 20.0, 1.6, 0.0, 15.0, 7.0, 3.0,
1285static const std::map<std::string, std::map<int, std::vector<float>>>
m_NTNRuralLOS{
1290 -9.55, 0.66, -3.42, 0.89, -9.45, 7.83, -4.2, 6.3, -6.03, 5.19, 24.72,
1291 5.07, 3.8, 12.0, 4.0, 2.0, 20.0, 0.0, 0.39, 10.81, 1.94, 3.0,
1295 -8.68, 0.44, -3.0, 0.63, -4.45, 6.86, -2.31, 5.04, -4.31, 4.18, 12.31,
1296 5.75, 3.8, 12.0, 4.0, 2.0, 20.0, 0.0, 0.31, 8.09, 1.83, 3.0,
1300 -8.46, 0.28, -2.86, 0.52, -2.39, 5.14, -0.28, 0.81, -2.57, 0.61, 8.05,
1301 5.46, 3.8, 12.0, 4.0, 2.0, 20.0, 0.0, 0.29, 13.7, 2.28, 3.0,
1305 -8.36, 0.19, -2.78, 0.45, -1.28, 3.44, -0.38, 1.16, -2.59, 0.79, 6.21,
1306 5.23, 3.8, 12.0, 4.0, 2.0, 20.0, 0.0, 0.37, 20.05, 2.93, 3.0,
1310 -8.29, 0.14, -2.7, 0.42, -0.99, 2.59, -0.38, 0.82, -2.59, 0.65, 5.04,
1311 3.95, 3.8, 12.0, 4.0, 2.0, 20.0, 0.0, 0.61, 24.51, 2.84, 3.0,
1315 -8.26, 0.1, -2.66, 0.41, -1.05, 2.42, -0.46, 0.67, -2.65, 0.52, 4.42,
1316 3.75, 3.8, 12.0, 4.0, 2.0, 20.0, 0.0, 0.9, 26.35, 3.17, 3.0,
1320 -8.22, 0.1, -2.53, 0.42, -0.9, 1.78, -0.49, 1.0, -2.69, 0.78, 3.92,
1321 2.56, 3.8, 12.0, 4.0, 2.0, 20.0, 0.0, 1.43, 31.84, 3.88, 3.0,
1325 -8.2, 0.05, -2.21, 0.5, -0.89, 1.65, -0.53, 1.18, -2.65, 1.01, 3.65,
1326 1.77, 3.8, 12.0, 4.0, 2.0, 20.0, 0.0, 2.87, 36.62, 4.17, 3.0,
1330 -8.19, 0.06, -1.78, 0.91, -0.81, 1.26, -0.46, 0.91, -2.65, 0.71, 3.59,
1331 1.77, 3.8, 12.0, 4.0, 2.0, 20.0, 0.0, 5.48, 36.77, 4.29, 3.0,
1338 -9.68, 0.46, -4.03, 0.91, -9.74, 7.52, -5.85, 6.51, -7.45, 5.3, 25.43,
1339 7.04, 3.8, 12.0, 4.0, 2.0, 20.0, 0.0, 0.36, 4.63, 0.75, 3.0,
1343 -8.86, 0.29, -3.55, 0.7, -4.88, 6.67, -3.27, 5.36, -5.25, 4.42, 12.72,
1344 7.47, 3.8, 12.0, 4.0, 2.0, 20.0, 0.0, 0.3, 6.83, 1.25, 3.0,
1348 -8.59, 0.18, -3.45, 0.55, -2.6, 4.63, -0.88, 0.93, -3.16, 0.68, 8.4,
1349 7.18, 3.8, 12.0, 4.0, 2.0, 20.0, 0.0, 0.25, 12.91, 1.93, 3.0,
1353 -8.46, 0.19, -3.38, 0.52, -1.92, 3.45, -0.93, 0.96, -3.15, 0.73, 6.52,
1354 6.88, 3.8, 12.0, 4.0, 2.0, 20.0, 0.0, 0.35, 18.9, 2.37, 3.0,
1358 -8.36, 0.14, -3.33, 0.46, -1.56, 2.44, -0.99, 0.97, -3.2, 0.77, 5.24,
1359 5.28, 3.8, 12.0, 4.0, 2.0, 20.0, 0.0, 0.53, 22.44, 2.66, 3.0,
1363 -8.3, 0.15, -3.29, 0.43, -1.66, 2.38, -1.04, 0.83, -3.27, 0.61, 4.57,
1364 4.92, 3.8, 12.0, 4.0, 2.0, 20.0, 0.0, 0.88, 25.69, 3.23, 3.0,
1368 -8.26, 0.13, -3.24, 0.46, -1.59, 1.67, -1.17, 1.01, -3.42, 0.74, 4.02,
1369 3.4, 3.8, 12.0, 4.0, 2.0, 20.0, 0.0, 1.39, 27.95, 3.71, 3.0,
1373 -8.22, 0.03, -2.9, 0.44, -1.58, 1.44, -1.19, 1.01, -3.36, 0.79, 3.7,
1374 2.22, 3.8, 12.0, 4.0, 2.0, 20.0, 0.0, 2.7, 31.45, 4.17, 3.0,
1378 -8.21, 0.07, -2.5, 0.82, -1.51, 1.13, -1.13, 0.85, -3.35, 0.65, 3.62,
1379 2.28, 3.8, 12.0, 4.0, 2.0, 20.0, 0.0, 4.97, 28.01, 4.14, 3.0,
1392 -9.01, 1.59, -2.9, 1.34, -3.33, 6.22, -0.88, 3.26, -4.92, 3.96, 0.0,
1393 0.0, 1.7, 7.0, 3.0, 3.0, 20.0, 0.0, 0.03, 18.16, 2.32, 3.0,
1397 -8.37, 0.95, -2.5, 1.18, -0.74, 4.22, -0.07, 3.29, -4.06, 4.07, 0.0,
1398 0.0, 1.7, 7.0, 3.0, 3.0, 20.0, 0.0, 0.05, 26.82, 7.34, 3.0,
1402 -8.05, 0.92, -2.12, 1.08, 0.08, 3.02, 0.75, 1.92, -2.33, 1.7, 0.0,
1403 0.0, 1.7, 7.0, 3.0, 2.0, 20.0, 0.0, 0.07, 21.99, 8.28, 3.0,
1407 -7.92, 0.92, -1.99, 1.06, 0.32, 2.45, 0.72, 1.92, -2.24, 2.01, 0.0,
1408 0.0, 1.7, 7.0, 3.0, 2.0, 20.0, 0.0, 0.1, 22.86, 8.76, 3.0,
1412 -7.92, 0.87, -1.9, 1.05, 0.53, 1.63, 0.95, 1.45, -2.24, 2.0, 0.0,
1413 0.0, 1.7, 7.0, 3.0, 2.0, 20.0, 0.0, 0.15, 25.93, 9.68, 3.0,
1417 -7.96, 0.87, -1.85, 1.06, 0.33, 2.08, 0.97, 1.62, -2.22, 1.82, 0.0,
1418 0.0, 1.7, 7.0, 3.0, 2.0, 20.0, 0.0, 0.22, 27.79, 9.94, 3.0,
1422 -7.91, 0.82, -1.69, 1.14, 0.55, 1.58, 1.1, 1.43, -2.19, 1.66, 0.0,
1423 0.0, 1.7, 7.0, 3.0, 2.0, 20.0, 0.0, 0.5, 28.5, 8.9, 3.0,
1427 -7.79, 0.86, -1.46, 1.16, 0.45, 2.01, 0.97, 1.88, -2.41, 2.58, 0.0,
1428 0.0, 1.7, 7.0, 3.0, 2.0, 20.0, 0.0, 1.04, 37.53, 13.74, 3.0,
1432 -7.74, 0.81, -1.32, 1.3, 0.4, 2.19, 1.35, 0.62, -2.45, 2.52, 0.0,
1433 0.0, 1.7, 7.0, 3.0, 2.0, 20.0, 0.0, 2.11, 29.23, 12.16, 3.0,
1440 -9.13, 1.91, -2.9, 1.32, -3.4, 6.28, -1.19, 3.81, -5.47, 4.39, 0.0,
1441 0.0, 1.7, 7.0, 3.0, 3.0, 20.0, 0.0, 0.03, 18.21, 2.13, 3.0,
1445 -8.39, 0.94, -2.53, 1.18, -0.51, 3.75, -0.11, 3.33, -4.06, 4.04, 0.0,
1446 0.0, 1.7, 7.0, 3.0, 3.0, 20.0, 0.0, 0.05, 24.08, 6.52, 3.0,
1450 -8.1, 0.92, -2.16, 1.08, 0.06, 2.95, 0.72, 1.93, -2.32, 1.54, 0.0,
1451 0.0, 1.7, 7.0, 3.0, 2.0, 20.0, 0.0, 0.07, 22.06, 7.72, 3.0,
1455 -7.96, 0.94, -2.04, 1.09, 0.2, 2.65, 0.69, 1.91, -2.19, 1.73, 0.0,
1456 0.0, 1.7, 7.0, 3.0, 2.0, 20.0, 0.0, 0.09, 21.4, 8.45, 3.0,
1460 -7.99, 0.89, -1.99, 1.08, 0.4, 1.85, 0.84, 1.7, -2.16, 1.5, 0.0,
1461 0.0, 1.7, 7.0, 3.0, 2.0, 20.0, 0.0, 0.16, 24.26, 8.92, 3.0,
1465 -8.05, 0.87, -1.95, 1.06, 0.32, 1.83, 0.99, 1.27, -2.24, 1.64, 0.0,
1466 0.0, 1.7, 7.0, 3.0, 2.0, 20.0, 0.0, 0.22, 24.15, 8.76, 3.0,
1470 -8.01, 0.82, -1.81, 1.17, 0.46, 1.57, 0.95, 1.86, -2.29, 1.66, 0.0,
1471 0.0, 1.7, 7.0, 3.0, 2.0, 20.0, 0.0, 0.51, 25.99, 9.0, 3.0,
1475 -8.05, 1.65, -1.56, 1.2, 0.33, 1.99, 0.92, 1.84, -2.65, 2.86, 0.0,
1476 0.0, 1.7, 7.0, 3.0, 2.0, 20.0, 0.0, 0.89, 36.07, 13.6, 3.0,
1480 -7.91, 0.76, -1.53, 1.27, 0.24, 2.18, 1.29, 0.59, -2.23, 1.12, 0.0,
1481 0.0, 1.7, 7.0, 3.0, 2.0, 20.0, 0.0, 1.68, 24.51, 10.56, 3.0,
1489 m_uniformRv = CreateObject<UniformRandomVariable>();
1493 m_normalRv = CreateObject<NormalRandomVariable>();
1520 TypeId(
"ns3::ThreeGppChannelModel")
1523 .AddConstructor<ThreeGppChannelModel>()
1524 .AddAttribute(
"Frequency",
1525 "The operating Frequency in Hz",
1529 MakeDoubleChecker<double>())
1532 "The 3GPP scenario (RMa, UMa, UMi-StreetCanyon, InH-OfficeOpen, InH-OfficeMixed, "
1533 "NTN-DenseUrban, NTN-Urban, NTN-Suburban, NTN-Rural)",
1538 .AddAttribute(
"ChannelConditionModel",
1539 "Pointer to the channel condition model",
1543 MakePointerChecker<ChannelConditionModel>())
1544 .AddAttribute(
"UpdatePeriod",
1545 "Specify the channel coherence time",
1550 .AddAttribute(
"Blockage",
1551 "Enable blockage model A (sec 7.6.4.1)",
1555 .AddAttribute(
"NumNonselfBlocking",
1556 "number of non-self-blocking regions",
1559 MakeIntegerChecker<uint16_t>())
1560 .AddAttribute(
"PortraitMode",
1561 "true for portrait mode, false for landscape mode",
1565 .AddAttribute(
"BlockerSpeed",
1566 "The speed of moving blockers, the unit is m/s",
1569 MakeDoubleChecker<double>())
1570 .AddAttribute(
"vScatt",
1571 "Maximum speed of the vehicle in the layout (see 3GPP TR 37.885 v15.3.0, "
1573 "Used to compute the additional contribution for the Doppler of"
1574 "delayed (reflected) paths",
1577 MakeDoubleChecker<double>(0.0))
1602 "Frequency should be between 0.5 and 100 GHz but is " << f);
1617 NS_ASSERT_MSG(scenario ==
"RMa" || scenario ==
"UMa" || scenario ==
"UMi-StreetCanyon" ||
1618 scenario ==
"InH-OfficeOpen" || scenario ==
"InH-OfficeMixed" ||
1619 scenario ==
"V2V-Urban" || scenario ==
"V2V-Highway" ||
1620 scenario ==
"NTN-DenseUrban" || scenario ==
"NTN-Urban" ||
1621 scenario ==
"NTN-Suburban" || scenario ==
"NTN-Rural",
1622 "Unknown scenario, choose between: RMa, UMa, UMi-StreetCanyon, "
1623 "InH-OfficeOpen, InH-OfficeMixed, V2V-Urban, V2V-Highway, "
1624 "NTN-DenseUrban, NTN-Urban, NTN-Suburban or NTN-Rural");
1644 double hUT = std::min(aMob->GetPosition().z, bMob->GetPosition().z);
1645 double hBS = std::max(aMob->GetPosition().z, bMob->GetPosition().z);
1647 double distance2D = sqrt(pow(aMob->GetPosition().x - bMob->GetPosition().x, 2) +
1648 pow(aMob->GetPosition().y - bMob->GetPosition().y, 2));
1657 bool los = channelCondition->IsLos();
1658 bool o2i = channelCondition->IsO2i();
1667 table3gpp->m_numOfCluster = 11;
1668 table3gpp->m_raysPerCluster = 20;
1669 table3gpp->m_uLgDS = -7.49;
1670 table3gpp->m_sigLgDS = 0.55;
1671 table3gpp->m_uLgASD = 0.90;
1672 table3gpp->m_sigLgASD = 0.38;
1673 table3gpp->m_uLgASA = 1.52;
1674 table3gpp->m_sigLgASA = 0.24;
1675 table3gpp->m_uLgZSA = 0.47;
1676 table3gpp->m_sigLgZSA = 0.40;
1677 table3gpp->m_uLgZSD = 0.34;
1678 table3gpp->m_sigLgZSD =
1679 std::max(-1.0, -0.17 * (distance2D / 1000.0) - 0.01 * (hUT - 1.5) + 0.22);
1680 table3gpp->m_offsetZOD = 0;
1681 table3gpp->m_cDS = 3.91e-9;
1682 table3gpp->m_cASD = 2;
1683 table3gpp->m_cASA = 3;
1684 table3gpp->m_cZSA = 3;
1685 table3gpp->m_uK = 7;
1686 table3gpp->m_sigK = 4;
1687 table3gpp->m_rTau = 3.8;
1688 table3gpp->m_uXpr = 12;
1689 table3gpp->m_sigXpr = 4;
1690 table3gpp->m_perClusterShadowingStd = 3;
1692 for (uint8_t row = 0; row < 7; row++)
1694 for (uint8_t column = 0; column < 7; column++)
1696 table3gpp->m_sqrtC[row][column] =
sqrtC_RMa_LOS[row][column];
1700 else if (!los && !o2i)
1702 table3gpp->m_numOfCluster = 10;
1703 table3gpp->m_raysPerCluster = 20;
1704 table3gpp->m_uLgDS = -7.43;
1705 table3gpp->m_sigLgDS = 0.48;
1706 table3gpp->m_uLgASD = 0.95;
1707 table3gpp->m_sigLgASD = 0.45;
1708 table3gpp->m_uLgASA = 1.52;
1709 table3gpp->m_sigLgASA = 0.13;
1710 table3gpp->m_uLgZSA = 0.58;
1711 table3gpp->m_sigLgZSA = 0.37;
1712 table3gpp->m_uLgZSD =
1713 std::max(-1.0, -0.19 * (distance2D / 1000.0) - 0.01 * (hUT - 1.5) + 0.28);
1714 table3gpp->m_sigLgZSD = 0.30;
1715 table3gpp->m_offsetZOD = atan((35 - 3.5) / distance2D) - atan((35 - 1.5) / distance2D);
1716 table3gpp->m_cDS = 3.91e-9;
1717 table3gpp->m_cASD = 2;
1718 table3gpp->m_cASA = 3;
1719 table3gpp->m_cZSA = 3;
1720 table3gpp->m_uK = 0;
1721 table3gpp->m_sigK = 0;
1722 table3gpp->m_rTau = 1.7;
1723 table3gpp->m_uXpr = 7;
1724 table3gpp->m_sigXpr = 3;
1725 table3gpp->m_perClusterShadowingStd = 3;
1727 for (uint8_t row = 0; row < 6; row++)
1729 for (uint8_t column = 0; column < 6; column++)
1737 table3gpp->m_numOfCluster = 10;
1738 table3gpp->m_raysPerCluster = 20;
1739 table3gpp->m_uLgDS = -7.47;
1740 table3gpp->m_sigLgDS = 0.24;
1741 table3gpp->m_uLgASD = 0.67;
1742 table3gpp->m_sigLgASD = 0.18;
1743 table3gpp->m_uLgASA = 1.66;
1744 table3gpp->m_sigLgASA = 0.21;
1745 table3gpp->m_uLgZSA = 0.93;
1746 table3gpp->m_sigLgZSA = 0.22;
1747 table3gpp->m_uLgZSD =
1748 std::max(-1.0, -0.19 * (distance2D / 1000.0) - 0.01 * (hUT - 1.5) + 0.28);
1749 table3gpp->m_sigLgZSD = 0.30;
1750 table3gpp->m_offsetZOD = atan((35 - 3.5) / distance2D) - atan((35 - 1.5) / distance2D);
1751 table3gpp->m_cDS = 3.91e-9;
1752 table3gpp->m_cASD = 2;
1753 table3gpp->m_cASA = 3;
1754 table3gpp->m_cZSA = 3;
1755 table3gpp->m_uK = 0;
1756 table3gpp->m_sigK = 0;
1757 table3gpp->m_rTau = 1.7;
1758 table3gpp->m_uXpr = 7;
1759 table3gpp->m_sigXpr = 3;
1760 table3gpp->m_perClusterShadowingStd = 3;
1762 for (uint8_t row = 0; row < 6; row++)
1764 for (uint8_t column = 0; column < 6; column++)
1766 table3gpp->m_sqrtC[row][column] =
sqrtC_RMa_O2I[row][column];
1775 table3gpp->m_numOfCluster = 12;
1776 table3gpp->m_raysPerCluster = 20;
1777 table3gpp->m_uLgDS = -6.955 - 0.0963 * log10(fcGHz);
1778 table3gpp->m_sigLgDS = 0.66;
1779 table3gpp->m_uLgASD = 1.06 + 0.1114 * log10(fcGHz);
1780 table3gpp->m_sigLgASD = 0.28;
1781 table3gpp->m_uLgASA = 1.81;
1782 table3gpp->m_sigLgASA = 0.20;
1783 table3gpp->m_uLgZSA = 0.95;
1784 table3gpp->m_sigLgZSA = 0.16;
1785 table3gpp->m_uLgZSD =
1786 std::max(-0.5, -2.1 * distance2D / 1000.0 - 0.01 * (hUT - 1.5) + 0.75);
1787 table3gpp->m_sigLgZSD = 0.40;
1788 table3gpp->m_offsetZOD = 0;
1789 table3gpp->m_cDS = std::max(0.25, -3.4084 * log10(fcGHz) + 6.5622) * 1e-9;
1790 table3gpp->m_cASD = 5;
1791 table3gpp->m_cASA = 11;
1792 table3gpp->m_cZSA = 7;
1793 table3gpp->m_uK = 9;
1794 table3gpp->m_sigK = 3.5;
1795 table3gpp->m_rTau = 2.5;
1796 table3gpp->m_uXpr = 8;
1797 table3gpp->m_sigXpr = 4;
1798 table3gpp->m_perClusterShadowingStd = 3;
1800 for (uint8_t row = 0; row < 7; row++)
1802 for (uint8_t column = 0; column < 7; column++)
1804 table3gpp->m_sqrtC[row][column] =
sqrtC_UMa_LOS[row][column];
1810 double uLgZSD = std::max(-0.5, -2.1 * distance2D / 1000.0 - 0.01 * (hUT - 1.5) + 0.9);
1812 double afc = 0.208 * log10(fcGHz) - 0.782;
1814 double cfc = -0.13 * log10(fcGHz) + 2.03;
1815 double efc = 7.66 * log10(fcGHz) - 5.96;
1817 double offsetZOD = efc - std::pow(10, afc * log10(std::max(bfc, distance2D)) + cfc);
1821 table3gpp->m_numOfCluster = 20;
1822 table3gpp->m_raysPerCluster = 20;
1823 table3gpp->m_uLgDS = -6.28 - 0.204 * log10(fcGHz);
1824 table3gpp->m_sigLgDS = 0.39;
1825 table3gpp->m_uLgASD = 1.5 - 0.1144 * log10(fcGHz);
1826 table3gpp->m_sigLgASD = 0.28;
1827 table3gpp->m_uLgASA = 2.08 - 0.27 * log10(fcGHz);
1828 table3gpp->m_sigLgASA = 0.11;
1829 table3gpp->m_uLgZSA = -0.3236 * log10(fcGHz) + 1.512;
1830 table3gpp->m_sigLgZSA = 0.16;
1831 table3gpp->m_uLgZSD =
uLgZSD;
1832 table3gpp->m_sigLgZSD = 0.49;
1833 table3gpp->m_offsetZOD = offsetZOD;
1834 table3gpp->m_cDS = std::max(0.25, -3.4084 * log10(fcGHz) + 6.5622) * 1e-9;
1835 table3gpp->m_cASD = 2;
1836 table3gpp->m_cASA = 15;
1837 table3gpp->m_cZSA = 7;
1838 table3gpp->m_uK = 0;
1839 table3gpp->m_sigK = 0;
1840 table3gpp->m_rTau = 2.3;
1841 table3gpp->m_uXpr = 7;
1842 table3gpp->m_sigXpr = 3;
1843 table3gpp->m_perClusterShadowingStd = 3;
1845 for (uint8_t row = 0; row < 6; row++)
1847 for (uint8_t column = 0; column < 6; column++)
1855 table3gpp->m_numOfCluster = 12;
1856 table3gpp->m_raysPerCluster = 20;
1857 table3gpp->m_uLgDS = -6.62;
1858 table3gpp->m_sigLgDS = 0.32;
1859 table3gpp->m_uLgASD = 1.25;
1860 table3gpp->m_sigLgASD = 0.42;
1861 table3gpp->m_uLgASA = 1.76;
1862 table3gpp->m_sigLgASA = 0.16;
1863 table3gpp->m_uLgZSA = 1.01;
1864 table3gpp->m_sigLgZSA = 0.43;
1865 table3gpp->m_uLgZSD =
uLgZSD;
1866 table3gpp->m_sigLgZSD = 0.49;
1867 table3gpp->m_offsetZOD = offsetZOD;
1868 table3gpp->m_cDS = 11e-9;
1869 table3gpp->m_cASD = 5;
1870 table3gpp->m_cASA = 8;
1871 table3gpp->m_cZSA = 3;
1872 table3gpp->m_uK = 0;
1873 table3gpp->m_sigK = 0;
1874 table3gpp->m_rTau = 2.2;
1875 table3gpp->m_uXpr = 9;
1876 table3gpp->m_sigXpr = 5;
1877 table3gpp->m_perClusterShadowingStd = 4;
1879 for (uint8_t row = 0; row < 6; row++)
1881 for (uint8_t column = 0; column < 6; column++)
1883 table3gpp->m_sqrtC[row][column] =
sqrtC_UMa_O2I[row][column];
1893 table3gpp->m_numOfCluster = 12;
1894 table3gpp->m_raysPerCluster = 20;
1895 table3gpp->m_uLgDS = -0.24 * log10(1 + fcGHz) - 7.14;
1896 table3gpp->m_sigLgDS = 0.38;
1897 table3gpp->m_uLgASD = -0.05 * log10(1 + fcGHz) + 1.21;
1898 table3gpp->m_sigLgASD = 0.41;
1899 table3gpp->m_uLgASA = -0.08 * log10(1 + fcGHz) + 1.73;
1900 table3gpp->m_sigLgASA = 0.014 * log10(1 + fcGHz) + 0.28;
1901 table3gpp->m_uLgZSA = -0.1 * log10(1 + fcGHz) + 0.73;
1902 table3gpp->m_sigLgZSA = -0.04 * log10(1 + fcGHz) + 0.34;
1903 table3gpp->m_uLgZSD =
1904 std::max(-0.21, -14.8 * distance2D / 1000.0 + 0.01 * std::abs(hUT - hBS) + 0.83);
1905 table3gpp->m_sigLgZSD = 0.35;
1906 table3gpp->m_offsetZOD = 0;
1907 table3gpp->m_cDS = 5e-9;
1908 table3gpp->m_cASD = 3;
1909 table3gpp->m_cASA = 17;
1910 table3gpp->m_cZSA = 7;
1911 table3gpp->m_uK = 9;
1912 table3gpp->m_sigK = 5;
1913 table3gpp->m_rTau = 3;
1914 table3gpp->m_uXpr = 9;
1915 table3gpp->m_sigXpr = 3;
1916 table3gpp->m_perClusterShadowingStd = 3;
1918 for (uint8_t row = 0; row < 7; row++)
1920 for (uint8_t column = 0; column < 7; column++)
1922 table3gpp->m_sqrtC[row][column] =
sqrtC_UMi_LOS[row][column];
1929 std::max(-0.5, -3.1 * distance2D / 1000.0 + 0.01 * std::max(hUT - hBS, 0.0) + 0.2);
1930 double offsetZOD = -1 * std::pow(10, -1.5 * log10(std::max(10.0, distance2D)) + 3.3);
1933 table3gpp->m_numOfCluster = 19;
1934 table3gpp->m_raysPerCluster = 20;
1935 table3gpp->m_uLgDS = -0.24 * log10(1 + fcGHz) - 6.83;
1936 table3gpp->m_sigLgDS = 0.16 * log10(1 + fcGHz) + 0.28;
1937 table3gpp->m_uLgASD = -0.23 * log10(1 + fcGHz) + 1.53;
1938 table3gpp->m_sigLgASD = 0.11 * log10(1 + fcGHz) + 0.33;
1939 table3gpp->m_uLgASA = -0.08 * log10(1 + fcGHz) + 1.81;
1940 table3gpp->m_sigLgASA = 0.05 * log10(1 + fcGHz) + 0.3;
1941 table3gpp->m_uLgZSA = -0.04 * log10(1 + fcGHz) + 0.92;
1942 table3gpp->m_sigLgZSA = -0.07 * log10(1 + fcGHz) + 0.41;
1943 table3gpp->m_uLgZSD =
uLgZSD;
1944 table3gpp->m_sigLgZSD = 0.35;
1945 table3gpp->m_offsetZOD = offsetZOD;
1946 table3gpp->m_cDS = 11e-9;
1947 table3gpp->m_cASD = 10;
1948 table3gpp->m_cASA = 22;
1949 table3gpp->m_cZSA = 7;
1950 table3gpp->m_uK = 0;
1951 table3gpp->m_sigK = 0;
1952 table3gpp->m_rTau = 2.1;
1953 table3gpp->m_uXpr = 8;
1954 table3gpp->m_sigXpr = 3;
1955 table3gpp->m_perClusterShadowingStd = 3;
1957 for (uint8_t row = 0; row < 6; row++)
1959 for (uint8_t column = 0; column < 6; column++)
1967 table3gpp->m_numOfCluster = 12;
1968 table3gpp->m_raysPerCluster = 20;
1969 table3gpp->m_uLgDS = -6.62;
1970 table3gpp->m_sigLgDS = 0.32;
1971 table3gpp->m_uLgASD = 1.25;
1972 table3gpp->m_sigLgASD = 0.42;
1973 table3gpp->m_uLgASA = 1.76;
1974 table3gpp->m_sigLgASA = 0.16;
1975 table3gpp->m_uLgZSA = 1.01;
1976 table3gpp->m_sigLgZSA = 0.43;
1977 table3gpp->m_uLgZSD =
uLgZSD;
1978 table3gpp->m_sigLgZSD = 0.35;
1979 table3gpp->m_offsetZOD = offsetZOD;
1980 table3gpp->m_cDS = 11e-9;
1981 table3gpp->m_cASD = 5;
1982 table3gpp->m_cASA = 8;
1983 table3gpp->m_cZSA = 3;
1984 table3gpp->m_uK = 0;
1985 table3gpp->m_sigK = 0;
1986 table3gpp->m_rTau = 2.2;
1987 table3gpp->m_uXpr = 9;
1988 table3gpp->m_sigXpr = 5;
1989 table3gpp->m_perClusterShadowingStd = 4;
1991 for (uint8_t row = 0; row < 6; row++)
1993 for (uint8_t column = 0; column < 6; column++)
1995 table3gpp->m_sqrtC[row][column] =
sqrtC_UMi_O2I[row][column];
2003 NS_ASSERT_MSG(!o2i,
"The indoor scenario does out support outdoor to indoor");
2006 table3gpp->m_numOfCluster = 15;
2007 table3gpp->m_raysPerCluster = 20;
2008 table3gpp->m_uLgDS = -0.01 * log10(1 + fcGHz) - 7.692;
2009 table3gpp->m_sigLgDS = 0.18;
2010 table3gpp->m_uLgASD = 1.60;
2011 table3gpp->m_sigLgASD = 0.18;
2012 table3gpp->m_uLgASA = -0.19 * log10(1 + fcGHz) + 1.781;
2013 table3gpp->m_sigLgASA = 0.12 * log10(1 + fcGHz) + 0.119;
2014 table3gpp->m_uLgZSA = -0.26 * log10(1 + fcGHz) + 1.44;
2015 table3gpp->m_sigLgZSA = -0.04 * log10(1 + fcGHz) + 0.264;
2016 table3gpp->m_uLgZSD = -1.43 * log10(1 + fcGHz) + 2.228;
2017 table3gpp->m_sigLgZSD = 0.13 * log10(1 + fcGHz) + 0.30;
2018 table3gpp->m_offsetZOD = 0;
2019 table3gpp->m_cDS = 3.91e-9;
2020 table3gpp->m_cASD = 5;
2021 table3gpp->m_cASA = 8;
2022 table3gpp->m_cZSA = 9;
2023 table3gpp->m_uK = 7;
2024 table3gpp->m_sigK = 4;
2025 table3gpp->m_rTau = 3.6;
2026 table3gpp->m_uXpr = 11;
2027 table3gpp->m_sigXpr = 4;
2028 table3gpp->m_perClusterShadowingStd = 6;
2030 for (uint8_t row = 0; row < 7; row++)
2032 for (uint8_t column = 0; column < 7; column++)
2040 table3gpp->m_numOfCluster = 19;
2041 table3gpp->m_raysPerCluster = 20;
2042 table3gpp->m_uLgDS = -0.28 * log10(1 + fcGHz) - 7.173;
2043 table3gpp->m_sigLgDS = 0.1 * log10(1 + fcGHz) + 0.055;
2044 table3gpp->m_uLgASD = 1.62;
2045 table3gpp->m_sigLgASD = 0.25;
2046 table3gpp->m_uLgASA = -0.11 * log10(1 + fcGHz) + 1.863;
2047 table3gpp->m_sigLgASA = 0.12 * log10(1 + fcGHz) + 0.059;
2048 table3gpp->m_uLgZSA = -0.15 * log10(1 + fcGHz) + 1.387;
2049 table3gpp->m_sigLgZSA = -0.09 * log10(1 + fcGHz) + 0.746;
2050 table3gpp->m_uLgZSD = 1.08;
2051 table3gpp->m_sigLgZSD = 0.36;
2052 table3gpp->m_offsetZOD = 0;
2053 table3gpp->m_cDS = 3.91e-9;
2054 table3gpp->m_cASD = 5;
2055 table3gpp->m_cASA = 11;
2056 table3gpp->m_cZSA = 9;
2057 table3gpp->m_uK = 0;
2058 table3gpp->m_sigK = 0;
2059 table3gpp->m_rTau = 3;
2060 table3gpp->m_uXpr = 10;
2061 table3gpp->m_sigXpr = 4;
2062 table3gpp->m_perClusterShadowingStd = 3;
2064 for (uint8_t row = 0; row < 6; row++)
2066 for (uint8_t column = 0; column < 6; column++)
2075 if (channelCondition->IsLos())
2079 table3gpp->m_numOfCluster = 12;
2080 table3gpp->m_raysPerCluster = 20;
2081 table3gpp->m_uLgDS = -0.2 * log10(1 + fcGHz) - 7.5;
2082 table3gpp->m_sigLgDS = 0.1;
2083 table3gpp->m_uLgASD = -0.1 * log10(1 + fcGHz) + 1.6;
2084 table3gpp->m_sigLgASD = 0.1;
2085 table3gpp->m_uLgASA = -0.1 * log10(1 + fcGHz) + 1.6;
2086 table3gpp->m_sigLgASA = 0.1;
2087 table3gpp->m_uLgZSA = -0.1 * log10(1 + fcGHz) + 0.73;
2088 table3gpp->m_sigLgZSA = -0.04 * log10(1 + fcGHz) + 0.34;
2089 table3gpp->m_uLgZSD = -0.1 * log10(1 + fcGHz) + 0.73;
2090 table3gpp->m_sigLgZSD = -0.04 * log10(1 + fcGHz) + 0.34;
2091 table3gpp->m_offsetZOD = 0;
2092 table3gpp->m_cDS = 5;
2093 table3gpp->m_cASD = 17;
2094 table3gpp->m_cASA = 17;
2095 table3gpp->m_cZSA = 7;
2096 table3gpp->m_uK = 3.48;
2097 table3gpp->m_sigK = 2;
2098 table3gpp->m_rTau = 3;
2099 table3gpp->m_uXpr = 9;
2100 table3gpp->m_sigXpr = 3;
2101 table3gpp->m_perClusterShadowingStd = 4;
2103 for (uint8_t row = 0; row < 7; row++)
2105 for (uint8_t column = 0; column < 7; column++)
2107 table3gpp->m_sqrtC[row][column] =
sqrtC_UMi_LOS[row][column];
2111 else if (channelCondition->IsNlos())
2113 table3gpp->m_numOfCluster = 19;
2114 table3gpp->m_raysPerCluster = 20;
2115 table3gpp->m_uLgDS = -0.3 * log10(1 + fcGHz) - 7;
2116 table3gpp->m_sigLgDS = 0.28;
2117 table3gpp->m_uLgASD = -0.08 * log10(1 + fcGHz) + 1.81;
2118 table3gpp->m_sigLgASD = 0.05 * log10(1 + fcGHz) + 0.3;
2119 table3gpp->m_uLgASA = -0.08 * log10(1 + fcGHz) + 1.81;
2120 table3gpp->m_sigLgASA = 0.05 * log10(1 + fcGHz) + 0.3;
2121 table3gpp->m_uLgZSA = -0.04 * log10(1 + fcGHz) + 0.92;
2122 table3gpp->m_sigLgZSA = -0.07 * log10(1 + fcGHz) + 0.41;
2123 table3gpp->m_uLgZSD = -0.04 * log10(1 + fcGHz) + 0.92;
2124 table3gpp->m_sigLgZSD = -0.07 * log10(1 + fcGHz) + 0.41;
2125 table3gpp->m_offsetZOD = 0;
2126 table3gpp->m_cDS = 11;
2127 table3gpp->m_cASD = 22;
2128 table3gpp->m_cASA = 22;
2129 table3gpp->m_cZSA = 7;
2130 table3gpp->m_uK = 0;
2131 table3gpp->m_sigK = 0;
2132 table3gpp->m_rTau = 2.1;
2133 table3gpp->m_uXpr = 8;
2134 table3gpp->m_sigXpr = 3;
2135 table3gpp->m_perClusterShadowingStd = 4;
2137 for (uint8_t row = 0; row < 6; row++)
2139 for (uint8_t column = 0; column < 6; column++)
2145 else if (channelCondition->IsNlosv())
2147 table3gpp->m_numOfCluster = 19;
2148 table3gpp->m_raysPerCluster = 20;
2149 table3gpp->m_uLgDS = -0.4 * log10(1 + fcGHz) - 7;
2150 table3gpp->m_sigLgDS = 0.1;
2151 table3gpp->m_uLgASD = -0.1 * log10(1 + fcGHz) + 1.7;
2152 table3gpp->m_sigLgASD = 0.1;
2153 table3gpp->m_uLgASA = -0.1 * log10(1 + fcGHz) + 1.7;
2154 table3gpp->m_sigLgASA = 0.1;
2155 table3gpp->m_uLgZSA = -0.04 * log10(1 + fcGHz) + 0.92;
2156 table3gpp->m_sigLgZSA = -0.07 * log10(1 + fcGHz) + 0.41;
2157 table3gpp->m_uLgZSD = -0.04 * log10(1 + fcGHz) + 0.92;
2158 table3gpp->m_sigLgZSD = -0.07 * log10(1 + fcGHz) + 0.41;
2159 table3gpp->m_offsetZOD = 0;
2160 table3gpp->m_cDS = 11;
2161 table3gpp->m_cASD = 22;
2162 table3gpp->m_cASA = 22;
2163 table3gpp->m_cZSA = 7;
2164 table3gpp->m_uK = 0;
2165 table3gpp->m_sigK = 4.5;
2166 table3gpp->m_rTau = 2.1;
2167 table3gpp->m_uXpr = 8;
2168 table3gpp->m_sigXpr = 3;
2169 table3gpp->m_perClusterShadowingStd = 4;
2171 for (uint8_t row = 0; row < 6; row++)
2173 for (uint8_t column = 0; column < 6; column++)
2175 table3gpp->m_sqrtC[row][column] =
sqrtC_UMi_LOS[row][column];
2186 if (channelCondition->IsLos())
2188 table3gpp->m_numOfCluster = 12;
2189 table3gpp->m_raysPerCluster = 20;
2190 table3gpp->m_uLgDS = -8.3;
2191 table3gpp->m_sigLgDS = 0.2;
2192 table3gpp->m_uLgASD = 1.4;
2193 table3gpp->m_sigLgASD = 0.1;
2194 table3gpp->m_uLgASA = 1.4;
2195 table3gpp->m_sigLgASA = 0.1;
2196 table3gpp->m_uLgZSA = -0.1 * log10(1 + fcGHz) + 0.73;
2197 table3gpp->m_sigLgZSA = -0.04 * log10(1 + fcGHz) + 0.34;
2198 table3gpp->m_uLgZSD = -0.1 * log10(1 + fcGHz) + 0.73;
2199 table3gpp->m_sigLgZSD = -0.04 * log10(1 + fcGHz) + 0.34;
2200 table3gpp->m_offsetZOD = 0;
2201 table3gpp->m_cDS = 5;
2202 table3gpp->m_cASD = 17;
2203 table3gpp->m_cASA = 17;
2204 table3gpp->m_cZSA = 7;
2205 table3gpp->m_uK = 9;
2206 table3gpp->m_sigK = 3.5;
2207 table3gpp->m_rTau = 3;
2208 table3gpp->m_uXpr = 9;
2209 table3gpp->m_sigXpr = 3;
2210 table3gpp->m_perClusterShadowingStd = 4;
2212 for (uint8_t row = 0; row < 7; row++)
2214 for (uint8_t column = 0; column < 7; column++)
2216 table3gpp->m_sqrtC[row][column] =
sqrtC_UMi_LOS[row][column];
2220 else if (channelCondition->IsNlosv())
2222 table3gpp->m_numOfCluster = 19;
2223 table3gpp->m_raysPerCluster = 20;
2224 table3gpp->m_uLgDS = -8.3;
2225 table3gpp->m_sigLgDS = 0.3;
2226 table3gpp->m_uLgASD = 1.5;
2227 table3gpp->m_sigLgASD = 0.1;
2228 table3gpp->m_uLgASA = 1.5;
2229 table3gpp->m_sigLgASA = 0.1;
2230 table3gpp->m_uLgZSA = -0.04 * log10(1 + fcGHz) + 0.92;
2231 table3gpp->m_sigLgZSA = -0.07 * log10(1 + fcGHz) + 0.41;
2232 table3gpp->m_uLgZSD = -0.04 * log10(1 + fcGHz) + 0.92;
2233 table3gpp->m_sigLgZSD = -0.07 * log10(1 + fcGHz) + 0.41;
2234 table3gpp->m_offsetZOD = 0;
2235 table3gpp->m_cDS = 11;
2236 table3gpp->m_cASD = 22;
2237 table3gpp->m_cASA = 22;
2238 table3gpp->m_cZSA = 7;
2239 table3gpp->m_uK = 0;
2240 table3gpp->m_sigK = 4.5;
2241 table3gpp->m_rTau = 2.1;
2242 table3gpp->m_uXpr = 8.0;
2243 table3gpp->m_sigXpr = 3;
2244 table3gpp->m_perClusterShadowingStd = 4;
2246 for (uint8_t row = 0; row < 6; row++)
2248 for (uint8_t column = 0; column < 6; column++)
2250 table3gpp->m_sqrtC[row][column] =
sqrtC_UMi_LOS[row][column];
2254 else if (channelCondition->IsNlos())
2257 "The fast fading parameters for the NLOS condition in the Highway scenario are not "
2258 "defined in TR 37.885, use the ones defined in TDoc R1-1803671 instead");
2260 table3gpp->m_numOfCluster = 19;
2261 table3gpp->m_raysPerCluster = 20;
2262 table3gpp->m_uLgDS = -0.3 * log10(1 + fcGHz) - 7;
2263 table3gpp->m_sigLgDS = 0.28;
2264 table3gpp->m_uLgASD = -0.08 * log10(1 + fcGHz) + 1.81;
2265 table3gpp->m_sigLgASD = 0.05 * log10(1 + fcGHz) + 0.3;
2266 table3gpp->m_uLgASA = -0.08 * log10(1 + fcGHz) + 1.81;
2267 table3gpp->m_sigLgASA = 0.05 * log10(1 + fcGHz) + 0.3;
2268 table3gpp->m_uLgZSA = -0.04 * log10(1 + fcGHz) + 0.92;
2269 table3gpp->m_sigLgZSA = -0.07 * log10(1 + fcGHz) + 0.41;
2270 table3gpp->m_uLgZSD = -0.04 * log10(1 + fcGHz) + 0.92;
2271 table3gpp->m_sigLgZSD = -0.07 * log10(1 + fcGHz) + 0.41;
2272 table3gpp->m_offsetZOD = 0;
2273 table3gpp->m_cDS = 11;
2274 table3gpp->m_cASD = 22;
2275 table3gpp->m_cASA = 22;
2276 table3gpp->m_cZSA = 7;
2277 table3gpp->m_uK = 0;
2278 table3gpp->m_sigK = 0;
2279 table3gpp->m_rTau = 2.1;
2280 table3gpp->m_uXpr = 8;
2281 table3gpp->m_sigXpr = 3;
2282 table3gpp->m_perClusterShadowingStd = 4;
2284 for (uint8_t row = 0; row < 6; row++)
2286 for (uint8_t column = 0; column < 6; column++)
2299 std::string freqBand = (fcGHz < 13) ?
"S" :
"Ka";
2301 double elevAngle = 0;
2302 bool isSatellite =
false;
2309 if (DynamicCast<GeocentricConstantPositionMobilityModel>(
2310 ConstCast<MobilityModel>(aMob)) &&
2311 DynamicCast<GeocentricConstantPositionMobilityModel>(
2312 ConstCast<MobilityModel>(bMob)))
2316 DynamicCast<GeocentricConstantPositionMobilityModel>(aMobNonConst);
2318 DynamicCast<GeocentricConstantPositionMobilityModel>(bMobNonConst);
2320 if (aNTNMob->GetGeographicPosition().z <
2321 bNTNMob->GetGeographicPosition().z)
2323 elevAngle = aNTNMob->GetElevationAngle(bNTNMob);
2324 if (bNTNMob->GetGeographicPosition().z > 50000)
2331 elevAngle = bNTNMob->GetElevationAngle(aNTNMob);
2332 if (aNTNMob->GetGeographicPosition().z > 50000)
2340 NS_FATAL_ERROR(
"Mobility Models needs to be of type Geocentric for NTN scenarios");
2344 int elevAngleQuantized = (elevAngle < 10) ? 10 : round(elevAngle / 10) * 10;
2348 if (channelCondition->IsLos())
2350 table3gpp->m_uLgDS = (*m_NTNDenseUrbanLOS)
2353 table3gpp->m_sigLgDS = (*m_NTNDenseUrbanLOS)
2358 table3gpp->m_uLgASD = (*m_NTNDenseUrbanLOS)
2362 table3gpp->m_sigLgASD = (*m_NTNDenseUrbanLOS)
2366 table3gpp->m_uLgASA = (*m_NTNDenseUrbanLOS)
2369 table3gpp->m_sigLgASA = (*m_NTNDenseUrbanLOS)
2372 table3gpp->m_uLgZSA = (*m_NTNDenseUrbanLOS)
2375 table3gpp->m_sigLgZSA = (*m_NTNDenseUrbanLOS)
2380 table3gpp->m_uLgZSD = (*m_NTNDenseUrbanLOS)
2384 table3gpp->m_sigLgZSD = (*m_NTNDenseUrbanLOS)
2390 table3gpp->m_sigK = (*m_NTNDenseUrbanLOS)
2393 table3gpp->m_rTau = (*m_NTNDenseUrbanLOS)
2396 table3gpp->m_uXpr = (*m_NTNDenseUrbanLOS)
2399 table3gpp->m_sigXpr = (*m_NTNDenseUrbanLOS)
2402 table3gpp->m_numOfCluster =
2403 (*m_NTNDenseUrbanLOS)
2406 table3gpp->m_raysPerCluster =
2407 (*m_NTNDenseUrbanLOS)
2412 table3gpp->m_cASD = (*m_NTNDenseUrbanLOS)
2415 table3gpp->m_cASA = (*m_NTNDenseUrbanLOS)
2418 table3gpp->m_cZSA = (*m_NTNDenseUrbanLOS)
2421 table3gpp->m_perClusterShadowingStd =
2422 (*m_NTNDenseUrbanLOS)
2426 for (uint8_t row = 0; row < 7; row++)
2428 for (uint8_t column = 0; column < 7; column++)
2434 else if (channelCondition->IsNlos())
2437 table3gpp->m_uLgDS = (*m_NTNDenseUrbanNLOS)
2440 table3gpp->m_sigLgDS = (*m_NTNDenseUrbanNLOS)
2443 table3gpp->m_uLgASD = (*m_NTNDenseUrbanNLOS)
2446 table3gpp->m_sigLgASD = (*m_NTNDenseUrbanNLOS)
2449 table3gpp->m_uLgASA = (*m_NTNDenseUrbanNLOS)
2452 table3gpp->m_sigLgASA = (*m_NTNDenseUrbanNLOS)
2455 table3gpp->m_uLgZSA = (*m_NTNDenseUrbanNLOS)
2458 table3gpp->m_sigLgZSA = (*m_NTNDenseUrbanNLOS)
2461 table3gpp->m_uLgZSD = (*m_NTNDenseUrbanNLOS)
2464 table3gpp->m_sigLgZSD = (*m_NTNDenseUrbanNLOS)
2467 table3gpp->m_rTau = (*m_NTNDenseUrbanNLOS)
2470 table3gpp->m_uXpr = (*m_NTNDenseUrbanNLOS)
2473 table3gpp->m_sigXpr = (*m_NTNDenseUrbanNLOS)
2476 table3gpp->m_numOfCluster =
2477 (*m_NTNDenseUrbanNLOS)
2480 table3gpp->m_raysPerCluster =
2481 (*m_NTNDenseUrbanNLOS)
2484 table3gpp->m_cDS = (*m_NTNDenseUrbanNLOS)
2487 table3gpp->m_cASD = (*m_NTNDenseUrbanNLOS)
2490 table3gpp->m_cASA = (*m_NTNDenseUrbanNLOS)
2493 table3gpp->m_cZSA = (*m_NTNDenseUrbanNLOS)
2496 table3gpp->m_perClusterShadowingStd =
2497 (*m_NTNDenseUrbanNLOS)
2501 for (uint8_t row = 0; row < 6; row++)
2503 for (uint8_t column = 0; column < 6; column++)
2512 if (channelCondition->IsLos())
2514 table3gpp->m_uLgDS =
2516 table3gpp->m_sigLgDS =
2518 table3gpp->m_uLgASD =
2520 table3gpp->m_sigLgASD =
2522 table3gpp->m_uLgASA =
2524 table3gpp->m_sigLgASA =
2526 table3gpp->m_uLgZSA =
2528 table3gpp->m_sigLgZSA =
2530 table3gpp->m_uLgZSD =
2532 table3gpp->m_sigLgZSD =
2542 table3gpp->m_sigXpr =
2544 table3gpp->m_numOfCluster =
2548 table3gpp->m_raysPerCluster =
2560 table3gpp->m_perClusterShadowingStd =
2565 for (uint8_t row = 0; row < 7; row++)
2567 for (uint8_t column = 0; column < 7; column++)
2573 else if (channelCondition->IsNlos())
2575 table3gpp->m_uLgDS =
2577 table3gpp->m_sigLgDS =
2579 table3gpp->m_uLgASD =
2581 table3gpp->m_sigLgASD = (*m_NTNUrbanNLOS)
2584 table3gpp->m_uLgASA =
2586 table3gpp->m_sigLgASA = (*m_NTNUrbanNLOS)
2589 table3gpp->m_uLgZSA =
2591 table3gpp->m_sigLgZSA = (*m_NTNUrbanNLOS)
2594 table3gpp->m_uLgZSD =
2596 table3gpp->m_sigLgZSD = (*m_NTNUrbanNLOS)
2607 table3gpp->m_sigXpr =
2609 table3gpp->m_numOfCluster =
2613 table3gpp->m_raysPerCluster =
2625 table3gpp->m_perClusterShadowingStd =
2630 for (uint8_t row = 0; row < 6; row++)
2632 for (uint8_t column = 0; column < 6; column++)
2634 table3gpp->m_sqrtC[row][column] =
2642 if (channelCondition->IsLos())
2644 table3gpp->m_uLgDS =
2646 table3gpp->m_sigLgDS = (*m_NTNSuburbanLOS)
2649 table3gpp->m_uLgASD = (*m_NTNSuburbanLOS)
2652 table3gpp->m_sigLgASD = (*m_NTNSuburbanLOS)
2655 table3gpp->m_uLgASA = (*m_NTNSuburbanLOS)
2658 table3gpp->m_sigLgASA = (*m_NTNSuburbanLOS)
2661 table3gpp->m_uLgZSA = (*m_NTNSuburbanLOS)
2664 table3gpp->m_sigLgZSA = (*m_NTNSuburbanLOS)
2667 table3gpp->m_uLgZSD = (*m_NTNSuburbanLOS)
2670 table3gpp->m_sigLgZSD = (*m_NTNSuburbanLOS)
2681 table3gpp->m_sigXpr = (*m_NTNSuburbanLOS)
2684 table3gpp->m_numOfCluster =
2688 table3gpp->m_raysPerCluster =
2700 table3gpp->m_perClusterShadowingStd =
2705 for (uint8_t row = 0; row < 7; row++)
2707 for (uint8_t column = 0; column < 7; column++)
2713 else if (channelCondition->IsNlos())
2715 table3gpp->m_uLgDS = (*m_NTNSuburbanNLOS)
2718 table3gpp->m_sigLgDS = (*m_NTNSuburbanNLOS)
2721 table3gpp->m_uLgASD = (*m_NTNSuburbanNLOS)
2724 table3gpp->m_sigLgASD = (*m_NTNSuburbanNLOS)
2727 table3gpp->m_uLgASA = (*m_NTNSuburbanNLOS)
2730 table3gpp->m_sigLgASA = (*m_NTNSuburbanNLOS)
2733 table3gpp->m_uLgZSA = (*m_NTNSuburbanNLOS)
2736 table3gpp->m_sigLgZSA = (*m_NTNSuburbanNLOS)
2739 table3gpp->m_uLgZSD = (*m_NTNSuburbanNLOS)
2742 table3gpp->m_sigLgZSD = (*m_NTNSuburbanNLOS)
2753 table3gpp->m_sigXpr = (*m_NTNSuburbanNLOS)
2756 table3gpp->m_numOfCluster =
2757 (*m_NTNSuburbanNLOS)
2760 table3gpp->m_raysPerCluster =
2761 (*m_NTNSuburbanNLOS)
2772 table3gpp->m_perClusterShadowingStd =
2773 (*m_NTNSuburbanNLOS)
2777 for (uint8_t row = 0; row < 6; row++)
2779 for (uint8_t column = 0; column < 6; column++)
2788 if (channelCondition->IsLos())
2790 table3gpp->m_uLgDS =
2792 table3gpp->m_sigLgDS =
2794 table3gpp->m_uLgASD =
2796 table3gpp->m_sigLgASD =
2798 table3gpp->m_uLgASA =
2800 table3gpp->m_sigLgASA =
2802 table3gpp->m_uLgZSA =
2804 table3gpp->m_sigLgZSA =
2806 table3gpp->m_uLgZSD =
2808 table3gpp->m_sigLgZSD =
2818 table3gpp->m_sigXpr =
2820 table3gpp->m_numOfCluster =
2824 table3gpp->m_raysPerCluster =
2836 table3gpp->m_perClusterShadowingStd =
2841 for (uint8_t row = 0; row < 7; row++)
2843 for (uint8_t column = 0; column < 7; column++)
2849 else if (channelCondition->IsNlos())
2851 table3gpp->m_uLgDS =
2853 table3gpp->m_sigLgDS =
2855 table3gpp->m_uLgASD =
2857 table3gpp->m_sigLgASD = (*m_NTNRuralNLOS)
2860 table3gpp->m_uLgASA =
2862 table3gpp->m_sigLgASA = (*m_NTNRuralNLOS)
2865 table3gpp->m_uLgZSA =
2867 table3gpp->m_sigLgZSA = (*m_NTNRuralNLOS)
2870 table3gpp->m_uLgZSD =
2872 table3gpp->m_sigLgZSD = (*m_NTNRuralNLOS)
2883 table3gpp->m_sigXpr =
2885 table3gpp->m_numOfCluster =
2889 table3gpp->m_raysPerCluster =
2901 table3gpp->m_perClusterShadowingStd =
2906 if (freqBand ==
"S")
2908 for (uint8_t row = 0; row < 6; row++)
2910 for (uint8_t column = 0; column < 6; column++)
2912 table3gpp->m_sqrtC[row][column] =
2917 else if (freqBand ==
"Ka")
2919 for (uint8_t row = 0; row < 6; row++)
2921 for (uint8_t column = 0; column < 6; column++)
2923 table3gpp->m_sqrtC[row][column] =
2934 table3gpp->m_uLgASD = std::numeric_limits<double>::min();
2935 table3gpp->m_sigLgASD = 0;
2936 table3gpp->m_uLgZSD = std::numeric_limits<double>::min();
2937 table3gpp->m_sigLgZSD = 0;
2954 bool update =
false;
2957 if (!channelCondition->IsEqual(channelParams->m_losCondition, channelParams->m_o2iCondition))
2979 return channelParams->m_generatedTime > channelMatrix->m_generatedTime;
2989 size_t sAntNumElems = aAntenna->GetNumElems();
2990 size_t uAntNumElems = bAntenna->GetNumElems();
2991 size_t chanNumRows = channelMatrix->m_channel.GetNumRows();
2992 size_t chanNumCols = channelMatrix->m_channel.GetNumCols();
2993 return ((uAntNumElems != chanNumRows) || (sAntNumElems != chanNumCols)) &&
2994 ((uAntNumElems != chanNumCols) || (sAntNumElems != chanNumRows));
3006 uint64_t channelParamsKey =
3009 uint64_t channelMatrixKey =
GetKey(aAntenna->GetId(), bAntenna->GetId());
3017 bool updateParams =
false;
3018 bool updateMatrix =
false;
3019 bool notFoundParams =
false;
3020 bool notFoundMatrix =
false;
3033 notFoundParams =
true;
3039 if (notFoundParams || updateParams)
3065 notFoundMatrix =
true;
3070 if (notFoundMatrix || updateMatrix)
3073 channelMatrix =
GetNewChannel(channelParams, table3gpp, aMob, bMob, aAntenna, bAntenna);
3074 channelMatrix->m_antennaPair =
3075 std::make_pair(aAntenna->GetId(),
3083 return channelMatrix;
3092 uint64_t channelParamsKey =
3101 NS_LOG_WARN(
"Channel params map not found. Returning a nullptr.");
3116 channelParams->m_nodeIds =
3118 channelParams->m_losCondition = channelCondition->GetLosCondition();
3119 channelParams->m_o2iCondition = channelCondition->GetO2iCondition();
3124 uint8_t paramNum = 6;
3131 for (uint8_t iter = 0; iter < paramNum; iter++)
3135 for (uint8_t row = 0; row < paramNum; row++)
3138 for (uint8_t column = 0; column < paramNum; column++)
3140 temp += table3gpp->m_sqrtC[row][column] * LSPsIndep[column];
3142 LSPs.push_back(temp);
3154 kFactor = LSPs[1] * table3gpp->m_sigK + table3gpp->m_uK;
3155 DS = pow(10, LSPs[2] * table3gpp->m_sigLgDS + table3gpp->m_uLgDS);
3156 ASD = pow(10, LSPs[3] * table3gpp->m_sigLgASD + table3gpp->m_uLgASD);
3157 ASA = pow(10, LSPs[4] * table3gpp->m_sigLgASA + table3gpp->m_uLgASA);
3158 ZSD = pow(10, LSPs[5] * table3gpp->m_sigLgZSD + table3gpp->m_uLgZSD);
3159 ZSA = pow(10, LSPs[6] * table3gpp->m_sigLgZSA + table3gpp->m_uLgZSA);
3163 DS = pow(10, LSPs[1] * table3gpp->m_sigLgDS + table3gpp->m_uLgDS);
3164 ASD = pow(10, LSPs[2] * table3gpp->m_sigLgASD + table3gpp->m_uLgASD);
3165 ASA = pow(10, LSPs[3] * table3gpp->m_sigLgASA + table3gpp->m_uLgASA);
3166 ZSD = pow(10, LSPs[4] * table3gpp->m_sigLgZSD + table3gpp->m_uLgZSD);
3167 ZSA = pow(10, LSPs[5] * table3gpp->m_sigLgZSA + table3gpp->m_uLgZSA);
3169 ASD = std::min(ASD, 104.0);
3170 ASA = std::min(ASA, 104.0);
3171 ZSD = std::min(ZSD, 52.0);
3172 ZSA = std::min(ZSA, 52.0);
3175 channelParams->m_DS = DS;
3176 channelParams->m_K_factor = kFactor;
3178 NS_LOG_INFO(
"K-factor=" << kFactor <<
", DS=" << DS <<
", ASD=" << ASD <<
", ASA=" << ASA
3179 <<
", ZSD=" << ZSD <<
", ZSA=" << ZSA);
3183 double minTau = 100.0;
3184 for (uint8_t cIndex = 0; cIndex < table3gpp->m_numOfCluster; cIndex++)
3191 clusterDelay.push_back(tau);
3194 for (uint8_t cIndex = 0; cIndex < table3gpp->m_numOfCluster; cIndex++)
3196 clusterDelay[cIndex] -= minTau;
3198 std::sort(clusterDelay.begin(), clusterDelay.end());
3205 double powerSum = 0;
3206 for (uint8_t cIndex = 0; cIndex < table3gpp->m_numOfCluster; cIndex++)
3209 exp(-1 * clusterDelay[cIndex] * (table3gpp->m_rTau - 1) / table3gpp->m_rTau / DS) *
3211 -1 *
m_normalRv->GetValue() * table3gpp->m_perClusterShadowingStd / 10.0);
3213 clusterPower.push_back(power);
3215 channelParams->m_clusterPower = clusterPower;
3217 double powerMax = 0;
3219 for (uint8_t cIndex = 0; cIndex < table3gpp->m_numOfCluster; cIndex++)
3221 channelParams->m_clusterPower[cIndex] =
3222 channelParams->m_clusterPower[cIndex] / powerSum;
3229 double kLinear = pow(10, kFactor / 10.0);
3231 for (uint8_t cIndex = 0; cIndex < table3gpp->m_numOfCluster; cIndex++)
3235 clusterPowerForAngles.push_back(channelParams->m_clusterPower[cIndex] /
3237 kLinear / (1 + kLinear));
3241 clusterPowerForAngles.push_back(channelParams->m_clusterPower[cIndex] /
3244 if (powerMax < clusterPowerForAngles[cIndex])
3246 powerMax = clusterPowerForAngles[cIndex];
3252 for (uint8_t cIndex = 0; cIndex < table3gpp->m_numOfCluster; cIndex++)
3254 clusterPowerForAngles.push_back(channelParams->m_clusterPower[cIndex]);
3255 if (powerMax < clusterPowerForAngles[cIndex])
3257 powerMax = clusterPowerForAngles[cIndex];
3264 double thresh = 0.0032;
3265 for (uint8_t cIndex = table3gpp->m_numOfCluster; cIndex > 0; cIndex--)
3267 if (clusterPowerForAngles[cIndex - 1] < thresh * powerMax)
3269 clusterPowerForAngles.erase(clusterPowerForAngles.begin() + cIndex - 1);
3270 channelParams->m_clusterPower.erase(channelParams->m_clusterPower.begin() + cIndex - 1);
3271 clusterDelay.erase(clusterDelay.begin() + cIndex - 1);
3275 NS_ASSERT(channelParams->m_clusterPower.size() < UINT8_MAX);
3276 channelParams->m_reducedClusterNumber = channelParams->m_clusterPower.size();
3281 0.7705 - 0.0433 * kFactor + 2e-4 * pow(kFactor, 2) + 17e-6 * pow(kFactor, 3);
3282 for (uint8_t cIndex = 0; cIndex < channelParams->m_reducedClusterNumber; cIndex++)
3284 clusterDelay[cIndex] = clusterDelay[cIndex] / cTau;
3294 switch (table3gpp->m_numOfCluster)
3339 double cPhi = cNlos;
3343 cPhi *= (1.1035 - 0.028 * kFactor - 2e-3 * pow(kFactor, 2) +
3344 1e-4 * pow(kFactor, 3));
3348 switch (table3gpp->m_numOfCluster)
3384 double cTheta = cNlos;
3385 if (channelCondition->IsLos())
3387 cTheta *= (1.3086 + 0.0339 * kFactor - 0.0077 * pow(kFactor, 2) +
3388 2e-4 * pow(kFactor, 3));
3395 for (uint8_t cIndex = 0; cIndex < channelParams->m_reducedClusterNumber; cIndex++)
3397 double logCalc = -1 * log(clusterPowerForAngles[cIndex] / powerMax);
3398 double angle = 2 * sqrt(logCalc) / 1.4 / cPhi;
3399 clusterAoa.push_back(ASA * angle);
3400 clusterAod.push_back(ASD * angle);
3401 angle = logCalc / cTheta;
3402 clusterZoa.push_back(ZSA * angle);
3403 clusterZod.push_back(ZSD * angle);
3406 Angles sAngle(bMob->GetPosition(), aMob->GetPosition());
3407 Angles uAngle(aMob->GetPosition(), bMob->GetPosition());
3409 for (uint8_t cIndex = 0; cIndex < channelParams->m_reducedClusterNumber; cIndex++)
3416 clusterAoa[cIndex] = clusterAoa[cIndex] * Xn + (
m_normalRv->GetValue() * ASA / 7.0) +
3418 clusterAod[cIndex] = clusterAod[cIndex] * Xn + (
m_normalRv->GetValue() * ASD / 7.0) +
3420 if (channelCondition->IsO2i())
3422 clusterZoa[cIndex] =
3423 clusterZoa[cIndex] * Xn + (
m_normalRv->GetValue() * ZSA / 7.0) + 90;
3427 clusterZoa[cIndex] = clusterZoa[cIndex] * Xn + (
m_normalRv->GetValue() * ZSA / 7.0) +
3430 clusterZod[cIndex] = clusterZod[cIndex] * Xn + (
m_normalRv->GetValue() * ZSD / 7.0) +
3432 table3gpp->m_offsetZOD;
3444 for (uint8_t cIndex = 0; cIndex < channelParams->m_reducedClusterNumber; cIndex++)
3446 clusterAoa[cIndex] -= diffAoa;
3447 clusterAod[cIndex] -= diffAod;
3448 clusterZoa[cIndex] -= diffZsa;
3449 clusterZod[cIndex] -= diffZsd;
3453 double sizeTemp = clusterZoa.size();
3454 for (uint8_t ind = 0; ind < 4; ind++)
3460 angleDegree = clusterAoa;
3463 angleDegree = clusterZoa;
3466 angleDegree = clusterAod;
3469 angleDegree = clusterZod;
3474 for (uint8_t nIndex = 0; nIndex < sizeTemp; nIndex++)
3476 while (angleDegree[nIndex] > 360)
3478 angleDegree[nIndex] -= 360;
3481 while (angleDegree[nIndex] < 0)
3483 angleDegree[nIndex] += 360;
3486 if (ind == 1 || ind == 3)
3488 if (angleDegree[nIndex] > 180)
3490 angleDegree[nIndex] = 360 - angleDegree[nIndex];
3497 clusterAoa = angleDegree;
3500 clusterZoa = angleDegree;
3503 clusterAod = angleDegree;
3506 clusterZod = angleDegree;
3517 for (uint8_t cInd = 0; cInd < channelParams->m_reducedClusterNumber; cInd++)
3519 channelParams->m_clusterPower[cInd] =
3520 channelParams->m_clusterPower[cInd] / pow(10, attenuationDb[cInd] / 10.0);
3525 attenuationDb.push_back(0);
3529 channelParams->m_attenuation_dB = attenuationDb;
3534 channelParams->m_reducedClusterNumber,
3538 channelParams->m_reducedClusterNumber,
3542 channelParams->m_reducedClusterNumber,
3546 channelParams->m_reducedClusterNumber,
3550 const double pow10_uLgZSD = pow(10, table3gpp->m_uLgZSD);
3551 for (uint8_t nInd = 0; nInd < channelParams->m_reducedClusterNumber; nInd++)
3553 for (uint8_t mInd = 0; mInd < table3gpp->m_raysPerCluster; mInd++)
3555 double tempAoa = clusterAoa[nInd] + table3gpp->m_cASA *
offSetAlpha[mInd];
3556 double tempZoa = clusterZoa[nInd] + table3gpp->m_cZSA *
offSetAlpha[mInd];
3557 std::tie(rayAoaRadian[nInd][mInd], rayZoaRadian[nInd][mInd]) =
3560 double tempAod = clusterAod[nInd] + table3gpp->m_cASD *
offSetAlpha[mInd];
3561 double tempZod = clusterZod[nInd] + 0.375 * pow10_uLgZSD *
offSetAlpha[mInd];
3562 std::tie(rayAodRadian[nInd][mInd], rayZodRadian[nInd][mInd]) =
3567 for (uint8_t cIndex = 0; cIndex < channelParams->m_reducedClusterNumber; cIndex++)
3569 Shuffle(&rayAodRadian[cIndex][0], &rayAodRadian[cIndex][table3gpp->m_raysPerCluster]);
3570 Shuffle(&rayAoaRadian[cIndex][0], &rayAoaRadian[cIndex][table3gpp->m_raysPerCluster]);
3571 Shuffle(&rayZodRadian[cIndex][0], &rayZodRadian[cIndex][table3gpp->m_raysPerCluster]);
3572 Shuffle(&rayZoaRadian[cIndex][0], &rayZoaRadian[cIndex][table3gpp->m_raysPerCluster]);
3576 channelParams->m_rayAodRadian = rayAodRadian;
3577 channelParams->m_rayAoaRadian = rayAoaRadian;
3578 channelParams->m_rayZodRadian = rayZodRadian;
3579 channelParams->m_rayZoaRadian = rayZoaRadian;
3585 auto& crossPolarizationPowerRatios = channelParams->m_crossPolarizationPowerRatios;
3587 auto& clusterPhase = channelParams->m_clusterPhase;
3589 const double uXprLinear = pow(10, table3gpp->m_uXpr / 10.0);
3590 const double sigXprLinear = pow(10, table3gpp->m_sigXpr / 10.0);
3593 clusterPhase.resize(channelParams->m_reducedClusterNumber);
3594 crossPolarizationPowerRatios.resize(channelParams->m_reducedClusterNumber);
3595 for (uint8_t nInd = 0; nInd < channelParams->m_reducedClusterNumber; nInd++)
3597 clusterPhase[nInd].resize(table3gpp->m_raysPerCluster);
3598 crossPolarizationPowerRatios[nInd].resize(table3gpp->m_raysPerCluster);
3599 for (uint8_t mInd = 0; mInd < table3gpp->m_raysPerCluster; mInd++)
3601 clusterPhase[nInd][mInd].resize(4);
3603 crossPolarizationPowerRatios[nInd][mInd] =
3604 std::pow(10, (
m_normalRv->GetValue() * sigXprLinear + uXprLinear) / 10.0);
3605 for (uint8_t pInd = 0; pInd < 4; pInd++)
3613 uint8_t cluster1st = 0;
3614 uint8_t cluster2nd = 0;
3615 double maxPower = 0;
3616 for (uint8_t cIndex = 0; cIndex < channelParams->m_reducedClusterNumber; cIndex++)
3618 if (maxPower < channelParams->m_clusterPower[cIndex])
3620 maxPower = channelParams->m_clusterPower[cIndex];
3621 cluster1st = cIndex;
3624 channelParams->m_cluster1st = cluster1st;
3626 for (uint8_t cIndex = 0; cIndex < channelParams->m_reducedClusterNumber; cIndex++)
3628 if (maxPower < channelParams->m_clusterPower[cIndex] && cluster1st != cIndex)
3630 maxPower = channelParams->m_clusterPower[cIndex];
3631 cluster2nd = cIndex;
3634 channelParams->m_cluster2nd = cluster2nd;
3636 NS_LOG_INFO(
"1st strongest cluster:" << +cluster1st
3637 <<
", 2nd strongest cluster:" << +cluster2nd);
3640 if (cluster1st == cluster2nd)
3642 clusterDelay.push_back(clusterDelay[cluster1st] + 1.28 * table3gpp->m_cDS);
3643 clusterDelay.push_back(clusterDelay[cluster1st] + 2.56 * table3gpp->m_cDS);
3645 clusterAoa.push_back(clusterAoa[cluster1st]);
3646 clusterAoa.push_back(clusterAoa[cluster1st]);
3648 clusterZoa.push_back(clusterZoa[cluster1st]);
3649 clusterZoa.push_back(clusterZoa[cluster1st]);
3651 clusterAod.push_back(clusterAod[cluster1st]);
3652 clusterAod.push_back(clusterAod[cluster1st]);
3654 clusterZod.push_back(clusterZod[cluster1st]);
3655 clusterZod.push_back(clusterZod[cluster1st]);
3661 if (cluster1st < cluster2nd)
3671 clusterDelay.push_back(clusterDelay[min] + 1.28 * table3gpp->m_cDS);
3672 clusterDelay.push_back(clusterDelay[min] + 2.56 * table3gpp->m_cDS);
3673 clusterDelay.push_back(clusterDelay[max] + 1.28 * table3gpp->m_cDS);
3674 clusterDelay.push_back(clusterDelay[max] + 2.56 * table3gpp->m_cDS);
3676 clusterAoa.push_back(clusterAoa[min]);
3677 clusterAoa.push_back(clusterAoa[min]);
3678 clusterAoa.push_back(clusterAoa[max]);
3679 clusterAoa.push_back(clusterAoa[max]);
3681 clusterZoa.push_back(clusterZoa[min]);
3682 clusterZoa.push_back(clusterZoa[min]);
3683 clusterZoa.push_back(clusterZoa[max]);
3684 clusterZoa.push_back(clusterZoa[max]);
3686 clusterAod.push_back(clusterAod[min]);
3687 clusterAod.push_back(clusterAod[min]);
3688 clusterAod.push_back(clusterAod[max]);
3689 clusterAod.push_back(clusterAod[max]);
3691 clusterZod.push_back(clusterZod[min]);
3692 clusterZod.push_back(clusterZod[min]);
3693 clusterZod.push_back(clusterZod[max]);
3694 clusterZod.push_back(clusterZod[max]);
3697 channelParams->m_delay = clusterDelay;
3698 channelParams->m_angle.clear();
3699 channelParams->m_angle.push_back(clusterAoa);
3700 channelParams->m_angle.push_back(clusterZoa);
3701 channelParams->m_angle.push_back(clusterAod);
3702 channelParams->m_angle.push_back(clusterZod);
3705 channelParams->m_cachedAngleSincos.resize(channelParams->m_angle.size());
3706 for (
size_t direction = 0; direction < channelParams->m_angle.size(); direction++)
3708 channelParams->m_cachedAngleSincos[direction].resize(
3709 channelParams->m_angle[direction].size());
3710 for (
size_t cluster = 0; cluster < channelParams->m_angle[direction].size(); cluster++)
3712 channelParams->m_cachedAngleSincos[direction][cluster] = {
3713 sin(channelParams->m_angle[direction][cluster] *
DEG2RAD),
3714 cos(channelParams->m_angle[direction][cluster] *
DEG2RAD)};
3734 uint8_t updatedClusterNumber = (channelParams->m_reducedClusterNumber == 1)
3735 ? channelParams->m_reducedClusterNumber + 2
3736 : channelParams->m_reducedClusterNumber + 4;
3738 for (uint8_t cIndex = 0; cIndex < updatedClusterNumber; cIndex++)
3747 dopplerTermAlpha.push_back(alpha);
3748 dopplerTermD.push_back(D);
3750 channelParams->m_alpha = dopplerTermAlpha;
3751 channelParams->m_D = dopplerTermD;
3753 return channelParams;
3772 channelMatrix->m_nodeIds =
3775 bool isSameDirection = (channelParams->m_nodeIds == channelMatrix->m_nodeIds);
3786 if (isSameDirection)
3788 rayAodRadian = channelParams->m_rayAodRadian;
3789 rayAoaRadian = channelParams->m_rayAoaRadian;
3790 rayZodRadian = channelParams->m_rayZodRadian;
3791 rayZoaRadian = channelParams->m_rayZoaRadian;
3795 rayAodRadian = channelParams->m_rayAoaRadian;
3796 rayAoaRadian = channelParams->m_rayAodRadian;
3797 rayZodRadian = channelParams->m_rayZoaRadian;
3798 rayZoaRadian = channelParams->m_rayZodRadian;
3804 size_t uSize = uAntenna->GetNumElems();
3805 size_t sSize = sAntenna->GetNumElems();
3811 uint16_t numOverallCluster = (channelParams->m_cluster1st != channelParams->m_cluster2nd)
3812 ? channelParams->m_reducedClusterNumber + 4
3813 : channelParams->m_reducedClusterNumber + 2;
3815 NS_ASSERT(channelParams->m_reducedClusterNumber <= channelParams->m_clusterPhase.size());
3816 NS_ASSERT(channelParams->m_reducedClusterNumber <= channelParams->m_clusterPower.size());
3817 NS_ASSERT(channelParams->m_reducedClusterNumber <=
3818 channelParams->m_crossPolarizationPowerRatios.size());
3819 NS_ASSERT(channelParams->m_reducedClusterNumber <= rayZoaRadian.size());
3820 NS_ASSERT(channelParams->m_reducedClusterNumber <= rayZodRadian.size());
3821 NS_ASSERT(channelParams->m_reducedClusterNumber <= rayAoaRadian.size());
3822 NS_ASSERT(channelParams->m_reducedClusterNumber <= rayAodRadian.size());
3823 NS_ASSERT(table3gpp->m_raysPerCluster <= channelParams->m_clusterPhase[0].size());
3824 NS_ASSERT(table3gpp->m_raysPerCluster <=
3825 channelParams->m_crossPolarizationPowerRatios[0].size());
3826 NS_ASSERT(table3gpp->m_raysPerCluster <= rayZoaRadian[0].size());
3827 NS_ASSERT(table3gpp->m_raysPerCluster <= rayZodRadian[0].size());
3828 NS_ASSERT(table3gpp->m_raysPerCluster <= rayAoaRadian[0].size());
3829 NS_ASSERT(table3gpp->m_raysPerCluster <= rayAodRadian[0].size());
3831 double x = sMob->GetPosition().x - uMob->GetPosition().x;
3832 double y = sMob->GetPosition().y - uMob->GetPosition().y;
3833 double distance2D = sqrt(x * x + y * y);
3836 double hUt = std::min(sMob->GetPosition().z, uMob->GetPosition().z);
3837 double hBs = std::max(sMob->GetPosition().z, uMob->GetPosition().z);
3839 double distance3D = std::sqrt(distance2D * distance2D + (hBs - hUt) * (hBs - hUt));
3841 Angles sAngle(uMob->GetPosition(), sMob->GetPosition());
3842 Angles uAngle(sMob->GetPosition(), uMob->GetPosition());
3854 for (
size_t polSa = 0; polSa < sAntenna->GetNumPols(); ++polSa)
3856 for (
size_t polUa = 0; polUa < uAntenna->GetNumPols(); ++polUa)
3858 raysPreComp[std::make_pair(polSa, polUa)] =
3859 Complex2DVector(channelParams->m_reducedClusterNumber, table3gpp->m_raysPerCluster);
3864 sinCosA.resize(channelParams->m_reducedClusterNumber);
3865 sinSinA.resize(channelParams->m_reducedClusterNumber);
3866 cosZoA.resize(channelParams->m_reducedClusterNumber);
3867 sinCosD.resize(channelParams->m_reducedClusterNumber);
3868 sinSinD.resize(channelParams->m_reducedClusterNumber);
3869 cosZoD.resize(channelParams->m_reducedClusterNumber);
3870 for (uint8_t nIndex = 0; nIndex < channelParams->m_reducedClusterNumber; nIndex++)
3872 sinCosA[nIndex].resize(table3gpp->m_raysPerCluster);
3873 sinSinA[nIndex].resize(table3gpp->m_raysPerCluster);
3874 cosZoA[nIndex].resize(table3gpp->m_raysPerCluster);
3875 sinCosD[nIndex].resize(table3gpp->m_raysPerCluster);
3876 sinSinD[nIndex].resize(table3gpp->m_raysPerCluster);
3877 cosZoD[nIndex].resize(table3gpp->m_raysPerCluster);
3880 for (uint8_t nIndex = 0; nIndex < channelParams->m_reducedClusterNumber; nIndex++)
3882 for (uint8_t mIndex = 0; mIndex < table3gpp->m_raysPerCluster; mIndex++)
3884 DoubleVector initialPhase = channelParams->m_clusterPhase[nIndex][mIndex];
3886 double k = channelParams->m_crossPolarizationPowerRatios[nIndex][mIndex];
3890 for (uint8_t polUa = 0; polUa < uAntenna->GetNumPols(); ++polUa)
3892 auto [rxFieldPatternPhi, rxFieldPatternTheta] = uAntenna->GetElementFieldPattern(
3893 Angles(channelParams->m_rayAoaRadian[nIndex][mIndex],
3894 channelParams->m_rayZoaRadian[nIndex][mIndex]),
3896 for (uint8_t polSa = 0; polSa < sAntenna->GetNumPols(); ++polSa)
3898 auto [txFieldPatternPhi, txFieldPatternTheta] =
3899 sAntenna->GetElementFieldPattern(
3900 Angles(channelParams->m_rayAodRadian[nIndex][mIndex],
3901 channelParams->m_rayZodRadian[nIndex][mIndex]),
3903 raysPreComp[std::make_pair(polSa, polUa)](nIndex, mIndex) =
3904 std::complex<double>(cos(initialPhase[0]), sin(initialPhase[0])) *
3905 rxFieldPatternTheta * txFieldPatternTheta +
3906 std::complex<double>(cos(initialPhase[1]), sin(initialPhase[1])) *
3907 std::sqrt(1.0 / k) * rxFieldPatternTheta * txFieldPatternPhi +
3908 std::complex<double>(cos(initialPhase[2]), sin(initialPhase[2])) *
3909 std::sqrt(1.0 / k) * rxFieldPatternPhi * txFieldPatternTheta +
3910 std::complex<double>(cos(initialPhase[3]), sin(initialPhase[3])) *
3911 rxFieldPatternPhi * txFieldPatternPhi;
3917 double sinRayZoa = sin(rayZoaRadian[nIndex][mIndex]);
3918 double sinRayAoa = sin(rayAoaRadian[nIndex][mIndex]);
3919 double cosRayAoa = cos(rayAoaRadian[nIndex][mIndex]);
3920 sinCosA[nIndex][mIndex] = sinRayZoa * cosRayAoa;
3921 sinSinA[nIndex][mIndex] = sinRayZoa * sinRayAoa;
3922 cosZoA[nIndex][mIndex] = cos(rayZoaRadian[nIndex][mIndex]);
3926 double sinRayZod = sin(rayZodRadian[nIndex][mIndex]);
3927 double sinRayAod = sin(rayAodRadian[nIndex][mIndex]);
3928 double cosRayAod = cos(rayAodRadian[nIndex][mIndex]);
3929 sinCosD[nIndex][mIndex] = sinRayZod * cosRayAod;
3930 sinSinD[nIndex][mIndex] = sinRayZod * sinRayAod;
3931 cosZoD[nIndex][mIndex] = cos(rayZodRadian[nIndex][mIndex]);
3937 uint8_t numSubClustersAdded = 0;
3938 for (uint8_t nIndex = 0; nIndex < channelParams->m_reducedClusterNumber; nIndex++)
3940 for (
size_t uIndex = 0; uIndex < uSize; uIndex++)
3942 Vector uLoc = uAntenna->GetElementLocation(uIndex);
3944 for (
size_t sIndex = 0; sIndex < sSize; sIndex++)
3946 Vector sLoc = sAntenna->GetElementLocation(sIndex);
3949 if (nIndex != channelParams->m_cluster1st && nIndex != channelParams->m_cluster2nd)
3951 std::complex<double> rays(0, 0);
3952 for (uint8_t mIndex = 0; mIndex < table3gpp->m_raysPerCluster; mIndex++)
3955 double rxPhaseDiff =
3957 (sinCosA[nIndex][mIndex] * uLoc.x + sinSinA[nIndex][mIndex] * uLoc.y +
3958 cosZoA[nIndex][mIndex] * uLoc.z);
3960 double txPhaseDiff =
3962 (sinCosD[nIndex][mIndex] * sLoc.x + sinSinD[nIndex][mIndex] * sLoc.y +
3963 cosZoD[nIndex][mIndex] * sLoc.z);
3966 rays += raysPreComp[std::make_pair(sAntenna->GetElemPol(sIndex),
3967 uAntenna->GetElemPol(uIndex))](nIndex,
3969 std::complex<double>(cos(rxPhaseDiff), sin(rxPhaseDiff)) *
3970 std::complex<double>(cos(txPhaseDiff), sin(txPhaseDiff));
3973 sqrt(channelParams->m_clusterPower[nIndex] / table3gpp->m_raysPerCluster);
3974 hUsn(uIndex, sIndex, nIndex) = rays;
3978 std::complex<double> raysSub1(0, 0);
3979 std::complex<double> raysSub2(0, 0);
3980 std::complex<double> raysSub3(0, 0);
3982 for (uint8_t mIndex = 0; mIndex < table3gpp->m_raysPerCluster; mIndex++)
3986 double rxPhaseDiff =
3988 (sinCosA[nIndex][mIndex] * uLoc.x + sinSinA[nIndex][mIndex] * uLoc.y +
3989 cosZoA[nIndex][mIndex] * uLoc.z);
3991 double txPhaseDiff =
3993 (sinCosD[nIndex][mIndex] * sLoc.x + sinSinD[nIndex][mIndex] * sLoc.y +
3994 cosZoD[nIndex][mIndex] * sLoc.z);
3996 std::complex<double> raySub =
3997 raysPreComp[std::make_pair(sAntenna->GetElemPol(sIndex),
3998 uAntenna->GetElemPol(uIndex))](nIndex,
4000 std::complex<double>(cos(rxPhaseDiff), sin(rxPhaseDiff)) *
4001 std::complex<double>(cos(txPhaseDiff), sin(txPhaseDiff));
4025 sqrt(channelParams->m_clusterPower[nIndex] / table3gpp->m_raysPerCluster);
4027 sqrt(channelParams->m_clusterPower[nIndex] / table3gpp->m_raysPerCluster);
4029 sqrt(channelParams->m_clusterPower[nIndex] / table3gpp->m_raysPerCluster);
4030 hUsn(uIndex, sIndex, nIndex) = raysSub1;
4033 channelParams->m_reducedClusterNumber + numSubClustersAdded) = raysSub2;
4036 channelParams->m_reducedClusterNumber + numSubClustersAdded + 1) =
4041 if (nIndex == channelParams->m_cluster1st || nIndex == channelParams->m_cluster2nd)
4043 numSubClustersAdded += 2;
4050 std::complex<double> phaseDiffDueToDistance(cos(-2 * M_PI * distance3D / lambda),
4051 sin(-2 * M_PI * distance3D / lambda));
4055 const double sinUAngleAz = sin(uAngle.
GetAzimuth());
4056 const double cosUAngleAz = cos(uAngle.
GetAzimuth());
4059 const double sinSAngleAz = sin(sAngle.
GetAzimuth());
4060 const double cosSAngleAz = cos(sAngle.
GetAzimuth());
4062 for (
size_t uIndex = 0; uIndex < uSize; uIndex++)
4064 Vector uLoc = uAntenna->GetElementLocation(uIndex);
4065 double rxPhaseDiff = 2 * M_PI *
4066 (sinUAngleIncl * cosUAngleAz * uLoc.x +
4067 sinUAngleIncl * sinUAngleAz * uLoc.y + cosUAngleIncl * uLoc.z);
4069 for (
size_t sIndex = 0; sIndex < sSize; sIndex++)
4071 Vector sLoc = sAntenna->GetElementLocation(sIndex);
4072 std::complex<double> ray(0, 0);
4073 double txPhaseDiff =
4075 (sinSAngleIncl * cosSAngleAz * sLoc.x + sinSAngleIncl * sinSAngleAz * sLoc.y +
4076 cosSAngleIncl * sLoc.z);
4078 auto [rxFieldPatternPhi, rxFieldPatternTheta] = uAntenna->GetElementFieldPattern(
4080 uAntenna->GetElemPol(uIndex));
4081 auto [txFieldPatternPhi, txFieldPatternTheta] = sAntenna->GetElementFieldPattern(
4083 sAntenna->GetElemPol(sIndex));
4085 ray = (rxFieldPatternTheta * txFieldPatternTheta -
4086 rxFieldPatternPhi * txFieldPatternPhi) *
4087 phaseDiffDueToDistance *
4088 std::complex<double>(cos(rxPhaseDiff), sin(rxPhaseDiff)) *
4089 std::complex<double>(cos(txPhaseDiff), sin(txPhaseDiff));
4091 double kLinear = pow(10, channelParams->m_K_factor / 10.0);
4093 hUsn(uIndex, sIndex, 0) =
4094 sqrt(1.0 / (kLinear + 1)) * hUsn(uIndex, sIndex, 0) +
4095 sqrt(kLinear / (1 + kLinear)) * ray /
4097 channelParams->m_attenuation_dB[0] / 10.0);
4098 for (
size_t nIndex = 1; nIndex < hUsn.GetNumPages(); nIndex++)
4100 hUsn(uIndex, sIndex, nIndex) *=
4101 sqrt(1.0 / (kLinear + 1));
4107 NS_LOG_DEBUG(
"Husn (sAntenna, uAntenna):" << sAntenna->GetId() <<
", " << uAntenna->GetId());
4108 for (
size_t cIndex = 0; cIndex < hUsn.GetNumPages(); cIndex++)
4110 for (
size_t rowIdx = 0; rowIdx < hUsn.GetNumRows(); rowIdx++)
4112 for (
size_t colIdx = 0; colIdx < hUsn.GetNumCols(); colIdx++)
4114 NS_LOG_DEBUG(
" " << hUsn(rowIdx, colIdx, cIndex) <<
",");
4119 NS_LOG_INFO(
"size of coefficient matrix (rows, columns, clusters) = ("
4120 << hUsn.GetNumRows() <<
", " << hUsn.GetNumCols() <<
", " << hUsn.GetNumPages()
4122 channelMatrix->m_channel = hUsn;
4123 return channelMatrix;
4126std::pair<double, double>
4129 inclinationRad =
WrapTo2Pi(inclinationRad);
4130 if (inclinationRad > M_PI)
4133 inclinationRad -= M_PI;
4139 NS_ASSERT_MSG(0 <= inclinationRad && inclinationRad <= M_PI,
4140 "inclinationRad=" << inclinationRad <<
" not valid, should be in [0, pi]");
4142 "azimuthRad=" << azimuthRad <<
" not valid, should be in [0, 2*pi]");
4144 return std::make_pair(azimuthRad, inclinationRad);
4155 auto clusterNum = clusterAOA.size();
4168 double thetaSb = 110;
4179 if (channelParams->m_nonSelfBlocking.empty())
4190 table.push_back(90);
4197 table.push_back(90);
4199 table.push_back(10);
4201 channelParams->m_nonSelfBlocking.push_back(table);
4206 double deltaX = sqrt(pow(channelParams->m_preLocUT.x - channelParams->m_locUT.x, 2) +
4207 pow(channelParams->m_preLocUT.y - channelParams->m_locUT.y, 2));
4234 R = exp(-1 * (deltaX / corrDis +
4235 (
Now().GetSeconds() - channelParams->m_generatedTime.GetSeconds()) /
4240 R = exp(-1 * (deltaX / corrDis));
4245 <<
Now().GetSeconds() - channelParams->m_generatedTime.GetSeconds()
4246 <<
" correlation:" << R);
4256 if (R * R * (-0.069) + R * 1.074 - 0.002 <
4259 R = R * R * (-0.069) + R * 1.074 - 0.002;
4264 channelParams->m_nonSelfBlocking[blockInd][
PHI_INDEX] =
4265 R * channelParams->m_nonSelfBlocking[blockInd][
PHI_INDEX] +
4272 for (std::size_t cInd = 0; cInd < clusterNum; cInd++)
4274 NS_ASSERT_MSG(clusterAOA[cInd] >= 0 && clusterAOA[cInd] <= 360,
4275 "the AOA should be the range of [0,360]");
4276 NS_ASSERT_MSG(clusterZOA[cInd] >= 0 && clusterZOA[cInd] <= 180,
4277 "the ZOA should be the range of [0,180]");
4280 NS_LOG_INFO(
"AOA=" << clusterAOA[cInd] <<
" Block Region[" << phiSb - xSb / 2.0 <<
","
4281 << phiSb + xSb / 2.0 <<
"]");
4282 NS_LOG_INFO(
"ZOA=" << clusterZOA[cInd] <<
" Block Region[" << thetaSb - ySb / 2.0 <<
","
4283 << thetaSb + ySb / 2.0 <<
"]");
4284 if (std::abs(clusterAOA[cInd] - phiSb) < (xSb / 2.0) &&
4285 std::abs(clusterZOA[cInd] - thetaSb) < (ySb / 2.0))
4287 powerAttenuation[cInd] += 30;
4289 <<
"] is blocked by self blocking region and reduce 30 dB power,"
4290 "the attenuation is ["
4291 << powerAttenuation[cInd] <<
" dB]");
4299 (0.5 * erfc(-1 * channelParams->m_nonSelfBlocking[blockInd][
PHI_INDEX] / sqrt(2))) *
4311 double xK = channelParams->m_nonSelfBlocking[blockInd][
X_INDEX];
4312 double thetaK = channelParams->m_nonSelfBlocking[blockInd][
THETA_INDEX];
4313 double yK = channelParams->m_nonSelfBlocking[blockInd][
Y_INDEX];
4315 NS_LOG_INFO(
"AOA=" << clusterAOA[cInd] <<
" Block Region[" << phiK - xK <<
","
4316 << phiK + xK <<
"]");
4317 NS_LOG_INFO(
"ZOA=" << clusterZOA[cInd] <<
" Block Region[" << thetaK - yK <<
","
4318 << thetaK + yK <<
"]");
4320 if (std::abs(clusterAOA[cInd] - phiK) < (xK) &&
4321 std::abs(clusterZOA[cInd] - thetaK) < (yK))
4323 double A1 = clusterAOA[cInd] - (phiK + xK / 2.0);
4324 double A2 = clusterAOA[cInd] - (phiK - xK / 2.0);
4325 double Z1 = clusterZOA[cInd] - (thetaK + yK / 2.0);
4326 double Z2 = clusterZOA[cInd] - (thetaK - yK / 2.0);
4333 if (xK / 2.0 < clusterAOA[cInd] - phiK && clusterAOA[cInd] - phiK <= xK)
4341 if (-1 * xK < clusterAOA[cInd] - phiK && clusterAOA[cInd] - phiK <= -1 * xK / 2.0)
4350 if (yK / 2.0 < clusterZOA[cInd] - thetaK && clusterZOA[cInd] - thetaK <= yK)
4358 if (-1 * yK < clusterZOA[cInd] - thetaK &&
4359 clusterZOA[cInd] - thetaK <= -1 * yK / 2.0)
4369 atan(signA1 * M_PI / 2.0 *
4370 sqrt(M_PI / lambda * channelParams->m_nonSelfBlocking[blockInd][
R_INDEX] *
4374 atan(signA2 * M_PI / 2.0 *
4375 sqrt(M_PI / lambda * channelParams->m_nonSelfBlocking[blockInd][
R_INDEX] *
4379 atan(signZ1 * M_PI / 2.0 *
4380 sqrt(M_PI / lambda * channelParams->m_nonSelfBlocking[blockInd][
R_INDEX] *
4384 atan(signZ2 * M_PI / 2.0 *
4385 sqrt(M_PI / lambda * channelParams->m_nonSelfBlocking[blockInd][
R_INDEX] *
4388 double lDb = -20 * log10(1 - (fA1 + fA2) * (fZ1 + fZ2));
4389 powerAttenuation[cInd] += lDb;
4390 NS_LOG_INFO(
"Cluster[" << +cInd <<
"] is blocked by no-self blocking, the loss is ["
4395 return powerAttenuation;
4401 for (
auto i = (last -
first) - 1; i > 0; --i)
Class holding the azimuth and inclination angles of spherical coordinates.
double GetInclination() const
Getter for inclination angle.
double GetAzimuth() const
Getter for azimuth angle.
AttributeValue implementation for Boolean.
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Hold a signed integer type.
This is an interface for a channel model that can be described by a channel matrix,...
std::vector< double > DoubleVector
Type definition for vectors of doubles.
ComplexMatrixArray Complex2DVector
Create an alias for 2D complex vectors.
std::vector< DoubleVector > Double2DVector
Type definition for matrices of doubles.
static uint64_t GetKey(uint32_t a, uint32_t b)
Generate a unique value for the pair of unsigned integer of 32 bits, where the order does not matter,...
AttributeValue implementation for Pointer.
Smart pointer class similar to boost::intrusive_ptr.
void SetStream(int64_t stream)
Specifies the stream number for the RngStream.
static Time Now()
Return the current simulation virtual time.
Hold variables of type string.
DoubleVector CalcAttenuationOfBlockage(const Ptr< ThreeGppChannelModel::ThreeGppChannelParams > channelParams, const DoubleVector &clusterAOA, const DoubleVector &clusterZOA) const
Applies the blockage model A described in 3GPP TR 38.901.
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model.
bool AntennaSetupChanged(Ptr< const PhasedArrayModel > aAntenna, Ptr< const PhasedArrayModel > bAntenna, Ptr< const ChannelMatrix > channelMatrix)
Check if the channel matrix has to be updated due to changes in the number of antenna ports.
bool m_portraitMode
true if portrait mode, false if landscape
bool ChannelParamsNeedsUpdate(Ptr< const ThreeGppChannelParams > channelParams, Ptr< const ChannelCondition > channelCondition) const
Check if the channel params has to be updated.
Ptr< NormalRandomVariable > m_normalRv
normal random variable
static const uint8_t Y_INDEX
index of the Y value in the m_nonSelfBlocking array
bool m_blockage
enables the blockage model A
Ptr< const ChannelParams > GetParams(Ptr< const MobilityModel > aMob, Ptr< const MobilityModel > bMob) const override
Looks for the channel params associated to the aMob and bMob pair in m_channelParamsMap.
~ThreeGppChannelModel() override
Destructor.
bool ChannelMatrixNeedsUpdate(Ptr< const ThreeGppChannelParams > channelParams, Ptr< const ChannelMatrix > channelMatrix)
Check if the channel matrix has to be updated (it needs update when the channel params generation tim...
static const uint8_t THETA_INDEX
index of the THETA value in the m_nonSelfBlocking array
std::unordered_map< uint64_t, Ptr< ThreeGppChannelParams > > m_channelParamsMap
map containing the common channel parameters per pair of nodes, the key of this map is reciprocal and...
static std::pair< double, double > WrapAngles(double azimuthRad, double inclinationRad)
Wrap an (azimuth, inclination) angle pair in a valid range.
ThreeGppChannelModel()
Constructor.
double m_blockerSpeed
the blocker speed
Ptr< const ChannelMatrix > GetChannel(Ptr< const MobilityModel > aMob, Ptr< const MobilityModel > bMob, Ptr< const PhasedArrayModel > aAntenna, Ptr< const PhasedArrayModel > bAntenna) override
Looks for the channel matrix associated to the aMob and bMob pair in m_channelMatrixMap.
void SetFrequency(double f)
Sets the center frequency of the model.
std::unordered_map< uint64_t, Ptr< ChannelMatrix > > m_channelMatrixMap
map containing the channel realizations per pair of PhasedAntennaArray instances, the key of this map...
Ptr< UniformRandomVariable > m_uniformRv
uniform random variable
void DoDispose() override
Destructor implementation.
void SetScenario(const std::string &scenario)
Sets the propagation scenario.
void SetChannelConditionModel(Ptr< ChannelConditionModel > model)
Set the channel condition model.
Ptr< UniformRandomVariable > m_uniformRvDoppler
uniform random variable, used to compute the additional Doppler contribution
uint16_t m_numNonSelfBlocking
number of non-self-blocking regions
Ptr< const ParamsTable > GetThreeGppTable(Ptr< const ChannelCondition > channelCondition, double hBS, double hUT, double distance2D) const
Get the parameters needed to apply the channel generation procedure.
std::string GetScenario() const
Returns the propagation scenario.
virtual Ptr< ChannelMatrix > GetNewChannel(Ptr< const ThreeGppChannelParams > channelParams, Ptr< const ParamsTable > table3gpp, const Ptr< const MobilityModel > sMob, const Ptr< const MobilityModel > uMob, Ptr< const PhasedArrayModel > sAntenna, Ptr< const PhasedArrayModel > uAntenna) const
Compute the channel matrix between two nodes a and b, and their antenna arrays aAntenna and bAntenna ...
static const uint8_t PHI_INDEX
index of the PHI value in the m_nonSelfBlocking array
double m_frequency
the operating frequency
double m_vScatt
value used to compute the additional Doppler contribution for the delayed paths
Ptr< ChannelConditionModel > GetChannelConditionModel() const
Get the associated channel condition model.
Ptr< ChannelConditionModel > m_channelConditionModel
the channel condition model
std::string m_scenario
the 3GPP scenario
static const uint8_t R_INDEX
index of the R value in the m_nonSelfBlocking array
static TypeId GetTypeId()
Get the type ID.
void Shuffle(double *first, double *last) const
Shuffle the elements of a simple sequence container of type double.
Ptr< ThreeGppChannelParams > GenerateChannelParameters(const Ptr< const ChannelCondition > channelCondition, const Ptr< const ParamsTable > table3gpp, const Ptr< const MobilityModel > aMob, const Ptr< const MobilityModel > bMob) const
Prepare 3gpp channel parameters among the nodes a and b.
double GetFrequency() const
Returns the center frequency.
Time m_updatePeriod
the channel update period
static const uint8_t X_INDEX
index of the X value in the m_nonSelfBlocking array
Ptr< UniformRandomVariable > m_uniformRvShuffle
uniform random variable used to shuffle array in GetNewChannel
bool IsZero() const
Exactly equivalent to t == 0.
AttributeValue implementation for Time.
a unique identifier for an interface.
TypeId SetGroupName(std::string groupName)
Set the group name.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Ptr< const AttributeChecker > MakeBooleanChecker()
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Ptr< const AttributeAccessor > MakeIntegerAccessor(T1 a1)
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Ptr< const AttributeChecker > MakeStringChecker()
Ptr< const AttributeAccessor > MakeStringAccessor(T1 a1)
Ptr< const AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_LOG_UNCOND(msg)
Output the requested message unconditionally.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Time Now()
create an ns3::Time instance which contains the current simulation time.
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
static const std::map< std::string, std::map< int, std::vector< float > > > m_NTNRuralLOS
The nested map containing the threegpp value tables for the NTN Rural LOS scenario.
Table3gppParams
The enumerator used for code clarity when performing parameter assignment in GetThreeGppTable.
static constexpr double DEG2RAD
Conversion factor: degrees to radians.
static const double sqrtC_NTN_Suburban_NLOS[6][6]
The square root matrix for NTN Suburban NLOS, which is generated using the Cholesky decomposition acc...
static const double offSetAlpha[20]
The ray offset angles within a cluster, given for rms angle spread normalized to 1.
static const double sqrtC_RMa_O2I[6][6]
The square root matrix for RMa O2I, which is generated using the Cholesky decomposition according to ...
static const std::map< std::string, std::map< int, std::vector< float > > > m_NTNDenseUrbanLOS
The nested map containing the threegpp value tables for the NTN Dense Urban LOS scenario.
static const double sqrtC_UMi_LOS[7][7]
The square root matrix for UMi LOS, which is generated using the Cholesky decomposition according to ...
static const std::map< std::string, std::map< int, std::vector< float > > > m_NTNUrbanNLOS
The nested map containing the threegpp value tables for the NTN Urban NLOS scenario.
static const double sqrtC_office_LOS[7][7]
The square root matrix for Indoor-Office LOS, which is generated using the Cholesky decomposition acc...
static const double sqrtC_UMa_O2I[6][6]
The square root matrix for UMa O2I, which is generated using the Cholesky decomposition according to ...
static const std::map< std::string, std::map< int, std::vector< float > > > m_NTNRuralNLOS
The nested map containing the threegpp value tables for the NTN Rural NLOS scenario.
static const double sqrtC_NTN_DenseUrban_NLOS[6][6]
The square root matrix for NTN Dense Urban NLOS, which is generated using the Cholesky decomposition ...
static const double sqrtC_RMa_NLOS[6][6]
The square root matrix for RMa NLOS, which is generated using the Cholesky decomposition according to...
static const double sqrtC_UMa_LOS[7][7]
The square root matrix for UMa LOS, which is generated using the Cholesky decomposition according to ...
static const double sqrtC_UMi_NLOS[6][6]
The square root matrix for UMi NLOS, which is generated using the Cholesky decomposition according to...
static const std::map< std::string, std::map< int, std::vector< float > > > m_NTNDenseUrbanNLOS
The nested map containing the threegpp value tables for the NTN Dense Urban NLOS scenario.
static const double sqrtC_NTN_Rural_LOS[7][7]
The square root matrix for NTN Rural LOS, which is generated using the Cholesky decomposition accordi...
static const double sqrtC_NTN_Suburban_LOS[7][7]
The square root matrix for NTN Suburban LOS, which is generated using the Cholesky decomposition acco...
static const std::map< std::string, std::map< int, std::vector< float > > > m_NTNUrbanLOS
The nested map containing the threegpp value tables for the NTN Urban LOS scenario.
static const double sqrtC_RMa_LOS[7][7]
The square root matrix for RMa LOS, which is generated using the Cholesky decomposition according to ...
static const std::map< std::string, std::map< int, std::vector< float > > > m_NTNSuburbanNLOS
The nested map containing the threegpp value tables for the NTN Suburban NLOS scenario.
double DegreesToRadians(double degrees)
converts degrees to radians
static const double sqrtC_NTN_Urban_LOS[7][7]
The square root matrix for NTN Urban LOS, which is generated using the Cholesky decomposition accordi...
static const std::map< std::string, std::map< int, std::vector< float > > > m_NTNSuburbanLOS
The nested map containing the threegpp value tables for the NTN Suburban LOS scenario.
static const double sqrtC_UMi_O2I[6][6]
The square root matrix for UMi O2I, which is generated using the Cholesky decomposition according to ...
static const double sqrtC_office_NLOS[6][6]
The square root matrix for Indoor-Office NLOS, which is generated using the Cholesky decomposition ac...
static const std::map< int, std::vector< std::vector< double > > > sqrtC_NTN_Rural_NLOS_Ka
The square root matrix for NTN Rural NLOS Ka Band, which is generated using the Cholesky decompositio...
static const std::map< int, std::vector< std::vector< double > > > sqrtC_NTN_Rural_NLOS_S
The square root matrix for NTN Rural NLOS S Band, which is generated using the Cholesky decomposition...
static const double sqrtC_UMa_NLOS[6][6]
The square root matrix for UMa NLOS, which is generated using the Cholesky decomposition according to...
double WrapTo2Pi(double a)
Wrap angle in [0, 2*M_PI)
static const double sqrtC_NTN_DenseUrban_LOS[7][7]
The square root matrix for NTN Dense Urban LOS, which is generated using the Cholesky decomposition a...
static const std::map< int, std::vector< std::vector< double > > > sqrtC_NTN_Urban_NLOS
The square root matrix for NTN Urban NLOS, which is generated using the Cholesky decomposition accord...
double RadiansToDegrees(double radians)
converts radians to degrees