| | |
| | | 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.component.mqtt.model.*; |
| | |
| | | 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.FlyToStatusEnum; |
| | | import com.dji.sample.control.model.enums.RemoteDebugMethodEnum; |
| | | import com.dji.sample.control.model.param.*; |
| | | import com.dji.sample.control.service.IControlService; |
| | |
| | | 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; |
| | |
| | | import org.springframework.messaging.MessageHeaders; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.util.Objects; |
| | | import java.util.Optional; |
| | | import java.util.UUID; |
| | | import java.util.*; |
| | | |
| | | /** |
| | | * @author sean |
| | |
| | | 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()); |
| | |
| | | "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); |
| | | } |
| | | return ResponseResult.success(); |
| | |
| | | |
| | | /** |
| | | * Handles multi-state command progress information. |
| | | * |
| | | * @param receiver |
| | | * @param headers |
| | | * @return |
| | |
| | | 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); |
| | | |
| | |
| | | Optional<DeviceDTO> deviceOpt = deviceRedisService.getDeviceOnline(sn); |
| | | |
| | | if (deviceOpt.isEmpty()) { |
| | | throw new RuntimeException("The device is offline."); |
| | | throw new RuntimeException("设备离线."); |
| | | } |
| | | |
| | | DeviceDTO device = deviceOpt.get(); |
| | |
| | | // 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); |
| | |
| | | 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(); |
| | | } |
| | | |
| | |
| | | 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(); |
| | | 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) |
| | |
| | | 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"); |
| | | flyToNextPoint(targetList, curIndex, dockSn); |
| | | } |
| | | } |
| | | return receiver; |
| | | } |
| | | |
| | | private ResponseResult flyToNextPoint(List<PointPOJO> targetList, int curIndex, String sn) { |
| | | curIndex = curIndex + 1; |
| | | //当无人机状态为人工时再发布下一个命令 |
| | | while (true) { |
| | | Optional<DeviceDTO> dockOpt = deviceRedisService.getDeviceOnline(sn); |
| | | DeviceModeCodeEnum deviceMode = deviceService.getDeviceMode(dockOpt.get().getChildDeviceSn()); |
| | | |
| | | if (DeviceModeCodeEnum.MANUAL == deviceMode) { |
| | | 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); |
| | | RedisOpsUtils.set("tuban:" + sn, jsonObject); |
| | | } |
| | | return flyToRes; |
| | | |
| | | |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | 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); |
| | |
| | | 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(), |
| | |
| | | } |
| | | 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); |
| | | } |
| | |
| | | |
| | | 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 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(); |
| | | } |
| | | |