2017-08-03 29 views
2

我在嘗試在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://stackoverflow.com/questions/29556610/cast-a-swift-struct-to-unsafemutablepointervoid? – Larme

回答

1

的定義。最後我找到了解決此問題的通過委託方法!其實是一種更好的方式使用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版本中,但其工作完好

0

首先請注意,密鑰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://stackoverflow.com/questions/45872030/retrieve-images-from-a-dji-drone-with-exif-data 我真的很感激,如果你可以看看 謝謝! –