2

I can't get my head around how to get out simple status data, like the current gimbal pitch for example.

I have not found a solid connection between the DJI SDK and what actually works in xcode. The SDK gives me hints and together with xcode autocompletion a go forwards, slowly..

Class GimbalState has member getAttitudeInDegrees() with description: "The current gimbal attitude in degrees. Roll, pitch and yaw are 0 if the gimbal is level with the aircraft and points in the forward direction of North Pole." - Great!

However, it does not autocomplete in xcode nor does it compile.

Other approaches tested:

var gimbalStateInformation = DJIGimbalState()
    print(gimbalStateInformatoin.attitudeInDegrees.pitch.description)

--> All pitch roll and yaw values come out as 0.0

var gimbalStateInformation = DJUGimbalAttitude()
    print(gimbalStateInformatoin.pitch.description)

--> All pitch roll and yaw values come out as 0.0

I've tried to reach the information via keys, but my app crashes when I run the code.

func getGimbalAttitude(){
    // Get the key
    guard let gimbalAttitudeKey = DJIGimbalKey(param: DJIGimbalParamAttitudeInDegrees) else {
        print("Could not create DJIGimbalParamAttitudeInDegrees key")
        return
    }
    // Get the keyManager
    guard let keyManager = DJISDKManager.keyManager() else {
        print("Could not get the key manager, manke sure you are registered")
        return
    }
    // Test if key is available
    let testing = keyManager.isKeySupported(gimbalAttitudeKey)
    self.statusLabel.text = String(testing)    // This comes out true

    // Use key to retreive info
    let gimbalAttitudeValue = keyManager.getValueFor(gimbalAttitudeKey)
    let gimbalAttitude = gimbalAttitudeValue?.value as! DJIGimbalState
    _ = gimbalAttitude.attitudeInDegrees.pitch
// --> Application crashes on the line above
}

I'm working towards a Mavic Mini.

Please advise in general terms how to connect the DJI Mobile SDK to Swift and specifically how I can read out the current gimbal pitch value.

  • At a guess your code is probably crashing due to implicitly unwrapping an optional value that is nil - in this case gimbalAttitudeValue is likely nil. Better to safely unwrap a value using `as?` rather than `as!` or use guard – Brien Crean Oct 04 '20 at 01:18
  • Brien, thank you for helping me! Implicit unwrapping is the cause, although gimbalAttitudeValue is not nil. 'if let gimbalAttitudeValue: DJIKeyedValue = keyManager.getValueFor(gimbalAttitudeKey){ if let gimbalAttitude = gimbalAttitudeValue.value as? DJIGimbalAttitude{ print("Attitude.pitch is: " + String(gimbalAttitude.pitch)) return gimbalAttitude } else{ print("Code ends up here") } } else{ print("Code does not end up here") }' – Andreas Gising Oct 05 '20 at 08:24

1 Answers1

2

You can access the current Gimbal pitch through its didUpdate state delegate function

import DJISDK
class GimbalController: NSObject, DJIGimbalDelegate {
  let gimbal: DJIGimbal
    init(gimbal: DJIGimbal) {
      self.gimbal = gimbal
      super.init()
      gimbal.delegate = self
    }

    func gimbal(_ gimbal: DJIGimbal, didUpdate state: DJIGimbalState) {
            print(state.attitudeInDegrees.pitch)
    }
}

// create an instance of the custom gimbal controller in some other class
// and pass it the gimbal instance
if let aircraft = DJISDKManager.product() as? DJIAircraft {
  if let gimbal = aircraft.gimbal {
    let gimbalController = GimbalController(gimbal: gimbal)
  }
}
Brien Crean
  • 2,599
  • 5
  • 21
  • 46
  • Thank you very much! Although, I'm afraid I need more guidance.. The only way I could figure to pass on DJIGimbalState to your function was to call DJIGimbalState(). This does not result in a correctly updated gimbalPitch though. Please give me an other hint. Did you manage this to work on a Mavic Mini? btw, I successfully use the key reading method for DJIGimbalParamAttitudeYawRelativeToAircraft but instead of casting to DJIGimbalAttitude I cast to Double. – Andreas Gising Oct 05 '20 at 08:33
  • The function above is a delegate function - it is called automatically by the DJI SDK multiple times per second. You shouldn't need to call DJIGimbalState() - that would just initialise an object of type DJIGimbalState with no values. Yes it works on the Mavic mini with no issues for me - I updated the code, it should print the current value of the gimbals pitch. If not then maybe another piece of code you wrote has already implemented DJIGimbalDelegate? It should only be implemented once – Brien Crean Oct 05 '20 at 21:13
  • Brien, I'm very greatful for your help, but there is something I'm missing. Nothing is printed. When I have time I will strip down my code to minimum and start from there, I'll post here when I figure it out. Thank you again – Andreas Gising Nov 05 '20 at 10:38
  • Happy to help. I haven't actually tested the code I wrote above but one critical piece I left out was setting an instance of the custom class above to be the delegate for the running gimbal instance. I updated the code to reflect. I suspect this may be the issue – Brien Crean Nov 06 '20 at 01:40
  • Also if you want a good Swift example to check out and see how they implement it, have a look at DronePan https://github.com/dbaldwin/DronePan/blob/3eabe4be300c6fb1017947cddff9467b6f05259a/DronePan/Controllers/GimbalController.swift – Brien Crean Nov 06 '20 at 01:42
  • Great! Again, thank you very much for helping me (and others) out! – Andreas Gising Nov 09 '20 at 09:26
  • I can now confirm that the code proposed by Brien works perfectly. I built a new app from scratch to verify. Thank you! – Andreas Gising Nov 24 '20 at 09:19