{ "nbformat": 4, "nbformat_minor": 0, "metadata": { "kernelspec": { "name": "python3", "display_name": "Python 3" }, "colab": { "provenance": [] } }, "cells": [ { "cell_type": "markdown", "metadata": { "id": "LF0f-9Cqt-9U" }, "source": [ "# Módulo II: Demodulación de señal APT" ] }, { "cell_type": "markdown", "metadata": { "id": "bbnvBrD8t-9X" }, "source": [ "`Grupo`:\n", "\n", "`Estudiantes`:" ] }, { "cell_type": "markdown", "metadata": { "id": "uWL5-Arot-9a" }, "source": [ "Ahora que Ud. conoce en qué consiste el sistema de transmisión APT de los satélites NOAA, el objetivo de este segundo módulo es demodular una señal previamente registrada con el SDR, y si todo sale bien, obtener una primera imagen.\n", "\n", "Como insumo para decodificar una primera imagen, Ud. va a contar con una grabación IQ (fase y cuadratura) que fue recibida con un SDR conectado a una antena adecuada. La captura fue registrada con una tasa de 96 000 muestras por segundo, con frecuencia central la correspondiente al satélite." ] }, { "cell_type": "code", "source": [ "# IMPORTS PARA TODO EL NOTEBOOK\n", "\n", "import numpy as np\n", "from scipy.io import wavfile\n", "import scipy.signal as signal\n", "import matplotlib.pyplot as plt\n", "from scipy import signal\n", "from PIL import Image\n", "from matplotlib.pyplot import imshow\n" ], "metadata": { "id": "OoWNC7X3wBHu" }, "execution_count": null, "outputs": [] }, { "cell_type": "markdown", "metadata": { "id": "jGD3p4RYt-9c" }, "source": [ "## 0. Levantar datos de grabación de señal capturada con SDR" ] }, { "cell_type": "markdown", "metadata": { "id": "zvCQLXtAt-9e" }, "source": [ "Durante este notebook trabajaremos con dos grabaciones de señales capturadas en 2019. Ambas consisten en la misma señal de 4 minutos aprox, solo que una de ellas fue acotada a 64 segundos para poder trabajar en una primera instancia de forma más rápida. Las grabaciones se encuentran en la carpeta \"Grabaciones\" en el EVA\n", "\n", "Comience a trabajar con la versión reducida y luego de armar todo el sistema de recepción repetir con la captura completa.\n", "\n", "El siguiente código sirve para levantar las muestras I y Q del archivo." ] }, { "cell_type": "code", "metadata": { "id": "nswdVG0Jt-9f" }, "source": [ "# Frecuencia de muestro del archivo\n", "fs = 96000\n", "\n", "# Levantar datos\n", "filename = 'satelite_64.npy'\n", "f = np.load(filename)\n", "\n", "i = f.real\n", "q = f.imag\n" ], "execution_count": null, "outputs": [] }, { "cell_type": "markdown", "metadata": { "id": "7aK21rvPt-9r" }, "source": [ "## 1. Analisís de la señal recibida\n", "\n" ] }, { "cell_type": "markdown", "source": [ "Comience por observar en tiempo y frecuencia la señal APT modulada.\n", "\n", "- ¿Cual es el ancho de banda esperado de la señal capturada?\n", "- ¿Qué ancho de banda se observa?" ], "metadata": { "id": "-g4K160YW_Oi" } }, { "cell_type": "code", "source": [ "# Funciones auxiliares\n", "\n", "def plot_frec(x,fs,fmax,m):\n", " puntos = int(fmax/fs*m)\n", " lx = len(x)\n", " nt = (lx + m - 1)//m\n", " xp = np.append(x,np.zeros(-lx+nt*m))\n", " xmw = np.reshape( xp, (m,nt), order='F')\n", " xmf = np.fft.fft(xmw,len(xmw),axis=0)/m\n", " xf = np.linspace(0, int(fs/2.0), int(m/2))\n", " plt.figure(figsize=(10,6))\n", " plt.title('Análisis en frecuencia',loc='center')\n", " plt.yscale(\"log\")\n", " plt.plot(xf[0:puntos],np.abs(xmf[0:int(m/2),0:int(lx/m-1)]).mean(1)[0:puntos])\n", " plt.show()\n", "\n", "def filtro_pasabajo(x,f_corte,fs):\n", "\ttaps = signal.firwin(151,f_corte,nyq=fs/2.0)\n", "\tfiltered_x = signal.lfilter(taps, 1.0, x)\n", "\treturn(filtered_x)\n", "\n", "def filtro_pasabanda(x,f_corte1,f_corte2,fs):\n", " taps = signal.firwin(151, [f_corte1, f_corte2], pass_zero=False,nyq=fs/2.0)\n", " filtered_x = signal.lfilter(taps, 1.0, x)\n", " return(filtered_x)\n", "\n" ], "metadata": { "id": "N6Q_WPxZSZ1Y" }, "execution_count": null, "outputs": [] }, { "cell_type": "code", "source": [ "# Analisis en Tiempo\n", "\n", "# Analisis en Frecuencia\n" ], "metadata": { "id": "WcaMmoutXMww" }, "execution_count": 1, "outputs": [] }, { "cell_type": "markdown", "source": [ "## 2. Demodulación FM\n" ], "metadata": { "id": "SWXQCXnqSMRX" } }, { "cell_type": "markdown", "source": [ "El primer paso para demodular la señal APT es realizar una demodulación FM. Para esto utilice el demodulador hecho en el parcial y analice nuevamente en tiempo y frecuencia la señal.\n", "\n", "- ¿Qué ancho de banda se esperaría que tenga la señal?\n", "- ¿Qué ancho de banda se tiene?\n", "\n" ], "metadata": { "id": "o2ZvyDzMcSUl" } }, { "cell_type": "code", "source": [ "# Demodular FM\n", "\n", "# Analisis en tiempo\n", "\n", "\n", "# Analisis en Frecuencia\n" ], "metadata": { "id": "Gbf8wXA0X4ix" }, "execution_count": null, "outputs": [] }, { "cell_type": "markdown", "source": [ "## 3. Demodulación AM" ], "metadata": { "id": "Pq1IcERXSO4Q" } }, { "cell_type": "markdown", "metadata": { "id": "4b9K5MoB8qFb" }, "source": [ "Luego de demodular la señal en FM, hay que demodularla en AM. Para esto, implementar un demodulador AM utilizando las técnicas tratadas en el parcial. Para esto recordar la siguiente relación trigonometrica:\n", "\n", "$$\\cos^2(\\theta) = \\frac{1 + \\cos(2\\theta)}{2}$$\n", "\n", "Finalmente analizar en tiempo y frecuencia.\n", "\n", "- ¿Que ancho de banda se espera que tenga la señal?\n", "- ¿Que ancho de banda se observa?\n" ] }, { "cell_type": "code", "source": [ "# Demodular AM\n", "\n", "\n", "# Analisis en tiempo\n", "\n", "\n", "# Analisis en frecuencia\n" ], "metadata": { "id": "Qhhx5lnExN7K" }, "execution_count": null, "outputs": [] }, { "cell_type": "markdown", "source": [ "## 4. Resampleo" ], "metadata": { "id": "jvhAOVRFYeRf" } }, { "cell_type": "markdown", "source": [ "Recordando el taller anterior, la imagen satlital se envia de forma serializada. Esto es, la imagen que es de 2 dimensiones, se transforma en 1D concatenando las filas una tras otra. También recordamos que cada linea consiste en 2080 píxeles, y se envía en 0.5 segundos.\n", "\n", "En esta sección y la siguiente buscaremos pasar nuestra señal 1D, a una matriz 2D que corresponda a la imagen. Las siguientes preguntas sirven como guía para este objetivo.\n", "\n", "- ¿Cuánto tiempo demora en enviarse un único píxel?\n", "- ¿Cuál es la frecuencia de muestro con la que estamos trabajando?\n", "- Dado la respuesta de las dos preguntas anterioriores, ¿cuántas muestras presenta la señal por píxel?\n", "- ¿Qué frecuencia de muestreo es necesaria, para que nuestra señal tenga una muestra por píxel?\n", "- ¿Cómo podemos hacer para cambiar a esa frecuencia de muestreo?\n", "\n", "Para responder esta última pregunta, averiguar sobre la función \"scipy.signal.resample_poly\".\n", "\n", "Implementar el resampleo y observar el resultado en tiempo y frecuencia.\n", "\n" ], "metadata": { "id": "lKeCFQDweVbS" } }, { "cell_type": "code", "source": [ "# Resampleo\n", "\n", "# Analisis en tiempo\n", "\n", "\n", "# Analisis en frecuencia\n" ], "metadata": { "id": "CJ1c_uUYYh4K" }, "execution_count": null, "outputs": [] }, { "cell_type": "markdown", "source": [ "## 6.Armado de Matriz" ], "metadata": { "id": "Gl6wjgAJtnHW" } }, { "cell_type": "markdown", "source": [ "Ahora tenemos una señal APT donde cada muestra corresponde a un píxel. Sin embargo sigue siendo una señal 1D. Para poder visualizar nuestra imagen debe ser 2D. Las siguientes preguntas sirven como guía para lograr esto.\n", "\n", "- ¿Si tenemos 64 segundos de señal, cuántas líneas vamos a tener?\n", "- ¿Cuántos píxeles tiene una línea?\n", "- Apartir de estas dos preguntas, ¿Qué tamaño debe tener la matriz a recuperar y cuantos píxeles va a tener?\n", "- ¿Cuántas muestras tenemos?\n", "\n", "Transformar la señal 1D en una señal 2D con las dimensiones adecuadas. Para esto investigar cómo se utiliza la función \"np.reshape\".\n", "\n", "Chequear que las dimensiones de la imagen sean las correctas, y graficar en el tiempo distintas líneas de la imagen. Analizar el resultado.\n" ], "metadata": { "id": "zsz-9an4tnvk" } }, { "cell_type": "code", "source": [ "# Reshape\n", "\n", "\n" ], "metadata": { "id": "QQLOzHvftJXs" }, "execution_count": null, "outputs": [] }, { "cell_type": "markdown", "source": [ "## 7. Visualización de la imagen" ], "metadata": { "id": "LJD1-GCtrxp5" } }, { "cell_type": "markdown", "source": [ "Ahora que cuenta con una matriz, es hora de visualizarla. Se da un código de ejemplo donde se muestra como visualizar una matriz de 2 dimensiones donde cada pixel es un numero random entre 0 y 255. Repetir esto para visualizar la imagen satelital demodulada." ], "metadata": { "id": "8SYeCPCqvAn-" } }, { "cell_type": "code", "source": [ "# Visualizar imagen random\n", "matriz_random = 255 * np.random.random((128,2048))\n", "img = Image.fromarray(matriz_random)\n", "plt.figure(figsize=(7,3))\n", "plt.axis('off')\n", "imshow(img,interpolation='none')\n", "plt.show()" ], "metadata": { "id": "ibQ-3Mwtu34d" }, "execution_count": null, "outputs": [] }, { "cell_type": "code", "source": [ "# Repetir con imagen satelital\n", "\n" ], "metadata": { "id": "P3jFdyajvQRX" }, "execution_count": null, "outputs": [] }, { "cell_type": "markdown", "source": [ "## 8. Reescalado de la matriz" ], "metadata": { "id": "VB2bjgMkesFY" } }, { "cell_type": "markdown", "source": [ "La imagen anterior no es muy esperanzadora. Para entender porque se observa todo negro, debemos entender qué valores esta tomando nuestra señal actualmente, qué valores deberia tomar, y por qué ocurre esto.\n", "\n", "- ¿Qué valor máximo y mínimo tiene la señal?\n", "- ¿Qué valor corresponde a negro en la imagen, y que valor corresponde a blanco en la imagen?\n", "- Pensar posibles causas que puedan provocar esto.\n", "- ¿Qué estrategia sencilla se le ocurre para que el valor máximo de nuestra señal corresponda a negro, y el valor mínimo corresponda a blanco? Implementarla y observar los nuevos valores máximos y mínimos de la señal.\n" ], "metadata": { "id": "wfuVRg9iyQv8" } }, { "cell_type": "code", "source": [ "# Reescalar imagen\n" ], "metadata": { "id": "VMkHu15wevvj" }, "execution_count": null, "outputs": [] }, { "cell_type": "markdown", "source": [ "## 9. Visualización de la imagen 2.0" ], "metadata": { "id": "XgkFF_9Ju7vY" } }, { "cell_type": "markdown", "source": [ "Utilizando el código de la parte 7 y con la imagen normalizada, volver a visualizar la imagen. Comentar que se observa" ], "metadata": { "id": "bZ_iLm8-voVE" } }, { "cell_type": "code", "source": [], "metadata": { "id": "cqeV5MhjvwdO" }, "execution_count": null, "outputs": [] }, { "cell_type": "markdown", "source": [ "Ahora que tenemos el sistema de recepción andando, repetir para la señal completa." ], "metadata": { "id": "x8nWTJY4z5rl" } }, { "cell_type": "markdown", "metadata": { "id": "w3Uc24DNt-9y" }, "source": [ "## Entregable\n", "\n", " - Ud. deberá subir el notebook al EVA con el código para la demodulación y visualización de la imagen, coloque también en el notebook todas las gráficas importantes para poder explicar el proceso de demodulación (tanto en tiempo como en frecuencia), recuerde que puede agregar celdas de texto para acompañar el código y facilitar la lectura." ] } ] }