From 55315e00d0219e437c732d519cef051e3a25f647 Mon Sep 17 00:00:00 2001 From: cbs <18617195505@163.com> Date: Wed, 23 Apr 2025 14:08:54 +0800 Subject: [PATCH] =?UTF-8?q?=E8=BD=A6=E8=BE=86=E5=8C=B9=E9=85=8D=E8=B7=AF?= =?UTF-8?q?=E7=BD=91/=E8=BF=9C=E9=81=A5=E5=88=87=E6=8D=A2=E6=A8=A1?= =?UTF-8?q?=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/remote/RemotePathPlanningDTO.java | 11 + .../yudao/module/mqtt/config/MqttFactory.java | 2 + .../module/mqtt/enums/DefineSubTopicEnum.java | 3 +- .../PlanningGraphMatchDataServiceImpl.java | 25 ++ .../admin/robot/RemoteRobotController.java | 15 +- .../robot/dto/RemoteRobotChangeModeDTO.java | 18 ++ .../service/robot/RemoteRobotService.java | 9 + .../service/robot/RemoteRobotServiceImpl.java | 15 ++ .../yudao/module/system/api/path/PathApi.java | 4 + .../system/api/remote/RemoteRobotApi.java | 10 +- .../system/enums/ErrorCodeConstants.java | 10 + .../module/system/api/path/PathApiImpl.java | 11 + .../system/api/remote/RemoteRobotApiImpl.java | 24 +- .../path/PathPlanningChcheConstant.java | 3 + .../path/PathPlanningTopicConstant.java | 15 ++ .../admin/path/dto/GraphMatchDataDTO.java | 19 ++ .../enums/robot/remote/RemoteModeEnum.java | 26 ++ .../service/path/PathPlanningService.java | 11 + .../service/path/PathPlanningServiceImpl.java | 23 ++ .../RemoteControllerInformationService.java | 13 + ...emoteControllerInformationServiceImpl.java | 251 +++++++++++++++++- .../robot/RobotInformationService.java | 24 ++ .../robot/RobotInformationServiceImpl.java | 163 +++++++++--- .../robot/job/DistributeTasksServiceImpl.java | 15 +- 24 files changed, 669 insertions(+), 51 deletions(-) create mode 100644 yudao-module-mqtt/yudao-module-mqtt-api/src/main/java/cn/iocoder/yudao/module/mqtt/api/path/dto/remote/RemotePathPlanningDTO.java create mode 100644 yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/service/PlanningGraphMatchDataServiceImpl.java create mode 100644 yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/controller/admin/robot/dto/RemoteRobotChangeModeDTO.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/path/dto/GraphMatchDataDTO.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/enums/robot/remote/RemoteModeEnum.java diff --git a/yudao-module-mqtt/yudao-module-mqtt-api/src/main/java/cn/iocoder/yudao/module/mqtt/api/path/dto/remote/RemotePathPlanningDTO.java b/yudao-module-mqtt/yudao-module-mqtt-api/src/main/java/cn/iocoder/yudao/module/mqtt/api/path/dto/remote/RemotePathPlanningDTO.java new file mode 100644 index 000000000..972862f67 --- /dev/null +++ b/yudao-module-mqtt/yudao-module-mqtt-api/src/main/java/cn/iocoder/yudao/module/mqtt/api/path/dto/remote/RemotePathPlanningDTO.java @@ -0,0 +1,11 @@ +package cn.iocoder.yudao.module.mqtt.api.path.dto.remote; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +public class RemotePathPlanningDTO { + + @Schema(description = "车辆编号") + private String robotNo; +} diff --git a/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/config/MqttFactory.java b/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/config/MqttFactory.java index 5793be367..3eee68b1d 100644 --- a/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/config/MqttFactory.java +++ b/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/config/MqttFactory.java @@ -159,6 +159,8 @@ public class MqttFactory { return BeanUtils.getBean(PathPlanningMoveServiceImpl.class); case PLANNING_ROUTE_DISPLAY: return BeanUtils.getBean(PathRouteDisplayPlanningServiceImpl.class); + case PLANNING_GRAPH_MATCH_DATA: + return BeanUtils.getBean(PlanningGraphMatchDataServiceImpl.class); default : return BeanUtils.getBean(RobotTaskStatusServiceImpl.class); } diff --git a/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/enums/DefineSubTopicEnum.java b/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/enums/DefineSubTopicEnum.java index e686b0cbe..81154d9db 100644 --- a/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/enums/DefineSubTopicEnum.java +++ b/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/enums/DefineSubTopicEnum.java @@ -27,7 +27,8 @@ public enum DefineSubTopicEnum { PLANNING_DISTRIBUTION_FAIL("TASK_ASSIGNMENT_FAIL", 2,"路径规划失败上报"), PLANNING_SIMULATION_ROBOT_POSE_REQUEST("SIMULATION_ROBOT_POSE_REQUEST", 2,"仿真初始化点位信息"), PLANNING_MOVE("UPDATE_ROUTE_DISPLAY_PLANNING", 2,"车辆即将走的点位"), - PLANNING_ROUTE_DISPLAY("ROBOT_MOVE_POSE_PLANNING", 2,"路径规划上报实时路径"); + PLANNING_ROUTE_DISPLAY("ROBOT_MOVE_POSE_PLANNING", 2,"路径规划上报实时路径"), + PLANNING_GRAPH_MATCH_DATA("GRAPH_MATCH_DATA", 2,"路网匹配实时数据"); private final String topic; diff --git a/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/service/PlanningGraphMatchDataServiceImpl.java b/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/service/PlanningGraphMatchDataServiceImpl.java new file mode 100644 index 000000000..a3dcd63d9 --- /dev/null +++ b/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/service/PlanningGraphMatchDataServiceImpl.java @@ -0,0 +1,25 @@ +package cn.iododer.yudao.module.mqtt.service; + +import cn.iocoder.yudao.module.system.api.path.PathApi; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; + +/** + * 路网匹配实时数据 + */ +@Slf4j +@Service +public class PlanningGraphMatchDataServiceImpl implements MqttService{ + + @Resource + private PathApi pathApi; + + @Override + public void analysisMessage(String message) { + log.info("匹配路网实时数据 :{}",message); + pathApi.graphMatchData(message); + } + +} diff --git a/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/controller/admin/robot/RemoteRobotController.java b/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/controller/admin/robot/RemoteRobotController.java index d09555a85..1eb5ba078 100644 --- a/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/controller/admin/robot/RemoteRobotController.java +++ b/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/controller/admin/robot/RemoteRobotController.java @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.remote.controller.admin.robot; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.module.remote.controller.admin.robot.dto.PositionMapRespDTO; +import cn.iocoder.yudao.module.remote.controller.admin.robot.dto.RemoteRobotChangeModeDTO; import cn.iocoder.yudao.module.remote.service.robot.RemoteRobotService; import cn.iocoder.yudao.module.system.api.remote.dto.RemoteRobotDTO; import cn.iocoder.yudao.module.system.api.remote.dto.RemoteRobotStatusDTO; @@ -14,6 +15,7 @@ import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletRequest; +import javax.validation.Valid; import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; @@ -37,7 +39,7 @@ public class RemoteRobotController { @GetMapping("/emergencyStopOrRecovery") @Operation(summary = "一键急停or一键恢复地图上所有AGV") @Parameter(name = "type", description = "类型(1:停止, 0:恢复)", required = true, example = "1024") - @PreAuthorize("@ss.hasPermission('system:position-map:emergencyStopOrRecovery')") + @PreAuthorize("@ss.hasPermission('remote:robot:emergencyStopOrRecovery')") public CommonResult remoteEmergencyStopOrRecovery(@RequestParam("id") Long id, @RequestParam("type") Integer type) { remoteRobotService.remoteEmergencyStopOrRecovery(id,type); return success(true); @@ -45,6 +47,7 @@ public class RemoteRobotController { @PostMapping("/getRobotRemoteStatus") @Operation(summary = "获取机器人远遥模式/急停/协控状态") + @PreAuthorize("@ss.hasPermission('remote:robot:getRobotRemoteStatus')") public CommonResult getRobotRemoteStatus(HttpServletRequest request) { return success(remoteRobotService.getRemoteRobotStatus(request)); } @@ -52,6 +55,7 @@ public class RemoteRobotController { @GetMapping("/stop") @Operation(summary = "暂停车辆") + @PreAuthorize("@ss.hasPermission('remote:robot:stop')") public CommonResult robotStop(@RequestParam("robotNo") String robotNo) { remoteRobotService.robotStop(robotNo); return success(true); @@ -60,12 +64,19 @@ public class RemoteRobotController { @GetMapping("/recovery") @Operation(summary = "恢复车辆") + @PreAuthorize("@ss.hasPermission('remote:robot:recovery')") public CommonResult recovery(@RequestParam("robotNo") String robotNo) { remoteRobotService.recovery(robotNo); return success(true); } - + @PostMapping("/robotChangeMode") + @Operation(summary = "获取机器人远遥模式/急停/协控状态") + @PreAuthorize("@ss.hasPermission('remote:robot:robotChangeMode')") + public CommonResult robotChangeMode(@Valid @RequestBody RemoteRobotChangeModeDTO data,HttpServletRequest request) { + remoteRobotService.robotChangeMode(data,request); + return success(true); + } } diff --git a/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/controller/admin/robot/dto/RemoteRobotChangeModeDTO.java b/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/controller/admin/robot/dto/RemoteRobotChangeModeDTO.java new file mode 100644 index 000000000..fd3cd0ee9 --- /dev/null +++ b/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/controller/admin/robot/dto/RemoteRobotChangeModeDTO.java @@ -0,0 +1,18 @@ +package cn.iocoder.yudao.module.remote.controller.admin.robot.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; + +@Data +public class RemoteRobotChangeModeDTO { + @Schema(description = "远遥模式(0:自动模式, 1:手动模式, 2:自由模式)") + @NotNull(message = "请选择远遥模式") + private Integer remoteMode = 0; + + @Schema(description = "车辆编号") + @NotEmpty(message = "请选择车辆编号") + private String robotNo ; +} diff --git a/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/service/robot/RemoteRobotService.java b/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/service/robot/RemoteRobotService.java index 300238eeb..1e9bdf6f8 100644 --- a/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/service/robot/RemoteRobotService.java +++ b/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/service/robot/RemoteRobotService.java @@ -1,10 +1,12 @@ package cn.iocoder.yudao.module.remote.service.robot; import cn.iocoder.yudao.module.remote.controller.admin.robot.dto.PositionMapRespDTO; +import cn.iocoder.yudao.module.remote.controller.admin.robot.dto.RemoteRobotChangeModeDTO; import cn.iocoder.yudao.module.system.api.remote.dto.RemoteRobotDTO; import cn.iocoder.yudao.module.system.api.remote.dto.RemoteRobotStatusDTO; import javax.servlet.http.HttpServletRequest; +import javax.validation.Valid; import java.util.List; public interface RemoteRobotService { @@ -41,4 +43,11 @@ public interface RemoteRobotService { * @param robotNo */ void recovery(String robotNo); + + /** + * 切换远遥模式 + * @param data + * @return + */ + void robotChangeMode( RemoteRobotChangeModeDTO data,HttpServletRequest request); } diff --git a/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/service/robot/RemoteRobotServiceImpl.java b/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/service/robot/RemoteRobotServiceImpl.java index a5b932324..83e22d643 100644 --- a/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/service/robot/RemoteRobotServiceImpl.java +++ b/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/service/robot/RemoteRobotServiceImpl.java @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.remote.service.robot; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.module.remote.controller.admin.robot.dto.PositionMapRespDTO; +import cn.iocoder.yudao.module.remote.controller.admin.robot.dto.RemoteRobotChangeModeDTO; import cn.iocoder.yudao.module.remote.util.IpUtils; import cn.iocoder.yudao.module.system.api.remote.RemoteRobotApi; import cn.iocoder.yudao.module.system.api.remote.dto.RemoteRobotDTO; @@ -82,4 +83,18 @@ public class RemoteRobotServiceImpl implements RemoteRobotService{ throw exception0(TASK_COMMONG_FAIL.getCode(), result.getMsg()); } } + + /** + * 切换远遥模式 + * @param data + * @return + */ + @Override + public void robotChangeMode(RemoteRobotChangeModeDTO data,HttpServletRequest request) { + String ip = IpUtils.getIp(request); + CommonResult result = remoteRobotApi.robotChangeMode(data.getRemoteMode(), ip, data.getRobotNo()); + if (!result.isSuccess()){ + throw exception0(TASK_COMMONG_FAIL.getCode(), result.getMsg()); + } + } } diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/path/PathApi.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/path/PathApi.java index 02f84fbdf..3813a201b 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/path/PathApi.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/path/PathApi.java @@ -36,4 +36,8 @@ public interface PathApi { @PostMapping(PREFIX + "/simulationRobotPose") @Operation(summary = "仿真初始化点位信息") void simulationRobotPoseRequest(@RequestParam("message") String message); + + @PostMapping(PREFIX + "/graphMatchData") + @Operation(summary = "路网匹配实时数据") + void graphMatchData(@RequestParam("message") String message); } diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/remote/RemoteRobotApi.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/remote/RemoteRobotApi.java index d25b354c3..2d8085832 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/remote/RemoteRobotApi.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/remote/RemoteRobotApi.java @@ -20,11 +20,11 @@ public interface RemoteRobotApi { @PostMapping(PREFIX + "/remoteGetAreaRobot") @Operation(summary = "获取地图区域对应的机器人信息") - List remoteGetAreaRobot(@RequestParam(value = "mapId",defaultValue = "-1") Long mapId); + List remoteGetAreaRobot(@RequestParam(value = "mapId", defaultValue = "-1") Long mapId); @PostMapping(PREFIX + "/remoteEmergencyStopOrRecovery") @Operation(summary = "一键急停or一键恢复地图上所有AGV") - CommonResult remoteEmergencyStopOrRecovery(@RequestParam(value = "mapId") Long mapId, @RequestParam(value = "type") Integer type); + CommonResult remoteEmergencyStopOrRecovery(@RequestParam(value = "mapId") Long mapId, @RequestParam(value = "type") Integer type); @PostMapping(PREFIX + "/getRemoteRobotStatus") @Operation(summary = "获取机器人远遥模式/急停/协控状态") @@ -37,4 +37,10 @@ public interface RemoteRobotApi { @PostMapping(PREFIX + "/recovery") @Operation(summary = "恢复机器人") CommonResult recovery(@RequestParam(value = "robotNo") String robotNo); + + @PostMapping(PREFIX + "/robotChangeMode") + @Operation(summary = "切换模式") + CommonResult robotChangeMode(@RequestParam(value = "remoteMode") Integer remoteMode, + @RequestParam(value = "ip") String ip, + @RequestParam(value = "robotNo") String robotNo); } diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java index 06f82c6dd..f39792aa9 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java @@ -196,6 +196,8 @@ public interface ErrorCodeConstants { ErrorCode ROBOT_HAVE_DOING_TASK = new ErrorCode(1-002-034-010, "车辆有处理中的任务,不允许修改/删除车辆编号和Mac地址"); ErrorCode ROBOT_REJECTION = new ErrorCode(1-002-034-011, "车辆已锁定"); ErrorCode ROBOT_DOING_REMOTE = new ErrorCode(1-002-034-012, "车辆目前远遥控制中,不能修改车辆信息"); + ErrorCode ROBOT_NOT_STAND_BY = new ErrorCode(1-002-034-013, "车辆非空闲"); + ErrorCode ROBOT_ELECTRICITY_INSUFFICIENT = new ErrorCode(1-002-034-014, "车辆电量不足"); // ========== 机器人任务主表 1-002-035-000 ========== ErrorCode TASK_NOT_EXISTS = new ErrorCode(1-002-035-001, "车辆任务主表不存在"); @@ -277,6 +279,14 @@ public interface ErrorCodeConstants { ErrorCode ROBOT_ALREADY_RECOVERY = new ErrorCode(1_002_052_003, "车辆已经恢复"); // ========== 远遥设备信息 1_002_053_001 ========== ErrorCode CONTROLLER_INFORMATION_NOT_EXISTS = new ErrorCode(1_002_053_001, "远遥设备信息不存在"); + ErrorCode REMOTE_DEVICE_NOT_SET_UP = new ErrorCode(1_002_053_002, "远遥设备未设置通讯信息"); + ErrorCode REMOTE_DEVICE_NEED_AUTOMATIC = new ErrorCode(1_002_053_003, "首次进入远遥设置,只能是自动模式"); + ErrorCode REMOTE_DEVICE_CONTROLLER = new ErrorCode(1_002_053_004, "目前远遥设备控制的机器人是 "); + ErrorCode REMOTE_NOT_HAVE_TASK = new ErrorCode(1_002_053_005, "车辆没有处理中的任务,不能切换成手动模式"); + ErrorCode REMOTE_HAVE_TASK = new ErrorCode(1_002_053_006, "车辆有处理中的任务,不能切换成自由模式"); + ErrorCode REMOTE_NOT_HAVE_PATH_MATCH = new ErrorCode(1_002_053_007, "车辆未匹配路网"); + ErrorCode REMOTE_AUTOMATIC_CAN_NOT_CHANGE_TO_FREE = new ErrorCode(1_002_053_008, "手动模式只能切换到自动模式"); + ErrorCode REMOTE_FREE_CAN_NOT_CHANGE_TO_HAND_MOVEMENT = new ErrorCode(1_002_053_009, "自由模式只能切换到自动模式"); // ========== 车辆摄像头信息 1_002_054_001 ========== ErrorCode CAMERA_NOT_EXISTS = new ErrorCode(1_002_054_001, "车辆摄像头信息不存在"); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/path/PathApiImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/path/PathApiImpl.java index 1dbc60d71..0a6f1eac2 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/path/PathApiImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/path/PathApiImpl.java @@ -49,6 +49,7 @@ public class PathApiImpl implements PathApi { taskExecutor.execute(() -> { TenantContextHolder.setTenantId(1L); log.info("初始化数据发送个PP---开始"); + pathPlanningService.synchronousStart(); //同步点位信息 PositionMapSaveReqVO positionMapSaveReqVO = new PositionMapSaveReqVO(); pathPlanningService.synchronousAllItem(positionMapSaveReqVO); @@ -115,5 +116,15 @@ public class PathApiImpl implements PathApi { pathPlanningService.simulationRobotPoseRequest(); } + /** + * 路网匹配实时数据 + * @param message + */ + @Override + public void graphMatchData(String message) { + TenantContextHolder.setTenantId(1L); + pathPlanningService.graphMatchData(message); + } + } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/remote/RemoteRobotApiImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/remote/RemoteRobotApiImpl.java index 410fea160..e868429cd 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/remote/RemoteRobotApiImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/remote/RemoteRobotApiImpl.java @@ -16,7 +16,7 @@ import java.util.List; @Slf4j @RestController // 提供 RESTful API 接口,给 Feign 调用 @Validated -public class RemoteRobotApiImpl implements RemoteRobotApi{ +public class RemoteRobotApiImpl implements RemoteRobotApi { @Resource private RobotMapStopService mapStopService; @@ -29,6 +29,7 @@ public class RemoteRobotApiImpl implements RemoteRobotApi{ /** * 远遥获取地图和车辆信息 + * * @param mapId * @return */ @@ -39,17 +40,19 @@ public class RemoteRobotApiImpl implements RemoteRobotApi{ /** * 远遥车辆暂停 + * * @param mapId * @param type */ @Override public CommonResult remoteEmergencyStopOrRecovery(Long mapId, Integer type) { - positionMapService.emergencyStopOrRecovery(mapId,type,true); + positionMapService.emergencyStopOrRecovery(mapId, type, true); return CommonResult.success(true); } /** * 获取机器人远遥模式/急停/协控状态 + * * @param ip * @return */ @@ -60,17 +63,19 @@ public class RemoteRobotApiImpl implements RemoteRobotApi{ /** * 远遥暂停车辆 + * * @param robotNo * @return */ @Override public CommonResult robotStop(String robotNo) { - mapStopService.remoteStopRobot(robotNo); + mapStopService.remoteStopRobot(robotNo); return CommonResult.success(true); } /** * 远遥恢复车辆 + * * @param robotNo * @return */ @@ -80,5 +85,18 @@ public class RemoteRobotApiImpl implements RemoteRobotApi{ return CommonResult.success(true); } + /** + * 远遥切换模式 + * + * @param remoteMode + * @param remoteIp + * @return + */ + @Override + public CommonResult robotChangeMode(Integer remoteMode, String remoteIp, String robotNo) { + controllerInformationService.robotChangeMode(remoteMode, remoteIp, robotNo); + return CommonResult.success(true); + } + } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/constant/path/PathPlanningChcheConstant.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/constant/path/PathPlanningChcheConstant.java index effbe5a2b..999f34e6d 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/constant/path/PathPlanningChcheConstant.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/constant/path/PathPlanningChcheConstant.java @@ -6,4 +6,7 @@ package cn.iocoder.yudao.module.system.constant.path; public class PathPlanningChcheConstant { //发送给路径规划的任务 (拼接的是任务id) public static String PATH_PLANNING_TASK = "path:planning:task"; + + //路网匹配 true表示匹配成功, false表示匹配失败 (拼接的是robotNo) + public static String PATH_PLANNING_GRAPH_MATCH = "path:planning:graph:match"; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/constant/path/PathPlanningTopicConstant.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/constant/path/PathPlanningTopicConstant.java index bb981dd42..c13f6b311 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/constant/path/PathPlanningTopicConstant.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/constant/path/PathPlanningTopicConstant.java @@ -89,5 +89,20 @@ public class PathPlanningTopicConstant { */ public static String UPDATE_BEHAVIOR = "UPDATE_BEHAVIOR"; + /** + * 开始同步信息给PP的通知 + */ + public static String SYNCHRONOUS_ALL_MAP_INIT = "SYNCHRONOUS_ALL_MAP_INIT"; + + /** + * 开启远遥 + */ + public static String START_REMOTE_CONTROLLER = "START_REMOTE_CONTROLLER"; + + /** + * 关闭远遥 + */ + public static String CLOSE_REMOTE_CONTROLLER = "CLOSE_REMOTE_CONTROLLER"; + } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/path/dto/GraphMatchDataDTO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/path/dto/GraphMatchDataDTO.java new file mode 100644 index 000000000..5541f9d3c --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/path/dto/GraphMatchDataDTO.java @@ -0,0 +1,19 @@ +package cn.iocoder.yudao.module.system.controller.admin.path.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +public class GraphMatchDataDTO { + @Schema(description = "车辆编号") + private String robotNo; + + @Schema(description = "true表示匹配成功, false表示匹配失败") + private Boolean isMatched; + + @Schema(description = "LINE表示匹配到线段,NODE表示匹配到节点") + private String matchedType; + + @Schema(description = "匹配到的线段或者节点的snowflake") + private String matchedId; +} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/enums/robot/remote/RemoteModeEnum.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/enums/robot/remote/RemoteModeEnum.java new file mode 100644 index 000000000..7f0b0385b --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/enums/robot/remote/RemoteModeEnum.java @@ -0,0 +1,26 @@ +package cn.iocoder.yudao.module.system.enums.robot.remote; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public enum RemoteModeEnum { + AUTOMATIC(0, "自动模式"), + HAND_MOVEMENT(1, "手动模式"), + FREE(2, "自由模式"); + /** + * 类型 + */ + private final Integer type; + private final String msg; + + public static String getMsg(Integer type) { + if (AUTOMATIC.getType().equals(type)) { + return AUTOMATIC.getMsg(); + } else if (HAND_MOVEMENT.getType().equals(type)) { + return HAND_MOVEMENT.getMsg(); + } + return FREE.getMsg(); + } +} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/path/PathPlanningService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/path/PathPlanningService.java index 816e0acb0..3ff6a1f3b 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/path/PathPlanningService.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/path/PathPlanningService.java @@ -49,4 +49,15 @@ public interface PathPlanningService { * 仿真点位信息 */ void simulationRobotPoseRequest(); + + /** + * 路网匹配实时数据 + * @param message + */ + void graphMatchData(String message); + + /** + * 开始同步 + */ + void synchronousStart(); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/path/PathPlanningServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/path/PathPlanningServiceImpl.java index 48838fb7e..d1d53fc31 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/path/PathPlanningServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/path/PathPlanningServiceImpl.java @@ -14,10 +14,12 @@ import cn.iocoder.yudao.module.system.api.robot.dto.RobotPoseStatusDTO; import cn.iocoder.yudao.module.system.api.robot.dto.RobotStatusDataPoseDTO; import cn.iocoder.yudao.module.system.api.robot.vo.PathPlanningMovePoseVO; import cn.iocoder.yudao.module.system.api.robot.vo.RobotInformationVO; +import cn.iocoder.yudao.module.system.constant.path.PathPlanningChcheConstant; import cn.iocoder.yudao.module.system.constant.path.PathPlanningTopicConstant; import cn.iocoder.yudao.module.system.constant.robot.RobotTaskChcheConstant; import cn.iocoder.yudao.module.system.constant.robot.RobotTopicConstant; import cn.iocoder.yudao.module.system.constant.webSocket.WebSocketConstant; +import cn.iocoder.yudao.module.system.controller.admin.path.dto.GraphMatchDataDTO; import cn.iocoder.yudao.module.system.controller.admin.path.dto.SimulationRobotPoseDTO; import cn.iocoder.yudao.module.system.controller.admin.positionmap.vo.PositionMapItemSaveReqVO; import cn.iocoder.yudao.module.system.controller.admin.positionmap.vo.PositionMapLineSaveReqVO; @@ -537,6 +539,27 @@ public class PathPlanningServiceImpl implements PathPlanningService { commonApi.commonMethod(simulationList, PathPlanningTopicConstant.INIT_ROBOT_POSE); } + /** + * 路网匹配实时数据 + * @param message + */ + @Override + public void graphMatchData(String message) { + GraphMatchDataDTO graphMatchData = JSON.parseObject(message, GraphMatchDataDTO.class); + String key = PathPlanningChcheConstant.PATH_PLANNING_GRAPH_MATCH + graphMatchData.getRobotNo(); + redisUtil.set(key,graphMatchData.getIsMatched()); + } + + @Override + public void synchronousStart() { + commonApi.commonMethodStr("开始同步点位信息", PathPlanningTopicConstant.SYNCHRONOUS_ALL_MAP_INIT); + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + public PositionMapLineDTO setPositionMapLineDTOData(PositionMapLineDTO positionMapLineDO) { PositionMapLineDTO build = PositionMapLineDTO.builder() .id(positionMapLineDO.getId()) diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/remote/RemoteControllerInformationService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/remote/RemoteControllerInformationService.java index 93f85657f..ba93fb539 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/remote/RemoteControllerInformationService.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/remote/RemoteControllerInformationService.java @@ -59,24 +59,28 @@ public interface RemoteControllerInformationService extends IService getAllRemoteController(); /** * 获取机器人远遥模式/急停/协控状态 + * * @param ip * @return */ @@ -84,8 +88,17 @@ public interface RemoteControllerInformationService extends IService implements RemoteControllerInformationService { @Resource @@ -59,6 +77,21 @@ public class RemoteControllerInformationServiceImpl extends ServiceImpl() .eq(RemoteControllerInformationDO::getRemoteIp, loginCheck.getRemoteIp()) @@ -139,6 +173,7 @@ public class RemoteControllerInformationServiceImpl extends ServiceImpl() + .eq(RemoteControllerInformationDO::getRemoteIp, remoteIp) + .last("limit 1")); + + if (ObjectUtil.isEmpty(information)) { + throw exception(REMOTE_DEVICE_NOT_SET_UP); + } + + if (ObjectUtil.isEmpty(information.getRobotNo()) && !RemoteModeEnum.AUTOMATIC.getType().equals(remoteMode)) { + throw exception(REMOTE_DEVICE_NEED_AUTOMATIC); + } + + RobotInformationDO robotInformation = informationService.getInformationByRobotNo(robotNo); + + + if (ObjectUtil.isNotEmpty(information.getRobotNo()) && !information.getRobotNo().equals(robotNo)) { + String msg = "目前远遥设备控制的机器人是 " + information.getRobotNo() + " 需要先将此机器人退出远遥"; + throw exception0(REMOTE_DEVICE_CONTROLLER.getCode(), msg, msg); + } + + //第一次设置为自动模式 + if (ObjectUtil.isEmpty(information.getRobotNo()) && RemoteModeEnum.AUTOMATIC.getType().equals(remoteMode)) { + String operateAction = information.getRemoteIp() + " 开启远遥为自动模式"; + setRemoteChangeLog(information, robotNo, remoteMode, operateAction); + sendRemoteMsgToRobotAndPP(false,robotNo); + //todo 同步苏工和PP 包括车速 + return; + } + + if (ObjectUtil.isNotEmpty(information.getRobotNo()) && information.getRobotNo().equals(robotNo) + && ObjectUtil.isNotEmpty(information.getRemoteMode()) && information.getRemoteMode().equals(remoteMode)) { + UserOperationLogSaveReqVO operationLog = UserOperationLogSaveReqVO.builder() + .operateAction(information.getRemoteIp() + " 重新进入远遥 " + RemoteModeEnum.getMsg(remoteMode)) + .nickName(SecurityFrameworkUtils.getLoginUserNickname()).build(); + userOperationLogService.createUserOperationLog(operationLog); + return; + } + + //自动切手动 + if (RemoteModeEnum.AUTOMATIC.getType().equals(information.getRemoteMode()) && RemoteModeEnum.HAND_MOVEMENT.getType().equals(remoteMode)) { + List doingTask = informationService.selectDoingTaskByRobotNo(robotNo); + if (ObjectUtil.isEmpty(doingTask)) { + throw exception(REMOTE_NOT_HAVE_TASK); + } + String operateAction = information.getRemoteIp() + " 切换远遥模式为 " + RemoteModeEnum.getMsg(remoteMode); + setRemoteChangeLog(information, robotNo, remoteMode, operateAction); + sendRemoteMsgToRobotAndPP(true,robotNo); + //todo 同步苏工和PP 包括车速 + return; + } + + //自动切自由 + if (RemoteModeEnum.AUTOMATIC.getType().equals(information.getRemoteMode()) && RemoteModeEnum.FREE.getType().equals(remoteMode)) { + List doingTask = informationService.selectDoingTaskByRobotNo(robotNo); + if (ObjectUtil.isNotEmpty(doingTask)) { + throw exception(REMOTE_HAVE_TASK); + } + + if (RobotTaskModelEnum.REJECTION.getType().equals(robotInformation.getRobotTaskModel())) { + throw exception(ROBOT_REJECTION); + } + + if (!RobotStatusEnum.STAND_BY.getType().equals(robotInformation.getRobotStatus())) { + throw exception(ROBOT_NOT_STAND_BY); + } + + //校验电量是否充足 + checkElectricity(robotInformation); + + String operateAction = information.getRemoteIp() + " 切换远遥模式为 " + RemoteModeEnum.getMsg(remoteMode); + setRemoteChangeLog(information, robotNo, remoteMode, operateAction); + sendRemoteMsgToRobotAndPP(true,robotNo); + //todo 同步苏工和PP 包括车速 + return; + } + + //手动切自动 + if (RemoteModeEnum.HAND_MOVEMENT.getType().equals(information.getRemoteMode()) && RemoteModeEnum.AUTOMATIC.getType().equals(remoteMode)) { + String graphMatchKey = PathPlanningChcheConstant.PATH_PLANNING_GRAPH_MATCH + robotNo; + Object o = redisUtil.get(graphMatchKey); + if (ObjectUtil.isEmpty(o) || !Boolean.parseBoolean(String.valueOf(o))) { + throw exception(REMOTE_NOT_HAVE_PATH_MATCH); + } + + String operateAction = information.getRemoteIp() + " 切换远遥模式为 " + RemoteModeEnum.getMsg(remoteMode); + setRemoteChangeLog(information, robotNo, remoteMode, operateAction); + sendRemoteMsgToRobotAndPP(false,robotNo); + //todo 同步苏工和PP 包括车速 + return; + } + + //手动切自由 + if (RemoteModeEnum.HAND_MOVEMENT.getType().equals(information.getRemoteMode()) && RemoteModeEnum.FREE.getType().equals(remoteMode)) { + log.info("手动模式不能切换到自由模式 :{}", remoteIp); + throw exception(REMOTE_AUTOMATIC_CAN_NOT_CHANGE_TO_FREE); + } + + //自由切手动 + if (RemoteModeEnum.FREE.getType().equals(information.getRemoteMode()) && RemoteModeEnum.HAND_MOVEMENT.getType().equals(remoteMode)) { + log.info("自由模式不能切换到手动模式 :{}", remoteIp); + throw exception(REMOTE_FREE_CAN_NOT_CHANGE_TO_HAND_MOVEMENT); + } + + //自由切自动 + if (RemoteModeEnum.FREE.getType().equals(information.getRemoteMode()) && RemoteModeEnum.AUTOMATIC.getType().equals(remoteMode)) { + String graphMatchKey = PathPlanningChcheConstant.PATH_PLANNING_GRAPH_MATCH + robotNo; + Object o = redisUtil.get(graphMatchKey); + if (ObjectUtil.isEmpty(o) || !Boolean.parseBoolean(String.valueOf(o))) { + throw exception(REMOTE_NOT_HAVE_PATH_MATCH); + } + + String operateAction = information.getRemoteIp() + " 切换远遥模式为 " + RemoteModeEnum.getMsg(remoteMode); + setRemoteChangeLog(information, robotNo, remoteMode, operateAction); + sendRemoteMsgToRobotAndPP(false,robotNo); + //todo 同步苏工和PP 包括车速 + } + + } + + /** + * 发送远遥信息给PP和车机 + * @param isAuto + * @param robotNo + */ + public void sendRemoteMsgToRobotAndPP(Boolean isAuto, String robotNo){ + RemotePathPlanningDTO remotePathPlanning = new RemotePathPlanningDTO(); + remotePathPlanning.setRobotNo(robotNo); + commonApi.commonMethod(remotePathPlanning, PathPlanningTopicConstant.START_REMOTE_CONTROLLER); + } + + /** + * 远遥切换,添加记录 + */ + public void setRemoteChangeLog(RemoteControllerInformationDO information, String robotNo, Integer remoteMode, String operateAction) { + information.setRobotNo(robotNo); + information.setRemoteMode(remoteMode); +// information.setCollaborativeControl(ZeroOneEnum.ZERO.getType()); + controllerInformationMapper.updateById(information); + + UserOperationLogSaveReqVO operationLog = UserOperationLogSaveReqVO.builder() + .operateAction(operateAction) + .nickName(SecurityFrameworkUtils.getLoginUserNickname()).build(); + + userOperationLogService.createUserOperationLog(operationLog); + } + + + + /** + * 校验电量是否充足 + * + * @param robotNo + */ + private void checkElectricity(RobotInformationDO information) { + + CommonConfigDO commonConfig = configMapper.selectOne(new LambdaQueryWrapper() + .eq(CommonConfigDO::getConfigType, CommandConfigTypeEnum.CHARG_CONFIG.getType())); + //校验机器人是否到达设定的电量 + Boolean canDoTask = informationService.checkRobotElectricity(information, commonConfig); + if (!canDoTask) { + log.info("车辆电量不足"); + throw exception(ROBOT_ELECTRICITY_INSUFFICIENT); + } + } + } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/RobotInformationService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/RobotInformationService.java index aa36b1689..bab180b4c 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/RobotInformationService.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/RobotInformationService.java @@ -5,7 +5,9 @@ import cn.iocoder.yudao.module.mqtt.api.task.dto.RobotSimulationPoseDTO; import cn.iocoder.yudao.module.system.api.robot.dto.RobotStatusDTO; import cn.iocoder.yudao.module.system.api.robot.vo.RobotInformationVO; import cn.iocoder.yudao.module.system.controller.admin.robot.vo.*; +import cn.iocoder.yudao.module.system.dal.dataobject.config.CommonConfigDO; import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotInformationDO; +import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotTaskDO; import com.baomidou.mybatisplus.extension.service.IService; import javax.validation.Valid; @@ -175,4 +177,26 @@ public interface RobotInformationService extends IService { * @param str */ void sendEmergencyStopOrRecoveryToRobot(RobotSimulationPoseDTO robotSimulationPose, List robotNos, String str); + + /** + * 查询机器人处理中的任务 + * @param robotNo + * @return + */ + List selectDoingTaskByRobotNo(String robotNo); + + /** + * 根据机器人编号查询 + * @param robotNo + * @return + */ + RobotInformationDO getInformationByRobotNo(String robotNo); + + /** + * 校验机器人是否到达设定的电量 + * @param robotNo + * @param commonConfig + * @return + */ + Boolean checkRobotElectricity(RobotInformationDO information, CommonConfigDO commonConfig); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/RobotInformationServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/RobotInformationServiceImpl.java index 560197d3f..99f2563e7 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/RobotInformationServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/RobotInformationServiceImpl.java @@ -30,12 +30,14 @@ import cn.iocoder.yudao.module.system.constant.path.PathPlanningTopicConstant; import cn.iocoder.yudao.module.system.constant.robot.RobotStatusCodeConstant; import cn.iocoder.yudao.module.system.constant.robot.RobotTaskChcheConstant; import cn.iocoder.yudao.module.system.constant.robot.RobotTopicConstant; +import cn.iocoder.yudao.module.system.controller.admin.config.vo.CommonConfigVO; import cn.iocoder.yudao.module.system.controller.admin.log.vo.UserOperationLogSaveReqVO; import cn.iocoder.yudao.module.system.controller.admin.robot.camera.RobotCameraAddVO; import cn.iocoder.yudao.module.system.controller.admin.robot.proceed.RobotTaskProceedSaveReqVO; import cn.iocoder.yudao.module.system.controller.admin.robot.vo.*; import cn.iocoder.yudao.module.system.controller.admin.tool.dto.CleanAgvDTO; import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserSaveReqVO; +import cn.iocoder.yudao.module.system.dal.dataobject.config.CommonConfigDO; import cn.iocoder.yudao.module.system.dal.dataobject.houselocation.WareHouseLocationDO; import cn.iocoder.yudao.module.system.dal.dataobject.information.DeviceInformationDO; import cn.iocoder.yudao.module.system.dal.dataobject.informationmapassociation.InformationMapAssociationDO; @@ -68,6 +70,7 @@ import cn.iocoder.yudao.module.system.enums.robot.RobotStatusEnum; import cn.iocoder.yudao.module.system.enums.robot.RobotTaskDetailStatusEnum; import cn.iocoder.yudao.module.system.enums.robot.RobotTaskModelEnum; import cn.iocoder.yudao.module.system.enums.robot.actionlog.ActionStatusEnum; +import cn.iocoder.yudao.module.system.enums.robot.charge.ChargeModelEnum; import cn.iocoder.yudao.module.system.enums.robot.information.RobotStatisticsTypeEnum; import cn.iocoder.yudao.module.system.enums.robot.task.RobotTaskStageEnum; import cn.iocoder.yudao.module.system.service.informationmapassociation.InformationMapAssociationService; @@ -94,6 +97,7 @@ import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; import javax.validation.ConstraintViolationException; +import java.math.BigDecimal; import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; @@ -175,6 +179,9 @@ public class RobotInformationServiceImpl extends ServiceImpl cameraAddVOList = createReqVO.getCameraAddVOList(); cameraService.checkCameraExist(cameraAddVOList); - cameraService.createCameraList(cameraAddVOList,createReqVO.getRobotNo()); + cameraService.createCameraList(cameraAddVOList, createReqVO.getRobotNo()); } RobotModelDO robotModelDO = modelMapper.selectById(createReqVO.getRobotModelId()); createReqVO.setRobotModelNumber(robotModelDO.getRobotModelNumber()); @@ -301,7 +308,7 @@ public class RobotInformationServiceImpl extends ServiceImpl cameraAddVOList = updateReqVO.getCameraAddVOList(); cameraService.checkCameraExist(cameraAddVOList); - cameraService.createCameraList(cameraAddVOList,updateReqVO.getRobotNo()); + cameraService.createCameraList(cameraAddVOList, updateReqVO.getRobotNo()); } // 更新 RobotInformationDO updateObj = BeanUtils.toBean(updateReqVO, RobotInformationDO.class); @@ -327,21 +334,21 @@ public class RobotInformationServiceImpl extends ServiceImpl map = new HashMap<>(); String value = floorZone.getFloor() + "-" + floorZone.getArea(); - map.put(updateReqVO.getRobotNo(),value); - redisUtil.hmset(value,map); + map.put(updateReqVO.getRobotNo(), value); + redisUtil.hmset(value, map); } } @@ -387,8 +394,8 @@ public class RobotInformationServiceImpl extends ServiceImpl().eq(RobotInformationDO::getMacAddress, macAddress)); if (ObjectUtil.isEmpty(item)) { - redisUtil.set(addressKey, macAddress, 30*1000); + redisUtil.set(addressKey, macAddress, 30 * 1000); } // -- 将获取到的存入到redis中 if (ObjectUtil.isNotEmpty(item)) { @@ -935,16 +942,16 @@ public class RobotInformationServiceImpl extends ServiceImpl pathPlanningList = new ArrayList<>(); @@ -993,20 +1001,21 @@ public class RobotInformationServiceImpl extends ServiceImpl locations = wareHouseLocationMapper.selectList(new LambdaQueryWrapperX() .eq(WareHouseLocationDO::getMapItemId, wareHouseLocation.getMapItemId()) - .ne(WareHouseLocationDO::getId,id)); + .ne(WareHouseLocationDO::getId, id)); if (ObjectUtil.isEmpty(locations)) { return; } @@ -1101,7 +1112,7 @@ public class RobotInformationServiceImpl extends ServiceImpl locations = wareHouseLocationMapper.selectList(new LambdaQueryWrapperX() .eq(WareHouseLocationDO::getMapItemId, wareHouseLocation.getMapItemId()) - .ne(WareHouseLocationDO::getId,id)); + .ne(WareHouseLocationDO::getId, id)); if (ObjectUtil.isEmpty(locations)) { return; } @@ -1117,6 +1128,7 @@ public class RobotInformationServiceImpl extends ServiceImpl robotNos = robots.stream().map(RobotInformationDO::getRobotNo).collect(Collectors.toList()); List list = new ArrayList<>(); - String floorArea = floor+"-"+area; + String floorArea = floor + "-" + area; Map hmget = redisUtil.hmget(floorArea); if (ObjectUtil.isEmpty(hmget)) { return new ArrayList<>(); } - hmget.forEach((k,v) ->{ + hmget.forEach((k, v) -> { if (robotNos.contains(k)) { - list.add((String)k ); + list.add((String) k); } }); @@ -1246,6 +1259,7 @@ public class RobotInformationServiceImpl extends ServiceImpl selectDoingTaskByRobotNo(String robotNo) { + List list = taskMapper.selectDoingTaskByRobotNo(robotNo); + return list; + } + + @Override + public RobotInformationDO getInformationByRobotNo(String robotNo) { + return informationMapper.selectOne(new LambdaQueryWrapper() + .eq(RobotInformationDO::getRobotNo, robotNo) + .last("limit 1")); + } + + /** + * 校验机器人是否到达设定的电量 + * false 不能做任务 + * + * @param robotInformation + * @param commonConfig + * @return + */ + @Override + public Boolean checkRobotElectricity(RobotInformationDO robotInformation, CommonConfigDO commonConfig) { + + if (ObjectUtil.isEmpty(commonConfig) || ObjectUtil.isEmpty(commonConfig.getConfigStr())) { + log.info("没有配置电量,不能做任务"); + return false; + } + + CommonConfigVO chargeConfig = JSONUtil.toBean(commonConfig.getConfigStr(), CommonConfigVO.class); + + String pose2dKey = RobotTaskChcheConstant.ROBOT_INFORMATION_POSE_BAT_SOC + robotInformation.getMacAddress(); + Object poseCache = redisUtil.get(pose2dKey); + if (ObjectUtil.isEmpty(poseCache)) { + log.info("车机没有电量信息 :{}", robotInformation.getRobotNo()); + return false; + } + RobotStatusDataPoseDTO dataPoseDTO = JSON.parseObject((String) poseCache, RobotStatusDataPoseDTO.class); + if (ObjectUtil.isEmpty(dataPoseDTO.getBatSoc())) { + log.info("车机没有电量信息 :{}", robotInformation.getRobotNo()); + return false; + } + + if (ObjectUtil.isNotEmpty(chargeConfig) && ObjectUtil.isNotEmpty(chargeConfig.getStartAutoCharge())) { + BigDecimal robotRemainingElectricity = new BigDecimal(dataPoseDTO.getBatSoc()); + BigDecimal robotEndElectricity = new BigDecimal(chargeConfig.getStartAutoCharge() + ""); + if (robotRemainingElectricity.compareTo(robotEndElectricity) < 0) { + log.info("机器人的电量少于自动充电电量,不能接任务 :{}", robotInformation.getRobotNo()); + return false; + } + } + + return checkElectricity(chargeConfig,robotInformation,dataPoseDTO); + } + + private Boolean checkElectricity(CommonConfigVO chargeConfig, RobotInformationDO robot, RobotStatusDataPoseDTO dataPoseDTO) { + String chargeModelKey = RobotTaskChcheConstant.ROBOT_CHARGE_MODEL + robot.getRobotNo(); + Object chargeModelCache = redisUtil.get(chargeModelKey); + log.info("充电机器人编号:{} ,信息: {}", robot.getRobotNo(), JSON.toJSONString(dataPoseDTO)); + + //车子剩余电量 + BigDecimal robotRemainingElectricity = new BigDecimal(dataPoseDTO.getBatSoc()); + //设置离开的电量 + BigDecimal robotEndElectricity = new BigDecimal("10"); + + if (ObjectUtil.isNotEmpty(robot.getAutoCharge()) && ObjectUtil.isNotEmpty(chargeModelCache) + && !ChargeModelEnum.FULL.getType().equals((Integer) chargeModelCache)) { + robotEndElectricity = new BigDecimal(String.valueOf(robot.getAutoCharge())); + } else if (ObjectUtil.isNotEmpty(chargeModelCache) && ChargeModelEnum.FULL.getType().equals((Integer) chargeModelCache)) { + robotEndElectricity = new BigDecimal(fullElectricity); + } else if (ObjectUtil.isNotEmpty(chargeModelCache) && ChargeModelEnum.CHANCE.getType().equals((Integer) chargeModelCache) + && ObjectUtil.isNotEmpty(chargeConfig.getChanceChargeEnd())) { + robotEndElectricity = new BigDecimal(String.valueOf(chargeConfig.getChanceChargeEnd())); + } else if (ObjectUtil.isNotEmpty(chargeConfig.getEndAutoCharge())){ + robotEndElectricity = new BigDecimal(String.valueOf(chargeConfig.getEndAutoCharge())); + } + + if (robotRemainingElectricity.compareTo(robotEndElectricity) >= 0) { + return true; + }else { + log.info("机器人正在充电,还没达到充电设置的电量,暂不能接任务:{} ", robot.getRobotNo()); + } + + return false; + } } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/job/DistributeTasksServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/job/DistributeTasksServiceImpl.java index 437dfd8f8..4f02a1877 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/job/DistributeTasksServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/job/DistributeTasksServiceImpl.java @@ -54,7 +54,7 @@ public class DistributeTasksServiceImpl implements DistributeTasksService { @Autowired private RobotTaskDetailMapper robotTaskDetailMapper; - @Value("${zn.full_electricity:100}") + @Value("${zn.full_electricity:95}") private String fullElectricity; @Resource @@ -111,6 +111,7 @@ public class DistributeTasksServiceImpl implements DistributeTasksService { } Object cargoDetected = redisUtil.get(cargoDetectedKey); + //取货的,先执行放货再去充电 if (ObjectUtil.isNotEmpty(lastTaskDetailMap) && ObjectUtil.isNotEmpty(lastTaskDetailMap.get(robot.getRobotNo()))) { robot.setRobotStatus(RobotStatusEnum.LAST_TASK_IS_TAKE.getType()); continue; @@ -140,10 +141,11 @@ public class DistributeTasksServiceImpl implements DistributeTasksService { continue; } //自动充电的车子,电量到达设定的阀值,也能执行任务 - if (ChargeTypeEnum.AUTOMATIC.getType().equals(robot.getChargeType()) + /*if (ChargeTypeEnum.AUTOMATIC.getType().equals(robot.getChargeType()) && RobotStatusEnum.CHARGE.getType().equals(robot.getRobotStatus())) { setRobotStatus(commonConfigDO, robot); - } + }*/ + setRobotStatus(commonConfigDO, robot); } robots = robots.stream() @@ -238,16 +240,17 @@ public class DistributeTasksServiceImpl implements DistributeTasksService { //车子剩余电量 BigDecimal robotRemainingElectricity = new BigDecimal(dataPoseDTO.getBatSoc()); //设置离开的电量 - BigDecimal robotEndElectricity = null; + BigDecimal robotEndElectricity = new BigDecimal("10"); if (ObjectUtil.isNotEmpty(robot.getAutoCharge()) && ObjectUtil.isNotEmpty(chargeModelCache) && !ChargeModelEnum.FULL.getType().equals((Integer) chargeModelCache)) { robotEndElectricity = new BigDecimal(String.valueOf(robot.getAutoCharge())); } else if (ObjectUtil.isNotEmpty(chargeModelCache) && ChargeModelEnum.FULL.getType().equals((Integer) chargeModelCache)) { robotEndElectricity = new BigDecimal(fullElectricity); - } else if (ObjectUtil.isNotEmpty(chargeModelCache) && ChargeModelEnum.CHANCE.getType().equals((Integer) chargeModelCache)) { + } else if (ObjectUtil.isNotEmpty(chargeModelCache) && ChargeModelEnum.CHANCE.getType().equals((Integer) chargeModelCache) + && ObjectUtil.isNotEmpty(chargeConfig.getEndAutoCharge())) { robotEndElectricity = new BigDecimal(String.valueOf(chargeConfig.getChanceChargeEnd())); - } else { + } else if (ObjectUtil.isNotEmpty(chargeConfig.getEndAutoCharge())){ robotEndElectricity = new BigDecimal(String.valueOf(chargeConfig.getEndAutoCharge())); }