waypoints-ff33bc0124.gif
Waypoint mission 是无人机开发中使用频率很高的一个任务。可以提前根据坐标规划好航点,每个航点除了坐标外还可以设置高度、航向、自定义动作。飞行过程中还可以手动调整无人机的飞行速度。需要强调的是受限于飞控的内存,目前消费级无人机的一次最多只能规划 99 个航点

DJIWaypoint

DJIWaypoint 的常规设置有坐标、高度、云台角度、机头朝向。

  1. let coordinate = CLLocationCoordinate2D(latitude: lat, longitude: long)
  2. var waypoint = DJIWaypoint(coordinate: coordinate)
  3. // 航点高度是 50 米
  4. waypoint.altitude = 50.0
  5. // 无人机朝向是 50 度
  6. waypoint.heading = 50
  7. // 云台角度是 60 度
  8. waypoint.gimbalPitch = -60.0

关于 heading 还有一个比较有意思的关联属性 turnMode。比如现在无人机的朝向是 0 度,这个时候我们希望机头调整到 3 点钟方向,就是 90 度。这个时候有两种运动轨迹:顺时针和逆时针。如果是顺时针,就和时针一样,向右旋转 90 度就到了。也可能是逆时针,走一个远路,往左旋转 270度。如果无人机朝向运动轨迹方向有要求,可以通过设置 turnMode来实现。

  1. // 顺时针调整机头朝向
  2. waypoint.turnMode = .clockwise
  3. // 逆时针调整机头朝向
  4. waypoint.turnMode = .counterClockwise

航点间飞行速度

还可以单独设置航点间的飞行速度,需要说明的是这个速度指的是当前航点前往下一个航点时的速度。航点速度的取值范围是 0 - 15 m/s,注意只能是正数。在 DJIWaypointMission 中有个属性 autoFlightSpeed,如果没有设置航点速度那么会按照任务的 autoFlightSpeed 速度飞行。与航点速度只能是正数不同,任务自动飞行速度可以是负数,取值范围是 -15 到 15 m/s。当速度是负数时,无人机会朝着前一个航点往回飞。在任务过程中,用户手中的遥控器拨杆也可以调整无人机的飞行速度。遥控器也可以让飞机往回飞。
总结一下,航点间速度只能是正数,autoFlightSpeed 和遥控器调整的速度可以是负数,可以让无人机往回飞。那么这三种方式都可以控制飞行速度,那么优先级是怎样的呢?遥控器 > 航点速度 > autoFlightSpeed。无人机优先响应遥控器的控制,其次是按照每个航点预设好的速度飞行,如果没有设置航点速度使用 autoFlightSpeed
在飞行过程中 DJIWaypointMissionOperator 可以通过 setAutoFlightSpeed 设置速度,飞行过程中设置的速度优先级大于任务配置的 autoFlightSpeed

DJIWaypointAction

Action 的执行时间最多只有 6 秒时间(除了 stay action,因为 stay 是用户主动表示要飞机停留的 action),如果一个 aciton 超过 6 秒没有执行完,这个 action 会被停止,无人机继续往下一个航点飞行。
Action 的类型有以下 6 种:
Waypoint Action.png
如果希望在两个航点间连续拍照,可以通过 waypoint 的 shootPhotoTimeInterval shootPhotoDistanceInterval 进行设置。shootPhotoTimeInterval 表示在航点间飞行时的拍照间隔时间,shootPhotoDistanceInterval 表示在航点间飞行时多远的距离拍一张照片。
如果有一组 action 是重复执行的,可以设置 waypoint 的 actionRepeatTimes 来实现。actionRepeatTimes 表示配置 action 的执行次数,默认是 1 次。
Action 的基本使用方式如下:

  1. let action = DJIWaypointAction(actionType: .rotateGimbalPitch, param: -30)
  2. waypoint.add(action)

Waypoint 可以添加 action,也有插入、删除等操作。

  1. - (BOOL)insertAction:(DJIWaypointAction *)action atIndex:(int)index;
  2. - (BOOL)removeAction:(DJIWaypointAction *)action;
  3. - (BOOL)removeActionAtIndex:(int)index;
  4. - (void)removeAllActions;

一个 waypoint 中 action 数量没有限制,但是对所有 action 执行总时长是有限制的。DJI 也提供了actionTimeoutInSeconds 属性来自定义 action 的执行总时长限制,取值范围是 0 - 999 秒,默认是 60 秒。

曲线飞行时的弧度:cornerRadiusInMeters

通常 waypoint 间的路径都是直线飞行,不过如果 pathMode 是 DJIWaypointMissionFlightPathCurved 时航点间就是以曲线飞行。在按照曲线飞行的模式下,不同航点间的弧度通过 cornerRadiusInMeters 属性调整。航点设置了航点圆角半径后,无人机就不会飞过航点的坐标,而是按照航点的设置的半径弧线飞行。

DJIWaypointMission

