# 石头同频匹配方案说明

## 1. 业务背景

用户将自己的"本命石"放到设备的 VEML7700 环境光传感器上，录入光源信息。社交场景下，将其他用户的石头放到传感器上检测，如果两块石头"同频"则匹配交友成功。

**核心挑战**：录入和匹配可能发生在完全不同的光照环境下（室内/室外/阴天/晴天），算法需要在不同环境下仍能正确识别"同一类"石头。

## 2. 为什么旧方案（绝对 Lux 值比较）不可靠

### 旧方案逻辑
```
差异% = |lux_A - lux_B| / max(lux_A, lux_B) × 100%
如果 ALS差异 < 30% 且 White差异 < 30% → 匹配成功
```

### 实测数据（同一块石头，同一设备）

| 条件 | ALS (lux) | 与录入值差异 |
|------|----------|------------|
| 无遮挡（录入时） | 43.97 | 基准 |
| 无遮挡（匹配时） | 42.29 ~ 47.17 | 2% ~ 7% |
| 手掌遮挡10cm | 22.79 ~ 34.74 | **21% ~ 48%** |

**问题**：同一块石头仅因为手掌遮挡（模拟不同光照环境），Lux 绝对值就变化了近 50%。在实际场景中（室内 vs 室外），差异会更大（可达数十倍），30% 阈值无论怎么调都无法同时满足：
- 同石头不同环境 → 能匹配上
- 不同石头同环境 → 不会误匹配

**根因**：Lux 绝对值 = 石头光学特征 × 环境光强度。环境变了，绝对值就完全不同。

## 3. 新方案：双维度匹配（光谱比值 + 亮度等级）

### 核心思想

把"石头的固有属性"和"环境因素"分离：

- **光谱比值 (ALS/White)**：反映石头对不同波长光的透过/反射比例，是石头材质和颜色的**固有特征**，不随光照强度变化
- **亮度等级**：反映当前光照环境，用于排除极端环境差异下的误匹配

### VEML7700 双通道原理

| 通道 | 光谱响应 | 物理含义 |
|------|---------|---------|
| ALS | 模拟人眼光视函数（偏绿光 555nm） | 人眼感知亮度 |
| White | 宽谱响应（近似全波段） | 总辐射能量 |

**ALS/White 比值**反映的是光线经过石头后的光谱分布变化。不同材质/颜色的石头对光谱的改变不同，因此比值不同。而同一块石头无论光多强多弱，比值基本不变。

### 实测数据验证

用上一轮测试数据反向计算比值：

| 条件 | ALS | White | **ALS/White 比值** | 比值波动 |
|------|-----|-------|--------------------|---------|
| 无遮挡（录入） | 43.97 | 50.25 | **0.875** | 基准 |
| 无遮挡 #1 | 42.29 | 48.95 | **0.864** | -1.3% |
| 无遮挡 #4 | 44.90 | 51.89 | **0.865** | -1.1% |
| 无遮挡 #5 | 46.82 | 54.07 | **0.866** | -1.0% |
| 手掌轻遮挡 | 33.46 | 41.82 | **0.800** | -8.6% |
| 手掌重遮挡 | 24.01 | 34.45 | **0.697** | -20.3% |

**关键发现**：
- **无遮挡条件下比值波动仅 ±1.3%**（Lux 绝对值波动 ±7%）
- 手掌遮挡时比值也有偏移（手掌吸收了部分光谱），但偏移幅度从绝对值的 47% 降低到比值的 20%
- 不同材质石头的比值差异会大于同材质石头的环境波动

## 4. 匹配算法详细设计

### 判定条件

**同时满足以下两个维度才算匹配成功：**

#### 维度1：光谱比值匹配（判断石头是否为同类）
```
ratio_A = ALS_A / White_A  （本命石）
ratio_B = ALS_B / White_B  （对方石）
差异% = |ratio_A - ratio_B| / max(ratio_A, ratio_B) × 100%

如果 差异% ≤ 15% → PASS
```

#### 维度2：亮度等级匹配（排除极端环境差异）
```
亮度等级划分：
  0 = 极暗  (<5 lux)
  1 = 暗    (5 ~ 50 lux)
  2 = 中    (50 ~ 500 lux)
  3 = 亮    (500 ~ 5000 lux)
  4 = 极亮  (>5000 lux)

如果 |等级_A - 等级_B| ≤ 1 → PASS（允许相差1个等级）
```

### 为什么这样设计

| 设计决策 | 理由 |
|---------|------|
| 比值阈值 15% | 无遮挡同石头波动约 1~2%，留足余量给不同环境（如手掌遮挡约 8~20%）。不同材质石头比值差异通常 >20% |
| 亮度等级用对数划分 | 人眼对亮度的感知是对数的；室内/室外的亮度差异是数量级的（10 lux vs 10000 lux）|
| 允许相差 1 个等级 | 同一环境内亮度波动可能跨越等级边界（如 48 lux vs 52 lux 分属"暗"和"中"）|
| 3 次采样取中位数 | 过滤传感器偶发异常读数（实测中观察到单次异常偏低 50% 的情况）|

### 匹配场景预测

| 场景 | 比值匹配 | 亮度等级 | 结果 | 说明 |
|------|---------|---------|------|------|
| 同石头 + 同光照 | ✅ (~1-2%) | ✅ 同级 | **匹配** | 理想场景 |
| 同石头 + 略有遮挡 | ✅ (~8%) | ✅ 同级 | **匹配** | 手遮一下不影响 |
| 同石头 + 室内→遮挡严重 | ⚠️ (~15-20%) | ✅ 可能同级 | **概率匹配** | 趣味性 |
| 同石头 + 室内→室外 | ✅ (~1-5%) | ❌ 差2+级 | **不匹配** | 环境差异过大 |
| 不同石头 + 同光照 | ❌ (>20%) | ✅ 同级 | **不匹配** | 不同材质 |
| 不同石头 + 不同光照 | ❌ | ❌ | **不匹配** | 双重不匹配 |
| 相似材质石头 + 同光照 | ✅ (<15%) | ✅ | **匹配** | 有缘！ |

