按 GSD 框架 .planning/milestones/digital_human_rtc/ 规划完成 Phase 1。 源代码全部保留,通过 Kconfig 开关 + CMakeLists 条件编译 + #ifdef 调用点保护 实现"吧唧模式不进固件但代码可恢复"。 ## 核心变更 ### Kconfig 开关(默认关闭) - 新增 CONFIG_BAJI_BADGE_MODE(main/Kconfig.projbuild) - sdkconfig.defaults 默认 =n - =y 时恢复双模式(电子吧唧 + AI 对话) - =n 时仅 AI 数字人 RTC 模式 ### CMakeLists 剥离(剥离式不重写) - 9 个 dzbj/ 吧唧专属 + 9 个 ui/screens/ 吧唧 UI 进入 if(CONFIG_BAJI_BADGE_MODE) 条件块 - 公共保留: dzbj/lcd.c, ai_chat_ui.c, sprite_demo.c, dual_gif_demo.c, bg_gif_demo.c, pages_pwm.c, dzbj_init.c, fatfs.c - 修正 PLAN 漏判:dzbj_init/fatfs 公共化(AI 模式调用 dzbj_hw_display_init/DecodeImg) ### 调用点 #ifdef 保护 - application.cc: L20 include, L63-66 background_task, L536 device_mode 分支 - movecall_moji_esp32s3.cc: dzbj headers, init_spiffs_image_list extern, dzbj_boot_click_handler extern, device_mode_is_badge 分支, InitializeBadgeMode, InitializeBadgeModeButtons, mode_switch_combo 注册, device_mode_in_switch_suppress - 保留公共 extern: ai_chat_screen_init, ai_chat_resume_animation, pwm_init ### 整体文件级 #ifdef 包裹 - dzbj/dzbj_button.c/h - dzbj/sleep_mgr.c - sleep_mgr/include/sleep_mgr.h ### 6 个文件显式 #include "sdkconfig.h" - ESP-IDF 不会 force-include,必须手动 include 才能拿到 CONFIG_* 宏 ## G7 验收双向编译 - =n 模式 build: ✅ EXIT=0(数字人 RTC 单一形态) - =y 模式 build: ✅ EXIT=0(双模式恢复可用) ## 固件大小变化 | 段 | =n | =y | 节省 | |----|-----|------|------| | .text | 2.03 MB | 2.06 MB | 27 KB | | .rodata | 2.48 MB | 3.87 MB | 1.39 MB | | Total | 4.63 MB | 6.05 MB | 1.45 MB | ## GSD 文档(同时提交) - .planning/milestones/digital_human_rtc/MILESTONE.md - .planning/milestones/digital_human_rtc/ROADMAP.md - .planning/milestones/digital_human_rtc/INTEL.md - .planning/milestones/digital_human_rtc/phases/phase_01_kconfig_isolation/PLAN.md - .planning/milestones/digital_human_rtc/phases/phase_01_kconfig_isolation/SIZE_REPORT.md - .planning/milestones/digital_human_rtc/phases/phase_01_kconfig_isolation/BADGE_MODE_ISOLATION_MAP.md - 编译大小原始数据: size_*.txt ## 已知事项 - =n 固件 4.63 MB 仍 > 4 MB 目标,Phase 2 调整分区 + Phase 3 物理移除图片资源解决 - main/dzbj/ 下所有源文件完整保留,无任何物理删除
6.1 KiB
6.1 KiB
里程碑:数字人 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) |