Realtime environmental awareness: distributed sound localization + classification + common operating picture
Project description
MinimapPR
Realtime environmental awareness: distributed sound localization + classification + common operating picture.
This repository now includes a complete Phase 1 core build focused on the base case:
- functional two-node ingestion model (point node + Sirith tetrahedral array node)
- TDOA localization backend (GCC-PHAT + least-squares solve)
- canonical event envelope (
event_id,source_type, TOA/TOR,time_quality, provenance refs) - core schema persistence for nodes, observations, detections, tracks, labels, alerts, and track updates
- geographic COP frontend with node health, GDOP overlay, symbology, uncertainty ellipses, velocity vectors, track table, and detection feed
First Delivery Scope (Implemented)
FastAPIbackend for node ingestion, localization, classification, tracking, and APIs- queue-driven fusion node runtime (ingest stage decoupled from localization/classification workers)
SQLitepersistence for Phase 1 core tables (nodes,observations,detections,tracks,labels,alerts,track_updates) plus activeenvironmentingestion/persistence- automatic snippet retention cleanup (self-cleaning raw audio extracts)
- snippet serving endpoint (
/api/v1/detections/{id}/audio) - live websocket feed with server-side subscription filtering (zone/category/confidence/track status)
- geographic Leaflet COP dashboard
- deterministic simulation stream with both required node types
Project Layout
minimappr/main.py: API server + lifecycleminimappr/core/: buffering, localization, tracking, fusion-node orchestrationminimappr/classifiers/: classifier interface, heuristic backend, optional YAMNet backendminimappr/storage/db.py: SQLite schema + persistenceminimappr/frontend/: basic web UIminimappr/sim/run_demo.py: realtime two-node simulator (point + Sirith tetra)firmware/: shared embedded node runtime + Sirith/point firmware targetstests/: localization and classifier tests
Quick Start
pip install minimappr[full] # installs birdnet + tensorflow + tensorflow-hub
minimappr # starts server at :8080
- Create environment and install dependencies.
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
- Start server.
uvicorn minimappr.main:app --host 0.0.0.0 --port 8080 --reload
- In a second terminal, run two-node live demo stream.
source .venv/bin/activate
python -m minimappr.sim.run_demo --server http://127.0.0.1:8080
- Open UI.
http://127.0.0.1:8080
You should see nodes appear, detections populate, and tracks move on the map.
Node Types in MVP
1) Point node (ESP32-style stream node)
- Single-channel microphone stream
- Node type:
point - Intended for GPS/PPS-timestamped network localization
2) Sirith tetrahedral node
- Four-channel array stream
- Node type:
sirith_tetra - Default geometry: regular tetrahedron with 50 mm edge (
schematicskept for hardware reference) - In this MVP it contributes 4 independent channels to the backend solver
Firmware (ESP32 + Pico)
Firmware projects are in firmware/:
firmware/lib/minimap_node_core: shared node runtime/protocol/transportfirmware/lib/minimap_audio_esp32: ESP32 I2S audio sourcesfirmware/lib/minimap_audio_pico: RP2040/RP2350 Pico TDM audio sourcesfirmware/nodes/sirith_tetra: Sirith tetrahedral node firmware (dual-I2S -> 4 channels)firmware/nodes/sirith_tetra_pico: Sirith tetrahedral Pico W / Pico 2 W firmware (TDM-4)firmware/nodes/point_single_mic: reference point node firmware
Full firmware setup and build instructions are in firmware/README.md.
Ingestion Protocol (Current)
Endpoint: POST /api/v1/ingest/frame
Payload:
{
"node": {
"id": "point-node-01",
"node_type": "point",
"position_m": [0.0, 0.0, 2.0],
"sensor_offsets_m": [[0.0, 0.0, 0.0]],
"capabilities": ["audio", "gps_pps"],
"metadata": {}
},
"frame": {
"start_time_ns": 1739810000000000000,
"sample_rate_hz": 16000,
"channels": 1,
"encoding": "pcm16le",
"samples_b64": "...",
"sequence": 42
},
"environment": {
"temperature_c": 21.4,
"humidity_fraction": 0.52,
"pressure_pa": 101325.0,
"source": "onboard_sensor"
}
}
Notes:
- audio payload is interleaved
pcm16le, base64 encoded frame.channelsmust matchlen(node.sensor_offsets_m)- timestamps are per-frame start timestamps in
ns - optional per-frame timing quality metadata supported:
time_quality,toa_ns,tor_ns - optional environmental payload supported:
environment.temperature_c(minimum), humidity/pressure/wind/lux optional - firmware-compatible fallback: if
node.metadata.temperature_cis provided, it is ingested intoenvironmenteven without an explicitenvironmentobject - response
triggered=truemeans an event candidate was queued for fusion workers; detection emission is asynchronous
Processing Pipeline
- Ingest timestamped audio frames.
- Append channel streams to rolling per-sensor buffers.
- Trigger candidate events from frame RMS threshold.
- Enqueue trigger candidates to fusion workers.
- Build synchronized multi-sensor windows.
- Run GCC-PHAT TDOA measurement and nonlinear 3D solve.
- Classify event audio (heuristic baseline, pluggable backend).
- Associate/update track.
- Persist detection + track and emit live websocket event.
- Save mono snippet for retention window; periodic cleanup removes expired snippets.
Classifier System
Implemented classifier architecture is pluggable:
- default:
heuristic(fast baseline labels:bird_like,speech_like,impulse,machine_hum,ambient,unknown) - optional:
yamnet(if TensorFlow dependencies are installed)
Set backend with:
export MINIMAPPR_CLASSIFIER=heuristic
# or
export MINIMAPPR_CLASSIFIER=yamnet
API Endpoints
GET /healthGET /api/v1/configGET /api/v1/fusion/statusGET /api/v1/federation/statusPOST /api/v1/ingest/frameGET /api/v1/nodesGET /api/v1/detections?limit=100GET /api/v1/tracks?limit=200&include_standby=falseGET /api/v1/cop/statusGET /api/v1/alerts?limit=100GET /api/v1/environment?limit=500&node_id=...GET /api/v1/environment/current?x=...&y=...&z=...GET /api/v1/detections/{detection_id}/audioPOST /api/v1/federation/heartbeat(peer-to-peer)POST /api/v1/federation/snapshot(peer-to-peer)WS /ws/live
Runtime Configuration
Key env vars:
MINIMAPPR_HOST(default0.0.0.0)MINIMAPPR_PORT(default8080)MINIMAPPR_DB_PATH(defaultdata/minimappr.db)MINIMAPPR_SNIPPET_DIR(defaultdata/snippets)MINIMAPPR_SNIPPET_RETENTION_SECONDS(default3600)MINIMAPPR_TRIGGER_RMS(default0.015)MINIMAPPR_TRIGGER_COOLDOWN_SECONDS(default0.8)MINIMAPPR_LOCALIZATION_WINDOW_SECONDS(default0.08)MINIMAPPR_DEFAULT_TEMPERATURE_C(default20.0)MINIMAPPR_DEFAULT_HUMIDITY(default0.5)MINIMAPPR_ENVIRONMENT_READING_MAX_AGE_SECONDS(default300.0,0disables staleness cutoff)MINIMAPPR_SITE_ORIGIN_LAT(default37.7749)MINIMAPPR_SITE_ORIGIN_LON(default-122.4194)MINIMAPPR_SITE_ORIGIN_ALT_M(default0.0)MINIMAPPR_COORDINATE_MODE(flatorgeodetic; defaultflat)MINIMAPPR_CLASSIFIER(heuristicoryamnet)MINIMAPPR_TRACKING_FILTER(lineardefault, orkalman)MINIMAPPR_KALMAN_PROCESS_NOISE(default2.0)MINIMAPPR_KALMAN_MEASUREMENT_NOISE(default1.5)MINIMAPPR_KALMAN_INITIAL_POSITION_VARIANCE(default4.0)MINIMAPPR_KALMAN_INITIAL_VELOCITY_VARIANCE(default16.0)MINIMAPPR_FUSION_WORKER_COUNT(default1)MINIMAPPR_FUSION_EVENT_QUEUE_SIZE(default256)MINIMAPPR_NODE_DEGRADED_AFTER_SECONDS(default15.0)MINIMAPPR_NODE_OFFLINE_AFTER_SECONDS(default45.0)MINIMAPPR_EVENT_STALE_SECONDS(default30.0)MINIMAPPR_RETENTION_TRACK_UPDATES_SECONDS(default604800, set-1to disable cleanup)MINIMAPPR_RETENTION_ALERTS_SECONDS(default2592000, set-1to disable cleanup)MINIMAPPR_RETENTION_ENVIRONMENT_SECONDS(default604800, set-1to disable cleanup)MINIMAPPR_RETENTION_DROPPED_TRACKS_SECONDS(default604800, set-1to disable cleanup)MINIMAPPR_FEDERATION_ENABLED(falsedefault)MINIMAPPR_FEDERATION_SERVER_ID(srv-localdefault)MINIMAPPR_FEDERATION_PEERS_CONFIG_PATH(data/federation_peers.jsondefault)MINIMAPPR_FEDERATION_PEERS_JSON(optional inline JSON peer config override)MINIMAPPR_FEDERATION_AUTH_TOKEN(optional shared token/fallback peer auth token)MINIMAPPR_FEDERATION_PUBLISH_INTERVAL_SECONDS(default1.0)MINIMAPPR_FEDERATION_HEARTBEAT_INTERVAL_SECONDS(default2.0)MINIMAPPR_FEDERATION_LINK_TIMEOUT_SECONDS(default8.0)MINIMAPPR_FEDERATION_REQUEST_TIMEOUT_SECONDS(default2.5)MINIMAPPR_FEDERATION_TRACK_TTL_SECONDS(default20.0)MINIMAPPR_FEDERATION_DECONFLICT_MAHALANOBIS_GATE(default4.5)MINIMAPPR_FEDERATION_TQI_HYSTERESIS(default0.05)
Testing
source .venv/bin/activate
pytest -q
5-minute soak harness:
source .venv/bin/activate
python scripts/run_soak.py --duration 300
Roadmap Foundation Included
This MVP lays groundwork for the broader goals in your notes/proposals:
- additional sensor modalities
- richer model chaining (speech/STT/Home Assistant integration)
- federated fusion server topology
- richer COP layers (GDOP overlays, zones, alerting policies)
- advanced tracking and multi-hypothesis association
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file minimappr-0.1.0.tar.gz.
File metadata
- Download URL: minimappr-0.1.0.tar.gz
- Upload date:
- Size: 172.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f6c90fa1fc0592336f1212d8889608af389473b050cee92992935c7b7e3609d3
|
|
| MD5 |
41f4f9a5cd8690546b44c93a45000863
|
|
| BLAKE2b-256 |
fd336b5f759d0a975de5d14e8bed6dcc6a65b6ad3b0fed27db109ad049fd2546
|
File details
Details for the file minimappr-0.1.0-py3-none-any.whl.
File metadata
- Download URL: minimappr-0.1.0-py3-none-any.whl
- Upload date:
- Size: 150.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
69c4d2c920cfa5f5b6ce5fecb8e6f86d51bec8ab2b101d731921d028ca754ee1
|
|
| MD5 |
6c3c319fcd3dd11dcbf0c78de768483e
|
|
| BLAKE2b-256 |
a02af58cee50da0fb2da0e726a51a9e09399aff68b3b82b950046f4669c13678
|