## 5. NVS 存储结构

| NVS Key | 类型 | 说明 |
|---------|------|------|
| `ratio` | int32 | 光谱比值 × 10000（如 0.875 存为 8750）|
| `als_lux` | int32 | ALS Lux × 100 |
| `white_lux` | int32 | White Lux × 100 |
| `br_level` | int32 | 亮度等级 (0~4) |
| `valid` | int32 | 1=已录入 |
| `ratio_th` | int32 | 比值匹配阈值%（默认 15）|
| `lux_th` | int32 | 亮度容差阈值%（默认 50，预留）|

## 6. 阈值调节指南

### 比值阈值 (`ratio_th`)

| 值 | 效果 | 适用场景 |
|----|------|---------|
| 5% | 极严格，几乎只有完全相同的石头能匹配 | 精确识别 |
| 10% | 严格，同材质同颜色可匹配 | 科学实验 |
| **15%** | **推荐默认**，兼顾准确性和社交趣味性 | **正常社交** |
| 20% | 宽松，相近材质也能匹配 | 破冰社交 |
| 30% | 非常宽松，大多数石头都能匹配 | 活动促进 |

### 亮度等级容差

当前固定允许相差 1 个等级。如果后续需要更灵活，可以通过 `lux_th` 字段扩展。

## 7. 相对于旧方案的优势

| 维度 | 旧方案（绝对Lux） | 新方案（比值+等级） |
|------|-------------------|-------------------|
| 环境光鲁棒性 | ❌ 光照变化直接导致失败 | ✅ 比值不随光强变化 |
| 石头区分能力 | ⚠️ 不同石头同环境可能误匹配 | ✅ 不同材质比值不同 |
| 偶发异常防护 | ❌ 单次读取 | ✅ 3次采样取中位数 |
| 极端环境保护 | ❌ 无 | ✅ 亮度等级兜底 |
| 匹配趣味性 | ⚠️ 要么全过要么全挂 | ✅ 物理属性+环境=概率匹配 |

## 8. 用户使用指南与注意事项

### 操作方式

本设备为吊坠产品，检测石头时用食指和大拇指捏住石头，贴紧设备传感器区域进行检测。

- **双击** KEY4 按键：录入本命石（等待提示后保持 3 秒）
- **长按** KEY4 按键 2 秒：匹配对方石头

### 操作规范

| 要求 | 说明 | 原因 |
|------|------|------|
| 石头贴紧传感器 | 尽量让石头紧贴传感器区域，减少缝隙 | 缝隙大小变化会引入环境光干扰 |
| 检测期间保持稳定 | 按键触发后保持手和石头不动约 3 秒 | 设备需要 3 次采样取中位数，晃动会影响数据 |
| 手指不要覆盖传感器 | 手指捏石头两侧即可，不要让手指遮挡传感器正上方 | 手指皮肤会吸收特定波长光线，改变光谱比值 |

### 推荐使用环境

| 环境 | 推荐度 | 说明 |
|------|--------|------|
| 室内正常照明（日光灯/LED灯） | 推荐 | 光照稳定，匹配成功率最高 |
| 室外阴天/树荫下 | 推荐 | 光照均匀，无强烈直射光干扰 |
| 室外晴天（非暴晒） | 可用 | 注意避免阳光直射传感器 |
| 暗室/关灯房间 | 不推荐 | 光照不足（<5 lux），传感器信噪比降低 |
| 强烈阳光直射 | 不推荐 | 传感器可能饱和，且手指阴影影响大 |

### 录入和匹配的环境一致性

**录入和匹配不要求在完全相同的环境下进行**，但需要注意：

- 同一亮度等级内（如都在室内），匹配成功率最高
- 跨越 1 个亮度等级（如室内录入 → 走廊匹配），仍可匹配
- 跨越 2 个及以上等级（如室内录入 → 室外烈日匹配），会被系统判为环境差异过大而拒绝匹配
- **如果频繁匹配失败，可以在当前环境下重新录入本命石**，然后再匹配

### 实测数据参考（手指捏石头姿势）

以下为同一块石头、同一环境、每次故意变化捏持角度和松紧度的 5 次匹配测试：

| 次序 | 光谱比值差异 | ALS亮度差异 | 结果 |
|------|-----------|-----------|------|
| 1 | 1.6% | 7.3% | 匹配成功 |
| 2 | 2.3% | 1.3% | 匹配成功 |
| 3（角度变化） | 6.6% | 5.9% | 匹配成功 |
| 4（角度变化大） | 9.6% | 3.1% | 匹配成功 |
| 5（松紧变化） | 5.4% | 9.7% | 匹配成功 |

**结论**：手指捏持姿势变化对比值的影响在 1.6%~9.6%，远低于 15% 匹配阈值，具有充足的安全余量（5.4%），正常操作下不会因姿势差异导致匹配失败。

### 常见问题

| 问题 | 原因 | 解决方法 |
|------|------|---------|
| 同一块石头反复匹配失败 | 录入和匹配时光照环境差异过大 | 在当前环境重新双击录入，再匹配 |
| 不同石头总是能匹配上 | 两块石头材质/颜色极其相近 | 这属于"有缘"，是正常现象 |
| 录入提示传感器未初始化 | VEML7700 传感器硬件连接异常 | 重启设备，检查硬件 |
| 匹配结果显示"光照环境差异过大" | 录入（室内）和匹配（室外）跨度过大 | 在相近光照环境下操作 |
