diff --git a/src/main/java/com/ruoyi/device/controller/AircraftFlyController.java b/src/main/java/com/ruoyi/device/controller/AircraftFlyController.java index 5b1b3cb..1b50b6b 100644 --- a/src/main/java/com/ruoyi/device/controller/AircraftFlyController.java +++ b/src/main/java/com/ruoyi/device/controller/AircraftFlyController.java @@ -38,6 +38,9 @@ public class AircraftFlyController extends BaseController @Autowired private com.ruoyi.device.domain.impl.machine.statemachine.MachineStateManager machineStateManager; + + @Autowired + private com.ruoyi.device.domain.impl.machine.mqtt.MqttClient mqttClient; /** * 无人机飞控命令 * @@ -48,8 +51,63 @@ public class AircraftFlyController extends BaseController @PostMapping("/flight-control") public R flightControl(@RequestBody DroneFlightControlRequest request) { - // TODO: 实现飞控命令逻辑 - return R.ok(); + 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 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()); + } } /** diff --git a/src/main/java/com/ruoyi/device/domain/impl/machine/command/CommandType.java b/src/main/java/com/ruoyi/device/domain/impl/machine/command/CommandType.java index c552725..6c48c01 100644 --- a/src/main/java/com/ruoyi/device/domain/impl/machine/command/CommandType.java +++ b/src/main/java/com/ruoyi/device/domain/impl/machine/command/CommandType.java @@ -92,5 +92,45 @@ public enum CommandType { /** * 重启机巢 */ - REBOOT_AIRPORT + REBOOT_AIRPORT, + + /** + * 前进 + */ + FORWARD, + + /** + * 后退 + */ + BACKWARD, + + /** + * 左移 + */ + LEFT, + + /** + * 右移 + */ + RIGHT, + + /** + * 左旋 + */ + ROTATE_LEFT, + + /** + * 右旋 + */ + ROTATE_RIGHT, + + /** + * 上升 + */ + UP, + + /** + * 下降 + */ + DOWN } diff --git a/src/main/java/com/ruoyi/device/domain/impl/machine/vendor/tuoheng/TuohengVendorConfig.java b/src/main/java/com/ruoyi/device/domain/impl/machine/vendor/tuoheng/TuohengVendorConfig.java index 11a1fe6..6d3bef5 100644 --- a/src/main/java/com/ruoyi/device/domain/impl/machine/vendor/tuoheng/TuohengVendorConfig.java +++ b/src/main/java/com/ruoyi/device/domain/impl/machine/vendor/tuoheng/TuohengVendorConfig.java @@ -124,6 +124,32 @@ public class TuohengVendorConfig implements VendorConfig { .setTimeout(300000); transactionMap.put(takeOffTransaction.getCommandType(), takeOffTransaction); + // 遥感控制命令 + transactionMap.put(CommandType.FORWARD, new Transaction("前进", CommandType.FORWARD) + .root(new com.ruoyi.device.domain.impl.machine.vendor.tuoheng.instruction.TuohengDroneControlInstruction("06", "前进")) + .setTimeout(5000)); + transactionMap.put(CommandType.BACKWARD, new Transaction("后退", CommandType.BACKWARD) + .root(new com.ruoyi.device.domain.impl.machine.vendor.tuoheng.instruction.TuohengDroneControlInstruction("07", "后退")) + .setTimeout(5000)); + transactionMap.put(CommandType.LEFT, new Transaction("左移", CommandType.LEFT) + .root(new com.ruoyi.device.domain.impl.machine.vendor.tuoheng.instruction.TuohengDroneControlInstruction("04", "左移")) + .setTimeout(5000)); + transactionMap.put(CommandType.RIGHT, new Transaction("右移", CommandType.RIGHT) + .root(new com.ruoyi.device.domain.impl.machine.vendor.tuoheng.instruction.TuohengDroneControlInstruction("05", "右移")) + .setTimeout(5000)); + transactionMap.put(CommandType.ROTATE_LEFT, new Transaction("左旋", CommandType.ROTATE_LEFT) + .root(new com.ruoyi.device.domain.impl.machine.vendor.tuoheng.instruction.TuohengDroneControlInstruction("10", "左旋")) + .setTimeout(5000)); + transactionMap.put(CommandType.ROTATE_RIGHT, new Transaction("右旋", CommandType.ROTATE_RIGHT) + .root(new com.ruoyi.device.domain.impl.machine.vendor.tuoheng.instruction.TuohengDroneControlInstruction("11", "右旋")) + .setTimeout(5000)); + transactionMap.put(CommandType.UP, new Transaction("上升", CommandType.UP) + .root(new com.ruoyi.device.domain.impl.machine.vendor.tuoheng.instruction.TuohengDroneControlInstruction("08", "上升")) + .setTimeout(5000)); + transactionMap.put(CommandType.DOWN, new Transaction("下降", CommandType.DOWN) + .root(new com.ruoyi.device.domain.impl.machine.vendor.tuoheng.instruction.TuohengDroneControlInstruction("09", "下降")) + .setTimeout(5000)); + log.info("拓恒厂家配置初始化完成,共配置{}个命令", transactionMap.size()); } } \ No newline at end of file diff --git a/src/main/java/com/ruoyi/device/domain/impl/machine/vendor/tuoheng/instruction/TuohengDroneControlInstruction.java b/src/main/java/com/ruoyi/device/domain/impl/machine/vendor/tuoheng/instruction/TuohengDroneControlInstruction.java new file mode 100644 index 0000000..fadb8e9 --- /dev/null +++ b/src/main/java/com/ruoyi/device/domain/impl/machine/vendor/tuoheng/instruction/TuohengDroneControlInstruction.java @@ -0,0 +1,58 @@ +package com.ruoyi.device.domain.impl.machine.vendor.tuoheng.instruction; + +import com.alibaba.fastjson.JSONObject; +import com.ruoyi.device.domain.impl.machine.instruction.AbstractInstruction; +import com.ruoyi.device.domain.impl.machine.instruction.CallbackConfig; +import com.ruoyi.device.domain.impl.machine.instruction.InstructionContext; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class TuohengDroneControlInstruction extends AbstractInstruction { + + private final String commandValue; + private final String description; + + public TuohengDroneControlInstruction(String commandValue, String description) { + this.commandValue = commandValue; + this.description = description; + } + + @Override + public String getName() { + return "TUOHENG_DRONE_CONTROL_" + commandValue; + } + + @Override + public void executeRemoteCall(InstructionContext context) throws Exception { + String sn = context.getSn(); + log.info("发送拓恒无人机遥感控制指令: sn={}, command={}, desc={}", sn, commandValue, description); + + JSONObject payload = new JSONObject(); + payload.put("code", "yaogan"); + payload.put("yaogan", commandValue); + payload.put("value", commandValue); + payload.put("messageID", System.currentTimeMillis()); + payload.put("timestamp", System.currentTimeMillis()); + payload.put("PWM", 35); + payload.put("desc", description); + + String topic = "/topic/v1/airportDrone/" + sn + "/control"; + context.getMqttClient().sendMessage(topic, payload.toJSONString()); + log.info("遥感控制指令发送成功: topic={}, payload={}", topic, payload.toJSONString()); + } + + @Override + public CallbackConfig getMethodCallbackConfig(InstructionContext context) { + return null; + } + + @Override + public CallbackConfig getStateCallbackConfig(InstructionContext context) { + return null; + } + + @Override + public long getTimeoutMs() { + return 5000; + } +}