From 589ff1b4b598f2f763eb421da960d5550e719144 Mon Sep 17 00:00:00 2001
From: rain <167982779@qq.com>
Date: Fri, 16 Aug 2024 16:38:51 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/ht-dev' into ht-dev

---
 src/main/java/com/dji/sample/control/service/impl/ControlServiceImpl.java |  204 +++++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 174 insertions(+), 30 deletions(-)

diff --git a/src/main/java/com/dji/sample/control/service/impl/ControlServiceImpl.java b/src/main/java/com/dji/sample/control/service/impl/ControlServiceImpl.java
index d9d43a7..322dc99 100644
--- a/src/main/java/com/dji/sample/control/service/impl/ControlServiceImpl.java
+++ b/src/main/java/com/dji/sample/control/service/impl/ControlServiceImpl.java
@@ -1,7 +1,9 @@
 package com.dji.sample.control.service.impl;
 
+import com.alibaba.fastjson.JSONObject;
 import com.dji.sample.common.error.CommonErrorEnum;
 import com.dji.sample.common.model.ResponseResult;
+import com.dji.sample.common.util.SpringBeanUtils;
 import com.dji.sample.component.mqtt.model.*;
 import com.dji.sample.component.mqtt.service.IMessageSenderService;
 import com.dji.sample.component.redis.RedisConst;
@@ -9,11 +11,10 @@
 import com.dji.sample.component.websocket.model.BizCodeEnum;
 import com.dji.sample.component.websocket.service.ISendMessageService;
 import com.dji.sample.control.model.dto.FlyToProgressReceiver;
+import com.dji.sample.control.model.dto.PointDTO;
 import com.dji.sample.control.model.dto.ResultNotifyDTO;
 import com.dji.sample.control.model.dto.TakeoffProgressReceiver;
-import com.dji.sample.control.model.enums.DroneAuthorityEnum;
-import com.dji.sample.control.model.enums.DroneControlMethodEnum;
-import com.dji.sample.control.model.enums.RemoteDebugMethodEnum;
+import com.dji.sample.control.model.enums.*;
 import com.dji.sample.control.model.param.*;
 import com.dji.sample.control.service.IControlService;
 import com.dji.sample.manage.model.dto.DeviceDTO;
@@ -24,6 +25,7 @@
 import com.dji.sample.manage.service.IDeviceRedisService;
 import com.dji.sample.manage.service.IDeviceService;
 import com.dji.sample.wayline.model.enums.WaylineErrorCodeEnum;
+import com.dji.sample.wayline.model.param.PointPOJO;
 import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import lombok.extern.slf4j.Slf4j;
@@ -31,10 +33,9 @@
 import org.springframework.integration.annotation.ServiceActivator;
 import org.springframework.messaging.MessageHeaders;
 import org.springframework.stereotype.Service;
+import org.springframework.util.StringUtils;
 
