{"id":2719,"date":"2020-11-21T12:46:33","date_gmt":"2020-11-21T17:46:33","guid":{"rendered":"http:\/\/blog.espol.edu.ec\/girni\/?p=2719"},"modified":"2026-08-04T21:13:39","modified_gmt":"2026-08-05T02:13:39","slug":"procesa-datos-funciones-girni_lora_libreria","status":"publish","type":"post","link":"https:\/\/blog.espol.edu.ec\/girni\/procesa-datos-funciones-girni_lora_libreria\/","title":{"rendered":"3.2 Procesa datos - Funciones girni_lora_libreria"},"content":{"rendered":"\n<p>El archivo contiene un grupo de&nbsp; funciones usadas para procesar los datos de este prototipo, se separaron del bloque principal de instrucciones con&nbsp; el objetivo de simplificar el desarrollo del las actividades principales.<\/p>\n\n\n\n<p>Recuerde disponer de este archivo en la misma carpeta que el algoritmo que invoca a la librer\u00eda.<\/p>\n\n\n\n<p>archivo de librer\u00eda: <a href=\"https:\/\/drive.google.com\/file\/d\/1XgGYzy0o6ZDTMH3E6OnXvyLdXpI6LH5W\/view?usp=sharing\">girni_lora_libreria<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">datos de muestras<\/h2>\n\n\n\n<p><strong><em>tabulaPunto(unarchivo,directorio)<\/em><\/strong>:<br>Lee el archivo de un punto, tabula cada lectura por dispositivo en diccionario,<br>por modo: rx, rx y remitente de cada paquete: baliza.<\/p>\n\n\n\n<p><strong><em>describePunto(punto)<\/em><\/strong>:<br>estadistica descriptiva de un punto, calcula: count, mean, std, min, 25%, 50%, 75%, min, max<\/p>\n\n\n\n<p><em><strong>resumen_medida(punto,medida,descriptor<\/strong><\/em>):<br>Realiza la tabla resumen de puntos por la medida y descriptor a partir de la tabla de los puntos estadisticos descritos<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Linealizaci\u00f3n para ecuaci\u00f3n<\/h2>\n\n\n\n<p><em><strong>pares_usar<\/strong><\/em>(<em><strong>tabla<\/strong><\/em>, <strong><em>baliza<\/em><\/strong>, <strong><em>analiza<\/em><\/strong>,<strong><em>unabaliza<\/em><\/strong>, unsector ='', medida = 'rssi',modo = 'rx')<\/p>\n\n\n\n<p>Selecciona desde la tabla puntos a usar respecto a una baliza, el resultado se entrega en una lista que contiene los pares ordenados y sus etiquetas [pares, par_etiqueta]<\/p>\n\n\n\n<p><em><strong>linealiza_lstsq<\/strong><\/em>(<em><strong>xi<\/strong><\/em>,<em><strong>yi<\/strong><\/em>,digitos = 3)<br>emplea el m\u00e9todo de minimos cuadrados para entregar la ecuacion mediante un diccionario que contiene los par\u00e1metros para aplicarla.<\/p>\n\n\n\n<p>La variable d\u00edgitos indica cu\u00e1ntos d\u00edgitos se usar\u00e1n para la ecuaci\u00f3n en formato latex.<\/p>\n\n\n\n<p>El procedimiento se describe en: <a href=\"http:\/\/blog.espol.edu.ec\/girni\/rssidistancia-linealizacion-funcion-python\/\">Rssi(distancia) Linealizaci\u00f3n \u2013 funci\u00f3n Python<\/a><\/p>\n\n\n\n<pre class=\"wp-block-code alignwide\"><code>unaecuacion = {<span style=\"color: #008000\">'alpha'<\/span>   : alpha,\n               <span style=\"color: #008000\">'beta'<\/span>    : beta,\n               <span style=\"color: #008000\">'eq_latex'<\/span>: fdtxt0,\n               <span style=\"color: #008000\">'intervalox'<\/span> : &#091;np.min(xi),np.max(xi)],\n               <span style=\"color: #008000\">'error_medio'<\/span>: dyi0mean,\n               <span style=\"color: #008000\">'error_std'<\/span>  : dyi0std,\n               <span style=\"color: #008000\">'eqg_latex'<\/span>  : grtxt0,\n               <span style=\"color: #008000\">'intervaloy'<\/span>  : &#091;np.min(yi),np.max(yi)],\n               <span style=\"color: #008000\">'errorx_medio'<\/span>: dxi0mean,\n               <span style=\"color: #008000\">'errorx_std'<\/span>  : dxi0std,\n               }<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Proceso de triangulaci\u00f3n<\/h2>\n\n\n\n<p><em><strong>dist_rssi<\/strong><\/em>(<strong><em>valor,ecuacion_rssi<\/em><\/strong>).&nbsp; Eval\u00faa la ecuaci\u00f3n de distancia(rssi) revisando los intervalos disponibles para el <strong>valor<\/strong> de rssi dado<strong>.<\/strong><\/p>\n\n\n\n<p><strong><em>cruce2circulos<\/em><\/strong>(<strong><em>x1<\/em><\/strong>,<strong><em>y1<\/em><\/strong>,<em><strong>r1<\/strong><\/em>,x2,y2,r2). Revisa intervalo de area de cruce entre dos c\u00edrculos de centro y radio: x1, y1, r1 \/\/ x2, y2, r2.<\/p>\n\n\n\n<p><strong><em>raices2circulos<\/em><\/strong>(<em>x1<\/em>,<em><strong>y1<\/strong><\/em>,<em><strong>r1<\/strong><\/em>,x2,y2,r2,tolera=1e-10). Busca las intersecci\u00f3n entre 2 c\u00edrculos de centro y radio: x1,y1,r1 || x2,y2,r2 . Revisa con cruce2circulos().<\/p>\n\n\n\n<p><em><strong>intersectacirculos<\/strong><\/em>(<em><strong>radio<\/strong><\/em>,<em><strong>centro<\/strong><\/em>,tolera=1e-10). Busca las intersecciones entre parejas de varios c\u00edrculos y las entrega como [raicesx,raicesy], usa las funciones cruce2circulos() y con raices2circulos() que se encuentran en el enlace: <a href=\"http:\/\/blog.espol.edu.ec\/analisisnumerico\/s3eva_it2018_t1-interseccion-de-dos-circulos\/#intersecta2circulos\">Soluci\u00f3n General de intersecci\u00f3n de c\u00edrculos<\/a><\/p>\n\n\n\n<p><em><strong>trilatera<\/strong><\/em>(<em><strong>radio<\/strong><\/em>,<em><strong>centro<\/strong><\/em>,tolera=1e-10). Busca el baricentro entre las intersecciones de varios c\u00edrculos, punto central en el \u00e1rea de<br>intersecci\u00f3n entre varios c\u00edrculos. Requiere el resultado de la funci\u00f3n:<br>raiztodas = intersectacirculos(centro,radio, tolera = 1e-10)<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">Algoritmo Python<\/h2>\n\n\n<div class=\"wp-block-syntaxhighlighter-code alignwide\"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n# Girni LoRa librerias 2020-10-07\n# LoRa-Multipunto, lecturas de Rssi y SNR\n# Girni 2020-10-07 propuesta: edelros@espol.edu.ec\n\nimport numpy as np\nimport pandas as pd\nimport scipy.optimize as sp\n\ndef tabulaPunto(unarchivo,carpeta, prefijo = 'multipunto'):\n    ''' Lee el archivo de un punto dentro del carpeta,\n        elimina el prefijo el nombre del archivo,\n        tabula cada lectura por dispositivo en diccionario,\n        por modo: rx, rx\n        y remitente de cada paquete: baliza\n        Prepara para procesar estadistica descriptiva\n    '''\n    # Datos estructura\n    punto = {'rx':{},\n             'tx':{},\n             'nombre': ' '}\n    \n    # Lectura de unarchivo\n    unarchivoubica = carpeta+'\/'+unarchivo\n    archivoPunto = open(unarchivoubica,'r')\n\n    # nombre del punto desde nombre archivo\n    pnombre = unarchivo\n    pnombre = pnombre.strip('.txt')\n    n = len(prefijo)\n    pnombre = pnombre&#x5B;n:]\n    punto&#x5B;'nombre'] = pnombre\n    \n    linea = archivoPunto.readline()\n    while (linea!=''):\n        linea_rx = linea.startswith('rx')\n        linea_tx = linea.startswith('tx')\n        if linea_rx or linea_tx:\n            # formato de trama:\n            # tx_rx, c1_ff, d1_d2_d3, numtrama,\n            # rssitx, snrtx, rssi_rx,snr_rx\n            texto = linea.strip('\\n')\n            texto = texto.split(',')\n            rx_tx      = texto&#x5B;0]\n            dir_recibe = texto&#x5B;1]\n            dir_remite = texto&#x5B;2]\n            ID_paquete = int(texto&#x5B;3])\n            rssi_tx    = float(texto&#x5B;4])\n            snr_tx     = float(texto&#x5B;5])\n            rssi_rx    = float(texto&#x5B;6])\n            snr_rx     = float(texto&#x5B;7])\n            # llena datos\n            if dir_remite in punto&#x5B;rx_tx].keys():\n                punto&#x5B;rx_tx]&#x5B;dir_remite]&#x5B;'rssi_rx'].append(rssi_rx)\n                punto&#x5B;rx_tx]&#x5B;dir_remite]&#x5B;'snr_rx'].append(snr_rx)\n                punto&#x5B;rx_tx]&#x5B;dir_remite]&#x5B;'secuencia_rx'].append(ID_paquete)\n                punto&#x5B;rx_tx]&#x5B;dir_remite]&#x5B;'rssi_tx'].append(rssi_tx)\n                punto&#x5B;rx_tx]&#x5B;dir_remite]&#x5B;'snr_tx'].append(snr_tx)\n            else:\n                punto&#x5B;rx_tx]&#x5B;dir_remite] = {'rssi_rx': &#x5B;rssi_rx],\n                                            'snr_rx' : &#x5B;snr_rx],\n                                            'secuencia_rx':&#x5B;ID_paquete],\n                                            'rssi_tx': &#x5B;rssi_tx],\n                                            'snr_tx' : &#x5B;snr_tx]}\n        # siguiente l\u00ednea\n        linea = archivoPunto.readline()\n    archivoPunto.close()\n    return(punto)\n\ndef describePunto(punto):\n    ''' estadistica descriptiva de un punto\n    calcula y registra count, mean, std,\n    min,25%,50%,75%,max\n    '''\n    estadistica = {}\n    for modo in punto.keys():\n        estadistica&#x5B;modo] = {}\n        # analiza rssi y snr para rx y tx\n        for disp in punto&#x5B;modo].keys():\n            estadistica&#x5B;modo]&#x5B;disp] = ''\n            valores = pd.DataFrame(punto&#x5B;modo]&#x5B;disp])\n            descrito = valores.describe()\n            descrito = descrito.drop('secuencia_rx',axis=1)\n            estadistica&#x5B;modo]&#x5B;disp] = descrito       \n    return(estadistica)\n\n\ndef resumen_medida(punto,medida,descriptor):\n    '''\n    Realiza la tabla resumen de puntos por\n    medida ('rssi' o 'snr')\n    y descriptor ('count, mean, std,\n     min,25%,50%,75%,max)\n    a partir de la tabla de los puntos estadisticos descritos\n    '''\n    rsm_disp = pd.DataFrame()\n    for disp in punto:\n        undisp_rx = punto&#x5B;disp]&#x5B;medida+'_rx']\n        etiquetarx = medida+'_rx_'+disp\n        rsm_disp&#x5B;etiquetarx] = undisp_rx.copy()\n    for disp in punto:\n        undisp_tx = punto&#x5B;disp]&#x5B;medida+'_tx']\n        etiquetatx = medida+'_tx_'+disp\n        rsm_disp&#x5B;etiquetatx] = undisp_tx.copy()\n    unafila = rsm_disp.loc&#x5B;descriptor]\n    return(unafila)\n\ndef pares_usar(tabla,baliza, analiza,\n                unabaliza, unsector ='', \n                medida = 'rssi', modo = 'rx'):\n    ''' Selecciona en tabla los puntos a usar\n        respecto a una baliza  y sector\n        resultado en &#x5B;pares, par_etiqueta]\n    '''\n    \n    # balizas referencia para analizar\n    baliza_key = list(baliza.keys())\n    baliza_val = list(baliza.values())\n\n    donde = baliza_val.index(unabaliza)\n    cualbaliza = baliza_key&#x5B;donde]\n\n    # banderas de uso y atipicos\n    bal_sec = cualbaliza+unsector\n    tabla&#x5B;'usar_'+bal_sec] = 0\n    tabla&#x5B;'atip_'+bal_sec] = 0\n        \n    # Parametros\n    if unsector == '':\n        analizarque = analiza&#x5B;unabaliza]\n    else:\n        analizarque = analiza&#x5B;unabaliza]&#x5B;unsector]\n    atipico_std = analizarque&#x5B;'atipico_std']\n    bal_grp = analizarque&#x5B;'grp']\n    bal_tip = analizarque&#x5B;'tip']\n    bal_LOS = analizarque&#x5B;'LOS']\n            \n    # usar segmento de grupo\/tipo, bandera True\/False\n    for cadapunto in tabla.index:\n        cond1 = tabla&#x5B;'grupo']&#x5B;cadapunto] in bal_grp\n        cond2 = tabla&#x5B;'tipo']&#x5B;cadapunto] in bal_tip\n        cond3 = tabla&#x5B;'LOS_'+cualbaliza]&#x5B;cadapunto] in bal_LOS\n        cond4 = True\n        if unsector != '':\n            cond4 = tabla&#x5B;'sector_'+cualbaliza]&#x5B;cadapunto] == int(unsector.strip('s'))\n        usar = cond1 and cond2 and cond3 and cond4\n        valor = 0\n        if usar:\n            valor = 1\n        tabla.loc&#x5B;cadapunto,'usar_'+bal_sec] = valor\n\n    # datos hacia baliza\n    pares = &#x5B;]\n    par_etiqueta = &#x5B;]\n    for cadapunto in tabla.index:\n        columna = medida+'_'+modo+'_'+cualbaliza\n        xk = tabla&#x5B;'dist_'+cualbaliza]&#x5B;cadapunto]\n        yk = tabla&#x5B;columna]&#x5B;cadapunto]\n        \n        # no vacio y para usar\n        cond1 = not(np.isnan(yk))\n        cond2 = tabla&#x5B;'usar_'+bal_sec]&#x5B;cadapunto]\n        if cond1 and cond2:\n            unpar = np.array(&#x5B;xk,yk])\n            \n            # llena pares y etiquetas\n            if len(pares)&gt;0:\n                pares = np.concatenate((pares,&#x5B;unpar]),axis=0)\n                par_etiqueta = np.concatenate((par_etiqueta,&#x5B;cadapunto]),\n                                              axis=0)\n            else:\n                pares = np.array(&#x5B;unpar])\n                par_etiqueta = np.array(&#x5B;cadapunto])\n\n    # ordena pares para gr\u00e1fica\n    if len(pares)&gt;0:\n        ordenar = np.argsort(pares&#x5B;:, 0])\n        pares = pares&#x5B;ordenar]\n        par_etiqueta = par_etiqueta&#x5B;ordenar]\n\n    return (&#x5B;pares, par_etiqueta])\n\ndef linealiza_lstsq(xi,yi,digitos = 3):\n    ''' usa minimos cuadrados para entregar la ecuacion\n        digitos: usados en expresion latex\n    '''\n    unaecuacion = {}\n    # Eje x en log10()\n    xilog = np.log10(xi)\n    n = len(xi)\n    \n    # m\u00ednimos cuadrados (least square),\n    # distancia vs medida\n    A = np.vstack(&#x5B;xilog, np.ones(n)]).T\n    &#x5B;m0, b0] = np.linalg.lstsq(A, yi, rcond=None)&#x5B;0]\n    alpha = -m0\/10\n    beta  = b0\n\n    # ecuaciones expresion rssi(d)\n    fdist0 = lambda d: -10*alpha*(np.log10(d))+beta\n    \n    fdtxt0 = r'$ rssi = -10(' + str(np.round(alpha,digitos))\n    fdtxt0 = fdtxt0 + ')log_{10}(d)' # +('\n    texto = '+'\n    if beta &lt;0:\n        texto = '-'\n    fdtxt0 = fdtxt0 + texto + str(np.round(np.abs(beta),digitos))+' \n\n\n    # Errores respecto a rssi(d) \n    yi0  = fdist0(xi)\n    dyi0 = yi - yi0\n    dyi0mean = np.mean(np.abs(dyi0))\n    dyi0std  = np.std(dyi0, dtype=np.float64)\n\n    # ecuaciones expresion d(rssi)\n    grssi0 = lambda rssi: 10**((beta-rssi)\/(10*alpha))\n    grtxt0 = r&quot;$ d = 10^{(&quot; + str(np.round(beta,digitos)) + ' - '\n    grtxt0 = grtxt0 + 'rssi)\/' + '(10('+str(np.round(alpha,digitos))+'))} \n\n\n    # Errores respecto a rssi(d) \n    xi0  = grssi0(yi)\n    dxi0 = xi - xi0\n    dxi0mean = np.mean(np.abs(dxi0))\n    dxi0std  = np.std(dxi0, dtype=np.float64)\n    \n    unaecuacion = {'alpha'   : alpha,\n                   'beta'    : beta,\n                   'eq_latex': fdtxt0,\n                   'intervalox' : &#x5B;np.min(xi),np.max(xi)],\n                   'error_medio': dyi0mean,\n                   'error_std'  : dyi0std,\n                   'eqg_latex'  : grtxt0,\n                   'intervaloy' : &#x5B;np.min(yi),np.max(yi)],\n                   'errorx_medio': dxi0mean,\n                   'errorx_std'  : dxi0std,\n                   }\n    return(unaecuacion)\n\ndef dist_rssi(valor,ecuacion_rssi, desplazar = 0):\n    ''' evalua ecuacion de distancia(rssi)\n        revisando los intervalos disponibles\n    '''\n    # resultados\n    distancia = np.nan\n    e_mean = np.nan\n    e_1std = np.nan\n    e_2std = np.nan\n    \n    # Revisa intervalos en ecuacion\n    interv_fuera = 0\n    tamano = len(ecuacion_rssi)\n    eq_cual = list(ecuacion_rssi.keys())\n\n    # revisa si hay ecuaciones\n    if tamano &gt;= 1:\n        # en intervalo de todos los puntos?\n        i_eq = 'r0'\n        a = ecuacion_rssi&#x5B;i_eq]&#x5B;'intervaloy']&#x5B;0]\n        b = ecuacion_rssi&#x5B;i_eq]&#x5B;'intervaloy']&#x5B;1]\n        desplaza = 0; valor0 = valor\n        if 'desplaza' in list(ecuacion_rssi&#x5B;i_eq].keys()):\n            desplaza = ecuacion_rssi&#x5B;i_eq]&#x5B;'desplaza']\n        if desplazar == 1:\n            valor0 = valor - desplaza\n        if valor0&lt;a:\n            interv_fuera = -1 # izquierda\n        if valor0&gt;=b:\n            interv_fuera = 1  # derecha\n    if interv_fuera!=0:\n        if interv_fuera == 1: # derecha\n            i_eq = eq_cual&#x5B;1]\n        if interv_fuera == -1: # izquierda\n            i_eq = eq_cual&#x5B;-1]\n        # intervalo rssi &#x5B;a,b)\n        a = ecuacion_rssi&#x5B;i_eq]&#x5B;'intervaloy']&#x5B;0]\n        b = ecuacion_rssi&#x5B;i_eq]&#x5B;'intervaloy']&#x5B;1]\n        alpha = ecuacion_rssi&#x5B;i_eq]&#x5B;'alpha']\n        beta = ecuacion_rssi&#x5B;i_eq]&#x5B;'beta']\n        # correccion de formula por desplazamiento\n        desplaza = 0; valor1 = valor\n        if 'desplaza' in list(ecuacion_rssi&#x5B;i_eq].keys()):\n            desplaza = ecuacion_rssi&#x5B;i_eq]&#x5B;'desplaza']\n        if desplazar == 1:\n            valor1 = valor - desplaza\n        distancia = 10**((valor1-beta)\/(-10*alpha))\n        \n        # errores estimados de distancia\n        error_medio = ecuacion_rssi&#x5B;i_eq]&#x5B;'error_medio']\n        error_std  = ecuacion_rssi&#x5B;i_eq]&#x5B;'error_std']\n        dist_mean = 10**((valor-error_medio-beta)\/(-10*alpha))\n        dist_1std = 10**((valor-error_std-beta)\/(-10*alpha))\n        dist_2std = 10**((valor-2*error_std-beta)\/(-10*alpha))\n        e_mean = np.abs(distancia-dist_mean)\n        e_1std = np.abs(distancia-dist_1std)\n        e_2std = np.abs(distancia-dist_2std)\n\n    # evalua valor si hay ecuacion\n    if tamano&gt;1 and interv_fuera == 0:\n        donde = eq_cual.index('r0')\n        eq_cual.pop(donde)\n        # Revisa que exista ecuacion en cada intervalo\n        for i_eq in eq_cual:\n            if ecuacion_rssi&#x5B;i_eq] is None:\n                donde = eq_cual.index(i_eq)\n                eq_cual.pop(donde)\n                \n        # revisa intervalo y evalua\n        for i_eq in eq_cual:\n            # correccion de formula por desplazamiento\n            desplaza = 0; valor1 = valor\n            if 'desplaza' in list(ecuacion_rssi&#x5B;i_eq].keys()):\n                desplaza = ecuacion_rssi&#x5B;i_eq]&#x5B;'desplaza']\n            if desplazar == 1:\n                valor1 = valor - desplaza\n            # intervalo rssi &#x5B;a,b)\n            a = ecuacion_rssi&#x5B;i_eq]&#x5B;'intervaloy']&#x5B;0]\n            b = ecuacion_rssi&#x5B;i_eq]&#x5B;'intervaloy']&#x5B;1]\n            \n            cond1 = (valor1&gt;=a) and (valor1&lt;b)\n            \n            if cond1:\n                alpha = ecuacion_rssi&#x5B;i_eq]&#x5B;'alpha']\n                beta = ecuacion_rssi&#x5B;i_eq]&#x5B;'beta']\n                distancia = 10**((valor1-beta)\/(-10*alpha))\n                \n                # errores estimados de distancia\n                error_medio = ecuacion_rssi&#x5B;i_eq]&#x5B;'error_medio']\n                error_std  = ecuacion_rssi&#x5B;i_eq]&#x5B;'error_std']\n                dist_mean = 10**((valor-error_medio-beta)\/(-10*alpha))\n                dist_1std = 10**((valor-error_std-beta)\/(-10*alpha))\n                dist_2std = 10**((valor-2*error_std-beta)\/(-10*alpha))\n                e_mean = np.abs(distancia-dist_mean)\n                e_1std = np.abs(distancia-dist_1std)\n                e_2std = np.abs(distancia-dist_2std)\n    \n    return(&#x5B;distancia,e_mean,e_1std,e_2std,interv_fuera])\n\n# Las siguientes funciones tienen como objetivo\n# realizar la trilateraci\u00f3n entre varios circulos\n# def trilatera(radio,centro,tolera=1e-10)\n# requieren las funiones:\n# def cruce2circulos(x1,y1,r1,x2,y2,r2)\n# def raices2circulos(x1,y1,r1,x2,y2,r2,tolera=1e-10)\n# def intersectacirculos(radio,centro,tolera=1e-10)\n\ndef cruce2circulos(x1,y1,r1,x2,y2,r2):\n    ''' Revisa intervalo de area de cruce\n        entre dos c\u00edrculos de centro y radio\n        x1,y1,r1 \/\/ x2,y2,r2\n    '''\n    uncruce = &#x5B;]\n    dx = x2 - x1\n    dy = y2 - y1\n    d_centros = np.sqrt(dx**2 + dy**2)\n    d_cruce   = r2 + r1\n    \n    # los circulos se cruzan o tocan\n    if d_cruce &gt;= d_centros:\n\n        # intervalos de cruce\n        xa = np.max(&#x5B;x1-r1,x2-r2])\n        xb = np.min(&#x5B;x1+r1,x2+r2])\n        ya = np.max(&#x5B;y1-r1,y2-r2])\n        yb = np.min(&#x5B;y1+r1,y2+r2])\n        \n        # cada circulo arriba, abajo\n        abajo1 = 0 ; arriba1 = 0\n        abajo2 = 0 ; arriba2 = 0\n        if ya&lt;=y1:\n            abajo1  = 1\n        if yb&gt;=y1:\n            arriba1 = 1\n        if ya&lt;=y2:\n            abajo2  = 1\n        if yb&gt;=y2:\n            arriba2 = 1\n        sector  = &#x5B; abajo1*abajo2, abajo1*arriba2,\n                   arriba1*abajo2, arriba1*arriba2]\n        uncruce = &#x5B;xa,xb,ya,yb,sector]\n    return(uncruce)\n\ndef raices2circulos(x1,y1,r1,x2,y2,r2,tolera=1e-10):\n    ''' busca las intersecci\u00f3n entre 2 circulos\n        de centro y radio: x1,y1,r1 || x2,y2,r2\n        revisa con cruce2circulos()\n    '''\n    casicero = tolera*np.min(&#x5B;r1,r2])\n    uncruce = cruce2circulos(x1,y1,r1,x2,y2,r2)\n    raizx = &#x5B;]; raizy = &#x5B;]\n    secruzan =  0\n    \n    # si hay cruce de circulos\n    if len(uncruce)&gt;0:\n        sectores = &#x5B;&#x5B;-1,-1],&#x5B;-1,1], \n                    &#x5B; 1,-1],&#x5B; 1,1]]\n        &#x5B;xa,xb,ya,yb,sector] = uncruce\n        xc = (xa+xb)\/2\n        dx = xb-xa\n        dy = yb-ya\n        k = len(sector)\n        if dx&lt;casicero: # se tocan en un punto\n            k = 1\n        for j in range(0,k,1):\n            if sector&#x5B;j]==1:\n                s1 = sectores&#x5B;j]&#x5B;0]\n                s2 = sectores&#x5B;j]&#x5B;1]\n                def gx(x,x1,r1,casicero):\n                    z = r1**2-(x-x1)**2\n                    if np.abs(z)&lt;casicero:\n                        z = 0\n                    return(z)\n                fx1 = lambda x: s1*np.sqrt(gx(x,x1,r1,casicero)) + y1\n                fx2 = lambda x: s2*np.sqrt(gx(x,x2,r2,casicero)) + y2\n                fx  = lambda x: fx1(x)-fx2(x)\n                \n                fa = fx(xa)\n                fb = fx(xb)\n                raiz1 = np.nan\n                raiz2 = np.nan\n                \n                # intervalo\/2 izquierda\n                xc = xc + dx*tolera\n                fc = fx(xc)\n                cambio = np.sign(fa)*np.sign(fc)\n                if cambio&lt;0:\n                    raiz1 = sp.bisect(fx,xa,xc,xtol=tolera)\n                    \n                # intervalo\/2 derecha\n                xc = xc - 2*dx*tolera\n                fc = fx(xc)\n                cambio = np.sign(fc)*np.sign(fb)\n                if cambio&lt;0:\n                    raiz2 = sp.bisect(fx,xc,xb,xtol=tolera)\n                    \n                # si hay contacto en un borde\n                if dx&lt;casicero and dy&gt;0:\n                    raiz1 = xa\n                if dy&lt;casicero and dx&gt;0:\n                    raiz1 = x1\n                    \n                # A\u00f1ade si existe raiz\n                if not(np.isnan(raiz1)):\n                    raizx.append(raiz1)\n                    raizy.append(fx1(raiz1))\n                if not(np.isnan(raiz2)):\n                    raizx.append(raiz2)\n                    raizy.append(fx1(raiz2))\n                secruzan = 1\n    # No hay cruce de circulos\n    if len(uncruce) == 0:\n        dx = x2 - x1\n        dy = y2 - y1\n        m = dy\/dx\n        theta = np.arctan2(dy,dx)\n        dx1 = r1* np.cos(theta)\n        dx2 = r2* np.cos(theta)\n        xi1 = x1 + dx1\n        xi2 = x2 - dx2\n        b = y1 - m*x1\n        raizx = &#x5B;(xi1+xi2)\/2]\n        raizy = &#x5B;m*raizx&#x5B;0]+b]\n        \n    raices = &#x5B;raizx,raizy,secruzan]\n    return(raices)\n\ndef intersectacirculos(radio,centro,tolera=1e-10):\n    ''' busca las intersecciones entre parejas de varios\n        c\u00edrculos y las entrega como &#x5B;raicesx,raicesy]\n        usa las funciones cruce2circulos()\n        y con raices2circulos() que se encuentran en el enlace:\n    http:\/\/blog.espol.edu.ec\/analisisnumerico\/s3eva_it2018_t1-interseccion-de-dos-circulos\/#intersecta2circulos\n    '''\n    vertices = list(centro.keys())\n    n = len (vertices)\n    \n    # agrupa raices en todasx y todasy\n    todasx  = &#x5B;] ; todasy  = &#x5B;]\n    cruces = np.zeros(shape=(n,n),dtype=int)\n    for i in range(0,n-1,1):\n        for j in range(i+1,n,1):\n            x1 = centro&#x5B;vertices&#x5B;i]]&#x5B;0]\n            y1 = centro&#x5B;vertices&#x5B;i]]&#x5B;1]\n            r1 = radio&#x5B;vertices&#x5B;i]]\n            x2 = centro&#x5B;vertices&#x5B;j]]&#x5B;0]\n            y2 = centro&#x5B;vertices&#x5B;j]]&#x5B;1]\n            r2 = radio&#x5B;vertices&#x5B;j]]\n\n            # busca raices entre 2 circulos\n            raices = raices2circulos(x1,y1,r1,x2,y2,r2,tolera)\n            raizx = raices&#x5B;0]\n            raizy = raices&#x5B;1]\n            cruces&#x5B;i,j] = raices&#x5B;2]\n            cruces&#x5B;j,i] = raices&#x5B;2]\n            m = len(raizx)\n            if m&gt;0:\n                for k in range(0,m,1):\n                    todasx.append(raizx&#x5B;k])\n                    todasy.append(raizy&#x5B;k])\n                \n    raiztodas = &#x5B;todasx,todasy,cruces]\n    return(raiztodas)\n\ndef trilatera(radio,centro,tolera=1e-10):\n    ''' busca el baricentro entre las intersecciones\n        de varios c\u00edrculos punto central en el \u00e1rea de\n        intersecci\u00f3n entre varios circulos.\n        requiere el resultado de la funci\u00f3n:\n        raiztodas = intersectacirculos(centro,radio, tolera = 1e-10)\n    '''\n    vertices = list(centro.keys())\n    n = len (vertices)\n    # revisa raiz dentro de cada circulo\n    raiztodas = intersectacirculos(radio,centro,tolera)\n    todasx = raiztodas&#x5B;0]\n    todasy = raiztodas&#x5B;1]\n    cruces = raiztodas&#x5B;2]\n    m = len(todasx)\n    raicesx = &#x5B;]\n    raicesy = &#x5B;]\n    fuera = &#x5B;]\n    for k in range(0,m,1):\n        xk = todasx&#x5B;k]\n        yk = todasy&#x5B;k]\n        dentro = 0\n        for i in range(0,n,1):\n            x1 = centro&#x5B;vertices&#x5B;i]]&#x5B;0]\n            y1 = centro&#x5B;vertices&#x5B;i]]&#x5B;1]\n            r1 = radio&#x5B;vertices&#x5B;i]]\n            dx = x1-xk\n            dy = y1-yk\n            d_centro = np.sqrt(dx**2+dy**2)\n            if d_centro&lt;=(r1*(1+tolera)):\n                dentro = dentro + 1\n        if dentro == n:\n            raicesx.append(xk)\n            raicesy.append(yk)\n            \n    # busca baricentro\n    baricentro = np.nan\n    barerror = np.nan\n    q = len(raicesx)\n    if q&gt;0:\n        xbar = np.mean(raicesx)\n        ybar = np.mean(raicesy)\n        baricentro = &#x5B;xbar,ybar]\n        barerror = 0\n        for i in range(0,q,1):\n            d = np.sqrt((xbar-raicesx&#x5B;i])**2+(ybar-raicesy&#x5B;i])**2)\n            if d&gt;barerror:\n                barerror = d\n        poligono = &#x5B;raicesx,raicesy]\n    else:\n        poligono = &#x5B;todasx,todasy]\n    resultado = {'baricentro': baricentro,\n                 'barerror'  : barerror,\n                 'poligono'  : poligono,\n                 'nocruzaen' : ''}\n\n    \n    # revisa espacio entre circulos\n    sumacruces = np.sum(cruces,axis = 0)\n    if 0 in list(sumacruces):\n        raicesx = todasx.copy()\n        raicesy = todasy.copy()\n        for i in range(0,n,1):\n            if sumacruces&#x5B;i]==0:\n                x1 = centro&#x5B;vertices&#x5B;i]]&#x5B;0]\n                y1 = centro&#x5B;vertices&#x5B;i]]&#x5B;1]\n                lejanamax = -1\n                lejana_en = -1\n                for k in range(0,len(raicesx),1):\n                    dx = x1 - raicesx&#x5B;k]\n                    dy = y1 - raicesy&#x5B;k]\n                    d_centro = np.sqrt(dx**2+dy**2)\n                    if d_centro&gt;lejanamax:\n                        lejanamax = d_centro\n                        lejana_en = k\n                if lejana_en&gt;=0:\n                    raicesx.pop(lejana_en)\n                    raicesy.pop(lejana_en)\n        # busca baricentro\n        baricentro = np.nan\n        barerror = np.nan\n        q = len(raicesx)\n        if q&gt;0:\n            xbar = np.mean(raicesx)\n            ybar = np.mean(raicesy)\n            baricentro = &#x5B;xbar,ybar]\n            barerror = 0\n            for i in range(0,q,1):\n                d = np.sqrt((xbar-raicesx&#x5B;i])**2+(ybar-raicesy&#x5B;i])**2)\n                if d&gt;barerror:\n                    barerror = d\n            poligono = &#x5B;raicesx,raicesy]\n        else:\n            poligono = &#x5B;todasx,todasy]\n        resultado = {'baricentro': baricentro,\n                     'barerror'  : barerror,\n                     'poligono'  : poligono,\n                     'nocruzaen' : vertices&#x5B;i] }\n\n\n    return(resultado)\n<\/pre><\/div>","protected":false},"excerpt":{"rendered":"<p>El archivo contiene un grupo de&nbsp; funciones usadas para procesar los datos de este prototipo, se separaron del bloque principal de instrucciones con&nbsp; el objetivo de simplificar el desarrollo del las actividades principales. Recuerde disponer de este archivo en la misma carpeta que el algoritmo que invoca a la librer\u00eda. archivo de librer\u00eda: girni_lora_libreria datos [&hellip;]<\/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":[20777],"class_list":["post-2719","post","type-post","status-publish","format-standard","hentry","category-lorawan-localizacion-rssi","tag-python"],"_links":{"self":[{"href":"https:\/\/blog.espol.edu.ec\/girni\/wp-json\/wp\/v2\/posts\/2719","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=2719"}],"version-history":[{"count":26,"href":"https:\/\/blog.espol.edu.ec\/girni\/wp-json\/wp\/v2\/posts\/2719\/revisions"}],"predecessor-version":[{"id":4834,"href":"https:\/\/blog.espol.edu.ec\/girni\/wp-json\/wp\/v2\/posts\/2719\/revisions\/4834"}],"wp:attachment":[{"href":"https:\/\/blog.espol.edu.ec\/girni\/wp-json\/wp\/v2\/media?parent=2719"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.espol.edu.ec\/girni\/wp-json\/wp\/v2\/categories?post=2719"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.espol.edu.ec\/girni\/wp-json\/wp\/v2\/tags?post=2719"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}