StochasticChannelModel.h Source File

Simu5G: StochasticChannelModel.h Source File
Simu5G
StochasticChannelModel.h
1//
2// Simu5G
3//
4// Copyright (C) 2012-2021 Giovanni Nardini, Giovanni Stea, Antonio Virdis et al. (University of Pisa)
5// Copyright (C) 2022-2026 Giovanni Nardini, Giovanni Stea et al. (University of Pisa)
6//
7// This file is part of a software released under the license included in file
8// "license.pdf". Please read LICENSE and README files before using it.
9// The above files and the present reference are part of the software itself,
10// and cannot be removed from it.
11//
12
13#ifndef STACK_PHY_CHANNELMODEL_STOCHASTICCHANNELMODEL_H_
14#define STACK_PHY_CHANNELMODEL_STOCHASTICCHANNELMODEL_H_
15
16#include "simu5g/common/LteDefs.h"
17#include "simu5g/stack/phy/channelmodel/ChannelModelBase.h"
18
19namespace simu5g {
20
21using namespace omnetpp;
22
23class Binder;
24class PathLossModel;
25
74{
75 protected:
76
77 // Information needed about the playground
78 bool useTorus_;
79
80 // eNodeB Height
81 double hNodeB_;
82
83 // UE Height
84 double hUe_;
85
86 // average Building Heights
87 double hBuilding_;
88
89 // true if the UE is inside a building
90 bool inside_building_;
91
92 // distance from the building wall
93 double inside_distance_;
94
95 // flag for using high-loss or low-loss model for building penetration
96 // see table 7.4.3-2 in TR 38.901
97 bool useBuildingPenetrationHighLossModel_;
98
99 // Average street's width
100 double wStreet_;
101
102 // enable/disable the shadowing
103 bool shadowing_;
104
105 // enable/disable intercell interference computation
106 bool enableBackgroundCellInterference_;
107 bool enableExtCellInterference_;
108 bool enableDownlinkInterference_;
109 bool enableUplinkInterference_;
110
111 bool enable_extCell_los_;
112
113 typedef std::pair<inet::simtime_t, inet::Coord> Position;
114
115 // Last position of current user
116 std::map<MacNodeId, std::queue<Position>> positionHistory_;
117
118 // Per link: the position at which the LOS probability was last computed.
119 std::map<LinkKey, Position> lastCorrelationPoint_;
120
121 // Scenario
122 DeploymentScenario scenario_;
123
124 // Formulas of the selected 3GPP propagation study; owned, created in initialize()
125 PathLossModel *pathLoss_ = nullptr;
126
127 // The ext-cell and background-cell interference paths evaluate their path
128 // loss with the TR 36.814 formulas regardless of which propagation study
129 // the model uses for its own links (see computeExtCellPathLoss); owned
130 PathLossModel *extCellPathLoss_ = nullptr;
131
132 // Per link: whether it is in Line of Sight
133 std::map<LinkKey, bool> losMap_;
134
135 // Stores the last computed shadowing for each user
136 typedef std::map<LinkKey, std::pair<inet::simtime_t, double>> ShadowFadingMap;
137 ShadowFadingMap lastComputedSF_;
138
139 // Correlation distance used in shadowing computation and
140 // also used to recompute the probability of LOS
141 double correlationDistance_;
142
143 // Percentage of error probability reduction for each h-arq retransmission
144 double harqReduction_;
145
146 // Antenna gain of eNodeB
147 double antennaGainEnB_;
148
149 // Antenna gain of micro node
150 double antennaGainMicro_;
151
152 // Antenna gain of UE
153 double antennaGainUe_;
154
155 // Thermal noise
156 double thermalNoise_;
157
158 // Cable loss
159 double cableLoss_;
160
161 // UE noise figure
162 double ueNoiseFigure_;
163
164 // eNodeB noise figure
165 double bsNoiseFigure_;
166
167 // Enable disable fading
168 bool fading_;
169
170 // Number of fading paths in Jakes fading
171 int fadingPaths_;
172
173 // Average delay spread in Jakes fading
174 double delayRMS_;
175
176 bool tolerateMaxDistViolation_;
177
178 // Struct used to store information about Jakes fading
179 struct JakesFadingData
180 {
181 std::vector<double> angleOfArrival;
182 std::vector<simtime_t> delaySpread;
183
184 friend std::ostream& operator<<(std::ostream& os, const JakesFadingData& e)
185 {
186 os << "paths=" << e.angleOfArrival.size();
187 return os;
188 }
189 };
190
191 // For each node and for each band we store information about Jakes fading
192 std::map<LinkKey, std::vector<JakesFadingData>> jakesFadingMap_;
193
194 // For each node and for each band we store information about Jakes fading
195 std::map<LinkKey, std::vector<JakesFadingData>> jakesFadingMapBgUe_;
196
197 typedef std::vector<JakesFadingData> JakesFadingVector;
198 typedef std::map<LinkKey, JakesFadingVector> JakesFadingMap;
199
200 enum FadingType
201 {
202 RAYLEIGH, JAKES
203 };
204
205 // Fading type (JAKES or RAYLEIGH)
206 FadingType fadingType_;
207
208 // Enable or disable the dynamic computation of LOS NLOS probability for each user
209 bool dynamicLos_;
210
211 // If dynamicLos is false this boolean is initialized to true if all users will be in LOS or false otherwise
212 bool fixedLos_;
213
214 // If false, disable the collection of SINR statistics, which might be quite time-consuming
215 bool collectSinrStatistics_;
216
217 // Statistics
218 static simsignal_t rcvdSinrDlSignal_;
219 static simsignal_t rcvdSinrUlSignal_;
220 static simsignal_t measuredSinrDlSignal_;
221 static simsignal_t measuredSinrUlSignal_;
222
223 public:
224 ~StochasticChannelModel() override;
225
226 void initialize(int stage) override;
227
228 /*
229 * Compute attenuation (path loss + optional shadowing) over a radio link.
230 */
231 double getAttenuation(const RadioLink& link) override;
232
233 /*
234 * Convenience overload for the cellular callers that still think in
235 * (UE, direction, remote coordinate) terms -- the interference helpers and
236 * the background-UE path. Builds a cellular link and forwards, so the
237 * subclass override of getAttenuation(const RadioLink&) still applies.
238 *
239 * @param nodeId mac node id of UE
240 * @param dir traffic direction
241 * @param coord position of end point communication (if dir==UL is the position of UE else is the position of eNodeB)
242 */
243 double getAttenuation(MacNodeId nodeId, Direction dir, inet::Coord coord, bool cqiDl)
244 {
245 return getAttenuation(cellularLink(nodeId, dir, coord, cqiDl));
246 }
247
248 /*
249 * Compute angle between two coordinates
250 *
251 * @param center first coord
252 * @param point second coord
253 */
254 virtual double computeAngle(Coord center, Coord point);
255
256 /*
257 * Compute vertical angle between two coordinates
258 * The returned angle is the angle with respect to the zenith direction
259 *
260 * @param center first coord
261 * @param point second coord
262 * @return angle
263 */
264 virtual double computeVerticalAngle(Coord center, Coord point);
265
266 /*
267 * Compute Attenuation caused by transmission direction
268 *
269 * @param angle angle
270 */
271 virtual double computeAngularAttenuation(double hAngle, double vAngle = 0);
272
273 /*
274 * Compute shadowing
275 *
276 * @param d3D 3D distance between UE and eNodeB
277 * @param d2D 2D distance between UE and eNodeB
278 * @param nodeid mac node id of UE
279 * @param speed speed of UE
280 */
281 virtual double computeShadowing(double d3D, double d2D, const LinkKey& key, MacNodeId ownerId, double speed, bool cqiDl);
282
283 /*
284 * Compute sir for each band for user nodeId according to multipath fading
285 *
286 * @param frame pointer to the packet
287 * @param lteinfo pointer to the user control info
288 */
289 std::vector<double> getSIR(LteAirFrame *frame, UserControlInfo *lteInfo) override;
290
291 /*
292 * Compute sinr for each band for user nodeId according to pathloss, shadowing (optional) and multipath fading
293 *
294 * @param frame pointer to the packet
295 * @param lteinfo pointer to the user control info
296 */
297 std::vector<double> getSINR(LteAirFrame *frame, UserControlInfo *lteInfo) override;
298
299 /*
300 * Add noise and interference to an already-computed per-band received-power
301 * vector. Split out so that a caller which already holds the RSRP (the D2D
302 * one-to-many capture-effect path) shares this implementation instead of
303 * repeating it.
304 */
305 virtual std::vector<double> getSINR(const RadioLink& link, UserControlInfo *lteInfo, std::vector<double> snrVector);
306
307 /*
308 * Compute received useful signal for each band for user nodeId according to pathloss, shadowing (optional) and multipath fading
309 *
310 * @param frame pointer to the packet
311 * @param lteinfo pointer to the user control info
312 */
313 std::vector<double> getRSRP(LteAirFrame *frame, UserControlInfo *lteInfo) override;
314
315 /*
316 * Compute sinr for each band for a background UE according to pathloss
317 *
318 * @param frame pointer to the packet
319 * @param lteinfo pointer to the user control info
320 */
321 std::vector<double> getSINR_bgUe(LteAirFrame *frame, UserControlInfo *lteInfo) override;
322
323 /*
324 * Compute received power for a background UE according to pathloss
325 *
326 */
327 double getReceivedPower_bgUe(double txPower, inet::Coord txPos, inet::Coord rxPos, Direction dir, bool losStatus, MacNodeId bsId) override;
328
329 /*
330 * Compute the error probability of the transmitted packet according to cqi used, txmode, and the received power
331 * after that it throws a random number in order to check if this packet will be corrupted or not
332 *
333 * @param frame pointer to the packet
334 * @param lteinfo pointer to the user control info
335 * @param rsrpVector the received signal for each RB, if it has already been computed
336 */
337 bool isReceptionSuccessful(LteAirFrame *frame, UserControlInfo *lteI, const std::vector<double>& rsrpVector) override;
338
339 /*
340 * Compute the path-loss attenuation according to the selected scenario
341 *
342 * @param distance between UE and eNodeB
343 * @param los line-of-sight flag
344 */
345 double computePathLoss(double distance, double dbp, bool los) override;
346
347 /*
348 * Compute Rayleigh fading
349 *
350 * @param i index in the trace file
351 * @param nodeid mac node id of UE
352 */
353 virtual double rayleighFading(MacNodeId id, unsigned int band);
354
355 /*
356 * Compute Jakes fading
357 *
358 * @param speed speed of UE
359 * @param nodeid mac node id of UE
360 * @param band logical band id
361 * @param cqiDl if true, the jakesMap in the UE side should be used
362 * @param isBgUe if true, this is called for a background UE
363 */
364 virtual double jakesFading(const LinkKey& key, MacNodeId ownerId, double speed, unsigned int band, bool cqiDl, bool isBgUe = false);
365
366 /*
367 * Compute LOS probability
368 *
369 * @param d3D 3D distance between UE and eNodeB
370 * @param d2D 2D distance between UE and eNodeB
371 * @param nodeid mac node id of UE
372 */
373 virtual void computeLosProbability(double d3D, double d2D, const LinkKey& key);
374
375 JakesFadingMap *getJakesMap()
376 {
377 return &jakesFadingMap_;
378 }
379
380 ShadowFadingMap *getShadowingMap()
381 {
382 return &lastComputedSF_;
383 }
384
385 bool isUplinkInterferenceEnabled() override { return enableUplinkInterference_; }
386 /*
387 * Compute the received useful signal (RSRP) per band over a radio link.
388 */
389 virtual std::vector<double> getRSRP(const RadioLink& link, double txPower);
390
391 protected:
392
393 /*
394 * Create the strategy object supplying the propagation formulas
395 * (pathLoss_), chosen by the pathLossType parameter.
396 */
397 virtual PathLossModel *createPathLossModel();
398
399 /*
400 * Build the RadioLink described by a frame's control info (DL, UL, and the
401 * feedback variants). The D2D path builds its links separately -- its API
402 * takes the peer endpoint explicitly rather than deriving it.
403 */
404 virtual RadioLink linkFor(UserControlInfo *lteInfo);
405
406 /*
407 * Build the RadioLink for a UE<->serving-BS link expressed the old way: the
408 * local module is one endpoint, 'coord' the other, and 'dir' says which of
409 * the two is the UE.
410 */
411 RadioLink cellularLink(MacNodeId ueId, Direction dir, inet::Coord coord, bool cqiDl);
412
413 /*
414 * Emit the received-SINR statistic for a decoded frame. Routes D2D/D2D_MULTI
415 * receptions to rcvdSinrD2D instead of letting them fall into the uplink
416 * statistic, which is where the DL/else split used to put them.
417 *
418 * @param dir direction of the reception
419 * @param ueId the UE end of the link (the sender, for an uplink reception)
420 * @param carrierFrequency carrier the frame arrived on
421 * @param sinr mean SINR over the resource blocks actually used
422 */
423 virtual void emitRcvdSinr(Direction dir, MacNodeId ueId, GHz carrierFrequency, double sinr);
424
425 /*
426 * Fill den[] with the per-band interference-plus-noise denominator, in dBm,
427 * for the bands this frame actually uses. Computes the cellular contributions
428 * (multi-cell, background-cell, external-cell). A subclass substitutes its own
429 * for link types the cellular model does not describe.
430 *
431 * @param totN linearized thermal noise + noise figure (mW)
432 */
433 virtual void computeInterferencePlusNoise(const RadioLink& link, UserControlInfo *lteInfo,
434 RbMap& rbmap, double totN, std::vector<double>& den);
435
436 /*
437 * Computes the per-band SINR used by isReceptionSuccessful(). Split out so that
438 * a subclass can route link types the cellular model does not describe -- the
439 * D2D channel model overrides this to send D2D/D2D_MULTI through getSINR_D2D.
440 *
441 * @param rsrpVector the RSRP the caller already holds, when it has one
442 */
443 virtual std::vector<double> getReceptionSinr(LteAirFrame *frame, UserControlInfo *lteInfo,
444 const std::vector<double>& rsrpVector) { return getSINR(frame, lteInfo); }
445
446 /*
447 * Returns the 2D distance between two coordinates (ignore z-axis)
448 */
449 virtual double getTwoDimDistance(inet::Coord a, inet::Coord b);
450
451 /*
452 * Compute speed (m/s) for a given node
453 * @param nodeid mac node id of UE
454 * @return the speed in m/s
455 */
456 virtual double computeSpeed(const MacNodeId nodeId, const inet::Coord coord);
457
458 /*
459 * Compute the euclidean distance between the current position and the
460 * last position used to calculate the LOS probability
461 */
462 virtual double computeCorrelationDistance(const LinkKey& key, const inet::Coord coord);
463
464 /*
465 * Update base point if distance to previous value is greater than the
466 * correlationDistance_
467 */
468 virtual void updateCorrelationDistance(const LinkKey& key, const inet::Coord coord);
469
470 /*
471 * Updates position for a given node
472 * @param nodeid mac node id of UE
473 */
474 virtual void updatePositionHistory(const MacNodeId nodeId, const inet::Coord coord);
475
476 /*
477 * One interfering transmitter, normalized across the two kinds the UL
478 * transmission map can hold: a real UE (with a PHY) and a background UE
479 * (with a traffic generator).
480 */
481 struct InterfererInfo
482 {
483 MacNodeId nodeId;
484 MacCellId cellId;
485 Direction dir;
486 double txPwr;
487 inet::Coord coord;
488 };
489
490 /*
491 * Unpack a UeAllocationInfo into the properties every interference
492 * computation needs. Shared by the uplink and D2D interference loops, which
493 * otherwise differ in their exclusion rules and antenna-gain terms.
494 */
495 static InterfererInfo describeInterferer(const UeAllocationInfo& allocation);
496
497 /*
498 * Compute total interference due to eNB coexistence for the DL direction
499 * @param eNbId id of the considered eNb
500 * @param isCqi if we are computing a CQI
501 */
502 virtual bool computeDownlinkInterference(MacNodeId eNbId, MacNodeId ueId, inet::Coord coord, bool isCqi, GHz carrierFrequency, const RbMap& rbmap, std::vector<double> *interference);
503
504 /*
505 * Compute interference coming from neighboring cells for the UL direction
506 */
507 virtual bool computeUplinkInterference(MacNodeId eNbId, MacNodeId senderId, bool isCqi, GHz carrierFrequency, const RbMap& rbmap, std::vector<double> *interference);
508
509 /*
510 * Evaluates total interference from external cells seen from the spot given by coord
511 * @return total interference expressed in dBm
512 */
513 virtual bool computeExtCellInterference(MacNodeId eNbId, MacNodeId nodeId, inet::Coord coord, bool isCqi, GHz carrierFrequency, std::vector<double> *interference);
514
515 /*
516 * Evaluates total interference from external cells seen from the spot given by coord
517 * @return total interference expressed in dBm
518 */
519 virtual bool computeBackgroundCellInterference(MacNodeId nodeId, inet::Coord bsCoord, inet::Coord ueCoord, bool isCqi, GHz carrierFrequency, const RbMap& rbmap, Direction dir, std::vector<double> *interference);
520
521 /*
522 * Compute attenuation due to path loss and shadowing
523 * @return attenuation expressed in dBm
524 */
525 virtual double computeExtCellPathLoss(double dist, const LinkKey& key);
526
527 /*
528 * Obtain the jakes map for the specified UE
529 * @param id mac id of the user
530 */
531 virtual JakesFadingMap *obtainUeJakesMap(MacNodeId id);
532
533 /*
534 * Obtain the shadowing map for the specified UE
535 * @param id mac id of the user
536 */
537 virtual ShadowFadingMap *obtainShadowingMap(MacNodeId id);
538};
539
540} //namespace
541
542#endif /* STACK_PHY_CHANNELMODEL_STOCHASTICCHANNELMODEL_H_ */
543
Definition Binder.h:48
Definition ChannelModelBase.h:145
Definition PathLossModel.h:36
Definition StochasticChannelModel.h:74
Definition AlertReceiver.h:24
MacNodeId MacCellId
Cell node ID. It is numerically equal to eNodeB MAC node ID.
Definition LteTypes.h:66
std::map< Remote, std::map< Band, unsigned int > > RbMap
Definition LteTypes.h:145
Definition ChannelModelBase.h:47