2

我在 Swift 中尝试使用适用于 iOS 的 DJI-SDK 时遇到了非常糟糕的情况。

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

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

这非常简单,因为我们的值是一个Bool强制转换NSNumber,当我需要发送结构值(如虚拟棒的位置(Objective-c 结构))时,问题就开始了,这是使无人机上升到 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;

这是 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;
4

2 回答 2

1

DJI-SDK最后我通过委托方法找到了解决这个问题的方法!实际上是使用in的更好方法SWIFT

首先将您的班级标记为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()
    }

}

在您可以发送虚拟摇杆命令之前,您必须启用它们并且必须满足一些条件

最后,您可以通过这种方式设置虚拟摇杆值

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 远程安装和调试是必须使用DJI-SDK当前在 xCode 和 iOS 的 Beta 版本中进行开发的,但它工作得非常好

于 2017-08-05T11:54:39.873 回答
0

首先,请注意键SendVirtualStickFlightControlDataAction 类型的键。因此,使用密钥的正确方法是调用.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)
})
于 2017-08-16T17:14:10.407 回答