feat: ADR-039 edge intelligence — on-device CSI processing pipeline

Implements a dual-core edge processing system for ESP32-S3:
- Lock-free SPSC ring buffer (Core 0 produces, Core 1 consumes)
- Tier 1: phase unwrap, Welford stats, top-K subcarrier selection, delta compression
- Tier 2: presence/motion detection, vital signs (breathing/heart rate via biquad IIR), fall detection
- Vitals UDP packet (magic 0xC5110002, 32 bytes, sent at 1 Hz)
- NVS/Kconfig configurable (edge_tier, thresholds, intervals)
- Backward compatible: tier=0 (default) is a no-op
- GitHub Actions firmware CI: build, binary size gate, credential scan, flash image verification
- Binary: 777 KB (24% free in 1 MB partition)

Co-Authored-By: claude-flow <ruv@ruv.net>
This commit is contained in:
ruv
2026-03-02 19:55:35 -05:00
parent 14902e6b4e
commit e9bb4faf53
9 changed files with 1671 additions and 5 deletions
+9 -4
View File
@@ -21,11 +21,13 @@
#include "csi_collector.h"
#include "stream_sender.h"
#include "nvs_config.h"
#include "edge_processing.h"
static const char *TAG = "main";
/* Runtime configuration (loaded from NVS or Kconfig defaults). */
static nvs_config_t s_cfg;
/* Runtime configuration (loaded from NVS or Kconfig defaults).
* Non-static so edge_processing.c can access it via extern. */
nvs_config_t s_cfg;
/* Event group bits */
#define WIFI_CONNECTED_BIT BIT0
@@ -141,8 +143,11 @@ void app_main(void)
ESP_LOGI(TAG, "No MAC filter — accepting CSI from all transmitters");
}
ESP_LOGI(TAG, "CSI streaming active → %s:%d",
s_cfg.target_ip, s_cfg.target_port);
/* ADR-039: Initialize edge processing (tier 0 = no-op for backward compat) */
edge_processing_init(s_cfg.edge_tier);
ESP_LOGI(TAG, "CSI streaming active → %s:%d (edge_tier=%u)",
s_cfg.target_ip, s_cfg.target_port, (unsigned)s_cfg.edge_tier);
/* Main loop — keep alive */
while (1) {