Compare commits

...

2 Commits

Author SHA1 Message Date
cbs
ecfcac2b65 处理车机上报的信息 2025-02-28 18:34:18 +08:00
cbs
9b515e2f04 处理PP上报的任务 2025-02-27 17:54:41 +08:00
46 changed files with 791 additions and 221 deletions

View File

@ -19,7 +19,7 @@ import java.util.List;
public class TaskToPathPlanningDTO {
@Schema(description = "robot_task_detail/robot_charge_log 的 id")
private Long id;
private String id;
@Schema(description = "任务类型(TASK:robot_task的任务、CHARGE:充电任务)")
private String type;

View File

@ -139,7 +139,7 @@ public class MqttFactory {
return BeanUtils.getBean(RobotStatusServiceImpl.class);
case SYNCHRONOUS_ALL_MAP_REQUEST:
return BeanUtils.getBean(PathPlanningInitDataServiceImpl.class);
case DISTRIBUTION_TASK:
case TASK_ASSIGNMENT_FEEDBACK:
return BeanUtils.getBean(PathPlanningDistributionTaskServiceImpl.class);
default :
// case ROBOT_TASK_STATUS:

View File

@ -19,7 +19,7 @@ public enum DefineSubTopicEnum {
ROBOT_TASK_STATUS("ROBOT_TASK_STATUS", 0,"机器人任务完成上报"),
ROBOT_GENERICS_STATUS("ROBOT_GENERICS_STATUS", 0,"机器人异常"),
SYNCHRONOUS_ALL_MAP_REQUEST("SYNCHRONOUS_ALL_MAP_REQUEST", 0,"路径规划需要初始数据上报"),
DISTRIBUTION_TASK("DISTRIBUTION_TASK", 0,"路径规划任务分配上报");
TASK_ASSIGNMENT_FEEDBACK("TASK_ASSIGNMENT_FEEDBACK", 0,"路径规划任务分配上报");
private final String topic;

View File

@ -23,7 +23,7 @@ public class PathPlanningDistributionTaskServiceImpl implements MqttService{
*/
@Override
public void analysisMessage(String message) {
log.info("PP上报任务分配");
log.info("PP上报任务分配 :{}", message);
pathApi.ppDistributionTask(message);
}
}

View File

@ -2,25 +2,32 @@ package cn.iocoder.yudao.module.system.api.robot;
import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
import cn.iocoder.yudao.module.system.api.robot.dto.RobotCommandStateDTO;
import cn.iocoder.yudao.module.system.api.robot.dto.RobotCompleteTaskDTO;
import cn.iocoder.yudao.module.system.constant.robot.RobotExecutionStateConstant;
import cn.iocoder.yudao.module.system.constant.robot.RobotTaskChcheConstant;
import cn.iocoder.yudao.module.system.dal.dataobject.actionlog.RobotTaskDetailActionLogDO;
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.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.mysql.actionlog.RobotTaskDetailActionLogMapper;
import cn.iocoder.yudao.module.system.dal.mysql.houselocation.WareHouseLocationMapper;
import cn.iocoder.yudao.module.system.dal.mysql.robot.RobotInformationMapper;
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.robot.CommandTypeEnum;
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.*;
import cn.iocoder.yudao.module.system.enums.robot.task.RobotStatusCodeEnum;
import cn.iocoder.yudao.module.system.enums.robot.task.RobotTaksOrderTypeEnum;
import cn.iocoder.yudao.module.system.service.robot.RobotInformationService;
import cn.iocoder.yudao.module.system.util.redis.RedisUtil;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
@ -30,6 +37,8 @@ import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import static com.baomidou.mybatisplus.core.toolkit.IdWorker.getId;
@Slf4j
@RestController // 提供 RESTful API 接口 Feign 调用
@Validated
@ -44,31 +53,92 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi {
@Autowired@Resource
private RobotInformationMapper robotInformationMapper;
@Resource
private RobotTaskDetailActionLogMapper taskDetailActionLogMapper;
@Autowired
private RobotInformationService robotInformationService;
@Resource
private RedisUtil redisUtil;
@Autowired
private ThreadPoolTaskExecutor taskExecutor;
@Resource
private WareHouseLocationMapper houseLocationMapper;
@Value("${zn.robot_doing_action.doing_action_cache_time:3*60*60}")
private Long doingActionCacheTime;
@Transactional(rollbackFor = Exception.class)
public void doRobotDoneTask(RobotCompleteTaskDTO robotCompleteTaskDTO) {
log.info("机器人完成任务上报 :{}", JSON.toJSONString(robotCompleteTaskDTO));
TenantContextHolder.setTenantId(1L);
if (!RobotStatusCodeEnum.SUCCESS.getType().equals(robotCompleteTaskDTO.getStatus_code())) {
log.info("车机上报异常 :{}", JSON.toJSONString(robotCompleteTaskDTO));
//todo 更新任务状态
return ;
}
if (RobotExecutionStateConstant.UN_DO.equals(robotCompleteTaskDTO.getExecution_state())) {
return ;
}
String robotDoingActionKey = RobotTaskChcheConstant.ROBOT_QUERY_DOING_ACTION +robotCompleteTaskDTO.getMac();
List<RobotCommandStateDTO> commandState = robotCompleteTaskDTO.getCommand_state();
if (ObjectUtil.isNotEmpty(commandState)) {
RobotCommandStateDTO robotCommandStateDTO = commandState.stream()
.filter(v -> RobotExecutionStateConstant.DOING.equals(Integer.valueOf(v.getExecution_state())))
.findFirst()
.orElse(null);
if (ObjectUtil.isNotEmpty(robotCommandStateDTO)) {
redisUtil.set(robotDoingActionKey,robotCommandStateDTO.getCommand_type());
}
String robotDoingActionKey = RobotTaskChcheConstant.ROBOT_QUERY_DOING_ACTION+robotCompleteTaskDTO.getMac();
if (RobotExecutionStateConstant.DOING.equals(robotCompleteTaskDTO.getExecution_state())
&& RobotTaksOrderTypeEnum.TASK.getType().equals(robotCompleteTaskDTO.getOrder_type())) {
taskDoing(robotCompleteTaskDTO, robotDoingActionKey);
} else if(RobotExecutionStateConstant.DONE.equals(robotCompleteTaskDTO.getExecution_state())
&& RobotTaksOrderTypeEnum.TASK.getType().equals(robotCompleteTaskDTO.getOrder_type())) {
taskDone(robotCompleteTaskDTO);
redisUtil.del(robotDoingActionKey);
} else if (RobotExecutionStateConstant.DOING.equals(robotCompleteTaskDTO.getExecution_state())
&& RobotTaksOrderTypeEnum.AUTO_CHARGE.getType().equals(robotCompleteTaskDTO.getOrder_type())) {
chargeDoing(robotCompleteTaskDTO , robotDoingActionKey);
} else if(RobotExecutionStateConstant.DONE.equals(robotCompleteTaskDTO.getExecution_state())
&& RobotTaksOrderTypeEnum.AUTO_CHARGE.getType().equals(robotCompleteTaskDTO.getOrder_type())) {
chargeDone(robotCompleteTaskDTO , robotDoingActionKey);
}
}
/**
* 车辆正在充电
* @param robotCompleteTaskDTO
*/
private void chargeDone(RobotCompleteTaskDTO robotCompleteTaskDTO, String robotDoingActionKey) {
RobotTaskDetailActionLogDO logOne = new RobotTaskDetailActionLogDO();
logOne.setCommandId(getId());
logOne.setActionMsg("车辆正在充电");
String robotNo = robotInformationService.getRobotNoByMac(robotCompleteTaskDTO.getMac());
logOne.setRobotNo(robotNo);
logOne.setTaskDetailId(robotCompleteTaskDTO.getOrder_id());
taskDetailActionLogMapper.insert(logOne);
redisUtil.set(robotDoingActionKey, logOne.getActionMsg(),doingActionCacheTime);
}
/**
* 处理充电中
* @param robotCompleteTaskDTO
*/
private void chargeDoing(RobotCompleteTaskDTO robotCompleteTaskDTO,String robotDoingActionKey) {
List<RobotCommandStateDTO> commandState = robotCompleteTaskDTO.getCommand_state();
if (ObjectUtil.isEmpty(commandState)) {
return;
}
addActionLog(commandState,robotDoingActionKey);
}
/**
* 任务完成
* @param robotCompleteTaskDTO
*/
private void taskDone(RobotCompleteTaskDTO robotCompleteTaskDTO) {
//更新任务状态
RobotTaskDetailDO detailDO = new RobotTaskDetailDO();
detailDO.setId(robotCompleteTaskDTO.getOrder_id());
@ -88,27 +158,112 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi {
robotTaskDO.setTaskStatus(RobotTaskDetailStatusEnum.DONE.getType());
robotTaskMapper.updateRobot(robotTaskDO);
}
//更新机器人任务状态
if ((RobotExecutionStateConstant.DONE.equals(robotCompleteTaskDTO.getExecution_state()) ||
RobotExecutionStateConstant.CLOSE.equals(robotCompleteTaskDTO.getExecution_state()))
&& !RobotTaksOrderTypeEnum.AUTO_CHARGE.getType().equals(robotCompleteTaskDTO.getOrder_type())) {
RobotInformationDO query = new RobotInformationDO();
query.setMacAddress(robotCompleteTaskDTO.getMac());
List<RobotInformationDO> existRobotMac = robotInformationMapper.queryAllByLimit(query);
String robotNo = existRobotMac.get(0).getRobotNo();
robotInformationMapper.updateRobotStatus(robotNo, RobotStatusEnum.STAND_BY.getType());
redisUtil.del(robotDoingActionKey);
} else if (RobotExecutionStateConstant.DONE.equals(robotCompleteTaskDTO.getExecution_state())
&& RobotTaksOrderTypeEnum.AUTO_CHARGE.getType().equals(robotCompleteTaskDTO.getOrder_type())) {
RobotInformationDO query = new RobotInformationDO();
query.setMacAddress(robotCompleteTaskDTO.getMac());
List<RobotInformationDO> existRobotMac = robotInformationMapper.queryAllByLimit(query);
String robotNo = existRobotMac.get(0).getRobotNo();
robotInformationMapper.updateRobotStatus(robotNo, RobotStatusEnum.CHARGE.getType());
redisUtil.set(robotDoingActionKey, CommandTypeEnum.CHARGE.getType());
if (RobotTaskTypeEnum.MOVE.getType().equals(robotTaskDetailDO.getTaskType())) {
robotInformationMapper.updateRobotTaskModel(robotTaskDetailDO.getRobotNo(), RobotTaskModelEnum.REJECTION.getType());
}
}
/**
* 添加操作日志
* @param commandState
*/
public void addActionLog(List<RobotCommandStateDTO> commandState,String robotDoingActionKey) {
RobotCommandStateDTO robotCommandStateDTO = commandState.stream()
.filter(v -> RobotExecutionStateConstant.DOING.equals(Integer.valueOf(v.getExecution_state())))
.findFirst()
.orElse(null);
if (ObjectUtil.isNotEmpty(robotCommandStateDTO)) {
String robotDoingActionLogKey = RobotTaskChcheConstant.ROBOT_ACTION_LOG_ENTITY+robotCommandStateDTO.getCommand_id();
Object o = redisUtil.get(robotDoingActionLogKey);
if (ObjectUtil.isNotEmpty(o)) {
RobotTaskDetailActionLogDO actionLog = JSON.parseObject(JSON.toJSONString(o), RobotTaskDetailActionLogDO.class);
taskDetailActionLogMapper.insert(actionLog);
redisUtil.set(robotDoingActionKey, actionLog.getActionMsg(),doingActionCacheTime);
}
}
}
/**
* 任务处理中
* @param robotCompleteTaskDTO
*/
@Transactional(rollbackFor = Exception.class)
public void taskDoing(RobotCompleteTaskDTO robotCompleteTaskDTO, String robotDoingActionKey) {
List<RobotCommandStateDTO> commandState = robotCompleteTaskDTO.getCommand_state();
if (ObjectUtil.isEmpty(commandState)) {
return;
}
addActionLog(commandState, robotDoingActionKey);
String robotActionTakeGoodsKey = RobotTaskChcheConstant.ROBOT_ACTION_TAKE_GOODS + robotCompleteTaskDTO.getOrder_id();
Object o1 = redisUtil.get(robotActionTakeGoodsKey);
String robotActionReleaseGoodsKey = RobotTaskChcheConstant.ROBOT_ACTION_RELEASE_GOODS + robotCompleteTaskDTO.getOrder_id();
Object o2 = redisUtil.get(robotActionReleaseGoodsKey);
if (ObjectUtil.isEmpty(o1) && ObjectUtil.isEmpty(o2)) {
return;
}
String takeCommonId = ObjectUtil.isNotEmpty(o1) ? String.valueOf(o1) : null;
String releaseCommonId = ObjectUtil.isNotEmpty(o2) ? String.valueOf(o2) : null;
for (RobotCommandStateDTO commandStateDTO : commandState) {
//释放取的库位
if (RobotExecutionStateConstant.DONE.equals(Integer.valueOf(commandStateDTO.getExecution_state()))
&& ObjectUtil.isNotEmpty(takeCommonId) && takeCommonId.equals(commandStateDTO.getCommand_id())) {
RobotTaskDetailActionLogDO actionLogDO =
taskDetailActionLogMapper.selectOne(new LambdaQueryWrapperX<RobotTaskDetailActionLogDO>()
.eq(RobotTaskDetailActionLogDO::getCommandId, commandStateDTO.getCommand_id()));
if (ObjectUtil.isNotEmpty(actionLogDO) && ObjectUtil.isNotEmpty(actionLogDO.getTaskDetailId())) {
freeLocation(true,actionLogDO.getTaskDetailId());
redisUtil.del(robotActionTakeGoodsKey);
}
}
//释放放的库位
if (RobotExecutionStateConstant.DONE.equals(Integer.valueOf(commandStateDTO.getExecution_state()))
&& ObjectUtil.isNotEmpty(releaseCommonId) && releaseCommonId.equals(commandStateDTO.getCommand_id())) {
RobotTaskDetailActionLogDO actionLogDO =
taskDetailActionLogMapper.selectOne(new LambdaQueryWrapperX<RobotTaskDetailActionLogDO>()
.eq(RobotTaskDetailActionLogDO::getCommandId, commandStateDTO.getCommand_id()));
if (ObjectUtil.isNotEmpty(actionLogDO) && ObjectUtil.isNotEmpty(actionLogDO.getTaskDetailId())) {
freeLocation(false,actionLogDO.getTaskDetailId());
redisUtil.del(robotActionReleaseGoodsKey);
}
}
}
}
public void freeLocation(Boolean isTake, Long taskDetailId){
RobotTaskDetailDO robotTaskDetailDO = robotTaskDetailMapper.selectById(taskDetailId);
if (ObjectUtil.isNotEmpty(robotTaskDetailDO) && ObjectUtil.isNotEmpty(robotTaskDetailDO.getFromLocationId())
&& isTake) {
WareHouseLocationDO wareHouseLocationDO = new WareHouseLocationDO();
wareHouseLocationDO.setId(robotTaskDetailDO.getFromLocationId());
wareHouseLocationDO.setLocationLock(LocationLockEnum.YES.getType());
wareHouseLocationDO.setSkuBatch("");
wareHouseLocationDO.setSkuInfo("");
wareHouseLocationDO.setSkuNumber(0l);
wareHouseLocationDO.setLocationUseStatus(LocationUseStatusEnum.NO.getType());
houseLocationMapper.updateEntity(wareHouseLocationDO);
}
if (ObjectUtil.isNotEmpty(robotTaskDetailDO) && ObjectUtil.isNotEmpty(robotTaskDetailDO.getToLocationId())
&& !isTake) {
RobotTaskDO robotTask = robotTaskMapper.selectById(robotTaskDetailDO.getRobotTaskId());
WareHouseLocationDO wareHouseLocationDO = new WareHouseLocationDO();
wareHouseLocationDO.setId(robotTaskDetailDO.getFromLocationId());
wareHouseLocationDO.setLocationLock(LocationLockEnum.YES.getType());
wareHouseLocationDO.setSkuBatch(robotTask.getSkuBatch());
wareHouseLocationDO.setSkuInfo(robotTask.getSkuInfo());
wareHouseLocationDO.setSkuNumber(robotTask.getSkuNumber());
wareHouseLocationDO.setLocationUseStatus(LocationUseStatusEnum.YES.getType());
houseLocationMapper.updateEntity(wareHouseLocationDO);
}
}
/**
* 机器人完成任务上报

View File

@ -12,6 +12,6 @@ public class RobotExecutionStateConstant {
public static Integer DONE = 2;
//已取消
public static Integer CLOSE = 3;
//已失败
//已失败异常
public static Integer FAIL = 4;
}

View File

@ -31,4 +31,13 @@ public class RobotTaskChcheConstant {
//机器人mac地址和机器人id以及机器人类型映射(通过mac地址获取机器人基本信息)
public static String ROBOT_GET_ROBOT_INFO = "robot:information:getRobotInfo";
//机器人正在做的任务整体信息(拼接common_id)
public static String ROBOT_ACTION_LOG_ENTITY = "robot:action:log:entity";
//机器人取货完成(拼接robot_task_detail的id)
public static String ROBOT_ACTION_TAKE_GOODS = "robot:take:";
//机器人放货完成(拼接robot_task_detail的id)
public static String ROBOT_ACTION_RELEASE_GOODS = "robot:release:";
}

View File

@ -33,7 +33,7 @@ import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
@Tag(name = "管理后台 - 车辆动作记录")
@RestController
@RequestMapping("/robot/task-detail-action-log")
@RequestMapping("/system/robot/task-detail-action-log")
@Validated
public class RobotTaskDetailActionLogController {

View File

@ -37,4 +37,7 @@ public class RobotTaskDetailActionLogPageReqVO extends PageParam {
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
@Schema(description = "robot_task_detail的id")
private Long taskDetailId;
}

View File

@ -44,4 +44,7 @@ public class RobotTaskDetailActionLogRespVO {
@ExcelProperty("创建时间")
private LocalDateTime createTime;
@Schema(description = "robot_task_detail的id")
private Long taskDetailId;
}

View File

@ -31,4 +31,7 @@ public class RobotTaskDetailActionLogSaveReqVO {
@Schema(description = "AGV编号")
private String robotNo;
@Schema(description = "robot_task_detail的id")
private Long taskDetailId;
}

View File

@ -1,5 +1,7 @@
package cn.iocoder.yudao.module.system.controller.admin.robot;
import cn.iocoder.yudao.module.system.controller.admin.robot.detail.RobotTaskDetailLogResoVO;
import cn.iocoder.yudao.module.system.controller.admin.robot.detail.RobotTaskDetailLogVO;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotTaskPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotTaskRespVO;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotTaskSaveReqVO;
@ -103,4 +105,12 @@ public class RobotTaskController {
BeanUtils.toBean(list, RobotTaskRespVO.class));
}
@PostMapping("/logPage")
@Operation(summary = "任务日志分页")
@PreAuthorize("@ss.hasPermission('robot:task:logPage')")
public CommonResult<PageResult<RobotTaskDetailLogResoVO>> logPage(@Valid @RequestBody RobotTaskDetailLogVO pageReqVO) {
PageResult<RobotTaskDetailLogResoVO> pageResult = taskService.logPage(pageReqVO);
return success(pageResult);
}
}

View File

@ -44,4 +44,7 @@ public class RobotChargeLogPageReqVO extends PageParam {
@Schema(description = "robot_task_detail的id")
private Long taskDetailId;
@Schema(description = "地图字表节点id")
private Long positionMapItemId;
}

View File

@ -52,4 +52,8 @@ public class RobotChargeLogRespVO {
@ExcelProperty("robot_task_detail的id")
private Long taskDetailId;
@Schema(description = "地图字表节点id")
@ExcelProperty("地图字表节点id")
private Long positionMapItemId;
}

View File

@ -39,4 +39,6 @@ public class RobotChargeLogSaveReqVO {
@Schema(description = "robot_task_detail的id")
private Long taskDetailId;
@Schema(description = "地图字表节点id")
private Long positionMapItemId;
}

View File

@ -0,0 +1,41 @@
package cn.iocoder.yudao.module.system.controller.admin.robot.detail;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class RobotTaskDetailLogResoVO {
@Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "26224")
private Long id;
@Schema(description = "任务号")
private String taskNo;
@Schema(description = "任务类型1取放货、2停车、 3充电、4移动、5仅取货、6仅放货", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
private Integer taskType;
@Schema(description = "任务内容")
private String msg;
@Schema(description = "任务状态(0:未开始、1执行中、2已完成、3已取消、4:异常)", example = "1")
private Integer taskStatus;
@Schema(description = "开始时间")
private LocalDateTime startTime;
@Schema(description = "结束时间")
private LocalDateTime endTime;
@Schema(description = "创建时间")
private LocalDateTime createTime;
@Schema(description = "计算后的目标库位编号")
private String toLocationNo;
@Schema(description = "计算后的来源库位编号")
private String fromLocationNo;
}

View File

@ -0,0 +1,33 @@
package cn.iocoder.yudao.module.system.controller.admin.robot.detail;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.Date;
@Data
public class RobotTaskDetailLogVO extends PageParam {
@Schema(description = "任务号")
private String taskNo;
@Schema(description = "任务类型1取放货、2停车、 3充电、4移动、5仅取货、6仅放货、", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
private Integer taskType;
@Schema(description = "任务状态(0:未开始、1执行中、2已完成、3已取消、4:异常)", example = "1")
private Integer taskStatus;
@Schema(description = "开始时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date startTime;
@Schema(description = "结束时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date endTime;
@Schema(description = "关键词")
private String msg;
}

View File

@ -7,7 +7,7 @@ import lombok.Data;
public class TaskPathPlanningDTO {
@Schema(description = "出发点id(点位子表id)", example = "20863")
private String startingPointId;
private String id;
private Double x;

View File

@ -53,7 +53,7 @@ public class RobotTaskDetailPageReqVO extends PageParam {
@Schema(description = "放货线库id")
private Long toLaneId;
@Schema(description = "任务状态(0:未开始、1执行中、2已完成、3已取消)", example = "1")
@Schema(description = "任务状态(0:未开始、1执行中、2已完成、3已取消、4:异常)", example = "1")
private Integer taskStatus;
@Schema(description = "任务阶段(0:待执行、1前往取货、2取货中、3运输中、4放货中、5结束)")

View File

@ -58,8 +58,8 @@ public class RobotTaskDetailRespVO {
@ExcelProperty("AGV动作")
private String robotAction;
@Schema(description = "任务状态(0:未开始、1执行中、2已完成、3已取消)", example = "1")
@ExcelProperty("任务状态(0:未开始、1执行中、2已完成、3已取消)")
@Schema(description = "任务状态(0:未开始、1执行中、2已完成、3已取消、4:异常)", example = "1")
@ExcelProperty("任务状态(0:未开始、1执行中、2已完成、3已取消、4:异常)")
private Integer taskStatus;
@Schema(description = "任务阶段(0:待执行、1前往取货、2取货中、3运输中、4放货中、5结束)")

View File

@ -59,7 +59,7 @@ public class RobotTaskDetailSaveReqVO {
@Schema(description = "AGV动作")
private String robotAction;
@Schema(description = "任务状态(0:未开始、1执行中、2已完成、3已取消)", example = "1")
@Schema(description = "任务状态(0:未开始、1执行中、2已完成、3已取消、4:异常)", example = "1")
private Integer taskStatus;
@Schema(description = "任务阶段(0:待执行、1前往取货、2取货中、3运输中、4放货中、5结束)")

View File

@ -51,5 +51,9 @@ public class RobotTaskDetailActionLogDO extends BaseDO {
* AGV编号
*/
private String robotNo;
/**
* robot_task_detail的id
*/
private Long taskDetailId;
}

View File

@ -63,4 +63,9 @@ public class RobotChargeLogDO extends BaseDO {
*/
private Long taskDetailId;
/**
* 地图字表节点id
*/
private Long positionMapItemId;
}

View File

@ -22,7 +22,7 @@ public interface RobotTaskDetailActionLogMapper extends BaseMapperX<RobotTaskDet
.eqIfPresent(RobotTaskDetailActionLogDO::getCommandId, reqVO.getCommandId())
.eqIfPresent(RobotTaskDetailActionLogDO::getCommandType, reqVO.getCommandType())
.eqIfPresent(RobotTaskDetailActionLogDO::getCommandMsg, reqVO.getCommandMsg())
.eqIfPresent(RobotTaskDetailActionLogDO::getActionMsg, reqVO.getActionMsg())
.likeIfPresent(RobotTaskDetailActionLogDO::getActionMsg, reqVO.getActionMsg())
.eqIfPresent(RobotTaskDetailActionLogDO::getActionStatus, reqVO.getActionStatus())
.eqIfPresent(RobotTaskDetailActionLogDO::getRobotNo, reqVO.getRobotNo())
.betweenIfPresent(RobotTaskDetailActionLogDO::getCreateTime, reqVO.getCreateTime())

View File

@ -108,4 +108,10 @@ public interface WareHouseLocationMapper extends BaseMapperX<WareHouseLocationDO
* @return
*/
List<WareHouseLocationDO> selectNeedMoveLocation(@Param("locationIds") Set<Long> locationIds);
/**
* 更新
* @param wareHouseLocationDO
*/
void updateEntity(WareHouseLocationDO wareHouseLocationDO);
}

View File

@ -57,10 +57,10 @@ public interface RobotInformationMapper extends BaseMapperX<RobotInformationDO>
/**
* 更新任务模式0拒收任务1正常
* @param robotNos
* @param robotNo
* @param robotTaskModel
*/
void updateRobotTaskModel(@Param("robotNos") Set<String> robotNos,
void updateRobotTaskModel(@Param("robotNo") String robotNo,
@Param("robotTaskModel") Integer robotTaskModel);
/**

View File

@ -5,6 +5,8 @@ import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.system.controller.admin.robot.detail.RobotTaskDetailLogResoVO;
import cn.iocoder.yudao.module.system.controller.admin.robot.detail.RobotTaskDetailLogVO;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotTaskPageReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotTaskDO;
import com.baomidou.mybatisplus.core.metadata.IPage;
@ -62,4 +64,13 @@ public interface RobotTaskMapper extends BaseMapperX<RobotTaskDO> {
*/
IPage<RobotTaskDO> selectPageList(@Param("mpPage") IPage mpPage,
@Param("pageReqVO") RobotTaskPageReqVO pageReqVO);
/**
* 任务日志
* @param mpPage
* @param pageReqVO
* @return
*/
IPage<RobotTaskDetailLogResoVO> selectLogPageList(@Param("mpPage") IPage mpPage,
@Param("pageReqVO") RobotTaskDetailLogVO pageReqVO);
}

View File

@ -0,0 +1,23 @@
package cn.iocoder.yudao.module.system.enums.device;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* device_information的`device_attribute` tinyint DEFAULT NULL COMMENT '设备专有属性1自动充电类型充电桩0手动充电类型充电桩',
*/
@Getter
@AllArgsConstructor
public enum DeviceAttributeEnum {
AUTO_CHARGE(1, "自动充电类型充电桩"),
HAND_MOVEMENT(0, "手动充电类型充电桩");
/**
* 类型
*/
private final Integer type;
/**
* 说明
*/
private final String msg;
}

View File

@ -21,8 +21,7 @@ public enum CommandTypeEnum {
WAIT("WAIT","等待"),
GET_PALLET_TOPIC("GET_PALLET_TOPIC","获取托盘位置"),
MOVE_TO_PALLET_POSE("MOVE_TO_PALLET_POSE","移动到取货终点"),
FORK("FORK","控制货叉上下移动"),
CHARGE("CHARGE","充电");
FORK("FORK","控制货叉上下移动");
/**
* 类型
*/

View File

@ -0,0 +1,22 @@
package cn.iocoder.yudao.module.system.enums.robot.task;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 车机上报的状态码
*/
@Getter
@AllArgsConstructor
public enum RobotStatusCodeEnum {
SUCCESS("10000","成功"),
FAIL_JSON("10001","入参JSON解析失败"),
FAIL_SYSTEM("10002","系统内部异常"),
FAIL_UN_KNOW("10003","未知错误"),
FAIL_UN_SUPPOD("10004","未支持该指令执行");
/**
* 类型
*/
private final String type;
private final String msg;
}

View File

@ -34,7 +34,10 @@ public class HouseLocationStrategyImpl implements NodeProcessingStrategy {
// -- 策略1 处理库位点
// -- 将data里面的json 数据转为实体类 - 再对比节点id - 然后做新增删除修改操作
List<WareHouseLocationDO> newList = new ArrayList<>();
Long locationNumber = nodeBaseDTOS.get(0).getLocationNumber();
Long locationNumber = 0l;
if (ObjectUtil.isNotEmpty(nodeBaseDTOS)) {
locationNumber = nodeBaseDTOS.get(0).getLocationNumber();
}
for (NodeBaseDTO item : nodeBaseDTOS) {
if (item.getId() == null) {
@ -73,15 +76,6 @@ public class HouseLocationStrategyImpl implements NodeProcessingStrategy {
item.setDataJson(JSONUtil.toJsonStr(wareHouseLocationDOS));
}
//判断排序是否重复
List<Long> locationNumbers = newList.stream().map(WareHouseLocationDO::getLocationNumber).collect(Collectors.toList());
if (ObjectUtil.isNotEmpty(locationNumbers)) {
List<WareHouseLocationDO> list = houseLocationService.getLocationByLocationNumbers(locationNumbers);
if (ObjectUtil.isNotEmpty(list)) {
throw exception(HOUSE_LOCATION_NO_EXIST);
}
}
List<WareHouseLocationDO> oldList = houseLocationService.getByMapId(positionMapId);
List<List<WareHouseLocationDO>> list = CollectionUtils.compareLists(oldList, newList,
(oldVal, newVal) -> ObjectUtil.equal(oldVal.getId(), newVal.getId()));

View File

@ -53,4 +53,9 @@ public interface RobotTaskDetailActionLogService {
*/
PageResult<RobotTaskDetailActionLogDO> getTaskDetailActionLogPage(RobotTaskDetailActionLogPageReqVO pageReqVO);
/**
* 添加到缓存
* @param logs
*/
void addLogInCache(List<RobotTaskDetailActionLogDO> logs);
}

View File

@ -1,9 +1,14 @@
package cn.iocoder.yudao.module.system.service.actionlog;
import cn.iocoder.yudao.module.system.constant.robot.RobotTaskChcheConstant;
import cn.iocoder.yudao.module.system.controller.admin.actionlog.vo.RobotTaskDetailActionLogPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.actionlog.vo.RobotTaskDetailActionLogSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.actionlog.RobotTaskDetailActionLogDO;
import cn.iocoder.yudao.module.system.dal.mysql.actionlog.RobotTaskDetailActionLogMapper;
import cn.iocoder.yudao.module.system.util.redis.RedisUtil;
import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
@ -16,6 +21,7 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.system.config.SystemJobConfiguration.NOTIFY_THREAD_POOL_TASK_EXECUTOR;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.TASK_DETAIL_ACTION_LOG_NOT_EXISTS;
/**
@ -30,6 +36,12 @@ public class RobotTaskDetailActionLogServiceImpl implements RobotTaskDetailActio
@Resource
private RobotTaskDetailActionLogMapper taskDetailActionLogMapper;
@Resource
private RedisUtil redisUtil;
@Value("${zn.robot_doing_action.action_entity_cache_time:3600*8}")
private Long robotPositionCacheTime;
@Override
public Long createTaskDetailActionLog(RobotTaskDetailActionLogSaveReqVO createReqVO) {
// 插入
@ -72,4 +84,13 @@ public class RobotTaskDetailActionLogServiceImpl implements RobotTaskDetailActio
return taskDetailActionLogMapper.selectPage(pageReqVO);
}
@Override
@Async(NOTIFY_THREAD_POOL_TASK_EXECUTOR)
public void addLogInCache(List<RobotTaskDetailActionLogDO> logs) {
for (RobotTaskDetailActionLogDO v : logs) {
redisUtil.set(RobotTaskChcheConstant.ROBOT_ACTION_LOG_ENTITY+v.getCommandId(),
JSON.toJSONString(v),robotPositionCacheTime);
}
}
}

View File

@ -276,10 +276,7 @@ public class RobotInformationServiceImpl extends ServiceImpl<RobotInformationMap
v.setRobotTaskStatus(1);
if (RobotStatusEnum.DOING.getType().equals(v.getRobotStatus()) && ObjectUtil.isNotEmpty(action)) {
v.setRobotStatus(1);
CommandTypeEnum commandType = CommandTypeEnum.getCommandType(String.valueOf(action));
if (ObjectUtil.isNotEmpty(commandType)) {
v.setMsg("车辆正在" + commandType.getMsg());
}
v.setMsg(String.valueOf(action));
}
}

View File

@ -4,6 +4,8 @@ import java.util.*;
import javax.validation.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.module.system.controller.admin.robot.detail.RobotTaskDetailLogResoVO;
import cn.iocoder.yudao.module.system.controller.admin.robot.detail.RobotTaskDetailLogVO;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotTaskPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotTaskRespVO;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotTaskSaveReqVO;
@ -66,4 +68,11 @@ public interface RobotTaskService extends IService<RobotTaskDO> {
* @param message
*/
void ppDistributionTask(String message);
/**
* 任务日志分页
* @param pageReqVO
* @return
*/
PageResult<RobotTaskDetailLogResoVO> logPage( RobotTaskDetailLogVO pageReqVO);
}

View File

@ -1,6 +1,7 @@
package cn.iocoder.yudao.module.system.service.robot;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.date.DateUtils;
@ -8,6 +9,9 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils;
import cn.iocoder.yudao.module.mqtt.enums.path.TaskTypeEnum;
import cn.iocoder.yudao.module.system.constant.robot.RobotTaskChcheConstant;
import cn.iocoder.yudao.module.system.controller.admin.robot.detail.RobotTaskDetailLogResoVO;
import cn.iocoder.yudao.module.system.controller.admin.robot.detail.RobotTaskDetailLogVO;
import cn.iocoder.yudao.module.system.controller.admin.robot.task.TaskPPDistribution;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.*;
import cn.iocoder.yudao.module.system.dal.dataobject.houselocation.WareHouseLocationDO;
@ -25,18 +29,21 @@ import cn.iocoder.yudao.module.system.enums.robot.*;
import cn.iocoder.yudao.module.system.service.robot.job.RobotCommonTaskService;
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.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
@ -88,6 +95,9 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper,RobotTaskD
@Resource
private RobotCommonTaskService robotCommonTaskService;
@Autowired
private RobotInformationService robotInformationService;
@Value("${zn.task-no:ZN}")
private String taskNo;
@Value("${zn.do_cycle:true}")
@ -726,11 +736,18 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper,RobotTaskD
* @param message
*/
@Override
@Transactional(rollbackFor = Exception.class)
public void ppDistributionTask(String message) {
log.info("PP分配任务 :{}",message);
TaskPPDistribution[] array = new Gson().fromJson(message, TaskPPDistribution[].class);
List<TaskPPDistribution> list = Arrays.asList(array);
//todo 如果车辆状态是充电中 更新充电表的充电数据
TaskPPDistribution distribution = JSON.parseObject(message,TaskPPDistribution.class);
String mac = robotInformationService.getMacByRobotNo(distribution.getRobotNo());
String robotDoingActionKey = RobotTaskChcheConstant.ROBOT_QUERY_DOING_ACTION+mac;
redisUtil.del(robotDoingActionKey);
List<TaskPPDistribution> list = Arrays.asList(distribution);
List<TaskPPDistribution> taskList = list.stream()
.filter(v -> TaskTypeEnum.TASK.getType().equals(v.getType()))
@ -740,32 +757,31 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper,RobotTaskD
.filter(v -> TaskTypeEnum.CHARGE.getType().equals(v.getType()))
.collect(Collectors.toList());
List<Long> detailIds = new ArrayList<>();
Map<Long, TaskPPDistribution> taskMap =
list.stream().collect(Collectors.toMap(v -> v.getId(), Function.identity()));
List<Long> chargeDetaildIds = null;
Map<Long,String> deviceNoMap = new HashMap<>();
List<RobotChargeLogDO> robotChargeLogs = null;
/**
* 充电
*/
if (ObjectUtil.isNotEmpty(chargeList)) {
List<Long> chargeIds = chargeList.stream().map(TaskPPDistribution::getId).collect(Collectors.toList());
List<RobotChargeLogDO> robotChargeLogs = chargeLogMapper.selectBatchIds(chargeIds);
robotChargeLogs = chargeLogMapper.selectBatchIds(chargeIds);
robotChargeLogs.stream().forEach(taskDetailDO -> {
taskDetailDO.setTaskStatus(RobotTaskDetailStatusEnum.DOING.getType());
});
chargeLogMapper.updateBatch(robotChargeLogs);
Set<String> robotNos = chargeList.stream().map(TaskPPDistribution::getRobotNo).collect(Collectors.toSet());
robotInformationMapper.updateRobotListStatus(robotNos,RobotStatusEnum.CHARGE.getType());
chargeDetaildIds = robotChargeLogs.stream()
robotChargeLogs.stream()
.filter(v -> ObjectUtil.isNotEmpty(v.getTaskDetailId()))
.map(RobotChargeLogDO::getTaskDetailId)
.collect(Collectors.toList());
if (ObjectUtil.isNotEmpty(chargeDetaildIds)) {
detailIds.addAll(chargeDetaildIds);
}
.forEach(v -> {
deviceNoMap.put(v.getTaskDetailId(),v.getDeviceNo());
detailIds.add(v.getTaskDetailId());
});
}
/**
@ -783,10 +799,15 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper,RobotTaskD
List<RobotTaskDetailDO> taskDetailDOS = taskDetailMapper.selectBatchIds(detailIds);
taskDetailDOS.stream().forEach(taskDetailDO -> {
taskDetailDO.setTaskStatus(RobotTaskDetailStatusEnum.DOING.getType());
taskDetailDO.setStartTime(LocalDateTime.now());
TaskPPDistribution taskPPDistribution = taskMap.get(taskDetailDO.getId());
if (ObjectUtil.isNotEmpty(taskPPDistribution) && ObjectUtil.isEmpty(taskDetailDO.getRobotNo())) {
taskDetailDO.setRobotNo(taskPPDistribution.getRobotNo());
}
if (ObjectUtil.isEmpty(taskDetailDO.getToLocationNo())
&& ObjectUtil.isNotEmpty(deviceNoMap.get(taskDetailDO.getId()))) {
taskDetailDO.setToLocationNo(deviceNoMap.get(taskDetailDO.getId()));
}
});
taskDetailMapper.updateBatch(taskDetailDOS);
@ -797,39 +818,72 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper,RobotTaskD
tasks.stream().forEach(task -> {
task.setTaskStatus(RobotTaskStatusEnum.DOING.getType());
});
taskDetailMapper.updateBatch(taskDetailDOS);
taskMapper.updateBatch(tasks);
}
robotCommonTaskService.sendTaskToRobot(taskList);
robotCommonTaskService.sendChargeTaskToRobot(chargeList);
robotCommonTaskService.sendChargeTaskToRobot(chargeList,robotChargeLogs);
}
/**
* 任务日志分页
* @param pageReqVO
* @return
*/
@Override
public PageResult<RobotTaskDetailLogResoVO> logPage(RobotTaskDetailLogVO pageReqVO) {
PageResult<RobotTaskDetailLogResoVO> dataPage = new PageResult<>();
IPage mpPage = MyBatisUtils.buildPage(pageReqVO);
IPage<RobotTaskDetailLogResoVO> page = taskMapper.selectLogPageList(mpPage, pageReqVO);
dataPage.setTotal(page.getTotal());
List<RobotTaskDetailLogResoVO> list = page.getRecords();
List<RobotTaskDetailLogResoVO> targetList = BeanUtil.copyToList(list, RobotTaskDetailLogResoVO.class);
for (RobotTaskDetailLogResoVO robotTaskRespVO : targetList) {
String msg = "";
RobotTaskTypeEnum robotTaskType = RobotTaskTypeEnum.getRobotTaskType(robotTaskRespVO.getTaskType());
switch (robotTaskType) {
case TAKE_RELEASE:
msg = "取货点 " + robotTaskRespVO.getFromLocationNo() +" 放货点 " + robotTaskRespVO.getToLocationNo();
break;
case PARK:
if (ObjectUtil.isNotEmpty(robotTaskRespVO.getToLocationNo())) {
msg = "停车点 " + robotTaskRespVO.getToLocationNo();
}else {
msg = "停车点";
}
break;
case CHARGE:
if (ObjectUtil.isNotEmpty(robotTaskRespVO.getToLocationNo())) {
msg = "充电点 " + robotTaskRespVO.getToLocationNo();
}else {
msg = "充电点";
}
break;
case MOVE:
if (ObjectUtil.isNotEmpty(robotTaskRespVO.getToLocationNo())) {
msg = "移动点 " + robotTaskRespVO.getToLocationNo();
}else {
msg = "移动点";
}
break;
case TAKE:
msg = "取货点 " + robotTaskRespVO.getFromLocationNo();
break;
case RELEASE:
msg = "放货点 " + robotTaskRespVO.getToLocationNo();
break;
default:
log.error("任务类型不存在");
}
robotTaskRespVO.setMsg(msg);
}
dataPage.setList(targetList);
return dataPage;
}
}

View File

@ -27,6 +27,7 @@ import cn.iocoder.yudao.module.system.enums.device.DeviceUseStatusEnum;
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.service.robot.pathplanning.RobotPathPlanningService;
import cn.iocoder.yudao.module.system.util.redis.RedisUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@ -76,6 +77,9 @@ public class AutoChargeServiceImpl implements AutoChargeService {
@Value("${zn.full_electricity:100}")
private String fullElectricity;
@Autowired
private RobotPathPlanningService robotPathPlanningService;
/**
* 自动充电
*/
@ -128,43 +132,18 @@ public class AutoChargeServiceImpl implements AutoChargeService {
detailMap = taskDetailDOS.stream().collect(Collectors.groupingBy(RobotTaskDetailDO::getRobotNo));
}
List<RobotTaskDetailDO> updateTaskDetails = new ArrayList<>();
List<RobotChargeLogDO> logs = new ArrayList<>();
Set<Long> taskIds = new HashSet<>();
//组装充电任务
assembleChargeTask(robots,deviceInformationDOS,chargeConfig,chargeFullNos,updateTaskDetails,logs,taskIds,detailMap);
assembleChargeTask(robots,deviceInformationDOS,chargeConfig,chargeFullNos,logs,detailMap);
if (ObjectUtil.isEmpty(logs)) {
log.info("没有需要执行的充电任务");
return;
}
if (ObjectUtil.isNotEmpty(updateTaskDetails)) {
robotTaskDetailMapper.updateBatch(updateTaskDetails);
}
if (ObjectUtil.isNotEmpty(taskIds)) {
List<RobotTaskDO> taskDOS = robotTaskMapper.selectBatchIds(taskIds);
for (RobotTaskDO taskDO : taskDOS) {
if (RobotTaskStatusEnum.NEW.getType().equals(taskDO.getTaskStatus())) {
taskDO.setTaskStatus(RobotTaskStatusEnum.DOING.getType());
taskDO.setStartTime(LocalDateTime.now());
}
}
robotTaskMapper.updateBatch(taskDOS);
}
Set<String> robotLists = logs.stream()
.map(RobotChargeLogDO::getDeviceNo)
.collect(Collectors.toSet());
if (ObjectUtil.isNotEmpty(robotLists)) {
robotInformationMapper.updateRobotListStatus(robotLists,RobotStatusEnum.DOING.getType());
}
chargeLogMapper.insertBatch(logs);
//todo 发送给路PP
robotPathPlanningService.sendChargeTaskToPP(logs,taskDetailDOS,robots);
//改成异步
logs.stream().forEach(v -> {
@ -180,14 +159,12 @@ public class AutoChargeServiceImpl implements AutoChargeService {
* @param deviceInformationDOS
* @param chargeConfig
* @param chargeFullNos
* @param updateTaskDetails
* @param logs
* @param taskIds
* @param detailMap
*/
public void assembleChargeTask(List<RobotInformationDO> robots, List<DeviceInformationDO> deviceInformationDOS,
CommonConfigVO chargeConfig, List<String> chargeFullNos, List<RobotTaskDetailDO> updateTaskDetails,
List<RobotChargeLogDO> logs, Set<Long> taskIds, Map<String, List<RobotTaskDetailDO>> detailMap) {
CommonConfigVO chargeConfig, List<String> chargeFullNos,
List<RobotChargeLogDO> logs, Map<String, List<RobotTaskDetailDO>> detailMap) {
//判断机器人身上的电量少于设定的电量
for (RobotInformationDO robot : robots) {
String pose2dKey = RobotTaskChcheConstant.ROBOT_INFORMATION_POSE_BAT_SOC +robot.getMacAddress();
@ -203,12 +180,22 @@ public class AutoChargeServiceImpl implements AutoChargeService {
break;
}
RobotChargeLogDO log = new RobotChargeLogDO();
log.setRobotNo(robot.getRobotNo());
// todo 后续需要根据车辆的自动充电/手动充电来分配充电桩
log.setDeviceNo(deviceInformationDOS.get(0).getDeviceNo());
DeviceInformationDO deviceInformationDO = deviceInformationDOS.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());
continue;
}
RobotChargeLogDO logDo = new RobotChargeLogDO();
logDo.setRobotNo(robot.getRobotNo());
logDo.setDeviceNo(deviceInformationDO.getDeviceNo());
logDo.setPositionMapItemId(deviceInformationDO.getPositionMapItemId());
String[] split = dataPoseDTO.getBat_soc().split("\\.");
log.setStartElectricity(Integer.valueOf(split[0]));
logDo.setStartElectricity(Integer.valueOf(split[0]));
//配置的充满电电量
BigDecimal robotFullElectricity = new BigDecimal(fullElectricity);
//车子剩余电量
@ -216,9 +203,10 @@ public class AutoChargeServiceImpl implements AutoChargeService {
if (ObjectUtil.isNotEmpty(chargeConfig.getChanceCycle()) && !chargeFullNos.contains(robot.getRobotNo())
&& robotRemainingElectricity.compareTo(robotFullElectricity) < 0) {
//充满电
log.setChargeModel(ChargeModelEnum.FULL.getType());
logs.add(log);
deviceInformationDOS.removeIf(v -> log.getDeviceNo().equals(v.getDeviceNo()));
logDo.setChargeModel(ChargeModelEnum.FULL.getType());
logs.add(logDo);
deviceInformationDOS.removeIf(v -> logDo.getDeviceNo().equals(v.getDeviceNo()));
log.info("分配到充满电充电任务 :{} ,充电设备编号是 :{}, 任务id :{}",logDo.getRobotNo(),logDo.getDeviceNo(),logDo.getTaskDetailId());
continue;
}
@ -228,15 +216,11 @@ public class AutoChargeServiceImpl implements AutoChargeService {
BigDecimal robotConfigElectricity = new BigDecimal(String.valueOf(robot.getAutoCharge()));
if (robotRemainingElectricity.compareTo(robotConfigElectricity) < 0) {
RobotTaskDetailDO robotTaskDetailDO = detailMap.get(robot.getRobotNo()).get(0);
robotTaskDetailDO.setRobotNo(robot.getRobotNo());
robotTaskDetailDO.setStartTime(LocalDateTime.now());
robotTaskDetailDO.setTaskStatus(RobotTaskDetailStatusEnum.DOING.getType());
updateTaskDetails.add(robotTaskDetailDO);
taskIds.add(robotTaskDetailDO.getRobotTaskId());
deviceInformationDOS.removeIf(v -> log.getDeviceNo().equals(v.getDeviceNo()));
log.setChargeModel(ChargeModelEnum.TASK.getType());
log.setTaskDetailId(robotTaskDetailDO.getId());
logs.add(log);
deviceInformationDOS.removeIf(v -> logDo.getDeviceNo().equals(v.getDeviceNo()));
logDo.setChargeModel(ChargeModelEnum.TASK.getType());
logDo.setTaskDetailId(robotTaskDetailDO.getId());
logs.add(logDo);
log.info("分配到任务充电任务 :{} ,充电设备编号是 :{}, 任务id :{}",logDo.getRobotNo(),logDo.getDeviceNo(),logDo.getTaskDetailId());
continue;
}
}
@ -247,15 +231,11 @@ public class AutoChargeServiceImpl implements AutoChargeService {
BigDecimal robotConfigElectricity = new BigDecimal(String.valueOf(chargeConfig.getStartAutoCharge()));
if (robotRemainingElectricity.compareTo(robotConfigElectricity) < 0) {
RobotTaskDetailDO robotTaskDetailDO = detailMap.get(robot.getRobotNo()).get(0);
robotTaskDetailDO.setRobotNo(robot.getRobotNo());
robotTaskDetailDO.setStartTime(LocalDateTime.now());
robotTaskDetailDO.setTaskStatus(RobotTaskDetailStatusEnum.DOING.getType());
updateTaskDetails.add(robotTaskDetailDO);
taskIds.add(robotTaskDetailDO.getRobotTaskId());
deviceInformationDOS.removeIf(v -> log.getDeviceNo().equals(v.getDeviceNo()));
log.setChargeModel(ChargeModelEnum.TASK.getType());
log.setTaskDetailId(robotTaskDetailDO.getId());
logs.add(log);
deviceInformationDOS.removeIf(v -> logDo.getDeviceNo().equals(v.getDeviceNo()));
logDo.setChargeModel(ChargeModelEnum.TASK.getType());
logDo.setTaskDetailId(robotTaskDetailDO.getId());
logs.add(logDo);
log.info("分配到任务充电任务 :{} ,充电设备编号是 :{}, 任务id :{}",logDo.getRobotNo(),logDo.getDeviceNo(),logDo.getTaskDetailId());
continue;
}
}
@ -266,15 +246,11 @@ public class AutoChargeServiceImpl implements AutoChargeService {
BigDecimal robotConfigElectricity = new BigDecimal(String.valueOf(chargeConfig.getChanceChargeStart()));
if (robotRemainingElectricity.compareTo(robotConfigElectricity) < 0) {
RobotTaskDetailDO robotTaskDetailDO = detailMap.get(robot.getRobotNo()).get(0);
robotTaskDetailDO.setRobotNo(robot.getRobotNo());
robotTaskDetailDO.setStartTime(LocalDateTime.now());
robotTaskDetailDO.setTaskStatus(RobotTaskDetailStatusEnum.DOING.getType());
updateTaskDetails.add(robotTaskDetailDO);
taskIds.add(robotTaskDetailDO.getRobotTaskId());
deviceInformationDOS.removeIf(v -> log.getDeviceNo().equals(v.getDeviceNo()));
log.setChargeModel(ChargeModelEnum.TASK.getType());
log.setTaskDetailId(robotTaskDetailDO.getId());
logs.add(log);
deviceInformationDOS.removeIf(v -> logDo.getDeviceNo().equals(v.getDeviceNo()));
logDo.setChargeModel(ChargeModelEnum.TASK.getType());
logDo.setTaskDetailId(robotTaskDetailDO.getId());
logs.add(logDo);
log.info("分配到任务充电任务 :{} ,充电设备编号是 :{}, 任务id :{}",logDo.getRobotNo(),logDo.getDeviceNo(),logDo.getTaskDetailId());
continue;
}
}
@ -283,9 +259,10 @@ public class AutoChargeServiceImpl implements AutoChargeService {
//自动充电
BigDecimal robotConfigElectricity = new BigDecimal(String.valueOf(robot.getAutoCharge()));
if (robotRemainingElectricity.compareTo(robotConfigElectricity) < 0) {
log.setChargeModel(ChargeModelEnum.AUTO.getType());
logs.add(log);
deviceInformationDOS.removeIf(v -> log.getDeviceNo().equals(v.getDeviceNo()));
logDo.setChargeModel(ChargeModelEnum.AUTO.getType());
logs.add(logDo);
deviceInformationDOS.removeIf(v -> logDo.getDeviceNo().equals(v.getDeviceNo()));
log.info("分配到自动充电任务 :{} ,充电设备编号是 :{}",logDo.getRobotNo(),logDo.getDeviceNo());
continue;
}
}
@ -294,9 +271,10 @@ public class AutoChargeServiceImpl implements AutoChargeService {
//自动充电
BigDecimal robotConfigElectricity = new BigDecimal(String.valueOf(chargeConfig.getStartAutoCharge()));
if (robotRemainingElectricity.compareTo(robotConfigElectricity) < 0) {
log.setChargeModel(ChargeModelEnum.AUTO.getType());
logs.add(log);
deviceInformationDOS.removeIf(v -> log.getDeviceNo().equals(v.getDeviceNo()));
logDo.setChargeModel(ChargeModelEnum.AUTO.getType());
logs.add(logDo);
deviceInformationDOS.removeIf(v -> logDo.getDeviceNo().equals(v.getDeviceNo()));
log.info("分配到自动充电任务 :{} ,充电设备编号是 :{}",logDo.getRobotNo(),logDo.getDeviceNo());
continue;
}
}
@ -305,9 +283,10 @@ public class AutoChargeServiceImpl implements AutoChargeService {
//机会充电
BigDecimal robotConfigElectricity = new BigDecimal(String.valueOf(chargeConfig.getChanceChargeStart()));
if (robotRemainingElectricity.compareTo(robotConfigElectricity) < 0) {
log.setChargeModel(ChargeModelEnum.CHANCE.getType());
logs.add(log);
deviceInformationDOS.removeIf(v -> log.getDeviceNo().equals(v.getDeviceNo()));
logDo.setChargeModel(ChargeModelEnum.CHANCE.getType());
logs.add(logDo);
deviceInformationDOS.removeIf(v -> logDo.getDeviceNo().equals(v.getDeviceNo()));
log.info("分配到机会充电任务 :{} ,充电设备编号是 :{}",logDo.getRobotNo(),logDo.getDeviceNo());
}
}
}

View File

@ -250,7 +250,7 @@ public class DistributeTasksServiceImpl implements DistributeTasksService {
Object chargeModelCache = redisUtil.get(chargeModelKey);
Object poseCache = redisUtil.get(pose2dKey);
RobotStatusDataPoseDTO dataPoseDTO = JSON.parseObject((String) poseCache, RobotStatusDataPoseDTO.class);
log.info("机器人编号:{} ,信息: {}", robot.getRobotNo(), JSON.toJSONString(dataPoseDTO));
log.info("充电机器人编号:{} ,信息: {}", robot.getRobotNo(), JSON.toJSONString(dataPoseDTO));
if (ObjectUtil.isEmpty(commonConfigDO) || ObjectUtil.isEmpty(poseCache) || ObjectUtil.isEmpty(dataPoseDTO.getBat_soc())) {
return;

View File

@ -1,6 +1,7 @@
package cn.iocoder.yudao.module.system.service.robot.job;
import cn.iocoder.yudao.module.system.controller.admin.robot.task.TaskPPDistribution;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotChargeLogDO;
import java.util.List;
@ -21,5 +22,5 @@ public interface RobotCommonTaskService {
* 发送充电任务给车机
* @param chargeList
*/
void sendChargeTaskToRobot(List<TaskPPDistribution> chargeList);
void sendChargeTaskToRobot(List<TaskPPDistribution> chargeList,List<RobotChargeLogDO> robotChargeLogs);
}

View File

@ -4,16 +4,17 @@ import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.mqtt.api.common.CommonApi;
import cn.iocoder.yudao.module.mqtt.api.task.RobotTaskApi;
import cn.iocoder.yudao.module.mqtt.api.task.dto.Pose2ds;
import cn.iocoder.yudao.module.mqtt.api.task.dto.RobotAcceptTaskDTO;
import cn.iocoder.yudao.module.mqtt.api.task.dto.RobotAcceptTaskData;
import cn.iocoder.yudao.module.mqtt.api.task.dto.RobotArgDTO;
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.robot.task.TaskPPDistribution;
import cn.iocoder.yudao.module.system.controller.admin.robot.task.TaskPathPlanningDTO;
import cn.iocoder.yudao.module.system.dal.dataobject.actionlog.RobotTaskDetailActionLogDO;
import cn.iocoder.yudao.module.system.dal.dataobject.houselocation.WareHouseLocationDO;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotChargeLogDO;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotTaskDetailDO;
import cn.iocoder.yudao.module.system.dal.mysql.actionlog.RobotTaskDetailActionLogMapper;
import cn.iocoder.yudao.module.system.dal.mysql.houselocation.WareHouseLocationMapper;
@ -21,7 +22,9 @@ import cn.iocoder.yudao.module.system.dal.mysql.robot.RobotTaskDetailMapper;
import cn.iocoder.yudao.module.system.enums.robot.CommandTypeEnum;
import cn.iocoder.yudao.module.system.enums.robot.RobotTaskTypeEnum;
import cn.iocoder.yudao.module.system.enums.robot.task.RobotTaksOrderTypeEnum;
import cn.iocoder.yudao.module.system.service.actionlog.RobotTaskDetailActionLogService;
import cn.iocoder.yudao.module.system.service.robot.RobotInformationService;
import cn.iocoder.yudao.module.system.util.redis.RedisUtil;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.tuple.Pair;
@ -91,8 +94,11 @@ public class RobotCommonTaskServiceImpl implements RobotCommonTaskService {
@Value("${zn.robot_doing_action.scan}")
private String scan;
@Value("${zn.robot_doing_action.move}")
private String move;
@Value("${zn.robot_doing_action.parking_space}")
private String parkingSpace;
@Value("${zn.robot_doing_action.charge}")
private String charge;
@Resource
private WareHouseLocationMapper houseLocationMapper;
@ -100,6 +106,12 @@ public class RobotCommonTaskServiceImpl implements RobotCommonTaskService {
@Resource
private CommonApi commonApi;
@Resource
private RobotTaskDetailActionLogService taskDetailActionLogService;
@Resource
private RedisUtil redisUtil;
/**
* 让机器人自动充电
@ -171,7 +183,7 @@ public class RobotCommonTaskServiceImpl implements RobotCommonTaskService {
}
}
taskDetailActionLogMapper.insertBatch(logs);
taskDetailActionLogService.addLogInCache(logs);
}
/**
@ -204,6 +216,10 @@ public class RobotCommonTaskServiceImpl implements RobotCommonTaskService {
RobotTaskDetailActionLogDO logTwelve = new RobotTaskDetailActionLogDO();
RobotAcceptTaskData twelveFork = getInitFork(logTwelve, serial, v, robotTaskDetailDO, true, locationMap);
//放货完成使用
String robotActionReleaseGoodsKey = RobotTaskChcheConstant.ROBOT_ACTION_RELEASE_GOODS + robotTaskDetailDO.getId();
redisUtil.set(robotActionReleaseGoodsKey, twelveFork.getCommand_id());
if (ObjectUtil.isNotEmpty(nightMove)) {
list.add(nightMove);
logList.add(logNight);
@ -259,6 +275,10 @@ public class RobotCommonTaskServiceImpl implements RobotCommonTaskService {
RobotAcceptTaskData eightFork = getMovePose(logEight, serial, v, robotTaskDetailDO, locationMap, true,
dongTakeMsg);
//取货完成使用
String robotActionTakeGoodsKey = RobotTaskChcheConstant.ROBOT_ACTION_TAKE_GOODS + robotTaskDetailDO.getId();
redisUtil.set(robotActionTakeGoodsKey, eightFork.getCommand_id());
if (ObjectUtil.isNotEmpty(oneMoveAndFork)) {
list.add(oneMoveAndFork);
logList.add(logOne);
@ -289,8 +309,8 @@ public class RobotCommonTaskServiceImpl implements RobotCommonTaskService {
List<RobotTaskDetailActionLogDO> logList = new ArrayList<>();
//移动
RobotTaskDetailActionLogDO logOne = new RobotTaskDetailActionLogDO();
String msg = move + robotTaskDetailDO.getToLocationNo();
RobotAcceptTaskData oneMoveAndFork = onlyMove(logOne, serial, v, robotTaskDetailDO, msg);
String msg = parkingSpace + robotTaskDetailDO.getToLocationNo();
RobotAcceptTaskData oneMoveAndFork = onlyMove(logOne, serial, v, msg);
list.add(oneMoveAndFork);
logList.add(logOne);
@ -305,11 +325,9 @@ public class RobotCommonTaskServiceImpl implements RobotCommonTaskService {
* @param logOne
* @param serial
* @param v
* @param robotTaskDetailDO
* @return
*/
private RobotAcceptTaskData onlyMove(RobotTaskDetailActionLogDO logOne, Integer serial, TaskPPDistribution v,
RobotTaskDetailDO robotTaskDetailDO, String msg) {
String msg) {
logOne.setCommandId(getId());
RobotAcceptTaskData robotAcceptTaskData = new RobotAcceptTaskData();
robotAcceptTaskData.setSerial(String.valueOf(serial));
@ -322,7 +340,7 @@ public class RobotCommonTaskServiceImpl implements RobotCommonTaskService {
robotAcceptTaskData.setArg(arg);
logOne.setActionMsg(msg);
setCommand(logOne, robotAcceptTaskData, robotTaskDetailDO);
setCommand(logOne, robotAcceptTaskData, v.getRobotNo());
return robotAcceptTaskData;
}
@ -367,6 +385,9 @@ public class RobotCommonTaskServiceImpl implements RobotCommonTaskService {
RobotTaskDetailActionLogDO logEight = new RobotTaskDetailActionLogDO();
RobotAcceptTaskData eightFork = getMovePose(logEight, serial, v, robotTaskDetailDO, locationMap, true,
dongTakeMsg);
//取货完成使用
String robotActionTakeGoodsKey = RobotTaskChcheConstant.ROBOT_ACTION_TAKE_GOODS + robotTaskDetailDO.getId();
redisUtil.set(robotActionTakeGoodsKey, eightFork.getCommand_id());
//行走-
RobotTaskDetailActionLogDO logNight = new RobotTaskDetailActionLogDO();
RobotAcceptTaskData nightMove = getToMovePose(logNight, serial, v, robotTaskDetailDO);
@ -381,6 +402,9 @@ public class RobotCommonTaskServiceImpl implements RobotCommonTaskService {
//抬初始化高度
RobotTaskDetailActionLogDO logTwelve = new RobotTaskDetailActionLogDO();
RobotAcceptTaskData twelveFork = getInitFork(logTwelve, serial, v, robotTaskDetailDO, true, locationMap);
//放货完成使用
String robotActionReleaseGoodsKey = RobotTaskChcheConstant.ROBOT_ACTION_RELEASE_GOODS + robotTaskDetailDO.getId();
redisUtil.set(robotActionReleaseGoodsKey, twelveFork.getCommand_id());
if (ObjectUtil.isNotEmpty(oneMoveAndFork)) {
list.add(oneMoveAndFork);
@ -405,6 +429,7 @@ public class RobotCommonTaskServiceImpl implements RobotCommonTaskService {
RobotTaskDetailDO robotTaskDetailDO, boolean b, Map<Long, WareHouseLocationDO> locationMap
) {
logTwelve.setCommandId(getId());
logTwelve.setTaskDetailId(robotTaskDetailDO.getId());
RobotAcceptTaskData robotAcceptTaskData = new RobotAcceptTaskData();
robotAcceptTaskData.setSerial(String.valueOf(serial));
robotAcceptTaskData.setCommand_id(String.valueOf(logTwelve.getCommandId()));
@ -414,7 +439,7 @@ public class RobotCommonTaskServiceImpl implements RobotCommonTaskService {
robotAcceptTaskData.setArg(arg);
logTwelve.setActionMsg(completeTask);
setCommand(logTwelve, robotAcceptTaskData, robotTaskDetailDO);
setCommand(logTwelve, robotAcceptTaskData, robotTaskDetailDO.getRobotNo());
return robotAcceptTaskData;
}
@ -431,10 +456,11 @@ public class RobotCommonTaskServiceImpl implements RobotCommonTaskService {
private RobotAcceptTaskData getToMovePose(RobotTaskDetailActionLogDO logNight, Integer serial, TaskPPDistribution v,
RobotTaskDetailDO robotTaskDetailDO) {
List<TaskPathPlanningDTO> releases = v.getReleases();
if (releases.size() ==1) {
if (releases.size() == 1) {
return null;
}
logNight.setCommandId(getId());
logNight.setTaskDetailId(robotTaskDetailDO.getId());
RobotAcceptTaskData robotAcceptTaskData = new RobotAcceptTaskData();
robotAcceptTaskData.setSerial(String.valueOf(serial));
robotAcceptTaskData.setCommand_id(String.valueOf(logNight.getCommandId()));
@ -446,7 +472,7 @@ public class RobotCommonTaskServiceImpl implements RobotCommonTaskService {
robotAcceptTaskData.setArg(arg);
logNight.setActionMsg(String.format("机器人正在前往%s%s", robotTaskDetailDO.getToLocationNo(), "放货"));
setCommand(logNight, robotAcceptTaskData, robotTaskDetailDO);
setCommand(logNight, robotAcceptTaskData, robotTaskDetailDO.getRobotNo());
return robotAcceptTaskData;
}
@ -464,6 +490,7 @@ public class RobotCommonTaskServiceImpl implements RobotCommonTaskService {
RobotTaskDetailDO robotTaskDetailDO, Map<Long, WareHouseLocationDO> locationMap,
Boolean isTake, String msg) {
logEight.setCommandId(getId());
logEight.setTaskDetailId(robotTaskDetailDO.getId());
RobotAcceptTaskData robotAcceptTaskData = new RobotAcceptTaskData();
robotAcceptTaskData.setSerial(String.valueOf(serial));
robotAcceptTaskData.setCommand_id(String.valueOf(logEight.getCommandId()));
@ -482,7 +509,7 @@ public class RobotCommonTaskServiceImpl implements RobotCommonTaskService {
RobotArgDTO arg = RobotArgDTO.builder().pose2d(pose2d).build();
robotAcceptTaskData.setArg(arg);
logEight.setActionMsg(msg);
setCommand(logEight, robotAcceptTaskData, robotTaskDetailDO);
setCommand(logEight, robotAcceptTaskData, robotTaskDetailDO.getRobotNo());
return robotAcceptTaskData;
}
@ -498,13 +525,14 @@ public class RobotCommonTaskServiceImpl implements RobotCommonTaskService {
private RobotAcceptTaskData moveToPalletPose(RobotTaskDetailActionLogDO logSix, Integer serial, TaskPPDistribution v,
RobotTaskDetailDO robotTaskDetailDO, String msg) {
logSix.setCommandId(getId());
logSix.setTaskDetailId(robotTaskDetailDO.getId());
RobotAcceptTaskData robotAcceptTaskData = new RobotAcceptTaskData();
robotAcceptTaskData.setSerial(String.valueOf(serial));
robotAcceptTaskData.setCommand_id(String.valueOf(logSix.getCommandId()));
serial++;
robotAcceptTaskData.setCommand_type(CommandTypeEnum.MOVE_TO_PALLET_POSE.getType());
logSix.setActionMsg(msg);
setCommand(logSix, robotAcceptTaskData, robotTaskDetailDO);
setCommand(logSix, robotAcceptTaskData, robotTaskDetailDO.getRobotNo());
return robotAcceptTaskData;
}
@ -520,13 +548,14 @@ public class RobotCommonTaskServiceImpl implements RobotCommonTaskService {
private RobotAcceptTaskData getPalletTopic(RobotTaskDetailActionLogDO logFour, Integer serial, TaskPPDistribution v,
RobotTaskDetailDO robotTaskDetailDO) {
logFour.setCommandId(getId());
logFour.setTaskDetailId(robotTaskDetailDO.getId());
RobotAcceptTaskData robotAcceptTaskData = new RobotAcceptTaskData();
robotAcceptTaskData.setSerial(String.valueOf(serial));
robotAcceptTaskData.setCommand_id(String.valueOf(logFour.getCommandId()));
serial++;
robotAcceptTaskData.setCommand_type(CommandTypeEnum.GET_PALLET_TOPIC.getType());
logFour.setActionMsg(getPalletTopic);
setCommand(logFour, robotAcceptTaskData, robotTaskDetailDO);
setCommand(logFour, robotAcceptTaskData, robotTaskDetailDO.getRobotNo());
return robotAcceptTaskData;
}
@ -534,6 +563,7 @@ public class RobotCommonTaskServiceImpl implements RobotCommonTaskService {
private RobotAcceptTaskData getWait(RobotTaskDetailActionLogDO logThree, Integer serial, TaskPPDistribution v,
RobotTaskDetailDO robotTaskDetailDO) {
logThree.setCommandId(getId());
logThree.setTaskDetailId(robotTaskDetailDO.getId());
RobotAcceptTaskData robotAcceptTaskData = new RobotAcceptTaskData();
robotAcceptTaskData.setSerial(String.valueOf(serial));
robotAcceptTaskData.setCommand_id(String.valueOf(logThree.getCommandId()));
@ -543,7 +573,7 @@ public class RobotCommonTaskServiceImpl implements RobotCommonTaskService {
robotAcceptTaskData.setArg(arg);
logThree.setActionMsg(scan);
setCommand(logThree, robotAcceptTaskData, robotTaskDetailDO);
setCommand(logThree, robotAcceptTaskData, robotTaskDetailDO.getRobotNo());
return robotAcceptTaskData;
}
@ -561,6 +591,7 @@ public class RobotCommonTaskServiceImpl implements RobotCommonTaskService {
Map<Long, WareHouseLocationDO> locationMap, Double addHeight,
String msg) {
logTwo.setCommandId(getId());
logTwo.setTaskDetailId(robotTaskDetailDO.getId());
RobotAcceptTaskData robotAcceptTaskData = new RobotAcceptTaskData();
robotAcceptTaskData.setSerial(String.valueOf(serial));
robotAcceptTaskData.setCommand_id(String.valueOf(logTwo.getCommandId()));
@ -586,7 +617,7 @@ public class RobotCommonTaskServiceImpl implements RobotCommonTaskService {
robotAcceptTaskData.setArg(arg);
logTwo.setActionMsg(msg);
setCommand(logTwo, robotAcceptTaskData, robotTaskDetailDO);
setCommand(logTwo, robotAcceptTaskData, robotTaskDetailDO.getRobotNo());
return robotAcceptTaskData;
}
@ -599,6 +630,7 @@ public class RobotCommonTaskServiceImpl implements RobotCommonTaskService {
}
logOne.setCommandId(getId());
logOne.setTaskDetailId(robotTaskDetailDO.getId());
RobotAcceptTaskData robotAcceptTaskData = new RobotAcceptTaskData();
robotAcceptTaskData.setSerial(String.valueOf(serial));
robotAcceptTaskData.setCommand_id(String.valueOf(logOne.getCommandId()));
@ -614,13 +646,13 @@ public class RobotCommonTaskServiceImpl implements RobotCommonTaskService {
robotAcceptTaskData.setArg(arg);
logOne.setActionMsg(String.format("机器人正在前往%s%s", robotTaskDetailDO.getFromLocationNo(), "取货"));
setCommand(logOne, robotAcceptTaskData, robotTaskDetailDO);
setCommand(logOne, robotAcceptTaskData, robotTaskDetailDO.getRobotNo());
return robotAcceptTaskData;
}
public void setCommand(RobotTaskDetailActionLogDO logOne, RobotAcceptTaskData robotAcceptTaskData, RobotTaskDetailDO robotTaskDetailDO) {
public void setCommand(RobotTaskDetailActionLogDO logOne, RobotAcceptTaskData robotAcceptTaskData, String robotNo) {
logOne.setCommandType(robotAcceptTaskData.getCommand_type());
logOne.setRobotNo(robotTaskDetailDO.getRobotNo());
logOne.setRobotNo(robotNo);
String str = JSON.toJSONString(robotAcceptTaskData);
if (str.length() > 210) {
logOne.setCommandMsg(str.substring(0, 200));
@ -632,13 +664,45 @@ public class RobotCommonTaskServiceImpl implements RobotCommonTaskService {
/**
* 充电任务
*
* @param chargeList
*/
@Override
@Async(NOTIFY_THREAD_POOL_TASK_EXECUTOR)
public void sendChargeTaskToRobot(List<TaskPPDistribution> chargeList) {
public void sendChargeTaskToRobot(List<TaskPPDistribution> chargeList, List<RobotChargeLogDO> robotChargeLogs) {
if (ObjectUtil.isEmpty(chargeList) || ObjectUtil.isEmpty(robotChargeLogs)) {
return;
}
Map<Long, RobotChargeLogDO> chargeMap =
robotChargeLogs.stream().collect(Collectors.toMap(v -> v.getId(), Function.identity()));
List<RobotTaskDetailActionLogDO> logList = new ArrayList<>();
for (TaskPPDistribution v : chargeList) {
RobotChargeLogDO chargeLogDO = chargeMap.get(v.getId());
RobotAcceptTaskDTO robotTask = new RobotAcceptTaskDTO();
robotTask.setOrder_id(v.getId().toString());
String mac = robotInformationService.getMacByRobotNo(v.getRobotNo());
robotTask.setTopic(RobotTopicConstant.ROBOT_TASK_TOPIC + mac);
robotTask.setOrder_type(RobotTaksOrderTypeEnum.AUTO_CHARGE.getType());
Integer serial = 1;
List<RobotAcceptTaskData> list = new ArrayList<>();
//移动
RobotTaskDetailActionLogDO logOne = new RobotTaskDetailActionLogDO();
String msg = charge + chargeLogDO.getDeviceNo();
RobotAcceptTaskData oneMoveAndFork = onlyMove(logOne, serial, v, msg);
list.add(oneMoveAndFork);
robotTask.setData(list);
logList.add(logOne);
log.info("发送给车机下发--充电任务 :{}", JSON.toJSONString(robotTask));
commonApi.commonMethod(robotTask, robotTask.getTopic());
}
//todo 充电后往 task_detail更新下 to_location_no
taskDetailActionLogService.addLogInCache(logList);
}

View File

@ -1,5 +1,17 @@
package cn.iocoder.yudao.module.system.service.robot.pathplanning;
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;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
public interface RobotPathPlanningService {
void sendTaskToPP();
void sendChargeTaskToPP(List<RobotChargeLogDO> logs,
List<RobotTaskDetailDO> taskDetailDOS,
List<RobotInformationDO> robots);
}

View File

@ -13,9 +13,11 @@ import cn.iocoder.yudao.module.mqtt.api.task.dto.RobotAcceptTaskDTO;
import cn.iocoder.yudao.module.mqtt.api.task.dto.RobotAcceptTaskData;
import cn.iocoder.yudao.module.mqtt.enums.path.TaskTypeEnum;
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.dal.dataobject.houselocation.WareHouseLocationDO;
import cn.iocoder.yudao.module.system.dal.dataobject.positionmap.PositionMapDO;
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;
import cn.iocoder.yudao.module.system.dal.mysql.config.CommonConfigMapper;
@ -26,6 +28,7 @@ import cn.iocoder.yudao.module.system.dal.mysql.robot.RobotInformationMapper;
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.robot.*;
import cn.iocoder.yudao.module.system.enums.robot.charge.ChargeModelEnum;
import cn.iocoder.yudao.module.system.service.robot.job.DistributeTasksService;
import cn.iocoder.yudao.module.system.util.redis.RedisUtil;
import com.alibaba.fastjson.JSON;
@ -104,6 +107,12 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
@Resource
private PathPlanningApi pathPlanningApi;
@Value("${zn.robot_chearg.release_location_number_config:50}")
private Long releaseLocationNumberConfig;
@Value("${zn.robot_chearg.priority_config:50}")
private Long priorityConfig;
/**
* 下发任务给PP
*/
@ -132,6 +141,53 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
}
@Override
public void sendChargeTaskToPP(List<RobotChargeLogDO> logs, List<RobotTaskDetailDO> taskDetailDOS,
List<RobotInformationDO> robots) {
//机器人不能行走的区域
List<TaskRobotNoLimittationAreaDTO> robotNoLimitationArea = getRobotNoLimitationArea(robots);
Map<String, TaskRobotNoLimittationAreaDTO> robotNoLimittationAreaDTOMap =
robotNoLimitationArea.stream().collect(Collectors.toMap(v -> v.getRobotNo(), Function.identity()));
Map<Long, RobotTaskDetailDO> taskDetailMap =
taskDetailDOS.stream().collect(Collectors.toMap(v -> v.getId(), Function.identity()));
List<TaskToPathPlanningDTO> pathPlanningList = new ArrayList<>();
for (RobotChargeLogDO v : logs) {
Long priority = priorityConfig;
LocalDateTime createTime = LocalDateTime.now();
if (ObjectUtil.isEmpty(ChargeModelEnum.TASK.getType().equals(v.getChargeModel()))
&& ObjectUtil.isNotEmpty(v.getTaskDetailId())
&& ObjectUtil.isNotEmpty(taskDetailMap.get(v.getTaskDetailId()))) {
createTime = taskDetailMap.get(v.getTaskDetailId()).getCreateTime();
priority = taskDetailMap.get(v.getTaskDetailId()).getPriority();
}
TaskToPathPlanningDTO pathPlanning = TaskToPathPlanningDTO.builder()
.id(String.valueOf(v.getId()))
.type(TaskTypeEnum.CHARGE.getType())
.priority(priority)
.createTime(createTime)
.build();
TaskRobotNoLimittationAreaDTO taskRobotNoLimittationAreaDTO = robotNoLimittationAreaDTOMap.get(v.getRobotNo());
List<TaskRobotNoLimittationAreaDTO> robotNoLimitions = Arrays.asList(taskRobotNoLimittationAreaDTO);
pathPlanning.setRobotNoLimitationAreaDTOS(robotNoLimitions);
pathPlanning.setReleaseGroupId("POINT_" + v.getPositionMapItemId());
pathPlanning.setReleaseLocationNumber(releaseLocationNumberConfig);
pathPlanning.setReleasePointId(v.getPositionMapItemId());
pathPlanningList.add(pathPlanning);
}
log.info("充电任务下发给PP :{}", JSON.toJSONString(pathPlanningList));
pathPlanningApi.synchronousLineObject(pathPlanningList, PathPlanningTopicConstant.TASK_ASSIGNMENT_REQUEST);
}
@Transactional(rollbackFor = Exception.class)
public void distributeTasksToPP(List<RobotInformationDO> robots, List<RobotTaskDetailDO> taskDetailDOS) {
//目前一个点位/线库 只能派一辆车去做
@ -153,13 +209,12 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
List<WareHouseLocationDO> locations = locationMapper.selectList(new LambdaQueryWrapperX<WareHouseLocationDO>()
.in(WareHouseLocationDO::getId, locationIds));
List<PositionMapDO> positionMapDOS = positionMapMapper.selectList(new LambdaQueryWrapperX<PositionMapDO>());
Map<Long, WareHouseLocationDO> locationDOMap =
locations.stream().collect(Collectors.toMap(v -> v.getId(), Function.identity()));
//能执行此任务的机器人 不能走的区域
List<TaskRobotNoLimittationAreaDTO> robotNoLimitationArea = getRobotNoLimitationArea(robots, positionMapDOS);
List<TaskRobotNoLimittationAreaDTO> robotNoLimitationArea = getRobotNoLimitationArea(robots);
Map<String, TaskRobotNoLimittationAreaDTO> robotNoLimittationAreaDTOMap =
robotNoLimitationArea.stream().collect(Collectors.toMap(v -> v.getRobotNo(), Function.identity()));
@ -168,7 +223,7 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
for (RobotTaskDetailDO taskDetailDO : taskDetailDOS) {
TaskToPathPlanningDTO pathPlanning = TaskToPathPlanningDTO.builder()
.id(taskDetailDO.getId())
.id(String.valueOf(taskDetailDO.getId()))
.type(TaskTypeEnum.TASK.getType())
.priority(taskDetailDO.getPriority())
.createTime(taskDetailDO.getCreateTime())
@ -178,7 +233,7 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
if (ObjectUtil.isNotEmpty(taskDetailDO.getRobotNo()) && ObjectUtil.isNotEmpty(robotNoLimittationAreaDTOMap)) {
TaskRobotNoLimittationAreaDTO taskRobotNoLimittationAreaDTO = robotNoLimittationAreaDTOMap.get(taskDetailDO.getRobotNo());
robotNoLimitions = Arrays.asList(taskRobotNoLimittationAreaDTO);
}else if (ObjectUtil.isEmpty(taskDetailDO.getRobotNo())){
} else if (ObjectUtil.isEmpty(taskDetailDO.getRobotNo())) {
robotNoLimitions = robotNoLimitationArea;
}
@ -224,7 +279,7 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
}
if (ObjectUtil.isNotEmpty(pathPlanningList)) {
log.info("任务下发给PP :{}", JSON.toJSONString(pathPlanningList));
log.info("作业任务下发给PP :{}", JSON.toJSONString(pathPlanningList));
pathPlanningApi.synchronousLineObject(pathPlanningList, PathPlanningTopicConstant.TASK_ASSIGNMENT_REQUEST);
}
}
@ -233,10 +288,10 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
* 设置机器人编号及不能行走的区域
*
* @param robots
* @param positionMapDOS
*/
private List<TaskRobotNoLimittationAreaDTO> getRobotNoLimitationArea(List<RobotInformationDO> robots,
List<PositionMapDO> positionMapDOS) {
private List<TaskRobotNoLimittationAreaDTO> getRobotNoLimitationArea(List<RobotInformationDO> robots) {
List<PositionMapDO> positionMapDOS = positionMapMapper.selectList(new LambdaQueryWrapperX<PositionMapDO>());
List<TaskRobotNoLimittationAreaDTO> robotNoLimitationAreaDTOS = new ArrayList<>();
for (RobotInformationDO robot : robots) {
@ -352,7 +407,7 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
} else if (RobotTaskTypeEnum.MOVE.getType().equals(v.getTaskType())
|| RobotTaskTypeEnum.RELEASE.getType().equals(v.getTaskType())) {
//移动和仅放货
moveSetTask(list, v, fromLane, toLane, fromLocation, toLocation, toHaveFrom, fromHaveTo,fromLaneDoRelease);
moveSetTask(list, v, fromLane, toLane, fromLocation, toLocation, toHaveFrom, fromHaveTo, fromLaneDoRelease);
} else if (RobotTaskTypeEnum.TAKE.getType().equals(v.getTaskType())) {
//仅取货
takeSetTask(list, v, fromLane, toLane, fromLocation, toLocation, toHaveFrom, fromHaveTo);
@ -410,7 +465,7 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
private void moveSetTask(List<RobotTaskDetailDO> list, RobotTaskDetailDO v, RobotTaskDetailDO fromLane,
RobotTaskDetailDO toLane,
Long fromLocation, Long toLocation, Long toHaveFrom,
Long fromHaveTo,RobotTaskDetailDO fromLaneDoRelease) {
Long fromHaveTo, RobotTaskDetailDO fromLaneDoRelease) {
if (ObjectUtil.isNotEmpty(toHaveFrom) && toHaveFrom < v.getToLocationNumber()) {
log.info("下发任务给PP--移动/仅放任务--放货点有取货任务 :{}", v.getId());

View File

@ -216,7 +216,7 @@ justauth:
timeout: 24h # 超时时长,目前只对 Redis 缓存生效,默认 3 分钟
map:
file:
upload-path: C:\system\config\map\map\map\2 # 地图文件上传路径
upload-path: /Users/aikai/Documents/map/ # 地图文件上传路径
zn:
task-no: ZN #任务号开头
@ -243,4 +243,11 @@ zn:
complete_task: 机器人完成任务
get_pallet_topic: 机器人扫描托盘位置
scan: 机器人正在扫描
move: 机器人正在前往停车位
parking_space: 机器人正在前往停车位
charge: 机器人正在前往充电位
action_entity_cache_time: 8*60*60 #机器人所有动作缓存时间
doing_action_cache_time: 3*60*60 #单个动作缓存时间
robot_chearg: #机器人充电的配置
release_location_number_config: 50 #同一组序号,越大越先执行
priority_config: 50 #优先级

View File

@ -381,7 +381,7 @@
</insert>
<!--通过主键修改数据-->
<update id="update">
<update id="updateEntity">
update ware_house_location
<set>
<if test="laneId != null">

View File

@ -257,11 +257,7 @@
set
robot_task_model = #{robotTaskModel}
where
robot_no in
<foreach collection="robotNos" item="robotNo" index="index" open="(" close=")"
separator=",">
#{robotNo}
</foreach>
robot_no = = #{robotNo}
</update>

View File

@ -287,6 +287,46 @@
order by t1.create_time desc
</select>
<select id="selectLogPageList"
resultType="cn.iocoder.yudao.module.system.controller.admin.robot.detail.RobotTaskDetailLogResoVO">
select
t1.task_no as taskNo,
t1.create_time as createTime,
t2.id,
t2.task_type as taskType,
t2.task_status as taskStatus,
t2.start_time as startTime,
t2.end_time as endTime,
t2.from_location_no as fromLocationNo,
t2.to_location_no as toLocationNo
from
robot_task t1 inner join robot_task_detail t2
on t1.id = t2.robot_task_id
<where>
t1.deleted = '0'
and t2.deleted = '0'
<if test="pageReqVO.taskNo != null and pageReqVO.taskNo != ''">
and t1.task_no like concat('%', #{pageReqVO.taskNo}, '%')
</if>
<if test="pageReqVO.taskType != null and pageReqVO.taskType != ''">
and t2.task_type = #{pageReqVO.taskType}
</if>
<if test="pageReqVO.taskStatus != null">
and t2.task_status = #{pageReqVO.taskStatus}
</if>
<if test="pageReqVO.msg != null and pageReqVO.msg != ''">
and (t2.from_location_no like concat('%', #{pageReqVO.msg}, '%') or t2.to_location_no like concat('%', #{pageReqVO.msg}, '%'))
</if>
<if test="pageReqVO.startTime!=null ">
AND t1.create_time >= #{pageReqVO.startTime}
</if>
<if test="pageReqVO.endTime!=null ">
AND t1.create_time &lt;= #{pageReqVO.endTime}
</if>
</where>
order by t1.create_time desc
</select>
<!--新增所有列-->
<insert id="insertEntity" keyProperty="id" useGeneratedKeys="true">