在这里插入图片描述

1. PSDK 基础概念与定位

1.1 什么是 PSDK

大疆负载软件开发套件(Payload SDK,负载端开发)是大疆为开发者提供的一套开发工具,用于在无人机上开发并集成自定义负载设备(如传感器、摄像头、机械臂等)。与 OSDK(Onboard SDK,机载端开发)和 MSDK(Mobile SDK,移动端开发)相比,PSDK 更侧重于硬件层面的深度集成。

  • 适用平台:Linux、RTOS(Real-Time Operating System,实时操作系统)
  • 硬件载体:通过以下接口连接无人机,配合开发板(如 Raspberry Pi、STM32)运行负载程序:
    • X-Port —— 通用转接件
    • SkyPort —— SkyPort 转接件(常用于行业机)
    • Extension Port —— 扩展接口(部分机型)
  • 开发语言:C/C++

对比:OSDK(Onboard SDK)跑在飞控上,MSDK(Mobile SDK)跑在手机/Pilot App 端,PSDK 跑在自研负载设备上,负责与飞控、遥控器、App 之间通信。

1.2 PSDK 架构简介

┌─────────────────────────────────────────────────┐
│ ③ 应用层 (application)  你的业务逻辑              │
│    main.c + module_sample/*.c                   │
├─────────────────────────────────────────────────┤
│ ② 移植层 (HAL / OSAL)  让 SDK 跑在你这台机器      │
│    hal/hal_usb_bulk.c    osal/osal_*.c          │
│    你负责提供:串口/USB收发、线程、文件、日志      │
├─────────────────────────────────────────────────┤
│ ① SDK 核心库 (psdk_lib)  大疆编译好的静态库       │
│    libpayloadsdk.a + include/ 头文件            │
│    你只管调用它的 API                            │
└─────────────────────────────────────────────────┘

2. Linux 开发环境搭建

本章基于 Raspberry Pi + Linux 环境进行配置,参照 DJI 官方快速入门文档进行操作。

2.1 硬件准备

  • 开发板:Raspberry Pi 4B(或 3B+,推荐 4GB 内存以上版本)
  • 连接配件:SkyPort V2 或 X-Port 适配板
  • 网络连接:同轴电缆、UART 串口线或依赖联网方式
  • 存储卡:至少 32GB 的 TF 卡(刷写系统后剩余空间用于编译调试)

2.2 Linux 系统配置

  1. 刷写系统:使用 Raspberry Pi Imager 刷入 Raspberry Pi OS(推荐基于 Debian 的 Lite 版本)
  2. 初始化设置
    # 启动后更新软件源并升级系统
    sudo apt update && sudo apt upgrade -y
    
    # 安装必要工具链
    sudo apt install -y build-essential cmake git wget
    
  3. 启用串口通信:编辑 /boot/config.txt,使能 UART 接口
  4. 网络配置:确保开发板与调试 PC 在同一网段,便于后续文件传输和远程调试

2.3 交叉编译工具链(可选)

若在 PC 端编译并将可执行文件传输到树莓派运行,需安装交叉编译工具链(如 arm-linux-gnueabihf-gcc)。本地编译则直接在树莓派上完成,省去交叉编译步骤。

3. PSDK 快速上手:官方 Demo 运行

3.1 下载 PSDK 源码

  1. 注册 DJI 开发者账号并创建应用,获取 App IDApp Key
  2. DJI Developer 下载中心 下载 PSDK 最新版本
  3. 将源码包传输至树莓派并解压:
    unzip Payload-SDK-*.zip
    cd Payload-SDK
    

3.2 配置并编译 Demo

  1. 修改 samples/sample_c/platform/linux/raspberry_pi/application/dji_sdk_app_info.h,填入 App ID 与 App Key
  2. 根据硬件连接方式选择通信接口(如 UART),在配置文件中指定串口设备名(/dev/ttyAMA0 等)
  3. 编译:
    mkdir build && cd build
    cmake ..
    make -j4
    

3.3 连接无人机并运行

  1. 将树莓派通过 SkyPort / X-Port 连接至无人机,上电启动
  2. 运行编译好的 demo 可执行文件,通过日志确认 PSDK 初始化、飞控连接和订阅数据功能正常工作

4. RTOS 与 HAL 抽象层移植要点

4.1 操作系统适配

官方提供基于 Linux 和 FreeRTOS 的 HAL 模板。若使用 RTOS(如 STM32 系列),需要额外适配以下组件:

  • 线程管理:创建并管理 PSDK 任务线程(psdk 主任务、数据订阅任务等)
  • 互斥锁与信号量:保证多线程访问安全
  • 定时器:提供毫秒级延时和周期性回调

4.2 关键 HAL/OSAL 接口分析

包括但不限于:

  • UART/串口收发:实现 DjiPlatform_UartSendHandler / DjiPlatform_UartRecvHandler 等回调(对应 OSAL/HAL 层注册的收发函数)
  • USB 通信:若走 USB Bulk 等通道(如 SkyPort/X-Port),需实现相应的 USB 收发读写回调
  • 网络通信:若使用 USB 虚拟网卡或网口与飞控通信,需实现相应网络层接口
  • 线程 / 互斥锁 / 定时器:提供线程创建、延时、加锁与定时回调(FreeRTOS/Linux 分别实现)
  • 电源管理:获取引脚供电状态、引脚电压等

注意:HAL/OSAL 是 PSDK 留给开发者唯一需要自己编写的部分,因为串口走哪种、线程用什么实现在不同平台上不一样。SDK 只定义接口(回调),由你补充具体实现。

这部分是很多开发者从 Linux 完整系统迁移到 RTOS 裸板时的核心难点,建议结合官方参考实现逐函数移植调试。

5. 探索模式与负载开发基础

5.1 负载协同 / 探索模式(DJI Pilot)

PSDK 支持负载在 DJI Pilot 2 App 中自定义界面、显示状态并接收用户交互(对应 dji_widget.h / dji_widget_manager.h)。开发步骤包括:

  1. 负载信息管理器 中注册负载属性
  2. 使用 控件组件(Widget) 定义界面布局(按钮、列表、开关、滑动条、文本等)
  3. 绑定控件事件回调实现交互逻辑

5.2 订阅无人机数据

PSDK 通过数据订阅功能(dji_fc_subscription.h)读取飞控遥测,例如:

  • 无人机姿态(四元数 / 欧拉角)
  • GPS 坐标与高度、速度
  • 电池电量与电压、剩余电量

示例代码片段:

// 订阅四元数 Topic
T_DjiDataSubscriptionTopic topic = {0};
topic.topic = DJI_DATA_SUBSCRIPTION_TOPIC_QUATERNION;
topic.interval = DJI_DATA_SUBSCRIPTION_TOPIC_QUATERNION_HZ;   // 订阅频率
DjiDataSubscription_SubscribeTopic(&topic, QuaternionCallback, &subscriptionHandle);

说明:真实接口为 DjiDataSubscription_SubscribeTopic,需要传入 Topic 结构体与回调函数;订阅前通常先调用 DjiDataSubscription_Init

5.3 控制权获取

部分高级功能(如云台控制)需要请求控制权。PSDK 通过权限管理模块实现多源控制权切换,避免冲突。

6. 如何开发负载功能(使用流程参考)

本节是给"下次要动手写负载功能"时的流程速查。核心思路:框架 + 一个主控(main.c)+ 多个功能模块。加功能 = 新建一个模块 + 在主控里调用它的启动函数。

6.1 代码结构总览

samples/sample_c/
├── platform/<平台>/<机型>/
│   ├── application/
│   │   ├── main.c              ← 主控:初始化 + 启动各模块(开关功能)
│   │   ├── dji_sdk_config.h    ← 总开关:决定启用哪些功能模块
│   │   └── dji_sdk_app_info.h  ← 应用身份信息(App ID/Key/License)
│   └── hal/hal_xxx.c           ← 硬件层:USB/串口收发(换硬件才改)
└── module_sample/              ← 各种功能模块,一个功能一个文件夹
    ├── fc_subscription/        ← 读飞控数据
    ├── gimbal_emu/             ← 云台控制
    ├── camera_emu/             ← 相机模拟
    └── ...

关键点:每个功能模块对外只暴露一个 DjiTest_XXXStartService() 启动函数,主控 main.c 只调用它来激活。

6.2 模块的标准范式(一个模块的生命周期)

以"读飞控数据"模块为例,内部固定三步:

T_DjiReturnCode DjiTest_FcSubscriptionStartService(void)
{
    // ① 初始化模块
    DjiFcSubscription_Init();

    // ② 订阅需要的数据(Topic),绑定回调函数
    DjiFcSubscription_SubscribeTopic(DJI_FC_SUBSCRIPTION_TOPIC_QUATERNION,
                                     DJI_DATA_SUBSCRIPTION_TOPIC_50_HZ,   // 订阅频率 50Hz
                                     ReceiveQuaternionCallback);

    // ③ 创建你自己的后台任务(线程)持续干活
    OsalHandler->TaskCreate("user_subscription_task", Subscription_Task, ...);
}

两种数据获取方式:

  • 回调式(被动):数据一到触发回调,适合高频数据(如姿态 50Hz)
  • 主动拉取:在任务循环里调 GetLatestValueOfTopic(...) 取最新值

日志统一用 USER_LOG_INFO / USER_LOG_DEBUG 输出,会自动同时打到终端和本地日志文件(由主控的日志控制台配置决定)。

6.3 主控 main.c 如何激活模块

每个模块在 main.c 里都是同一套接入写法:

#ifdef CONFIG_MODULE_SAMPLE_XXX_ON      // ← 宏开关决定是否编译进来
    returnCode = DjiTest_XXXStartService();    // ← 调用模块启动函数
    if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
        USER_LOG_ERROR("xxx init error");
    }
#endif

开关宏统一定义在 dji_sdk_config.h。例如:

  • CONFIG_MODULE_SAMPLE_FC_SUBSCRIPTION_ON 数据订阅
  • CONFIG_MODULE_SAMPLE_CAMERA_EMU_ON 相机模拟
  • CONFIG_MODULE_SAMPLE_GIMBAL_EMU_ON 云台模拟
  • CONFIG_MODULE_SAMPLE_WIDGET_ON 探索模式界面
  • CONFIG_MODULE_SAMPLE_POWER_MANAGEMENT_ON 电源管理

通信连接模式也在此配置,如 CONFIG_HARDWARE_CONNECTION 选择走 USB Bulk / UART / 网络。

6.4 如何添加自己的负载功能(7 步流程)

假设开发一个自定义传感器(如气体检测仪):

  1. 新建模块文件夹:在 module_sample/ 下建 my_sensor/ 目录。
  2. 写头文件 test_my_sensor.h:定义 DjiTest_MySensorStartService(void)
  3. 写实现 test_my_sensor.c:内部 Init → 创建后台任务(TaskCreate),任务里循环读自己的传感器 API,用 USER_LOG_INFO 打印。
  4. CMake 无需改动:官方 CMake 用 file(GLOB_RECURSE ... module_sample/*.c) 自动收集所有模块源码,放进目录即自动编译。
  5. 加总开关:在 dji_sdk_config.h 里加 #define CONFIG_MODULE_SAMPLE_MY_SENSOR_ON
  6. 主控接入:在 main.c 的模块启动段加 #ifdef CONFIG_MODULE_SAMPLE_MY_SENSOR_ON 包裹的 DjiTest_MySensorStartService() 调用,并在头部 #include "my_sensor/test_my_sensor.h"
  7. 编译
    mkdir build && cd build
    cmake ..
    make -j4
    
    成功后生成可执行文件,并自动调用 build_dpk.sh 生成 .dpk 部署包(供安装到负载平台)。

注意:C 任务函数若是 while(1) 死循环,需参考官方加 #pragma GCC diagnostic ignored "-Wmissing-noreturn" 屏蔽告警。

6.5 两类开发方向(接线原则)

方向含义典型 API
读数据从飞机获取遥测、状态DjiFcSubscription_SubscribeTopic + 回调
控制设备向飞机发送指令云台 DjiGimbal_*、相机 DjiCamera_*

若要在 DJI Pilot App 里显示你的传感器数据,用 Widget 模块:在对应 test_widget.c 中注册控件并绑定回调(对应 5.1 节的负载协同)。

7. 调试技巧与常见问题排查

7.1 日志输出与级别控制

  • 利用 DjiLogger_SetLevel() 调节日志详细度(对应 dji_logger.h
  • 调试阶段建议开启 DEBUG 级别日志,可通过串口/终端实时查看
  • 日志目录、文件数量等日志策略需要在 HAL/OSAL 的日志写入回调中实现(代码中常配置为 logs/ 目录)

7.2 常见连接失败问题

现象可能原因排查方向
PSDK 初始化超时串口未正确连接或波特率不匹配检查串口设备及其配置参数
飞控无响应未正确绑定机型 / 授权或版本不匹配核对官方应用信息、机型与固件版本
硬件识别失败SkyPort/X-Port 未正确供电测量引脚电压,确认硬件接线

8. 学习路线图与进阶方向

8.1 推荐学习阶段

  1. 第一阶段(入门):在 Raspberry Pi 上跑通官方 Demo,理解代码结构
  2. 第二阶段(基础开发):修改 Demo,实现自定义负载功能(如 GPIO 控制 LED)
  3. 第三阶段(深入 HAL):尝试在 STM32 或其他 RTOS 平台移植 PSDK
  4. 第四阶段(应用集成):开发自定义传感器驱动,并将数据回传至飞控或地面站

9. 总结

本文以 DJI PSDK 官方快速入门文档为依据,结合 Linux 环境下的 Raspberry Pi 平台,梳理了 PSDK 学习过程中的关键知识点,包括开发环境搭建、Demo 编译运行、HAL 移植、数据订阅及常见问题排查等。后续可在此基础上深入探索模式开发、多负载协同等功能模块。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