DJI Windows SDK踩坑记录
前言
DJI的windows SDK已经近3年未更新,最后一个版本仍为beta版。使用它的人也没有那么多,许多问题网上可以找的到的资料也相对较少,本文记录了我自己踩过的一些坑,以供大家参考。作者水平有限,有任何问题欢迎在文章下方留言交流!
DJI Windows SDK现状
大疆的WSDK已经近三年未更新了,DJI最后一次更新Windows SDK(以下简称WSDK)是2019年9月17号,且是Beta版本,具体版本号是0.3.2Beta
。
DJI官方称WSDK将不会再进行更新维护
我们曾在部署WSDK官方示例程序时遇到问题,之后我们去DJI发布在GitHub的WSDK示例程序库下寻求帮助,DJI官方给到我们的回复却是Windows SDK项目已永久暂停,且未来也不会在继续更新、维护,并推荐我们使用Mobile SDK进行开发。WSDK项目永久暂停的原因未知。
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)。
但是Mavic 2 pro并不支持通过WiFi连接到电脑。不过我抱着试一试的心态仍然尝试使用此方法去控制Mavic 2 pro,结果确实是无法控制。
之后我翻遍了整个WSDK接口文档,但是并没有发现其他可以适用于Mavic 2 pro的飞行姿态控制方法。于是我又跑到DJI的WSDK的Github仓库下面寻求帮助,DJI官方给我的回复是WSDK确实无法控制Mavic 2 pro的飞行姿态。
一个不熟悉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);
});
}