☰
muse-gadget-sdk UI 模拟器:在桌面上编译并运行生产级 SenseCAP Watcher 界面
2026/10/9 7:31:03 网站建设 项目流程

【免费下载链接】muse-gadget-sdk

Open source SDK to build Muse gadgets

项目地址:https://gitcode.com/gh_mirrors/mu/muse-gadget-sdk
点击查看免费下载

本文介绍 muse-gadget-sdk 仓库中的 UI 模拟器(esp32/simulator/):它如何直接编译生产环境的muse_ui.c、状态机与像素头像渲染代码,在 412 x 412 的 SenseCAP Watcher 窗口里完成桌面预览;并覆盖构建、依赖解析、交互式操作、脚本化/无头渲染与自动化测试的完整流程,帮助你掌握“不改一行 UI 代码就能复现设备画面、可回归、可截图”的桌面验证方案。

一、模拟器是什么、不是什么

模拟器是 Muse 接口的桌面预览:它在 412 x 412 的 SenseCAP Watcher 窗口中渲染生产代码——包括muse_ui.c、状态与文本代码以及头像渲染器(muse_pixel.c)。SDL 负责显示、鼠标输入和计时,而一组小型主机适配层(host adapters)替代 ESP-IDF、FreeRTOS、Wi-Fi、蓝牙、Link、设置与电源服务。

需要明确的边界(来自 esp32/simulator/README.md):

  • 它不模拟 ESP32-S3 CPU、Watcher 的 Himax 摄像头、音频硬件、蓝牙射频、内存压力或电源时序;
  • 这些路径仍需固件构建并在真机上做最终测试;
  • 它的定位是快速 UI 迭代与可重复截图,不是硬件仿真器。

从源码结构看,可执行文件muse_simulator只包含五个源文件与四个生产文件(见 CMakeLists.txt):

来源文件角色
模拟器src/main.c命令行解析、SDL 事件、场景执行、截图
模拟器src/sim_board.c412x412 桌面板级配置 + SDL 显示/触摸
模拟器src/sim_platform.cESP-IDF/FreeRTOS/mbedTLS API 的主机替身(含可推进的假时钟)
模拟器src/sim_services.c内存态 Wi-Fi/BLE/Link/Chat/亮度/扬声器服务
生产代码components/muse/muse_ui.c、muse_state.c、muse_text.c、esp32/avatar/muse_pixel.c与真机完全相同的 UI 逻辑

compat/目录提供了esp_err.h、freertos/、mbedtls/base64.h等桩头文件,让生产代码无需 ESP-IDF 即可在桌面编译。

二、构建环境与依赖解析

2.1 主机要求

模拟器支持 Linux 与 macOS。主机需要:

  • CMake 3.24 或更新版本;
  • Ninja;
  • 支持 C11 的 GCC 或 Clang(CMakeLists.txt 明确拒绝其他编译器,且仅支持 Unix 平台);
  • Python 3.9 或更新(仅测试需要);
  • 不需要 ESP-IDF。

Debian/Ubuntu 安装构建工具:

sudo apt-get update sudo apt-get install -y build-essential cmake ninja-build python3

macOS 安装 Xcode 命令行工具与其余工具:

xcode-select --install brew install cmake ninja python

xcode-select --install可能提示工具已安装,可忽略。Apple Silicon 与 Intel Mac 均可构建出原生二进制,无需 Rosetta。

2.2 SDL2 与 LVGL 的解析策略

这是构建中最容易出错的环节。CMakeLists.txt 的解析顺序为:

SDL2(优先级从高到低):

  1. CMake CONFIG 包SDL2::SDL2或SDL2::SDL2-static(要求 >= 2.0.18);
  2. pkg-config 的sdl2>=2.0.18;
  3. 以上都不满足且MUSE_SIM_FETCH_DEPS=ON(默认)时,下载固定版本SDL 2.32.10源码(SHA256 校验),且只构建静态运行时(关闭 audio/haptic/hidapi/joystick/等子系统,SDL2_DISABLE_SDL2MAIN=ON)。

