航点飞行教程文档
1. 航点飞行介绍
航点飞行(waypoint)是Mobile SDK重要的功能模块。在地图上选定航线点、配置航点动作参数以及设定航线参数以后,飞机可以按照指定的地图选定点开始执行飞行任务,并执行设置的航线动作和航点动作。
本教程展示了完整的类、接口说明以及接口调用流程的示例。
2. 航点飞行流程图
3. 航点飞行关键类和API介绍
3.1 航点飞行涉及到的类
类 | 描述 | 备注 |
---|---|---|
AUTELWaypointMissionHandler | 继承自AUTELMissionHandler ,是处理航线任务的协议管理类,用于下载,上传,执行,停止,暂停任务。 | |
AUTELWaypointMission | 继承自AUTELMission ,是航线飞行任务的基类。 | |
AUTELGen2WaypointMission | 继承自AUTELWaypointMission ,EVO I的航线飞行任务类。 | |
AUTELMCWaypointMission | 继承自AUTELGen2WaypointMission ,EVO II V1、EVO II V2的航线飞行任务类。 | |
AUTELWaypointG2 | 继承自AUTELWaypoint ,EVO I的航线飞行任务中的一个航点类定义。 | |
AUTELWaypointMC | 继承自AUTELWaypointG2 ,EVO II V1、EVO II V2的航线飞行任务中的一个航点类定义。 | |
AUTELMissionProgressStatus | 当前任务的进度状态类的基类。通过onNavigationMissionStatusChanged 方法上报任务执行状态。 | |
AUTELWaypointMissionStatus | 继承自AUTELMissionProgressStatus ,当前航线飞行任务执行状态。 |
3.1.1 AUTELMCWaypointMission类
EVO II V1、EVO II V2的航线飞行任务类,相关参数及方法定义如下:
参数 | 类型 | 描述 | 备注 |
---|---|---|---|
missionName | NSString | 任务名称 | |
guid | NSString | 任务唯一识别ID | |
missionType | AUTELMissionType | 任务类型,见AUTELMissionType 枚举定义。AUTELMissionTypeWaypoint :航点任务AUTELMissionTypeRectangle :矩形测绘任务AUTELMissionTypePolygon :多边形测绘任务AUTELMissionTypeObliquePhoto :倾斜摄影任务 | |
altitudeType | int | 航点高度类型:0是相对高度,1是海拔高度 | 仅适用于航点任务 |
lostConnectAction | AUTELMission SignalLostHandleType | 飞行器失联动作,默认 AUTELMissionSignalLostHandleTypeNone 。如果等于 AUTELMissionSignalLostHandleTypeGoHome ,飞行器返航到Home点。如果等于 AUTELMissionSignalLostHandleTypeContinue ,飞行器继续执行任务直到电量不足或者任务完成。 | |
finishMode | AUTELNavigation MissionFinishMode | 任务结束动作,默认 AUTELNavigationMissionFinishModeGoHome 。如果等于 AUTELNavigationMissionFinishModeGoHome ,飞行器执行完该任务后,会自动返航。如果等于 AUTELNavigationMissionFinishModeHover ,飞行器在完成任务后原地悬停。 | |
poiList | NSArray<InterestPointModel > | 兴趣点集合,一个兴趣点可以与一个或多个航点关联。一个航点只能与一个兴趣点关联。关联兴趣点的航点在执行任务时机头朝向兴趣点。 | 仅适用于航点任务 |
totalTimes | int | 航线飞行总时间,由航线规划算法计算返回。目前要设置为-1。 | 仅适用于航点任务 |
totalDistance | int | 航线总飞行距离,由航线规划算法计算返回。目前要设置为-1。 | 仅适用于航点任务 |
3.1.2 AUTELWaypointMC类
EVO II V1、EVO II V2的航线飞行任务中的一个航点类定义。
一个航点任务由一个或多个航点组成。每个航点可以配置航线动作或航点动作。
参数 | 类型 | 描述 | 备注 |
---|---|---|---|
coordinate | CLLocationCoordinate2D | 航点坐标。 | |
style | AUTELWaypointStyle | 航点类型,见AUTELWaypointStyle 枚举定义,当前支持两种航点类型,如下:AUTELWaypointStyleNormal :飞越,飞行器到达航点后不停,直接飞走AUTELWaypointStyleHover :悬停,飞行器到达航点后停下来,若设置了航点动作,则停下来执行航点动作 | |
altitude | float | 航点高度,该高度是相对于飞行器起飞点的高度,不能高度飞行器的最大高度限制。 | |
speed | float | 航点飞行速度 | |
headingMode | AUTELWaypointHeadingMode | 定义航点朝向模式 如果等于 AUTELWaypointHeadingModeTowardsNext,朝向下一个航点。 如果等于 AUTELWaypointHeadingModeCustom ,朝向用户定义的方向。如果等于 AUTELWaypointHeadingModeFreedom,自由朝向,用用户控制,响应用户打杆。 | |
userDefinedHeading | float | 自定义机头朝向角度。 | |
poiIndex | int | 关联兴趣点,若没关联要传-1,一个航点只能与一个兴趣点关联。 | |
actions | NSArray <AUTELWaypointAction > | 航点动作列表。具体定义见AUTELWaypointAction 类说明 |
3.1.3 AUTELWaypointAction类
该类描述航点动作信息,支持EVO II V1、EVO II V2系列飞行器。
参数 | 类型 | 描述 | 备注 |
---|---|---|---|
actionId | int | 当前动作标识,对应航点动作列表的索引。 | |
actionType | AUTELWaypointActionType | 定义航点动作类型,具体见:3.1.5 AUTELWaypointActionType枚举 | |
actionPara | AUTELWaypointActionPara | 航点动作参数列表,具体见:3.1.4 AUTELWaypointActionPara类 |
若航点类型是飞越,此航点的航点动作允许有0组或1组,支持动作类型及其参数个数的逻辑如下:
支持动作类型 | 参数个数 | 描述 | 备注 |
---|---|---|---|
开始录像 | 0 | 无参数 | |
停止录像 | 0 | 无参数 | |
拍照 | 0 | 无参数 | |
定时拍 | 1 | 定时拍照间隔(单位s) | |
定距拍 | 1 | 定距拍照间隔(单位m) |
若航点类型是悬停,航点动作允许有0到多组。若相机动作是拍照,则没有参数;若相机动作是录像,则有一个参数(录像时长);若相机动作是定时拍照,有2个参数(拍照间隙和拍照时长);
支持动作类型 | 参数个数 | 描述 | 备注 |
---|---|---|---|
拍照 | 0 | 无参数 | |
录像 | 1 | 录像时长(单位s) | |
定时拍 | 2 | 拍照间隔(单位s),拍照时长(单位s) |
3.1.4 AUTELWaypointActionPara类
该类描述航点动作信息,支持EVO II V1、EVO II V2系列飞行器。
航点动作分两种:航线动作或航点动作。
参数 | 类型 | 描述 | 备注 |
---|---|---|---|
cameraPitch | float | 云台俯仰角,参数范围:0到90,0表示水平,90表示垂直朝下。 | |
cameraYaw | float | 飞行器偏航角 | |
cameraRoll | float | 云台roll角 | 暂时参数无效 |
timeInterval | float | 定时拍照间隔(单位s) | |
timeIntervalTimeDuration | float | 定时拍照总时长(单位s) | |
distanceInterval | float | 定距拍照间隔(单位m) | |
recordVideoTimeDuration | float | 录像时长(单位s) | |
cameraZoom | float | 相机变焦倍数,默认是1 |
3.1.5 AUTELWaypointActionType枚举
定义航点动作类型,具体定义如下:
/**
* Define Waypoint Action Type
*
* 定义航点动作类型
*/
typedef NS_ENUM(int, AUTELWaypointActionType) {
/**
* @brief Invalid
*
* 无效动作。
*/
AUTELWaypointActionTypeInvalid = 0,
/**
* @brief TakePhoto
*
* 拍照。
*/
AUTELWaypointActionTypeTakePhoto = 1,
/**
* @brief Start Video Record
*
* 开始录像
*/
AUTELWaypointActionTypeStartRecordVideo = 2,
/**
* @brief Stop Video Record
*
* 停止录像
*/
AUTELWaypointActionTypeStopRecordVideo = 3,
/**
* @brief TakePhoto Interval
*
* 定时拍
*/
AUTELWaypointActionTypeTimeInterval = 11,
/**
* @brief TakePhoto Distance
*
* 定距拍
*/
AUTELWaypointActionTypeDistance= 12,
/**
* @brief Unknown
*
* 未知。
*/
AUTELWaypointActionTypeUnknown = 0xff
};
3.1.6 AUTELWaypointMissionStatus类
该类描述当前航点飞行任务状态,
参数 | 类型 | 描述 | 备注 |
---|---|---|---|
execState | AUTELWaypointMissionExecuteState | 无人机航点飞行任务的当前状态,具体见:3.1.7 AUTELWaypointMissionExecuteState枚举 | |
targetWaypointIndex | int | 无人机正在飞去的航点下标 | |
residualTime | float | 当前航点飞行任务剩余飞行时间。 | |
residualDistance | float | 当前航点飞行任务剩余飞行路线长度。 | |
photoCount | float | 当前航点飞行任务已拍照片张数。 |
3.1.7 航点飞行任务状态上报接口
/**
* @brief Updates the navigation mission status. If the missionType is of type AUTELNavigationMissionWaypoint
* then the missionStatus will be of class AUTELWaypointMissionStatus.
*
* 更新智能飞行任务的状态。
* 若 missionStatus 是 AUTELWaypointMissionStatus 类型,则当前正在执行航点任务。
*
* @param missionStatus Mission status based on the current mission.
*
根据当前智能飞行模式返回的任务状态
*
* @see AUTELWaypointMissionStatus
*/
- (void)onNavigationMissionStatusChanged:(AUTELMissionProgressStatus* _Nonnull)missionStatus;
/**
* @brief The mission status information is pushed in real time during mission flight execution.Specifically refers to mission flight (waypoint flight, rectangular mission, polygonal mission)
*
* 任务飞行执行时实时推送任务状态信息。特指任务飞行(航点飞行、矩形任务、多边形任务)。
*
* @param missionStatus Mission status based on the current mission.
*
* 任务飞行执行时实时推送任务状态信息
*
* @see AUTELMissionProgressStatus
*/
- (void)onMissionCurrentStatusUpdateNote:(AUTELWaypointMissionStatus* _Nonnull)missionStatus;
4. 航点飞行功能实现
1. 监听航点飞行任务状态上报
注册监听航点飞行任务状态上报
AUTELNavigationDelegateConnection.shared.addProtocol(self)
监听航点飞行任务状态上报
func onNavigationMissionStatusChanged(_ missionStatus: AUTELMissionProgressStatus!) {
DispatchQueue.main.async {
}
}
- (void)onMissionCurrentStatusUpdateNote:(AUTELWaypointMissionStatus* _Nonnull)missionStatus {
DispatchQueue.main.async {
}
}
2. 开始任务
开始任务包括以下操作步骤
- 配置任务数据模型
- 上传任务数据
- 开始执行任务
3.1 创建航点飞行任务
private func creatMissionForMC() -> AUTELMCWaypointMission {
let mission = AUTELMCWaypointMission()
mission.missionId = 5
let finishModeIndex = 0
mission.finishMode = finishModeIndex == 0 ? .goHome : .hover
mission.totalTimes = -1
mission.totalDistance = -1
mission.executeIndex = 0
mission.executePhotos = 0
mission.lostConnectAction = .continue
mission.guid = "0fd18b3fca64b83089d5c9bad4420c94"//MD5字符串,字符串长度限制32
mission.missionName = "Waypoint Mission"
mission.missionType = .waypoint
mission.addGen2Waypoints(setWayPointTypeForHover())
return mission
}
3.2 配置任务数据示例一
航点类型是飞越,航线偏航角设置为135°,云台俯仰角设置为45度,相机动作设置为定时拍:
private func setWayPointTypeForflyOver() -> [AUTELWaypointMC] {
var items = [AUTELWaypointMC]()
typealias dataSetTuple = (curFlyTime: Float, curFlyDistance: Float, waypoint: WayPointModel)
var dataSets = [dataSetTuple]()
WayPointManager.shared.wayPoints.enumerated().forEach { (index, element) in
let dataSetTuple = (Float(19*index), Float(36*index), element)
dataSets.append(dataSetTuple)
}
for i in 0..<dataSets.count {
let mc = AUTELWaypointMC()
mc.coordinate = coordinateAntiCorrectIfNeeded(dataSets[i].waypoint.coordinate)
mc.altitude = dataSets[i].waypoint.height
mc.speed = dataSets[i].waypoint.speed
mc.userDefinedHeading = 0
mc.headingMode = .custom//偏航角设置为自定义
mc.poiIndex = -1
mc.curFlyTime = dataSets[i].curFlyTime
mc.curFlyDistance = dataSets[i].curFlyDistance
mc.style = .normal//航点类型是飞越
//相机动作示例
var actions = [AUTELWaypointAction]()//创建动作数组
let waypointAction = AUTELWaypointAction()//配置动作1
waypointAction.actionId = 0
waypointAction.actionType = AUTELWaypointActionType.timeInterval//动作类型设置为定时拍
let actioinPara = AUTELWaypointActionPara.init()//配置动作参数
actioinPara.cameraPitch = 45//设置云台pitch角度朝下45°
actioinPara.cameraYaw = 135//设置飞机偏航角135°,其中0°表示正北,90°表示沿航线
actioinPara.cameraZoom = 1//变焦倍数是1倍
actioinPara.timeInterval = 2//设置定时拍照时间间隙为2秒
waypointAction.actionPara = actioinPara
actions.append(waypointAction)
mc.actions = actions
items.append(mc)
}
return items
}
3.3 配置任务数据示例二
航点类型是悬停,以下代码展示了如何自定义多组相机动作,如何自定义飞机偏航角,如何自定义云台pitch角度:
private func setWayPointTypeForHover() -> [AUTELWaypointMC] {
var items = [AUTELWaypointMC]()
typealias dataSetTuple = (curFlyTime: Float, curFlyDistance: Float, waypoint: WayPointModel)
var dataSets = [dataSetTuple]()
WayPointManager.shared.wayPoints.enumerated().forEach { (index, element) in
let dataSetTuple = (Float(19*index), Float(36*index), element)
dataSets.append(dataSetTuple)
}
for i in 0..<dataSets.count {
let mc = AUTELWaypointMC()
mc.coordinate = coordinateAntiCorrectIfNeeded(dataSets[i].waypoint.coordinate)
mc.altitude = dataSets[i].waypoint.height
mc.speed = dataSets[i].waypoint.speed
mc.userDefinedHeading = 0
mc.headingMode = .custom//偏航角设置为自定义,配合下面的actioinPara.cameraYaw来自定义偏航角
mc.poiIndex = -1
mc.curFlyTime = -1//dataSets[i].curFlyTime
mc.curFlyDistance = -1//dataSets[i].curFlyDistance
mc.style = .hover// 航点类型是悬停,表示飞机到达航点会停下来执行航点动作
mc.holdTime = 0
var actions = [AUTELWaypointAction]()//创建动作数组
let waypointAction = AUTELWaypointAction()//配置动作1
let actioinPara = AUTELWaypointActionPara.init()//配置动作1参数
waypointAction.actionId = 0
if i == 0 {//航点0动作参数
waypointAction.actionType = AUTELWaypointActionType.takePhoto//动作类型设置为单拍
actioinPara.cameraPitch = 45//设置云台pitch角度朝下45°
actioinPara.cameraYaw = 135//设置飞机偏航角135°,其中0°表示正北,90°表示沿航线
} else if i == 1 {//航点1动作参数
waypointAction.actionType = AUTELWaypointActionType.timeInterval//动作类型设置为单拍
actioinPara.timeIntervalTimeDuration = 20//设置定时拍照时间20s
actioinPara.timeInterval = 3//设置定时拍照时间间隙为2秒
actioinPara.cameraPitch = 70//设置云台pitch角度朝下45°
actioinPara.cameraYaw = 0//设置飞机偏航角0°,其中0°表示正北,90°表示沿航线
} else if i == 2 {//航点1动作参数
waypointAction.actionType = AUTELWaypointActionType.timeInterval//动作类型设置为单拍
actioinPara.timeIntervalTimeDuration = 21//设置定时拍照时间20s
actioinPara.timeInterval = 3//设置定时拍照时间间隙为3秒
actioinPara.cameraPitch = 0//设置云台pitch角度朝下0°
actioinPara.cameraYaw = 0//设置飞机偏航角0°,其中0°表示正北,90°表示沿航线
} else {
waypointAction.actionType = AUTELWaypointActionType.takePhoto//动作类型设置为单拍
actioinPara.cameraPitch = 90//设置云台pitch角度朝下45°
actioinPara.cameraYaw = 180//设置飞机偏航角180°,其中0°表示正北,90°表示沿航线
}
actioinPara.cameraZoom = 1//变焦倍数是1倍
waypointAction.actionPara = actioinPara
actions.append(waypointAction)
mc.actions = actions
items.append(mc)
}
return items
}
3.4 上传任务并开始执行任务
//1. 配置任务数据模型
let mission = creatMissionForMC()
//2. 上传任务数据
let handler = DroneConnection.shared.drone?.mainController.navigationManager.waypointMissionHandler
handler?.prepare(mission, withProgress: { (progress) in
print("waypoint:\(progress)\n");
}, withCompletion: { (error) in
if let err = error {
print("prepare waypoint mission error: " + err.localizedDescription);
DispatchQueue.main.async {
completionHandler(error)
}
return
} else {
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
//3. 开始执行任务
handler?.startMissionExecution(completion: { (error) in
if let err = error {
DispatchQueue.main.async {
print("2. Start the mission error: " + err.localizedDescription);
completionHandler(error)
}
} else {
DispatchQueue.main.async {
completionHandler(nil)
}
}
})
}
}
})
4.暂停任务
DroneConnection.shared.drone?.mainController.navigationManager.waypointMissionHandler.pauseMissionExecution(completion: { (error) in
if let err = error {
print("pause waypoint error: \(err.localizedDescription)")
DispatchQueue.main.async {
}
} else {
}
})
5.继续任务
DroneConnection.shared.drone?.mainController.navigationManager.waypointMissionHandler.resumeMissionExecution(completion: { (error) in
if let err = error {
print("resume waypoint error: \(err.localizedDescription)")
DispatchQueue.main.async {
}
} else {
}
})
6. 停止任务
航点飞行任务正在执行,可调用以下方法停止任务,根据输入参数,无人机停止任务后将进行返航或者悬停。
DroneConnection.shared.drone?.mainController.navigationManager.waypointMissionHandler.stopMissionExecution(.goHome, withCompletion: { [weak self] (error) in
guard let _ = self else { return }
if let err = error {
DispatchQueue.main.async {
}
print("exit waypoint mission error: \(err.localizedDescription)")
} else {
}
})
本教程到此结束,再见。