大疆 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_replytopic,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_DjiReturnCodeSpeaker_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. 注册喊话器 HandlerreturnCode=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);returnDJI_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 指令汇总
| Method | 功能 | 关键参数 |
|---|---|---|
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):
| 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):
| step_key | 说明 |
|---|---|
change_work_mode | 切换工作模式 |
download | 从云端下载音频文件到机场 |
encoding | 编码 PCM 为 Opus |
upload | 机场上传音频到 PSDK |
play | 开始播放 |
6.2 Events(设备 → 云端,上行通知)
所有上行事件在 topic:thing/product/{gateway_sn}/events
| Method | 功能 |
|---|---|
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-iinput.mp3\-acodecpcm_s16le\-ar16000\-ac1\-fs16le\output.pcm# 计算 MD5(用于 API 调用)md5sum output.pcm7.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_key8. 参考资料
- 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
如有疑问或合作意向,欢迎交流探讨!!!