# NaviGlass Client 📱

<div align="center">

**面向视障人士的智能导航与辅助系统 - 客户端**

基于 Avaota F1 (全志 V821 RISC-V) 的嵌入式终端

[功能特性](#功能特性) • [硬件配置](#硬件配置) • [编译部署](#编译部署) • [程序架构](#程序架构)

</div>

---

## ✨ 功能特性

- **摄像头采集**: GC2083 MIPI (1280×720 @20fps, JPEG 硬件编码)
- **音频采集**: 板载模拟麦克风 (16kHz/mono)
- **音频播放**: I2S + MAX98357A 功放
- **IMU 传感**: ICM-42688-P 六轴 (GPIO 模拟 SPI)
- **网络通信**: WebSocket (音视频) + UDP (IMU)
- **自动启动**: 开机自动连接服务器

---

## 🔧 硬件配置

### 核心硬件

| 组件 | 型号 | 接口 |
|------|------|------|
| SoC | 全志 V821 | 32-bit RISC-V |
| 摄像头 | GC2083 | MIPI-CSI2 |
| 功放 | MAX98357A | I2S (PD12/PD13/PD15) |
| 麦克风 | 板载模拟 | Audio Codec |
| IMU | ICM-42688-P | GPIO SPI |

### 引脚配置

| 功能 | 引脚 | 说明 |
|------|------|------|
| I2S BCLK | PD12 | 音频位时钟 |
| I2S LRCK | PD13 | 左右声道时钟 |
| I2S DOUT | PD15 | 音频数据输出 |
| SPI SCLK | PD3 | IMU 时钟 |
| SPI MOSI | PD2 | IMU 数据输入 |
| SPI MISO | PD4 | IMU 数据输出 |
| SPI CS | PD5 | IMU 片选 |

---

## 💻 开发环境

### 主机环境

- **系统**: Ubuntu 24.04 LTS
- **SDK**: Tina SDK (tina-v821-release)
- **工具链**: musl (`riscv32-linux-musl-`)

### SDK 路径

```
/home/rongye/ProgramFiles/AvaotaF1/avaota_sdk/tina-v821-release
├── prebuilt/rootfsbuilt/riscv/nds32le-linux-musl-v5d/  ← 工具链
└── ...
```

> ⚠️ 必须使用 **musl 工具链**，glibc 工具链与开发板不兼容

---

## 🚀 编译部署

### 1. 环境初始化

```bash
cd ~/ProgramFiles/AvaotaF1/avaota_sdk/tina-v821-release
source build/envsetup.sh
lunch  # 选择 avaota_f1
```

### 2. 交叉编译

```bash
cd ~/ProgramFiles/AvaotaF1/avaota_app_demo
./build_main.sh
```

### 3. 部署到开发板

```bash
# 复制到 SD 卡
cp avaota_client /media/$USER/SDCARD/

# 板端执行
mount /dev/mmcblk0p1 /mnt/extsd
cp /mnt/extsd/avaota_client /mnt/UDISK/
chmod +x /mnt/UDISK/avaota_client
/mnt/UDISK/avaota_client
```

### 4. 自动启动配置

程序已配置开机自启动：
- 位置: `/mnt/UDISK/avaota_client`
- 方式: `/etc/init.d/avaota` + `load_script.conf`
- 延迟: 15 秒 (等待音频系统就绪)

---

## 🏗️ 程序架构

```cpp
int main() {
    init_signal_handler();     // Ctrl+C 安全退出
    
    std::thread cam_thread(run_camera_loop);    // 摄像头 → WebSocket
    std::thread mic_thread(run_audio_capture);  // 麦克风 → WebSocket
    std::thread spk_thread(run_audio_play);     // WebSocket → 扬声器
    std::thread imu_thread(run_imu_udp);        // IMU → UDP
    
    cam_thread.join();
    mic_thread.join();
    spk_thread.join();
    imu_thread.join();
}
```

### 核心模块

| 目录 | 模块 | 功能 |
|------|------|------|
| `src/audio/` | AudioCapture | 麦克风采集 (ALSA) |
| `src/audio/` | AudioPlayer | 扬声器播放 (I2S) |
| `src/camera/` | Camera | MPP 框架封装 |
| `src/imu/` | ICM42688 | GPIO SPI 驱动 |
| `src/network/` | WSClient | WebSocket 客户端 |
| `src/network/` | UDPSender | UDP 发送 |

---

## 📡 通信协议

### WebSocket 连接

| 端点 | 用途 | 数据格式 |
|------|------|---------|
| `/ws/camera` | 摄像头上传 | Binary (JPEG) |
| `/ws_audio` | 音频双向 | Binary (PCM16 16kHz) |

### UDP 连接

| 端口 | 用途 | 数据格式 |
|------|------|---------|
| 12345 | IMU 数据 | JSON |

### 服务器地址

```cpp
// main.cpp
#define SERVER_IP "8.148.25.142"  // 公网 IP (frp 穿透)
#define SERVER_PORT 8081
```

---

## 📁 目录结构

```
NaviGlassClient/
├── avaota_app_demo/
│   ├── src/
│   │   ├── audio/          # 音频模块
│   │   ├── camera/         # 摄像头模块
│   │   ├── imu/            # IMU 模块
│   │   ├── network/        # 网络模块
│   │   ├── main.cpp        # 主程序
│   │   └── Makefile
│   └── build_main.sh
├── Device_Tree/            # DTS 配置
├── docs/                   # 硬件文档
└── README.md
```

---

## 📊 性能参数

| 指标 | 数值 |
|------|------|
| 视频帧率 | 10 FPS (上传) |
| 音频采样 | 16kHz / 16bit / Mono |
| IMU 采样 | 10 Hz |
| 启动时间 | ~15 秒 (音频系统就绪) |
| 功耗 | 待测 |

---

## 🔗 相关文档

- [服务器代码](../NaviGlassServer/) - Python 后端
- [开发日志](../Docs/DevLogs/) - Day 1 ~ Day 25
- [任务清单](../Docs/task_complete.md)
- [Avaota F1 文档](./docs/)

---

## 📄 许可证

MIT License
