按 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/ 下所有源文件完整保留,无任何物理删除
8.5 KiB
INTEL — 数字人 RTC 项目调研结果沉淀
来源:3 个并行 Explore 代理的调研报告(电子吧唧盘点 / 必保留模块 / 资源评估) 用途:作为后续 Phase 规划的事实依据,避免重复 grep
重要原则更新(2026-05-12):所有"必删"清单实际是"通过 Kconfig + CMakeLists 条件编译屏蔽"。 源代码文件全部保留在
main/dzbj/下作为参考,后续可通过开启CONFIG_BAJI_BADGE_MODE=y恢复双模式。 下文使用"屏蔽"代替"删除"语义,文件路径清单本身不变。
1. 电子吧唧专属代码盘点
1.1 dzbj/ 待屏蔽模块(共 12 文件,约 4180 行,源码保留)
| 文件 | 行数 | 功能 | 关联接口 |
|---|---|---|---|
device_mode.c/h |
70 | NVS 双模式标志 + esp_restart 切换 | device_mode_get/set/in_switch_suppress |
dzbj_ble.c |
650 | 吧唧 BLE 图传 GATT Server(Service 0x0B00) | dzbj_ble_start/stop |
ble_transfer.c/h |
780 | 设备间图片 P2P(GATT Client 扫描+分包) | dzbj_ble_start_transfer |
dzbj_button.c/h |
440 | iot_button 注册 + KEY2 GPIO4 处理 | 注意 BOOT 处理要保留 |
pages.c |
1200 | LVGL 图片浏览界面逻辑 | pages_init_*、pages_show_* |
pages.h |
50 | pages 接口声明 | — |
pages_pwm.c/h |
90 | 吧唧专用 PWM 背光 | AI 模式用 display.cc 抽象 |
fatfs.c/h |
350 | SPIFFS 文件管理 + JPEG 解码 | DecodeImg、spiffs_list_files |
dzbj_battery.c/h |
280 | ADC 电量监测后台任务 | dzbj_battery_init |
dzbj_init.c/h |
50 | 吧唧硬件初始化入口 | dzbj_display_init |
dzbj_gpio.h |
40 | KEY2/BAT_ADC GPIO 宏 | — |
sleep_mgr.c |
250 | 10s 超时熄屏 + 唤醒 | sleep_mgr_init/notify_activity/is_screen_off |
1.2 待屏蔽 UI 屏幕(9 个 SquareLine 生成的 .c,源码保留)
main/ui/screens/ui_ScreenHome.c/h # 吧唧主菜单
main/ui/screens/ui_ScreenImg.c/h # 图片浏览
main/ui/screens/ui_ScreenSet.c/h # 设置
main/ui/screens/ui_ScreenPeiwang.c/h # 等待配对
main/ui/screens/ui_ScreenImageShar.c/h # 发送方等待
main/ui/screens/ui_ScreenImageReception.c/h # 接收方等待
main/ui/screens/ui_ScreenSharing.c/h # 发送中
main/ui/screens/ui_ScreenReceiving.c/h # 接收中
main/ui/screens/ui_ScreenUpdate.c/h # APP 推送
1.3 待条件化的 CMakeLists.txt 条目
main/CMakeLists.txt 第 26-41 行(dzbj srcs)+ 第 46-54 行(ui screens)—— Phase 1 用 if(CONFIG_BAJI_BADGE_MODE) 包裹
1.4 待 #ifdef 保护的应用层调用点
main/application.cc:
- L20:
#include "dzbj/device_mode.h" - L63: 吧唧模式背景任务条件分支
- L536-540:
if (device_mode_get() == MODE_BADGE) { ... }
main/boards/movecall-moji-esp32s3/movecall_moji_esp32s3.cc:
- L19:
#include "dzbj/device_mode.h" - L21-23: 吧唧 BLE/电池/按键头文件
- L494-501: 吧唧模式初始化分支
- L527, L739: BOOT+KEY2 组合键回调注册
2. 必须保留模块清单
2.1 火山 RTC 核心(绝对不动)
| 文件 | 功能 |
|---|---|
main/protocols/volc_rtc_protocol.h/cc |
WebSocket + RTC 消息回调 + IAC 认证 |
main/protocols/protocol.h/cc |
通用协议基类、Listening 状态机、Function Calling |
components/78__esp-opus-encoder/opus_encoder.cc |
16kHz Opus 编码 |
components/78__esp-opus-encoder/opus_decoder.cc |
Opus 解码 + 转采样 |
main/audio_codecs/audio_codec.h/cc |
I2S DMA + sample rate 管理 |
main/application.cc(RTC 分支) |
状态机 + Function Call + HTTPS 中止信号 |
2.2 BLE 配网(注意与吧唧 BLE 区分)
| 文件 | 说明 |
|---|---|
main/bluetooth_provisioning.h/cc |
GATT Server Service 0xABF0(不是吧唧 0x0B00) |
main/boards/common/wifi_board.cc L374 |
StartBleProvisioning() |
main/dzbj/dzbj_button.c(仅 BOOT 部分) |
iot_button BOOT 单击/长按回调 |
main/boards/common/system_reset.cc |
NVS 工厂重置 |
2.3 基础设施
| 文件 | 用途 |
|---|---|
main/dzbj/lcd.c |
ST77916 QSPI LCD 驱动(数字人显示需要) |
main/display/lcd_display.cc |
LVGL 显示抽象 + 字幕渲染 SetChatMessage + 情绪映射表 |
main/dzbj/ai_chat_ui.c |
AI 对话主界面 + 字幕标签 + GIF 容器 |
main/dzbj/bg_gif_demo.c/h |
背景图 + 透明 GIF 叠加(数字人显示) |
main/ota.cc |
OTA 升级 |
2.4 资源文件保留
spiffs_image/Background_360x360.jpg # 背景图(bg_gif_demo 依赖)
spiffs_image/hiyori_m05.gif # 现有 PoC GIF(Phase 3 后替换为 m03/m06/m07)
3. 资源评估数据
3.1 当前分区表
| 分区 | 大小 | 用途 |
|---|---|---|
| nvs | 16KB | NVS 键值 |
| otadata | 8KB | OTA 选择标志 |
| phy_init | 4KB | PHY 配置 |
| model | 64KB | AI 模型预留(未用,可删) |
| ota_0 | 6.5MB | 应用分区 0 |
| ota_1 | 6.5MB | 应用分区 1 |
| storage | 2.88MB | SPIFFS |
| 合计 | 16MB |
3.2 hiyori 8 GIF 实测体积
来源:docs/Rtc_AIavatar/Resources/hiyori_free_zh/Export/m{01..08}/
| GIF | 大小 | 选用 |
|---|---|---|
| m01 | 3.6MB | ✗ |
| m02 | 4.6MB | ✗ |
| m03 | 3.3MB | ✓ 负面情绪 |
| m04 | 3.3MB | ✗ |
| m05 | 6.7MB | ✗(PoC 用过) |
| m06 | 1.3MB | ✓ 默认/积极 |
| m07 | 1.1MB | ✓ 思考/疲倦 |
| m08 | 3.0MB | ✗ |
精选 3 个合计 5.7MB,6MB SPIFFS 可装下,留 0.3MB 给背景图(20KB)+ 余量。
3.3 新分区方案
# Name, Type, SubType, Offset, Size
nvs, data, nvs, 0x9000, 0x4000 # 16KB
otadata, data, ota, 0xD000, 0x2000 # 8KB
phy_init, data, phy, 0xF000, 0x1000 # 4KB
ota_0, app, ota_0, 0x10000, 0x400000 # 4MB(缩 2.5MB)
ota_1, app, ota_1, 0x410000, 0x400000 # 4MB(缩 2.5MB)
storage, data, spiffs, 0x810000, 0x600000 # 6MB(扩 3.1MB)
# 删除 model 分区
合计 4+4+6 = 14MB + 28KB 引导/NVS ≈ 14.03MB(< 16MB Flash,留 ~2MB 备用)
3.4 字幕显示当前状态
main/dzbj/ai_chat_ui.c:
- L165:
lv_obj_add_flag(chat_label, LV_OBJ_FLAG_HIDDEN)— 字幕被 PoC 隐藏 - L342:
if (USE_BG_GIF_POC) return— 更新函数屏蔽
字幕字体:font_puhui_20_4(GB2312 简体中文,已存在)
字幕宽度:300px,wrap 模式
3.5 内存预算
| 组件 | PSRAM 峰值 |
|---|---|
| Opus 解码缓冲 | ~200KB |
| GIF 解码(gifdec 逐帧) | ~1MB |
| LVGL 帧缓冲 + 对象 | ~200KB |
| 文件系统/堆碎片 | ~500KB |
| 合计峰值 | ~1.9MB |
| PSRAM 余量 | ~6.1MB / 8MB |
结论:充足,无需特别优化。
4. 情绪标签 → GIF 映射决策
22 种情绪标签(来自现有 emotions[] 映射表)→ 3 个 hiyori GIF:
| GIF | 情绪标签 |
|---|---|
| m06(默认/积极) | neutral, happy, laughing, funny, cool, loving, relaxed, delicious, silly, winking, kissy, confident |
| m07(思考/疲倦) | sleepy, thinking, confused, embarrassed |
| m03(负面/严肃) | sad, crying, angry, surprised, shocked, serious |
5. 字幕显示设计
- 位置:
lv_obj_align(chat_label, LV_ALIGN_BOTTOM_MID, 0, -70) - 容器:半透明黑底(
LV_OPA_50),圆角,padding 10px - 字体:font_puhui_20_4,文字白色 0xFFFFFF
- 创建顺序(z-index):背景图 → GIF → 字幕容器
6. RTC 空闲超时设计
复用 application.cc 现有 listening_idle_ticks_ 机制:
- 触发条件:60s 无 RTC 字幕/STT/Function Call 信号
- 触发动作:CloseAudioChannel + pwm_set_brightness(0) + 暂停 LVGL
- 唤醒:BOOT 单击 → 恢复亮度 + 重连 RTC
删除 dzbj/sleep_mgr.c,其功能并入 application.cc。
7. 风险点(来自调研)
| 风险 | 来源 |
|---|---|
lcd.c 归属 dzbj/ 但 AI 模式也用 |
调研报告 A vs B 有分歧,结论:保留(数字人显示必需) |
| sleep_mgr 是公共还是吧唧专属 | 决策:改造为 RTC 联动而非删除(用户决策 D3) |
| ble_transfer.c 删除后 dzbj_ble.c 依赖链 | Phase 1 实施时要 grep 确认无残留引用 |
| SquareLine .c 删除后工程文件失效 | 只删 generated .c,保留 SquareLine 源工程 |
| 分区调整后 OTA 兼容性 | 首次烧录用 esptool.py write_flash 整片烧 |
8. Git 当前状态
- 当前分支:
Rtc_AIavatar - 起始 commit:
eb96130(数字人 GIF PoC) - 远程:gitea
origin+ GitHub(手动 URL push) - main 已与 adaptation_dzbjImg_shar 同步(双模式基线)