1.ndc交互粘包需要分割判断
2.空架入库会出现最后同时满料,增加软锁控制,创建任务时过滤,二次分配时可以放,任务完成或取消后解锁
This commit is contained in:
@@ -17,6 +17,7 @@ import org.nl.acs.instruction.service.impl.InstructionServiceImpl;
|
||||
import org.nl.acs.log.service.DeviceExecuteLogService;
|
||||
import org.nl.acs.opc.DeviceAppService;
|
||||
import org.nl.acs.task.service.TaskService;
|
||||
import org.nl.acs.utils.ByteUtil;
|
||||
import org.nl.system.service.lucene.LuceneExecuteLogService;
|
||||
import org.nl.system.service.param.ISysParamService;
|
||||
import org.nl.config.SpringContextHolder;
|
||||
@@ -28,7 +29,7 @@ import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.Socket;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@@ -112,12 +113,13 @@ public class OneNDCSocketConnectionAutoRun extends AbstractAutoRunnable {
|
||||
StringBuffer bs1 = new StringBuffer("0");
|
||||
bs.append(temp < 16 ? bs1.append(Integer.toHexString(temp)) : Integer.toHexString(temp));
|
||||
}
|
||||
|
||||
int chunkSize = 28;
|
||||
List<int[]> chunks = this.splitArray(arrAll, chunkSize);
|
||||
for (int i = 0; i < chunks.size(); i++) {
|
||||
int[] arr = chunks.get(i);
|
||||
if (arr[8] * 256 + arr[9] == 0x73) {
|
||||
List<int[]> packets = ByteUtil.splitAndConvertPackets(bs.toString());
|
||||
log.info("接收agv上报信息:" + bs);
|
||||
// 打印分割后的报文
|
||||
for (int i = 0; i < packets.size(); i++) {
|
||||
int[] arr = packets.get(i);
|
||||
log.info("处理当前分割部分{}", Arrays.toString(arr));
|
||||
if (arr.length>10&&arr[8] * 256 + arr[9] == 0x73) {
|
||||
byte[] data = null;
|
||||
//执行阶段
|
||||
int phase = arr[16] * 256 + arr[17];
|
||||
@@ -247,6 +249,7 @@ public class OneNDCSocketConnectionAutoRun extends AbstractAutoRunnable {
|
||||
if (!ObjectUtil.isEmpty(data)) {
|
||||
write(data);
|
||||
}
|
||||
|
||||
} else {
|
||||
log.info("agv上报不是0073类型动作,不处理");
|
||||
}
|
||||
@@ -303,22 +306,5 @@ public class OneNDCSocketConnectionAutoRun extends AbstractAutoRunnable {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static List<int[]> splitArray(int[] array, int chunkSize) {
|
||||
List<int[]> resultList = new ArrayList<>();
|
||||
int length = array.length;
|
||||
|
||||
for (int i = 0; i < length; i += chunkSize) {
|
||||
// 计算当前子数组的大小
|
||||
int currentChunkSize = Math.min(chunkSize, length - i);
|
||||
|
||||
// 创建并填充新的子数组
|
||||
int[] chunk = new int[currentChunkSize];
|
||||
System.arraycopy(array, i, chunk, 0, currentChunkSize);
|
||||
resultList.add(chunk);
|
||||
}
|
||||
|
||||
return resultList;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
package org.nl.acs.utils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ByteUtil{
|
||||
|
||||
public static List<int[]> splitAndConvertPackets(String data) {
|
||||
// 将输入的十六进制字符串转换为字节数组
|
||||
byte[] dataBytes = hexStringToByteArray(data);
|
||||
|
||||
// 87CD的字节表示
|
||||
byte[] startMarker = {(byte) 0x87, (byte) 0xCD};
|
||||
|
||||
// 存储结果的列表
|
||||
List<int[]> packets = new ArrayList<>();
|
||||
|
||||
// 当前分割点
|
||||
int start = 0;
|
||||
|
||||
// 遍历整个字节数组
|
||||
while (start < dataBytes.length) {
|
||||
// 找到下一个87CD的起始位置
|
||||
int nextStart = findStartMarker(dataBytes, startMarker, start + 2);
|
||||
|
||||
if (nextStart == -1) {
|
||||
// 没有找到下一个87CD,说明到了最后一个包
|
||||
packets.add(byteArrayToIntArray(dataBytes, start, dataBytes.length - start));
|
||||
break;
|
||||
} else {
|
||||
// 找到一个新的87CD,将前面的部分作为一个完整的包
|
||||
packets.add(byteArrayToIntArray(dataBytes, start, nextStart - start));
|
||||
start = nextStart;
|
||||
}
|
||||
}
|
||||
|
||||
return packets;
|
||||
}
|
||||
|
||||
private static int findStartMarker(byte[] data, byte[] marker, int start) {
|
||||
for (int i = start; i <= data.length - marker.length; i++) {
|
||||
boolean match = true;
|
||||
for (int j = 0; j < marker.length; j++) {
|
||||
if (data[i + j] != marker[j]) {
|
||||
match = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (match) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private static byte[] hexStringToByteArray(String s) {
|
||||
int len = s.length();
|
||||
byte[] data = new byte[len / 2];
|
||||
for (int i = 0; i < len; i += 2) {
|
||||
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
|
||||
+ Character.digit(s.charAt(i + 1), 16));
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
private static int[] byteArrayToIntArray(byte[] bytes, int offset, int length) {
|
||||
int[] intArray = new int[length];
|
||||
for (int i = 0; i < length; i++) {
|
||||
intArray[i] = bytes[offset + i] & 0xFF;
|
||||
}
|
||||
return intArray;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
String data = "87cd0008001400010073001000796e030003023e0300000000003f2c87cd00080014000100730010007b6e03000309370200000000003f2d87cd00080014000100730010007f6e03000309310600000000003f3087cd00080014000100730010001f6e030009085c06000001085c3eec87cd00080036000100450032002f00020000000000000000000300000085669788c40000708000000000000000000000000200000a59000000000000000087cd00080036000100450032002f00020000000000000000000300000085669788c40000708000000000000000000000000200000a59000000000000000087cd00080036000100450032002f0006000000000000000000030000012e669788c40000708000000000000000000000000400000000000000000000000087cd00080036000100450032002f00020000000000000000000300000085669788c40000708000000000000000000000000200000a59000000000000000087cd00080036000100450032002f00020000000000000000000300000085669788c50000708000000000000000000000000200000a590000000000000000";
|
||||
|
||||
// 处理数据
|
||||
List<int[]> packets = splitAndConvertPackets(data);
|
||||
|
||||
// 打印分割后的报文
|
||||
for (int i = 0; i < packets.size(); i++) {
|
||||
System.out.print("Packet " + (i + 1) + ": ");
|
||||
for (int value : packets.get(i)) {
|
||||
System.out.print(String.format("%02x", value) + " ");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,6 +137,9 @@ public class SchBasePoint implements Serializable {
|
||||
@TableField(exist = false)
|
||||
private String point_status_name;
|
||||
|
||||
@ApiModelProperty(value = "是否锁定")
|
||||
private Boolean is_lock;
|
||||
|
||||
// 组盘标识
|
||||
@TableField(exist = false)
|
||||
private String group_id;
|
||||
|
||||
@@ -76,7 +76,8 @@ public class KGHJRKTask extends AbstractTask {
|
||||
// 找终点
|
||||
SchBasePoint startPoint = pointService.getOne(new LambdaQueryWrapper<SchBasePoint>()
|
||||
.eq(SchBasePoint::getPoint_code, task.getPoint_code1()));
|
||||
SchBasePoint point = findNextPoint(startPoint, task.getVehicle_type());
|
||||
//创建任务时判断软锁,已锁则不能创建,下发任务时不考虑
|
||||
SchBasePoint point = findNextPoint(startPoint, task.getVehicle_type(),0);
|
||||
if (ObjectUtil.isEmpty(point)) {
|
||||
task.setRemark("未找到所需点位!");
|
||||
taskService.update(task);
|
||||
@@ -97,9 +98,9 @@ public class KGHJRKTask extends AbstractTask {
|
||||
task.setRemark("");
|
||||
taskService.update(task);
|
||||
|
||||
// //发起任务时先把点位占用,防止发起重复任务
|
||||
// point.setIng_task_code(task.getTask_code());
|
||||
// pointService.update(point);
|
||||
//发起任务时先把点位占用,防止发起重复任务
|
||||
point.setIs_lock(true);
|
||||
pointService.update(point);
|
||||
|
||||
//下发
|
||||
this.renotifyAcs(task);
|
||||
@@ -112,7 +113,7 @@ public class KGHJRKTask extends AbstractTask {
|
||||
* 2.倒叙查找,找到满足当前位置数量不足3的即可
|
||||
* 3.负极板优先放到HCQ7,放满了再放到HCQ1
|
||||
*/
|
||||
private SchBasePoint findNextPoint(SchBasePoint startPoint, String vehicleType) {
|
||||
private SchBasePoint findNextPoint(SchBasePoint startPoint, String vehicleType,int type) {
|
||||
String regionCode = null;
|
||||
String regionCode2 = null;
|
||||
if ("A1".equals(startPoint.getWorkshop_code())) {
|
||||
@@ -139,6 +140,9 @@ public class KGHJRKTask extends AbstractTask {
|
||||
if (!temp.getPoint_code().endsWith("01")) {
|
||||
continue;
|
||||
}
|
||||
if(type==0&&temp.getIs_lock()){
|
||||
log.info("当前点位{}已被软锁,寻找终点时默认跳过",temp.getPoint_code());
|
||||
}
|
||||
//如果当列已放满,跳过到下一列最后一个点位0501开始判断
|
||||
if (flag && !temp.getPoint_code().endsWith("0501")) {
|
||||
continue;
|
||||
@@ -235,14 +239,17 @@ public class KGHJRKTask extends AbstractTask {
|
||||
// 终点解锁,库存增加
|
||||
endPointObj.setIng_task_code("");
|
||||
endPointObj.setVehicle_qty(1);
|
||||
endPointObj.setIs_lock(false);
|
||||
pointService.update(endPointObj);
|
||||
endPointObj = pointService.getById(endPoint.substring(0, endPoint.length() - 1) + "2");
|
||||
endPointObj.setIng_task_code("");
|
||||
endPointObj.setVehicle_qty(1);
|
||||
endPointObj.setIs_lock(false);
|
||||
pointService.update(endPointObj);
|
||||
endPointObj = pointService.getById(endPoint.substring(0, endPoint.length() - 1) + "3");
|
||||
endPointObj.setIng_task_code("");
|
||||
endPointObj.setVehicle_qty(1);
|
||||
endPointObj.setIs_lock(false);
|
||||
pointService.update(endPointObj);
|
||||
|
||||
|
||||
@@ -254,6 +261,7 @@ public class KGHJRKTask extends AbstractTask {
|
||||
// 终点解锁
|
||||
if (ObjectUtil.isNotEmpty(endPointObj)) {
|
||||
endPointObj.setIng_task_code("");
|
||||
endPointObj.setIs_lock(false);
|
||||
pointService.update(endPointObj);
|
||||
}
|
||||
taskObj.setRemark("任务取消");
|
||||
@@ -282,7 +290,7 @@ public class KGHJRKTask extends AbstractTask {
|
||||
}
|
||||
SchBasePoint startPoint = pointService.getOne(new LambdaQueryWrapper<SchBasePoint>()
|
||||
.eq(SchBasePoint::getPoint_code, schBaseTask.getPoint_code1()));
|
||||
SchBasePoint point = findNextPoint(startPoint, schBaseTask.getVehicle_type());
|
||||
SchBasePoint point = findNextPoint(startPoint, schBaseTask.getVehicle_type(),1);
|
||||
if ("ZJBKGHJDJW".equals(point.getRegion_code())) {
|
||||
schBaseTask.setPoint_code2(point.getPoint_code() + "0" + (point.getVehicle_qty() + 1));
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user