LVGL(总是锁定版本):默认始终下载固定版本 LVGL 9.5.0,因为生产 UI 依赖版本特定的私有 API 以及本目录lv_conf.h中启用的字体与驱动。lv_conf.h 的关键配置包括LV_COLOR_DEPTH 16(16 位色,对应设备屏幕)、LV_USE_SDL 1(启用 SDL 驱动)、Montserrat 14/16/20/28 与 Unscii 字体,默认字体为lv_font_montserrat_20。

只有在系统同时装有兼容的 SDL2 与按本配置编译的LVGL 时,才设置-DMUSE_SIM_FETCH_DEPS=OFF改用系统包;关闭后 CMake 会检查系统 LVGL 是否暴露私有头文件(src/draw/lv_image_decoder_private.h、src/misc/lv_area_private.h),不满足即报错退出。首次拉取成功后,可用-DFETCHCONTENT_FULLY_DISCONNECTED=ON复用已填充的依赖缓存,脱离网络。Homebrew 安装 SDL2 是可选的。

2.3 构建命令

从仓库根目录执行:

cmake -S esp32/simulator -B esp32/simulator/build -G Ninja \ -DCMAKE_BUILD_TYPE=Debug cmake --build esp32/simulator/build --parallel

其他 CMake 选项:

选项默认说明
MUSE_SIM_FETCH_DEPSON无合适系统包时拉取固定版本 LVGL/SDL2 源码
MUSE_SIM_SANITIZERSOFF以 ASan + UBSan 构建
MUSE_SIM_WARNINGS_AS_ERRORSOFF将警告视为错误(默认已开启-Wall -Wextra -Wpedantic)

构建完成时会打印实际选用的LVGL target与SDL2 target,可用于核对依赖解析结果。macOS 上会自动链接 IOKit 框架(SDL 的 Cocoa 显示/屏保后端即使在禁用可选电源子系统时也会使用 IOKit)。

三、交互式预览与键盘控制

在已登录的 Linux/macOS 桌面会话的终端中运行:

./esp32/simulator/build/muse_simulator

鼠标输入作为触摸。键盘控制常用 UI 状态(main.c 中通过SDL_AddEventWatch注册的事件监听实现):

按键动作
F1 ... F7Boot、idle、listening、thinking、speaking、error、off 七个状态
H触发 happy idle 动画
Space(按住)按住时进入 listening,松开切换为 thinking
+/-提高/降低音频电平(每步 0.1)
[/]降低/提高回合进度(每步 0.1)
S切换睡眠
P在当前目录保存muse-simulator.ppm
Esc退出

muse_simulator --help会输出同样的控制说明与全部命令行选项。MacBook 上若系统未将 F1–F7 配置为标准功能键,需按住 Fn 或地球键再按。

源码中有一个值得注意的细节:生产端关闭流程之后只允许进入 Idle 模式,而模拟器为了让预览可控,在选择任意状态前会先强制回到MUSE_MODE_IDLE再切换到目标模式(main.c 的 select_mode),注释里明确这是“Preview controls should still be able to select any state after showing Off”的设计取舍。

3.1 手工冒烟测试清单

README 给出的一套快速验证流程:

  1. 确认打开固定尺寸 412 x 412 的Muse Gadget Simulator窗口;
  2. 按 F3 进入 listening,用+/-调节电平表;
  3. 按住 Space 进入 listening,松开进入 thinking,进度环应变成移动段;
  4. 按 F5 进入 speaking,用+/-让嘴部动画;
  5. 按 H 确认头像执行 happy 动画;
  6. 按 S 睡眠,点击黑屏唤醒;
  7. 向左拖拽打开设置占位页,向右拖拽回到头像(模拟器未实现设置控件);
  8. 按 P 确认当前目录出现muse-simulator.ppm,然后按 Esc 退出。

场景文件同样可以初始化一个可见的交互会话:

