6.1 KiB
6.1 KiB
Day 23 - 移动端优化 + PM2 部署 + 红绿灯检测修复
日期: 2025-12-29
主题: 可视化界面移动端适配与服务器部署优化
🔧 移动端可视化界面优化 (12:44)
问题:手机访问可视化界面时看不到视频画面
根因:
.stage容器在移动端height: auto时高度坍塌为 0- IMU 浮窗占满全宽,遮挡视频区域
fitCanvas()函数只用宽度计算高度,忽略容器实际高度- 移动端 IMU 浮窗无法折叠
修复内容
1. CSS 布局修复 (index.html)
/* 1100px 以下屏幕 */
@media (max-width:1100px) {
.stage {
min-height: 50vh; /* 确保视频区域有高度 */
height: 50vh;
}
.imu-float {
width: 160px;
right: 8px; bottom: 8px; /* 移到右下角 */
}
.imu-float:not(.expanded) {
height: 40px; /* 默认折叠 */
}
}
2. Canvas 尺寸计算修复 (main.js)
function fitCanvas() {
const rect = canvas.getBoundingClientRect();
const w = Math.max(320, Math.floor(rect.width) || 320);
let h = Math.floor(rect.height) || 0;
if (h < 100) h = Math.floor(w * 3 / 4); // 回退 4:3
...
}
3. 移动端默认折叠 IMU (main.js)
const isMobile = window.innerWidth < 1100;
if (isMobile) {
imuFloat.classList.add('collapsed');
imuToggle.textContent = '+';
}
🔧 PM2 服务器部署配置 (14:12)
需求:使用 PM2 管理 NaviGlass 后端服务
最简启动命令
pm2 start ~/ProgramFiles/OpenAIglasses_for_Navigation/venv/bin/python \
--name naviglass \
--cwd ~/ProgramFiles/OpenAIglasses_for_Navigation \
-- app_main.py
pm2 save
pm2 startup
🔧 VAD 模型加载优化 (14:25)
问题:PM2 启动时 VAD 模型加载卡住(尝试从 GitHub 检查更新超时)
原因:torch.hub.load() 默认每次检查远程更新,网络慢则超时
修复:优先使用本地缓存 (source='local')
代码变更 (server_vad.py)
# 优先使用缓存,避免每次检查 GitHub 更新
cache_dir = os.path.expanduser("~/.cache/torch/hub/snakers4_silero-vad_master")
if os.path.exists(cache_dir):
print(f"[VAD] 使用 torch hub 缓存: {cache_dir}")
_vad_model, _ = torch.hub.load(
repo_or_dir=cache_dir,
source="local",
model="silero_vad",
force_reload=False,
)
效果:启动从 ~30s 降至 ~3s
🔧 红绿灯检测画面卡住修复 (17:36)
问题:户外测试时,启动红绿灯检测后视频画面卡住
日志表现:
[PERF] 导航:147.2ms | state=TRAFFIC_LIGHT_DETECTION (第一帧)
[PERF] 导航:0.0ms | state=TRAFFIC_LIGHT_DETECTION (后续帧无处理)
根因分析:
- 红绿灯检测使用
await loop.run_in_executor(...)同步等待,阻塞主循环 - 广播时错误使用盲道导航的缓存
_nav_last_result_jpeg,而非红绿灯检测结果 - 如果之前运行过盲道导航,会一直广播旧的盲道检测图
修复方案
1. 添加红绿灯检测独立缓存 (app_main.py 第 550 行)
# ============== 红绿灯检测跳帧机制 =================
_traffic_light_task = None
_traffic_light_result_jpeg = None
_traffic_light_pending_frame = None
2. 实现非阻塞跳帧机制 (app_main.py 第 1503-1541 行)
if current_state == "TRAFFIC_LIGHT_DETECTION":
# 更新待处理帧
_traffic_light_pending_frame = bgr
# 如果任务完成,获取结果并启动新任务
if _traffic_light_task is None or _traffic_light_task.done():
if _traffic_light_task is not None and _traffic_light_task.done():
result = _traffic_light_task.result()
if result and result.get('vis_image') is not None:
_traffic_light_result_jpeg = turbo_encode(result['vis_image'])
# 启动新任务(不等待)
_traffic_light_task = loop.run_in_executor(...)
# 独立广播红绿灯检测结果
if _traffic_light_result_jpeg is not None:
await _broadcast_to_viewers(_traffic_light_result_jpeg)
else:
await _broadcast_to_viewers(data) # 首帧回退
continue # 跳过盲道导航逻辑
3. 停止时清除缓存
if "停止检测" in user_text:
global _traffic_light_result_jpeg
_traffic_light_result_jpeg = None # 清除缓存
修复效果:
- ✅ 红绿灯检测不再阻塞主循环
- ✅ 独立缓存,不干扰盲道导航
- ✅ 跳帧机制与盲道导航一致
🔧 Nginx 域名配置 (14:06)
需求:为可视化界面配置域名 naviglass.hbyrkj.top
Nginx 配置
server {
listen 80;
server_name naviglass.hbyrkj.top;
location /ws {
proxy_pass http://127.0.0.1:8081;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 86400;
}
location / {
proxy_pass http://127.0.0.1:8081;
proxy_set_header Host $host;
proxy_buffering off;
}
}
SSL 证书
sudo certbot --nginx -d naviglass.hbyrkj.top
📁 修改文件汇总
| 文件 | 修改内容 |
|---|---|
templates/index.html |
移动端 CSS 布局修复 |
static/main.js |
fitCanvas() 优化、移动端 IMU 折叠 |
server_vad.py |
VAD 模型本地缓存优先 |
app_main.py |
红绿灯检测跳帧机制 + 独立缓存 |
📝 Day 23 总结
| 类别 | 状态 | 说明 |
|---|---|---|
| 移动端视频显示 | ✅ | 布局修复 + Canvas 适配 |
| 移动端 IMU 折叠 | ✅ | 默认折叠 + 移到右下角 |
| PM2 部署 | ✅ | 一行命令启动 |
| VAD 加载优化 | ✅ | 本地缓存优先,启动快 30s→3s |
| 红绿灯检测卡顿 | ✅ | 跳帧机制 + 独立缓存 |
| Nginx 域名 | ✅ | naviglass.hbyrkj.top |