处理机场飞行控制数据

This commit is contained in:
孙小云 2026-02-27 14:15:31 +08:00
parent b7fee49c77
commit 9f6b5f21bb
5 changed files with 109 additions and 45 deletions

View File

@ -2,11 +2,7 @@ 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.DroneCurrentStatusVO;
import com.ruoyi.device.api.domain.DroneFlightControlRequest;
import com.ruoyi.device.api.domain.DroneRealtimeInfoVO;
import com.ruoyi.device.api.domain.DroneTakeoffResponseVO;
import com.ruoyi.device.api.domain.MachineStateVO;
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;
@ -19,6 +15,8 @@ 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;
/**
@ -156,32 +154,38 @@ public class AircraftFlyController extends BaseController
}
/**
* 无人机起飞接口
* 无人机一键起飞
*
* @param sn 机场SN号
* @param request 起飞请求对象
* @return 起飞响应
*/
@Operation(summary = "无人机起飞", description = "控制指定机场的无人机执行起飞操作")
@PostMapping("/takeoff/{sn}")
public R<String> takeoff(
@Parameter(description = "机场SN号", required = true, example = "THJSQ03B2309DN7VQN43")
@PathVariable("sn") String sn)
@Operation(summary = "无人机一键起飞", description = "控制指定机场的无人机执行起飞操作")
@PostMapping("/takeoff")
public R<String> takeoff(@RequestBody DroneTakeoffRequest request)
{
log.info("收到无人机起飞请求: sn={}", sn);
log.info("收到无人机起飞请求: sn={}, messageID={}", request.getSn(), request.getMessageID());
try {
CompletableFuture<CommandResult> future = machineCommandManager.executeCommand(sn, CommandType.TAKE_OFF);
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={}", sn);
log.info("无人机起飞成功: sn={}", request.getSn());
return R.ok("起飞命令执行成功");
} else {
log.error("无人机起飞失败: sn={}, reason={}", sn, result.getErrorMessage());
log.error("无人机起飞失败: sn={}, reason={}", request.getSn(), result.getErrorMessage());
return R.fail("起飞命令执行失败: " + result.getErrorMessage());
}
} catch (Exception e) {
log.error("无人机起飞异常: sn={}", sn, e);
log.error("无人机起飞异常: sn={}", request.getSn(), e);
return R.fail("起飞命令执行异常: " + e.getMessage());
}
}
@ -360,30 +364,36 @@ public class AircraftFlyController extends BaseController
/**
* 无人机返航接口
*
* @param sn 机场SN号
* @param request 返航请求对象
* @return 返航响应
*/
@Operation(summary = "无人机返航", description = "控制指定机场的无人机执行返航操作")
@PostMapping("/return-home/{sn}")
public R<String> returnHome(
@Parameter(description = "机场SN号", required = true, example = "THJSQ03B2309DN7VQN43")
@PathVariable("sn") String sn)
@PostMapping("/return-home")
public R<String> returnHome(@RequestBody DroneReturnHomeRequest request)
{
log.info("收到无人机返航请求: sn={}", sn);
log.info("收到无人机返航请求: sn={}, messageID={}, taskId={}", request.getSn(), request.getMessageID(), request.getTaskId());
try {
CompletableFuture<CommandResult> future = machineCommandManager.executeCommand(sn, CommandType.RETURN_HOME);
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={}", sn);
log.info("无人机返航成功: sn={}", request.getSn());
return R.ok("返航命令执行成功");
} else {
log.error("无人机返航失败: sn={}, reason={}", sn, result.getErrorMessage());
log.error("无人机返航失败: sn={}, reason={}", request.getSn(), result.getErrorMessage());
return R.fail("返航命令执行失败: " + result.getErrorMessage());
}
} catch (Exception e) {
log.error("无人机返航异常: sn={}", sn, e);
log.error("无人机返航异常: sn={}", request.getSn(), e);
return R.fail("返航命令执行异常: " + e.getMessage());
}
}

View File

