2026-02-04 09:54:59 +08:00
|
|
|
|
package com.ruoyi.device.controller;
|
|
|
|
|
|
|
2026-03-14 11:22:11 +08:00
|
|
|
|
import com.alibaba.fastjson.JSON;
|
2026-02-04 09:54:59 +08:00
|
|
|
|
import com.ruoyi.common.core.domain.R;
|
2026-03-19 08:35:39 +08:00
|
|
|
|
import com.ruoyi.common.core.utils.StringUtils;
|
2026-02-04 09:54:59 +08:00
|
|
|
|
import com.ruoyi.common.core.web.controller.BaseController;
|
2026-02-27 14:15:31 +08:00
|
|
|
|
import com.ruoyi.device.api.domain.*;
|
2026-02-04 09:54:59 +08:00
|
|
|
|
import com.ruoyi.device.api.enums.DroneCurrentStatusEnum;
|
|
|
|
|
|
import com.ruoyi.device.api.enums.DroneMissionStatusEnum;
|
2026-02-10 15:07:15 +08:00
|
|
|
|
import com.ruoyi.device.domain.impl.machine.MachineCommandManager;
|
|
|
|
|
|
import com.ruoyi.device.domain.impl.machine.command.CommandResult;
|
|
|
|
|
|
import com.ruoyi.device.domain.impl.machine.command.CommandType;
|
2026-03-10 10:47:15 +08:00
|
|
|
|
import com.ruoyi.device.domain.impl.machine.state.MachineStates;
|
|
|
|
|
|
import com.ruoyi.device.service.FlightService;
|
2026-03-10 14:56:42 +08:00
|
|
|
|
import com.ruoyi.task.api.enums.StatusEnum;
|
2026-02-04 09:54:59 +08:00
|
|
|
|
import io.swagger.v3.oas.annotations.Operation;
|
|
|
|
|
|
import io.swagger.v3.oas.annotations.Parameter;
|
|
|
|
|
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
2026-02-10 15:07:15 +08:00
|
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
2026-02-04 09:54:59 +08:00
|
|
|
|
import org.springframework.web.bind.annotation.*;
|
|
|
|
|
|
|
2026-02-27 14:15:31 +08:00
|
|
|
|
import java.util.Objects;
|
|
|
|
|
|
import java.util.UUID;
|
2026-02-10 15:07:15 +08:00
|
|
|
|
import java.util.concurrent.CompletableFuture;
|
|
|
|
|
|
|
2026-02-04 09:54:59 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 无人机飞控Controller
|
|
|
|
|
|
*
|
|
|
|
|
|
* @author ruoyi
|
|
|
|
|
|
* @date 2026-02-04
|
|
|
|
|
|
*/
|
2026-02-10 15:07:15 +08:00
|
|
|
|
@Slf4j
|
2026-02-04 09:54:59 +08:00
|
|
|
|
@Tag(name = "无人机飞控管理", description = "无人机飞控相关接口")
|
|
|
|
|
|
@RestController
|
|
|
|
|
|
@RequestMapping("/drone")
|
|
|
|
|
|
public class AircraftFlyController extends BaseController
|
|
|
|
|
|
{
|
2026-02-10 15:07:15 +08:00
|
|
|
|
@Autowired
|
|
|
|
|
|
private MachineCommandManager machineCommandManager;
|
2026-02-10 15:29:53 +08:00
|
|
|
|
|
|
|
|
|
|
@Autowired
|
|
|
|
|
|
private com.ruoyi.device.domain.impl.machine.statemachine.MachineStateManager machineStateManager;
|
2026-02-24 11:08:58 +08:00
|
|
|
|
|
|
|
|
|
|
@Autowired
|
2026-03-10 10:47:15 +08:00
|
|
|
|
private FlightService flightService;
|
|
|
|
|
|
|
2026-02-04 09:54:59 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 无人机飞控命令
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param request 飞控命令请求
|
|
|
|
|
|
* @return 结果
|
|
|
|
|
|
*/
|
2026-02-28 15:38:16 +08:00
|
|
|
|
@Operation(summary = "无人机飞控命令", description = "发送飞控指令")
|
2026-02-04 09:54:59 +08:00
|
|
|
|
@PostMapping("/flight-control")
|
|
|
|
|
|
public R<Void> flightControl(@RequestBody DroneFlightControlRequest request)
|
|
|
|
|
|
{
|
2026-02-24 11:08:58 +08:00
|
|
|
|
if (request.getCommand() == null || request.getSn() == null) {
|
|
|
|
|
|
return R.fail("飞控命令和机场SN号不能为空");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
String sn = request.getSn();
|
|
|
|
|
|
log.info("收到飞控命令: sn={}, command={}", sn, request.getCommand());
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
CommandType commandType;
|
2026-02-28 14:53:07 +08:00
|
|
|
|
java.util.Map<String, Object> params = new java.util.HashMap<>();
|
|
|
|
|
|
|
|
|
|
|
|
// 处理消息ID
|
|
|
|
|
|
if (request.getMessageID() != null) {
|
|
|
|
|
|
params.put("messageID", request.getMessageID());
|
|
|
|
|
|
} else {
|
|
|
|
|
|
params.put("messageID", System.currentTimeMillis());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 处理扩展参数
|
|
|
|
|
|
if (request.getEvalue() != null) {
|
|
|
|
|
|
params.put("evalue", request.getEvalue());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (request.getValue() != null) {
|
|
|
|
|
|
params.put("value", request.getValue());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (request.getLightMode() != null) {
|
|
|
|
|
|
params.put("lightMode", request.getLightMode());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-04 15:04:21 +08:00
|
|
|
|
// 处理航线飞行、悬停、继续任务所需的参数
|
|
|
|
|
|
if (request.getAirlineFileUrl() != null) {
|
|
|
|
|
|
params.put("airlineFileUrl", request.getAirlineFileUrl());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (request.getFlyBatteryMin() != null) {
|
|
|
|
|
|
params.put("flyBatteryMin", request.getFlyBatteryMin());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (request.getIsMustFly() != null) {
|
|
|
|
|
|
params.put("isMustFly", request.getIsMustFly());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (request.getTaskId() != null) {
|
|
|
|
|
|
params.put("taskId", request.getTaskId());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (request.getZhilin() != null) {
|
|
|
|
|
|
params.put("zhilin", request.getZhilin());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-24 11:08:58 +08:00
|
|
|
|
switch (request.getCommand()) {
|
|
|
|
|
|
case FORWARD:
|
|
|
|
|
|
commandType = CommandType.FORWARD;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case BACKWARD:
|
|
|
|
|
|
commandType = CommandType.BACKWARD;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case LEFT:
|
|
|
|
|
|
commandType = CommandType.LEFT;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case RIGHT:
|
|
|
|
|
|
commandType = CommandType.RIGHT;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case ROTATE_LEFT:
|
|
|
|
|
|
commandType = CommandType.ROTATE_LEFT;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case ROTATE_RIGHT:
|
|
|
|
|
|
commandType = CommandType.ROTATE_RIGHT;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case UP:
|
|
|
|
|
|
commandType = CommandType.UP;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case DOWN:
|
|
|
|
|
|
commandType = CommandType.DOWN;
|
|
|
|
|
|
break;
|
2026-02-28 14:53:07 +08:00
|
|
|
|
case SWITCH_VISIBLE_LIGHT:
|
|
|
|
|
|
commandType = CommandType.SWITCH_VISIBLE_LIGHT;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case GIMBAL_ZOOM:
|
|
|
|
|
|
commandType = CommandType.GIMBAL_ZOOM;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case SWITCH_IR:
|
|
|
|
|
|
commandType = CommandType.SWITCH_IR;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case SWITCH_WIDE_ANGLE:
|
|
|
|
|
|
commandType = CommandType.SWITCH_WIDE_ANGLE;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case GIMBAL_MOVE_RIGHT:
|
|
|
|
|
|
commandType = CommandType.GIMBAL_MOVE_RIGHT;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case GIMBAL_MOVE_LEFT:
|
|
|
|
|
|
commandType = CommandType.GIMBAL_MOVE_LEFT;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case GIMBAL_PITCH_UP:
|
|
|
|
|
|
commandType = CommandType.GIMBAL_PITCH_UP;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case GIMBAL_PITCH_DOWN:
|
|
|
|
|
|
commandType = CommandType.GIMBAL_PITCH_DOWN;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case GIMBAL_RESET:
|
|
|
|
|
|
commandType = CommandType.GIMBAL_RESET;
|
|
|
|
|
|
break;
|
2026-03-04 15:04:21 +08:00
|
|
|
|
case AIRLINE_FLIGHT:
|
|
|
|
|
|
commandType = CommandType.AIRLINE_FLIGHT;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case HOVER:
|
|
|
|
|
|
commandType = CommandType.HOVER;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case CONTINUE_TASK:
|
|
|
|
|
|
commandType = CommandType.CONTINUE_TASK;
|
|
|
|
|
|
break;
|
2026-02-24 11:08:58 +08:00
|
|
|
|
case EMERGENCY_STOP:
|
|
|
|
|
|
return R.fail("急停命令暂不支持");
|
|
|
|
|
|
default:
|
|
|
|
|
|
return R.fail("不支持的飞控命令");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-28 14:53:07 +08:00
|
|
|
|
CompletableFuture<CommandResult> future = machineCommandManager.executeCommand(sn, commandType, params);
|
2026-02-24 11:08:58 +08:00
|
|
|
|
CommandResult result = future.get();
|
|
|
|
|
|
|
|
|
|
|
|
if (result.isSuccess()) {
|
|
|
|
|
|
log.info("飞控命令执行成功: sn={}, command={}", sn, request.getCommand());
|
|
|
|
|
|
return R.ok();
|
|
|
|
|
|
} else {
|
|
|
|
|
|
log.error("飞控命令执行失败: sn={}, command={}, reason={}", sn, request.getCommand(), result.getErrorMessage());
|
|
|
|
|
|
return R.fail("飞控命令执行失败: " + result.getErrorMessage());
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
|
log.error("飞控命令执行异常: sn={}, command={}", sn, request.getCommand(), e);
|
|
|
|
|
|
return R.fail("飞控命令执行异常: " + e.getMessage());
|
|
|
|
|
|
}
|
2026-02-04 09:54:59 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 无人机实时信息展示
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param taskId 任务ID
|
|
|
|
|
|
* @return 实时信息
|
|
|
|
|
|
*/
|
|
|
|
|
|
@Operation(summary = "无人机实时信息展示", description = "根据任务ID获取无人机的实时飞行信息,包括速度、高度、姿态角等")
|
|
|
|
|
|
@GetMapping("/realtime-info/{taskId}")
|
|
|
|
|
|
public R<DroneRealtimeInfoVO> getRealtimeInfo(
|
|
|
|
|
|
@Parameter(description = "任务ID", required = true, example = "1")
|
|
|
|
|
|
@PathVariable("taskId") Long taskId)
|
|
|
|
|
|
{
|
|
|
|
|
|
// TODO: 实现获取实时信息逻辑
|
|
|
|
|
|
DroneRealtimeInfoVO vo = new DroneRealtimeInfoVO();
|
|
|
|
|
|
vo.setClimbSpeed(0);
|
|
|
|
|
|
vo.setCruiseSpeed(0);
|
|
|
|
|
|
vo.setDistanceToAirport(0);
|
|
|
|
|
|
vo.setAltitude(0);
|
|
|
|
|
|
vo.setPitch(0);
|
|
|
|
|
|
vo.setYaw(0);
|
|
|
|
|
|
vo.setGimbalPitch(0);
|
|
|
|
|
|
vo.setGimbalYaw(0);
|
|
|
|
|
|
vo.setMissionStatus(DroneMissionStatusEnum.IDLE);
|
|
|
|
|
|
return R.ok(vo);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 无人机当前状态查询
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param dockId 机场ID
|
|
|
|
|
|
* @return 当前状态
|
|
|
|
|
|
*/
|
|
|
|
|
|
@Operation(summary = "无人机当前状态查询", description = "根据机场ID查询无人机的当前飞行状态")
|
|
|
|
|
|
@GetMapping("/current-status/{dockId}")
|
|
|
|
|
|
public R<DroneCurrentStatusVO> getCurrentStatus(
|
|
|
|
|
|
@Parameter(description = "机场ID", required = true, example = "1")
|
|
|
|
|
|
@PathVariable("dockId") Long dockId)
|
|
|
|
|
|
{
|
|
|
|
|
|
// TODO: 实现查询当前状态逻辑
|
|
|
|
|
|
DroneCurrentStatusVO vo = new DroneCurrentStatusVO();
|
|
|
|
|
|
vo.setDockId(dockId);
|
|
|
|
|
|
vo.setCurrentStatus(DroneCurrentStatusEnum.HOVERING);
|
|
|
|
|
|
return R.ok(vo);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-10 10:47:15 +08:00
|
|
|
|
//从配置文件获取
|
2026-03-10 14:56:42 +08:00
|
|
|
|
private final static String airlineFileUrl = "https://minio-dx.t-aaron.com:2443/th-airport/testFile/191ec54c-062c-4828-aab6-cefc901add78.waypoints";
|
2026-03-10 10:47:15 +08:00
|
|
|
|
|
2026-02-04 09:54:59 +08:00
|
|
|
|
/**
|
2026-02-27 14:15:31 +08:00
|
|
|
|
* 无人机一键起飞
|
2026-02-04 09:54:59 +08:00
|
|
|
|
*
|
2026-02-27 14:15:31 +08:00
|
|
|
|
* @param request 起飞请求对象
|
2026-02-24 10:35:02 +08:00
|
|
|
|
* @return 起飞响应
|
2026-02-04 09:54:59 +08:00
|
|
|
|
*/
|
2026-03-19 08:35:39 +08:00
|
|
|
|
@Operation(summary = "无人机航线任务(一键起飞用的也是该接口)", description = "控制指定机场的无人机执行起飞操作")
|
2026-02-27 14:15:31 +08:00
|
|
|
|
@PostMapping("/takeoff")
|
|
|
|
|
|
public R<String> takeoff(@RequestBody DroneTakeoffRequest request)
|
2026-02-04 09:54:59 +08:00
|
|
|
|
{
|
2026-03-10 10:47:15 +08:00
|
|
|
|
|
2026-03-14 11:04:00 +08:00
|
|
|
|
// Long taskId = flightService.createClickTakeOffTask(request.getSn(),airlineFileUrl);
|
2026-03-19 08:35:39 +08:00
|
|
|
|
log.info("无人机航线任务(一键起飞用的也是该接口) {} ", JSON.toJSONString(request));
|
2026-03-19 09:49:40 +08:00
|
|
|
|
|
2026-03-19 15:06:57 +08:00
|
|
|
|
// if(true){
|
|
|
|
|
|
// return R.ok("无人机起飞命令发送失败: ");
|
|
|
|
|
|
// }
|
2026-03-19 09:49:40 +08:00
|
|
|
|
|
2026-02-24 10:35:02 +08:00
|
|
|
|
try {
|
2026-02-27 14:15:31 +08:00
|
|
|
|
java.util.Map<String, Object> params = new java.util.HashMap<>();
|
2026-03-19 08:35:39 +08:00
|
|
|
|
if(StringUtils.isEmpty(request.getAirlineFileUrl())){
|
|
|
|
|
|
params.put("airlineFileUrl", airlineFileUrl);
|
|
|
|
|
|
}else {
|
|
|
|
|
|
params.put("airlineFileUrl", request.getAirlineFileUrl());
|
|
|
|
|
|
}
|
2026-03-19 15:06:57 +08:00
|
|
|
|
if(Objects.nonNull(request.getFlyBatteryMin())){
|
|
|
|
|
|
params.put("flyBatteryMin", request.getFlyBatteryMin());
|
|
|
|
|
|
}else {
|
|
|
|
|
|
params.put("flyBatteryMin", 0.3);
|
|
|
|
|
|
}
|
2026-03-14 11:04:00 +08:00
|
|
|
|
params.put("messageID", request.getTaskId());
|
2026-02-27 14:15:31 +08:00
|
|
|
|
CompletableFuture<CommandResult> future = machineCommandManager.executeCommand(request.getSn(), CommandType.TAKE_OFF, params);
|
2026-02-24 10:35:02 +08:00
|
|
|
|
CommandResult result = future.get();
|
|
|
|
|
|
|
|
|
|
|
|
if (result.isSuccess()) {
|
2026-03-14 11:22:11 +08:00
|
|
|
|
log.info("无人机起飞命令发送成功: sn={}", request.getSn());
|
2026-03-14 11:04:00 +08:00
|
|
|
|
flightService.updateFlightStatus(request.getTaskId(), StatusEnum.CHECKING);
|
2026-03-14 11:22:11 +08:00
|
|
|
|
return R.ok("无人机起飞命令发送成功");
|
2026-02-24 10:35:02 +08:00
|
|
|
|
} else {
|
2026-03-14 11:22:11 +08:00
|
|
|
|
log.error("无人机起飞命令发送失败: sn={}, reason={}", request.getSn(), result.getErrorMessage());
|
2026-03-14 11:04:00 +08:00
|
|
|
|
flightService.updateFlightStatus(request.getTaskId(), StatusEnum.FAILED);
|
2026-03-14 11:22:11 +08:00
|
|
|
|
return R.fail("无人机起飞命令发送失败: " + result.getErrorMessage());
|
2026-02-24 10:35:02 +08:00
|
|
|
|
}
|
|
|
|
|
|
} catch (Exception e) {
|
2026-03-14 11:22:11 +08:00
|
|
|
|
log.error("无人机起飞命令发送失败: sn={}", request.getSn(), e);
|
2026-03-14 11:04:00 +08:00
|
|
|
|
flightService.updateFlightStatus(request.getTaskId(), StatusEnum.FAILED);
|
2026-03-14 11:22:11 +08:00
|
|
|
|
return R.fail("无人机起飞命令发送失败: " + e.getMessage());
|
2026-02-24 10:35:02 +08:00
|
|
|
|
}
|
2026-02-04 09:54:59 +08:00
|
|
|
|
}
|
2026-02-10 15:07:15 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 无人机开机接口
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param sn 机场SN号
|
|
|
|
|
|
* @return 开机响应
|
|
|
|
|
|
*/
|
|
|
|
|
|
@Operation(summary = "无人机开机", description = "控制指定机场的无人机执行开机操作")
|
|
|
|
|
|
@PostMapping("/power-on/{sn}")
|
|
|
|
|
|
public R<String> powerOn(
|
|
|
|
|
|
@Parameter(description = "机场SN号", required = true, example = "THJSQ03B2309DN7VQN43")
|
|
|
|
|
|
@PathVariable("sn") String sn)
|
|
|
|
|
|
{
|
|
|
|
|
|
log.info("收到无人机开机请求: sn={}", sn);
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
// 调用机器命令管理器执行开机命令
|
|
|
|
|
|
CompletableFuture<CommandResult> future = machineCommandManager.executeCommand(sn, CommandType.POWER_ON);
|
|
|
|
|
|
|
|
|
|
|
|
// 等待命令执行完成
|
|
|
|
|
|
CommandResult result = future.get();
|
|
|
|
|
|
|
|
|
|
|
|
if (result.isSuccess()) {
|
|
|
|
|
|
log.info("无人机开机成功: sn={}", sn);
|
|
|
|
|
|
return R.ok("开机命令执行成功");
|
|
|
|
|
|
} else {
|
|
|
|
|
|
log.error("无人机开机失败: sn={}, reason={}", sn, result.getErrorMessage());
|
|
|
|
|
|
return R.fail("开机命令执行失败: " + result.getErrorMessage());
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
|
log.error("无人机开机异常: sn={}", sn, e);
|
|
|
|
|
|
return R.fail("开机命令执行异常: " + e.getMessage());
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-02-10 15:29:53 +08:00
|
|
|
|
|
2026-02-11 09:16:35 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 无人机关机接口
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param sn 机场SN号
|
|
|
|
|
|
* @return 关机响应
|
|
|
|
|
|
*/
|
|
|
|
|
|
@Operation(summary = "无人机关机", description = "控制指定机场的无人机执行关机操作")
|
|
|
|
|
|
@PostMapping("/power-off/{sn}")
|
|
|
|
|
|
public R<String> powerOff(
|
|
|
|
|
|
@Parameter(description = "机场SN号", required = true, example = "THJSQ03B2309DN7VQN43")
|
|
|
|
|
|
@PathVariable("sn") String sn)
|
|
|
|
|
|
{
|
|
|
|
|
|
log.info("收到无人机关机请求: sn={}", sn);
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
// 调用机器命令管理器执行关机命令
|
|
|
|
|
|
CompletableFuture<CommandResult> future = machineCommandManager.executeCommand(sn, CommandType.POWER_OFF);
|
|
|
|
|
|
|
|
|
|
|
|
// 等待命令执行完成
|
|
|
|
|
|
CommandResult result = future.get();
|
|
|
|
|
|
|
|
|
|
|
|
if (result.isSuccess()) {
|
|
|
|
|
|
log.info("无人机关机成功: sn={}", sn);
|
|
|
|
|
|
return R.ok("关机命令执行成功");
|
|
|
|
|
|
} else {
|
|
|
|
|
|
log.error("无人机关机失败: sn={}, reason={}", sn, result.getErrorMessage());
|
|
|
|
|
|
return R.fail("关机命令执行失败: " + result.getErrorMessage());
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
|
log.error("无人机关机异常: sn={}", sn, e);
|
|
|
|
|
|
return R.fail("关机命令执行异常: " + e.getMessage());
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-10 15:29:53 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 查询无人机状态
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param sn 设备SN号
|
|
|
|
|
|
* @return 状态信息
|
|
|
|
|
|
*/
|
|
|
|
|
|
@Operation(summary = "查询无人机状态", description = "根据设备SN号查询无人机的实时状态信息")
|
|
|
|
|
|
@GetMapping("/machine-state/{sn}")
|
|
|
|
|
|
public R<MachineStateVO> getMachineState(
|
|
|
|
|
|
@Parameter(description = "设备SN号", required = true, example = "TH001")
|
|
|
|
|
|
@PathVariable("sn") String sn)
|
|
|
|
|
|
{
|
|
|
|
|
|
log.info("查询无人机状态: sn={}", sn);
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
// 从 MachineStateManager 获取状态
|
2026-03-10 10:47:15 +08:00
|
|
|
|
MachineStates states = machineStateManager.getStates(sn);
|
2026-02-10 15:29:53 +08:00
|
|
|
|
|
|
|
|
|
|
// 转换为 VO 对象
|
|
|
|
|
|
MachineStateVO vo = new MachineStateVO();
|
|
|
|
|
|
vo.setSn(sn);
|
|
|
|
|
|
vo.setDroneState(states.getDroneState().name());
|
|
|
|
|
|
vo.setAirportState(states.getAirportState().name());
|
|
|
|
|
|
vo.setCoverState(states.getCoverState().name());
|
|
|
|
|
|
vo.setDrcState(states.getDrcState().name());
|
|
|
|
|
|
vo.setDebugModeState(states.getDebugModeState().name());
|
|
|
|
|
|
|
|
|
|
|
|
log.info("查询到状态: sn={}, vo={}", sn, vo);
|
|
|
|
|
|
return R.ok(vo);
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
|
log.error("查询无人机状态异常: sn={}", sn, e);
|
|
|
|
|
|
return R.fail("查询状态失败: " + e.getMessage());
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-02-11 14:49:48 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 出舱接口
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param sn 机场SN号
|
|
|
|
|
|
* @return 出舱响应
|
|
|
|
|
|
*/
|
|
|
|
|
|
@Operation(summary = "出舱", description = "控制指定机场执行出舱操作")
|
|
|
|
|
|
@PostMapping("/cover-open/{sn}")
|
|
|
|
|
|
public R<String> coverOpen(
|
|
|
|
|
|
@Parameter(description = "机场SN号", required = true, example = "THJSQ03B2309DN7VQN43")
|
|
|
|
|
|
@PathVariable("sn") String sn)
|
|
|
|
|
|
{
|
|
|
|
|
|
log.info("收到出舱请求: sn={}", sn);
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
// 调用机器命令管理器执行出舱命令
|
|
|
|
|
|
CompletableFuture<CommandResult> future = machineCommandManager.executeCommand(sn, CommandType.OPEN_COVER);
|
|
|
|
|
|
|
|
|
|
|
|
// 等待命令执行完成
|
|
|
|
|
|
CommandResult result = future.get();
|
|
|
|
|
|
|
|
|
|
|
|
if (result.isSuccess()) {
|
|
|
|
|
|
log.info("出舱成功: sn={}", sn);
|
|
|
|
|
|
return R.ok("出舱命令执行成功");
|
|
|
|
|
|
} else {
|
|
|
|
|
|
log.error("出舱失败: sn={}, reason={}", sn, result.getErrorMessage());
|
|
|
|
|
|
return R.fail("出舱命令执行失败: " + result.getErrorMessage());
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
|
log.error("出舱异常: sn={}", sn, e);
|
|
|
|
|
|
return R.fail("出舱命令执行异常: " + e.getMessage());
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 回舱接口
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param sn 机场SN号
|
|
|
|
|
|
* @return 回舱响应
|
|
|
|
|
|
*/
|
|
|
|
|
|
@Operation(summary = "回舱", description = "控制指定机场执行回舱操作")
|
|
|
|
|
|
@PostMapping("/cover-close/{sn}")
|
|
|
|
|
|
public R<String> coverClose(
|
|
|
|
|
|
@Parameter(description = "机场SN号", required = true, example = "THJSQ03B2309DN7VQN43")
|
|
|
|
|
|
@PathVariable("sn") String sn)
|
|
|
|
|
|
{
|
|
|
|
|
|
log.info("收到回舱请求: sn={}", sn);
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
// 调用机器命令管理器执行回舱命令
|
|
|
|
|
|
CompletableFuture<CommandResult> future = machineCommandManager.executeCommand(sn, CommandType.CLOSE_COVER);
|
|
|
|
|
|
|
|
|
|
|
|
// 等待命令执行完成
|
|
|
|
|
|
CommandResult result = future.get();
|
|
|
|
|
|
|
|
|
|
|
|
if (result.isSuccess()) {
|
|
|
|
|
|
log.info("回舱成功: sn={}", sn);
|
|
|
|
|
|
return R.ok("回舱命令执行成功");
|
|
|
|
|
|
} else {
|
|
|
|
|
|
log.error("回舱失败: sn={}, reason={}", sn, result.getErrorMessage());
|
|
|
|
|
|
return R.fail("回舱命令执行失败: " + result.getErrorMessage());
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
|
log.error("回舱异常: sn={}", sn, e);
|
|
|
|
|
|
return R.fail("回舱命令执行异常: " + e.getMessage());
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-02-24 10:35:02 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 无人机返航接口
|
|
|
|
|
|
*
|
2026-02-27 14:15:31 +08:00
|
|
|
|
* @param request 返航请求对象
|
2026-02-24 10:35:02 +08:00
|
|
|
|
* @return 返航响应
|
|
|
|
|
|
*/
|
|
|
|
|
|
@Operation(summary = "无人机返航", description = "控制指定机场的无人机执行返航操作")
|
2026-02-27 14:15:31 +08:00
|
|
|
|
@PostMapping("/return-home")
|
|
|
|
|
|
public R<String> returnHome(@RequestBody DroneReturnHomeRequest request)
|
2026-02-24 10:35:02 +08:00
|
|
|
|
{
|
2026-03-10 15:56:15 +08:00
|
|
|
|
log.info("收到无人机返航请求: sn={} ", request.getSn());
|
2026-02-24 10:35:02 +08:00
|
|
|
|
|
|
|
|
|
|
try {
|
2026-03-10 15:56:15 +08:00
|
|
|
|
|
|
|
|
|
|
Long currentTaskId = flightService.currentRunningTask(request.getSn());
|
2026-02-27 14:15:31 +08:00
|
|
|
|
java.util.Map<String, Object> params = new java.util.HashMap<>();
|
2026-03-10 15:56:15 +08:00
|
|
|
|
if(Objects.isNull(currentTaskId)){
|
2026-02-27 14:15:31 +08:00
|
|
|
|
params.put("messageID", UUID.randomUUID().toString());
|
|
|
|
|
|
}else {
|
2026-03-10 15:56:15 +08:00
|
|
|
|
params.put("messageID",currentTaskId);
|
2026-02-27 14:15:31 +08:00
|
|
|
|
}
|
|
|
|
|
|
params.put("taskId", 9074);
|
2026-03-10 15:56:15 +08:00
|
|
|
|
params.put("zhilin", "03");
|
2026-02-27 14:15:31 +08:00
|
|
|
|
CompletableFuture<CommandResult> future = machineCommandManager.executeCommand(request.getSn(), CommandType.RETURN_HOME, params);
|
2026-02-24 10:35:02 +08:00
|
|
|
|
CommandResult result = future.get();
|
|
|
|
|
|
|
|
|
|
|
|
if (result.isSuccess()) {
|
2026-02-27 14:15:31 +08:00
|
|
|
|
log.info("无人机返航成功: sn={}", request.getSn());
|
2026-02-24 10:35:02 +08:00
|
|
|
|
return R.ok("返航命令执行成功");
|
|
|
|
|
|
} else {
|
2026-02-27 14:15:31 +08:00
|
|
|
|
log.error("无人机返航失败: sn={}, reason={}", request.getSn(), result.getErrorMessage());
|
2026-02-24 10:35:02 +08:00
|
|
|
|
return R.fail("返航命令执行失败: " + result.getErrorMessage());
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (Exception e) {
|
2026-02-27 14:15:31 +08:00
|
|
|
|
log.error("无人机返航异常: sn={}", request.getSn(), e);
|
2026-02-24 10:35:02 +08:00
|
|
|
|
return R.fail("返航命令执行异常: " + e.getMessage());
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-02-04 09:54:59 +08:00
|
|
|
|
}
|