214 lines
4.4 KiB
Plaintext
214 lines
4.4 KiB
Plaintext
🧠 一、系统总体架构(通用版)
|
||
雷达输入(两种类型)
|
||
↓
|
||
统一存在检测层(Presence Layer)
|
||
↓
|
||
生理信号层(HR / RR / HRV / Movement)
|
||
↓
|
||
睡眠状态机(核心)
|
||
↓
|
||
睡眠分期
|
||
↓
|
||
事件检测(入睡 / 醒来 / 离床)
|
||
↓
|
||
统计 + 评分
|
||
🧩 二、雷达适配层设计(重点)
|
||
|
||
你要做的是:统一接口,底层适配
|
||
|
||
✅ 统一输出结构
|
||
typedef struct {
|
||
bool isPresent; // 是否有人
|
||
float distance; // 距离(无距离雷达填-1)
|
||
float confidence; // 存在置信度 0~1
|
||
float motionEnergy; // 微动能量(关键!)
|
||
} PresenceData;
|
||
🟢 情况1:支持距离雷达(如FMCW)
|
||
isPresent = (distance > 20cm && distance < 100cm)
|
||
&& (energy > threshold);
|
||
|
||
confidence = energy归一化;
|
||
|
||
👉 优势:
|
||
|
||
可以判断是否在床上
|
||
可以做“离床”精准检测
|
||
🔵 情况2:不支持距离(如存在检测雷达)
|
||
|
||
👉 用“微动 + 呼吸”判断
|
||
|
||
isPresent = (motionEnergy > lowThreshold)
|
||
|| (检测到呼吸信号);
|
||
|
||
confidence = motionEnergy归一化;
|
||
⚠️ 关键优化(必须做)
|
||
|
||
👉 防误判(静止误判无人):
|
||
|
||
if (HR 或 RR 有效)
|
||
isPresent = true;
|
||
🚶 三、有人 / 离床 / 无人逻辑(统一)
|
||
✅ 状态定义
|
||
NO_PERSON
|
||
IN_BED
|
||
OUT_OF_BED
|
||
🧾 通用逻辑
|
||
if (!presence.isPresent) {
|
||
noPersonTimer += dt;
|
||
|
||
if (noPersonTimer > 10min) {
|
||
state = NO_PERSON;
|
||
endSleepSession();
|
||
} else {
|
||
state = OUT_OF_BED;
|
||
awakeTime += dt;
|
||
}
|
||
|
||
} else {
|
||
noPersonTimer = 0;
|
||
|
||
// 有距离版本
|
||
if (presence.distance > 80cm)
|
||
state = OUT_OF_BED;
|
||
else
|
||
state = IN_BED;
|
||
}
|
||
😴 四、入睡判断(统一方案)
|
||
✅ 输入
|
||
HR(心率)
|
||
RR(呼吸)
|
||
HRV
|
||
Movement(0~100)
|
||
📐 Sleepiness Score
|
||
S = 0.35*(1 - HR_norm)
|
||
+ 0.25*(HRV_norm)
|
||
+ 0.20*(1 - RR_var)
|
||
+ 0.20*(1 - Movement_norm)
|
||
🧾 判定
|
||
if (S > 0.6 持续 5~10分钟)
|
||
→ 入睡
|
||
⚠️ 雷达适配补充
|
||
|
||
👉 无距离雷达必须加:
|
||
|
||
if (!presence.isPresent)
|
||
不允许入睡
|
||
🌙 五、睡眠分期(核心)
|
||
🧠 特征统一归一化
|
||
HR_norm = (HR - baselineHR)/20
|
||
RR_norm = (RR - baselineRR)/4
|
||
HRV_norm = HRV / 50
|
||
Move_norm= Movement / 100
|
||
🟢 深睡(Deep Sleep)
|
||
DeepScore =
|
||
0.4*(1 - HR_norm)
|
||
+ 0.3*(HRV_norm)
|
||
+ 0.2*(1 - Move_norm)
|
||
+ 0.1*(RR稳定)
|
||
|
||
条件加强版:
|
||
|
||
Movement < 10
|
||
HRV > baseline
|
||
🔵 浅睡(Light Sleep)
|
||
LightScore =
|
||
0.3*(HR适中)
|
||
+ 0.3*(HRV中)
|
||
+ 0.2*(Move 10~40)
|
||
+ 0.2*(RR稳定)
|
||
🔴 清醒(Awake)
|
||
AwakeScore =
|
||
0.5*(Move_norm)
|
||
+ 0.3*(HR_norm)
|
||
+ 0.2*(RR波动)
|
||
🧾 分类
|
||
max(Deep, Light, Awake)
|
||
⏰ 六、醒来判断
|
||
✅ 强规则(推荐)
|
||
if (Movement > 50 持续 2分钟)
|
||
→ 醒来
|
||
✅ 融合规则
|
||
if (HR ↑ && RR ↑ && Movement ↑)
|
||
→ 醒来
|
||
🚪 七、离床判断(通用版)
|
||
🟢 有距离雷达
|
||
if (distance > 80cm)
|
||
OUT_OF_BED
|
||
🔵 无距离雷达
|
||
if (!presence.isPresent 持续 > 30秒)
|
||
OUT_OF_BED
|
||
🧾 最终结束
|
||
if (无人 > 10分钟)
|
||
→ 结束睡眠
|
||
📊 八、睡眠统计
|
||
|
||
记录:
|
||
|
||
totalSleepTime
|
||
deepSleepTime
|
||
lightSleepTime
|
||
awakeTime
|
||
outOfBedTime
|
||
sleepLatency(入睡时间)
|
||
wakeCount
|
||
⭐ 九、睡眠评分系统
|
||
🎯 总分100
|
||
1️⃣ 时长(30)
|
||
7~9小时 → 满分
|
||
2️⃣ 深睡比例(25)
|
||
Deep / Total > 20%
|
||
3️⃣ 连续性(20)
|
||
醒来少 → 高分
|
||
4️⃣ 生理质量(15)
|
||
HRV高 + HR稳定
|
||
5️⃣ 入睡速度(10)
|
||
<20分钟
|
||
📐 总公式
|
||
Score =
|
||
0.3*duration +
|
||
0.25*deep +
|
||
0.2*continuity +
|
||
0.15*physiology +
|
||
0.1*latency
|
||
🔁 十、完整状态机(统一)
|
||
NO_PERSON
|
||
↓
|
||
IN_BED
|
||
↓
|
||
AWAKE
|
||
↓ (满足入睡)
|
||
LIGHT_SLEEP
|
||
↓
|
||
DEEP_SLEEP
|
||
↑↓
|
||
LIGHT_SLEEP
|
||
↓
|
||
AWAKE
|
||
↓
|
||
OUT_OF_BED
|
||
↓(10min)
|
||
END
|
||
⚙️ 十一、ESP32建议架构(实战)
|
||
🧵 任务划分(FreeRTOS)
|
||
Task1:雷达采集(Presence)
|
||
Task2:HR/RR/HRV计算
|
||
Task3:睡眠状态机(核心)
|
||
Task4:UI / MQTT上传
|
||
⏱ 更新周期
|
||
Presence:10~20Hz
|
||
HR/RR:1Hz
|
||
睡眠分析:1Hz
|
||
🚀 十二、关键工程优化(你必须做)
|
||
1️⃣ 防误判“无人”
|
||
if (HR有效 || RR有效)
|
||
强制 presence = true
|
||
2️⃣ 防抖动(超级关键)
|
||
状态必须持续 N 秒才切换
|
||
3️⃣ 数据无效保护
|
||
if (!HRV valid)
|
||
不参与深睡判断
|
||
✅ 总结(最核心一句话)
|
||
|
||
👉 这套方案本质是:
|
||
|
||
“雷达判断人 → 生理判断睡 → 时间保证稳定 → 状态机做最终决策” |