我们知道大疆MobileSDK中的函数调用,大多数都是异步回调,这一点应该好理解:用户通过移动设备上的屏幕交互对无人机下指令,而无人机要响应执行后才能反馈结果,所以它是异步的。而之前我的理解是,只要去处理好异步的问题就可以了,比如在iOS中为了更好的代码集成可以用RAC、PromiseKit等,而在异步回调中是能判断出这个函数调用是否得到了正确执行!但是,最近做的一个和云台转动有关的功能点,又让我加深了对此的理解!
碰到的情况是这样的,需要云台按指定俯仰角度进行旋转,而对应的函数也很简单,如下所示:
@interface DJIGimbal : DJIBaseComponent
/**
* @param rotation An instance of `DJIGimbalRotation`.
* @param completion Completion block.
*/
- (void)rotateWithRotation:(DJIGimbalRotation *)rotation
completion:(DJICompletionBlock)completion;
使用需要的参数值来进行调用,在completion中判断是成功了的,但在某些飞机上(Mavic 2Pro)反复测试云台都没有真正的转动。于是我又进行一些更简单的测试,同样的一段代码,当飞机放在地面上时就能转动了,但又飞到空中测试还是不行。后来终于发现是这样的,当一次调用后没有转动,那么稍等一下再调用就转动了! 再将地面上时的测试情况放在一起思考,我突然好像懂了一些,与飞行器的姿态是否稳定有关吧,这个函数调用调用成功了,只是代表触发了飞行器去执行这个动作,但云台转动这个动作有没有真的发生还要另去判断。所以后来的解决思路如下:
先调用云台转动的函数,然后在DJIGimbal的Delegate中去监测,如果云台一直没有转动,那么伺机再去调用一次并再进入监测流程。以这样的方式解决后实测多种机型都运行良好!
个人事后的一点感悟,无人机在空中本来就不能像地面上那样处于一个较稳定的状态,而与用户之间通过遥控器/WIFI连接,这种连接状态本身就会受到多种因素的干扰,进而影响到函数调用的结果!所以对待大疆无人机开发的一种比较保险的处理思路就是:调用 -->> 监测 -->> 反馈修正!