# 遥控器 App 交互架构与问题导读（RC-2000 / RC-3000 通用）

> **阅读对象：** 产品、测试、售后、管理层——无需读懂代码，也能理解「数据怎么流」「问题可能出在哪」。  
> **技术细节：** 见 `CODE_REVIEW_jetwave-rc-2000.md`、`CODE_REVIEW_jetwave-rc-3000.md`

---

## 1. 用一句话说清楚

遥控器里装了一个 Android 应用（**waverider**），它负责四件事：

1. **连上冲浪板上的电脑（ECU）**，看清速度、电量、故障  
2. **读手柄油门**，把「你想跑多快」发给板子  
3. **航行时每秒记一笔账**（位置、油门、故障码等）  
4. **结束后把账本上传到云端**，后台才能看到 [轨迹分析页](https://manager.jetwave.cn/motion/trajectoryHistory/analysis/14873)

近期用户反馈的 **断联、板体失速、无法控制**，在数据里主要对应三类信号：

| 用户感受 | 数据里的名字 | 数值 |
|----------|--------------|------|
| 板子失速、动力没了 | ESC 失速保护 | esc = **131072** |
| 过压保护 | ESC 过压保护 | esc = **4194304** |
| 和板子通信断了 | ECU：ESC 通信故障 | ecu = **1073741824** |

---

## 2. 整体交互架构（五层）

```mermaid
flowchart TB
    subgraph 用户层
        U[用户手柄油门/按键]
        UI[屏幕: 速度 电量 故障弹窗]
    end

    subgraph 遥控器App["遥控器 App (waverider)"]
        HF[主界面 HomeFragment<br/>航行/记日志/弹故障]
        DH[协议解析 DataHandler]
        UP[上传 UploadSailingRecordUtil]
    end

    subgraph 连接层["连接方式(两项目默认不同)"]
        BLE[板载蓝牙]
        SP[串口+星闪/增强蓝牙模块]
    end

    subgraph 板子端["冲浪板电子设备"]
        ECU[ECU 主控]
        ESC[ESC 电调/电机]
        BMS[电池管理]
    end

    subgraph 云端
        OSS[阿里云 OSS 存 txt 明细]
        API[JetWave 后台 API]
        WEB[管理后台可视化<br/>/analysis/日志id]
    end

    U --> HF
    HF --> UI
    HF -->|每秒记一笔| DB[(手机本地数据库)]
    HF -->|发油门/收心跳| DH
    DH --> BLE
    DH --> SP
    BLE --> ECU
    SP --> ECU
    ECU --> ESC
    ECU --> BMS
    ECU -->|心跳含故障码| DH
    DH -->|EventBus 通知| HF
    HF -->|结束航行| UP
    DB --> UP
    UP --> OSS
    UP --> API
    API --> WEB
    OSS --> WEB
```

**两项目唯一重大差别（连接层默认）：**

| 项目 | 默认怎么连板子 |
|------|----------------|
| **RC-2000** | 板载 **蓝牙** 直连 |
| **RC-3000** | **星闪**（先走串口 AT 命令，再透传数据） |

---

## 3. 关键业务逻辑说明

### 3.1 开机 → 连接板子

```mermaid
sequenceDiagram
    participant 用户
    participant App as 遥控器App
    participant 连接 as 蓝牙或星闪服务
    participant 板子 as ECU

    用户->>App: 打开应用 / 进入主界面
    App->>连接: 启动 BleService 或 SerialPortService
    连接->>板子: 扫描 / 配对 / AT建链
    板子-->>连接: 连接成功
    连接->>App: 通知「已连接」
    App->>板子: 请求设备信息(版本号等)
    板子-->>App: 返回 ECU/BMS/ESC 版本

    Note over 连接,App: ⚠️风险① 切换蓝牙/星闪时<br/>旧连接未干净断开
    Note over App: ⚠️风险② 协议解析器全局共用<br/>多线程可能串包
```

**普通人理解：** 就像手机连蓝牙耳机，连不上或连上又掉，后面所有速度、故障都不可信。

---

### 3.2 航行中：油门怎么变成板子动作

```mermaid
flowchart LR
    A[手柄霍尔传感器<br/>读油门角度] --> B[App 显示油门条]
    B --> C[通过 MAVLink 消息<br/>发给 ECU]
    C --> D[ECU 控制 ESC/电机]
    D --> E[板子运动]
    E --> F[ECU 每秒回传心跳<br/>速度/电流/故障码]
    F --> G[App 更新仪表盘]
    F --> H[App 写入本地轨迹<br/>约1秒1条]

    style A fill:#e8f4e8
    style H fill:#e8f4e8
```

**与「失速不可控」的关系：**

- 数据里常见：**油门 > 0，但 motorSpeed = 0**，且 esc = 131072（失速保护）  
- 说明：**人还在加油门，板子保护态不输出**——是保护逻辑或通信问题，不是用户没推油门  

```mermaid
flowchart TB
    subgraph 正常
        N1[油门推] --> N2[ECU收到] --> N3[电机转]
    end
    subgraph 异常_日志中常见
        A1[油门推] --> A2[ECU/ESC报失速131072]
        A2 --> A3[电机不转或无力]
        A3 --> A4[用户感觉失控]
    end
```

---

### 3.3 故障是怎么产生、显示、写进日志的

```mermaid
flowchart TB
    START[ECU/ESC 检测到异常] --> CODE[置位故障码<br/>esc或ecu字段]
    CODE --> MAV[MAVLink 心跳包<br/>每秒发给 App]
    MAV --> PARSE[DataHandler 解析]
    PARSE --> BUS[EventBus 广播]
    BUS --> UI{HomeFragment}

    UI --> POP[弹窗提示用户]
    UI --> SLS[阿里云埋点 SLS]
    UI --> DB[写入轨迹表<br/>escEventCode/ecuEventCode]

    DB --> OSS[航行结束上传 OSS]
    OSS --> BACK[后台 analysis/id 页面]

    style CODE fill:#ffe0e0
    style PARSE fill:#fff3cd
    style UI fill:#fff3cd
```

**三类故障在 App 里的处理（代码已命名）：**

| 故障码 | App 常量名 | 用户可能看到 |
|--------|------------|--------------|
| esc=131072 | ESC_FAULT_STALL_PROTECTION | 失速相关提示 + 埋点 |
| esc=4194304 | ESC_FAULT_OVERVOLTAGE_PROTECTION | 过压相关提示 + 埋点 |
| ecu=1073741824 | FAULT_ESC_COMMUNICATION | ESC 通信异常提示 + 埋点 |

**⚠️ 逻辑风险③（两项目共有）：**  
App 用「故障码 **等于** 某一个数」判断，如果板子一次上报 **多个故障同时存在**，界面可能 **只认一个**，漏报其它故障。

---

### 3.4 结束航行 → 上传云端

```mermaid
sequenceDiagram
    participant 用户
    participant App
    participant 本地 as 本地DB+txt文件
    participant OSS
    participant 后台

    用户->>App: 停止航行
    App->>本地: 汇总轨迹点(含esc/ecu码)
    App->>本地: 生成 txt<br/>命名: 遥控器SN_1_用户ID_时间.txt
    App->>OSS: 上传 txt
    OSS-->>App: 返回 objectKey
    App->>后台: 上报轨迹元数据
    后台->>后台: 生成日志 id
    Note over 后台: 可视化 URL<br/>.../analysis/{id}

    Note over App: ⚠️风险④ isUpload标志<br/>可能重复上传或卡死
    Note over App: ⚠️风险⑤ 上传成功即删本地文件<br/>失败难重传
```

**普通人理解：** 后台看到的每一条「飞行日志」，就是这次生成的 txt；我们分析的 719 条 CSV，每一行对应一个这样的 txt。

---

## 4. 问题环节总览图（按链路标红）

```mermaid
flowchart TB
    subgraph 环节1_连接
        L1A[蓝牙/星闪连接]
        L1B[SerialPortService 状态机复杂]
        R1((风险: 断联))
    end

    subgraph 环节2_协议
        L2A[字节流 → Parser 解析]
        R2((风险: 多线程串包))
    end

    subgraph 环节3_控制
        L3A[油门读取 vs 下发]
        L3B[ECU/ESC 保护态]
        R3((风险: 失速131072<br/>有油门无电机))
    end

    subgraph 环节4_故障逻辑
        L4A[心跳里的 esc/ecu 码]
        L4B[弹窗 + 写数据库]
        R4((风险: 只判断单一故障码))
    end

    subgraph 环节5_上传
        L5A[SQLite → JSON → OSS]
        R5((风险: 上传竞态/删文件))
    end

    subgraph 环节6_环境
        L6A[RC-3000 测试域名]
        R6B[线程池过大200]
        R6((风险: 性能/环境错配))
    end

    L1A --> L1B --> L2A --> L3A --> L3B --> L4A --> L4B --> L5A
    L1B -.-> R1
    L2A -.-> R2
    L3B -.-> R3
    L4B -.-> R4
    L5A -.-> R5
    L6A -.-> R6
    L6B -.-> R6
```

---

## 5. 两项目差异（一张表看懂）

| 对比 | RC-2000 | RC-3000 |
|------|---------|---------|
| 默认连接 | 蓝牙 | 星闪 |
| 云端 API | 生产 api.jetwave.ai | 测试 surfdev.aliyu.vip |
| 功能 | 核心航行 | + 对讲、AI、NFC、地图 |
| 油门硬件 | yyadc 霍尔 | kth5762 霍尔 + 开机校准 |
| 故障码/上传格式 | **相同** | **相同** |
| 代码风险点 | **相同** | **相同** + 更多后台服务 |

**排查建议：** 对比两项目设备的 **断联率、失速率**，若 3000 明显更高，优先查 **星闪链路**；若两项目都高，优先查 **ESC 固件 + Parser 线程安全**。

---

## 6. 和「一个月飞行日志」怎么对上号

```mermaid
flowchart LR
    A[用户航行] --> B[App 每秒记录<br/>含 esc/ecu 码]
    B --> C[上传 OSS txt]
    C --> D[入库 CSV 汇总行]
    D --> E[我们脚本筛选<br/>STALL/OV/ECU]
    E --> F[报告+后台链接<br/>analysis/id]

    G[代码 EscFaultMask] -.定义一致.-> B
    H[代码 EcuFaultMask] -.定义一致.-> B
```

| 日志分析结论 | 在架构哪一环 |
|--------------|--------------|
| 32 条有失速码 131072 | 环节3 ESC 保护 + 环节4 写入 |
| 6 条有过压 4194304 | 环节3 大电流/电压 + 环节4 |
| ecu 1073741824 常与 stall 同会话 | 环节1 通信 + 环节2 解析 |
| STALL+ECU 但很少同时有过压 | 说明不是过压引起，查通信/失速恢复 |

---

## 7. 会前 3 分钟怎么讲（口述稿）

1. 遥控器 App 是 **连接板子 → 推油门 → 每秒记日志 → 上传云端** 四条线。  
2. 用户说的失速、断联，在数据里主要是 **三个数字**：131072、4194304、1073741824，和代码里故障定义 **一致**。  
3. 问题 **不一定在 App 算错**，更可能在 **连接掉线、ESC 保护不恢复、上传/解析并发**；3000 还要多看 **星闪** 和 **测试环境域名**。  
4. 每条问题日志可在后台点开：`https://manager.jetwave.cn/motion/trajectoryHistory/analysis/{id}`。  
5. 优先查设备：**5G002872、6A000193、6A000540**（失速主导），**5C002991、5G001585**（过压）。

---

## 8. 快速优化改进（一页纸）

> 详细方案见两份 CODE_REVIEW 第 11/12 章。

### 本周必做 Top 5（两项目同步）

| 序号 | 改什么 | 为什么 |
|------|--------|--------|
| 1 | MAVLink 解析放 **单线程** | 现在多线程共用一个 Parser，可能「假断联、假故障」 |
| 2 | 故障判断改成 **位运算** | 板子可能同时报失速+通信故障，现在只认一个 |
| 3 | 上传加 **原子锁**，失败别删文件 | 避免传不上去或传两次 |
| 4 | 线程池从 200 收到 **4** | 遥控器 CPU 扛不住，通信会卡 |
| 5 | 3000 确认 **生产 API 域名** | 否则日志进测试环境，查问题白查 |

### 3000 多加 2 条

- 星闪断线：**3 秒无心跳就重连**，重连中别发油门  
- 航行时：**对讲/地图降资源**，别和 ECU 抢线程  

### 固件必须并行

- 失速 131072：**保护后能否恢复？** 不能就改 ESC 策略  
- 通信 1073741824：**ECU 和 ESC 之间** 是否超时  

---

## 9. 相关报告索引

| 文档 | 用途 |
|------|------|
| 本文 | 架构图 + 业务逻辑 + 问题环节（通俗） |
| `CODE_REVIEW_jetwave-rc-2000.md` | RC2000 技术审查 + **§11 快速改进** |
| `CODE_REVIEW_jetwave-rc-3000.md` | RC3000 技术审查 + **§12 快速改进** |
| `FAULT_FILTER_STALL_OV_ECU_REPORT.md` | 49 条故障日志清单+链接 |
| `MEETING_FULL_ANALYSIS_REPORT.md` | 719 条数据分析总报告 |
