Skip to content

IPathLoss: the path loss of a reception, per receiver and over frequency - #1308

Merged
torokati44 merged 4 commits into
inet-framework:masterfrom
torokati44:topic/pathloss-per-receiver
Oct 13, 2026
Merged

torokati44 merged 4 commits into
inet-framework:masterfrom
torokati44:topic/pathloss-per-receiver

Conversation

@torokati44

@torokati44 torokati44 commented Oct 7, 2026 •

Copy link
Copy Markdown
Member

What

IPathLoss gets a per-reception method that knows the receiver radio:

Ptr<const IReceptionPathLoss> computeReceptionPathLoss(const IRadio *receiverRadio, const ITransmission *transmission, const IArrival *arrival) const;

It replaces computePathLoss(transmission, arrival). The returned IReceptionPathLoss gives the loss factor at any frequency through computePathLoss(Hz). This is the same shape as IAntenna::getGain() and IAntennaGain.

Why

  • No receiver, so no per-link state. A path loss could see the transmitter but not the receiver. Shadowing that is correlated over distance needs per-link state, and so do cellular models, which keep a line-of-sight state per link.
  • The dimensional model ignored the link. DimensionalMediumAnalogModel never called the link form. It called the distance form per frequency, so link geometry (the TwoRay models) was ignored there.
  • The value is settled when the reception is computed. The dimensional model evaluates the attenuation lazily, repeatedly, and possibly after the transmission and arrival are deleted. So a model resolves any per-link state in the call, and the returned object holds values only. This also keeps the dimensional math types (IFunction) out of the path-loss contract.

Commits

  1. Rename: computePathLoss(speed, frequency, distance) becomes computeDistancePathLoss(). It was overloaded with the link form, and overriding one overload hid the other. Mechanical.
  2. The new method: computeReceptionPathLoss() and IReceptionPathLoss. The PathLossBase default reduces the link to its distance. TwoRayGroundReflection and TwoRayInterference keep the link's geometry. Both analog models call it once per reception.
  3. Correlated shadowing: LogNormalShadowing gets an optional correlationDistance; the default, NaN, keeps the old behaviour. With a distance, there is one value per radio pair, the same in both directions, redrawn when either end moves farther than that distance.
  4. One shadowing value per reception: without a correlation distance, LogNormalShadowing now draws one value per reception. Before, under the dimensional model, it drew one per evaluation.

Compatibility

Breaking C++ API (WHATSNEW incompatible items 23 and 24):

  • every path-loss model derived from PathLossBase must rename its computePathLoss(speed, frequency, distance) override;
  • code that implements or calls computePathLoss(transmission, arrival), or constructs FrequencyDependentAttenuationFunction, must be updated.

No NED or ini changes except the new correlationDistance parameter. Default behaviour is unchanged. Under the dimensional model, both TwoRay models now use the link's geometry; before, TwoRayGroundReflection acted as free space and TwoRayInterference returned NaN.

Testing

  • Release fingerprints (wireless-combo, examples, showcases, tutorials, mipv6-refactoring) give the same results as the base commit.
  • The module tests pass, including the new LogNormalShadowing_Correlated_1 to _5.

Notes for review

  • computeDistancePathLoss() is now documented as possibly NaN. The medium visualizer's power-density maps don't handle NaN; that is already the case today with TwoRayInterference.

@torokati44
torokati44 force-pushed the topic/pathloss-per-receiver branch from cdf0988 to 9173331 Compare October 13, 2026 10:21
@torokati44 torokati44 changed the title IPathLoss: per receiver and over frequency, with correlated log-normal shadowing as its first user IPathLoss: the path loss of a reception, per receiver and over frequency Oct 13, 2026
@torokati44
torokati44 marked this pull request as ready for review October 13, 2026 13:32
IPathLoss had two computePathLoss() overloads: one for a transmission and
an arrival, one for a propagation speed, a frequency and a distance. Every
path loss model derived from PathLossBase overrides only the latter, and a
class that overrides one overload hides the other in its own scope; the
next commit replaces the former with a method that computes the path loss
of a reception, so the overload set would only grow more confusing.

