rev:ndc netty
This commit is contained in:
@@ -55,25 +55,30 @@ public enum StatusEnum {
|
||||
QXXL_FULL_REQ("9", "取满框请求(清洗下料)", ""),
|
||||
QXXL_EMPTY_REQ("10", "叫空框请求(清洗下料)", ""),
|
||||
QXXL_COMPEL_REQ("11", "强制搬出请求(清洗下料)", ""),
|
||||
KZSL_EMPTY_REQ("12","取空框请求(刻字上料)",""),
|
||||
KZSL_EMPTY_REQ("12", "取空框请求(刻字上料)", ""),
|
||||
EMPTY_REQ("22", "补空框请求(三工位)", ""),
|
||||
|
||||
HAIROU_IN_REQ("13","半成品入库(海柔)",""),
|
||||
HAIROU_OUT_REQ("14","半成品出库(海柔)",""),
|
||||
HAIROU_INVENTORY_REQ("15","盘点(海柔)",""),
|
||||
HAIROU_EMPTY_OUT_REQ("16","空载具出库(海柔)",""),
|
||||
HAIROU_EMPTY_IN_REQ("17","空载具入库(海柔)",""),
|
||||
HAIROU_IN_REQ("13", "半成品入库(海柔)", ""),
|
||||
HAIROU_OUT_REQ("14", "半成品出库(海柔)", ""),
|
||||
HAIROU_INVENTORY_REQ("15", "盘点(海柔)", ""),
|
||||
HAIROU_EMPTY_OUT_REQ("16", "空载具出库(海柔)", ""),
|
||||
HAIROU_EMPTY_IN_REQ("17", "空载具入库(海柔)", ""),
|
||||
|
||||
HAIROU_LIKU_REQ("18","半成品库任务(海柔)",""),
|
||||
TWO_TASK_1("10", "双点位任务", "取放/取取放放"),
|
||||
TWO_TASK_2("12", "双点位任务", "取放取放"),
|
||||
THREE_TASK("11", "三点位任务", "取倒放"),
|
||||
|
||||
HAIROU_RELOCATION("19","移库(海柔)",""),
|
||||
HAIROU_CARRY("20","搬运(海柔)",""),
|
||||
HAIROU_CHECK("21","盘库(海柔)",""),
|
||||
HAIROU_LIKU_REQ("18", "半成品库任务(海柔)", ""),
|
||||
|
||||
TOTE_INBOUND("1","容器入库","tote_inbound"),
|
||||
TOTE_OUTBOUND("2","容器出库","tote_outbound"),
|
||||
TOTE_RELOCATION("3","容器移库","tote_relocation"),
|
||||
TOTE_CARRY("4","容器搬运","tote_carry"),
|
||||
TOTE_CHECK("5","容器盘库","tote_check"),
|
||||
HAIROU_RELOCATION("19", "移库(海柔)", ""),
|
||||
HAIROU_CARRY("20", "搬运(海柔)", ""),
|
||||
HAIROU_CHECK("21", "盘库(海柔)", ""),
|
||||
|
||||
TOTE_INBOUND("1", "容器入库", "tote_inbound"),
|
||||
TOTE_OUTBOUND("2", "容器出库", "tote_outbound"),
|
||||
TOTE_RELOCATION("3", "容器移库", "tote_relocation"),
|
||||
TOTE_CARRY("4", "容器搬运", "tote_carry"),
|
||||
TOTE_CHECK("5", "容器盘库", "tote_check"),
|
||||
|
||||
//指令状态
|
||||
INST_READY("0", "就绪", ""),
|
||||
@@ -86,9 +91,9 @@ public enum StatusEnum {
|
||||
TASK_RUNNING("1", "执行中", "6"),
|
||||
TASK_FINISH("2", "完成", "7"),
|
||||
TASK_CANCEL("3", "取消", "8"),
|
||||
TASK_FULL_IN("4","满入",""),
|
||||
TASK_EMPTY_OUT("5","空出",""),
|
||||
TASK_CHECK_ANOMALY("6","盘点异常","");
|
||||
TASK_FULL_IN("4", "满入", ""),
|
||||
TASK_EMPTY_OUT("5", "空出", ""),
|
||||
TASK_CHECK_ANOMALY("6", "盘点异常", "");
|
||||
|
||||
private String code;
|
||||
private String desc;
|
||||
|
||||
@@ -73,4 +73,22 @@ public interface NDCAgvService {
|
||||
* @throws Exception
|
||||
*/
|
||||
public void sendAgvTwoInstToNDC(Instruction inst, Instruction inst2) throws Exception;
|
||||
|
||||
/**
|
||||
* 智能三线反馈诺宝AGV
|
||||
*
|
||||
* @param phase
|
||||
* @param index
|
||||
* @param result
|
||||
* @return
|
||||
*/
|
||||
byte[] sendInstToNuoBaoNdc(int phase, int index, int result);
|
||||
|
||||
/**
|
||||
* 智能三线下发诺宝AGV指令
|
||||
*
|
||||
* @param inst
|
||||
* @param inst2
|
||||
*/
|
||||
void sendNuoBaoAgvInst(Instruction inst, Instruction inst2);
|
||||
}
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
package org.nl.acs.agv.server.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
public class AgvDto implements Serializable {
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,9 +5,11 @@ import cn.hutool.core.util.StrUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.nl.acs.AcsConfig;
|
||||
import org.nl.acs.acsEnum.StatusEnum;
|
||||
import org.nl.acs.agv.server.NDCAgvService;
|
||||
import org.nl.acs.agv.server.dto.AgvDto;
|
||||
import org.nl.acs.auto.run.NDCSocketConnectionAutoRun;
|
||||
import org.nl.acs.auto.run.NdcNettyConnectionAutoRun;
|
||||
import org.nl.acs.auto.run.OneNDCSocketConnectionAutoRun;
|
||||
import org.nl.acs.device.service.DeviceService;
|
||||
import org.nl.acs.device.service.impl.DeviceServiceImpl;
|
||||
@@ -493,7 +495,7 @@ public class NDCAgvServiceImpl implements NDCAgvService {
|
||||
(byte) 0X00, (byte) 0X01,
|
||||
(byte) 0X00, (byte) 0X71,
|
||||
(byte) 0X00, (byte) 0X16,
|
||||
(byte) 0X01, (byte) 0X80,
|
||||
(byte) 0X01, (byte) prioritylow,
|
||||
(byte) 0X00, (byte) 0X01,
|
||||
(byte) ikeyhigh, (byte) ikeylow,
|
||||
(byte) ikeyhigh, (byte) ikeylow,
|
||||
@@ -512,4 +514,131 @@ public class NDCAgvServiceImpl implements NDCAgvService {
|
||||
System.out.println("下发agv指令数据:" + Bytes2HexString(b));
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] sendInstToNuoBaoNdc(int phase, int index, int result) {
|
||||
log.info("反馈agv动作数据--index:" + hexToString((byte) IntToHexHigh(index) & 0xFF) + hexToString((byte) IntToHexLow(index) & 0xFF) + ",phase:" + hexToString((byte) IntToHexHigh(phase) & 0xFF) + hexToString((byte) IntToHexLow(phase) & 0xFF));
|
||||
return (phase < 0 || index < 0) ? null : new byte[]{
|
||||
(byte) 0X87, (byte) 0XCD,
|
||||
(byte) 0X00, (byte) 0X08,
|
||||
(byte) 0X00, (byte) 0X0A,
|
||||
(byte) 0X00, (byte) 0X01,
|
||||
(byte) 0X00, (byte) 0X6D,
|
||||
(byte) 0X00, (byte) 0X06,
|
||||
(byte) IntToHexHigh(index), (byte) IntToHexLow(index),
|
||||
(byte) 0X01, (byte) 0X17,
|
||||
(byte) IntToHexHigh(phase), (byte) IntToHexLow(phase)
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendNuoBaoAgvInst(Instruction inst, Instruction inst2) {
|
||||
int type = 1;
|
||||
if (inst2 != null && StatusEnum.TWO_TASK_1.getCode().equals(inst.getInstruction_type())) {
|
||||
type = 4;
|
||||
} else if (inst2 != null && StatusEnum.TWO_TASK_2.getCode().equals(inst.getInstruction_type())) {
|
||||
type = 3;
|
||||
} else if (inst2 != null && StatusEnum.THREE_TASK.getCode().equals(inst.getInstruction_type())) {
|
||||
type = 5;
|
||||
} else if (inst2 == null && StatusEnum.THREE_TASK.getCode().equals(inst.getInstruction_type())) {
|
||||
type = 2;
|
||||
}
|
||||
String instcode = inst.getLink_num();
|
||||
int priority = Integer.parseInt(inst.getPriority()) + 128;
|
||||
DeviceService deviceService = SpringContextHolder.getBean(DeviceServiceImpl.class);
|
||||
int startAddress1 = deviceService.queryAddressBydeviceCode(inst.getStart_point_code());
|
||||
int putAddress1 = deviceService.queryAddressBydeviceCode(inst.getPut_point_code());
|
||||
int nextAddress1 = deviceService.queryAddressBydeviceCode(inst.getNext_point_code());
|
||||
int startAddress2 = 0;
|
||||
int putAddress2 = 0;
|
||||
int nextAddress2 = 0;
|
||||
if (ObjectUtil.isNotEmpty(inst2)) {
|
||||
startAddress2 = deviceService.queryAddressBydeviceCode(inst2.getStart_point_code());
|
||||
putAddress2 = deviceService.queryAddressBydeviceCode(inst2.getPut_point_code());
|
||||
nextAddress2 = deviceService.queryAddressBydeviceCode(inst2.getNext_point_code());
|
||||
}
|
||||
|
||||
|
||||
byte ikeyhigh = (byte) IntToHexHigh(Integer.parseInt(instcode));
|
||||
byte ikeylow = (byte) IntToHexLow(Integer.parseInt(instcode));
|
||||
byte typehigh = (byte) IntToHexHigh(type);
|
||||
byte typelow = (byte) IntToHexLow(type);
|
||||
|
||||
byte qhd1high = (byte) IntToHexHigh(startAddress1);
|
||||
byte qhd1low = (byte) IntToHexLow(startAddress1);
|
||||
|
||||
byte qhd2high = (type == 4 || type == 5) ? (byte) IntToHexHigh(startAddress2) : 0;
|
||||
byte qhd2low = (type == 4 || type == 5) ? (byte) IntToHexLow(startAddress2) : 0;
|
||||
|
||||
byte dld1high = (byte) IntToHexHigh(putAddress1);
|
||||
byte dld1low = (byte) IntToHexLow(putAddress1);
|
||||
|
||||
byte dld2high = (byte) IntToHexHigh(putAddress2);
|
||||
byte dld2low = (byte) IntToHexLow(putAddress2);
|
||||
|
||||
byte fhd1high = (byte) IntToHexHigh(nextAddress1);
|
||||
byte fhd1low = (byte) IntToHexLow(nextAddress1);
|
||||
|
||||
byte fhd2high = (byte) IntToHexHigh(nextAddress2);
|
||||
byte fhd2low = (byte) IntToHexLow(nextAddress2);
|
||||
|
||||
byte qhd3high = (type == 3 || type == 6) ? (byte) IntToHexHigh(startAddress1) : 0;
|
||||
byte qhd3low = (type == 3 || type == 6) ? (byte) IntToHexLow(startAddress1) : 0;
|
||||
|
||||
byte qhd4high = type == 6 ? (byte) IntToHexHigh(startAddress2) : 0;
|
||||
byte qhd4low = type == 6 ? (byte) IntToHexLow(startAddress2) : 0;
|
||||
|
||||
byte fhd3high = (type == 3 || type == 6) ? (byte) IntToHexHigh(nextAddress1) : 0;
|
||||
byte fhd3low = (type == 3 || type == 6) ? (byte) IntToHexLow(nextAddress1) : 0;
|
||||
|
||||
byte fhd4high = type == 6 ? (byte) IntToHexHigh(nextAddress2) : 0;
|
||||
byte fhd4low = type == 6 ? (byte) IntToHexLow(nextAddress2) : 0;
|
||||
|
||||
byte prioritylow = (byte) IntToHexLow(priority);
|
||||
|
||||
String str = "十进制下发:";
|
||||
String str1 = "十六进制下发:";
|
||||
str1 += "ikey:" + hexToString(ikeyhigh & 0xFF) + hexToString(ikeylow & 0xFF);
|
||||
|
||||
str += "/type:" + (type);
|
||||
str1 += "/type:" + hexToString(typehigh & 0xFF) + hexToString(typelow & 0xFF);
|
||||
|
||||
str1 += "/qhd1:" + hexToString(qhd1high & 0xFF) + hexToString(qhd1low & 0xFF);
|
||||
str1 += "/qhd2:" + hexToString(qhd2high & 0xFF) + hexToString(qhd2low & 0xFF);
|
||||
str1 += "/dld1:" + hexToString(dld1high & 0xFF) + hexToString(dld1low & 0xFF);
|
||||
|
||||
str1 += "/dld2:" + hexToString(dld2high & 0xFF) + hexToString(dld2low & 0xFF);
|
||||
str1 += "/fhd1:" + hexToString(fhd1high & 0xFF) + hexToString(fhd1low & 0xFF);
|
||||
str1 += "/fhd2:" + hexToString(fhd2high & 0xFF) + hexToString(fhd2low & 0xFF);
|
||||
|
||||
System.out.println(str);
|
||||
System.out.println(str1);
|
||||
|
||||
byte[] b = new byte[]{(byte) 0X87, (byte) 0XCD,
|
||||
(byte) 0X00, (byte) 0X08,
|
||||
(byte) 0X00, (byte) 0X22,
|
||||
(byte) 0X00, (byte) 0X01,
|
||||
(byte) 0X00, (byte) 0X71,
|
||||
(byte) 0X00, (byte) 0X1E,
|
||||
(byte) 0X01, (byte) prioritylow,
|
||||
(byte) 0X00, (byte) 0X01,
|
||||
ikeyhigh, ikeylow,
|
||||
ikeyhigh, ikeylow,
|
||||
typehigh, typelow,
|
||||
qhd1high, qhd1low,
|
||||
qhd2high, qhd2low,
|
||||
dld1high, dld1low,
|
||||
dld2high, dld2low,
|
||||
fhd1high, fhd1low,
|
||||
fhd2high, fhd2low,
|
||||
qhd3high, qhd3low,
|
||||
qhd4high, qhd4low,
|
||||
fhd3high, fhd3low,
|
||||
fhd4high, fhd4low,
|
||||
};
|
||||
log.info("下发AGV作业指令--{}", str1);
|
||||
|
||||
NdcNettyConnectionAutoRun.write(b);
|
||||
System.out.println("下发agv指令数据:" + Bytes2HexString(b));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
package org.nl.acs.auto.run;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import io.netty.bootstrap.Bootstrap;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.*;
|
||||
import io.netty.channel.nio.NioEventLoopGroup;
|
||||
import io.netty.channel.socket.SocketChannel;
|
||||
import io.netty.channel.socket.nio.NioSocketChannel;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.nl.acs.AcsConfig;
|
||||
import org.nl.acs.device_driver.basedriver.agv.nuoBaoNdc.NuoBaoNdcDeviceDriver;
|
||||
import org.nl.acs.opc.Device;
|
||||
import org.nl.acs.opc.DeviceAppService;
|
||||
import org.nl.config.ProtocolCodec;
|
||||
import org.nl.modules.common.exception.BadRequestException;
|
||||
import org.nl.modules.system.service.ParamService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import static org.nl.acs.agv.server.impl.NDCAgvServiceImpl.Bytes2HexString;
|
||||
|
||||
/**
|
||||
* @author onepiece
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class NdcNettyConnectionAutoRun extends AbstractAutoRunnable {
|
||||
|
||||
@Autowired
|
||||
private ParamService paramService;
|
||||
@Autowired
|
||||
private DeviceAppService deviceAppService;
|
||||
|
||||
private static final int[] PHASES_CAR_ID = {0x67, 0x70, 0x71, 0x72, 0x73, 0x74};
|
||||
|
||||
private final Bootstrap bootstrap = new Bootstrap();
|
||||
private static final EventLoopGroup group = new NioEventLoopGroup();
|
||||
private static Channel channel;
|
||||
|
||||
@Override
|
||||
public String getCode() {
|
||||
return NdcNettyConnectionAutoRun.class.getSimpleName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "智能三线诺宝NDC连接";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void autoRun() {
|
||||
String ip = paramService.findByCode(AcsConfig.ONEAGVURL).getValue();
|
||||
int port = Integer.parseInt(paramService.findByCode(AcsConfig.ONEAGVPORT).getValue());
|
||||
try {
|
||||
Bootstrap bootstrap = createBootstrap();
|
||||
ChannelFuture boot = bootstrap.connect(ip, port).sync();
|
||||
channel = boot.channel();
|
||||
channel.closeFuture().sync();
|
||||
} catch (Exception e) {
|
||||
log.error("agv连接出现异常: {}", JSON.toJSONString(e));
|
||||
if (channel != null) {
|
||||
channel.flush();
|
||||
channel.close();
|
||||
}
|
||||
} finally {
|
||||
group.shutdownGracefully();
|
||||
}
|
||||
}
|
||||
|
||||
private Bootstrap createBootstrap() {
|
||||
return bootstrap.group(group)
|
||||
.option(ChannelOption.SO_KEEPALIVE, true)
|
||||
.option(ChannelOption.TCP_NODELAY, true)
|
||||
.channel(NioSocketChannel.class)
|
||||
.handler(new ChannelInitializer<SocketChannel>() {
|
||||
@Override
|
||||
protected void initChannel(SocketChannel ch) {
|
||||
ch.pipeline().addLast(new MsgHandler());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
if (channel != null) {
|
||||
channel.flush();
|
||||
channel.close();
|
||||
}
|
||||
group.shutdownGracefully();
|
||||
}
|
||||
|
||||
public static void write(byte[] b) {
|
||||
try {
|
||||
log.info("下发agv数据:" + Bytes2HexString(b));
|
||||
channel.writeAndFlush(Unpooled.copiedBuffer(b));
|
||||
} catch (Exception e) {
|
||||
try {
|
||||
log.info("再次下发agv数据:" + Bytes2HexString(b));
|
||||
channel.writeAndFlush(Unpooled.copiedBuffer(b));
|
||||
} catch (Exception e1) {
|
||||
throw new BadRequestException(e1.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class MsgHandler extends SimpleChannelInboundHandler<ByteBuf> {
|
||||
@Override
|
||||
@SneakyThrows
|
||||
protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) {
|
||||
if (msg.isReadable()) {
|
||||
byte[] bytes = ProtocolCodec.readBody(msg);
|
||||
if (bytes.length > 0) {
|
||||
//执行阶段
|
||||
Integer phase = (Byte.toUnsignedInt(bytes[16]) << 8) + Byte.toUnsignedInt(bytes[17]);
|
||||
//agv任务号
|
||||
Integer index = (Byte.toUnsignedInt(bytes[12]) << 8) + Byte.toUnsignedInt(bytes[13]);
|
||||
//任务号
|
||||
Integer ikey = (Byte.toUnsignedInt(bytes[26]) << 8) + Byte.toUnsignedInt(bytes[27]);
|
||||
//站点号
|
||||
Integer param = (Byte.toUnsignedInt(bytes[18]) << 8) + Byte.toUnsignedInt(bytes[19]);
|
||||
//车号
|
||||
byte carId = bytes[20];
|
||||
Device device = null;
|
||||
//Phase值为这些站点号param代表小车号,否则carId代表小车号
|
||||
if (Arrays.stream(PHASES_CAR_ID).anyMatch(v -> v == phase)) {
|
||||
device = deviceAppService.findDeviceByCode(Integer.toString(param));
|
||||
} else {
|
||||
device = deviceAppService.findDeviceByCode(Integer.toString(carId));
|
||||
}
|
||||
if (device != null && device.getDeviceDriver() instanceof NuoBaoNdcDeviceDriver) {
|
||||
NuoBaoNdcDeviceDriver deviceDriver = (NuoBaoNdcDeviceDriver) device.getDeviceDriver();
|
||||
deviceDriver.processSocket(bytes, phase, index, ikey, Byte.toUnsignedInt(carId), param);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package org.nl.acs.device_driver.basedriver.agv.nuoBaoNdc;
|
||||
|
||||
import org.nl.acs.device_driver.DeviceDriver;
|
||||
import org.nl.acs.device_driver.DeviceDriverDefination;
|
||||
import org.nl.acs.opc.Device;
|
||||
import org.nl.acs.opc.DeviceType;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 智能三线诺宝AGV
|
||||
*/
|
||||
@Service
|
||||
public class NuoBaoNdcDefination implements DeviceDriverDefination {
|
||||
@Override
|
||||
public String getDriverCode() {
|
||||
return "nuo_bao_ndc";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDriverName() {
|
||||
return "智能三线诺宝AGV";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDriverDescription() {
|
||||
return "智能三线诺宝AGV";
|
||||
}
|
||||
|
||||
@Override
|
||||
public DeviceDriver getDriverInstance(Device device) {
|
||||
return (new NuoBaoNdcDeviceDriver()).setDevice(device).setDriverDefination(this);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends DeviceDriver> getDeviceDriverType() {
|
||||
return NuoBaoNdcDeviceDriver.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DeviceType> getFitDeviceTypes() {
|
||||
List<DeviceType> types = new LinkedList();
|
||||
types.add(DeviceType.agv);
|
||||
return types;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,869 @@
|
||||
package org.nl.acs.device_driver.basedriver.agv.nuoBaoNdc;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import lombok.Data;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.nl.acs.acsEnum.StatusEnum;
|
||||
import org.nl.acs.agv.server.NDCAgvService;
|
||||
import org.nl.acs.agv.server.dto.AgvDto;
|
||||
import org.nl.acs.agv.server.impl.NDCAgvServiceImpl;
|
||||
import org.nl.acs.auto.run.NdcNettyConnectionAutoRun;
|
||||
import org.nl.acs.device.service.DeviceService;
|
||||
import org.nl.acs.device_driver.DeviceDriver;
|
||||
import org.nl.acs.device_driver.basedriver.hailiang_one.hailiang_cleaning_put_line.HailiangCleaningPutLineDeviceDriver;
|
||||
import org.nl.acs.device_driver.basedriver.hailiang_one.hailiang_engraving_cache.HailiangEngravingCacheDeviceDriver;
|
||||
import org.nl.acs.device_driver.basedriver.hailiang_one.hailiang_engraving_in.HailiangEngravingInDeviceDriver;
|
||||
import org.nl.acs.device_driver.basedriver.hailiang_one.hailiang_engraving_machine.HailiangEngravingMachineDeviceDriver;
|
||||
import org.nl.acs.device_driver.basedriver.hailiang_one.hailiang_packer_station.HailiangPackerStationDeviceDriver;
|
||||
import org.nl.acs.device_driver.basedriver.standard_ordinary_site.StandardOrdinarySiteDeviceDriver;
|
||||
import org.nl.acs.device_driver.basedriver.standard_storage.StandardStorageDeviceDriver;
|
||||
import org.nl.acs.device_driver.driver.AbstractDeviceDriver;
|
||||
import org.nl.acs.instruction.service.InstructionService;
|
||||
import org.nl.acs.instruction.service.dto.Instruction;
|
||||
import org.nl.acs.instruction.service.impl.InstructionServiceImpl;
|
||||
import org.nl.acs.opc.Device;
|
||||
import org.nl.acs.opc.DeviceAppService;
|
||||
import org.nl.acs.task.service.TaskService;
|
||||
import org.nl.acs.task.service.dto.TaskDto;
|
||||
import org.nl.acs.task.service.impl.TaskServiceImpl;
|
||||
import org.nl.modules.wql.util.SpringContextHolder;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 智能三线诺宝AGV
|
||||
*
|
||||
* @author onepiece
|
||||
*/
|
||||
@Slf4j
|
||||
@Data
|
||||
@RequiredArgsConstructor
|
||||
public class NuoBaoNdcDeviceDriver extends AbstractDeviceDriver implements DeviceDriver {
|
||||
|
||||
private final InstructionService instructionService = SpringContextHolder.getBean(InstructionServiceImpl.class);
|
||||
private final NDCAgvService ndcAgvService = SpringContextHolder.getBean(NDCAgvServiceImpl.class);
|
||||
private final DeviceAppService deviceAppService = SpringContextHolder.getBean(DeviceAppService.class);
|
||||
private final DeviceService deviceService = SpringContextHolder.getBean(DeviceService.class);
|
||||
private final TaskService taskService = SpringContextHolder.getBean(TaskServiceImpl.class);
|
||||
|
||||
/**
|
||||
* 当前AGV正在执行的指令信息
|
||||
*/
|
||||
private List<Instruction> instructions = null;
|
||||
|
||||
/**
|
||||
* AGV设备编码
|
||||
*/
|
||||
private String device_code;
|
||||
|
||||
/**
|
||||
* AGV上报站点值
|
||||
*/
|
||||
private int agv_address = 0;
|
||||
private int agv_address_copy = 0;
|
||||
|
||||
/**
|
||||
* AGV上报当前phase值
|
||||
*/
|
||||
private int currentPhase = 0;
|
||||
|
||||
/**
|
||||
* 存放AGV状态信息
|
||||
*/
|
||||
private final AgvDto agvInfo = AgvDto.builder()
|
||||
.name(this.getDevice().getDevice_code())
|
||||
.state("UNKNOWN")
|
||||
.energyLevel("0")
|
||||
.transportOrder(null)
|
||||
.positionX("0")
|
||||
.positionY("0")
|
||||
.positionAngle("0")
|
||||
.build();
|
||||
|
||||
/**
|
||||
* 当AGV上报这些phase值时,param代表小车Id,此时carId无实际用途
|
||||
*/
|
||||
private static final int[] PHASES_CAR_ID = {0x67, 0x70, 0x71, 0x72, 0x73, 0x74};
|
||||
|
||||
/**
|
||||
* 取货点phase值
|
||||
*/
|
||||
private static final int[] GET_PHASES = {0x03, 0x05, 0x07, 0x09, 0x1B, 0x1D, 0x1F, 0x21};
|
||||
|
||||
/**
|
||||
* 倒料点phase值
|
||||
*/
|
||||
private static final int[] FALL_PHASES = {0x0B, 0x0D, 0x0F, 0x11};
|
||||
|
||||
/**
|
||||
* 放货点phase值
|
||||
*/
|
||||
private static final int[] PUT_PHASES = {0x13, 0x15, 0x17, 0x19, 0x23, 0x25, 0x27, 0x29};
|
||||
|
||||
/**
|
||||
* 开始任务
|
||||
*/
|
||||
private static final int PHASE_01 = 0x01;
|
||||
|
||||
/**
|
||||
* 分配车ID
|
||||
*/
|
||||
private static final int PHASE_02 = 0x02;
|
||||
|
||||
/**
|
||||
* 到达取货点1
|
||||
*/
|
||||
private static final int PHASE_03 = 0x03;
|
||||
|
||||
/**
|
||||
* 取货完毕
|
||||
*/
|
||||
private static final int PHASE_05 = 0x05;
|
||||
|
||||
/**
|
||||
* 到达取货点2
|
||||
*/
|
||||
private static final int PHASE_07 = 0x07;
|
||||
|
||||
/**
|
||||
* 取货完毕
|
||||
*/
|
||||
private static final int PHASE_09 = 0x09;
|
||||
|
||||
/**
|
||||
* 到达倒料点1
|
||||
*/
|
||||
private static final int PHASE_0B = 0x0B;
|
||||
|
||||
/**
|
||||
* 倒料完毕
|
||||
*/
|
||||
private static final int PHASE_0D = 0x0D;
|
||||
|
||||
/**
|
||||
* 到达倒料点2
|
||||
*/
|
||||
private static final int PHASE_0F = 0x0F;
|
||||
|
||||
/**
|
||||
* 倒料完毕
|
||||
*/
|
||||
private static final int PHASE_11 = 0x11;
|
||||
|
||||
/**
|
||||
* 到达放货点1
|
||||
*/
|
||||
private static final int PHASE_13 = 0x13;
|
||||
|
||||
/**
|
||||
* 放货完毕
|
||||
*/
|
||||
private static final int PHASE_15 = 0x15;
|
||||
|
||||
/**
|
||||
* 到达放货点2
|
||||
*/
|
||||
private static final int PHASE_17 = 0x17;
|
||||
|
||||
/**
|
||||
* 放货完毕
|
||||
*/
|
||||
private static final int PHASE_19 = 0x19;
|
||||
|
||||
/**
|
||||
* 到达取货点3
|
||||
*/
|
||||
private static final int PHASE_1B = 0x1B;
|
||||
|
||||
/**
|
||||
* 取货完毕
|
||||
*/
|
||||
private static final int PHASE_1D = 0x1D;
|
||||
|
||||
/**
|
||||
* 到达取货点4
|
||||
*/
|
||||
private static final int PHASE_1F = 0x1F;
|
||||
|
||||
/**
|
||||
* 取货完毕
|
||||
*/
|
||||
private static final int PHASE_21 = 0x21;
|
||||
|
||||
/**
|
||||
* 到达放货点3
|
||||
*/
|
||||
private static final int PHASE_23 = 0x23;
|
||||
|
||||
/**
|
||||
* 放货完毕
|
||||
*/
|
||||
private static final int PHASE_25 = 0x25;
|
||||
|
||||
/**
|
||||
* 到达放货点4
|
||||
*/
|
||||
private static final int PHASE_27 = 0x27;
|
||||
|
||||
/**
|
||||
* 放货完毕
|
||||
*/
|
||||
private static final int PHASE_29 = 0x29;
|
||||
|
||||
/**
|
||||
* 任务完毕
|
||||
*/
|
||||
private static final int PHASE_2A = 0x2A;
|
||||
|
||||
/**
|
||||
* 请求删除任务
|
||||
*/
|
||||
private static final int PHASE_30 = 0x30;
|
||||
|
||||
/**
|
||||
* 任务删除确认
|
||||
*/
|
||||
private static final int PHASE_FF = 0xFF;
|
||||
|
||||
|
||||
/**
|
||||
* 进入交通灯区域
|
||||
*/
|
||||
private static final int PHASE_50 = 0x50;
|
||||
|
||||
/**
|
||||
* 离开交通灯区域
|
||||
*/
|
||||
private static final int PHASE_51 = 0x51;
|
||||
|
||||
|
||||
/**
|
||||
* 到达位置点
|
||||
*/
|
||||
private static final int PHASE_64 = 0x64;
|
||||
|
||||
/**
|
||||
* 称重就绪
|
||||
*/
|
||||
private static final int PHASE_65 = 0x65;
|
||||
|
||||
|
||||
/**
|
||||
* 上报异常信息
|
||||
*/
|
||||
private static final int PHASE_67 = 0x67;
|
||||
|
||||
/**
|
||||
* 上报X坐标
|
||||
*/
|
||||
private static final int PHASE_70 = 0x70;
|
||||
|
||||
/**
|
||||
* 上报Y坐标
|
||||
*/
|
||||
private static final int PHASE_71 = 0x71;
|
||||
|
||||
/**
|
||||
* 上报车辆角度
|
||||
*/
|
||||
private static final int PHASE_72 = 0x72;
|
||||
|
||||
/**
|
||||
* 上报车辆电量
|
||||
*/
|
||||
private static final int PHASE_73 = 0x73;
|
||||
|
||||
/**
|
||||
* 上报三色灯状态
|
||||
*/
|
||||
private static final int PHASE_74 = 0x74;
|
||||
|
||||
/**
|
||||
* 处理NDC交互逻辑
|
||||
*
|
||||
* @param arr NDC上报报文信息
|
||||
* @param phase phase值,AGV执行阶段
|
||||
* @param index NDC调度系统的任务号
|
||||
* @param ikey phase值不在phasesCarsId中,代表ACS指令号或关联编号,否则代表phase值对应的上报的信息异常、X坐标、Y坐标、角度、电量、三色灯状态等信息
|
||||
* @param carId phase值不在phasesCarsId中,代表小车Id,否则暂无实际作用
|
||||
* @param param phase值在phasesCarsId中,代表小车Id,否则代表站点号-即AGV地址
|
||||
*/
|
||||
public synchronized void processSocket(byte[] arr, Integer phase, Integer index, Integer ikey, Integer carId, Integer param) {
|
||||
this.device_code = this.getDevice_code();
|
||||
byte[] data = null;
|
||||
this.setTaskCodeToAgvInfo(ikey, phase);
|
||||
this.currentPhase = phase;
|
||||
switch (phase) {
|
||||
//开始任务
|
||||
case PHASE_01:
|
||||
data = this.handleStartTask(ikey, index);
|
||||
break;
|
||||
//分配车Id
|
||||
case PHASE_02:
|
||||
this.assignCarId(ikey, carId);
|
||||
break;
|
||||
//到达取货点1、2、3、4
|
||||
case PHASE_03:
|
||||
case PHASE_07:
|
||||
case PHASE_1B:
|
||||
case PHASE_1F:
|
||||
data = this.toGetPoint(ikey, index);
|
||||
break;
|
||||
//取货完闭1、2、3、4
|
||||
case PHASE_05:
|
||||
case PHASE_09:
|
||||
case PHASE_1D:
|
||||
case PHASE_21:
|
||||
data = this.getFinish(ikey, index);
|
||||
break;
|
||||
//到达倒料点1、2
|
||||
case PHASE_0B:
|
||||
case PHASE_0F:
|
||||
data = this.toFallPoint(ikey, index);
|
||||
break;
|
||||
//倒料完毕1、2
|
||||
case PHASE_0D:
|
||||
case PHASE_11:
|
||||
data = this.fallFinish(ikey, index);
|
||||
break;
|
||||
//到达放货点1、2、3、4
|
||||
case PHASE_13:
|
||||
case PHASE_17:
|
||||
case PHASE_23:
|
||||
case PHASE_27:
|
||||
data = this.toPutPoint(ikey, index);
|
||||
break;
|
||||
//放货完毕1、2、3、4
|
||||
case PHASE_15:
|
||||
case PHASE_19:
|
||||
case PHASE_25:
|
||||
case PHASE_29:
|
||||
data = this.putFinish(ikey, index);
|
||||
break;
|
||||
//任务完成
|
||||
case PHASE_2A:
|
||||
data = this.taskFinish(ikey, index);
|
||||
break;
|
||||
//删除任务
|
||||
case PHASE_30:
|
||||
data = this.delTask(ikey, index);
|
||||
break;
|
||||
//删除任务确认
|
||||
case PHASE_FF:
|
||||
data = this.delTaskConfirm(ikey, index);
|
||||
break;
|
||||
//进入交通灯区域
|
||||
case PHASE_50:
|
||||
data = this.inLightArea();
|
||||
break;
|
||||
//离开交通灯区域
|
||||
case PHASE_51:
|
||||
data = this.outLightArea();
|
||||
break;
|
||||
//到达位置点
|
||||
case PHASE_64:
|
||||
data = this.arrivedPoint(param, index);
|
||||
break;
|
||||
//开始称重
|
||||
case PHASE_65:
|
||||
data = this.startWeighing(phase, ikey, index, param);
|
||||
break;
|
||||
//上报异常信息
|
||||
case PHASE_67:
|
||||
this.reportExceptionInfo();
|
||||
break;
|
||||
//上报车辆X坐标
|
||||
case PHASE_70:
|
||||
this.reportXCoordinate(ikey);
|
||||
break;
|
||||
//上报车辆Y坐标
|
||||
case PHASE_71:
|
||||
this.reportYCoordinate(ikey);
|
||||
break;
|
||||
//上报车辆角度
|
||||
case PHASE_72:
|
||||
this.reportAngle(ikey);
|
||||
break;
|
||||
//上报车辆电量
|
||||
case PHASE_73:
|
||||
this.reportElectric(ikey);
|
||||
break;
|
||||
//上报三色灯状态
|
||||
case PHASE_74:
|
||||
this.reportThreeColorStatus(ikey);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (data != null) {
|
||||
NdcNettyConnectionAutoRun.write(data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 开始任务
|
||||
*
|
||||
* @param ikey 指令号或关联编号
|
||||
* @param index NDC的任务号
|
||||
*/
|
||||
private byte[] handleStartTask(Integer ikey, Integer index) {
|
||||
List<Instruction> instructions = this.getInstructions(ikey);
|
||||
if (ObjectUtil.isNotEmpty(instructions)) {
|
||||
boolean flag = false;
|
||||
Instruction instruction = instructions.get(0);
|
||||
TaskDto taskDto = taskService.findByTaskCode(instruction.getTask_code());
|
||||
if (taskDto != null) {
|
||||
List<TaskDto> taskDtos = taskService.findByLinkNumFromCache(taskDto.getLink_num());
|
||||
if (taskDtos != null) {
|
||||
if (taskDtos.size() == 1) {
|
||||
for (Instruction inst : instructions) {
|
||||
inst.setInstruction_status(StatusEnum.INST_RUNNING.getCode());
|
||||
inst.setAgv_jobno(String.valueOf(index));
|
||||
inst.setSend_status(StatusEnum.YES.getCode());
|
||||
instructionService.update(inst);
|
||||
log.info("修改指令执行信息成功,指令号:{}", inst.getInstruction_code());
|
||||
flag = true;
|
||||
}
|
||||
} else if (taskDtos.size() == 2) {
|
||||
for (int i = 0; i < instructions.size(); i++) {
|
||||
Instruction inst = instructions.get(i);
|
||||
inst.setInstruction_status(StatusEnum.INST_RUNNING.getCode());
|
||||
inst.setAgv_jobno(String.valueOf(index));
|
||||
inst.setSend_status(StatusEnum.YES.getCode());
|
||||
instructionService.update(inst);
|
||||
if (i == 1) {
|
||||
flag = true;
|
||||
}
|
||||
log.info("修改指令执行信息成功,指令号:{}", inst.getInstruction_code());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (flag) {
|
||||
return ndcAgvService.sendInstToNuoBaoNdc(currentPhase, index, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 上报车号
|
||||
*
|
||||
* @param ikey 指令号或关联编号
|
||||
* @param carId 车辆Id
|
||||
*/
|
||||
private void assignCarId(Integer ikey, Integer carId) {
|
||||
List<Instruction> instructions = this.getInstructions(ikey);
|
||||
for (Instruction inst : instructions) {
|
||||
inst.setCarno(String.valueOf(carId));
|
||||
instructionService.update(inst);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 到达取货点1、2、3、4
|
||||
*
|
||||
* @param ikey 指令号或关联编号
|
||||
* @param index AGV任务号
|
||||
*/
|
||||
private byte[] toGetPoint(Integer ikey, Integer index) {
|
||||
return processInstruction(ikey, index, currentPhase, new int[]{PHASE_03, PHASE_07, PHASE_1B, PHASE_1F});
|
||||
}
|
||||
|
||||
/**
|
||||
* 取货完成1、2、3、4
|
||||
*
|
||||
* @param ikey 指令号或关联编号
|
||||
* @param index AGV任务号
|
||||
*/
|
||||
private byte[] getFinish(Integer ikey, Integer index) {
|
||||
return processInstruction(ikey, index, currentPhase, new int[]{PHASE_05, PHASE_09, PHASE_1D, PHASE_21});
|
||||
}
|
||||
|
||||
/**
|
||||
* 到达倒料点1、2
|
||||
*
|
||||
* @param ikey
|
||||
* @param index
|
||||
* @return
|
||||
*/
|
||||
private byte[] fallFinish(Integer ikey, Integer index) {
|
||||
return processInstruction(ikey, index, currentPhase, new int[]{PHASE_0D, PHASE_11});
|
||||
}
|
||||
|
||||
/**
|
||||
* 倒料完毕1、2
|
||||
*
|
||||
* @param ikey
|
||||
* @param index
|
||||
* @return
|
||||
*/
|
||||
private byte[] toFallPoint(Integer ikey, Integer index) {
|
||||
return processInstruction(ikey, index, currentPhase, new int[]{PHASE_0B, PHASE_0F});
|
||||
}
|
||||
|
||||
/**
|
||||
* 到达放货点1、2、3、4
|
||||
*
|
||||
* @param ikey 指令号或关联编号
|
||||
* @param index AGV任务号
|
||||
*/
|
||||
private byte[] toPutPoint(Integer ikey, Integer index) {
|
||||
return processInstruction(ikey, index, currentPhase, new int[]{PHASE_13, PHASE_17, PHASE_23, PHASE_27});
|
||||
}
|
||||
|
||||
/**
|
||||
* 放货完毕1、2、3、4
|
||||
*
|
||||
* @param ikey 指令号或关联编号
|
||||
* @param index AGV任务号
|
||||
*/
|
||||
private byte[] putFinish(Integer ikey, Integer index) {
|
||||
return processInstruction(ikey, index, currentPhase, new int[]{PHASE_15, PHASE_19, PHASE_25, PHASE_29});
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理取、倒、放货逻辑
|
||||
*
|
||||
* @param ikey
|
||||
* @param index
|
||||
* @param currentPhase
|
||||
* @param phases
|
||||
* @return
|
||||
*/
|
||||
private byte[] processInstruction(Integer ikey, Integer index, int currentPhase, int[] phases) {
|
||||
Device device = this.getDeviceCodeByAgvAddress(agv_address);
|
||||
if (device == null) {
|
||||
log.info("AGV上报站点信息:{},根据站点信息查询设备为空!", agv_address);
|
||||
return null;
|
||||
}
|
||||
List<Instruction> insts = this.getInstructions(ikey);
|
||||
if (insts == null) {
|
||||
log.info("AGV上报指令关联编号:{},根据指令关联编号查询指令信息为空!", ikey);
|
||||
return null;
|
||||
}
|
||||
// 排序
|
||||
insts.sort(Comparator.comparing(Instruction::getCreate_time));
|
||||
Instruction inst = null;
|
||||
// 根据当前阶段获取指令
|
||||
for (int i = 0; i < phases.length; i++) {
|
||||
if (currentPhase == (phases[i])) {
|
||||
inst = getInstructionAtIndex(insts, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// 校验指令和设备起始点
|
||||
if (ObjectUtil.isEmpty(inst)) {
|
||||
log.info("AGV上报phase值:{},获取指令信息为空!", currentPhase);
|
||||
return null;
|
||||
}
|
||||
|
||||
boolean isValidPhase = false;
|
||||
|
||||
//如果当前Phase值与取货点Phase值相同比较AGV上报站点与起点是否一致
|
||||
//如果当前Phase值与倒料点Phase值相同比较AGV上报站点与倒料点是否一致
|
||||
//如果当前Phase值与放货点Phase值相同比较AGV上报站点与放货点是否一致
|
||||
if (Arrays.asList(GET_PHASES).contains(currentPhase)) {
|
||||
isValidPhase = StrUtil.equals(inst.getStart_device_code(), device.getDevice_code());
|
||||
} else if (Arrays.asList(FALL_PHASES).contains(currentPhase)) {
|
||||
isValidPhase = StrUtil.equals(inst.getPut_device_code(), device.getDevice_code());
|
||||
} else if (Arrays.asList(PUT_PHASES).contains(currentPhase)) {
|
||||
isValidPhase = StrUtil.equals(inst.getNext_device_code(), device.getDevice_code());
|
||||
}
|
||||
|
||||
if (isValidPhase) {
|
||||
this.setPhaseToDriver(device, currentPhase, index, inst);
|
||||
if (device.getDeviceDriver() instanceof StandardStorageDeviceDriver) {
|
||||
return ndcAgvService.sendInstToNuoBaoNdc(currentPhase, index, 0);
|
||||
}
|
||||
} else {
|
||||
log.info("AGV上报站点:{},上报phase值:{},与查询到的指令信息:{},中的取、倒、放点位信息不一致!", agv_address, currentPhase, inst.getInstruction_code());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定索引处的指令,如果索引超出范围,返回 null
|
||||
*
|
||||
* @param insts
|
||||
* @param index
|
||||
* @return
|
||||
*/
|
||||
private Instruction getInstructionAtIndex(List<Instruction> insts, int index) {
|
||||
if (index < 0 || index >= insts.size()) {
|
||||
return null;
|
||||
}
|
||||
return insts.get(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* 任务完成
|
||||
*
|
||||
* @param ikey 指令号或关联编号
|
||||
*/
|
||||
private byte[] taskFinish(Integer ikey, Integer index) {
|
||||
instructionService.finishByLinkNum(String.valueOf(ikey));
|
||||
this.instructions = null;
|
||||
this.agvInfo.setTransportOrder(null);
|
||||
return ndcAgvService.sendInstToNuoBaoNdc(currentPhase, index, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除任务
|
||||
*
|
||||
* @param ikey 指令号或关联编号
|
||||
*/
|
||||
private byte[] delTask(Integer ikey, Integer index) {
|
||||
this.instructions = null;
|
||||
this.agvInfo.setTransportOrder(null);
|
||||
return ndcAgvService.sendInstToNuoBaoNdc(143, index, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除任务确认
|
||||
*
|
||||
* @param ikey 指令号或关联编号
|
||||
*/
|
||||
private byte[] delTaskConfirm(Integer ikey, Integer index) {
|
||||
try {
|
||||
instructionService.forceCancelByLinkNum(String.valueOf(ikey));
|
||||
this.instructions = null;
|
||||
this.agvInfo.setTransportOrder(null);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return ndcAgvService.sendInstToNuoBaoNdc(currentPhase, index, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 到达位置点
|
||||
*
|
||||
* @param param AGV站点
|
||||
*/
|
||||
private byte[] arrivedPoint(Integer param, Integer index) {
|
||||
agv_address = param;
|
||||
agv_address_copy = agv_address;
|
||||
return ndcAgvService.sendInstToNuoBaoNdc(currentPhase, index, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始称重
|
||||
*
|
||||
* @param param AGV称重信息
|
||||
*/
|
||||
private byte[] startWeighing(Integer phase, Integer ikey, Integer index, Integer param) {
|
||||
if (agv_address < 1) {
|
||||
log.info("AGV开始称重,上报站点信息有误:{}", agv_address);
|
||||
return null;
|
||||
}
|
||||
agv_address = agv_address_copy;
|
||||
String device_code = deviceService.queryDeviceCodeByAddress(agv_address);
|
||||
if (ObjectUtil.isEmpty(device_code)) {
|
||||
log.info("AGV上报重量时站点:" + agv_address + ",对应设备号为空!");
|
||||
return null;
|
||||
}
|
||||
//1、得到重量信息
|
||||
int weight = param * 10;
|
||||
if (weight < 0) {
|
||||
log.info("AGV上报重量小于0不反馈AGV信息,指令号:{}", ikey);
|
||||
return null;
|
||||
}
|
||||
List<Instruction> insts = this.getInstructions(ikey);
|
||||
if (insts == null) {
|
||||
log.info("AGV上报重量时根据ikey:{},查询指令信息为空!", ikey);
|
||||
return null;
|
||||
}
|
||||
insts.sort(Comparator.comparing(Instruction::getCreate_time));
|
||||
Instruction instruction = insts.stream()
|
||||
.filter(inst -> StrUtil.isEmpty(inst.getWeight()))
|
||||
.limit(1)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
if (instruction == null) {
|
||||
log.info("未找到关联编号{}对应的指令", ikey);
|
||||
return null;
|
||||
}
|
||||
if (StrUtil.equals(instruction.getStart_device_code(), device_code)) {
|
||||
String now = DateUtil.now();
|
||||
instruction.setWeight(String.valueOf(weight));
|
||||
instruction.setUpdate_time(now);
|
||||
instructionService.update(instruction);
|
||||
TaskDto taskDto = taskService.findByCodeFromCache(instruction.getTask_code());
|
||||
if (taskDto != null) {
|
||||
taskDto.setWeight(String.valueOf(weight));
|
||||
taskDto.setUpdate_time(now);
|
||||
taskService.update(taskDto);
|
||||
}
|
||||
}
|
||||
return ndcAgvService.sendAgvTwoModeInst(phase, index, 0);
|
||||
}
|
||||
|
||||
private void reportExceptionInfo() {
|
||||
|
||||
}
|
||||
|
||||
private byte[] inLightArea() {
|
||||
return null;
|
||||
}
|
||||
|
||||
private byte[] outLightArea() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 上报x坐标
|
||||
*
|
||||
* @param ikey x坐标
|
||||
*/
|
||||
private void reportXCoordinate(Integer ikey) {
|
||||
this.agvInfo.setPositionX(String.valueOf(ikey));
|
||||
}
|
||||
|
||||
/**
|
||||
* 上报y坐标
|
||||
*
|
||||
* @param ikey y坐标
|
||||
*/
|
||||
private void reportYCoordinate(Integer ikey) {
|
||||
this.agvInfo.setPositionY(String.valueOf(ikey));
|
||||
}
|
||||
|
||||
/**
|
||||
* 上报AGV角度
|
||||
*
|
||||
* @param ikey 角度
|
||||
*/
|
||||
private void reportAngle(Integer ikey) {
|
||||
this.agvInfo.setPositionAngle(String.valueOf(ikey));
|
||||
}
|
||||
|
||||
/**
|
||||
* 上报AGV电量
|
||||
*
|
||||
* @param ikey 电量
|
||||
*/
|
||||
private void reportElectric(Integer ikey) {
|
||||
this.agvInfo.setEnergyLevel(String.valueOf(ikey));
|
||||
}
|
||||
|
||||
/**
|
||||
* 上报三色灯状态
|
||||
*
|
||||
* @param ikey 三色灯状态
|
||||
*/
|
||||
private void reportThreeColorStatus(Integer ikey) {
|
||||
this.agvInfo.setState("");
|
||||
}
|
||||
|
||||
/**
|
||||
* 向AGV设置任务号
|
||||
*
|
||||
* @param ikey 指令号或者关联编号
|
||||
* @param phase 执行阶段
|
||||
*/
|
||||
private void setTaskCodeToAgvInfo(Integer ikey, Integer phase) {
|
||||
if (ikey != 0 && ikey != null) {
|
||||
if (!Arrays.asList(PHASES_CAR_ID).contains(phase)) {
|
||||
if (this.instructions == null) {
|
||||
this.instructions = this.getInstructions(ikey);
|
||||
for (Instruction inst : this.instructions) {
|
||||
this.agvInfo.setTransportOrder(inst.getTask_code());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据ikey查询指令信息
|
||||
*
|
||||
* @param ikey 指令编号或者关联编号
|
||||
* @return
|
||||
*/
|
||||
private List<Instruction> getInstructions(Integer ikey) {
|
||||
return instructionService.findByLinkNum(String.valueOf(ikey));
|
||||
}
|
||||
|
||||
/**
|
||||
* 抽取取放货公共逻辑
|
||||
* 根据AGV上报的地址值获取设备信息
|
||||
*
|
||||
* @param agvAddress
|
||||
* @return
|
||||
*/
|
||||
private Device getDeviceCodeByAgvAddress(Integer agvAddress) {
|
||||
this.agv_address = this.agv_address == 0 ? this.agv_address_copy : this.agv_address;
|
||||
if (agv_address < 1) {
|
||||
//打日志
|
||||
return null;
|
||||
}
|
||||
String device_code = deviceService.queryDeviceCodeByAddress(agvAddress);
|
||||
if (agvAddress != 0) {
|
||||
String old_device_code = deviceService.queryDeviceCodeByAddress(agvAddress);
|
||||
if (StrUtil.contains(old_device_code, "-")) {
|
||||
String[] point = old_device_code.split("-");
|
||||
device_code = point[0];
|
||||
} else if (StrUtil.contains(old_device_code, ".")) {
|
||||
String[] point = old_device_code.split("\\.");
|
||||
device_code = point[0];
|
||||
} else {
|
||||
device_code = old_device_code;
|
||||
}
|
||||
}
|
||||
return deviceAppService.findDeviceByCode(device_code);
|
||||
}
|
||||
|
||||
private void setPhaseToDriver(Device device, Integer phase, Integer index, Instruction inst) {
|
||||
//刻字缓存位
|
||||
HailiangEngravingCacheDeviceDriver hailiangEngravingCacheDeviceDriver;
|
||||
//刻字机工位
|
||||
HailiangEngravingMachineDeviceDriver hailiangEngravingMachineDeviceDriver;
|
||||
//包装机工位
|
||||
HailiangPackerStationDeviceDriver hailiangPackerStationDeviceDriver;
|
||||
//普通站点
|
||||
StandardOrdinarySiteDeviceDriver standardOrdinarySiteDeviceDriver;
|
||||
//货架
|
||||
StandardStorageDeviceDriver standardStorageDeviceDriver;
|
||||
//刻字上料线体
|
||||
HailiangEngravingInDeviceDriver hailiangEngravingInDeviceDriver;
|
||||
//
|
||||
HailiangCleaningPutLineDeviceDriver hailiangCleaningPutLineDeviceDriver;
|
||||
if (device.getDeviceDriver() instanceof HailiangEngravingMachineDeviceDriver) {
|
||||
hailiangEngravingMachineDeviceDriver = (HailiangEngravingMachineDeviceDriver) device.getDeviceDriver();
|
||||
hailiangEngravingMachineDeviceDriver.set(phase, index, inst);
|
||||
}
|
||||
|
||||
if (device.getDeviceDriver() instanceof HailiangEngravingCacheDeviceDriver) {
|
||||
hailiangEngravingCacheDeviceDriver = (HailiangEngravingCacheDeviceDriver) device.getDeviceDriver();
|
||||
hailiangEngravingCacheDeviceDriver.set(phase, index, inst);
|
||||
}
|
||||
|
||||
if (device.getDeviceDriver() instanceof StandardOrdinarySiteDeviceDriver) {
|
||||
standardOrdinarySiteDeviceDriver = (StandardOrdinarySiteDeviceDriver) device.getDeviceDriver();
|
||||
standardOrdinarySiteDeviceDriver.set(phase, index, inst);
|
||||
}
|
||||
|
||||
if (device.getDeviceDriver() instanceof HailiangPackerStationDeviceDriver) {
|
||||
hailiangPackerStationDeviceDriver = (HailiangPackerStationDeviceDriver) device.getDeviceDriver();
|
||||
hailiangPackerStationDeviceDriver.set(phase, index, inst);
|
||||
}
|
||||
|
||||
if (device.getDeviceDriver() instanceof HailiangEngravingInDeviceDriver) {
|
||||
hailiangEngravingInDeviceDriver = (HailiangEngravingInDeviceDriver) device.getDeviceDriver();
|
||||
hailiangEngravingInDeviceDriver.set(phase, index, inst);
|
||||
}
|
||||
|
||||
if (device.getDeviceDriver() instanceof HailiangCleaningPutLineDeviceDriver) {
|
||||
hailiangCleaningPutLineDeviceDriver = (HailiangCleaningPutLineDeviceDriver) device.getDeviceDriver();
|
||||
hailiangCleaningPutLineDeviceDriver.set(phase, index, inst);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user