Ir para o conteúdo

Modelos de propagação — matriz auditável

Escopo. Esta página descreve, com fidelidade ao código fonte, os modelos de propagação RF efetivamente em produção no TELECOM-TOWER-POWER (TTP), a seleção entre eles, os limites de cada um e o estado atual de cada caminho. Substitui qualquer documento anterior que descreva o TTP como tendo um único modelo de propagação.

Resumo executivo

O TTP não usa um único modelo de propagação. A engine é selecionada pelo campo engine da API (ou resolvida em modo engine='auto', sob critérios documentados abaixo). As três engines físicas ativas são:

Engine Método Dimensionalidade Onde é usada Caminho
fspl FSPL + zona de Fresnel + knife-edge único (k=4/3) 2D (perfil 1D do terreno + envelope de Fresnel) /analyze_link (qualquer chave), default de /coverage/interference (Pro+), gráfico do PDF. Não é aceita em /coverage/predict Síncrono
p1812 ITU-R P.1812 (via Py1812, multi-knife-edge / Deygout) 2D (perfil 1D do terreno, regimes ITU-R) Default de /coverage/predict (Pro+) e baseline do resíduo LightGBM Síncrono
sionna_rt Sionna RT — ray-tracing (Mitsuba 3 / Dr.Jit, materiais ITU-R P.2040) 3D (cena Mitsuba: terreno + edificações) Opt-in, Business / Enterprise / Ultra por padrão. Não promovido para serving Assíncrono (fila RQ ttp_rt, serviço rt-worker em CPU)

Duas camadas completam a matriz:

  • Resíduo LightGBM. Em /coverage/predict, o P.1812 é o baseline de uma correção aprendida: o artefato residual soma ao baseline P.1812/P.1411 uma correção treinada com 124.309 medições reais de drive-test, agregadas em 76.139 pontos, em Brasília. A validação espacial e a banda conformal dessa cadeia estão em Validação do modelo. A resposta mantém engine_used = p1812; quem respondeu aparece em model_source (residual-lgbm).
  • Kernel determinístico em Go. FSPL, raio de Fresnel, estimativa de sinal e folga de terreno, além de best server, interferência e otimização de potência, rodam no serviço rf-kernel (Go, só biblioteca padrão; rf-kernel/kernel/), com RF_KERNEL_PCT=100 desde 11/08/2026. Cada função é porta 1:1 do LinkEngine Python, com teste de paridade de 1e-9 em CI (.github/workflows/rf-kernel-ci.yml). Se o kernel não responde, a requisição cai para o LinkEngine Python (rf_kernel_client.py).

Seleção da engine

/coverage/predict aceita no campo engine:

  • p1812 — default. ITU-R P.1812; com o artefato residual carregado, a resposta é a cadeia P.1812/P.1411 + resíduo. Responde HTTP 503 se os mapas digitais da ITU não estiverem instalados.
  • auto — resolve, nesta ordem: sionna_rt quando o tier é Enterprise/Ultra e há bbox e cena (scene_s3_uri, ou cena sugerida automaticamente quando SIONNA_RT_AUTO_SCENE_ENABLED está ligado); senão p1812, se o P.1812 está disponível; senão ridge.
  • ridge — aceito; com o artefato residual carregado, quem responde continua sendo o resíduo. O ridge é o fallback (Validação do modelo — ridge-v1).
  • itm / itmlogic — NTIA Longley-Rice (Irregular Terrain Model) via itmlogic 1.2. Modo ponto (point mode); cobertura em grid via ITM está no roadmap.
  • sionna_rt / sionna-rt — força ray-tracing 3D. Exige bbox e scene_s3_uri (bundle Mitsuba da cena).

O valor fspl não é aceito em /coverage/predict.

/coverage/interference aceita auto (= fspl, o default), fspl, itu-p1812 (responde 501 enquanto INTERFERENCE_P1812_ENABLED não está ligado), itu-p452 (alias p452; responde 501 enquanto INTERFERENCE_P452_ENABLED não está ligado e 503 sem o pacote ou os mapas — ver a engine 4), sionna-rt e itmlogic (responde 501: no roadmap).

