DJI SDK waypoint mission 使用教程(下):生命周期

在 DJI SDK 中 Mission 的执行是由各自对应的 operator 管理的,WaypointMission 的生命周期由 DJIWaypointMissionOperator 管理。

基本流程

检查任务

在上一篇文章中介绍了 mission 和 waypoint 可以进行的配置。很多配置项要在对应的模式下才有效,因此在开始任务前需要检查一下任务的配置是否正确。这里的检查函数有两个,一个检查 mission 的配置,一个检查 waypoint 的配置:

// 检查任务的参数配置是否有效
mission.checkParameters()
// 检查 waypoint 的配置是否有效
mission.checkValidity()

加载、上传任务

任务的执行是由 DJIWaypointMissionOperator 管理的,所以首先需要把任务加载到 operator 中:

 guard let missionOperator = DJISDKManager.missionControl()?.waypointMissionOperator() else { return }
 missionOperator.load(mission) 

加载成功后需要把任务数据上传到无人机的飞控中。Waypoint 是一个一个上传的,如果 waypoint 比较多可能上传时间会久一些。要注意和无人机的通信状况是否良好,这一步很容易因为通信状况不佳失败。

missionOperator.uploadMission { (error) in
    if let error = error {
        // 处理上传失败的错误
    }
}

考虑到可能有多个对象关心航点的上传进度,DJI 使用观察者模式来处理上传的进度通知。

// 添加观察者
/**
 *  Adds listener to receive the event related to upload.
 */
- (void)addListenerToUploadEvent:(id)listener
                       withQueue:(nullable dispatch_queue_t)queue
                       andBlock:(DJIWaypointMissionOperatorUploadEventBlock)block;
// 移除观察者
- (void)removeListenerOfUploadEvents:(id)listener;

通过回调的 DJIWaypointMissionUploadEvent 实例可以获取到当前的上传进度和任务的状态。

missionOperator.addListener(toUploadEvent: self, with: listenerQueue) { (uploadEvent) in
    if let progress = uploadEvent.progress {
        print("progress: \(progress.uploadedWaypointIndex)/\(progress.totalWaypointCount)")
    }
    if uploadEvent.currentState == .readyToExecute {
        missionOperator.removeListener(ofUploadEvents: self)
    }
}

当 uploadEvent 中的当前任务状态是 readyToExecute 时说明航点已经上传结束,无人机准备就绪。

任务控制

任务的控制有:开始、暂停、继续、停止四种操作。

- (void)startMissionWithCompletion:(DJICompletionBlock)completion;

- (void)pauseMissionWithCompletion:(DJICompletionBlock)completion;

- (void)resumeMissionWithCompletion:(DJICompletionBlock)completion;

- (void)stopMissionWithCompletion:(DJICompletionBlock)completion;

只要任务在对应正确的状态时这些操作才会成功。比如只有当任务是在执行的状态时暂停和停止才能正确执行,否则会返回一个错误。

任务进度监听

与上传航点的监听方式一致,任务的执行进度通知也采用了一样的的观察者模式。

/**
 *  Adds listener to receive the event related to execution.
 */
- (void)addListenerToExecutionEvent:(id)listener
                          withQueue:(nullable dispatch_queue_t)queue
                           andBlock:(DJIWaypointMissionOperatorExecutionEventBlock)block;

ExecutionEvent 返回的 DJIWaypointMissionExecutionEvent 实例。DJIWaypointMissionExecutionEvent 包含了任务当前的状态和任务执行的进度。

 DJIWaypointMissionExecutionEvent : NSObject
/**
 *  The previous state of the operator.
 */ (nonatomic, readonly) DJIWaypointMissionState previousState;

/**
 *  The current state of the operator.
 */ (nonatomic, readonly) DJIWaypointMissionState currentState;

/**
 *  The execution progress of the mission. It is `nil` if there is an error during
 *  the execution.
 */ (nonatomic, readonly, nullable) DJIWaypointExecutionProgress *progress;

/**
 *  The encountered error during the execution if there is any. Otherwise, it is
 *  `nil`.
 */ (nonatomic, readonly, nullable) NSError *error;

通过 ExecutionEvent 中的 error 属性可以判断执行是否遇到错误,currentState 和 previousState 反应了此时的任务状态。progress 可以知道当前无人机飞过的航点进度。

 DJIWaypointExecutionProgress : NSObject

