大疆 Dock3 基于 PSDK 接入喊话器方案
📡 Dji-cloud-api-tool · 技术干货 全面解析 Dock3 + PSDK 喊话器的硬件接口、通信协议与云端集成
1. 引言
本周已经将大疆PSDK喊话器功能全部集成到Dji-cloud-api-tool工具中,并且功能调试通过,特意整理了一下对接完整方案,希望能帮助到你。

2. 概述
本文档调研基于大疆 Dock3(配套 Matrice 4D/4TD 飞行平台)通过 PSDK(Payload SDK)接入喊话器负载设备的完整方案,涵盖硬件接口、PSDK 端开发、Cloud API 通信协议、以及第三方平台集成架构。
2.1 核心产品关系
| DJI Dock 3 | 第三代无人机机场/机巢,支持 24/7 远程无人值守作业 |
| Matrice 4D/4TD | Dock3 配套飞行平台,提供 E-Port(PSDK 扩展接口) |
| E-Port | M4D 系列飞机上的负载扩展接口,供电 + 通信一体化 |
| PSDK | DJI 提供的负载设备软件开发套件(当前最新 V3.12.0) |
| Cloud API | DJI 提供的云端 API,基于 MQTT 实现设备-云端双向通信 |
2.2 两种接入路径
喊话器可通过以下两种方式接入 Dock3 系统:
| 路径 A:官方/第三方 PSDK 喊话器 | 直接通过 E-Port 挂载符合 PSDK 规范的喊话器硬件 | 快速部署,开箱即用 |
| 路径 B:自定义 PSDK 喊话器 | 基于 PSDK 自行开发喊话器负载(含硬件 + 固件) | 定制需求,深度集成 |
3. 硬件层:E-Port 接口规格
3.1 电气规格
| 输出电压 | 16.8V – 25.5V(飞机电池直供) |
| 最大电流 | 3A |
| 保护电流 | 4A(超过则断电保护) |
| 负载电容限制 | ≤ 500 µF(超过触发短路保护) |
| PPS 引脚电压 | ≤ 3.3V |
| 通信协议 | USB 2.0 / UART 3.3V TTL |
3.2 物理接口
M4D 系列 E-Port 支持以下挂载方式:
- E-Port 直连(推荐):直接连接 PSDK 负载设备
- SkyPort V2 转接环:标准云台接口(兼容旧款负载)
- X-Port 标准云台:一体化标准云台
3.3 关键约束
⚠️ 单负载限制:同一时间飞机只能与一个 PSDK 负载设备通信。如果 E-Port 已被占用,无法通过分线器同时接入多个负载。
⚠️ 安装后需重新校准飞机罗盘。
⚠️ 负载会增加飞机功耗,降低飞行续航和抗风能力。
4. 系统架构:端到端通信链路
4.1 整体架构图
┌─────────────────────────────────────────────────┐
│ 第三方云端平台 │
│ (Dji-cloud-api-tool / 其他) │
│ │
│ ┌──────────┐ ┌──────────┐ ┌───────────────┐ │
│ │ 喊话器 UI │ │ TTS 引擎 │ │ 音频文件管理 │ │
│ └────┬─────┘ └────┬─────┘ └───────┬───────┘ │
│ └──────────────┼───────────────┘ │
│ │ MQTT │
└──────────────────────┼───────────────────────────┘
│
┌────────┴────────┐
│ DJI Cloud API │
│ (MQTT Broker) │
└────────┬────────┘
│
┌────────┴────────┐
│ DJI Dock 3 │
│ (机场/机巢) │
└────────┬────────┘
│ OcuSync/SDR
┌────────┴────────┐
│ Matrice 4D/4TD │
│ (飞行平台) │
└────────┬────────┘
│ E-Port (USB/UART)
┌────────┴────────┐
│ PSDK 喊话器 │
│ (负载设备) │
│ │
│ ┌─────────────┐ │
│ │ MCU / Linux │ │
│ │ + 音频PA │ │
│ │ + 扬声器 │ │
│ └─────────────┘ │
└─────────────────┘
4.2 通信协议分层
| 云端 → Dock | MQTT(Dock-to-Cloud Protocol) | services/services_reply topic,JSON 格式 |
| Dock → 飞机 | OcuSync / SDR | DJI 私有协议,透明传输 |
| 飞机 → PSDK | USB_BULK / UART | PSDK 协议,C 语言 API |
| PSDK → 扬声器 | I2S / I2C / GPIO | 硬件相关 |
4.3 扩展架构:机载计算平台中转
如果需要同时接入喊话器和其他负载设备(如探照灯、RTK 等),推荐使用机载计算平台统一接入:
Matrice 4D E-Port
│
└── 机载计算平台 (如品立 17F1 / NVIDIA Jetson)
├── PSDK 主程序(与飞机通信)
├── 喊话器负载(I2S/UART 音频输出)
├── 探照灯负载(GPIO/PWM 控制)
└── 其他传感器(串口/SPI/I2C)
5. PSDK 喊话器开发(硬件端)
5.1 PSDK 喊话器核心 API
PSDK 喊话器功能通过 dji_widget.h 提供的接口实现,核心是注册 T_DjiWidgetSpeakerHandler 回调函数集:
| GetSpeakerState | 飞控→负载 | 上报播放状态、工作模式、播放模式、音量 |
| SetWorkMode | 飞控→负载 | 设置 TTS / 语音工作模式 |
| SetPlayMode | 飞控→负载 | 设置单次播放 / 循环播放 |
| SetVolume | 飞控→负载 | 设置音量(0-100) |
| StartPlay | 飞控→负载 | 开始播放 |
| StopPlay | 飞控→负载 | 停止播放 |
| ReceiveTtsData | 飞控→负载 | 接收 TTS 文本数据 |
| ReceiveAudioData | 飞控→负载 | 接收 Opus 编码的语音数据 |
5.2 喊话器状态机
SetWorkMode / SetPlayMode
│
▼
┌──────┐ StartPlay ┌─────────┐ 播放完成 ┌──────┐
│ IDLE │────────────▶│ PLAYING │───────────▶│ IDLE │
└──────┘ └─────────┘ └──────┘
▲ │
│ StopPlay │
└────────────────────┘
工作模式:
- DJI_WIDGET_SPEAKER_WORK_MODE_TTS — TTS 文字转语音
- DJI_WIDGET_SPEAKER_WORK_MODE_VOICE — 语音喊话(实时/录音)
播放模式:
- DJI_WIDGET_SPEAKER_PLAY_MODE_SINGLE_PLAY — 单次播放
- DJI_WIDGET_SPEAKER_PLAY_MODE_LOOP_PLAY — 循环播放
5.3 音频参数规范
| 采样率 | 16 kHz |
| 声道 | 单声道 (Mono) |
| 量化格式 | 16 bit |
| 编码格式 | Opus @ 16 kbps |
| 单帧数据 | 160 字节 |
| 最大录音时长 | 3 分钟 |
| 导入音频格式 | MP3 / WAV / AAC |
| 导入音频大小限制 | 10 MB |
| 音频文件最大数量 | 20 个 |
| TTS 文本字符限制 | 1000 字符(汉字计为 1 字符) |
5.4 初始化示例代码
T_DjiReturnCode Speaker_Init(void)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
// 1. 注册回调函数
s_speakerHandler.GetSpeakerState = Speaker_GetState;
s_speakerHandler.SetWorkMode = Speaker_SetWorkMode;
s_speakerHandler.SetPlayMode = Speaker_SetPlayMode;
s_speakerHandler.SetVolume = Speaker_SetVolume;
s_speakerHandler.StartPlay = Speaker_StartPlay;
s_speakerHandler.StopPlay = Speaker_StopPlay;
s_speakerHandler.ReceiveTtsData = Speaker_ReceiveTtsData;
s_speakerHandler.ReceiveAudioData = Speaker_ReceiveAudioData;
// 2. 创建互斥锁保护状态
osalHandler->MutexCreate(&s_speakerMutex);
// 3. 注册喊话器 Handler
returnCode = DjiWidget_RegSpeakerHandler(&s_speakerHandler);
// 4. 初始化状态
s_speakerState.state = DJI_WIDGET_SPEAKER_STATE_IDEL;
s_speakerState.workMode = DJI_WIDGET_SPEAKER_WORK_MODE_VOICE;
s_speakerState.playMode = DJI_WIDGET_SPEAKER_PLAY_MODE_SINGLE_PLAY;
// 5. 启动后台播放任务线程
osalHandler->TaskCreate("speaker_task", Speaker_BackgroundTask,
STACK_SIZE, NULL, &s_speakerThread);
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
5.5 控件配置 JSON
{
"main_interface": {
"floating_window": {
"is_enable": true
},
"speaker": {
"is_enable_tts": true,
"is_enable_voice": true
}
}
}
6. 上云API通信协议(云端 ↔ Dock)
Dock3 通过 MQTT 与云端通信,喊话器相关 API 分为以下两组:
6.1 Services(云端 → 设备,下行指令)
所有下行指令发送到 topic:thing/product/{gateway_sn}/services
设备回复在 topic:thing/product/{gateway_sn}/services_reply
6.1.1 指令汇总
| speaker_play_volume_set | 设置音量 | psdk_index, play_volume (0–100) |
| speaker_play_mode_set | 设置播放模式 | psdk_index, play_mode (0=单次, 1=循环) |
| speaker_play_stop | 停止播放 | psdk_index |
| speaker_replay | 重新播放 | psdk_index |
| speaker_tts_play_start | TTS 文本播放 | psdk_index, tts.name, tts.text, tts.md5 |
| speaker_audio_play_start | 音频文件播放 | psdk_index, file.name, file.url, file.md5, file.format |
6.1.2 设置音量
Topic: thing/product/{gateway_sn}/services
Method: speaker_play_volume_set
[14:46:59] 设置音量 ✅ 成功 (result=0)
Topic: thing/product/8UUXXXXXXXXXXX/services
下发:
{
"bid": "9e29ce43-a386-4c89-9320-2b794225069e",
"data": {
"play_volume": 54,
"psdk_index": 2
},
"method": "speaker_play_volume_set",
"tid": "940ec08d-a0f6-427e-a897-35539f473860",
"timestamp": 1785307619550
}
响应:
{
"bid": "9e29ce43-a386-4c89-9320-2b794225069e",
"data": {
"result": 0
},
"method": "speaker_play_volume_set",
"tid": "940ec08d-a0f6-427e-a897-35539f473860",
"timestamp": 1785307623339
}
字段说明:
| psdk_index | int | 是 | PSDK 负载设备索引(0–3) |
| play_volume | int | 是 | 音量值(0–100),0 为静音,100 为最大音量 |
6.1.3 设置播放模式
Topic: thing/product/{gateway_sn}/services
Method: speaker_play_mode_set
[14:49:23] 设置播放模式 ✅ 成功 (result=0)
Topic: thing/product/8UUXXXXXXXXXXX/services
下发:
{
"bid": "d56d07b3-737c-423b-b38f-c7a40c535f05",
"data": {
"play_mode": 1,
"psdk_index": 2
},
"method": "speaker_play_mode_set",
"tid": "05eb6bf9-56e2-4d0c-b453-a4e838842b2e",
"timestamp": 1785307763832
}
响应:
{
"bid": "d56d07b3-737c-423b-b38f-c7a40c535f05",
"data": {
"result": 0
},
"method": "speaker_play_mode_set",
"tid": "05eb6bf9-56e2-4d0c-b453-a4e838842b2e",
"timestamp": 1785307767493
}
字段说明:
| psdk_index | int | 是 | PSDK 负载设备索引(0–3) |
| play_mode | int | 是 | 播放模式:0 = 单次播放(播完停止),1 = 循环播放(重复播放) |
6.1.4 停止播放
Topic: thing/product/{gateway_sn}/services
Method: speaker_play_stop
[14:53:02] 停止播放 ✅ 成功 (result=0)
Topic: thing/product/8UUXXXXXXXXXXX/services
下发:
{
"bid": "6920c62c-526e-4ac8-9cde-006df03a9a90",
"data": {
"psdk_index": 2
},
"method": "speaker_play_stop",
"tid": "334d3823-cde7-43fa-a007-b8df8d2eccc9",
"timestamp": 1785307982361
}
响应:
{
"bid": "6920c62c-526e-4ac8-9cde-006df03a9a90",
"data": {
"result": 0
},
"method": "speaker_play_stop",
"tid": "334d3823-cde7-43fa-a007-b8df8d2eccc9",
"timestamp": 1785307985515
}
字段说明:
| psdk_index | int | 是 | PSDK 负载设备索引(0–3) |
说明: 停止当前正在进行的 TTS 或音频文件播放,对应 PSDK 端 StopPlay 回调。停止后喊话器回到 IDLE 状态,可接收新的播放指令。
6.1.5 重新播放
Topic: thing/product/{gateway_sn}/services
Method: speaker_replay
[14:53:08] 重新播放 ✅ 成功 (result=0)
Topic: thing/product/8UUXXXXXXXXXXX/services
下发:
{
"bid": "92bd80d9-8601-49a3-be9a-2cce25c49f1e",
"data": {
"psdk_index": 2
},
"method": "speaker_replay",
"tid": "dbabed3e-ca8e-47f0-bd5e-5f87d958117a",
"timestamp": 1785307988390
}
响应:
{
"bid": "92bd80d9-8601-49a3-be9a-2cce25c49f1e",
"data": {
"result": 0
},
"method": "speaker_replay",
"tid": "dbabed3e-ca8e-47f0-bd5e-5f87d958117a",
"timestamp": 1785307991565
}
字段说明:
| psdk_index | int | 是 | PSDK 负载设备索引(0–3) |
说明: 重新播放上一次通过 speaker_tts_play_start 或 speaker_audio_play_start 发送的音频内容,无需重新上传音频数据。
6.1.6 TTS 文本播放
Topic: thing/product/{gateway_sn}/services
Method: speaker_tts_play_start
[14:51:32] TTS文本喊话 ✅ 成功 (result=0)
Topic: thing/product/8UUXXXXXXXXXXX/services
下发:
{
"bid": "dc8da309-f96e-4f17-b8b0-538c46f9d141",
"data": {
"psdk_index": 2,
"tts": {
"md5": "3dc5fa788a1a0f687e8350ce9019f5ac",
"name": "测试文本喊话",
"text": "先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。然侍卫之臣不懈于内,忠志之士忘身于外者,盖追先帝之殊遇,欲报之于陛下也。诚宜开张圣听,以光先帝遗德,恢弘志士之气,不宜妄自菲薄,引喻失义,以塞忠谏之路也"
}
},
"method": "speaker_tts_play_start",
"tid": "705fe0d9-4d91-48bb-b0a7-f12337c4bd9c",
"timestamp": 1785307892599
}
响应:
{
"bid": "dc8da309-f96e-4f17-b8b0-538c46f9d141",
"data": {
"result": 0
},
"method": "speaker_tts_play_start",
"tid": "705fe0d9-4d91-48bb-b0a7-f12337c4bd9c",
"timestamp": 1785307895946
}
字段说明:
| psdk_index | int | 是 | PSDK 负载设备索引(0–3) |
| tts.name | text | 是 | 文件名(用于在机场侧标识) |
| tts.text | text | 是 | TTS 文本内容(≤1000 字符) |
| tts.md5 | text | 是 | 文本内容的 MD5 校验和 |
TTS 播放进度事件(上行):
Topic: thing/product/{gateway_sn}/events
Method: speaker_tts_play_start_progress
进度阶段(step_key):
| change_work_mode | 切换工作模式 |
| upload | 机场上传音频到 PSDK |
| play | 开始播放 |
6.1.7 音频文件播放
Topic: thing/product/{gateway_sn}/services
Method: speaker_audio_play_start
[17:24:49] 音频文件喊话 ✅ 成功 (result=0)
Topic: thing/product/8UUXXXXXXXXXXX/services
下发:
{
"bid": "222cd9f1-15fa-4cc9-9b8f-f6d19a2a67d8",
"data": {
"file": {
"format": "pcm",
"md5": "8cfa8d06fa2707332a7a319d98d975a4",
"name": "audio_172449",
"url": "http://127.0.0.1:8888/file/get?id=domp-track-binary:psdk:short_pcm_s16le.pcm"
},
"psdk_index": 2
},
"method": "speaker_audio_play_start",
"tid": "265d9172-901e-44d3-984f-2e68fc9beccd",
"timestamp": 1785317089694
}
响应:
{
"bid": "222cd9f1-15fa-4cc9-9b8f-f6d19a2a67d8",
"data": {
"result": 0
},
"method": "speaker_audio_play_start",
"tid": "265d9172-901e-44d3-984f-2e68fc9beccd",
"timestamp": 1785317088714
}
字段说明:
| psdk_index | int | 是 | PSDK 负载设备索引 |
| file.name | text | 是 | 文件名 |
| file.url | text | 是 | 音频文件下载链接(公网可访问) |
| file.md5 | text | 是 | 音频文件的 MD5 校验和 |
| file.format | enum_string | 是 | 目前仅支持 "pcm" |
音频播放进度事件(上行):
Topic: thing/product/{gateway_sn}/events
Method: speaker_audio_play_start_progress
进度阶段(step_key):
| change_work_mode | 切换工作模式 |
| download | 从云端下载音频文件到机场 |
| encoding | 编码 PCM 为 Opus |
| upload | 机场上传音频到 PSDK |
| play | 开始播放 |
6.2 Events(设备 → 云端,上行通知)
所有上行事件在 topic:thing/product/{gateway_sn}/events
| speaker_tts_play_start_progress | TTS 播放进度通知 |
| speaker_audio_play_start_progress | 音频播放进度通知 |
| psdk_floating_window_text | PSDK 浮窗文本推送 |
6.2.1 播放进度事件通用结构
{
"bid": "1740d345-1d70-4a8c-b49a-feae3308d569",
"data": {
"output": {
"md5": "8cfa8d06fa2707332a7a319d98d975a4",
"progress": {
"percent": 100,
"step_key": "change_work_mode"
},
"psdk_index": 2,
"status": "in_progress"
},
"result": 0
},
"gateway": "8UUXXXXXXXXXXX",
"method": "speaker_audio_play_start_progress",
"need_reply": 0,
"tid": "71b96927-504a-47f7-8485-e448bd55c5c2",
"timestamp": 1785376016406
}
status 枚举:
| in_progress | 处理中 |
| ok | 播放成功 |
6.3 完整指令时序图
云端 Dock3/飞机 PSDK喊话器
│ │ │
│── speaker_tts_play_start ──▶│ │
│ │── SetWorkMode(TTS) ────────▶│
│ │── ReceiveTtsData(text) ────▶│
│ │── StartPlay ───────────────▶│
│ │ │── TTS合成
│ │ │── 音频播放
│◀── speaker_tts_play_start │ │
│ _progress(in_progress) ──│ │
│◀── speaker_tts_play_start │ │
│ _progress(ok) ───────────│ │
│ │ │
│── speaker_play_stop ───────▶│ │
│ │── StopPlay ────────────────▶│── 停止播放
│◀── services_reply(result) ──│ │
│ │ │
7. 云端集成方案
7.1 音频文件准备
云端需要为 speaker_audio_play_start 指令准备机场可访问的 PCM 音频文件:
| 格式 | PCM(未压缩原始音频) |
| 采样率 | 16 kHz |
| 声道 | 单声道 |
| 位深 | 16 bit |
| 托管方式 | OSS / S3 / CDN(需生成可公开下载的 URL) |
PCM 文件生成示例(FFmpeg):
# 将任意音频文件转换为 PSDK 喊话器兼容的 PCM 格式
ffmpeg -i input.mp3 \\
-acodec pcm_s16le \\
-ar 16000 \\
-ac 1 \\
-f s16le \\
output.pcm
# 计算 MD5(用于 API 调用)
md5sum output.pcm
7.2 OSS 上传临时凭证
如果云端需要接收 PSDK UI 资源包上传结果,可使用 storage_config_get 获取临时凭证:
Topic: thing/product/{gateway_sn}/requests
Method: storage_config_get
{
"bid": "…",
"data": { "module": 1 },
"gateway": "4TADKAQ000002J",
"method": "storage_config_get",
"tid": "…",
"timestamp": 1689911314560
}
返回临时 OSS 凭证(有效期 3600 秒),支持阿里云/AWS/MinIO。
7.3 MQTT 消息处理流程
1. 构造 MQTT 消息
├── 生成唯一 tid(消息追踪 ID)
├── 生成唯一 bid(业务追踪 ID)
├── 填充 method 和 data
└── 设置 timestamp(毫秒级 Unix 时间戳)
2. 发布到 thing/product/{gateway_sn}/services
3. 监听 thing/product/{gateway_sn}/services_reply
├── 匹配 tid → 确认指令是否被 Dock 接收
└── result=0 表示成功
4. 监听 thing/product/{gateway_sn}/events
├── 匹配 method → 确认正在监听的进度事件
├── 检查 status(in_progress / ok)
└── 解析 progress.percent 和 step_key
8. 参考资料
- DJI Cloud API 文档
- DJI PSDK 开发教程
- PSDK Speaker Widget 文档
- DJI Dock 3 产品页
- Glider WR-01 Dock3 喊话器
- FlytBase Speaker & Spotlight 集成
- DJI Zenmuse V1 喊话器
📬 Dji-cloud-api-tool · 专注大疆 Cloud API 开发者工具 github:https://github.com/damon-liu/Dji-cloud-api-tool gitee:https://gitee.com/damon123-liu/dji-cloud-api-tool 如有疑问或合作意向,欢迎交流探讨!!!
网硕互联帮助中心






评论前必须登录!
注册