A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
three-gpp-channel-model.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2015, NYU WIRELESS, Tandon School of Engineering,
3 * New York University
4 * Copyright (c) 2019 SIGNET Lab, Department of Information Engineering,
5 * University of Padova
6 * Copyright (c) 2026, CTTC, Centre Tecnologic de Telecomunicacions de Catalunya
7 *
8 * SPDX-License-Identifier: GPL-2.0-only
9 */
10
11#ifndef THREE_GPP_CHANNEL_H
12#define THREE_GPP_CHANNEL_H
13
15
16#include "ns3/channel-condition-model.h"
17
18#include <unordered_map>
19
20namespace ns3
21{
22
23class MobilityModel;
24
25/**
26 * ThreeGppChannelModel extends MatrixBasedChannelModel and represents a channel
27 * model based on 3GPP specifications, including functionality for
28 * managing channel conditions, scenarios, and frequency requirements.
29 */
31{
32 public:
33 /**
34 * Constructor
35 */
37
38 /**
39 * Destructor
40 */
41 ~ThreeGppChannelModel() override;
42
43 void DoDispose() override;
44
45 /**
46 * Get the type ID
47 * @return the object TypeId
48 */
49 static TypeId GetTypeId();
50
51 /**
52 * Set the channel condition model
53 * @param model a pointer to the ChannelConditionModel object
54 */
56
57 /**
58 * Get the associated channel condition model
59 * @return a pointer to the ChannelConditionModel object
60 */
62
63 /**
64 * Sets the center frequency of the model
65 * @param f the center frequency in Hz
66 */
67 void SetFrequency(double f);
68
69 /**
70 * Returns the center frequency
71 * @return the center frequency in Hz
72 */
73 double GetFrequency() const;
74
75 /**
76 * Sets the propagation scenario
77 * @param scenario the propagation scenario
78 */
79 void SetScenario(const std::string& scenario);
80
81 /**
82 * Returns the propagation scenario
83 * @return the propagation scenario
84 */
85 std::string GetScenario() const;
86
87 /**
88 * Looks for the channel matrix associated with the aMob and bMob pair in m_channelMatrixMap.
89 * If found, it checks if it has to be updated. If not found or if it has to
90 * be updated, it generates a new uncorrelated channel matrix using the
91 * method GetNewChannel and updates m_channelMap.
92 *
93 * @param aMob mobility model of the a device
94 * @param bMob mobility model of the b device
95 * @param aAntenna antenna of the a device
96 * @param bAntenna antenna of the b device
97 * @return the channel matrix
98 */
102 Ptr<const PhasedArrayModel> bAntenna) override;
103
104 /**
105 * Looks for the channel params associated with the aMob and bMob pair in
106 * m_channelParamsMap. If not found, it will return a nullptr.
107 *
108 * @param aMob mobility model of the a device
109 * @param bMob mobility model of the b device
110 * @return the channel params
111 */
113 Ptr<const MobilityModel> bMob) const override;
114 /**
115 * @brief Assign a fixed random variable stream number to the random variables
116 * used by this model.
117 *
118 * @param stream first stream index to use
119 * @return the number of stream indices assigned by this model
120 */
121 int64_t AssignStreams(int64_t stream);
122
123 /**
124 * Wrap an (azimuth, inclination) angle pair in a valid range.
125 * Specifically, inclination must be in [0, M_PI] and azimuth in [0, 2*M_PI).
126 * If the inclination angle is outside its range, the azimuth angle is
127 * rotated by M_PI.
128 * This method aims specifically at solving the problem of generating angles at
129 * the boundaries of the angle domain, specifically, generating angle distributions
130 * close to inclinationRad=0 and inclinationRad=M_PI.
131 *
132 * @param azimuthRad the azimuth angle in radians
133 * @param inclinationRad the inclination angle in radians
134 * @return the wrapped (azimuth, inclination) angle pair in radians
135 */
136 static std::pair<double, double> WrapAngles(double azimuthRad, double inclinationRad);
137
138 /**
139 * Extends the struct ChannelParams by including information that is used
140 * within the ThreeGppChannelModel class
141 */
143 {
144 /// contains the information about the LOS state of the channel
146 /// contains the information about the O2I state of the channel
148 /*The following parameters are stored for spatially consistent updating. The notation is
149 that of 3GPP technical reports, but it can apply also to other channel realizations*/
150 /// store the blockages
152 /** stores the normal variable for random angles angle[cluster][id]
153 * generated for equation (7.6-11)-(7.6-14), where id follows
154 * MatrixBasedChannelModel::{AOA,ZOA,AOD,ZOD}_INDEX ordering.
155 */
157 /// delay spread
158 double m_DS;
159 /// K factor
161 /// reduced cluster number
163 /** The signs of the XN per cluster -1 or +1, per NLOS used in channel consistency procedure
164 */
165 std::vector<int> m_clusterXnNlosSign;
166 Double2DVector m_rayAodRadian; //!< the vector containing AOD angles
167 Double2DVector m_rayAoaRadian; //!< the vector containing AOA angles
168 Double2DVector m_rayZodRadian; //!< the vector containing ZOD angles
169 Double2DVector m_rayZoaRadian; //!< the vector containing ZOA angles
170 Double3DVector m_clusterPhase; //!< the initial random phases
171 Double2DVector m_crossPolarizationPowerRatios; //!< cross-polarization power ratios
172 double m_dis2D; //!< 2D distance between tx and rx
173 double m_dis3D; //!< 3D distance between tx and rx
174 DoubleVector m_clusterShadowing; //!< cluster shadowing
175 DoubleVector m_clusterPower; //!< cluster powers
176 DoubleVector m_attenuation_dB; //!< vector that stores the attenuation of the blockage
177 uint8_t m_cluster1st; //!< index of the first strongest cluster
178 uint8_t m_cluster2nd; //!< index of the second-strongest cluster
179 Vector m_txSpeed; //!< TX velocity
180 Vector m_rxSpeed; //!< RX velocity
181 DoubleVector m_delayConsistency; //!< cluster delay for consistency update
182 /**
183 * The effective 2D displacement used to determine whether a channel-consistency update
184 * can be applied, computed between consecutive endpoint positions.
185 *
186 * Since channel parameters are stored using a reciprocal key, endpoint-specific state is
187 * handled using a canonical ordering by node ID (min ID / max ID). The displacement is
188 * computed as the maximum of the two endpoint displacements since the last
189 * generation/update.
190 */
192 /**
193 * 2D displacement of the canonical relative position vector between the two endpoints
194 * since the last generation/update.
195 *
196 * This corresponds to the change in the link geometry in the horizontal plane and is used
197 * by Procedure A updates that evolve cluster-level random variables as a function of
198 * displacement (e.g., per-cluster shadowing correlation).
199 */
201 /**
202 * Position of the endpoint with the smallest node ID (canonical endpoint ordering) at the
203 * time of the last channel parameter generation/update.
204 */
206 /**
207 * Position of the endpoint with the largest node ID (canonical endpoint ordering) at the
208 * time of the last channel parameter generation/update.
209 */
211 /**
212 * Canonical 2D relative position vector (first -> second) stored at the time of the last
213 * channel parameter generation/update.
214 *
215 * This is used to compute m_relativeDisplacement2D as the 2D displacement of the link
216 * geometry between consecutive updates.
217 */
219 };
220
221 /**
222 * Data structure that stores the parameters of 3GPP TR 38.901, Table 7.5-6,
223 * for a certain scenario
224 */
225 struct ParamsTable : SimpleRefCount<ParamsTable>
226 {
227 uint8_t m_numOfCluster = 0; //!< Number of clusters
228 uint8_t m_raysPerCluster = 0; //!< Number of rays per cluster
229 double m_uLgDS = 0; //!< Mean value of 10-base logarithm of delay spread
230 double m_sigLgDS = 0; //!< Standard deviation value of 10-base logarithm of delay spread
231 //! Mean value of 10-base logarithm of azimuth angle spread of departure
232 double m_uLgASD = 0;
233 //! Standard deviation of 10-base logarithm of azimuth angle spread of departure
234 double m_sigLgASD = 0;
235 //! Mean value of 10-base logarithm of azimuth angle spread of arrival
236 double m_uLgASA = 0;
237 //! Standard deviation of 10-base logarithm of azimuth angle spread of arrival
238 double m_sigLgASA = 0;
239 //! Mean value of 10-base logarithm of zenith angle spread of arrival
240 double m_uLgZSA = 0;
241 //! Standard deviation of 10-base logarithm of zenith angle spread of arrival
242 double m_sigLgZSA = 0;
243 //! Mean value of 10-base logarithm of zenith angle spread of departure
244 double m_uLgZSD = 0;
245 //! Standard deviation of 10-base logarithm of zenith angle spread of departure
246 double m_sigLgZSD = 0;
247 double m_offsetZOD = 0; //!< Offset of a zenith angle of departure
248 double m_cDS = 0; //!< Cluster DS
249 double m_cASD = 0; //!< Cluster ASD (Azimuth angle Spread of Departure)
250 double m_cASA = 0; //!< Cluster ASA (Azimuth angle Spread of Arrival)
251 double m_cZSA = 0; //!< Cluster ZSA (Zenith angle Spread of Arrival)
252 double m_uK = 0; //!< Mean of K-factor
253 double m_sigK = 0; //!< Standard deviation of K-factor
254 double m_rTau = 0; //!< Delay scaling parameter
255 double m_uXpr = 0; //!< Mean of Cross-Polarization Ratio
256 double m_sigXpr = 0; //!< Standard deviation of Cross-Polarization Ratio
257 double m_perClusterShadowingStd = 0; //!< Per cluster shadowing standard deviation
258 //! Correlation distance for spatial consistency (7.6.3.1-2) in meters.
259 //! Default value set to 1, because V2V and NTN models documentations do not provide this
260 //! parameter value
262 //! The spatial correlation distance for the random variable determining the centre of the
263 //! blocker in meters; Default value set to 1, because V2V and NTN models documentations do
264 //! not provide
265 // this parameter value
267
268 /**
269 * For LOS, LSP is following the order of [SF,K,DS,ASD,ASA,ZSD,ZSA].
270 * For NLOS, LSP is following the order of [SF,DS,ASD,ASA,ZSD,ZSA].
271 * https://github.com/nyuwireless-unipd/ns3-mmwave/blob/master/src/mmwave/model/BeamFormingMatrix/SqrtMatrix.m
272 */
273 double m_sqrtC[7][7];
274 };
275
276 /**
277 * Get the parameters needed to apply the channel generation procedure
278 * @param aMob the mobility model of node A
279 * @param bMob the mobility model of node B
280 * @param channelCondition the channel condition
281 * @return the parameters table
282 */
286 Ptr<const ChannelCondition> channelCondition) const;
287
288 protected:
289 /**
290 * Update distance- and displacement-related values between two nodes.
291 *
292 * The function computes the current 2D and 3D distances between two mobility models.
293 *
294 * It also computes two 2D displacement measures with respect to previously stored state.
295 * Since channel parameters are stored using a reciprocal key, endpoint-specific state is
296 * handled using a canonical ordering by node ID (min ID / max ID).
297 * ``endpointDisplacement2D`` is the maximum 2D displacement of the two endpoints since the last
298 * channel parameter generation/update.
299 * ``relativeDisplacement2D`` is the 2D displacement of the canonical relative position vector
300 * between the endpoints since the last generation/update.
301 *
302 * @param aMob The mobility model of the first node (unordered).
303 * @param bMob The mobility model of the second node (unordered).
304 * @param distance2D Output parameter that stores the 2D distance between the two nodes.
305 * @param distance3D Output parameter that stores the 3D distance between the two nodes.
306 * @param endpointDisplacement2D Output parameter that stores the effective 2D displacement
307 * (in meters).
308 * @param relativeDisplacement2D Output parameter that stores the 2D displacement (in meters)
309 * of the canonical relative position vector between the two endpoints since the last
310 * channel parameter generation/update.
311 * @param lastPositionFirst Position of the endpoint with the smallest node ID at the time of
312 * the last channel parameter generation/update.
313 * @param lastPositionSecond Position of the endpoint with the largest node ID at the time of
314 * the last channel parameter generation/update.
315 * @param lastRelativePosition2D Previously stored canonical 2D relative position vector
316 * (first endpoint minus second endpoint) at the time of the last channel parameter
317 * generation/update.
318 */
321 double* distance2D,
322 double* distance3D,
323 double* endpointDisplacement2D,
324 double* relativeDisplacement2D,
325 Vector* lastPositionFirst,
326 Vector* lastPositionSecond,
327 Vector2D* lastRelativePosition2D) const;
328
329 /**
330 * Prepare 3gpp channel parameters among the nodes a and b.
331 * The function does the following steps described in 3GPP 38.901:
332 *
333 * Step 4: Generate large scale parameters. All LSPs are uncorrelated.
334 * Step 5: Generate Delays.
335 * Step 6: Generate cluster powers.
336 * Step 7: Generate arrival and departure angles for both azimuth and elevation.
337 * Step 8: Coupling of rays within a cluster for both azimuth and elevation
338 * shuffle all the arrays to perform random coupling
339 * Step 9: Generate the cross-polarization power ratios
340 * Step 10: Draw initial phases
341 *
342 * All relevant generated parameters are added then to ThreeGppChannelParams
343 * which is the return value of this function.
344 * @param channelCondition the channel condition
345 * @param table3gpp the 3gpp parameters from the table
346 * @param aMob the a node mobility model
347 * @param bMob the b node mobility model
348 * @return ThreeGppChannelParams structure with all the channel parameters generated
349 * according 38.901 steps from 4 to 10.
350 */
352 Ptr<const ChannelCondition> channelCondition,
353 Ptr<const ParamsTable> table3gpp,
355 Ptr<const MobilityModel> bMob) const;
356
357 /**
358 * @brief Large-scale channel parameters (3GPP TR 38.901).
359 *
360 * Contains the large-scale statistics used by the channel model.
361 * Shadow fading (SF) is handled in the propagation loss model, not here.
362 *
363 * @note Units:
364 * - DS: delay spread [s]
365 * - ASD/ASA/ZSD/ZSA: angular spreads [deg]
366 * - kFactor: Rician K-factor [dB] (LOS only; 0 for NLOS usage)
367 */
369 {
370 /** Delay spread [s]. */
371 double DS{0};
372 /** Azimuth spread of departure [deg]. */
373 double ASD{0};
374 /** Azimuth spread of arrival [deg]. */
375 double ASA{0};
376 /** Zenith spread of arrival [deg]. */
377 double ZSA{0};
378 /** Zenith spread of departure [deg]. */
379 double ZSD{0};
380 /** Rician K-factor [dB] (used in LOS). */
381 double kFactor{0};
382 };
383
384 /**
385 * @brief Generate large-scale parameters (LSPs) for the current channel state.
386 *
387 * Draws correlated large-scale parameters according to the 3GPP table and the
388 * specified LOS/NLOS condition, including delay spread (DS), angular spreads
389 * (ASD/ASA/ZSD/ZSA), and K-factor for LOS.
390 *
391 * @param losCondition Line-of-sight condition (LOS or NLOS).
392 * @param table3gpp Pointer to the 3GPP parameters table (means, std-devs, sqrt correlation).
393 * @return LargeScaleParameters structure containing the generated LSPs.
394 */
395 LargeScaleParameters GenerateLSPs(const ChannelCondition::LosConditionValue losCondition,
396 Ptr<const ParamsTable> table3gpp) const;
397
398 /**
399 * Generate the cluster delays.
400 * @param DS Delay Spread
401 * @param table3gpp 3GPP parameters from the table
402 * @param minTau the minimum delay
403 * @param clusterDelays output vector for cluster delays
404 */
405
406 void GenerateClusterDelays(const double DS,
407 Ptr<const ParamsTable> table3gpp,
408 double* minTau,
409 DoubleVector* clusterDelays) const;
410
411 /**
412 * @brief Generate per-cluster shadowing terms (in dB) as specified by 3GPP TR 38.901.
413 *
414 * Draws one large-scale shadowing realization per cluster using the scenario-specific
415 * per-cluster shadowing standard deviation from the provided 3GPP table. These terms
416 * represent the intrinsic random strength of each cluster and are later used when
417 * computing and updating cluster powers.
418 *
419 * Behavior:
420 * - The output vector is resized to the number of clusters defined by the table.
421 * - Each entry is an independent zero-mean Gaussian random variable with standard
422 * deviation equal to table3gpp->m_perClusterShadowingStd (units: dB).
423 *
424 * @param table3gpp Pointer to the 3GPP parameters table (provides number of clusters
425 * and per-cluster shadowing std-dev).
426 * @param clusterShadowing Output vector filled with per-cluster shadowing values (dB);
427 * size equals the number of clusters.
428 */
430 DoubleVector* clusterShadowing) const;
431
432 /**
433 * Update shadowing per cluster by using the normalized auto correlation function R, which is
434 * defined as an exponential function in ITU-R P.1816 and used by 38.901 in 7.4-5 equation for
435 * the correlation of shadowing.
436 * @param table3gpp The 3GPP parameters
437 * @param clusterShadowing The previous values of the per-cluster shadowing.
438 * @param displacementLength The displacement length between the nodes.
439 */
441 DoubleVector* clusterShadowing,
442 const double displacementLength) const;
443
444 /**
445 * Generate cluster powers.
446 * @param clusterDelays cluster delays
447 * @param DS Delay Spread
448 * @param table3gpp 3GPP parameters from the table
449 * @param clusterShadowing the shadowing realization per each cluster, representing the
450 * intrinsic random strength of each cluster
451 * @param clusterPowers output vector for cluster powers
452 */
453 void GenerateClusterPowers(const DoubleVector& clusterDelays,
454 const double DS,
455 Ptr<const ParamsTable> table3gpp,
456 const DoubleVector& clusterShadowing,
457 DoubleVector* clusterPowers) const;
458
459 /**
460 * Remove the clusters with less power.
461 * @param clusterPowers input/output vector of cluster powers (will be modified)
462 * @param clusterDelays input/output vector of cluster delays (will be modified)
463 * @param losCondition LOS condition
464 * @param table3gpp 3GPP parameters from the table
465 * @param kFactor K factor
466 * @param powerMax output for maximum power
467 * @return Vector of per-cluster powers used for angle generation, after removing clusters
468 * more than 25 dB below the strongest cluster.
469 */
470 DoubleVector RemoveWeakClusters(DoubleVector* clusterPowers,
471 DoubleVector* clusterDelays,
472 const ChannelCondition::LosConditionValue losCondition,
473 Ptr<const ParamsTable> table3gpp,
474 const double kFactor,
475 double* powerMax) const;
476
477 /**
478 * @brief Adjusts cluster delays for LOS channel condition based on the K-factor.
479 *
480 * This function scales the initial NLOS cluster delays to reflect LOS conditions
481 * as described in 3GPP TR 38.901. The delays are normalized using a correction
482 * factor `cTau` that depends on the Rician K-factor, as defined in Table 7.5-3.
483 *
484 * The formula used to compute `cTau` is:
485 * \f[
486 * c_{\tau} = 0.7705 - 0.0433K + 0.0002K^2 + 0.000017K^3
487 * \f]
488 *
489 * Each cluster delay \f$\tau_i\f$ is then scaled by:
490 * \f[
491 * tau_i^{\text{LOS}} = \frac{\tau_i^{\text{NLOS}}}{c_{\tau}}
492 * \f]
493 * (see Equation 7.5-4)
494 *
495 * @param clusterDelays Pointer to a vector of initial (NLOS) cluster delays, which will be
496 * updated in place.
497 * @param reducedClusterNumber The number of clusters to be considered (can be < total
498 * clusters).
499 * @param kFactor The Rician K-factor, used to adjust the delay scaling factor `cTau`.
500 */
501 void AdjustClusterDelaysForLosCondition(DoubleVector* clusterDelays,
502 const uint8_t reducedClusterNumber,
503 const double kFactor) const;
504
505 /**
506 * @brief Calculates the cPhi parameter for azimuth angular spread modeling.
507 *
508 * This function computes the `cPhi` coefficient used to model the azimuth
509 * angular spread (ASA or ASD) for a given channel condition and cluster configuration.
510 *
511 * - In NLOS conditions, the value is taken directly from the `cNlosTablePhi`.
512 * - In LOS conditions, the NLOS value is adjusted using a polynomial function
513 * of the Rician K-factor, as defined in Table 7.5-10 of 3GPP TR 38.901.
514 *
515 * The formula applied under LOS is:
516 * \f[
517 * c_{\phi,\text{LOS}} = c_{\phi,\text{NLOS}} \cdot (1.1035 - 0.028K - 0.002K^2 + 0.0001K^3)
518 * \f]
519 *
520 * @param losCondition Indicates whether the channel is LOS or NLOS.
521 * @param table3gpp Pointer to the table containing the number of clusters.
522 * @param kFactor The Rician K-factor, used to scale cPhi in LOS conditions.
523 *
524 * @return The computed cPhi value.
525 *
526 * @warning NS_FATAL_ERROR if the number of clusters is invalid or not found in the lookup
527 * table.
528 */
529 static double CalculateCphi(const ChannelCondition::LosConditionValue losCondition,
530 Ptr<const ParamsTable> table3gpp,
531 const double kFactor);
532
533 /**
534 * @brief Calculates the cTheta parameter for zenith angular spread modeling.
535 *
536 * This function computes the `cTheta` coefficient used to model the zenith
537 * angular spread (ZSA or ZSD) for a given channel condition and cluster configuration.
538 *
539 * - In NLOS conditions, the value is taken directly from the `cNlosTableTheta`.
540 * - In LOS conditions, the NLOS value is adjusted using a polynomial function
541 * of the Rician K-factor, as defined in Table 7.5-15 of 3GPP TR 38.901.
542 *
543 * The formula applied under LOS is:
544 * \f[
545 * c_{\theta,\text{LOS}} = c_{\theta,\text{NLOS}} \cdot (1.3086 + 0.0339K - 0.0077K^2 +
546 * 0.0002K^3) \f]
547 *
548 * @param losCondition Indicates whether the channel is LOS or NLOS.
549 * @param table3gpp Pointer to the table containing the number of clusters.
550 * @param kFactor The Rician K-factor, used to scale cTheta in LOS conditions.
551 *
552 * @return The computed cTheta value.
553 *
554 * @warning NS_FATAL_ERROR if the number of clusters is invalid or not found in the lookup
555 * table.
556 */
557 static double CalculateCtheta(const ChannelCondition::LosConditionValue losCondition,
558 Ptr<const ParamsTable> table3gpp,
559 const double kFactor);
560
561 /**
562 * @brief Generate a random sign (+1 or -1) for each cluster for XN for NLOS computation for
563 * channel consistency updates.
564 *
565 * Fills the provided vector with one sign per cluster, where each sign is
566 * independently drawn from a fair Bernoulli distribution over {+1, -1}.
567 * The output vector is cleared and reserved to the specified size.
568 *
569 * @param clusterNumber Number of clusters to generate signs for.
570 * @param clusterSign Output pointer to the vector that will contain the signs
571 * (size = clusterNumber), each element being either +1 or -1.
572 */
573 void GenerateClusterXnNLos(const uint8_t clusterNumber, std::vector<int>* clusterSign) const;
574
575 /**
576 * Generate cluster angles for a 3GPP channel model based on provided parameters.
577 * This method computes angles such as Angle of Arrival (AoA), Angle of Departure (AoD),
578 * Zenith Angle of Arrival (ZoA), and Zenith Angle of Departure (ZoD) for each cluster.
579 *
580 * @param channelParams Pointer to the structure containing channel parameters.
581 * @param clusterPowerForAngles A vector containing the power of clusters used for angle
582 * generation.
583 * @param powerMax The maximum power among clusters.
584 * @param cPhi Constant used for calculating azimuthal angles.
585 * @param cTheta Constant used for calculating zenith angles.
586 * @param lsps Reference to the structure holding large-scale parameters.
587 * @param aMob Pointer to the mobility model of Node A.
588 * @param bMob Pointer to the mobility model of Node B.
589 * @param table3gpp Pointer to the table containing 3GPP-specific parameters.
590 * @param clusterAngles Per-cluster angles [deg]; duplicated for sub-clusters.
591 */
593 const DoubleVector& clusterPowerForAngles,
594 double powerMax,
595 double cPhi,
596 double cTheta,
597 const LargeScaleParameters& lsps,
600 Ptr<const ParamsTable> table3gpp,
601 Double2DVector* clusterAngles) const;
602
603 /**
604 * @brief Calculates the per-cluster power attenuation (in dB) due to self-blocking and
605 * non-self-blocking effects, based on the 3GPP TR 38.901 blockage model
606 * (Section 7.6.4.1).
607 *
608 * This method applies the spatial blockage attenuation to each cluster of the channel model
609 * by determining whether the corresponding azimuth (AOA) and zenith (ZOA) angles fall
610 * into predefined self-blocking or randomly generated non-self-blocking regions. The resulting
611 * attenuation values are returned as a vector.
612 *
613 * - **Self-blocking** simulates the user’s own body blocking the signal. The region is defined
614 * using fixed or portrait-mode-specific parameters (Table 7.6.4.1-1).
615 *
616 * - **Non-self-blocking** simulates environmental blockers (e.g., furniture, walls) and
617 * is modeled using correlated random variables for blocker location and size, based on
618 * scenario-specific rules from Table 7.6.4.1-2 and spatial correlation models
619 * (Tables 7.6.4.1-3, 7.6.4.1-4).
620 *
621 * @param [in,out] nonSelfBlocking
622 * Pointer to a 2D vector representing the existing or to-be-generated non-self-blocking
623 * regions. Each inner vector contains the parameters for a single blocker:
624 * [phi_k, x_k, theta_k, y_k, r_k], as defined in 3GPP Table 7.6.4.1-2.
625 *
626 * @param [in,out] powerAttenuation A vector of attenuation values in decibels (dB),
627 * with one value per cluster to be generated.
628 *
629 * @param [in] channelParams
630 * Pointer to the channel parameters, including UT location and generation time, used
631 * to calculate spatial correlation and motion updates for non-self-blocking regions.
632 *
633 * @param [in] clusterAOA
634 * A vector of azimuth angles of arrival (AOA) in degrees for each cluster.
635 * Must be in the range [0°, 360°].
636 *
637 * @param [in] clusterZOA
638 * A vector of zenith angles of arrival (ZOA) in degrees for each cluster.
639 * Must be in the range [0°, 180°].
640 *
641 * @param [in] table3gpp Table with 3GPP parameters
642 *
643 * @note
644 * - Follows the 3GPP TR 38.901 blockage model precisely, including the transformation
645 * from normally-distributed to uniformly distributed random variables with correlated
646 * updates.
647 * - Uses scenario-specific correlation distances and blocker dimensions.
648 * - Attenuation for non-self-blocking is computed using the formulas (7.6-22) to (7.6-27).
649 * - A cluster can be affected by both self-blocking and non-self-blocking.
650 *
651 * @see 3GPP TR 38.901 v15.x.x or v16.x.x, Section 7.6.4.1
652 */
653 void CalcAttenuationOfBlockage(Double2DVector* nonSelfBlocking,
654 DoubleVector* powerAttenuation,
656 const DoubleVector& clusterAOA,
657 const DoubleVector& clusterZOA,
658 Ptr<const ParamsTable> table3gpp) const;
659
660 /**
661 * Updates the cluster delays for the 3GPP channel model based on the
662 * channel parameters and consistency requirements.
663 *
664 * @param clusterDelay Pointer to the vector that stores the current cluster delays to be
665 * updated.
666 * @param delayConsistency Pointer to the vector capturing the consistency of the delays.
667 * @param channelParams Smart pointer to a constant ThreeGppChannelParams object containing
668 * the necessary channel parameters for update computations.
669 */
670 void UpdateClusterDelay(DoubleVector* clusterDelay,
671 DoubleVector* delayConsistency,
672 Ptr<const ThreeGppChannelParams> channelParams) const;
673
674 /**
675 * @brief Rotate a 3D velocity vector by specified angles, around y-axis and z-axis.
676 * Rotation matrices being used are the ones defined in 38.901 in Equation (7.1-2).
677 * The formula being applied is the one from Procedure A, Rn,rx and Rn,ry from formula 7.6-10b
678 * and 7.6-10c:
679 *
680 * [[ 1, 0, 0 ],
681 * R = Rz (alphaRad) * Ry (betaRad) * [ 0, Xn, 0 ], * Ry (gammaRad) * Rz (etaRad)
682 * [ 0, 0, 1 ]]
683 *
684 * NOTE: Currently, only x and y components are calculated, the z component is not used.
685 *
686 * @param alphaRad the first angle from the rotation formula R [rad]
687 * @param betaRad the second angle from the rotation formula R [rad]
688 * @param gammaRad the third angle from the rotation formula R [rad]
689 * @param etaRad the fourth angle from the rotation formula R [rad]
690 * @param speed Input velocity vector in the original (unrotated) frame [m/s].
691 * @param Xn Direction sign indicator; use +1 to keep orientation, −1 to flip.
692 * @return The rotated (and possibly sign-flipped) velocity vector in the target frame [m/s].
693 */
694 Vector ApplyVelocityRotation(double alphaRad,
695 double betaRad,
696 double gammaRad,
697 double etaRad,
698 const Vector& speed,
699 const int Xn) const;
700
701 /**
702 * @brief Update cluster angles based on node mobility according to 3GPP TR 38.901.
703 *
704 * This function implements the spatial consistency procedure for updating cluster
705 * angles when nodes move, as specified in 3GPP TR 38.901 Section 7.6.3. The cluster
706 * angles are updated based on the relative velocity between transmitter and receiver
707 * nodes, considering both Line-of-Sight (LOS) and Non-Line-of-Sight (NLOS) conditions.
708 *
709 * The update equations are based on 3GPP TR 38.901 equations (7.6-11) to (7.6-14):
710 * - For LOS: Simple relative velocity calculation
711 * - For NLOS: Complex velocity transformation considering cluster-specific directions
712 *
713 * @param channelParams Pointer to the channel parameters containing node velocities,
714 * LOS condition, and reduced cluster number. Must contain valid
715 * m_rxSpeed, m_txSpeed, m_losCondition, and m_reducedClusterNumber.
716 * @param clusterAngles Cluster angles {AOA, ZOA, AOD, ZOD}
717 * @param prevClusterDelay Vector containing the previous cluster delays in seconds.
718 * Used in the angle update calculations. Size must equal
719 * channelParams->m_reducedClusterNumber.
720 */
722 Double2DVector* clusterAngles,
723 const DoubleVector& prevClusterDelay) const;
724
725 /**
726 * Shift per-ray angles to follow updated cluster mean angles while preserving
727 * intra-cluster offsets and existing random coupling.
728 * This is used during Spatial Consistency Procedure A updates when cluster means
729 * change, but ray coupling, XPR, and initial phases must remain the same.
730 *
731 * @param table3gpp Table of 3GPP parameters.
732 * @param channelParams Channel parameters to update (rays stored inside will be modified).
733 * @param prevClusterAngles Previous cluster angles {AOA, ZOA, AOD, ZOD}
734 * @param rayAoaRadian Ray AOA in radian to be updated.
735 * @param rayAodRadian Ray AOD in radian to be updated.
736 * @param rayZodRadian Ray ZOD in radian to be updated.
737 * @param rayZoaRadian Ray ZOA in radian to be updated.
738 */
741 const Double2DVector& prevClusterAngles,
742 Double2DVector* rayAodRadian,
743 Double2DVector* rayAoaRadian,
744 Double2DVector* rayZodRadian,
745 Double2DVector* rayZoaRadian) const;
746
747 /**
748 * @brief Applies blockage-based attenuation to the cluster powers according to
749 * the 3GPP TR 38.901 blockage model (Section 7.6.4.1).
750 *
751 * This method attenuates the power of each multipath cluster based on whether
752 * it is blocked by self- or non-self-blocking regions. The attenuation is calculated
753 * using the `CalcAttenuationOfBlockage()` method and applied in dB to each cluster power.
754 *
755 * If the `m_blockage` flag is enabled, each cluster is checked for intersection
756 * with:
757 * - **Self-blocking** regions, defined based on device orientation.
758 * - **Non-self-blocking** regions, generated or updated using spatial correlation and
759 * scenario-specific parameters.
760 *
761 * The attenuation is subtracted from the cluster powers using:
762 * \f[
763 * P' = \frac{P}{10^{A_{\text{dB}}/10}}
764 * \f]
765 * where \f$ A_{\text{dB}} \f$ is the blockage attenuation for the cluster.
766 *
767 *@param [in,out] nonSelfBlocking
768 * Pointer to the 2D vector of non-self-blocking regions to be generated.
769 * Each inner vector contains the parameters for a single blocker as defined in
770 * 3GPP Table 7.6.4.1-2.
771 *
772 * @param [in,out] clusterPowers
773 * Pointer to the vector of cluster powers (linear scale), modified in-place
774 * with the applied attenuation (one per cluster).
775 *
776 * @param [out] attenuation_dB
777 * Pointer to the output vector containing the per-cluster attenuation values
778 * in dB. This is filled using `CalcAttenuationOfBlockage()`.
779 *
780 * @param [in] channelParams
781 * Pointer to the channel parameters (e.g., UT location, time of generation),
782 * used for computing motion-based updates to non-self-blocking regions.
783 *
784 * @param [in] clusterAoa
785 * Azimuth angles of arrival (AOA) for each cluster, in degrees.
786 *
787 * @param [in] clusterZoa
788 * Zenith angles of arrival (ZOA) for each cluster, in degrees.
789 *
790 * @param [in] table3gpp
791 * Table with 3GPP scenario dependent parameters
792 *
793 * @note
794 * - If `m_blockage` is false, no attenuation is applied, and `attenuation_dB` contains a single
795 * 0.
796 * - This function assumes the vectors are pre-sized and match `reducedClusterNumber`.
797 * - Internally uses `CalcAttenuationOfBlockage()` to compute spatial intersection with
798 * blockers.
799 *
800 * @see ThreeGppChannelModel::CalcAttenuationOfBlockage
801 * @see 3GPP TR 38.901 v15.x.x or v16.x.x, Section 7.6.4.1
802 */
803 void ApplyAttenuationToClusterPowers(Double2DVector* nonSelfBlocking,
804 DoubleVector* clusterPowers,
805 DoubleVector* attenuation_dB,
807 const DoubleVector& clusterAoa,
808 const DoubleVector& clusterZoa,
809 Ptr<const ParamsTable> table3gpp) const;
810
811 /**
812 * @brief Compute per-ray angles (no shuffling), centered on cluster means.
813 *
814 * Initializes and fills per-ray AOA/AOD/ZOA/ZOD angles in radians for each
815 * cluster according to 3GPP intra-cluster offsets. Angles are wrapped to valid
816 * ranges via WrapAngles.
817 *
818 * @param channelParams Channel parameters (provides reduced cluster count).
819 * @param table3gpp 3GPP parameters table (provides rays per cluster and spread constants).
820 * @param[out] rayAoaRadian Per-ray azimuth-of-arrival angles [rad] as
821 * [numClusters][raysPerCluster].
822 * @param[out] rayAodRadian Per-ray azimuth-of-departure angles [rad] as
823 * [numClusters][raysPerCluster].
824 * @param[out] rayZoaRadian Per-ray zenith-of-arrival angles [rad] as
825 * [numClusters][raysPerCluster].
826 * @param[out] rayZodRadian Per-ray zenith-of-departure angles [rad] as
827 * [numClusters][raysPerCluster].
828 */
830 Ptr<const ParamsTable> table3gpp,
831 Double2DVector* rayAoaRadian,
832 Double2DVector* rayAodRadian,
833 Double2DVector* rayZoaRadian,
834 Double2DVector* rayZodRadian) const;
835
836 /**
837 * @brief Randomly couples rays within each cluster by shuffling per-ray angles.
838 *
839 * Applies in-place shuffling of per-ray AOA/AOD/ZOA/ZOD arrays independently
840 * for each cluster, realizing random intra-cluster ray coupling.
841 *
842 * @param channelParams Channel parameters (provides reduced cluster count).
843 * @param[in,out] rayAoaRadian Per-ray AOA angles [rad] as [numClusters][raysPerCluster].
844 * @param[in,out] rayAodRadian Per-ray AOD angles [rad] as [numClusters][raysPerCluster].
845 * @param[in,out] rayZoaRadian Per-ray ZOA angles [rad] as [numClusters][raysPerCluster].
846 * @param[in,out] rayZodRadian Per-ray ZOD angles [rad] as [numClusters][raysPerCluster].
847 */
849 Double2DVector* rayAoaRadian,
850 Double2DVector* rayAodRadian,
851 Double2DVector* rayZoaRadian,
852 Double2DVector* rayZodRadian) const;
853 /**
854 * @brief Generate cross-polarization power ratios and initial per-ray phases.
855 *
856 * For each cluster and ray, draws the cross-polarization power ratio (XPR) according
857 * to the 3GPP parameters and initializes four polarization-dependent phases
858 * uniformly in [-pi, pi]. The outputs are resized/filled by this function.
859 *
860 * @param[out] crossPolarizationPowerRatios Matrix [numClusters][raysPerCluster] with
861 * XPR values (linear scale).
862 * @param[out] clusterPhase 3D array [numClusters][raysPerCluster][4] with initial
863 * phases (radians).
864 * @param reducedClusterNumber Number of (possibly reduced) clusters to generate.
865 * @param table3gpp Pointer to the 3GPP parameters table (uXpr, sigXpr, rays per
866 * cluster).
867 */
868 void GenerateCrossPolPowerRatiosAndInitialPhases(Double2DVector* crossPolarizationPowerRatios,
869 Double3DVector* clusterPhase,
870 const uint8_t reducedClusterNumber,
871 Ptr<const ParamsTable> table3gpp) const;
872 /**
873 * @brief Identify the two strongest base clusters and append their derived subclusters.
874 *
875 * Finds the indices of the strongest and second-strongest clusters (by power) within the
876 * base (reduced) cluster set, and appends the corresponding subclusters by extending the
877 * per-cluster delay/angle vectors according to the 3GPP strongest-cluster subclustering rule.
878 * The associated Doppler terms (alpha and dTerm) are appended in the same order,
879 * inheriting the parent cluster values for each appended subcluster.
880 *
881 * @param channelParams Current channel parameters (cluster powers and reduced cluster count).
882 * @param table3gpp 3GPP parameters table (e.g., cDS).
883 * @param[out] cluster1st Index of the strongest base cluster.
884 * @param[out] cluster2nd Index of the second-strongest base cluster.
885 * @param[in,out] clusterDelay Per-cluster delays [s]; subcluster delays are appended.
886 * @param[in,out] angles Per-cluster angles [deg]; subcluster angles are appended/duplicated.
887 * @param[in,out] alpha Per-cluster Doppler alpha terms; subcluster terms are appended.
888 * @param[in,out] dTerm Per-cluster Doppler D terms; subcluster terms are appended.
889 * @param[in,out] clusterPower Per-cluster power; subcluster powers are appended.
890 */
892 Ptr<const ParamsTable> table3gpp,
893 uint8_t* cluster1st,
894 uint8_t* cluster2nd,
895 DoubleVector* clusterDelay,
896 Double2DVector* angles,
897 DoubleVector* alpha,
898 DoubleVector* dTerm,
899 DoubleVector* clusterPower) const;
900
901 /**
902 * @brief Trim per-cluster vectors back to the base (reduced) cluster set.
903 *
904 * After channel generation/update, two or four derived subclusters may be appended
905 * at the end of the per-cluster vectors (to represent the additional strongest-cluster
906 * subclusters). This helper removes any such appended tail so that the vectors
907 * contain exactly @p reducedClusterNumber base clusters.
908 *
909 * @param reducedClusterNumber Number of base clusters (after weak-cluster removal).
910 * @param delay Per-cluster delays (tail subclusters, if present, are removed).
911 * @param angles Per-cluster angles (AOA/ZOA/AOD/ZOD; tail subclusters, if present, are
912 * removed).
913 * @param cachedAngleSincos Optional cached sin/cos pairs per cluster angle (tail
914 * subclusters, if present, are removed).
915 * @param alpha Optional Doppler alpha terms per cluster (tail subclusters, if present, are
916 * removed).
917 * @param dTerm Optional Doppler D terms per cluster (tail subclusters, if present, are
918 * removed).
919 * @param clusterPower Per cluster power (tail subclusters, if present, are removed).
920 */
921 void TrimToBaseClusters(const uint8_t reducedClusterNumber,
922 DoubleVector* delay,
923 Double2DVector* angles,
924 std::vector<std::vector<std::pair<double, double>>>* cachedAngleSincos,
925 DoubleVector* alpha,
926 DoubleVector* dTerm,
927 DoubleVector* clusterPower) const;
928
929 /**
930 * @brief Precomputes the sine and cosine values for angles.
931 *
932 * This method precomputes the sine and cosine values of specified angles,
933 * storing them in a vector of pairs. The computation is based on provided
934 * channel parameters.
935 *
936 * @param channelParams Pointer to the constant ThreeGppChannelParams object containing
937 * channel-specific parameters.
938 * @param cachedAngleSinCos Pointer to the vector where precomputed sine and cosine values will
939 * be stored.
940 */
943 std::vector<std::vector<std::pair<double, double>>>* cachedAngleSinCos) const;
944
945 /**
946 * @brief Generate additional Doppler terms for delayed (reflected) paths.
947 *
948 * Produces per-cluster Doppler parameters used to model moving scatterers
949 * as per TR 37.885. v15.3.0, Sec. 6.2.3. These terms account for an additional
950 * Doppler contribution due to the presence of moving objects in the surrounding
951 * environment, such as in vehicular scenarios. This contribution is applied
952 * only to the delayed (reflected) paths and must be properly configured by
953 * setting the value of m_vScatt, which is defined as "maximum speed of the
954 * vehicle in the layout".
955 *
956 * @param reducedClusterNumber Number of (possibly reduced) clusters.
957 * @param[out] dopplerTermAlpha Per-cluster alpha terms in [-1, 1].
958 * @param[out] dopplerTermD Per-cluster Doppler speed terms in [-vScatt, vScatt] [m/s].
959 */
960 void GenerateDopplerTerms(const uint8_t reducedClusterNumber,
961 DoubleVector* dopplerTermAlpha,
962 DoubleVector* dopplerTermD) const;
963
964 /**
965 * Compute the channel matrix between two nodes a and b, and their
966 * antenna arrays aAntenna and bAntenna using the procedure
967 * described in 3GPP TR 38.901
968 * @param channelParams the channel parameters previously generated for the pair of
969 * nodes a and b
970 * @param table3gpp the 3gpp parameters table
971 * @param sMob the mobility model of node s
972 * @param uMob the mobility model of node u
973 * @param sAntenna the antenna array of node s
974 * @param uAntenna the antenna array of node u
975 * @return the channel realization
976 */
978 Ptr<const ParamsTable> table3gpp,
982 Ptr<const PhasedArrayModel> uAntenna) const;
983
984 /**
985 * @brief Update channel parameters for spatial consistency using 3GPP TR 38.901 procedure A.
986 *
987 * This function updates existing channel parameters to maintain spatial and temporal
988 * consistency when nodes move. It reuses most of the functions from GenerateChannelParameters
989 * but applies spatial correlation to LSPs and temporal evolution to phases.
990 *
991 * Following 3GPP TR 38.901 Procedure A, the function:
992 * - Updates Large Scale Parameters (LSPs)
993 * - Regenerates cluster delays and powers
994 * - Filters weak clusters
995 * - Updates angles and phases with continuity from previous channel state
996 * - Maintains Doppler terms and cross-polarization ratios for consistency
997 * - Preserves phase evolution according to 3GPP specifications
998 *
999 * @param channelParams existing channel parameters to update
1000 * @param channelCondition current channel condition
1001 * @param aMob mobility model of device A
1002 * @param bMob mobility model of device B
1003 */
1005 Ptr<const ChannelCondition> channelCondition,
1007 Ptr<const MobilityModel> bMob) const;
1008
1009 /**
1010 * Compute the effective 2D displacement of a link with respect to previously stored endpoint
1011 * positions.
1012 *
1013 * The channel parameters are stored using a reciprocal key, therefore endpoint-specific state
1014 * is handled using a canonical ordering by node ID (min ID / max ID). The returned endpoint
1015 * displacement is the maximum of the two endpoint displacements, so that the channel can evolve
1016 * even when the change in inter-node distance between consecutive updates is close to zero
1017 * (e.g., parallel motion in V2V).
1018 *
1019 * @param aMob The mobility model of the first node (unordered).
1020 * @param bMob The mobility model of the second node (unordered).
1021 * @param lastPositionFirst Previously stored position of the endpoint with the smallest node
1022 * ID.
1023 * @param lastPositionSecond Previously stored position of the endpoint with the largest node
1024 * ID.
1025 * @return The effective 2D displacement (in meters).
1026 */
1029 const Vector& lastPositionFirst,
1030 const Vector& lastPositionSecond) const;
1031
1032 /**
1033 * Check if the channel params has to be updated
1034 * @param channelParamsKey the channel params key
1035 * @param condition the pointer to the channel condition instance
1036 * @param aMob mobility model of the device a
1037 * @param bMob mobility model of the device b
1038 * @return true if the channel params has to be updated, false otherwise
1039 */
1040 bool NewChannelParamsNeeded(const uint64_t channelParamsKey,
1043 Ptr<const MobilityModel> bMob) const;
1044
1045 /**
1046 * @brief Check if channel matrix needs update based on parameter changes or
1047 * the update period expired.
1048 *
1049 * This method determines whether a new channel matrix should be generated by comparing
1050 * the generation times of the current channel parameters and existing channel matrix.
1051 * It also considers any potential changes in antenna configurations.
1052 *
1053 * @param channelMatrixKey Channel matrix key
1054 * @param channelParams Current channel parameters to check against
1055 * @param aAntenna Transmitting antenna model configuration
1056 * @param bAntenna Receiving antenna model configuration
1057 * @return whether the channel matrix needs an update
1058 */
1059 bool NewChannelMatrixNeeded(uint64_t channelMatrixKey,
1062 Ptr<const PhasedArrayModel> bAntenna) const;
1063
1064 /**
1065 * @brief Check if spatial-consistency requires updating channel parameters.
1066 *
1067 * Returns true when spatial consistency is enabled, and the update period
1068 * (UpdatePeriod) has elapsed since the parameters were generated.
1069 *
1070 * @param channelParams Channel parameters whose generation time is checked.
1071 * @param aMob mobility model of the device a
1072 * @param bMob mobility model of the device b
1073 * @return true if a parameter update is needed; false otherwise.
1074 */
1077 Ptr<const MobilityModel> bMob) const;
1078
1079 /**
1080 * Check if the channel matrix has to be updated due to
1081 * changes in the number of antenna ports
1082 * @param aAntenna the antenna array of node a
1083 * @param bAntenna the antenna array of node b
1084 * @param channelMatrix channel matrix structure
1085 * @return true if the channel matrix has to be updated, false otherwise
1086 */
1089 Ptr<const ChannelMatrix> channelMatrix) const;
1090
1091 /**
1092 * map containing the channel realizations per a pair of
1093 * PhasedAntennaArray instances; the key of this map is reciprocal
1094 * uniquely identifies a pair of PhasedAntennaArrays
1095 */
1096 std::unordered_map<uint64_t, Ptr<ChannelMatrix>> m_channelMatrixMap;
1097 /**
1098 * map containing the common channel parameters per a pair of nodes, the
1099 * key of this map is reciprocal and uniquely identifies a pair of
1100 * nodes
1101 */
1102 std::unordered_map<uint64_t, Ptr<ThreeGppChannelParams>> m_channelParamsMap;
1103 /// the channel update period enables spatial consistency, procedure A
1105 /// the operating frequency
1107 /// the 3GPP scenario
1108 std::string m_scenario;
1109 /// the channel condition model
1111 /// uniform random variable
1113 /// normal random variable
1115 /// uniform random variable used to shuffle an array in GetNewChannel
1117 /**
1118 * Variable used to compute the additional Doppler contribution for the delayed
1119 * (reflected) paths, as described in 3GPP TR 37.885 v15.3.0, Sec. 6.2.3.
1120 */
1121 double m_vScatt;
1122 /**
1123 * Uniform random variable, used to compute the additional Doppler contribution
1124 */
1126 // parameters for the blockage model
1127 /// enables the blockage model A
1129 /// number of non-self-blocking regions
1131 /// true if portrait mode, false if landscape
1133 /// the blocker speed
1135
1136 /// index of the PHI value in the m_nonSelfBlocking array
1137 static constexpr uint8_t PHI_INDEX = 0;
1138 /// index of the X value in the m_nonSelfBlocking array
1139 static constexpr uint8_t X_INDEX = 1;
1140 /// index of the THETA value in the m_nonSelfBlocking array
1141 static constexpr uint8_t THETA_INDEX = 2;
1142 /// index of the Y value in the m_nonSelfBlocking array
1143 static constexpr uint8_t Y_INDEX = 3;
1144 /// index of the R value in the m_nonSelfBlocking array
1145 static constexpr uint8_t R_INDEX = 4;
1146};
1147} // namespace ns3
1148
1149#endif /* THREE_GPP_CHANNEL_H */
O2iConditionValue
Possible values for Outdoor to Indoor condition.
LosConditionValue
Possible values for Line-of-Sight condition.
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.
std::vector< Double2DVector > Double3DVector
Type definition for 3D matrices of doubles.
std::vector< DoubleVector > Double2DVector
Type definition for matrices of doubles.
Keep track of the current position and velocity of an object.
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:70
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model.
void ComputeRayAngles(Ptr< const ThreeGppChannelParams > channelParams, Ptr< const ParamsTable > table3gpp, Double2DVector *rayAoaRadian, Double2DVector *rayAodRadian, Double2DVector *rayZoaRadian, Double2DVector *rayZodRadian) const
Compute per-ray angles (no shuffling), centered on cluster means.
double ComputeEndpointDisplacement2d(Ptr< const MobilityModel > aMob, Ptr< const MobilityModel > bMob, const Vector &lastPositionFirst, const Vector &lastPositionSecond) const
Compute the effective 2D displacement of a link with respect to previously stored endpoint positions.
Vector ApplyVelocityRotation(double alphaRad, double betaRad, double gammaRad, double etaRad, const Vector &speed, const int Xn) const
Rotate a 3D velocity vector by specified angles, around y-axis and z-axis.
bool m_portraitMode
true if portrait mode, false if landscape
static double CalculateCtheta(const ChannelCondition::LosConditionValue losCondition, Ptr< const ParamsTable > table3gpp, const double kFactor)
Calculates the cTheta parameter for zenith angular spread modeling.
Ptr< NormalRandomVariable > m_normalRv
normal random variable
void ApplyAttenuationToClusterPowers(Double2DVector *nonSelfBlocking, DoubleVector *clusterPowers, DoubleVector *attenuation_dB, Ptr< const ThreeGppChannelParams > channelParams, const DoubleVector &clusterAoa, const DoubleVector &clusterZoa, Ptr< const ParamsTable > table3gpp) const
Applies blockage-based attenuation to the cluster powers according to the 3GPP TR 38....
bool ChannelUpdateNeeded(Ptr< const ThreeGppChannelParams > channelParams, Ptr< const MobilityModel > aMob, Ptr< const MobilityModel > bMob) const
Check if spatial-consistency requires updating channel parameters.
void FindStrongestClusters(Ptr< const ThreeGppChannelParams > channelParams, Ptr< const ParamsTable > table3gpp, uint8_t *cluster1st, uint8_t *cluster2nd, DoubleVector *clusterDelay, Double2DVector *angles, DoubleVector *alpha, DoubleVector *dTerm, DoubleVector *clusterPower) const
Identify the two strongest base clusters and append their derived subclusters.
bool m_blockage
enables the blockage model A
void GenerateCrossPolPowerRatiosAndInitialPhases(Double2DVector *crossPolarizationPowerRatios, Double3DVector *clusterPhase, const uint8_t reducedClusterNumber, Ptr< const ParamsTable > table3gpp) const
Generate cross-polarization power ratios and initial per-ray phases.
LargeScaleParameters GenerateLSPs(const ChannelCondition::LosConditionValue losCondition, Ptr< const ParamsTable > table3gpp) const
Generate large-scale parameters (LSPs) for the current channel state.
Ptr< const ChannelParams > GetParams(Ptr< const MobilityModel > aMob, Ptr< const MobilityModel > bMob) const override
Looks for the channel params associated with the aMob and bMob pair in m_channelParamsMap.
~ThreeGppChannelModel() override
Destructor.
void UpdateClusterDelay(DoubleVector *clusterDelay, DoubleVector *delayConsistency, Ptr< const ThreeGppChannelParams > channelParams) const
Updates the cluster delays for the 3GPP channel model based on the channel parameters and consistency...
void PrecomputeAnglesSinCos(Ptr< const ThreeGppChannelParams > channelParams, std::vector< std::vector< std::pair< double, double > > > *cachedAngleSinCos) const
Precomputes the sine and cosine values for angles.
void TrimToBaseClusters(const uint8_t reducedClusterNumber, DoubleVector *delay, Double2DVector *angles, std::vector< std::vector< std::pair< double, double > > > *cachedAngleSincos, DoubleVector *alpha, DoubleVector *dTerm, DoubleVector *clusterPower) const
Trim per-cluster vectors back to the base (reduced) cluster set.
void CalcAttenuationOfBlockage(Double2DVector *nonSelfBlocking, DoubleVector *powerAttenuation, Ptr< const ThreeGppChannelParams > channelParams, const DoubleVector &clusterAOA, const DoubleVector &clusterZOA, Ptr< const ParamsTable > table3gpp) const
Calculates the per-cluster power attenuation (in dB) due to self-blocking and non-self-blocking effec...
std::unordered_map< uint64_t, Ptr< ThreeGppChannelParams > > m_channelParamsMap
map containing the common channel parameters per a pair of nodes, the key of this map is reciprocal a...
static std::pair< double, double > WrapAngles(double azimuthRad, double inclinationRad)
Wrap an (azimuth, inclination) angle pair in a valid range.
DoubleVector RemoveWeakClusters(DoubleVector *clusterPowers, DoubleVector *clusterDelays, const ChannelCondition::LosConditionValue losCondition, Ptr< const ParamsTable > table3gpp, const double kFactor, double *powerMax) const
Remove the clusters with less power.
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 with the aMob and bMob pair in m_channelMatrixMap.
static constexpr uint8_t Y_INDEX
index of the Y value in the m_nonSelfBlocking array
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 a pair of PhasedAntennaArray instances; the key of this m...
Ptr< UniformRandomVariable > m_uniformRv
uniform random variable
void UpdateLinkGeometry(Ptr< const MobilityModel > aMob, Ptr< const MobilityModel > bMob, double *distance2D, double *distance3D, double *endpointDisplacement2D, double *relativeDisplacement2D, Vector *lastPositionFirst, Vector *lastPositionSecond, Vector2D *lastRelativePosition2D) const
Update distance- and displacement-related values between two nodes.
void DoDispose() override
Destructor implementation.
void SetScenario(const std::string &scenario)
Sets the propagation scenario.
void GenerateClusterDelays(const double DS, Ptr< const ParamsTable > table3gpp, double *minTau, DoubleVector *clusterDelays) const
Generate the cluster delays.
static constexpr uint8_t X_INDEX
index of the X value in the m_nonSelfBlocking array
bool NewChannelMatrixNeeded(uint64_t channelMatrixKey, Ptr< const ThreeGppChannelParams > channelParams, Ptr< const PhasedArrayModel > aAntenna, Ptr< const PhasedArrayModel > bAntenna) const
Check if channel matrix needs update based on parameter changes or the update period expired.
void RandomRaysCoupling(Ptr< const ThreeGppChannelParams > channelParams, Double2DVector *rayAoaRadian, Double2DVector *rayAodRadian, Double2DVector *rayZoaRadian, Double2DVector *rayZodRadian) const
Randomly couples rays within each cluster by shuffling per-ray angles.
void SetChannelConditionModel(Ptr< ChannelConditionModel > model)
Set the channel condition model.
Ptr< UniformRandomVariable > m_uniformRvDoppler
Uniform random variable, used to compute the additional Doppler contribution.
static double CalculateCphi(const ChannelCondition::LosConditionValue losCondition, Ptr< const ParamsTable > table3gpp, const double kFactor)
Calculates the cPhi parameter for azimuth angular spread modeling.
uint16_t m_numNonSelfBlocking
number of non-self-blocking regions
std::string GetScenario() const
Returns the propagation scenario.
bool NewChannelParamsNeeded(const uint64_t channelParamsKey, Ptr< const ChannelCondition > condition, Ptr< const MobilityModel > aMob, Ptr< const MobilityModel > bMob) const
Check if the channel params has to be updated.
void ShiftRayAnglesToUpdatedClusterMeans(Ptr< const ParamsTable > table3gpp, Ptr< const ThreeGppChannelParams > channelParams, const Double2DVector &prevClusterAngles, Double2DVector *rayAodRadian, Double2DVector *rayAoaRadian, Double2DVector *rayZodRadian, Double2DVector *rayZoaRadian) const
Shift per-ray angles to follow updated cluster mean angles while preserving intra-cluster offsets and...
void GenerateClusterPowers(const DoubleVector &clusterDelays, const double DS, Ptr< const ParamsTable > table3gpp, const DoubleVector &clusterShadowing, DoubleVector *clusterPowers) const
Generate cluster powers.
void GenerateClusterXnNLos(const uint8_t clusterNumber, std::vector< int > *clusterSign) const
Generate a random sign (+1 or -1) for each cluster for XN for NLOS computation for channel consistenc...
void GenerateClusterAngles(Ptr< const ThreeGppChannelParams > channelParams, const DoubleVector &clusterPowerForAngles, double powerMax, double cPhi, double cTheta, const LargeScaleParameters &lsps, Ptr< const MobilityModel > aMob, Ptr< const MobilityModel > bMob, Ptr< const ParamsTable > table3gpp, Double2DVector *clusterAngles) const
Generate cluster angles for a 3GPP channel model based on provided parameters.
double m_frequency
the operating frequency
void GenerateClusterShadowingTerm(Ptr< const ParamsTable > table3gpp, DoubleVector *clusterShadowing) const
Generate per-cluster shadowing terms (in dB) as specified by 3GPP TR 38.901.
double m_vScatt
Variable used to compute the additional Doppler contribution for the delayed (reflected) paths,...
void AdjustClusterDelaysForLosCondition(DoubleVector *clusterDelays, const uint8_t reducedClusterNumber, const double kFactor) const
Adjusts cluster delays for LOS channel condition based on the K-factor.
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 TypeId GetTypeId()
Get the type ID.
void UpdateChannelParameters(Ptr< ThreeGppChannelParams > channelParams, Ptr< const ChannelCondition > channelCondition, Ptr< const MobilityModel > aMob, Ptr< const MobilityModel > bMob) const
Update channel parameters for spatial consistency using 3GPP TR 38.901 procedure A.
static constexpr uint8_t R_INDEX
index of the R value in the m_nonSelfBlocking array
virtual Ptr< ChannelMatrix > GetNewChannel(Ptr< const ThreeGppChannelParams > channelParams, Ptr< const ParamsTable > table3gpp, Ptr< const MobilityModel > sMob, 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 ...
Ptr< ThreeGppChannelParams > GenerateChannelParameters(Ptr< const ChannelCondition > channelCondition, Ptr< const ParamsTable > table3gpp, Ptr< const MobilityModel > aMob, Ptr< const MobilityModel > bMob) const
Prepare 3gpp channel parameters among the nodes a and b.
static constexpr uint8_t PHI_INDEX
index of the PHI value in the m_nonSelfBlocking array
bool AntennaSetupChanged(Ptr< const PhasedArrayModel > aAntenna, Ptr< const PhasedArrayModel > bAntenna, Ptr< const ChannelMatrix > channelMatrix) const
Check if the channel matrix has to be updated due to changes in the number of antenna ports.
static constexpr uint8_t THETA_INDEX
index of the THETA value in the m_nonSelfBlocking array
void GenerateDopplerTerms(const uint8_t reducedClusterNumber, DoubleVector *dopplerTermAlpha, DoubleVector *dopplerTermD) const
Generate additional Doppler terms for delayed (reflected) paths.
double GetFrequency() const
Returns the center frequency.
void UpdateClusterAngles(Ptr< const ThreeGppChannelParams > channelParams, Double2DVector *clusterAngles, const DoubleVector &prevClusterDelay) const
Update cluster angles based on node mobility according to 3GPP TR 38.901.
Time m_updatePeriod
the channel update period enables spatial consistency, procedure A
Ptr< UniformRandomVariable > m_uniformRvShuffle
uniform random variable used to shuffle an array in GetNewChannel
virtual Ptr< const ParamsTable > GetThreeGppTable(Ptr< const MobilityModel > aMob, Ptr< const MobilityModel > bMob, Ptr< const ChannelCondition > channelCondition) const
Get the parameters needed to apply the channel generation procedure.
void UpdateClusterShadowingTerm(Ptr< const ParamsTable > table3gpp, DoubleVector *clusterShadowing, const double displacementLength) const
Update shadowing per cluster by using the normalized auto correlation function R, which is defined as...
Simulation virtual time values and global simulation resolution.
Definition nstime.h:95
a unique identifier for an interface.
Definition type-id.h:50
a 2d vector
Definition vector.h:196
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Data structure that stores channel parameters.
Large-scale channel parameters (3GPP TR 38.901).
double kFactor
Rician K-factor [dB] (used in LOS).
double ZSD
Zenith spread of departure [deg].
double ASD
Azimuth spread of departure [deg].
Data structure that stores the parameters of 3GPP TR 38.901, Table 7.5-6, for a certain scenario.
double m_sqrtC[7][7]
For LOS, LSP is following the order of [SF,K,DS,ASD,ASA,ZSD,ZSA].
double m_sigLgZSD
Standard deviation of 10-base logarithm of zenith angle spread of departure.
double m_cASD
Cluster ASD (Azimuth angle Spread of Departure).
double m_uLgZSD
Mean value of 10-base logarithm of zenith angle spread of departure.
double m_uLgASA
Mean value of 10-base logarithm of azimuth angle spread of arrival.
double m_sigXpr
Standard deviation of Cross-Polarization Ratio.
double m_uLgASD
Mean value of 10-base logarithm of azimuth angle spread of departure.
double m_cASA
Cluster ASA (Azimuth angle Spread of Arrival).
double m_perClusterRayDcorDistance
Correlation distance for spatial consistency (7.6.3.1-2) in meters.
uint8_t m_raysPerCluster
Number of rays per cluster.
double m_sigK
Standard deviation of K-factor.
double m_perClusterShadowingStd
Per cluster shadowing standard deviation.
double m_sigLgASD
Standard deviation of 10-base logarithm of azimuth angle spread of departure.
double m_offsetZOD
Offset of a zenith angle of departure.
double m_uLgDS
Mean value of 10-base logarithm of delay spread.
double m_sigLgASA
Standard deviation of 10-base logarithm of azimuth angle spread of arrival.
double m_uLgZSA
Mean value of 10-base logarithm of zenith angle spread of arrival.
double m_cZSA
Cluster ZSA (Zenith angle Spread of Arrival).
double m_blockerDcorDistance
The spatial correlation distance for the random variable determining the centre of the blocker in met...
double m_sigLgZSA
Standard deviation of 10-base logarithm of zenith angle spread of arrival.
double m_uXpr
Mean of Cross-Polarization Ratio.
double m_sigLgDS
Standard deviation value of 10-base logarithm of delay spread.
Extends the struct ChannelParams by including information that is used within the ThreeGppChannelMode...
std::vector< int > m_clusterXnNlosSign
The signs of the XN per cluster -1 or +1, per NLOS used in channel consistency procedure.
ChannelCondition::LosConditionValue m_losCondition
contains the information about the LOS state of the channel
Double2DVector m_rayAoaRadian
the vector containing AOA angles
Double2DVector m_rayZoaRadian
the vector containing ZOA angles
Vector m_lastPositionSecond
Position of the endpoint with the largest node ID (canonical endpoint ordering) at the time of the la...
double m_relativeDisplacement2D
2D displacement of the canonical relative position vector between the two endpoints since the last ge...
Double2DVector m_rayAodRadian
the vector containing AOD angles
Double2DVector m_norRvAngles
stores the normal variable for random angles angle[cluster][id] generated for equation (7....
ChannelCondition::O2iConditionValue m_o2iCondition
contains the information about the O2I state of the channel
Vector2D m_lastRelativePosition2D
Canonical 2D relative position vector (first -> second) stored at the time of the last channel parame...
DoubleVector m_attenuation_dB
vector that stores the attenuation of the blockage
Double2DVector m_rayZodRadian
the vector containing ZOD angles
Double2DVector m_crossPolarizationPowerRatios
cross-polarization power ratios
uint8_t m_cluster1st
index of the first strongest cluster
DoubleVector m_delayConsistency
cluster delay for consistency update
uint8_t m_cluster2nd
index of the second-strongest cluster
Double3DVector m_clusterPhase
the initial random phases
double m_endpointDisplacement2D
The effective 2D displacement used to determine whether a channel-consistency update can be applied,...
Vector m_lastPositionFirst
Position of the endpoint with the smallest node ID (canonical endpoint ordering) at the time of the l...