src/main/java/com/zy/asrs/controller/LiftController.java
@@ -12,16 +12,19 @@ import com.zy.asrs.entity.BasLift; import com.zy.asrs.service.BasLiftService; import com.zy.common.service.CommonService; import com.zy.common.utils.NyLiftUtils; import com.zy.common.utils.RedisUtil; import com.zy.core.cache.MessageQueue; import com.zy.core.cache.OutputQueue; import com.zy.core.cache.SlaveConnection; import com.zy.core.enums.LiftProtocolStatusType; import com.zy.core.enums.NyLiftTaskModelType; import com.zy.core.enums.SlaveType; import com.zy.core.model.LiftSlave; import com.zy.core.model.Task; import com.zy.core.model.command.*; import com.zy.core.model.protocol.LiftProtocol; import com.zy.core.model.protocol.LiftStaProtocol; import com.zy.core.properties.SlaveProperties; import com.zy.core.thread.LiftThread; import lombok.extern.slf4j.Slf4j; @@ -189,18 +192,86 @@ throw new CoolException("提升机不在线"); } LiftAssignCommand assignCommand = new LiftAssignCommand(); assignCommand.setLiftNo(liftSlave.getId().shortValue()); // 提升机编号 assignCommand.setTaskNo((short) commonService.getWorkNo(3));//获取任务号 assignCommand.setTaskMode(param.getLiftTaskMode().shortValue()); assignCommand.setAuto(false);//手动模式 assignCommand.setLev(param.getLev());//移动楼层 if (param.getLiftTaskMode() == 1) { //提升机升降楼层 int workNo = commonService.getWorkNo(3);//获取任务号 if (MessageQueue.offer(SlaveType.Lift, liftSlave.getId(), new Task(3, assignCommand))) { return R.ok(); Integer startSta = null; Integer targetSta = null; for (LiftStaProtocol liftStaProtocol : liftThread.getLiftStaProtocols()) { if (liftStaProtocol.getLev() == liftProtocol.getLev().intValue()) { startSta = liftStaProtocol.getStaNo(); } if (liftStaProtocol.getLev() == param.getLev()) { targetSta = liftStaProtocol.getStaNo(); } } if (startSta == null || targetSta == null) { throw new CoolException("起点或目标点不存在"); } //获取提升机命令 NyLiftCommand liftCommand = NyLiftUtils.getLiftCommand(liftProtocol.getLiftNo().intValue(), NyLiftTaskModelType.MOVE_CAR.id, startSta, targetSta, workNo); ArrayList<NyLiftCommand> commands = new ArrayList<>(); commands.add(liftCommand); //提交到线程去工作 LiftAssignCommand assignCommand = new LiftAssignCommand(); assignCommand.setCommands(commands); assignCommand.setLiftNo(liftProtocol.getLiftNo()); assignCommand.setTaskNo((short) workNo); assignCommand.setAuto(false);//手动模式 assignCommand.setTaskMode(NyLiftTaskModelType.MOVE_CAR.id.shortValue()); if (MessageQueue.offer(SlaveType.Lift, liftSlave.getId(), new Task(3, assignCommand))) { return R.ok(); } else { throw new CoolException("命令下发失败"); } } else if (param.getLiftTaskMode() == 2) { //移动托盘 int workNo = commonService.getWorkNo(3);//获取任务号 Integer startSta = null; Integer targetSta = null; for (LiftStaProtocol liftStaProtocol : liftThread.getLiftStaProtocols()) { if (liftStaProtocol.getStaNo() == param.getSourceStaNo()) { startSta = liftStaProtocol.getStaNo(); } if (liftStaProtocol.getLev() == param.getStaNo()) { targetSta = liftStaProtocol.getStaNo(); } } if (startSta == null || targetSta == null) { throw new CoolException("起点或目标点不存在"); } //获取提升机命令 NyLiftCommand liftCommand = NyLiftUtils.getLiftCommand(liftProtocol.getLiftNo().intValue(), NyLiftTaskModelType.MOVE_TRAY.id, startSta, targetSta, workNo); ArrayList<NyLiftCommand> commands = new ArrayList<>(); commands.add(liftCommand); //提交到线程去工作 LiftAssignCommand assignCommand = new LiftAssignCommand(); assignCommand.setCommands(commands); assignCommand.setLiftNo(liftProtocol.getLiftNo()); assignCommand.setTaskNo((short) workNo); assignCommand.setAuto(false);//手动模式 assignCommand.setTaskMode(NyLiftTaskModelType.MOVE_TRAY.id.shortValue()); if (MessageQueue.offer(SlaveType.Lift, liftSlave.getId(), new Task(3, assignCommand))) { return R.ok(); } else { throw new CoolException("命令下发失败"); } } else { throw new CoolException("命令下发失败"); throw new CoolException("未知命令"); } } } return R.error(); src/main/java/com/zy/asrs/controller/ShuttleController.java
@@ -21,6 +21,7 @@ import com.zy.common.utils.NyHttpUtils; import com.zy.common.utils.NyShuttleOperaUtils; import com.zy.common.utils.RedisUtil; import com.zy.common.utils.ShuttleDispatchUtils; import com.zy.core.cache.MessageQueue; import com.zy.core.cache.OutputQueue; import com.zy.core.cache.SlaveConnection; @@ -62,6 +63,8 @@ private CommonService commonService; @Autowired private RedisUtil redisUtil; @Autowired private ShuttleDispatchUtils shuttleDispatchUtils; @PostMapping("/table/shuttle/state") @ManagerAuth(memo = "四向穿梭车信息表") @@ -339,6 +342,10 @@ ArrayList<NyShuttleHttpCommand> commands = new ArrayList<>(); commands.add(suspendCommand); assignCommand.setCommands(commands); } else if (shuttleTaskModeType == ShuttleTaskModeType.MOVE_LOC_NO_WRK_MAST) { //移动到目标库位(生成移动任务) shuttleDispatchUtils.dispatchShuttle(commonService.getWorkNo(3), param.getDistLocNo(), param.getShuttleNo()); return R.ok(); } else { throw new CoolException("未知命令"); } src/main/java/com/zy/asrs/domain/param/LiftOperatorParam.java
@@ -17,4 +17,10 @@ //提升机楼层 private Integer lev; //源站 private Integer sourceStaNo; //目标站 private Integer staNo; } src/main/java/com/zy/asrs/entity/WrkMastLog.java
New file @@ -0,0 +1,504 @@ package com.zy.asrs.entity; import com.baomidou.mybatisplus.annotations.TableField; import com.baomidou.mybatisplus.annotations.TableId; import com.baomidou.mybatisplus.annotations.TableName; import com.baomidou.mybatisplus.enums.IdType; import com.core.common.Cools; import com.core.common.SpringUtils; import com.zy.asrs.service.BasCrnpService; import com.zy.asrs.service.BasDevpService; import com.zy.asrs.service.LocMastService; import com.zy.asrs.service.WrkMastService; import com.zy.system.entity.User; import com.zy.system.service.UserService; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.io.Serializable; import java.text.SimpleDateFormat; import java.util.Date; @Data @TableName("asr_wrk_mast_log") public class WrkMastLog implements Serializable { private static final long serialVersionUID = 1L; /** * 编号 */ @ApiModelProperty(value= "编号") @TableId(value = "id", type = IdType.AUTO) private Long id; /** * 工作号 */ @ApiModelProperty(value= "工作号") @TableField("wrk_no") private Integer wrkNo; @ApiModelProperty(value= "") @TableField("inv_wh") private String invWh; @ApiModelProperty(value= "") private Date ymd; @ApiModelProperty(value= "") private String mk; @ApiModelProperty(value= "") @TableField("whs_type") private Integer whsType; /** * 工作状态 */ @ApiModelProperty(value= "工作状态") @TableField("wrk_sts") private Long wrkSts; /** * 入出库类型 */ @ApiModelProperty(value= "入出库类型") @TableField("io_type") private Integer ioType; /** * 堆垛机号 */ @ApiModelProperty(value= "堆垛机号") @TableField("crn_no") private Integer crnNo; /** * 穿梭车 */ @ApiModelProperty(value= "穿梭车") @TableField("ste_no") private Integer steNo; /** * 边缘库位 */ @ApiModelProperty(value= "边缘库位") @TableField("out_most") private Integer outMost; @ApiModelProperty(value= "") @TableField("sheet_no") private String sheetNo; /** * 优先级 */ @ApiModelProperty(value= "优先级") @TableField("io_pri") private Double ioPri; @ApiModelProperty(value= "") @TableField("wrk_date") private Date wrkDate; /** * 目标库位 */ @ApiModelProperty(value= "目标库位") @TableField("loc_no") private String locNo; /** * 目标站 */ @ApiModelProperty(value= "目标站") @TableField("sta_no") private Integer staNo; /** * 源站 */ @ApiModelProperty(value= "源站") @TableField("source_sta_no") private Integer sourceStaNo; /** * 源库位 */ @ApiModelProperty(value= "源库位") @TableField("source_loc_no") private String sourceLocNo; @ApiModelProperty(value= "") @TableField("loc_sts") private String locSts; /** * 拣料 */ @ApiModelProperty(value= "拣料") private String picking; @ApiModelProperty(value= "") @TableField("link_mis") private String linkMis; @ApiModelProperty(value= "") @TableField("online_yn") private String onlineYn; @ApiModelProperty(value= "") @TableField("upd_mk") private String updMk; /** * 退出 */ @ApiModelProperty(value= "退出") @TableField("exit_mk") private String exitMk; @ApiModelProperty(value= "") @TableField("plt_type") private Integer pltType; /** * 空板 */ @ApiModelProperty(value= "空板") @TableField("empty_mk") private String emptyMk; /** * 工作时间 */ @ApiModelProperty(value= "工作时间") @TableField("io_time") private Date ioTime; @ApiModelProperty(value= "") @TableField("ctn_type") private Integer ctnType; @ApiModelProperty(value= "") private String packed; @ApiModelProperty(value= "") @TableField("ove_mk") private String oveMk; @ApiModelProperty(value= "") @TableField("mtn_type") private Double mtnType; @ApiModelProperty(value= "") @TableField("user_no") private String userNo; /** * 堆垛机启动时间 */ @ApiModelProperty(value= "堆垛机启动时间") @TableField("crn_str_time") private Date crnStrTime; /** * 堆垛机停止时间 */ @ApiModelProperty(value= "堆垛机停止时间") @TableField("crn_end_time") private Date crnEndTime; /** * 拣料时间 */ @ApiModelProperty(value= "拣料时间") @TableField("plc_str_time") private Date plcStrTime; @ApiModelProperty(value= "") @TableField("crn_pos_time") private Date crnPosTime; @ApiModelProperty(value= "") @TableField("load_time") private Double loadTime; @ApiModelProperty(value= "") @TableField("exp_time") private Double expTime; @ApiModelProperty(value= "") @TableField("ref_wrkno") private Double refWrkno; @ApiModelProperty(value= "") @TableField("ref_iotime") private Date refIotime; /** * 修改人员 */ @ApiModelProperty(value= "修改人员") @TableField("modi_user") private Long modiUser; /** * 修改时间 */ @ApiModelProperty(value= "修改时间") @TableField("modi_time") private Date modiTime; /** * 创建者 */ @ApiModelProperty(value= "创建者") @TableField("appe_user") private Long appeUser; /** * 添加时间 */ @ApiModelProperty(value= "添加时间") @TableField("appe_time") private Date appeTime; @ApiModelProperty(value= "") @TableField("pause_mk") private String pauseMk; @ApiModelProperty(value= "") @TableField("error_time") private Date errorTime; @ApiModelProperty(value= "") @TableField("error_memo") private String errorMemo; @ApiModelProperty(value= "") @TableField("ctn_kind") private Integer ctnKind; @ApiModelProperty(value= "") @TableField("manu_type") private String manuType; @ApiModelProperty(value= "") @TableField("memo_m") private String memoM; @ApiModelProperty(value= "") @TableField("sc_weight") private Double scWeight; @ApiModelProperty(value= "") @TableField("log_mk") private String logMk; @ApiModelProperty(value= "") @TableField("log_err_time") private Date logErrTime; @ApiModelProperty(value= "") @TableField("log_err_memo") private String logErrMemo; /** * 条码 */ @ApiModelProperty(value= "条码") private String barcode; @ApiModelProperty(value= "") @TableField("Pdc_type") private String PdcType; @ApiModelProperty(value= "") @TableField("ctn_no") private String ctnNo; /** * 满板 */ @ApiModelProperty(value= "满板") @TableField("full_plt") private String fullPlt; /** * 先入品 / 双重入库 */ @ApiModelProperty(value= "先入品") @TableField("pre_have") private String preHave; /** * 空操作 / 取货无箱 */ @ApiModelProperty(value= "空操作") @TableField("take_none") private String takeNone; public WrkMastLog() {} public String getWrkNo$(){ WrkMastService service = SpringUtils.getBean(WrkMastService.class); WrkMast wrkMast = service.selectById(this.wrkNo); if (!Cools.isEmpty(wrkMast)){ return String.valueOf(wrkMast.getWrkNo()); } return null; } public String getYmd$(){ if (Cools.isEmpty(this.ymd)){ return ""; } return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.ymd); } public String getCrnNo$(){ BasCrnpService service = SpringUtils.getBean(BasCrnpService.class); BasCrnp basCrnp = service.selectById(this.crnNo); if (!Cools.isEmpty(basCrnp)){ return String.valueOf(basCrnp.getCrnNo()); } return null; } public String getWrkDate$(){ if (Cools.isEmpty(this.wrkDate)){ return ""; } return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.wrkDate); } public String getLocNo$(){ LocMastService service = SpringUtils.getBean(LocMastService.class); LocMast locMast = service.selectById(this.locNo); if (!Cools.isEmpty(locMast)){ return String.valueOf(locMast.getLocNo()); } return null; } public String getStaNo$(){ BasDevpService service = SpringUtils.getBean(BasDevpService.class); BasDevp basDevp = service.selectById(this.staNo); if (!Cools.isEmpty(basDevp)){ return String.valueOf(basDevp.getDevNo()); } return null; } public String getSourceStaNo$(){ BasDevpService service = SpringUtils.getBean(BasDevpService.class); BasDevp basDevp = service.selectById(this.sourceStaNo); if (!Cools.isEmpty(basDevp)){ return String.valueOf(basDevp.getDevNo()); } return null; } public String getSourceLocNo$(){ LocMastService service = SpringUtils.getBean(LocMastService.class); LocMast locMast = service.selectById(this.sourceLocNo); if (!Cools.isEmpty(locMast)){ return String.valueOf(locMast.getLocNo()); } return null; } public String getIoTime$(){ if (Cools.isEmpty(this.ioTime)){ return ""; } return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.ioTime); } public String getCrnStrTime$(){ if (Cools.isEmpty(this.crnStrTime)){ return ""; } return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.crnStrTime); } public String getCrnEndTime$(){ if (Cools.isEmpty(this.crnEndTime)){ return ""; } return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.crnEndTime); } public String getPlcStrTime$(){ if (Cools.isEmpty(this.plcStrTime)){ return ""; } return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.plcStrTime); } public String getCrnPosTime$(){ if (Cools.isEmpty(this.crnPosTime)){ return ""; } return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.crnPosTime); } public String getRefIotime$(){ if (Cools.isEmpty(this.refIotime)){ return ""; } return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.refIotime); } public String getModiUser$(){ UserService service = SpringUtils.getBean(UserService.class); User user = service.selectById(this.modiUser); if (!Cools.isEmpty(user)){ return String.valueOf(user.getUsername()); } return null; } public String getModiTime$(){ if (Cools.isEmpty(this.modiTime)){ return ""; } return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.modiTime); } public String getAppeUser$(){ UserService service = SpringUtils.getBean(UserService.class); User user = service.selectById(this.appeUser); if (!Cools.isEmpty(user)){ return String.valueOf(user.getUsername()); } return null; } public String getAppeTime$(){ if (Cools.isEmpty(this.appeTime)){ return ""; } return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.appeTime); } public String getErrorTime$(){ if (Cools.isEmpty(this.errorTime)){ return ""; } return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.errorTime); } public String getLogErrTime$(){ if (Cools.isEmpty(this.logErrTime)){ return ""; } return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.logErrTime); } } src/main/java/com/zy/asrs/mapper/WrkMastLocMapper.java
New file @@ -0,0 +1,16 @@ package com.zy.asrs.mapper; import com.baomidou.mybatisplus.mapper.BaseMapper; import com.zy.asrs.entity.WrkMastLog; import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Mapper; import org.springframework.stereotype.Repository; @Mapper @Repository public interface WrkMastLocMapper extends BaseMapper<WrkMastLog> { @Insert("insert into asr_wrk_mast_log select * from asr_wrk_mast where wrk_no=#{workNo}") int save(Integer workNo); } src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java
@@ -99,6 +99,9 @@ private ShuttleDispatchUtils shuttleDispatchUtils; @Autowired private RedisUtil redisUtil; @Autowired private WrkMastLocMapper wrkMastLocMapper; /** * 组托 @@ -928,6 +931,16 @@ if (shuttleProtocol.getToken() == wrkMast.getWrkNo()) { //释放小车令牌 shuttleProtocol.setToken(0); } break; case 111: // 保存工作主档历史档 if (wrkMastLocMapper.save(wrkMast.getWrkNo()) <= 0) { log.info("保存工作历史档[workNo={0}]失败", wrkMast.getWrkNo()); } // 删除工作主档 if (!wrkMastService.deleteById(wrkMast)) { log.info("删除工作主档[workNo={0}]失败", wrkMast.getWrkNo()); } break; default: @@ -2156,6 +2169,8 @@ continue; } // this.shuttleMoveExecuteStepClearWrkMast(wrkMast);//清理111.小车移动完成 } } @@ -2181,7 +2196,7 @@ } //小车处于空闲状态 if (!shuttleProtocol.isIdleNoCharge()) { if (!shuttleProtocol.isIdleNoCharge(wrkMast.getWrkNo())) { return false; } @@ -2358,6 +2373,8 @@ wrkMast.setWrkSts(104L);//小车移动到提升机中 103.小车移动至站点完成 ==> 104.小车迁入提升机中 wrkMast.setModiTime(now); wrkMast.setLiftNo(liftThread.getSlave().getId());//锁定提升机防止被占用 liftProtocol.setToken(wrkMast.getShuttleNo());//提升机令牌绑定当前小车 if (wrkMastMapper.updateById(wrkMast) > 0) { //下发任务 MessageQueue.offer(SlaveType.Shuttle, assignCommand.getShuttleNo().intValue(), new Task(3, assignCommand)); @@ -2552,15 +2569,6 @@ //小车移动到目标库位中 109.小车迁出提升机完成 ==> 110.小车移动中 if (wrkMast.getWrkSts() == 109) { LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, wrkMast.getLiftNo()); if (liftThread == null) { return false; } LiftProtocol liftProtocol = liftThread.getLiftProtocol(); if (liftProtocol == null) { return false; } //获取四向穿梭车线程 NyShuttleThread shuttleThread = (NyShuttleThread) SlaveConnection.get(SlaveType.Shuttle, wrkMast.getShuttleNo()); if (shuttleThread == null) { @@ -2572,34 +2580,34 @@ } //小车处于空闲状态 if (!shuttleProtocol.isIdleNoCharge()) { if (!shuttleProtocol.isIdleNoCharge(wrkMast.getWrkNo())) { return false; } //判断小车令牌是否为当前任务 if (shuttleProtocol.getToken() != wrkMast.getWrkNo()) { if (shuttleProtocol.getToken() != 0 && shuttleProtocol.getToken() != wrkMast.getWrkNo()) { return false; } //获取目标站对应的输送站点 BasDevp targetBasDevp = basDevpService.selectByLevAndLiftNo(Utils.getLev(wrkMast.getLocNo()), wrkMast.getLiftNo()); if (targetBasDevp == null) { return false;//缺少站点信息 } // //获取目标站对应的输送站点 // BasDevp targetBasDevp = basDevpService.selectByLevAndLiftNo(Utils.getLev(wrkMast.getLocNo()), wrkMast.getLiftNo()); // if (targetBasDevp == null) { // return false;//缺少站点信息 // } // // //获取提升机数据 // BasLift basLift = basLiftService.selectById(targetBasDevp.getLiftNo()); // if (basLift == null) { // return false;//没有提升机数据 // } // if (basLift.getPoint() == null) { // return false;//没有设置提升机点位坐标 // } // NavigateNode liftNode = new NavigateNode(basLift.getPoint$().getX(), basLift.getPoint$().getY()); // liftNode.setZ(basLift.getPoint$().getZ()); //获取提升机数据 BasLift basLift = basLiftService.selectById(targetBasDevp.getLiftNo()); if (basLift == null) { return false;//没有提升机数据 } if (basLift.getPoint() == null) { return false;//没有设置提升机点位坐标 } NavigateNode liftNode = new NavigateNode(basLift.getPoint$().getX(), basLift.getPoint$().getY()); liftNode.setZ(basLift.getPoint$().getZ()); //获取小车从输送站到目标库位命令 NyShuttleOperaResult result = NyShuttleOperaUtils.getStartToTargetCommands(shuttleThread.getSlave().getId(), wrkMast.getWrkNo(), targetBasDevp.getLocNo(), wrkMast.getLocNo()); //获取小车到目标库位命令 NyShuttleOperaResult result = NyShuttleOperaUtils.getStartToTargetCommands(shuttleThread.getSlave().getId(), wrkMast.getWrkNo(), shuttleProtocol.getCurrentLocNo(), wrkMast.getLocNo()); if (result == null) { return false;//路径计算失败 } @@ -2616,7 +2624,20 @@ wrkMast.setWrkSts(110L);//小车移动到目标库位中 109.小车迁出提升机完成 ==> 110.小车移动中 wrkMast.setLiftNo(null);//释放提升机 wrkMast.setModiTime(now); liftProtocol.setToken(0);//释放提升机令牌 if (wrkMast.getLiftNo() != null) { LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, wrkMast.getLiftNo()); if (liftThread == null) { return false; } LiftProtocol liftProtocol = liftThread.getLiftProtocol(); if (liftProtocol == null) { return false; } if (liftProtocol.getToken() == shuttleProtocol.getShuttleNo().intValue()) { liftProtocol.setToken(0);//释放提升机令牌 } } if (wrkMastMapper.updateById(wrkMast) > 0) { //下发任务 MessageQueue.offer(SlaveType.Shuttle, assignCommand.getShuttleNo().intValue(), new Task(3, assignCommand)); @@ -2626,6 +2647,69 @@ } /** * 小车迁移-清理111.小车移动完成 */ private boolean shuttleMoveExecuteStepClearWrkMast(WrkMast wrkMast) { if (wrkMast.getWrkSts() == 111) { //获取四向穿梭车线程 NyShuttleThread shuttleThread = (NyShuttleThread) SlaveConnection.get(SlaveType.Shuttle, wrkMast.getShuttleNo()); if (shuttleThread == null) { return false; } NyShuttleProtocol shuttleProtocol = shuttleThread.getShuttleProtocol(); if (shuttleProtocol == null) { return false; } //小车处于空闲状态 if (!shuttleProtocol.isIdleNoCharge(wrkMast.getWrkNo())) { return false; } Object o = redisUtil.get("shuttle_wrk_no_" + shuttleProtocol.getTaskNo()); if (o != null) { ShuttleRedisCommand redisCommand = JSON.parseObject(o.toString(), ShuttleRedisCommand.class); ShuttleAssignCommand assignCommand = redisCommand.getAssignCommand(); int size = assignCommand.getCommands().size(); NyShuttleHttpCommand command = assignCommand.getCommands().get(size - 1);//获取最后一段命令 if (!command.getComplete()) { return false;//最后一段命令还未完成,不做操作 } NavigateMapData navigateMapData = new NavigateMapData(Utils.getLev(shuttleProtocol.getCurrentLocNo())); navigateMapData.writeNavigateNodeToRedisMap(assignCommand.getNodes(), false);//解锁路径 //删除redis redisUtil.del("shuttle_wrk_no_" + redisCommand.getWrkNo()); } // 保存工作主档历史档 if (wrkMastLocMapper.save(wrkMast.getWrkNo()) <= 0) { log.info("保存工作历史档[workNo={0}]失败", wrkMast.getWrkNo()); } // 删除工作主档 if (!wrkMastService.deleteById(wrkMast)) { log.info("删除工作主档[workNo={0}]失败", wrkMast.getWrkNo()); } //设置四向穿梭车为空闲状态 shuttleProtocol.setProtocolStatus(ShuttleProtocolStatusType.IDLE); //源库位清零 shuttleProtocol.setSourceLocNo(null); //目标库位清零 shuttleProtocol.setLocNo(null); //任务指令清零 shuttleProtocol.setAssignCommand(null); //工作号清零 shuttleProtocol.setTaskNo(0); //清除令牌 shuttleProtocol.setToken(0); News.info("四向穿梭车已确认且移动任务完成状态,复位。四向穿梭车号={}", shuttleProtocol.getShuttleNo()); } return true; } /** * 出入库模式切换 */ public synchronized void outAndIn() { src/main/java/com/zy/common/utils/ShuttleDispatchUtils.java
@@ -189,7 +189,7 @@ } Integer staNo = null; if (Utils.getLev(locNo) == shuttleProtocol.getPoint().getZ()) { if (Utils.getLev(locNo) != shuttleProtocol.getPoint().getZ()) { //目标库位和小车库位处于不同一楼层,需要通过提升机调度 //获取穿梭车最近且空闲的提升机输送站点 BasDevp liftSta = this.getRecentLiftSta(shuttleNo); src/main/java/com/zy/core/enums/ShuttleTaskModeType.java
@@ -25,6 +25,7 @@ SHUTTLE_LOC_TO_LOC(20, "库位移转"), SHUTTLE_CONTROL(21, "小车管制"), SHUTTLE_CANCEL_CONTROL(22, "小车取消管制"), MOVE_LOC_NO_WRK_MAST(23, "移动到目标库位(生成移动任务)"), ; public Integer id; src/main/java/com/zy/core/model/protocol/NyShuttleProtocol.java
@@ -494,6 +494,17 @@ return res; } // 是否处于空闲待命状态 public Boolean isIdleNoCharge(int taskNo) { boolean res = this.free == ShuttleStatusType.IDLE.id && !this.pakMk && this.errState == 0 && (this.taskNo == 0 || this.taskNo == taskNo) && this.protocolStatus == ShuttleProtocolStatusType.IDLE.id ; return res; } // 是否满足充电状态 public Boolean isRequireCharge() { if (this.free == null || this.pakMk == null || this.errState == null || this.taskNo == null) { src/main/java/com/zy/core/thread/LiftThread.java
@@ -141,7 +141,7 @@ private void readStatus() { try { //获取提升机数据 OperateResultExOne<byte[]> result1 = siemensS7Net.Read("DB4.0", (short) 10); OperateResultExOne<byte[]> result1 = siemensS7Net.Read("DB82.4.0", (short) 10); if (result1.IsSuccess) { if (null == liftProtocol) { liftProtocol = new LiftProtocol(); @@ -154,7 +154,7 @@ //模式 liftProtocol.setModel(status1[0]); //忙闲 liftProtocol.setBusy(status1[1]); liftProtocol.setBusy(!status1[1]); //前超限 liftProtocol.setFrontOverrun(status1[4]); //后超限 @@ -220,7 +220,7 @@ Thread.sleep(200); //获取提升机站点数据 OperateResultExOne<byte[]> result2 = siemensS7Net.Read("DB14.0", (short) (10 * liftStaProtocols.size())); OperateResultExOne<byte[]> result2 = siemensS7Net.Read("DB82.14.0", (short) (10 * liftStaProtocols.size())); if (result1.IsSuccess) { for (int i = 0; i < slave.getSta().size(); i++) { LiftStaProtocol liftStaProtocol = liftStaProtocols.get(i); @@ -233,7 +233,7 @@ //模式 liftStaProtocol.setModel(status1[0]); //忙闲 liftStaProtocol.setBusy(status1[1]); liftStaProtocol.setBusy(!status1[1]); //有托盘 liftStaProtocol.setHasTray(status1[2]); //前超限 @@ -273,7 +273,7 @@ command.setLiftNo(slave.getId().shortValue()); short[] array = getCommandArr(command);//获取命令报文 OperateResult result = siemensS7Net.Write("41088", array); OperateResult result = siemensS7Net.Write("DB83.0", array); if (result != null && result.IsSuccess) { News.info("提升机命令下发[id:{}] >>>>> {}", slave.getId(), JSON.toJSON(command)); OutputQueue.LIFT.offer(MessageFormat.format("【{0}】[id:{1}] >>>>> 命令下发: {2}", DateUtils.convert(new Date()), slave.getId(), JSON.toJSON(command))); src/main/java/com/zy/core/thread/NyShuttleThread.java
@@ -176,20 +176,6 @@ //小车处于运行中,将标记置为true if (shuttleProtocol.getFree() == 0) { shuttleProtocol.setPakMk(true); }else { //小车处于等待确认且空闲状态,如有工作号则清空路径 if (shuttleProtocol.getTaskNo() != 0 && shuttleProtocol.getProtocolStatusType() == ShuttleProtocolStatusType.WAITING) { Object o = redisUtil.get("shuttle_wrk_no_" + shuttleProtocol.getTaskNo()); if (o != null) { ShuttleRedisCommand redisCommand = JSON.parseObject(o.toString(), ShuttleRedisCommand.class); ShuttleAssignCommand assignCommand = redisCommand.getAssignCommand(); NavigateMapData navigateMapData = new NavigateMapData(Utils.getLev(shuttleProtocol.getCurrentLocNo())); navigateMapData.writeNavigateNodeToRedisMap(assignCommand.getNodes(), false);//解锁路径 //删除redis redisUtil.del("shuttle_wrk_no_" + redisCommand.getWrkNo()); } } } //将四向穿梭车状态保存至数据库 @@ -396,6 +382,23 @@ //上一条任务未完成,禁止下发命令 return false; } //判断是否为最后一条命令且命令执行完成,抛出等待确认状态 NyShuttleHttpCommand endCommand = commands.get(commands.size() - 1); if (endCommand.getComplete()) { //删除redis redisUtil.del("shuttle_wrk_no_" + redisCommand.getWrkNo()); if (!assignCommand.getCharge()) { //对主线程抛出等待确认状态waiting shuttleProtocol.setProtocolStatus(ShuttleProtocolStatusType.WAITING); }else { shuttleProtocol.setProtocolStatus(ShuttleProtocolStatusType.CHARGING_WAITING); } News.info("四向穿梭车任务执行下发完成等待执行结束,穿梭车号={},任务数据={}", shuttleProtocol.getShuttleNo(), JSON.toJSON(command)); return false;//禁止再下发命令 } } List<NavigateNode> nextNodes = null;//下一步命令行走路径 @@ -471,20 +474,21 @@ }else { //已执行完成 //最后一段命令为移动命令,则暂缓删除redis等待清除路径时一次性删除 //最后一段命令为不是移动命令,则删除redis if (!command.getRequest().getBody().get("requestType").equals("move")) { //删除redis redisUtil.del("shuttle_wrk_no_" + redisCommand.getWrkNo()); } if (!assignCommand.getCharge()) { //对主线程抛出等待确认状态waiting shuttleProtocol.setProtocolStatus(ShuttleProtocolStatusType.WAITING); }else { shuttleProtocol.setProtocolStatus(ShuttleProtocolStatusType.CHARGING_WAITING); } News.info("四向穿梭车任务执行下发完成等待执行结束,穿梭车号={},任务数据={}", shuttleProtocol.getShuttleNo(), JSON.toJSON(command)); commandStep++; // //最后一段命令为移动命令,则暂缓删除redis等待清除路径时一次性删除 // //最后一段命令为不是移动命令,则删除redis // if (!command.getRequest().getBody().get("requestType").equals("move")) { // //删除redis // redisUtil.del("shuttle_wrk_no_" + redisCommand.getWrkNo()); // } // // if (!assignCommand.getCharge()) { // //对主线程抛出等待确认状态waiting // shuttleProtocol.setProtocolStatus(ShuttleProtocolStatusType.WAITING); // }else { // shuttleProtocol.setProtocolStatus(ShuttleProtocolStatusType.CHARGING_WAITING); // } // News.info("四向穿梭车任务执行下发完成等待执行结束,穿梭车号={},任务数据={}", shuttleProtocol.getShuttleNo(), JSON.toJSON(command)); } return true; @@ -629,6 +633,7 @@ if (checkPathIsAvailable) { return true;//可行走 } return false; }else { boolean checkPathIsAvailable2 = NavigateUtils.checkPathIsAvailable(nextNodes, shuttleProtocol.getShuttleNo().intValue(), Utils.getLev(shuttleProtocol.getCurrentLocNo())); if (checkPathIsAvailable && checkPathIsAvailable2) { src/main/java/com/zy/core/thread/SiemensDevpThread.java
@@ -41,7 +41,7 @@ private SiemensS7Net siemensS7Net; private Map<Integer, StaProtocol> station = new ConcurrentHashMap<>(); private short heartBeatVal = 1; private int barcodeSize = 1; private int barcodeSize = 9; public static final ArrayList<Integer> staNos = new ArrayList<Integer>() {{ add(100);add(101); add(102);add(103); @@ -170,32 +170,15 @@ //读条码 Thread.sleep(100); OperateResultExOne<byte[]> result2 = siemensS7Net.Read("DB100.200",(short)24); OperateResultExOne<byte[]> result2 = siemensS7Net.Read("DB1000.200", (short) 72); if (result2.IsSuccess) { for (int i = 0; i <= barcodeSize; i++) { // byte[] bytes = siemensS7Net.getByteTransform().TransByte(result2.Content, i * 8, 8); // String barcode = CommonUtils.bytesToBarcode(bytes); for (int i = 0; i < barcodeSize; i++) { String barcode = siemensS7Net.getByteTransform().TransString(result2.Content,i*8,8, "UTF-8"); BarcodeThread barcodeThread = (BarcodeThread) SlaveConnection.get(SlaveType.Barcode, i + 1); if(!Cools.isEmpty(barcodeThread) && !barcodeThread.getBarcode().equals(barcode)) { barcodeThread.setBarcode(barcode); } } } // 充电信号位1 Thread.sleep(50); OperateResultExOne<byte[]> result32 = siemensS7Net.Read("DB102.109", (short)1); if (result32.IsSuccess) { boolean[] status = siemensS7Net.getByteTransform().TransBool(result32.Content, 0, 1); charge0 = status[0]; //1:可以充电 0:可能离线 可能在充电 } // 充电信号位2 Thread.sleep(50); OperateResultExOne<byte[]> result31 = siemensS7Net.Read("DB100.201", (short)1); if (result31.IsSuccess) { boolean[] status = siemensS7Net.getByteTransform().TransBool(result31.Content, 0, 1); charge1 = status[0]; } // 外形检测 - 102 src/main/resources/mapper/WrkMastLogMapper.xml
New file @@ -0,0 +1,69 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.zy.asrs.mapper.WrkMastLogMapper"> <!-- 通用查询映射结果 --> <resultMap id="BaseResultMap" type="com.zy.asrs.entity.WrkMastLog"> <id column="id" property="id" /> <result column="wrk_no" property="wrkNo" /> <result column="inv_wh" property="invWh" /> <result column="ymd" property="ymd" /> <result column="mk" property="mk" /> <result column="whs_type" property="whsType" /> <result column="wrk_sts" property="wrkSts" /> <result column="io_type" property="ioType" /> <result column="crn_no" property="crnNo" /> <result column="ste_no" property="steNo" /> <result column="out_most" property="outMost" /> <result column="sheet_no" property="sheetNo" /> <result column="io_pri" property="ioPri" /> <result column="wrk_date" property="wrkDate" /> <result column="loc_no" property="locNo" /> <result column="sta_no" property="staNo" /> <result column="source_sta_no" property="sourceStaNo" /> <result column="source_loc_no" property="sourceLocNo" /> <result column="loc_sts" property="locSts" /> <result column="picking" property="picking" /> <result column="link_mis" property="linkMis" /> <result column="online_yn" property="onlineYn" /> <result column="upd_mk" property="updMk" /> <result column="exit_mk" property="exitMk" /> <result column="plt_type" property="pltType" /> <result column="empty_mk" property="emptyMk" /> <result column="io_time" property="ioTime" /> <result column="ctn_type" property="ctnType" /> <result column="packed" property="packed" /> <result column="ove_mk" property="oveMk" /> <result column="mtn_type" property="mtnType" /> <result column="user_no" property="userNo" /> <result column="crn_str_time" property="crnStrTime" /> <result column="crn_end_time" property="crnEndTime" /> <result column="plc_str_time" property="plcStrTime" /> <result column="crn_pos_time" property="crnPosTime" /> <result column="load_time" property="loadTime" /> <result column="exp_time" property="expTime" /> <result column="ref_wrkno" property="refWrkno" /> <result column="ref_iotime" property="refIotime" /> <result column="modi_user" property="modiUser" /> <result column="modi_time" property="modiTime" /> <result column="appe_user" property="appeUser" /> <result column="appe_time" property="appeTime" /> <result column="pause_mk" property="pauseMk" /> <result column="error_time" property="errorTime" /> <result column="error_memo" property="errorMemo" /> <result column="ctn_kind" property="ctnKind" /> <result column="manu_type" property="manuType" /> <result column="memo_m" property="memoM" /> <result column="sc_weight" property="scWeight" /> <result column="log_mk" property="logMk" /> <result column="log_err_time" property="logErrTime" /> <result column="log_err_memo" property="logErrMemo" /> <result column="barcode" property="barcode" /> <result column="Pdc_type" property="PdcType" /> <result column="ctn_no" property="ctnNo" /> <result column="full_plt" property="fullPlt" /> <result column="pre_have" property="preHave" /> <result column="take_none" property="takeNone" /> </resultMap> </mapper> src/main/resources/mapper/WrkMastMapper.xml
@@ -195,7 +195,7 @@ <select id="selectShuttleMoveWrk" resultMap="BaseResultMap"> select * from dbo.asr_wrk_mast where 1=1 and wrk_sts in (101,103,105,107) and wrk_sts in (101,103,105,107,109,111) and io_type = 200 order by io_pri desc,io_time,wrk_no asc </select> src/main/webapp/views/lift.html
@@ -93,13 +93,28 @@ <div class="button-group"> <select id="liftLev"> <option value="1" selected>1F</option> <option value="3">2F</option> <option value="4">3F</option> <option value="5">4F</option> <option value="2">输送线位置</option> <option value="2">2F</option> <option value="3">3F</option> <option value="4">4F</option> <option value="5">5F</option> <option value="6">6F</option> <option value="7">7F</option> <option value="8">8F</option> <option value="9">9F</option> <option value="10">10F</option> </select> <button class="item" onclick="liftOperator(1)">移动提升机</button> <button class="item" onclick="liftOperator(0)">复位</button> <div class="select-container-item"> <span>源站</span> <label><input id="sourceStaNo" type="text" name="sourceStaNo" /></label> </div> <div class="select-container-item"> <span>目标站</span> <label><input id="staNo" type="text" name="staNo" /></label> </div> <button class="item" onclick="liftOperator(2)">移动托盘</button> <!-- <button class="item" onclick="liftOperator(0)">复位</button>--> </div> </fieldset> </div> src/main/webapp/views/shuttle.html
@@ -120,6 +120,7 @@ <div style="margin-top: 10px;"> <button class="item" onclick="shuttleOperator(18)">搬运货物</button> <button class="item" onclick="shuttleOperator(14)">移动到目标库位</button> <button class="item" onclick="shuttleOperator(23)">移动到目标库位(任务)</button> <button class="item" onclick="shuttleOperator(16)">移动到提升机</button> </div> </div>