ESPectre Wi-Fi CSI 数据集采集指南:用 `espectre collect` 采集 empty / static_presence / motion 标注数据
2026/9/16 17:08:28 网站建设 项目流程

ESPectre Wi-Fi CSI 数据集采集指南:用espectre collect采集 empty / static_presence / motion 标注数据

【免费下载链接】espectreWi-Fi CSI motion sensing for ESP32. C++ SDK, ESPHome, Native, and Matter frontends, browser tools, and a CLI for the full device lifecycle. GPLv3 and commercial licensing.项目地址: https://gitcode.com/GitHub_Trending/es/espectre

本指南面向 ESPectre(ESP32 上的 Wi-Fi CSI 人体感知)数据集贡献者,完整讲解 v3 主线的emptystatic_presencemotion三类标注数据的采集流程:从环境准备、espectre collect命令实战,到data/dataset_info.json目录维护、NPZ 文件格式契约、质量校验与隐私规范。读完本文,你将能够独立完成一次"采集 → 归档 → 验证"的完整数据贡献闭环,并理解采集链路背后的源码级原理。

采集范围(Scope):v3 主线三类标签

当前 v3 数据集采集优先级固定在以下三种房间状态标签,它们直接喂给生产二分类 ML 工作流:

标签含义ML 映射
empty安静房间,无人在场IDLE
static_presence有人在房间但基本静止IDLE
motion普通房间活动MOTION

Gesture(手势)、HAR(人体活动识别)、people-counting(人数统计)数据集是可能的扩展方向,但不是当前 v3 主线采集目标。整段采集必须保持标签同质(homogeneous),混合会话不属于当前 v3 数据集契约的一部分。

支持的采集链路

主采集路径是:

CSI-capable ESPectre frontend -> ExternalTrafficGenerator UDP marker -> connection-bound GET /espectre/v1/csi response -> ./espectre collect -> one .npz per device_id

在源码层面,该链路由 src/python/espectre_cli/host.py 的_prepare_raw_http_collection依次完成:解析 Direct 端点 → 检查capabilities资源确认raw HTTP v1与外部流量标记 →PATCH /espectre/v1/sensing持久化csi_traffic_mode=external→ 校验配置已生效 → 打开未节流的原始 HTTP 流。外部 UDP 生成器复用 tools/espectre_traffic_generator.py 中的ExternalTrafficGenerator类,采集器与独立脚本共用同一实现。本指南假设你已有一台可用的 raw-capable ESPectre 设备在运行并可达(固件搭建见 docs/SETUP.md)。

快速开始

从仓库根目录准备环境:

python3 -m venv .venv source .venv/bin/activate python -m pip install -r requirements.txt

Windows PowerShell 用户改用.venv\Scripts\Activate.ps1激活,并把./espectre替换为.\espectre.cmd

先不做标注,检查实时流是否工作:

./espectre collect --target 192.168.1.50

然后按标签录制带标注数据:

./espectre collect --label empty --duration 60 --target 192.168.1.50 ./espectre collect --label static_presence --duration 60 --target 192.168.1.50 ./espectre collect --label motion --duration 60 --target 192.168.1.50

每条命令会在data/<label>/下写入一个.npz文件,并在data/dataset_info.json中登记一条记录。

espectre collect命令详解

./espectre collect是采集工作流的主机侧入口,一条命令支持三种模式:

  • 实时检视(live inspection):省略--label,只观察不落盘;
  • 实时录制(live recording):设置--label,满足就绪门(ready gate)后开始保存;
  • 只读盘点(read-only inventory)--info直接读取data/dataset_info.json输出统计。

参数定义来自 src/python/espectre_cli/app.py 的_add_collect_parser

参数作用默认值
--target/-tDirect IP、主机名、完整 HTTP 端点或 device ID;省略时自动发现 raw-capable 设备自动发现
--frontend限制自动发现到nativeesphomematter前端之一
--source-ip多网卡主机上指定本地 IPv4 源地址
--duration/-dN 秒后停止;与--start-delay搭配时必填无(录到 Ctrl+C)
--label/-l保存用的数据集标签(1-64 位 ASCII 字母/数字/下划线/连字符);省略则不保存
--start-delay开始前等待 N 秒(方便操作者离开房间);必须配合--duration0.0
--pps外部 UDP 生成器速率与名义数据集节拍100
--detector就绪门使用的检测档案:lightweighthigh_accuracy;逗号分隔列表仅用于并行实时对比lightweight
--ready-stable-seconds保存开始前检测器须低于阈值的秒数;0关闭就绪门3.0
--contributor/-c贡献者标识(默认取 git user.name)自动
--description样本描述自动生成
--info/-i显示数据集统计(只读)关闭

