From e44347eec9874e55910ba8d94b67c113799e8889 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=99=E5=B0=8F=E4=BA=91?= Date: Thu, 18 Dec 2025 13:22:34 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=A1=86=E6=9E=B6=E5=86=85?= =?UTF-8?q?=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../machine/MachineCommandManager.java | 2 +- .../tuoheng/machine/command/CommandType.java | 2 - .../tuoheng/machine/command/Transaction.java | 2 +- .../machine/instruction/CallbackConfig.java | 16 +- .../tuoheng/machine/state/AirportState.java | 1 - .../machine/vendor/dji/DjiVendorConfig.java | 102 +------- .../DjiCancelPointInstruction.java | 2 - .../instruction/DjiCloseCoverInstruction.java | 2 - .../DjiEmergencyStopInstruction.java | 2 - .../dji/instruction/DjiLandInstruction.java | 2 - .../instruction/DjiOpenCoverInstruction.java | 2 - .../instruction/DjiPointFlyInstruction.java | 2 - .../DjiResumeFlightInstruction.java | 2 - .../instruction/DjiReturnHomeInstruction.java | 2 - .../DjiStartMissionInstruction.java | 2 - .../instruction/DjiTakeOffInstruction.java | 10 +- .../com/tuoheng/old/DrcStateMachineTest.java | 224 +++++++++++++----- 17 files changed, 190 insertions(+), 187 deletions(-) diff --git a/src/main/java/com/tuoheng/machine/MachineCommandManager.java b/src/main/java/com/tuoheng/machine/MachineCommandManager.java index dfc59c5..401253d 100644 --- a/src/main/java/com/tuoheng/machine/MachineCommandManager.java +++ b/src/main/java/com/tuoheng/machine/MachineCommandManager.java @@ -52,7 +52,7 @@ public class MachineCommandManager { */ public void bindMachine(String sn, String vendorType) { vendorRegistry.bindSnToVendor(sn, vendorType); - log.info("绑定设备到厂家: sn=, vendorType={}", sn, vendorType); + log.info("绑定设备到厂家: sn={}, vendorType={}", sn, vendorType); } /** diff --git a/src/main/java/com/tuoheng/machine/command/CommandType.java b/src/main/java/com/tuoheng/machine/command/CommandType.java index 991d995..42d6f52 100644 --- a/src/main/java/com/tuoheng/machine/command/CommandType.java +++ b/src/main/java/com/tuoheng/machine/command/CommandType.java @@ -9,8 +9,6 @@ public enum CommandType { */ TAKE_OFF, - - /** * 返航 */ diff --git a/src/main/java/com/tuoheng/machine/command/Transaction.java b/src/main/java/com/tuoheng/machine/command/Transaction.java index b930a81..d2002bf 100644 --- a/src/main/java/com/tuoheng/machine/command/Transaction.java +++ b/src/main/java/com/tuoheng/machine/command/Transaction.java @@ -26,7 +26,7 @@ public class Transaction { /** * 事务超时时间(毫秒) */ - private long timeoutMs = 120000; // 默认2分钟 + private long timeoutMs = 10000; // 默认10秒 public Transaction(String name, CommandType commandType) { this.name = name; diff --git a/src/main/java/com/tuoheng/machine/instruction/CallbackConfig.java b/src/main/java/com/tuoheng/machine/instruction/CallbackConfig.java index c4d169f..edb8c9d 100644 --- a/src/main/java/com/tuoheng/machine/instruction/CallbackConfig.java +++ b/src/main/java/com/tuoheng/machine/instruction/CallbackConfig.java @@ -1,5 +1,6 @@ package com.tuoheng.machine.instruction; +import com.fasterxml.jackson.databind.ObjectMapper; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -38,7 +39,7 @@ public class CallbackConfig { /** * 超时时间(毫秒) */ - private long timeoutMs = 30000; + private long timeoutMs = 3000; /** * 判断消息是否匹配 @@ -60,8 +61,19 @@ public class CallbackConfig { return null; } - String[] parts = path.split("\\."); + // 如果 messageBody 是字符串,尝试解析为 JSON Object current = messageBody; + if (messageBody instanceof String) { + try { + ObjectMapper objectMapper = new ObjectMapper(); + current = objectMapper.readValue((String) messageBody, Object.class); + } catch (Exception e) { + // 解析失败,返回 null + return null; + } + } + + String[] parts = path.split("\\."); for (String part : parts) { if (current == null) { diff --git a/src/main/java/com/tuoheng/machine/state/AirportState.java b/src/main/java/com/tuoheng/machine/state/AirportState.java index e3ba072..14746a1 100644 --- a/src/main/java/com/tuoheng/machine/state/AirportState.java +++ b/src/main/java/com/tuoheng/machine/state/AirportState.java @@ -9,7 +9,6 @@ public enum AirportState { */ UNKNOWN, - /** * 在线 */ diff --git a/src/main/java/com/tuoheng/machine/vendor/dji/DjiVendorConfig.java b/src/main/java/com/tuoheng/machine/vendor/dji/DjiVendorConfig.java index 3e70f3e..ca0023e 100644 --- a/src/main/java/com/tuoheng/machine/vendor/dji/DjiVendorConfig.java +++ b/src/main/java/com/tuoheng/machine/vendor/dji/DjiVendorConfig.java @@ -52,59 +52,13 @@ public class DjiVendorConfig implements VendorConfig { switch (commandType) { case TAKE_OFF: - return droneState == DroneState.ONLINE ; + return droneState == DroneState.ONLINE && airportState == AirportState.ONLINE; case RETURN_HOME: - return droneState == DroneState.FLYING ; - - case EMERGENCY_STOP: - // 飞行中、返航中可以急停(未处于急停状态) - return (droneState == DroneState.FLYING || droneState == DroneState.RETURNING) && - stopState != StopState.ENTERED; - - case RESUME_FLIGHT: - // 急停状态可以继续飞行 - return stopState == StopState.ENTERED; - - case POINT_FLY: - // 飞行中、到达目的地、返航中可以指点飞行(未急停) - return (droneState == DroneState.FLYING || - droneState == DroneState.ARRIVED || - droneState == DroneState.RETURNING) && - stopState != StopState.ENTERED; - - case CANCEL_POINT: - // 飞行中可以取消指点 - return droneState == DroneState.FLYING; - - case START_MISSION: - // 未知状态或离线状态且未急停时可以开始航线任务 - return (droneState == DroneState.UNKNOWN || droneState == DroneState.ONLINE) && - stopState != StopState.ENTERED; - - case OPEN_COVER: - // 舱门关闭状态可以打开 - return coverState == CoverState.CLOSED; - - case CLOSE_COVER: - // 舱门打开状态可以关闭 - return coverState == CoverState.OPENED; - - case ENTER_DEBUG_MODE: - // 在线状态且未处于调试模式时可以进入调试模式 - return airportState == AirportState.ONLINE && - debugModeState == DebugModeState.UNKNOWN; - - case EXIT_DEBUG_MODE: - // 调试模式可以退出 - return debugModeState == DebugModeState.ENTERED; - - case REBOOT_AIRPORT: - // 在线状态可以重启 - return airportState == AirportState.ONLINE; + return droneState == DroneState.FLYING || droneState == DroneState.ARRIVED; default: - return false; + return true; } } @@ -117,7 +71,6 @@ public class DjiVendorConfig implements VendorConfig { availableCommands.add(commandType); } } - return availableCommands; } @@ -128,56 +81,9 @@ public class DjiVendorConfig implements VendorConfig { // 起飞命令 Transaction takeOffTransaction = new Transaction("起飞", CommandType.TAKE_OFF) .root(new DjiTakeOffInstruction()) - .setTimeout(90000); + .setTimeout(10000); transactionMap.put(CommandType.TAKE_OFF, takeOffTransaction); - // 返航命令 - Transaction returnHomeTransaction = new Transaction("返航", CommandType.RETURN_HOME) - .root(new DjiReturnHomeInstruction()) - .setTimeout(120000); - transactionMap.put(CommandType.RETURN_HOME, returnHomeTransaction); - - // 急停命令 - Transaction emergencyStopTransaction = new Transaction("急停", CommandType.EMERGENCY_STOP) - .root(new DjiEmergencyStopInstruction()) - .setTimeout(30000); - transactionMap.put(CommandType.EMERGENCY_STOP, emergencyStopTransaction); - - // 继续飞行命令 - Transaction resumeFlightTransaction = new Transaction("继续飞行", CommandType.RESUME_FLIGHT) - .root(new DjiResumeFlightInstruction()) - .setTimeout(60000); - transactionMap.put(CommandType.RESUME_FLIGHT, resumeFlightTransaction); - - // 指点飞行命令 - Transaction pointFlyTransaction = new Transaction("指点飞行", CommandType.POINT_FLY) - .root(new DjiPointFlyInstruction()) - .setTimeout(90000); - transactionMap.put(CommandType.POINT_FLY, pointFlyTransaction); - - // 取消指点命令 - Transaction cancelPointTransaction = new Transaction("取消指点", CommandType.CANCEL_POINT) - .root(new DjiCancelPointInstruction()) - .setTimeout(30000); - transactionMap.put(CommandType.CANCEL_POINT, cancelPointTransaction); - - // 开始航线任务命令 - Transaction startMissionTransaction = new Transaction("开始航线任务", CommandType.START_MISSION) - .root(new DjiStartMissionInstruction()) - .setTimeout(120000); - transactionMap.put(CommandType.START_MISSION, startMissionTransaction); - - // 打开舱门命令 - Transaction openCoverTransaction = new Transaction("打开舱门", CommandType.OPEN_COVER) - .root(new DjiOpenCoverInstruction()) - .setTimeout(60000); - transactionMap.put(CommandType.OPEN_COVER, openCoverTransaction); - - // 关闭舱门命令 - Transaction closeCoverTransaction = new Transaction("关闭舱门", CommandType.CLOSE_COVER) - .root(new DjiCloseCoverInstruction()) - .setTimeout(60000); - transactionMap.put(CommandType.CLOSE_COVER, closeCoverTransaction); log.info("大疆厂家配置初始化完成,共配置{}个命令", transactionMap.size()); } diff --git a/src/main/java/com/tuoheng/machine/vendor/dji/instruction/DjiCancelPointInstruction.java b/src/main/java/com/tuoheng/machine/vendor/dji/instruction/DjiCancelPointInstruction.java index af9e7f3..767a71e 100644 --- a/src/main/java/com/tuoheng/machine/vendor/dji/instruction/DjiCancelPointInstruction.java +++ b/src/main/java/com/tuoheng/machine/vendor/dji/instruction/DjiCancelPointInstruction.java @@ -34,7 +34,6 @@ public class DjiCancelPointInstruction extends AbstractInstruction { .topic("dji/" + sn + "/response") .fieldPath("cmd") .expectedValue("cancelPoint") - .canShortCircuit(false) .timeoutMs(10000) .build(); } @@ -47,7 +46,6 @@ public class DjiCancelPointInstruction extends AbstractInstruction { .topic("dji/" + sn + "/state") .fieldPath("droneState") .expectedValue("POINT_CANCELLED") - .canShortCircuit(false) .timeoutMs(30000) .build(); } diff --git a/src/main/java/com/tuoheng/machine/vendor/dji/instruction/DjiCloseCoverInstruction.java b/src/main/java/com/tuoheng/machine/vendor/dji/instruction/DjiCloseCoverInstruction.java index b75f7c3..c06c90c 100644 --- a/src/main/java/com/tuoheng/machine/vendor/dji/instruction/DjiCloseCoverInstruction.java +++ b/src/main/java/com/tuoheng/machine/vendor/dji/instruction/DjiCloseCoverInstruction.java @@ -34,7 +34,6 @@ public class DjiCloseCoverInstruction extends AbstractInstruction { .topic("dji/" + sn + "/response") .fieldPath("cmd") .expectedValue("closeCover") - .canShortCircuit(false) .timeoutMs(10000) .build(); } @@ -47,7 +46,6 @@ public class DjiCloseCoverInstruction extends AbstractInstruction { .topic("dji/" + sn + "/state") .fieldPath("coverState") .expectedValue("CLOSED") - .canShortCircuit(false) .timeoutMs(60000) .build(); } diff --git a/src/main/java/com/tuoheng/machine/vendor/dji/instruction/DjiEmergencyStopInstruction.java b/src/main/java/com/tuoheng/machine/vendor/dji/instruction/DjiEmergencyStopInstruction.java index c355acf..ab4a9ca 100644 --- a/src/main/java/com/tuoheng/machine/vendor/dji/instruction/DjiEmergencyStopInstruction.java +++ b/src/main/java/com/tuoheng/machine/vendor/dji/instruction/DjiEmergencyStopInstruction.java @@ -34,7 +34,6 @@ public class DjiEmergencyStopInstruction extends AbstractInstruction { .topic("dji/" + sn + "/response") .fieldPath("cmd") .expectedValue("emergencyStop") - .canShortCircuit(false) .timeoutMs(5000) .build(); } @@ -50,7 +49,6 @@ public class DjiEmergencyStopInstruction extends AbstractInstruction { // 急停状态可能是 EMERGENCY_STOP 或 RETURN_EMERGENCY_STOP return "EMERGENCY_STOP".equals(state) || "RETURN_EMERGENCY_STOP".equals(state); }) - .canShortCircuit(false) .timeoutMs(30000) .build(); } diff --git a/src/main/java/com/tuoheng/machine/vendor/dji/instruction/DjiLandInstruction.java b/src/main/java/com/tuoheng/machine/vendor/dji/instruction/DjiLandInstruction.java index 07ac132..6a7e7df 100644 --- a/src/main/java/com/tuoheng/machine/vendor/dji/instruction/DjiLandInstruction.java +++ b/src/main/java/com/tuoheng/machine/vendor/dji/instruction/DjiLandInstruction.java @@ -35,7 +35,6 @@ public class DjiLandInstruction extends AbstractInstruction { .topic("dji/" + sn + "/response") .fieldPath("cmd") .expectedValue("land") - .canShortCircuit(false) .timeoutMs(10000) .build(); } @@ -48,7 +47,6 @@ public class DjiLandInstruction extends AbstractInstruction { .topic("dji/" + sn + "/state") .fieldPath("droneState") .expectedValue("PREPARING") - .canShortCircuit(false) .timeoutMs(60000) .build(); } diff --git a/src/main/java/com/tuoheng/machine/vendor/dji/instruction/DjiOpenCoverInstruction.java b/src/main/java/com/tuoheng/machine/vendor/dji/instruction/DjiOpenCoverInstruction.java index 8c1be4e..7767a8b 100644 --- a/src/main/java/com/tuoheng/machine/vendor/dji/instruction/DjiOpenCoverInstruction.java +++ b/src/main/java/com/tuoheng/machine/vendor/dji/instruction/DjiOpenCoverInstruction.java @@ -34,7 +34,6 @@ public class DjiOpenCoverInstruction extends AbstractInstruction { .topic("dji/" + sn + "/response") .fieldPath("cmd") .expectedValue("openCover") - .canShortCircuit(false) .timeoutMs(10000) .build(); } @@ -47,7 +46,6 @@ public class DjiOpenCoverInstruction extends AbstractInstruction { .topic("dji/" + sn + "/state") .fieldPath("coverState") .expectedValue("OPENED") - .canShortCircuit(false) .timeoutMs(60000) .build(); } diff --git a/src/main/java/com/tuoheng/machine/vendor/dji/instruction/DjiPointFlyInstruction.java b/src/main/java/com/tuoheng/machine/vendor/dji/instruction/DjiPointFlyInstruction.java index 9485a6d..1f2f0ce 100644 --- a/src/main/java/com/tuoheng/machine/vendor/dji/instruction/DjiPointFlyInstruction.java +++ b/src/main/java/com/tuoheng/machine/vendor/dji/instruction/DjiPointFlyInstruction.java @@ -39,7 +39,6 @@ public class DjiPointFlyInstruction extends AbstractInstruction { .topic("dji/" + sn + "/response") .fieldPath("cmd") .expectedValue("pointFly") - .canShortCircuit(false) .timeoutMs(10000) .build(); } @@ -52,7 +51,6 @@ public class DjiPointFlyInstruction extends AbstractInstruction { .topic("dji/" + sn + "/state") .fieldPath("droneState") .expectedValue("POINT_FLYING") - .canShortCircuit(false) .timeoutMs(30000) .build(); } diff --git a/src/main/java/com/tuoheng/machine/vendor/dji/instruction/DjiResumeFlightInstruction.java b/src/main/java/com/tuoheng/machine/vendor/dji/instruction/DjiResumeFlightInstruction.java index 2a4386b..88417c6 100644 --- a/src/main/java/com/tuoheng/machine/vendor/dji/instruction/DjiResumeFlightInstruction.java +++ b/src/main/java/com/tuoheng/machine/vendor/dji/instruction/DjiResumeFlightInstruction.java @@ -34,7 +34,6 @@ public class DjiResumeFlightInstruction extends AbstractInstruction { .topic("dji/" + sn + "/response") .fieldPath("cmd") .expectedValue("resumeFlight") - .canShortCircuit(false) .timeoutMs(10000) .build(); } @@ -50,7 +49,6 @@ public class DjiResumeFlightInstruction extends AbstractInstruction { // 继续飞行后可能变为 FLYING 或 RETURNING return "FLYING".equals(state) || "RETURNING".equals(state); }) - .canShortCircuit(false) .timeoutMs(30000) .build(); } diff --git a/src/main/java/com/tuoheng/machine/vendor/dji/instruction/DjiReturnHomeInstruction.java b/src/main/java/com/tuoheng/machine/vendor/dji/instruction/DjiReturnHomeInstruction.java index ba682b2..f3e0ae7 100644 --- a/src/main/java/com/tuoheng/machine/vendor/dji/instruction/DjiReturnHomeInstruction.java +++ b/src/main/java/com/tuoheng/machine/vendor/dji/instruction/DjiReturnHomeInstruction.java @@ -34,7 +34,6 @@ public class DjiReturnHomeInstruction extends AbstractInstruction { .topic("dji/" + sn + "/response") .fieldPath("cmd") .expectedValue("returnHome") - .canShortCircuit(false) .timeoutMs(10000) .build(); } @@ -47,7 +46,6 @@ public class DjiReturnHomeInstruction extends AbstractInstruction { .topic("dji/" + sn + "/state") .fieldPath("droneState") .expectedValue("RETURNING") - .canShortCircuit(false) .timeoutMs(60000) .build(); } diff --git a/src/main/java/com/tuoheng/machine/vendor/dji/instruction/DjiStartMissionInstruction.java b/src/main/java/com/tuoheng/machine/vendor/dji/instruction/DjiStartMissionInstruction.java index 85b9a45..87a1dd2 100644 --- a/src/main/java/com/tuoheng/machine/vendor/dji/instruction/DjiStartMissionInstruction.java +++ b/src/main/java/com/tuoheng/machine/vendor/dji/instruction/DjiStartMissionInstruction.java @@ -36,7 +36,6 @@ public class DjiStartMissionInstruction extends AbstractInstruction { .topic("dji/" + sn + "/response") .fieldPath("cmd") .expectedValue("startMission") - .canShortCircuit(false) .timeoutMs(10000) .build(); } @@ -49,7 +48,6 @@ public class DjiStartMissionInstruction extends AbstractInstruction { .topic("dji/" + sn + "/state") .fieldPath("droneState") .expectedValue("FLYING") - .canShortCircuit(false) .timeoutMs(60000) .build(); } diff --git a/src/main/java/com/tuoheng/machine/vendor/dji/instruction/DjiTakeOffInstruction.java b/src/main/java/com/tuoheng/machine/vendor/dji/instruction/DjiTakeOffInstruction.java index 5697cdd..69129c5 100644 --- a/src/main/java/com/tuoheng/machine/vendor/dji/instruction/DjiTakeOffInstruction.java +++ b/src/main/java/com/tuoheng/machine/vendor/dji/instruction/DjiTakeOffInstruction.java @@ -32,20 +32,21 @@ public class DjiTakeOffInstruction extends AbstractInstruction { @Override public CallbackConfig getMethodCallbackConfig(InstructionContext context) { +// return null; String sn = context.getSn(); // 方法回调:等待起飞指令的ACK响应 return CallbackConfig.builder() .topic("dji/" + sn + "/response") - .fieldPath("cmd") + .fieldPath("data.result") .expectedValue("takeoff") - .canShortCircuit(false) // 不可短路,必须等待响应 .timeoutMs(10000) // 10秒超时 .build(); } @Override public CallbackConfig getStateCallbackConfig(InstructionContext context) { +// return null; String sn = context.getSn(); // 状态回调:等待无人机状态变为飞行中 @@ -53,13 +54,12 @@ public class DjiTakeOffInstruction extends AbstractInstruction { .topic("dji/" + sn + "/state") .fieldPath("droneState") .expectedValue("FLYING") - .canShortCircuit(false) // 不可短路,必须等待状态变化 - .timeoutMs(60000) // 60秒超时 + .timeoutMs(10000) // 10秒超时 .build(); } @Override public long getTimeoutMs() { - return 90000; // 90秒总超时 + return 10000; // 10秒总超时 } } diff --git a/src/test/java/com/tuoheng/old/DrcStateMachineTest.java b/src/test/java/com/tuoheng/old/DrcStateMachineTest.java index 93c68f2..0c79d85 100644 --- a/src/test/java/com/tuoheng/old/DrcStateMachineTest.java +++ b/src/test/java/com/tuoheng/old/DrcStateMachineTest.java @@ -1,13 +1,25 @@ package com.tuoheng.old; -import com.tuoheng.old.events.DrcEvent; -import com.tuoheng.old.service.DrcMachineService; -import com.tuoheng.old.status.DrcState; +import com.tuoheng.machine.MachineCommandManager; +import com.tuoheng.machine.command.CommandResult; +import com.tuoheng.machine.command.CommandType; +import com.tuoheng.machine.mqtt.MqttCallbackRegistry; +import com.tuoheng.machine.state.*; import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.MethodOrderer; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.statemachine.StateMachine; +import org.junit.jupiter.api.*; +import org.springframework.util.Assert; + +import java.util.HashMap; +import java.util.concurrent.*; + +import static org.junit.jupiter.api.Assertions.*; + /** * DRC状态机测试 @@ -15,71 +27,165 @@ import org.springframework.statemachine.StateMachine; */ @SpringBootTest @Slf4j +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) public class DrcStateMachineTest { @Autowired - DrcMachineService drcMachineService; + MachineCommandManager machineCommandManager; - @Test - public void testDrcMachineService(){ + @Autowired + MqttCallbackRegistry mqttCallbackRegistry; - String sn = "airport-001"; - /** - * 不存在的会报错,需要在 MachinePlatTypeRepository 里面定义有这个机场编号 - */ - try { - StateMachine stateMachine = - drcMachineService.getOrCreateStateMachine("airport-001--2"); - }catch (RuntimeException runtimeException){} + private static final ScheduledExecutorService scheduler = + Executors.newScheduledThreadPool(2); - StateMachine stateMachine = drcMachineService.getStateMachine("airport-001"); - drcMachineService.getOrCreateStateMachine("airport-001"); - stateMachine = drcMachineService.getStateMachine("airport-001"); - /** - * 打印一下当前的状态 - */ - log.debug(drcMachineService.getCurrentStates("airport-001")); + private Boolean initState = false; - /** - * 从UnKnown状态可以走到任意状态 - */ - drcMachineService.sendEvent(sn,DrcEvent.ENTERED); + private static final String SN = "SN9527"; - /** - * ENTERED无法进入ENTERING DrcMachineConfig 里面配置的 - */ - log.debug(String.valueOf(drcMachineService.sendEvent(sn,DrcEvent.ENTERING))); - - /** - * 现在是 ENTERED,但是你还想进入ENTERED ,这个是不可以的 - */ - log.debug(String.valueOf(drcMachineService.sendEvent(sn,DrcEvent.ENTERED))); - - /** - * 打印一下当前的状态 - */ - log.debug(drcMachineService.getCurrentStates("airport-001")); - - /** - * 变成退出中;这个时候需要在 - * DjiCanExitGuard 判断是否可以执行 - * DjiExitAction 执行远程方法,远程方法本身执行成功则不抛出异常,否则抛出异常 - */ - log.debug(String.valueOf(drcMachineService.sendEvent(sn,DrcEvent.EXITING))); - - /** - * 打印一下当前的状态 - * 修改 stateContext 里面的实现,就可以跳过某些状态 - */ - log.debug(drcMachineService.getCurrentStates("airport-001")); - -; - -// log.debug(String.valueOf(drcMachineService.sendEvent(sn,DrcEvent.EXITED))); -// -// log.debug(drcMachineService.getCurrentStates("airport-001")); + @BeforeEach + public void init(){ + if(initState){ + return; + } + initState = true; + machineCommandManager.bindMachine(SN,"DJI"); } + @Test + @Order(1) + public void checkInitState(){ + MachineStates machineStates = machineCommandManager.getMachineStates(SN); + assertNotNull(machineStates); + assertEquals(AirportState.UNKNOWN, machineStates.getAirportState()); + assertEquals(DrcState.UNKNOWN, machineStates.getDrcState()); + assertEquals(CoverState.UNKNOWN, machineStates.getCoverState()); + assertEquals(DroneState.UNKNOWN, machineStates.getDroneState()); + assertEquals(StopState.UNKNOWN, machineStates.getStopState()); + } + + /** + * 非在线状态下不可起飞 + * @throws ExecutionException + * @throws InterruptedException + */ + @Test + @Order(2) + public void checkTakeOffCommand() throws ExecutionException, InterruptedException { + CompletableFuture future = + machineCommandManager.executeCommand(SN, CommandType.TAKE_OFF,new HashMap<>()); + assertFalse(future.get().isSuccess()); + } + + @Test + @Order(3) + public void setState() { + + MachineStates machineStates = new MachineStates(); + machineStates.setAirportState(AirportState.ONLINE); + machineStates.setDroneState(DroneState.ONLINE); + machineCommandManager.updateMachineStates(SN, machineStates); + + machineStates = machineCommandManager.getMachineStates(SN); + assertNotNull(machineStates); + assertEquals(AirportState.ONLINE, machineStates.getAirportState()); + assertEquals(DroneState.ONLINE, machineStates.getDroneState()); + assertEquals(DrcState.UNKNOWN, machineStates.getDrcState()); + assertEquals(CoverState.UNKNOWN, machineStates.getCoverState()); + assertEquals(StopState.UNKNOWN, machineStates.getStopState()); + + } + +// @Test +// @Order(4) +// public void checkTakeOffOverTime1() throws ExecutionException, InterruptedException, TimeoutException { +// /** +// * 指令执行超时;因为缺乏指令成功的回调 +// */ +// CompletableFuture future = +// machineCommandManager.executeCommand(SN, CommandType.TAKE_OFF,new HashMap<>()); +// assertFalse(future.get().isSuccess()); +// +// } + + /** + * 指令执行成功,因为mqttCallbackRegistry模拟了发送回调 + * 需要将 DjiTakeOffInstruction 的 getStateCallbackConfig 中直接返回null + */ +// @Test +// @Order(5) +// public void checkTakeOffOverTime2() throws ExecutionException, InterruptedException, TimeoutException { +// +// CompletableFuture future = +// machineCommandManager.executeCommand(SN, CommandType.TAKE_OFF,new HashMap<>()); +// +// scheduler.schedule(new Runnable() { +// @Override +// public void run() { +// String response = "{\"data\":{\"result\":\"takeoff\"}}"; +// mqttCallbackRegistry.handleMessage("dji/SN9527/response",response); +// } +// },100,TimeUnit.MILLISECONDS); +// +// assertTrue(future.get().isSuccess()); +// +// } + + /** + * 指令执行失败 + * 需要将 DjiTakeOffInstruction 的 getStateCallbackConfig 中的注释放开 + */ +// @Test +// @Order(5) +// public void checkTakeOffOverTime2() throws ExecutionException, InterruptedException, TimeoutException { +// +// CompletableFuture future = +// machineCommandManager.executeCommand(SN, CommandType.TAKE_OFF,new HashMap<>()); +// +// scheduler.schedule(new Runnable() { +// @Override +// public void run() { +// String response = "{\"data\":{\"result\":\"takeoff\"}}"; +// mqttCallbackRegistry.handleMessage("dji/SN9527/response",response); +// } +// },100,TimeUnit.MILLISECONDS); +// +// assertFalse(future.get().isSuccess()); +// } + + /** + * 需要将 DjiTakeOffInstruction 的 getStateCallbackConfig 中的注释放开 + * @throws ExecutionException + * @throws InterruptedException + * @throws TimeoutException + */ + @Test + @Order(5) + public void checkTakeOffOverTime2() throws ExecutionException, InterruptedException, TimeoutException { + + CompletableFuture future = + machineCommandManager.executeCommand(SN, CommandType.TAKE_OFF,new HashMap<>()); + + scheduler.schedule(new Runnable() { + @Override + public void run() { + String response = "{\"data\":{\"result\":\"takeoff\"}}"; + mqttCallbackRegistry.handleMessage("dji/SN9527/response",response); + + // 添加延迟,等待状态回调监听器注册 + try { + Thread.sleep(50); // 等待50ms + } catch (InterruptedException e) { + e.printStackTrace(); + } + + response = "{\"droneState\":\"FLYING\"}"; + mqttCallbackRegistry.handleMessage("dji/SN9527/state",response); + } + },100,TimeUnit.MILLISECONDS); + + assertTrue(future.get().isSuccess()); + } }