自动移动

This commit is contained in:
cbs 2025-05-22 09:05:06 +08:00
parent 49ac409b44
commit c7dc602b7f
19 changed files with 190 additions and 197 deletions

View File

@ -28,14 +28,12 @@ import cn.iocoder.yudao.module.system.enums.robot.actionlog.ActionStatusEnum;
import cn.iocoder.yudao.module.system.enums.robot.charge.ChargeTaskStatusEnum;
import cn.iocoder.yudao.module.system.enums.robot.task.RobotStatusCodeEnum;
import cn.iocoder.yudao.module.system.enums.robot.task.RobotTaskStageEnum;
import cn.iocoder.yudao.module.system.enums.wait.WaitStatusEnum;
import cn.iocoder.yudao.module.system.service.information.DeviceInformationService;
import cn.iocoder.yudao.module.system.service.log.RobotTaskDetailActionLogService;
import cn.iocoder.yudao.module.system.service.path.PathPlanningService;
import cn.iocoder.yudao.module.system.service.robot.RobotInformationService;
import cn.iocoder.yudao.module.system.service.robot.RobotTaskDetailService;
import cn.iocoder.yudao.module.system.service.robot.RobotWarnMsgService;
import cn.iocoder.yudao.module.system.service.wait.MoveToWaitService;
import cn.iocoder.yudao.module.system.util.redis.RedisUtil;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
@ -103,9 +101,6 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi {
@Resource
private RobotWarnMsgService warnMsgService;
@Resource
private MoveToWaitService moveToWaitService;
@Resource
private PathPlanningService pathPlanningService;
@ -183,7 +178,6 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi {
}
taskDetailActionLogService.createTaskDetailActionLog(logOne);
redisUtil.set(robotDoingActionKey, logOne.getActionMsg(), doingActionCacheTime);
moveToWaitService.updateWaitStatus(robotCompleteTaskDTO.getOrderId(), WaitStatusEnum.GO_TO_WAIT.getType());
} else {
taskDoing(robotCompleteTaskDTO, robotDoingActionKey);
}
@ -231,6 +225,7 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi {
//todo 后面考虑下充电车机目前对充电的逻辑未定义
if (PathTaskTypeEnum.MOVE.getType().equals(robotCompleteTaskDTO.getOrderType())
|| PathTaskTypeEnum.MOVE_TO_WAIT_STOP.getType().equals(robotCompleteTaskDTO.getOrderType())
|| PathTaskTypeEnum.MOVE_TO_WAIT.getType().equals(robotCompleteTaskDTO.getOrderType())
|| PathTaskTypeEnum.TAKE.getType().equals(robotCompleteTaskDTO.getOrderType())
|| PathTaskTypeEnum.CHARGE.getType().equals(robotCompleteTaskDTO.getOrderType())
|| PathTaskTypeEnum.RELEASE.getType().equals(robotCompleteTaskDTO.getOrderType())) {
@ -248,8 +243,6 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi {
} else if (CommandTypeEnum.WORK_DROP_OFF_GOODS.getType().equals(robotCompleteTaskDTO.getCommandStatus().getCommandType())) {
taskDone(robotCompleteTaskDTO);
}
} else if (PathTaskTypeEnum.MOVE_TO_WAIT.getType().equals(robotCompleteTaskDTO.getOrderType())) {
moveToWaitService.updateWaitStatus(robotCompleteTaskDTO.getOrderId(), WaitStatusEnum.REACH_WAIT.getType());
} else if (PathTaskTypeEnum.AUTO_CHARGE.getType().equals(robotCompleteTaskDTO.getOrderType())) {
RobotChargeLogDO build = RobotChargeLogDO
.builder()
@ -334,8 +327,7 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi {
String solve = "";
String taskNo = "";
if (!PathTaskTypeEnum.MOVE_TO_WAIT.getType().equals(robotCompleteTaskDTO.getOrderType())
&& !PathTaskTypeEnum.AUTO_CHARGE.getType().equals(robotCompleteTaskDTO.getOrderType())
if (!PathTaskTypeEnum.AUTO_CHARGE.getType().equals(robotCompleteTaskDTO.getOrderType())
&& ObjectUtil.isEmpty(msg)) {
taskNo = taskDetailService.getTaskNoByDetailId(robotCompleteTaskDTO.getOrderId());
solve = " 并且到任务列表关闭任务 " + taskNo;

View File

@ -8,6 +8,7 @@ import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.springframework.format.annotation.DateTimeFormat;
import javax.validation.constraints.NotEmpty;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@ -52,7 +53,9 @@ public class PositionMapItemPageReqVO extends PageParam {
@Schema(description = "排序的位置,越大越优先堆放")
private Long locationNumber;
@Schema(description = "等待点使用状态(0.空闲 1.使用中)")
@Schema(description = "等待点使用状态, 0:空闲 ,1:前往停车点(预占用停车点) ,2.使用中(已经在停车位上)")
private Integer useStatus;
@Schema(description = "AGV编号")
private String robotNo;
}

View File

@ -70,8 +70,12 @@ public class PositionMapItemRespVO {
@ExcelProperty("排序的位置,越大越优先堆放")
private Long locationNumber;
@Schema(description = "等待点使用状态(0.空闲 1.使用中)")
@ExcelProperty("等待点使用状态(0.空闲 1.使用中)")
@Schema(description = "等待点使用状态, 0:空闲 ,1:前往停车点(预占用停车点) ,2.使用中(已经在停车位上)")
@ExcelProperty("等待点使用状态, 0:空闲 ,1:前往停车点(预占用停车点) ,2.使用中(已经在停车位上)")
private Integer useStatus;
@Schema(description = "AGV编号")
@ExcelProperty("等待点使用状态(0.空闲 1.使用中)")
private String robotNo;
}

View File

@ -43,6 +43,9 @@ public class PositionMapItemSaveReqVO {
@Schema(description = "排序的位置,越大越优先堆放")
private Long locationNumber;
@Schema(description = "等待点使用状态(0.空闲 1.使用中)")
@Schema(description = "等待点使用状态, 0:空闲 ,1:前往停车点(预占用停车点) ,2.使用中(已经在停车位上)")
private Integer useStatus;
@Schema(description = "AGV编号")
private String robotNo;
}

View File

@ -9,6 +9,7 @@ import javax.validation.constraints.NotNull;
@Data
@Schema(description = "子列表")
public class RobotTaskDetailAddVO {
private Long id;
@Schema(description = "任务类型1取放货、2停车、 3充电、4移动、5仅取货、6仅放货、7扫描码、8检测托盘类型、9:移动到点位)", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
@NotNull(message = "任务类型1取放货、2停车、 3充电、4移动、5仅取货、6仅放货、7扫描码、8检测托盘类型、9:移动到点位)不能为空")
private Integer taskType;

View File

@ -78,8 +78,12 @@ public class PositionMapItemDO extends BaseDO {
*/
private Long locationNumber;
/**
* 等待点使用状态(0.空闲 1.使用中)
* 等待点使用状态, 0:空闲 ,1:前往停车点(预占用停车点) ,2.使用中(已经在停车位上)
*/
private Integer useStatus;
/**
* AGV编号
*/
private String robotNo;
}

View File

@ -0,0 +1,21 @@
package cn.iocoder.yudao.module.system.enums.item;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public enum UseStatusEnum {
FREE(0,"空闲"),
PRE_OCCUPANCY(1,"前往停车点(预占用停车点)"),
USEING(2,"使用中(已经在停车位上)");
/**
* 类型
*/
private final Integer type;
private final String msg;
}

View File

@ -11,6 +11,7 @@ import lombok.Getter;
public enum RobotCacheLockEnum {
TASK_NO("task:robot:no", "任务号"),
MOVE_TASK_NO("task:robot:no:move", "移动任务号"),
ROBOT_TASK_ADD_LOCK("robot:task:add:lock", "所有创建机器人任务的锁"),
ROBOT_RCS_HEART_BEAT_LOCK("robot:rcs:heart:beat:lock", "RCS维持与车机心跳的锁"),
ROBOT_STATISTICS_DURATION_LOCK("robot:statistics:duration:lock", "统计车辆工作时长的锁"),

View File

@ -6,6 +6,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
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.module.mqtt.api.task.dto.Pose2ds;
import cn.iocoder.yudao.module.system.constant.robot.RobotTaskChcheConstant;
import cn.iocoder.yudao.module.system.controller.admin.log.vo.UserOperationLogSaveReqVO;
import cn.iocoder.yudao.module.system.controller.admin.positionmap.dto.PositionMapConditionDTO;
@ -15,6 +16,7 @@ import cn.iocoder.yudao.module.system.dal.dataobject.positionmap.PositionMapItem
import cn.iocoder.yudao.module.system.dal.mysql.positionmap.PositionMapItemMapper;
import cn.iocoder.yudao.module.system.enums.common.ZeroOneEnum;
import cn.iocoder.yudao.module.system.enums.item.PositionMapItemEnum;
import cn.iocoder.yudao.module.system.enums.item.UseStatusEnum;
import cn.iocoder.yudao.module.system.service.log.UserOperationLogService;
import cn.iocoder.yudao.module.system.util.redis.RedisUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@ -139,7 +141,13 @@ public class PositionMapItemServiceImpl extends ServiceImpl<PositionMapItemMappe
@Override
public void setMapItemIdle(Long id) {
PositionMapItemDO item = PositionMapItemDO.builder().id(id).useStatus(ZeroOneEnum.ZERO.getType()).build();
PositionMapItemDO positionMapItem = positionMapItemMapper.selectById(id);
//预占说明是车子在前往这个点位的路上出故障了需要把这个点位设置为未使用
if (!UseStatusEnum.PRE_OCCUPANCY.getType().equals(positionMapItem.getUseStatus())) {
return;
}
PositionMapItemDO item = PositionMapItemDO.builder().id(id).useStatus(UseStatusEnum.FREE.getType()).build();
positionMapItemMapper.updateById(item);
}

View File

@ -43,7 +43,6 @@ 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.remote.RemoteControllerInformationDO;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.*;
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;
@ -54,6 +53,7 @@ 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.item.UseStatusEnum;
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;
@ -72,7 +72,6 @@ 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.camera.RobotCameraService;
import cn.iocoder.yudao.module.system.service.robot.pathplanning.RobotPathPlanningService;
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;
@ -131,9 +130,6 @@ public class RobotInformationServiceImpl extends ServiceImpl<RobotInformationMap
@Resource
private PositionMapItemService positionMapItemService;
@Resource
private MoveToWaitService moveToWaitService;
@Resource
private RobotTaskMapper taskMapper;
@ -1038,9 +1034,8 @@ public class RobotInformationServiceImpl extends ServiceImpl<RobotInformationMap
positionMapItemService.setMapItemIdle(robotTaskDetail.getToLocationId());
}
} else if (PathTaskTypeEnum.MOVE_TO_WAIT.getType().equals(log.getCommandType())) {
MoveToWaitDO moveToWait = moveToWaitService.getMoveToWait(log.getTaskDetailId());
if (ObjectUtil.isNotEmpty(moveToWait)) {
positionMapItemService.setMapItemIdle(moveToWait.getPositionMapItemId());
if (ObjectUtil.isNotEmpty(robotTaskDetail.getReleaseId())) {
positionMapItemService.setMapItemIdle(robotTaskDetail.getReleaseId());
}
} else if (PathTaskTypeEnum.TAKE_RELEASE.getType().equals(log.getCommandType())
|| PathTaskTypeEnum.TAKE.getType().equals(log.getCommandType())
@ -1335,20 +1330,24 @@ public class RobotInformationServiceImpl extends ServiceImpl<RobotInformationMap
*/
private void moveToWaitTask(TaskToPathPlanningDTO pathPlanning, String robotNo) {
List<PositionMapItemDO> positionMapItems = positionMapItemMapper.selectList(new LambdaQueryWrapperX<PositionMapItemDO>()
PositionMapItemDO positionMapItems = positionMapItemMapper.selectOne(new LambdaQueryWrapperX<PositionMapItemDO>()
.eq(PositionMapItemDO::getType, PositionMapItemEnum.STOP.getType())
.eq(PositionMapItemDO::getUseStatus, ZeroOneEnum.ZERO.getType()));
.eq(PositionMapItemDO::getRobotNo, robotNo)
.last("limit 1"));
if (ObjectUtil.isEmpty(positionMapItems)) {
positionMapItems = positionMapItemMapper.selectOne(new LambdaQueryWrapperX<PositionMapItemDO>()
.eq(PositionMapItemDO::getType, PositionMapItemEnum.STOP.getType())
.eq(PositionMapItemDO::getUseStatus, UseStatusEnum.FREE.getType())
.last("limit 1"));
}
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);
pathPlanning.setWaitIds(Collections.singletonList(positionMapItems.getId() + ""));
}

View File

@ -48,6 +48,7 @@ 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.DeviceUseStatusEnum;
import cn.iocoder.yudao.module.system.enums.item.UseStatusEnum;
import cn.iocoder.yudao.module.system.enums.path.PathTaskTypeEnum;
import cn.iocoder.yudao.module.system.enums.redis.RobotCacheLockEnum;
import cn.iocoder.yudao.module.system.enums.robot.*;
@ -158,9 +159,6 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
@Resource
private DeviceInformationMapper deviceInformationMapper;
@Resource
private MoveToWaitService moveToWaitService;
@Resource
private CommonApi commonApi;
@ -277,7 +275,7 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
if (ObjectUtil.isNotEmpty(pointList)) {
List<PositionMapItemDO> positionMapItemList = positionMapItemService.getPositionMapItemByIds(pointList);
List<Long> list = positionMapItemList.stream()
.filter(v -> ZeroOneEnum.ONE.getType().equals(v.getUseStatus()))
.filter(v -> !UseStatusEnum.FREE.getType().equals(v.getUseStatus()))
.map(PositionMapItemDO::getSortNum)
.collect(Collectors.toList());
if (ObjectUtil.isNotEmpty(list)) {
@ -576,10 +574,6 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
}
detailId = ObjectUtil.isNotEmpty(robotChargeLogs.getTaskDetailId()) ? robotChargeLogs.getTaskDetailId() : null;
} else if (PathTaskTypeEnum.MOVE_TO_WAIT.getType().equals(taskAssignDTO.getOrderType())) {
moveToWaitService.updateWaitStatusAndItrmId(taskAssignDTO.getOrderId(), WaitStatusEnum.GO_TO_WAIT.getType(), taskAssignDTO.getWaitId());
String signDate = DateUtil.date().setTimeZone(TimeZone.getTimeZone("UTC")).toString("yyyyMMdd'T'HHmmss'Z'");
taskNo = "MOVE_TO_WAIT_" + signDate;
} else {
detailId = taskAssignDTO.getOrderId();
}
@ -612,8 +606,6 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
}
taskDetailActionLogService.createTaskDetailActionLog(logOne);
// sendTaskToRobot(robotTaskDetailDO, taskAssignDTO);
robotWorkingHoursStatisticsService.createFreeTime(taskAssignDTO.getRobotNo());
}
@ -629,7 +621,9 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
actionLog.setEndTime(LocalDateTime.now());
taskDetailActionLogService.updateTaskDetailActionLogs(Collections.singletonList(actionLog));
}
if (ObjectUtil.isEmpty(actionLog) || !PathTaskTypeEnum.MOVE_TO_POINT.getType().equals(actionLog.getCommandType())) {
//前一个任务是移动到点位或者移动到等待点需要把点位状态改为空闲
if (ObjectUtil.isEmpty(actionLog) || (!PathTaskTypeEnum.MOVE_TO_POINT.getType().equals(actionLog.getCommandType()))
&& !PathTaskTypeEnum.MOVE_TO_WAIT.getType().equals(actionLog.getCommandType())) {
return;
}
@ -639,7 +633,7 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
}
PositionMapItemSaveReqVO positionMapItemSaveReq = new PositionMapItemSaveReqVO();
positionMapItemSaveReq.setId(robotTaskDetail.getReleaseId());
positionMapItemSaveReq.setUseStatus(ZeroOneEnum.ZERO.getType());
positionMapItemSaveReq.setUseStatus(UseStatusEnum.FREE.getType());
positionMapItemService.updatePositionMapItem(positionMapItemSaveReq);
}

View File

@ -190,14 +190,14 @@ public class DistributeTasksServiceImpl implements DistributeTasksService {
if (ObjectUtil.isEmpty(montageTaskIds) && ObjectUtil.isEmpty(singleTaskIds)) {
log.info("暂无需要处理的主任务");
return pair;
return ImmutablePair.of(robots, null);
}
List<RobotTaskDetailDO> taskDetails = getTaskDetail(montageTaskIds, singleTaskIds);
if (taskDetails.isEmpty()) {
log.info("暂无需要处理的明细任务");
return pair;
return ImmutablePair.of(robots, null);
}
return ImmutablePair.of(robots, taskDetails);
}

View File

@ -1,36 +1,36 @@
package cn.iocoder.yudao.module.system.service.robot.pathplanning;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import cn.iocoder.yudao.framework.common.util.date.DateUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
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.task.TaskLimitationAreaDTO;
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;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotTaskDetailAddVO;
import cn.iocoder.yudao.module.system.dal.dataobject.houselocation.WareHouseLocationDO;
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.RobotChargeLogDO;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotInformationDO;
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.positionmap.PositionMapItemMapper;
import cn.iocoder.yudao.module.system.dal.mysql.positionmap.PositionMapMapper;
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.dal.mysql.wait.MoveToWaitMapper;
import cn.iocoder.yudao.module.system.enums.common.ZeroOneEnum;
import cn.iocoder.yudao.module.system.enums.item.PositionMapItemEnum;
import cn.iocoder.yudao.module.system.enums.item.UseStatusEnum;
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.*;
import cn.iocoder.yudao.module.system.enums.robot.charge.ChargeModelEnum;
import cn.iocoder.yudao.module.system.enums.robot.information.ChargeTypeEnum;
@ -93,8 +93,8 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
@Value("${zn.path_planning.task_chche_time:604800}")
private Long taskChcheTime;
@Resource
private MoveToWaitMapper moveToWaitMapper;
@Value("${zn.move-no:MOVE}")
private String moveTaskNo;
@Autowired
private RobotTaskMapper robotTaskMapper;
@ -175,7 +175,7 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
private void moveRobotToWait(List<RobotInformationDO> robots) {
robots = robots.stream()
.filter(v -> !v.getRobotStatus().equals(RobotStatusEnum.STAND_BY.getType()))
.filter(v -> v.getRobotStatus().equals(RobotStatusEnum.STAND_BY.getType()))
.collect(Collectors.toList());
if (ObjectUtil.isEmpty(robots)) {
log.info("------没有空闲的机器人可以去等待点-----");
@ -183,135 +183,123 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
}
List<PositionMapItemDO> positionMapItems = positionMapItemMapper.selectList(new LambdaQueryWrapperX<PositionMapItemDO>()
.eq(PositionMapItemDO::getType, PositionMapItemEnum.STOP.getType())
.eq(PositionMapItemDO::getUseStatus, ZeroOneEnum.ZERO.getType()));
.eq(PositionMapItemDO::getType, PositionMapItemEnum.STOP.getType()));
if (ObjectUtil.isEmpty(positionMapItems)) {
log.info("------没有空闲的停车-----");
log.info("------没有设置停车点,无法派发空闲的车辆去停车-----");
return;
}
List<PositionMapDO> positionMaps = positionMapMapper.selectList(new LambdaQueryWrapperX<PositionMapDO>());
Map<String, PositionMapDO> positionMap =
positionMaps.stream().collect(Collectors.toMap(v -> v.getFloor() + "_" + v.getArea(), Function.identity()));
List<String> robotNos = robots.stream().map(RobotInformationDO::getRobotNo).collect(Collectors.toList());
List<RobotPositionMapDTO> list = new ArrayList<>();
for (RobotInformationDO robot : robots) {
String pose2dKey = RobotTaskChcheConstant.ROBOT_INFORMATION_POSE_BAT + robot.getMacAddress();
Object object = redisUtil.get(pose2dKey);
RobotStatusDataPoseDTO robotStatusDataPoseDTO = JSONUtil.toBean((String) object, RobotStatusDataPoseDTO.class);
if (ObjectUtil.isEmpty(object) || ObjectUtil.isEmpty(robotStatusDataPoseDTO)) {
log.info("------此机器人没有点位信息------ :{}", robot.getRobotNo());
continue;
}
String floorAreaKey = RobotTaskChcheConstant.ROBOT_FLOOR_AREA + robot.getMacAddress();
Object floorAreaObject = redisUtil.get(floorAreaKey);
FloorZoneDTO floorZoneDTO = JSONUtil.toBean((String) floorAreaObject, FloorZoneDTO.class);
String mapKey = floorZoneDTO.getFloor() + "_" + floorZoneDTO.getArea();
PositionMapDO positionMapDO = positionMap.get(mapKey);
if (ObjectUtil.isEmpty(positionMapDO)) {
log.info("------此机器人没有匹配到楼层和区域------ :{}", robot.getRobotNo());
}
RobotPositionMapDTO build = RobotPositionMapDTO.builder()
.actualLocationX(robotStatusDataPoseDTO.getX())
.actualLocationY(robotStatusDataPoseDTO.getY())
.robotNo(robot.getRobotNo())
.positionMapId(positionMapDO.getId())
.type(PositionMapItemEnum.STOP.getType())
.build();
list.add(build);
}
if (ObjectUtil.isEmpty(list)) {
log.info("------没有需要移动到等待点的机器人------");
return;
}
//在等待点的车
List<PositionMapItemDO> existItems = positionMapItemMapper.selectInWaitList(list);
if (ObjectUtil.isEmpty(existItems)) {
robotToWait(list, positionMapItems);
} else {
robotToWaitFilterWait(list, positionMapItems, existItems);
}
}
/**
* 派部分车去停车点
*
* @param list 车辆
* @param freePositionMapItems 空闲点位
* @param existItems 已经有车的点位
*/
private void robotToWaitFilterWait(List<RobotPositionMapDTO> list, List<PositionMapItemDO> freePositionMapItems,
List<PositionMapItemDO> existItems) {
Map<String, RobotPositionMapDTO> robotNoPositionMap =
list.stream().collect(Collectors.toMap(v -> v.getActualLocationX() + "_"
+ v.getActualLocationY() + "_" + v.getPositionMapId(), Function.identity()));
Map<String, PositionMapItemDO> existItemsMap =
existItems.stream().collect(Collectors.toMap(v -> v.getActualLocationX() + "_"
+ v.getActualLocationY() + "_" + v.getPositionMapId(), Function.identity()));
List<RobotPositionMapDTO> needMoveToWaitList = new ArrayList<>();
robotNoPositionMap.forEach((key, value) -> {
PositionMapItemDO positionMapItemDO = existItemsMap.get(key);
if (ObjectUtil.isEmpty(positionMapItemDO)) {
needMoveToWaitList.add(value);
}
});
if (ObjectUtil.isEmpty(needMoveToWaitList)) {
log.info("没有需要移动到等待点的车辆");
return;
}
robotToWait(needMoveToWaitList, freePositionMapItems);
}
/**
* 派车去停车点
*
* @param list
* @param positionMapItems
*/
private void robotToWait(List<RobotPositionMapDTO> list, List<PositionMapItemDO> positionMapItems) {
if (positionMapItems.size() < list.size()) {
log.info("空闲停车点少于车辆数量");
list = list.subList(0, positionMapItems.size());
}
List<String> waitIds = positionMapItems
.stream()
.map(u -> u.getId() + "")
List<PositionMapItemDO> existMapItems = positionMapItems.stream()
.filter(v -> ObjectUtil.isNotEmpty(v.getRobotNo()) && robotNos.contains(v.getRobotNo()))
.collect(Collectors.toList());
List<MoveToWaitDO> waits = list.stream()
.map(v -> {
MoveToWaitDO build = MoveToWaitDO.builder().robotNo(v.getRobotNo()).build();
return build;
})
.collect(Collectors.toList());
moveToWaitMapper.insertBatch(waits);
//车辆直接分配的停车点集合
List<PositionMapItemDO> robotMapItems = new ArrayList<>();
if (ObjectUtil.isNotEmpty(existMapItems)) {
for (PositionMapItemDO positionMapItem : positionMapItems) {
robotNos.removeIf(v -> v.equals(positionMapItem.getRobotNo()));
if (UseStatusEnum.USEING.getType().equals(positionMapItem.getUseStatus())) {
continue;
}
positionMapItem.setUseStatus(UseStatusEnum.PRE_OCCUPANCY.getType());
robotMapItems.add(positionMapItem);
}
}
if (ObjectUtil.isNotEmpty(robotNos)) {
List<PositionMapItemDO> emptyMapItems = positionMapItems.stream()
.filter(v -> ObjectUtil.isEmpty(v.getRobotNo()))
.collect(Collectors.toList());
if (ObjectUtil.isNotEmpty(emptyMapItems)) {
for (PositionMapItemDO positionMapItem : emptyMapItems) {
if (ObjectUtil.isEmpty(robotNos)) {
break;
}
positionMapItem.setRobotNo(robotNos.get(0));
robotNos.removeIf(v -> v.equals(positionMapItem.getRobotNo()));
positionMapItem.setUseStatus(UseStatusEnum.PRE_OCCUPANCY.getType());
robotMapItems.add(positionMapItem);
}
}
}
if (ObjectUtil.isEmpty(robotMapItems)) {
log.info("车辆找不到合适的停车点,或者车辆都在停车点了,或者停车点不够用");
return;
}
Map<String, PositionMapItemDO> positionMap =
robotMapItems.stream().collect(Collectors.toMap(PositionMapItemDO::getRobotNo, Function.identity()));
Map<Long, Long> sortMap = positionMapItems.stream().collect(Collectors.toMap(PositionMapItemDO::getId, PositionMapItemDO::getSortNum));
//机器人不能行走的区域
List<TaskRobotNoLimittationAreaDTO> robotNoLimitationArea = getRobotNoLimitationArea(robots);
Map<String, TaskRobotNoLimittationAreaDTO> robotNoLimittationAreaDTOMap =
robotNoLimitationArea.stream().collect(Collectors.toMap(v -> v.getRobotNo(), Function.identity()));
List<TaskToPathPlanningDTO> pathPlanningList = new ArrayList<>();
for (MoveToWaitDO wait : waits) {
List<RobotTaskDetailAddVO> taskDetails = new ArrayList<>();
List<RobotTaskDO> tasks = new ArrayList<>();
for (PositionMapItemDO v : robotMapItems) {
RobotTaskDO task = new RobotTaskDO();
String incrementByKey = redisUtil.getIncrementByKey(RobotCacheLockEnum.MOVE_TASK_NO.getKey());
task.setTaskNo(moveTaskNo + DateUtils.getYearMonthDay() + incrementByKey);
task.setId(IdUtil.getSnowflakeNextId());
task.setCycleNumber(0L);
task.setRemainingCycleNumber(0L);
task.setStartTime(LocalDateTime.now());
tasks.add(task);
RobotTaskDetailAddVO detailAddVO = new RobotTaskDetailAddVO();
detailAddVO.setId(IdUtil.getSnowflakeNextId());
detailAddVO.setRobotTaskId(task.getId());
detailAddVO.setTaskType(RobotTaskTypeEnum.MOVE_TO_POINT.getType());
detailAddVO.setReleaseType(ReleaseTakeEnum.TO_LOCATION.getType());
detailAddVO.setReleaseId(v.getId());
detailAddVO.setToLocationNo(sortMap.get(v.getId())+"");
detailAddVO.setRobotNo(v.getRobotNo());
taskDetails.add(detailAddVO);
TaskToPathPlanningDTO pathPlanning = TaskToPathPlanningDTO.builder()
.orderId(String.valueOf(wait.getId()))
.orderId(detailAddVO.getId()+"")
.orderType(PathTaskTypeEnum.MOVE_TO_WAIT.getType())
.priority(1l)
.createTime(LocalDateTime.now())
.taskType(PathTaskTypeToRobotEnum.MOVE.getType())
.waitIds(waitIds)
.waitIds(Collections.singletonList(v.getId() + ""))
.build();
TaskRobotNoLimittationAreaDTO taskRobotNoLimittationAreaDTO = robotNoLimittationAreaDTOMap.get(v.getRobotNo());
List<TaskRobotNoLimittationAreaDTO> robotNoLimitions = Arrays.asList(taskRobotNoLimittationAreaDTO);
pathPlanning.setRobotNoLimitationAreaDTOS(robotNoLimitions);
String key = PathPlanningChcheConstant.PATH_PLANNING_TASK + pathPlanning.getOrderId();
redisUtil.set(key, JSON.toJSONString(pathPlanning), taskChcheTime);
pathPlanningList.add(pathPlanning);
}
robotTaskMapper.insertBatch(tasks);
List<RobotTaskDetailDO> bean = BeanUtils.toBean(taskDetails, RobotTaskDetailDO.class);
robotTaskDetailMapper.insertBatch(bean);
positionMapItemMapper.updateById(robotMapItems);
log.info("派车去停车点--任务下发给PP :{}", JSON.toJSONString(pathPlanningList));
commonApi.commonMethod(pathPlanningList, PathPlanningTopicConstant.TASK_ASSIGNMENT_REQUEST);
}
@Override
public void sendChargeTaskToPP(List<RobotChargeLogDO> logs, List<RobotTaskDetailDO> taskDetailDOS,
List<RobotInformationDO> robots) {
@ -406,7 +394,7 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
List<PositionMapItemDO> positionMapItems = positionMapItemMapper.selectList(new LambdaQueryWrapperX<PositionMapItemDO>()
.eq(PositionMapItemDO::getType, PositionMapItemEnum.STOP.getType())
.eq(PositionMapItemDO::getUseStatus, ZeroOneEnum.ZERO.getType()));
.eq(PositionMapItemDO::getUseStatus, UseStatusEnum.FREE.getType()));
List<String> waitIds = null;
if (ObjectUtil.isNotEmpty(positionMapItems)) {
waitIds = positionMapItems

View File

@ -50,7 +50,6 @@ public interface MoveToWaitService {
*/
PageResult<MoveToWaitDO> getMoveToWaitPage(MoveToWaitPageReqVO pageReqVO);
void updateWaitStatus(Long orderId, Integer status);
void updateWaitStatusAndItrmId(Long orderId, Integer type, String waitId);
}

View File

@ -71,21 +71,6 @@ public class MoveToWaitServiceImpl implements MoveToWaitService {
return moveToWaitMapper.selectPage(pageReqVO);
}
@Override
public void updateWaitStatus(Long orderId, Integer status) {
MoveToWaitDO updateObj = new MoveToWaitDO();
updateObj.setId(orderId);
updateObj.setWaitStatus(status);
moveToWaitMapper.updateById(updateObj);
}
@Override
public void updateWaitStatusAndItrmId(Long orderId, Integer status, String waitId) {
MoveToWaitDO updateObj = new MoveToWaitDO();
updateObj.setId(orderId);
updateObj.setPositionMapItemId(Long.valueOf(waitId));
updateObj.setWaitStatus(status);
moveToWaitMapper.updateById(updateObj);
}
}

View File

@ -185,7 +185,8 @@ justauth:
timeout: 24h # 超时时长,目前只对 Redis 缓存生效,默认 3 分钟
zn:
task-no: ZN #任务号开头
task-no: TASK #任务号开头
move-no: MOVE #自动移动任务号开头
camera_secret_key: A2C4rv7DY012c9ef #摄像头秘钥
do_cycle: true #是否开启循环
lane_auto_move: true #线库是否自动移库 true:线库执行自动移库 、false线库关闭执行自动移库

View File

@ -220,7 +220,8 @@ map:
warn-path: /Users/aikai/Documents/json/ # 告警码值上传路径
zn:
task-no: ZN #任务号开头
task-no: TASK #任务号开头
move-no: MOVE #自动移动任务号开头
camera_secret_key: A2C4rv7DY012c9ef #摄像头秘钥
do_cycle: true #是否开启循环
lane_auto_move: true #线库是否自动移库 true:线库执行自动移库 、false线库关闭执行自动移库
@ -244,7 +245,7 @@ zn:
task_chche_time: 1209600 #任务缓存的时间, 默认一星期
is_simulation: true # 是否为仿真环境
send_robot_init_pose: true # 是否为发送默认的车辆所在地图和点位
restore_task_restart: false # 恢复任务是否全部重新执行 true:全部重新开始
restore_task_restart: true # 恢复任务是否全部重新执行 true:全部重新开始
logging:
file:

View File

@ -213,7 +213,8 @@ map:
warn-path: D:\project\rcs\json\ # 告警码值上传路径
zn:
task-no: ZN #任务号开头
task-no: TASK #任务号开头
move-no: MOVE #自动移动任务号开头
camera_secret_key: A2C4rv7DY012c9ef #摄像头秘钥
do_cycle: true #是否开启循环
lane_auto_move: true #线库是否自动移库 true:线库执行自动移库 、false线库关闭执行自动移库

View File

@ -81,21 +81,9 @@
<include refid="base_sql"></include>
from
ware_position_map_item
where deleted = '0'
<foreach collection="list" item="item" index="index" open="(" close=")"
separator=",">
<if test="positionMapId != null">
and position_map_id = #{positionMapId}
</if>
<if test="actualLocationX != null and actualLocationX != ''">
and actual_location_x = #{actualLocationX}
</if>
<if test="actualLocationY != null and actualLocationY != ''">
and actual_location_y = #{actualLocationY},
</if>
<if test="type != null">
and type = #{type},
</if>
where (position_map_id, actual_location_x,actual_location_y,type) IN
<foreach collection="list" item="item" open="(" separator=")," close=")">
(#{item.positionMapId}, #{item.actualLocationX}, #{item.actualLocationY}, #{item.type})
</foreach>
</select>