继续任务
This commit is contained in:
parent
41ad86f563
commit
2ffbd9a4b8
@ -187,6 +187,10 @@ public interface ErrorCodeConstants {
|
||||
ErrorCode ROBOT_INFORMATION_NOT_EXISTS = new ErrorCode(1-002-034-001, "车辆信息不存在");
|
||||
ErrorCode ROBOT_MAC_ADDRESS_EXISTS = new ErrorCode(1-002-034-002, "MAC地址重复");
|
||||
ErrorCode ROBOT_ROBOT_NO_EXISTS = new ErrorCode(1-002-034-003, "机器人编号重复");
|
||||
ErrorCode ROBOT_LAST_TASK_NO_EXISTS = new ErrorCode(1-002-034-004, "机器人前一个任务不存在或已经完成");
|
||||
ErrorCode ROBOT_LAST_TASK_DELETE = new ErrorCode(1-002-034-005, "超过限制的时间,无法继续执行前一个任务");
|
||||
ErrorCode ROBOT_NOT_FOUND_WAIT_ITEM = new ErrorCode(1-002-034-006, "没有空闲的停车点");
|
||||
ErrorCode ROBOT_NOT_FOUND_FREE_CHARGING_STATION = new ErrorCode(1-002-034-007, "没有空闲的充电桩");
|
||||
|
||||
// ========== 机器人任务主表 1-002-035-000 ==========
|
||||
ErrorCode TASK_NOT_EXISTS = new ErrorCode(1-002-035-001, "机器人任务主表不存在");
|
||||
@ -200,6 +204,12 @@ public interface ErrorCodeConstants {
|
||||
ErrorCode TASK_CHECK_UPDATE_STATUS = new ErrorCode(1-002-035-101, "订单更新失败");
|
||||
ErrorCode TASK_CHECK_EXIST_NO = new ErrorCode(1-002-035-102, "订单号已存在");
|
||||
ErrorCode TASK_TYPE_UN_EXIST = new ErrorCode(1-002-035-103, "找不到对应的任务类型");
|
||||
ErrorCode TASK_TAKE_LOCATION_EMPTY = new ErrorCode(1-002-035-104, "取货库位没有库存");
|
||||
ErrorCode TASK_TAKE_LOCATION_UPPER_LEVELS_NOT_EMPTY = new ErrorCode(1-002-035-105, "取货库位上层不为空");
|
||||
ErrorCode TASK_RELEASE_LOCATION_NOT_EMPTY = new ErrorCode(1-002-035-106, "放货库位不为空");
|
||||
ErrorCode TASK_RELEASE_LOCATION_LOWER_LEVELS_EMPTY = new ErrorCode(1-002-035-107, "放货库位下层为空");
|
||||
ErrorCode TASK_TAKE_LOCATION_HAVE_OTHER_TASK = new ErrorCode(1-002-035-108, "取货库位已经分配了其他任务");
|
||||
ErrorCode TASK_RELEASE_LOCATION_HAVE_OTHER_TASK = new ErrorCode(1-002-035-109, "放货库位已经分配了其他任务");
|
||||
|
||||
// ========== 机器人任务明细 1-002-036-000 ==========
|
||||
ErrorCode TASK_DETAIL_NOT_EXISTS = new ErrorCode(1-002-036-001, "机器人任务明细不存在");
|
||||
|
@ -0,0 +1,9 @@
|
||||
package cn.iocoder.yudao.module.system.constant.path;
|
||||
|
||||
/**
|
||||
* 路径规划相关缓存
|
||||
*/
|
||||
public class PathPlanningChcheConstant {
|
||||
//发送给路径规划的任务 (拼接的是任务id)
|
||||
public static String PATH_PLANNING_TASK = "path:planning:task";
|
||||
}
|
@ -148,4 +148,12 @@ public class RobotInformationController {
|
||||
informationService.cleanTrafficManagement(robotNo);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PostMapping("/doTaskContinue")
|
||||
@Operation(summary = "继续做任务")
|
||||
@PreAuthorize("@ss.hasPermission('robot:information:doTaskContinue')")
|
||||
public CommonResult<Boolean> doTaskContinue(@RequestParam("robotNo") String robotNo) {
|
||||
informationService.doTaskContinue(robotNo);
|
||||
return success(true);
|
||||
}
|
||||
}
|
||||
|
@ -144,4 +144,10 @@ public interface RobotInformationService extends IService<RobotInformationDO> {
|
||||
* @param robotNo
|
||||
*/
|
||||
void cleanTrafficManagement(String robotNo);
|
||||
|
||||
/**
|
||||
* 继续做任务
|
||||
* @param robotNo
|
||||
*/
|
||||
void doTaskContinue(String robotNo);
|
||||
}
|
||||
|
@ -7,9 +7,13 @@ import cn.hutool.json.JSONUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
|
||||
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
|
||||
import cn.iocoder.yudao.module.mqtt.api.common.CommonApi;
|
||||
import cn.iocoder.yudao.module.mqtt.api.path.PathPlanningApi;
|
||||
import cn.iocoder.yudao.module.mqtt.api.path.task.TaskRobotNoLimittationAreaDTO;
|
||||
import cn.iocoder.yudao.module.mqtt.api.path.task.TaskToPathPlanningDTO;
|
||||
import cn.iocoder.yudao.module.mqtt.api.task.dto.RobotAcceptTaskDTO;
|
||||
import cn.iocoder.yudao.module.mqtt.api.task.dto.RobotRcsHeartBeatDTO;
|
||||
import cn.iocoder.yudao.module.mqtt.enums.task.ExecutionTypeEnum;
|
||||
@ -18,6 +22,7 @@ import cn.iocoder.yudao.module.system.api.robot.dto.FloorZoneDTO;
|
||||
import cn.iocoder.yudao.module.system.api.robot.dto.RobotStatusDTO;
|
||||
import cn.iocoder.yudao.module.system.api.robot.dto.RobotStatusDataPoseDTO;
|
||||
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;
|
||||
@ -25,22 +30,32 @@ import cn.iocoder.yudao.module.system.controller.admin.log.vo.UserOperationLogSa
|
||||
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.dal.dataobject.houselocation.WareHouseLocationDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.information.DeviceInformationDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.informationmapassociation.InformationMapAssociationDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.log.RobotTaskDetailActionLogDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.positionmap.PositionMapDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.positionmap.PositionMapItemDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotInformationDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotModelDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotTaskDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotTaskDetailDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.wait.MoveToWaitDO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.houselocation.WareHouseLocationMapper;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.information.DeviceInformationMapper;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.positionmap.PositionMapItemMapper;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.positionmap.PositionMapMapper;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.robot.RobotInformationMapper;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.robot.RobotModelMapper;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.robot.RobotTaskDetailMapper;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.robot.RobotTaskMapper;
|
||||
import cn.iocoder.yudao.module.system.enums.common.ZeroOneEnum;
|
||||
import cn.iocoder.yudao.module.system.enums.device.DeviceTypeEnum;
|
||||
import cn.iocoder.yudao.module.system.enums.device.DeviceUseStatusEnum;
|
||||
import cn.iocoder.yudao.module.system.enums.item.PositionMapItemEnum;
|
||||
import cn.iocoder.yudao.module.system.enums.path.PathTaskTypeEnum;
|
||||
import cn.iocoder.yudao.module.system.enums.path.PathTaskTypeToRobotEnum;
|
||||
import cn.iocoder.yudao.module.system.enums.redis.RobotCacheLockEnum;
|
||||
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;
|
||||
@ -51,12 +66,17 @@ import cn.iocoder.yudao.module.system.service.informationmapassociation.Informat
|
||||
import cn.iocoder.yudao.module.system.service.log.RobotTaskDetailActionLogService;
|
||||
import cn.iocoder.yudao.module.system.service.log.UserOperationLogService;
|
||||
import cn.iocoder.yudao.module.system.service.positionmap.PositionMapItemService;
|
||||
import cn.iocoder.yudao.module.system.service.robot.pathplanning.RobotPathPlanningService;
|
||||
import cn.iocoder.yudao.module.system.service.robot.proceed.RobotTaskProceedService;
|
||||
import cn.iocoder.yudao.module.system.service.wait.MoveToWaitService;
|
||||
import cn.iocoder.yudao.module.system.util.redis.RedisUtil;
|
||||
import cn.iocoder.yudao.module.system.util.redis.RedissonUtils;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.redisson.api.RLock;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
@ -67,6 +87,7 @@ import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception0;
|
||||
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
|
||||
|
||||
/**
|
||||
@ -114,6 +135,12 @@ public class RobotInformationServiceImpl extends ServiceImpl<RobotInformationMap
|
||||
@Resource
|
||||
private RobotTaskMapper taskMapper;
|
||||
|
||||
@Autowired
|
||||
private RobotPathPlanningService robotPathPlanningService;
|
||||
|
||||
@Resource
|
||||
private PositionMapItemMapper positionMapItemMapper;
|
||||
|
||||
@Resource
|
||||
private RedisUtil redisUtil;
|
||||
@Resource
|
||||
@ -122,6 +149,14 @@ public class RobotInformationServiceImpl extends ServiceImpl<RobotInformationMap
|
||||
private InformationMapAssociationService informationMapAssociationService;
|
||||
// -- 获取所有的设备信息key
|
||||
public static final String key = RobotTaskChcheConstant.ROBOT_GET_ROBOT_INFO;
|
||||
@Autowired
|
||||
private WareHouseLocationMapper wareHouseLocationMapper;
|
||||
|
||||
@Resource
|
||||
private PathPlanningApi pathPlanningApi;
|
||||
|
||||
@Resource
|
||||
private RedissonUtils redissonUtils;
|
||||
|
||||
@Override
|
||||
public Long createInformation(RobotInformationSaveReqVO createReqVO) {
|
||||
@ -679,14 +714,10 @@ public class RobotInformationServiceImpl extends ServiceImpl<RobotInformationMap
|
||||
.operateAction("清除交管 " + robotNo)
|
||||
.nickName(SecurityFrameworkUtils.getLoginUserNickname()).build();
|
||||
userOperationLogService.createUserOperationLog(operationLog);
|
||||
CleanAgvDTO build = CleanAgvDTO.builder().robotNo(robotNo).build();
|
||||
commonApi.commonMethod(build, PathPlanningTopicConstant.CLEAN_AGV);
|
||||
RobotTaskDetailActionLogDO log = taskDetailActionLogService.getLastTaskByRobotNo(robotNo);
|
||||
if (ObjectUtil.isEmpty(log) || ActionStatusEnum.DONE.getType().equals(log.getActionStatus())) {
|
||||
RobotTaskDetailActionLogDO log = closeTask(robotNo);
|
||||
if (ObjectUtil.isEmpty(log)) {
|
||||
return;
|
||||
}
|
||||
String mac = getMacByRobotNo(robotNo);
|
||||
robotCloseTaskDetail(log.getTaskDetailId() + "", mac, log.getCommandType());
|
||||
RobotTaskDetailDO robotTaskDetail = taskDetailMapper.selectById(log.getTaskDetailId());
|
||||
//移动、充电任务需手动关闭
|
||||
if (PathTaskTypeEnum.CHARGE.getType().equals(log.getCommandType())
|
||||
@ -702,23 +733,278 @@ public class RobotInformationServiceImpl extends ServiceImpl<RobotInformationMap
|
||||
positionMapItemService.setMapItemIdle(moveToWait.getPositionMapItemId());
|
||||
}
|
||||
} else if (PathTaskTypeEnum.TAKE_RELEASE.getType().equals(log.getCommandType())
|
||||
|| PathTaskTypeEnum.TAKE.getType().equals(log.getCommandType())
|
||||
|| PathTaskTypeEnum.RELEASE.getType().equals(log.getCommandType())) {
|
||||
|| PathTaskTypeEnum.TAKE.getType().equals(log.getCommandType())
|
||||
|| PathTaskTypeEnum.RELEASE.getType().equals(log.getCommandType())) {
|
||||
takeReleaseCleanTrafficManagement(robotTaskDetail);
|
||||
}
|
||||
//不释放机器人状态,怕机器人接新任务
|
||||
}
|
||||
|
||||
public RobotTaskDetailActionLogDO closeTask(String robotNo) {
|
||||
CleanAgvDTO build = CleanAgvDTO.builder().robotNo(robotNo).build();
|
||||
commonApi.commonMethod(build, PathPlanningTopicConstant.CLEAN_AGV);
|
||||
RobotTaskDetailActionLogDO log = taskDetailActionLogService.getLastTaskByRobotNo(robotNo);
|
||||
if (ObjectUtil.isEmpty(log) || ActionStatusEnum.DONE.getType().equals(log.getActionStatus())) {
|
||||
return null;
|
||||
}
|
||||
String mac = getMacByRobotNo(robotNo);
|
||||
robotCloseTaskDetail(log.getTaskDetailId() + "", mac, log.getCommandType());
|
||||
return log;
|
||||
}
|
||||
|
||||
/**
|
||||
* 继续做任务
|
||||
*
|
||||
* @param robotNo
|
||||
*/
|
||||
@Override
|
||||
public void doTaskContinue(String robotNo) {
|
||||
UserOperationLogSaveReqVO operationLog = UserOperationLogSaveReqVO.builder()
|
||||
.operateAction("继续做任务 " + robotNo)
|
||||
.nickName(SecurityFrameworkUtils.getLoginUserNickname()).build();
|
||||
userOperationLogService.createUserOperationLog(operationLog);
|
||||
RobotTaskDetailActionLogDO actionLog = closeTask(robotNo);
|
||||
if (ObjectUtil.isEmpty(actionLog) || ActionStatusEnum.DONE.getType().equals(actionLog.getActionStatus())) {
|
||||
throw exception(ROBOT_LAST_TASK_NO_EXISTS);
|
||||
}
|
||||
|
||||
String key = PathPlanningChcheConstant.PATH_PLANNING_TASK + actionLog.getTaskDetailId();
|
||||
Object o = redisUtil.get(key);
|
||||
if (ObjectUtil.isEmpty(o)) {
|
||||
throw exception(ROBOT_LAST_TASK_DELETE);
|
||||
}
|
||||
|
||||
TaskToPathPlanningDTO pathPlanning = JSONUtil.toBean((String) o, TaskToPathPlanningDTO.class);
|
||||
|
||||
RLock lock = redissonUtils.getLock(RobotCacheLockEnum.ROBOT_TASK_DISTRIBUTE_LOCK.getKey());
|
||||
String msg = "";
|
||||
if (lock.tryLock()){
|
||||
try {
|
||||
resendToPP(pathPlanning,actionLog);
|
||||
} catch (Exception e) {
|
||||
log.error("下发任务给路径规划现异常 :{}",e);
|
||||
msg = ObjectUtil.isNotEmpty(e.getMessage()) ? e.getMessage(): "任务下发失败";
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}else {
|
||||
log.info("下发任务给路径规划未获取到锁");
|
||||
throw exception(REDISSON_NOT_OBTAIN_LOCK);
|
||||
}
|
||||
|
||||
if (ObjectUtil.isNotEmpty(msg)) {
|
||||
throw exception0(TASK_CHECK_EXCEPTION.getCode(), msg);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将任务重新发给PP
|
||||
* @param pathPlanning
|
||||
* @param actionLog
|
||||
*/
|
||||
private void resendToPP(TaskToPathPlanningDTO pathPlanning, RobotTaskDetailActionLogDO actionLog) {
|
||||
RobotInformationDO robotInformationDO = informationMapper.selectOne(new LambdaQueryWrapper<RobotInformationDO>()
|
||||
.eq(RobotInformationDO::getRobotNo, actionLog.getRobotNo()));
|
||||
TaskRobotNoLimittationAreaDTO taskRobotNoLimittationAreaDTO =
|
||||
robotPathPlanningService.getRobotNoLimitationArea(Collections.singletonList(robotInformationDO)).get(0);
|
||||
|
||||
List<TaskRobotNoLimittationAreaDTO> robotNoLimitions = Arrays.asList(taskRobotNoLimittationAreaDTO);
|
||||
pathPlanning.setRobotNoLimitationAreaDTOS(robotNoLimitions);
|
||||
|
||||
if (PathTaskTypeEnum.MOVE_TO_WAIT.getType().equals(actionLog.getCommandType())
|
||||
|| PathTaskTypeEnum.MOVE_TO_WAIT_STOP.getType().equals(actionLog.getCommandType())) {
|
||||
moveToWaitTask(pathPlanning, actionLog.getRobotNo());
|
||||
} else if (PathTaskTypeEnum.CHARGE.getType().equals(actionLog.getCommandType())
|
||||
|| PathTaskTypeEnum.AUTO_CHARGE.getType().equals(actionLog.getCommandType())) {
|
||||
chargeTask(pathPlanning,robotInformationDO);
|
||||
} else if (PathTaskTypeEnum.TAKE_RELEASE.getType().equals(actionLog.getCommandType())) {
|
||||
takeReleaseTask(pathPlanning);
|
||||
} else if (PathTaskTypeEnum.TAKE.getType().equals(actionLog.getCommandType())) {
|
||||
takeTask(pathPlanning);
|
||||
}else if (PathTaskTypeEnum.RELEASE.getType().equals(actionLog.getCommandType())) {
|
||||
releaseTask(pathPlanning);
|
||||
}else if (PathTaskTypeEnum.MOVE.getType().equals(actionLog.getCommandType())) {
|
||||
|
||||
}
|
||||
|
||||
List<TaskToPathPlanningDTO> pathPlanningList = new ArrayList<>();
|
||||
pathPlanningList.add(pathPlanning);
|
||||
log.info("任务下发给PP :{}", JSON.toJSONString(pathPlanningList));
|
||||
pathPlanningApi.synchronousLineObject(pathPlanningList, PathPlanningTopicConstant.TASK_ASSIGNMENT_REQUEST);
|
||||
}
|
||||
|
||||
/**
|
||||
* 仅放货
|
||||
* @param pathPlanning
|
||||
*/
|
||||
private void releaseTask(TaskToPathPlanningDTO pathPlanning) {
|
||||
RobotTaskDetailDO robotTaskDetail = checkTaskDone(pathPlanning.getOrderId());
|
||||
releaseCheck(robotTaskDetail.getToLocationId(), robotTaskDetail.getRobotTaskId());
|
||||
}
|
||||
|
||||
/**
|
||||
* 仅取货
|
||||
* @param pathPlanning
|
||||
*/
|
||||
private void takeTask(TaskToPathPlanningDTO pathPlanning) {
|
||||
RobotTaskDetailDO robotTaskDetail = checkTaskDone(pathPlanning.getOrderId());
|
||||
takeCheck(robotTaskDetail.getFromLocationId(),robotTaskDetail.getRobotTaskId());
|
||||
}
|
||||
|
||||
public RobotTaskDetailDO checkTaskDone(String id){
|
||||
RobotTaskDetailDO robotTaskDetail = taskDetailMapper.selectById(id);
|
||||
if (RobotTaskStageEnum.DONE.getType().equals(robotTaskDetail.getTaskStage())) {
|
||||
throw exception(ROBOT_LAST_TASK_NO_EXISTS);
|
||||
}
|
||||
return robotTaskDetail;
|
||||
}
|
||||
|
||||
/**
|
||||
* 取放货
|
||||
* @param pathPlanning
|
||||
*/
|
||||
private void takeReleaseTask(TaskToPathPlanningDTO pathPlanning) {
|
||||
RobotTaskDetailDO robotTaskDetail = checkTaskDone(pathPlanning.getOrderId());
|
||||
if (!RobotTaskStageEnum.TAKEING.getType().equals(robotTaskDetail.getTaskStage())
|
||||
&& !RobotTaskStageEnum.GO_TAKE.getType().equals(robotTaskDetail.getTaskStage())
|
||||
&& !RobotTaskStageEnum.UN_START.getType().equals(robotTaskDetail.getTaskStage())) {
|
||||
//只要放货
|
||||
pathPlanning.setTakeLevel(null);
|
||||
pathPlanning.setTakeGroupId(null);
|
||||
pathPlanning.setTakeLocationNumber(null);
|
||||
pathPlanning.setTakePointId(null);
|
||||
pathPlanning.setTakeOffsetHeight(null);
|
||||
pathPlanning.setTakeOffsetHeight(null);
|
||||
pathPlanning.setTaskType(PathTaskTypeToRobotEnum.DROP_OFF_GOODS.getType());
|
||||
}else {
|
||||
takeCheck(robotTaskDetail.getFromLocationId(), robotTaskDetail.getRobotTaskId());
|
||||
}
|
||||
releaseCheck(robotTaskDetail.getToLocationId(),robotTaskDetail.getRobotTaskId());
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验放货任务
|
||||
*
|
||||
* @param id
|
||||
* @param takeId
|
||||
*/
|
||||
private void releaseCheck(Long id, Long takeId) {
|
||||
WareHouseLocationDO wareHouseLocation = wareHouseLocationMapper.selectById(id);
|
||||
if (ZeroOneEnum.ONE.getType().equals(wareHouseLocation.getLocationUseStatus())) {
|
||||
throw exception(TASK_RELEASE_LOCATION_NOT_EMPTY);
|
||||
}
|
||||
if (!wareHouseLocation.getTaskId().equals(takeId)) {
|
||||
throw exception(TASK_RELEASE_LOCATION_HAVE_OTHER_TASK);
|
||||
}
|
||||
List<WareHouseLocationDO> locations = wareHouseLocationMapper.selectList(new LambdaQueryWrapperX<WareHouseLocationDO>()
|
||||
.eq(WareHouseLocationDO::getMapItemId, wareHouseLocation.getMapItemId())
|
||||
.ne(WareHouseLocationDO::getId,id));
|
||||
if (ObjectUtil.isEmpty(locations)) {
|
||||
return;
|
||||
}
|
||||
List<WareHouseLocationDO> bigNumbers = locations.stream()
|
||||
.filter(v -> v.getLocationNumber() > wareHouseLocation.getLocationNumber()
|
||||
&& ZeroOneEnum.ZERO.getType().equals(v.getLocationUseStatus()))
|
||||
.collect(Collectors.toList());
|
||||
if (ObjectUtil.isNotEmpty(bigNumbers)) {
|
||||
throw exception(TASK_RELEASE_LOCATION_LOWER_LEVELS_EMPTY);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 取货校验
|
||||
*
|
||||
* @param id
|
||||
* @param takeId
|
||||
*/
|
||||
private void takeCheck(Long id, Long takeId) {
|
||||
WareHouseLocationDO wareHouseLocation = wareHouseLocationMapper.selectById(id);
|
||||
if (ZeroOneEnum.ZERO.getType().equals(wareHouseLocation.getLocationUseStatus())) {
|
||||
throw exception(TASK_TAKE_LOCATION_EMPTY);
|
||||
}
|
||||
|
||||
if (!wareHouseLocation.getTaskId().equals(takeId)) {
|
||||
throw exception(TASK_TAKE_LOCATION_HAVE_OTHER_TASK);
|
||||
}
|
||||
|
||||
List<WareHouseLocationDO> locations = wareHouseLocationMapper.selectList(new LambdaQueryWrapperX<WareHouseLocationDO>()
|
||||
.eq(WareHouseLocationDO::getMapItemId, wareHouseLocation.getMapItemId())
|
||||
.ne(WareHouseLocationDO::getId,id));
|
||||
if (ObjectUtil.isEmpty(locations)) {
|
||||
return;
|
||||
}
|
||||
List<WareHouseLocationDO> bigNumbers = locations.stream()
|
||||
.filter(v -> v.getLocationNumber() < wareHouseLocation.getLocationNumber()
|
||||
&& ZeroOneEnum.ONE.getType().equals(v.getLocationUseStatus()))
|
||||
.collect(Collectors.toList());
|
||||
if (ObjectUtil.isNotEmpty(bigNumbers)) {
|
||||
throw exception(TASK_TAKE_LOCATION_UPPER_LEVELS_NOT_EMPTY);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 充电任务
|
||||
* @param pathPlanning
|
||||
* @param robot
|
||||
*/
|
||||
private void chargeTask(TaskToPathPlanningDTO pathPlanning, RobotInformationDO robot) {
|
||||
List<DeviceInformationDO> deviceInformations = deviceInformationMapper.selectList(new LambdaQueryWrapperX<DeviceInformationDO>()
|
||||
.eq(DeviceInformationDO::getDeviceEnable, ZeroOneEnum.ONE.getType())
|
||||
.eq(DeviceInformationDO::getDeviceUseStatus, DeviceUseStatusEnum.IDLE.getType())
|
||||
.eq(DeviceInformationDO::getDeviceType, DeviceTypeEnum.CHARGING_STATION.getType()));
|
||||
if (ObjectUtil.isEmpty(deviceInformations)) {
|
||||
log.info("没有空闲的充电桩 :{}",robot.getRobotNo());
|
||||
throw exception(ROBOT_NOT_FOUND_FREE_CHARGING_STATION);
|
||||
}
|
||||
|
||||
DeviceInformationDO deviceInformationDO = deviceInformations.stream()
|
||||
.filter(v -> v.getDeviceAttribute().equals(robot.getChargeType())
|
||||
&& robot.getFloorAreaJson().contains(v.getPositionMapId()))
|
||||
.findFirst()
|
||||
.orElse(new DeviceInformationDO());
|
||||
if (ObjectUtil.isEmpty(deviceInformationDO.getDeviceNo())) {
|
||||
log.info("当前机器人查不到对应的充电桩类型、或者机器人不能在此区域充电 :{}",robot.getRobotNo());
|
||||
throw exception(ROBOT_NOT_FOUND_FREE_CHARGING_STATION);
|
||||
}
|
||||
|
||||
pathPlanning.setReleaseGroupId("POINT_" + deviceInformationDO.getPositionMapItemId());
|
||||
pathPlanning.setReleasePointId(deviceInformationDO.getPositionMapItemId());
|
||||
}
|
||||
|
||||
/**
|
||||
* 移动到等待点
|
||||
*
|
||||
* @param pathPlanning
|
||||
*/
|
||||
private void moveToWaitTask(TaskToPathPlanningDTO pathPlanning, String robotNo) {
|
||||
|
||||
List<PositionMapItemDO> positionMapItems = positionMapItemMapper.selectList(new LambdaQueryWrapperX<PositionMapItemDO>()
|
||||
.eq(PositionMapItemDO::getType, PositionMapItemEnum.STOP.getType())
|
||||
.eq(PositionMapItemDO::getUseStatus, ZeroOneEnum.ZERO.getType()));
|
||||
|
||||
if (ObjectUtil.isEmpty(positionMapItems)) {
|
||||
log.info("------没有空闲的停车点----- :{}", robotNo);
|
||||
throw exception(ROBOT_NOT_FOUND_WAIT_ITEM);
|
||||
}
|
||||
|
||||
List<String> waitIds = positionMapItems
|
||||
.stream()
|
||||
.map(u -> u.getId() + "")
|
||||
.collect(Collectors.toList());
|
||||
pathPlanning.setWaitIds(waitIds);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 取放货清除交管
|
||||
*
|
||||
* @param robotTaskDetail
|
||||
*/
|
||||
private void takeReleaseCleanTrafficManagement(RobotTaskDetailDO robotTaskDetail) {
|
||||
if (RobotTaskStageEnum.UN_START.getType().equals(robotTaskDetail.getTaskStage())
|
||||
|| RobotTaskStageEnum.GO_TAKE.getType().equals(robotTaskDetail.getTaskStage())
|
||||
|| RobotTaskStageEnum.GO_RELEASE.getType().equals(robotTaskDetail.getTaskStage())) {
|
||||
log.info("清除交管--任务阶段是前往取货/待执行/前往放货 :{}",robotTaskDetail.getRobotNo());
|
||||
|| RobotTaskStageEnum.GO_TAKE.getType().equals(robotTaskDetail.getTaskStage())) {
|
||||
log.info("清除交管--任务阶段是前往取货/待执行/前往放货 :{}", robotTaskDetail.getRobotNo());
|
||||
robotTaskDetail.setTaskStatus(RobotTaskDetailStatusEnum.NEW.getType());
|
||||
robotTaskDetail.setRobotNo(null);
|
||||
taskDetailMapper.updateById(robotTaskDetail);
|
||||
@ -739,6 +1025,7 @@ public class RobotInformationServiceImpl extends ServiceImpl<RobotInformationMap
|
||||
|
||||
/**
|
||||
* 车机关闭任务
|
||||
*
|
||||
* @param id
|
||||
* @param mac
|
||||
* @param orderType
|
||||
|
@ -183,7 +183,7 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
|
||||
addResult = addTask(createReqVO);
|
||||
} catch (Exception e) {
|
||||
log.error("下发任务出现异常 :{}", e);
|
||||
addResult = e.getMessage();
|
||||
addResult = ObjectUtil.isNotEmpty(e.getMessage()) ? e.getMessage(): "创建任务失败";
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package cn.iocoder.yudao.module.system.service.robot.pathplanning;
|
||||
|
||||
import cn.iocoder.yudao.module.mqtt.api.path.task.TaskRobotNoLimittationAreaDTO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotChargeLogDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotInformationDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotTaskDetailDO;
|
||||
@ -14,4 +15,6 @@ public interface RobotPathPlanningService {
|
||||
void sendChargeTaskToPP(List<RobotChargeLogDO> logs,
|
||||
List<RobotTaskDetailDO> taskDetailDOS,
|
||||
List<RobotInformationDO> robots);
|
||||
|
||||
List<TaskRobotNoLimittationAreaDTO> getRobotNoLimitationArea(List<RobotInformationDO> robots);
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ import cn.iocoder.yudao.module.mqtt.api.path.task.TaskRobotNoLimittationAreaDTO;
|
||||
import cn.iocoder.yudao.module.mqtt.api.path.task.TaskToPathPlanningDTO;
|
||||
import cn.iocoder.yudao.module.system.api.robot.dto.FloorZoneDTO;
|
||||
import cn.iocoder.yudao.module.system.api.robot.dto.RobotStatusDataPoseDTO;
|
||||
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.controller.admin.positionmap.dto.RobotPositionMapDTO;
|
||||
@ -92,6 +93,9 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
|
||||
@Value("${zn.robot_config.offset_height}")
|
||||
private Double offsetHeight;
|
||||
|
||||
@Value("${zn.path_planning.task_chche_time:604800}")
|
||||
private Long taskChcheTime;
|
||||
|
||||
@Resource
|
||||
private MoveToWaitMapper moveToWaitMapper;
|
||||
|
||||
@ -136,6 +140,7 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
|
||||
|
||||
/**
|
||||
* 处理停车不锁车的任务
|
||||
*
|
||||
* @param taskDetailDOS
|
||||
* @return
|
||||
*/
|
||||
@ -144,9 +149,9 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
|
||||
List<RobotTaskDetailDO> detailList = new ArrayList<>();
|
||||
for (RobotTaskDetailDO v : taskDetailDOS) {
|
||||
if (RobotTaskTypeEnum.PARK.getType().equals(v.getTaskType())
|
||||
&& ZeroOneEnum.ZERO.getType().equals(v.getNeedLock())) {
|
||||
&& ZeroOneEnum.ZERO.getType().equals(v.getNeedLock())) {
|
||||
parkList.add(v);
|
||||
}else if (!RobotTaskTypeEnum.CHARGE.getType().equals(v.getTaskType())){
|
||||
} else if (!RobotTaskTypeEnum.CHARGE.getType().equals(v.getTaskType())) {
|
||||
detailList.add(v);
|
||||
}
|
||||
}
|
||||
@ -298,6 +303,8 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
|
||||
.taskType(PathTaskTypeToRobotEnum.MOVE.getType())
|
||||
.waitIds(waitIds)
|
||||
.build();
|
||||
String key = PathPlanningChcheConstant.PATH_PLANNING_TASK + pathPlanning.getOrderId();
|
||||
redisUtil.set(key, JSON.toJSONString(pathPlanning), taskChcheTime);
|
||||
pathPlanningList.add(pathPlanning);
|
||||
}
|
||||
|
||||
@ -354,6 +361,10 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
|
||||
pathPlanning.setReleaseGroupId("POINT_" + v.getPositionMapItemId());
|
||||
pathPlanning.setReleaseLocationNumber(releaseLocationNumberConfig);
|
||||
pathPlanning.setReleasePointId(v.getPositionMapItemId());
|
||||
|
||||
String key = PathPlanningChcheConstant.PATH_PLANNING_TASK + pathPlanning.getOrderId();
|
||||
redisUtil.set(key, JSON.toJSONString(pathPlanning), taskChcheTime);
|
||||
|
||||
pathPlanningList.add(pathPlanning);
|
||||
}
|
||||
|
||||
@ -418,10 +429,10 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
|
||||
.build();
|
||||
|
||||
if (RobotTaskTypeEnum.PARK.getType().equals(taskDetailDO.getTaskType())
|
||||
&& (ObjectUtil.isEmpty(waitIds) || waitIds.size() < i)) {
|
||||
log.info("停车任务,没有多余的空闲点位 :{}",taskDetailDO.getId());
|
||||
&& (ObjectUtil.isEmpty(waitIds) || waitIds.size() < i)) {
|
||||
log.info("停车任务,没有多余的空闲点位 :{}", taskDetailDO.getId());
|
||||
return;
|
||||
}else if (RobotTaskTypeEnum.PARK.getType().equals(taskDetailDO.getTaskType())) {
|
||||
} else if (RobotTaskTypeEnum.PARK.getType().equals(taskDetailDO.getTaskType())) {
|
||||
pathPlanning.setWaitIds(waitIds);
|
||||
i++;
|
||||
}
|
||||
@ -460,12 +471,12 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
|
||||
pathPlanning.setTakeOffsetHeight(offsetHeight);
|
||||
if (ObjectUtil.isNotEmpty(taskDetailDO.getFromLaneId())) {
|
||||
pathPlanning.setTakeGroupId("LINE_" + taskDetailDO.getFromLaneId());
|
||||
}else {
|
||||
} else {
|
||||
pathPlanning.setTakeGroupId("POINT_" + taskDetailDO.getFromMapItemId());
|
||||
}
|
||||
}
|
||||
|
||||
if (ObjectUtil.isNotEmpty(taskDetailDO.getToLocationId())){
|
||||
if (ObjectUtil.isNotEmpty(taskDetailDO.getToLocationId())) {
|
||||
pathPlanning.setReleaseLocationNumber(taskDetailDO.getToLocationNumber());
|
||||
pathPlanning.setReleasePointId(toLocation.getMapItemId());
|
||||
if (ObjectUtil.isNotEmpty(toLocation.getLocationTrayHeight())) {
|
||||
@ -473,12 +484,16 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
|
||||
}
|
||||
pathPlanning.setReleaseLevel(toLocation.getLocationStorey());
|
||||
pathPlanning.setReleaseOffsetHeight(offsetHeight);
|
||||
if (ObjectUtil.isNotEmpty(taskDetailDO.getToLaneId())){
|
||||
if (ObjectUtil.isNotEmpty(taskDetailDO.getToLaneId())) {
|
||||
pathPlanning.setReleaseGroupId("LINE_" + taskDetailDO.getToLaneId());
|
||||
}else {
|
||||
} else {
|
||||
pathPlanning.setReleaseGroupId("POINT_" + taskDetailDO.getToMapItemId());
|
||||
}
|
||||
}
|
||||
|
||||
String key = PathPlanningChcheConstant.PATH_PLANNING_TASK + pathPlanning.getOrderId();
|
||||
redisUtil.set(key, JSON.toJSONString(pathPlanning), taskChcheTime);
|
||||
|
||||
pathPlanningList.add(pathPlanning);
|
||||
}
|
||||
|
||||
@ -544,7 +559,8 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
|
||||
*
|
||||
* @param robots
|
||||
*/
|
||||
private List<TaskRobotNoLimittationAreaDTO> getRobotNoLimitationArea(List<RobotInformationDO> robots) {
|
||||
@Override
|
||||
public List<TaskRobotNoLimittationAreaDTO> getRobotNoLimitationArea(List<RobotInformationDO> robots) {
|
||||
List<PositionMapDO> positionMapDOS = positionMapMapper.selectList(new LambdaQueryWrapperX<PositionMapDO>());
|
||||
|
||||
List<TaskRobotNoLimittationAreaDTO> robotNoLimitationAreaDTOS = new ArrayList<>();
|
||||
@ -664,7 +680,7 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
|
||||
} else if (RobotTaskTypeEnum.TAKE.getType().equals(v.getTaskType())) {
|
||||
//仅取货
|
||||
takeSetTask(list, v, fromLane, toLane, fromLocation, toLocation, toHaveFrom, fromHaveTo);
|
||||
}else if (RobotTaskTypeEnum.PARK.getType().equals(v.getTaskType())) {
|
||||
} else if (RobotTaskTypeEnum.PARK.getType().equals(v.getTaskType())) {
|
||||
list.add(v);
|
||||
}
|
||||
}
|
||||
|
@ -240,4 +240,5 @@ zn:
|
||||
offset_height: 0.1 #叉起货需要在原来高度基础上偏移的高度
|
||||
default_tray_height: 1.1 #默认每层高度
|
||||
open_rate_limiter: true #是否开启限流
|
||||
|
||||
path_planning:
|
||||
task_chche_time: 604800 #任务缓存的时间, 默认一星期
|
||||
|
Loading…
Reference in New Issue
Block a user