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