大疆无人机安卓Mobile Sdk开发(二)连接无人机,获取无人机信息
大疆无人机安卓Mobile Sdk开发(三)制定航点任务WaypointMission
大疆无人机安卓Mobile Sdk开发(四)读取飞机的图片和视频并下载
大疆无人机安卓Mobile Sdk开发(五)解决M300Rtk H20相机无法获取图片视频的问题
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());
}
});
}
以上是一个航点任务定义和执行的流程,有不懂的欢迎交流。