目标解析与设备发现

省略--target时,collect执行一次_espectre._tcp.local.mDNS 浏览并只保留带csi能力的记录:0 台设备直接报错并建议--target;1 台自动选中;多台进入交互选择。发现完成采用事件驱动:完整记录到达后 350ms 无变更即结束,无记录时耗尽 2.5 秒超时。

--target是确定性旁路,支持 IP、主机名、完整 Direct 端点或完整 16 位十六进制 device ID(见 src/python/espectre_cli/host.py 的_resolve_collect_target_via_discovery)。Native、Matter、ESPHome 前端统一使用端口62587;手工输入完整端点可指定其他端口,但解析器不会探测遗留端口。对通过发现选中的目标,采集器还会校验 CSI 记录携带的device_id与 mDNS 广播一致——若地址被其他设备复用,采集会中止而不是把混台数据存错身份。

实时链路:外部流量标记与持久化 external 模式

采集器先协商 CSI 能力,然后PATCH sensingcsi_traffic_mode持久化为external,校验资源生效后,先启动ExternalTrafficGenerator再打开GET /espectre/v1/csi原始 HTTP 流。外部流量标记是精确的四字节 UTF-8 载荷"👻".encode("utf-8")F0 9F 91 BB),发送到能力通告的 UDP 端点。HTTP 侧不做任何节流或抽取(no pacing, no decimation)——外部生成器是唯一的速率所有者。采集结束后生成器停止,但设备会故意保持在external模式(不恢复先前状态),collect在终端也会提示这一点。

生成器实现见 tools/espectre_traffic_generator.py:默认端口5555、单播每个设备 IP 或加入组播组239.255.0.1,推荐 100 pps;工具文件头明确警告不要向子网/受限广播地址发包,因为那些帧通常以 legacy PHY 到达、不会产生 HT20 CSI。SENSING_IP_TOS = 46 << 2为低时延标记,next_send_deadline保持请求速率的相位而不做追赶式补偿发包。

保存语义(Save Semantics)

  • 就绪门(ready gate):只有就绪门满足后才开始保存;对lightweight,这发生在启动标定(startup calibration)完成之后;high_accuracy使用其生产特征窗口、不运行启动标定;
  • --detector的语义lightweight在就绪前会执行其正常启动标定;high_accuracy无需启动标定,但仍需填满特征窗口;定时采集只接受一种档案,实时检视可以lightweight,high_accuracy并行对比;
  • Ctrl+C 行为:在--duration结束前中断,会中止本次部分实时采集且不落盘;未指定--duration时,Ctrl+C 保存已接受的包;
  • 保存后即检:每保存一个采集,采集器就运行验证器的逐文件完整性、信号质量、时间占用与流连续性检查(见 src/python/espectre_cli/host.py 的_run_post_collect_quality_checks)。时间占用在完整生产检测器窗口上测量,低于 85% 警告、低于 70% 准入失败;失败文件仍保留用于诊断,但collect以失败码退出。

采集链路数据平面源码

DirectRawCSIReceiver(tools/lib/csi_io.py)负责 Direct HTTP 原始流:先GET capabilities验证transport=httpprotocol_version=1record_version=8(V8)与帧前缀长度,再GET device记录前端、固件版本与固件身份,然后GET /espectre/v1/csi绑定连接。V8 HTTP 帧头(RAW_CSI_HTTP_FRAME_STRUCT)携带 session id、stream_sequencerecord_len、flags、fresh_totalraw_drop_totalbackpressure_total等计数器,接收端逐帧校验这些计数器的一致性。采集结束时通过GET diagnostics?fields=["raw_csi"]回读最终计数器,验证不变量fresh_record_total + raw_drop_total == classified_frames_offered_to_raw,从而暴露网络发送前的任何隐藏丢失。

标签(Labels)

当前规范房间状态标签:

  • empty:安静房间,无人在场;
  • static_presence:人在场但基本静止;
  • motion:普通房间活动。

仅当整段采集同质时才使用这些标签。安静的长时间回放(quiet long-run replays)也归入empty,并在dataset_info.json中标记long_recording: true,供验证与长录制套件定位。训练器会将这些录制排除在拟合之外,但selectionholdout的长录制仍参与静音回放门。