flightSpeed

前面提到的执行任务时的默认速度属性是 autoFlightSpeed。与之相关的还有 maxFlightSpeed。因为执行任务期间遥控器可以调整当前飞行速度。maxFlightSpeed 的值用来限制遥控器影响飞行速度时的最大偏移量。比如当前 autoFlightSpeed 是 5,maxFlightSpeed 的值是 10。这个时候遥控器提高飞行速度,那么速度到 10 m_s 后就不会再提高了。遥控器还可以降低飞机速度到负数,所以也同时限制了无人机往回飞的时候速度最快是 -10 m_s。往回飞如果到底第一个点飞机就会悬停。

finishedAction

FinishedAction 指的是无人机飞到最后一个航点后要进行什么操作。有五个 action 可供选择:

  • NoAction:什么都不做
  • GoHome:任务结束后返航
  • AutoLand:到达最后一个航点后自动降落
  • GoFirstWaypoint:回到第一个航点
  • ContinueUntilStop:任务的状态不会自动结束(可以继续手动控制无人机做一些操作),直到调用 stopMission 任务才会结束

    headingMode

    无人机在航点间飞行时的航向。有以下 5 种选择:

  • Auto:和无人机飞行方向一致

  • UsingInitialDirection:使用无人机到达第一个航点时的航向。在到达第一个航点前遥控器可以控制航向,到达第一个点后航向就固定不再改变。
  • ControlledByRemoteController:遥控器控制
  • UsingWaypointHeading:使用每个航点设置的航向
  • TowardPointOfInterest:总是朝向设置的兴趣点
    默认航向的策略是 auto。
    如果 headingMode 是 TowardPointOfInterest,当然需要设置一下兴趣点位置。兴趣点位置的属性是 pointOfInterest,示例代码如下:

    1. waypointMission.headingMode = .towardPointOfInterest
    2. waypointMission.pointOfInterest = CLLocationCoordinate2D(latitude: 30.27, longitude: 120.12)

    flightPathMode

    航点间的路径。默认是 normal ,使用直线飞行。如果希望按照曲线飞行,设置为 Curved,但是需要配合 waypoint 的 cornerRadiusInMeters

    gotoFirstWaypointMode

    无人机如何到达第一个航点。有两种方式:

  • PointToPoint:起飞后径直朝第一个航点以最短距离飞过去。

  • Safely:无人机先垂直上升到和第一个航点同样的高度后水平飞过去。
    假设起飞地点和第一个航点的路线中有一栋楼,如果采用 Safely 模式则可以避过这栋楼,所以安全一些。

    exitMissionOnRCSignalLost

    无人机丢失遥控器信号后是否停止任务。Waypoint 任务航点是一次性上传好的,如果刚好某个位置遥控器信号差,只要 GPS 信号正常无人机还是可以按照规划好的航点飞行。默认值是 false,如果遥控器信号丢失,无人机继续执行任务。
    如果在航点过程中需要手动控制航向,或者一些拍照动作,遥控器信号丢失肯定数据采集的就有问题了,这种场景下就会把 exitMissionOnRCSignalLost 设置成 true。

    rotateGimbalPitch

    布尔值,飞行过程中云台角度是否可以被设置。如果设置为 true,航点的 gimbalPitch 可以控制云台角度。

    repeatTimes

    任务结束后是否重复一次。默认值是 0,表示任务只执行一次。1 表示任务结束后再重复一次,那么就是总共执行两次任务。

    DJIMutableWaypointMission

    为了保证 mission 的一些参数飞行过程中不会被程序意外更改,一些属性在 DJIWaypointMission 上是只读的,任务中的航点也是不能被编辑的。DJI SDK 采用了和 OC 中字典相似的机制,在创建时使用一个可变的对象 DJIMutableWaypointMission,任务启动后再获取到的实例就是只读属性的 DJIWaypointMission 实例。
    1. let waypointMission = DJIMutableWaypointMission()
    2. // 添加一个航点
    3. waypointMission.add(waypoint)
    4. waypointMission.addWaypoints([waypoint,waypoint])
    5. waypointMission.finishedAction = .goHome
    6. let readOnlyWaypointMission = DJISDKManager.missionControl()?.waypointMissionOperator().loadedMission
    7. // 也可以调用 waypointMission 的 `mutableCopy` 获得一个可编辑的实例
    8. let mutableMission = readOnlyWaypointMission!.mutableCopy()

    航点间的距离限制

    Waypoint mission 中的 waypoint 距离是有限制的,两个 waypoint 间的距离要大于 0.5 米。如果两个航点距离过近在添加 waypoint 时是不会报错的,所以切记选定 waypoint 后注意要检查下两个点的距离。如果两个点的距离实在很近,可以保持航点坐标,高度提高 0.5 米。这样既可以保证两个点的距离不要太近,又不太影响任务的航点数据采集。

Creating a MapView and Waypoint Application