From cbf5045d84088891ef0696b189e1f8af6a653bad Mon Sep 17 00:00:00 2001
From: guoshilong <123456>
Date: Mon, 13 Nov 2023 10:09:32 +0800
Subject: [PATCH] 图斑距离计算,定时任务添加逻辑

---
 src/main/java/com/dji/sample/wayline/service/impl/WaylineJobServiceImpl.java |  389 ++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 351 insertions(+), 38 deletions(-)

diff --git a/src/main/java/com/dji/sample/wayline/service/impl/WaylineJobServiceImpl.java b/src/main/java/com/dji/sample/wayline/service/impl/WaylineJobServiceImpl.java
index c149023..0c72c27 100644
--- a/src/main/java/com/dji/sample/wayline/service/impl/WaylineJobServiceImpl.java
+++ b/src/main/java/com/dji/sample/wayline/service/impl/WaylineJobServiceImpl.java
@@ -1,7 +1,9 @@
 package com.dji.sample.wayline.service.impl;
 
+import com.alibaba.druid.stat.TableStat;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.dji.sample.common.error.CommonErrorEnum;
 import com.dji.sample.common.model.CustomClaim;
@@ -12,11 +14,17 @@
 import com.dji.sample.component.mqtt.service.IMessageSenderService;
 import com.dji.sample.component.redis.RedisConst;
 import com.dji.sample.component.redis.RedisOpsUtils;
+import com.dji.sample.control.model.dto.PointDTO;
 import com.dji.sample.control.model.param.DrcModeParam;
+import com.dji.sample.control.model.param.FlyToPointParam;
+import com.dji.sample.control.model.param.TakeoffToPointParam;
+import com.dji.sample.control.service.IControlService;
 import com.dji.sample.control.service.IDrcService;
 import com.dji.sample.manage.model.dto.DeviceDTO;
 import com.dji.sample.manage.model.enums.DeviceModeCodeEnum;
 import com.dji.sample.manage.model.enums.DockModeCodeEnum;
+import com.dji.sample.manage.model.enums.DroneRcLostActionEnum;
+import com.dji.sample.manage.model.enums.WaylineRcLostActionEnum;
 import com.dji.sample.manage.model.receiver.OsdDockReceiver;
 import com.dji.sample.manage.model.receiver.OsdSubDeviceReceiver;
 import com.dji.sample.manage.service.IDeviceRedisService;
@@ -24,13 +32,12 @@
 import com.dji.sample.media.model.MediaFileCountDTO;
 import com.dji.sample.media.model.MediaMethodEnum;
 import com.dji.sample.media.service.IFileService;
+import com.dji.sample.utils.GeoUtils;
 import com.dji.sample.wayline.dao.IWaylineJobMapper;
 import com.dji.sample.wayline.model.dto.*;
 import com.dji.sample.wayline.model.entity.WaylineJobEntity;
 import com.dji.sample.wayline.model.enums.*;
-import com.dji.sample.wayline.model.param.CreateJobParam;
-import com.dji.sample.wayline.model.param.UpdateJobParam;
-import com.dji.sample.wayline.model.param.WaylineJobQueryParam;
+import com.dji.sample.wayline.model.param.*;
 import com.dji.sample.wayline.service.IWaylineFileService;
 import com.dji.sample.wayline.service.IWaylineJobService;
 import com.dji.sample.wayline.service.IWaylineRedisService;
@@ -89,6 +96,9 @@
 
     @Autowired
     private IWaylineRedisService waylineRedisService;
