{"id":3029,"date":"2021-02-13T12:20:27","date_gmt":"2021-02-13T17:20:27","guid":{"rendered":"http:\/\/blog.espol.edu.ec\/girni\/?p=3029"},"modified":"2026-08-04T21:42:37","modified_gmt":"2026-08-05T02:42:37","slug":"5-2-localiza-por-trilateracion-intervalos-algoritmo-python","status":"publish","type":"post","link":"https:\/\/blog.espol.edu.ec\/girni\/5-2-localiza-por-trilateracion-intervalos-algoritmo-python\/","title":{"rendered":"5.2 Localiza por Trilateraci\u00f3n \u2013 Intervalos. Algoritmo Python"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Algoritmo en Python<\/h2>\n\n\n<div class=\"wp-block-syntaxhighlighter-code alignwide\"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n# Localizaci\u00f3n por trilateraci\u00f3n\n# Ubicaci\u00f3n de puntos en el mapa\n# Girni 2020-10-07 propuesta: edelros@espol.edu.ec\n\nimport numpy as np\nimport sympy as sym\nimport matplotlib.pyplot as plt\n\nimport pandas as pd\nimport json\nimport girni_lora_libreria as girni\n\n# INGRESO\n# revisar parametros al inicio\nmodo   = 'rx'\nmedida = 'rssi'\n\n# archivos de entrada\narch_medUbAtrib = 'rsmP06_'+medida+'UbicaUsar01.txt'\narch_ecuaciones = 'rsmP06_ecuaciones01.json'\n\n# archivos de salida\narch_trilatera = 'rsmP07_'+medida+'trilatera01.txt'\n\n# grupo a procesar\nmostrargrp   = &#x5B;'FIEC'] #&#x5B;'FIEC','FCNM','RECT','CIRC']\nmostrartip   = &#x5B;'punto']\nmostrarfuera = &#x5B;0,1]    #&#x5B;0,1]\ntolera_error = 2 # decimales en error\n\n# Referencias\nbaliza  = {'d1':'gtwRECT',\n           'd2':'gtwFIEC',\n           'd3':'gtwFCNM'}\n\n# PROCEDIMIENTO \nbaliza_key = list(baliza.keys())\nbaliza_val = list(baliza.values())\n\n# leer datos\nwith open(arch_ecuaciones) as json_file: \n    ecuacion = json.load(json_file) \ntabla = pd.read_csv(arch_medUbAtrib, index_col='etiqueta')\ntabla = pd.DataFrame(tabla)\n\n# coordenadas de baliza\ncoordbaliza = {}\nfor cadabaliza in baliza:\n    cualbaliza = baliza&#x5B;cadabaliza]\n    coordbaliza&#x5B;cadabaliza] = &#x5B;tabla&#x5B;'c_este']&#x5B;cualbaliza]]\n    coordbaliza&#x5B;cadabaliza].append(tabla&#x5B;'c_norte']&#x5B;cualbaliza])\n\n# inicializa ubicados, encontrados, intervalos fuera, errores\n# ubicados tiene &#x5B;distancia, distancia+1s, distancia +2s,total]\nubicados   = np.zeros(shape=(3,4),dtype=int)\ntabla&#x5B;'interv_fuera'] = ''\ntabla&#x5B;'encontrado'] = np.nan\n# suma de errores\nsumatrilat = np.zeros(shape=(2,4),dtype=float)\nsumagps    = np.zeros(shape=(2,4),dtype=float)\nsumagpsdx  = np.zeros(shape=(2,4),dtype=float)\nsumagpsdy  = np.zeros(shape=(2,4),dtype=float)\n\n# distancias y errores a cada baliza\nfor unabaliza in baliza_val:\n    donde = baliza_val.index(unabaliza)\n    cualbaliza = baliza_key&#x5B;donde]\n    columna = medida+'_'+modo+'_'+cualbaliza\n    tabla&#x5B;'dist0_'+cualbaliza] = np.nan\n    tabla&#x5B;'dist1_'+cualbaliza] = np.nan\n    tabla&#x5B;'dist2_'+cualbaliza] = np.nan\n    \n    # distancia estimada por punto\n    for cadapunto in tabla.index:\n        p_rssi = tabla&#x5B;columna]&#x5B;cadapunto]\n        esgrupo = tabla&#x5B;'grupo']&#x5B;cadapunto]\n        estipo  = tabla&#x5B;'tipo']&#x5B;cadapunto]\n        # ecuacion a usar\n        ecuacion_rssi = ecuacion&#x5B;unabaliza]\n        if not(np.isnan(p_rssi)):\n            if (esgrupo in mostrargrp) and (estipo in mostrartip):\n                ubicados&#x5B;2,donde] = ubicados&#x5B;2,donde] + 1\n            dist = girni.dist_rssi(p_rssi,ecuacion_rssi)\n            &#x5B;distancia,e_mean,e_1std,e_2std,interv_fuera] = dist\n            dist1 = distancia + e_1std\n            dist2 = distancia + e_2std\n            tabla.loc&#x5B;cadapunto,'dist0_'+cualbaliza] = distancia\n            tabla.loc&#x5B;cadapunto,'dist1_'+cualbaliza] = dist1\n            tabla.loc&#x5B;cadapunto,'dist2_'+cualbaliza] = dist2\n            if interv_fuera&gt;0:\n                if len(tabla&#x5B;'interv_fuera']&#x5B;cadapunto])==0:\n                       separador=''\n                else:\n                       separador=','\n                tabla.loc&#x5B;cadapunto,'interv_fuera'] = tabla&#x5B;'interv_fuera']&#x5B;cadapunto]+separador+cualbaliza\nprocesados = np.max(ubicados&#x5B;2,:])\n\n# trilateraci\u00f3n. estima localizaci\u00f3n cada punto\n# inicializa cada punto a i*std\nfor i in range(0,3,1):\n    tabla&#x5B;'trilat_este_'+str(i)] = np.nan\n    tabla&#x5B;'trilat_norte_'+str(i)] = np.nan\n    tabla&#x5B;'trilat_error_'+str(i)] = np.nan\n    tabla&#x5B;'ubicado_'+str(i)] = np.nan\n    tabla&#x5B;'trilat_gps_error_'+str(i)] = np.nan\n    tabla&#x5B;'trilat_gps_dx_'+str(i)] = np.nan\n    tabla&#x5B;'trilat_gps_dy_'+str(i)] = np.nan\n\n# procesa cada punto\nfor cadapunto in tabla.index:\n    esgrupo = tabla&#x5B;'grupo']&#x5B;cadapunto]\n    if esgrupo in mostrargrp:\n        # coordenadas GPS del punto\n        c_este  = tabla&#x5B;'c_este']&#x5B;cadapunto]\n        c_norte = tabla&#x5B;'c_norte']&#x5B;cadapunto]\n\n        # cada punto a i*std\n        punto = {}\n        for i in range(0,3,1):\n            punto&#x5B;i] = {}\n            cuenta = 0\n            for unabaliza in baliza:\n                punto&#x5B;i]&#x5B;unabaliza] = tabla&#x5B;'dist'+str(i)+'_'+unabaliza]&#x5B;cadapunto]\n                # si existe distancia\n                if not(np.isnan(punto&#x5B;i]&#x5B;unabaliza])):\n                    cuenta = cuenta + 1\n            # Hay 3 mediciones a baliza\n            if cuenta==3:\n                localiza = girni.trilatera(punto&#x5B;i],\n                                           coordbaliza,\n                                           tolera = 10e-4)\n                baricentro = localiza&#x5B;'baricentro']\n                barerror   = localiza&#x5B;'barerror']\n                poligono   = localiza&#x5B;'poligono']\n                sumabaricentro = np.sum(baricentro)\n                # Hay coordenadas de baricentro\n                if not(np.isnan(sumabaricentro)):\n                    tabla.loc&#x5B;cadapunto,'trilat_este_'+str(i)]  = baricentro&#x5B;0]\n                    tabla.loc&#x5B;cadapunto,'trilat_norte_'+str(i)] = baricentro&#x5B;1]\n                    tabla.loc&#x5B;cadapunto,'trilat_error_'+str(i)] = np.round(barerror,tolera_error)\n\n                    # error trilatera hacia gps\n                    dx = baricentro&#x5B;0] - c_este\n                    dy = baricentro&#x5B;1] - c_norte\n                    error_gps = np.sqrt(dx**2+dy**2)\n                    tabla.loc&#x5B;cadapunto,'trilat_gps_error_'+str(i)] = np.round(error_gps,tolera_error)\n                    tabla.loc&#x5B;cadapunto,'trilat_gps_dx_'+str(i)] = np.round(dx,tolera_error)\n                    tabla.loc&#x5B;cadapunto,'trilat_gps_dy_'+str(i)] = np.round(dy,tolera_error)\n\n                    # cuenta error si encuentra primera vez\n                    cond1 = np.isnan(tabla&#x5B;'encontrado']&#x5B;cadapunto])\n                    cond2 = len(tabla&#x5B;'interv_fuera']&#x5B;cadapunto])&gt;0\n                    k = int(cond2) # intervalo extendido\n                    if cond1:\n                        tabla.loc&#x5B;cadapunto,'encontrado'] = i\n                        ubicados&#x5B;k,i]   = ubicados&#x5B;k,i]+1\n                        sumatrilat&#x5B;k,i] = sumatrilat&#x5B;k,i] + np.round(barerror,tolera_error)\n                        sumagps&#x5B;k,i]    = sumagps&#x5B;k,i] + np.round(error_gps,tolera_error)\n                        sumagpsdx&#x5B;k,i]  = sumagpsdx&#x5B;k,i] + np.round(np.abs(dx),tolera_error)\n                        sumagpsdy&#x5B;k,i]  = sumagpsdy&#x5B;k,i] + np.round(np.abs(dy),tolera_error)\n\n# contabiliza errores de localizados\nubicasuma = np.zeros(2)\nubicasumporc = np.zeros(2)\nubicaporc = np.zeros(shape=(2,3))\nfor k in range(0,2,1):\n    ubicados&#x5B;k,3] = int(np.sum(ubicados&#x5B;k,0:3]))\n    ubicasuma&#x5B;k]  = np.sum(ubicados&#x5B;k,0:3])\n    ubicasumporc&#x5B;k] = np.round(100*ubicasuma&#x5B;k]\/ubicados&#x5B;k,3],1)\n    for i  in range(0,3,1):\n        ubicaporc&#x5B;k,i]  = np.round(100*ubicados&#x5B;k,i]\/ubicasuma&#x5B;k],1)\n        if ubicados&#x5B;k,i]&gt;0:\n            sumatrilat&#x5B;k,i] = np.round(sumatrilat&#x5B;k,i]\/ubicados&#x5B;k,i],1)\n            sumagps&#x5B;k,i]    = np.round(sumagps&#x5B;k,i]\/ubicados&#x5B;k,i],1)\n            sumagpsdx&#x5B;k,i]  = np.round(sumagpsdx&#x5B;k,i]\/ubicados&#x5B;k,i],1)\n            sumagpsdy&#x5B;k,i]  = np.round(sumagpsdy&#x5B;k,i]\/ubicados&#x5B;k,i],1)\n\n# SALIDA\nprint('Errores localizacion')\n\nimport prettytable as ptt\nprint('Errores estimado: Cota-Trilatera-pol\u00edgono y Trilatera_vs_GPS')\nmostrar = ptt.PrettyTable(&#x5B;'punto','i*std','fuera','trilat',\n                           'gps','gps_dx','gps_dy',\n                           'u_d1','u_d2','u_d3'])\nfor cadapunto in tabla.index:\n\n    # selecciona puntos a mostrar\n    encontrado = tabla&#x5B;'encontrado']&#x5B;cadapunto]\n    esgrupo = tabla&#x5B;'grupo']&#x5B;cadapunto]\n    interv_fuera = int(len(tabla&#x5B;'interv_fuera']&#x5B;cadapunto])!=0)\n    cond1 = not(np.isnan(encontrado))\n    cond2 = esgrupo in mostrargrp\n    cond3 = interv_fuera in mostrarfuera \n\n    if cond1 and cond2 and cond3:\n        encontrado = int(encontrado)\n        \n        mostrar.add_row(&#x5B;cadapunto,\n                str(int(tabla&#x5B;'encontrado']&#x5B;cadapunto])),\n                tabla&#x5B;'interv_fuera']&#x5B;cadapunto],\n                str(tabla&#x5B;'trilat_error_'+str(encontrado)]&#x5B;cadapunto]),\n                str(tabla&#x5B;'trilat_gps_error_'+str(encontrado)]&#x5B;cadapunto]),\n                str(tabla&#x5B;'trilat_gps_dx_'+str(encontrado)]&#x5B;cadapunto]),\n                str(tabla&#x5B;'trilat_gps_dy_'+str(encontrado)]&#x5B;cadapunto]),\n                tabla&#x5B;'usar_d1']&#x5B;cadapunto],\n                tabla&#x5B;'usar_d2']&#x5B;cadapunto],\n                tabla&#x5B;'usar_d3']&#x5B;cadapunto]])\nprint(mostrar)\nprint('puntos con medidas:        ',procesados)\nloc_alg = np.round(100*np.sum(ubicados&#x5B;:,3])\/procesados,1)\nprint('localizados con algoritmo: ',\n      np.sum(ubicados&#x5B;:,3]),\n      '  , '+str(loc_alg)+'%' )\nprint('Errores Promedio:')\nresumen = ptt.PrettyTable(&#x5B;'error+i*std','cant','%',\n                           'trilat','gps','gps_dx',\n                           'gps_dy'])\nfor k in range(0,2,1):\n    if k == 0:\n        texto = 'dentro'\n    if k == 1:\n        texto = 'fuera'\n    resumen.add_row(&#x5B;'interv_'+texto,ubicados&#x5B;k,3],'',\n                     '','','',''])\n    for i in range(0,3,1):\n        resumen.add_row(&#x5B;'error_'+str(i),ubicados&#x5B;k,i],\n                         str(ubicaporc&#x5B;k,i])+'%',\n                         sumatrilat&#x5B;k,i],sumagps&#x5B;k,i],\n                         sumagpsdx&#x5B;k,i],sumagpsdy&#x5B;k,i],\n                         ])\nprint(resumen)\n\n# salida hacia archivo\ntabla.to_csv(arch_trilatera)\n\n# Grafica ubicados ------------\n# Referencias para gr\u00e1fica\ngrupo   = &#x5B;'FIEC' ,'FCNM'  ,'RECT','CIRC']\ncolores = &#x5B;'green','orange','grey','magenta']\ntipo    = &#x5B;'punto','1m' ,'gtw','dispositivo']\nmarcas  = &#x5B;    'o','D'  ,'D'  ,'*' ]\ncolorstd = &#x5B;'lightblue', 'lightgreen','orange']\ncolorlin = &#x5B;'lightblue', 'lightgreen','orange']\n\nfigura,grafica = plt.subplots()\n# balizas\nfor unabaliza in coordbaliza:\n    g_este = coordbaliza&#x5B;unabaliza]&#x5B;0]\n    g_norte = coordbaliza&#x5B;unabaliza]&#x5B;1]\n    grafica.scatter(g_este,g_norte,\n                    color = 'red',\n                    marker = 'D',\n                    label = cadapunto)\n    grafica.annotate(unabaliza,\n                     (g_este,g_norte))\n# Puntos\nfor cadapunto in tabla.index:\n    g_este  = tabla&#x5B;'c_este']&#x5B;cadapunto]\n    g_norte = tabla&#x5B;'c_norte']&#x5B;cadapunto]\n\n    # selecciona puntos a mostrar\n    encontrado = tabla&#x5B;'encontrado']&#x5B;cadapunto]\n    esgrupo = tabla&#x5B;'grupo']&#x5B;cadapunto]\n    interv_fuera = int(len(tabla&#x5B;'interv_fuera']&#x5B;cadapunto])!=0)\n    cond1 = not(np.isnan(encontrado))\n    cond2 = esgrupo in mostrargrp\n    cond3 = interv_fuera in mostrarfuera \n\n    if cond1 and cond2 and cond3:\n        encontrado = int(encontrado)\n        p_este  = tabla&#x5B;'trilat_este_'+str(encontrado)]&#x5B;cadapunto]\n        p_norte = tabla&#x5B;'trilat_norte_'+str(encontrado)]&#x5B;cadapunto]\n        grafica.scatter(p_este,p_norte,\n                        color = colorstd&#x5B;encontrado],\n                        label = cadapunto)\n        grafica.plot(&#x5B;p_este,g_este],\n                     &#x5B;p_norte,g_norte],\n                     color = colorstd&#x5B;encontrado],\n                     linestyle='dotted')\n        grafica.scatter(g_este,g_norte,\n                        color = 'blue',\n                        label = cadapunto)\n        grafica.annotate(cadapunto,(g_este,g_norte),\n                         color='blue')\n\ngrafica.set_xlabel('UTM_este')\ngrafica.set_ylabel('UTM_norte')\ngrafica.grid()\ngrafica.set_title('Puntos Ubicados')\n\nplt.show()\n<\/pre><\/div>","protected":false},"excerpt":{"rendered":"<p>Algoritmo en Python<\/p>\n","protected":false},"author":8043,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1463489],"tags":[],"class_list":["post-3029","post","type-post","status-publish","format-standard","hentry","category-lorawan-localizacion-rssi"],"_links":{"self":[{"href":"https:\/\/blog.espol.edu.ec\/girni\/wp-json\/wp\/v2\/posts\/3029","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.espol.edu.ec\/girni\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.espol.edu.ec\/girni\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.espol.edu.ec\/girni\/wp-json\/wp\/v2\/users\/8043"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.espol.edu.ec\/girni\/wp-json\/wp\/v2\/comments?post=3029"}],"version-history":[{"count":6,"href":"https:\/\/blog.espol.edu.ec\/girni\/wp-json\/wp\/v2\/posts\/3029\/revisions"}],"predecessor-version":[{"id":4854,"href":"https:\/\/blog.espol.edu.ec\/girni\/wp-json\/wp\/v2\/posts\/3029\/revisions\/4854"}],"wp:attachment":[{"href":"https:\/\/blog.espol.edu.ec\/girni\/wp-json\/wp\/v2\/media?parent=3029"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.espol.edu.ec\/girni\/wp-json\/wp\/v2\/categories?post=3029"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.espol.edu.ec\/girni\/wp-json\/wp\/v2\/tags?post=3029"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}