一、项目概述
青鸾云步是一款面向视障人士的智能导盲机器人配套 APP,运行于 Android 手机,通过蓝牙连接 ESP32 双轮机器人,实现障碍物语音预警 + AI 智能对话 + 高德步行导航三大核心功能。用户全程无需看屏幕,所有交互通过语音完成。
核心体验闭环:机器人推杆 → 超声波检测障碍物 → 蓝牙推送数据 → 手机 APP 语音播报方向与距离 → AI 大模型理解用户意图 → 高德地图规划步行路线 → TTS 逐段语音导航。
二、技术栈一览
| 层级 | 技术 | 用途 |
|---|---|---|
| 容器框架 | Apache Cordova 12 + Android 14 | 将 HTML5 网页打包为原生 APK |
| 前端 UI | 纯 HTML/CSS/JS 单文件 | 深色主题适老化界面 |
| 离线语音识别 | Vosk Android SDK 0.3.32(中文 small 模型 66MB) | 本地离线 STT,无需联网 |
| 语音合成 | cordova-plugin-tts(Android 原生 TTS)+ Web Speech API 降级 | 中文 TTS 播报 |
| AI 大模型 | DeepSeek V4 Flash/Pro(OpenAI 兼容 API) | 自然语言理解、导航意图解析 |
| 地图导航 | 高德 Web Services REST API v3 | GPS 定位、地址编码、步行路线规划 |
| 蓝牙通信 | cordova-plugin-ble-central + BLE GATT 轮询 | 接收机器人障碍物 JSON 数据 |
| 定位 | cordova-plugin-geolocation(WGS-84 GPS) | 高精度实时位置追踪 |
| 音频提示 | Web Audio API | 方向性蜂鸣(左/右/中立体声定位) |
三、架构设计