-import java.util.Objects;
-import java.util.Optional;
-import java.util.UUID;
+import java.util.*;
 
 /**
  * @author sean
@@ -68,7 +69,7 @@
                 mapper.convertValue(Objects.nonNull(param) ? param : new Object(), controlMethodEnum.getClazz())
                 : new RemoteDebugHandler();
         if (!handler.canPublish(sn)) {
-            throw new RuntimeException("The current state of the dock does not support this function.");
+            throw new RuntimeException("当前的机场状态不支持此功能。");
         }
         if (Objects.nonNull(param) && !handler.valid()) {
             throw new RuntimeException(CommonErrorEnum.ILLEGAL_ARGUMENT.getErrorMsg());
@@ -80,14 +81,14 @@
     public ResponseResult controlDockDebug(String sn, String serviceIdentifier, RemoteDebugParam param) {
         RemoteDebugMethodEnum controlMethodEnum = RemoteDebugMethodEnum.find(serviceIdentifier);
         if (RemoteDebugMethodEnum.UNKNOWN == controlMethodEnum) {
-            return ResponseResult.error("The " + serviceIdentifier + " method does not exist.");
+            return ResponseResult.error(" 没有找到" + serviceIdentifier + " 这个指令。");
         }
 
         RemoteDebugHandler data = checkDebugCondition(sn, param, controlMethodEnum);
 
         boolean isExist = deviceRedisService.checkDeviceOnline(sn);
         if (!isExist) {
-            return ResponseResult.error("The dock is offline.");
+            return ResponseResult.error("设备离线");
         }
         String bid = UUID.randomUUID().toString();
         ServiceReply serviceReply = messageSenderService.publishServicesTopic(sn, serviceIdentifier, data, bid);
@@ -97,14 +98,25 @@
                     "error: " + serviceIdentifier + serviceReply.getResult());
         }
         if (controlMethodEnum.getProgress()) {
-            RedisOpsUtils.setWithExpire(serviceIdentifier + RedisConst.DELIMITER +  bid, sn,
+            RedisOpsUtils.setWithExpire(serviceIdentifier + RedisConst.DELIMITER + bid, sn,
                     RedisConst.DEVICE_ALIVE_SECOND * RedisConst.DEVICE_ALIVE_SECOND);
         }
+
+        //当执行返航指令时,删除图斑redis
+        if (serviceIdentifier == "return_home"){
+            if (RedisOpsUtils.checkExist("tuban:" + sn)){
+                RedisOpsUtils.del("tuban:" + sn);
+            }
+        }
+
+
+
         return ResponseResult.success();
     }
 
     /**
      * Handles multi-state command progress information.
+     *
      * @param receiver
      * @param headers
      * @return
@@ -118,7 +130,8 @@
         String sn = RedisOpsUtils.get(key).toString();
 
         EventsReceiver<EventsOutputProgressReceiver> eventsReceiver = mapper.convertValue(receiver.getData(),
-                new TypeReference<EventsReceiver<EventsOutputProgressReceiver>>(){});
+                new TypeReference<EventsReceiver<EventsOutputProgressReceiver>>() {
+                });
         eventsReceiver.setBid(receiver.getBid());
         eventsReceiver.setSn(sn);
 
@@ -137,7 +150,7 @@
         Optional<DeviceDTO> deviceOpt = deviceRedisService.getDeviceOnline(sn);
 
         if (deviceOpt.isEmpty()) {
-            throw new RuntimeException("The device is offline.");
+            throw new RuntimeException("设备离线.");
         }
 
         DeviceDTO device = deviceOpt.get();
@@ -151,12 +164,12 @@
         // TODO 设备固件版本不兼容情况
         Optional<DeviceDTO> dockOpt = deviceRedisService.getDeviceOnline(dockSn);
         if (dockOpt.isEmpty()) {
-            throw new RuntimeException("The dock is offline, please restart the dock.");
+            throw new RuntimeException("机场离线请重启机场");
         }
 
         DeviceModeCodeEnum deviceMode = deviceService.getDeviceMode(dockOpt.get().getChildDeviceSn());
         if (DeviceModeCodeEnum.MANUAL != deviceMode) {
-            throw new RuntimeException("The current state of the drone does not support this function, please try again later.");
+            throw new RuntimeException("无人机当前状态不支持此功能,请稍后再试");
         }
 
         ResponseResult result = seizeAuthority(dockSn, DroneAuthorityEnum.FLIGHT, null);
@@ -172,7 +185,7 @@
         param.setFlyToId(UUID.randomUUID().toString());
         ServiceReply reply = messageSenderService.publishServicesTopic(sn, DroneControlMethodEnum.FLY_TO_POINT.getMethod(), param, param.getFlyToId());
         return ResponseResult.CODE_SUCCESS != reply.getResult() ?
-                ResponseResult.error("Flying to the target point failed." + reply.getResult())
+                ResponseResult.error("飞向目标点失败。" + reply.getResult())
                 : ResponseResult.success();
     }
 
@@ -180,21 +193,22 @@
     public ResponseResult flyToPointStop(String sn) {
         ServiceReply reply = messageSenderService.publishServicesTopic(sn, DroneControlMethodEnum.FLY_TO_POINT_STOP.getMethod(), null);
         return ResponseResult.CODE_SUCCESS != reply.getResult() ?
-                ResponseResult.error("The drone flying to the target point failed to stop. " + reply.getResult())
+                ResponseResult.error("飞向目标点的无人机停止失败" + reply.getResult())
                 : ResponseResult.success();
     }
 
     @ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_FLY_TO_POINT_PROGRESS, outputChannel = ChannelName.OUTBOUND_EVENTS)
-    public CommonTopicReceiver handleFlyToPointProgress(CommonTopicReceiver receiver, MessageHeaders headers) {
-        String dockSn  = receiver.getGateway();
+    public CommonTopicReceiver handleFlyToPointProgress(CommonTopicReceiver receiver, MessageHeaders headers) throws Exception {
+        String dockSn = receiver.getGateway();
 
         Optional<DeviceDTO> deviceOpt = deviceRedisService.getDeviceOnline(dockSn);
         if (deviceOpt.isEmpty()) {
-            log.error("The dock is offline.");
+            log.error("机场离线");
             return null;
         }
 
-        FlyToProgressReceiver eventsReceiver = mapper.convertValue(receiver.getData(), new TypeReference<FlyToProgressReceiver>(){});
+        FlyToProgressReceiver eventsReceiver = mapper.convertValue(receiver.getData(), new TypeReference<FlyToProgressReceiver>() {
+        });
         webSocketMessageService.sendBatch(deviceOpt.get().getWorkspaceId(), UserTypeEnum.WEB.getVal(),
                 BizCodeEnum.FLY_TO_POINT_PROGRESS.getCode(),
                 ResultNotifyDTO.builder().sn(dockSn)
@@ -202,13 +216,115 @@
                                 eventsReceiver.getStatus().getMessage() : eventsReceiver.getResult().getErrorMsg())
                         .result(eventsReceiver.getResult().getErrorCode())
                         .build());
+        //当飞向目标点成功后
+        if (eventsReceiver.getStatus().equals(FlyToStatusEnum.WAYLINE_OK)) {
+            JSONObject jsonObject = (JSONObject) RedisOpsUtils.get("tuban:" + dockSn);
+            if (jsonObject != null) {
+                List<PointPOJO> targetList = (List<PointPOJO>) jsonObject.get("targetList");
+                int curIndex = (Integer) jsonObject.get("curIndex");
+                String payloadIndex = jsonObject.getString("payloadIndex");
+                flyToNextPoint(targetList, curIndex+1, dockSn, payloadIndex);
+            }
+        }
         return receiver;
     }
+
+    @Override
+    public ResponseResult flyToNextPoint(List<PointPOJO> targetList, int curIndex, String sn, String payloadIndex) throws Exception {
+        //当无人机状态为人工时再发布下一个命令
+        while (true) {
+            Optional<DeviceDTO> dockOpt = deviceRedisService.getDeviceOnline(sn);
+            DeviceModeCodeEnum deviceMode = deviceService.getDeviceMode(dockOpt.get().getChildDeviceSn());
+
+            if (DeviceModeCodeEnum.MANUAL == deviceMode) {
+
+                //执行拍照
+                ResponseResult responseResult = takePhoto(sn, payloadIndex);
+
+                //发布飞行指令
+                if (curIndex == targetList.size()) {
+                    //当前是最后一个点,返航
+                    ResponseResult returnHome = controlDockDebug(sn, "return_home", null);
+
+                    RedisOpsUtils.del("tuban:" + sn);
+
+                    return returnHome;
+                } else {
+                    //当前不是最后一个点,飞行到下一个点
+                    FlyToPointParam flyToPointParam = new FlyToPointParam();
+                    flyToPointParam.setMaxSpeed(14);
+                    List<PointDTO> pointDTOS = new ArrayList<>();
+
+                    PointDTO pointDTO = new PointDTO();
+                    pointDTO.setHeight(150.0);
+                    pointDTO.setLongitude(targetList.get(curIndex).getLon());
+                    pointDTO.setLatitude(targetList.get(curIndex).getLat());
+                    pointDTOS.add(pointDTO);
+                    flyToPointParam.setPoints(pointDTOS);
+
+                    //发布下一个飞行指令
+                    ResponseResult flyToRes = flyToPoint(sn, flyToPointParam);
+                    if (flyToRes.getCode() == ResponseResult.CODE_SUCCESS) {
+                        JSONObject jsonObject = new JSONObject();
+                        jsonObject.put("targetList", targetList);
+                        jsonObject.put("curIndex", curIndex);
+                        jsonObject.put("payloadIndex",payloadIndex);
+                        RedisOpsUtils.set("tuban:" + sn, jsonObject);
+                    }
+                    return flyToRes;
+
+                }
+            }
+        }
+    }
+
+    @Override
+    public ResponseResult takePhoto(String sn, String payloadIndex) throws Exception {
+
+        //获取负载控制权
+        DronePayloadParam dronePayloadParam = new DronePayloadParam();
+        dronePayloadParam.setPayloadIndex(payloadIndex);
+
+        ResponseResult seizeAuthorityRes = seizeAuthority(sn, DroneAuthorityEnum.PAYLOAD, dronePayloadParam);
+
+        //切换为相机模式
+        if (seizeAuthorityRes.getCode() != ResponseResult.CODE_SUCCESS) {
+            return seizeAuthorityRes;
+        }
+
+        PayloadCommandsParam payloadCommandsParam = new PayloadCommandsParam();
+
+//            DronePayloadParam switchParam = new DronePayloadParam();
+//            switchParam.setCameraMode(CameraModeEnum.PHOTO);
+//            switchParam.setPayloadIndex(payloadIndex);
+
+//            payloadCommandsParam.setSn(sn);
+//            payloadCommandsParam.setCmd(PayloadCommandsEnum.CAMERA_MODE_SWitCH);
+//            payloadCommandsParam.setData(switchParam);
+//
+//            ResponseResult switchModeRes = payloadCommands(payloadCommandsParam);
+
+//            if (switchModeRes.getCode() != ResponseResult.CODE_SUCCESS){
+//                return  switchModeRes;
+//            }
+        //拍照
+        payloadCommandsParam.setCmd(PayloadCommandsEnum.CAMERA_PHOTO_TAKE);
+        DronePayloadParam takePhotoParam = new DronePayloadParam();
+        takePhotoParam.setPayloadIndex(payloadIndex);
+
+        payloadCommandsParam.setData(takePhotoParam);
+        payloadCommandsParam.setSn(sn);
+
+        ResponseResult responseResult = payloadCommands(payloadCommandsParam);
+
+        return responseResult;
+    }
+
 
     private void checkTakeoffCondition(String dockSn) {
         Optional<DeviceDTO> dockOpt = deviceRedisService.getDeviceOnline(dockSn);
         if (dockOpt.isEmpty() || DockModeCodeEnum.IDLE != deviceService.getDockMode(dockSn)) {
-            throw new RuntimeException("The current state does not support takeoff.");
+            throw new RuntimeException("当前状态不支持起飞");
         }
 
         ResponseResult result = seizeAuthority(dockSn, DroneAuthorityEnum.FLIGHT, null);
@@ -221,24 +337,26 @@
     @Override
     public ResponseResult takeoffToPoint(String sn, TakeoffToPointParam param) {
         checkTakeoffCondition(sn);
-
-        param.setFlightId(UUID.randomUUID().toString());
+        if (!StringUtils.hasText(param.getFlightId())){
+            param.setFlightId(UUID.randomUUID().toString());
+        }
         ServiceReply reply = messageSenderService.publishServicesTopic(sn, DroneControlMethodEnum.TAKE_OFF_TO_POINT.getMethod(), param, param.getFlightId());
         return ResponseResult.CODE_SUCCESS != reply.getResult() ?
-                ResponseResult.error("The drone failed to take off. " + reply.getResult())
+                ResponseResult.error("无人机起飞失败 " + reply.getResult())
                 : ResponseResult.success();
     }
 
     @ServiceActivator(inputChannel = ChannelName.INBOUND_EVENTS_TAKE_OFF_TO_POINT_PROGRESS, outputChannel = ChannelName.OUTBOUND_EVENTS)
     public CommonTopicReceiver handleTakeoffToPointProgress(CommonTopicReceiver receiver, MessageHeaders headers) {
-        String dockSn  = receiver.getGateway();
+        String dockSn = receiver.getGateway();
 
         Optional<DeviceDTO> deviceOpt = deviceRedisService.getDeviceOnline(dockSn);
         if (deviceOpt.isEmpty()) {
-            log.error("The dock is offline.");
+            log.error("机场离线");
             return null;
         }
-        TakeoffProgressReceiver eventsReceiver = mapper.convertValue(receiver.getData(), new TypeReference<TakeoffProgressReceiver>(){});
+        TakeoffProgressReceiver eventsReceiver = mapper.convertValue(receiver.getData(), new TypeReference<TakeoffProgressReceiver>() {
+        });
 
         webSocketMessageService.sendBatch(deviceOpt.get().getWorkspaceId(), UserTypeEnum.WEB.getVal(),
                 BizCodeEnum.TAKE_OFF_TO_POINT_PROGRESS.getCode(),
@@ -272,14 +390,14 @@
         }
         ServiceReply serviceReply = messageSenderService.publishServicesTopic(sn, method, param);
         return ResponseResult.CODE_SUCCESS != serviceReply.getResult() ?
-                ResponseResult.error(serviceReply.getResult(), "Method: " + method + " Error Code:" + serviceReply.getResult())
+                ResponseResult.error(serviceReply.getResult(), "方法: " + method + " 错误码:" + serviceReply.getResult())
                 : ResponseResult.success();
     }
 
     private Boolean checkPayloadAuthority(String sn, String payloadIndex) {
         Optional<DeviceDTO> dockOpt = deviceRedisService.getDeviceOnline(sn);
         if (dockOpt.isEmpty()) {
-            throw new RuntimeException("The dock is offline, please restart the dock.");
+            throw new RuntimeException("机场离线请重启机场");
         }
         return devicePayloadService.checkAuthorityPayload(dockOpt.get().getChildDeviceSn(), payloadIndex);
     }
@@ -294,7 +412,33 @@
 
         ServiceReply serviceReply = messageSenderService.publishServicesTopic(param.getSn(), param.getCmd().getCmd(), param.getData());
         return ResponseResult.CODE_SUCCESS != serviceReply.getResult() ?
-                ResponseResult.error(serviceReply.getResult(), " Error Code:" + serviceReply.getResult())
+                ResponseResult.error(serviceReply.getResult(), "错误码:" + serviceReply.getResult())
+                : ResponseResult.success();
+    }
+
+    @Override
+    public ResponseResult payloadCommands(PayloadCommandsParam param, String bid) throws Exception {
+        param.getCmd().getClazz()
+                .getDeclaredConstructor(DronePayloadParam.class)
+                .newInstance(param.getData())
+                .checkCondition(param.getSn());
+
+        Long timestamp = System.currentTimeMillis();
+
+        //拍照事件存redis
+        RedisOpsUtils.hashSet(RedisConst.COMMANDS_PREFIX + param.getSn() + RedisConst.DELIMITER + bid,bid,timestamp);
+
+        ServiceReply serviceReply = messageSenderService.publishServicesTopic(param.getSn(), param.getCmd().getCmd(), param.getData(),bid,timestamp);
+        return ResponseResult.CODE_SUCCESS != serviceReply.getResult() ?
+                ResponseResult.error(serviceReply.getResult(), "错误码:" + serviceReply.getResult())
+                : ResponseResult.success(bid);
+    }
+
+    @Override
+    public ResponseResult requestsConfig(String sn, String method, RequestsParam param) {
+        ServiceReply serviceReply = messageSenderService.publishRequestsTopic(sn, method, param);
+        return ResponseResult.CODE_SUCCESS != serviceReply.getResult() ?
+                ResponseResult.error(serviceReply.getResult(), "错误码:" + serviceReply.getResult())
                 : ResponseResult.success();
     }
 

--
Gitblit v1.9.3