Files
Docs/DevLogs/Day15.md
2025-12-31 16:18:28 +08:00

3.7 KiB
Raw Blame History

Day 15: 性能优化 - 解决导航模式帧率问题

问题描述

导航模式下 FPS 从 10.0 降到 0.5-1.5,画面严重卡顿。


已完成优化

1. YOLO 帧间隔修复

yolo_process_interval 从 1 帧改为 5 帧。

2. 性能诊断日志

添加了 [NAVIGATION DEBUG] 日志用于监控状态。

3. 线程池化帧处理

使用 ThreadPoolExecutor 将 CPU 密集型处理移至后台线程。

4. 修复模型重复加载 BUG

根因audio_stream.py 中的 import app_main 触发模块顶层代码再次执行。 修复:改为 sys.modules['app_main'] 获取已加载的模块。

5. 跳帧机制

根因:虽然用了 run_in_executor,但 await 仍同步等待处理完成。 修复:实现非阻塞式帧处理:

  • 后台任务处理帧,主循环不等待
  • 使用最后一次成功的结果广播
  • 新帧覆盖待处理队列(跳过中间帧)

6. 导航语音频率优化

问题FPS 恢复后导航指令触发过于频繁每1秒一次造成干扰。 修复:将 audio_player.py 中的 _voice_cooldown 从 1.0秒 调整为 3.0秒。


代码修改

audio_stream.py

  • get_tts_websocket(): 改用 sys.modules 避免触发模块重载

app_main.py

  • 添加跳帧机制全局变量:_nav_processing_task, _nav_last_result_image, _nav_pending_frame
  • 修改 ws_camera_esp 中的帧处理为非阻塞式

audio_player.py

  • 调整 _voice_cooldown = 3.0 (原 1.0)

预期效果

场景 修改前 修改后
CHAT 模式 10 FPS 10 FPS
导航模式 0.5-1.5 FPS 8-10 FPS
Omni 对话 0.5 FPS 8-10 FPS

真正的根因

  1. 同步帧处理阻塞事件循环 - orchestrator.process_frame() 在主 async 循环中同步执行
  2. Omni 对话阻塞 - TTS 音频流发送与帧处理串行竞争时间片
  3. 双重 JPEG 编解码 - 每帧都解码+重编码

4. 线程池化帧处理

方案:将 CPU 密集型的帧处理移至 ThreadPoolExecutor 后台线程执行。

修改

  • 添加 concurrent.futures.ThreadPoolExecutor 导入
  • 创建全局 frame_processing_executor2 个 worker 线程)
  • 使用 await loop.run_in_executor() 执行 orchestrator.process_frame()
  • 使用 await loop.run_in_executor() 执行 trafficlight_detection.process_single_frame()
  • 在 lifespan 关闭时调用 executor.shutdown(wait=False)

📝 代码变更汇总

文件 变更
workflow_blindpath.py YOLO 帧间隔检查 + 性能诊断计时
app_main.py 添加线程池 + run_in_executor 异步帧处理
audio_player.py 增加语音冷却时间至 3秒

⏭️ 下一步 (Day 16 计划)

1. 户外测试全流程配置

  • 公网连接支持:修改代码支持命令行指定 IP (避免硬编码) 或配置公网服务器地址。
  • 开机自启动:配置 /etc/rc.local 实现通电即运行。
  • 程序固化:将 avaota_client 部署到 /usr/bin 等非易失存储。

3. 程序部署与自启动 (已验证)

  • 解决存储空间不足问题/overlay 空间不足 (316KB),改用 /mnt/UDISK (17MB)。
  • 部署命令adb push avaota_client /mnt/UDISK/
  • 自启动配置/etc/rc.local 添加启动脚本
    sleep 15
    /mnt/UDISK/avaota_client &
    
  • 连通性验证:通过串口日志确认 WiFi 连接成功,程序成功收发数据。

2. 网络自动连接

  • 配置 wpa_supplicant.conf 预存户外热点信息。
  • 验证断电重启后的自动重连能力。