Commit inicial: splat-rs — fork/port a Rust de SPLAT!
Fork de SPLAT! (John A. Magliacane, KD2BD, 2002-2014), bajo GPLv2 heredada del original. El núcleo de cálculo de propagación (ITWOM v3.0, Sid Shumate) se mantiene sin modificar en cpp/itwom3.0.cpp, llamado vía FFI. El resto del pipeline (lectura de formatos SPLAT!, reportes, mapas, KML, gnuplot) se reescribió en Rust, con paralelización nativa vía rayon reemplazando el paralelismo por múltiples procesos del original. Validado contra el corpus golden de SPLAT! con drift < 0.02 dB en cálculos ITWOM.
This commit is contained in:
@@ -0,0 +1,565 @@
|
||||
# splat-rs — Manual del Usuario
|
||||
|
||||
**splat-rs** es un port en Rust de SPLAT! (Signal Propagation, Loss, And Terrain
|
||||
analysis tool) con paralelización nativa, salidas en español y una nueva
|
||||
funcionalidad de tabla de intensidad de campo.
|
||||
|
||||
Compatible con los formatos `.qth`, `.lrp`, `.az`, `.el`, `.udt`, `.cities` y
|
||||
`.sdf[.bz2]` del SPLAT! 1.4.x original. Validado contra el corpus golden de
|
||||
SPLAT! con drift inferior a 0.02 dB en cálculos ITWOM.
|
||||
|
||||
---
|
||||
|
||||
## 1. Inicio rápido
|
||||
|
||||
```bash
|
||||
# Análisis de enlace TX → RX
|
||||
splat-rs -t txenlace.qth -r rxenlace.qth -d sdf/
|
||||
|
||||
# Cobertura completa de un sitio
|
||||
splat-rs -t tx_site.qth -d sdf/ -L 10 -R 80
|
||||
|
||||
# Tabla de intensidad de campo (alternativa al script perfiles.sh)
|
||||
splat-rs -t tx_site.qth -d sdf/ --sft atenuaciones.txt --sft-max-km 150
|
||||
```
|
||||
|
||||
Salidas en `--out-dir` (default: directorio actual):
|
||||
|
||||
| Archivo | Cuándo se genera |
|
||||
|---|---|
|
||||
| `<TX>-site_report.txt` | si **no** hay `-r` |
|
||||
| `<TX>-to-<RX>.txt` | si hay `-r` (path report) |
|
||||
| `coverage.ppm`/`.png`/`.kml` | si **no** está `--no-map` |
|
||||
| `<archivo>.txt` + `.csv` | si está `--sft <archivo>` |
|
||||
| `splat.gp` + `*.gp` | si está `-h/-H/-p/-e/-l <archivo>` |
|
||||
|
||||
---
|
||||
|
||||
## 2. Construcción
|
||||
|
||||
```bash
|
||||
cd splat-rs
|
||||
cargo build --release
|
||||
# Binario: ./target/release/splat-rs
|
||||
```
|
||||
|
||||
Requiere:
|
||||
- Rust ≥ 1.80 (probado con 1.92)
|
||||
- `libbz2.so` accesible (sistema o miniconda)
|
||||
- `gnuplot` (opcional, para renderizar los `.gp`)
|
||||
- `convert` de ImageMagick (opcional, para PPM → PNG transparente)
|
||||
|
||||
Para ejecutar con libbz2 desde miniconda:
|
||||
```bash
|
||||
LD_LIBRARY_PATH=$HOME/miniconda3/lib ./target/release/splat-rs ...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Formatos de entrada
|
||||
|
||||
### `.qth` — Sitio (TX o RX)
|
||||
|
||||
Cuatro líneas:
|
||||
```
|
||||
Nombre del sitio
|
||||
-1 -01 -23.54 ; latitud (DMS o decimal)
|
||||
79 27 31.21 ; longitud (DMS o decimal, positiva = oeste)
|
||||
14 m ; altura antena AGL (metros con 'm', si no = pies)
|
||||
```
|
||||
|
||||
### `.lrp` — Parámetros Longley-Rice
|
||||
|
||||
Una constante numérica por línea, comentarios con `;`:
|
||||
```
|
||||
15.000 ; Constante dieléctrica de la Tierra
|
||||
0.005 ; Conductividad (S/m)
|
||||
301.00 ; Refracción atmosférica (N-units)
|
||||
426 ; Frecuencia (MHz)
|
||||
5 ; Clima radioeléctrico (1-7)
|
||||
1 ; Polarización (0=H, 1=V)
|
||||
0.50 ; Fracción de situaciones
|
||||
0.50 ; Fracción de tiempo
|
||||
2000 ; ERP en watts (línea 9, opcional)
|
||||
```
|
||||
|
||||
Climas: `1`=Ecuatorial, `2`=Subtropical Continental, `3`=Subtropical Marítimo,
|
||||
`4`=Desértico, `5`=Templado Continental, `6`=Templado Marítimo (tierra),
|
||||
`7`=Templado Marítimo (mar).
|
||||
|
||||
### `.az` — Patrón azimutal de antena (autodetectado al lado del `.qth` del TX)
|
||||
|
||||
```
|
||||
345.0 ; rotación en grados (clockwise desde el norte verdadero)
|
||||
0 0.49 ; az amplitud (0..1)
|
||||
1 0.50
|
||||
2 0.51
|
||||
...
|
||||
```
|
||||
|
||||
### `.el` — Patrón vertical de antena
|
||||
|
||||
```
|
||||
8.0 345.0 ; tilt mecánico, azimuth del tilt
|
||||
-10 0.04
|
||||
-9.5 0.06
|
||||
...
|
||||
```
|
||||
|
||||
Usa `--no-pattern` para ignorar archivos `.az`/`.el` aun si existen.
|
||||
|
||||
### `.udt` — Terreno definido por usuario
|
||||
|
||||
CSV de obstáculos puntuales:
|
||||
```
|
||||
; Edificios y antenas en Quevedo
|
||||
-1.0250, 79.4587, 50 m
|
||||
-1.0260, 79.4590, 80 m
|
||||
```
|
||||
|
||||
Cada feature se "pinta" en un radio de ~5 píxeles (~465 m a 1200 ppd) sobre el DEM.
|
||||
El máximo entre la base SDF y el UDT prevalece.
|
||||
|
||||
### `.cities` o `-s <file>` — Sitios de interés
|
||||
|
||||
CSV `name, lat, lon`:
|
||||
```
|
||||
Quito, -0.18, 78.47
|
||||
Guayaquil, -2 10 0, 79 53 0
|
||||
```
|
||||
|
||||
### `.sdf[.bz2]` — Datos de elevación digital
|
||||
|
||||
Archivos SPLAT! estándar. Nombres `minlat:maxlat:minlon:maxlon.sdf.bz2` cubriendo
|
||||
1° × 1° cada uno. Carpeta vía `-d sdf/`. Soporta tanto 3 arc-sec (1200 ppd) como
|
||||
1 arc-sec (3600 ppd, modo HD).
|
||||
|
||||
---
|
||||
|
||||
## 4. Referencia de banderas
|
||||
|
||||
### Entrada
|
||||
| Bandera | Descripción |
|
||||
|---|---|
|
||||
| `-t, --tx FILE` | TX `.qth` (obligatorio) |
|
||||
| `-r, --rx FILE` | RX `.qth` (opcional; si está → path report; si no → site report) |
|
||||
| `-d, --sdf DIR` | Directorio con tiles `.sdf[.bz2]` (obligatorio) |
|
||||
| `--lrp FILE` | `.lrp` (default: `splat.lrp` junto al TX) |
|
||||
| `--erp WATTS` | Override del ERP del `.lrp` |
|
||||
| `-s, --cities FILE` | Archivo de sitios; repetible |
|
||||
| `--udt FILE` | Terreno definido por usuario; repetible |
|
||||
|
||||
### Modelo y geometría
|
||||
| Bandera | Descripción | Default |
|
||||
|---|---|---|
|
||||
| `--olditm` | Usa Longley-Rice clásico en vez de ITWOM v3.0 | off (ITWOM) |
|
||||
| `-L, --rx-altitude-m M` | Altura RX AGL para sweep de cobertura | 10 m |
|
||||
| `-R, --range-km KM` | Radio de cobertura | 40 km |
|
||||
| `--metric` | Unidades métricas en reportes | true |
|
||||
| `--gc M` | Altura de clutter (obstáculos urbanos) | 0 |
|
||||
| `--fz F` | Clearance Fresnel (`F` ∈ [0,1]) | 0.6 (60%) |
|
||||
| `--no-pattern` | Ignora `.az`/`.el` autodetectados | off |
|
||||
|
||||
### Salidas — gráficas (cada una toma un nombre de archivo)
|
||||
| Bandera | Genera | Equivale a SPLAT |
|
||||
|---|---|---|
|
||||
| `-h FILE` | Gráfico de alturas (perfil + LOS + curvatura + Fresnel) | `-h` |
|
||||
| `-H FILE` | Versión normalizada del anterior | `-H` |
|
||||
| `-p FILE` | Perfil del terreno (elevación vs distancia) | `-p` |
|
||||
| `-e FILE` | Perfil de ángulo de elevación | `-e` |
|
||||
| `-l FILE` | Gráfico de pérdida del trayecto | `-l` |
|
||||
| `--plot-format FMT` | Tipo de salida gnuplot (png, svg, ps...) | — |
|
||||
|
||||
> **Convención `-h`/`-H`**: el plot de alturas usa el marco de **tierra
|
||||
> aplanada (4/3)**: el perfil del terreno se eleva por
|
||||
> `d·(D-d)/(2·R')` para que la LOS sea una recta y la zona de Fresnel se
|
||||
> dibuje como su geometría natural debajo. Si el terreno aparente toca la
|
||||
> Fresnel en el gráfico, es una obstrucción real — convención estándar en
|
||||
> ingeniería de RF (ATDI, Pathloss, etc.). Además se superpone una
|
||||
> **referencia de curvatura** (parábola en el mismo eje Y, anclada al
|
||||
> fondo del plot) cuyo peak coincide con el terreno más bajo y endpoints
|
||||
> sit en `min(terreno)−max_drop`. La magnitud del hump es D²/(8·R'):
|
||||
> ~150 m para D=100 km, ~180 m para D=110 km. Si quieres ver el perfil
|
||||
> geográfico crudo (sin corrección de curvatura), usa `-p`.
|
||||
|
||||
> **Auto-render**: si `gnuplot` está en el PATH, splat-rs lo invoca automáticamente
|
||||
> tras escribir los `.gp` y produce directamente el PNG/SVG/PS. Cada flag escribe
|
||||
> a su propio subdirectorio (`h-<stem>/`, `p-<stem>/`, etc.) para que no colisionen
|
||||
> al pedir varios plots a la vez:
|
||||
>
|
||||
> ```bash
|
||||
> splat-rs -t tx.qth -r rx.qth -d sdf/ --no-map \
|
||||
> -h alturas.png -p terreno.png -e elevacion.png
|
||||
> # → out_dir/h-alturas/alturas.png
|
||||
> # → out_dir/p-terreno/terreno.png
|
||||
> # → out_dir/e-elevacion/elevacion.png
|
||||
> ```
|
||||
>
|
||||
> Si no hay `gnuplot`, splat-rs deja los `.gp` para que el usuario los renderice
|
||||
> manualmente (`cd subdir && gnuplot splat.gp`).
|
||||
|
||||
### Salidas — mapa de cobertura (sweep 360°)
|
||||
| Bandera | Descripción |
|
||||
|---|---|
|
||||
| `-c, --los-coverage` | Modo LOS (sin ITWOM, ~75× más rápido) |
|
||||
| `--no-map` | No generar mapa (solo reporte) |
|
||||
| `--no-kml` | No generar KML |
|
||||
| `--no-link-line` | Omitir línea TX→RX en KML |
|
||||
| `--max-loss-db DB` | Umbral de pérdida (mayor → blanco transparente). FM: 110-120, UHF: 125-135, microondas: 160+ |
|
||||
| `--min-loss-db DB` | Pérdida mínima (mapea al color más fuerte) |
|
||||
|
||||
> **Leyenda automática**: cada vez que se genera un mapa de cobertura, splat-rs
|
||||
> también escribe `legend.svg` (con texto) y `legend.ppm` (barra de colores
|
||||
> sola) que muestran el mapeo color↔pérdida↔intensidad de campo del run.
|
||||
|
||||
### Tabla de intensidad de campo (`-sft`)
|
||||
| Bandera | Descripción |
|
||||
|---|---|
|
||||
| `--sft FILE` | Genera tabla en `<FILE>` (texto) y `<FILE>.csv` |
|
||||
| `--sft-max-km KM` | Extiende a `KM` (default 90; pasos de 10 km después de 90) |
|
||||
| `--sft-azimuths LISTA` | Azimuts custom CSV (default: 0,30,60,...,330) |
|
||||
| `--sft-distances LISTA` | Distancias custom CSV (override total) |
|
||||
|
||||
### Sistema
|
||||
| Bandera | Descripción | Default |
|
||||
|---|---|---|
|
||||
| `--threads N` | Hilos para rayon (0 = todos los cores) | 0 |
|
||||
| `--out-dir DIR` | Directorio de salida | `.` |
|
||||
| `--help` | Ayuda completa | — |
|
||||
| `-V, --version` | Versión | — |
|
||||
|
||||
---
|
||||
|
||||
## 5. Flujos de trabajo comunes
|
||||
|
||||
### 5.1 Análisis rápido de sitio (qué tan elevada está la antena vs el terreno)
|
||||
|
||||
```bash
|
||||
splat-rs -t mi_sitio.qth -d sdf/ --no-map
|
||||
```
|
||||
|
||||
Genera `mi_sitio-site_report.txt` con: ubicación, elevación del terreno,
|
||||
altura de la antena, **HAAT** (altura sobre terreno promedio según FCC
|
||||
Part 73.313(d)) y promedios de terreno en 8 azimuts cardinales.
|
||||
|
||||
### 5.2 Estudio de enlace punto-a-punto
|
||||
|
||||
```bash
|
||||
splat-rs -t tx.qth -r rx.qth -d sdf/ --no-map -h alturas.png
|
||||
```
|
||||
|
||||
Genera:
|
||||
- Path report en español con pérdida ITWOM, modo de propagación, análisis de
|
||||
obstrucciones y zonas de Fresnel
|
||||
- `alturas.png` (vía `gnuplot splat.gp`) con perfil + LOS + curvatura 4/3 +
|
||||
Fresnel del 60% y 100%
|
||||
|
||||
### 5.3 Mapa de cobertura ITWOM completo (lento pero preciso)
|
||||
|
||||
```bash
|
||||
splat-rs -t tx.qth -d sdf/ -L 10 -R 80 \
|
||||
--max-loss-db 120 \
|
||||
-s ciudades.cities --out-dir cobertura/
|
||||
```
|
||||
|
||||
Genera en `cobertura/`:
|
||||
- `coverage.ppm` (raster PPM puro)
|
||||
- `coverage.png` (con blanco → transparente)
|
||||
- `coverage.kml` (Google Earth con TX, ciudades y línea de enlace)
|
||||
- `<TX>-site_report.txt`
|
||||
|
||||
Tiempo típico: ~2-4 min en 16 cores para 80 km de radio.
|
||||
|
||||
### 5.4 Mapa LOS rápido (bosquejo previo)
|
||||
|
||||
```bash
|
||||
splat-rs -t tx.qth -d sdf/ -L 10 -R 80 -c
|
||||
```
|
||||
|
||||
Mismo formato de salidas pero **~75× más rápido** (sin llamadas a ITWOM).
|
||||
Útil para identificar primero qué zonas tienen línea de vista antes de hacer
|
||||
el sweep ITWOM completo. Tiempo típico: 1-3 s.
|
||||
|
||||
### 5.5 Tabla de intensidad de campo (alternativa a `perfiles.sh`)
|
||||
|
||||
**Default**: 12 azimuts × 13 distancias (5–40 km en pasos de 5, luego 50/60/70/80/90):
|
||||
```bash
|
||||
splat-rs -t tx.qth -d sdf/ --olditm --no-map --sft atenuaciones.txt
|
||||
```
|
||||
|
||||
**Extendida hasta 150 km**:
|
||||
```bash
|
||||
splat-rs -t tx.qth -d sdf/ --olditm --no-map \
|
||||
--sft atenuaciones.txt --sft-max-km 150
|
||||
```
|
||||
|
||||
**Grid completamente personalizado** (8 cardinales × distancias específicas):
|
||||
```bash
|
||||
splat-rs -t tx.qth -d sdf/ --olditm --no-map \
|
||||
--sft puntos.txt \
|
||||
--sft-azimuths 0,45,90,135,180,225,270,315 \
|
||||
--sft-distances 1,2,5,10,20,50,100,150,200
|
||||
```
|
||||
|
||||
Salida en `atenuaciones.txt`:
|
||||
```
|
||||
# Tabla de intensidad de campo (dBµV/m) — splat-rs
|
||||
# TX: Cerro Cochabamba @ (-1.6986, 79.1072), 91.5 MHz, ERP 2000 W, modelo LongleyRice
|
||||
|
||||
Dist/Az 0° 30° 60° 90° 120° ...
|
||||
5 km 95.08 69.96 43.30 35.89 35.82 ...
|
||||
10 km 24.62 47.60 30.73 33.41 13.03 ...
|
||||
...
|
||||
```
|
||||
|
||||
Y CSV `atenuaciones.csv` para Excel/LibreOffice. Si necesitas decimal coma
|
||||
para `es_EC`:
|
||||
```bash
|
||||
sed 's/\./,/g' atenuaciones.csv > atenuaciones-es.csv
|
||||
```
|
||||
|
||||
Tiempo típico: **<10 ms** por tabla (compute) más 6-7 s de carga SDF (una vez).
|
||||
|
||||
### 5.6 Estudio con patrón de antena directiva
|
||||
|
||||
Si junto al `.qth` del TX están `<base>.az` y `<base>.el`, splat-rs los detecta
|
||||
automáticamente y aplica el patrón en la pérdida y la tabla SFT:
|
||||
|
||||
```bash
|
||||
ls
|
||||
# tx_site.qth tx_site.az tx_site.el splat.lrp
|
||||
|
||||
splat-rs -t tx_site.qth -d sdf/ --sft tabla.txt
|
||||
# stderr: "Patrón de antena cargado (rotación 345.0°, tilt 8.0°)"
|
||||
```
|
||||
|
||||
El reporte incluye `Patrón de antena de TX hacia RX: 0.562 (-5.00 dB)` cuando
|
||||
hay `-r`.
|
||||
|
||||
### 5.7 Override de ERP para análisis A/B
|
||||
|
||||
```bash
|
||||
splat-rs -t tx.qth -r rx.qth -d sdf/ --erp 2000 --no-map
|
||||
splat-rs -t tx.qth -r rx.qth -d sdf/ --erp 5000 --no-map # comparar
|
||||
```
|
||||
|
||||
### 5.8 UDT — terreno con edificios sintéticos
|
||||
|
||||
```bash
|
||||
cat > obstaculos.udt <<EOF
|
||||
; Torre de transmisión vecina
|
||||
-1.0245, 79.4593, 50 m
|
||||
EOF
|
||||
|
||||
splat-rs -t tx.qth -r rx.qth -d sdf/ --udt obstaculos.udt --no-map
|
||||
```
|
||||
|
||||
El reporte detectará obstrucciones en cada UDT y recomendará la altura mínima
|
||||
de antena RX para librar terreno y zonas de Fresnel.
|
||||
|
||||
---
|
||||
|
||||
## 6. Salidas explicadas
|
||||
|
||||
### Path report (`<TX>-to-<RX>.txt`)
|
||||
|
||||
Bloques en orden:
|
||||
1. **Sitio transmisor**: nombre, ubicación DMS, elevación, altura antena, HAAT,
|
||||
distancia, azimut, ángulo elevación al RX
|
||||
2. **Sitio receptor**: idem desde el RX
|
||||
3. **Parámetros del modelo**: dieléctrica, conductividad, refracción, frecuencia,
|
||||
clima, polarización, fracciones, ERP/EIRP (si está en `.lrp`)
|
||||
4. **Resumen del enlace**: pérdida en espacio libre, pérdida ITWOM (o LR),
|
||||
atenuación por terreno, modo de propagación (LDV / horizonte simple /
|
||||
horizonte doble + difracción/troposcatter)
|
||||
5. **Análisis de obstrucciones**: lista de cada punto bloqueante y recomendaciones
|
||||
de altura para librar LOS / 60% Fresnel / Fresnel completa
|
||||
|
||||
### Site report (`<TX>-site_report.txt`)
|
||||
|
||||
Cuando solo se da `-t`. Estructura:
|
||||
- Sitio (DMS), elevación del terreno, altura de la antena
|
||||
- HAAT (altura sobre promedio del terreno)
|
||||
- Promedio del terreno en 8 azimuts (0°, 45°, 90°, ..., 315°) entre 2 y 10 millas
|
||||
|
||||
### Coverage map
|
||||
|
||||
- **`coverage.ppm`**: raster PPM/P6, dimensiones automáticas según los radiales
|
||||
- **`coverage.png`**: misma imagen con `convert -transparent white` si está
|
||||
ImageMagick disponible
|
||||
- **`coverage.kml`**: Google Earth con `GroundOverlay` apuntando al PNG, línea
|
||||
amarilla TX→RX (si hay -r), Placemarks para TX/RX/ciudades
|
||||
- **`legend.svg`**: leyenda con barra de colores y dos ejes:
|
||||
pérdida en dB a la izquierda, intensidad de campo (dBµV/m) a la derecha.
|
||||
Calculada con la frecuencia y ERP del `.lrp`. Renderiza en cualquier navegador
|
||||
o se convierte con `convert legend.svg legend.png`.
|
||||
- **`legend.ppm`**: solo la barra de color (sin texto), 30×280 px. Útil para
|
||||
componer con el mapa via `convert +append coverage.png legend.ppm composite.png`
|
||||
o similar.
|
||||
|
||||
### Tabla SFT
|
||||
|
||||
- **`<archivo>`**: tabla de texto formateada con encabezado descriptivo
|
||||
- **`<archivo>.csv`**: para importar en hojas de cálculo
|
||||
|
||||
### Gráficos gnuplot
|
||||
|
||||
Cada vez que se pide `-h/-H/-p/-e/-l`, se genera un set en el subdirectorio:
|
||||
- `splat.gp`: orquestador (set title/xlabel/ylabel + plot)
|
||||
- `profile.gp`: terreno
|
||||
- `reference.gp`: línea de vista
|
||||
- `curvature.gp`: curvatura 4/3 Tierra
|
||||
- `fresnel.gp`, `fresnel_pt_6.gp`: zonas de Fresnel (cuando aplica)
|
||||
|
||||
Para renderizar: `cd subdir && gnuplot splat.gp` produce el archivo de imagen.
|
||||
|
||||
---
|
||||
|
||||
## 7. Rendimiento
|
||||
|
||||
### Hardware típico (16 cores)
|
||||
|
||||
| Operación | Tiempo |
|
||||
|---|---|
|
||||
| Carga 54 tiles SDF (Ecuador completo) | 6-7 s |
|
||||
| Path report TX↔RX (1 enlace) | <1 s |
|
||||
| Site report (HAAT + 8 radiales) | <1 s |
|
||||
| Tabla SFT 12×13 | 1-2 ms |
|
||||
| Tabla SFT 12×19 (hasta 150 km) | 2-3 ms |
|
||||
| Mapa LOS coverage 80 km | 1-3 s |
|
||||
| Mapa ITWOM coverage 40 km | 1-2 min |
|
||||
| Mapa ITWOM coverage 80 km | 3-5 min |
|
||||
|
||||
Speedup típico paralelo / secuencial: 10-12× (eficiencia 65-75% de los 16 cores).
|
||||
|
||||
### Comparación con SPLAT! original (single-thread)
|
||||
|
||||
| | SPLAT! v1.4.2 | splat-rs |
|
||||
|---|---|---|
|
||||
| Mapa ITWOM 40 km | ~25 min | ~2 min (12.5× más rápido) |
|
||||
| Tabla SFT (`perfiles.sh`) | ~30 min | ~7 s (260× más rápido) |
|
||||
| Path report único | ~2 s | <1 s |
|
||||
|
||||
---
|
||||
|
||||
## 8. Diagnóstico de problemas
|
||||
|
||||
### "El TX (X, Y) no está cubierto por los tiles SDF de ..."
|
||||
|
||||
El TX cae fuera de los tiles cargados. Verifica los nombres de archivo en
|
||||
`sdf/`: deben tener formato `minlat:maxlat:minlon:maxlon.sdf.bz2` y cubrir
|
||||
el rango de coordenadas del TX/RX.
|
||||
|
||||
### Mapa de cobertura completamente blanco
|
||||
|
||||
`--max-loss-db` demasiado bajo para el escenario:
|
||||
- Microondas en LOS limpio: pérdida 100-130 dB → `--max-loss-db 130` o más
|
||||
- Microondas con obstrucciones: hasta 180 dB → `--max-loss-db 180`
|
||||
|
||||
### Patrón de antena no aplicado
|
||||
|
||||
splat-rs busca `<base>.az` y `<base>.el` donde `<base>` es el nombre del `.qth`
|
||||
sin extensión. Si tu antena se llama `tx.qth`, debe haber `tx.az` / `tx.el` en
|
||||
el mismo directorio. Verifica con `--no-pattern` para forzar isotrópica y
|
||||
comparar.
|
||||
|
||||
### Aliasing radial visible en mapa de cobertura
|
||||
|
||||
Es inherente al método radial-sweep. Mitigaciones:
|
||||
- Subir umbral con `--max-loss-db` para mostrar solo cobertura útil
|
||||
- Usar HD mode (DEM 1 arc-sec, ppd=3600) — 9× más lento pero menos artifacts
|
||||
- El renderer ya aplica supercover 2×2 + dilatación; resta es físicamente irreducible
|
||||
|
||||
### `gnuplot: not found` al pedir `-h/-H/-p/-e/-l`
|
||||
|
||||
splat-rs solo escribe los `.gp` data y orquestador. Para rasterizar necesitas
|
||||
`gnuplot` instalado:
|
||||
```bash
|
||||
sudo apt install gnuplot
|
||||
```
|
||||
|
||||
### Ejecución más lenta de lo esperado
|
||||
|
||||
Verifica que rayon esté usando todos los cores:
|
||||
```bash
|
||||
splat-rs ... 2>&1 | head -1
|
||||
# "Hilos disponibles: 16 (de 16 lógicos)"
|
||||
```
|
||||
Si aparece menos, usa `--threads N` para forzar.
|
||||
|
||||
---
|
||||
|
||||
## 9. Diferencias con SPLAT! original
|
||||
|
||||
### Mejoras
|
||||
- **Reentrancia thread-safe**: `static → thread_local` en ITWOM permite N hilos sin contención
|
||||
- **Paralelización nativa**: rayon distribuye radiales/SFT-celdas entre todos los cores
|
||||
- **Carga DEM única**: vs SPLAT que recarga en cada invocación
|
||||
- **Salida en español** (homologada por Charles)
|
||||
- **Sintaxis CLI compatible** + extensiones (`--sft`, `--threads`, `--max-loss-db`)
|
||||
- **CSV de la tabla SFT** además del texto
|
||||
- **Mensajes de error útiles** con contexto
|
||||
|
||||
### No implementado
|
||||
- `-ano` / `-ani`: input/output alfanumérico (uso poco común)
|
||||
- `-b`: archivos de fronteras cartográficas (overlay PPM)
|
||||
- `-dbm`: paleta dBm en vez de dBµV/m (existe en código pero no expuesto en CLI)
|
||||
- `-geo`: archivo georreferencia Xastir (formato muy específico)
|
||||
- `-log`: registro del comando (uso `>&2` redirect en shell)
|
||||
- `-ngs`: topografía gris como blanco (escala de grises)
|
||||
- `-sc`: contornos suaves (paleta lineal vs cuantizada)
|
||||
- `-db`: contornos por encima de un umbral
|
||||
- `-nf`: omitir Fresnel en height plot (siempre se grafica)
|
||||
|
||||
### Drift numérico
|
||||
- ITWOM path loss: ±0.02 dB vs SPLAT golden (floating-point con `-ffast-math` activado en C++ original)
|
||||
- HAAT: ±0.1 m por sampling de los 8 radiales
|
||||
- Ángulos: bit-idénticos (mismo radio terrestre 20902230.97 ft)
|
||||
|
||||
---
|
||||
|
||||
## 10. Estructura del proyecto
|
||||
|
||||
```
|
||||
splat-rs/
|
||||
├── Cargo.toml
|
||||
├── MANUAL.md # este archivo
|
||||
├── build.rs # compila itwom + linkea libbz2
|
||||
├── cpp/
|
||||
│ ├── itwom3.0.cpp # vendored, static→thread_local
|
||||
│ └── itwom_ffi.cpp # C ABI wrapper (refs → pointers)
|
||||
└── src/
|
||||
├── lib.rs # mod tree
|
||||
├── itwom.rs # FFI seguro a ITWOM/Longley-Rice
|
||||
├── sdf.rs # loader .sdf[.bz2] + DemTileSet indexado
|
||||
├── qth.rs # parser .qth (DMS o decimal)
|
||||
├── lrp.rs # parser .lrp (tolerante a prosa)
|
||||
├── pat.rs # parser .az/.el + AntennaPattern
|
||||
├── udt.rs # parser .udt + DemWithUdt overlay
|
||||
├── cities.rs # parser .cities
|
||||
├── geo.rs # Distance, Azimuth, step_great_circle
|
||||
├── radial.rs # compute_radial + plot_lr_map_parallel
|
||||
├── coverage.rs # CoverageMap + rasterize_line + fill_holes
|
||||
├── ppm.rs # writer PPM con paleta signal-strength
|
||||
├── kml.rs # writer KML GroundOverlay + LineString
|
||||
├── gnuplot.rs # writers .gp (perfil/altura/elevación)
|
||||
├── report.rs # PathReport + SiteReport + ObstructionAnalysis
|
||||
├── sft.rs # Strength Field Table (paralelo)
|
||||
├── types.rs # Site, Config
|
||||
└── bin/
|
||||
├── splat-rs.rs # CLI principal
|
||||
└── bench.rs # microbenchmark ser vs par
|
||||
```
|
||||
|
||||
26 tests unitarios + 4 ignored (end-to-end con DEM real).
|
||||
|
||||
---
|
||||
|
||||
## 11. Créditos
|
||||
|
||||
- **SPLAT!** original: John A. Magliacane, KD2BD (2002–2014)
|
||||
- **ITWOM v3.0**: Sid Shumate (2010)
|
||||
- **Adaptación al español + variante 1.4.2-Charles**: Ing. Charles Escobar
|
||||
- **Port a Rust + paralelización**: 2026
|
||||
|
||||
Bajo licencia GPLv2 (heredada del SPLAT! original).
|
||||
Reference in New Issue
Block a user