-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch '204-introduce-otfs' into 'master'
Introduce OTFS Closes #204 See merge request barkhauseninstitut/wicon/hermespy!170
- Loading branch information
Showing
14 changed files
with
338 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
==== | ||
OTFS | ||
==== | ||
|
||
.. inheritance-diagram:: hermespy.modem.waveforms.orthogonal.otfs.OTFSWaveform | ||
:parts: 1 | ||
|
||
Orthogonal Time Frequency Space (OTFS) modulation is a modulation scheme that is designed to provide high spectral efficiency and low latency. | ||
It is particularly well suited for high mobility scenarios, such as satellite and mobile communications. | ||
Within HermesPy, OTFS is implemented as type of :class:`OrthogonalWaveform<hermespy.modem.waveforms.orthogonal.waveform.OrthogonalWaveform>` | ||
and a precoding of :class:`OFDM<hermespy.modem.waveforms.orthogonal.ofdm.OFDMWaveform>`. | ||
|
||
Considering a simplex-link scenario of two modems communicating over a 3GPP 5G TDL channel | ||
|
||
.. literalinclude:: ../scripts/examples/modem_waveforms_otfs.py | ||
:language: python | ||
:linenos: | ||
:lines: 10-21 | ||
|
||
configuring an OTFS waveform requires the specification of the resource-time | ||
grid onto which the transmitted data and pilot symbols are placed: | ||
|
||
.. literalinclude:: ../scripts/examples/modem_waveforms_otfs.py | ||
:language: python | ||
:linenos: | ||
:lines: 23-37 | ||
|
||
The grid considers :math:`128` orthogonal subcarriers each modulated with a unique symbol, | ||
with :math:`128` repetitions in time-domain, so that overall :math:`16384` symbols are transmitted per frame. | ||
The grid alternates between two types of symbol sections, one carrying a reference element on every :math:`8`-th subcarrier | ||
and one consisting only of data symbols. | ||
|
||
Additionally, post-processing routines for channel estimation and channel equalization | ||
may be specified on the waveform level | ||
|
||
.. literalinclude:: ../scripts/examples/modem_waveforms_otfs.py | ||
:language: python | ||
:linenos: | ||
:lines: 39-45 | ||
|
||
.. autoclass:: hermespy.modem.waveforms.orthogonal.otfs.OTFSWaveform | ||
|
||
.. footbibliography:: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
import matplotlib.pyplot as plt | ||
|
||
from hermespy.channel import MultipathFading5GTDL, TDLType | ||
from hermespy.modem import OTFSWaveform, OrthogonalLeastSquaresChannelEstimation, PilotSection, CorrelationSynchronization, ZeroForcingChannelEqualization, PrefixType, SimplexLink, GridResource, GridElement, GuardSection, ElementType, SymbolSection | ||
from hermespy.simulation import Simulation | ||
|
||
|
||
# Initialize a simulation with two dedicated devices for transmission and reception | ||
carrier_frequency = 3.7e9 | ||
simulation = Simulation() | ||
tx_device = simulation.new_device(carrier_frequency=carrier_frequency) | ||
rx_device = simulation.new_device(carrier_frequency=carrier_frequency) | ||
|
||
# Assume a 5G TDL channel model | ||
channel = MultipathFading5GTDL(TDLType.A, 1e-7, doppler_frequency=10) | ||
simulation.set_channel(tx_device, rx_device, channel) | ||
|
||
# Link the devices | ||
link = SimplexLink(tx_device, rx_device) | ||
|
||
# Configure an orthogonal waveform featuring 128 subcarriers | ||
grid_resources = [ | ||
GridResource(16, PrefixType.CYCLIC, .1, [GridElement(ElementType.DATA, 7), GridElement(ElementType.REFERENCE, 1)]), | ||
GridResource(128, PrefixType.CYCLIC, .1, [GridElement(ElementType.DATA, 1)]), | ||
] | ||
grid_structure = [ | ||
SymbolSection(64, [0, 1]) | ||
] | ||
waveform = OTFSWaveform( | ||
grid_resources=grid_resources, | ||
grid_structure=grid_structure, | ||
num_subcarriers=128, | ||
subcarrier_spacing=1e3, | ||
) | ||
link.waveform = waveform | ||
|
||
# Configure channel estimation and equalization | ||
waveform.channel_estimation = OrthogonalLeastSquaresChannelEstimation() | ||
waveform.channel_equalization = ZeroForcingChannelEqualization() | ||
|
||
# Configure frame synchronization | ||
waveform.pilot_section = PilotSection() | ||
waveform.synchronization = CorrelationSynchronization() | ||
|
||
# Visualize the resource grid | ||
waveform.plot_grid() | ||
plt.show() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
from __future__ import annotations | ||
|
||
import numpy as np | ||
from scipy.fft import fft, ifft | ||
|
||
from .ofdm import OFDMWaveform | ||
|
||
__author__ = "Jan Adler" | ||
__copyright__ = "Copyright 2024, Barkhausen Institut gGmbH" | ||
__credits__ = ["Jan Adler"] | ||
__license__ = "AGPLv3" | ||
__version__ = "1.2.0" | ||
__maintainer__ = "Jan Adler" | ||
__email__ = "[email protected]" | ||
__status__ = "Prototype" | ||
|
||
|
||
class OTFSWaveform(OFDMWaveform): | ||
"""Orthogonal Time Frequency Space (OTFS) waveform.""" | ||
|
||
def _forward_transformation(self, symbol_grid: np.ndarray) -> np.ndarray: | ||
# Initial step: ISFFT | ||
delay_doppler_symbols = fft(ifft(symbol_grid, axis=-1, norm="ortho"), axis=-2, norm="ortho") | ||
|
||
# Second step: Heisenberg transform, i.e. the regular OFDM treatment | ||
sample_sections = OFDMWaveform._forward_transformation(self, delay_doppler_symbols) | ||
|
||
return sample_sections | ||
|
||
def _backward_transformation( | ||
self, sample_sections: np.ndarray, normalize: bool = True | ||
) -> np.ndarray: | ||
# Initial step: Inverse Heisenberg transform, i.e. the regular OFDM treatment | ||
delay_doppler_symbols = OFDMWaveform._backward_transformation( | ||
self, sample_sections, normalize, | ||
) | ||
|
||
# Second step: SFFT | ||
symbol_grid = ifft( | ||
fft(delay_doppler_symbols, axis=-1, norm="ortho"), axis=-2, norm="ortho" | ||
) | ||
|
||
# Normalize the symbol grid | ||
if normalize: | ||
symbol_grid /= np.sqrt(np.prod(symbol_grid.shape[:-2])) | ||
|
||
return symbol_grid |
Oops, something went wrong.