fix: 输送线筛掉行架、堆垛机策略开发测试

This commit is contained in:
2024-07-25 16:25:24 +08:00
parent 2237725716
commit 8f49489147
8 changed files with 233 additions and 84 deletions

View File

@@ -1,13 +1,32 @@
package org.nl.acs.custompolicy;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import org.nl.acs.auto.initial.ApplicationAutoInitial;
import java.util.HashMap;
import java.util.Map;
import org.nl.acs.custompolicy.domain.CustomPolicy;
import org.nl.acs.custompolicy.server.mapper.CustomPolicyMapper;
import org.nl.acs.task.domain.Task;
import org.nl.acs.task.enums.TaskStatusEnum;
import org.nl.acs.task.service.mapper.TaskMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
public class CustomerStragetyCacheService implements ApplicationAutoInitial {
private Map<String, StackerStrategyDto> strategyCache = new HashMap();
@Autowired
private CustomPolicyMapper customPolicyMapper;
public CustomerStragetyCacheService() {
}
@@ -27,5 +46,23 @@ public class CustomerStragetyCacheService implements ApplicationAutoInitial {
@Override
public void autoInitial() throws Exception {
// 策略缓存
List<CustomPolicy> customPolicyList = new LambdaQueryChainWrapper<>(customPolicyMapper)
.eq(CustomPolicy::getIs_on, "1")
.orderByDesc(CustomPolicy::getCreate_time)
.list();
for (CustomPolicy customPolicy : customPolicyList) {
if (StrUtil.isEmpty(customPolicy.getKey_value())){
continue;
}
JSONObject jsonObject = JSONObject.parseObject(customPolicy.getKey_value());
JSONArray plans = jsonObject.getJSONArray("plans");
if (ObjectUtil.isNotEmpty(plans)) {
List<StackerInstruction> plansList = plans.toJavaList(StackerInstruction.class);
StackerStrategyDto stackerStrategyDto = new StackerStrategyDto();
stackerStrategyDto.setPlan(plansList);
stackerStrategyDto.setDeviceCode(customPolicy.getKey_code());
strategyCache.put(customPolicy.getKey_code(), stackerStrategyDto);
}
}
}
}

View File

@@ -1,61 +1,16 @@
package org.nl.acs.custompolicy;
import lombok.Data;
@Data
public class StackerInstruction {
private String procedure;
private String type;
private String from;
private String to;
private int quantity = 1;
private int quantity;
private int sort;
private String to;
private int type;
public StackerInstruction() {
}
public String getProcedure() {
return this.procedure;
}
public void setProcedure(String procedure) {
this.procedure = procedure;
}
public String getType() {
return this.type;
}
public void setType(String type) {
this.type = type;
}
public String getFrom() {
return this.from;
}
public void setFrom(String from) {
this.from = from;
}
public String getTo() {
return this.to;
}
public void setTo(String to) {
this.to = to;
}
public int getQuantity() {
return this.quantity;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
public int getSort() {
return this.sort;
}
public void setSort(int sort) {
this.sort = sort;
}
}

View File

@@ -8,7 +8,7 @@ public class StackerStrategyDto {
/**
* 策略
*/
private List<StackerInstruction> plan = new ArrayList();
private List<StackerInstruction> plans = new ArrayList();
/**
* 禁止策略 暂时未开发
*/
@@ -26,11 +26,11 @@ public class StackerStrategyDto {
}
public List<StackerInstruction> getPlan() {
return this.plan;
return this.plans;
}
public void setPlan(List<StackerInstruction> plan) {
this.plan = plan;
this.plans = plan;
}
public List<StackerInstruction> getForbid() {

View File

@@ -19,15 +19,15 @@ import java.io.Serializable;
public class CustomPolicyPlantDTO implements Serializable {
private static final long serialVersionUID = 1L;
private Integer type;
private Integer from;
private Integer to;
private String from;
private String to;
private Integer quantity;
private Integer sort;
}

View File

@@ -18,9 +18,15 @@ import org.nl.acs.custompolicy.server.dto.CustomPolicyDTO;
import org.nl.acs.custompolicy.server.dto.CustomPolicyPlantDTO;
import org.nl.acs.custompolicy.server.mapper.CustomPolicyMapper;
import org.nl.acs.custompolicy.server.vo.CustomPolicyPlantVO;
import org.nl.acs.device.domain.Device;
import org.nl.acs.device_driver.stacker.standard_stacker.StandardStackerDeviceDriver;
import org.nl.acs.opc.DeviceAppService;
import org.nl.acs.opc.DeviceAppServiceImpl;
import org.nl.acs.utils.ConvertUtil;
import org.nl.acs.utils.PageUtil;
import org.nl.common.utils.SecurityUtils;
import org.nl.config.SpringContextHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
@@ -44,6 +50,8 @@ public class CustomPolicyServiceImpl extends CommonServiceImpl<CustomPolicyMappe
private final CustomPolicyMapper customPolicyMapper;
private final HashMap<String, List<CustomPolicyPlantDTO>> customPolicyPlantDTOMap;
@Autowired
DeviceAppService deviceAppService;
/**
* 初始化策略
@@ -122,6 +130,14 @@ public class CustomPolicyServiceImpl extends CommonServiceImpl<CustomPolicyMappe
customPolicy.setKey_value(null);
}
customPolicyMapper.updateById(customPolicy);
//清除堆垛机策略缓存
Device ddjDevice = deviceAppService.findDeviceByCode(customPolicyPlantVO.getDeviceCode());
StandardStackerDeviceDriver standardStackerDeviceDriver;
if (ddjDevice.getDeviceDriver() instanceof StandardStackerDeviceDriver){
standardStackerDeviceDriver = (StandardStackerDeviceDriver) ddjDevice.getDeviceDriver();
standardStackerDeviceDriver.setTackerInstructionQueue(null);
}
}
@Override

View File

@@ -36,6 +36,7 @@ import org.nl.acs.opc.DeviceAppService;
import org.nl.acs.route.service.RouteLineService;
import org.nl.acs.route.service.dto.RouteLineDto;
import org.nl.acs.task.enums.TaskStatusEnum;
import org.nl.acs.task.enums.TaskTypeEnum;
import org.nl.acs.task.service.TaskService;
import org.nl.acs.task.service.dto.TaskDto;
import org.nl.common.utils.SecurityUtils;
@@ -557,6 +558,10 @@ public class BeltConveyorDeviceDriver extends AbstractOpcDeviceDriver implements
//入库异常口为起点的任务
TaskDto taskdto = taskserver.findByStartCodeAndReady(device_code);
//移除行架任务
if (taskdto.getTask_type().equals(TaskTypeEnum.Truss_Task.getIndex())){
return false;
}
if (ObjectUtil.isNotNull(taskdto)) {
//判断指令的起点和当前的设备号相同
if (!taskdto.getStart_device_code().equals(device_code)) {
@@ -581,6 +586,7 @@ public class BeltConveyorDeviceDriver extends AbstractOpcDeviceDriver implements
}
String this_coevice_code = taskserver.queryAssignedByDevice(device_code, taskdto.getNext_device_code());
if (StrUtil.isEmpty(this_coevice_code)) {
List<RouteLineDto> shortPathsList = routeLineService.getShortPathLines(start_device_code, taskdto.getNext_device_code(), route_plan_code);
RouteLineDto routeLineDto = shortPathsList.get(0);

View File

@@ -9,6 +9,9 @@ import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.nl.acs.common.base.CommonFinalParam;
import org.nl.acs.custompolicy.CustomerStragetyCacheService;
import org.nl.acs.custompolicy.StackerInstruction;
import org.nl.acs.custompolicy.StackerStrategyDto;
import org.nl.acs.device.domain.Device;
import org.nl.acs.device.enums.DeviceType;
import org.nl.acs.device.service.DeviceExtraService;
@@ -19,6 +22,7 @@ import org.nl.acs.device_driver.conveyor.belt_conveyor.BeltConveyorDeviceDriver;
import org.nl.acs.device_driver.conveyor.siemens_conveyor.SiemensConveyorDeviceDriver;
import org.nl.acs.device_driver.driver.AbstractOpcDeviceDriver;
import org.nl.acs.device_driver.driver.ExecutableDeviceDriver;
import org.nl.acs.device_driver.stacker.standard_stacker.enums.CustomPolicyTaskTypeEnum;
import org.nl.acs.device_driver.storage.standard_storage.StandardStorageDeviceDriver;
import org.nl.acs.ext.wms.service.AcsToWmsService;
import org.nl.acs.ext.wms.service.impl.AcsToWmsServiceImpl;
@@ -46,7 +50,9 @@ import org.nl.config.lucene.service.dto.LuceneLogDto;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.*;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
/**
* 单工位堆垛机驱动
@@ -80,6 +86,9 @@ public class StandardStackerDeviceDriver extends AbstractOpcDeviceDriver impleme
@Autowired
private RedisUtils redisUtils;
private CustomerStragetyCacheService customerStragetyCacheService = SpringContextHolder.getBean(CustomerStragetyCacheService.class);;
/**
* 禁止入库
*/
@@ -270,6 +279,9 @@ public class StandardStackerDeviceDriver extends AbstractOpcDeviceDriver impleme
List<String> getDeviceCodeList = null;
List<String> putDeviceCodeList = null;
/**
* 请求成功标记
*/
@@ -295,7 +307,8 @@ public class StandardStackerDeviceDriver extends AbstractOpcDeviceDriver impleme
Boolean iserror = false;
String inst_message;
//阻塞队列,保证指令顺序执行
LinkedBlockingQueue<StackerInstruction> tackerInstructionQueue = new LinkedBlockingQueue<>();
@Override
public Device getDevice() {
@@ -333,16 +346,14 @@ public class StandardStackerDeviceDriver extends AbstractOpcDeviceDriver impleme
}
}
// 更新指令状态
if (mode == 3 && task > 0 && command == 1 && error == 0) {
if (null!=inst) {
if (null != inst) {
inst_message = "指令号:" + inst.getInstruction_code() + " " + inst.getStart_point_code() + "->" + inst.getNext_point_code();
}
Date date = new Date();
if (date.getTime() - this.instruction_update_time.getTime() < (long) this.instruction_update_time_out) {
log.trace("触发时间因为小于{}毫秒,而被无视", this.instruction_update_time_out);
} else {
this.instruction_update_time = date;
//更改指令状态
@@ -360,14 +371,14 @@ public class StandardStackerDeviceDriver extends AbstractOpcDeviceDriver impleme
}
//不同任务限制清零
if (!Objects.equals(task, last_task)) {
this.isonline=true;
this.isonline = true;
count = 0;
}
if (mode == 0 || command == 9) {
this.setIsonline(false);
message = "universal_off";
}else {
} else {
this.setIsonline(true);
}
if (error != 0) {
@@ -425,7 +436,7 @@ public class StandardStackerDeviceDriver extends AbstractOpcDeviceDriver impleme
Pattern compile = Pattern.compile(pattern);
Map<String, Object> map = new HashMap<>();
map.put("code", "to_y");
map.put("value", inst.getTo_z() );
map.put("value", inst.getTo_z());
list.add(map);
if (inst.getTo_x().length() > 1 && !compile.matcher(inst.getTo_x()).matches()) {
String substring = inst.getTo_x().substring(1);
@@ -504,9 +515,9 @@ public class StandardStackerDeviceDriver extends AbstractOpcDeviceDriver impleme
String start_device_code = errorInst.getStart_device_code();
Device startDevice = deviceAppService.findDeviceByCode(start_device_code);
List listError = new ArrayList();
pakageCommand(listError , errorInst.getInstruction_code());
pakageCommand(listError, errorInst.getInstruction_code());
if (StrUtil.equals(startDevice.getDevice_type(), DeviceType.storage.name()) && !prohibitOutWarehouse) {
pakagePlc(errorInst, listError,"1");
pakagePlc(errorInst, listError, "1");
}
if (ObjectUtil.isNotEmpty(listError)) {
this.writing(listError);
@@ -571,7 +582,6 @@ public class StandardStackerDeviceDriver extends AbstractOpcDeviceDriver impleme
}
last_heartbeat = heartbeat;
last_item_deviceCode = item_deviceCode;
last_mode = mode;
@@ -725,7 +735,7 @@ public class StandardStackerDeviceDriver extends AbstractOpcDeviceDriver impleme
luceneExecuteLogService.deviceExecuteLog(logDto1);
String response = acsToWmsService.applyUpdatePointCode(param);
JSONObject jo = JSON.parseObject(response);
if ( jo.getInteger("status") == 200) {
if (jo.getInteger("status") == 200) {
try {
//清警
cleanErro();
@@ -884,7 +894,7 @@ public class StandardStackerDeviceDriver extends AbstractOpcDeviceDriver impleme
//放货完成
if (forkCargo == 0) {
//取货中或者取货完成(分入库出库)
if ("1".equals(instructionErro.getExecute_code()) ) {
if ("1".equals(instructionErro.getExecute_code())) {
List list = new ArrayList();
String startDeviceCode = instructionErro.getStart_device_code();
Device startDeviceError = deviceAppService.findDeviceByCode(startDeviceCode);
@@ -893,7 +903,7 @@ public class StandardStackerDeviceDriver extends AbstractOpcDeviceDriver impleme
requireSucess = true;
return true;
}
}else {
} else {
message = "one_message19";
}
}
@@ -905,21 +915,21 @@ public class StandardStackerDeviceDriver extends AbstractOpcDeviceDriver impleme
requireSucess = true;
return true;
}
}else {
} else {
message = "one_message20";
}
}
//出库报警
if (startDevice.getDeviceDriver() instanceof StandardStorageDeviceDriver) {
//取货报警
if ("1".equals(instructionErro.getExecute_code()) ) {
if ("1".equals(instructionErro.getExecute_code())) {
List list = new ArrayList();
if (StrUtil.equals(startDevice.getDevice_type(), DeviceType.storage.name())) {
pakagePLCData(list, instructionErro.getFrom_x(), instructionErro.getFrom_y(), instructionErro.getFrom_z(), "1", instructionErro.getInstruction_code());
requireSucess = true;
return true;
}
}else {
} else {
message = "one_message19";
}
//放货中报警
@@ -938,7 +948,7 @@ public class StandardStackerDeviceDriver extends AbstractOpcDeviceDriver impleme
requireSucess = true;
return true;
}
}else {
} else {
message = "one_message20";
}
}
@@ -993,7 +1003,22 @@ public class StandardStackerDeviceDriver extends AbstractOpcDeviceDriver impleme
return false;
}
instructionList = this.sortInst(instructionList);
inst = instructionList.get(0);
//堆垛机策略
StackerStrategyDto stragety = customerStragetyCacheService.getStragety(device_code);
List<Instruction> instructionStragetyList = new ArrayList<>();
if (ObjectUtil.isNotEmpty(stragety)) {
//根据筛选指令,指令中包含策略起点终点的指令
stragetySort(stragety, instructionList, instructionStragetyList);
if (!instructionStragetyList.isEmpty()) {
inst = instructionStragetyList.get(0);
} else {
inst = instructionList.get(0);
}
} else {
inst = instructionList.get(0);
}
//指令未执行
if (StrUtil.equals(inst.getInstruction_status(), "0")) {
String start_device_code = inst.getStart_device_code();
@@ -1019,9 +1044,9 @@ public class StandardStackerDeviceDriver extends AbstractOpcDeviceDriver impleme
}
List list = new ArrayList();
pakageCommand(list, inst.getInstruction_code());
packagePlcCoordinate(startDevice, list,"1");
packagePlcCoordinate(startDevice, list, "1");
if (StrUtil.equals(startDevice.getDevice_type(), DeviceType.storage.name()) && !prohibitOutWarehouse) {
pakagePlc(inst, list,"1");
pakagePlc(inst, list, "1");
}
if (ObjectUtil.isNotEmpty(list)) {
this.writing(list);
@@ -1032,6 +1057,78 @@ public class StandardStackerDeviceDriver extends AbstractOpcDeviceDriver impleme
return true;
}
private void stragetySort(StackerStrategyDto stragety, List<Instruction> instructionList, List<Instruction> instructionStragetyList) {
List<StackerInstruction> plan = stragety.getPlan();
Map<String, List<Instruction>> startDeviceCodes = instructionList.stream().collect(Collectors.groupingBy(Instruction::getStart_device_code));
Map<String, List<Instruction>> endDeviceCodes = instructionList.stream().collect(Collectors.groupingBy(Instruction::getNext_device_code));
//初始化队列
if (CollUtil.isNotEmpty(plan)){
if (tackerInstructionQueue.isEmpty()) {
for (StackerInstruction stackerInstruction : plan) {
tackerInstructionQueue.offer(stackerInstruction);
}
}
}
//找到满足策略的指令跳出循环
for (StackerInstruction stackerInstruction : tackerInstructionQueue) {
//从头拿队列
//入库策略
if (StrUtil.isNotEmpty(stackerInstruction.getFrom())) {
if (startDeviceCodes.containsKey(stackerInstruction.getFrom())) {
instructionStragetyList.add(startDeviceCodes.get(stackerInstruction.getFrom()).get(0));
//从头移除队列
tackerInstructionQueue.poll();
break;
}
}
//出库策略
if (StrUtil.isNotEmpty(stackerInstruction.getTo())) {
if (endDeviceCodes.containsKey(stackerInstruction.getTo())) {
instructionStragetyList.add(endDeviceCodes.get(stackerInstruction.getTo()).get(0));
//从头移除队列
tackerInstructionQueue.poll();
break;
}
}
//起点终点都为空根据类型做任务
if (StrUtil.isEmpty(stackerInstruction.getFrom()) && StrUtil.isEmpty(stackerInstruction.getTo())){
//入库
if (CustomPolicyTaskTypeEnum.IN.getCode().equals(stackerInstruction.getType())){
List<Instruction> instIn = instructionList.stream().filter(item -> item.getNext_device_code().contains("L")).collect(Collectors.toList());
if (CollUtil.isNotEmpty(instIn)){
instructionStragetyList.add(instIn.get(0));
//从头移除队列
tackerInstructionQueue.poll();
break;
}
}
//出库
if (CustomPolicyTaskTypeEnum.OUT.getCode().equals(stackerInstruction.getType())){
List<Instruction> instOut = instructionList.stream().filter(item -> item.getStart_device_code().contains("L")).collect(Collectors.toList());
if (CollUtil.isNotEmpty(instOut)){
instructionStragetyList.add(instOut.get(0));
//从头移除队列
tackerInstructionQueue.poll();
break;
}
}
//移库
if (CustomPolicyTaskTypeEnum.MOVE.getCode().equals(stackerInstruction.getType())){
List<Instruction> instInAndOut = instructionList.stream().filter(item -> item.getStart_device_code().contains("L") && item.getNext_device_code().contains("L") ).collect(Collectors.toList());
if (CollUtil.isNotEmpty(instInAndOut)){
instructionStragetyList.add(instInAndOut.get(0));
//从头移除队列
tackerInstructionQueue.poll();
break;
}
}
}
}
}
private void packagePlcCoordinate(Device startDevice, List list, String toCommand) {
if (StrUtil.equals(startDevice.getDevice_type(), DeviceType.conveyor.name()) && !prohibitInWarehouse) {
if (ObjectUtil.isNotEmpty(startDevice.getExtraValue().get("z"))) {

View File

@@ -0,0 +1,38 @@
/**
* @author ls
* @date 2023/11/20 13:33
*/
package org.nl.acs.device_driver.stacker.standard_stacker.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public enum CustomPolicyTaskTypeEnum {
/**
* 入库
*/
OUT(1, "入库"),
/**
* 出库
*/
IN(2, "出库"),
/**
* 移库
*/
MOVE(3, "移库");
Integer code;
String status;
public static String getStatus(Integer code) {
for (CustomPolicyTaskTypeEnum value : values()) {
if (value.code.equals(code)) {
return value.status;
}
}
return null;
}
}