@ -82,4 +82,23 @@ public class InstructionContext {
public Object getCommandParam(String key) {
return commandParams.get(key);
}
/**
* 获取命令参数并转换为指定类型
* @param key 参数键
* @param type 目标类型
* @param <T> 泛型类型
* @return 转换后的参数值如果不存在或类型不匹配则返回null
*/
@SuppressWarnings("unchecked")
public <T> T getCommandParam(String key, Class<T> type) {
Object value = commandParams.get(key);
if (value == null) {
return null;
}
if (type.isInstance(value)) {
return (T) value;
}
return null;
}
}

View File

@ -59,9 +59,8 @@ public class TuohengVendorConfig implements VendorConfig {
&& droneState == DroneState.ONLINE;
case TAKE_OFF:
// 起飞前置条件无人机已开机机场在线
return droneState == DroneState.ONLINE
&& airportState == AirportState.ONLINE;
// 起飞前置条件机场在线
return airportState == AirportState.ONLINE;
case RETURN_HOME:
// 返航前置条件无人机飞行中

View File

@ -19,10 +19,35 @@ public class TuohengReturnHomeInstruction extends AbstractInstruction {
String sn = context.getSn();
log.info("发送拓恒无人机返航指令: sn={}", sn);
long timestamp = System.currentTimeMillis();
// 从上下文获取 messageID如果没有则使用时间戳
Long messageID = context.getCommandParam("messageID", Long.class);
if (messageID == null) {
messageID = timestamp;
}
// 从上下文获取 taskId如果没有则使用默认值
Long taskId = context.getCommandParam("taskId", Long.class);
if (taskId == null) {
taskId = 9074L;
}
// 从上下文获取 zhilin如果没有则使用默认值
String zhilin = context.getCommandParam("zhilin", String.class);
if (zhilin == null) {
zhilin = "03";
}
JSONObject param = new JSONObject();
param.put("zhilin", zhilin);
param.put("taskId", taskId);
JSONObject payload = new JSONObject();
payload.put("messageID", System.currentTimeMillis());
payload.put("timestamp", System.currentTimeMillis());
payload.put("zhilin", "03");
payload.put("param", param);
payload.put("messageID", messageID);
payload.put("action", "immediateReturn");
payload.put("timestamp", timestamp);
String topic = "/topic/v1/airportFly/" + sn + "/control";
context.getMqttClient().sendMessage(topic, payload.toJSONString());
@ -31,13 +56,7 @@ public class TuohengReturnHomeInstruction extends AbstractInstruction {
@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();
return null; // 移除方法回调避免回调不匹配问题
}
@Override

View File

@ -21,16 +21,33 @@ public class TuohengTakeOffInstruction extends AbstractInstruction {
long timestamp = System.currentTimeMillis();
// 从上下文获取 messageID如果没有则使用时间戳
Long messageID = context.getCommandParam("messageID", Long.class);
if (messageID == null) {
messageID = timestamp;
}
// 从上下文获取 airlineFileUrl如果没有则使用默认值
String airlineFileUrl = context.getCommandParam("airlineFileUrl", String.class);
if (airlineFileUrl == null) {
airlineFileUrl = "https://minio-jndsj.t-aaron.com:2443/th-airport/testFile/13912c62-b96f-4df5-ab65-813c8c4b04eb.waypoints";
}
// 从上下文获取 flyBatteryMin如果没有则使用默认值
Double flyBatteryMin = context.getCommandParam("flyBatteryMin", Double.class);
if (flyBatteryMin == null) {
flyBatteryMin = 0.3;
}
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);
param.put("flyBatteryMin", flyBatteryMin);
param.put("airlineFileUrl", airlineFileUrl);
JSONObject payload = new JSONObject();
payload.put("messageID", String.valueOf(timestamp));
payload.put("timestamp", timestamp);
payload.put("action", "airlineFlight");
payload.put("messageID", String.valueOf(messageID));
payload.put("param", param);
payload.put("timestamp", timestamp);
String topic = "/topic/v1/airportFly/" + sn + "/control";
context.getMqttClient().sendMessage(topic, payload.toJSONString());