添加一键起飞和返航接口

This commit is contained in:
孙小云 2026-02-24 10:35:02 +08:00
parent a367415167
commit 75b7b1ba09
4 changed files with 174 additions and 14 deletions

View File

@ -100,20 +100,32 @@ public class AircraftFlyController extends BaseController
/**
* 无人机起飞接口
*
* @param dockId 机场ID
* @return 起飞响应任务ID和任务状态
* @param sn 机场SN号
* @return 起飞响应
*/
@Operation(summary = "无人机起飞", description = "控制指定机场的无人机执行起飞操作返回任务ID和当前任务状态")
@PostMapping("/takeoff/{dockId}")
public R<DroneTakeoffResponseVO> takeoff(
@Parameter(description = "机场ID", required = true, example = "1")
@PathVariable("dockId") Long dockId)
@Operation(summary = "无人机起飞", description = "控制指定机场的无人机执行起飞操作")
@PostMapping("/takeoff/{sn}")
public R<String> takeoff(
@Parameter(description = "机场SN号", required = true, example = "THJSQ03B2309DN7VQN43")
@PathVariable("sn") String sn)
{
// TODO: 实现起飞逻辑
DroneTakeoffResponseVO vo = new DroneTakeoffResponseVO();
vo.setTaskId(1L);
vo.setMissionStatus(DroneMissionStatusEnum.TAKING_OFF);
return R.ok(vo);
log.info("收到无人机起飞请求: sn={}", sn);
try {
CompletableFuture<CommandResult> future = machineCommandManager.executeCommand(sn, CommandType.TAKE_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());
}
}
/**
@ -286,4 +298,35 @@ public class AircraftFlyController extends BaseController
return R.fail("回舱命令执行异常: " + e.getMessage());
}
}
/**
* 无人机返航接口
*
* @param sn 机场SN号
* @return 返航响应
*/
@Operation(summary = "无人机返航", description = "控制指定机场的无人机执行返航操作")
@PostMapping("/return-home/{sn}")
public R<String> returnHome(
@Parameter(description = "机场SN号", required = true, example = "THJSQ03B2309DN7VQN43")
@PathVariable("sn") String sn)
{
log.info("收到无人机返航请求: sn={}", sn);
try {
CompletableFuture<CommandResult> future = machineCommandManager.executeCommand(sn, CommandType.RETURN_HOME);
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());
}
}
}

View File

@ -65,8 +65,7 @@ public class TuohengVendorConfig implements VendorConfig {
case RETURN_HOME:
// 返航前置条件无人机飞行中
return droneState == DroneState.FLYING
|| droneState == DroneState.ARRIVED;
return true;
default:
return true;
@ -113,6 +112,18 @@ public class TuohengVendorConfig implements VendorConfig {
.setTimeout(60000);
transactionMap.put(coverCloseTransaction.getCommandType(), coverCloseTransaction);
// 返航命令
Transaction returnHomeTransaction = new Transaction("返航", CommandType.RETURN_HOME)
.root(new com.ruoyi.device.domain.impl.machine.vendor.tuoheng.instruction.TuohengReturnHomeInstruction())
.setTimeout(15000);
transactionMap.put(returnHomeTransaction.getCommandType(), returnHomeTransaction);
// 起飞命令
Transaction takeOffTransaction = new Transaction("起飞", CommandType.TAKE_OFF)
.root(new com.ruoyi.device.domain.impl.machine.vendor.tuoheng.instruction.TuohengTakeOffInstruction())
.setTimeout(300000);
transactionMap.put(takeOffTransaction.getCommandType(), takeOffTransaction);
log.info("拓恒厂家配置初始化完成,共配置{}个命令", transactionMap.size());
}
}

View File

@ -0,0 +1,52 @@
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 TuohengReturnHomeInstruction extends AbstractInstruction {
@Override
public String getName() {
return "TUOHENG_RETURN_HOME";
}
@Override
public void executeRemoteCall(InstructionContext context) throws Exception {
String sn = context.getSn();
log.info("发送拓恒无人机返航指令: sn={}", sn);
JSONObject payload = new JSONObject();
payload.put("messageID", System.currentTimeMillis());
payload.put("timestamp", System.currentTimeMillis());
payload.put("zhilin", "03");
String topic = "/topic/v1/airportFly/" + sn + "/control";
context.getMqttClient().sendMessage(topic, payload.toJSONString());
log.info("拓恒返航指令发送成功: topic={}, payload={}", topic, payload.toJSONString());
}
@Override
public CallbackConfig getMethodCallbackConfig(InstructionContext context) {
String sn = context.getSn();
return CallbackConfig.builder()
.topic("/topic/v1/airportFly/" + sn + "/control/confirm")
.fieldPath("msg")
.expectedValue("[综管]立即返航指令接收成功")
.timeoutMs(10000)
.build();
}
@Override
public CallbackConfig getStateCallbackConfig(InstructionContext context) {
return null; // 返航不需要状态回调
}
@Override
public long getTimeoutMs() {
return 15000;
}
}

View File

@ -0,0 +1,54 @@
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 TuohengTakeOffInstruction extends AbstractInstruction {
@Override
public String getName() {
return "TUOHENG_TAKE_OFF";
}
@Override
public void executeRemoteCall(InstructionContext context) throws Exception {
String sn = context.getSn();
log.info("发送拓恒无人机起飞指令: sn={}", sn);
long timestamp = System.currentTimeMillis();
JSONObject param = new JSONObject();
param.put("airlineFileUrl", "http://45.120.103.238:8899/waypoint/default.waypoints");
param.put("flyBatteryMin", 0.3);
param.put("isMustFly", 1);
JSONObject payload = new JSONObject();
payload.put("messageID", String.valueOf(timestamp));
payload.put("timestamp", timestamp);
payload.put("action", "airlineFlight");
payload.put("param", param);
String topic = "/topic/v1/airportFly/" + 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 300000;
}
}