/**
 *  Index of the waypoint for the next mission to which the aircraft will proceed.
 */(nonatomic, readonly) NSInteger targetWaypointIndex;

/**
 *  YES when the aircraft reaches a waypoint. After the waypoint actions and heading
 *  change is complete,  the `targetWaypointIndex` will increment and this  property
 *  will become NO.
 */(nonatomic, readonly) BOOL isWaypointReached;

/**
 *  Current execution state of the aircraft.
 */(nonatomic, readonly) DJIWaypointMissionExecuteState execState;

targetWaypointIndex 表示飞机正在飞向的航点的索引,在飞行过程中 isWaypointReached 的值是 false。当无人机到达航点航点位置时 isWaypointReached 的值会变成 true。接着无人机根据设置调整 heading,执行 waypoint action。执行完成后 targetWaypointIndex 加 1,朝下一个航点飞去。

通常我们认为任务结束时 targetWaypointIndex 会是最后一个点,但是如果刚好 finishAction 是 goFirstWaypoint,无人机飞到最后一个点后会返回第一个航点,所以最后任务结束时的 targetWaypointIndex 会是 0。
另外一个容易理解错误的是 ExecutionEvent 是一个定时回调的事件,不是在 value changed 的时候才回调。所以无人机飞行过程中你可能会一直收到同样的值的 ExecutionEvent。

任务结束监听

任务结束的通知也采用了一样的的观察者模式。

/**
 *  Adds listener to receive the notification when a waypoint mission is finished.
 */
- (void)addListenerToFinished:(id)listener
                    withQueue:(nullable dispatch_queue_t)queue
                     andBlock:(DJICompletionBlock)block;

任务结束的回调有三种可能:

  • 回调有 error,任务执行过程中遇到了错误,任务终止
  • 回调无 error,到达过最后一个航点,任务正常结束
  • 回调无 error,没有到达过最后一个航点,任务过程中用户主动停止了任务或者过程中触发无人机返航 ## 任务状态 在任务生命周期中很多操作都和任务的状态有关。Operator 上的 currentState 能取到最近一次同步的任务状态。任务状态 DJIWaypointMissionState 总共有以下几种状态:
  • Unknown:和无人机没有正常的通信,无法确认任务当前状态
  • Disconnected:无人机断开连接
  • Recovering:手机和遥控器、无人机间的连接正在重连,任务状态正在同步中
  • NotSupported:连接的设备不支持该任务的状态同步
  • ReadyToUpload:无人机现在可以上传航点数据
  • Uploading:上传航点数据中
  • ReadyToExecute:航点数据上传成功,准备好开始执行任务
  • Executing:任务执行中
  • Paused:任务被暂停 ## 下载任务 Waypoint mission 因为航点是一次性上传到飞控中,默认又是遥控器丢失信号任务继续执行。所以可能出现任务过程中应用退出,应用重新连接上无人机后,无人机虽然在执行任务,但是 sdk 中已经取不到 waypointMission 中的航点信息了。如果这个时候你需要在任务结束后重新进行一次同样的任务,那么任务 start 的时候就会报错,因为本地没有航点信息可以上传。针对这个情况 Operator 提供了下载航点的方法,和上传航点类似,需要注意的是只有在任务暂停和执行状态时下载航点才有效。
/**
 *  Downloads information of each waypoint from aircraft and save it to
 *  `loadedMission`. If a download operation is started, the operator will download
 *  the information of waypoints missing in `loadedMission` one-by-one in ascending
 *  order. If `loadedMission` is already complete (containing all the waypoints),
 *  this method will call `completion` immediately without error. It can only be
 *  called when the `currentState` is one of the following: -
 *  `DJIWaypointMissionStateExecuting` - `DJIWaypointMissionStateExecutionPaused`
 */
- (void)downloadMissionWithCompletion:(DJICompletionBlock)completion;

// 监听下载的进度
- (void)addListenerToDownloadEvent:(id)listener
                         withQueue:(nullable dispatch_queue_t)queue
                          andBlock:(DJIWaypointMissionOperatorDownloadEventBlock)block;
© 著作权归作者所有
这个作品真棒,我要支持一下!
奇志技术团队博客 http://meshtech.co/
0条评论
top Created with Sketch.