./esp32/simulator/build/muse_simulator \ --scenario esp32/simulator/tests/scenarios/pairing.txt

例如仓库自带的 pairing.txt 会呈现含六位配对码(passkey=123456)的配对提示界面。交互式窗口需要显示会话;SSH 或 CI 环境请加--headless。

四、脚本化与无头渲染

4.1 场景文件格式

场景是一个文本文件,每行一条key=value设置;空行与以#开头的行被忽略;设置按文件顺序应用,因此advance可以在下一项变更之前渲染出中间状态。main.c 的 run_scenario 负责逐行解析。

一个完整示例(对应仓库 thinking.txt 风格):

face=thinking caption=Finding a good answer... progress=0.65 battery=72 usb=false wifi=connected ble=connected paired=true link=online advance=800

4.2 无头渲染命令

无需显示服务器即可渲染,并把最终合成画面存为二进制 PPM 图像(P6 格式,见 write_snapshot):

./esp32/simulator/build/muse_simulator \ --headless \ --scenario esp32/simulator/tests/scenarios/thinking.txt \ --run-ms 250 \ --screenshot thinking.ppm

命令行选项(解析见 main.c):

选项说明
--headless设置SDL_VIDEODRIVER=dummy与SDL_AUDIODRIVER=dummy后运行,结束前渲染--run-ms时长
--scenario FILE按序应用场景设置;无显示时也可配合使用来初始化可见会话
--run-ms N总渲染毫秒数,范围 0..3600000,非法值退出码 2
--screenshot FILE.ppm渲染结束后捕获 SDL 渲染器像素写出 PPM
-h/--help输出用法

4.3 场景键全集与取值范围

README 列出支持的键,结合 apply_setting 的解析逻辑可以补充精确的取值范围:

键取值 / 范围
faceboot、idle、listening、thinking、speaking、error、off或happy(happy先切 idle 再触发 muse_state_make_happy)
caption任意文本,经muse_state_set_caption写入
level0..1 浮点(非法值如nan会被拒)
progress0..1 浮点
battery-1..100 整数(-1 表示无电池/未知)
battery_mv0..6000 整数
usb/charging/asleeptrue\|false(parse_bool同时接受on/1、off/0)
wifioff、no_network、connecting、connected、failed或not_nearby(connected 时 SSID 置为 "Muse Simulator")
bleoff、advertising或connected;另有passkey(0..999999)与paired(true/false)
linkboot、unpaired、pairing、confirm、connecting、online、offline或error
speakertrue/false
brightness10..100 整数
advance0..3600000 毫秒,推进模拟时钟并渲染对应时长

错误处理:非法命令行选项与非法场景值都会返回非零退出状态,并在 stderr 中指明坏行,格式为文件:行号: unsupported or invalid setting: key=value(退出码 2)。仓库测试 test_simulator.py 正是用face=definitely-not-a-mode与level=nan两条坏场景断言了该行为。

仓库自带 5 个场景,分别覆盖错误态、待机、聆听、配对与思考(tests/scenarios/):error.txt、idle.txt、listening.txt、pairing.txt、thinking.txt。

五、自动化测试与 Sanitizer 构建

5.1 无头确定性测试

构建完成后运行:

ctest --test-dir esp32/simulator/build --output-on-failure

测试由 tests/test_simulator.py 实现(CMake 以muse_simulator_headless注册,超时 60 秒),使用 SDL 的 dummy 视频驱动,具体验证:

  1. 校验命令行与场景错误处理(非法键值 → 退出码 2 + stderr 定位);
  2. 渲染每一个自带场景两次(--run-ms 200+--screenshot),要求两次 framebuffer 逐字节一致(SHA256 相同),证明渲染是确定性的;
  3. 要求不同场景渲染出的画面互不相同(颜色数 > 8、尺寸恒为 412x412 的 PPM 头校验);
  4. 追加一条face=off后接listening场景的渲染,断言其画面与单独渲染 listening 一致——即“显示关机画面后不能锁死后续预览状态选择”,与 select_mode 的解锁逻辑对应。

