{ "cells": [ { "cell_type": "markdown", "metadata": { "id": "arMydWfHifPF" }, "source": [ "# Localization with time of arrival measurements\n", "\n", "\"Open" ] }, { "cell_type": "markdown", "metadata": { "id": "7ER921sUifPI" }, "source": [ "## Introduction\n", "\n", "Acoustic sensors can be used as a mean to track a moving object. Typically, acoustic measurements are characteristic of the distance between the receiver and an acoustic source. Hence, they convey information on the position of the latter, which can be leveraged for localization. In the next, we will see how gtsam can be used in such a scenario. \n", "\n", "The following example considers an omnidirectional sound source that periodically emits an acoustic signal while moving. The signals are received by a fixed array of microphones that can synchronously record the signals from which Time of Arrival (ToA) measurements are extracted. The objective is to recover, from the ToA measurements, the trajectory of the moving agent. In this simple example, no odometry information is used, but odometry factors can seamlessly be integrated." ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "id": "JoW4C_OkOMhe", "tags": [ "remove-cell" ], "trusted": true }, "outputs": [], "source": [ "# Install the pre-requisites\n", "%pip -q install gtbook " ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "id": "10-snNDwOSuC", "tags": [ "remove-cell" ], "trusted": true }, "outputs": [], "source": [ "import numpy as np\n", "import matplotlib.pyplot as plt\n", "import gtsam\n", "\n", "from gtsam import (LevenbergMarquardtOptimizer, LevenbergMarquardtParams,\n", " NonlinearFactorGraph, Point3, Values, noiseModel)\n", "from gtsam_unstable import Event, TimeOfArrival, TOAFactor" ] }, { "cell_type": "markdown", "metadata": { "id": "nAvx4-UCNzt2", "tags": [] }, "source": [ "## Example trajectory\n", "\n", "We start by defining the microphones position and create the ground truth trajectory along with sound events. We first define useful units." ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "id": "X0BsBHPGifPN", "trusted": true }, "outputs": [], "source": [ "MS = 1e-3 # 1 millisecond in s\n", "CM = 1e-2 # 1 centimeter in m" ] }, { "cell_type": "markdown", "metadata": { "id": "QpwKGbRylV-7" }, "source": [ " Next, we istantiate a functor with a value $v = 330 m.s^{-1}$ for the speed of sound." ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "id": "xirrSUgtifPP", "trusted": true }, "outputs": [], "source": [ "TIME_OF_ARRIVAL = TimeOfArrival(330)" ] }, { "cell_type": "markdown", "metadata": { "id": "Ykno7J8MifPP" }, "source": [ "We define the positions of four microphones that we constrain to lie in a horizontal plane (*i.e* with constant $z$ coordinate)." ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "jZE77ghYifPQ", "outputId": "50d4d96f-55fb-4b3d-ae08-d7508737725d", "trusted": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "mic 0 = [0. 0. 0.5]\n", "mic 1 = [4.03 0. 0.5 ]\n", "mic 2 = [4.03 4.03 0.5 ]\n", "mic 3 = [0. 4.03 1. ]\n" ] } ], "source": [ "height = 0.5\n", "microphones = []\n", "microphones.append(Point3(0, 0, height))\n", "microphones.append(Point3(403 * CM, 0, height))\n", "microphones.append(Point3(403 * CM, 403 * CM, height))\n", "microphones.append(Point3(0, 403 * CM, 2 * height))\n", "\n", "K = len(microphones)\n", "for i in range(K):\n", " print(\"mic {} = {}\".format(i, microphones[i]))" ] }, { "cell_type": "markdown", "metadata": { "id": "c0Q43BDxifPT" }, "source": [ "We subsequently create a ground truth trajectory for the moving sound emitter which follows a straight line, and specify the times at which a sound is emitted." ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "id": "wO5_ocxiifPU", "tags": [], "trusted": true }, "outputs": [], "source": [ "n = 5\n", "groundTruth = []\n", "timeOfEvent = 10\n", "\n", "# simulate emitting a sound every second while moving on straight line\n", "for key in range(n):\n", " groundTruth.append(\n", " Event(timeOfEvent, 245 * CM + key * 1.0, 201.5 * CM, (212 - 45) * CM))\n", " timeOfEvent += 1\n", " \n", "#for event in groundTruth:\n", "# event.print()" ] }, { "cell_type": "markdown", "metadata": { "id": "NvXX8a2YifPU" }, "source": [ "For visualization, we display the agent positions corresponding to an excitation event, along with the microphone array." ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 279 }, "id": "L_tLoHdOifPV", "outputId": "9b0e3587-b124-439d-bb41-ed46f2b49370" }, "outputs": [ { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "fig = plt.figure()\n", "plt.plot([mic[0] for mic in microphones], [mic[1] for mic in microphones], \"b.\", markersize=10, label=\"Microphones\")\n", "plt.plot([ev.location()[0] for ev in groundTruth], [ev.location()[1] for ev in groundTruth], \"s\", color=\"r\", markersize=5, linestyle=\"-\", lw=0.5, label=\"Source positions\")\n", "plt.xlabel(\"x [m]\"); plt.ylabel(\"y [m]\")\n", "plt.legend(); fig.show()" ] }, { "cell_type": "markdown", "metadata": { "id": "MkerMqa9ifPW" }, "source": [ "We can now simulate the time of arrival measurements based on the distance between each microphone and the moving sound source. To determine the (noise-free) ToA between microphone $j$ for the $i$-th source position, one may simply use the formula:\n", "\n", "$$ z_{i, j} = \\frac{d_{i, j}}{v}, $$\n", "\n", "where $d_{i, j}$ is the distance between them. Otherwise, the function TIME_OF_ARRIVAL.measure can take care of it." ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "EdsVLXlXifPW", "outputId": "cd736783-df1a-4f26-abe2-ad897ea8bd24", "trusted": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "z_00 = 10010.245662478956 ms\n", "z_01 = 10008.531002716338 ms\n", "z_02 = 10008.531002716338 ms\n", "z_03 = 10009.824738271 ms\n", "z_10 = 11012.615535847513 ms\n", "z_11 = 11007.276214441754 ms\n", "z_12 = 11007.276214441754 ms\n", "z_13 = 11012.276140565378 ms\n", "z_20 = 12015.22154271807 ms\n", "z_21 = 12007.174542408371 ms\n", "z_22 = 12007.174542408371 ms\n", "z_23 = 12014.941460610633 ms\n", "z_30 = 13017.961192990088 ms\n", "z_31 = 13008.268633130547 ms\n", "z_32 = 13008.268633130547 ms\n", "z_33 = 13017.724455875657 ms\n", "z_40 = 14020.78169909914 ms\n", "z_41 = 14010.17998044382 ms\n", "z_42 = 14010.17998044382 ms\n", "z_43 = 14020.577436670008 ms\n" ] } ], "source": [ "def simulate_one_toa(microphones, event):\n", " \"\"\"Simulate time-of-arrival measurements for a single event.\"\"\"\n", " return [TIME_OF_ARRIVAL.measure(event, microphones[i])\n", " for i in range(len(microphones))]\n", "\n", "simulatedTOA = [simulate_one_toa(microphones, event)\n", " for event in groundTruth]\n", "\n", "for key in range(n):\n", " for i in range(K):\n", " print(\"z_{}{} = {} ms\".format(key, i, simulatedTOA[key][i] / MS))" ] }, { "cell_type": "markdown", "metadata": { "id": "qR0JNEZlifPX" }, "source": [ "## Creation of the nonlinear factor graph\n", "\n", "As always, we create a factor graph to solve the problem at hand. " ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "rJ0D8cGFifPX", "outputId": "6480b693-c47a-4b46-df73-e74b95628cf0", "trusted": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " keys = { 0 }\n", "isotropic dim=1 sigma=0.0005\n", "ExpressionFactor with measurement: 10.0102\n", "\n" ] } ], "source": [ "graph = NonlinearFactorGraph()\n", "\n", "# Create a noise model for the TOA error\n", "model = noiseModel.Isotropic.Sigma(1, 0.5 * MS)\n", "\n", "K = len(microphones)\n", "key = 0\n", "for toa in simulatedTOA:\n", " for i in range(K):\n", " factor = TOAFactor(key, microphones[i], toa[i], model)\n", " graph.push_back(factor)\n", " key += 1\n", " \n", "print(graph.at(0))" ] }, { "cell_type": "markdown", "metadata": { "id": "t3FYzhipifPX" }, "source": [ "## Optimization and results\n", "\n", "The optimizer needs to be provided an initial trajectory estimate." ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "Tk5NVy_7ifPY", "outputId": "b9981d9c-ed84-450b-f1de-08a73ac42305" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Values with 5 values:\n", "Value 0: (gtsam::Event)\n", "{'time':0, 'location': 0 0 0}\n", "Value 1: (gtsam::Event)\n", "{'time':0, 'location': 0 0 0}\n", "Value 2: (gtsam::Event)\n", "{'time':0, 'location': 0 0 0}\n", "Value 3: (gtsam::Event)\n", "{'time':0, 'location': 0 0 0}\n", "Value 4: (gtsam::Event)\n", "{'time':0, 'location': 0 0 0}\n", "\n" ] } ], "source": [ "initial_estimate = Values()\n", "zero = Event()\n", "for key in range(n):\n", " TOAFactor.InsertEvent(key, zero, initial_estimate)\n", "print(initial_estimate)" ] }, { "cell_type": "markdown", "metadata": { "id": "cCTqrJa1ifPY" }, "source": [ "The graph is optimized using the Levenberg-Marquardt optimizer." ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "7VNSYxFOifPa", "outputId": "3c3c432d-16b3-4f8c-9a04-ea8a1d8997c9" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Final Result:\n", " Values with 5 values:\n", "Value 0: (gtsam::Event)\n", "{'time':10, 'location': 2.45 2.015 1.67}\n", "Value 1: (gtsam::Event)\n", "{'time':11, 'location': 3.45 2.015 1.67}\n", "Value 2: (gtsam::Event)\n", "{'time':12, 'location': 4.45 2.015 1.67}\n", "Value 3: (gtsam::Event)\n", "{'time':13, 'location': 5.45 2.015 1.67}\n", "Value 4: (gtsam::Event)\n", "{'time':14, 'location': 6.45 2.015 1.67}\n", "\n" ] } ], "source": [ "params = LevenbergMarquardtParams()\n", "params.setAbsoluteErrorTol(1e-10)\n", "params.setVerbosityLM(\"SUMMARY\")\n", "optimizer = LevenbergMarquardtOptimizer(graph, initial_estimate, params)\n", "result = optimizer.optimize()\n", "print(\"Final Result:\\n\", result)" ] }, { "cell_type": "markdown", "metadata": { "id": "kmxKML2RifPa" }, "source": [ "The visual representation of the result shows the excelent matching between estimated and ground truth positions." ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 279 }, "id": "fZDgkEfTifPa", "outputId": "73e33986-88f9-4b70-abf4-68fa5517c949" }, "outputs": [ { "data": { "image/png": "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Ep599llKo9ly8+bNbN26lX/96180btyYa665hoKCApYtW1blfuqbOnmgzN3nA/Oj0/eUW74HuKIuYhAJu/39ZbNnRy4H5ebW7lP2rVq1OuAafDyPPPIIw4YN45lnniElJYUnn3ySE0888YA2AwYM4N133yUnJwcz43e/+x0tW7Zk7dq1nHXWWdx0002sX7+eH/3oRwwYMKDK4z322GNce+21PPDAA6Snp/Pcc89V2f7iiy9mzZo1nH322UDkttQXXniB9evXU1BQQIMGDUhNTY0ls6OF1bcrMXl5ea6BaUQi1qxZww9/+MNkh1En5s+fz4MPPsisWQc9myoVxHtfmNlSd8+L115lqEVEQu6orzUkIkeHbt260a1bt2SHcVTSGYGISMgpEYiIhJwSgYhIyCkRiIiEnBKBiByW++67jzPPPJPs7Gxyc3NZvHhxskOqFYWFhbHnIubPn88777wTWzd+/Hief/75ZIVW63TXkIgcsnfffZdZs2axbNkyGjVqxGeffcY333xz2PstKyujYcPkfjzl5eWRlxe57X7+/Pk0bdqUc845B4Dhw4cnM7RapzMCkTBp2TJSX6L8q2XLQ97dli1baNGiRaxuT4sWLTjppJMAeOutt+jQoQNZWVlcd911fP311wBkZGTw2WefAZFv3ftvCR0zZgyDBw/m3HPPZfDgwXFLVgO88MILdO7cmdzcXK6//nr2xqmjnZGRwe23305WVhadO3dm/fr1QOVlqf/85z+TmZlJTk4OF1xwARD58O/bty/FxcWMHz+ehx56iNzcXBYuXMiYMWN48MEHASgqKqJr165kZ2czYMAAvvjiCyByu+sdd9xB586dadu2LQsXLgTggw8+iMWfnZ3NunXrDvn3X1uUCETCJFpls9plCbr44ovZuHEjbdu25cYbb+Rvf/sbAHv27CE/P59p06axcuVKysrKEirLsHr1at58802mTJkSt2T1mjVrmDZtGm+//TZFRUWkpKQwefLkuPtq3rw5K1eu5KabbuKWW24BKi9LPXbsWF5//XWWL1/OzJkzD9hPRkYGw4cP59Zbb6WoqOigekVDhgzh/vvvZ8WKFWRlZXHvvffG1pWVlbFkyRIefvjh2PLx48czcuRIioqKKCwspFWrVgn+toOjS0MiR5MJEyBagrlGxoyJvzwjA/LzK92sadOmLF26lIULFzJv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", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "# parsing the result to retrieve the estimated locations\n", "L = result.__repr__().split('\\n'); L = [L[ind] for ind in range(2, len(L), 2)]\n", "L = [l.split('location')[1].split()[1:] for l in L]\n", "estimated_trajectory = [ [float(coord.split('}')[0]) for coord in l] for l in L]\n", "\n", "# Display\n", "fig = plt.figure()\n", "plt.plot([mic[0] for mic in microphones], [mic[1] for mic in microphones], \"b.\", markersize=10, label=\"Microphones\")\n", "plt.plot([ev.location()[0] for ev in groundTruth], [ev.location()[1] for ev in groundTruth], \"s\", color=\"r\", markersize=5, linestyle=\"-\", lw=0.5, label=\"Source positions\")\n", "plt.plot([x[0] for x in estimated_trajectory], [x[1] for x in estimated_trajectory], \"s\", color=\"g\", markersize=5, linestyle=\"-\", lw=0.5, label=\"Estimated positions\")\n", "plt.xlabel(\"x [m]\"); plt.ylabel(\"y [m]\")\n", "plt.legend(); fig.show()" ] } ], "metadata": { "colab": { "collapsed_sections": [], "name": "TimeOfArrivalExample.ipynb", "provenance": [] }, "interpreter": { "hash": "c6e4e9f98eb68ad3b7c296f83d20e6de614cb42e90992a65aa266555a3137d0d" }, "kernelspec": { "display_name": "Python 3", "name": "python3" }, "language_info": { "name": "python" }, "latex_metadata": { "affiliation": "International Research Lab 2958 Georgia Tech-Cnrs", "author": "Othmane-Latif Ouabi", "title": "Localization_with_time_of_arrival_measurements" } }, "nbformat": 4, "nbformat_minor": 0 }