一次会话的建议流程:

  1. 采集empty
  2. 采集static_presence
  3. 采集motion
  4. 为每条新记录在data/dataset_info.json中添加environment和显式dataset_role
  5. 运行./espectre collect --info
  6. 运行python tools/validate_dataset_quality.py

推荐的起点:每个样本 30–60 秒;每个标签至少 10 个样本;一次只在一个环境采集;在同一环境内变化位置与距离。

原始记录元数据(Raw Record Metadata)

原始 HTTP 流携带 CSI V8 记录,其元数据对分析与验证很有价值:

  • device_ticks_us:设备单调时间戳;
  • wifi_rx_ts_us:Wi-Fi RX 时间戳(可用时);
  • wifi_rx_start_ts_ns:RX 起始估算(可用时);
  • RF 上下文:channelrssi_dbmnoise_floor_dbm

这些字段由 tools/lib/csi_io.py 的parse_csi_record从 V7/V8 记录头解析(CSI_HEADER_FORMAT),并在CSIPacket中保留。NOISE_FLOOR_INVALID_DBM = -128作为固件未覆盖目标时的哨兵值,远低于 20 MHz 信道热噪声,永远不可能是真实测量值。CSI 采用 Espressif 顺序[Q0, I0, Q1, I1, ...]

数据集目录布局

目录结构:

data/ ├── dataset_info.json ├── empty/ ├── static_presence/ └── motion/

典型文件名:

{label}_{chip}_{num_sc}sc_{device_token}_{timestamp}_{save_index}.npz

例如data/static_presence/下的真实文件static_presence_c6_64sc_dev00007c2c6742bbac_20260704_153259_586375_0001.npz,对应 C6 芯片、64 逻辑子载波、伪匿名设备 tokendev00007c2c6742bbac、2026-07-04 采集时间戳与保存序号(命名逻辑见 tools/lib/csi_io.py 的_generate_filename)。当前所有 ESPectre 数据集使用 HT20 CSI、64 逻辑子载波;训练与验证加载器因此把缺少逐记录 PHY 元数据的采集标记为ht20,而新的 raw HTTP 采集保留显式 PHY 与 LTF 元数据。

dataset_info.json元数据

data/dataset_info.json是数据集级索引(当前format_version1.2,见 tools/lib/dataset_metadata.py 的DATASET_FORMAT_VERSION)。它存储每条记录的:

  • filename
  • chipsubcarriers
  • device_id
  • contributor
  • collected_at
  • duration_msnum_packetsaverage_packet_ratenominal_packet_rate
  • descriptionenvironment
  • optimal_pair_motion_file/optimal_pair_static_presence_file:静态在场与运动之间的互反配对;
  • low_rssi: true:真实与合成的弱链路数据集,存放在语义标签目录下。流连续性准入对缺失序列记录在 1% 以上告警、常规录制 3% 以上失败、low_rssi录制 5% 以上失败;最大序列间隔与包间隔门保持不变;
  • synthetic: true:非真实测量的生成采集;
  • long_recording: true:保留给长录制回放套件的静音长程empty采集,只用于评估,不进入 ML 训练或标准空房间准入表;dataset_role: exclude的长录制仍留在目录中供溯源与质量报告诊断;
  • dataset_role: train | selection | holdout | exclude:控制记录如何参与拟合与部署回放。训练器把缺失角色视为exclude以保证安全,但数据集验证会一直失败,直到每条记录显式声明角色。selection记录把关候选选择,holdout记录保持密封直到训练器对最终胜出者做一次性评估,exclude保留记录在目录中但移出当前 train/selection/holdout 流程。

新条目示例:

{ "filename": "static_presence_c6_64sc_dev...npz", "environment": "bedroom", "dataset_role": "exclude" }

可比记录使用同一环境名。不要手工添加配对字段:验证器会在必需的手工元数据就绪后自动推导互反的静态在场/运动配对。tools/validate_dataset_quality.py在准入与共享特征空间评审前自动重生成这些配对字段,且绝不会把真实采集与合成采集配对——生成配对的标识从 NPZ 元数据中读取。

从 data/dataset_info.json 可以看到真实归档实践:同一条environment(如bedroom)内多个芯片(C3/C5/C6/S3/ESP32)的样本,dataset_role覆盖train/selection/holdout/exclude四种状态,弱链路样本统一标low_rssi: true,并注明"AP is in hobby room"等环境说明。仓库不再携带合成生成器,当前模型晋升依赖真实采集;遗留生成 NPZ 中的syntheticsource_datasetlow_rssi_profilegeneration_mode等字段是向后兼容的自描述遗留契约,运行时包加载器会忽略它们。