+
+    @Autowired
+    private IControlService controlService;
 
     private Optional<WaylineJobDTO> insertWaylineJob(WaylineJobEntity jobEntity) {
         int id = mapper.insert(jobEntity);
@@ -238,42 +248,141 @@
 
         WaylineJobDTO waylineJob = waylineJobOpt.get();
 
-        //循环执行时间
-        for (List<Long> timeArr : param.getExecuteStartTimeArr()) {
-            LocalDate date = LocalDate.ofInstant(Instant.ofEpochSecond(timeArr.get(0)), ZoneId.systemDefault());
-            long beginTime = LocalDateTime.of(date, LocalTime.ofInstant(Instant.ofEpochSecond(timeArr.get(0)), ZoneId.systemDefault()))
-                    .atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
+        //存一条记录,
+        List<Long> timeArr = param.getExecuteStartTimeArr().get(0);
 
-            long endTime = timeArr.size() > 1 && Objects.nonNull(timeArr.get(1)) ?
-                    LocalDateTime.of(date, LocalTime.ofInstant(Instant.ofEpochSecond(timeArr.get(1)), ZoneId.systemDefault()))
-                            .atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() : beginTime;
+        LocalDate date = LocalDate.ofInstant(Instant.ofEpochSecond(timeArr.get(0)), ZoneId.systemDefault());
+        LocalDateTime beginTime = LocalDateTime.of(date, LocalTime.ofInstant(Instant.ofEpochSecond(timeArr.get(0)), ZoneId.systemDefault()));
 
-            if (WaylineTaskTypeEnum.IMMEDIATE != param.getTaskType() && endTime < System.currentTimeMillis()) {
-                //中断当前循环执行下一个
-                continue;
-            }
+        LocalDateTime endTime = timeArr.size() > 1 && Objects.nonNull(timeArr.get(1)) ?
+                LocalDateTime.of(date, LocalTime.ofInstant(Instant.ofEpochSecond(timeArr.get(1)), ZoneId.systemDefault())) : beginTime;
 
-
-            //条件任务
-            if (param.getTaskType() == WaylineTaskTypeEnum.CONDITION) {
-                //如果是条件任务类型,需要在任务参数中添加条件。
-                waylineJob.setConditions(
-                        WaylineTaskConditionDTO.builder()
-                                .executableConditions(Objects.nonNull(param.getMinStorageCapacity()) ? WaylineTaskExecutableConditionDTO.builder().storageCapacity(param.getMinStorageCapacity()).build() : null)
-                                .readyConditions(WaylineTaskReadyConditionDTO.builder()
-                                        .batteryCapacity(param.getMinBatteryCapacity())
-                                        .beginTime(beginTime)
-                                        .endTime(endTime)
-                                        .build())
-                                .build());
-            }
-
-            ResponseResult response = this.publishOneFlightTask(waylineJob);
-            if (ResponseResult.CODE_SUCCESS != response.getCode()) {
-                return response;
-            }
-
+        if (WaylineTaskTypeEnum.IMMEDIATE != param.getTaskType() && endTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() < System.currentTimeMillis()) {
+            return ResponseResult.error("任务已过期");
         }
+        //条件任务
+        if (param.getTaskType() == WaylineTaskTypeEnum.CONDITION) {
+            //如果是条件任务类型,需要在任务参数中添加条件。
+            waylineJob.setConditions(
+                    WaylineTaskConditionDTO.builder()
+                            .executableConditions(Objects.nonNull(param.getMinStorageCapacity()) ? WaylineTaskExecutableConditionDTO.builder().storageCapacity(param.getMinStorageCapacity()).build() : null)
+                            .readyConditions(WaylineTaskReadyConditionDTO.builder()
+                                    .batteryCapacity(param.getMinBatteryCapacity())
+                                    .beginTime(beginTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli())
+                                    .endTime(endTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli())
+                                    .build())
+                            .build());
+        } else {
+            waylineJob.setBeginTime(beginTime);
+        }
+
+        ResponseResult response = this.publishOneFlightTask(waylineJob);
+        if (ResponseResult.CODE_SUCCESS != response.getCode()) {
+            return response;
+        }
+
+
+        //新增多条数据
+        //开始日期
+//        String parentId = "";
+//        for (int i = 0; i < param.getExecuteStartTimeArr().size(); i++) {
+//            List<Long> timeArr = param.getExecuteStartTimeArr().get(i);
+//
+//            long beginTimeLong = 0L;
+//            long endTimeLong = 0L;
+//            LocalDateTime beginTime = null;
+//            if (i == 0) {
+//                //父,开始-结束为整个区间
+//                //开始日期
+//                LocalDate startDate = LocalDate.ofInstant(Instant.ofEpochSecond(param.getTaskDays().get(0)), ZoneId.systemDefault());
+//                beginTimeLong = LocalDateTime.of(startDate, LocalTime.ofInstant(Instant.ofEpochSecond(param.getExecuteStartTimeArr().get(0).get(0)), ZoneId.systemDefault()))
+//                        .atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
+//
+//                //结束日期
+//                LocalDate endDate = LocalDate.ofInstant(Instant.ofEpochSecond(param.getTaskDays().get(1)), ZoneId.systemDefault());
+//                endTimeLong = LocalDateTime.of(endDate, LocalTime.ofInstant(Instant.ofEpochSecond(param.getExecuteStartTimeArr().get(param.getExecuteStartTimeArr().size() - 1).get(0)), ZoneId.systemDefault()))
+//                        .atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
+//            } else {
+//                //子,开始-结束为当前区间
+//                //开始日期
+//                LocalDate date = LocalDate.ofInstant(Instant.ofEpochSecond(timeArr.get(0)), ZoneId.systemDefault());
+//                //任务执行开始时间
+//                beginTime = LocalDateTime.of(date, LocalTime.ofInstant(Instant.ofEpochSecond(timeArr.get(0)), ZoneId.systemDefault()));
+//                //任务结束时间
+//                LocalDateTime endTime = timeArr.size() > 1 && Objects.nonNull(timeArr.get(1)) ?
+//                        LocalDateTime.of(date, LocalTime.ofInstant(Instant.ofEpochSecond(timeArr.get(1)), ZoneId.systemDefault())) : beginTime;
+//
+//                beginTimeLong = beginTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
+//                endTimeLong = endTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
+//            }
+//
+//
+//            //保存数据
+//            WaylineJobEntity waylineJobEntity = WaylineJobEntity.builder()
+//                    .parentId(parentId.equals("") ? null : parentId)
+//                    .jobId(UUID.randomUUID().toString())
+//                    .name(param.getName())
+//                    .dockSn(param.getDockSn())
+//                    .fileId(param.getFileId())
+//                    .username(customClaim.getUsername())
+//                    .workspaceId(customClaim.getWorkspaceId())
+//
+//                    .beginTime(beginTimeLong)
+//                    .endTime(endTimeLong)
+//                    .status(WaylineJobStatusEnum.PENDING.getVal())
+//                    .taskType(param.getTaskType().getVal())
+//                    .waylineType(param.getWaylineType().getVal())
+//                    .outOfControlAction(param.getOutOfControlAction())
+//                    .batteryCapacity(param.getMinBatteryCapacity())
+//                    .rthAltitude(param.getRthAltitude())
+//                    .mediaCount(0)
+//                    .repFreVal(param.getRepFreVal())
+//                    .repFreType(param.getRepFreType())
+//                    .repRuleType(param.getRepRuleType())
+//                    .repRuleVal(param.getRepRuleVal())
+//                    .executeTimeArr(param.getTaskPeriods())
+//                    .executeStartTimeArr(param.getExecuteStartTimeArr())
+//                    .build();
+//
+//            Optional<WaylineJobDTO> waylineJobOpt = insertWaylineJob(waylineJobEntity);
+//
+//            if (waylineJobOpt.isEmpty()) {
+//                throw new SQLException("任务创建失败");
+//            }
+//
+//
+//            if (i == 0) {
+//                //把第一个当作父
+//                parentId = waylineJobEntity.getId().toString();
+//            }
+//            WaylineJobDTO waylineJob = waylineJobOpt.get();
+//
+//            //条件任务
+//            if (param.getTaskType() == WaylineTaskTypeEnum.CONDITION) {
+//                //如果是条件任务类型,需要在任务参数中添加条件。
+//                waylineJob.setConditions(
+//                        WaylineTaskConditionDTO.builder()
+//                                .executableConditions(Objects.nonNull(param.getMinStorageCapacity()) ? WaylineTaskExecutableConditionDTO.builder().storageCapacity(param.getMinStorageCapacity()).build() : null)
+//                                .readyConditions(WaylineTaskReadyConditionDTO.builder()
+//                                        .batteryCapacity(param.getMinBatteryCapacity())
+//                                        .beginTime(beginTimeLong)
+//                                        .endTime(endTimeLong)
+//                                        .build())
+//                                .build());
+//            } else {
+//                waylineJob.setBeginTime(beginTime);
+//            }
+//
+//            if (waylineJobOpt.isEmpty()) {
+//                throw new SQLException("任务创建失败");
+//            }
+//
+//            ResponseResult response = this.publishOneFlightTask(waylineJob);
+//            if (ResponseResult.CODE_SUCCESS != response.getCode()) {
+//                return response;
+//            }
+//        }
+
         return ResponseResult.success();
     }
 
@@ -481,7 +590,17 @@
     }
 
     @Override