/planning/site-optimizer/async, /planning/site-gaps/async e /planning/pipeline/async são jobs assíncronos, executados pelo serviço worker. O schema aceita itmlogic (o default) e itu-p1812, mas o worker ainda não carrega os mapas digitais do P.1812: um pedido com itu-p1812 é recusado com HTTP 422 antes de o job ser criado. No app, o Site Optimizer e o Plan My Network mostram o ITU-R P.1812 desabilitado.

Validação no código: telecom_tower_power_api.py (CoveragePredictRequest.engine, _resolve_coverage_engine, _interference_select_engine, _require_cpu_worker_engine) e job_dispatch.py (CPU_WORKER_ENGINES). O estado ao vivo do default está em GET /health/engine (público): auto_default e p1812_available.

Engine 1 — FSPL + Fresnel 2D + knife-edge único

Implementação. telecom_tower_power_api.py (LinkEngine), rf-kernel/kernel/fspl.go (a mesma física em Go, servida via rf_kernel_client.py), worker.py (LinkEngine dos jobs em lote) e pdf_generator.py (gráfico do perfil).

Fórmulas.

  • Perda em espaço livre: $L_{\text{FSPL}} = 20\log_{10}(d) + 20\log_{10}(f) - 147{,}55$ dB.
  • Raio da primeira zona de Fresnel ao longo do perfil: $r_n = \sqrt{\dfrac{n \lambda d_1 d_2}{d_1 + d_2}}$, com $n=1$.
  • Bulge da Terra com fator $k = 4/3$ ($R_{\text{eff}} = 6371 \cdot k$ km).
  • Single knife-edge: a clearance é avaliada pelo ponto de maior intrusão do terreno no envelope de Fresnel ao longo do perfil 1D.

Para que serve. Análise rápida de enlace, default de interferência, gráfico do PDF e teto físico: em /coverage/predict, um valor acima do espaço livre é cortado e a resposta marca physics_capped. Não é o modelo recomendado para decisão de projeto onde existir terreno acidentado, múltiplos obstáculos ou clutter denso.

Limites declarados (auditáveis).

  • Não captura múltiplos obstáculos sucessivos (single knife-edge).
  • Não captura reflexões nem espalhamento.
  • Não captura materiais (ITU-R P.2040) nem perdas por clutter urbano.
  • Envelope de Fresnel calculado em 1D ao longo do azimute do enlace; não é ellipsoide 3D.

Engine 2 — ITU-R P.1812 (multi-knife-edge / Deygout)

Implementação. itu_p1812.py — wrapper sobre o pacote Py1812 (eeveetza/Py1812), conformante à Recomendação ITU-R P.1812. O arquivo P1812.npz, derivado dos mapas digitais N050 / DN50 da ITU, é provisionado no boot do container: de um bucket privado compatível com S3 quando ITU_P1812_NPZ_S3_URI está definido; senão o container baixa o ZIP oficial da ITU e confere o SHA-256 dos mapas antes de derivar o arquivo (entrypoint.sh, itu_p1812_pins.py). Os mapas não são redistribuídos (licença ITU). Enquanto não estão no disco, itu_p1812_available = 0 em /metrics (autenticado).

O que P.1812 cobre que a engine FSPL não cobre.

  • Difração multi-knife-edge (Deygout) sobre o perfil real.
  • Refração troposférica com gradiente $\Delta N$ regional (mapa N050).
  • Dispersão troposférica de longo alcance.
  • Zonas radiometeorológicas (Inland / Coastal Land / Sea) por chamada.
  • Polarização horizontal/vertical e percentis de tempo/localização.
  • Cache: in-process LRU(2048) → Redis 7 d TTL, indexado pelo hash do perfil + parâmetros (≈ 30–80 ms por chamada não-cacheada).

Limites declarados.

  • Continua sendo cálculo sobre perfil 1D (a recomendação é inerentemente baseada em perfil). Não substitui ray-tracing 3D para geometrias urbanas densas em mmWave.
  • Requer cobertura por mapas digitais ITU; fora da grade cai para interpolação degradada.
  • Abaixo de 250 m o P.1812 recusa o perfil. Na cadeia do resíduo, o baseline é avaliado a 250 m e estendido com o expoente LoS da ITU-R P.1411 (rf_engines/hybrid_short_path_engine.py).

Engine 3 — Sionna RT (ray-tracing 3D)

Implementação. rf_engines/sionna_rt_engine.py; handler de interferência em rf_engines/interference_engine.py; despacho em rt_dispatch.py e gpu_dispatch.py; núcleo do job em scripts/sionna_rt_worker.py, chamado por rq_tasks.run_rt_raster_job no serviço rt-worker (rt-worker/railway.json).

O que faz.

  • Ray-tracing em cena Mitsuba (terreno + edificações), com Mitsuba 3 / Dr.Jit.
  • Visada direta, reflexão especular e difração de cunha (PathSolver do Sionna RT; a difração é ligada por SIONNA_RT_DIFFRACTION, default 1).
  • Materiais por ITU-R P.2040 (concreto, vidro, vegetação, metal etc.).
  • Não promovido para serving. Os resultados não entram na cadeia validada em Validação do modelo.

Restrições operacionais.

  • Opt-in explícito. Não é a engine default. Tiers Business / Enterprise / Ultra por padrão (RT_ALLOWED_TIERS, gpu_dispatch.py). A promoção em engine='auto' só ocorre para Enterprise / Ultra com bbox e cena.
  • Assíncrono. O endpoint responde HTTP 202 + job_id; o job vai para a fila RQ ttp_rt e é executado pelo serviço rt-worker. O cliente faz polling em poll_url (/coverage/engines/sionna-rt/raster/{job_id}). O raster resultante é gravado no armazenamento de objetos (MinIO).
  • Hardware. O Railway não tem hosts com GPU. O rt-worker roda a imagem CPU com a pilha de ray-tracing (INSTALL_RT_STACK=1) e SIONNA_RT_BACKEND=auto: traça no backend LLVM (CPU) quando a cena tem geometria (scene.xml), e cai para o stub fspl_stub, cego à geometria, quando não tem. tracer=sionna_rt no resultado nomeia o motor, não o hardware. O Dockerfile.gpu (CUDA) existe, mas o Railway, onde roda a produção, não tem hosts com GPU.
  • Latência. Fila e traçado: muito acima das engines síncronas.

Engine 4 — ITU-R P.452-18 (interferência entre estações)

Implementação. itu_p452.py — wrapper sobre o pacote Py452 (eeveetza/Py452, fixado no commit 77aa8164, versão 18.1), do mesmo autor do Py1812; motor itu-p452 em rf_engines/itu_p452_engine.py. Em GET /coverage/engines aparece como experimental.

Para que serve. É a Recomendação da UIT-R para prever interferência entre estações na superfície da Terra: a perda básica de transmissão não excedida em p % do tempo, de cerca de 0,1 a 50 GHz, com p de 0,001 a 50 %. Em /coverage/interference (atrás de INTERFERENCE_P452_ENABLED) cada agressor ganha um perfil de terreno e uma solução P.452, com zona interior, p = 50 % (a mediana, como a P.1812 no mesmo endpoint) e ganho de 0 dBi na direção do horizonte. Fora da faixa de frequência, ou quando a solução falha, o agressor entra pelo FSPL e é contado em n_path_loss_failures — nunca some do agregado.

O que cobre. Visada direta com multipercurso e focalização, difração (delta-Bullington), troposcatter, dutos e reflexão em camadas, e o clutter representativo de cada ponto do perfil, por polarização e por zona radioclimática (terra costeira, interior, mar).

Mapas. A P.452-18 usa os mesmos mapas digitais DN50/N050 da P.1812-8, byte a byte: o SHA-256 dos dois arquivos do zip oficial da P.452-18 é o mesmo que itu_p1812_pins.py já fixa. Por isso nada novo é baixado: a imagem liga o arquivo de mapas do Py452 ao P1812.npz que o boot já deriva e confere pelo pino. Os mapas não são redistribuídos (licença ITU).

Validação. tests/test_itu_p452_validation.py compara o Py452 com os 17 exemplos oficiais de validação (595 casos): sem os mapas em todo CI, com os valores de ΔN e N0 de referência, e com os mapas pinados quando o CI os tem, na tolerância do próprio autor (1e-6 dB).

Limites declarados.

  • Cálculo sobre perfil 1D, como a P.1812.
  • p é configuração do serviço (ITU_P452_TIME_PCT), não campo da requisição; a zona é uniforme (interior) no endpoint de interferência.
  • Desligada por padrão: o default de /coverage/interference continua fspl, e o caminho assíncrono aceita só fspl e sionna-rt.

Sionna ML (engine secundária, desligada)

Existe uma engine sionna adicional baseada em modelo ML treinado (features extraídas do perfil + clutter, inferência TFLite; rf_engines/sionna_engine.py). Status atual:

  • Desligada por padrão (SIONNA_DISABLED=1). O artefato é lido de SIONNA_MODEL_PATH (default /srv/models/sionna_model.tflite).
  • Guard-rail. rf_engines/sionna_engine.py::_load() recusa registrar o modelo quando o sidecar declara synthetic_only=True, ou quando training_rows < SIONNA_MIN_TRAINING_ROWS (default 500).
  • Sem retreino agendado. O workflow retrain-sionna.yml foi retirado na decomissão AWS (#410); o treino é manual (scripts/train_sionna.py). O último artefato documentado (v2, feature_dim=30, maio/2026) era 100 % sintético e foi bloqueado pelo guard-rail.
  • Desligada ou bloqueada, a engine sionna fica invisível em /coverage/engines e /coverage/engines/compare, e o registry cai para P.1812.

Esta engine não é apresentada ao cliente como ativa.

O que a auditoria de propagação geralmente alega — e a resposta

"Fresnel/knife-edge simplificado (não 3D)."

Procedente para a engine fspl. É deliberado: ela serve /analyze_link, o default de /coverage/interference e o gráfico do PDF, e não é aceita em /coverage/predict. A predição de cobertura usa P.1812 (multi-knife-edge Deygout, regulatório ITU-R) corrigido pelo resíduo LightGBM; Sionna RT 3D é opt-in e não promovido. A engine usada volta na resposta de /coverage/predict em engine_used, e o modelo que respondeu, em model_source.

"O PDF mostra apenas Fresnel 2D mesmo quando a engine 3D foi usada."

Procedente. O gráfico em pdf_generator.py é, por desenho, uma projeção 2D do perfil terreno + envelope de Fresnel. Ele é uma representação ilustrativa do enlace, não o resultado numérico. O valor numérico de perda total no PDF (signal_dbm, fresnel_clearance) provém da engine selecionada. O título do gráfico e a legenda da figura no PDF (em inglês) dizem isso: projeção 2D ilustrativa, valores numéricos da engine selecionada na requisição.

Evidência verificável

  • Default ao vivo: GET /health/engine (público) retorna auto_default e p1812_available.
  • Engines registradas: GET /coverage/engines (autenticado) lista as engines e a disponibilidade de cada uma.
  • Comparação lado-a-lado: POST /coverage/engines/compare executa o mesmo enlace (perfil enviado na requisição) em todas as engines disponíveis e retorna a tabela de resultados.
  • Validação contra drive-test: ver Validação do modelo.

Histórico de mudanças relevantes

  • 2026-11-11 — ITU-R P.452-18 (itu-p452, alias p452) entra como opção de /coverage/interference, atrás de INTERFERENCE_P452_ENABLED, com os mapas pinados da P.1812 e validação contra os 17 exemplos oficiais no CI. O default continua fspl.
  • 2026-10-10 — Página revista: o default de /coverage/predict é p1812 (o FSPL ficou em /analyze_link, /coverage/interference e no PDF); a camada de resíduo LightGBM e o rf-kernel em Go passam a ser descritos; Sionna RT documentado como assíncrono na fila RQ ttp_rt, em CPU, não promovido para serving; AWS Batch, SQS/Lambda e ECS aposentados (#398/#410).
  • 2026-05-11 — Promoção Sionna v2 (SIONNA_FEATURES_VERSION=v2, feature_dim=30). Guard-rail real-data introduzido (commit 23ac54b, ECS rev 145; o ECS foi aposentado depois, #398/#410): artefato v2 atual fica bloqueado por ser sintético; engine sionna ML invisível até re-treino com ≥500 linhas reais.
  • Maio/2026 — Sionna RT 3D exposto como engine opt-in para os tiers Enterprise/Ultra com scene_s3_uri, então em AWS Batch GPU (aposentado depois, #398/#410). FSPL/P.1812 mantidos como engines anteriores; nenhum modelo foi removido.