DJI Windows SDK踩坑记录

  • 前言
  • DJI Windows SDK现状
  • DJI官方称WSDK将不会再进行更新维护
  • DJI Windows SDK无法直接控制Mavic 2 pro的飞行姿态
  • 一个不熟悉UWP的开发者可能会犯的错误


前言

DJI的windows SDK已经近3年未更新,最后一个版本仍为beta版。使用它的人也没有那么多,许多问题网上可以找的到的资料也相对较少,本文记录了我自己踩过的一些坑,以供大家参考。作者水平有限,有任何问题欢迎在文章下方留言交流!

DJI Windows SDK现状

大疆的WSDK已经近三年未更新了,DJI最后一次更新Windows SDK(以下简称WSDK)是2019年9月17号,且是Beta版本,具体版本号是0.3.2Beta

大疆sdk开发 能不能用python 大疆 windows sdk_windows

DJI官方称WSDK将不会再进行更新维护

我们曾在部署WSDK官方示例程序时遇到问题,之后我们去DJI发布在GitHub的WSDK示例程序库下寻求帮助,DJI官方给到我们的回复却是Windows SDK项目已永久暂停,且未来也不会在继续更新、维护,并推荐我们使用Mobile SDK进行开发。WSDK项目永久暂停的原因未知。

大疆sdk开发 能不能用python 大疆 windows sdk_Windows_02

DJI Windows SDK无法直接控制Mavic 2 pro的飞行姿态

在我想进一步控制Mavic 2 pro进行上升、下降、前进、后退等动作时遇到了问题。

// WSDK API文档地址
https://developer.dji.com/api-reference/windows-api/SDKManager/DJISDKManager.html

查阅WSDK的接口文档,可以知道VirtualRemoteController这个类下的UpdateJoystickValue方法可以用于控制飞行器的飞行姿态,但是文档中说仅在飞行器通过WiFi连接电脑且没有物理遥控器的情况下才能使用此方法(例如mavic air通过wifi连接pc)。

大疆sdk开发 能不能用python 大疆 windows sdk_Windows_03

但是Mavic 2 pro并不支持通过WiFi连接到电脑。不过我抱着试一试的心态仍然尝试使用此方法去控制Mavic 2 pro,结果确实是无法控制。

之后我翻遍了整个WSDK接口文档,但是并没有发现其他可以适用于Mavic 2 pro的飞行姿态控制方法。于是我又跑到DJI的WSDK的Github仓库下面寻求帮助,DJI官方给我的回复是WSDK确实无法控制Mavic 2 pro的飞行姿态。

大疆sdk开发 能不能用python 大疆 windows sdk_windows_04

一个不熟悉UWP的开发者可能会犯的错误

首先我本身一没做过前端,二初次接触UWP桌面程序开发。然后我在跟着大疆的wsdk官方文档中的“相机”应用教程,在获取相机画面的时候遇到了一个问题:每次代码一运行,刚开始能看到相机的画面,然后几秒之后就没了。这个问题我还疑惑了好久,后来仔细看了大疆的代码,发现了那一句“Must in UI Thread”,必须在UI线程中!恍然大悟。

//Callback of SDKRegistrationEvent
private async void Instance_SDKRegistrationEvent(SDKRegistrationState state, SDKError resultCode)
{
    if (resultCode == SDKError.NO_ERROR)
    {
        System.Diagnostics.Debug.WriteLine("Register app successfully.");

        //Must in UI Thread
        //必须在UI线程中!
        await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async () =>
        {
            //Raw data and decoded data listener
            if (videoParser == null)
            {
                videoParser = new DJIVideoParser.Parser();
                videoParser.Initialize(delegate (byte[]data)
                {
                    //Note: This function must be called because we need DJI Windows SDK to help us to parse frame data.
                    return DJISDKManager.Instance.VideoFeeder.ParseAssitantDecodingInfo(0, data);
                });
                //Set the swapChainPanel to display and set the decoded data callback.
                videoParser.SetSurfaceAndVideoCallback(0, 0, swapChainPanel, ReceiveDecodedData);
                DJISDKManager.Instance.VideoFeeder.GetPrimaryVideoFeed(0).VideoDataUpdated += OnVideoPush;
            }
            //get the camera type and observe the CameraTypeChanged event.
            DJISDKManager.Instance.ComponentManager.GetCameraHandler(0, 0).CameraTypeChanged += OnCameraTypeChanged;
            var type = await DJISDKManager.Instance.ComponentManager.GetCameraHandler(0, 0).GetCameraTypeAsync();
            OnCameraTypeChanged(this, type.value);
        });
    }
    else
    {
        System.Diagnostics.Debug.WriteLine("SDK register failed, the error is: ");
        System.Diagnostics.Debug.WriteLine(resultCode.ToString());
    }
}

把代码改成下面这样就好了

// OnNavigatedTo方法是当Page加载并成为父Frame的当前源时调用的
// 具体可以自行查询UWP官方文档
protected override async void OnNavigatedTo(NavigationEventArgs e)
{
	base.OnNavigatedFrom(e);
	InitializeVideoFeedModule();
}
private async void InitializeVideoFeedModule()
{
	// 必须在UI线程中运行
	await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async () =>
	{
	// 原始数据和解码数据侦听器
	if (videoParser == null)
	{
		videoParser = new DJIVideoParser.Parser();
		videoParser.Initialize(delegate (byte[] data)
		{
			// 注意:必须调用此函数,因为我们需要DJI Windows SDK来帮助我们解析帧数据。
			return DJISDKManager.Instance.VideoFeeder.ParseAssitantDecodingInfo(0, data);
		});
		// 设置swapChainPanel以显示并设置解码数据回调
		videoParser.SetSurfaceAndVideoCallback(0, 0, swapChainPanel, ReceiveDecodedData);
		DJISDKManager.Instance.VideoFeeder.GetPrimaryVideoFeed(0).VideoDataUpdated += OnVideoPush;
	}
	// 获取相机类型并观察CameraTypeChanged事件
	DJISDKManager.Instance.ComponentManager.GetCameraHandler(0, 0).CameraTypeChanged += OnCameraTypeChanged;
	var type = await DJISDKManager.Instance.ComponentManager.GetCameraHandler(0, 0).GetCameraTypeAsync();
	OnCameraTypeChanged(this, type.value);
	});
}