新任务下发

This commit is contained in:
cbs 2025-03-08 17:04:02 +08:00
parent 19fd048a1b
commit a57374f2c0
16 changed files with 321 additions and 11 deletions

View File

@ -0,0 +1,17 @@
package cn.iocoder.yudao.module.mqtt.api.task.dto;
import lombok.Builder;
import lombok.Data;
@Data
@Builder
public class RobotAssignTaskArgDTO {
//检测托盘时需要抬叉的高度现在是需要以后不用了
private Double check_pallet_height;
//取货高度
private Double height;
//整型 取第几层货
private Double level;
//叉起货需要在原来高度基础上偏移的高度
private Double offset_height;
}

View File

@ -0,0 +1,18 @@
package cn.iocoder.yudao.module.mqtt.api.task.dto;
import lombok.Builder;
import lombok.Data;
import java.util.List;
/**
* 下发任务给机器人
*/
@Data
@Builder
public class RobotAssignTaskDTO {
private String topic;
private String order_id;
private String order_type;
private List<RobotAssignTaskDataDTO> data;
}

View File

@ -0,0 +1,11 @@
package cn.iocoder.yudao.module.mqtt.api.task.dto;
import lombok.Data;
import java.util.List;
@Data
public class RobotAssignTaskDataDTO {
private String command_type;
private List<RobotAssignTaskArgDTO> arg;
}

View File

