{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Cross Correlation" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The general form of the cross correlation with integration:\n", "\\begin{equation}\n", "{\\displaystyle (f\\star g)(\\tau )\\ = \\int _{-\\infty }^{\\infty }{{f^{\\star}(t)}}g(t+\\tau )\\,dt}\n", "\\end{equation}\n", "This can be written in discrete form as:\n", "\\begin{equation}\n", "{\\displaystyle (f\\star g)[n]\\ = \\sum _{m=-\\infty }^{\\infty }{{f^{\\star}[m]}}g[m+n]}\n", "\\end{equation}" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from matplotlib import pylab\n", "from matplotlib import pyplot as plt\n", "pylab.rcParams['savefig.dpi'] = 300\n", "import numpy as np" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from gps_helper.prn import PRN\n", "from sk_dsp_comm import sigsys as ss\n", "from sk_dsp_comm import digitalcom as dc\n", "from caf_verilog.quantizer import quantize" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Test Signals" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "prn = PRN(10)\n", "prn2 = PRN(20)\n", "fs = 625e3\n", "Ns = fs / 125e3\n", "prn_seq = prn.prn_seq()\n", "prn_seq2 = prn2.prn_seq()\n", "prn_seq,b = ss.nrz_bits2(np.array(prn_seq), Ns)\n", "prn_seq2,b2 = ss.nrz_bits2(np.array(prn_seq2), Ns)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "Px,f = plt.psd(prn_seq, 2**12, Fs=fs)\n", "plt.plot(f, 10*np.log10(Px))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Autocorrelation" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "r, lags = dc.xcorr(prn_seq, prn_seq, 100)\n", "plt.plot(lags, abs(r)) # r -> abs" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Time Shifted Signals" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "r, lags = dc.xcorr(np.roll(prn_seq, 50), prn_seq, 100)\n", "plt.plot(lags, abs(r))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "r, lags = dc.xcorr(np.roll(prn_seq, -50), prn_seq, 100)\n", "plt.plot(lags, abs(r))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## No Correlation" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "r_nc, lags_nc = dc.xcorr(prn_seq, prn_seq2, 100)\n", "plt.plot(lags_nc, abs(r_nc))\n", "plt.ylim([0, 1])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Calculation Space Visualization" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from caf_verilog.xcorr import size_visualization\n", "size_visualization(prn_seq[:10], prn_seq[:10], 5)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Simple Cross Correlation" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from caf_verilog.xcorr import simple_xcorr\n", "r, lags = simple_xcorr(prn_seq, prn_seq, 100)\n", "plt.plot(lags, r)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Time Shifted Signals" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "r, lags = simple_xcorr(prn_seq, np.roll(prn_seq, 50), 100)\n", "plt.plot(lags, abs(np.array(r)))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "r, lags = simple_xcorr(prn_seq, np.roll(prn_seq, -50), 100)\n", "plt.plot(lags, abs(np.array(r)))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### No Correlation" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "r, lags = simple_xcorr(prn_seq, prn_seq2, 100)\n", "plt.plot(lags, abs(np.array(r)))\n", "plt.ylim([0, 5000])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Dot Product Method" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To ensure the integration time is filled, the secondary or received signal must be twice the length of the reference signal." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from caf_verilog.sim_helper import sim_shift\n", "center = 300\n", "corr_length = 250\n", "shift = 25\n", "ref, rec = sim_shift(prn_seq, center, corr_length, shift=shift, padding=True)\n", "ref = np.array(ref)\n", "rec = np.array(rec)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "f, axarr = plt.subplots(2, sharex=True, gridspec_kw={'hspace': 0})\n", "axarr[0].plot(ref.real)\n", "axarr[1].plot(rec.real)\n", "plt.xlabel(\"Sample Number\")\n", "plt.savefig('prn_seq.png')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from caf_verilog.xcorr import dot_xcorr\n", "ref = np.array(ref)\n", "rec = np.array(rec)\n", "rr = dot_xcorr(ref, rec)\n", "rr = np.array(rr)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "rxy, lags = dc.xcorr(ref, rec, corr_length)\n", "plt.plot(lags, abs(rxy))\n", "plt.xlabel(\"Center Offset (Samples)\")\n", "plt.grid();\n", "plt.savefig('xcorr.png')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "np.argmax(rxy) - corr_length" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "ref, rec = sim_shift(prn_seq, center, corr_length, shift=shift)\n", "ref = np.array(ref)\n", "rec = np.array(rec)\n", "rr = dot_xcorr(ref, rec)\n", "rr = np.array(rr)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "fig, axs = plt.subplots(2, sharey=True)\n", "axs[0].plot(abs(rr))\n", "axs[0].grid(True)\n", "axs[1].plot(abs(rr))\n", "axs[1].set_xlim([80, 120])\n", "axs[1].set_xlabel('Inverse Center Offset (Samples)')\n", "axs[1].grid(True)\n", "fig.savefig('xcorr_250.png')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "(corr_length / 2) - np.argmax(rr)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from caf_verilog.xcorr import XCorr\n", "xc = XCorr(ref, rec, output_dir='.')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "xc.gen_tb()" ] } ], "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.10.12" } }, "nbformat": 4, "nbformat_minor": 4 }