rmayormartins commited on
Commit
5c35a76
·
1 Parent(s): 894b4f1

Subindo arquivos

Browse files
Files changed (3) hide show
  1. README.md +51 -6
  2. app.py +205 -0
  3. requirements.txt +6 -0
README.md CHANGED
@@ -1,13 +1,58 @@
1
  ---
2
- title: Rf Radioenlace
3
- emoji: 🦀
4
- colorFrom: green
5
- colorTo: indigo
6
  sdk: gradio
7
- sdk_version: 4.40.0
8
  app_file: app.py
9
  pinned: false
10
  license: ecl-2.0
11
  ---
12
 
13
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
+ title: Rf-Radioenlace
3
+ emoji: 📡〰️〰️📡
4
+ colorFrom: blue
5
+ colorTo: cyan
6
  sdk: gradio
7
+ sdk_version: 4.12.0
8
  app_file: app.py
9
  pinned: false
10
  license: ecl-2.0
11
  ---
12
 
13
+ ## Informação
14
+
15
+ Este projeto permite calcular a linha de visada e perda de propagação entre dois pontos, além de fornecer o Link Budget e os diagramas de Fresnel. Os usuários podem interagir com um mapa, ajustar as coordenadas (manualmente) dos sites e visualizar os resultados dos cálculos.
16
+
17
+ ## Modelos de Propagação
18
+
19
+ **Okumura-Hata-Davidson:**
20
+ Este modelo é uma extensão do modelo Okumura-Hata, desenvolvido principalmente para ambientes urbanos. Ele não é especificamente projetado para condições de linha de visada e é mais adequado para predições em macrocélulas com distâncias acima de 1 km. Portanto, não é a melhor escolha para cenários LOS.
21
+
22
+ **ITU-R P.1546:**
23
+ Este modelo é destinado a predições ponto-área para serviços terrestres na faixa de frequência de 30 MHz a 4000 MHz. Embora possa ser usado em várias condições, incluindo percursos sobre terra e mar, ele não é otimizado especificamente para condições de linha de visada.
24
+
25
+ **ITU-R 525/526:**
26
+ - **ITU-R P.525** fornece cálculos de atenuação em espaço livre, aplicáveis em condições de linha de visada.
27
+ - **ITU-R P.526** trata da propagação por difração, relevante quando há obstruções no caminho (modelo Deygout).
28
+
29
+ O ITU-R P.525 é mais apropriado para condições LOS.
30
+
31
+ **Longley-Rice (ITM - Irregular Terrain Model):**
32
+ Este modelo pode ser aplicado a uma variedade de problemas de engenharia e leva em conta características do terreno. Embora possa ser usado em condições LOS, ele é mais conhecido por sua capacidade de modelar propagação em terrenos irregulares.
33
+
34
+ ## Referências Teóricas
35
+
36
+ [1] Botelho, Alberto Leonardo Penteado; 2019. Propagation Models Comparison by Propagation Features. SET INTERNATIONAL JOURNAL OF BROADCAST ENGINEERING. ISSN Print: 2446-9246 ISSN Online: 2446-9432. doi: 10.18580/setijbe.2019.8. Web Link: [http://dx.doi.org/10.18580/setijbe.2019.8](http://dx.doi.org/10.18580/setijbe.2019.8) [Link](https://www.set.org.br/ijbe/ed5/artigo8.pdf)
37
+
38
+ [2] Fratu, Octavia, Martian, Alexandru, Lazaridis, Pavlos, Zaharis, Zaharias D. and Kasampalis, Stylianos (2015) Comparative study of Radio Mobile and ICS Telecom propagation prediction models for DVB-T. In: IEEE BMSB 2015 International Conference, 17th - 19th June 2015, Ghent, Belgium [Link](https://eprints.hud.ac.uk/id/eprint/25670/1/MM-15-102.pdf)
39
+
40
+ ## A fazer
41
+ - Capturar automaticamente as coordenadas movendo os marcadores
42
+ - Verificar modelos de propagação e cálculo
43
+ - Verificar outros cálculos e diagramas úteis
44
+
45
+ ## Informação adicional
46
+
47
+ - Developed by Ramon Mayor Martins, Ph.D. (2024)
48
+ - E-mail: rmayormartins at: gmail.com
49
+ - Homepage: [https://rmayormartins.github.io/](https://rmayormartins.github.io/)
50
+ - Twitter: [@rmayormartins](https://twitter.com/rmayormartins)
51
+ - GitHub: [https://github.com/rmayormartins](https://github.com/rmayormartins)
52
+
53
+ Check out the configuration reference at [https://huggingface.co/docs/hub/spaces-config-reference](https://huggingface.co/docs/hub/spaces-config-reference)
54
+
55
+ ## Agradecimento especial
56
+
57
+ Instituto Federal de Santa Catarina, Câmpus São José, Área de Telecomunicações [https://ifsc.edu.br/](https://ifsc.edu.br/)
58
+ A futura Engenheira de Telecomunicações, Jéssica Gomes Carrico
app.py ADDED
@@ -0,0 +1,205 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import folium
3
+ from geopy.distance import geodesic
4
+ import numpy as np
5
+ import matplotlib.pyplot as plt
6
+ import matplotlib.figure as Figure
7
+ from IPython.display import display, Javascript
8
+
9
+ #
10
+ def calculate_line_of_sight(site1, site2):
11
+ distance = geodesic(site1[:2], site2[:2]).km
12
+ return distance
13
+
14
+ #
15
+ def calculate_propagation_loss(distance, frequency, model):
16
+ if model == "Okumura-Hata-Davidson":
17
+ loss = 69.55 + 26.16 * np.log10(frequency) - 13.82 * np.log10(30) + (44.9 - 6.55 * np.log10(30)) * np.log10(distance)
18
+ elif model == "ITU-R P.1546":
19
+ loss = 20 * np.log10(distance) + 20 * np.log10(frequency) + 92.45
20
+ elif model == "ITU-R 525/526":
21
+ loss = 20 * np.log10(distance * 1e3) + 20 * np.log10(frequency) + 92.45
22
+ elif model == "Longley Rice":
23
+ loss = 32.45 + 20 * np.log10(distance) + 20 * np.log10(frequency)
24
+ else:
25
+ loss = None
26
+ return loss
27
+
28
+ #
29
+ def calculate_link_budget(tx_power, rx_sensitivity, propagation_loss):
30
+ return tx_power - propagation_loss - rx_sensitivity
31
+
32
+ #
33
+ def create_map():
34
+ m = folium.Map(location=[-27.595, -48.558], zoom_start=15, width='100%', height='400px')
35
+ site1 = folium.Marker(location=[-27.5968, -48.5686], tooltip='Site 1', draggable=True, icon=folium.Icon(color='red'))
36
+ site2 = folium.Marker(location=[-27.5970, -48.5613], tooltip='Site 2', draggable=True, icon=folium.Icon(color='blue'))
37
+ site1.add_to(m)
38
+ site2.add_to(m)
39
+ folium.LatLngPopup().add_to(m)
40
+ return m._repr_html_()
41
+
42
+ #
43
+ def draw_fresnel(site1, site2, distance):
44
+ frequency = 2400 #
45
+ wavelength = 300 / frequency #
46
+ d1 = np.linspace(0, distance, 500)
47
+ r1 = np.sqrt((wavelength * d1 * (distance - d1)) / distance)
48
+ r2 = np.sqrt((2 * wavelength * d1 * (distance - d1)) / distance)
49
+ r3 = np.sqrt((3 * wavelength * d1 * (distance - d1)) / distance)
50
+ r4 = np.sqrt((4 * wavelength * d1 * (distance - d1)) / distance)
51
+
52
+ fig, ax = plt.subplots()
53
+ ax.plot(d1, r1, label='1ª Zona de Fresnel')
54
+ ax.plot(d1, r2, label='2ª Zona de Fresnel', linestyle='--')
55
+ ax.plot(d1, r3, label='3ª Zona de Fresnel', linestyle=':')
56
+ ax.plot(d1, r4, label='4ª Zona de Fresnel', linestyle='-.')
57
+ ax.fill_between(d1, 0, r1, color='lightblue', alpha=0.5)
58
+ ax.set_title('Diagrama de Fresnel')
59
+ ax.set_xlabel('Distância (km)')
60
+ ax.set_ylabel('Raio da Zona de Fresnel (m)')
61
+ ax.legend()
62
+ ax.grid(True)
63
+ return fig
64
+
65
+ #
66
+ def draw_line_of_sight(site1, site2, distance, site1_height, site2_height):
67
+ d1 = np.linspace(0, distance, 500)
68
+
69
+ #
70
+ los = np.linspace(site1_height, site2_height, 500)
71
+
72
+ fig, ax = plt.subplots()
73
+ ax.plot(d1, los, label='Linha de Visada', color='magenta')
74
+ ax.set_title('Linha de Visada')
75
+ ax.set_xlabel('Distância (km)')
76
+ ax.set_ylabel('Elevação (m)')
77
+ ax.legend()
78
+ ax.grid(True)
79
+ return fig
80
+
81
+ #
82
+ def interactive_propagation_map(site1_coords, site2_coords, site1_height, site2_height, frequency, model, tx_power1, rx_sensitivity1, tx_power2, rx_sensitivity2):
83
+ try:
84
+ site1_lat, site1_lon = map(float, site1_coords.split(','))
85
+ site2_lat, site2_lon = map(float, site2_coords.split(','))
86
+ except ValueError:
87
+ return "Erro: Coordenadas inválidas.", "Erro: Coordenadas inválidas.", "Erro: Coordenadas inválidas.", None, None, None
88
+
89
+ site1 = (site1_lat, site1_lon, site1_height)
90
+ site2 = (site2_lat, site2_lon, site2_height)
91
+
92
+ #
93
+ distance = calculate_line_of_sight(site1, site2)
94
+
95
+ #
96
+ propagation_loss = calculate_propagation_loss(distance, frequency, model)
97
+
98
+ #
99
+ link_budget1 = calculate_link_budget(tx_power1, rx_sensitivity2, propagation_loss)
100
+ link_budget2 = calculate_link_budget(tx_power2, rx_sensitivity1, propagation_loss)
101
+
102
+ #
103
+ m = folium.Map(location=[(site1_lat + site2_lat) / 2, (site1_lon + site2_lon) / 2], zoom_start=15, width='100%', height='400px')
104
+ folium.Marker(location=[site1_lat, site1_lon], popup='Site 1 Coordenadas: {:.6f}, {:.6f}'.format(site1_lat, site1_lon), tooltip='Site 1', draggable=True, icon=folium.Icon(color='red')).add_to(m)
105
+ folium.Marker(location=[site2_lat, site2_lon], popup='Site 2 Coordenadas: {:.6f}, {:.6f}'.format(site2_lat, site2_lon), tooltip='Site 2', draggable=True, icon=folium.Icon(color='blue')).add_to(m)
106
+ folium.PolyLine(locations=[[site1_lat, site1_lon], [site2_lat, site2_lon]], color='blue', weight=2.5).add_to(m)
107
+ m.add_child(folium.LatLngPopup())
108
+
109
+ map_html = m._repr_html_()
110
+
111
+ #
112
+ fresnel_plot = draw_fresnel(site1, site2, distance)
113
+
114
+ #
115
+ los_plot = draw_line_of_sight(site1, site2, distance, site1_height, site2_height)
116
+
117
+ return map_html, f"Distância: {distance:.2f} km", f"Perda de propagação: {propagation_loss:.2f} dB", fresnel_plot, f"Orçamento de enlace (Site 1 -> Site 2): {link_budget1:.2f} dB", f"Orçamento de enlace (Site 2 -> Site 1): {link_budget2:.2f} dB", los_plot
118
+
119
+ with gr.Blocks() as interface:
120
+ with gr.Row():
121
+ with gr.Column(scale=1):
122
+ gr.Markdown("### Mapa")
123
+ map_display = gr.HTML(create_map(), label="Clique no mapa para marcar os sites e arraste os marcadores para ajustar a posição. Copie e cole as coordenadas nos campos abaixo.")
124
+ with gr.Column(scale=1):
125
+ gr.Markdown("### Coordenadas")
126
+ site1_coords = gr.Textbox(label="Coordenadas do Site 1", placeholder="-27.5968, -48.5686", value="-27.5968, -48.5686")
127
+ site2_coords = gr.Textbox(label="Coordenadas do Site 2", placeholder="-27.5970, -48.5613", value="-27.5970, -48.5613")
128
+ site1_height = gr.Number(label="Altura do Site 1 (m)", value=30)
129
+ site2_height = gr.Number(label="Altura do Site 2 (m)", value=30)
130
+
131
+ with gr.Row():
132
+ with gr.Column(scale=1):
133
+ gr.Markdown("### Modelo de Propagação")
134
+ frequency = gr.Slider(minimum=30, maximum=3000, label="Frequência (MHz)")
135
+ model = gr.Radio(choices=["Okumura-Hata-Davidson", "ITU-R P.1546", "ITU-R 525/526", "Longley Rice"], label="Modelo de Propagação")
136
+ with gr.Column(scale=1):
137
+ gr.Markdown("### Link Budget")
138
+ tx_power1 = gr.Number(label="Potência Tx do Site 1 (dBm)", value=20)
139
+ rx_sensitivity1 = gr.Number(label="Sensibilidade Rx do Site 1 (dBm)", value=-90)
140
+ tx_power2 = gr.Number(label="Potência Tx do Site 2 (dBm)", value=20)
141
+ rx_sensitivity2 = gr.Number(label="Sensibilidade Rx do Site 2 (dBm)", value=-90)
142
+
143
+ with gr.Row():
144
+ calculate_button = gr.Button("Calcular")
145
+
146
+ gr.Markdown("### Resultados:")
147
+
148
+ with gr.Row():
149
+ with gr.Column(scale=1):
150
+ distance_output = gr.Textbox(label="Distância", interactive=False)
151
+ loss_output = gr.Textbox(label="Perda de Propagação", interactive=False)
152
+ with gr.Column(scale=1):
153
+ link_budget1_output = gr.Textbox(label="Link Budget (Site 1 -> Site 2)", interactive=False)
154
+ link_budget2_output = gr.Textbox(label="Link Budget (Site 2 -> Site 1)", interactive=False)
155
+
156
+ with gr.Row():
157
+ with gr.Column(scale=1):
158
+ fresnel_plot = gr.Plot(label="Diagrama de Fresnel")
159
+ with gr.Column(scale=1):
160
+ terrain_plot = gr.Plot(label="Linha de Visada")
161
+
162
+ calculate_button.click(fn=interactive_propagation_map, inputs=[site1_coords, site2_coords, site1_height, site2_height, frequency, model, tx_power1, rx_sensitivity1, tx_power2, rx_sensitivity2], outputs=[map_display, distance_output, loss_output, fresnel_plot, link_budget1_output, link_budget2_output, terrain_plot])
163
+
164
+ #
165
+ interface.launch(share=True)
166
+
167
+ #Campo do Javascript (arrumar!)
168
+ display(Javascript('''
169
+ document.addEventListener('DOMContentLoaded', function() {
170
+ var iframe = document.querySelector('iframe');
171
+ iframe.addEventListener('load', function() {
172
+ var iframeDocument = iframe.contentDocument || iframe.contentWindow.document;
173
+
174
+ function addDragEndListener(marker, siteLabel) {
175
+ marker.on('moveend', function(e) {
176
+ var lat = e.target.getLatLng().lat.toFixed(6);
177
+ var lon = e.target.getLatLng().lng.toFixed(6);
178
+ var popupContent = siteLabel + ' Coordenadas: ' + lat + ',' + lon;
179
+ marker.bindPopup(popupContent).openPopup();
180
+ console.log(popupContent);
181
+ });
182
+ // Atualizar o popup imediatamente com a posição inicial
183
+ var lat = marker.getLatLng().lat.toFixed(6);
184
+ var lon = marker.getLatLng().lng.toFixed(6);
185
+ var popupContent = siteLabel + ' Coordenadas: ' + lat + ',' + lon;
186
+ marker.bindPopup(popupContent).openPopup();
187
+ console.log(popupContent);
188
+ }
189
+
190
+ var markers = iframeDocument.querySelectorAll('.leaflet-marker-icon');
191
+ console.log('Markers found:', markers.length);
192
+ var siteLabels = ['Site 1', 'Site 2'];
193
+
194
+ markers.forEach((marker, index) => {
195
+ console.log('Adding event listener to marker', index);
196
+ addDragEndListener(marker, siteLabels[index]);
197
+ });
198
+ });
199
+ });
200
+ '''))
201
+
202
+ #Pra manter celula ativa.
203
+ import time
204
+ while True:
205
+ time.sleep(1)
requirements.txt ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ gradio
2
+ folium==0.12.1
3
+ geopy==2.2.0
4
+ numpy==1.21.2
5
+ matplotlib==3.4.3
6
+