Channel Modeling¶
The channel modeling module provides functionalities to model the wireless transmission link between devices on a physical level.
In general, the transmission of any multi-antenna signal
considering \(N_\mathrm{Tx}\) transmitted antenna signal streams will lead to an excitation of all \(N_\mathrm{Rx}\) considered reveing antennas
Naturally, this excitation strongly depends on the physical environment and its parameters, for example the transmitted wavelengths, velocities of transmitter and receiver, distance and orientation between transmitter and receiver, environmental scatterers and their respective positions, extents and velocities, just to name a few. The environment assumptions, also referred to as channel model, can be described by a linear system
as a function of time \(t\), propagation delay \(\tau\) as well as the transmitter’s and receiver’s respective positions and orientations in space, denoted by the global coordinate system transformation matrices
respectively. For ease of notation, the coordinate system transformations will be ommitted in the following discussion, unless specifically required. The received antenna signals are then the convolution
of the transmitted signals with the channel model. Neither \(\mathbf{H}(t, \tau)\) nor \(\mathbf{x}(t)\) are generally differentiable. Therefore HermesPy models the channel and signals as a discrete-time system instead, sampling the continuous-time models at a rate \(f_\mathrm{s}\). Let
be the uniformly sampled transmitted signal at sampling rate \(f_\mathrm{s}\) consisting of \(M_\mathrm{Tx}\) samples and \(N_\mathrm{Tx}\) antenna signal streams. Equivalently, the received signal can be expressed as
the uniformly sampled received signal at sampling rate \(f_\mathrm{s}\) consisting of \(M_\mathrm{Rx}\) samples and \(N_\mathrm{Rx}\) antenna signal streams. Sampling the channel model at the same rate in both time and delay
enables the expression of the received signal as a time-discrete convolution of the transmitted signal and the channel model
Note that many channel models that consider discrete delay taps \(\lbrace \tau_0,\,\dotsc,\,\tau_{\ast} \rbrace\) meaning that the channel is sparse in its delay domain
and therefore zero for delays outside the set of discrete taps.
Uniformly sampling such models at discrete time-instances results in zero propagation,
since the sampling points will not fall directly on the discrete taps.
To avoid this, HermesPy requires channel models to resample their delay dimension
by either interpolating in between the delays using a sinc-kernel or rounding all delays to the closest sampling tap.
This behaviour is controlled by the InterpolationMode
flag exposed in several methods.
Each channel model conists of the implementation of a tandem of two abstract base classes: The Channel, which acts as the basic generator, the Channel Realization, which represents a specific realization of the channel model, and the Channel Sample, which represents a specific sample of the channel model in time and space. The following class diagram visualizes the general interaction:
classDiagram direction LR class Channel { <<Abstract>> realize() : ChannelRealization } class ChannelRealization { <<Abstract>> +sample() : ChannelSample } class ChannelSample { <<Abstract>> propagate(Signal) : Signal } Channel --o ChannelRealization : realize() ChannelRealization --o ChannelSample : sample() click Channel href "channel.Channel.html" click ChannelRealization href "channel.ChannelRealization.html" click ChannelSample href "channel.ChannelSample.html"
Each invocation of a Channel object’s realize
or propagate
method
results in the generation of a new ChannelRealization object.
A ChannelRealization fixes all spatially invariant parameters of the channel model and realizes the spatially random parameter distributions.
Calling the ChannelRealization’s sample
method results in a new ChannelSample object,
which represents a single one-directional propagation channel in space and time,
meaning calling the ChannelSample’s propagate
method with identical input will result in the identical output.
flowchart LR device_alpha_reception[Device Reception] device_alpha[Simulated Device] device_beta_propagation[Propagated Signal] device_alpha_transmission[Device Transmission] subgraph Channel direction TB channel[Channel] --> channel_realization[Channel Realization] --> channel_sample[Channel Sample] end device_beta_transmission[Device Transmission] device_alpha_propagation[Propagated Signal] device_beta[Simulated Device] device_beta_reception[Device Reception] device_alpha_reception --- device_alpha device_alpha --> device_alpha_transmission device_alpha_transmission --> Channel Channel --> device_alpha_propagation --> device_beta device_beta --> device_beta_reception device_alpha --- device_beta_propagation --- Channel --- device_beta_transmission --- device_beta click channel href "channel.Channel.html" click channel_realization href "channel.ChannelRealization.html" click channel_sample href "channel.ChannelSample.html" click device_alpha_propagation href "../core.signal_model.Signal.html" click device_beta_propagation href "../core.signal_model.Signal.html" click device_alpha href "simulation.simulated_device.html" click device_beta href "simulation.simulated_device.html" click device_alpha_reception "simulation.simulated_deviceReception.html" click device_beta_reception "simulation.simulated_deviceReception.html" click device_alpha_transmission "simulation.simulated_deviceTransmission.html" click device_beta_transmission "simulation.simulated_deviceTransmission.html"
Operating the described interface requires the import of a Channel
implementation and
the Simulated Devices
to be linked.
1from hermespy.channel import Channel
2from hermespy.simulation import SimulatedDevice
Note that, since it is an abstract base class, the Channel
used in this example cannot be instantiated directly.
Instead, a concrete implementation such as the Ideal Channel
must be used.
Now, the Channel
can be linked to the Simulated Devices
.
1# Initialize two devices to be linked by a channel
2alpha_device = SimulatedDevice()
3beta_device = SimulatedDevice()
4
5# Create a channel between the two devices
6channel = Channel()
The basic order to simulate a reciprocal channel transmission, meaning both devices transmit and receive simulataneously, requires the generation of both transmissions, followed by a propagation over a joint channel realization and finally the reception of both propagations.
1# Generate the device's transmissions
2alpha_transmission = alpha_device.transmit()
3beta_transmission = beta_device.transmit()
4
5# Propagate the transmissions over the channel
6channel_realization = channel.realize()
7alpha_propagation = channel_realization.sample(alpha_device, beta_device).propagate(alpha_transmission)
8beta_propagation = channel_realization.sample(beta_device, alpha_device).propagate(beta_transmission)
9
10# Receive the transmissions at both devices
11alpha_reception = alpha_device.receive(beta_propagation)
12beta_reception = beta_device.receive(alpha_propagation)
This snippet is essentially a summary of what is happening within the drop generation of Simulations
.
However, by default devices won’t generate any waveforms to be transmitted.
For example, a SimplexLink
transmitting a hermespy.modem.waveform.single_carrier.RootRaisedCosine
from the first to the second device can be configured as follows:
1# Configure communication link between the two devices
2link = SimplexLink()
3alpha_device.transmitters.add(link)
4beta_device.receivers.add(link)
5
6# Specify the waveform and postprocessing to be used by the link
7link.waveform = RootRaisedCosineWaveform(symbol_rate=1e8, oversampling_factor=2,
8 num_data_symbols=1000, num_preamble_symbols=10, pilot_rate=10)
9link.waveform.channel_estimation = SingleCarrierLeastSquaresChannelEstimation()
10link.waveform.channel_equalization = SingleCarrierZeroForcingChannelEqualization()
Investigating the performance of the configured waveform over the specific Channel
within a Simulation
requires the instantiation of a new Simulation
and adding the already existing Channel
and Simulated Devices
.
1from hermespy.simulation import Simulation
2
3# Create a new simulation and add the two existing devices
4simulation = Simulation()
5
6simulation.add_device(alpha_device)
7simulation.add_device(beta_device)
Now, evaluators such as BER
can be added to the simulation pipeline and
the Simulation
can be executed and the results can be analyzed.
1# Configure a bit error rate evaluation
2simulation.add_evaluator(BitErrorEvaluator(link, link))
3
4# Run the simulation
5simulation.new_dimension('noise_level', dB(0, 2, 4, 8, 12, 16, 20), beta_device)
The channel module consists of the base classes
HermesPy provides serveral purely statistical channel models, which do not assume any spatial correlation between the devices, their antennas or the propagation environment
In addition, geometry-based stochastical and deterministic channel models are provided,
which model the propagation environment as a collection of scatterers.
Note that these models might require specifying the linked devices position
.