关键设计决策
- 离线 STT 优先:Vosk 模型直接嵌入 APK(assets 目录),首次启动自动解压,无需下载。解决视障用户网络不稳定场景。
- 纯 REST 地图方案:不使用高德 Android SDK(体积大、需原生集成),改用 REST API 在 JS 层完成所有地图操作,APK 零侵入。
- BLE 轮询模式:放弃不可靠的 BLE notify/indicate,用 200ms 定时 readCharacteristic 获取传感器数据,兼容性更好。
四、核心技术实现
4.1 Vosk 离线语音识别
APK 内嵌模型 + 自动解压
Vosk 中文小模型约 66MB,直接放入 assets/vosk-models/ 目录随 APK 分发。关键踩坑:Android 的 aapt2 构建工具默认压缩 assets 中大于 1MB 的文件,导致模型文件(final.mdl 16MB、Gr.fst 26MB)被压缩后无法通过 AssetManager.open() 读取。
解决方案:在 build-extras.gradle 中配置禁止压缩:
gradle
android {
aaptOptions {
noCompress 'mdl', 'fst', 'int', 'ie', 'mat', 'dubm', 'conf', 'stats'
}
}
回声消除
通话模式下,APP 播报 TTS 时麦克风会录到自己的声音,导致"自问自答"死循环。解决方案分三层:
- TTS 播报前停止识别器(
cordova.plugins.SpeechToText.stop()),清空 Vosk 缓冲区 ttsSpeaking标志位,识别回调检测到后直接跳过- 播报时长估算(中文 ~4字/秒),延时后重启识别器
去重机制
Vosk 在用户沉默时会持续返回上一次的最终识别结果。通过 lastRecognizedText 变量记录上次已发送文本,相同时跳过。
4.2 高德地图步行导航
采用高德 Web 服务 API(非 SDK),纯 HTTP 调用:
| 接口 | 端点 | 用途 |
|---|---|---|
| 地理编码 | /v3/geocode/geo |
地名 → 坐标 |
| 逆地理编码 | /v3/geocode/regeo |
坐标 → 街道名 |
| POI 搜索 | /v3/place/text |
附近地点查询 |
| 步行路线 | /v3/direction/walking |
步行路径规划 |
坐标系统坑点 :Android GPS 返回 WGS-84 坐标,高德默认使用 GCJ-02(国测局坐标)。通过在所有请求中传入 coordsys=gps 参数告知高德输入为 WGS-84,省去手动坐标转换。
坐标顺序坑点 :高德 API 返回的坐标格式统一为 "经度,纬度"(lng 在前),解析时必须注意顺序。JS 端 parseFloat(loc[0]) 是经度,loc[1] 是纬度。
导航语音优先级体系:
| 优先级 | 事件 | 行为 |
|---|---|---|
| emergency | BLE 避障危险/紧急转弯 | 立即打断一切 |
| high | 转弯接近 < 30m | 等待 emergency 结束 |
| medium | 转弯预告 30-100m | 空闲 3 秒后播报 |
| low | 继续直行 | 空闲 5 秒后播报 |
4.3 AI 导航意图解析
利用 DeepSeek 大模型理解用户自然语言中的导航意图,而非传统的关键词匹配。
系统提示词注入当前 GPS 位置和导航状态,并约定输出格式:
如果用户询问导航相关问题,请在回复末尾附加一行
[[NAV:地点名称]]
前端检测 AI 回复中的 [[NAV:...]] 标记后,自动提取目的地 → 调用高德 POI 搜索/地理编码 → 启动步行导航。
示例对话:
- 用户:"带我去最近的药店"
- AI:"好的,附近有老百姓大药房,距离约300米。正在为您规划步行路线。[[NAV:老百姓大药房]]"
- 系统:自动搜索 POI 坐标 → 规划路线 → 语音引导
4.4 BLE 蓝牙通信
使用轮询模式(每 200ms 读取一次 GATT 特征值),替代不可靠的 BLE notify。ESP32 端每秒推送一次 JSON:
json
{
"distance": 85.3,
"direction": "left",
"direction_cn": "左前方",
"status": "Obstacle",
"level": "warning",
"level_cn": "警告",
"emergency": false,
"turning": false,
"turn_dir": "",
"angle": 95.0
}
APP 解析后实时更新障碍物界面(距离数字、方向标签、安全等级色条),并根据等级和方向触发立体声蜂鸣(Web Audio API 的 StereoPanner 实现左右耳定位)。
五、项目结构
text
android_app/
├── www/
│ └── index.html # 整个 APP(1402行,HTML+CSS+JS 全内联)
├── config.xml # Cordova 配置
├── platforms/android/
│ ├── build-extras.gradle # 禁止压缩 Vosk 模型文件
│ └── app/src/main/
│ ├── assets/
│ │ ├── www/ # cordova prepare 自动同步
│ │ └── vosk-models/ # 内嵌中文语音模型 (66MB)
│ ├── res/
│ │ ├── drawable/ # 启动画面图标
│ │ ├── mipmap-*/ # 自适应图标(含 v26 版本)
│ │ └── values/ # 主题和颜色
│ └── java/com/vayapedal/speechtotext/
│ ├── SpeechToText.java # Vosk 插件(已修改:内嵌模型自动复制)
│ └── FileManager.java # 资产文件管理(已修改:assets→存储)
└── plugins/
├── cordova-plugin-tts
├── cordova-plugin-ble-central
├── cordova-plugin-geolocation
└── vosk-speech-to-text # 离线语音识别插件
六、构建命令
bash
cd android_app
cordova prepare android # 同步 www/ 到平台
cd platforms/android
./gradlew assembleDebug # 编译 APK
# 输出: app/build/outputs/apk/debug/app-debug.apk (~107MB)
七、总结
"青鸾云步"以 Cordova 混合开发框架为基座,将离线语音识别、大模型 AI 对话、高德步行导航三大能力整合进一个 1400 行的单 HTML 文件,实现了完全语音驱动的导盲体验。核心技术亮点包括 Vosk 模型 APK 内嵌免下载、BLE 轮询模式替代不可靠通知、AI 自然语言导航意图解析、以及导航语音与避障语音的优先级调度。