大疆无人机安卓Mobile Sdk开发(三)制定航点任务WaypointMission

大疆无人机安卓Mobile Sdk开发(一)简单介绍

大疆无人机安卓Mobile Sdk开发(二)连接无人机,获取无人机信息

大疆无人机安卓Mobile Sdk开发(三)制定航点任务WaypointMission

qq505057618

        mobile sdk提供了很多种任务类型,有WaypointMission,FollowMeMission,PanoramaMission,HotPointMission,TapFlyMission等,其中最主要也是最常用的就是WaypointMission,我们可以提前根据坐标规划好航点,每个航点除了坐标外还可以设置高度、航向、自定义动作等,飞机会按照制定的航点按顺序去执行任务,目前消费级无人机最多支持99个航点设置。

dji.common.mission.waypoint.WaypointMission.Builder builder = new dji.common.mission.waypoint.WaypointMission.Builder();
        builder.autoFlightSpeed(rawMission.getFlySpeed());
        builder.finishedAction(toDJI(rawMission.getFinishedAction()));
        builder.flightPathMode(WaypointMissionFlightPathMode.NORMAL);
        builder.gotoFirstWaypointMode(WaypointMissionGotoWaypointMode.SAFELY);
        builder.headingMode(toDJI(rawMission.getHeadingMode()));
        builder.maxFlightSpeed(15);
        builder.setExitMissionOnRCSignalLostEnabled(rawMission.exitMissionOnRCSignalLost);
        builder.setGimbalPitchRotationEnabled(true);
        builder.repeatTimes(1);

这是初始化一个WaypointMission,下面解释每个方法的含义

autoFlightSpeed

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

maxFlightSpeed

前面提到的执行任务时的默认速度属性是 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。

flightPathMode

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

曲线飞行时的弧度:cornerRadiusInMeters

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

gotoFirstWaypointMode

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

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

exitMissionOnRCSignalLost

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

rotateGimbalPitch

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

repeatTimes

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

waypointList

传入一组wayPoint的list,就是传入一组航点,然后任务按照航点顺序去执行,一个wayPoint代表一个航点。

下面我们看如何添加WayPoint

List<Waypoint> resultList = new ArrayList<>(rawList.size());
        for (int i = index; i < rawList.size(); i++) {
            DIYWaypoint item = rawList.get(i);
            Waypoint waypoint = new Waypoint(item.getLatLng().getLat(), item.getLatLng().getLng(), item.getAltitude());
            waypoint.gimbalPitch = item.getGimbalPitch();
            waypoint.heading = item.getHeading();
            waypoint.turnMode = toDJI(item.getTurnMode());
            waypoint.altitude = item.getAltitude();
            List<DIYWaypoint.DIYWaypointAction> rawActionList = item.getWaypointActions();
            if (rawActionList != null && rawActionList.size() > 0) {
                for (DIYWaypoint.DIYWaypointAction action : rawActionList) {
                    waypoint.addAction(new WaypointAction(toDJI(action.getmActionType()), action.getmActionParam()));
                }
            }
            resultList.add(waypoint);
        }
        builder.waypointList(resultList);
        builder.waypointCount(resultList.size());

 这里我的代码是是用我自定义的类转换成大疆的WayPoint,大家可以参考官方的文档,这里wayPoint可以设置很多参数,比如设置云台的角俯仰角,飞机的航向角,飞机的高度,最主要的是到了航点飞机要执行的动作WaypointAction

Action 的执行时间最多只有 6 秒时间(除了 stay action,因为 stay 是用户主动表示要飞机停留的 action),如果一个 aciton 超过 6 秒没有执行完,这个 action 会被停止,无人机继续往下一个航点飞行。

一个 waypoint 中 action 数量没有限制,但是对所有 action 执行总时长是有限制的。DJI 也提供了actionTimeoutInSeconds 属性来自定义 action 的执行总时长限制,取值范围是 0 - 999 秒,默认是 60 秒。如果有一组 action 是重复执行的,可以设置 waypoint 的 actionRepeatTimes 来实现。actionRepeatTimes 表示配置 action 的执行次数,默认是 1 次。

任务的上传,开始和监听

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

当WaypintMission定义完成之后,我们可以调用operator.uploadMission()去上传任务,同时我们可以监听任务的上传进度

 private void uploadMission(WaypointMission mission) {
        DJIError checkError = mission.checkParameters();
        if (checkError != null) {
            passResult(MISSION_UPLOAD, VALUE_FAILED, checkError.getDescription());
        } else {
            DJIError loadError = operator.loadMission(mission);
            if (loadError != null) {
                passResult(MISSION_UPLOAD, VALUE_FAILED, loadError.getDescription());
            } else {
                operator.uploadMission(djiError -> {
                    if (djiError != null) {
                        passResult(MISSION_UPLOAD, VALUE_FAILED, djiError.getDescription());
                    } else {
                        passResult(MISSION_UPLOAD, VALUE_STARTED, "");
                    }
                });
            }
        }
    }

当任务上传完成之后,我们可以调用operator.startMission()去执行任务,在任务执行的过程中我们可以通过WaypointMissionOperatorListener监听任务执行的进度,同时我们也可以通过operator.startMission()去暂定任务的执行,通过operator.resumeMission会继续执行任务。

 @Override
    public void startMission() {
        operator.startMission(djiError -> {
            if (djiError == null) {
                passResult(MISSION_START, VALUE_SUCCEED, "");
            } else {
                passResult(MISSION_START, VALUE_FAILED, djiError.getDescription());
            }
        });
    }

    @Override
    public void pauseMission() {
        operator.pauseMission(djiError -> {
            if (djiError == null) {
                passResult(MISSION_PAUSE, VALUE_SUCCEED, "");
            } else {
                passResult(MISSION_PAUSE, VALUE_FAILED, djiError.getDescription());
            }
        });
    }

 @Override
    public void resumeMission() {
        operator.resumeMission(djiError -> {
            if (djiError == null) {
                passResult(MISSION_RESUME, VALUE_SUCCEED, "");
            } else {
                passResult(MISSION_RESUME, VALUE_FAILED, djiError.getDescription());
            }
        });
    }

以上是一个航点任务定义和执行的流程,有不懂的欢迎交流。

发布了24 篇原创文章 · 获赞 5 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_26923265/article/details/104946124