Whitepaper: Building an Apple-Style 3D Volumetric WiFi Heatmap & Triangulation Radar
Document Index
1. Executive Abstract & Mission Statement
In modern telecommunications, radio frequency (RF) mapping has traditionally been limited to static 2D floor plans. Waves scatter, reflect off metallic objects, and attenuate heavily when passing through concrete slabs. This leaves engineers blind to structural multipath bottlenecks.
Our mission with the sudonishant Spatial Mapper & Radar was to create a hardware-accelerated, cross-platform volumetric analysis tool. By taking raw signal metrics from standard network interfaces, combining them with log-distance path loss calibration constants, and rendering them in an Apple Space Gray styled WebGL environment, we make RF fields tangible in 3D space.
2. Detailed 3-Tier Pipeline Flow
To support high-frequency polling (10Hz sweeps) without blocking the client browser thread, the architecture separates responsibilities into three distinct sandboxed modules:
Layer A: Low-Overhead C++ Daemon (wifi_scanner_cli)
Written in native C++17, this daemon bypasses bulky user-space CLI programs by querying kernel structures directly:
- Linux (proc/net/wireless): Opens descriptor nodes to read real-time link quality, raw RSSI, and noise floors directly from the sysfs subsystem.
- macOS (CoreWLAN): Links against Apple's private native frameworks to sweep Channels, RSSI, and BSSIDs at millisecond frequencies.
- Windows (Wlanapi): Initiates client handles on the wireless interfaces to retrieve structured network information frames.
Layer B: Node.js IPC & WebSocket Bridge (server.js)
The backend Node server executes the C++ scanner as a child subprocess, capturing stdout buffers on-the-fly.
- Memory Guard: Prunes the loaded scan history on startup to a maximum of 1,500 points, preventing browser GPU overflow.
- Debounced Persistence: Performs asynchronous disk writes to
scan_history.jsonusing a 2-second debounce timer to prevent hardware write flooding. - Broadcaster Channel: Manages real-time WebSocket connection pools to sync scanning points across multiple client sessions simultaneously.
Layer C: WebGL 3D Visualization Port (app.js)
The client interface uses hardware-accelerated WebGL through Three.js:
- Voxel Point Cloud Grid: Dynamically maps volumetric data points colored via custom thermal palette lookup tables (Ironbow, Rainbow, White/Black Hot).
- Multipath Reflection Rays: Calculates ray paths bouncing between walker nodes and the transmitter.
- Doppler Waterfall: Displays spectrograms of subcarrier CSI metrics to alert engineers to human breathing rates (12-18 BPM).
3. Distance Physics & Calibration Sliders
To convert logarithmic received signal power (RSSI in dBm) into geometric distance (meters), we implement the Log-Distance Path Loss Model, a standard RF propagation equation:
Solving this mathematically for distance d yields:
Because every building material blocks RF waves differently, we integrated interactive calibration sliders on-screen in the HUD sidebar:
- Reference RSSI (A): The reference signal strength logged at exactly 1 meter from the router. Typically ranges from -35 dBm (high gain) to -55 dBm (low gain).
- Path Loss Exponent (N): Dictates how fast the signal decays. Adjusted by material densities:
| Environment Material | Typical Exponent (N) | Signal Decay Rate |
|---|---|---|
| 💨 Open Air / Free Space | 2.0 | Standard spherical decay |
| 🚪 Residential Drywall / Wood partitions | 2.8 to 3.2 | Moderate attenuation |
| 🧱 Thick Concrete / Brick walls | 3.8 to 4.2 | Severe attenuation |
| 🛡️ Faraday Cage / Metal enclosures | > 4.5 | Near-complete blockage |
Code Integration: Sliders directly adjust pathLossN and refSignalA in app.js, updating calculations in real-time:
function estimateDistance(rssi) {
const distance = Math.pow(10, (refSignalA - rssi) / (10 * pathLossN));
// Clamp boundaries to prevent walker from flying off grid
return Math.max(1.0, Math.min(12.5, distance));
}
4. Mathematical Centroid Triangulation Algorithm
Tracking the location of an unknown transmitter requires gathering coordinates from multiple directions. To solve this, our locator predictor runs a Weighted Centroid Algorithm.
Since decibel scales are logarithmic, we convert RSSI values back into a linear power scale ratio to act as geometric weights W:
The estimated transmitter coordinates \((X_{est}, Z_{est})\) are computed as the weighted averages of all logged coordinates \((X_i, Z_i)\):
This centroid calculation updates in real-time as you walk, moving the glowing blue wireframe target mesh closer to the physical transmitter coordinates.
5. Proximity Geiger Sound (Web Audio API)
To facilitate blind search patterns, we mapped RSSI decibels to oscillator rate clicks using the HTML5 **Web Audio API**:
- An
AudioContextis initialized upon user activation. - An
OscillatorNodegenerates raw sine waves at a base pitch of \(500\text{ Hz}\), scaling up to \(1200\text{ Hz}\) (higher pitch) as signal improves. - A
GainNodedecays the volume exponentially over \(45\text{ ms}\) to create a crisp Geiger click. - Beep delays are adjusted from \(80\text{ ms}\) (strong signal) to \(1000\text{ ms}\) (weak signal) in a recursive loop.
6. Three.js Raycast Obstruction Calculations
The mapper monitors signal attenuation caused by wall obstruction:
- A virtual ray is cast from the walker coordinate directly to the estimated router coordinate.
- We check for intersections against wall objects:
raycaster.intersectObjects(collisionWalls). - If intersections are found, we estimate wall thicknesses and attenuate the baseline signal by \(12\text{ dBm}\) per partition wall.
- When attenuation exceeds safe thresholds, a red-vignette **Haptic Alert** flashes around the screen.
7. Installation & Deployment Guide
The workspace includes a one-command initialization script `setup.sh` that automates C++ compilation and Node packages installation:
# 1. Give execution permission to setup script
chmod +x setup.sh
# 2. Run the initialization script
./setup.sh
# 3. Open the browser to load the dashboard
xdg-open http://localhost:8080
Toggle **Virtual Emu** mode in the HUD sidebar if running on systems without a physical wireless card, or select **Real Card** to start parsing hardware streams!