From 67108657901ce4925a27f88e4181c70f9a050c2b Mon Sep 17 00:00:00 2001
From: aix <vip_xiaobin810@163.com>
Date: Tue, 30 Jul 2024 11:58:52 +0800
Subject: [PATCH] 面状航线
---
src/main/java/com/dji/sample/patches/xml/mode/CameraActionEnum.java | 4
src/main/java/com/dji/sample/patches/xml/mode/XMLTemplateModel.java | 104 +++++++++++++++++++++++++
src/main/java/com/dji/sample/patches/xml/mode/share/action/param/StartTimeLapseParam.java | 17 ++++
src/main/java/com/dji/sample/patches/xml/mode/Folder.java | 3
src/main/java/com/dji/sample/patches/xml/mode/Placemark.java | 1
src/main/java/com/dji/sample/wayline/plane/param/CreateWaylineParam.java | 2
src/main/java/com/dji/sample/patches/xml/mode/share/action/param/ActionActuatorFuncParam.java | 2
src/main/resources/template/waylines-polygon.xml | 73 +++++++++++++++++
src/main/java/com/dji/sample/patches/xml/mode/share/action/utils/ActionUtils.java | 33 ++++++++
9 files changed, 234 insertions(+), 5 deletions(-)
diff --git a/src/main/java/com/dji/sample/patches/xml/mode/CameraActionEnum.java b/src/main/java/com/dji/sample/patches/xml/mode/CameraActionEnum.java
index 25f8c6a..bf27641 100644
--- a/src/main/java/com/dji/sample/patches/xml/mode/CameraActionEnum.java
+++ b/src/main/java/com/dji/sample/patches/xml/mode/CameraActionEnum.java
@@ -20,7 +20,9 @@
GIMBAL_EVENLY_ROTATE("gimbalEvenlyRotate"),//航段间均匀转动云台pitch角
ACCURATE_SHOOT("accurateShoot"),//精准复拍动作(已暂停维护,建议使用ORIENTED_SHOOT)
ORIENTED_SHOOT("orientedShoot"),//精准复拍动作
- PANO_SHOT("panoShot");//全景拍照动作(仅支持M30/M30T)
+ PANO_SHOT("panoShot"),//全景拍照动作(仅支持M30/M30T)
+
+ START_TIME_LAPSE("startTimeLapse");//面状航线需要使用的默认事件
private final String description;
diff --git a/src/main/java/com/dji/sample/patches/xml/mode/Folder.java b/src/main/java/com/dji/sample/patches/xml/mode/Folder.java
index 2fc9335..5ff1536 100644
--- a/src/main/java/com/dji/sample/patches/xml/mode/Folder.java
+++ b/src/main/java/com/dji/sample/patches/xml/mode/Folder.java
@@ -38,4 +38,7 @@
private PayloadParam payloadParam;
+ private String distance;//长度
+ private String duration;//时间
+
}
diff --git a/src/main/java/com/dji/sample/patches/xml/mode/Placemark.java b/src/main/java/com/dji/sample/patches/xml/mode/Placemark.java
index 186f25c..3a026cf 100644
--- a/src/main/java/com/dji/sample/patches/xml/mode/Placemark.java
+++ b/src/main/java/com/dji/sample/patches/xml/mode/Placemark.java
@@ -21,6 +21,7 @@
private String index;
private Double ellipsoidHeight;
private Double height;
+ private Double executeHeight;
private String waypointSpeed;
private WaypointHeadingParam waypointHeadingParam;
private WaypointTurnParam waypointTurnParam;
diff --git a/src/main/java/com/dji/sample/patches/xml/mode/XMLTemplateModel.java b/src/main/java/com/dji/sample/patches/xml/mode/XMLTemplateModel.java
index 9ef5203..e7993b1 100644
--- a/src/main/java/com/dji/sample/patches/xml/mode/XMLTemplateModel.java
+++ b/src/main/java/com/dji/sample/patches/xml/mode/XMLTemplateModel.java
@@ -1,6 +1,7 @@
package com.dji.sample.patches.xml.mode;
import com.dji.sample.patches.model.entity.LotInfo;
+import com.dji.sample.patches.utils.DistanceCalculator;
import com.dji.sample.patches.utils.GeoToolsUtil;
import com.dji.sample.patches.utils.PointPO;
import com.dji.sample.patches.xml.mode.share.*;
@@ -165,18 +166,118 @@
//航点
List<Coordinate> pointList = PlaneCourseUtils.createWaylinePoints(param);
List<Placemark> placemarkList = new ArrayList<>();
+ //计算距离
+ Coordinate droneC = param.getCoordinate();//机场经纬度
+ int pointListIndex = 0;
+ double distanceOne = 0.0; //第一个点到机场得距离
+ double distance = 0.0;
+ Coordinate pointTmp = null;
for (Coordinate c:pointList) {
+ //计算距离
+ if (pointListIndex == 0) {
+ distanceOne = DistanceCalculator.calculateDistance(droneC.y,droneC.x,c.y,c.x) * 1000;
+ distance += distanceOne;
+ pointTmp = c;
+ } else {
+ double distanceTmp = DistanceCalculator.calculateDistance(pointTmp.y,pointTmp.x,c.y,c.x) * 1000;
+ distance += distanceTmp;
+ pointTmp = c;
+ }
+ pointListIndex += 1;
+
Placemark placemark = new Placemark();
placemark.setCoordinates(c.x + "," + c.y);
placemark.setEllipsoidHeight(param.getHeight());
placemark.setHeight(param.getHeight());
+ placemark.setExecuteHeight(param.getHeight() + param.getDroneHeight()); //执行高度 = 机场高度 + 飞行高度
placemark.setWaypointSpeed(param.getAutoFlightSpeed() + "");
placemark.setUseStraightLine(1);
- //事件暂时不考虑添加
+
+ //
+ WaypointTurnParam waypointTurnParam = new WaypointTurnParam();
+ waypointTurnParam.setWaypointTurnMode("coordinateTurn");
+ waypointTurnParam.setWaypointTurnDampingDist("0.2");
+ //添加事件 第一个和结尾需要添加事件
+ if (pointListIndex == 1) { //第一个航点事件
+
+ waypointTurnParam.setWaypointTurnMode("toPointAndStopWithDiscontinuityCurvature");
+ waypointTurnParam.setWaypointTurnDampingDist("0");
+
+ // 增加事件组
+ ActionGroup actionGroup = new ActionGroup();
+ actionGroup.setActionGroupId(0);
+ actionGroup.setActionGroupStartIndex(pointListIndex - 1);//动作组开始生效的航点
+ actionGroup.setActionGroupEndIndex(pointList.size() - 1);//动作组结束生效的航点
+ actionGroup.setActionGroupMode("sequence");
+ ActionTrigger at = new ActionTrigger();
+ at.setActionTriggerType("betweenAdjacentPoints");
+ actionGroup.setActionTrigger(at);
+ // 开始增加事件
+ List<ActionMode> list = new ArrayList<>();
+ ActionMode actionMode = new ActionMode();
+
+ actionMode.setActionId(0);
+ actionMode.setActionActuatorFunc("gimbalAngleLock");
+
+ ActionMode actionMode2 = new ActionMode();
+ actionMode2.setActionId(1);
+ actionMode2.setActionActuatorFunc(CameraActionEnum.GIMBAL_ROTATE.getDescription());//旋转云台
+ actionMode2.setActionActuatorFuncParam(ActionUtils.setGimbalRotateByPlane());
+
+ ActionMode actionMode3 = new ActionMode();
+ actionMode3.setActionId(2);
+ actionMode3.setActionActuatorFunc("startTimeLapse");
+ actionMode3.setActionActuatorFuncParam(ActionUtils.setStartTimeLapseByPlane());
+
+ list.add(actionMode);
+ list.add(actionMode2);
+ list.add(actionMode3);
+ actionGroup.setActions(list);
+
+ placemark.setActionGroup(actionGroup);
+
+ } else if(pointListIndex == pointList.size()) { // 结尾需要添加事件
+
+ waypointTurnParam.setWaypointTurnMode("toPointAndStopWithDiscontinuityCurvature");
+ waypointTurnParam.setWaypointTurnDampingDist("0");
+
+ // 增加事件组
+ ActionGroup actionGroup = new ActionGroup();
+ actionGroup.setActionGroupId(1);
+ actionGroup.setActionGroupStartIndex(pointListIndex - 1);//动作组开始生效的航点
+ actionGroup.setActionGroupEndIndex(pointList.size()-1);//动作组结束生效的航点
+ actionGroup.setActionGroupMode("sequence");
+ ActionTrigger at = new ActionTrigger();
+ at.setActionTriggerType("reachPoint");
+ actionGroup.setActionTrigger(at);
+ // 开始增加事件
+ List<ActionMode> list = new ArrayList<>();
+
+ ActionMode actionMode = new ActionMode();
+ actionMode.setActionId(0);
+ actionMode.setActionActuatorFunc("stopTimeLapse");
+ actionMode.setActionActuatorFuncParam(ActionUtils.setStopTimeLapseByPlane());
+
+ ActionMode actionMode2 = new ActionMode();
+ actionMode2.setActionId(1);
+ actionMode2.setActionActuatorFunc("gimbalAngleUnlock");
+
+ list.add(actionMode);
+ list.add(actionMode2);
+ actionGroup.setActions(list);
+
+ placemark.setActionGroup(actionGroup);
+ }
+
+ placemark.setWaypointTurnParam(waypointTurnParam);
placemarkList.add(placemark);
}
+
+ //距离和时间
+ folder.setDistance((distance - distanceOne) + "");
+ folder.setDuration((distance / param.getAutoFlightSpeed()) + "");//时间 = 长度 / 速度
folder.setPlacemarkList(placemarkList);
@@ -205,6 +306,7 @@
param.setSideRatio(0.8);
param.setFocal(10*6.9999943);
param.setFrame(100);
+ param.setDroneHeight(14.731968792284789);
List<double[]> polygon = new ArrayList<>();
double[] a = {116.028037250229,25.8948290570725};
double[] a2 = {116.031565260299,25.8950672687002};
diff --git a/src/main/java/com/dji/sample/patches/xml/mode/share/action/param/ActionActuatorFuncParam.java b/src/main/java/com/dji/sample/patches/xml/mode/share/action/param/ActionActuatorFuncParam.java
index 9db3c15..06b06dc 100644
--- a/src/main/java/com/dji/sample/patches/xml/mode/share/action/param/ActionActuatorFuncParam.java
+++ b/src/main/java/com/dji/sample/patches/xml/mode/share/action/param/ActionActuatorFuncParam.java
@@ -47,6 +47,8 @@
return new OrientedShootParam();
case PANO_SHOT:
return new PanoShotParam();
+ case START_TIME_LAPSE:
+ return new StartTimeLapseParam();
default:
throw new IllegalStateException("Unexpected value: " + type);
}
diff --git a/src/main/java/com/dji/sample/patches/xml/mode/share/action/param/StartTimeLapseParam.java b/src/main/java/com/dji/sample/patches/xml/mode/share/action/param/StartTimeLapseParam.java
new file mode 100644
index 0000000..fcc4c8a
--- /dev/null
+++ b/src/main/java/com/dji/sample/patches/xml/mode/share/action/param/StartTimeLapseParam.java
@@ -0,0 +1,17 @@
+package com.dji.sample.patches.xml.mode.share.action.param;
+
+import lombok.Data;
+
+/**
+ * @Author AIX
+ * @Date 2024/7/30 10:33
+ * @Version 1.0
+ */
+@Data
+public class StartTimeLapseParam extends ActionActuatorFuncParam{
+
+ private String useGlobalPayloadLensIndex;
+ private String payloadLensIndex;
+ private String minShootInterval;
+
+}
diff --git a/src/main/java/com/dji/sample/patches/xml/mode/share/action/utils/ActionUtils.java b/src/main/java/com/dji/sample/patches/xml/mode/share/action/utils/ActionUtils.java
index 21676fb..d45ffaa 100644
--- a/src/main/java/com/dji/sample/patches/xml/mode/share/action/utils/ActionUtils.java
+++ b/src/main/java/com/dji/sample/patches/xml/mode/share/action/utils/ActionUtils.java
@@ -73,4 +73,37 @@
return rotateYawParam;
}
+ /**
+ * 面状航线旋转云台
+ * @return
+ */
+ public static GimbalRotateParam setGimbalRotateByPlane() {
+ GimbalRotateParam gimbalRotateParam = new GimbalRotateParam();
+ gimbalRotateParam.setGimbalHeadingYawBase("aircraft");
+ gimbalRotateParam.setGimbalRotateMode("absoluteAngle");
+ gimbalRotateParam.setGimbalPitchRotateEnable(1);
+ gimbalRotateParam.setGimbalPitchRotateAngle(-90D);
+ gimbalRotateParam.setGimbalRollRotateEnable(0);
+ gimbalRotateParam.setGimbalRollRotateAngle(0D);
+ gimbalRotateParam.setGimbalYawRotateEnable(0);
+ gimbalRotateParam.setGimbalYawRotateAngle(0D);
+ gimbalRotateParam.setGimbalRotateTimeEnable(10);
+ gimbalRotateParam.setGimbalRotateTime(0D);
+ return gimbalRotateParam;
+ }
+
+ public static StartTimeLapseParam setStartTimeLapseByPlane() {
+ StartTimeLapseParam startTimeLapseParam = new StartTimeLapseParam();
+ startTimeLapseParam.setUseGlobalPayloadLensIndex("0");
+ startTimeLapseParam.setPayloadLensIndex("visable");
+ startTimeLapseParam.setMinShootInterval("5.27466630935669");
+ return startTimeLapseParam;
+ }
+
+ public static StartTimeLapseParam setStopTimeLapseByPlane() {
+ StartTimeLapseParam startTimeLapseParam = new StartTimeLapseParam();
+ startTimeLapseParam.setPayloadLensIndex("visable");
+ return startTimeLapseParam;
+ }
+
}
diff --git a/src/main/java/com/dji/sample/wayline/plane/param/CreateWaylineParam.java b/src/main/java/com/dji/sample/wayline/plane/param/CreateWaylineParam.java
index a5bb6b5..46c1623 100644
--- a/src/main/java/com/dji/sample/wayline/plane/param/CreateWaylineParam.java
+++ b/src/main/java/com/dji/sample/wayline/plane/param/CreateWaylineParam.java
@@ -20,6 +20,8 @@
private List<double[]> polygon;//面
@NotNull(message = "高度不能为空")
private double height;//高度
+ @NotNull(message = "机场高度不能为空")
+ private double droneHeight;//机场高度
@NotNull(message = "画幅不能为空")
private double frame;//画幅
@NotNull(message = "焦距不能为空")
diff --git a/src/main/resources/template/waylines-polygon.xml b/src/main/resources/template/waylines-polygon.xml
index 6003c64..2815952 100644
--- a/src/main/resources/template/waylines-polygon.xml
+++ b/src/main/resources/template/waylines-polygon.xml
@@ -23,6 +23,8 @@
<wpml:templateId>${folder.templateId!''}</wpml:templateId>
<wpml:executeHeightMode>${folder.executeHeightMode!''}</wpml:executeHeightMode>
<wpml:waylineId>0</wpml:waylineId>
+ <wpml:distance>${folder.distance!''}</wpml:distance>
+ <wpml:duration>${folder.duration!''}</wpml:duration>
<wpml:autoFlightSpeed>${folder.autoFlightSpeed!''}</wpml:autoFlightSpeed>
<wpml:startActionGroup>
<wpml:action>
@@ -89,7 +91,7 @@
</Point>
<wpml:index>${placemarkIndex!''}</wpml:index>
<#assign placemarkIndex = placemarkIndex + 1>
- <wpml:executeHeight>${placemark.height!''}</wpml:executeHeight>
+ <wpml:executeHeight>${placemark.executeHeight!''}</wpml:executeHeight>
<wpml:waypointSpeed>${placemark.waypointSpeed!''}</wpml:waypointSpeed>
<wpml:waypointHeadingParam>
<wpml:waypointHeadingMode>${folder.globalWaypointHeadingParam.waypointHeadingMode!''}</wpml:waypointHeadingMode>
@@ -100,10 +102,75 @@
<wpml:waypointHeadingPoiIndex>${folder.globalWaypointHeadingParam.waypointHeadingPoiIndex!''}</wpml:waypointHeadingPoiIndex>
</wpml:waypointHeadingParam>
<wpml:waypointTurnParam>
- <wpml:waypointTurnMode>${folder.globalWaypointTurnMode!''}</wpml:waypointTurnMode>
- <wpml:waypointTurnDampingDist>0.2</wpml:waypointTurnDampingDist>
+ <wpml:waypointTurnMode>${placemark.waypointTurnParam.waypointTurnMode!''}</wpml:waypointTurnMode>
+ <wpml:waypointTurnDampingDist>${placemark.waypointTurnParam.waypointTurnDampingDist!''}</wpml:waypointTurnDampingDist>
</wpml:waypointTurnParam>
<wpml:useStraightLine>${folder.globalUseStraightLine!''}</wpml:useStraightLine>
+ <#if placemark.actionGroup??>
+ <wpml:actionGroup>
+ <wpml:actionGroupId>${placemark.actionGroup.actionGroupId!''}</wpml:actionGroupId>
+ <wpml:actionGroupStartIndex>${placemark.actionGroup.actionGroupStartIndex!''}</wpml:actionGroupStartIndex>
+ <wpml:actionGroupEndIndex>${placemark.actionGroup.actionGroupEndIndex!''}</wpml:actionGroupEndIndex>
+ <wpml:actionGroupMode>${placemark.actionGroup.actionGroupMode!''}</wpml:actionGroupMode>
+ <wpml:actionTrigger>
+ <wpml:actionTriggerType>${placemark.actionGroup.actionTrigger.actionTriggerType!''}</wpml:actionTriggerType>
+ </wpml:actionTrigger>
+ <#if placemark.actionGroup.actions??>
+ <#assign idx = 0>
+ <#list placemark.actionGroup.actions as action>
+ <wpml:action>
+ <wpml:actionId>${idx!''}</wpml:actionId>
+ <wpml:actionActuatorFunc>${action.actionActuatorFunc!''}</wpml:actionActuatorFunc>
+ <#if action.actionActuatorFuncParam??>
+ <wpml:actionActuatorFuncParam>
+ <wpml:payloadPositionIndex>0</wpml:payloadPositionIndex>
+ <#if action.actionActuatorFuncParam.gimbalHeadingYawBase??>
+ <wpml:gimbalHeadingYawBase>${action.actionActuatorFuncParam.gimbalHeadingYawBase!''}</wpml:gimbalHeadingYawBase>
+ </#if>
+ <#if action.actionActuatorFuncParam.gimbalRotateMode??>
+ <wpml:gimbalRotateMode>${action.actionActuatorFuncParam.gimbalRotateMode!''}</wpml:gimbalRotateMode>
+ </#if>
+ <#if action.actionActuatorFuncParam.gimbalPitchRotateEnable??>
+ <wpml:gimbalPitchRotateEnable>${action.actionActuatorFuncParam.gimbalPitchRotateEnable!''}</wpml:gimbalPitchRotateEnable>
+ </#if>
+ <#if action.actionActuatorFuncParam.gimbalPitchRotateAngle??>
+ <wpml:gimbalPitchRotateAngle>${action.actionActuatorFuncParam.gimbalPitchRotateAngle!''}</wpml:gimbalPitchRotateAngle>
+ </#if>
+ <#if action.actionActuatorFuncParam.gimbalRollRotateEnable??>
+ <wpml:gimbalRollRotateEnable>${action.actionActuatorFuncParam.gimbalRollRotateEnable!''}</wpml:gimbalRollRotateEnable>
+ </#if>
+ <#if action.actionActuatorFuncParam.gimbalRollRotateAngle??>
+ <wpml:gimbalRollRotateAngle>${action.actionActuatorFuncParam.gimbalRollRotateAngle!''}</wpml:gimbalRollRotateAngle>
+ </#if>
+ <#if action.actionActuatorFuncParam.gimbalYawRotateEnable??>
+ <wpml:gimbalYawRotateEnable>${action.actionActuatorFuncParam.gimbalYawRotateEnable!''}</wpml:gimbalYawRotateEnable>
+ </#if>
+ <#if action.actionActuatorFuncParam.gimbalYawRotateAngle??>
+ <wpml:gimbalYawRotateAngle>${action.actionActuatorFuncParam.gimbalYawRotateAngle!''}</wpml:gimbalYawRotateAngle>
+ </#if>
+ <#if action.actionActuatorFuncParam.gimbalRotateTimeEnable??>
+ <wpml:gimbalRotateTimeEnable>${action.actionActuatorFuncParam.gimbalRotateTimeEnable!''}</wpml:gimbalRotateTimeEnable>
+ </#if>
+ <#if action.actionActuatorFuncParam.gimbalRotateTime??>
+ <wpml:gimbalRotateTime>${action.actionActuatorFuncParam.gimbalRotateTime!''}</wpml:gimbalRotateTime>
+ </#if>
+ <#if action.actionActuatorFuncParam.useGlobalPayloadLensIndex??>
+ <wpml:useGlobalPayloadLensIndex>${action.actionActuatorFuncParam.useGlobalPayloadLensIndex!''}</wpml:useGlobalPayloadLensIndex>
+ </#if>
+ <#if action.actionActuatorFuncParam.payloadLensIndex??>
+ <wpml:payloadLensIndex>${action.actionActuatorFuncParam.payloadLensIndex!''}</wpml:payloadLensIndex>
+ </#if>
+ <#if action.actionActuatorFuncParam.minShootInterval??>
+ <wpml:minShootInterval>${action.actionActuatorFuncParam.minShootInterval!''}</wpml:minShootInterval>
+ </#if>
+ </wpml:actionActuatorFuncParam>
+ </#if>
+ </wpml:action>
+ <#assign idx = idx + 1>
+ </#list>
+ </#if>
+ </wpml:actionGroup>
+ </#if>
<wpml:waypointGimbalHeadingParam>
<wpml:waypointGimbalPitchAngle>0</wpml:waypointGimbalPitchAngle>
<wpml:waypointGimbalYawAngle>0</wpml:waypointGimbalYawAngle>
--
Gitblit v1.9.3