feat(lcd): use Montserrat clock and battery icon assets

This commit is contained in:
chenjintao
2026-10-10 10:12:11 +08:00
parent 22f5ac70a2
commit bf06618848
31 changed files with 970 additions and 187 deletions
+33 -3
View File
@@ -124,9 +124,38 @@ DMA 等待超时后禁止继续复用可能仍被硬件读取的缓冲,GFX 传
左上显示系统本地时间,尚未同步时显示 `--:--`。当前配置为中国标准时间;时区应通过现有时间服务配置,不在显示模块硬编码。
右上显示领域层提供的电量百分比、有效性及充电状态。未知时显示 `--%`,充电显示绿色电池及闪电缺口,低电量显示红色。显示层不得从 ADC 电压自行重算电量。
右上只显示电池图标,不再显示百分比。电量有效性及充电状态仍来自领域层;
未知电量时暂不显示图标,避免把未知值画成某个电量档位。显示层不得从 ADC
电压自行重算电量。旧底部低电量提示保留。
状态栏复用内置 5×7 点阵数字和程序绘制图标,无需额外字体包。GFX 状态栏为 320×40 RGB565 图层,只在内容变化时刷新。PNG 表情在每帧合成时更新状态;二维码和屏幕边界测试不叠加它。
时间改用现有 LVGL 依赖中的 Montserrat 14 字形,仅提取 `0..9`、冒号及横线,
不缩放,保留原始 4-bit Alpha。白字及黑色偏移阴影直接合成到已有缓冲,
并非创建 GFX label,也不启动 LVGL GUI。字形数组常量位于 Flash,无动态字形缓存。
电池使用用户提供的 `battery_icons.zip` 中 40×20 的十张透明 PNG(五档及充电版本),
位于 `(272,12)`(320 像素宽时);不采用 80×40 版本,不拉伸、不改图标画风。
电量分档:0~10→1、11~25→25、26~50→50、51~75→75、76~100→100。
图标名表示视觉档位,不是重新计算 SOC;充电状态选择对应带闪电版本。
PNG 原图和优化图均保留,但实际编译为 RGB565+A8 调色板+游程数组,
每条游程为“数量、调色板索引”,与表情的四字节 RLE 不同。
在 Flash 中流式读取并按 Alpha 混合,不解码成常驻纹理。
GFX 状态栏仍为 320×40 RGB565 图层,只在内容变化时刷新。PNG 表情在每帧合成时
更新状态;二维码和屏幕边界测试不叠加它。两种后端使用同一字体和图标。
资源生成:`tools/prepare_status_hud_assets.py`;原图及优化图:
`components/platform/assets/status_hud/battery_source/` 与 `battery_optimized/`;
实际编译:`components/platform/src/generated/lcd_status_assets.c`,私有描述见
`components/platform/internal/lcd_status_assets.h`。运行生成脚本会重建优化 PNG/C,
原 PNG 不覆盖;首次导入可指定 `--import-zip <压缩包路径>`,日常验证用 `--check`。
需要 Pillow;字形来自现有依赖,不需要下载新字体。
本次 HUD 构建镜像 3,105,872 B,相对前一版 3,094,176 B 增加 11,696 B。
生成资产的 ESP32-S3 对象只读数据为 12,083 B:字形位图 425 B、字形描述 96 B、
十图标压缩载荷 11,442 B、图标描述 120 B。原十 PNG 9,973 B,优化后 9,806 B;
压缩载荷仍比优化 PNG 大 1,636 B,选择它是为避免 PNG 解码及额外像素缓存,
不能称作最小 Flash。新增常驻/初始化像素 PSRAM、普通堆、静态可写 RAM、DMA
均为 0;复用原状态栏/行缓冲,仍有局部栈和绘制 CPU 成本,需实机测量。
四个主机显示测试、ESP-IDF 5.5.4 构建及日志关闭/GFX 关闭的 LCD 编译均通过;
字体大小、图标显示、充电插拔及最低内存仍待实机验收。
当前不能据此声称已实现任意中文文字。后续中文提示需要选择字体、字符子集、布局及字形缓存策略;数字时间和电量不需要引入完整中文字库或大型界面框架。
@@ -393,7 +422,8 @@ python3 tools/test_lcd_listening_gfx.py
| 不需要触摸/复杂 GUI,精致流畅为主 | 局部 GFX 图层,不迁移完整 LVGL GUI |
| 拆分原表情,允许性能适配但整体保持 | 待机/listening 拆分与固定静态层;后续延续原画风,大幅变化需确认 |
| 眼睛向中间闭合,避免重影和撕裂 | 单一轮廓、闭眼弧线、缓存和连续传输;没有 TE,不能承诺零撕裂 |
| 统一所有返回待机入口、补时间电量 | 已实现统一后端及 HUD;不能覆盖新 pending;数字点阵不代表任意中文文字 |
| 统一所有返回待机入口、补时间电量 | 已实现统一后端及 HUD;不能覆盖新 pending;Montserrat 数字子集不代表任意中文文字 |
| 时间使用 Montserrat 14、移除电量数值、使用提供的电池图标 | 直接合成字形子集和 40×20 图标;构建与主机检查通过,待实机验收 |
| 增加可开关日志、计算具体帧数 | 已有 emote_fps/emote_cost;区分步骤/实际更新/面板扫描率 |
| 全中文开发说明与 AI 注意事项 | 本指南、资产台账及 AGENTS.md 中文 GFX 约束;原有仓库架构规范保留 |
| listening 也迁移为流畅表情并报告开销 | 已接入,开销见上表;保持业务监听生命周期与旧 PNG 后备 |
+11 -6
View File
@@ -24,21 +24,26 @@
## 状态栏
- 左上 HH:MM,沿用 SNTP 和系统时区;未同步显示 --:--。
- 右上百分比和电池;未知值显示 --%,充电绿色并带闪电缺口,低电量红色。
- 左上时间已改成 Montserrat 14 原始字号,提取数字、冒号、横线直接绘制;
无 GFX label 分配、无 LVGL GUI 初始化。旧 5×7 字形已从 HUD 实现移除。
- 右上删除百分比,使用用户提供的 40×20 五档电池图标及对应充电版本;
未知电量不显示,保留原底部低电量提示。档位规则、成本和生成入口见新指南第五节。
- SOC、有效性和充电状态来自现有 domain battery 服务,不从 ADC 重算。
- GFX 顶部 320x40 RGB565 图层,常驻 25,600 B PSRAM;只在分钟或电池状态
改变时使图层失效并刷新。正常待机/listening 眨眼切换缓存,不重新解码 PNG;
实时网格与程序闭眼弧线属于待机缓存生成或缓存失败后备路径。
- PNG 表情复用相同点阵 / 电池绘制器,在每帧合成时更新;二维码和 LCD
- PNG 表情复用相同 Montserrat 子集 / 电池素材绘制器,在每帧合成时更新;二维码和 LCD
边界测试页面不显示状态栏。PNG 无限等待期间不会独立重绘状态栏。
- 不需要字体包或新图片。旧 PNG 低电量底部告警保留;旧充电 PNG 不再自动
叠加,避免与数字电量冲突。GFX 待机低电量以红色电池表示。
- 新增字形子集和十个电池素材编译数组,不创建字形/图标解码缓存;普通堆、
像素 PSRAM 和 DMA 无新增。旧 PNG 低电量底部告警保留;旧充电 PNG 不再
自动叠加。低电量图标颜色来自用户素材,不再由代码统一染红。
## 验证
`python3 tools/test_lcd_status_hud.py` 从实际源码提取绘制函数,用 Clang
AddressSanitizer / UndefinedBehaviorSanitizer 检查 808 组有效性、充电、
低电量、0..100% 组合,验证行块和整帧等价、边界及颜色。
AddressSanitizer / UndefinedBehaviorSanitizer 检查 2,048 组有效性、充电、
低电量、完整 uint8 电量输入组合和全天 1,440 个时间,验证行块与整帧等价、
边界、原图 Alpha、透明背景恢复、240/320 像素画布和字节交换开关。
使用 ESP-IDF v5.5.4 执行 idf.py build。实机需验证:
+50 -6
View File
@@ -2,8 +2,9 @@
## 范围、日期与计量口径
这是 2026-10-09 lucky-cat 工作区的只读核对快照;采集时包含尚未提交的 listening
素材以及两个未跟踪的历史待机 C 资产。它不是构建输入或自动生成的实时报告。
这是 2026-10-09 lucky-cat 工作区的核对快照;初始采集时 listening 素材尚未提交,
两个历史待机 C 资产未跟踪;本次已追加 HUD 字形/电池素材及构建结果。
它不是构建输入或自动生成的实时报告。
新增、替换、移出固件或经授权清理资产时,应同步更新此表及指南。
范围包含平台图片/图层/音频、生成 GFX C 文件、旧音频副本、领域内嵌网页和项目
@@ -33,7 +34,7 @@
| 领域网页资源 | 1 | 5,373 | 8,192 | user_config.html 单独 EMBED_TXTFILES,不在素材包 |
| 文档中的独立显示预览 | 2 | 98,302 | 102,400 | 仅电脑预览,不入固件 |
以下同名文件跨目录是不同用途,不应直接合并或重复计入 Flash。当前没有独立中文字体包;数字 HUD 使用代码内置点阵,不意味着已支持任意中文字形。
以下同名文件跨目录是不同用途,不应直接合并或重复计入 Flash。当前没有独立中文字体包;时间 HUD 已改为 Montserrat 14 数字子集,电量仅显示素材图标,不意味着已支持任意中文字形。
## 原始 LCD 图片
@@ -358,8 +359,8 @@
| 包头、条目头及名称 | 3,222 | 打包元数据 |
| platform_assets.pack | 820,125 | 上述三项之和,包含于应用 |
| 六份在用 RLE 载荷 | 69,512 | 独立 C 数组链接入应用,不在素材包内 |
| 应用镜像 | 3,094,176 | 已包含 PNG、Opus、RLE、网页、代码及其他链接数据 |
| 单个 OTA 槽 | 4,718,592 | 应用余量 1,624,416 字节;不能把两个槽余量合并供一次 OTA 使用 |
| 应用镜像 | 3,105,872 | HUD 更新后的本次构建,包含 PNG、Opus、RLE、网页、代码及其他链接数据 |
| 单个 OTA 槽 | 4,718,592 | 应用余量 1,612,720 字节;不能把两个槽余量合并供一次 OTA 使用 |
| 独立语音模型镜像 | 2,681,351 | model 分区容量 3,145,728 字节,不属于应用内图片包 |
文件总大小不能当作“当前整个 Flash 用量”;NVS、分区表、引导程序、模型和
@@ -375,6 +376,49 @@ RGB565+A8 像素共 255,528 字节,新 RLE 载荷共 50,176 字节。相对原
常驻像素共 423,234 字节;初始化额外关键图 167,706 字节,随后释放。
当前没有新增 DMA 暂存区、合成缓冲或任务。它是用户已接受的空间换流畅度方案。
## 新增时间字形与电池图标(2026-10-09 HUD 更新)
素材来自用户提供的 `battery_icons.zip`,只导入 `out/40x20/` 中明确列出的十张 PNG,
80×40 版本不入工程。源图与优化 PNG 均不加入 `platform_assets.pack`,避免重复计费;
实际链接生成的 C 只读数组。以下新增项不包含在上面的旧目录汇总里。
| 源图名称 | 原 PNG 字节 | 优化 PNG 字节 | 调色板+游程载荷字节 |
| --- | ---: | ---: | ---: |
| `battery_1.png` | 704 | 687 | 805 |
| `battery_25.png` | 815 | 800 | 995 |
| `battery_50.png` | 594 | 571 | 927 |
| `battery_75.png` | 601 | 574 | 919 |
| `battery_100.png` | 543 | 524 | 806 |
| `battery_charging_1.png` | 1,206 | 1,197 | 1,300 |
| `battery_charging_25.png` | 1,367 | 1,344 | 1,500 |
| `battery_charging_50.png` | 1,333 | 1,319 | 1,363 |
| `battery_charging_75.png` | 1,451 | 1,437 | 1,477 |
| `battery_charging_100.png` | 1,359 | 1,353 | 1,350 |
| 合计 | 9,973 | 9,806 | 11,442 |
源 PNG:`components/platform/assets/status_hud/battery_source/`,十文件分配空间共
40,960 B;优化 PNG:同目录 `battery_optimized/`,十文件分配空间共 40,960 B。
颜色先按现有 RGB565 精度转换,完整保留 A8;调色板编码对 RGB565+A8 无损,
不等于 RGB888 转 RGB565 无损。游程往返与 PNG 优化像素一致性由生成脚本验证。
十图标原始 RGB565+A8 为 24,000 B,索引游程为 11,442 B,减少约 52.3%;
但比优化 PNG 大 1,636 B。这里选的是无需运行时解码缓存的折中,不是最小文件编码。
时间字形来自已安装 LVGL 的 `lv_font_montserrat_14.c`,只提取数字、冒号、横线,
4-bit Alpha 位图 425 B,十二个描述共 96 B(ESP32-S3 对象验证),原始字号不放大。
许可说明保留在 `status_hud/LVGL-LICENSE.txt`(不入固件)。
生成脚本 `tools/prepare_status_hud_assets.py`,验证用 `--check`;输入字体版本/格式
变化会触发断言,不能静默生成错误字形。
实际编译 `components/platform/src/generated/lcd_status_assets.c`:文本文件 75,630 B,
目标对象只读载荷 12,083 B,包括 425 B 字形、96 B 字形描述、11,442 B 图标数据、
120 B 图标描述;目标对象可写 data/BSS 为 0。它不属于上面的六份表情 RLE。
PNG 包仍为 820,125 B、75 PNG/32 Opus;只读资产已包含于整个应用,不再重复相加。
完整应用从 3,094,176 B 增至 3,105,872 B,净增 11,696 B(包含旧字形/绘制代码
移除和段对齐变化),OTA 槽剩余 1,612,720 B。新增常驻/初始化像素 PSRAM、普通堆、
内部/DMA 专用缓冲及静态可写数据均为 0;复用既有 HUD 和行缓冲。
局部栈、CPU 耗时和设备最低内存尚未新增实机测量,不应写成整体资源零成本。
## 维护与后续清理
1. PNG 新增/替换按 [图片优化流程](lcd-image-asset-optimization.zh-CN.md) 生成并验证,
@@ -385,4 +429,4 @@ RGB565+A8 像素共 255,528 字节,新 RLE 载荷共 50,176 字节。相对原
GFX 关闭/故障后备以及收益,经过用户确认并完成迁移验收后再修改构建及资源表。
4. 清理优先区分“不再入固件”与“删除可编辑源文件”。前者有 Flash 收益,后者
可能仅省开发机空间,不能混为一谈。保留 Git 可恢复记录,并验证正常/故障路径。
5. 这里没有安排立即清理、批量迁移所有表情或新增字体;这些需要单独确定范围。
5. 这里没有安排立即清理、批量迁移所有表情或加入完整字库;当前仅按用户要求提取 Montserrat 数字子集。