diff --git a/cmvr-iot-admin/src/main/java/com/cmvr/web/controller/api/EdgeAgvController.java b/cmvr-iot-admin/src/main/java/com/cmvr/web/controller/api/EdgeAgvController.java new file mode 100644 index 0000000..7449e8c --- /dev/null +++ b/cmvr-iot-admin/src/main/java/com/cmvr/web/controller/api/EdgeAgvController.java @@ -0,0 +1,169 @@ +package com.cmvr.web.controller.api; + +import cmvr.api.AgvCommand; +import com.cmvr.common.core.domain.AjaxResult; +import com.cmvr.edge.client.model.EdgeCommonVO; +import com.cmvr.edge.client.model.agv.*; +import com.cmvr.edge.client.service.EdgeAgvService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.ArrayList; +import java.util.List; + +/** + * 边缘系统AGV控制器 + * + * @author cmvr-iot + * @since 2026-07-01 + */ +@Api(tags = "边缘--AGV") +@RestController +@RequestMapping("/api/agv") +@RequiredArgsConstructor +public class EdgeAgvController { + + private final EdgeAgvService edgeAgvService; + + @ApiOperation("获取AGV状态信息") + @GetMapping("/getStatusInfo") + public AjaxResult getStatusInfo(EdgeCommonVO vo) { + AgvCommand.AgvStatusInfo statusInfo = edgeAgvService.getStatusInfo(vo); + // 直接返回对象,Jackson会自动序列化 + return AjaxResult.ok(statusInfo); + } + + @ApiOperation("获取机器人位置") + @GetMapping("/getRobotLocation") + public AjaxResult getRobotLocation(EdgeCommonVO vo) { + AgvCommand.AgvRobotLocation location = edgeAgvService.getRobotLocation(vo); + return AjaxResult.ok(location); + } + + @ApiOperation("获取地图状态") + @GetMapping("/getMapStatus") + public AjaxResult getMapStatus(EdgeCommonVO vo) { + AgvCommand.AgvMapStatus mapStatus = edgeAgvService.getMapStatus(vo); + return AjaxResult.ok(mapStatus); + } + + @ApiOperation("下载地图") + @GetMapping("/downloadMap") + public AjaxResult downloadMap(EdgeCommonVO vo, + @ApiParam("地图名称") String mapName) { + AgvCommand.AgvDownloadMapResult result = edgeAgvService.robotConfigDownloadMap(vo, mapName); + return AjaxResult.ok(result); + } + + @ApiOperation("上传地图") + @PostMapping("/uploadMap") + public AjaxResult uploadMap(EdgeCommonVO vo, + @ApiParam("地图内容") String mapContent) { + AgvCommand.AgvUploadMapResult result = edgeAgvService.robotConfigUploadMap(vo, mapContent); + java.util.Map resultMap = new java.util.HashMap<>(); + resultMap.put("retCode", result.getRetCode()); + resultMap.put("errMsg", result.getErrMsg()); + return AjaxResult.ok(resultMap); + } + + @ApiOperation("获取电池状态") + @GetMapping("/getBatteryStatus") + public AjaxResult getBatteryStatus(EdgeCommonVO vo) { + AgvCommand.AgvBatteryStatus batteryStatus = edgeAgvService.getBatteryStatus(vo); + return AjaxResult.ok(batteryStatus); + } + + @ApiOperation("导航到指定站点") + @GetMapping("/goToStation") + public AjaxResult goToStation(EdgeCommonVO vo, + @ApiParam("起始站点ID") String sourceId, + @ApiParam("目标站点ID") String targetId, + @ApiParam("任务ID") String taskId, + @ApiParam("操作类型") String operation, + @ApiParam("顶升高度") Double jackHeight) { + AgvCommand.RobotGoTargetResData result = edgeAgvService.robotGoTarget( + vo, sourceId, targetId, taskId, operation, jackHeight + ); + return AjaxResult.ok(result); + } + + @ApiOperation("自由导航到坐标点") + @GetMapping("/freeGo") + public AjaxResult freeGo(EdgeCommonVO vo, + @ApiParam("X坐标") double x, + @ApiParam("Y坐标") double y, + @ApiParam("角度") double theta, + @ApiParam("任务ID") String taskId) { + // 构建自由导航点 + AgvCommand.FreeGoPoint freeGoPoint = AgvCommand.FreeGoPoint.newBuilder() + .setX(x) + .setY(y) + .setTheta(theta) + .build(); + + AgvCommand.RobotGoTargetResData result = edgeAgvService.robotGoTargetWithFreeGo( + vo, freeGoPoint, taskId + ); + return AjaxResult.ok(result); + } + + @ApiOperation("暂停导航任务") + @GetMapping("/pauseTask") + public AjaxResult pauseTask(EdgeCommonVO vo) { + edgeAgvService.robotTaskPause(vo); + return AjaxResult.ok(); + } + + @ApiOperation("继续导航任务") + @GetMapping("/resumeTask") + public AjaxResult resumeTask(EdgeCommonVO vo) { + edgeAgvService.robotTaskResume(vo); + return AjaxResult.ok(); + } + + @ApiOperation("取消导航任务") + @GetMapping("/cancelTask") + public AjaxResult cancelTask(EdgeCommonVO vo) { + edgeAgvService.robotTaskCancel(vo); + return AjaxResult.ok(); + } + + @ApiOperation("查询当前导航状态") + @GetMapping("/getTaskStatus") + public AjaxResult getTaskStatus(EdgeCommonVO vo, + @ApiParam("是否简化返回") boolean simple) { + AgvCommand.RobotStatusTaskResData taskData = edgeAgvService.getRobotStatusTaskCurrent(vo, simple); + return AjaxResult.ok(taskData); + } + + @ApiOperation("查询站点列表") + @GetMapping("/getStationList") + public AjaxResult getStationList(EdgeCommonVO vo) { + AgvCommand.QueryStationListResult result = edgeAgvService.queryStationList(vo); + return AjaxResult.ok(result); + } + + @ApiOperation("切换地图") + @GetMapping("/loadMap") + public AjaxResult loadMap(EdgeCommonVO vo, + @ApiParam("地图名称") String mapName) { + AgvCommand.RobotLoadMapResult result = edgeAgvService.robotLoadMap(vo, mapName); + java.util.Map resultMap = new java.util.HashMap<>(); + resultMap.put("retCode", result.getRetCode()); + resultMap.put("errMsg", result.getErrMsg()); + return AjaxResult.ok(resultMap); + } + + @ApiOperation("查询地图加载状态") + @GetMapping("/getLoadMapStatus") + public AjaxResult getLoadMapStatus(EdgeCommonVO vo) { + AgvCommand.RobotQueryLoadMapStatusResult result = edgeAgvService.queryLoadMapStatus(vo); + return AjaxResult.ok(result); + } +} diff --git a/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-client/src/main/java/com/cmvr/edge/client/model/agv/EdgeAgvBatteryStatusVO.java b/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-client/src/main/java/com/cmvr/edge/client/model/agv/EdgeAgvBatteryStatusVO.java new file mode 100644 index 0000000..9566c4f --- /dev/null +++ b/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-client/src/main/java/com/cmvr/edge/client/model/agv/EdgeAgvBatteryStatusVO.java @@ -0,0 +1,28 @@ +package com.cmvr.edge.client.model.agv; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * AGV电池状态VO + * + * @author cmvr-iot + * @since 2026-07-01 + */ +@Data +@ApiModel("AGV电池状态") +public class EdgeAgvBatteryStatusVO { + + @ApiModelProperty("电池电量百分比(0-100)") + private double batteryPercent; + + @ApiModelProperty("电池电压(单位:伏特)") + private double voltage; + + @ApiModelProperty("电池电流(单位:安培)") + private double current; + + @ApiModelProperty("充电状态(true=充电中,false=未充电)") + private boolean charging; +} diff --git a/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-client/src/main/java/com/cmvr/edge/client/model/agv/EdgeAgvNavigationResultVO.java b/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-client/src/main/java/com/cmvr/edge/client/model/agv/EdgeAgvNavigationResultVO.java new file mode 100644 index 0000000..441adb5 --- /dev/null +++ b/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-client/src/main/java/com/cmvr/edge/client/model/agv/EdgeAgvNavigationResultVO.java @@ -0,0 +1,25 @@ +package com.cmvr.edge.client.model.agv; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * AGV导航任务结果VO + * + * @author cmvr-iot + * @since 2026-07-01 + */ +@Data +@ApiModel("AGV导航任务结果") +public class EdgeAgvNavigationResultVO { + + @ApiModelProperty("返回码(0=成功)") + private int retCode; + + @ApiModelProperty("错误信息") + private String errMsg; + + @ApiModelProperty("任务ID") + private String taskId; +} diff --git a/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-client/src/main/java/com/cmvr/edge/client/model/agv/EdgeAgvRobotLocationVO.java b/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-client/src/main/java/com/cmvr/edge/client/model/agv/EdgeAgvRobotLocationVO.java new file mode 100644 index 0000000..55160f8 --- /dev/null +++ b/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-client/src/main/java/com/cmvr/edge/client/model/agv/EdgeAgvRobotLocationVO.java @@ -0,0 +1,28 @@ +package com.cmvr.edge.client.model.agv; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * AGV机器人位置VO + * + * @author cmvr-iot + * @since 2026-07-01 + */ +@Data +@ApiModel("AGV机器人位置") +public class EdgeAgvRobotLocationVO { + + @ApiModelProperty("X坐标(单位:米)") + private double x; + + @ApiModelProperty("Y坐标(单位:米)") + private double y; + + @ApiModelProperty("角度(单位:弧度)") + private double theta; + + @ApiModelProperty("地图名称") + private String mapName; +} diff --git a/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-client/src/main/java/com/cmvr/edge/client/model/agv/EdgeAgvStationVO.java b/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-client/src/main/java/com/cmvr/edge/client/model/agv/EdgeAgvStationVO.java new file mode 100644 index 0000000..8675ba8 --- /dev/null +++ b/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-client/src/main/java/com/cmvr/edge/client/model/agv/EdgeAgvStationVO.java @@ -0,0 +1,37 @@ +package com.cmvr.edge.client.model.agv; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * AGV站点信息VO + * + * @author cmvr-iot + * @since 2026-07-01 + */ +@Data +@ApiModel("AGV站点信息") +public class EdgeAgvStationVO { + + @ApiModelProperty("站点ID") + private String stationId; + + @ApiModelProperty("站点名称") + private String stationName; + + @ApiModelProperty("X坐标(单位:米)") + private double x; + + @ApiModelProperty("Y坐标(单位:米)") + private double y; + + @ApiModelProperty("角度(单位:弧度)") + private double theta; + + @ApiModelProperty("站点类型") + private String stationType; + + @ApiModelProperty("站点描述") + private String description; +} diff --git a/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-client/src/main/java/com/cmvr/edge/client/model/agv/EdgeAgvTaskStatusVO.java b/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-client/src/main/java/com/cmvr/edge/client/model/agv/EdgeAgvTaskStatusVO.java new file mode 100644 index 0000000..cd2d1d1 --- /dev/null +++ b/cmvr-iot-api/cmvr-iot-edge/cmvr-iot-grpc-client/src/main/java/com/cmvr/edge/client/model/agv/EdgeAgvTaskStatusVO.java @@ -0,0 +1,31 @@ +package com.cmvr.edge.client.model.agv; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * AGV任务状态VO + * + * @author cmvr-iot + * @since 2026-07-01 + */ +@Data +@ApiModel("AGV任务状态") +public class EdgeAgvTaskStatusVO { + + @ApiModelProperty("任务状态") + private int taskStatus; + + @ApiModelProperty("当前站点ID") + private String currentStationId; + + @ApiModelProperty("目标站点ID") + private String targetStationId; + + @ApiModelProperty("已经过的站点数量") + private int passedStationCount; + + @ApiModelProperty("剩余站点数量") + private int remainingStationCount; +}