Jetwave RC-3000 遥控器应用 — 代码分析报告
项目路径: jetwave-rc-3000/
包名: com.szdbi.waverider
审查日期: 2026-05-25
审查视角: 嵌入式系统、AI 硬件链路、全栈/客户端、产品架构、代码审查
非技术人员请先读: 交互架构与问题导读(含全流程图)
本文档偏技术细节;RC-2000 与 RC-3000 共用同一套故障码与上传格式,差异主要在 默认连接方式。
〇、整体交互架构(RC-3000)
这个 App 和 RC-2000 有什么不同?
相同: 连板子、推油门、记日志、上传云端、三种故障码(131072 / 4194304 / 1073741824)的定义 完全一致。
不同(对问题排查很重要):
| 项目 |
RC-3000 |
RC-2000 |
| 默认连板子方式 |
星闪(串口 AT + 模块) |
蓝牙 直连 |
| 云端地址 |
测试环境 surfdev |
生产 api.jetwave.ai |
| 额外功能 |
对讲、AI、NFC、地图页 |
无 |
整体架构图(RC-3000:默认星闪 + 扩展功能)
flowchart TB
subgraph 用户侧
U[油门/屏幕/对讲]
end
subgraph RC3000_App["RC-3000 App"]
MA[MainActivity]
HF[HomeFragment 主航行]
SM[SailMapFragment 地图]
IC[IntercomService 对讲]
SPS[SerialPortService 星闪/串口]
DH[DataHandler]
UP[UploadSailingRecordUtil]
end
subgraph 连接
SP[串口 /dev/ttyS1<br/>AT命令控制星闪模块]
GATT[BLE GATT 透传 MAVLink]
end
subgraph 板子
ECU[ECU]
ESC[ESC]
end
subgraph 云
OSS[OSS]
WEB[后台 analysis/id]
end
U --> HF
U --> SM
U --> IC
MA --> HF
MA --> SM
SPS --> SP
SP --> GATT
GATT --> ECU
SPS --> DH
DH --> ECU
ECU --> ESC
HF --> DH
HF --> UP
UP --> OSS --> WEB
关键业务逻辑(五条线,比 2000 多一条)
| 业务线 |
做什么 |
主要程序 |
出问题时的表现 |
| 连接 |
星闪模块扫描、AT 建链 |
SerialPortService、SerialPortUtil |
断联、连接耗时长 |
| 控制 |
油门(kth5762)+ 开机写校准值 |
CommandHelper、MyApplication |
油门不准、失速 |
| 故障 |
同 2000 |
HomeFragment、EscFaultMask |
同上 |
| 上传 |
同 2000 |
UploadSailingRecordUtil |
同上;注意 测试域名 |
| 对讲/地图 |
语音、Mapbox |
IntercomService、SailMapFragment |
抢占 CPU/网络,间接影响 ECU 通信 |
业务流程图 ①:星闪连接(RC-3000 特有路径)
sequenceDiagram
autonumber
actor 用户
participant App as SerialPortService
participant AT as SerialPortUtil AT命令
participant 模块 as 星闪/BLE模块
participant DH as DataHandler
participant ECU as 板子ECU
用户->>App: 打开 App(默认星闪)
App->>AT: 打开串口 ttyS1
AT->>模块: AT+扫描/连接 星闪
模块->>ECU: 建立无线链路
ECU-->>模块: 连接OK
模块-->>AT: 透传字节流
AT->>DH: 送入 Parser
rect rgb(255, 230, 230)
Note over App,DH: ⚠️【风险A】状态机步骤多<br/>比直连蓝牙更易断联
Note over DH: ⚠️【风险B】Parser 全局共用
end
业务流程图 ②:故障从板子到后台(与日志完全同源)
flowchart TB
subgraph 板子端
E1[ESC触发保护] --> E2[esc=131072 或 4194304]
E3[ECU发现ESC通信异常] --> E4[ecu=1073741824]
end
subgraph App端
H1[心跳 msg_ecuheatbeatdata] --> H2[DataHandler]
H2 --> H3[HomeFragment]
H3 --> H4[弹窗 + 写SQLite]
H4 --> H5[结束上传OSS]
end
subgraph 云端
C1[CSV汇总行] --> C2[analysis/id 页面]
end
E2 --> H1
E4 --> H1
H5 --> C1 --> C2
style E2 fill:#ffcdd2
style E4 fill:#ffcdd2
普通人版问题逻辑:
- 失速(131072):电机保护,像「保险跳闸」,油门可能还在推,车不动
- 过压(4194304):电压太高保护,多在 大电流高速 时出现(日志里 6 条会话)
- ESC通信故障(1073741824):ECU 和 ESC 说话中断,和「断联、失控」描述最接近
- 日志里 经常是失速 + 通信故障在同一台设备,但 很少同时有过压 → 排查应优先 通信/失速恢复,不是过压
业务流程图 ③:RC-3000 额外风险(对讲/环境)
flowchart LR
subgraph 资源竞争
A[IntercomService 对讲]
B[SailMap 地图]
C[ECU 通信服务]
end
A -.->|抢网络/CPU| C
B -.->|占内存| C
subgraph 环境
D[API=测试域名 surfdev]
E[⚠️量产若未改则数据进错环境]
end
问题环节与程序对照表(RC-3000)
| 环节 |
可能问题 |
涉及程序 |
严重度 |
| 星闪连接 |
断联多、建链慢 |
SerialPortService、SerialPortUtil |
高 |
| 协议解析 |
同 2000 |
DataHandler 静态 Parser |
高 |
| 失速/通信故障 |
131072 + 1073741824 |
固件 + HomeFragment |
高 |
| 过压 |
4194304 |
ESC 固件 / 电池 |
中(会话少) |
| 测试环境 |
数据与生产后台不一致 |
RequestManager surfdev |
高(若量产未改) |
| 对讲/地图 |
间接导致通信差 |
IntercomService、SailMapFragment |
中 |
| 上传/线程 |
同 2000 |
UploadSailingRecordUtil、ThreadPoolUtil |
中 |
本仓库相关设备示例(可点开后台)
| 现象 |
日志 id |
后台链接 |
| 过压为主 |
14840 |
https://manager.jetwave.cn/motion/trajectoryHistory/analysis/14840 |
| 轻度失速 |
14873 |
https://manager.jetwave.cn/motion/trajectoryHistory/analysis/14873 |
| 失速+通信 |
14607 |
https://manager.jetwave.cn/motion/trajectoryHistory/analysis/14607 |
0. 执行摘要
| 维度 |
评级 |
一句话 |
| 整体结构 |
B- |
在 RC-2000 基线上扩展对讲/AI/NFC/地图,复杂度更高 |
| 通信设计 |
B |
默认 星闪,协议栈与 2000 同源 |
| 交互逻辑 |
B- |
多 Fragment 并行(航行/对讲/地图),状态同步依赖 EventBus |
| 运动控制 |
B |
增加开机角度校准写 sysfs,油门链路同 2000 |
| 日志上传 |
B |
同 OSS 格式,API 指向测试环境 |
| 内存管理 |
C+ |
对讲 SDK + Mapbox + 大地图,内存压力高于 2000 |
| 线程安全 |
C |
继承 2000 的 Parser/线程池/上传竞态问题 |
| 风险漏洞 |
C- |
测试域名上线、自定义证书、功能面更大攻击面 |
与飞行日志: 故障码定义与 RC-2000 完全相同。日志中 231AAAA5G001585(过压+轻度失速)等设备需在本仓库确认固件版本与 默认星闪通信 是否影响断联统计。
1. 项目概览
| 项 |
内容 |
| 类型 |
Android 系统应用(RC3000 专用 Launcher) |
| 工程名 |
waverider-yoyo-rc3000 |
| Java 源文件 |
361(+54 vs RC-2000) |
| Activity |
26 |
| 默认通信 |
星闪 STAR_DODGES(MyApplication) |
| API 环境 |
测试 https://surfdev.aliyu.vip |
| 独有能力 |
MCX 对讲、火山 AI SSE、NFC 绑定、航行地图 Fragment |
2. 整体结构
2.1 增量模块(相对 RC-2000)
| 模块 |
路径 |
说明 |
| 对讲 |
service/IntercomService.java、intercom/* |
MCX SDK |
| AI |
sse/BackendClient.java、dialog/ai/DialogAiIntercom.java |
SSE 语音 |
| NFC |
manager/JetWaveLinkManager.java、service/MyHostApduService.java |
碰一碰绑定 |
| 地图航行 |
fragments/SailMapFragment.java |
Mapbox 实时轨迹 |
| 语音好友 |
activity/VoiceIntercomActivity.java 等 |
社交对讲 |
| 角度校准 |
MyApplication 开机写 CommandHelper.WRITE_ANGLE_CALIBRATION_VALUE_CMD |
RC-3000 独有 |
2.2 架构图(扩展版)
flowchart TB
MA[MainActivity]
HF[HomeFragment]
SM[SailMapFragment]
IC[IntercomService / MCX]
AI[SSE / 语音引擎]
MA --> HF
MA --> SM
MA --> IC
MA --> AI
HF --> DH[DataHandler]
SM --> DH
DH --> ECU[ECU/BMS/ESC]
HF --> UP[UploadSailingRecordUtil]
UP --> OSS[阿里云 OSS]
UP --> API[surfdev.aliyu.vip]
2.3 结构评审
| 优点 |
缺点 |
| 功能完整,覆盖 RC3000 产品定义 |
模块耦合度高于 RC-2000 |
| 与 2000 共享 MAVLink,固件契约统一 |
测试 API 与生产数据混用风险 |
| ViewBinding + Fragment 分治 |
缺少模块边界文档 |
3. 通信设计
3.1 默认星闪路径(与 2000 最大差异)
// MyApplication.java (RC-3000)
SpUtil.putString(..., DataCommunicationMethodEnum.STAR_DODGES.name());
// MyApplication.java (RC-2000)
SpUtil.putString(..., DataCommunicationMethodEnum.BLUETOOTH.name());
影响分析:
- 首次启动走 串口 AT → 星闪模块 → BLE GATT 透传 MAVLink
- 日志中部分设备 长时间 stall + ecu 通信故障,需确认星闪链路稳定性是否优于板载 BLE
- OTA/扫描流程更长,状态机集中在
SerialPortService.java
3.2 协议与故障码(与 RC-2000 一致)
| 故障 |
枚举 |
值 |
| 失速保护 |
EscFaultMask.ESC_FAULT_STALL_PROTECTION |
131072 |
| 过压保护 |
EscFaultMask.ESC_FAULT_OVERVOLTAGE_PROTECTION |
4194304 |
| ESC 通信故障 |
EcuFaultMask.FAULT_ESC_COMMUNICATION |
1073741824 |
定义文件:com/mavlink/enums/EscFaultMask.java、EcuFaultMask.java
3.3 通信相关增量风险(3000 特有)
| 风险 |
说明 |
| 星闪 AT 超时 |
SerialPortService 状态多,切换 BLE/星闪易留僵尸连接 |
| 对讲占用音频/网络 |
IntercomService 与 ECU 通信争抢主线程/网络 |
| NFC + BLE 同时 |
JetWaveLinkManager 与 BleService 生命周期交叉 |
| 4G 模组串口 |
CommandHelper 操作 /dev/ttyUSB0,与 /dev/ttyS1 并存 |
4. 交互逻辑
4.1 页面结构
MainActivity + ViewPager2:
HomeFragment — 主仪表盘航行
SailMapFragment — 地图航行(3000 独有)
IntercomMapFragment — 对讲地图
StopFragment / CompleteFragment — 结束流程
MusicFragment — 媒体
4.2 故障 UI 逻辑
与 RC-2000 相同,集中在 fragments/HomeFragment.java:
escEvent == EscFaultMask.ESC_FAULT_STALL_PROTECTION → 失速弹窗 + SLS 埋点
escEvent == EscFaultMask.ESC_FAULT_OVERVOLTAGE_PROTECTION → 过压埋点
ecuEvent == EcuFaultMask.FAULT_ESC_COMMUNICATION → ESC 通信故障提示
缺陷(两项目共有): 使用 == 而非位掩码,无法表达多故障同时置位。
4.3 产品交互风险
- 用户可在设置中切换通信方式,切换中 Parser/连接状态需复位(
DataHandler.disconnect() 需保证调用)
- 新手引导、体验单、租赁模式交织在
HomeFragment Timer 内,异常状态难复现
- AI 对讲弹窗可能与故障弹窗 叠加,需规范 Dialog 优先级
5. 运动控制模块
5.1 RC-3000 增强点
开机角度校准(硬件层):
// MyApplication.onCreate
CommandHelper.exec(WRITE_ANGLE_CALIBRATION_VALUE_CMD, angleCalibrationValueStr);
- 读取路径:
CommandHelper 使用 kth5762/read_angle(与 RC-2000 的 yyadc/hall_sensor 路径不同,需硬件确认)
5.2 油门 → 轨迹 → OSS(与日志分析一致)
| 阶段 |
文件 |
| 采样 |
HomeFragment Timer → SailingRecordItem |
| 字段 |
throttleLeverQuantity, gear, mode, motorSpeed, escEventCode, ecuEventCode |
| 导出 |
UploadSailingRecordUtil → {remoteSn}_1_{userId}_{time}.txt |
| 回放 |
已验证 231AAAA5G001585_1_10000259_20260517180513 可提取油门曲线 |
5.3 运动控制风险(结合日志)
| 设备 SN |
日志现象 |
代码关联 |
| 5G001585 |
过压 68% + stall 2% |
同 SN 在 HomeFragment 记录 esc/ecu 原始码 |
| 5G002872 |
100% stall 会话 |
需查该 SN 默认通信方式与固件 esc=0551 |
| 6A000193 |
stall 91.6% + ecu 8% |
FAULT_ESC_COMMUNICATION 埋点 |
6. 日志上传模块
6.1 环境与域名(重要差异)
// RequestManager.java (RC-3000)
public final static String API_SERVER_URL = "https://surfdev.aliyu.vip";
public final static String VOICE_API_SERVER_URL = "https://surfdev.aliyu.vip/robot-api";
// RC-2000
public final static String API_SERVER_URL = "https://api.jetwave.ai";
风险: 若 RC3000 量产包仍指向测试域,轨迹与 manager.jetwave.cn 生产后台数据 可能不一致。
6.2 网络安全配置
res/xml/network_security_config.xml:
cleartextTrafficPermitted=true
- 信任
@raw/surfdev_aliyu_vip 自定义证书
审查意见: 利于测试环境调试,生产需收紧。
6.3 上传链路(同 RC-2000)
SailingRecordItem (SQLite, ~1Hz)
→ SailingRecordDTO + trajectoryList
→ 本地 JSON 文件
→ AlibabaCloudOssUtil
→ TrajectoryApi 上报 objectKey
故障字段原样上传,与 surf_motion_trajectory_history / OSS JSON 完全一致。
6.4 埋点扩展
DataTrackingConstant 含:
ESC_FAULT_STALL_PROTECTION
ESC_FAULT_OVERVOLTAGE_PROTECTION
FAULT_ESC_COMMUNICATION
与 SLS 离线队列 DataTrackingManager 联动,可用于 无 OSS 明细时的故障率统计。
7. 内存管理
| 因素 |
RC-3000 额外压力 |
| Mapbox |
SailMapFragment / IntercomMapFragment 地图瓦片缓存 |
| 对讲 SDK |
MCX native 内存 |
| 语音 AI |
SpeechEngine + SSE 长连接 |
| 大图堆 |
largeHeap=true 已开启 |
日志文件策略同 2000: 10MB/文件,100MB 总量,LogFileManager + ReentrantLock。
建议: 航行中降低地图刷新率;对讲与 ECU 通信分进程优先级(若系统允许)。
8. 线程安全
8.1 继承自 RC-2000 的共性问题
| 问题 |
文件 |
严重度 |
静态 Parser |
DataHandler.java |
高 |
| 线程池 100~200 |
ThreadPoolUtil.java |
高 |
isUpload 静态 boolean |
UploadSailingRecordUtil.java |
中 |
8.2 RC-3000 新增并发点
| 组件 |
风险 |
IntercomService |
回调线程与 UI 线程交错 |
BackendClient SSE |
长连接读线程 + EventBus |
SailMapFragment |
地图渲染线程 + 定位回调 |
OTAAppFragment |
多处 synchronized 仍可能死锁 APK 安装流程 |
未见统一的 SerialExecutor 约束 MAVLink 解析。
9. 风险与漏洞
| 等级 |
项 |
RC-3000 特有 |
| 高 |
测试 API 域名用于系统应用 |
是 |
| 高 |
Parser 线程安全 |
共有 |
| 中 |
自定义证书 + 明文 HTTP |
是 |
| 中 |
MCX/语音第三方 SDK 黑盒 |
是 |
| 中 |
功能开关多导致状态不一致 |
是 |
| 低 |
签名密钥仓库内 JetwaveKey.jks |
是 |
10. 与近一月飞行日志的交叉分析
10.1 代码 — 日志 — 后台 三角关系
ECU/ESC 固件置位 esc/ecu event
→ MAVLink msg_ecuheatbeatdata
→ DataHandler → EventBus
→ HomeFragment 写入 SailingRecordItem.escEventCode / ecuEventCode
→ UploadSailingRecordUtil → OSS txt
→ 后台入库 surf_motion_trajectory_history
→ manager.jetwave.cn 可视化 /analysis/{id}
10.2 RC-3000 相关设备(来自故障筛选报告)
| id |
SN |
链接 |
代码侧关注 |
| 14873 |
231AAAA5G001585 |
分析 |
油门回放已提取;过压见 14840 |
| 14840 |
231AAAA5G001585 |
分析 |
esc=0557, bms=0276 |
| 14671 |
231AAAA5G001585 |
分析 |
stall 45% |
10.3 共性问题结论(两项目适用)
- STALL+ECU 无 OV → 软件应优先查 ESC 通信/失速状态机,非过压逻辑
- eventCode 单值存储 → 分析侧用精确匹配正确,但 App 展示可能漏报复合故障
- 星闪默认(3000) → 对比 BLE 默认(2000)设备的断联率是否有系统性差异
11. RC-2000 vs RC-3000 对照表
| 维度 |
RC-2000 |
RC-3000 |
| 规模 |
307 Java |
361 Java |
| 默认通信 |
蓝牙 |
星闪 |
| API |
api.jetwave.ai |
surfdev.aliyu.vip |
| 油门 sysfs |
yyadc/hall_sensor |
kth5762/read_angle |
| 开机校准写 |
无 |
有 |
| 对讲/AI/NFC |
无 |
有 |
| 地图航行页 |
无独立 SailMap |
有 |
| 故障码定义 |
相同 |
相同 |
| 上传文件格式 |
相同 |
相同 |
| 线程/Parser 风险 |
相同 |
相同 |
12. 快速优化改进建议(RC-3000)
RC-3000 在 RC-2000 共性问题上 额外关注:星闪默认链路、测试 API、对讲/地图抢资源。下列 Q1~Q5 与 2000 相同,两项目应同步改。
12.1 改进优先级总览
flowchart LR
subgraph P0_本周必做
A1[Parser单线程]
A2[故障位运算]
A3[上传原子锁]
A4[确认生产API域名]
A5[星闪断线策略]
end
subgraph P1_两周
B1[连接质量埋点]
B2[对讲/航行资源隔离]
B3[问题设备回归]
end
subgraph P2_一月
C1[HomeFragment拆分]
C2[通信层抽象]
C3[断点续传]
end
P0_本周必做 --> P1_两周 --> P2_一月
12.2 快速赢(与 RC-2000 同步,1~3 天)
| # |
改进项 |
RC-3000 补充说明 |
| Q1 |
Parser 单线程化 |
必做;星闪路径多线程 AT+透传,风险高于纯蓝牙 |
| Q2 |
故障码位运算 |
同 2000;见 HomeFragment.java |
| Q3 |
上传 AtomicBoolean |
同 2000;测试环境更需防丢文件 |
| Q4 |
线程池缩容 |
对讲 SDK 已占资源,App 侧必须收紧 |
| Q5 |
连接切换复位 |
星闪 ↔ 蓝牙切换时 强制 disconnect |
12.3 RC-3000 专属快速项(建议 1 周内)
| # |
改进项 |
方案 |
改哪里 |
| T1 |
确认量产 API |
发布包 RequestManager.API_SERVER_URL 必须为 api.jetwave.ai;测试包用 flavor 区分 |
RequestManager.java、build.gradle |
| T2 |
星闪断线重连策略 |
心跳超时 3s → 触发重连;重连中 禁止发油门;重连次数写入 SLS |
SerialPortService.java、HomeFragment |
| T3 |
航行与对讲资源隔离 |
航行中降低对讲优先级或提示关闭;IntercomService 与 ECU 通信分线程 |
IntercomService、MainActivity |
| T4 |
地图页降级策略 |
SailMapFragment 航行中降低刷新率(如 2s 一次) |
SailMapFragment.java |
| T5 |
开机校准失败兜底 |
WRITE_ANGLE_CALIBRATION_VALUE 失败时禁止航行并提示校准 |
MyApplication.java |
12.4 针对日志热点设备的专项方案
| 设备 SN |
日志特征 |
建议动作 |
| 231AAAA5G002872 |
多会话 100% stall |
固件抓 CAN;App 加「全程失速」标记;考虑临时降级固件 esc=0551 |
| 231AAAA6A000193 |
stall 91.6% + ecu 8% |
优先查 ESC 通信;返厂测星闪+蓝牙对比 |
| 231AAAA5G001585 |
过压 14840 + 轻度 stall 14873 |
电池/线束/0557 固件;App 侧记录大电流时刻与 ov 对齐 |
| 231AAAA5C002991 |
过压为主 |
硬件电池批次排查;非 App 过压逻辑问题 |
12.5 产品 / 后台可快速配合(不改 App 也能做)
| 方 |
动作 |
价值 |
| 后台 |
列表筛 esc_event_code in (131072,4194304) + ecu=1073741824 |
与 App 埋点闭环 |
| 后台 |
分析页展示 故障码中文名(对照 EscFaultMask) |
售后可读 |
| 售后 |
问题 SN 统一走 analysis/{id} + OSS 明细 |
减少扯皮 |
| 测试 |
建立「失速/断联」标准复现用例(油门曲线回放已有 JSON) |
可自动化回归 |
12.6 不建议现阶段做的(避免拖慢止血)
| 项 |
原因 |
| 全面 Kotlin 重构 |
改动面大,与当前故障无关 |
| 替换 OrmLite |
收益慢,上传链路先稳住即可 |
| 重写 MAVLink 协议栈 |
生成代码已稳定,改 使用方式 即可 |
| 上 Compose 新 UI |
非 P0,HomeFragment 逻辑拆分优先 |
12.7 验证清单(RC-3000 额外项)
| 场景 |
通过标准 |
| 星闪默认连接 |
冷启动 30s 内连上;断线 5s 内自动重连或明确提示 |
| 量产包 API |
轨迹出现在 生产 后台,非仅 surfdev |
| 航行+对讲同时开 |
30min 内 ECU 心跳不掉帧率明显优于当前 |
| 问题 SN 回归 |
131072 / 1073741824 频率下降或恢复时间缩短(固件+App 联合) |
共性改动详见: RC-2000 报告 §11 快速优化
13. 关键文件索引
| 模块 |
路径 |
| Application |
app/.../MyApplication.java |
| 主界面 |
app/.../activity/MainActivity.java |
| 航行 |
app/.../fragments/HomeFragment.java |
| 地图 |
app/.../fragments/SailMapFragment.java |
| 串口星闪 |
app/.../service/SerialPortService.java |
| 对讲 |
app/.../service/IntercomService.java |
| MAVLink |
app/.../service/DataHandler.java |
| 故障码 |
app/.../mavlink/enums/EscFaultMask.java、EcuFaultMask.java |
| 上传 |
app/.../utils/UploadSailingRecordUtil.java |
| API |
app/.../network/RequestManager.java |
| 网络安全 |
app/.../res/xml/network_security_config.xml |
| 线程池 |
app/.../utils/ThreadPoolUtil.java |
静态审查结论;建议结合 RC3000 实机、星闪/BLE 对比测试与固件 release note 交叉验证。