来自swift的DJI Virtual Sticks控制

时间:2017-08-03 12:28:03

标签: objective-c swift struct compatibility dji-sdk

我在Swift中尝试使用DJI-SDK for iOS时非常糟糕。

这个SDK是用Objective-c编写的,它使用一个键值系统来存储值并向无人机发送命令,所以如果你需要告诉无人机启用虚拟棒,你需要执行如下操作:< / p>

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

这非常简单,因为我们的值是Bool强制转换为NSNumber,当我需要发送像虚拟棒的位置(Objective-c struct)这样的结构值时问题就开始了,这个是一个让无人机以1米/秒的速度上升的值的例子:

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对象转换为Objective-C兼容类型需要进行哪种类型的转换?

这是DJIVirtualStickFlightControlData

中的DJIFlightControllerBaseTypes.h定义
    typedef struct
{
    float pitch;
    float roll;
    float yaw;
    float verticalThrottle;
} DJIVirtualStickFlightControlData;

这是DJIKeyManager.h

中setValue方法的定义
/**
 *  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;

2 个答案:

答案 0 :(得分:1)

Finally I find a workaround to this problem through delegate methods!, actually is a much better way to use the DJI-SDK in SWIFT

First mark your class as a implementer of DJIFlightControllerDelegate

class FPVViewController: DJISDKManagerDelegate, DJIFlightControllerDelegate{

Create a method to retrieve the FlightController instance

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
    }

Call it from the productConnected method (this is actually another delegate method from DJISDKManagerDelegate) and set this class as the delegate for the 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()
    }

}

Before you can send virtual stick commands you must enable them and to do that some conditions must be accomplished

Finally you can set the virtual sticks values this way

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))")
            }
        })

One more thing: Xcode remote install and debugging is a must have to develop with the DJI-SDK is currently in the Beta versions of xCode and iOS but its working perfectly fine

答案 1 :(得分:0)

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

要在密钥中传递struct值,需要将其包含在NSValue中。这对Swift来说有点棘手,因为你必须使用NSValue初始值设定项,它需要UnsafeRawPointer。你可以这样做:

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)
})