{ "cells": [ { "cell_type": "markdown", "id": "c40822ff", "metadata": {}, "source": [ "# FMCW Intro\n", "\n", "You can open this workbook in Google Colab to experiment with mmWrt \n", "[![](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/matt-chv/mmWrt/blob/main/docs/Intro_nb.ipynb)\n", "\n", "Below is an intro to mmWrt for simple targets position estimation\n", "\n", "For a generic introduction to mmWave sensors:\n", "[Watch Here](https://www.youtube.com/watch?v=XJ6JhB8wOPU)" ] }, { "cell_type": "markdown", "id": "302506ed", "metadata": {}, "source": [ "### linear chirps and IF frequencies\n", "\n", "Signal model\n", "According to (Barriok 1973; Stove 1992; Komarov and Smolskiy 2003; Winkler 2007) the\n", "transmitted signal of an FMCW radar system can be modeled as\n", "where\n", "\n", "$$ y_T (t) = A_T \\cdot cos\\left( 2 \\pi \\cdot ( f_{0min} \\cdot t +\\int_0^tf_T({\\tau}) d\\tau)\\right)$$\n", "\n", "Given for a linear chirp that\n", "$$ f_T(\\tau) = \\frac{B}{T} \\cdot \\tau = s \\cdot \\tau $$\n", "We derive the phase, given\n", "$$ \\int_0^t f_T({\\tau}) d\\tau = \\frac{s}{2} \\cdot \\tau^2 - K$$\n", "\n", "which can be written as:\n", "$$ y_T (t) = A_T \\cdot cos \\left( 2 \\pi \\cdot ( f_{0min} \\cdot t + \\frac{s}{2} \\cdot t^2 )+\\Phi_0 \\right) $$\n", "\n", "Where:\n", "* $ f_{0min} $ is the start frequency at the begining of the raising frequency of the chirp.\n", "* s is the slope at which the frequency is ramped ( $ S = \\frac{B}{T} $)\n", "* B is the total bandwdith of the chirp\n", "* T is the total time of the chirp\n", "\n", "Considering a reflected signal with a time delay $ \\delta = 2 · \\frac{R0+ v\\cdot t}{c} $ and Doppler shift $ f_D = −2 · \\frac{f_c \\cdot v}{c} $\n", "\n", "Where:\n", "\n", "* c is the speed of light\n", "* $ f_D $ is the doppler shift\n", "* R0 is the nominal distance to the target\n", "* $ \\delta $ is the time of flight (to and from the target)\n", "* v is the velocity of the target\n", "\n", "The receive signal $ y_R(t) $ can be written as :\n", "\n", "$$ y_R(t) = A_R \\cdot cos ( 2\\pi \\cdot (f_{0min} + \\frac{s}{2} \\cdot (t-\\delta)) \\cdot (t-\\delta)) $$\n", "\n", "\n", "$ y_{IF}(t) $ is the IF signal (after mixer) which is obtained by multiplication in the time domain, and passed to a low-pass filter (LPF)\n", "\n", "This can be done easily when remembering the trigonometric relation:\n", "\n", "$$ cos(\\alpha) \\cdot cos(\\beta) = \\frac{cos(\\alpha + \\beta) + cos(\\alpha - \\beta)}{2} $$\n", "\n", "$$ y_{IF}(t) = y_R(t) \\cdot y_T(t) $$\n", "\n", "Noticing that the element which sums the elements will be higher frequency and will be filtered by the LPF, it remains that:\n", "\n", "$$ y_{IF}(t) = \\frac{A_t \\cdot A_r}{2} \\cdot cos(2 \\pi \\cdot [f_{0min} \\cdot \\delta + s \\cdot \\delta \\cdot t - \\frac{s}{2} \\cdot \\delta^2])$$\n", "\n", "Where:\n", "\n", "* $ f_{0min} $ the starting frequency of the chirp\n", "* s is the slope of the chirp\n", "* $\\delta $ is the total time of flight between antennas and target\n", "* At, Ar: Amplitude of the RX and TX waves" ] }, { "cell_type": "code", "execution_count": 1, "id": "9e78a038", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "running from git folder, using local path (latest) mmWrt code c:\\git\\mmWrt\n", "2024-05-23 14:22:24.667261\n" ] } ], "source": [ "# Install a pip package in the current Jupyter kernel\n", "import sys\n", "from os.path import abspath, basename, join, pardir\n", "import datetime\n", "\n", "# hack to handle if running from git cloned folder or stand alone (like Google Colab)\n", "cw = basename(abspath(join(\".\")))\n", "dp = abspath(join(\".\",pardir))\n", "if cw==\"docs\" and basename(dp) == \"mmWrt\":\n", " # running from cloned folder\n", " print(\"running from git folder, using local path (latest) mmWrt code\", dp)\n", " sys.path.insert(0, dp)\n", "else:\n", " print(\"running standalone, need to ensure mmWrt is installed\")\n", " !{sys.executable} -m pip install mmWrt\n", "print(datetime.datetime.now())" ] }, { "cell_type": "code", "execution_count": 2, "id": "5fca4b34", "metadata": {}, "outputs": [], "source": [ "from os.path import abspath, join, pardir\n", "import sys\n", "import matplotlib.pyplot as plt\n", "import matplotlib.cm as cm\n", "from matplotlib import colors\n", "from numpy import where, expand_dims\n", "\n", "# uncomment below if the notebook is launched from project's root folder\n", "# dp = abspath(join(\".\",pardir))\n", "# sys.path.insert(0, dp)\n", "\n", "\n", "from mmWrt.Raytracing import rt_points # noqa: E402\n", "from mmWrt.Scene import Radar, Transmitter, Receiver, Target # noqa: E402\n", "from mmWrt import RadarSignalProcessing as rsp # noqa: E402\n" ] }, { "cell_type": "code", "execution_count": 3, "id": "325ff150", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "synthetic targets [2.11, 4.53]\n", "found targets [2.112676056338028, 4.527162977867203]\n", "error is 0.005513078470825494\n" ] }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAh8AAAGzCAYAAACPa3XZAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/H5lhTAAAACXBIWXMAAA9hAAAPYQGoP6dpAABlgUlEQVR4nO29e3wU1f3//5rZzSYhIeGekHIxKgqCoIJiRJRqLF9Kqf7E65dWrPZjP/3gBeinVrRaa2tR+7VaFPFSirZKrbTFSrVYRUVUQKRiixdQBKFigihJIJBkL/P7Y3dmZza7m9kwc87s7Ov5eOyDZC8zJznR8zrvy+somqZpIIQQQggRhCp7AIQQQggpLCg+CCGEECIUig9CCCGECIXigxBCCCFCofgghBBCiFAoPgghhBAiFIoPQgghhAiF4oMQQgghQqH4IIQQQohQKD4IyTN27NgBRVHw6KOPyh4KIYR0C4oPQtKwYcMGXH311Rg5ciTKysowZMgQXHTRRdi6dWun906aNAmKokBRFKiqioqKChx77LH49re/jRdeeEHC6DPzxhtv4NZbb0VTU5Nj1zziiCOMnz/10dbWBgB49NFHM77nhhtusPwOsz1uvfVWx8adyg9+8AMcd9xxXb6vpaUFP/3pTzFmzBiUl5ejtLQUo0aNwo9+9CPs3r3beN/ll1+e8edYuXKl5ZoXXXQRFEXBj370o7T3fOWVVyyfDwQCGDBgAC644AK8//77h/eDEyKBoOwBEOJF7rzzTrz++uu48MILMXr0aDQ0NOD+++/HSSedhHXr1mHUqFGW9w8aNAjz588HALS2tuKjjz7CX/7yFzz++OO46KKL8Pjjj6OoqEjGj2LhjTfewE9/+lNcfvnl6NWrl2PXPeGEE/CDH/yg0/OhUMjy/W233Yba2lrLc6NGjcLZZ5+N7373u8ZzGzZswIIFC3DjjTdixIgRxvOjR492bMypPPvss5g2bVrW93z88ceor6/Hzp07ceGFF+Kqq65CKBTCv/71LyxevBjLly+3CNTi4mL85je/6XSdMWPGGF+3tLRgxYoVOOKII/CHP/wBd9xxBxRFSXv/a6+9FieffDLC4TD+9a9/4cEHH8Qrr7yCzZs3o7q6ups/OSES0AghnXj99de19vZ2y3Nbt27ViouLtRkzZlieP/PMM7WRI0d2ukYkEtH+53/+RwOgXX/99Y6Nbfv27RoAbcmSJTl/9pe//KUGQNu+fbtj4xk6dKg2derUrO9ZsmSJBkDbsGGDrWsuW7ZMA6C9/PLLDoywa7Zt29bl/cLhsDZmzBitR48e2po1azq93tzcrN14443G9zNnztTKysq6vPdvf/tbraioSHvppZc0ANorr7zS6T0vv/yyBkBbtmyZ5flFixZpALQ777yzy/sQ4iWYdiEkDaeddlqnXfuwYcMwcuRI22HuQCCABQsW4LjjjsP999+P5ubmrO+fNGkSRo0ahY0bN+K0005DaWkpamtr8eCDD9q630svvYSJEyeirKwMvXr1wrnnnmsZ66233oof/vCHAIDa2lojhL9jxw4AwAsvvIDTTz8dvXr1Qnl5OY499ljceOONtu4tmwULFiAQCFjSSXfffTcURcHcuXON56LRKHr27NkpvfHss8+isrISp59+esZ7/PnPf8Y777yDm266Ke37KioqcPvtt+c89ieeeALnnHMOvvrVr2LEiBF44oknbH924sSJAIBt27blfF9CZELxQYhNNE1DY2Mj+vXrZ/szgUAAl156KQ4ePIjXXnuty/fv27cPX//61zF27FjcddddGDRoEL7//e/jt7/9bdbPvfjii5g8eTL27NmDW2+9FXPnzsUbb7yBCRMmGOLi/PPPx6WXXgoAuOeee/D73/8ev//979G/f3+8++67+MY3voH29nbcdtttuPvuu/HNb34Tr7/+uq2fMxwOY+/evZbHwYMHO72vubm50/ucYOLEiYjFYpbf8Zo1a6CqKtasWWM89/bbb+PAgQM444wzLJ9/7rnncM455yAYzJyJfuaZZwAA3/72t3MaW+rPaxahu3fvxssvv2zMy6WXXoo//elP6OjosHVtfW579+6d05gIkY7s0Ash+cLvf/97DYC2ePFiy/OZ0i46y5cv1wBov/71r7Ne/8wzz9QAaHfffbfxXHt7u3bCCSdoAwYM0Do6OjRNS5920d/zxRdfGM+98847mqqq2mWXXWY8lyntcs8992gAtM8//zzrGNMxdOhQDUCnx09+8hPjPXraJd0jHbmmXaLRqFZRUWGkt2KxmNa3b1/twgsv1AKBgLZ//35N0zTtV7/6laaqqrZv3z7js62trVpJSUmXaawTTzxRq6ystDUeTYunXdL9vGeeeabxnv/3//6fVlpaqrW0tGiaFk/tAdCWL19uuZaedvntb3+rff7559ru3bu1lStXakcffbSmKIr25ptv2h4XIV6ABaeE2OCDDz7ArFmzUFdXh5kzZ+b02fLycgDA/v37u3xvMBjE9773PeP7UCiE733ve/j+97+PjRs34tRTT+30mc8++wybNm3C9ddfjz59+hjPjx49Gueccw6ee+65Lu+rF5/+9a9/xXe+8x2oam5B0fHjx+PnP/+55bkjjzyy0/sWLlyIY445Jqdr20FVVZx22ml49dVXAQDvv/8+vvjiC9xwww3485//jLVr1+Kcc87BmjVrMGrUKEux7UsvvYT29nZMmTIl6z1aWlrQs2fPnMZVUlKCFStWWJ4zRymeeOIJTJ061bjusGHDMHbsWDzxxBM477zzOl3viiuusHzfv39//P73v8fJJ5+c07gIkQ3FByFd0NDQgKlTp6KyshJ/+tOfEAgEcvr8gQMHAMDWwlVTU4OysjLLc/pivWPHjrTi45NPPgEAHHvssZ1eGzFiBJ5//nm0trZ2uq6Ziy++GL/5zW/w3e9+FzfccAPOPvtsnH/++bjgggtsCZF+/fqhvr6+y/edcsopGDduXJfv6w4TJ07ErbfeikOHDmHNmjUYOHAgTjrpJIwZMwZr1qzBOeecg9deew0XXXSR5XPPPvssxo0bh6qqqqzXr6iowMcff5zTmAKBQMbfy/vvv4+3334bl112GT766CPj+UmTJmHhwoVoaWlBRUWF5TO33HILJk6ciAMHDmD58uV48skncxaKhHgB/tUSkoXm5mZMmTIFTU1NWLlyJWpqanK+xubNmwEARx99tNPDc4zS0lK8+uqrePHFF/Htb38b//rXv3DxxRfjnHPOQTQalT08W5x++ukIh8NYu3Yt1qxZYxRjTpw4EWvWrMEHH3yAzz//3Hhe57nnnsPXv/71Lq8/fPhwNDc3Y9euXY6M9/HHHwcAzJkzB8OGDTMed999N9ra2vDnP/+502eOP/541NfX47zzzsNjjz2Gb37zm/iv//ovx8ZEiCgoPgjJQFtbG6ZNm4atW7fib3/7my0DqlSi0SiWLl2KHj16ZO2k0Nm9ezdaW1stz+m+EUcccUTazwwdOhQAsGXLlk6vffDBB+jXr58R9cjkHwHEUxdnn302fvWrX+G9997D7bffjpdeegkvv/xyl+P2AqeccgpCoRDWrFljER9nnHEG1q9fj1WrVhnf62zevBk7d+7E1KlTu7y+7gGii4bDQdM0LF26FF/96lexbNmyTo/Ro0fb6nq544470NbW1q0uG0JkQvFBSBqi0SguvvhirF27FsuWLUNdXV23rnHttdfi/fffx7XXXtsphJ6OSCSChx56yPi+o6MDDz30EPr374+xY8em/czAgQNxwgkn4LHHHrO0mm7evBn/+Mc/LLt6XYSkOpx++eWXna57wgknAADa29u7HLcXKCkpwcknn4w//OEP2LlzpyXycejQISxYsABHHXUUBg4caHzmueeeQ1VVla1U0AUXXIDjjz8et99+O9auXdvp9f379+Omm26yNdbXX38dO3bswHe+8x1ccMEFnR4XX3wxXn75ZYtjajqOOuooTJ8+HY8++igaGhps3ZsQL8CaD0LS8IMf/ADPPPMMpk2bhi+//LLTbvdb3/qW5fvm5mbjPQcPHjQcTrdt24ZLLrkEP/vZz2zdt6amBnfeeSd27NiBY445Bn/84x+xadMmPPzww1kdUn/5y19iypQpqKurw5VXXolDhw7hvvvuQ2VlpcWSXBcwN910Ey655BIUFRVh2rRpuO222/Dqq69i6tSpGDp0KPbs2YMHHngAgwYNshWx8QoTJ07EHXfcgcrKShx//PEAgAEDBuDYY4/Fli1bcPnll1ve/+yzz2LKlClZI0I6RUVF+Mtf/oL6+nqcccYZuOiiizBhwgQUFRXh3XffxdKlS9G7d29bUYgnnngCgUAgY8Tlm9/8Jm666SY8+eSTFp+SdPzwhz/EU089hXvvvRd33HFHl/cmxBPIbrchxIvoba+ZHtneW15erg0bNkz71re+pf3jH//I6Z4jR47U3nrrLa2urk4rKSnRhg4dqt1///2W92VyOH3xxRe1CRMmaKWlpVpFRYU2bdo07b333ut0n5/97GfaV77yFU1VVaPtdtWqVdq5556r1dTUaKFQSKupqdEuvfRSbevWrV2O20sOp88++6wGQJsyZYrl+e9+97ud2qSbmpq0YDCoPfXUUzndY9++fdott9yiHX/88VqPHj20kpISbdSoUdq8efO0zz77zHhfJofTjo4OrW/fvtrEiROz3qe2tlY78cQTNU3L7HCqM2nSJK2iokJramrK6WchRBaKpmmacMVDCOnEpEmTsHfvXqNAlbjLU089hRkzZmDv3r2orKyUPRxC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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "c = 3e8\n", "\n", "debug_ON = False\n", "test = 0\n", "radar = Radar(transmitter=Transmitter(bw=1e9, slope=70e8),\n", " receiver=Receiver(fs=1e3, max_adc_buffer_size=256,\n", " debug=debug_ON), debug=debug_ON)\n", "\n", "target1 = Target(2.11)\n", "target2 = Target(4.53, 0, 0, xt=lambda t: 2*t+4.53)\n", "# below is also an equivalent definition of target2\n", "# as at t=0 the position will be x0=2+3=5\n", "# target2 = Target(2, 0, 0, vx=lambda t: 2*t+3)\n", "targets = [target1, target2]\n", "\n", "bb = rt_points(radar, targets, debug=debug_ON)\n", "Distances, range_profile = rsp.range_fft(bb)\n", "ca_cfar = rsp.cfar_ca_1d(range_profile)\n", "\n", "mag_r = abs(range_profile)\n", "mag_c = abs(ca_cfar)\n", "# little hack to remove small FFT ripples : mag_r> 5\n", "target_filter = ((mag_r > mag_c) & (mag_r > 5))\n", "\n", "index_peaks = where(target_filter)[0]\n", "# grouped_peaks = rsp.peak_grouping_1d(index_peaks)\n", "\n", "found_targets = [Target(Distances[i]) for i in index_peaks]\n", "error = rsp.error([target1, target2], found_targets)\n", "print(\"synthetic targets\", [t.distance() for t in targets])\n", "print(\"found targets\", [t.distance() for t in found_targets])\n", "print(\"error is\", error)\n", "\n", "# 2D representation of the FFT and CFAR\n", "# plot on X,Y axis the FFT and CFAR\n", "plt.plot(Distances, mag_r)\n", "plt.plot(Distances, mag_c)\n", "plt.title(\"2D plots FFT w/ CFAR\")\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": 4, "id": "22d0a23a", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "C:\\Users\\matth\\AppData\\Local\\Temp\\ipykernel_20492\\95121931.py:5: MatplotlibDeprecationWarning: The get_cmap function was deprecated in Matplotlib 3.7 and will be removed two minor releases later. Use ``matplotlib.colormaps[name]`` or ``matplotlib.colormaps.get_cmap(obj)`` instead.\n", " cmap = cm.get_cmap(name='CMRmap_r')\n" ] }, { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# 1D representation of the FFT\n", "# useful later on to show the link between 1D FFT and 2D FFTs\n", "\n", "# Select the color map named CMRmap_r\n", "cmap = cm.get_cmap(name='CMRmap_r')\n", "# convert the 1D array in 2D array to plot using imshow\n", "mag_r = expand_dims(mag_r, axis=0)\n", "# set aspect ratio to auto to have high enough pixels to see them in the y_axis\n", "# change the norm to have a log color scale\n", "# to better see the peaks in correlation with 2D FFT plot\n", "plt.imshow(mag_r, cmap,\n", " aspect='auto',\n", " norm=colors.LogNorm(vmin=min(mag_r[0][:]), vmax=max(mag_r[0][:])))\n", "plt.title(\"1D FFT\")\n", "# plt.savefig(fp_fft_1D)\n", "plt.show()" ] }, { "cell_type": "markdown", "id": "38295fe3", "metadata": {}, "source": [ "### NON REGRESSION" ] }, { "cell_type": "code", "execution_count": 6, "id": "ee8b5c0f", "metadata": {}, "outputs": [], "source": [ "assert index_peaks[0]==14" ] }, { "cell_type": "code", "execution_count": null, "id": "3b4ae28e-319a-4eda-815a-a361d09173aa", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "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.11.1" } }, "nbformat": 4, "nbformat_minor": 5 }