computePathLoss(propagationSpeed, frequency, distance) is renamed to
computeDistancePathLoss(), in IPathLoss, PathLossBase, the eleven models
and its three callers (PathLossBase, FrequencyDependentAttenuationFunction
and the medium visualizer's PathLossFunction). Its documentation states
what the models already do: the value is independent of the transmitter
and the receiver, or NaN when the model cannot tell it from the distance
alone, as TwoRayInterference. API change, stated in WHATSNEW.
IPathLoss::computePathLoss(transmission, arrival) saw the transmitter
(through the transmission) but not the receiver, so no path loss could keep
per-link state. DimensionalMediumAnalogModel did not call it at all: it
reduced the link to its distance and called computeDistancePathLoss() for
every frequency it sampled, so a path loss could not use the link's
geometry there either.

computeReceptionPathLoss(receiverRadio, transmission, arrival) replaces it
and returns an IReceptionPathLoss, the path loss of that one reception,
whose computePathLoss(frequency) gives the loss factor at any frequency:
the same shape as IAntenna::getGain() and IAntennaGain, and like those it
keeps the dimensional math out of the contract. Both medium analog models
call it once per reception, with the receiver radio they already had: the
scalar one evaluates the result at the center frequency, the dimensional
one samples it across the band, through FrequencyDependentAttenuationFunction,
which takes the reception's path loss in place of calling the path loss
model itself. The dimensional model evaluates its attenuation lazily,
possibly several times and at any later time, and the medium may delete the
transmission and the arrival before the last evaluation, so the returned
object holds values only (and may refer to the path loss model): a path
loss that keeps per-link state resolves it in the call.

The PathLossBase default returns a DistanceReceptionPathLoss, which calls
computeDistancePathLoss() for the link's distance whenever it is
evaluated, with the same arguments and at the same moments as both analog
models did before. TwoRayGroundReflection and TwoRayInterference, the two
models that overrode the replaced method, each return a nested
ReceptionPathLoss that holds the link's geometry; under the dimensional
model they now use it too, where before the former acted as
FreeSpacePathLoss and the latter returned NaN. API change, stated in
WHATSNEW.
LogNormalShadowing drew a new shadowing value on every path loss
computation: two receptions of the same link at the same position could
differ by several sigma. With computeReceptionPathLoss() knowing the
receiver radio, a path loss can keep per-link state; this is the first to
do so.

New parameter correlationDistance, default NaN = the memoryless draw as
before. With a distance, the value is kept per pair of radios, keyed by
the smaller radio id first, together with the position of each radio at
the draw, and drawn again when either radio has moved farther than the
distance from its position then. Shadowing is caused by the obstacles on
the path between the two radios: it is the same in both directions, and
it changes when either end moves (with a receiver-only rule, the uplink
of a node moving away from a stationary base station would keep its first
value forever). The shadowing draw moved into a helper, computeShadowedPathLoss(); in the
default mode it is drawn once per computation at the same point as before.

The value is resolved in computeReceptionPathLoss(), once per reception,
and the returned ReceptionPathLoss holds it, so it does not depend on when
or how often the medium analog model evaluates it: with
DimensionalMediumAnalogModel the whole band of a reception has the same
shadowing, as with the scalar model.

The values of a radio's links are dropped when the radio is removed from
the medium, so that in a simulation where nodes come and go the map does
not grow with every radio that ever existed. When a correlation distance
is set, the module subscribes to IRadioMedium::radioRemovedSignal at its
parent module, the medium, which emits the signal on itself; the parent
is checked to be an IRadioMedium, as the obstacle loss models and
MediumLimitCache look up theirs. With the default nothing is subscribed.

Tests: LogNormalShadowing_Correlated_1..5 (stationary nodes: one power for
all eight receptions, both directions; the default: a new value every
time; host2 circling a stationary host1 at constant distance: a new value
per ping, reused by its reply, four powers each received in both
directions; host2 deleted after two pings: its one pair is dropped; the
stationary case on a dimensional medium: one power spectral density for
all eight receptions).
Without a correlation distance, computeReceptionPathLoss() returned the
PathLossBase default, which calls computeDistancePathLoss() on every
evaluation, and that draws a new shadowing value each time.
DimensionalMediumAnalogModel evaluates the attenuation per frequency sample
and possibly again later, so the samples of one reception had independent
shadowing values, and a repeated evaluation gave a different one.

computeReceptionPathLoss() now draws the value once, when the reception is
computed, and returns a ReceptionPathLoss that holds it, as with a
correlation distance. The scalar model and the dimensional one with the
default attenuateWithCenterFrequency evaluate it once, right after the
call, so the draws happen in the same order as before.
computeDistancePathLoss() keeps drawing per call; only callers without a
link use it.
@torokati44
torokati44 force-pushed the topic/pathloss-per-receiver branch from 9173331 to d83f1ee Compare October 13, 2026 13:40
@torokati44
torokati44 merged commit 11b59c2 into inet-framework:master Oct 13, 2026
15 checks passed
@torokati44
torokati44 deleted the topic/pathloss-per-receiver branch October 13, 2026 14:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant