Repositorio del sensor SDR de monitoreo espectral con arquitectura híbrida C + Python:
- C (tiempo real): adquisición IQ con HackRF, PSD/demodulación, GPS/LTE, GPIO, publicación por ZMQ.
- Python (orquestación): lógica de campañas/realtime, calibración, subida a API, cola de reintentos, estado.
- Shared state:
ShmStoresobre/dev/shm/persistent.jsonpara intercambio entre procesos.
rf/rf.c: loop principal del motor RF.rf/libs/parser.c: parsea/valida config JSON y aplica defaults/clamping (incluyeppm_error).rf/libs/zmq_util.c: transporte ZMQ tipoPAIR.gps-lte/gps-lte.c: adquisición GPS + conectividad LTE + update de coordenadas en SHM.common/bacn_gpio.*: acceso GPIO (cuando no compilas en modo standalone).
orchestrator.py: estado global (IDLE/REALTIME/CAMPAIGN/KALIBRATING) y coordinación.campaign_runner.py: ejecución de campañas programadas.retry_queue.py: reintentos de payloads fallidos.status.py: heartbeat/estado del sensor.functions.py: scheduler, utilidades y claseAcquireDual.utils/request_util.py: cliente HTTP +ZmqPairController.utils/io_util.py:ShmStore, escritura atómica y timers.
kal_sync_legal_FM.py: calibración deppm_errorusando frecuencias legales FM cercanas.kal_sync_pilot_tone.py: estimación alternativa por tono piloto FM y persistencia deppm_error.
build.sh: compilación CMake (standardo-dev).install.sh: instalación completa para despliegue (servicios, permisos, SHM, reboot).document.sh: pipeline de documentación (Doxygen + Sphinx HTML).build_docs.sh: rebuild rápido de docs HTML condoc-venvexistente.docs/: fuente Sphinx.Doxyfile: fuente Doxygen para C.
Genera los dos binarios principales:
rf_appltegps_app
./build.shInternamente:
- Configura CMake sin flags especiales.
- Compila target
all. - Mueve binarios al root del repo.
- Elimina carpeta
build/temporal.
Este modo está pensado para desarrollo local (por ejemplo, laptop/desktop sin hardware GPIO):
./build.sh -devQué hace exactamente:
- Pasa
-DBUILD_STANDALONE=ONa CMake. - Compila solo target
rf_app. - En
CMakeLists.txtevitagpiody defineNO_COMMON_LIBS.
Resultado: puedes compilar y trabajar el motor RF sin dependencia de GPIO real.
install.sh está orientado a instalación end-to-end en el equipo objetivo:
sudo ./install.shResumen de lo que hace:
- Detiene servicios
*-ane2activos (excepto LTE según regla del script). - Instala dependencias del sistema.
- Compila dependencias de hardware si faltan (
libgpiod,kalibrate-hackrf). - Crea/recrea
venv, instalarequirements.txt, ejecutabuild.sh. - Inicializa
/dev/shm/persistent.jsoncon permisos compartidos. - Genera y habilita daemons/timers via
init_sys.py+daemons/*.service. - Recarga systemd y reinicia el equipo.
El repo ya incluye automatización de documentación para código C + Python.
./document.shEste script:
- Crea
doc-venvsi no existe. - Instala
docs/requirements.txt. - Limpia
docs/_buildydocs/xml. - Ejecuta
doxygen Doxyfile(genera XML C). - Ejecuta Sphinx para HTML.
Salida HTML:
docs/_build/html/index.html
Si ya tienes doc-venv armado:
./build_docs.shHace limpieza y make html en docs/.
El docs/Makefile soporta objetivos de Sphinx; para PDF usa latexpdf.
source doc-venv/bin/activate
cd docs
make latexpdfSalida típica:
docs/_build/latex/*.pdf
Si falta toolchain LaTeX, instala (Debian/Ubuntu):
sudo apt-get update
sudo apt-get install -y texlive-latex-extra texlive-lang-spanish latexmkTip: si quieres HTML + PDF en una sola corrida:
./document.sh && (source doc-venv/bin/activate && cd docs && make latexpdf)
- Python arma config (
ServerRealtimeConfig) y la manda por ZMQ (ZmqPairController.send_command). - C recibe payload (
on_command_receivedenrf/rf.c). parse_config_rf(rf/libs/parser.c) aplica:- defaults de seguridad,
- parseo de campos,
- clamping del filtro a banda Nyquist,
- parseo de
ppm_error, - parseo de
cooldown_request(float en segundos, default1.0, comportamiento sticky).
- C ejecuta adquisición/PSD y publica resultados JSON por ZMQ (
publish_results). - Python consume respuesta (
wait_for_data) y la usa en realtime/campaign/calibración.
flowchart TD
A[Python Orchestrator / Campaign / KalSync] --> B[ServerRealtimeConfig]
B --> C[ZmqPairController.send_command\nIPC: ipc:///tmp/rf_engine]
C --> D[rf_app - on_command_received]
D --> E[parse_config_rf en parser.c]
E --> E1[Defaults seguros]
E --> E2[Clamp filtro a Nyquist]
E --> E3[Parse ppm_error]
E --> F[find_params_psd + apply HW cfg]
F --> G[HackRF RX + DSP]
G --> H[publish_results JSON]
H --> I[ZMQ PAIR send desde C]
I --> J[Python wait_for_data]
J --> K[post a API / WebRTC / calibración]
kal_sync_legal_FM.pycalcula corrección y persiste en SHM:ppm_errorlast_kal_ms
kal_sync_pilot_tone.pytambién puede persistir corrección estimada.parser.cconsumeppm_erroral parsear la config entrante.
En operación, la calibración alimenta el parámetro que utiliza el motor RF para compensación de frecuencia.
Estado compartido real:
/dev/shm/persistent.json
Snapshot/placeholder del esquema esperado:
json/shmstore.jsonc
Campos relevantes para calibración y GPS:
last_lat,last_lng,changed_gpslegal_freqs(cache para evitar recargar DB ANE cada corrida)ppm_error,last_kal_ms
Campos relevantes para pacing RF:
cooldown_request(float, segundos,>= 0): intervalo mínimo entre requests/procesamiento PSD enrf_app.- Si no se envía, el motor usa
1.0s por defecto; si se envía, mantiene ese valor hasta nuevo update.
# 1) Crear entorno Python
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
# 2) Compilar C sin GPIO
./build.sh -dev
# 3) Ejecutar componentes Python según necesidad
python3 orchestrator.pyinstall.shestá pensado para despliegue y termina en reboot.- En modo dev usa
build.sh -devpara evitar dependencias de GPIO físico. - El IPC por defecto se define en
cfg.py(IPC_ADDR = ipc:///tmp/rf_engine). - Para documentar C correctamente, asegúrate de tener
doxygeninstalado.
Este README describe la estructura y operación técnica actual del repositorio. Para políticas de publicación, uso y licencias, revisar los lineamientos del proyecto/organización.