# 里程碑:数字人 RTC 项目(阉割版) > 单一形态产品:纯 AI 对话 + Live2D 数字人显示。剥离电子吧唧模式,简化代码、释放资源。 ## 1. 背景 主仓 `Baji_Rtc_Toy` 当前是"AI 对话 + 电子吧唧"双模式固件,所有共享底层(火山 RTC、Opus 编解码、BLE 配网、LCD/LVGL)已稳定。Hiyori 数字人透明 GIF 显示在 `Rtc_AIavatar` 分支已完成 PoC(背景图 + 透明 GIF 叠加方案)。 本里程碑目标:将 `Rtc_AIavatar` 分支演进为**独立产品形态**——只保留 AI 对话 + 数字人显示,移除全部电子吧唧业务,并将单一情绪 emoji 升级为多动态 GIF 表情。 ## 2. 业务目标 | # | 目标 | 衡量 | |---|------|------| | G1 | 屏蔽电子吧唧专属功能(**不物理删除,仅条件编译排除**) | 引入 `CONFIG_BAJI_BADGE_MODE` Kconfig 开关(默认 N);编译固件 .text 段较双模式版减小 ≥ 80KB;源代码保留以供后续借鉴 | | G2 | 数字人 GIF 替代静态 emoji | 至少 3 个 hiyori 表情通过 RTC 字幕情绪标签自动切换 | | G3 | RTC 对话字幕恢复显示 | 字幕实时显示在屏幕底部,不遮挡数字人 | | G4 | 资源容量满足 GIF 资源 | SPIFFS ≥ 6MB,装下 3 个高频表情 | | G5 | 低功耗与 RTC 联动 | 60s RTC 空闲自动断开连接 + 熄屏;任意键/语音唤醒 | | G6 | 保留所有必要业务 | BLE 配网(0xABF0)/WiFi/OTA/Function Calling(故事/音乐)/双向音频切换 全部可用 | | G7 | **保留吧唧代码可恢复性** | 在 Rtc_AIavatar 分支切换 `CONFIG_BAJI_BADGE_MODE=y` 后能重新编译出双模式固件 | ## 3. 范围 ### 3.1 In Scope(本里程碑做) - **新增 Kconfig 开关** `CONFIG_BAJI_BADGE_MODE`(默认 N,源代码不删) - **CMakeLists.txt 条件化** 编译:`if(CONFIG_BAJI_BADGE_MODE)` 包裹吧唧 srcs/ui screens - **源代码加 `#ifdef CONFIG_BAJI_BADGE_MODE`** 保护吧唧的调用点: - `main/dzbj/` 下吧唧专属模块的调用入口(device_mode/dzbj_ble/ble_transfer/dzbj_button[KEY2部分]/pages/fatfs/pages_pwm/dzbj_battery/dzbj_init) - `main/ui/screens/` 下 9 个吧唧 UI 屏幕的调用入口 - `application.cc` / `boards/movecall-moji-esp32s3/` 中的模式切换分支 - BOOT+KEY2 组合键切换模式逻辑 - 调整 `partitions.csv`:ota 双分区 4MB + SPIFFS 6MB - 准备 3 个 hiyori GIF(m03/m06/m07,gifsicle 处理 + 240×320 裁剪) - 实现"情绪标签 → 数字人 GIF"映射表(22 情绪 → 3 GIF) - 恢复 RTC 字幕显示在屏幕底部(半透明背景层) - 实现 RTC 60s 空闲超时 → 断开 + 熄屏 联动(sleep_mgr 改造为 RTC 联动版,原代码用 #ifdef 保护) **关键原则**:所有"屏蔽"动作 = 通过 Kconfig 关闭编译 + `#ifdef` 注释化调用,**源代码文件全部保留在 `main/dzbj/` 下作为参考**。 ### 3.2 Out of Scope(本里程碑不做) - ❌ 电子吧唧模式相关任何新功能 - ❌ Live2D 实时渲染(继续用预渲染 GIF 方案) - ❌ 云端 BLE OTA 推送 GIF(先用 SPIFFS 预烧) - ❌ 数字人表情动画过渡(GIF 间无淡入淡出) - ❌ Haru 角色(先只跑 Hiyori,Haru 留作后续里程碑) - ❌ 主仓 main 分支的修改(main 保持双模式基线不动) ## 4. 关键决策(已与用户对齐) | # | 决策项 | 选择 | |---|--------|------| | D1 | hiyori GIF 数量 | **精选 3 个最小**(m06+m07+m03,约 5.7MB) | | D2 | KEY2(GPIO4) 按键 | **完全删除**,仅保留 BOOT 单键配网 | | D3 | 低功耗熄屏机制 | **RTC 空闲超时联动**(复用 listening_idle_ticks_,60s 断开+熄屏) | | D4 | 字幕显示位置 | **屏幕底部 y=-70**(半透明背景,不遮挡数字人) | ## 5. 约束 | # | 约束 | 影响 | |---|------|------| | C1 | 硬件不变(ESP32-S3-N16R8 / 16MB Flash / 8MB PSRAM / ST77916 360×360 LCD) | 不能扩 Flash 解决资源问题 | | C2 | 主仓 main 保持双模式基线 | 本里程碑只在 `Rtc_AIavatar` 分支演进,不合并回 main | | C3 | 火山 RTC 协议层不动 | 复用现有 `protocols/volc_rtc_protocol.cc` | | C4 | 现有 BLE 配网协议不动 | APP 端无需适配 | | C5 | 中文字幕字体已存在 | 复用 font_puhui_20_4,不引入新字体 | ## 6. 成功标准(验收清单) 固件烧录后端到端验证: - [ ] 首次开机 → BLE 配网 APP 成功连接 → WiFi 凭据存入 NVS - [ ] 重启 → 自动连 WiFi → 进入 AI 对话主界面(背景图 + hiyori GIF + 状态栏) - [ ] 语音唤醒 AI → 字幕实时显示在屏幕底部 → 数字人 GIF 根据情绪标签切换(至少看到 3 种表情切换) - [ ] AI 调用 Function Call → 故事/音乐 HTTPS 播放正常 - [ ] 任意时刻 BOOT 单击 → 中断 AI 发言 - [ ] 60s 无对话 → 自动断 RTC + 熄屏;任意操作 → 唤醒 - [ ] 长按 BOOT 5s → 触发 WiFi 重置 → 回到配网模式 - [ ] OTA 升级流程可用(双分区切换) - [ ] 整机持续运行 30 分钟无内存泄漏、无重启 ## 7. 风险 | # | 风险 | 缓解 | |---|------|------| | R1 | sleep_mgr 与 RTC 空闲超时合并可能引入回归 | Phase 6 单独验证 + 旧 sleep_mgr 代码用 `#ifdef CONFIG_BAJI_BADGE_MODE` 保留可恢复 | | R2 | 3 个 GIF 装载切换可能与 RTC 音频争 PSRAM | Phase 4 监控 `heap_caps_get_free_size(MALLOC_CAP_SPIRAM)` | | R3 | Kconfig 条件编译可能漏掉某些隐式调用导致链接错误 | Phase 1 完成后开启 `CONFIG_BAJI_BADGE_MODE=y` 二次编译验证可恢复双模式(G7 验收) | | R4 | 字幕 z-index 与 GIF 冲突 | Phase 5 用 LVGL 容器层级控制,必要时改用 layer_top | | R5 | 分区表调整导致旧固件 OTA 兼容性 | 首次烧录用 `esptool.py write_flash`,OTA 在新分区基础上启用 | | R6 | `#ifdef` 散落各处后续不易维护 | Phase 1 任务最后产出一份 `BADGE_MODE_ISOLATION_MAP.md`,列出所有 `#ifdef` 边界 | ## 8. 状态 | 阶段 | 状态 | |------|------| | **当前** | 📝 规划中(已完成调研、决策对齐) | | 起始分支 | `Rtc_AIavatar`(commit `eb96130`) | | 目标分支 | `Rtc_AIavatar`(完成后 push 到 gitea + GitHub) |