@ -68,10 +68,11 @@ public class PathApiImpl implements PathApi {
public void ppDistributionTask(String message) {
taskExecutor.execute(() -> {
TenantContextHolder.setTenantId(1L);
taskService.assignTasks(message);
if (ObjectUtil.isEmpty(message)) {
return;
}
taskService.ppDistributionTask(message);
// taskService.ppDistributionTask(message); 废弃了
});
}

View File

@ -84,10 +84,10 @@ public class RobotStatusApiImpl implements RobotStatusApi {
String pose2dKey = RobotTaskChcheConstant.ROBOT_INFORMATION_POSE_BAT_SOC + robotStatusDataDTO.getMac();
// todo 后续需要改为从车机上报
/*redisUtil.set(taskStatusKey, robotStatusDataDTO.getData().getTask_status(), robotPositionCacheTime);
redisUtil.set(cargoDetectedKey, robotStatusDataDTO.getData().getCargo_detected(), robotPositionCacheTime);*/
redisUtil.set(taskStatusKey, "IDLE", robotPositionCacheTime);
redisUtil.set(cargoDetectedKey, false, robotPositionCacheTime);
redisUtil.set(taskStatusKey, robotStatusDataDTO.getData().getTask_status(), robotPositionCacheTime);
redisUtil.set(cargoDetectedKey, robotStatusDataDTO.getData().getCargo_detected(), robotPositionCacheTime);
/*redisUtil.set(taskStatusKey, "IDLE", robotPositionCacheTime);
redisUtil.set(cargoDetectedKey, false, robotPositionCacheTime);*/
Object object = redisUtil.get(pose2dKey);
RobotStatusDataPoseDTO robotStatusDataPoseDTO = JSONUtil.toBean((String) object, RobotStatusDataPoseDTO.class);
@ -105,8 +105,8 @@ public class RobotStatusApiImpl implements RobotStatusApi {
robotStatusDataPoseDTO.setArea(robotStatusDataDTO.getData().getFloor_zone().getArea());
}
robotStatusDataPoseDTO.setFloor("1");
robotStatusDataPoseDTO.setArea("D区");
/*robotStatusDataPoseDTO.setFloor("1");
robotStatusDataPoseDTO.setArea("C区");*/
robotStatusDataPoseDTO.setRobotNo(robotNo);
redisUtil.set(pose2dKey, JSON.toJSONString(robotStatusDataPoseDTO), robotPositionCacheTime);

View File

@ -43,4 +43,7 @@ public class NodeBaseDTO {
@Schema(description = "排序的位置,越大越优先堆放")
private Long locationNumber;
@Schema(description = " 弧度")
private String locationYaw;
}

View File

@ -1,6 +1,7 @@
package cn.iocoder.yudao.module.system.controller.admin.positionmap.vo;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
@ -48,4 +49,7 @@ public class PositionMapItemPageReqVO extends PageParam {
@Schema(description = "弧度")
private String locationYaw;
@Schema(description = "排序的位置,越大越优先堆放")
private Long locationNumber;
}

View File

@ -66,4 +66,8 @@ public class PositionMapItemRespVO {
@ExcelProperty("弧度")
private String locationYaw;
@Schema(description = "排序的位置,越大越优先堆放")
@ExcelProperty("排序的位置,越大越优先堆放")
private Long locationNumber;
}

View File

@ -39,4 +39,7 @@ public class PositionMapItemSaveReqVO {
@Schema(description = "弧度")
private String locationYaw;
@Schema(description = "排序的位置,越大越优先堆放")
private Long locationNumber;
}

View File

@ -0,0 +1,25 @@
package cn.iocoder.yudao.module.system.controller.admin.robot.task;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* PP分配的任务
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class TaskAssignDTO {
@Schema(description = "robot_task_detail/robot_charge_log 的 id")
private Long id;
@Schema(description = "任务类型(TAKE_RELEASE、CHARGE、MOVE、TAKE、RELEASE、AUTO_CHARGE)")
private String type;
@Schema(description = "AGV编号")
private String robotNo;
}

View File

@ -1,6 +1,7 @@
package cn.iocoder.yudao.module.system.dal.dataobject.positionmap;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import com.alibaba.excel.annotation.ExcelProperty;
import com.baomidou.mybatisplus.annotation.*;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
@ -72,4 +73,9 @@ public class PositionMapItemDO extends BaseDO {
*/
private String locationYaw;
/**
* 排序的位置,越大越优先堆放
*/
private Long locationNumber;
}

View File

@ -0,0 +1,46 @@
package cn.iocoder.yudao.module.system.enums.path;
import cn.iocoder.yudao.module.system.enums.robot.RobotTaskTypeEnum;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 下发路径规划的任务类型
*/
@Getter
@AllArgsConstructor
public enum PathTaskType {
TAKE_RELEASE("TAKE_RELEASE","取放货"),
CHARGE("CHARGE","充电任务"),
MOVE("MOVE","移动任务"),
TAKE("TAKE","仅取货"),
RELEASE("RELEASE","仅放货"),
AUTO_CHARGE("AUTO_CHARGE","自动充电");
/**
* 类型
*/
private final String type;
private final String msg;
/**
* 仅设计个别类型
* @param taskType
* @return
*/
public static String getTaskType(Integer taskType) {
if (RobotTaskTypeEnum.TAKE_RELEASE.getType().equals(taskType)) {
return TAKE_RELEASE.getType();
}else if (RobotTaskTypeEnum.CHARGE.getType().equals(taskType)) {
return CHARGE.getType();
}else if (RobotTaskTypeEnum.MOVE.getType().equals(taskType)) {
return MOVE.getType();
}else if (RobotTaskTypeEnum.TAKE.getType().equals(taskType)) {
return TAKE.getType();
}else if (RobotTaskTypeEnum.RELEASE.getType().equals(taskType)) {
return RELEASE.getType();
}else {
return AUTO_CHARGE.getType();
}
}
}

View File

@ -0,0 +1,18 @@
package cn.iocoder.yudao.module.system.enums.robot.task;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public enum RobotCommandTypeEnum {
WORD_PICK_UP_GOODS("WORD_PICK_UP_GOODS","取货"),
WORD_DROP_OFF_GOODS("WORD_DROP_OFF_GOODS","放货");
/**
* 类型
*/
private final String type;
private final String msg;
}

View File

@ -85,4 +85,10 @@ public interface RobotTaskService extends IService<RobotTaskDO> {
void addCycle(Long id, List<RobotTaskDetailAddVO> taskDetailList);
void closeTask(@Valid RobotTaskSaveReqVO updateReqVO);
/**
* PP分配任务
* @param message
*/
void assignTasks(String message);
}

View File

@ -11,6 +11,9 @@ import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils;
import cn.iocoder.yudao.module.mqtt.api.common.CommonApi;
import cn.iocoder.yudao.module.mqtt.api.task.dto.RobotAcceptTaskDTO;
import cn.iocoder.yudao.module.mqtt.api.task.dto.RobotAssignTaskArgDTO;
import cn.iocoder.yudao.module.mqtt.api.task.dto.RobotAssignTaskDTO;
import cn.iocoder.yudao.module.mqtt.api.task.dto.RobotAssignTaskDataDTO;
import cn.iocoder.yudao.module.mqtt.enums.path.TaskTypeEnum;
import cn.iocoder.yudao.module.mqtt.enums.task.ExecutionTypeEnum;
import cn.iocoder.yudao.module.system.api.path.vo.RobotClosePathPlantingDTO;
@ -21,6 +24,7 @@ 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.detail.RobotTaskDetailLogResoVO;
import cn.iocoder.yudao.module.system.controller.admin.robot.detail.RobotTaskDetailLogVO;
import cn.iocoder.yudao.module.system.controller.admin.robot.task.TaskAssignDTO;
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.cycle.TaskCycleDO;
@ -44,9 +48,11 @@ 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.path.PathTaskType;
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.ChargeTaskStatusEnum;
import cn.iocoder.yudao.module.system.enums.robot.task.RobotCommandTypeEnum;
import cn.iocoder.yudao.module.system.enums.robot.task.RobotTaksOrderTypeEnum;
import cn.iocoder.yudao.module.system.service.robot.job.RobotCommonTaskService;
import cn.iocoder.yudao.module.system.util.redis.RedisUtil;
@ -133,6 +139,12 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
@Value("${zn.task.check_sku_info:true}")
private Boolean checkSkuInfo;
@Value("${zn.robot_config.check_pallet_height}")
private Double checkPalletHeight;
@Value("${zn.robot_config.offset_height}")
private Double offsetHeight;
@Resource
private WareHouseLaneMapper houseLaneMapper;
@ -434,6 +446,138 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
}
/**
* PP分配任务
*
* @param message
*/
@Override
public void assignTasks(String message) {
log.info("PP分配任务,开始更新任务状态 :{}", message);
TaskAssignDTO taskAssignDTO = JSON.parseObject(message, TaskAssignDTO.class);
String mac = robotInformationService.getMacByRobotNo(taskAssignDTO.getRobotNo());
String robotDoingActionKey = RobotTaskChcheConstant.ROBOT_QUERY_DOING_ACTION + mac;
redisUtil.del(robotDoingActionKey);
Long detailId = null;
Map<Long, String> deviceNoMap = new HashMap<>();
RobotChargeLogDO robotChargeLogs = null;
/**
* 充电
*/
if (PathTaskType.AUTO_CHARGE.getType().equals(taskAssignDTO.getType())) {
robotChargeLogs = chargeLogMapper.selectById(taskAssignDTO.getId());
robotChargeLogs.setTaskStatus(ChargeTaskStatusEnum.DOING.getType());
chargeLogMapper.updateBatch(robotChargeLogs);
robotInformationMapper.updateRobotListStatus(taskAssignDTO.getRobotNo(), RobotStatusEnum.CHARGE.getType(), taskAssignDTO.getId());
if (ObjectUtil.isNotEmpty(robotChargeLogs.getTaskDetailId())) {
deviceNoMap.put(robotChargeLogs.getTaskDetailId(), robotChargeLogs.getDeviceNo());
detailId = robotChargeLogs.getTaskDetailId();
}
} else {
chargeDone(taskAssignDTO.getRobotNo());
robotInformationMapper.updateRobotListStatus(taskAssignDTO.getRobotNo(), RobotStatusEnum.DOING.getType(), taskAssignDTO.getId());
detailId = taskAssignDTO.getId();
}
RobotTaskDetailDO robotTaskDetailDO = null;
if (ObjectUtil.isNotEmpty(detailId)) {
robotTaskDetailDO = setTaskDoing(detailId, taskAssignDTO.getRobotNo(), deviceNoMap);
}
if (ObjectUtil.isNotEmpty(robotTaskDetailDO)) {
sendTaskToRobot(robotTaskDetailDO, taskAssignDTO);
}
}
/**
* 发送任务给车机
*
* @param v
*/
private void sendTaskToRobot(RobotTaskDetailDO v, TaskAssignDTO taskAssignDTO) {
String mac = robotInformationService.getMacByRobotNo(v.getRobotNo());
String orderType = PathTaskType.getTaskType(v.getTaskType());
RobotAssignTaskDTO build = RobotAssignTaskDTO.builder()
.topic(RobotTopicConstant.ROBOT_TASK_TOPIC + mac)
.order_type(orderType)
.order_id(v.getId().toString())
.build();
if (PathTaskType.TAKE_RELEASE.getType().equals(taskAssignDTO.getType())
|| PathTaskType.TAKE.getType().equals(taskAssignDTO.getType())
|| PathTaskType.RELEASE.getType().equals(taskAssignDTO.getType())) {
List<RobotAssignTaskDataDTO> robotAssignTaskData = getRobotAssignTaskData(v,taskAssignDTO);
build.setData(robotAssignTaskData);
}
log.info("发送任务给车机 :{}",JSON.toJSONString(build));
commonApi.commonMethod(build, build.getTopic());
}
public List<RobotAssignTaskDataDTO> getRobotAssignTaskData(RobotTaskDetailDO v,TaskAssignDTO taskAssignDTO) {
RobotAssignTaskDataDTO take = null;
RobotAssignTaskDataDTO release = null;
if (PathTaskType.TAKE_RELEASE.getType().equals(taskAssignDTO.getType()) ||
PathTaskType.TAKE.getType().equals(taskAssignDTO.getType())) {
take = new RobotAssignTaskDataDTO();
take.setCommand_type(RobotCommandTypeEnum.WORD_PICK_UP_GOODS.getType());
WareHouseLocationDO location = locationMapper.selectById(v.getFromLocationId());
RobotAssignTaskArgDTO build = RobotAssignTaskArgDTO.builder()
.level(Double.valueOf(location.getLocationStorey()))
.height(Double.valueOf(location.getLocationTrayHeight() + ""))
.check_pallet_height(checkPalletHeight)
.offset_height(offsetHeight)
.build();
take.setArg(Arrays.asList(build));
}
if (PathTaskType.TAKE_RELEASE.getType().equals(taskAssignDTO.getType()) ||
PathTaskType.RELEASE.getType().equals(taskAssignDTO.getType())) {
release = new RobotAssignTaskDataDTO();
release.setCommand_type(RobotCommandTypeEnum.WORD_DROP_OFF_GOODS.getType());
WareHouseLocationDO location = locationMapper.selectById(v.getToLocationId());
RobotAssignTaskArgDTO build = RobotAssignTaskArgDTO.builder()
.level(Double.valueOf(location.getLocationStorey()))
.height(Double.valueOf(location.getLocationTrayHeight() + ""))
.check_pallet_height(checkPalletHeight)
.offset_height(offsetHeight)
.build();
release.setArg(Arrays.asList(build));
}
List<RobotAssignTaskDataDTO> list = new ArrayList<>();
if (ObjectUtil.isNotEmpty(take)) {
list.add(take);
}
if (ObjectUtil.isNotEmpty(release)) {
list.add(release);
}
return list;
}
public RobotTaskDetailDO setTaskDoing(Long detailId, String robotNo, Map<Long, String> deviceNoMap) {
RobotTaskDetailDO taskDetailDO = taskDetailMapper.selectById(detailId);
taskDetailDO.setTaskStatus(RobotTaskDetailStatusEnum.DOING.getType());
taskDetailDO.setStartTime(LocalDateTime.now());
if (ObjectUtil.isEmpty(taskDetailDO.getRobotNo())) {
taskDetailDO.setRobotNo(robotNo);
}
if (ObjectUtil.isEmpty(taskDetailDO.getToLocationNo())
&& ObjectUtil.isNotEmpty(deviceNoMap.get(taskDetailDO.getId()))) {
taskDetailDO.setToLocationNo(deviceNoMap.get(taskDetailDO.getId()));
}
taskDetailMapper.updateBatch(taskDetailDO);
RobotTaskDO task = taskMapper.selectById(taskDetailDO.getRobotTaskId());
task.setTaskStatus(RobotTaskStatusEnum.DOING.getType());
taskMapper.updateBatch(task);
return taskDetailDO;
}
/**
* 设置放货和取货的id
*
@ -994,11 +1138,12 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
}
/**
* PP分配的任务
* PP分配的任务(此方法已经废弃)
*
* @param message
*/
@Override
@Deprecated
@Transactional(rollbackFor = Exception.class)
public void ppDistributionTask(String message) {
log.info("PP分配任务 :{}", message);
@ -1022,7 +1167,7 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
robotChargeLogs.setTaskStatus(ChargeTaskStatusEnum.DOING.getType());
chargeLogMapper.updateBatch(robotChargeLogs);
robotInformationMapper.updateRobotListStatus(distribution.getRobotNo(), RobotStatusEnum.CHARGE.getType(),distribution.getId());
robotInformationMapper.updateRobotListStatus(distribution.getRobotNo(), RobotStatusEnum.CHARGE.getType(), distribution.getId());
if (ObjectUtil.isNotEmpty(robotChargeLogs.getTaskDetailId())) {
deviceNoMap.put(robotChargeLogs.getTaskDetailId(), robotChargeLogs.getDeviceNo());
detailIds.add(robotChargeLogs.getTaskDetailId());
@ -1034,7 +1179,7 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
*/
if (TaskTypeEnum.TASK.getType().equals(distribution.getType())) {
chargeDone(distribution.getRobotNo());
robotInformationMapper.updateRobotListStatus(distribution.getRobotNo(), RobotStatusEnum.DOING.getType(),distribution.getId());
robotInformationMapper.updateRobotListStatus(distribution.getRobotNo(), RobotStatusEnum.DOING.getType(), distribution.getId());
detailIds.add(distribution.getId());
}
@ -1065,7 +1210,7 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
if (TaskTypeEnum.TASK.getType().equals(distribution.getType())) {
robotCommonTaskService.sendTaskToRobot(distribution);
}else if (TaskTypeEnum.CHARGE.getType().equals(distribution.getType())) {
} else if (TaskTypeEnum.CHARGE.getType().equals(distribution.getType())) {
robotCommonTaskService.sendChargeTaskToRobot(distribution, robotChargeLogs);
}

View File

@ -252,4 +252,7 @@ zn:
priority_config: 50 #优先级
task: #任务相关的配置
check_sku_info: true #校验物料信息
robot_config: #机器人取放货默认配置
check_pallet_height: 0.0 #检测托盘时需要抬叉的高度,现在是需要,以后不用了
offset_height: 0.1 #叉起货需要在原来高度基础上偏移的高度