-    public Boolean updateJob(WaylineJobDTO dto) {
+    public Boolean updateJob(WaylineJobDTO dto){
+
+        try {
+            if (dto.getStatus() == 3){
+                this.checkNextJob(dto);
+            }
+        }catch (SQLException e) {
+            throw new RuntimeException(e);
+        }
+
+
         return mapper.update(this.dto2Entity(dto),
                 new LambdaUpdateWrapper<WaylineJobEntity>()
                         .eq(WaylineJobEntity::getJobId, dto.getJobId())) > 0;
@@ -683,12 +802,206 @@
 //                .orderByDesc(WaylineJobEntity::getBeginTime)
 //        );
 
-        WaylineJobEntity waylineJobEntity = mapper.getLatest(workspaceId,waylineJobQueryParam);
+        WaylineJobEntity waylineJobEntity = mapper.getLatest(workspaceId, waylineJobQueryParam);
 
 
-       return waylineJobEntity;
+        return waylineJobEntity;
     }
 
+    @Override
+    public ResponseResult flyByArea(String sn, FlyAreaParam flyAreaParam) {
+
+        List<List<PointPOJO>> areaList = flyAreaParam.getAreaList();
+        PointPOJO dockPoint = flyAreaParam.getDockPoint();
+        Double radius = flyAreaParam.getRadius();
+
+        List<PointPOJO> centerPointList = new ArrayList<>();
+
+        //根据区域获取中心点
+        areaList.forEach(area -> {
+            PointPOJO centerPoint = GeoUtils.getCenterPoint(area);
+            centerPointList.add(centerPoint);
+        });
+
+        //巡逻目标集合
+        List<PointPOJO> targetList = new ArrayList<>();
+        //获取所有中心点之后,
+        centerPointList.forEach(centerPoint -> {
+            //判断各个中心点和机场点的距离
+            double distance = GeoUtils.distance(dockPoint.getLon(), dockPoint.getLat(), centerPoint.getLon(), centerPoint.getLat());
+
+            //当距离小于半径时,添加到目标集合中
+            if (distance <= radius) {
+                centerPoint.setDistance(distance);
+                targetList.add(centerPoint);
+            }
+        });
+
+        //按距离从近到远排序
+        targetList.sort(Comparator.comparing(PointPOJO::getDistance));
+
+        //后续为无人机操作逻辑
+        //先飞到空中
+        TakeoffToPointParam takeoffToPointParam = new TakeoffToPointParam();
+
+        takeoffToPointParam.setTargetLatitude(dockPoint.getLat());
+        takeoffToPointParam.setTargetLongitude(dockPoint.getLon());
+        //设置飞行高度
+        takeoffToPointParam.setTargetHeight(120.0);
+        //设置安全起飞高度
+        takeoffToPointParam.setSecurityTakeoffHeight(100.0);
+        //设置返航高度
+        takeoffToPointParam.setRthAltitude(100.0);
+        //设置失控操作
+        takeoffToPointParam.setRcLostAction(DroneRcLostActionEnum.RETURN_HOME);
+        //设置起飞速度
+        takeoffToPointParam.setMaxSpeed(10.0);
+        takeoffToPointParam.setExitWaylineWhenRcLost(WaylineRcLostActionEnum.EXECUTE_RC_LOST_ACTION);
+
+        //起飞
+        ResponseResult responseResult = controlService.takeoffToPoint(sn, takeoffToPointParam);
+
+        if (responseResult.getCode() != ResponseResult.CODE_SUCCESS) {
+            return responseResult;
+        }
+        //向目标点飞行
+
+        FlyToPointParam flyToPointParam = new FlyToPointParam();
+        flyToPointParam.setMaxSpeed(14);
+        List<PointDTO> pointDTOS = new ArrayList<>();
+        targetList.forEach(pointPOJO -> {
+            PointDTO pointDTO = new PointDTO();
+            pointDTO.setHeight(150.0);
+            pointDTO.setLongitude(pointPOJO.getLon());
+            pointDTO.setLatitude(pointPOJO.getLat());
+
+            pointDTOS.add(pointDTO);
+        });
+        flyToPointParam.setPoints(pointDTOS);
+        ResponseResult responseResult1 = controlService.flyToPoint(sn, flyToPointParam);
+
+        if (responseResult1.getCode() != ResponseResult.CODE_SUCCESS) {
+            return responseResult1;
+        }
+
+        //返航
+        //return_home
+
+
+        return ResponseResult.success();
+    }
+
+    @Override
+    public ResponseResult checkNextJob(WaylineJobDTO job)  throws SQLException  {
+
+        WaylineJobEntity params = new WaylineJobEntity();
+        params.setJobId(job.getJobId());
+
+
+        WaylineJobEntity currentJob = mapper.selectOne(Wrappers.query(params));
+        if (currentJob == null) {
+            return ResponseResult.error("该任务不存在");
+        }
+
+        //该任务没有多次时间
+        if (currentJob.getExecuteStartTimeArr() == null) {
+            return ResponseResult.success();
+        }
+
+        List<List<Long>> executeStartTimeArr = currentJob.getExecuteStartTimeArr();
+        int indexTime = -1;
+
+        long currentTime = System.currentTimeMillis();
+        for (int i = 0; i < executeStartTimeArr.size(); i++) {
+            Long startTime = Long.valueOf(executeStartTimeArr.get(i).get(0));
+            //如果当前时间小于开始时间
+            if (currentTime < startTime) {
+                //当前索引就是下一次要执行的时间
+                indexTime = i;
+                break;
+            }
+        }
+
+        List<Long> timeArr = currentJob.getExecuteStartTimeArr().get(indexTime);
+        LocalDate date = LocalDate.ofInstant(Instant.ofEpochSecond(timeArr.get(0)), ZoneId.systemDefault());
+        LocalDateTime beginDate = LocalDateTime.of(date, LocalTime.ofInstant(Instant.ofEpochSecond(timeArr.get(0)), ZoneId.systemDefault()));
+        LocalDateTime endDate = timeArr.size() > 1 && Objects.nonNull(timeArr.get(1)) ?
+                LocalDateTime.of(date, LocalTime.ofInstant(Instant.ofEpochSecond(timeArr.get(1)), ZoneId.systemDefault()))
+                : beginDate;
+
+        long beginTime = beginDate
+                .atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
+        long endTime = endDate
+                .atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
+
+
+        //添加一条新数据
+        WaylineJobEntity waylineJobEntity = WaylineJobEntity.builder()
+                .jobId(UUID.randomUUID().toString())
+                //大于1则拿前面的parentId,为1则拿第0个的id
+                .parentId(indexTime > 1 ? currentJob.getParentId().toString() : currentJob.getId().toString())
+                .name(currentJob.getName())
+                .dockSn(currentJob.getDockSn())
+                .fileId(currentJob.getFileId())
+                .username(currentJob.getUsername())
+                .workspaceId(currentJob.getWorkspaceId())
+
+                .beginTime(beginTime)
+                .endTime(endTime)
+                .status(WaylineJobStatusEnum.PENDING.getVal())
+                .taskType(currentJob.getTaskType())
+                .waylineType(currentJob.getWaylineType())
+                .outOfControlAction(currentJob.getOutOfControlAction())
+                .batteryCapacity(currentJob.getBatteryCapacity())
+                .rthAltitude(currentJob.getRthAltitude())
+                .mediaCount(0)
+                .repFreVal(currentJob.getRepFreVal())
+                .repFreType(currentJob.getRepFreType())
+                .repRuleType(currentJob.getRepRuleType())
+                .repRuleVal(currentJob.getRepRuleVal())
+                .executeTimeArr(currentJob.getExecuteTimeArr())
+                .executeStartTimeArr(currentJob.getExecuteStartTimeArr())
+                .build();
+
+        Optional<WaylineJobDTO> waylineJobOpt = insertWaylineJob(waylineJobEntity);
+
+        if (waylineJobOpt.isEmpty()) {
+            return ResponseResult.error("任务创建失败");
+        }
+
+        WaylineJobDTO waylineJob = waylineJobOpt.get();
+
+        LocalDateTime beginTimeNext = LocalDateTime.of(date, LocalTime.ofInstant(Instant.ofEpochSecond(timeArr.get(0)), ZoneId.systemDefault()));
+
+        LocalDateTime endTimeNext = timeArr.size() > 1 && Objects.nonNull(timeArr.get(1)) ?
+                LocalDateTime.of(date, LocalTime.ofInstant(Instant.ofEpochSecond(timeArr.get(1)), ZoneId.systemDefault())) : beginTimeNext;
+
+
+        //条件任务
+        if (currentJob.getTaskType() == 2) {
+            //如果是条件任务类型,需要在任务参数中添加条件。
+            waylineJob.setConditions(
+                    WaylineTaskConditionDTO.builder()
+                            .executableConditions(null)
+                            .readyConditions(WaylineTaskReadyConditionDTO.builder()
+                                    .batteryCapacity(currentJob.getBatteryCapacity())
+                                    .beginTime(beginTime)
+                                    .endTime(endTime)
+                                    .build())
+                            .build());
+        } else {
+            waylineJob.setBeginTime(beginDate);
+        }
+
+        ResponseResult response = this.publishOneFlightTask(waylineJob);
+        if (ResponseResult.CODE_SUCCESS != response.getCode()) {
+            return response;
+        }
+
+        return ResponseResult.success();
+    }
+
+
     private void pauseJob(String workspaceId, String dockSn, String jobId, WaylineJobStatusEnum statusEnum) {
         if (WaylineJobStatusEnum.PAUSED == statusEnum && jobId.equals(waylineRedisService.getPausedWaylineJobId(dockSn))) {
             waylineRedisService.setPausedWaylineJob(dockSn, jobId);

--
Gitblit v1.9.3