5.2 ASan/UBSan 构建

cmake -S esp32/simulator -B esp32/simulator/build-asan -G Ninja \ -DCMAKE_BUILD_TYPE=Debug \ -DMUSE_SIM_SANITIZERS=ON cmake --build esp32/simulator/build-asan --parallel ctest --test-dir esp32/simulator/build-asan --output-on-failure

开启后测试环境会注入ASAN_OPTIONS与UBSAN_OPTIONS=halt_on_error=1:print_stacktrace=1。平台差异:macOS 上 Apple Clang 的 ASan 运行时不支持泄漏检测,故detect_leaks=0;Linux 上启用detect_leaks=1(见 CMakeLists.txt)。

六、实现要点:为什么渲染是可重复的

模拟器“可复现截图”的能力来自三处设计,均能在源码中直接核对:

  1. 假时钟注入 LVGL。sim_platform.c 实现了一套可切换真实/虚构时间轴的esp_timer_get_time()替身:sim_time_advance_us直接推进虚拟时钟;sim_board.c 在创建 SDL 窗口后调用lv_tick_set_cb(sim_time_tick_ms),替换 SDL 驱动默认安装的SDL_GetTicks——注释说明其目的正是“scripted runs can advance time without sleeping and render repeatably”。无头/截图模式下render_for以 5ms 步长推进假时钟并调用lv_timer_handler(),不真实睡眠(real_time=false)。
  2. 生产 UI 走生产全局变量。sim_board.c 定义生产全局muse_board指向桌面板级配置(412x412、round=true、touch=true、frame_ms=40、1.45 英寸对角线),muse_ui.c无需任何修改即可读取它;power_off直接返回ESP_FAIL,set_brightness/panel_sleep为空实现,即桌面版不提供真实电源语义。
  3. 内存态服务替身。sim_services.h 声明了sim_services_set_wifi/ble/paired/chat_status/link_state/brightness/speaker等函数,注释明确 setter 设计为在模拟器 LVGL/事件循环线程的下一个 tick 前运行——场景文件里的wifi=、ble=、link=等键最终都通过这些 setter 更新内存态,供生产 UI 读取显示。

截图路径同样简单透明:lv_refr_now强制刷新后,经lv_sdl_window_get_renderer拿到 SDL 渲染器,SDL_RenderReadPixels读出 RGB24 像素,写出P6头 PPM 文件(write_snapshot)。

七、延伸阅读与相关路径

  • 模拟器文档主体:esp32/simulator/README.md
  • 依赖版本与许可证:esp32/simulator/THIRD_PARTY.md(LVGL 9.5.0 MIT、SDL 2.32.10 zlib)
  • 构建与依赖解析:esp32/simulator/CMakeLists.txt
  • 模拟器配置:esp32/simulator/lv_conf.h
  • 入口与场景解析:esp32/simulator/src/main.c
  • 板级/显示/时钟替身:esp32/simulator/src/sim_board.c、esp32/simulator/src/sim_platform.c
  • 服务替身接口:esp32/simulator/src/sim_services.h
  • 测试与场景:esp32/simulator/tests/test_simulator.py、esp32/simulator/tests/scenarios/

适用前提与限制再次强调:该模拟器面向 Linux/macOS 桌面,用于 UI 迭代与截图回归;任何涉及摄像头、音频、蓝牙射频、内存与功耗的行为验证,仍须走esp32/下的固件构建并在真机完成。

【免费下载链接】muse-gadget-sdk

Open source SDK to build Muse gadgets

项目地址:https://gitcode.com/gh_mirrors/mu/muse-gadget-sdk
点击查看免费下载

相关推荐

上一篇:全网资源下载神器:5分钟掌握视频音频图片下载技巧
下一篇:Windows激活终极方案:KMS_VL_ALL_AIO智能激活工具完全指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询