{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "b61d19e0",
   "metadata": {
    "nbgrader": {
     "grade": false,
     "grade_id": "cell-195080798f7dd794",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "source": [
    "# Multipath Fading Simulation\n",
    "\n",
    "**Betreuer:** Karl Besser (besser@ifn.ing.tu-bs.de)\n",
    "\n",
    "## Szenario\n",
    "Wir gehen von einem Übertragungsszenario mit einem Sender und einem Empfänger aus.\n",
    "Beide befinden sich in einem (sehr langen) Tunnel mit Breite $B$ und Höhe $H$.\n",
    "Dieses Szenario ist in der Projektbeschreibung dargestellt.\n",
    "Der Sender befindet sich an den Koordinaten $(x_t, 0, h_t)$ und der Empfänger bei $(x_r, y_r, h_r)$.\n",
    "\n",
    "## Ziel der Aufgabe\n",
    "Es soll die Leistung des empfangenen Signals am Empfänger berechnet werden.\n",
    "Diese soll über einen variierenden Abstand des Empfängers in $y$-Richtung geplottet werden.\n",
    "\n",
    "\n",
    "## Mathematische/Nachrichtentechnische Grundlagen\n",
    "Aufgrund der geometrischen Anordnung von Sender und Empfänger wird das am Sender abgestrahlte Signal an den Wänden (inkl. Boden) reflektiert.\n",
    "Diese Reflexionen überlagern sich am Empfänger und bilden das Gesamtsignal.\n",
    "\n",
    "Es wird das folgende (vereinfachte) Modell der Empfangsleistung $P_r$ verwendet\n",
    "\\begin{equation}\\label{eq:rec-power}\n",
    "\tP_r = P_t\\left(\\frac{c}{2\\omega}\\right)^2 \\left|{\\sum_{i=1}^{N} \\frac{A_i}{\\ell_i} \\exp\\left(-\\mathrm{i}\\frac{\\omega}{c}\\ell_i\\right)}\\right|^2\\,,\n",
    "\\end{equation}\n",
    "\n",
    "Eine Erklärung der verwendeten Variablen ist in der Projektbeschreibung aufgeführt.\n",
    "Für alle Betrachtungen in diesem Praktikum sollen nur die einfachen Reflexionen betrachtet werden.\n",
    "\n",
    "## Aufgaben\n",
    "Die folgenden Aufgaben sollen im Rahmen des Praktikums in der Programmiersprache Python implementiert werden.\n",
    "\n",
    "1. Berechnung der absoluten Pfadlängen $\\ell_i$ für gegebene Positionen $(x_t, 0, h_t)$ und $(x_r, y_r, h_r)$\n",
    "2. Berechnung der Empfangsleistung nach obiger Gleichung für gegebene Positionen von Sender und Empfänger und Frequenz~$f$\n",
    "3. Plot der Empfangsleistung über $y_r$ und Vergleich mit der Empfangsleistung ohne Reflexionen"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cd894130",
   "metadata": {
    "nbgrader": {
     "grade": false,
     "grade_id": "cell-5da9bb0b02ca0754",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "from scipy import constants\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "def to_decibel(x):\n",
    "    return 10*np.log10(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e8a65013",
   "metadata": {
    "nbgrader": {
     "grade": false,
     "grade_id": "cell-3d341853860bac83",
     "locked": false,
     "schema_version": 3,
     "solution": true,
     "task": false
    }
   },
   "outputs": [],
   "source": [
    "# Berechnung der einzelnen Pfadlaengen\n",
    "\n",
    "### BEGIN SOLUTION\n",
    "def length_los(x_tx, x_rx, y_tx, y_rx, h_tx, h_rx, **kwargs):\n",
    "    distance_sq = (x_tx-x_rx)**2 + (y_tx-y_rx)**2\n",
    "    return np.sqrt(distance_sq + (h_tx-h_rx)**2)\n",
    "\n",
    "def length_ground(x_tx, x_rx, y_tx, y_rx, h_tx, h_rx, **kwargs):\n",
    "    distance_sq = (x_tx-x_rx)**2 + (y_tx-y_rx)**2\n",
    "    return np.sqrt(distance_sq + (h_tx+h_rx)**2)\n",
    "\n",
    "def length_left(x_tx, x_rx, y_tx, y_rx, h_tx, h_rx, **kwargs):\n",
    "    return np.sqrt((x_tx+x_rx)**2 + (y_tx-y_rx)**2 + (h_tx-h_rx)**2)\n",
    "\n",
    "def length_right(x_tx, x_rx, y_tx, y_rx, h_tx, h_rx, width, **kwargs):\n",
    "    return np.sqrt((2*width-x_tx-x_rx)**2 + (y_tx-y_rx)**2 + (h_tx-h_rx)**2)\n",
    "\n",
    "def length_top(x_tx, x_rx, y_tx, y_rx, h_tx, h_rx, height, **kwargs):\n",
    "    return np.sqrt((x_tx-x_rx)**2 + (y_tx-y_rx)**2 + (2*height-h_tx-h_rx)**2)\n",
    "### END SOLUTION"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a8d72017",
   "metadata": {
    "nbgrader": {
     "grade": false,
     "grade_id": "cell-c1c65928c63568af",
     "locked": false,
     "schema_version": 3,
     "solution": true,
     "task": false
    }
   },
   "outputs": [],
   "source": [
    "# Berechnung der Empfangsleistung\n",
    "\n",
    "### BEGIN SOLUTION\n",
    "def receive_power(path_len, refl_coeff, freq, pow_tx=1, c=constants.c):\n",
    "    omega = 2*np.pi*freq\n",
    "    _factor = pow_tx * (c/(2*omega))**2\n",
    "    _sum_components = refl_coeff * np.exp(-1j*omega/c*path_len)\n",
    "    path_sum = np.sum(_sum_components, axis=-1)\n",
    "    rec_power = _factor * np.abs(path_sum)**2\n",
    "    return rec_power\n",
    "### END SOLUTION"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "adb191eb",
   "metadata": {
    "nbgrader": {
     "grade": false,
     "grade_id": "cell-ad92c5daedf4aa1b",
     "locked": false,
     "schema_version": 3,
     "solution": true,
     "task": false
    }
   },
   "outputs": [],
   "source": [
    "def main():\n",
    "    y_rx = np.logspace(1, 3, 3000)\n",
    "    y_tx = np.zeros_like(y_rx)\n",
    "    h_tx = 3\n",
    "    h_rx = 1.5\n",
    "    x_tx = 5\n",
    "    x_rx = 5\n",
    "    width = 10\n",
    "    height = 10\n",
    "    freq=2.4e9\n",
    "\n",
    "    fig, axs = plt.subplots()\n",
    "    \n",
    "    ### BEGIN SOLUTION\n",
    "    func_lengths = {\n",
    "                    \"All components\": [length_los, length_ground, length_left, length_right, length_top],\n",
    "                    \"Two-Ray Ground\": [length_los, length_ground],\n",
    "                    \"LOS only\": [length_los],\n",
    "                   }\n",
    "    for name, _func_lengths in func_lengths.items():\n",
    "        path_len = np.vstack([_length(x_tx, x_rx, y_tx, y_rx, h_tx, h_rx,\n",
    "                                      width=width, height=height)\n",
    "                              for _length in _func_lengths]).T\n",
    "        refl_coeff = -1./path_len\n",
    "        refl_coeff[:, 0] = -refl_coeff[:, 0]\n",
    "        rec_power = receive_power(path_len, refl_coeff, freq)\n",
    "        axs.semilogx(y_rx, to_decibel(rec_power), label=name)\n",
    "    ### END SOLUTION\n",
    "    \n",
    "    axs.legend()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4ee66458",
   "metadata": {},
   "outputs": [],
   "source": [
    "main()"
   ]
  }
 ],
 "metadata": {
  "celltoolbar": "Create Assignment",
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
