Observar el perfil del terreno en una ruta, y estimar la primera zona de Fresnel permite revisar algunas situaciones donde se presente bloqueo, dispersión, difracción de la señal en el enlace.
Los datos del perfil se obtienen del proceso anterior desde el siguiente archivo:
En el proceso se añade al perfil la altura de las antenas en los dispositivos, la altura de la vegetación promedio y se genera la gráfica mostrada.
punto,altitud,altitud_gps,dist_Gw03,latitud,longitud,utm_este,utm_norte,utm_zLetra,utm_zNum,vegetacion,alt_antena Gw03,65.0,68.3,0.0,-2.140439491218423,-79.96247385948875,615377.0,9763377.0,M,17,65.0,73.0 LOS01,64.0,66.16,24.74,-2.140222431275481,-79.96252795441376,615371.0,9763401.0,M,17,64.0,65.0 LOS02,59.0,66.16,75.93,-2.139770213855424,-79.96262716484223,615360.0,9763451.0,M,17,59.0,60.0 LOS03,58.0,66.16,99.64,-2.139553123308579,-79.96263630222327,615359.0,9763475.0,M,17,59.5,59.0 ...
El resultado se guarda en un archivo.csv y en la gráfica.png
Instrucciones en Python
# Procesa perfiles y Zona Fresnel # girni-fiec-espol Revisión: 20220724 # http://blog.espol.edu.ec/girni/ import numpy as np import pandas as pd import matplotlib.pyplot as plt import os # INGRESO archivocsv = 'Granja2021_LOS.csv' carp_coord = 'coordenadas' carpeta_rsm = 'resultado_LOS' LineaObs = 'LOS' segmentos = ['Gw03','LOS'] # Fresnel, selecciona dispositivo analiza_punto = 'LOS09' # vegetacion plantas_entre = [0, 0] #[90,250] plantas_altura = 1.6 # antenas alturaGw = 8 alturapunto = 1 # parametros Fresnel nFres = 1 freq = 915 # 915MHz # Gráficas muestras = 41 # resolución guarda = True # PROCEDIMIENTO procesoCompleto = 0 # ruta de archivo if len(carp_coord)>0: carp_coord = carp_coord+'/' archivo_ruta = carp_coord + archivocsv if os.path.exists(archivo_ruta): puntostodos = pd.read_csv(archivo_ruta, index_col='punto') procesoCompleto = 1 if procesoCompleto == 1: # busca gateway Gw_nombre = ''; for unpunto in puntostodos.index: if unpunto.startswith('Gw'): Gw_nombre = unpunto if len(Gw_nombre)>0: procesoCompleto = 2 if procesoCompleto == 2: #ordena por distancia puntostodos = puntostodos.sort_values(by=['dist_'+Gw_nombre]) puntostodos['enruta']=0 for unpunto in puntostodos.index: for elemento in segmentos: if unpunto.startswith(elemento): puntostodos.loc[[unpunto],['enruta']] = 1 puntos = puntostodos[puntostodos['enruta']==1].copy() procesoCompleto = 3 if procesoCompleto == 3: # busca gateway y ubicación de punto observado i_punto = -1 ; i_Gw=-1 i=0 for unpunto in puntos.index: if unpunto.startswith('Gw'): i_Gw = i if unpunto==analiza_punto: i_punto = i i = i+1 if i_punto>=0 and i_Gw>=0: procesoCompleto = 4 if procesoCompleto ==4: # plantación sector puntos['vegetacion'] = puntos['altitud'] for unpunto in puntos.index: dist_punto = puntos['dist_'+Gw_nombre][unpunto] envegetacion = (dist_punto>=np.min(plantas_entre)) envegetacion = envegetacion and (dist_punto<=np.max(plantas_entre)) if envegetacion: puntos.at[unpunto,'vegetacion'] = puntos['altitud'][unpunto] + plantas_altura # añade alturas de antenas puntos['alt_antena'] = puntos['altitud'] + alturapunto puntos.at[Gw_nombre,'alt_antena'] = puntos['altitud'][Gw_nombre] + alturaGw procesoCompleto = 5 if procesoCompleto == 5: # lambda Fresnel lamb = 300/freq #300e6(m/s)/(freq*1e6) # Zona de Fresnel xi = puntos['dist_'+Gw_nombre] yi_ant = puntos['alt_antena'] if i_punto>0: # linea directa dy = yi_ant[i_punto]-yi_ant[i_Gw] dx = xi[i_punto]-xi[i_Gw] m = dy/dx alpha = np.arctan(m) yi_f = lambda x: m*x + yi_ant[i_Gw] xi_D = np.linspace(xi[i_Gw],xi[i_punto], muestras) yi_D = yi_f(xi_D) dist_D = np.sqrt(dx**2+dy**2) # zona Fresnel 1 F1_up = np.zeros(len(xi_D)) F1_down = np.zeros(len(xi_D)) for i in range(0,len(xi_D),1): d1 = xi_D[i]/np.cos(alpha) d2 = dist_D-d1 F1 = np.sqrt(np.abs(nFres*lamb*d1*d2)/(d1+d2)) xiu = xi_D[i]-F1*np.sin(np.abs(alpha)) d1_u = xiu d2_u = dist_D-d1_u xid = xi_D[i]+F1*np.sin(np.abs(alpha)) d1_d = xid d2_d = dist_D-d1_d # Fresnel, formula Fup = np.sqrt(np.abs(nFres*lamb*d1_u*d2_u)/(d1_u+d2_u)) Fdown = np.sqrt(np.abs(nFres*lamb*d1_d*d2_d)/(d1_d+d2_d)) # Linea directa +/- Fresnel F1_up[i] = yi_D[i] + Fup*np.cos(alpha) F1_down[i] = yi_D[i] - Fdown*np.cos(alpha) procesoCompleto = 6 # SALIDA if procesoCompleto == 6: print(puntos) # guarda el reporte en csv unreporte = carpeta_rsm+'/perfil_'+LineaObs+'.csv' if os.path.exists(carpeta_rsm): puntos.to_csv(unreporte) else: print('no existe carpeta:',carpeta_rsm) else: print('proceso completado hasta:', procesoCompleto) print('Revisar errores en proceso:', procesoCompleto+1) print(' Procesos:') print('1: abrir archivo de datos ',archivocsv ) print('2: encontrar gateway con nombre Gw##') print('3: ordenar tabla por distancias al gateway') print('4: encontrar punto a analizar:',analiza_punto) print('5: añadir altura de antenas y plantas') print('6: calcular zona de fresnel') if procesoCompleto == 6: # GRAFICA figura,(grafica1,grafica2) = plt.subplots(2,1) # vegetacion con_veget = np.array(puntos['vegetacion']-puntos['altitud']) xiv = np.array(puntos['dist_'+Gw_nombre])[con_veget>0] perfil = np.array(puntos['altitud'])[con_veget>0] vegetacion = np.array(puntos['vegetacion'])[con_veget>0] grafica1.fill_between(xiv,perfil,vegetacion, color='lightgreen') # perfil grafica1.plot(puntos['dist_'+Gw_nombre], puntos['altitud'],label='Perfil', color='brown') # antenas grafica1.scatter(puntos['dist_'+Gw_nombre], puntos['alt_antena'], color='blue') # etiquetas y lineas enlace xigw = puntos['dist_'+Gw_nombre][Gw_nombre] yigw = puntos['alt_antena'][Gw_nombre] for unpunto in puntos.index: xip = puntos['dist_'+Gw_nombre][unpunto] yip = puntos['alt_antena'][unpunto] grafica1.annotate(unpunto,(xip,yip), rotation=45) grafica1.plot((xigw,xip),(yigw,yip), color = 'green', linestyle='dotted') untitulo = 'Ruta: '+LineaObs untitulo = untitulo + ', Antena: Gw '+str(alturaGw) untitulo = untitulo + 'm Dispositivo '+str(alturapunto) untitulo = untitulo + 'm' grafica1.set_title(untitulo) grafica1.set_ylabel('altura') grafica1.legend() grafica1.grid(True,linestyle='dotted', axis='x',which='both') # plt.axis('equal') grafica2.fill_between(xiv,perfil,vegetacion, color='lightgreen') # perfil grafica2.plot(puntos['dist_'+Gw_nombre], puntos['altitud'], color='brown') # antenas grafica2.scatter(puntos['dist_'+Gw_nombre], puntos['alt_antena'], color='blue') # etiquetas y lineas enlace xigw = puntos['dist_'+Gw_nombre][Gw_nombre] yigw = puntos['alt_antena'][Gw_nombre] for unpunto in puntos.index: if unpunto in [Gw_nombre, analiza_punto]: xip = puntos['dist_'+Gw_nombre][unpunto] yip = puntos['alt_antena'][unpunto] grafica2.annotate(unpunto,(xip,yip), rotation=45) if i_punto>0: # Fresnel grafica2.plot(xi_D,yi_D, label='linea enlace', color='orange', linestyle = 'dashed') grafica2.plot(xi_D,F1_down, label='Fresnel1',color='orange') grafica2.plot(xi_D,F1_up, color='orange') grafica2.set_xlabel('distancia') grafica2.set_ylabel('altura') grafica2.legend() grafica2.grid(True,linestyle='dotted', axis='x',which='both') # plt.axis('equal') unarchivo = carpeta_rsm+'/perfil_'+LineaObs+'.png' if (guarda==True) and os.path.exists(carpeta_rsm): plt.savefig(unarchivo) plt.show()
Referencia: https://es.wikipedia.org/wiki/Zona_de_Fresnel