目录
一、实时信号质量指标体系
1.1 核心连接指标
通过 KeyRawSignalQuality(JSON 格式)监听,遥控器端实时上报以下关键字段:
| 字段名 | 数据类型 | 说明 |
|---|---|---|
dev_connect | Boolean | 设备连接状态(核心指标,true=已连接,false=已断开) |
signal | Integer | 综合信号强度值(数值越大信号越好) |
ap_tx_chan | Integer | 地面端当前发射信道编号(0~N) |
dev_tx_chan | Integer | 天空端当前发射信道编号(0~N) |
1.2 链路吞吐量指标
通过 KeyGLinkThroughput 获取,每秒轮询一次:
| 字段 | 类型 | 说明 | 单位 |
|---|---|---|---|
txPhy | long | 物理层发送速率(理论峰值) | kbps |
txReal | long | 实际有效发送速率(应用层) | kbps |
rxPhy | long | 物理层接收速率(理论峰值) | kbps |
rxReal | long | 实际有效接收速率(应用层) | kbps |
注:
txReal/rxReal通常远小于txPhy/rxPhy,因为包含协议开销和重传。
1.3 信道扫描指标
通过 KeyG12RCScanChanInfo(地面端)和 KeyG12SkyScanChanInfo(天空端)获取:
// ChanInfo 数据结构
public final class ChanInfo {
private boolean autoMode; // 是否自动跳频模式(true=正在跳频)
private int chanNum; // 扫描的信道总数(如 7、13)
private long[] freq; // 各信道中心频率(单位 MHz)
private int[] power; // 各信道信号功率(单位 dBm)
}
信号功率显示范围:
- 最小值(YMIN):-110 dBm(极弱信号/纯噪声)
- 最大值(YMAX):-50 dBm(极强信号)
- 正常飞行范围:-90 dBm ~ -60 dBm
1.4 LTE D2D 信号指标(青鳉直连方案)
通过 Android 系统 D2D Service 获取:
| 指标方法 | 数据类型 | 说明 |
|---|---|---|
getLteRsrp() | int (dBm) | 参考信号接收功率,范围约 -140 ~ -44 dBm |
getLteRsrq() | int (dB) | 参考信号接收质量,范围约 -19.5 ~ -3 dB |
getLteSignalStrength() | int (0~31) | 信号强度等级(0=无信号,31=最强) |
RSRP 信号质量分级:
| RSRP (dBm) | 信号等级 | 说明 |
|---|---|---|
| > -85 | 优秀 | 近距离,无延迟风险 |
| -85 ~ -95 | 良好 | 正常飞行范围 |
| -95 ~ -105 | 一般 | 远距离,需注意链路稳定性 |
| < -105 | 较差 | 可能断连,建议返航 |
1.5 多设备类型区分
KeyGLinkSkyDevice 返回已连接的天空端设备数组(GLinkSkyDevice[]):
| 枚举值 | value | 设备类型 |
|---|---|---|
UNKNOWN | 0 | 未识别设备 |
GR01 | 1 | GR01 接收机 |
GR02 | 4 | GR02 接收机 |
GR03 | 2 | GR03 接收机 |
TR01 | 3 | TR01 中继器 |
YL20 | 5 | YL20 配套设备 |
二、遥控器端如何获取信号质量
2.1 获取方式总览
遥控器端获取信号质量有 三种方式,对应不同的场景和设备类型:
┌─────────────────────────────────────────────────────────────────┐
│ 三种信号获取方式 │
├─────────────────────────┬───────────────┬───────────────────────┤
│ 方式 │ 适用场景 │ 触发时机 │
├─────────────────────────┼───────────────┼───────────────────────┤
│ KeyManager.listen() │ 正常飞行模式 │ onResume / 页面启动 │
│ (SDK 回调推送) │ │ │
├─────────────────────────┼───────────────┼───────────────────────┤
│ UdpConnectManager │ 开发调试模式 │ is401DDeveloper=true │
│ + GetInfoThread │ │ 时启用 │
├─────────────────────────┼───────────────┼───────────────────────┤
│ D2dController │ LTE D2D 直连 │ 使用青鳉 D2D 硬件模块 │
│ + ID2DInfoListener │ │ 时启用 │
└─────────────────────────┴───────────────┴───────────────────────┘
2.2 G 系列遥控器(主力方案:SDK 回调)
代码入口: D2dFragment.initConnect()
// 监听信号质量(SDK 主动推送,无需轮询)
KeyManager.INSTANCE.listen(
AirLinkKey.INSTANCE.getKeyRawSignalQuality(),
this.keyRawSignalQualityListener
);
回调处理: D2dFragment.m410keyRawSignalQualityListener$lambda6()
回调触发(每收到一条 SDK 数据)
↓
解析 JSON:
├── dev_connect → Boolean(连接状态)
├── signal → Integer(信号值)
├── ap_tx_chan → Integer(地面端信道)
└── dev_tx_chan → Integer(天空端信道)
↓
重置超时检测计时器(5秒无数据视为断开)
↓
runOnUiThread → 更新 UI:
├── d2dConnection.setText(getNewuiConnectedStr(context, dev_connect))
├── tvLeft / tvCenter / tvRight 显示详细字段
└── 若 dev_connect=true 且首次对频成功 → Toast "对频成功"
2.3 信道功率扫描(Timer 轮询方案)
代码入口: NewuiG12SignalFragment.onResume()
// 启动 1 秒定时器
private final TimerTask timerTask = new TimerTask(new Runnable() {
public void run() {
// 每秒轮询地面端和天空端的信道功率
KeyManager.INSTANCE.get(
AirLinkKey.INSTANCE.getKeyG12RCScanChanInfo(),
callback // onSuccess → setLineChartDatas(power[], isSky=false)
);
KeyManager.INSTANCE.get(
AirLinkKey.INSTANCE.getKeyG12SkyScanChanInfo(),
callback // onSuccess → setLineChartDatas(power[], isSky=true)
);
}
}, 1000); // 1 秒间隔
2.4 吞吐量轮询
// 每秒获取一次链路吞吐量
TimerTask g12ThroughputTask = new TimerTask(..., 1000);
g12ThroughputTask.start();
// 定时器任务内:
KeyManager.INSTANCE.get(
AirLinkKey.INSTANCE.getKeyGLinkThroughput(),
new CompletionCallbackWith<GLinkThroughput>() {
public void onSuccess(GLinkThroughput throughput) {
gLinkThroughput = throughput;
// 用于在浮动窗口展示 RX/TX kbps
}
}
);
2.5 开发调试模式(UDP 网络方案)
触发条件: AppSettings.INSTANCE.is401DDeveloper() == true
// 创建 UDP Socket(本地 12581 ↔ 天空端 192.168.144.10:12580)
this.udpKey = UdpConnectManager.INSTANCE.createUDPKey(
12581, // 本地监听端口
"192.168.144.10", // 天空端 IP 地址
12580 // 天空端发送端口
);
// 启动请求线程
GetInfoThread getInfoThread = new GetInfoThread(udpKey);
getInfoThread.setOnSendDataListener(() -> {
if (!checkTimeoutRunning) {
checkTimeoutRunning = true;
handler.postDelayed(checkTimeoutRunnable, 5000L);
}
});
getInfoThread.start(); // 周期性发送 "GET_INFO_REQUEST\n"
三、信号质量的监听机制
3.1 KeyManager 监听模型
┌──────────────────────────────────────────────────────────────────┐
│ KeyManager 架构 │
│ │
│ App Layer SDK Layer Hardware Layer │
│ ┌──────────────┐ ┌──────────────┐ ┌────────────┐ │
│ │ KeyListener │──────→│ KeyManager │──────→│ Serial/ │ │
│ │ (App注册) │←──────│ (事件分发) │←──────│ UDP/USB │ │
│ └──────────────┘ └──────────────┘ └────────────┘ │
│ ↑ ↑ ↑ │
│ │ 回调通知 │ 数据变化检测 │ 底层读取│
│ └─────────────────────────┘ │ │
│ 内部状态机 │ │
└──────────────────────────────────────────────────────────┘
3.2 监听注册生命周期
public class D2dFragment extends NewUIBaseFragment {
// 1. 在 onViewCreated 时注册监听
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
initView(); // → initConnect() → KeyManager.listen()
}
// 2. 在 onResume 时重新连接(确保前台活跃)
@Override
public void onResume() {
super.onResume();
initConnect(); // → KeyManager.listen(KeyRawSignalQuality, listener)
}
// 3. 在 onDestroy 时取消监听(防止内存泄漏)
@Override
public void onDestroy() {
super.onDestroy();
onDestroys();
// → KeyManager.INSTANCE.cancelListen(this.keyRawSignalQualityListener);
}
}
3.3 超时检测机制(看门狗)
收到任何有效信号数据时:
handler.removeCallbacks(checkTimeoutRunnable) // 取消旧计时器
checkTimeoutRunning = false
handler.postDelayed(checkTimeoutRunnable, 5000ms) // 重置 5 秒计时器
5 秒内未收到新数据 → checkTimeoutRunnable 触发:
→ d2dConnection.setText("未连接")
→ tvLeft / tvCenter / tvRight 清空
→ checkTimeoutRunning = false
设计意图:即使 SDK 回调正常触发,如果 5 秒内没有有效数据,也判定为链路中断,避免 UI 显示过期数据。
四、信号数据的来源分析
4.1 信号数据产生位置
┌─────────────────────────────────────────────────────────────────────┐
│ 信号数据产生源 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ 物理层信号产生 │ │
│ │ │ │
│ │ ┌──────────────┐ ┌──────────────┐ │ │
│ │ │ 地面端射频 │ │ 天空端射频 │ │ │
│ │ │ (AP/遥控器) │◄───────►│ (DEV/无人机) │ │ │
│ │ │ GLink 模块 │ 无线 │ GLink 模块 │ │ │
│ │ └──────┬───────┘ 链路 └──────┬───────┘ │ │
│ │ │ │ │ │
│ │ └────────┬───────────────┘ │ │
│ │ ▼ │ │
│ │ ┌─────────────────────────────────────┐ │ │
│ │ │ 信号质量测量 │ │ │
│ │ │ • RSSI(接收信号强度指示) │ │ │
│ │ │ • 当前工作信道 │ │ │
│ │ │ • 各信道功率谱 │ │ │
│ │ │ • 传输吞吐量计数器 │ │ │
│ │ └─────────────────────────────────────┘ │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ ┌─────────────────────────────────────┐ │ │
│ │ │ 固件 MCU 处理 │ │ │
│ │ │ • 定期采集信号寄存器值 │ │ │
│ │ │ • 计算功率统计 │ │ │
│ │ │ • 组包下发给 App │ │ │
│ │ └─────────────────────────────────────┘ │ │
│ │ │ │ │
│ └─────────────────────────┼────────────────────────────────┘ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ App 层处理(Android) │ │
│ │ │ │
│ │ SerialPort / UDP / D2DService │ │
│ │ ↓ │ │
│ │ rcsdk KeyManager(数据解析与分发) │ │
│ │ ↓ │ │
│ │ D2dFragment / NewuiG12SignalFragment │ │
│ │ ↓ │ │
│ │ UI 渲染(TextView / BarChart / FloatWindow) │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
4.2 各指标的具体来源
| 指标 | 物理来源 | 测量原理 |
|---|---|---|
signal | GLink 射频芯片 RSSI 寄存器 | 接收到的参考信号功率,由 RF 前端自动测量 |
dev_connect | 协议层心跳检测 | SDK 持续收到有效数据包 = 连接,超时未收到 = 断开 |
ap_tx_chan / dev_tx_chan | GLink 跳频控制器 | 当前跳频序列中的信道序号 |
power[](信道功率) | 频谱扫描 | 逐信道测量接收功率,返回所有信道的功率谱 |
txReal / rxReal | 数据链路层计数器 | 应用层实际传输的字节数 ÷ 时间间隔 |
| RSRP(LTE) | 青鳉 D2D 模块 LTE 接收机 | 3GPP 标准定义的参考信号接收功率 |
4.3 信号的发出方
信号质量数据由以下实体发出:
1. 遥控器固件 MCU(主信号源)
发出内容:dev_connect, signal, ap_tx_chan, dev_tx_chan, power[], 吞吐量
发出方式:串口(UART)→ CDC/FTDI/CH340 → Android USB Host
2. 天空端固件(通过遥控器中转)
发出内容:天空端信号强度、信道信息
发出方式:无人机 → 无线链路 → 遥控器固件 → 串口 → App
3. 青鳉 D2D Service(系统服务)
发出内容:RSRP, RSRQ, SignalStrength
发出方式:Android binder IPC → ID2DInfoListener 回调
五、遥控器端的接收技术
5.1 技术一:串口/USB 通信(主力)
文件: rcsdk/comm/SerialPort.java、rcsdk/comm/AR8030Comm.java
硬件链路:
┌─────────┐ USB OTG ┌─────────┐ UART ┌─────────┐
│ Android │ ←──────────→ │ 转换芯片 │ ←───────→ │ 遥控器 │
│ 手机/Pad │ CDC/FTDI │ CH340/ │ 921600 │ MCU │
│ │ │ CP2102 │ baud │ (STM32) │
└────┬────┘ └────┬─────┘ └────┬────┘
│ │ │
▼ ▼ ▼
SerialPort.open() AR8030Comm 固件协议解析
│ │ │
└────────┬───────────────┘ │
▼ │
KeyManager 读取线程 │
│ │
▼ │
协议解码 → Key 映射 → 回调 App │
关键类:
SerialPort.java— JNI 封装,调用/dev/ttyUSBx等串口设备AR8030Comm.java— AR8030 射频模块通信协议封装CommListener.java— 串口数据监听回调接口TCPComm.java— TCP 网络通信备用方案
5.2 技术二:UDP 网络通信(开发调试)
文件: h12ptool/common/UdpConnectManager.java、h12ptool/common/UDPComm.java
网络拓扑(开发版):
┌──────────────┐ UDP ┌──────────────┐
│ Android │ 192.168.144.10 │ 天空端 │
│ App │ ◄────────────────► │ 固件 │
│ Port:12581 │ Port:12580 │ Port:12580 │
└──────────────┘ └──────────────┘
│ │
│ 定时发送: │ 收到请求后回复:
│ "GET_INFO_REQUEST\n" │ JSON 格式的状态数据
│ (每秒一次) │ (包含所有信号指标)
└──────────────────────────────────┘
5.3 技术三:Android D2D Service(LTE 直连)
文件: fishsemi/sdk/d2dcontrol/D2dController.java
系统架构:
┌─────────────────────────────────────────────────────────┐
│ Android 系统层 │
│ │
│ ┌─────────────────────────────────────────────┐ │
│ │ com.pinecone.telephony.D2DService │ │
│ │ (青鳉 D2D 系统服务) │ │
│ │ │ │
│ │ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ LTE 射频模块 │ │ D2D 协议栈 │ │ │
│ │ │ (青鳉自研) │ │ (3GPP Rel13)│ │ │
│ │ └─────────────┘ └─────────────┘ │ │
│ └─────────────────────────────────────────────┘ │
│ ▲ ▲ │
│ │ │ AIDL │
│ ┌──────────────────┘ └──────────────────┐ │
│ │ ID2DInfoListener │ │
│ │ onD2DSignalStrengthChanged() │ │
│ │ onD2DServiceStatusChanged() │ │
│ └─────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
▲
│ bindService
┌──────────────────┘
▼
D2dController (App 进程)
使用流程:
// 1. 绑定系统 D2D 服务
Intent intent = new Intent();
intent.setClassName("com.pinecone.telephony", "com.pinecone.telephony.D2DService");
mContext.bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
// 2. 注册监听器
mD2DService.registerForD2dInfoChanged(mD2DInfoListener);
// 3. 获取初始信息
mD2DService.requestGetD2dInfo();
// 4. 请求对频
mD2DService.requestD2dFreqNegotiation();
5.4 技术四:超时看门狗
无论使用哪种通信方式,都有一套统一的超时检测机制:
// 每次收到有效数据时重置计时器
handler.removeCallbacks(checkTimeoutRunnable);
checkTimeoutRunning = false;
handler.postDelayed(checkTimeoutRunnable, 5000L);
// 5 秒超时后判定为断开
private final Runnable checkTimeoutRunnable = () -> {
checkTimeoutRunning = false;
d2dConnection.setText("未连接"); // 更新连接状态
tvLeft.setText(""); // 清空详细信息
tvCenter.setText("");
tvRight.setText("");
tvCHANNEL.setText("");
};
六、核心技术栈总结
6.1 通信技术矩阵
| 技术 | 包路径 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|---|
| SerialPort (USB CDC) | rcsdk/comm/ | 所有设备(主力) | 低延迟、稳定、即插即用 | 需要 USB OTG |
| UDP Socket | h12ptool/common/ | 开发调试版本 | 可在同一 WiFi 下远程调试 | 依赖网络配置 |
| AIDL D2D Service | fishsemi/sdk/d2dcontrol/ | 青鳉 D2D 硬件 | 无需 WiFi,LTE 直连 | 仅支持特定硬件 |
| TCP Comm | rcsdk/comm/TCPComm.java | 备用方案 | 长距离传输 | 延迟较高 |
6.2 关键组件索引
┌────────────────────────────────────────────────────────────────┐
│ 关键文件索引 │
├────────────────────────────────────────────────────────────────┤
│ │
│ 【信号监听入口】 │
│ ├── D2dFragment.java:825 KeyRawSignalQuality 监听注册 │
│ ├── D2dActivity.java:565 旧 UI 信号监听注册 │
│ └── NewuiG12SignalFragment.java:80 信道扫描定时器启动 │
│ │
│ 【数据回调处理】 │
│ ├── D2dFragment.java:166-344 JSON 解析与 UI 更新 │
│ ├── D2dActivity.java:129-214 旧 UI 数据处理 │
│ └── NewuiG12SignalFragment.java:80-111 信道功率图表更新 │
│ │
│ 【底层通信封装】 │
│ ├── rcsdk/comm/SerialPort.java JNI 串口操作 │
│ ├── rcsdk/comm/AR8030Comm.java AR8030 模块通信 │
│ ├── h12ptool/common/UDPComm.java UDP 数据收发 │
│ ├── h12ptool/common/UdpConnectManager.java UDP 连接管理 │
│ ├── h12ptool/common/GetInfoThread.java 数据请求线程 │
│ └── fishsemi/sdk/d2dcontrol/D2dController.java D2D 控制 │
│ │
│ 【数据模型】 │
│ ├── rcsdk/common/airlink/ChanInfo.java 信道信息 │
│ ├── rcsdk/common/airlink/GLinkThroughput.java 吞吐量 │
│ ├── rcsdk/common/airlink/PairParam.java 对频参数 │
│ └── rcsdk/common/airlink/GLinkSkyDevice.java 设备类型 │
│ │
│ 【Key 定义】 │
│ ├── rcsdk/key/AirLinkKey.java 信号质量相关 Key 定义 │
│ └── rcsdk/key/RemoteControllerKey.java 对频动作 Key 定义 │
│ │
└────────────────────────────────────────────────────────────────┘
七、数据流向全景图
┌─────────────────────────────────────────────────────────────────────────────────┐
│ 信号质量数据完整流向 │
│ │
│ 【物理层】 │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ 地面端 GLink │◄────────►│ 无线射频链路 │◄────────►│ 天空端 GLink │ │
│ │ 射频芯片 │ 2.4GHz │ (跳频扩频) │ 2.4GHz │ 射频芯片 │ │
│ │ (AP侧) │ 跳频通信 │ │ 跳频通信 │ (DEV侧) │ │
│ └──────┬───────┘ └──────────────┘ └──────┬───────┘ │
│ │ RSSI/信道/功率/吞吐量测量 │ │
│ └────────────────────────┬───────────────────────┘ │
│ ▼ │
│ 【固件层】(遥控器 MCU STM32) │
│ ┌──────────────────────────────────────────────────────────────────┐ │
│ │ • 定时读取 RF 寄存器(RSSI、信道状态) │ │
│ │ • 统计链路吞吐量(TX/RX 字节数) │ │
│ │ • 心跳检测(维护 dev_connect 状态) │ │
│ │ • 组包:将上述数据封装为二进制协议包 │ │
│ └──────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ 串口/USB (921600 baud) │
│ 【SDK 层】(rcsdk Android 库) │
│ ┌──────────────────────────────────────────────────────────────────┐ │
│ │ SerialPort / UDPComm / D2dController │ │
│ │ ↓ │ │
│ │ KeyManager(协议解码 + Key 映射) │ │
│ │ ↓ │ │
│ │ KeyRawSignalQuality → JSON 字符串 │ │
│ │ KeyGLinkThroughput → GLinkThroughput 对象 │ │
│ │ KeyG12RCScanChanInfo→ ChanInfo 对象(地面端) │ │
│ │ KeyG12SkyScanChanInfo→ ChanInfo 对象(天空端) │ │
│ └──────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ KeyListener 回调 │
│ 【App 层】(D2dFragment / NewuiG12SignalFragment) │
│ ┌──────────────────────────────────────────────────────────────────┐ │
│ │ 主线程 UI 更新: │ │
│ │ ├── d2dConnection TextView:显示 "已连接" / "未连接" │ │
│ │ ├── tvCHANNEL TextView:显示完整 JSON 信息 │ │
│ │ ├── tvLeft/Center/Right:分栏显示详细指标 │ │
│ │ ├── BarChart(MPAndroidChart):显示各信道功率分布 │ │
│ │ └── FloatWindow(悬浮窗):全局显示信号强度和吞吐量 │ │
│ │ │ │
│ │ 超时检测: │ │
│ │ └── 5 秒无数据 → 自动切换为"未连接"状态 │ │
│ └──────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────────┘
八、附录:典型信号数据 JSON 示例
8.1 正常连接状态
{
"dev_connect": true,
"signal": -62,
"ap_tx_chan": 6,
"dev_tx_chan": 6,
"ap_signal_strength": -65,
"dev_signal_strength": -60,
"acs_chan": 6,
"work_chan": 6,
"tx_real": 2400,
"rx_real": 2350
}
8.2 断开连接状态
{
"dev_connect": false,
"signal": -110,
"ap_tx_chan": -1,
"dev_tx_chan": -1
}
8.3 对频进行中状态
{
"dev_connect": false,
"signal": -105,
"pairing": true,
"scan_progress": 3
}
文档生成完毕。