来自swift的DJI虚拟棒控制

问题描述:

我在尝试在Swift中使用iOS的DJI-SDK非常糟糕。来自swift的DJI虚拟棒控制

该SDK使用Objective-c编写,并使用键值系统存储值并将命令发送给无人机,因此如果您需要告诉无人机启用虚拟杆,您需要执行如下操作:

DJISDKManager.keyManager()?.setValue(true as NSNumber, for: enableVirtualStickModeKey!, withCompletion: { (error) in...... 

这是非常简单的,因为我们的价值是Bool投给NSNumber,问题开始时,我需要发送结构值,如虚拟棒(Objective-C的结构)的位置,这是一个例子使无人机以1m/s上升的值:

var controlData = DJIVirtualStickFlightControlData() 
    controlData.verticalThrottle = 1 
    controlData.pitch = 0 
    controlData.roll = 0 
    controlData.yaw = 0 

DJISDKManager.keyManager()?.setValue(controlData, for: virtualSticksKey!, withCompletion: { (error) in.. 

但是,SDK尝试设置值时出现错误。 我写信给DJI支持团队,得到的答复是,他们希望社会能够帮助我解决问题....

的问题是我需要什么类型的演员,使这一DJIVirtualStickFlightControlData对象转换为一个目标-C兼容型?

这是从DJIFlightControllerBaseTypes.h

typedef struct 
{ 
    float pitch; 
    float roll; 
    float yaw; 
    float verticalThrottle; 
} DJIVirtualStickFlightControlData; 

DJIVirtualStickFlightControlData定义,这是setValue方法从DJIKeyManager.h

/** 
* Performs a set on a settable key, changing attributes on the connected product. 
* 
* @param value A value object relevant to the given key 
* @param key A valid settable key 
* @param completion A set completion block. 
*/ 
- (void)setValue:(id)value 
      forKey:(DJIKey *)key 
     withCompletion:(DJIKeyedSetCompletionBlock)completion; 
+0

setValue返回什么错误? – paiv

+0

有一些方法可以将'struct'转换为'(NS)Data',这是蓝牙低能耗问题并不罕见。检查那里:https://*.com/questions/29556610/cast-a-swift-struct-to-unsafemutablepointervoid? – Larme

的定义。最后我找到了解决此问题的通过委托方法!其实是一种更好的方式使用SWIFTDJI-SDK

首先你的类为DJIFlightControllerDelegate

class FPVViewController: DJISDKManagerDelegate, DJIFlightControllerDelegate{ 

一个实施者创建检索FlightController实例

func fetchFlightController() -> DJIFlightController?{ 
     let product = DJISDKManager.product() 
     if (product == nil) { 
      return nil 
     } 

     if product!.isKind(of: DJIAircraft.self){ 
      return (product as! DJIAircraft).flightController 
     } 
     return nil 
    } 

productConnected方法调用它的方法(这是从DJISDKManagerDelegate其实另一个委托方法),并设置这个班级作为FlightController的代表

func productConnected(_ product: DJIBaseProduct?) { 

    NSLog("Product Connected") 

    if (product != nil) { 
     //Set this class as the delegate for the hardware 

     let flightController = self.fetchFlightController() 
     if flightController != nil{ 
      flightController!.delegate = self 
     } 

     self.setupVideoPreviewer() 
    } 

} 

之前你ca ň发虚棒命令,你必须让他们要做到这一点some conditions必须完成

最后,你可以设置虚拟棒值这样

var controlData = DJIVirtualStickFlightControlData() 
    controlData.verticalThrottle = 2 
    controlData.pitch = 0 
    controlData.roll = 0 
    controlData.yaw = 0 

let flightController = self.fetchFlightController() 
     flightController?.send(controlData, withCompletion: { (error) in 
      if error != nil{ 
       let nserror = error! as NSError 
       NSLog("Error controling virtual throttle \(String(describing: nserror))") 
      } 
     }) 

一两件事:Xcode remote install and debugging是一个必须有与开发DJI-SDK目前处于xCode和iOS的Beta版本中,但其工作完好

首先请注意,密钥SendVirtualStickFlightControlDatatype Action的关键。因此,使用密钥的正确方法是拨打.performAction而不是.setValue

要通过密钥中的struct值,它需要包装在NSValue中。由于你不得不求助于使用NSValue初始值设定项,它需要UnsafeRawPointer,这对Swift来说有点棘手。你可以这样做:

var controlData = DJIVirtualStickFlightControlData() 
controlData.verticalThrottle = 1 
controlData.pitch = 0 
controlData.roll = 0 
controlData.yaw = 0 

let value: NSValue = NSValue.init(pointer: &controlData) 

let key = DJIFlightControllerKey(param: DJIFlightControllerParamSendVirtualStickFlightControlData) 

DJISDKManager.keyManager()?.performAction(for: key!, withArguments: [value], andCompletion: { (success, value, error) in 
    print(success) 
}) 
+0

感谢您的帮助aksh1t,我最终使用委托方法,更容易,并且使用委托方法获得很多控制权来接收飞机状态更新 –

+0

嗨aksh1t,或许您可以帮我解决这个问题? https://*.com/questions/45872030/retrieve-images-from-a-dji-drone-with-exif-data 我真的很感激,如果你可以看看 谢谢! –