|
|
497c1b4654
|
feat(rtc-only): Phase 4 - 情绪标签 → 数字人 hiyori GIF 映射 + 切换接口
按 GSD 框架 .planning/milestones/digital_human_rtc/phases/phase_04_emotion_mapping/
规划完成 Phase 4 情绪映射 + 运行时切换。
## 核心变更
### bg_gif_demo 新增运行时切换接口
```c
esp_err_t bg_gif_demo_switch_gif(const char *new_gif_path);
```
实现要点:
- 先 heap_caps_free(g_gif_data) 释放旧 PSRAM,再加载新 GIF,单峰仅一份
- 内部 static last_gif_path 去重(相同路径直接返回 ESP_OK)
- 切换后立即 lv_timer_set_period(timer, 20) 防止 lv_gif_set_src 重建为默认 10ms
- LVGL 锁保护 200ms 超时
### 22 情绪 → 3 hiyori GIF 映射表
定义在 main/dzbj/ai_chat_ui.c USE_BG_GIF_POC 包裹内:
| GIF | 情绪标签 (个数) |
|-----|----------------|
| m06 (默认/积极) | neutral, happy, laughing, funny, loving, relaxed, delicious, kissy, confident, silly, blink, curious (12) |
| m07 (思考/疲倦) | sleepy, thinking, confused, embarrassed, dizzy (5) |
| m03 (负面/严肃) | sad, crying, angry, surprised, shocked (5) |
22 个标准情绪 100% 覆盖,未映射的情绪默认 fallback 到 m06。
### ai_chat_set_emotion 改造
PoC 模式下优先切换数字人大图(不再切隐藏的 emoji 200x89):
```c
#ifdef USE_BG_GIF_POC
if (bg_gif_demo_is_running()) {
const char *path = find_hiyori_gif(emotion);
bg_gif_demo_switch_gif(path);
return;
}
#endif
// 非 PoC 模式 fallback emoji 路径保留
```
## 调用链(已与现有 RTC 字幕解析对接,无需改 application.cc)
RTC 字幕 → application.cc:1419 display->SetEmotion(emo)
→ AiChatDisplay::SetEmotion (display/ai_chat_display.cc)
→ ai_chat_set_emotion (dzbj/ai_chat_ui.c)
→ bg_gif_demo_switch_gif (PoC 模式)
→ 数字人 hiyori GIF 切换
## 烧录验证(用户实测)
监控 60s 期间捕获情绪切换:
- neutral / happy → m06(已在播,去重)
- thinking → m07 切换成功 (590ms 延迟)
- confused → m07 去重跳过
- AI 回复结束 → 自动回到 neutral
- 无 abort / 重启
m06 ↔ m07 切换屏幕可视确认,m03 走相同代码路径无需重复测试。
## GSD 文档(同时提交)
- .planning/milestones/digital_human_rtc/phases/phase_04_emotion_mapping/PLAN.md
- .planning/milestones/digital_human_rtc/phases/phase_04_emotion_mapping/EMOTION_REPORT.md
|
2026-05-13 11:59:38 +08:00 |
|
|
|
7d1c7dc1f0
|
feat(rtc-only): Phase 3 - 数字人 GIF 资源准备(hiyori m03/m06/m07,209x360)
按 GSD 框架 .planning/milestones/digital_human_rtc/phases/phase_03_gif_resources/
规划完成 Phase 3 数字人表情 GIF 资源处理。
## 处理方式(与 PoC 阶段 hiyori_m05.gif 一致)
```bash
gifsicle --resize _x360 -O3 input.gif -o output.gif
```
- 高度 = LCD 360px,宽度按原比例自动算 → 209px
- 不裁剪(保持源 GIF 完整人物)
- 不加 --lossy / --colors(保留 256 色,画质优先)
- 只用 -O3 优化文件大小
## 处理结果
| GIF | 用途 | 源 | 处理后 | 节省 |
|-----|------|-----|--------|------|
| m03 | 负面/严肃 | 407×700 3.3MB | 209×360 1.15MB | 66% |
| m06 | 默认/积极 | 407×700 1.3MB | 209×360 0.44MB | 66% |
| m07 | 思考/疲倦 | 407×700 1.2MB | 209×360 0.40MB | 66% |
| 合计 | — | 5.7MB | 1.94MB | 66% |
## 决策过程(避免后续重复犯错)
Phase 3 初稿曾尝试裁剪到 240×320 + PIL 全帧 bbox 居中裁剪,
用户烧录后反馈"视觉感官不好"——角色被横向压扁(240×320 纵横比 0.75
vs 源 407×700 纵横比 0.583)。回归 PoC 等比例缩放方式后效果与 PoC 一致。
PoC 处理标准已写入用户级 feedback memory(feedback_hiyori_gif_processing.md),
后续 hiyori GIF 处理一律用本方式,除非用户主动要求修改。
## 显示效果(用户已目视确认)
LCD 360×360 居中显示 209×360 GIF:
- 垂直方向: 360 = 360,完全充满
- 横向: 209 < 360,左右各 75.5px 留边显示背景图
- 角色比例: 完整保留源 GIF 的 407:700 = 0.582 纵横比,人物细高自然
## 删除项
- spiffs_image/hiyori_m05.gif (2.3MB) 已删除 - 被 m06/m07/m03 替代
文件历史保留在 git,可通过 git show eb96130:spiffs_image/hiyori_m05.gif 恢复
## 默认表情切换
main/dzbj/ai_chat_ui.c:234:
- PoC: bg_gif_demo_start(..., "/spiflash/hiyori_m05.gif")
- Phase 3: bg_gif_demo_start(..., "/spiflash/hiyori_m06.gif")
## 烧录运行时验证
- 烧录后 0 次重启(连续监控 18 秒)
- BG_GIF: GIF 已加载到 PSRAM: /spiflash/hiyori_m06.gif (441.8 KB)
- AudioCodec: Audio codec started(首次冷启动直接成功)
- 用户目视确认显示效果良好
## GSD 文档(同时提交)
- .planning/milestones/digital_human_rtc/phases/phase_03_gif_resources/PLAN.md
- .planning/milestones/digital_human_rtc/phases/phase_03_gif_resources/GIF_REPORT.md
## SPIFFS 容量
新 SPIFFS 4.94MB 当前实际占用 ~2MB(40%),余量 ~2.94MB 充足。
|
2026-05-13 11:42:30 +08:00 |
|
|
|
672506e7c7
|
feat(rtc-only): Phase 1 - 通过 CONFIG_BAJI_BADGE_MODE 屏蔽电子吧唧模式
按 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/ 下所有源文件完整保留,无任何物理删除
|
2026-05-13 10:22:48 +08:00 |
|