继续任务

This commit is contained in:
cbs 2025-03-26 14:37:09 +08:00
parent 41ad86f563
commit 2ffbd9a4b8
9 changed files with 364 additions and 24 deletions

View File

@ -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, "机器人任务明细不存在");

View File

@ -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";
}

View File

@ -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);
}
}

View File

@ -144,4 +144,10 @@ public interface RobotInformationService extends IService<RobotInformationDO> {
* @param robotNo
*/
void cleanTrafficManagement(String robotNo);
/**
* 继续做任务
* @param robotNo
*/
void doTaskContinue(String robotNo);
}

View File

@ -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

View File

@ -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();
}

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -240,4 +240,5 @@ zn:
offset_height: 0.1 #叉起货需要在原来高度基础上偏移的高度
default_tray_height: 1.1 #默认每层高度
open_rate_limiter: true #是否开启限流
path_planning:
task_chche_time: 604800 #任务缓存的时间, 默认一星期