ESPectre SDK 2.8.0-280-gac7af68
Wi-Fi CSI motion sensing for ESP32 firmware
Loading...
Searching...
No Matches
runtime_snapshot.h
Go to the documentation of this file.
1/*
2 * ESPectre - Runtime Snapshot
3 *
4 * Runtime snapshot types shared by sensing status and diagnostics.
5 *
6 * Author: Francesco Pace <francesco.pace@gmail.com>
7 * SPDX-License-Identifier: GPL-3.0-only
8 * Commercial licensing available under separate agreement; see LICENSING.md.
9 */
10#pragma once
11
12#include <cstdint>
13
14#include "csi_types.h"
15#include "detector_types.h"
17
18namespace espectre {
19
20/** How the runtime chose the subcarriers it measures on. */
22 /** The fixed band validated for the shipped detectors. Currently the only mode. */
24};
25
26/**
27 * Low-frequency counters and radio state used by optional diagnostic surfaces.
28 *
29 * This deliberately stays separate from `RuntimeSnapshot`: sensing snapshots
30 * travel through the hot callback path, while frontends query diagnostics when
31 * they already handle a periodic sensing update.
32 *
33 * Counters are cumulative and monotonic within a session; pass them through
34 * `RuntimeDiagnosticsSampler` to turn them into rates.
35 */
37 /** RSSI of the current Wi-Fi association. `INT8_MIN` when unavailable. */
38 int8_t wifi_rssi_dbm{INT8_MIN};
39 /** Primary channel of the current Wi-Fi association. Zero when unavailable. */
40 uint8_t wifi_channel{0U};
41 /** Traffic packets sent or observed by the active traffic source. */
43 /** Raw invocations of the ESP-IDF CSI callback. */
44 uint64_t csi_callbacks_total{0U};
45 /** CSI packets accepted by capture validation, before temporal admission. */
46 uint64_t csi_accepted_total{0U};
47 /** CSI packets admitted to the detector's temporal grid. */
48 uint64_t csi_admitted_total{0U};
49 /** CSI packets rejected by capture-level validation. */
50 uint64_t csi_filtered_total{0U};
51 /** Empty temporal detector slots observed before admitted packets. */
53 /** Valid packets dropped because their temporal slot was already occupied. */
54 uint64_t csi_excess_total{0U};
55 /** Packets rejected because processing began after the active window. */
56 uint64_t csi_stale_total{0U};
57 /** Packets rejected because their timestamp moved backwards. */
59 /** Valid slots in the current detector window. */
60 uint32_t csi_occupancy_slots{0U};
61 /** Total slots in the configured detector window. */
62 uint32_t csi_window_slots{0U};
63};
64
65/**
66 * A consistent view of the sensing state at one instant.
67 *
68 * Passed to every `IRuntimeListener` callback and returned by
69 * `RuntimeFrontendController::snapshot()`. It is a plain value type: copy it
70 * freely, and copy it if you need it past the callback that delivered it.
71 *
72 * Read `ready_to_publish` before anything else. The runtime keeps emitting
73 * snapshots while it calibrates, and `motion_state` is not meaningful until
74 * that flag is true.
75 */
77 /** Debounced motion state, after the `motion_on_hits` / `motion_off_hits` filter. */
79 /**
80 * Current motion metric, on a 0..1 probability scale for both detectors.
81 *
82 * Comparable to `threshold`, but not comparable across detectors: Lightweight
83 * and ML produce the number differently even though the scale matches.
84 */
85 float movement_metric{0.0f};
86 /** Threshold `movement_metric` is compared against, on the same scale. */
88 // Link quality of the packets that produced `movement_metric`, carried here
89 // so the shared status logger stays a formatter instead of querying the radio
90 // itself at print time.
91 /** RSSI of the packets behind this metric. `INT8_MIN` when unknown. */
92 int8_t link_rssi_dbm{INT8_MIN};
93 /** Wi-Fi channel those packets arrived on. Zero when unknown. */
94 uint8_t link_channel{0};
95 /** Startup calibration is running; detection results are not valid yet. */
96 bool calibrating{false};
97 /**
98 * Packets observed by the current Lightweight startup calibrator.
99 *
100 * Zero when calibration is not running. Lightweight can finish early once
101 * motion evidence is accepted, so this may stay below `calibration_target_packets`.
102 */
104 /**
105 * Packet budget for the current Lightweight startup calibrator.
106 *
107 * Zero when calibration is not running. `csi:`/`miss:` on the status heartbeat
108 * are last-second pipeline rates, not remaining calibration work.
109 */
111 /**
112 * The runtime is calibrated, linked, and its output is safe to act on.
113 *
114 * Gate every user-visible publication on this. It goes false again when the
115 * Wi-Fi link drops.
116 */
117 bool ready_to_publish{false};
118 /** Threshold startup calibration settled on. Zero before it completes. */
119 float startup_threshold{0.0f};
120 /**
121 * Active detector label: `"lightweight"`, `"high_accuracy"`, or `"stream"` under
122 * `RuntimeProfile::STREAM`.
123 *
124 * Always a static string literal, so it stays valid for the process, but the
125 * pointer changes when the detector changes. `parse_detection_algorithm()`
126 * turns it back into a `DetectionAlgorithm`. Note these are the protocol
127 * names, not `BaseDetector::get_name()`, which is capitalized for logs.
128 */
129 const char *detector_name{"unknown"};
130 /** How `fixed_subcarriers` was chosen. */
132 /** Subcarrier indices the detector is measuring on. */
134};
135
136} // namespace espectre
constexpr SelectedSubcarriers make_default_subcarriers()
Definition csi_types.h:34
std::array< uint8_t, HT20_SELECTED_BAND_SIZE > SelectedSubcarriers
Definition csi_types.h:32
constexpr float RUNTIME_SEGMENTATION_THRESHOLD_DEFAULT
MotionState
Debounced detector state.
RuntimeSubcarrierSource
How the runtime chose the subcarriers it measures on.
@ FIXED_DEFAULT
The fixed band validated for the shipped detectors.
The schema behind RuntimeConfig: enums, defaults, and valid ranges.
Low-frequency counters and radio state used by optional diagnostic surfaces.
uint32_t csi_window_slots
Total slots in the configured detector window.
uint64_t csi_stale_total
Packets rejected because processing began after the active window.
uint64_t csi_accepted_total
CSI packets accepted by capture validation, before temporal admission.
uint64_t csi_callbacks_total
Raw invocations of the ESP-IDF CSI callback.
uint64_t csi_excess_total
Valid packets dropped because their temporal slot was already occupied.
uint32_t csi_occupancy_slots
Valid slots in the current detector window.
uint64_t traffic_packets_total
Traffic packets sent or observed by the active traffic source.
uint8_t wifi_channel
Primary channel of the current Wi-Fi association.
uint64_t csi_filtered_total
CSI packets rejected by capture-level validation.
uint64_t csi_out_of_order_total
Packets rejected because their timestamp moved backwards.
uint64_t csi_missing_slots_total
Empty temporal detector slots observed before admitted packets.
uint64_t csi_admitted_total
CSI packets admitted to the detector's temporal grid.
int8_t wifi_rssi_dbm
RSSI of the current Wi-Fi association.
A consistent view of the sensing state at one instant.
uint32_t calibration_packets
Packets observed by the current Lightweight startup calibrator.
float startup_threshold
Threshold startup calibration settled on.
MotionState motion_state
Debounced motion state, after the motion_on_hits / motion_off_hits filter.
uint8_t link_channel
Wi-Fi channel those packets arrived on.
bool ready_to_publish
The runtime is calibrated, linked, and its output is safe to act on.
int8_t link_rssi_dbm
RSSI of the packets behind this metric.
float movement_metric
Current motion metric, on a 0..1 probability scale for both detectors.
uint16_t calibration_target_packets
Packet budget for the current Lightweight startup calibrator.
bool calibrating
Startup calibration is running; detection results are not valid yet.
const char * detector_name
Active detector label: "lightweight", "high_accuracy", or "stream" under RuntimeProfile::STREAM.
RuntimeSubcarrierSource subcarrier_source
How fixed_subcarriers was chosen.
float threshold
Threshold movement_metric is compared against, on the same scale.
SelectedSubcarriers fixed_subcarriers
Subcarrier indices the detector is measuring on.