a-tuoheng-device/src/main/java/com/ruoyi/device/controller/AircraftFlyController.java

400 lines
16 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.ruoyi.device.controller;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.web.controller.BaseController;
import com.ruoyi.device.api.domain.*;
import com.ruoyi.device.api.enums.DroneCurrentStatusEnum;
import com.ruoyi.device.api.enums.DroneMissionStatusEnum;
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;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
/**
* 无人机飞控Controller
*
* @author ruoyi
* @date 2026-02-04
*/
@Slf4j
@Tag(name = "无人机飞控管理", description = "无人机飞控相关接口")
@RestController
@RequestMapping("/drone")
public class AircraftFlyController extends BaseController
{
@Autowired
private MachineCommandManager machineCommandManager;
@Autowired
private com.ruoyi.device.domain.impl.machine.statemachine.MachineStateManager machineStateManager;
@Autowired
private com.ruoyi.device.domain.impl.machine.mqtt.MqttClient mqttClient;
/**
* 无人机飞控命令
*
* @param request 飞控命令请求
* @return 结果
*/
@Operation(summary = "无人机飞控命令", description = "发送飞控命令控制无人机的飞行动作,包括前进、后退、左移、右移、左旋、右旋、上升、下降、返航、急停等")
@PostMapping("/flight-control")
public R<Void> flightControl(@RequestBody DroneFlightControlRequest request)
{
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;
switch (request.getCommand()) {
case RETURN_HOME:
commandType = CommandType.RETURN_HOME;
break;
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;
case EMERGENCY_STOP:
return R.fail("急停命令暂不支持");
default:
return R.fail("不支持的飞控命令");
}
CompletableFuture<CommandResult> future = machineCommandManager.executeCommand(sn, commandType);
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());
}
}
/**
* 无人机实时信息展示
*
* @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);
}
/**
* 无人机一键起飞
*
* @param request 起飞请求对象
* @return 起飞响应
*/
@Operation(summary = "无人机一键起飞", description = "控制指定机场的无人机执行起飞操作")
@PostMapping("/takeoff")
public R<String> takeoff(@RequestBody DroneTakeoffRequest request)
{
log.info("收到无人机起飞请求: sn={}, messageID={}", request.getSn(), request.getMessageID());
try {
java.util.Map<String, Object> params = new java.util.HashMap<>();
if(Objects.isNull(request.getMessageID())){
params.put("messageID", UUID.randomUUID().toString());
}else {
params.put("messageID", request.getMessageID());
}
params.put("airlineFileUrl", request.getAirlineFileUrl());
params.put("flyBatteryMin", request.getFlyBatteryMin());
CompletableFuture<CommandResult> future = machineCommandManager.executeCommand(request.getSn(), CommandType.TAKE_OFF, params);
CommandResult result = future.get();
if (result.isSuccess()) {
log.info("无人机起飞成功: sn={}", request.getSn());
return R.ok("起飞命令执行成功");
} else {
log.error("无人机起飞失败: sn={}, reason={}", request.getSn(), result.getErrorMessage());
return R.fail("起飞命令执行失败: " + result.getErrorMessage());
}
} catch (Exception e) {
log.error("无人机起飞异常: sn={}", request.getSn(), e);
return R.fail("起飞命令执行异常: " + e.getMessage());
}
}
/**
* 无人机开机接口
*
* @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());
}
}
/**
* 无人机关机接口
*
* @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());
}
}
/**
* 查询无人机状态
*
* @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 获取状态
com.ruoyi.device.domain.impl.machine.state.MachineStates states = machineStateManager.getStates(sn);
// 转换为 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());
}
}
/**
* 出舱接口
*
* @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());
}
}
/**
* 无人机返航接口
*
* @param request 返航请求对象
* @return 返航响应
*/
@Operation(summary = "无人机返航", description = "控制指定机场的无人机执行返航操作")
@PostMapping("/return-home")
public R<String> returnHome(@RequestBody DroneReturnHomeRequest request)
{
log.info("收到无人机返航请求: sn={}, messageID={}, taskId={}", request.getSn(), request.getMessageID(), request.getTaskId());
try {
java.util.Map<String, Object> params = new java.util.HashMap<>();
if(Objects.isNull(request.getMessageID())){
params.put("messageID", UUID.randomUUID().toString());
}else {
params.put("messageID", request.getMessageID());
}
params.put("taskId", 9074);
params.put("zhilin", request.getZhilin());
CompletableFuture<CommandResult> future = machineCommandManager.executeCommand(request.getSn(), CommandType.RETURN_HOME, params);
CommandResult result = future.get();
if (result.isSuccess()) {
log.info("无人机返航成功: sn={}", request.getSn());
return R.ok("返航命令执行成功");
} else {
log.error("无人机返航失败: sn={}, reason={}", request.getSn(), result.getErrorMessage());
return R.fail("返航命令执行失败: " + result.getErrorMessage());
}
} catch (Exception e) {
log.error("无人机返航异常: sn={}", request.getSn(), e);
return R.fail("返航命令执行异常: " + e.getMessage());
}
}
}