7.4 KiB
Day 26 开发日志
日期:2026-01-04 主题:室内导盲模型服务器集成
🔧 室内导盲服务器集成
1. 状态机扩展 (NavigationMaster)
在 NavigationMaster 中添加了 INDOOR_NAV 状态,支持复用 BlindPathNavigator 进行室内导航。
# 新增状态常量
INDOOR_NAV = "INDOOR_NAV"
# 室内导航处理逻辑
if self.state == INDOOR_NAV:
# 优先使用室内导航器,fallback 到盲道导航器
nav = self.indoor if self.indoor else self.blind
bres = nav.process_frame(bgr)
2. 模型加载与初始化
在 app_main.py 中实现了 load_indoor_model() 函数,支持加载 TensorRT 优化的室内分割模型 yolo11l-seg-indoor14.engine。
在系统启动时,如果检测到室内模型,会自动初始化 indoor_navigator 并注入到 NavigationMaster。
3. 语音命令支持
扩展了 start_ai_with_text_custom 和 asr_core.py 白名单,支持以下命令:
- "室内导航" / "室内导盲": 启动室内导航模式
- "停止导航" / "结束导航": 停止当前导航(适用于所有模式)
4. 互斥逻辑
实现了室内导航与室外盲道导航、红绿灯检测的互斥逻辑。无论当前处于何种导航模式,新的导航命令都会正确切换状态或停止当前任务。
✅ 验证结果
- 模型加载: 系统启动时成功加载
yolo11l-seg-indoor14.engine(TensorRT FP16) - 语音控制: 语音命令正确触发
start_indoor_navigation() - 状态切换: UI 正确显示
[系统] 室内导航已启动
5. 动态语音合成 (EdgeTTS Fallback)
功能:室内导航检测到未预录的物体(如"前方有吸尘器")时,系统不再静默。 实现:
- 修改
audio_player.play_voice_text,当本地语音包缺失时,自动调用EdgeTTS。 - 采用
asyncio.create_task异步合成,不阻塞导航主线程。 - 增加了运行时内存缓存,相同语句只需合成一次。
🔧 客户端优化 (NaviGlassClient)
1. 内存碎片修复 (camera.cpp)
问题:原代码每帧画面(30fps)都执行 new/delete,在嵌入式设备(V821)上导致严重的内存碎片。
修复:
- 实现了静态双缓冲池 (
m_frame_buffers[2])。 - 启动时分配两次,运行期间零
malloc。 结果:✅ 彻底消除了运行时堆内存分配,防止 OOM。
2. 依赖移除 (ws_client.cpp)
问题:仅为了 WebSocket 握手时的 Base64 编码而引入了完整的 OpenSSL 库,增加了二进制体积和编译复杂度。 修复:
- 移除了所有 OpenSSL 头文件和链接库 (
-lssl -lcrypto)。 - 内置了一个轻量级的 Base64 编码器。 结果:✅ 减少了二进制体积,简化了交叉编译流程。
🔧 服务器重构与优化 (NaviGlassServer)
1. 全局状态重构 (ServerContext)
问题:app_main.py 包含 30+ 个分散的全局变量,导致状态管理混乱且容易产生竞态条件。
解决方案:
- 创建
ServerContext单例 (ctx) 统一管理所有状态(WebSocket 连接、导航标志、模型实例)。 - 提供了
ctx.reset_navigation_state()以安全地重置所有业务状态。
2. 结构化日志
问题:大量使用 print() 导致日志难以追踪且无法轮转。
修复:
- 引入
logging模块,配置了TimedRotatingFileHandler(每日轮转)。 - 关键错误使用
logger.error(..., exc_info=True)记录堆栈信息。
3. 动态导入与容错
修复:
- 将
trafficlight_detection和hand_landmarker等可选/重型模块移至顶层,并包裹在try-except中。 - 业务逻辑中增加了
if module:检查,确保模块加载失败时系统不崩溃。
4. 鲁棒性增强 (Retry Logic)
修复:
- EdgeTTS:
text_to_speech函数增加了指数退避重试,防止网络抖动导致语音缺失。 - GLM Client:
chat_stream增加了对 API 429 (Rate Limit) 的自动重试。
🐛 Bug Fixes & Optimization
1. 语音命令与模式互斥修复
问题: "停止室内导航" 命令被错误识别为启动命令;室内模式下仍触发室外斑马线检测。 修复:
- 命令优先级: 在
app_main.py中,将停止命令的判断移至启动命令之前。 - 检测互斥: 在
workflow_blindpath.py中引入enable_crosswalk_detection标志。室内模式初始化时禁用斑马线检测。
2. 服务器启动日志净化
目标: 消除启动时的冗余警告和刷屏日志,提供干净的专业级控制台输出。 优化内容:
- 音频压缩日志: 屏蔽了
audio_compressor.py中 100+ 行的详细压缩比率日志 ([INFO] [压缩] ...)。 - HandLandmarker: 注释了旧 AI 管道未使用的
hand_landmarker导入,消除 ImportError 警告。 - TensorRT 警告: 修复了
model.to(device)错误调用导致的警告(TRT 引擎不需要移至 GPU)。 - YOLO Task: 显式指定
YOLO(..., task='detect'),消除任务自动猜测警告。 - 结果: 启动日志行数减少 80%,关键信息一目了然。
3. EdgeTTS 磁盘缓存 (代码审查优化)
问题: EdgeTTS 动态合成的语音只在运行时缓存,重启后需重新合成。 修复:
- 在
audio_player.py中添加磁盘缓存目录voice/tts_cache/ - 使用 MD5 哈希作为文件名,首次合成后自动保存
- 重启后优先从磁盘加载,减少网络延迟
4. 可配置日志采样间隔
目标: 调试时可临时增加日志输出,生产环境减少刷屏。 实现:
- 新增环境变量
AIGLASS_LOG_INTERVAL(默认 30 帧) - 在
workflow_blindpath.py中替换硬编码的% 30
5. API Key 管理规范化
GLM_API_KEY从glm_client.py硬编码移至.envDASHSCOPE_API_KEY标记为可选(旧管道)
6. 项目文件清理
清理内容:
mobileclip_blt.ts(571MB) - 无引用残留模型recordings/(~600MB) - 测试录音文件test/(~580MB) - 测试视频文件compile/- ESP32 残留代码.env.performance- 重复配置 释放空间: ~1.75GB
7. 启动日志优化
- pygame 欢迎信息: 设置
PYGAME_HIDE_SUPPORT_PROMPT=1抑制 - CROSS_STREET .to() 警告: 改用
is_tensorrt_engine()静默处理
8. 室内导航工作流 (IndoorNavigator)
问题: 室内模式使用 BlindPathNavigator,但类别 ID 不匹配(期望 blind_path ID=1,实际是 corridor)。
解决方案: 创建专用 workflow_indoor.py
# 室内类别映射 (14 classes from MIT Indoor)
WALKABLE_CLASSES = {0, 1, 2} # floor, corridor, sidewalk
OBSTACLE_CLASSES = {3, 4, 5, 11, 12} # chair, table, sofa_bed, cabinet, trash_can
POI_CLASSES = {6, 7, 8} # door, elevator, stairs
实现内容:
IndoorNavigator类 (~400行)- 可行走区域检测: 合并 floor + corridor + sidewalk
- 障碍物避障: 前方区域 chair/table/person 检测
- 兴趣点提示: door/elevator/stairs 语音播报
- 方向引导: 基于可行走区域左中右分布计算
修改文件:
app_main.py: 室内导航器改用IndoorNavigatornavigation_master.py: 兼容IndoorResult类型
📋 下一步
- 室内导航实际测试
- 根据用户反馈微调语音引导策略