NPZ 契约

每个.npz文件存储原始 CSI 加采集元数据。当前采集器字段(保存实现见 tools/lib/csi_io.py 的CSICollector.save_sample):

字段类型含义
csi_dataint8[N, SC*2]原始 I/Q 数据
num_subcarriersint逻辑子载波数,当前64
labelstr数据集标签
chipstr芯片标识
collected_atstrISO 时间戳
duration_msfloat采集时长
format_versionstr数据集格式版本
stream_seq_numuint32[N]流序列号
raw_stream_sequenceuint64[N]规范 raw HTTP 序列号(含可观测缺口)
device_ticks_usuint64[N]设备单调时间戳
phy_modestr[N]逐记录 PHY 模式;当前感知行使用ht
ltf_typestr[N]逐记录 LTF 类型;当前感知行使用ht-ltf
channel_widthstr[N]逐记录信道宽度;当前感知行使用20
device_iduint64稳定的伪匿名设备标识
transportstr实时传输方式,新采集为http
endpointtransport_targetstr采集所用的 Direct raw 端点
requested_ppsfloat每个目标请求的外部生成器速率
observed_ppseffective_ppsfloat采集器观察到的接收速率
raw_protocol_versionuint8raw HTTP 协议版本,当前1
record_versionuint8CSI 记录版本,实时采集当前为8
frontendstr设备前端(nativeesphomematter
firmware_versionfirmware_identitystrDirectdevice资源报告的固件溯源
fresh_record_totalraw_fresh_record_totaluint64最终已发送记录计数器
raw_drop_totaluint64未传输的 raw 记录最终计数
send_backpressure_totalraw_send_backpressure_totaluint64最终发送失败背压计数器
raw_final_stream_sequenceuint64最终 offered-frame 序列,与最终计数器一起校验 raw 丢失不变量
csi_target_ppsuint64回放用的名义时间准入速率
detector_admitted_packetsuint64采集评审中生产时间采样器接受的记录数
temporal_missing_slotstemporal_excess_packetsuint64缺失的名义时隙与超过配置时隙节拍的记录数
temporal_stale_packetstemporal_out_of_order_packetsuint64因过期或乱序时间戳被拒的记录数
temporal_occupancy_slotstemporal_window_slotsuint64用于计算平均时间占用的已占用与可用时隙
wifi_rx_ts_usuint32[N]可选的 Wi-Fi RX 时间戳
wifi_rx_start_ts_nsuint64[N]可选的 RX 起始估算
channeluint8[N]可选的逐包 Wi-Fi 信道
rssi_dbmint16[N]可选的 RSSI 元数据
noise_floor_dbmint16[N]可选噪声底元数据

时间准入溯源字段(temporal_*csi_target_pps)在保存时由TemporalCsiSampler对包时间戳执行名义节拍重放计算得出。CSI 采用 Espressif 顺序[Q0, I0, Q1, I1, ...]

幅值与相位提取:

Q = csi_data[:, 0::2].astype(float) I = csi_data[:, 1::2].astype(float) amplitudes = np.sqrt(I**2 + Q**2) phases = np.arctan2(Q, I)

加载数据

最小示例(直接读取磁盘上的原始数组,含任何非 HT20 行):

import numpy as np data = np.load("data/static_presence/sample.npz") csi_data = data["csi_data"] label = str(data["label"])

使用工具库(默认 HT20 感知视图):

from pathlib import Path from tools.lib.csi_io import load_npz_as_packets packets = load_npz_as_packets(Path("data/static_presence/sample.npz"))

load_npz_as_packetsload_npz_csi_data(tools/lib/csi_io.py)默认暴露生产感知视图:phy_mode=htltf_type=ht-ltfchannel_width=20,以及存储的 64 子载波 HT20 布局(filter_npz_arrays_sensing通过ht20_packet_mask过滤)。历史采集如果完全缺失逐记录 PHY 元数据,只有当磁盘载荷已经匹配同样的 64 子载波契约时才被接受。部分缺失 PHY 元数据(部分数组存在、部分缺失)会被拒绝而非默认填充:引入 PHY 溯源后记录的采集应当携带每个字段,缺失即标记文件可疑,且不回退到legacy行。传keep_all_phy=True可显式检查混合 PHY 或不支持的采集。数据集质量验证与 C++ 测试 NPZ 加载器使用同一过滤视图,因此过量的非感知行丢弃会表现为流连续性缺口。加载路径同时做了安全加固:allow_pickle=False并拒绝 pickle 背书的 object 数组(_raise_unsafe_npz_object_array),并会把旧式 classic 顺序的 HT20 行旋转到 centered 约定(normalize_stored_csi_bin_layout)。

采集注意事项(Collection Notes)

  • 采集中 AGC 保持开启;
  • --pps控制外部 UDP 生成器与名义数据集速率;HTTP 不节流也不抽取记录;
  • 采集器停止后故意将设备留在external模式
  • 外部流量标记是精确的四字节 UTF-8 载荷"👻".encode("utf-8")F0 9F 91 BB),发往能力通告的 UDP 端点;
  • 固定训练与验证视图是 HT20 + HT-LTF + 64 子载波;运行时可能在原始 ESP32 与 ESP32-S2 上选择lltf20、或在 VHT 能力的 5 GHz 关联上选择vht20,但这些原始行保留其 PHY 元数据,且在本默认数据集视图之外;
  • 当前 ML 运行时与训练流程使用 docs/FEATURES.md 中定义的八个尺度不变生产特征。

