我在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
/**
* 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 :(得分: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)
首先,请注意,密钥SendVirtualStickFlightControlData
是type 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)
})