← 返回目录

遥控器 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. 结束后把账本上传到云端,后台才能看到 轨迹分析页

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

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

2. 整体交互架构(五层)

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 开机 → 连接板子

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 航行中:油门怎么变成板子动作

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

与「失速不可控」的关系:

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

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

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 结束航行 → 上传云端

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. 问题环节总览图(按链路标红)

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. 和「一个月飞行日志」怎么对上号

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 条

固件必须并行


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 条数据分析总报告