数据集检视与验证

./espectre collect --info python tools/validate_dataset_quality.py python tools/train_ml_model.py --info

三者分工明确:

  • collect --info汇总已采集文件(按environment分表、每个标签一行、每个芯片一列),但分配环境或数据集角色;
  • python tools/validate_dataset_quality.py需要那些手工字段,刷新配对元数据,运行准入与质量评审,并更新data/auto_generated/DATASET_QUALITY_CHECK.md。平均有效时隙占用低于 85% 告警、低于 70% 准入失败并封顶所有受影响的评审分数;时间质量与 ML 就绪检查要求可用的记录包速率(或num_packetsduration_ms)。时间元数据不足是验证失败,绝不会被当作 100 pps。命令支持--chip--data-dir--preserve-pairs--diagnostic-all-phy--no-report--no-cache--check-current等选项(tools/validate_dataset_quality.py);
  • python tools/train_ml_model.py --info显示训练器使用的数据集视图。

在整理新条目之后、训练之前运行验证器。准入失败会阻断工作流;特征空间分数仅作诊断。数据集角色始终是手工的,验证器绝不会分配trainselectionholdout。命令变体与报告行为参见 tools/README.md 的 dataset inspection and validation 一节。

贡献数据

对当前项目方向最有价值的贡献:

  • 降低误报的empty采集;
  • 提升空闲鲁棒性的static_presence采集;
  • 覆盖不同芯片、路由器与房间布局的motion采集。

开 PR 之前:

  1. 尽量每个标签至少采集 10 个样本;
  2. 保持标签同质;
  3. 为每条目录记录添加稳定的环境名与显式数据集角色;
  4. 在描述中记录房间类型与异常环境条件;
  5. ./espectre collect --info验证数据集;
  6. 运行python tools/validate_dataset_quality.py并解决准入 FAIL。

数据隐私

CSI 采集不包含图像或音频,但并非天生匿名。持久的设备标识符、时间戳、贡献者姓名、环境标签、包级射频元数据,以及推断出的在场或活动信息,都可能识别个人或泄露敏感信息。

只在你有权采集的空间中采集数据,告知受影响的人,并遵守适用的隐私法律。开 pull request 前检查.npz元数据与data/dataset_info.json,移除不必要的可识别细节,并在归属不需要真实姓名时使用伪匿名贡献者值。不要提交 Wi-Fi 凭证、SSID、BSSID、本地 IP 地址、串口日志或无关个人信息。贡献者保留其数据的所有权,并在数据集文档中获得署名。DCO 与 CLA 要求见 CONTRIBUTING.md 的 DCO and CLA 一节。

下一步

  • docs/ML_TRAINING.md:模型训练、导出与回归检查;
  • docs/API.md:raw HTTP 帧格式与会话所有权;
  • tools/README.md:分析辅助工具;
  • docs/ALGORITHMS.md:检测器与特征定义;
  • 数据集契约的历史依据保留在 docs/adr/README.md 的 ADR 索引中。

【免费下载链接】espectreWi-Fi CSI motion sensing for ESP32. C++ SDK, ESPHome, Native, and Matter frontends, browser tools, and a CLI for the full device lifecycle. GPLv3 and commercial licensing.项目地址: https://gitcode.com/GitHub_Trending/es/espectre

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询