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},
679 {10, {-7.12, 0.8, -3.06, 0.48, 0.94, 0.7, 0.82, 0.03, -2.52, 0.5, 4.4,
680 3.3, 2.5, 24.4, 3.8, 3.0, 20.0, 3.9, 0.0, 11.0, 7.0, 3.0}},
681 {20, {-7.28, 0.67, -2.68, 0.36, 0.87, 0.66, 0.5, 0.09, -2.29, 0.53, 9.0,
682 6.6, 2.5, 23.6, 4.7, 3.0, 20.0, 3.9, 0.0, 11.0, 7.0, 3.0}},
683 {30, {-7.45, 0.68, -2.51, 0.38, 0.92, 0.68, 0.82, 0.05, -2.19, 0.58, 9.3,
684 6.1, 2.5, 23.2, 4.6, 3.0, 20.0, 3.9, 0.0, 11.0, 7.0, 3.0}},
685 {40, {-7.73, 0.66, -2.4, 0.32, 0.79, 0.64, 1.23, 0.03, -2.24, 0.51, 7.9,
686 4.0, 2.5, 22.6, 4.9, 3.0, 20.0, 3.9, 0.0, 11.0, 7.0, 3.0}},
687 {50, {-7.91, 0.62, -2.31, 0.33, 0.72, 0.63, 1.43, 0.06, -2.3, 0.46, 7.4,
688 3.0, 2.5, 21.8, 5.7, 3.0, 20.0, 3.9, 0.0, 11.0, 7.0, 3.0}},
689 {60, {-8.14, 0.51, -2.2, 0.39, 0.6, 0.54, 1.56, 0.05, -2.48, 0.35, 7.0,
690 2.6, 2.5, 20.5, 6.9, 3.0, 20.0, 3.9, 0.0, 11.0, 7.0, 3.0}},
691 {70, {-8.23, 0.45, -2.0, 0.4, 0.55, 0.52, 1.66, 0.05, -2.64, 0.31, 6.9,
692 2.2, 2.5, 19.3, 8.1, 3.0, 20.0, 3.9, 0.0, 11.0, 7.0, 3.0}},
693 {80, {-8.28, 0.31, -1.64, 0.32, 0.71, 0.53, 1.73, 0.02, -2.68, 0.39, 6.5,
694 2.1, 2.5, 17.4, 10.3, 3.0, 20.0, 3.9, 0.0, 11.0, 7.0, 3.0}},
695 {90, {-8.36, 0.08, -0.63, 0.53, 0.81, 0.62, 1.79, 0.01, -2.61, 0.28, 6.8,
696 1.9, 2.5, 12.3, 15.2, 3.0, 20.0, 3.9, 0.0, 11.0, 7.0, 3.0}},
700 {10, {-7.43, 0.9, -3.43, 0.54, 0.65, 0.82, 0.82, 0.05, -2.75, 0.55, 6.1,
701 2.6, 2.5, 24.7, 2.1, 3.0, 20.0, 1.6, 0.0, 11.0, 7.0, 3.0}},
702 {20, {-7.62, 0.78, -3.06, 0.41, 0.53, 0.78, 0.47, 0.11, -2.64, 0.64, 13.7,
703 6.8, 2.5, 24.4, 2.8, 3.0, 20.0, 1.6, 0.0, 11.0, 7.0, 3.0}},
704 {30, {-7.76, 0.8, -2.91, 0.42, 0.6, 0.83, 0.8, 0.05, -2.49, 0.69, 12.9,
705 6.0, 2.5, 24.4, 2.7, 3.0, 20.0, 1.6, 0.0, 11.0, 7.0, 3.0}},
706 {40, {-8.02, 0.72, -2.81, 0.34, 0.43, 0.78, 1.23, 0.04, -2.51, 0.57, 10.3,
707 3.3, 2.5, 24.2, 2.7, 3.0, 20.0, 1.6, 0.0, 11.0, 7.0, 3.0}},
708 {50, {-8.13, 0.61, -2.74, 0.34, 0.36, 0.77, 1.42, 0.1, -2.54, 0.5, 9.2,
709 2.2, 2.5, 23.9, 3.1, 3.0, 20.0, 1.6, 0.0, 11.0, 7.0, 3.0}},
710 {60, {-8.3, 0.47, -2.72, 0.7, 0.16, 0.84, 1.56, 0.06, -2.71, 0.37, 8.4,
711 1.9, 2.5, 23.3, 3.9, 3.0, 20.0, 1.6, 0.0, 11.0, 7.0, 3.0}},
712 {70, {-8.34, 0.39, -2.46, 0.4, 0.18, 0.64, 1.65, 0.07, -2.85, 0.31, 8.0,
713 1.5, 2.5, 22.6, 4.8, 3.0, 20.0, 1.6, 0.0, 11.0, 7.0, 3.0}},
714 {80, {-8.39, 0.26, -2.3, 0.78, 0.24, 0.81, 1.73, 0.02, -3.01, 0.45, 7.4,
715 1.6, 2.5, 21.2, 6.8, 3.0, 20.0, 1.6, 0.0, 11.0, 7.0, 3.0}},
716 {90, {-8.45, 0.01, -1.11, 0.51, 0.36, 0.65, 1.79, 0.01, -3.08, 0.27, 7.6,
717 1.3, 2.5, 17.6, 12.7, 3.0, 20.0, 1.6, 0.0, 11.0, 7.0, 3.0}},
730 {10, {-6.84, 0.82, -2.08, 0.87, 1.0, 1.6, 1.0, 0.63, -2.08, 0.58,
731 2.3, 23.8, 4.4, 4.0, 20.0, 3.9, 0.0, 15.0, 7.0, 3.0}},
732 {20, {-6.81, 0.61, -1.68, 0.73, 1.44, 0.87, 0.94, 0.65, -1.66, 0.5,
733 2.3, 21.9, 6.3, 4.0, 20.0, 3.9, 0.0, 15.0, 7.0, 3.0}},
734 {30, {-6.94, 0.49, -1.46, 0.53, 1.54, 0.64, 1.15, 0.42, -1.48, 0.4,
735 2.3, 19.7, 8.1, 4.0, 20.0, 3.9, 0.0, 15.0, 7.0, 3.0}},
736 {40, {-7.14, 0.49, -1.43, 0.5, 1.53, 0.56, 1.35, 0.28, -1.46, 0.37,
737 2.3, 18.1, 9.3, 4.0, 20.0, 3.9, 0.0, 15.0, 7.0, 3.0}},
738 {50, {-7.34, 0.51, -1.44, 0.58, 1.48, 0.54, 1.44, 0.25, -1.53, 0.47,
739 2.3, 16.3, 11.5, 4.0, 20.0, 3.9, 0.0, 15.0, 7.0, 3.0}},
740 {60, {-7.53, 0.47, -1.33, 0.49, 1.39, 0.68, 1.56, 0.16, -1.61, 0.43,
741 2.3, 14.0, 13.3, 4.0, 20.0, 3.9, 0.0, 15.0, 7.0, 3.0}},
742 {70, {-7.67, 0.44, -1.31, 0.65, 1.42, 0.55, 1.64, 0.18, -1.77, 0.5,
743 2.3, 12.1, 14.9, 4.0, 20.0, 3.9, 0.0, 15.0, 7.0, 3.0}},
744 {80, {-7.82, 0.42, -1.11, 0.69, 1.38, 0.6, 1.7, 0.09, -1.9, 0.42,
745 2.3, 8.7, 17.0, 4.0, 20.0, 3.9, 0.0, 15.0, 7.0, 3.0}},
746 {90, {-7.84, 0.55, -0.11, 0.53, 1.23, 0.6, 1.7, 0.17, -1.99, 0.5,
747 2.3, 6.4, 12.3, 4.0, 20.0, 3.9, 0.0, 15.0, 7.0, 3.0}},
751 {10, {-6.86, 0.81, -2.12, 0.94, 1.02, 1.44, 1.01, 0.56, -2.11, 0.59,
752 2.3, 23.7, 4.5, 4.0, 20.0, 3.9, 0.0, 15.0, 7.0, 3.0}},
753 {20, {-6.84, 0.61, -1.74, 0.79, 1.44, 0.77, 0.96, 0.55, -1.69, 0.51,
754 2.3, 21.8, 6.3, 4.0, 20.0, 3.9, 0.0, 15.0, 7.0, 3.0}},
755 {30, {-7.0, 0.56, -1.56, 0.66, 1.48, 0.7, 1.13, 0.43, -1.52, 0.46,
756 2.3, 19.6, 8.2, 4.0, 20.0, 3.9, 0.0, 15.0, 7.0, 3.0}},
757 {40, {-7.21, 0.56, -1.54, 0.63, 1.46, 0.6, 1.3, 0.37, -1.51, 0.43,
758 2.3, 18.0, 9.4, 4.0, 20.0, 3.9, 0.0, 15.0, 7.0, 3.0}},
759 {50, {-7.42, 0.57, -1.45, 0.56, 1.4, 0.59, 1.4, 0.32, -1.54, 0.45,
760 2.3, 16.3, 11.5, 4.0, 20.0, 3.9, 0.0, 15.0, 7.0, 3.0}},
761 {60, {-7.86, 0.55, -1.64, 0.78, 0.97, 1.27, 1.41, 0.45, -1.84, 0.63,
762 2.3, 15.9, 12.4, 4.0, 20.0, 3.9, 0.0, 15.0, 7.0, 3.0}},
763 {70, {-7.76, 0.47, -1.37, 0.56, 1.33, 0.56, 1.63, 0.17, -1.86, 0.51,
764 2.3, 12.3, 15.0, 4.0, 20.0, 3.9, 0.0, 15.0, 7.0, 3.0}},
765 {80, {-8.07, 0.42, -1.29, 0.76, 1.12, 1.04, 1.68, 0.14, -2.16, 0.74,
766 2.3, 10.5, 15.7, 4.0, 20.0, 3.9, 0.0, 15.0, 7.0, 3.0}},
767 {90, {-7.95, 0.59, -0.41, 0.59, 1.04, 0.63, 1.7, 0.17, -2.21, 0.61,
768 2.3, 10.5, 15.7, 4.0, 20.0, 3.9, 0.0, 15.0, 7.0, 3.0}},
778static const std::map<std::string, std::map<int, std::vector<float>>>
NTNUrbanLOS{
781 {10, {-7.97, 1.0, -2.6, 0.79, 0.18, 0.74, -0.63, 2.6, -2.54, 2.62, 31.83,
782 13.84, 2.5, 8.0, 4.0, 4.0, 20.0, 3.9, 0.09, 12.55, 1.25, 3.0}},
783 {20, {-8.12, 0.83, -2.48, 0.8, 0.42, 0.9, -0.15, 3.31, -2.67, 2.96, 18.78,
784 13.78, 2.5, 8.0, 4.0, 3.0, 20.0, 3.9, 0.09, 12.76, 3.23, 3.0}},
785 {30, {-8.21, 0.68, -2.44, 0.91, 0.41, 1.3, 0.54, 1.1, -2.03, 0.86, 10.49,
786 10.42, 2.5, 8.0, 4.0, 3.0, 20.0, 3.9, 0.12, 14.36, 4.39, 3.0}},
787 {40, {-8.31, 0.48, -2.6, 1.02, 0.18, 1.69, 0.35, 1.59, -2.28, 1.19, 7.46,
788 8.01, 2.5, 8.0, 4.0, 3.0, 20.0, 3.9, 0.16, 16.42, 5.72, 3.0}},
789 {50, {-8.37, 0.38, -2.71, 1.17, -0.07, 2.04, 0.27, 1.62, -2.48, 1.4, 6.52,
790 8.27, 2.5, 8.0, 4.0, 3.0, 20.0, 3.9, 0.2, 17.13, 6.17, 3.0}},
791 {60, {-8.39, 0.24, -2.76, 1.17, -0.43, 2.54, 0.26, 0.97, -2.56, 0.85, 5.47,
792 7.26, 2.5, 8.0, 4.0, 3.0, 20.0, 3.9, 0.28, 19.01, 7.36, 3.0}},
793 {70, {-8.38, 0.18, -2.78, 1.2, -0.64, 2.47, -0.12, 1.99, -2.96, 1.61, 4.54,
794 5.53, 2.5, 8.0, 4.0, 3.0, 20.0, 3.9, 0.44, 19.31, 7.3, 3.0}},
795 {80, {-8.35, 0.13, -2.65, 1.45, -0.91, 2.69, -0.21, 1.82, -3.08, 1.49, 4.03,
796 4.49, 2.5, 8.0, 4.0, 3.0, 20.0, 3.9, 0.9, 22.39, 7.7, 3.0}},
797 {90, {-8.34, 0.09, -2.27, 1.85, -0.54, 1.66, -0.07, 1.43, -3.0, 1.09, 3.68,
798 3.14, 2.5, 8.0, 4.0, 3.0, 20.0, 3.9, 2.87, 27.8, 9.25, 3.0}},
802 {10, {-8.52, 0.92, -3.18, 0.79, -0.4, 0.77, -0.67, 2.22, -2.61, 2.41, 40.18,
803 16.99, 2.5, 8.0, 4.0, 4.0, 20.0, 1.6, 0.09, 11.8, 1.14, 3.0}},
804 {20, {-8.59, 0.79, -3.05, 0.87, -0.15, 0.97, -0.34, 3.04, -2.82, 2.59, 23.62,
805 18.96, 2.5, 8.0, 4.0, 3.0, 20.0, 1.6, 0.09, 11.6, 2.78, 3.0}},
806 {30, {-8.51, 0.65, -2.98, 1.04, -0.18, 1.58, 0.07, 1.33, -2.48, 1.02, 12.48,
807 14.23, 2.5, 8.0, 4.0, 3.0, 20.0, 1.6, 0.11, 13.05, 3.87, 3.0}},
808 {40, {-8.49, 0.48, -3.11, 1.06, -0.31, 1.69, -0.08, 1.45, -2.76, 1.27, 8.56,
809 11.06, 2.5, 8.0, 4.0, 3.0, 20.0, 1.6, 0.15, 14.56, 4.94, 3.0}},
810 {50, {-8.48, 0.46, -3.19, 1.12, -0.58, 2.13, -0.21, 1.62, -2.93, 1.38, 7.42,
811 11.21, 2.5, 8.0, 4.0, 3.0, 20.0, 1.6, 0.18, 15.35, 5.41, 3.0}},
812 {60, {-8.44, 0.34, -3.25, 1.14, -0.9, 2.51, -0.25, 1.06, -3.05, 0.96, 5.97,
813 9.47, 2.5, 8.0, 4.0, 3.0, 20.0, 1.6, 0.27, 16.97, 6.31, 3.0}},
814 {70, {-8.4, 0.27, -3.33, 1.25, -1.16, 2.47, -0.61, 1.88, -3.45, 1.51, 4.88,
815 7.24, 2.5, 8.0, 4.0, 3.0, 20.0, 1.6, 0.42, 17.96, 6.66, 3.0}},
816 {80, {-8.37, 0.19, -3.22, 1.35, -1.48, 2.61, -0.79, 1.87, -3.66, 1.49, 4.22,
817 5.79, 2.5, 8.0, 4.0, 3.0, 20.0, 1.6, 0.86, 20.68, 7.31, 3.0}},
818 {90, {-8.35, 0.14, -2.83, 1.62, -1.14, 1.7, -0.58, 1.19, -3.56, 0.89, 3.81,
819 4.25, 2.5, 8.0, 4.0, 3.0, 20.0, 1.6, 2.55, 25.08, 9.23, 3.0}},
829static const std::map<std::string, std::map<int, std::vector<float>>>
NTNUrbanNLOS{
832 {10, {-7.24, 1.26, -1.58, 0.89, 0.13, 2.99, -1.13, 2.66, -2.87, 2.76, 0.0,
833 0.0, 2.3, 7.0, 3.0, 3.0, 20.0, 1.6, 0.08, 14.72, 1.57, 3.0}},
834 {20, {-7.7, 0.99, -1.67, 0.89, 0.19, 3.12, 0.49, 2.03, -2.68, 2.76, 0.0,
835 0.0, 2.3, 7.0, 3.0, 3.0, 20.0, 1.6, 0.1, 14.62, 4.3, 3.0}},
836 {30, {-7.82, 0.86, -1.84, 1.3, 0.44, 2.69, 0.95, 1.54, -2.12, 1.54, 0.0,
837 0.0, 2.3, 7.0, 3.0, 3.0, 20.0, 1.6, 0.14, 16.4, 6.64, 3.0}},
838 {40, {-8.04, 0.75, -2.02, 1.15, 0.48, 2.45, 1.15, 1.02, -2.27, 1.77, 0.0,
839 0.0, 2.3, 7.0, 3.0, 3.0, 20.0, 1.6, 0.22, 17.86, 9.21, 3.0}},
840 {50, {-8.08, 0.77, -2.06, 1.23, 0.56, 2.17, 1.14, 1.61, -2.5, 2.36, 0.0,
841 0.0, 2.3, 7.0, 3.0, 3.0, 20.0, 1.6, 0.31, 19.74, 10.32, 3.0}},
842 {60, {-8.1, 0.76, -1.99, 1.02, 0.55, 1.93, 1.13, 1.84, -2.47, 2.33, 0.0,
843 0.0, 2.3, 7.0, 3.0, 3.0, 20.0, 1.6, 0.49, 19.73, 10.3, 3.0}},
844 {70, {-8.16, 0.73, -2.19, 1.78, 0.48, 1.72, 1.16, 1.81, -2.83, 2.84, 0.0,
845 0.0, 2.3, 7.0, 3.0, 2.0, 20.0, 1.6, 0.97, 20.5, 10.2, 3.0}},
846 {80, {-8.03, 0.79, -1.88, 1.55, 0.53, 1.51, 1.28, 1.35, -2.82, 2.87, 0.0,
847 0.0, 2.3, 7.0, 3.0, 2.0, 20.0, 1.6, 1.52, 26.16, 12.27, 3.0}},
848 {90, {-8.33, 0.7, -2.0, 1.4, 0.32, 1.2, 1.42, 0.6, -4.55, 4.27, 0.0,
849 0.0, 2.3, 7.0, 3.0, 2.0, 20.0, 1.6, 5.36, 25.83, 12.75, 3.0}},
853 {10, {-7.24, 1.26, -1.58, 0.89, 0.13, 2.99, -1.13, 2.66, -2.87, 2.76, 0.0,
854 0.0, 2.3, 7.0, 3.0, 3.0, 20.0, 1.6, 0.08, 14.72, 1.57, 3.0}},
855 {20, {-7.7, 0.99, -1.67, 0.89, 0.19, 3.12, 0.49, 2.03, -2.68, 2.76, 0.0,
856 0.0, 2.3, 7.0, 3.0, 3.0, 20.0, 1.6, 0.1, 14.62, 4.3, 3.0}},
857 {30, {-7.82, 0.86, -1.84, 1.3, 0.44, 2.69, 0.95, 1.54, -2.12, 1.54, 0.0,
858 0.0, 2.3, 7.0, 3.0, 3.0, 20.0, 1.6, 0.14, 16.4, 6.64, 3.0}},
859 {40, {-8.04, 0.75, -2.02, 1.15, 0.48, 2.45, 1.15, 1.02, -2.27, 1.77, 0.0,
860 0.0, 2.3, 7.0, 3.0, 3.0, 20.0, 1.6, 0.22, 17.86, 9.21, 3.0}},
861 {50, {-8.08, 0.77, -2.06, 1.23, 0.56, 2.17, 1.14, 1.61, -2.5, 2.36, 0.0,
862 0.0, 2.3, 7.0, 3.0, 3.0, 20.0, 1.6, 0.31, 19.74, 10.32, 3.0}},
863 {60, {-8.1, 0.76, -1.99, 1.02, 0.55, 1.93, 1.13, 1.84, -2.47, 2.33, 0.0,
864 0.0, 2.3, 7.0, 3.0, 3.0, 20.0, 1.6, 0.49, 19.73, 10.3, 3.0}},
865 {70, {-8.16, 0.73, -2.19, 1.78, 0.48, 1.72, 1.16, 1.81, -2.83, 2.84, 0.0,
866 0.0, 2.3, 7.0, 3.0, 2.0, 20.0, 1.6, 0.97, 20.5, 10.2, 3.0}},
867 {80, {-8.03, 0.79, -1.88, 1.55, 0.53, 1.51, 1.28, 1.35, -2.82, 2.87, 0.0,
868 0.0, 2.3, 7.0, 3.0, 2.0, 20.0, 1.6, 1.52, 26.16, 12.27, 3.0}},
869 {90, {-8.33, 0.7, -2.0, 1.4, 0.32, 1.2, 1.42, 0.6, -4.55, 4.27, 0.0,
870 0.0, 2.3, 7.0, 3.0, 2.0, 20.0, 1.6, 5.36, 25.83, 12.75, 3.0}},
880static const std::map<std::string, std::map<int, std::vector<float>>>
NTNSuburbanLOS{
883 {10, {-8.16, 0.99, -3.57, 1.62, 0.05, 1.84, -1.78, 0.62, -1.06, 0.96, 11.4,
884 6.26, 2.2, 21.3, 7.6, 3.0, 20.0, 1.6, 0.0, 11.0, 7.0, 3.0}},
885 {20, {-8.56, 0.96, -3.8, 1.74, -0.38, 1.94, -1.84, 0.81, -1.21, 0.95, 19.45,
886 10.32, 3.36, 21.0, 8.9, 3.0, 20.0, 1.6, 0.0, 11.0, 7.0, 3.0}},
887 {30, {-8.72, 0.79, -3.77, 1.72, -0.56, 1.75, -1.67, 0.57, -1.28, 0.49, 20.8,
888 16.34, 3.5, 21.2, 8.5, 3.0, 20.0, 1.6, 0.0, 11.0, 7.0, 3.0}},
889 {40, {-8.71, 0.81, -3.57, 1.6, -0.59, 1.82, -1.59, 0.86, -1.32, 0.79, 21.2,
890 15.63, 2.81, 21.1, 8.4, 3.0, 20.0, 1.6, 0.0, 11.0, 7.0, 3.0}},
891 {50, {-8.72, 1.12, -3.42, 1.49, -0.58, 1.87, -1.55, 1.05, -1.39, 0.97, 21.6,
892 14.22, 2.39, 20.7, 9.2, 3.0, 20.0, 1.6, 0.0, 11.0, 7.0, 3.0}},
893 {60, {-8.66, 1.23, -3.27, 1.43, -0.55, 1.92, -1.51, 1.23, -1.36, 1.17, 19.75,
894 14.19, 2.73, 20.6, 9.8, 3.0, 20.0, 1.6, 0.0, 11.0, 7.0, 3.0}},
895 {70, {-8.38, 0.55, -3.08, 1.36, -0.28, 1.16, -1.27, 0.54, -1.08, 0.62, 12.0,
896 5.7, 2.07, 20.3, 10.8, 2.0, 20.0, 1.6, 0.0, 11.0, 7.0, 3.0}},
897 {80, {-8.34, 0.63, -2.75, 1.26, -0.17, 1.09, -1.28, 0.67, -1.31, 0.76, 12.85,
898 9.91, 2.04, 19.8, 12.2, 2.0, 20.0, 1.6, 0.0, 11.0, 7.0, 3.0}},
899 {90, {-8.34, 0.63, -2.75, 1.26, -0.17, 1.09, -1.28, 0.67, -1.31, 0.76, 12.85,
900 9.91, 2.04, 19.1, 13.0, 2.0, 20.0, 1.6, 0.0, 11.0, 7.0, 3.0}},
904 {10, {-8.07, 0.46, -3.55, 0.48, 0.89, 0.67, 0.63, 0.35, -3.37, 0.28, 8.9,
905 4.4, 2.5, 23.2, 5.0, 3.0, 20.0, 1.6, 0.0, 11.0, 7.0, 3.0}},
906 {20, {-8.61, 0.45, -3.69, 0.41, 0.31, 0.78, 0.76, 0.3, -3.28, 0.27, 14.0,
907 4.6, 2.5, 23.6, 4.5, 3.0, 20.0, 1.6, 0.0, 11.0, 7.0, 3.0}},
908 {30, {-8.72, 0.28, -3.59, 0.41, 0.02, 0.75, 1.11, 0.28, -3.04, 0.26, 11.3,
909 3.7, 2.5, 23.5, 4.7, 3.0, 20.0, 1.6, 0.0, 11.0, 7.0, 3.0}},
910 {40, {-8.63, 0.17, -3.38, 0.35, -0.1, 0.65, 1.37, 0.23, -2.88, 0.21, 9.0,
911 3.5, 2.5, 23.4, 5.2, 3.0, 20.0, 1.6, 0.0, 11.0, 7.0, 3.0}},
912 {50, {-8.54, 0.14, -3.23, 0.35, -0.19, 0.55, 1.53, 0.23, -2.83, 0.18, 7.5,
913 3.0, 2.5, 23.2, 5.7, 3.0, 20.0, 1.6, 0.0, 11.0, 7.0, 3.0}},
914 {60, {-8.48, 0.15, -3.19, 0.43, -0.54, 0.96, 1.65, 0.17, -2.86, 0.17, 6.6,
915 2.6, 2.5, 23.3, 5.9, 3.0, 20.0, 1.6, 0.0, 11.0, 7.0, 3.0}},
916 {70, {-8.42, 0.09, -2.83, 0.33, -0.24, 0.43, 1.74, 0.11, -2.95, 0.1, 5.9,
917 1.7, 2.5, 23.4, 6.2, 2.0, 20.0, 1.6, 0.0, 11.0, 7.0, 3.0}},
918 {80, {-8.39, 0.05, -2.66, 0.44, -0.52, 0.93, 1.82, 0.05, -3.21, 0.07, 5.5,
919 0.7, 2.5, 23.2, 7.0, 2.0, 20.0, 1.6, 0.0, 11.0, 7.0, 3.0}},
920 {90, {-8.37, 0.02, -1.22, 0.31, -0.15, 0.44, 1.87, 0.02, -3.49, 0.24, 5.4,
921 0.3, 2.5, 23.1, 7.6, 2.0, 20.0, 1.6, 0.0, 11.0, 7.0, 3.0}},
934 {10, {-7.43, 0.5, -2.89, 0.41, 1.49, 0.4, 0.81, 0.36, -3.09, 0.32, 0.0,
935 0.0, 2.3, 22.5, 5.0, 4.0, 20.0, 1.6, 0.0, 15.0, 7.0, 3.0}},
936 {20, {-7.63, 0.61, -2.76, 0.41, 1.24, 0.82, 1.06, 0.41, -2.93, 0.47, 0.0,
937 0.0, 2.3, 19.4, 8.5, 4.0, 20.0, 1.6, 0.0, 15.0, 7.0, 3.0}},
938 {30, {-7.86, 0.56, -2.64, 0.41, 1.06, 0.71, 1.12, 0.4, -2.91, 0.46, 0.0,
939 0.0, 2.3, 15.5, 10.0, 4.0, 20.0, 1.6, 0.0, 15.0, 7.0, 3.0}},
940 {40, {-7.96, 0.58, -2.41, 0.52, 0.91, 0.55, 1.14, 0.39, -2.78, 0.54, 0.0,
941 0.0, 2.3, 13.9, 10.6, 4.0, 20.0, 1.6, 0.0, 15.0, 7.0, 3.0}},
942 {50, {-7.98, 0.59, -2.42, 0.7, 0.98, 0.58, 1.29, 0.35, -2.7, 0.45, 0.0,
943 0.0, 2.3, 11.7, 10.0, 4.0, 20.0, 1.6, 0.0, 15.0, 7.0, 3.0}},
944 {60, {-8.45, 0.47, -2.53, 0.5, 0.49, 1.37, 1.38, 0.36, -3.03, 0.36, 0.0,
945 0.0, 2.3, 9.8, 9.1, 3.0, 20.0, 1.6, 0.0, 15.0, 7.0, 3.0}},
946 {70, {-8.21, 0.36, -2.35, 0.58, 0.73, 0.49, 1.36, 0.29, -2.9, 0.42, 0.0,
947 0.0, 2.3, 10.3, 9.1, 3.0, 20.0, 1.6, 0.0, 15.0, 7.0, 3.0}},
948 {80, {-8.69, 0.29, -2.31, 0.73, -0.04, 1.48, 1.38, 0.2, -3.2, 0.3, 0.0,
949 0.0, 2.3, 15.6, 9.1, 3.0, 20.0, 1.6, 0.0, 15.0, 7.0, 3.0}},
950 {90, {-8.69, 0.29, -2.31, 0.73, -0.04, 1.48, 1.38, 0.2, -3.2, 0.3, 0.0,
951 0.0, 2.3, 15.6, 9.1, 3.0, 20.0, 1.6, 0.0, 15.0, 7.0, 3.0}},
955 {10, {-7.43, 0.5, -2.89, 0.41, 1.49, 0.4, 0.81, 0.36, -3.09, 0.32, 0.0,
956 0.0, 2.3, 22.5, 5.0, 4.0, 20.0, 1.6, 0.0, 15.0, 7.0, 3.0}},
957 {20, {-7.63, 0.61, -2.76, 0.41, 1.24, 0.82, 1.06, 0.41, -2.93, 0.47, 0.0,
958 0.0, 2.3, 19.4, 8.5, 4.0, 20.0, 1.6, 0.0, 15.0, 7.0, 3.0}},
959 {30, {-7.86, 0.56, -2.64, 0.41, 1.06, 0.71, 1.12, 0.4, -2.91, 0.46, 0.0,
960 0.0, 2.3, 15.5, 10.0, 4.0, 20.0, 1.6, 0.0, 15.0, 7.0, 3.0}},
961 {40, {-7.96, 0.58, -2.41, 0.52, 0.91, 0.55, 1.14, 0.39, -2.78, 0.54, 0.0,
962 0.0, 2.3, 13.9, 10.6, 4.0, 20.0, 1.6, 0.0, 15.0, 7.0, 3.0}},
963 {50, {-7.98, 0.59, -2.42, 0.7, 0.98, 0.58, 1.29, 0.35, -2.7, 0.45, 0.0,
964 0.0, 2.3, 11.7, 10.0, 4.0, 20.0, 1.6, 0.0, 15.0, 7.0, 3.0}},
965 {60, {-8.45, 0.47, -2.53, 0.5, 0.49, 1.37, 1.38, 0.36, -3.03, 0.36, 0.0,
966 0.0, 2.3, 9.8, 9.1, 3.0, 20.0, 1.6, 0.0, 15.0, 7.0, 3.0}},
967 {70, {-8.21, 0.36, -2.35, 0.58, 0.73, 0.49, 1.36, 0.29, -2.9, 0.42, 0.0,
968 0.0, 2.3, 10.3, 9.1, 3.0, 20.0, 1.6, 0.0, 15.0, 7.0, 3.0}},
969 {80, {-8.69, 0.29, -2.31, 0.73, -0.04, 1.48, 1.38, 0.2, -3.2, 0.3, 0.0,
970 0.0, 2.3, 15.6, 9.1, 3.0, 20.0, 1.6, 0.0, 15.0, 7.0, 3.0}},
971 {90, {-8.69, 0.29, -2.31, 0.73, -0.04, 1.48, 1.38, 0.2, -3.2, 0.3, 0.0,
972 0.0, 2.3, 15.6, 9.1, 3.0, 20.0, 1.6, 0.0, 15.0, 7.0, 3.0}},
982static const std::map<std::string, std::map<int, std::vector<float>>>
NTNRuralLOS{
985 {10, {-9.55, 0.66, -3.42, 0.89, -9.45, 7.83, -4.2, 6.3, -6.03, 5.19, 24.72,
986 5.07, 3.8, 12.0, 4.0, 2.0, 20.0, 0.0, 0.39, 10.81, 1.94, 3.0}},
987 {20, {-8.68, 0.44, -3.0, 0.63, -4.45, 6.86, -2.31, 5.04, -4.31, 4.18, 12.31,
988 5.75, 3.8, 12.0, 4.0, 2.0, 20.0, 0.0, 0.31, 8.09, 1.83, 3.0}},
989 {30, {-8.46, 0.28, -2.86, 0.52, -2.39, 5.14, -0.28, 0.81, -2.57, 0.61, 8.05,
990 5.46, 3.8, 12.0, 4.0, 2.0, 20.0, 0.0, 0.29, 13.7, 2.28, 3.0}},
991 {40, {-8.36, 0.19, -2.78, 0.45, -1.28, 3.44, -0.38, 1.16, -2.59, 0.79, 6.21,
992 5.23, 3.8, 12.0, 4.0, 2.0, 20.0, 0.0, 0.37, 20.05, 2.93, 3.0}},
993 {50, {-8.29, 0.14, -2.7, 0.42, -0.99, 2.59, -0.38, 0.82, -2.59, 0.65, 5.04,
994 3.95, 3.8, 12.0, 4.0, 2.0, 20.0, 0.0, 0.61, 24.51, 2.84, 3.0}},
995 {60, {-8.26, 0.1, -2.66, 0.41, -1.05, 2.42, -0.46, 0.67, -2.65, 0.52, 4.42,
996 3.75, 3.8, 12.0, 4.0, 2.0, 20.0, 0.0, 0.9, 26.35, 3.17, 3.0}},
997 {70, {-8.22, 0.1, -2.53, 0.42, -0.9, 1.78, -0.49, 1.0, -2.69, 0.78, 3.92,
998 2.56, 3.8, 12.0, 4.0, 2.0, 20.0, 0.0, 1.43, 31.84, 3.88, 3.0}},
999 {80, {-8.2, 0.05, -2.21, 0.5, -0.89, 1.65, -0.53, 1.18, -2.65, 1.01, 3.65,
1000 1.77, 3.8, 12.0, 4.0, 2.0, 20.0, 0.0, 2.87, 36.62, 4.17, 3.0}},
1001 {90, {-8.19, 0.06, -1.78, 0.91, -0.81, 1.26, -0.46, 0.91, -2.65, 0.71, 3.59,
1002 1.77, 3.8, 12.0, 4.0, 2.0, 20.0, 0.0, 5.48, 36.77, 4.29, 3.0}},
1006 {10, {-9.68, 0.46, -4.03, 0.91, -9.74, 7.52, -5.85, 6.51, -7.45, 5.3, 25.43,
1007 7.04, 3.8, 12.0, 4.0, 2.0, 20.0, 0.0, 0.36, 4.63, 0.75, 3.0}},
1008 {20, {-8.86, 0.29, -3.55, 0.7, -4.88, 6.67, -3.27, 5.36, -5.25, 4.42, 12.72,
1009 7.47, 3.8, 12.0, 4.0, 2.0, 20.0, 0.0, 0.3, 6.83, 1.25, 3.0}},
1010 {30, {-8.59, 0.18, -3.45, 0.55, -2.6, 4.63, -0.88, 0.93, -3.16, 0.68, 8.4,
1011 7.18, 3.8, 12.0, 4.0, 2.0, 20.0, 0.0, 0.25, 12.91, 1.93, 3.0}},
1012 {40, {-8.46, 0.19, -3.38, 0.52, -1.92, 3.45, -0.93, 0.96, -3.15, 0.73, 6.52,
1013 6.88, 3.8, 12.0, 4.0, 2.0, 20.0, 0.0, 0.35, 18.9, 2.37, 3.0}},
1014 {50, {-8.36, 0.14, -3.33, 0.46, -1.56, 2.44, -0.99, 0.97, -3.2, 0.77, 5.24,
1015 5.28, 3.8, 12.0, 4.0, 2.0, 20.0, 0.0, 0.53, 22.44, 2.66, 3.0}},
1016 {60, {-8.3, 0.15, -3.29, 0.43, -1.66, 2.38, -1.04, 0.83, -3.27, 0.61, 4.57,
1017 4.92, 3.8, 12.0, 4.0, 2.0, 20.0, 0.0, 0.88, 25.69, 3.23, 3.0}},
1018 {70, {-8.26, 0.13, -3.24, 0.46, -1.59, 1.67, -1.17, 1.01, -3.42, 0.74, 4.02,
1019 3.4, 3.8, 12.0, 4.0, 2.0, 20.0, 0.0, 1.39, 27.95, 3.71, 3.0}},
1020 {80, {-8.22, 0.03, -2.9, 0.44, -1.58, 1.44, -1.19, 1.01, -3.36, 0.79, 3.7,
1021 2.22, 3.8, 12.0, 4.0, 2.0, 20.0, 0.0, 2.7, 31.45, 4.17, 3.0}},
1022 {90, {-8.21, 0.07, -2.5, 0.82, -1.51, 1.13, -1.13, 0.85, -3.35, 0.65, 3.62,
1023 2.28, 3.8, 12.0, 4.0, 2.0, 20.0, 0.0, 4.97, 28.01, 4.14, 3.0}},
1033static const std::map<std::string, std::map<int, std::vector<float>>>
NTNRuralNLOS{
1036 {10, {-9.01, 1.59, -2.9, 1.34, -3.33, 6.22, -0.88, 3.26, -4.92, 3.96, 0.0,
1037 0.0, 1.7, 7.0, 3.0, 3.0, 20.0, 0.0, 0.03, 18.16, 2.32, 3.0}},
1038 {20, {-8.37, 0.95, -2.5, 1.18, -0.74, 4.22, -0.07, 3.29, -4.06, 4.07, 0.0,
1039 0.0, 1.7, 7.0, 3.0, 3.0, 20.0, 0.0, 0.05, 26.82, 7.34, 3.0}},
1040 {30, {-8.05, 0.92, -2.12, 1.08, 0.08, 3.02, 0.75, 1.92, -2.33, 1.7, 0.0,
1041 0.0, 1.7, 7.0, 3.0, 2.0, 20.0, 0.0, 0.07, 21.99, 8.28, 3.0}},
1042 {40, {-7.92, 0.92, -1.99, 1.06, 0.32, 2.45, 0.72, 1.92, -2.24, 2.01, 0.0,
1043 0.0, 1.7, 7.0, 3.0, 2.0, 20.0, 0.0, 0.1, 22.86, 8.76, 3.0}},
1044 {50, {-7.92, 0.87, -1.9, 1.05, 0.53, 1.63, 0.95, 1.45, -2.24, 2.0, 0.0,
1045 0.0, 1.7, 7.0, 3.0, 2.0, 20.0, 0.0, 0.15, 25.93, 9.68, 3.0}},
1046 {60, {-7.96, 0.87, -1.85, 1.06, 0.33, 2.08, 0.97, 1.62, -2.22, 1.82, 0.0,
1047 0.0, 1.7, 7.0, 3.0, 2.0, 20.0, 0.0, 0.22, 27.79, 9.94, 3.0}},
1048 {70, {-7.91, 0.82, -1.69, 1.14, 0.55, 1.58, 1.1, 1.43, -2.19, 1.66, 0.0,
1049 0.0, 1.7, 7.0, 3.0, 2.0, 20.0, 0.0, 0.5, 28.5, 8.9, 3.0}},
1050 {80, {-7.79, 0.86, -1.46, 1.16, 0.45, 2.01, 0.97, 1.88, -2.41, 2.58, 0.0,
1051 0.0, 1.7, 7.0, 3.0, 2.0, 20.0, 0.0, 1.04, 37.53, 13.74, 3.0}},
1052 {90, {-7.74, 0.81, -1.32, 1.3, 0.4, 2.19, 1.35, 0.62, -2.45, 2.52, 0.0,
1053 0.0, 1.7, 7.0, 3.0, 2.0, 20.0, 0.0, 2.11, 29.23, 12.16, 3.0}},
1057 {10, {-9.13, 1.91, -2.9, 1.32, -3.4, 6.28, -1.19, 3.81, -5.47, 4.39, 0.0,
1058 0.0, 1.7, 7.0, 3.0, 3.0, 20.0, 0.0, 0.03, 18.21, 2.13, 3.0}},
1059 {20, {-8.39, 0.94, -2.53, 1.18, -0.51, 3.75, -0.11, 3.33, -4.06, 4.04, 0.0,
1060 0.0, 1.7, 7.0, 3.0, 3.0, 20.0, 0.0, 0.05, 24.08, 6.52, 3.0}},
1061 {30, {-8.1, 0.92, -2.16, 1.08, 0.06, 2.95, 0.72, 1.93, -2.32, 1.54, 0.0,
1062 0.0, 1.7, 7.0, 3.0, 2.0, 20.0, 0.0, 0.07, 22.06, 7.72, 3.0}},
1063 {40, {-7.96, 0.94, -2.04, 1.09, 0.2, 2.65, 0.69, 1.91, -2.19, 1.73, 0.0,
1064 0.0, 1.7, 7.0, 3.0, 2.0, 20.0, 0.0, 0.09, 21.4, 8.45, 3.0}},
1065 {50, {-7.99, 0.89, -1.99, 1.08, 0.4, 1.85, 0.84, 1.7, -2.16, 1.5, 0.0,
1066 0.0, 1.7, 7.0, 3.0, 2.0, 20.0, 0.0, 0.16, 24.26, 8.92, 3.0}},
1067 {60, {-8.05, 0.87, -1.95, 1.06, 0.32, 1.83, 0.99, 1.27, -2.24, 1.64, 0.0,
1068 0.0, 1.7, 7.0, 3.0, 2.0, 20.0, 0.0, 0.22, 24.15, 8.76, 3.0}},
1069 {70, {-8.01, 0.82, -1.81, 1.17, 0.46, 1.57, 0.95, 1.86, -2.29, 1.66, 0.0,
1070 0.0, 1.7, 7.0, 3.0, 2.0, 20.0, 0.0, 0.51, 25.99, 9.0, 3.0}},
1071 {80, {-8.05, 1.65, -1.56, 1.2, 0.33, 1.99, 0.92, 1.84, -2.65, 2.86, 0.0,
1072 0.0, 1.7, 7.0, 3.0, 2.0, 20.0, 0.0, 0.89, 36.07, 13.6, 3.0}},
1073 {90, {-7.91, 0.76, -1.53, 1.27, 0.24, 2.18, 1.29, 0.59, -2.23, 1.12, 0.0,
1074 0.0, 1.7, 7.0, 3.0, 2.0, 20.0, 0.0, 1.68, 24.51, 10.56, 3.0}},
1081 m_uniformRv = CreateObject<UniformRandomVariable>();
1085 m_normalRv = CreateObject<NormalRandomVariable>();
1112 TypeId(
"ns3::ThreeGppChannelModel")
1115 .AddConstructor<ThreeGppChannelModel>()
1116 .AddAttribute(
"Frequency",
1117 "The operating Frequency in Hz",
1121 MakeDoubleChecker<double>())
1124 "The 3GPP scenario (RMa, UMa, UMi-StreetCanyon, InH-OfficeOpen, InH-OfficeMixed, "
1125 "NTN-DenseUrban, NTN-Urban, NTN-Suburban, NTN-Rural)",
1130 .AddAttribute(
"ChannelConditionModel",
1131 "Pointer to the channel condition model",
1135 MakePointerChecker<ChannelConditionModel>())
1136 .AddAttribute(
"UpdatePeriod",
1137 "Specify the channel coherence time",
1142 .AddAttribute(
"Blockage",
1143 "Enable blockage model A (sec 7.6.4.1)",
1147 .AddAttribute(
"NumNonselfBlocking",
1148 "number of non-self-blocking regions",
1151 MakeIntegerChecker<uint16_t>())
1152 .AddAttribute(
"PortraitMode",
1153 "true for portrait mode, false for landscape mode",
1157 .AddAttribute(
"BlockerSpeed",
1158 "The speed of moving blockers, the unit is m/s",
1161 MakeDoubleChecker<double>())
1162 .AddAttribute(
"vScatt",
1163 "Maximum speed of the vehicle in the layout (see 3GPP TR 37.885 v15.3.0, "
1165 "Used to compute the additional contribution for the Doppler of"
1166 "delayed (reflected) paths",
1169 MakeDoubleChecker<double>(0.0))
1194 "Frequency should be between 0.5 and 100 GHz but is " << f);
1209 NS_ASSERT_MSG(scenario ==
"RMa" || scenario ==
"UMa" || scenario ==
"UMi-StreetCanyon" ||
1210 scenario ==
"InH-OfficeOpen" || scenario ==
"InH-OfficeMixed" ||
1211 scenario ==
"V2V-Urban" || scenario ==
"V2V-Highway" ||
1212 scenario ==
"NTN-DenseUrban" || scenario ==
"NTN-Urban" ||
1213 scenario ==
"NTN-Suburban" || scenario ==
"NTN-Rural",
1214 "Unknown scenario, choose between: RMa, UMa, UMi-StreetCanyon, "
1215 "InH-OfficeOpen, InH-OfficeMixed, V2V-Urban, V2V-Highway, "
1216 "NTN-DenseUrban, NTN-Urban, NTN-Suburban or NTN-Rural");
1236 double hUT = std::min(aMob->GetPosition().z, bMob->GetPosition().z);
1237 double hBS = std::max(aMob->GetPosition().z, bMob->GetPosition().z);
1239 double distance2D = sqrt(pow(aMob->GetPosition().x - bMob->GetPosition().x, 2) +
1240 pow(aMob->GetPosition().y - bMob->GetPosition().y, 2));
1249 bool los = channelCondition->IsLos();
1250 bool o2i = channelCondition->IsO2i();
1259 table3gpp->m_numOfCluster = 11;
1260 table3gpp->m_raysPerCluster = 20;
1261 table3gpp->m_uLgDS = -7.49;
1262 table3gpp->m_sigLgDS = 0.55;
1263 table3gpp->m_uLgASD = 0.90;
1264 table3gpp->m_sigLgASD = 0.38;
1265 table3gpp->m_uLgASA = 1.52;
1266 table3gpp->m_sigLgASA = 0.24;
1267 table3gpp->m_uLgZSA = 0.47;
1268 table3gpp->m_sigLgZSA = 0.40;
1269 table3gpp->m_uLgZSD = 0.34;
1270 table3gpp->m_sigLgZSD =
1271 std::max(-1.0, -0.17 * (distance2D / 1000.0) - 0.01 * (hUT - 1.5) + 0.22);
1272 table3gpp->m_offsetZOD = 0;
1273 table3gpp->m_cDS = 3.91e-9;
1274 table3gpp->m_cASD = 2;
1275 table3gpp->m_cASA = 3;
1276 table3gpp->m_cZSA = 3;
1277 table3gpp->m_uK = 7;
1278 table3gpp->m_sigK = 4;
1279 table3gpp->m_rTau = 3.8;
1280 table3gpp->m_uXpr = 12;
1281 table3gpp->m_sigXpr = 4;
1282 table3gpp->m_perClusterShadowingStd = 3;
1284 for (uint8_t row = 0; row < 7; row++)
1286 for (uint8_t column = 0; column < 7; column++)
1288 table3gpp->m_sqrtC[row][column] =
sqrtC_RMa_LOS[row][column];
1292 else if (!los && !o2i)
1294 table3gpp->m_numOfCluster = 10;
1295 table3gpp->m_raysPerCluster = 20;
1296 table3gpp->m_uLgDS = -7.43;
1297 table3gpp->m_sigLgDS = 0.48;
1298 table3gpp->m_uLgASD = 0.95;
1299 table3gpp->m_sigLgASD = 0.45;
1300 table3gpp->m_uLgASA = 1.52;
1301 table3gpp->m_sigLgASA = 0.13;
1302 table3gpp->m_uLgZSA = 0.58;
1303 table3gpp->m_sigLgZSA = 0.37;
1304 table3gpp->m_uLgZSD =
1305 std::max(-1.0, -0.19 * (distance2D / 1000.0) - 0.01 * (hUT - 1.5) + 0.28);
1306 table3gpp->m_sigLgZSD = 0.30;
1307 table3gpp->m_offsetZOD = atan((35 - 3.5) / distance2D) - atan((35 - 1.5) / distance2D);
1308 table3gpp->m_cDS = 3.91e-9;
1309 table3gpp->m_cASD = 2;
1310 table3gpp->m_cASA = 3;
1311 table3gpp->m_cZSA = 3;
1312 table3gpp->m_uK = 0;
1313 table3gpp->m_sigK = 0;
1314 table3gpp->m_rTau = 1.7;
1315 table3gpp->m_uXpr = 7;
1316 table3gpp->m_sigXpr = 3;
1317 table3gpp->m_perClusterShadowingStd = 3;
1319 for (uint8_t row = 0; row < 6; row++)
1321 for (uint8_t column = 0; column < 6; column++)
1329 table3gpp->m_numOfCluster = 10;
1330 table3gpp->m_raysPerCluster = 20;
1331 table3gpp->m_uLgDS = -7.47;
1332 table3gpp->m_sigLgDS = 0.24;
1333 table3gpp->m_uLgASD = 0.67;
1334 table3gpp->m_sigLgASD = 0.18;
1335 table3gpp->m_uLgASA = 1.66;
1336 table3gpp->m_sigLgASA = 0.21;
1337 table3gpp->m_uLgZSA = 0.93;
1338 table3gpp->m_sigLgZSA = 0.22;
1339 table3gpp->m_uLgZSD =
1340 std::max(-1.0, -0.19 * (distance2D / 1000.0) - 0.01 * (hUT - 1.5) + 0.28);
1341 table3gpp->m_sigLgZSD = 0.30;
1342 table3gpp->m_offsetZOD = atan((35 - 3.5) / distance2D) - atan((35 - 1.5) / distance2D);
1343 table3gpp->m_cDS = 3.91e-9;
1344 table3gpp->m_cASD = 2;
1345 table3gpp->m_cASA = 3;
1346 table3gpp->m_cZSA = 3;
1347 table3gpp->m_uK = 0;
1348 table3gpp->m_sigK = 0;
1349 table3gpp->m_rTau = 1.7;
1350 table3gpp->m_uXpr = 7;
1351 table3gpp->m_sigXpr = 3;
1352 table3gpp->m_perClusterShadowingStd = 3;
1354 for (uint8_t row = 0; row < 6; row++)
1356 for (uint8_t column = 0; column < 6; column++)
1358 table3gpp->m_sqrtC[row][column] =
sqrtC_RMa_O2I[row][column];
1367 table3gpp->m_numOfCluster = 12;
1368 table3gpp->m_raysPerCluster = 20;
1369 table3gpp->m_uLgDS = -6.955 - 0.0963 * log10(fcGHz);
1370 table3gpp->m_sigLgDS = 0.66;
1371 table3gpp->m_uLgASD = 1.06 + 0.1114 * log10(fcGHz);
1372 table3gpp->m_sigLgASD = 0.28;
1373 table3gpp->m_uLgASA = 1.81;
1374 table3gpp->m_sigLgASA = 0.20;
1375 table3gpp->m_uLgZSA = 0.95;
1376 table3gpp->m_sigLgZSA = 0.16;
1377 table3gpp->m_uLgZSD =
1378 std::max(-0.5, -2.1 * distance2D / 1000.0 - 0.01 * (hUT - 1.5) + 0.75);
1379 table3gpp->m_sigLgZSD = 0.40;
1380 table3gpp->m_offsetZOD = 0;
1381 table3gpp->m_cDS = std::max(0.25, -3.4084 * log10(fcGHz) + 6.5622) * 1e-9;
1382 table3gpp->m_cASD = 5;
1383 table3gpp->m_cASA = 11;
1384 table3gpp->m_cZSA = 7;
1385 table3gpp->m_uK = 9;
1386 table3gpp->m_sigK = 3.5;
1387 table3gpp->m_rTau = 2.5;
1388 table3gpp->m_uXpr = 8;
1389 table3gpp->m_sigXpr = 4;
1390 table3gpp->m_perClusterShadowingStd = 3;
1392 for (uint8_t row = 0; row < 7; row++)
1394 for (uint8_t column = 0; column < 7; column++)
1396 table3gpp->m_sqrtC[row][column] =
sqrtC_UMa_LOS[row][column];
1402 double uLgZSD = std::max(-0.5, -2.1 * distance2D / 1000.0 - 0.01 * (hUT - 1.5) + 0.9);
1404 double afc = 0.208 * log10(fcGHz) - 0.782;
1406 double cfc = -0.13 * log10(fcGHz) + 2.03;
1407 double efc = 7.66 * log10(fcGHz) - 5.96;
1409 double offsetZOD = efc - std::pow(10, afc * log10(std::max(bfc, distance2D)) + cfc);
1413 table3gpp->m_numOfCluster = 20;
1414 table3gpp->m_raysPerCluster = 20;
1415 table3gpp->m_uLgDS = -6.28 - 0.204 * log10(fcGHz);
1416 table3gpp->m_sigLgDS = 0.39;
1417 table3gpp->m_uLgASD = 1.5 - 0.1144 * log10(fcGHz);
1418 table3gpp->m_sigLgASD = 0.28;
1419 table3gpp->m_uLgASA = 2.08 - 0.27 * log10(fcGHz);
1420 table3gpp->m_sigLgASA = 0.11;
1421 table3gpp->m_uLgZSA = -0.3236 * log10(fcGHz) + 1.512;
1422 table3gpp->m_sigLgZSA = 0.16;
1423 table3gpp->m_uLgZSD =
uLgZSD;
1424 table3gpp->m_sigLgZSD = 0.49;
1425 table3gpp->m_offsetZOD = offsetZOD;
1426 table3gpp->m_cDS = std::max(0.25, -3.4084 * log10(fcGHz) + 6.5622) * 1e-9;
1427 table3gpp->m_cASD = 2;
1428 table3gpp->m_cASA = 15;
1429 table3gpp->m_cZSA = 7;
1430 table3gpp->m_uK = 0;
1431 table3gpp->m_sigK = 0;
1432 table3gpp->m_rTau = 2.3;
1433 table3gpp->m_uXpr = 7;
1434 table3gpp->m_sigXpr = 3;
1435 table3gpp->m_perClusterShadowingStd = 3;
1437 for (uint8_t row = 0; row < 6; row++)
1439 for (uint8_t column = 0; column < 6; column++)
1447 table3gpp->m_numOfCluster = 12;
1448 table3gpp->m_raysPerCluster = 20;
1449 table3gpp->m_uLgDS = -6.62;
1450 table3gpp->m_sigLgDS = 0.32;
1451 table3gpp->m_uLgASD = 1.25;
1452 table3gpp->m_sigLgASD = 0.42;
1453 table3gpp->m_uLgASA = 1.76;
1454 table3gpp->m_sigLgASA = 0.16;
1455 table3gpp->m_uLgZSA = 1.01;
1456 table3gpp->m_sigLgZSA = 0.43;
1457 table3gpp->m_uLgZSD =
uLgZSD;
1458 table3gpp->m_sigLgZSD = 0.49;
1459 table3gpp->m_offsetZOD = offsetZOD;
1460 table3gpp->m_cDS = 11e-9;
1461 table3gpp->m_cASD = 5;
1462 table3gpp->m_cASA = 8;
1463 table3gpp->m_cZSA = 3;
1464 table3gpp->m_uK = 0;
1465 table3gpp->m_sigK = 0;
1466 table3gpp->m_rTau = 2.2;
1467 table3gpp->m_uXpr = 9;
1468 table3gpp->m_sigXpr = 5;
1469 table3gpp->m_perClusterShadowingStd = 4;
1471 for (uint8_t row = 0; row < 6; row++)
1473 for (uint8_t column = 0; column < 6; column++)
1475 table3gpp->m_sqrtC[row][column] =
sqrtC_UMa_O2I[row][column];
1485 table3gpp->m_numOfCluster = 12;
1486 table3gpp->m_raysPerCluster = 20;
1487 table3gpp->m_uLgDS = -0.24 * log10(1 + fcGHz) - 7.14;
1488 table3gpp->m_sigLgDS = 0.38;
1489 table3gpp->m_uLgASD = -0.05 * log10(1 + fcGHz) + 1.21;
1490 table3gpp->m_sigLgASD = 0.41;
1491 table3gpp->m_uLgASA = -0.08 * log10(1 + fcGHz) + 1.73;
1492 table3gpp->m_sigLgASA = 0.014 * log10(1 + fcGHz) + 0.28;
1493 table3gpp->m_uLgZSA = -0.1 * log10(1 + fcGHz) + 0.73;
1494 table3gpp->m_sigLgZSA = -0.04 * log10(1 + fcGHz) + 0.34;
1495 table3gpp->m_uLgZSD =
1496 std::max(-0.21, -14.8 * distance2D / 1000.0 + 0.01 * std::abs(hUT - hBS) + 0.83);
1497 table3gpp->m_sigLgZSD = 0.35;
1498 table3gpp->m_offsetZOD = 0;
1499 table3gpp->m_cDS = 5e-9;
1500 table3gpp->m_cASD = 3;
1501 table3gpp->m_cASA = 17;
1502 table3gpp->m_cZSA = 7;
1503 table3gpp->m_uK = 9;
1504 table3gpp->m_sigK = 5;
1505 table3gpp->m_rTau = 3;
1506 table3gpp->m_uXpr = 9;
1507 table3gpp->m_sigXpr = 3;
1508 table3gpp->m_perClusterShadowingStd = 3;
1510 for (uint8_t row = 0; row < 7; row++)
1512 for (uint8_t column = 0; column < 7; column++)
1514 table3gpp->m_sqrtC[row][column] =
sqrtC_UMi_LOS[row][column];
1521 std::max(-0.5, -3.1 * distance2D / 1000.0 + 0.01 * std::max(hUT - hBS, 0.0) + 0.2);
1522 double offsetZOD = -1 * std::pow(10, -1.5 * log10(std::max(10.0, distance2D)) + 3.3);
1525 table3gpp->m_numOfCluster = 19;
1526 table3gpp->m_raysPerCluster = 20;
1527 table3gpp->m_uLgDS = -0.24 * log10(1 + fcGHz) - 6.83;
1528 table3gpp->m_sigLgDS = 0.16 * log10(1 + fcGHz) + 0.28;
1529 table3gpp->m_uLgASD = -0.23 * log10(1 + fcGHz) + 1.53;
1530 table3gpp->m_sigLgASD = 0.11 * log10(1 + fcGHz) + 0.33;
1531 table3gpp->m_uLgASA = -0.08 * log10(1 + fcGHz) + 1.81;
1532 table3gpp->m_sigLgASA = 0.05 * log10(1 + fcGHz) + 0.3;
1533 table3gpp->m_uLgZSA = -0.04 * log10(1 + fcGHz) + 0.92;
1534 table3gpp->m_sigLgZSA = -0.07 * log10(1 + fcGHz) + 0.41;
1535 table3gpp->m_uLgZSD =
uLgZSD;
1536 table3gpp->m_sigLgZSD = 0.35;
1537 table3gpp->m_offsetZOD = offsetZOD;
1538 table3gpp->m_cDS = 11e-9;
1539 table3gpp->m_cASD = 10;
1540 table3gpp->m_cASA = 22;
1541 table3gpp->m_cZSA = 7;
1542 table3gpp->m_uK = 0;
1543 table3gpp->m_sigK = 0;
1544 table3gpp->m_rTau = 2.1;
1545 table3gpp->m_uXpr = 8;
1546 table3gpp->m_sigXpr = 3;
1547 table3gpp->m_perClusterShadowingStd = 3;
1549 for (uint8_t row = 0; row < 6; row++)
1551 for (uint8_t column = 0; column < 6; column++)
1559 table3gpp->m_numOfCluster = 12;
1560 table3gpp->m_raysPerCluster = 20;
1561 table3gpp->m_uLgDS = -6.62;
1562 table3gpp->m_sigLgDS = 0.32;
1563 table3gpp->m_uLgASD = 1.25;
1564 table3gpp->m_sigLgASD = 0.42;
1565 table3gpp->m_uLgASA = 1.76;
1566 table3gpp->m_sigLgASA = 0.16;
1567 table3gpp->m_uLgZSA = 1.01;
1568 table3gpp->m_sigLgZSA = 0.43;
1569 table3gpp->m_uLgZSD =
uLgZSD;
1570 table3gpp->m_sigLgZSD = 0.35;
1571 table3gpp->m_offsetZOD = offsetZOD;
1572 table3gpp->m_cDS = 11e-9;
1573 table3gpp->m_cASD = 5;
1574 table3gpp->m_cASA = 8;
1575 table3gpp->m_cZSA = 3;
1576 table3gpp->m_uK = 0;
1577 table3gpp->m_sigK = 0;
1578 table3gpp->m_rTau = 2.2;
1579 table3gpp->m_uXpr = 9;
1580 table3gpp->m_sigXpr = 5;
1581 table3gpp->m_perClusterShadowingStd = 4;
1583 for (uint8_t row = 0; row < 6; row++)
1585 for (uint8_t column = 0; column < 6; column++)
1587 table3gpp->m_sqrtC[row][column] =
sqrtC_UMi_O2I[row][column];
1595 NS_ASSERT_MSG(!o2i,
"The indoor scenario does out support outdoor to indoor");
1598 table3gpp->m_numOfCluster = 15;
1599 table3gpp->m_raysPerCluster = 20;
1600 table3gpp->m_uLgDS = -0.01 * log10(1 + fcGHz) - 7.692;
1601 table3gpp->m_sigLgDS = 0.18;
1602 table3gpp->m_uLgASD = 1.60;
1603 table3gpp->m_sigLgASD = 0.18;
1604 table3gpp->m_uLgASA = -0.19 * log10(1 + fcGHz) + 1.781;
1605 table3gpp->m_sigLgASA = 0.12 * log10(1 + fcGHz) + 0.119;
1606 table3gpp->m_uLgZSA = -0.26 * log10(1 + fcGHz) + 1.44;
1607 table3gpp->m_sigLgZSA = -0.04 * log10(1 + fcGHz) + 0.264;
1608 table3gpp->m_uLgZSD = -1.43 * log10(1 + fcGHz) + 2.228;
1609 table3gpp->m_sigLgZSD = 0.13 * log10(1 + fcGHz) + 0.30;
1610 table3gpp->m_offsetZOD = 0;
1611 table3gpp->m_cDS = 3.91e-9;
1612 table3gpp->m_cASD = 5;
1613 table3gpp->m_cASA = 8;
1614 table3gpp->m_cZSA = 9;
1615 table3gpp->m_uK = 7;
1616 table3gpp->m_sigK = 4;
1617 table3gpp->m_rTau = 3.6;
1618 table3gpp->m_uXpr = 11;
1619 table3gpp->m_sigXpr = 4;
1620 table3gpp->m_perClusterShadowingStd = 6;
1622 for (uint8_t row = 0; row < 7; row++)
1624 for (uint8_t column = 0; column < 7; column++)
1632 table3gpp->m_numOfCluster = 19;
1633 table3gpp->m_raysPerCluster = 20;
1634 table3gpp->m_uLgDS = -0.28 * log10(1 + fcGHz) - 7.173;
1635 table3gpp->m_sigLgDS = 0.1 * log10(1 + fcGHz) + 0.055;
1636 table3gpp->m_uLgASD = 1.62;
1637 table3gpp->m_sigLgASD = 0.25;
1638 table3gpp->m_uLgASA = -0.11 * log10(1 + fcGHz) + 1.863;
1639 table3gpp->m_sigLgASA = 0.12 * log10(1 + fcGHz) + 0.059;
1640 table3gpp->m_uLgZSA = -0.15 * log10(1 + fcGHz) + 1.387;
1641 table3gpp->m_sigLgZSA = -0.09 * log10(1 + fcGHz) + 0.746;
1642 table3gpp->m_uLgZSD = 1.08;
1643 table3gpp->m_sigLgZSD = 0.36;
1644 table3gpp->m_offsetZOD = 0;
1645 table3gpp->m_cDS = 3.91e-9;
1646 table3gpp->m_cASD = 5;
1647 table3gpp->m_cASA = 11;
1648 table3gpp->m_cZSA = 9;
1649 table3gpp->m_uK = 0;
1650 table3gpp->m_sigK = 0;
1651 table3gpp->m_rTau = 3;
1652 table3gpp->m_uXpr = 10;
1653 table3gpp->m_sigXpr = 4;
1654 table3gpp->m_perClusterShadowingStd = 3;
1656 for (uint8_t row = 0; row < 6; row++)
1658 for (uint8_t column = 0; column < 6; column++)
1667 if (channelCondition->IsLos())
1671 table3gpp->m_numOfCluster = 12;
1672 table3gpp->m_raysPerCluster = 20;
1673 table3gpp->m_uLgDS = -0.2 * log10(1 + fcGHz) - 7.5;
1674 table3gpp->m_sigLgDS = 0.1;
1675 table3gpp->m_uLgASD = -0.1 * log10(1 + fcGHz) + 1.6;
1676 table3gpp->m_sigLgASD = 0.1;
1677 table3gpp->m_uLgASA = -0.1 * log10(1 + fcGHz) + 1.6;
1678 table3gpp->m_sigLgASA = 0.1;
1679 table3gpp->m_uLgZSA = -0.1 * log10(1 + fcGHz) + 0.73;
1680 table3gpp->m_sigLgZSA = -0.04 * log10(1 + fcGHz) + 0.34;
1681 table3gpp->m_uLgZSD = -0.1 * log10(1 + fcGHz) + 0.73;
1682 table3gpp->m_sigLgZSD = -0.04 * log10(1 + fcGHz) + 0.34;
1683 table3gpp->m_offsetZOD = 0;
1684 table3gpp->m_cDS = 5;
1685 table3gpp->m_cASD = 17;
1686 table3gpp->m_cASA = 17;
1687 table3gpp->m_cZSA = 7;
1688 table3gpp->m_uK = 3.48;
1689 table3gpp->m_sigK = 2;
1690 table3gpp->m_rTau = 3;
1691 table3gpp->m_uXpr = 9;
1692 table3gpp->m_sigXpr = 3;
1693 table3gpp->m_perClusterShadowingStd = 4;
1695 for (uint8_t row = 0; row < 7; row++)
1697 for (uint8_t column = 0; column < 7; column++)
1699 table3gpp->m_sqrtC[row][column] =
sqrtC_UMi_LOS[row][column];
1703 else if (channelCondition->IsNlos())
1705 table3gpp->m_numOfCluster = 19;
1706 table3gpp->m_raysPerCluster = 20;
1707 table3gpp->m_uLgDS = -0.3 * log10(1 + fcGHz) - 7;
1708 table3gpp->m_sigLgDS = 0.28;
1709 table3gpp->m_uLgASD = -0.08 * log10(1 + fcGHz) + 1.81;
1710 table3gpp->m_sigLgASD = 0.05 * log10(1 + fcGHz) + 0.3;
1711 table3gpp->m_uLgASA = -0.08 * log10(1 + fcGHz) + 1.81;
1712 table3gpp->m_sigLgASA = 0.05 * log10(1 + fcGHz) + 0.3;
1713 table3gpp->m_uLgZSA = -0.04 * log10(1 + fcGHz) + 0.92;
1714 table3gpp->m_sigLgZSA = -0.07 * log10(1 + fcGHz) + 0.41;
1715 table3gpp->m_uLgZSD = -0.04 * log10(1 + fcGHz) + 0.92;
1716 table3gpp->m_sigLgZSD = -0.07 * log10(1 + fcGHz) + 0.41;
1717 table3gpp->m_offsetZOD = 0;
1718 table3gpp->m_cDS = 11;
1719 table3gpp->m_cASD = 22;
1720 table3gpp->m_cASA = 22;
1721 table3gpp->m_cZSA = 7;
1722 table3gpp->m_uK = 0;
1723 table3gpp->m_sigK = 0;
1724 table3gpp->m_rTau = 2.1;
1725 table3gpp->m_uXpr = 8;
1726 table3gpp->m_sigXpr = 3;
1727 table3gpp->m_perClusterShadowingStd = 4;
1729 for (uint8_t row = 0; row < 6; row++)
1731 for (uint8_t column = 0; column < 6; column++)
1737 else if (channelCondition->IsNlosv())
1739 table3gpp->m_numOfCluster = 19;
1740 table3gpp->m_raysPerCluster = 20;
1741 table3gpp->m_uLgDS = -0.4 * log10(1 + fcGHz) - 7;
1742 table3gpp->m_sigLgDS = 0.1;
1743 table3gpp->m_uLgASD = -0.1 * log10(1 + fcGHz) + 1.7;
1744 table3gpp->m_sigLgASD = 0.1;
1745 table3gpp->m_uLgASA = -0.1 * log10(1 + fcGHz) + 1.7;
1746 table3gpp->m_sigLgASA = 0.1;
1747 table3gpp->m_uLgZSA = -0.04 * log10(1 + fcGHz) + 0.92;
1748 table3gpp->m_sigLgZSA = -0.07 * log10(1 + fcGHz) + 0.41;
1749 table3gpp->m_uLgZSD = -0.04 * log10(1 + fcGHz) + 0.92;
1750 table3gpp->m_sigLgZSD = -0.07 * log10(1 + fcGHz) + 0.41;
1751 table3gpp->m_offsetZOD = 0;
1752 table3gpp->m_cDS = 11;
1753 table3gpp->m_cASD = 22;
1754 table3gpp->m_cASA = 22;
1755 table3gpp->m_cZSA = 7;
1756 table3gpp->m_uK = 0;
1757 table3gpp->m_sigK = 4.5;
1758 table3gpp->m_rTau = 2.1;
1759 table3gpp->m_uXpr = 8;
1760 table3gpp->m_sigXpr = 3;
1761 table3gpp->m_perClusterShadowingStd = 4;
1763 for (uint8_t row = 0; row < 6; row++)
1765 for (uint8_t column = 0; column < 6; column++)
1767 table3gpp->m_sqrtC[row][column] =
sqrtC_UMi_LOS[row][column];
1778 if (channelCondition->IsLos())
1780 table3gpp->m_numOfCluster = 12;
1781 table3gpp->m_raysPerCluster = 20;
1782 table3gpp->m_uLgDS = -8.3;
1783 table3gpp->m_sigLgDS = 0.2;
1784 table3gpp->m_uLgASD = 1.4;
1785 table3gpp->m_sigLgASD = 0.1;
1786 table3gpp->m_uLgASA = 1.4;
1787 table3gpp->m_sigLgASA = 0.1;
1788 table3gpp->m_uLgZSA = -0.1 * log10(1 + fcGHz) + 0.73;
1789 table3gpp->m_sigLgZSA = -0.04 * log10(1 + fcGHz) + 0.34;
1790 table3gpp->m_uLgZSD = -0.1 * log10(1 + fcGHz) + 0.73;
1791 table3gpp->m_sigLgZSD = -0.04 * log10(1 + fcGHz) + 0.34;
1792 table3gpp->m_offsetZOD = 0;
1793 table3gpp->m_cDS = 5;
1794 table3gpp->m_cASD = 17;
1795 table3gpp->m_cASA = 17;
1796 table3gpp->m_cZSA = 7;
1797 table3gpp->m_uK = 9;
1798 table3gpp->m_sigK = 3.5;
1799 table3gpp->m_rTau = 3;
1800 table3gpp->m_uXpr = 9;
1801 table3gpp->m_sigXpr = 3;
1802 table3gpp->m_perClusterShadowingStd = 4;
1804 for (uint8_t row = 0; row < 7; row++)
1806 for (uint8_t column = 0; column < 7; column++)
1808 table3gpp->m_sqrtC[row][column] =
sqrtC_UMi_LOS[row][column];
1812 else if (channelCondition->IsNlosv())
1814 table3gpp->m_numOfCluster = 19;
1815 table3gpp->m_raysPerCluster = 20;
1816 table3gpp->m_uLgDS = -8.3;
1817 table3gpp->m_sigLgDS = 0.3;
1818 table3gpp->m_uLgASD = 1.5;
1819 table3gpp->m_sigLgASD = 0.1;
1820 table3gpp->m_uLgASA = 1.5;
1821 table3gpp->m_sigLgASA = 0.1;
1822 table3gpp->m_uLgZSA = -0.04 * log10(1 + fcGHz) + 0.92;
1823 table3gpp->m_sigLgZSA = -0.07 * log10(1 + fcGHz) + 0.41;
1824 table3gpp->m_uLgZSD = -0.04 * log10(1 + fcGHz) + 0.92;
1825 table3gpp->m_sigLgZSD = -0.07 * log10(1 + fcGHz) + 0.41;
1826 table3gpp->m_offsetZOD = 0;
1827 table3gpp->m_cDS = 11;
1828 table3gpp->m_cASD = 22;
1829 table3gpp->m_cASA = 22;
1830 table3gpp->m_cZSA = 7;
1831 table3gpp->m_uK = 0;
1832 table3gpp->m_sigK = 4.5;
1833 table3gpp->m_rTau = 2.1;
1834 table3gpp->m_uXpr = 8.0;
1835 table3gpp->m_sigXpr = 3;
1836 table3gpp->m_perClusterShadowingStd = 4;
1838 for (uint8_t row = 0; row < 6; row++)
1840 for (uint8_t column = 0; column < 6; column++)
1842 table3gpp->m_sqrtC[row][column] =
sqrtC_UMi_LOS[row][column];
1846 else if (channelCondition->IsNlos())
1849 "The fast fading parameters for the NLOS condition in the Highway scenario are not "
1850 "defined in TR 37.885, use the ones defined in TDoc R1-1803671 instead");
1852 table3gpp->m_numOfCluster = 19;
1853 table3gpp->m_raysPerCluster = 20;
1854 table3gpp->m_uLgDS = -0.3 * log10(1 + fcGHz) - 7;
1855 table3gpp->m_sigLgDS = 0.28;
1856 table3gpp->m_uLgASD = -0.08 * log10(1 + fcGHz) + 1.81;
1857 table3gpp->m_sigLgASD = 0.05 * log10(1 + fcGHz) + 0.3;
1858 table3gpp->m_uLgASA = -0.08 * log10(1 + fcGHz) + 1.81;
1859 table3gpp->m_sigLgASA = 0.05 * log10(1 + fcGHz) + 0.3;
1860 table3gpp->m_uLgZSA = -0.04 * log10(1 + fcGHz) + 0.92;
1861 table3gpp->m_sigLgZSA = -0.07 * log10(1 + fcGHz) + 0.41;
1862 table3gpp->m_uLgZSD = -0.04 * log10(1 + fcGHz) + 0.92;
1863 table3gpp->m_sigLgZSD = -0.07 * log10(1 + fcGHz) + 0.41;
1864 table3gpp->m_offsetZOD = 0;
1865 table3gpp->m_cDS = 11;
1866 table3gpp->m_cASD = 22;
1867 table3gpp->m_cASA = 22;
1868 table3gpp->m_cZSA = 7;
1869 table3gpp->m_uK = 0;
1870 table3gpp->m_sigK = 0;
1871 table3gpp->m_rTau = 2.1;
1872 table3gpp->m_uXpr = 8;
1873 table3gpp->m_sigXpr = 3;
1874 table3gpp->m_perClusterShadowingStd = 4;
1876 for (uint8_t row = 0; row < 6; row++)
1878 for (uint8_t column = 0; column < 6; column++)
1891 std::string freqBand = (fcGHz < 13) ?
"S" :
"Ka";
1893 double elevAngle = 0;
1894 bool isSatellite =
false;
1901 if (DynamicCast<GeocentricConstantPositionMobilityModel>(
1902 ConstCast<MobilityModel>(aMob)) &&
1903 DynamicCast<GeocentricConstantPositionMobilityModel>(
1904 ConstCast<MobilityModel>(bMob)))
1908 DynamicCast<GeocentricConstantPositionMobilityModel>(aMobNonConst);
1910 DynamicCast<GeocentricConstantPositionMobilityModel>(bMobNonConst);
1912 if (aNTNMob->GetGeographicPosition().z <
1913 bNTNMob->GetGeographicPosition().z)
1915 elevAngle = aNTNMob->GetElevationAngle(bNTNMob);
1916 if (bNTNMob->GetGeographicPosition().z > 50000)
1923 elevAngle = bNTNMob->GetElevationAngle(aNTNMob);
1924 if (aNTNMob->GetGeographicPosition().z > 50000)
1932 NS_FATAL_ERROR(
"Mobility Models needs to be of type Geocentric for NTN scenarios");
1936 int elevAngleQuantized = (elevAngle < 10) ? 10 : round(elevAngle / 10) * 10;
1940 if (channelCondition->IsLos())
1942 table3gpp->m_uLgDS =
1944 table3gpp->m_sigLgDS =
1948 table3gpp->m_uLgASD =
1951 table3gpp->m_sigLgASD =
1954 table3gpp->m_uLgASA =
1956 table3gpp->m_sigLgASA =
1958 table3gpp->m_uLgZSA =
1960 table3gpp->m_sigLgZSA =
1964 table3gpp->m_uLgZSD =
1967 table3gpp->m_sigLgZSD =
1978 table3gpp->m_sigXpr =
1995 for (uint8_t row = 0; row < 7; row++)
1997 for (uint8_t column = 0; column < 7; column++)
2003 else if (channelCondition->IsNlos())
2006 table3gpp->m_uLgDS =
2008 table3gpp->m_sigLgDS =
2010 table3gpp->m_uLgASD =
2014 table3gpp->m_uLgASA =
2018 table3gpp->m_uLgZSA =
2022 table3gpp->m_uLgZSD =
2030 table3gpp->m_sigXpr =
2047 for (uint8_t row = 0; row < 6; row++)
2049 for (uint8_t column = 0; column < 6; column++)
2058 if (channelCondition->IsLos())
2060 table3gpp->m_uLgDS =
2062 table3gpp->m_sigLgDS =
2064 table3gpp->m_uLgASD =
2066 table3gpp->m_sigLgASD =
2068 table3gpp->m_uLgASA =
2070 table3gpp->m_sigLgASA =
2072 table3gpp->m_uLgZSA =
2074 table3gpp->m_sigLgZSA =
2076 table3gpp->m_uLgZSD =
2078 table3gpp->m_sigLgZSD =
2088 table3gpp->m_sigXpr =
2090 table3gpp->m_numOfCluster =
2092 table3gpp->m_raysPerCluster =
NTNUrbanLOS.at(freqBand).at(
2102 table3gpp->m_perClusterShadowingStd =
NTNUrbanLOS.at(freqBand).at(
2105 for (uint8_t row = 0; row < 7; row++)
2107 for (uint8_t column = 0; column < 7; column++)
2113 else if (channelCondition->IsNlos())
2115 table3gpp->m_uLgDS =
2117 table3gpp->m_sigLgDS =
2119 table3gpp->m_uLgASD =
2121 table3gpp->m_sigLgASD =
2123 table3gpp->m_uLgASA =
2125 table3gpp->m_sigLgASA =
2127 table3gpp->m_uLgZSA =
2129 table3gpp->m_sigLgZSA =
2131 table3gpp->m_uLgZSD =
2133 table3gpp->m_sigLgZSD =
2143 table3gpp->m_sigXpr =
2145 table3gpp->m_numOfCluster =
2147 table3gpp->m_raysPerCluster =
NTNUrbanNLOS.at(freqBand).at(
2157 table3gpp->m_perClusterShadowingStd =
NTNUrbanNLOS.at(freqBand).at(
2160 for (uint8_t row = 0; row < 6; row++)
2162 for (uint8_t column = 0; column < 6; column++)
2164 table3gpp->m_sqrtC[row][column] =
2172 if (channelCondition->IsLos())
2174 table3gpp->m_uLgDS =
2176 table3gpp->m_sigLgDS =
2178 table3gpp->m_uLgASD =
2180 table3gpp->m_sigLgASD =
2182 table3gpp->m_uLgASA =
2184 table3gpp->m_sigLgASA =
2186 table3gpp->m_uLgZSA =
2188 table3gpp->m_sigLgZSA =
2190 table3gpp->m_uLgZSD =
2192 table3gpp->m_sigLgZSD =
2202 table3gpp->m_sigXpr =
2216 table3gpp->m_perClusterShadowingStd =
NTNSuburbanLOS.at(freqBand).at(
2219 for (uint8_t row = 0; row < 7; row++)
2221 for (uint8_t column = 0; column < 7; column++)
2227 else if (channelCondition->IsNlos())
2229 table3gpp->m_uLgDS =
2231 table3gpp->m_sigLgDS =
2233 table3gpp->m_uLgASD =
2235 table3gpp->m_sigLgASD =
2237 table3gpp->m_uLgASA =
2239 table3gpp->m_sigLgASA =
2241 table3gpp->m_uLgZSA =
2243 table3gpp->m_sigLgZSA =
2245 table3gpp->m_uLgZSD =
2247 table3gpp->m_sigLgZSD =
2257 table3gpp->m_sigXpr =
2271 table3gpp->m_perClusterShadowingStd =
NTNSuburbanNLOS.at(freqBand).at(
2274 for (uint8_t row = 0; row < 6; row++)
2276 for (uint8_t column = 0; column < 6; column++)
2285 if (channelCondition->IsLos())
2287 table3gpp->m_uLgDS =
2289 table3gpp->m_sigLgDS =
2291 table3gpp->m_uLgASD =
2293 table3gpp->m_sigLgASD =
2295 table3gpp->m_uLgASA =
2297 table3gpp->m_sigLgASA =
2299 table3gpp->m_uLgZSA =
2301 table3gpp->m_sigLgZSA =
2303 table3gpp->m_uLgZSD =
2305 table3gpp->m_sigLgZSD =
2315 table3gpp->m_sigXpr =
2317 table3gpp->m_numOfCluster =
2319 table3gpp->m_raysPerCluster =
NTNRuralLOS.at(freqBand).at(
2329 table3gpp->m_perClusterShadowingStd =
NTNRuralLOS.at(freqBand).at(
2332 for (uint8_t row = 0; row < 7; row++)
2334 for (uint8_t column = 0; column < 7; column++)
2340 else if (channelCondition->IsNlos())
2342 table3gpp->m_uLgDS =
2344 table3gpp->m_sigLgDS =
2346 table3gpp->m_uLgASD =
2348 table3gpp->m_sigLgASD =
2350 table3gpp->m_uLgASA =
2352 table3gpp->m_sigLgASA =
2354 table3gpp->m_uLgZSA =
2356 table3gpp->m_sigLgZSA =
2358 table3gpp->m_uLgZSD =
2360 table3gpp->m_sigLgZSD =
2370 table3gpp->m_sigXpr =
2372 table3gpp->m_numOfCluster =
2374 table3gpp->m_raysPerCluster =
NTNRuralNLOS.at(freqBand).at(
2384 table3gpp->m_perClusterShadowingStd =
NTNRuralNLOS.at(freqBand).at(
2387 if (freqBand ==
"S")
2389 for (uint8_t row = 0; row < 6; row++)
2391 for (uint8_t column = 0; column < 6; column++)
2393 table3gpp->m_sqrtC[row][column] =
2398 else if (freqBand ==
"Ka")
2400 for (uint8_t row = 0; row < 6; row++)
2402 for (uint8_t column = 0; column < 6; column++)
2404 table3gpp->m_sqrtC[row][column] =
2415 table3gpp->m_uLgASD = std::numeric_limits<double>::min();
2416 table3gpp->m_sigLgASD = 0;
2417 table3gpp->m_uLgZSD = std::numeric_limits<double>::min();
2418 table3gpp->m_sigLgZSD = 0;
2435 bool update =
false;
2438 if (!channelCondition->IsEqual(channelParams->m_losCondition, channelParams->m_o2iCondition))
2460 return channelParams->m_generatedTime > channelMatrix->m_generatedTime;
2470 size_t sAntNumElems = aAntenna->GetNumElems();
2471 size_t uAntNumElems = bAntenna->GetNumElems();
2472 size_t chanNumRows = channelMatrix->m_channel.GetNumRows();
2473 size_t chanNumCols = channelMatrix->m_channel.GetNumCols();
2474 return ((uAntNumElems != chanNumRows) || (sAntNumElems != chanNumCols)) &&
2475 ((uAntNumElems != chanNumCols) || (sAntNumElems != chanNumRows));
2487 uint64_t channelParamsKey =
2490 uint64_t channelMatrixKey =
GetKey(aAntenna->GetId(), bAntenna->GetId());
2498 bool updateParams =
false;
2499 bool updateMatrix =
false;
2500 bool notFoundParams =
false;
2501 bool notFoundMatrix =
false;
2514 notFoundParams =
true;
2520 if (notFoundParams || updateParams)
2546 notFoundMatrix =
true;
2551 if (notFoundMatrix || updateMatrix)
2554 channelMatrix =
GetNewChannel(channelParams, table3gpp, aMob, bMob, aAntenna, bAntenna);
2555 channelMatrix->m_antennaPair =
2556 std::make_pair(aAntenna->GetId(),
2564 return channelMatrix;
2573 uint64_t channelParamsKey =
2582 NS_LOG_WARN(
"Channel params map not found. Returning a nullptr.");
2597 channelParams->m_nodeIds =
2599 channelParams->m_losCondition = channelCondition->GetLosCondition();
2600 channelParams->m_o2iCondition = channelCondition->GetO2iCondition();
2605 uint8_t paramNum = 6;
2612 for (uint8_t iter = 0; iter < paramNum; iter++)
2616 for (uint8_t row = 0; row < paramNum; row++)
2619 for (uint8_t column = 0; column < paramNum; column++)
2621 temp += table3gpp->m_sqrtC[row][column] * LSPsIndep[column];
2623 LSPs.push_back(temp);
2635 kFactor = LSPs[1] * table3gpp->m_sigK + table3gpp->m_uK;
2636 DS = pow(10, LSPs[2] * table3gpp->m_sigLgDS + table3gpp->m_uLgDS);
2637 ASD = pow(10, LSPs[3] * table3gpp->m_sigLgASD + table3gpp->m_uLgASD);
2638 ASA = pow(10, LSPs[4] * table3gpp->m_sigLgASA + table3gpp->m_uLgASA);
2639 ZSD = pow(10, LSPs[5] * table3gpp->m_sigLgZSD + table3gpp->m_uLgZSD);
2640 ZSA = pow(10, LSPs[6] * table3gpp->m_sigLgZSA + table3gpp->m_uLgZSA);
2644 DS = pow(10, LSPs[1] * table3gpp->m_sigLgDS + table3gpp->m_uLgDS);
2645 ASD = pow(10, LSPs[2] * table3gpp->m_sigLgASD + table3gpp->m_uLgASD);
2646 ASA = pow(10, LSPs[3] * table3gpp->m_sigLgASA + table3gpp->m_uLgASA);
2647 ZSD = pow(10, LSPs[4] * table3gpp->m_sigLgZSD + table3gpp->m_uLgZSD);
2648 ZSA = pow(10, LSPs[5] * table3gpp->m_sigLgZSA + table3gpp->m_uLgZSA);
2650 ASD = std::min(ASD, 104.0);
2651 ASA = std::min(ASA, 104.0);
2652 ZSD = std::min(ZSD, 52.0);
2653 ZSA = std::min(ZSA, 52.0);
2656 channelParams->m_DS = DS;
2657 channelParams->m_K_factor = kFactor;
2659 NS_LOG_INFO(
"K-factor=" << kFactor <<
", DS=" << DS <<
", ASD=" << ASD <<
", ASA=" << ASA
2660 <<
", ZSD=" << ZSD <<
", ZSA=" << ZSA);
2664 double minTau = 100.0;
2665 for (uint8_t cIndex = 0; cIndex < table3gpp->m_numOfCluster; cIndex++)
2672 clusterDelay.push_back(tau);
2675 for (uint8_t cIndex = 0; cIndex < table3gpp->m_numOfCluster; cIndex++)
2677 clusterDelay[cIndex] -= minTau;
2679 std::sort(clusterDelay.begin(), clusterDelay.end());
2686 double powerSum = 0;
2687 for (uint8_t cIndex = 0; cIndex < table3gpp->m_numOfCluster; cIndex++)
2690 exp(-1 * clusterDelay[cIndex] * (table3gpp->m_rTau - 1) / table3gpp->m_rTau / DS) *
2692 -1 *
m_normalRv->GetValue() * table3gpp->m_perClusterShadowingStd / 10.0);
2694 clusterPower.push_back(power);
2696 channelParams->m_clusterPower = clusterPower;
2698 double powerMax = 0;
2700 for (uint8_t cIndex = 0; cIndex < table3gpp->m_numOfCluster; cIndex++)
2702 channelParams->m_clusterPower[cIndex] =
2703 channelParams->m_clusterPower[cIndex] / powerSum;
2710 double kLinear = pow(10, kFactor / 10.0);
2712 for (uint8_t cIndex = 0; cIndex < table3gpp->m_numOfCluster; cIndex++)
2716 clusterPowerForAngles.push_back(channelParams->m_clusterPower[cIndex] /
2718 kLinear / (1 + kLinear));
2722 clusterPowerForAngles.push_back(channelParams->m_clusterPower[cIndex] /
2725 if (powerMax < clusterPowerForAngles[cIndex])
2727 powerMax = clusterPowerForAngles[cIndex];
2733 for (uint8_t cIndex = 0; cIndex < table3gpp->m_numOfCluster; cIndex++)
2735 clusterPowerForAngles.push_back(channelParams->m_clusterPower[cIndex]);
2736 if (powerMax < clusterPowerForAngles[cIndex])
2738 powerMax = clusterPowerForAngles[cIndex];
2745 double thresh = 0.0032;
2746 for (uint8_t cIndex = table3gpp->m_numOfCluster; cIndex > 0; cIndex--)
2748 if (clusterPowerForAngles[cIndex - 1] < thresh * powerMax)
2750 clusterPowerForAngles.erase(clusterPowerForAngles.begin() + cIndex - 1);
2751 channelParams->m_clusterPower.erase(channelParams->m_clusterPower.begin() + cIndex - 1);
2752 clusterDelay.erase(clusterDelay.begin() + cIndex - 1);
2756 NS_ASSERT(channelParams->m_clusterPower.size() < UINT8_MAX);
2757 channelParams->m_reducedClusterNumber = channelParams->m_clusterPower.size();
2762 0.7705 - 0.0433 * kFactor + 2e-4 * pow(kFactor, 2) + 17e-6 * pow(kFactor, 3);
2763 for (uint8_t cIndex = 0; cIndex < channelParams->m_reducedClusterNumber; cIndex++)
2765 clusterDelay[cIndex] = clusterDelay[cIndex] / cTau;
2775 switch (table3gpp->m_numOfCluster)
2820 double cPhi = cNlos;
2824 cPhi *= (1.1035 - 0.028 * kFactor - 2e-3 * pow(kFactor, 2) +
2825 1e-4 * pow(kFactor, 3));
2829 switch (table3gpp->m_numOfCluster)
2865 double cTheta = cNlos;
2866 if (channelCondition->IsLos())
2868 cTheta *= (1.3086 + 0.0339 * kFactor - 0.0077 * pow(kFactor, 2) +
2869 2e-4 * pow(kFactor, 3));
2876 for (uint8_t cIndex = 0; cIndex < channelParams->m_reducedClusterNumber; cIndex++)
2878 double logCalc = -1 * log(clusterPowerForAngles[cIndex] / powerMax);
2879 double angle = 2 * sqrt(logCalc) / 1.4 / cPhi;
2880 clusterAoa.push_back(ASA * angle);
2881 clusterAod.push_back(ASD * angle);
2882 angle = logCalc / cTheta;
2883 clusterZoa.push_back(ZSA * angle);
2884 clusterZod.push_back(ZSD * angle);
2887 Angles sAngle(bMob->GetPosition(), aMob->GetPosition());
2888 Angles uAngle(aMob->GetPosition(), bMob->GetPosition());
2890 for (uint8_t cIndex = 0; cIndex < channelParams->m_reducedClusterNumber; cIndex++)
2897 clusterAoa[cIndex] = clusterAoa[cIndex] * Xn + (
m_normalRv->GetValue() * ASA / 7.0) +
2899 clusterAod[cIndex] = clusterAod[cIndex] * Xn + (
m_normalRv->GetValue() * ASD / 7.0) +
2901 if (channelCondition->IsO2i())
2903 clusterZoa[cIndex] =
2904 clusterZoa[cIndex] * Xn + (
m_normalRv->GetValue() * ZSA / 7.0) + 90;
2908 clusterZoa[cIndex] = clusterZoa[cIndex] * Xn + (
m_normalRv->GetValue() * ZSA / 7.0) +
2911 clusterZod[cIndex] = clusterZod[cIndex] * Xn + (
m_normalRv->GetValue() * ZSD / 7.0) +
2913 table3gpp->m_offsetZOD;
2925 for (uint8_t cIndex = 0; cIndex < channelParams->m_reducedClusterNumber; cIndex++)
2927 clusterAoa[cIndex] -= diffAoa;
2928 clusterAod[cIndex] -= diffAod;
2929 clusterZoa[cIndex] -= diffZsa;
2930 clusterZod[cIndex] -= diffZsd;
2934 double sizeTemp = clusterZoa.size();
2935 for (uint8_t ind = 0; ind < 4; ind++)
2941 angleDegree = clusterAoa;
2944 angleDegree = clusterZoa;
2947 angleDegree = clusterAod;
2950 angleDegree = clusterZod;
2955 for (uint8_t nIndex = 0; nIndex < sizeTemp; nIndex++)
2957 while (angleDegree[nIndex] > 360)
2959 angleDegree[nIndex] -= 360;
2962 while (angleDegree[nIndex] < 0)
2964 angleDegree[nIndex] += 360;
2967 if (ind == 1 || ind == 3)
2969 if (angleDegree[nIndex] > 180)
2971 angleDegree[nIndex] = 360 - angleDegree[nIndex];
2978 clusterAoa = angleDegree;
2981 clusterZoa = angleDegree;
2984 clusterAod = angleDegree;
2987 clusterZod = angleDegree;
2998 for (uint8_t cInd = 0; cInd < channelParams->m_reducedClusterNumber; cInd++)
3000 channelParams->m_clusterPower[cInd] =
3001 channelParams->m_clusterPower[cInd] / pow(10, attenuationDb[cInd] / 10.0);
3006 attenuationDb.push_back(0);
3010 channelParams->m_attenuation_dB = attenuationDb;
3015 channelParams->m_reducedClusterNumber,
3019 channelParams->m_reducedClusterNumber,
3023 channelParams->m_reducedClusterNumber,
3027 channelParams->m_reducedClusterNumber,
3031 const double pow10_uLgZSD = pow(10, table3gpp->m_uLgZSD);
3032 for (uint8_t nInd = 0; nInd < channelParams->m_reducedClusterNumber; nInd++)
3034 for (uint8_t mInd = 0; mInd < table3gpp->m_raysPerCluster; mInd++)
3036 double tempAoa = clusterAoa[nInd] + table3gpp->m_cASA *
offSetAlpha[mInd];
3037 double tempZoa = clusterZoa[nInd] + table3gpp->m_cZSA *
offSetAlpha[mInd];
3038 std::tie(rayAoaRadian[nInd][mInd], rayZoaRadian[nInd][mInd]) =
3041 double tempAod = clusterAod[nInd] + table3gpp->m_cASD *
offSetAlpha[mInd];
3042 double tempZod = clusterZod[nInd] + 0.375 * pow10_uLgZSD *
offSetAlpha[mInd];
3043 std::tie(rayAodRadian[nInd][mInd], rayZodRadian[nInd][mInd]) =
3048 for (uint8_t cIndex = 0; cIndex < channelParams->m_reducedClusterNumber; cIndex++)
3050 Shuffle(&rayAodRadian[cIndex][0], &rayAodRadian[cIndex][table3gpp->m_raysPerCluster]);
3051 Shuffle(&rayAoaRadian[cIndex][0], &rayAoaRadian[cIndex][table3gpp->m_raysPerCluster]);
3052 Shuffle(&rayZodRadian[cIndex][0], &rayZodRadian[cIndex][table3gpp->m_raysPerCluster]);
3053 Shuffle(&rayZoaRadian[cIndex][0], &rayZoaRadian[cIndex][table3gpp->m_raysPerCluster]);
3057 channelParams->m_rayAodRadian = rayAodRadian;
3058 channelParams->m_rayAoaRadian = rayAoaRadian;
3059 channelParams->m_rayZodRadian = rayZodRadian;
3060 channelParams->m_rayZoaRadian = rayZoaRadian;
3066 auto& crossPolarizationPowerRatios = channelParams->m_crossPolarizationPowerRatios;
3068 auto& clusterPhase = channelParams->m_clusterPhase;
3070 const double uXprLinear = pow(10, table3gpp->m_uXpr / 10.0);
3071 const double sigXprLinear = pow(10, table3gpp->m_sigXpr / 10.0);
3074 clusterPhase.resize(channelParams->m_reducedClusterNumber);
3075 crossPolarizationPowerRatios.resize(channelParams->m_reducedClusterNumber);
3076 for (uint8_t nInd = 0; nInd < channelParams->m_reducedClusterNumber; nInd++)
3078 clusterPhase[nInd].resize(table3gpp->m_raysPerCluster);
3079 crossPolarizationPowerRatios[nInd].resize(table3gpp->m_raysPerCluster);
3080 for (uint8_t mInd = 0; mInd < table3gpp->m_raysPerCluster; mInd++)
3082 clusterPhase[nInd][mInd].resize(4);
3084 crossPolarizationPowerRatios[nInd][mInd] =
3085 std::pow(10, (
m_normalRv->GetValue() * sigXprLinear + uXprLinear) / 10.0);
3086 for (uint8_t pInd = 0; pInd < 4; pInd++)
3094 uint8_t cluster1st = 0;
3095 uint8_t cluster2nd = 0;
3096 double maxPower = 0;
3097 for (uint8_t cIndex = 0; cIndex < channelParams->m_reducedClusterNumber; cIndex++)
3099 if (maxPower < channelParams->m_clusterPower[cIndex])
3101 maxPower = channelParams->m_clusterPower[cIndex];
3102 cluster1st = cIndex;
3105 channelParams->m_cluster1st = cluster1st;
3107 for (uint8_t cIndex = 0; cIndex < channelParams->m_reducedClusterNumber; cIndex++)
3109 if (maxPower < channelParams->m_clusterPower[cIndex] && cluster1st != cIndex)
3111 maxPower = channelParams->m_clusterPower[cIndex];
3112 cluster2nd = cIndex;
3115 channelParams->m_cluster2nd = cluster2nd;
3117 NS_LOG_INFO(
"1st strongest cluster:" << +cluster1st
3118 <<
", 2nd strongest cluster:" << +cluster2nd);
3121 if (cluster1st == cluster2nd)
3123 clusterDelay.push_back(clusterDelay[cluster1st] + 1.28 * table3gpp->m_cDS);
3124 clusterDelay.push_back(clusterDelay[cluster1st] + 2.56 * table3gpp->m_cDS);
3126 clusterAoa.push_back(clusterAoa[cluster1st]);
3127 clusterAoa.push_back(clusterAoa[cluster1st]);
3129 clusterZoa.push_back(clusterZoa[cluster1st]);
3130 clusterZoa.push_back(clusterZoa[cluster1st]);
3132 clusterAod.push_back(clusterAod[cluster1st]);
3133 clusterAod.push_back(clusterAod[cluster1st]);
3135 clusterZod.push_back(clusterZod[cluster1st]);
3136 clusterZod.push_back(clusterZod[cluster1st]);
3142 if (cluster1st < cluster2nd)
3152 clusterDelay.push_back(clusterDelay[min] + 1.28 * table3gpp->m_cDS);
3153 clusterDelay.push_back(clusterDelay[min] + 2.56 * table3gpp->m_cDS);
3154 clusterDelay.push_back(clusterDelay[max] + 1.28 * table3gpp->m_cDS);
3155 clusterDelay.push_back(clusterDelay[max] + 2.56 * table3gpp->m_cDS);
3157 clusterAoa.push_back(clusterAoa[min]);
3158 clusterAoa.push_back(clusterAoa[min]);
3159 clusterAoa.push_back(clusterAoa[max]);
3160 clusterAoa.push_back(clusterAoa[max]);
3162 clusterZoa.push_back(clusterZoa[min]);
3163 clusterZoa.push_back(clusterZoa[min]);
3164 clusterZoa.push_back(clusterZoa[max]);
3165 clusterZoa.push_back(clusterZoa[max]);
3167 clusterAod.push_back(clusterAod[min]);
3168 clusterAod.push_back(clusterAod[min]);
3169 clusterAod.push_back(clusterAod[max]);
3170 clusterAod.push_back(clusterAod[max]);
3172 clusterZod.push_back(clusterZod[min]);
3173 clusterZod.push_back(clusterZod[min]);
3174 clusterZod.push_back(clusterZod[max]);
3175 clusterZod.push_back(clusterZod[max]);
3178 channelParams->m_delay = clusterDelay;
3179 channelParams->m_angle.clear();
3180 channelParams->m_angle.push_back(clusterAoa);
3181 channelParams->m_angle.push_back(clusterZoa);
3182 channelParams->m_angle.push_back(clusterAod);
3183 channelParams->m_angle.push_back(clusterZod);
3186 channelParams->m_cachedAngleSincos.resize(channelParams->m_angle.size());
3187 for (
size_t direction = 0; direction < channelParams->m_angle.size(); direction++)
3189 channelParams->m_cachedAngleSincos[direction].resize(
3190 channelParams->m_angle[direction].size());
3191 for (
size_t cluster = 0; cluster < channelParams->m_angle[direction].size(); cluster++)
3193 channelParams->m_cachedAngleSincos[direction][cluster] = {
3194 sin(channelParams->m_angle[direction][cluster] *
DEG2RAD),
3195 cos(channelParams->m_angle[direction][cluster] *
DEG2RAD)};
3215 uint8_t updatedClusterNumber = (channelParams->m_reducedClusterNumber == 1)
3216 ? channelParams->m_reducedClusterNumber + 2
3217 : channelParams->m_reducedClusterNumber + 4;
3219 for (uint8_t cIndex = 0; cIndex < updatedClusterNumber; cIndex++)
3228 dopplerTermAlpha.push_back(alpha);
3229 dopplerTermD.push_back(D);
3231 channelParams->m_alpha = dopplerTermAlpha;
3232 channelParams->m_D = dopplerTermD;
3234 return channelParams;
3253 channelMatrix->m_nodeIds =
3256 bool isSameDirection = (channelParams->m_nodeIds == channelMatrix->m_nodeIds);
3267 if (isSameDirection)
3269 rayAodRadian = channelParams->m_rayAodRadian;
3270 rayAoaRadian = channelParams->m_rayAoaRadian;
3271 rayZodRadian = channelParams->m_rayZodRadian;
3272 rayZoaRadian = channelParams->m_rayZoaRadian;
3276 rayAodRadian = channelParams->m_rayAoaRadian;
3277 rayAoaRadian = channelParams->m_rayAodRadian;
3278 rayZodRadian = channelParams->m_rayZoaRadian;
3279 rayZoaRadian = channelParams->m_rayZodRadian;
3285 size_t uSize = uAntenna->GetNumElems();
3286 size_t sSize = sAntenna->GetNumElems();
3292 uint16_t numOverallCluster = (channelParams->m_cluster1st != channelParams->m_cluster2nd)
3293 ? channelParams->m_reducedClusterNumber + 4
3294 : channelParams->m_reducedClusterNumber + 2;
3296 NS_ASSERT(channelParams->m_reducedClusterNumber <= channelParams->m_clusterPhase.size());
3297 NS_ASSERT(channelParams->m_reducedClusterNumber <= channelParams->m_clusterPower.size());
3298 NS_ASSERT(channelParams->m_reducedClusterNumber <=
3299 channelParams->m_crossPolarizationPowerRatios.size());
3300 NS_ASSERT(channelParams->m_reducedClusterNumber <= rayZoaRadian.size());
3301 NS_ASSERT(channelParams->m_reducedClusterNumber <= rayZodRadian.size());
3302 NS_ASSERT(channelParams->m_reducedClusterNumber <= rayAoaRadian.size());
3303 NS_ASSERT(channelParams->m_reducedClusterNumber <= rayAodRadian.size());
3304 NS_ASSERT(table3gpp->m_raysPerCluster <= channelParams->m_clusterPhase[0].size());
3305 NS_ASSERT(table3gpp->m_raysPerCluster <=
3306 channelParams->m_crossPolarizationPowerRatios[0].size());
3307 NS_ASSERT(table3gpp->m_raysPerCluster <= rayZoaRadian[0].size());
3308 NS_ASSERT(table3gpp->m_raysPerCluster <= rayZodRadian[0].size());
3309 NS_ASSERT(table3gpp->m_raysPerCluster <= rayAoaRadian[0].size());
3310 NS_ASSERT(table3gpp->m_raysPerCluster <= rayAodRadian[0].size());
3312 double x = sMob->GetPosition().x - uMob->GetPosition().x;
3313 double y = sMob->GetPosition().y - uMob->GetPosition().y;
3314 double distance2D = sqrt(x * x + y * y);
3317 double hUt = std::min(sMob->GetPosition().z, uMob->GetPosition().z);
3318 double hBs = std::max(sMob->GetPosition().z, uMob->GetPosition().z);
3320 double distance3D = std::sqrt(distance2D * distance2D + (hBs - hUt) * (hBs - hUt));
3322 Angles sAngle(uMob->GetPosition(), sMob->GetPosition());
3323 Angles uAngle(sMob->GetPosition(), uMob->GetPosition());
3335 for (
size_t polSa = 0; polSa < sAntenna->GetNumPols(); ++polSa)
3337 for (
size_t polUa = 0; polUa < uAntenna->GetNumPols(); ++polUa)
3339 raysPreComp[std::make_pair(polSa, polUa)] =
3340 Complex2DVector(channelParams->m_reducedClusterNumber, table3gpp->m_raysPerCluster);
3345 sinCosA.resize(channelParams->m_reducedClusterNumber);
3346 sinSinA.resize(channelParams->m_reducedClusterNumber);
3347 cosZoA.resize(channelParams->m_reducedClusterNumber);
3348 sinCosD.resize(channelParams->m_reducedClusterNumber);
3349 sinSinD.resize(channelParams->m_reducedClusterNumber);
3350 cosZoD.resize(channelParams->m_reducedClusterNumber);
3351 for (uint8_t nIndex = 0; nIndex < channelParams->m_reducedClusterNumber; nIndex++)
3353 sinCosA[nIndex].resize(table3gpp->m_raysPerCluster);
3354 sinSinA[nIndex].resize(table3gpp->m_raysPerCluster);
3355 cosZoA[nIndex].resize(table3gpp->m_raysPerCluster);
3356 sinCosD[nIndex].resize(table3gpp->m_raysPerCluster);
3357 sinSinD[nIndex].resize(table3gpp->m_raysPerCluster);
3358 cosZoD[nIndex].resize(table3gpp->m_raysPerCluster);
3361 for (uint8_t nIndex = 0; nIndex < channelParams->m_reducedClusterNumber; nIndex++)
3363 for (uint8_t mIndex = 0; mIndex < table3gpp->m_raysPerCluster; mIndex++)
3365 DoubleVector initialPhase = channelParams->m_clusterPhase[nIndex][mIndex];
3367 double k = channelParams->m_crossPolarizationPowerRatios[nIndex][mIndex];
3371 for (uint8_t polUa = 0; polUa < uAntenna->GetNumPols(); ++polUa)
3373 auto [rxFieldPatternPhi, rxFieldPatternTheta] = uAntenna->GetElementFieldPattern(
3374 Angles(channelParams->m_rayAoaRadian[nIndex][mIndex],
3375 channelParams->m_rayZoaRadian[nIndex][mIndex]),
3377 for (uint8_t polSa = 0; polSa < sAntenna->GetNumPols(); ++polSa)
3379 auto [txFieldPatternPhi, txFieldPatternTheta] =
3380 sAntenna->GetElementFieldPattern(
3381 Angles(channelParams->m_rayAodRadian[nIndex][mIndex],
3382 channelParams->m_rayZodRadian[nIndex][mIndex]),
3384 raysPreComp[std::make_pair(polSa, polUa)](nIndex, mIndex) =
3385 std::complex<double>(cos(initialPhase[0]), sin(initialPhase[0])) *
3386 rxFieldPatternTheta * txFieldPatternTheta +
3387 std::complex<double>(cos(initialPhase[1]), sin(initialPhase[1])) *
3388 std::sqrt(1.0 / k) * rxFieldPatternTheta * txFieldPatternPhi +
3389 std::complex<double>(cos(initialPhase[2]), sin(initialPhase[2])) *
3390 std::sqrt(1.0 / k) * rxFieldPatternPhi * txFieldPatternTheta +
3391 std::complex<double>(cos(initialPhase[3]), sin(initialPhase[3])) *
3392 rxFieldPatternPhi * txFieldPatternPhi;
3398 double sinRayZoa = sin(rayZoaRadian[nIndex][mIndex]);
3399 double sinRayAoa = sin(rayAoaRadian[nIndex][mIndex]);
3400 double cosRayAoa = cos(rayAoaRadian[nIndex][mIndex]);
3401 sinCosA[nIndex][mIndex] = sinRayZoa * cosRayAoa;
3402 sinSinA[nIndex][mIndex] = sinRayZoa * sinRayAoa;
3403 cosZoA[nIndex][mIndex] = cos(rayZoaRadian[nIndex][mIndex]);
3407 double sinRayZod = sin(rayZodRadian[nIndex][mIndex]);
3408 double sinRayAod = sin(rayAodRadian[nIndex][mIndex]);
3409 double cosRayAod = cos(rayAodRadian[nIndex][mIndex]);
3410 sinCosD[nIndex][mIndex] = sinRayZod * cosRayAod;
3411 sinSinD[nIndex][mIndex] = sinRayZod * sinRayAod;
3412 cosZoD[nIndex][mIndex] = cos(rayZodRadian[nIndex][mIndex]);
3418 uint8_t numSubClustersAdded = 0;
3419 for (uint8_t nIndex = 0; nIndex < channelParams->m_reducedClusterNumber; nIndex++)
3421 for (
size_t uIndex = 0; uIndex < uSize; uIndex++)
3423 Vector uLoc = uAntenna->GetElementLocation(uIndex);
3425 for (
size_t sIndex = 0; sIndex < sSize; sIndex++)
3427 Vector sLoc = sAntenna->GetElementLocation(sIndex);
3430 if (nIndex != channelParams->m_cluster1st && nIndex != channelParams->m_cluster2nd)
3432 std::complex<double> rays(0, 0);
3433 for (uint8_t mIndex = 0; mIndex < table3gpp->m_raysPerCluster; mIndex++)
3436 double rxPhaseDiff =
3438 (sinCosA[nIndex][mIndex] * uLoc.x + sinSinA[nIndex][mIndex] * uLoc.y +
3439 cosZoA[nIndex][mIndex] * uLoc.z);
3441 double txPhaseDiff =
3443 (sinCosD[nIndex][mIndex] * sLoc.x + sinSinD[nIndex][mIndex] * sLoc.y +
3444 cosZoD[nIndex][mIndex] * sLoc.z);
3447 rays += raysPreComp[std::make_pair(sAntenna->GetElemPol(sIndex),
3448 uAntenna->GetElemPol(uIndex))](nIndex,
3450 std::complex<double>(cos(rxPhaseDiff), sin(rxPhaseDiff)) *
3451 std::complex<double>(cos(txPhaseDiff), sin(txPhaseDiff));
3454 sqrt(channelParams->m_clusterPower[nIndex] / table3gpp->m_raysPerCluster);
3455 hUsn(uIndex, sIndex, nIndex) = rays;
3459 std::complex<double> raysSub1(0, 0);
3460 std::complex<double> raysSub2(0, 0);
3461 std::complex<double> raysSub3(0, 0);
3463 for (uint8_t mIndex = 0; mIndex < table3gpp->m_raysPerCluster; mIndex++)
3467 double rxPhaseDiff =
3469 (sinCosA[nIndex][mIndex] * uLoc.x + sinSinA[nIndex][mIndex] * uLoc.y +
3470 cosZoA[nIndex][mIndex] * uLoc.z);
3472 double txPhaseDiff =
3474 (sinCosD[nIndex][mIndex] * sLoc.x + sinSinD[nIndex][mIndex] * sLoc.y +
3475 cosZoD[nIndex][mIndex] * sLoc.z);
3477 std::complex<double> raySub =
3478 raysPreComp[std::make_pair(sAntenna->GetElemPol(sIndex),
3479 uAntenna->GetElemPol(uIndex))](nIndex,
3481 std::complex<double>(cos(rxPhaseDiff), sin(rxPhaseDiff)) *
3482 std::complex<double>(cos(txPhaseDiff), sin(txPhaseDiff));
3506 sqrt(channelParams->m_clusterPower[nIndex] / table3gpp->m_raysPerCluster);
3508 sqrt(channelParams->m_clusterPower[nIndex] / table3gpp->m_raysPerCluster);
3510 sqrt(channelParams->m_clusterPower[nIndex] / table3gpp->m_raysPerCluster);
3511 hUsn(uIndex, sIndex, nIndex) = raysSub1;
3514 channelParams->m_reducedClusterNumber + numSubClustersAdded) = raysSub2;
3517 channelParams->m_reducedClusterNumber + numSubClustersAdded + 1) =
3522 if (nIndex == channelParams->m_cluster1st || nIndex == channelParams->m_cluster2nd)
3524 numSubClustersAdded += 2;
3531 std::complex<double> phaseDiffDueToDistance(cos(-2 * M_PI * distance3D / lambda),
3532 sin(-2 * M_PI * distance3D / lambda));
3536 const double sinUAngleAz = sin(uAngle.
GetAzimuth());
3537 const double cosUAngleAz = cos(uAngle.
GetAzimuth());
3540 const double sinSAngleAz = sin(sAngle.
GetAzimuth());
3541 const double cosSAngleAz = cos(sAngle.
GetAzimuth());
3543 for (
size_t uIndex = 0; uIndex < uSize; uIndex++)
3545 Vector uLoc = uAntenna->GetElementLocation(uIndex);
3546 double rxPhaseDiff = 2 * M_PI *
3547 (sinUAngleIncl * cosUAngleAz * uLoc.x +
3548 sinUAngleIncl * sinUAngleAz * uLoc.y + cosUAngleIncl * uLoc.z);
3550 for (
size_t sIndex = 0; sIndex < sSize; sIndex++)
3552 Vector sLoc = sAntenna->GetElementLocation(sIndex);
3553 std::complex<double> ray(0, 0);
3554 double txPhaseDiff =
3556 (sinSAngleIncl * cosSAngleAz * sLoc.x + sinSAngleIncl * sinSAngleAz * sLoc.y +
3557 cosSAngleIncl * sLoc.z);
3559 auto [rxFieldPatternPhi, rxFieldPatternTheta] = uAntenna->GetElementFieldPattern(
3561 uAntenna->GetElemPol(uIndex));
3562 auto [txFieldPatternPhi, txFieldPatternTheta] = sAntenna->GetElementFieldPattern(
3564 sAntenna->GetElemPol(sIndex));
3566 ray = (rxFieldPatternTheta * txFieldPatternTheta -
3567 rxFieldPatternPhi * txFieldPatternPhi) *
3568 phaseDiffDueToDistance *
3569 std::complex<double>(cos(rxPhaseDiff), sin(rxPhaseDiff)) *
3570 std::complex<double>(cos(txPhaseDiff), sin(txPhaseDiff));
3572 double kLinear = pow(10, channelParams->m_K_factor / 10.0);
3574 hUsn(uIndex, sIndex, 0) =
3575 sqrt(1.0 / (kLinear + 1)) * hUsn(uIndex, sIndex, 0) +
3576 sqrt(kLinear / (1 + kLinear)) * ray /
3578 channelParams->m_attenuation_dB[0] / 10.0);
3579 for (
size_t nIndex = 1; nIndex < hUsn.GetNumPages(); nIndex++)
3581 hUsn(uIndex, sIndex, nIndex) *=
3582 sqrt(1.0 / (kLinear + 1));
3588 NS_LOG_DEBUG(
"Husn (sAntenna, uAntenna):" << sAntenna->GetId() <<
", " << uAntenna->GetId());
3589 for (
size_t cIndex = 0; cIndex < hUsn.GetNumPages(); cIndex++)
3591 for (
size_t rowIdx = 0; rowIdx < hUsn.GetNumRows(); rowIdx++)
3593 for (
size_t colIdx = 0; colIdx < hUsn.GetNumCols(); colIdx++)
3595 NS_LOG_DEBUG(
" " << hUsn(rowIdx, colIdx, cIndex) <<
",");
3600 NS_LOG_INFO(
"size of coefficient matrix (rows, columns, clusters) = ("
3601 << hUsn.GetNumRows() <<
", " << hUsn.GetNumCols() <<
", " << hUsn.GetNumPages()
3603 channelMatrix->m_channel = hUsn;
3604 return channelMatrix;
3607std::pair<double, double>
3610 inclinationRad =
WrapTo2Pi(inclinationRad);
3611 if (inclinationRad > M_PI)
3614 inclinationRad -= M_PI;
3620 NS_ASSERT_MSG(0 <= inclinationRad && inclinationRad <= M_PI,
3621 "inclinationRad=" << inclinationRad <<
" not valid, should be in [0, pi]");
3623 "azimuthRad=" << azimuthRad <<
" not valid, should be in [0, 2*pi]");
3625 return std::make_pair(azimuthRad, inclinationRad);
3636 auto clusterNum = clusterAOA.size();
3649 double thetaSb = 110;
3660 if (channelParams->m_nonSelfBlocking.empty())
3671 table.push_back(90);
3678 table.push_back(90);
3680 table.push_back(10);
3682 channelParams->m_nonSelfBlocking.push_back(table);
3687 double deltaX = sqrt(pow(channelParams->m_preLocUT.x - channelParams->m_locUT.x, 2) +
3688 pow(channelParams->m_preLocUT.y - channelParams->m_locUT.y, 2));
3715 R = exp(-1 * (deltaX / corrDis +
3716 (
Now().GetSeconds() - channelParams->m_generatedTime.GetSeconds()) /
3721 R = exp(-1 * (deltaX / corrDis));
3726 <<
Now().GetSeconds() - channelParams->m_generatedTime.GetSeconds()
3727 <<
" correlation:" << R);
3737 if (R * R * (-0.069) + R * 1.074 - 0.002 <
3740 R = R * R * (-0.069) + R * 1.074 - 0.002;
3745 channelParams->m_nonSelfBlocking[blockInd][
PHI_INDEX] =
3746 R * channelParams->m_nonSelfBlocking[blockInd][
PHI_INDEX] +
3753 for (std::size_t cInd = 0; cInd < clusterNum; cInd++)
3755 NS_ASSERT_MSG(clusterAOA[cInd] >= 0 && clusterAOA[cInd] <= 360,
3756 "the AOA should be the range of [0,360]");
3757 NS_ASSERT_MSG(clusterZOA[cInd] >= 0 && clusterZOA[cInd] <= 180,
3758 "the ZOA should be the range of [0,180]");
3761 NS_LOG_INFO(
"AOA=" << clusterAOA[cInd] <<
" Block Region[" << phiSb - xSb / 2.0 <<
","
3762 << phiSb + xSb / 2.0 <<
"]");
3763 NS_LOG_INFO(
"ZOA=" << clusterZOA[cInd] <<
" Block Region[" << thetaSb - ySb / 2.0 <<
","
3764 << thetaSb + ySb / 2.0 <<
"]");
3765 if (std::abs(clusterAOA[cInd] - phiSb) < (xSb / 2.0) &&
3766 std::abs(clusterZOA[cInd] - thetaSb) < (ySb / 2.0))
3768 powerAttenuation[cInd] += 30;
3770 <<
"] is blocked by self blocking region and reduce 30 dB power,"
3771 "the attenuation is ["
3772 << powerAttenuation[cInd] <<
" dB]");
3780 (0.5 * erfc(-1 * channelParams->m_nonSelfBlocking[blockInd][
PHI_INDEX] / sqrt(2))) *
3792 double xK = channelParams->m_nonSelfBlocking[blockInd][
X_INDEX];
3793 double thetaK = channelParams->m_nonSelfBlocking[blockInd][
THETA_INDEX];
3794 double yK = channelParams->m_nonSelfBlocking[blockInd][
Y_INDEX];
3796 NS_LOG_INFO(
"AOA=" << clusterAOA[cInd] <<
" Block Region[" << phiK - xK <<
","
3797 << phiK + xK <<
"]");
3798 NS_LOG_INFO(
"ZOA=" << clusterZOA[cInd] <<
" Block Region[" << thetaK - yK <<
","
3799 << thetaK + yK <<
"]");
3801 if (std::abs(clusterAOA[cInd] - phiK) < (xK) &&
3802 std::abs(clusterZOA[cInd] - thetaK) < (yK))
3804 double A1 = clusterAOA[cInd] - (phiK + xK / 2.0);
3805 double A2 = clusterAOA[cInd] - (phiK - xK / 2.0);
3806 double Z1 = clusterZOA[cInd] - (thetaK + yK / 2.0);
3807 double Z2 = clusterZOA[cInd] - (thetaK - yK / 2.0);
3814 if (xK / 2.0 < clusterAOA[cInd] - phiK && clusterAOA[cInd] - phiK <= xK)
3822 if (-1 * xK < clusterAOA[cInd] - phiK && clusterAOA[cInd] - phiK <= -1 * xK / 2.0)
3831 if (yK / 2.0 < clusterZOA[cInd] - thetaK && clusterZOA[cInd] - thetaK <= yK)
3839 if (-1 * yK < clusterZOA[cInd] - thetaK &&
3840 clusterZOA[cInd] - thetaK <= -1 * yK / 2.0)
3850 atan(signA1 * M_PI / 2.0 *
3851 sqrt(M_PI / lambda * channelParams->m_nonSelfBlocking[blockInd][
R_INDEX] *
3855 atan(signA2 * M_PI / 2.0 *
3856 sqrt(M_PI / lambda * channelParams->m_nonSelfBlocking[blockInd][
R_INDEX] *
3860 atan(signZ1 * M_PI / 2.0 *
3861 sqrt(M_PI / lambda * channelParams->m_nonSelfBlocking[blockInd][
R_INDEX] *
3865 atan(signZ2 * M_PI / 2.0 *
3866 sqrt(M_PI / lambda * channelParams->m_nonSelfBlocking[blockInd][
R_INDEX] *
3869 double lDb = -20 * log10(1 - (fA1 + fA2) * (fZ1 + fZ2));
3870 powerAttenuation[cInd] += lDb;
3871 NS_LOG_INFO(
"Cluster[" << +cInd <<
"] is blocked by no-self blocking, the loss is ["
3876 return powerAttenuation;
3882 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.
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.
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 > MakePointerAccessor(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.
Ptr< const AttributeChecker > MakeBooleanChecker()
Ptr< const AttributeAccessor > MakeIntegerAccessor(T1 a1)
Table3gppParams
The enumerator used for code clarity when performing parameter assignment in GetThreeGppTable.
static const std::map< std::string, std::map< int, std::vector< float > > > NTNSuburbanNLOS
The nested map containing the 3GPP value tables for the NTN Suburban NLOS scenario.
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 std::map< std::string, std::map< int, std::vector< float > > > NTNSuburbanLOS
The nested map containing the 3GPP value tables for the NTN Suburban LOS scenario.
static const double offSetAlpha[20]
The ray offset angles within a cluster, given for rms angle spread normalized to 1.
static const std::map< std::string, std::map< int, std::vector< float > > > NTNUrbanNLOS
The nested map containing the 3GPP value tables for the NTN Urban NLOS scenario.
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
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 double sqrtC_UMi_LOS[7][7]
The square root matrix for UMi LOS, which is generated using the Cholesky decomposition according to ...
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 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 std::map< std::string, std::map< int, std::vector< float > > > NTNRuralLOS
The nested map containing the 3GPP value tables for the NTN Rural LOS scenario.
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 > > > NTNDenseUrbanLOS
The nested map containing the 3GPP value tables for the NTN Dense Urban LOS 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 double sqrtC_RMa_LOS[7][7]
The square root matrix for RMa LOS, which is generated using the Cholesky decomposition according to ...
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...
Ptr< const AttributeChecker > MakeStringChecker()
static const std::map< std::string, std::map< int, std::vector< float > > > NTNDenseUrbanNLOS
The nested map containing the 3GPP value tables for the NTN Dense Urban NLOS scenario.
Ptr< const AttributeAccessor > MakeStringAccessor(T1 a1)
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
static const std::map< std::string, std::map< int, std::vector< float > > > NTNRuralNLOS
The nested map containing the 3GPP value tables for the NTN Rural NLOS scenario The outer key specifi...
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
Ptr< const AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
static const std::map< std::string, std::map< int, std::vector< float > > > NTNUrbanLOS
The nested map containing the 3GPP value tables for the NTN Urban LOS scenario.