src/main/java/com/zy/asrs/controller/ShuttleController.java
@@ -10,14 +10,12 @@ import com.zy.asrs.domain.param.ShuttleOperatorParam; import com.zy.asrs.domain.vo.*; import com.zy.asrs.entity.BasShuttle; import com.zy.asrs.entity.LocMast; import com.zy.asrs.entity.WrkMast; import com.zy.asrs.service.BasShuttleService; import com.zy.asrs.service.LocMastService; import com.zy.asrs.service.WrkMastService; import com.zy.asrs.utils.Utils; import com.zy.common.service.CommonService; import com.zy.common.utils.NavigatePositionConvert; import com.zy.common.utils.RedisUtil; import com.zy.core.cache.MessageQueue; import com.zy.core.cache.OutputQueue; @@ -28,8 +26,10 @@ import com.zy.core.model.command.ShuttleAssignCommand; import com.zy.core.model.command.ShuttleCommand; import com.zy.core.model.command.ShuttleRedisCommand; import com.zy.core.model.protocol.NyShuttleProtocol; import com.zy.core.model.protocol.ShuttleProtocol; import com.zy.core.properties.SlaveProperties; import com.zy.core.thread.NyShuttleThread; import com.zy.core.thread.ShuttleThread; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -61,73 +61,20 @@ @PostMapping("/table/shuttle/state") @ManagerAuth(memo = "四向穿梭车信息表") public R steStateTable(){ List<ShuttleStateTableVo> list = new ArrayList<>(); public R shuttleStateTable(){ ArrayList<NyShuttleProtocol> list = new ArrayList<>(); List<BasShuttle> shuttles = basShuttleService.selectList(new EntityWrapper<BasShuttle>().orderBy("shuttle_no")); for (BasShuttle basShuttle : shuttles) { // 表格行 ShuttleStateTableVo vo = new ShuttleStateTableVo(); vo.setShuttleNo(basShuttle.getShuttleNo()); //四向穿梭车号 list.add(vo); // 获取四向穿梭车信息 ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, basShuttle.getShuttleNo()); NyShuttleThread shuttleThread = (NyShuttleThread) SlaveConnection.get(SlaveType.Shuttle, basShuttle.getShuttleNo()); if (shuttleThread == null) { vo.setStatus(ShuttleProtocolStatusType.OFFLINE.id);//设备离线 vo.setBusyStatus(ShuttleProtocolStatusType.OFFLINE.desc); continue; } ShuttleProtocol shuttleProtocol = shuttleThread.getShuttleProtocol(); NyShuttleProtocol shuttleProtocol = shuttleThread.getShuttleProtocol(); if (shuttleProtocol == null || shuttleProtocol.getShuttleNo()==null) { continue; } vo.setTaskNo(shuttleProtocol.getTaskNo().intValue()); // 任务号 vo.setBusyStatus(shuttleProtocol.getBusyStatusType().desc); //四向穿梭车状态 vo.setStatus(shuttleProtocol.getProtocolStatusType().id);//当前任务状态 vo.setCurrentCode(shuttleProtocol.getCurrentCode());//当前二维码 LocMast currentLocMast = locMastService.queryByQrCode(shuttleProtocol.getCurrentCode().toString()); if (currentLocMast == null) { vo.setLocNo("");//获取当前库位号 vo.setLocNoX(0); vo.setLocNoY(0); vo.setLocNoLev(0);//当前库位层高 }else { vo.setLocNo(currentLocMast.getLocNo());//获取当前库位号 int[] locNoXY = NavigatePositionConvert.positionToXY(currentLocMast.getLocNo());//获取库位号XY坐标 vo.setLocNoX(locNoXY[0]); vo.setLocNoY(locNoXY[1]); vo.setLocNoLev(Utils.getLev(currentLocMast.getLocNo()));//当前库位层高 } vo.setBatteryPower(shuttleProtocol.getBatteryPower$() == null ? "" : shuttleProtocol.getBatteryPower$() + "%");//电池电量 vo.setBatteryTemp(shuttleProtocol.getBatteryTemp$() == null ? "" : shuttleProtocol.getBatteryTemp$() + "°");//电池温度 if (!Cools.isEmpty(shuttleProtocol.getErrorCode())) { vo.setErrorCode(shuttleProtocol.getErrorCodeType());//错误编号 } vo.setPlcOutputStatusIO(shuttleProtocol.getPlcOutputStatusIO());//Plc输出状态IO if (!Cools.isEmpty(shuttleProtocol.getPlcOutputLift())) { vo.setPlcOutputLift(shuttleProtocol.getPlcOutputLift()); } if (!Cools.isEmpty(shuttleProtocol.getPlcOutputTransfer())) { vo.setPlcOutputTransfer(shuttleProtocol.getPlcOutputTransfer()); } if (!Cools.isEmpty(shuttleProtocol.getPlcOutputBrake())) { vo.setPlcOutputBrake(shuttleProtocol.getPlcOutputBrake()); } if (!Cools.isEmpty(shuttleProtocol.getPlcOutputCharge())) { vo.setPlcOutputCharge(shuttleProtocol.getPlcOutputCharge()); } if (!Cools.isEmpty(shuttleProtocol.getStatusErrorCode())) { vo.setStatusErrorCode(shuttleProtocol.getStatusErrorCode$());//错误信息码 } vo.setPlcInputStatus(shuttleProtocol.getPlcInputStatus());//PLC输入状态 vo.setCurrentOrBeforeCode(shuttleProtocol.getCurrentOrBeforeCode());//当前或者之前读到的二维码值 vo.setCodeOffsetX(shuttleProtocol.getCodeOffsetX());//读到的二维码X方向偏移量 vo.setCodeOffsetY(shuttleProtocol.getCodeOffsetY());//读到的二维码Y方向偏移量 vo.setCurrentVoltage(shuttleProtocol.getCurrentVoltage());//当前的电压值 vo.setCurrentAnalogValue(shuttleProtocol.getCurrentAnalogValue());//当前的模拟量值 vo.setCurrentLiftServoSpeed(shuttleProtocol.getCurrentLiftServoSpeed());//当前的升降伺服速度 vo.setCurrentMoveServoSpeed(shuttleProtocol.getCurrentMoveServoSpeed());//当前的行走伺服速度 vo.setCurrentLiftServoLoad(shuttleProtocol.getCurrentLiftServoLoad());//当前的升降伺服负载率 vo.setCurrentMoveServoLoad(shuttleProtocol.getCurrentMoveServoLoad());//当前的行走伺服负载率 list.add(shuttleProtocol); } return R.ok().add(list); } @@ -177,7 +124,7 @@ vo.setPakMk(shuttleProtocol.getPakMk()?"Y" : "N"); // 作业标记 vo.setLocNo(shuttleProtocol.getLocNo());//四向穿梭车当前库位号 vo.setLev(shuttleProtocol.getLocNo() == null ? 0 : Utils.getLev(shuttleProtocol.getLocNo()));//四向穿梭车当前层高 vo.setRunSpeed(basShuttle.getRunSpeed());//四向穿梭车运行速度(设置) // vo.setRunSpeed(basShuttle.getRunSpeed());//四向穿梭车运行速度(设置) vo.setChargeLine(basShuttle.getChargeLine());//充电阈值 } return R.ok().add(list); @@ -200,51 +147,6 @@ i++; } return R.ok().add(str.toString()); } @GetMapping("/detl/{shuttleNo}") public R steDetl(@PathVariable("shuttleNo") Integer shuttleNo){ ShuttleDataVo vo = new ShuttleDataVo(); for (ShuttleSlave shuttleSlave : slaveProperties.getShuttle()) { if (shuttleNo.equals(shuttleSlave.getId())) { vo.setShuttleNo(shuttleSlave.getId()); BasShuttle basShuttle = basShuttleService.selectById(shuttleSlave.getId()); if (!Cools.isEmpty(basShuttle)) { vo.setWorkNo(basShuttle.getWrkNo()); vo.setPakMk(basShuttle.getPakMk()); } break; } } return R.ok().add(vo); } @GetMapping("/sensor/detl/{shuttleNo}") public R shuttleSensorDetl(@PathVariable("shuttleNo") Integer shuttleNo){ ShuttleSensorDataVo vo = new ShuttleSensorDataVo(); for (ShuttleSlave shuttleSlave : slaveProperties.getShuttle()) { if (shuttleNo.equals(shuttleSlave.getId())) { vo.setShuttleNo(shuttleSlave.getId()); // 获取穿梭车信息 ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, shuttleSlave.getId()); if (shuttleThread == null) { return R.error("设备不在线"); } ShuttleProtocol shuttleProtocol = shuttleThread.getShuttleProtocol(); if (shuttleProtocol == null) { return R.error("设备不在线"); } // 穿梭车异常 ----------- // 穿梭车提示信息 ---------------------- // 状态信息 ------------- break; } } return R.ok().add(vo); } @RequestMapping(value = "/command/query") @@ -298,11 +200,11 @@ } ShuttleRedisCommand redisCommand = JSON.parseObject(o.toString(), ShuttleRedisCommand.class); Short shuttleNo = redisCommand.getShuttleNo(); ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, shuttleNo.intValue()); NyShuttleThread shuttleThread = (NyShuttleThread) SlaveConnection.get(SlaveType.Shuttle, shuttleNo.intValue()); if (shuttleThread == null) { return R.error(); } ShuttleProtocol shuttleProtocol = shuttleThread.getShuttleProtocol(); NyShuttleProtocol shuttleProtocol = shuttleThread.getShuttleProtocol(); if (shuttleProtocol == null) { return R.error(); } @@ -310,7 +212,7 @@ return R.error(); } //四向穿梭车处于空闲状态,进行任务的恢复 shuttleProtocol.setTaskNo(redisCommand.getWrkNo());//将四向穿梭车线程分配任务号 shuttleProtocol.setTaskNo(redisCommand.getWrkNo().intValue());//将四向穿梭车线程分配任务号 shuttleProtocol.setProtocolStatus(ShuttleProtocolStatusType.WORKING);//工作状态 return R.ok(); } @@ -349,11 +251,11 @@ for (ShuttleSlave shuttleSlave : slaveProperties.getShuttle()) { if (param.getShuttleNo().equals(shuttleSlave.getId())) { ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, shuttleSlave.getId()); NyShuttleThread shuttleThread = (NyShuttleThread) SlaveConnection.get(SlaveType.Shuttle, shuttleSlave.getId()); if (shuttleThread == null) { throw new CoolException("四向穿梭车不在线"); } ShuttleProtocol shuttleProtocol = shuttleThread.getShuttleProtocol(); NyShuttleProtocol shuttleProtocol = shuttleThread.getShuttleProtocol(); if (shuttleProtocol == null) { throw new CoolException("四向穿梭车不在线"); } @@ -377,13 +279,13 @@ @PostMapping("/detl/update") @ManagerAuth(memo = "修改数据") public R shuttleUpdate(@RequestParam Integer shuttleNo, @RequestParam Short workNo, @RequestParam Integer workNo, @RequestParam String pakMk){ ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, shuttleNo); NyShuttleThread shuttleThread = (NyShuttleThread) SlaveConnection.get(SlaveType.Shuttle, shuttleNo); if (shuttleThread == null) { return R.error("plc已掉线"); } ShuttleProtocol shuttleProtocol = shuttleThread.getShuttleProtocol(); NyShuttleProtocol shuttleProtocol = shuttleThread.getShuttleProtocol(); if (shuttleProtocol == null) { return R.error("plc已掉线"); } @@ -399,12 +301,11 @@ @PostMapping("/runSpeed/{shuttleNo}") @ManagerAuth public R setRunSpeed(@PathVariable("shuttleNo") String shuttleNo, @RequestParam("runSpeed") Integer runSpeed, @RequestParam("chargeLine") Integer chargeLine) { BasShuttle basShuttle = basShuttleService.selectById(shuttleNo); if (basShuttle == null) { return R.error("四向穿梭车不存在"); } basShuttle.setRunSpeed(runSpeed); // basShuttle.setRunSpeed(runSpeed); basShuttle.setChargeLine(chargeLine); if (!basShuttleService.updateById(basShuttle)) { return R.error(); src/main/java/com/zy/asrs/entity/BasShuttle.java
@@ -125,135 +125,296 @@ @TableField("pak_mk") private Boolean pakMk; /** * 小车忙状态位 */ @ApiModelProperty(value= "小车忙状态位") @TableField("busy_status") private Integer busyStatus; // /** // * 小车忙状态位 // */ // @ApiModelProperty(value= "小车忙状态位") //// @TableField("busy_status") // private Integer busyStatus; // // /** // * 当前二维码 // */ // @ApiModelProperty(value= "当前二维码") //// @TableField("current_code") // private Integer currentCode; // // /** // * 电池电量百分比 // */ // @ApiModelProperty(value= "电池电量百分比") //// @TableField("battery_power") // private Integer batteryPower; // // /** // * 电池温度 // */ // @ApiModelProperty(value= "电池温度") //// @TableField("battery_temp") // private Integer batteryTemp; // // /** // * 错误编号 // */ // @ApiModelProperty(value= "错误编号") //// @TableField("error_code") // private Integer errorCode; // // /** // * Plc输出状态IO // */ // @ApiModelProperty(value= "Plc输出状态IO") //// @TableField("plc_output_status_io") // private Integer plcOutputStatusIo; // // /** // * 错误信息码 // */ // @ApiModelProperty(value= "错误信息码") //// @TableField("status_error_code") // private Integer statusErrorCode; // // /** // * PLC输入状态 // */ // @ApiModelProperty(value= "PLC输入状态") //// @TableField("plc_input_status") // private Integer plcInputStatus; // // /** // * 当前或者之前读到的二维码值 // */ // @ApiModelProperty(value= "当前或者之前读到的二维码值") //// @TableField("current_or_before_code") // private Integer currentOrBeforeCode; // // /** // * 读到的二维码X方向偏移量 // */ // @ApiModelProperty(value= "读到的二维码X方向偏移量") //// @TableField("code_offset_x") // private Integer codeOffsetX; // // /** // * 读到的二维码Y方向偏移量 // */ // @ApiModelProperty(value= "读到的二维码Y方向偏移量") //// @TableField("code_offset_y") // private Integer codeOffsetY; // // /** // * 当前的电压值 // */ // @ApiModelProperty(value= "当前的电压值") //// @TableField("current_voltage") // private Integer currentVoltage; // // /** // * 当前的模拟量值 // */ // @ApiModelProperty(value= "当前的模拟量值") //// @TableField("current_analog_value") // private Integer currentAnalogValue; // // /** // * 当前的升降伺服速度 // */ // @ApiModelProperty(value= "当前的升降伺服速度") //// @TableField("current_lift_servo_speed") // private Integer currentLiftServoSpeed; // // /** // * 当前的行走伺服速度 // */ // @ApiModelProperty(value= "当前的行走伺服速度") //// @TableField("current_move_servo_speed") // private Integer currentMoveServoSpeed; // // /** // * 当前的升降伺服负载率 // */ // @ApiModelProperty(value= "当前的升降伺服负载率") //// @TableField("current_lift_servo_load") // private Integer currentLiftServoLoad; // // /** // * 当前的行走伺服负载率 // */ // @ApiModelProperty(value= "当前的行走伺服负载率") //// @TableField("current_move_servo_load") // private Integer currentMoveServoLoad; // // /** // * 小车运行速度 // */ // @ApiModelProperty(value= "小车运行速度") //// @TableField("run_speed") // private Integer runSpeed; /** * 当前二维码 * 牛眼-工作模式 */ @ApiModelProperty(value= "当前二维码") @TableField("current_code") private Integer currentCode; @ApiModelProperty(value= "工作模式") @TableField("working_mode") private Integer workingMode; /** * 电池电量百分比 * 牛眼-运行状态 */ @ApiModelProperty(value= "电池电量百分比") @TableField("battery_power") private Integer batteryPower; @ApiModelProperty(value= "运行状态") @TableField("free") private Integer free; /** * 电池温度 * 牛眼-当前速度 */ @ApiModelProperty(value= "电池温度") @TableField("battery_temp") private Integer batteryTemp; @ApiModelProperty(value= "当前速度") @TableField("speed") private Integer speed; /** * 错误编号 * 牛眼-负载状态 */ @ApiModelProperty(value= "错误编号") @TableField("error_code") private Integer errorCode; @ApiModelProperty(value= "负载状态") @TableField("load_state") private Integer loadState; /** * Plc输出状态IO * 牛眼-管制状态 */ @ApiModelProperty(value= "Plc输出状态IO") @TableField("plc_output_status_io") private Integer plcOutputStatusIo; @ApiModelProperty(value= "管制状态") @TableField("suspend_state") private Integer suspendState; /** * 错误信息码 * 牛眼-顶升位置 */ @ApiModelProperty(value= "错误信息码") @TableField("status_error_code") private Integer statusErrorCode; @ApiModelProperty(value= "顶升位置") @TableField("lift_position") private Integer liftPosition; /** * PLC输入状态 * 牛眼-运行方向 */ @ApiModelProperty(value= "PLC输入状态") @TableField("plc_input_status") private Integer plcInputStatus; @ApiModelProperty(value= "运行方向") @TableField("run_dir") private Integer runDir; /** * 当前或者之前读到的二维码值 * 牛眼-运行方向 */ @ApiModelProperty(value= "当前或者之前读到的二维码值") @TableField("current_or_before_code") private Integer currentOrBeforeCode; @ApiModelProperty(value= "运行方向") @TableField("run_dir2") private Integer runDir2; /** * 读到的二维码X方向偏移量 * 牛眼-充电状态 */ @ApiModelProperty(value= "读到的二维码X方向偏移量") @TableField("code_offset_x") private Integer codeOffsetX; @ApiModelProperty(value= "充电状态") @TableField("charg_state") private Integer chargState; /** * 读到的二维码Y方向偏移量 * 牛眼-电池电量 */ @ApiModelProperty(value= "读到的二维码Y方向偏移量") @TableField("code_offset_y") private Integer codeOffsetY; @ApiModelProperty(value= "电池电量") @TableField("power_percent") private Integer powerPercent; /** * 当前的电压值 * 牛眼-最高电芯电压 */ @ApiModelProperty(value= "当前的电压值") @TableField("current_voltage") private Integer currentVoltage; @ApiModelProperty(value= "最高电芯电压") @TableField("max_cell_voltage") private Integer maxCellVoltage; /** * 当前的模拟量值 * 牛眼-最低电芯电压 */ @ApiModelProperty(value= "当前的模拟量值") @TableField("current_analog_value") private Integer currentAnalogValue; @ApiModelProperty(value= "最低电芯电压") @TableField("min_cell_voltage") private Integer minCellVoltage; /** * 当前的升降伺服速度 * 牛眼-电池电压 */ @ApiModelProperty(value= "当前的升降伺服速度") @TableField("current_lift_servo_speed") private Integer currentLiftServoSpeed; @ApiModelProperty(value= "电池电压") @TableField("voltage") private Integer voltage; /** * 当前的行走伺服速度 * 牛眼-充放电循环次数 */ @ApiModelProperty(value= "当前的行走伺服速度") @TableField("current_move_servo_speed") private Integer currentMoveServoSpeed; @ApiModelProperty(value= "充放电循环次数") @TableField("charge_cycle_times") private Integer chargeCycleTimes; /** * 当前的升降伺服负载率 * 牛眼-剩余电量 */ @ApiModelProperty(value= "当前的升降伺服负载率") @TableField("current_lift_servo_load") private Integer currentLiftServoLoad; @ApiModelProperty(value= "剩余电量") @TableField("surplus_quantity") private Integer surplusQuantity; /** * 当前的行走伺服负载率 * 牛眼-总电量 */ @ApiModelProperty(value= "当前的行走伺服负载率") @TableField("current_move_servo_load") private Integer currentMoveServoLoad; @ApiModelProperty(value= "总电量") @TableField("count_quantity") private Integer countQuantity; /** * 小车运行速度 * 牛眼-实际库位 */ @ApiModelProperty(value= "小车运行速度") @TableField("run_speed") private Integer runSpeed; @ApiModelProperty(value= "实际库位") @TableField("point") private String point; /** * 牛眼-实际坐标 */ @ApiModelProperty(value= "实际坐标") @TableField("coord") private String coord; /** * 牛眼-任务目的库位 */ @ApiModelProperty(value= "任务目的库位") @TableField("task") private String task; /** * 牛眼-任务状态 */ @ApiModelProperty(value= "任务状态") @TableField("task_state") private Integer taskState; /** * 牛眼-故障状态 */ @ApiModelProperty(value= "故障状态") @TableField("err_state") private Integer errState; /** * 牛眼-总里程数 */ @ApiModelProperty(value= "总里程数") @TableField("status_sum") private String statusSum; /** * 牛眼-非自动状态时间计时 */ @ApiModelProperty(value= "非自动状态时间计时") @TableField("err_time") private Integer errTime; public BasShuttle() {} public BasShuttle(Integer shuttleNo,Integer status,Integer shuttleStatus,Integer wrkNo,String idleLoc,Integer autoCharge,Integer chargeLine,Long createBy,Date createTime,Long updateBy,Date updateTime,String memo,Integer liftNo,Boolean pakMk,Integer busyStatus,Integer currentCode,Integer batteryPower,Integer batteryTemp,Integer errorCode,Integer plcOutputStatusIo,Integer statusErrorCode,Integer plcInputStatus,Integer currentOrBeforeCode,Integer codeOffsetX,Integer codeOffsetY,Integer currentVoltage,Integer currentAnalogValue,Integer currentLiftServoSpeed,Integer currentMoveServoSpeed,Integer currentLiftServoLoad,Integer currentMoveServoLoad) { public BasShuttle(Integer shuttleNo, Integer status, Integer shuttleStatus, Integer wrkNo, String idleLoc, Integer autoCharge, Integer chargeLine, Long createBy, Date createTime, Long updateBy, Date updateTime, String memo, Integer liftNo, Boolean pakMk, Integer busyStatus, Integer currentCode, Integer batteryPower, Integer batteryTemp, Integer errorCode, Integer plcOutputStatusIo, Integer statusErrorCode, Integer plcInputStatus, Integer currentOrBeforeCode, Integer codeOffsetX, Integer codeOffsetY, Integer currentVoltage, Integer currentAnalogValue, Integer currentLiftServoSpeed, Integer currentMoveServoSpeed, Integer currentLiftServoLoad, Integer currentMoveServoLoad, Integer runSpeed, Integer workingMode, Integer free, Integer speed, Integer loadState, Integer suspendState, Integer liftPosition, Integer runDir, Integer runDir2, Integer chargState, Integer powerPercent, Integer maxCellVoltage, Integer minCellVoltage, Integer voltage, Integer chargeCycleTimes, Integer surplusQuantity, Integer countQuantity, String point, String coord, String task, Integer taskState, Integer errState, String statusSum, Integer errTime) { this.shuttleNo = shuttleNo; this.status = status; this.shuttleStatus = shuttleStatus; @@ -268,23 +429,47 @@ this.memo = memo; this.liftNo = liftNo; this.pakMk = pakMk; this.busyStatus = busyStatus; this.currentCode = currentCode; this.batteryPower = batteryPower; this.batteryTemp = batteryTemp; this.errorCode = errorCode; this.plcOutputStatusIo = plcOutputStatusIo; this.statusErrorCode = statusErrorCode; this.plcInputStatus = plcInputStatus; this.currentOrBeforeCode = currentOrBeforeCode; this.codeOffsetX = codeOffsetX; this.codeOffsetY = codeOffsetY; this.currentVoltage = currentVoltage; this.currentAnalogValue = currentAnalogValue; this.currentLiftServoSpeed = currentLiftServoSpeed; this.currentMoveServoSpeed = currentMoveServoSpeed; this.currentLiftServoLoad = currentLiftServoLoad; this.currentMoveServoLoad = currentMoveServoLoad; // this.busyStatus = busyStatus; // this.currentCode = currentCode; // this.batteryPower = batteryPower; // this.batteryTemp = batteryTemp; // this.errorCode = errorCode; // this.plcOutputStatusIo = plcOutputStatusIo; // this.statusErrorCode = statusErrorCode; // this.plcInputStatus = plcInputStatus; // this.currentOrBeforeCode = currentOrBeforeCode; // this.codeOffsetX = codeOffsetX; // this.codeOffsetY = codeOffsetY; // this.currentVoltage = currentVoltage; // this.currentAnalogValue = currentAnalogValue; // this.currentLiftServoSpeed = currentLiftServoSpeed; // this.currentMoveServoSpeed = currentMoveServoSpeed; // this.currentLiftServoLoad = currentLiftServoLoad; // this.currentMoveServoLoad = currentMoveServoLoad; // this.runSpeed = runSpeed; this.workingMode = workingMode; this.free = free; this.speed = speed; this.loadState = loadState; this.suspendState = suspendState; this.liftPosition = liftPosition; this.runDir = runDir; this.runDir2 = runDir2; this.chargState = chargState; this.powerPercent = powerPercent; this.maxCellVoltage = maxCellVoltage; this.minCellVoltage = minCellVoltage; this.voltage = voltage; this.chargeCycleTimes = chargeCycleTimes; this.surplusQuantity = surplusQuantity; this.countQuantity = countQuantity; this.point = point; this.coord = coord; this.task = task; this.taskState = taskState; this.errState = errState; this.statusSum = statusSum; this.errTime = errTime; } // BasShuttle basShuttle = new BasShuttle( src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java
@@ -909,12 +909,12 @@ //获取小车移动速度 BasShuttle basShuttle = basShuttleService.selectById(assignCommand.getShuttleNo()); Integer runSpeed = 1000; if (basShuttle != null) { Integer runSpeed1 = basShuttle.getRunSpeed(); if (runSpeed1 != null) { runSpeed = runSpeed1; } } // if (basShuttle != null) { // Integer runSpeed1 = basShuttle.getRunSpeed(); // if (runSpeed1 != null) { // runSpeed = runSpeed1; // } // } //计算小车起点到中点所需命令 List<NavigateNode> calc = NavigateUtils.calc(startLocNo, locNo, mapType, Utils.getShuttlePoints(shuttleThread.getSlave().getId(), Utils.getLev(startLocNo))); @@ -979,12 +979,12 @@ //获取小车移动速度 BasShuttle basShuttle = basShuttleService.selectById(assignCommand.getShuttleNo()); Integer runSpeed = 1000; if (basShuttle != null) { Integer runSpeed1 = basShuttle.getRunSpeed(); if (runSpeed1 != null) { runSpeed = runSpeed1; } } // if (basShuttle != null) { // Integer runSpeed1 = basShuttle.getRunSpeed(); // if (runSpeed1 != null) { // runSpeed = runSpeed1; // } // } List<NavigateNode> allNode = new ArrayList<>(); src/main/java/com/zy/common/utils/NavigatePositionConvert.java
@@ -5,6 +5,7 @@ import com.zy.asrs.entity.LocMast; import com.zy.asrs.service.BasDevpService; import com.zy.asrs.service.LocMastService; import com.zy.asrs.utils.Utils; /** * 库位编号和A*算法的xy轴转换工具类 @@ -34,6 +35,12 @@ return Short.parseShort(sb.toString()); } //xyz轴转库位号 public static String xyzToLocNo(int x, int y, int z) { String locNo = Utils.getLocNo(x, y, z); return locNo; } //xyz轴转坐标编号 public static Short xyToPosition(int x, int y, int z) { StringBuffer sb = new StringBuffer(); src/main/java/com/zy/common/utils/NyHttpUtils.java
@@ -273,21 +273,24 @@ try { String response = new HttpHandler.Builder() .setUri(requestUrl) .setPath("/test") .setPath("/static/readStatus.json") .setJson(JSON.toJSONString(httpCommand)) .build() .doPost(); .doGet(); JSONObject jsonObject = JSON.parseObject(response); JSONObject request = jsonObject.getJSONObject("request"); JSONObject body = request.getJSONObject("body"); if (body.get("result").equals("success")) { JSONObject response2 = jsonObject.getJSONObject("response"); JSONObject body = response2.getJSONObject("body"); if (body.get("responseType").equals("state")) {//读取状态,不需要判断success return body; } if (body.get("result").equals("success")) { return body; } } catch (Exception e) { e.printStackTrace(); // e.printStackTrace(); } return null; } src/main/java/com/zy/core/MainProcess.java
@@ -57,20 +57,20 @@ // mainService.restartTaskFromRedis(); // 拣料、并板、盘点再入库 mainService.stnToCrnStnPick(); // 入库 ===>> 四向穿梭车入库作业下发 mainService.shuttleIoInExecute(); // 出库 ===>> 四向穿梭车出库作业下发 mainService.shuttleIoOutExecute(); //四向穿梭车任务完成 mainService.shuttleFinished(); // // 入库 ===>> 四向穿梭车入库作业下发 // mainService.shuttleIoInExecute(); // // 出库 ===>> 四向穿梭车出库作业下发 // mainService.shuttleIoOutExecute(); // //四向穿梭车任务完成 // mainService.shuttleFinished(); //提升机任务 mainService.liftIoExecute(); //提升机任务完成 mainService.liftFinished(); //库位移转 mainService.locToLocExecute(); // 异常信息记录 mainService.recErr(); // // 异常信息记录 // mainService.recErr(); // 入库 ===>> 空栈板初始化入库,叉车入库站放货 mainService.storeEmptyPlt(); // 出库 ===>> 工作档信息写入led显示器 @@ -78,8 +78,8 @@ // 其他 ===>> LED显示器复位,显示默认信息 mainService.ledReset(); // 穿梭车 ===>> 小车电量检测充电 mainService.loopShuttleCharge(); mainService.executeShuttleCharge(); // mainService.loopShuttleCharge(); // mainService.executeShuttleCharge(); // //出入库模式 // i++; src/main/java/com/zy/core/ServerBootstrap.java
@@ -93,7 +93,7 @@ // 初始化四向穿梭车 News.info("初始化四向穿梭车......................................................"); for (ShuttleSlave shuttleSlave : slaveProperties.getShuttle()) { ShuttleThread shuttleThread = new ShuttleThread(shuttleSlave,redisUtil); NyShuttleThread shuttleThread = new NyShuttleThread(shuttleSlave,redisUtil); new Thread(shuttleThread).start(); SlaveConnection.put(SlaveType.Shuttle, shuttleSlave.getId(), shuttleThread); } src/main/java/com/zy/core/enums/ShuttleStatusType.java
@@ -2,28 +2,27 @@ /** * 四向穿梭车 * Wm200 小车忙状态位 */ public enum ShuttleStatusType { IDLE((short)0, "空闲"), BUSY((short)1, "忙"), IDLE(1, "空闲"), BUSY(0, "忙"), ; public Short id; public Integer id; public String desc; ShuttleStatusType(Short id,String desc) { ShuttleStatusType(Integer id,String desc) { this.id = id; this.desc = desc; } public static ShuttleStatusType get(Short id) { public static ShuttleStatusType get(Integer id) { if (null == id) { return null; } for (ShuttleStatusType type : ShuttleStatusType.values()) { if (type.id.equals(id.shortValue())) { if (type.id == id) { return type; } } src/main/java/com/zy/core/model/protocol/NyShuttleProtocol.java
New file @@ -0,0 +1,431 @@ package com.zy.core.model.protocol; import com.alibaba.fastjson.JSON; import com.core.common.SpringUtils; import com.zy.asrs.service.BasShuttleService; import com.zy.common.utils.NavigatePositionConvert; import com.zy.core.News; import com.zy.core.enums.ShuttleErrorCodeType; import com.zy.core.enums.ShuttleProtocolStatusType; import com.zy.core.enums.ShuttleStatusType; import com.zy.core.model.command.ShuttleAssignCommand; import lombok.Data; import lombok.extern.slf4j.Slf4j; import java.util.List; /** * 牛眼四向穿梭车 */ @Slf4j @Data public class NyShuttleProtocol { /** * 四向穿梭车号 */ private Short shuttleNo; /** * 任务号 */ private Integer taskNo = 0; /** * 任务指令 */ private ShuttleAssignCommand assignCommand; /** * 当前小车状态(内部自我维护) */ private Integer protocolStatus; /** * 当前小车状态枚举 */ private ShuttleProtocolStatusType protocolStatusType; /** * 源库位 */ private String sourceLocNo; /** * 目标库位 */ private String locNo; /** * 作业标记 */ private Boolean pakMk = false; /** * 手动状态/自动状态 * 0/1 */ private Integer workingMode; /** * 0:运行中1:空闲。(车自动模式下,在 * 静止状态下,且没有其他任务且满足发送 * 新任务的状态) */ private Integer free; /** * 当前速度,单位mm/s */ private Integer speed; /** * 负载状态无/有负载 * 0/1 */ private Integer loadState; /** * 管制状态不在管制下/被管制中 * 0/1 */ private Integer suspendState; /** * 顶升位置0-未知1-下降位置2-托举位置 */ private Integer liftPosition; /** * 运行方向0-未知1-X向2-Y向 */ private Integer runDir; /** * 运行方向0-未知(静止)1-X+向2-X向3-Y+向4-Y-向 */ private Integer runDir2; /** * 充电状态0不在充电状态1充电中 */ private Integer chargState; /** * 电池电量0%-100% */ private Integer powerPercent; /** * 最高电芯电压(mV) */ private Integer maxCellVoltage; /** * 最低电芯电压(mV),低于2900mv需要立即充电 */ private Integer minCellVoltage; /** * 电池电压(mV) */ private Integer voltage; /** * 充放电循环次数 */ private Integer chargeCycleTimes; /** * 剩余电量/10(A) */ private Integer surplusQuantity; /** * 总电量/10(A) */ private Integer countQuantity; /** * 实际库位xyz */ private NyShuttlePointClass point; /** * 实际坐标xyz单位mm */ private NyShuttlePointClass coord; /** * 任务目的库位xyztaskId(正在动作的任务ID)lastTaskId(最后一个完成的任务ID)recentTaskId(收到的最后一个任务ID) */ private TaskClass task; /** * 任务状态0无任务1有任务 */ private Integer taskState; /** * 故障状态0无故障1故障中 */ private Integer errState; /** * 故障码 */ private List<Integer> errCode; /** * mileage总里程数(米),liftNumber顶升总数dropNumber下降总数reversingX换X总数reversingY换Y总数 */ private StatusSumClass statusSum; /** * 非自动状态时间计时(S) */ private Integer errTime; //总里程数 @Data public static class StatusSumClass { private Integer mileage;//总里程数(米) private Integer liftNumber;//顶升总数 private Integer dropNumber;//下降总数 private Integer reversingX;//换X总数 private Integer reversingY;//换Y总数 } @Data public static class NyShuttlePointClass{ private Integer x; private Integer y; private Integer z; } //任务目的库位 @Data public static class TaskClass extends NyShuttlePointClass{ private Integer taskState; private Integer taskId;//当前任务ID private Integer lastTaskId;//上一次完成的任务ID private Integer recentTaskId;//最后一次接收到的任务ID } public String getFree$() { if (this.getFree() == null) { return ""; } return this.getFree() == 1 ? "空闲" : "运行中"; } public String getLoadState$() { if (this.getLoadState() == null) { return ""; } return this.getLoadState() == 1 ? "有" : "无"; } public String getSuspendState$() { if (this.getSuspendState() == null) { return ""; } return this.getSuspendState() == 1 ? "是" : "否"; } public String getPowerPercent$() { if (this.getPowerPercent() == null) { return ""; } return this.getPowerPercent() + "%"; } public String getLiftPosition$() { if (this.getLiftPosition() == null) { return ""; } switch (this.getRunDir()) { case 0: return "未知"; case 1: return "下降位置"; case 2: return "托举位置"; default: return this.getLiftPosition().toString(); } } public String getChargState$() { if (this.getChargState() == null) { return ""; } return this.getChargState() == 1 ? "充电中" : "未充电"; } public String getMaxCellVoltage$() { if (this.getMaxCellVoltage() == null) { return ""; } return this.getMaxCellVoltage() + "mV"; } public String getMinCellVoltage$() { if (this.getMinCellVoltage() == null) { return ""; } return this.getMinCellVoltage() + "mV"; } public String getVoltage$() { if (this.getVoltage() == null) { return ""; } return this.getVoltage() + "mV"; } public String getTaskState$() { if (this.getTaskState() == null) { return ""; } return this.getTaskState() == 1 ? "有任务" : "无任务"; } public String getErrState$() { if (this.getErrState() == null) { return ""; } return this.getErrState() == 1 ? "故障中" : "无故障"; } public String getRunDir$() { if (this.getRunDir() == null) { return ""; } switch (this.getRunDir()) { case 0: return "未知"; case 1: return "X向"; case 2: return "Y向"; default: return "未知"; } } public String getRunDir2$() { if (this.getRunDir2() == null) { return ""; } switch (this.getRunDir2()) { case 0: return "未知"; case 1: return "X+向"; case 2: return "X-向"; case 3: return "Y+向"; case 4: return "Y-向"; default: return "未知"; } } /** * 设置小车状态 */ public void setProtocolStatus(Integer status) { this.protocolStatus = status; this.protocolStatusType = ShuttleProtocolStatusType.get(status); } /** * 设置小车状态 */ public void setProtocolStatus(ShuttleProtocolStatusType status) { this.protocolStatus = status.id; this.protocolStatusType = status; } public String getProtocolStatus$() { if (this.getProtocolStatus() == null) { return ""; } return ShuttleProtocolStatusType.get(this.getProtocolStatus()).desc; } public String getPakMk$() { if (this.getPakMk() == null) { return ""; } return this.getPakMk() ? "Y" : "N"; } public String getPoint$() { if (this.getPoint() == null) { return ""; } return NavigatePositionConvert.xyzToLocNo(this.getPoint().getX(), this.getPoint().getY(), this.getPoint().getZ()); } public String getCoord$() { if (this.getCoord() == null) { return ""; } return JSON.toJSONString(this.getCoord()); } // 是否处于空闲待命状态 public Boolean isIdle() { boolean res = this.free == ShuttleStatusType.IDLE.id && this.pakMk.equals(true) && this.errState == 0 && this.taskNo == 0 && this.protocolStatus == ShuttleProtocolStatusType.IDLE.id ; if (!res) { return res; } else { // 电量 try { Integer chargeLine = SpringUtils.getBean(BasShuttleService.class).selectById(this.shuttleNo).getChargeLine(); if (chargeLine == null) { return false; } return this.getPowerPercent() >= chargeLine; } catch (Exception e) { News.error("fail", e); return false; } } } // 是否处于空闲待命状态,传入的taskNo和当前taskNo相同时允许放行 public Boolean isIdle(int taskNo) { boolean res = this.free == ShuttleStatusType.IDLE.id && this.pakMk.equals(true) && this.errState == 0 && (this.taskNo == 0 || this.taskNo == taskNo) && this.protocolStatus.intValue() == ShuttleProtocolStatusType.IDLE.id ; if (!res) { return res; } else { // 电量 try { Integer chargeLine = SpringUtils.getBean(BasShuttleService.class).selectById(this.shuttleNo).getChargeLine(); return this.getPowerPercent() > chargeLine; } catch (Exception e) { News.error("fail", e); return false; } } } } src/main/java/com/zy/core/model/protocol/ShuttleProtocol.java
@@ -184,7 +184,7 @@ public void setBusyStatus(Short status) { this.busyStatus = status; this.busyStatusType = ShuttleStatusType.get(status); this.busyStatusType = ShuttleStatusType.get(status.intValue()); } public void setBusyStatus(ShuttleStatusType type) { src/main/java/com/zy/core/thread/NyShuttleThread.java
New file @@ -0,0 +1,815 @@ package com.zy.core.thread; import com.alibaba.fastjson.JSONObject; import com.core.common.DateUtils; import com.core.common.SpringUtils; import com.zy.asrs.entity.*; import com.zy.asrs.service.*; import com.zy.common.utils.*; import com.zy.core.News; import com.zy.core.ThreadHandler; import com.zy.core.cache.MessageQueue; import com.zy.core.cache.OutputQueue; import com.zy.core.enums.*; import com.zy.core.model.ShuttleSlave; import com.zy.core.model.Task; import com.zy.core.model.command.NyShuttleHttpCommand; import com.zy.core.model.command.ShuttleAssignCommand; import com.zy.core.model.command.ShuttleCommand; import com.zy.core.model.protocol.NyShuttleProtocol; import lombok.Data; import lombok.extern.slf4j.Slf4j; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Date; /** * 牛眼四向穿梭车线程 */ @Data @Slf4j public class NyShuttleThread implements Runnable, ThreadHandler { private ShuttleSlave slave; private NyShuttleProtocol shuttleProtocol; private RedisUtil redisUtil; public NyShuttleThread(ShuttleSlave slave,RedisUtil redisUtil) { this.slave = slave; this.redisUtil = redisUtil; } @Override public void run() { this.connect(); while (true) { try { int step = 1; Task task = MessageQueue.poll(SlaveType.Shuttle, slave.getId()); if (task != null) { step = task.getStep(); } switch (step) { // 读数据 case 1: read(); break; // 写入数据 case 2: write((ShuttleCommand) task.getData()); break; //下发任务 case 3: assignWork((ShuttleAssignCommand) task.getData()); break; default: break; } Thread.sleep(500); } catch (Exception e) { e.printStackTrace(); } } } private void read() { try { readStatus(); //四向穿梭车空闲、有任务、标记为true、存在任务指令,需要执行任务的下一条指令 if (shuttleProtocol.getFree() == ShuttleStatusType.IDLE.id && shuttleProtocol.getTaskNo() != 0 && shuttleProtocol.getPakMk()) { //执行下一步指令 executeWork(shuttleProtocol.getTaskNo()); } } catch (Exception e) { e.printStackTrace(); OutputQueue.SHUTTLE.offer(MessageFormat.format("【{0}】四向穿梭车plc状态信息失败 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort())); } } private void readStatus() { try { if (null == shuttleProtocol) { shuttleProtocol = new NyShuttleProtocol(); shuttleProtocol.setShuttleNo(slave.getId().shortValue()); shuttleProtocol.setProtocolStatus(ShuttleProtocolStatusType.IDLE); } //----------读取四向穿梭车状态----------- NyShuttleHttpCommand readStatusCommand = NyHttpUtils.getReadStatusCommand(slave.getId()); JSONObject jsonObject = NyHttpUtils.requestCommand(readStatusCommand); if (jsonObject == null) { OutputQueue.SHUTTLE.offer(MessageFormat.format("【{0}】四向穿梭车plc状态信息失败 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort())); }else { //手动状态/自动状态 shuttleProtocol.setWorkingMode(jsonObject.getInteger("workingMode")); //允许状态 0:运行中1:空闲 shuttleProtocol.setFree(jsonObject.getInteger("free")); //当前速度 shuttleProtocol.setSpeed(jsonObject.getInteger("speed")); //负载状态 shuttleProtocol.setLoadState(jsonObject.getInteger("loadState")); //管制状态 shuttleProtocol.setSuspendState(jsonObject.getInteger("suspendState")); //顶升位置 shuttleProtocol.setLiftPosition(jsonObject.getInteger("liftPosition")); //运行方向 shuttleProtocol.setRunDir(jsonObject.getInteger("runDir")); //运行方向 shuttleProtocol.setRunDir2(jsonObject.getInteger("runDir2")); //充电状态 shuttleProtocol.setChargState(jsonObject.getInteger("chargState")); //电池电量 shuttleProtocol.setPowerPercent(jsonObject.getInteger("powerPercent")); //最高电芯电压(mV) shuttleProtocol.setMaxCellVoltage(jsonObject.getInteger("maxCellVoltage")); //最低电芯电压(mV) shuttleProtocol.setMinCellVoltage(jsonObject.getInteger("minCellVoltage")); //电池电压 shuttleProtocol.setVoltage(jsonObject.getInteger("voltage")); //充放电循环次数 shuttleProtocol.setChargeCycleTimes(jsonObject.getInteger("chargeCycleTimes")); //剩余电量 shuttleProtocol.setSurplusQuantity(jsonObject.getInteger("surplusQuantity")); //总电量 shuttleProtocol.setCountQuantity(jsonObject.getInteger("countQuantity")); //实际库位xyz shuttleProtocol.setPoint(jsonObject.getObject("point", NyShuttleProtocol.NyShuttlePointClass.class)); //实际坐标xyz shuttleProtocol.setCoord(jsonObject.getObject("coord", NyShuttleProtocol.NyShuttlePointClass.class)); //任务目的库位 shuttleProtocol.setTask(jsonObject.getObject("task", NyShuttleProtocol.TaskClass.class)); //任务状态 shuttleProtocol.setTaskState(jsonObject.getInteger("taskState")); //故障状态 shuttleProtocol.setErrState(jsonObject.getInteger("errState")); ArrayList<Integer> errCode = new ArrayList<>(); for (Object o : jsonObject.getJSONArray("errCode")) { errCode.add(Integer.parseInt(o.toString())); } //故障码 shuttleProtocol.setErrCode(errCode); //总里程数 shuttleProtocol.setStatusSum(jsonObject.getObject("statusSum", NyShuttleProtocol.StatusSumClass.class)); //非自动状态时间计时 shuttleProtocol.setErrTime(jsonObject.getInteger("errTime")); //小车处于运行中,将标记置为true if (shuttleProtocol.getFree() == 0) { shuttleProtocol.setPakMk(true); } //将四向穿梭车状态保存至数据库 BasShuttleService shuttleService = SpringUtils.getBean(BasShuttleService.class); BasShuttle basShuttle = shuttleService.selectById(slave.getId()); if (basShuttle == null) { basShuttle = new BasShuttle(); //四向穿梭车号 basShuttle.setShuttleNo(slave.getId()); shuttleService.insert(basShuttle); } //工作模式 basShuttle.setWorkingMode(shuttleProtocol.getWorkingMode()); //运行状态 basShuttle.setFree(shuttleProtocol.getFree()); //当前速度 basShuttle.setSpeed(shuttleProtocol.getSpeed()); //负载状态 basShuttle.setLoadState(shuttleProtocol.getLoadState()); //管制状态 basShuttle.setSuspendState(shuttleProtocol.getSuspendState()); //顶升位置 basShuttle.setLiftPosition(shuttleProtocol.getLiftPosition()); //运行方向 basShuttle.setRunDir(shuttleProtocol.getRunDir()); //运行方向 basShuttle.setRunDir2(shuttleProtocol.getRunDir2()); //充电状态 basShuttle.setChargState(shuttleProtocol.getChargState()); //电池电量 basShuttle.setPowerPercent(shuttleProtocol.getPowerPercent()); //最高电芯电压 basShuttle.setMaxCellVoltage(shuttleProtocol.getMaxCellVoltage()); //电池电压 basShuttle.setVoltage(shuttleProtocol.getVoltage()); //充放电循环次数 basShuttle.setChargeCycleTimes(shuttleProtocol.getChargeCycleTimes()); //剩余电量 basShuttle.setSurplusQuantity(shuttleProtocol.getSurplusQuantity()); //总电量 basShuttle.setCountQuantity(shuttleProtocol.getCountQuantity()); //实际库位 basShuttle.setPoint(JSONObject.toJSONString(shuttleProtocol.getPoint())); //实际坐标 basShuttle.setCoord(JSONObject.toJSONString(shuttleProtocol.getCoord())); //任务目的库位 basShuttle.setTask(JSONObject.toJSONString(shuttleProtocol.getTask())); //任务状态 basShuttle.setTaskState(shuttleProtocol.getTaskState()); //故障状态 basShuttle.setErrState(shuttleProtocol.getErrState()); //总里程数 basShuttle.setStatusSum(JSONObject.toJSONString(shuttleProtocol.getStatusSum())); //非自动状态时间计时 basShuttle.setErrTime(shuttleProtocol.getErrTime()); //任务号 basShuttle.setWrkNo(shuttleProtocol.getTaskNo().intValue()); //修改时间 basShuttle.setUpdateTime(new Date()); //作业标记 basShuttle.setPakMk(shuttleProtocol.getPakMk()); if (shuttleService.updateById(basShuttle)) { OutputQueue.SHUTTLE.offer(MessageFormat.format("【{0}】[id:{1}] <<<<< 实时数据更新成功",DateUtils.convert(new Date()), slave.getId())); // log.info(MessageFormat.format("【{0}】[id:{1}] <<<<< 实时数据更新成功",DateUtils.convert(new Date()), slave.getId())); } } } catch (Exception e) { e.printStackTrace(); OutputQueue.SHUTTLE.offer(MessageFormat.format("【{0}】四向穿梭车plc状态信息失败 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort())); } } @Override public boolean connect() { return true; } @Override public void close() { } private boolean write(ShuttleCommand command){ if (null == command) { News.error("四向穿梭车写入命令为空"); return false; } BasShuttleService shuttleService = SpringUtils.getBean(BasShuttleService.class); if (shuttleService == null) { News.error("系统错误"); return false; } BasShuttle basShuttle = shuttleService.selectById(slave.getId().shortValue()); if (basShuttle == null) { News.error("四向穿梭车不存在"); return false; } // command.setShuttleNo(slave.getId().shortValue()); // short[] array = getCommandArr(command);//获取命令报文 // OperateResult result = modbusTcpNet.Write("0", array); // if (result != null && result.IsSuccess) { // News.info("四向穿梭车命令下发[id:{}] >>>>> {}", slave.getId(), JSON.toJSON(command)); // OutputQueue.SHUTTLE.offer(MessageFormat.format("【{0}】[id:{1}] >>>>> 命令下发: {2}", DateUtils.convert(new Date()), slave.getId(), JSON.toJSON(command))); // // try { // Thread.sleep(3000);//命令下发后休眠 // } catch (InterruptedException e) { // throw new RuntimeException(e); // } // // for (int i = 0; i < 5; i++) { // if (command.getCommandWord().intValue() == 5 || command.getCommandWord().intValue() == 6) { // break;//充电开关和系统复位不需要重发机制 // } // readStatus();//重新读取状态 // if (shuttleProtocol.getBusyStatusType().equals(ShuttleStatusType.BUSY)) { // break; // } // // //判断是否运行中,如不运行,重新下发命令 // result = modbusTcpNet.Write("0", array); // News.info("四向穿梭车命令下发[id:{}] >>>>> {},次数:{}", slave.getId(), JSON.toJSON(command), i); // OutputQueue.SHUTTLE.offer(MessageFormat.format("【{0}】[id:{1}] >>>>> 命令下发: {2},次数:{}", DateUtils.convert(new Date()), slave.getId(), JSON.toJSON(command), i)); // try { // Thread.sleep(300);//命令下发后休眠 // } catch (InterruptedException e) { // throw new RuntimeException(e); // } // } // // return true; // } else { // OutputQueue.SHUTTLE.offer(MessageFormat.format("【{0}】写入四向穿梭车plc数据失败 ===>> [id:{1}] [ip:{2}] [port:{3}],次数:{}", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort())); // News.error("写入四向穿梭车plc数据失败 ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort()); // return false; // } return false; } //分配任务 private void assignWork(ShuttleAssignCommand assignCommand) { // ShuttleRedisCommand redisCommand = new ShuttleRedisCommand(); // // if (!assignCommand.getAuto()) { // List<NavigateNode> allNode = new ArrayList<>(); // List<ShuttleCommand> commands = new ArrayList<>(); // LocMastService locMastService = SpringUtils.getBean(LocMastService.class); // BasShuttleService shuttleService = SpringUtils.getBean(BasShuttleService.class); // NavigateMapData navigateMapData; // // //获取小车移动速度 // BasShuttle basShuttle = shuttleService.selectById(slave.getId()); // Integer runSpeed = 1000; // if (basShuttle != null) { // Integer runSpeed1 = basShuttle.getRunSpeed(); // if (runSpeed1 != null) { // runSpeed = runSpeed1; // } // } // // LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, 1); // LiftProtocol liftProtocol = liftThread.getLiftProtocol(); // // switch (assignCommand.getTaskMode()) { // case 1://入库 // case 2://出库 // //小车移动到提升机口,计算路径 // //计算小车起点到中点所需命令 // LocMast currentLocMast = locMastService.queryByQrCode(shuttleProtocol.getCurrentCode().toString()); // List<NavigateNode> firstMastResult = NavigateUtils.calc(currentLocMast.getLocNo(), assignCommand.getSourceLocNo(), NavigationMapType.NORMAL.id, Utils.getShuttlePoints(assignCommand.getShuttleNo().intValue(), Utils.getLev(currentLocMast.getLocNo())));//小车到中点,处于无货状态,使用正常通道地图 // boolean checkResult = Utils.checkShuttlePath(firstMastResult, shuttleProtocol.getShuttleNo().intValue()); // if (firstMastResult != null && checkResult) { // allNode.addAll(firstMastResult);//将节点进行保存 // //获取分段路径 // ArrayList<ArrayList<NavigateNode>> data = NavigateUtils.getSectionPath(firstMastResult); // //将每一段路径分成command指令 // for (ArrayList<NavigateNode> nodes : data) { // //开始路径 // NavigateNode startPath = nodes.get(0); // //中间路径 // NavigateNode middlePath = nodes.get(nodes.size() - 2); // //目标路径 // NavigateNode endPath = nodes.get(nodes.size() - 1); // Integer allDistance = NavigateUtils.getCurrentPathAllDistance(nodes);//计算当前路径行走总距离 // Integer middleToDistDistance = NavigateUtils.getMiddleToDistDistance(nodes, middlePath);//计算中间点到目标点行走距离 // // //正常移动命令 // Short startCode = NavigatePositionConvert.xyToPosition(startPath.getX(), startPath.getY(), startPath.getZ());//开始二维码 // Short middleCode = NavigatePositionConvert.xyToPosition(middlePath.getX(), middlePath.getY(), middlePath.getZ());//目标二维码 // Short distCode = NavigatePositionConvert.xyToPosition(endPath.getX(), endPath.getY(), endPath.getZ());//目标二维码 // commands.add(getMoveCommand(startCode, distCode, allDistance, ShuttleRunDirection.get(startPath.getDirection()).id, middleCode, middleToDistDistance, runSpeed)); // } // // //托盘顶升 // commands.add(getPalletCommand((short) 1)); // }else { // //没有计算到路径,可能存在小车位置就是起点位置 // if (currentLocMast.getLocNo().equals(assignCommand.getSourceLocNo())) { // //小车位置就是起点位置,无需移动,直接顶升 // //托盘顶升 // commands.add(getPalletCommand((short) 1)); // } // } // // //计算中点到终点路径 // List<NavigateNode> secMastResult = NavigateUtils.calc(assignCommand.getSourceLocNo(), assignCommand.getLocNo(), NavigationMapType.DFX.id, Utils.getShuttlePoints(assignCommand.getShuttleNo().intValue(), Utils.getLev(assignCommand.getSourceLocNo())));//小车从中点到终点,处于有货状态,使用DFX地图 // boolean checkResult2 = Utils.checkShuttlePath(secMastResult, shuttleProtocol.getShuttleNo().intValue()); // if (secMastResult != null && checkResult2) { // allNode.addAll(secMastResult);//将节点进行保存 // //获取分段路径 // ArrayList<ArrayList<NavigateNode>> data = NavigateUtils.getSectionPath(secMastResult); // //将每一段路径分成command指令 // for (ArrayList<NavigateNode> nodes : data) { // //开始路径 // NavigateNode startPath = nodes.get(0); // //中间路径 // NavigateNode middlePath = nodes.get(nodes.size() - 2); // //目标路径 // NavigateNode endPath = nodes.get(nodes.size() - 1); // Integer allDistance = NavigateUtils.getCurrentPathAllDistance(nodes);//计算当前路径行走总距离 // Integer middleToDistDistance = NavigateUtils.getMiddleToDistDistance(nodes, middlePath);//计算中间点到目标点行走距离 // // //正常移动命令 // Short startCode = NavigatePositionConvert.xyToPosition(startPath.getX(), startPath.getY(), startPath.getZ());//开始二维码 // Short middleCode = NavigatePositionConvert.xyToPosition(middlePath.getX(), middlePath.getY(), middlePath.getZ());//中间二维码 // Short distCode = NavigatePositionConvert.xyToPosition(endPath.getX(), endPath.getY(), endPath.getZ());//目标二维码 // commands.add(getMoveCommand(startCode, distCode, allDistance, ShuttleRunDirection.get(startPath.getDirection()).id, middleCode, middleToDistDistance, runSpeed)); // } // // //托盘下降 // commands.add(getPalletCommand((short) 2)); // } // // if (firstMastResult == null || secMastResult == null) { // throw new CoolException(MessageFormat.format( "四向穿梭车出入库路径搜索失败 ===>> [id:{0}] [ip:{1}] [port:{2}]", slave.getId(), slave.getIp(), slave.getPort())); // } // // navigateMapData = new NavigateMapData(Utils.getLev(currentLocMast.getLocNo())); // //所使用的路径进行锁定禁用 // navigateMapData.writeNavigateNodeToRedisMap(firstMastResult, true);////所使用的路径进行锁定禁用 // navigateMapData.writeNavigateNodeToRedisMap(secMastResult, true);////所使用的路径进行锁定禁用 // break; // case 3://托盘顶升 // case 4://托盘下降 // commands.add(getPalletCommand(assignCommand.getTaskMode() == 3 ? (short) 1 : (short) 2)); // break; // case 5://强制左移 // commands.add(getForceMoveCommand((short) 2)); // break; // case 6://强制右移 // commands.add(getForceMoveCommand((short) 1)); // break; // case 7://强制上移 // commands.add(getForceMoveCommand((short) 3)); // break; // case 8://强制下移 // commands.add(getForceMoveCommand((short) 4)); // break; // case 9://状态复位 // ShuttleCommand reset = getResetCommand(); // commands.add(reset); // break; // case 10://正方向(右)寻库位 // commands.add(getFindLocCommand((short) 1)); // break; // case 11://负方向(左)寻库位 // commands.add(getFindLocCommand((short) 2)); // break; // case 12://向正方向(前)寻库位 // commands.add(getFindLocCommand((short) 4)); // break; // case 13://向负方向(后)寻库位 // commands.add(getFindLocCommand((short) 3)); // break; // case 14://移动到目标库位 // String startQr = shuttleProtocol.getCurrentCode().toString();//起始位置 // //如果穿梭车在提升机内,移动时需要先下发出提升机命令 // if (liftProtocol.getBarcode().intValue() == shuttleProtocol.getCurrentCode().intValue()) { // //穿梭车出提升机 // Short liftArrival = liftProtocol.getPositionArrivalFeedback();//提升机位置反馈 // String liftSiteLocNo = Utils.liftArrivalToOutInStaLocNo(liftArrival); // LocMast locMast1 = locMastService.selectById(liftSiteLocNo); // ShuttleCommand moveCommand = getMoveCommand(liftProtocol.getBarcode(), Short.parseShort(locMast1.getQrCodeValue()), 1600, ShuttleRunDirection.BOTTOM.id, null, null, runSpeed); // commands.add(moveCommand); // // //起始位置修改为提升机口站点位置 // startQr = locMast1.getQrCodeValue(); // } // // LocMast locMast = locMastService.queryByQrCode(startQr); // List<NavigateNode> result = NavigateUtils.calc(locMast.getLocNo(), assignCommand.getLocNo(), NavigationMapType.NONE.id, Utils.getShuttlePoints(assignCommand.getShuttleNo().intValue(), Utils.getLev(locMast.getLocNo())));//手动命令-移动命令,使用无过滤地图 // boolean checkResult3 = Utils.checkShuttlePath(result, shuttleProtocol.getShuttleNo().intValue()); // if (result != null && checkResult3) { // //所使用的路径进行锁定禁用 // navigateMapData = new NavigateMapData(Utils.getLev(locMast.getLocNo())); // navigateMapData.writeNavigateNodeToRedisMap(result, true);////所使用的路径进行锁定禁用 // // allNode.addAll(result);//将节点进行保存 // //获取分段路径 // ArrayList<ArrayList<NavigateNode>> data = NavigateUtils.getSectionPath(result); // //将每一段路径分成command指令 // for (ArrayList<NavigateNode> nodes : data) { // //开始路径 // NavigateNode startPath = nodes.get(0); // //中间路径 // NavigateNode middlePath = nodes.get(nodes.size() - 2); // //目标路径 // NavigateNode endPath = nodes.get(nodes.size() - 1); // Integer allDistance = NavigateUtils.getCurrentPathAllDistance(nodes);//计算当前路径行走总距离 // Integer middleToDistDistance = NavigateUtils.getMiddleToDistDistance(nodes, middlePath);//计算中间点到目标点行走距离 // Short startCode = NavigatePositionConvert.xyToPosition(startPath.getX(), startPath.getY(), startPath.getZ());//开始二维码 // Short middleCode = NavigatePositionConvert.xyToPosition(middlePath.getX(), middlePath.getY(), middlePath.getZ());//中间二维码 // Short distCode = NavigatePositionConvert.xyToPosition(endPath.getX(), endPath.getY(), endPath.getZ());//目标二维码 // //正常移动命令 // commands.add(getMoveCommand(startCode, distCode, allDistance, ShuttleRunDirection.get(startPath.getDirection()).id, middleCode, middleToDistDistance, runSpeed)); // } // } // break; // case 15://充电开关 // commands.add(getChargeSwitchCommand()); // break; // case 16://移动到提升机 // LocMast locMast1 = locMastService.queryByQrCode(shuttleProtocol.getCurrentCode().toString()); // int lev = Utils.getLev(locMast1.getLocNo());//穿梭车当前高度 // String liftSiteLocNo = Utils.levToOutInStaLocNo(lev);//当前楼层站点库位号 // LocMast liftSitelocMast = locMastService.selectById(liftSiteLocNo); // List<NavigateNode> result1 = NavigateUtils.calc(locMast1.getLocNo(), liftSiteLocNo, NavigationMapType.NONE.id, Utils.getShuttlePoints(assignCommand.getShuttleNo().intValue(), Utils.getLev(locMast1.getLocNo())));//移动到提升机,使用无过滤地图 // boolean checkResult4 = Utils.checkShuttlePath(result1, shuttleProtocol.getShuttleNo().intValue()); // Short endStartCode = null; // if (result1 != null && checkResult4) { // //所使用的路径进行锁定禁用 // navigateMapData = new NavigateMapData(Utils.getLev(locMast1.getLocNo())); // navigateMapData.writeNavigateNodeToRedisMap(result1, true);////所使用的路径进行锁定禁用 // // allNode.addAll(result1);//将节点进行保存 // //获取分段路径 // ArrayList<ArrayList<NavigateNode>> data = NavigateUtils.getSectionPath(result1); // //将每一段路径分成command指令 // for (ArrayList<NavigateNode> nodes : data) { // //开始路径 // NavigateNode startPath = nodes.get(0); // //中间路径 // NavigateNode middlePath = nodes.get(nodes.size() - 2); // //目标路径 // NavigateNode endPath = nodes.get(nodes.size() - 1); // Integer allDistance = NavigateUtils.getCurrentPathAllDistance(nodes);//计算当前路径行走总距离 // Integer middleToDistDistance = NavigateUtils.getMiddleToDistDistance(nodes, middlePath);//计算中间点到目标点行走距离 // Short startCode = NavigatePositionConvert.xyToPosition(startPath.getX(), startPath.getY(), startPath.getZ());//开始二维码 // Short middleCode = NavigatePositionConvert.xyToPosition(middlePath.getX(), middlePath.getY(), middlePath.getZ());//中间二维码 // Short distCode = NavigatePositionConvert.xyToPosition(endPath.getX(), endPath.getY(), endPath.getZ());//目标二维码 // endStartCode = distCode; // //正常移动命令 // commands.add(getMoveCommand(startCode, distCode, allDistance, ShuttleRunDirection.get(startPath.getDirection()).id, middleCode, middleToDistDistance, runSpeed)); // } // } // // if (endStartCode == null && shuttleProtocol.getCurrentCode() == Short.parseShort(liftSitelocMast.getQrCodeValue())) { // //穿梭车已经在提升机站点口 // endStartCode = shuttleProtocol.getCurrentCode(); // } // // //增加移动进提升机命令 // ShuttleCommand moveCommand = getMoveCommand(endStartCode, liftProtocol.getBarcode(), 1600, ShuttleRunDirection.TOP.id, null, null, runSpeed); // commands.add(moveCommand); // break; // default: // } // assignCommand.setCommands(commands); // assignCommand.setNodes(allNode);//当前任务所占用的节点list // } // // redisCommand.setShuttleNo(assignCommand.getShuttleNo());//四向穿梭车号 // redisCommand.setWrkNo(assignCommand.getTaskNo());//工作号 // redisCommand.setCommandStep(0);//命令执行步序 // redisCommand.setAssignCommand(assignCommand);//命令 // redisCommand.setErrorCommands(new ArrayList<ShuttleCommand>());//发生错误时尝试执行的指令,优先级最高 // shuttleProtocol.setTaskNo(assignCommand.getTaskNo()); // shuttleProtocol.setAssignCommand(assignCommand); // shuttleProtocol.setProtocolStatus(ShuttleProtocolStatusType.WORKING); // //任务数据保存到redis // redisUtil.set("shuttle_wrk_no_" + assignCommand.getTaskNo(), JSON.toJSONString(redisCommand)); // //执行下发任务 // executeWork(assignCommand.getTaskNo()); } //执行下发的指令 private boolean executeWork(Integer wrkNo) { // //读取redis数据 // if (wrkNo == null) { // return false; // } // // WrkMastService wrkMastService = SpringUtils.getBean(WrkMastService.class); // // Object o = redisUtil.get("shuttle_wrk_no_" + wrkNo); // if (o == null) { // return false; // } // ShuttleRedisCommand redisCommand = JSON.parseObject(o.toString(), ShuttleRedisCommand.class); // // if (shuttleProtocol.getBusyStatus().intValue() == ShuttleStatusType.BUSY.id) { // return false;//小车状态忙 // } // // if (!checkLiftStation(wrkNo)) {//检测是否有提升机站点,有则调度提升机 // return false; // } // // LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, 1); // LiftProtocol liftProtocol = liftThread.getLiftProtocol(); // // List<ShuttleCommand> commands = redisCommand.getAssignCommand().getCommands(); // //当前步序 // int commandStep = redisCommand.getCommandStep(); // //path路径数目 // int size = commands.size(); // ShuttleAssignCommand assignCommand = redisCommand.getAssignCommand(); // // if (commandStep != 0) { // //判断上一条指令是否完成 // ShuttleCommand command = commands.get(commandStep - 1); // if (command.getCommandWord().intValue() == 1) { // //移动命令 // if (command.getDistCodeNum().intValue() == shuttleProtocol.getCurrentCode().intValue()) { // //上一条指令的目标位置和当前小车位置相同,则认定上一条任务完成 // command.setComplete(true); // // //上一条指令起点是提升机二维码,则清零提升机任务号 // if (command.getStartCodeNum().intValue() == liftProtocol.getBarcode().intValue()) { // //判断提升机是否处于空闲 // if (liftProtocol.isIdleNoTask() && liftProtocol.getTaskNo().intValue() == redisCommand.getWrkNo().intValue()) { // liftProtocol.setTaskNo((short) 0);//清空任务号 // WrkMast wrkMast = wrkMastService.selectById(wrkNo); // if (wrkMast != null) { // wrkMast.setLiftNo(null);//解锁提升机 // wrkMastService.updateById(wrkMast); // } // } // } // // //入库命令,当小车取完货后,需要将提升机释放 // if (assignCommand.getTaskMode().intValue() == ShuttleTaskModeType.PAK_IN.id) { // //判断上一条指令的起点是否为输送站点且目标点不是提升机内部二维码 // Short startCodeNum = command.getStartCodeNum(); // BasDevpService basDevpService = SpringUtils.getBean(BasDevpService.class); // BasDevp basDevp = basDevpService.queryByQrCode(startCodeNum.intValue());//目标站点 // if (basDevp != null && command.getDistCodeNum().intValue() != liftProtocol.getBarcode().intValue()) { // //上一条指令的起点为输送站点且目标点不是提升机内部二维码 // //此时小车应该已经离开输送站点,判断提升机是否空闲且有工作号 // if (liftProtocol.isIdleNoTask() && liftProtocol.getTaskNo().intValue() == redisCommand.getWrkNo().intValue()) { // liftProtocol.setTaskNo((short) 0);//清空任务号 // WrkMast wrkMast = wrkMastService.selectById(wrkNo); // if (wrkMast != null) { // wrkMast.setLiftNo(null);//解锁提升机 // wrkMastService.updateById(wrkMast); // } // } // } // } // // } // } else if (command.getCommandWord().intValue() == 2) { // //托盘顶升命令 // if (command.getPalletLift().intValue() == 1) { // //顶升 // //判断是否顶升到位 // if (shuttleProtocol.getPlcOutputLift()) { // //自动模式 // if (assignCommand.getAuto() && shuttleProtocol.getPlcInputStatus().intValue() == 1) { // //顶升到位,且托盘雷达有物,认定任务完成 // command.setComplete(true); // }else { // //手动模式,不判断托盘雷达 // //顶升到位,认定任务完成 // command.setComplete(true); // } // } // }else { // //下降 // //判断是否下降到位,判断托盘雷达是否无物 // if (!shuttleProtocol.getPlcOutputLift() && !shuttleProtocol.getPlcOutputTransfer()) { // //自动模式 // if (assignCommand.getAuto() && shuttleProtocol.getPlcInputStatus().intValue() == 0) { // //下降到位,且托盘雷达无物,认定任务完成 // command.setComplete(true); // }else { // //手动模式,不判断托盘雷达 // //下降到位,且托盘雷达无物,认定任务完成 // command.setComplete(true); // } // } // } // } else if (command.getCommandWord().intValue() == 5) { // //充电命令 // //判断小车充电开关 // if (shuttleProtocol.getPlcOutputCharge()) { // //正常充电,认定任务完成 // command.setComplete(true); // } // } // //任务数据保存到redis // redisUtil.set("shuttle_wrk_no_" + redisCommand.getWrkNo(), JSON.toJSONString(redisCommand)); // // if (!command.getComplete()) { // //上一条任务未完成,禁止下发命令 // return false; // } // } // // if (commands.size() == 0) { // return false; // } // // //取出命令 // ShuttleCommand command = commands.get(commandStep); // // if (assignCommand.getTaskMode() == ShuttleTaskModeType.PAK_IN.id.shortValue() // || assignCommand.getTaskMode() == ShuttleTaskModeType.PAK_OUT.id.shortValue() // ) { // //小车失去坐标,禁止下发命令 // if (shuttleProtocol.getCurrentCode() == 0) { // return false; // } // } // // // //判断小车当前二维码是否为提升机二维码 // if (shuttleProtocol.getCurrentCode().intValue() == liftProtocol.getBarcode().intValue()) { // //小车当前命令起始位置就是提升机二维码,说明小车需要向提升机外移动,则需要判断状态是否满足 // if (command.getStartCodeNum().intValue() == liftProtocol.getBarcode().intValue()){ // //提升机是否空闲,提升机是否到达目标楼层,目标楼层是否给出提升机到位信号位 // if (!liftProtocol.isIdleNoTask()) { // return false;//提升机忙,禁止下发命令 // } // if (liftProtocol.getTaskNo().intValue() != 0 && liftProtocol.getTaskNo().intValue() != wrkNo) { // //提升机工作号和当前工作不相同,禁止下发命令 // return false; // } // // Short distCodeNum = command.getDistCodeNum();//目标二维码 // BasDevpService basDevpService = SpringUtils.getBean(BasDevpService.class); // BasDevp basDevp = basDevpService.queryByQrCode(distCodeNum.intValue());//目标站点 // if (basDevp == null) { // return false;//找不到目标站,禁止下发命令 // } // // int lev = Utils.getLev(basDevp.getLocNo());//目标二维码所在楼层 // int liftLev = liftProtocol.getLev().intValue();//提升机所在楼层 // if (liftLev != lev) { // return false;//提升机不在目标楼层,禁止下发命令 // } // // //获取目标站信息 // SiemensDevpThread devpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, 1); // StaProtocol staProtocol = devpThread.getStation().get(basDevp.getDevNo()); // if (staProtocol == null) { // return false;//站点信息不存在,禁止下发命令 // } // if (!staProtocol.isLiftArrival()) { // return false;//站点提升机到位信号false,禁止下发命令 // } // // //条件满足,占用提升机 // liftProtocol.setTaskNo(wrkNo); // } // } // // //下发命令 // if (!write(command)) { // News.error("四向穿梭车命令下发失败,穿梭车号={},任务数据={}", shuttleProtocol.getShuttleNo(), JSON.toJSON(command)); // return false; // } else { // News.info("四向穿梭车命令下发成功,穿梭车号={},任务数据={}", shuttleProtocol.getShuttleNo(), JSON.toJSON(command)); // // //将标记置为false(防止重发) // shuttleProtocol.setPakMk(false); // // //保存数据到数据库做流水 // BasShuttleOptService shuttleOptService = SpringUtils.getBean(BasShuttleOptService.class); // if (shuttleOptService != null) { // short[] commandArr = getCommandArr(command);//获取命令报文 // BasShuttleOpt opt = new BasShuttleOpt( // assignCommand.getTaskNo().intValue(), // assignCommand.getShuttleNo().intValue(), // new Date(), // ShuttleTaskModeType.get(assignCommand.getTaskMode()).desc, // assignCommand.getSourceLocNo(), // assignCommand.getLocNo(), // null, // null, // null, // JSON.toJSONString(command), // JSON.toJSONString(commandArr) // ); // shuttleOptService.insert(opt); // } // // //判断数据是否执行完成 // if (commandStep < size - 1) { // //更新redis数据 // //步序增加 // commandStep++; // redisCommand.setCommandStep(commandStep); // //任务数据保存到redis // redisUtil.set("shuttle_wrk_no_" + redisCommand.getWrkNo(), JSON.toJSONString(redisCommand)); // }else { // //已执行完成 // // if (redisCommand.getLiftSecurityMk()) { // //曾锁定过提升机,需要进行解锁 // if (liftProtocol != null) { // liftProtocol.setSecurityMk(false); // } // } // // String locNo = shuttleProtocol.getLocNo() == null ? shuttleProtocol.getSourceLocNo() : shuttleProtocol.getLocNo(); // if (locNo != null) { // //解除锁定的库位路径 // NavigateMapData navigateMapData = new NavigateMapData(Utils.getLev(locNo)); // navigateMapData.writeNavigateNodeToRedisMap(redisCommand.getAssignCommand().getNodes(), false); // } // // //删除redis // redisUtil.del("shuttle_wrk_no_" + redisCommand.getWrkNo()); // // if (!assignCommand.getAuto()) { // //手动模式不抛出等待状态,直接复位 // //设置四向穿梭车为空闲状态 // shuttleProtocol.setProtocolStatus(ShuttleProtocolStatusType.IDLE); // //任务号清零 // shuttleProtocol.setTaskNo((short) 0); // //标记复位 // shuttleProtocol.setPakMk(true); // News.info("四向穿梭车手动任务执行完成,穿梭车号={},任务数据={}", shuttleProtocol.getShuttleNo(), JSON.toJSON(command)); // }else { // if (!assignCommand.getCharge()) { // //对主线程抛出等待确认状态waiting // shuttleProtocol.setProtocolStatus(ShuttleProtocolStatusType.WAITING); // }else { // shuttleProtocol.setProtocolStatus(ShuttleProtocolStatusType.CHARGING_WAITING); // } // News.info("四向穿梭车任务执行下发完成等待执行结束,穿梭车号={},任务数据={}", shuttleProtocol.getShuttleNo(), JSON.toJSON(command)); // } // // } // // } return true; } } src/main/java/com/zy/core/thread/ShuttleThread.java
@@ -190,61 +190,61 @@ shuttleProtocol.setPakMk(true); } //将四向穿梭车状态保存至数据库 BasShuttleService shuttleService = SpringUtils.getBean(BasShuttleService.class); BasShuttle basShuttle = shuttleService.selectById(slave.getId()); if (basShuttle == null) { basShuttle = new BasShuttle(); //四向穿梭车号 basShuttle.setShuttleNo(slave.getId()); shuttleService.insert(basShuttle); } //小车忙状态位 basShuttle.setBusyStatus(shuttleProtocol.getBusyStatus().intValue()); //当前二维码 basShuttle.setCurrentCode(shuttleProtocol.getCurrentCode().intValue()); //电池电量百分比 basShuttle.setBatteryPower(shuttleProtocol.getBatteryPower().intValue()); //电池温度 basShuttle.setBatteryTemp(shuttleProtocol.getBatteryTemp().intValue()); //错误编号 basShuttle.setErrorCode(shuttleProtocol.getErrorCode().intValue()); //Plc输出状态IO basShuttle.setPlcOutputStatusIo(shuttleProtocol.getPlcOutputStatusIO().intValue()); //错误信息码 basShuttle.setStatusErrorCode(shuttleProtocol.getStatusErrorCode().intValue()); //PLC输入状态 basShuttle.setPlcInputStatus(shuttleProtocol.getPlcInputStatus().intValue()); //当前或者之前读到的二维码值 basShuttle.setCurrentOrBeforeCode(shuttleProtocol.getCurrentOrBeforeCode().intValue()); //读到的二维码X方向偏移量 basShuttle.setCodeOffsetX(shuttleProtocol.getCodeOffsetX().intValue()); //读到的二维码Y方向偏移量 basShuttle.setCodeOffsetY(shuttleProtocol.getCodeOffsetY().intValue()); //当前的电压值 basShuttle.setCurrentVoltage(shuttleProtocol.getCurrentVoltage().intValue()); //当前的模拟量值 basShuttle.setCurrentAnalogValue(shuttleProtocol.getCurrentAnalogValue().intValue()); //当前的升降伺服速度 basShuttle.setCurrentLiftServoSpeed(shuttleProtocol.getCurrentLiftServoSpeed().intValue()); //当前的行走伺服速度 basShuttle.setCurrentMoveServoSpeed(shuttleProtocol.getCurrentMoveServoSpeed().intValue()); //当前的升降伺服负载率 basShuttle.setCurrentLiftServoLoad(shuttleProtocol.getCurrentLiftServoLoad().intValue()); //当前的行走伺服负载率 basShuttle.setCurrentMoveServoLoad(shuttleProtocol.getCurrentMoveServoLoad().intValue()); //当前小车状态(内部自我维护) basShuttle.setShuttleStatus(shuttleProtocol.getProtocolStatus()); //任务号 basShuttle.setWrkNo(shuttleProtocol.getTaskNo().intValue()); //修改时间 basShuttle.setUpdateTime(new Date()); //作业标记 basShuttle.setPakMk(shuttleProtocol.getPakMk()); if (shuttleService.updateById(basShuttle)) { OutputQueue.SHUTTLE.offer(MessageFormat.format("【{0}】[id:{1}] <<<<< 实时数据更新成功",DateUtils.convert(new Date()), slave.getId())); // log.info(MessageFormat.format("【{0}】[id:{1}] <<<<< 实时数据更新成功",DateUtils.convert(new Date()), slave.getId())); } // //将四向穿梭车状态保存至数据库 // BasShuttleService shuttleService = SpringUtils.getBean(BasShuttleService.class); // BasShuttle basShuttle = shuttleService.selectById(slave.getId()); // if (basShuttle == null) { // basShuttle = new BasShuttle(); // //四向穿梭车号 // basShuttle.setShuttleNo(slave.getId()); // shuttleService.insert(basShuttle); // } // //小车忙状态位 // basShuttle.setBusyStatus(shuttleProtocol.getBusyStatus().intValue()); // //当前二维码 // basShuttle.setCurrentCode(shuttleProtocol.getCurrentCode().intValue()); // //电池电量百分比 // basShuttle.setBatteryPower(shuttleProtocol.getBatteryPower().intValue()); // //电池温度 // basShuttle.setBatteryTemp(shuttleProtocol.getBatteryTemp().intValue()); // //错误编号 // basShuttle.setErrorCode(shuttleProtocol.getErrorCode().intValue()); // //Plc输出状态IO // basShuttle.setPlcOutputStatusIo(shuttleProtocol.getPlcOutputStatusIO().intValue()); // //错误信息码 // basShuttle.setStatusErrorCode(shuttleProtocol.getStatusErrorCode().intValue()); // //PLC输入状态 // basShuttle.setPlcInputStatus(shuttleProtocol.getPlcInputStatus().intValue()); // //当前或者之前读到的二维码值 // basShuttle.setCurrentOrBeforeCode(shuttleProtocol.getCurrentOrBeforeCode().intValue()); // //读到的二维码X方向偏移量 // basShuttle.setCodeOffsetX(shuttleProtocol.getCodeOffsetX().intValue()); // //读到的二维码Y方向偏移量 // basShuttle.setCodeOffsetY(shuttleProtocol.getCodeOffsetY().intValue()); // //当前的电压值 // basShuttle.setCurrentVoltage(shuttleProtocol.getCurrentVoltage().intValue()); // //当前的模拟量值 // basShuttle.setCurrentAnalogValue(shuttleProtocol.getCurrentAnalogValue().intValue()); // //当前的升降伺服速度 // basShuttle.setCurrentLiftServoSpeed(shuttleProtocol.getCurrentLiftServoSpeed().intValue()); // //当前的行走伺服速度 // basShuttle.setCurrentMoveServoSpeed(shuttleProtocol.getCurrentMoveServoSpeed().intValue()); // //当前的升降伺服负载率 // basShuttle.setCurrentLiftServoLoad(shuttleProtocol.getCurrentLiftServoLoad().intValue()); // //当前的行走伺服负载率 // basShuttle.setCurrentMoveServoLoad(shuttleProtocol.getCurrentMoveServoLoad().intValue()); // //当前小车状态(内部自我维护) // basShuttle.setShuttleStatus(shuttleProtocol.getProtocolStatus()); // //任务号 // basShuttle.setWrkNo(shuttleProtocol.getTaskNo().intValue()); // //修改时间 // basShuttle.setUpdateTime(new Date()); // //作业标记 // basShuttle.setPakMk(shuttleProtocol.getPakMk()); // if (shuttleService.updateById(basShuttle)) { // OutputQueue.SHUTTLE.offer(MessageFormat.format("【{0}】[id:{1}] <<<<< 实时数据更新成功",DateUtils.convert(new Date()), slave.getId())); //// log.info(MessageFormat.format("【{0}】[id:{1}] <<<<< 实时数据更新成功",DateUtils.convert(new Date()), slave.getId())); // } }else { OutputQueue.SHUTTLE.offer(MessageFormat.format("【{0}】{1}四向穿梭车plc状态信息失败", DateUtils.convert(new Date()), slave.getId())); @@ -414,12 +414,12 @@ //获取小车移动速度 BasShuttle basShuttle = shuttleService.selectById(slave.getId()); Integer runSpeed = 1000; if (basShuttle != null) { Integer runSpeed1 = basShuttle.getRunSpeed(); if (runSpeed1 != null) { runSpeed = runSpeed1; } } // if (basShuttle != null) { // Integer runSpeed1 = basShuttle.getRunSpeed(); // if (runSpeed1 != null) { // runSpeed = runSpeed1; // } // } LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, 1); LiftProtocol liftProtocol = liftThread.getLiftProtocol(); src/main/resources/mapper/BasShuttleMapper.xml
@@ -18,23 +18,47 @@ <result column="memo" property="memo" /> <result column="lift_no" property="liftNo" /> <result column="pak_mk" property="pakMk" /> <result column="busy_status" property="busyStatus" /> <result column="current_code" property="currentCode" /> <result column="battery_power" property="batteryPower" /> <result column="battery_temp" property="batteryTemp" /> <result column="error_code" property="errorCode" /> <result column="plc_output_status_io" property="plcOutputStatusIo" /> <result column="status_error_code" property="statusErrorCode" /> <result column="plc_input_status" property="plcInputStatus" /> <result column="current_or_before_code" property="currentOrBeforeCode" /> <result column="code_offset_x" property="codeOffsetX" /> <result column="code_offset_y" property="codeOffsetY" /> <result column="current_voltage" property="currentVoltage" /> <result column="current_analog_value" property="currentAnalogValue" /> <result column="current_lift_servo_speed" property="currentLiftServoSpeed" /> <result column="current_move_servo_speed" property="currentMoveServoSpeed" /> <result column="current_lift_servo_load" property="currentLiftServoLoad" /> <result column="current_move_servo_load" property="currentMoveServoLoad" /> <!-- <result column="busy_status" property="busyStatus" />--> <!-- <result column="current_code" property="currentCode" />--> <!-- <result column="battery_power" property="batteryPower" />--> <!-- <result column="battery_temp" property="batteryTemp" />--> <!-- <result column="error_code" property="errorCode" />--> <!-- <result column="plc_output_status_io" property="plcOutputStatusIo" />--> <!-- <result column="status_error_code" property="statusErrorCode" />--> <!-- <result column="plc_input_status" property="plcInputStatus" />--> <!-- <result column="current_or_before_code" property="currentOrBeforeCode" />--> <!-- <result column="code_offset_x" property="codeOffsetX" />--> <!-- <result column="code_offset_y" property="codeOffsetY" />--> <!-- <result column="current_voltage" property="currentVoltage" />--> <!-- <result column="current_analog_value" property="currentAnalogValue" />--> <!-- <result column="current_lift_servo_speed" property="currentLiftServoSpeed" />--> <!-- <result column="current_move_servo_speed" property="currentMoveServoSpeed" />--> <!-- <result column="current_lift_servo_load" property="currentLiftServoLoad" />--> <!-- <result column="current_move_servo_load" property="currentMoveServoLoad" />--> <result column="working_mode" property="workingMode" /> <result column="free" property="free" /> <result column="speed" property="speed" /> <result column="load_state" property="loadState" /> <result column="suspend_state" property="suspendState" /> <result column="lift_position" property="liftPosition" /> <result column="run_dir" property="runDir" /> <result column="run_dir2" property="runDir2" /> <result column="charg_state" property="chargState" /> <result column="power_percent" property="powerPercent" /> <result column="max_cell_voltage" property="maxCellVoltage" /> <result column="min_cell_voltage" property="minCellVoltage" /> <result column="voltage" property="voltage" /> <result column="charge_cycle_times" property="chargeCycleTimes" /> <result column="surplus_quantity" property="surplusQuantity" /> <result column="count_quantity" property="countQuantity" /> <result column="point" property="point" /> <result column="coord" property="coord" /> <result column="task" property="task" /> <result column="task_state" property="taskState" /> <result column="err_state" property="errState" /> <result column="status_sum" property="statusSum" /> <result column="err_time" property="errTime" /> </resultMap> src/main/webapp/static/readStatus.json
New file @@ -0,0 +1,58 @@ { "msgType": "responseMsg", "robotId": 50001, "response": { "header": { "responseId": 1234, "version": "1.0" }, "body": { "responseType": "state", "workingMode": 1, "free": 1, "speed": 1000, "loadState": 1, "suspendState": 0, "liftPosition": 1, "runDir": 1, "runDir2": 1, "chargState": 0, "powerPercent": 0, "maxCellVoltage": 4165, "minCellVoltage": 4147, "voltage": 5405, "chargeCycleTimes": 0, "surplusQuantity": 450, "countQuantity": 500, "point": { "x": 1, "y": 2, "z": 1 }, "coord": { "x": 1000, "y": 2000, "z": 1 }, "task": { "x": 1, "y": 2, "z": 1, "taskState": 0, "taskId": 0, "lastTaskId": 0, "recentTaskId": 0 }, "errState": 1, "errCode": [0, 0, 0, 0, 0], "statusSum": { "mileage": 0, "liftNumber": 0, "dropNumber": 0, "reversingX": 0, "reversingY": 0 }, "errTime": 68391 } } } src/main/webapp/views/shuttle.html
@@ -35,21 +35,17 @@ <th>四向穿梭车</th> <th>任务状态</th> <th>小车状态</th> <th>当前二维码</th> <th>实际库位</th> <th>实际坐标</th> <th>电量</th> <th>电池温度</th> <th>错误编号</th> <th>plc输出状态IO-顶升位</th> <th>plc输出状态IO-换向位</th> <th>plc输出状态IO-抱闸位</th> <th>plc输出状态IO-充电位</th> <th>错误信息码</th> <th>plc输入状态(光电有物)</th> <th>当前或之前二维码</th> <th>x偏移量</th> <th>y偏移量</th> <th>电压</th> <th>模拟量</th> <th>当前速度</th> <th>负载状态</th> <th>顶升位置</th> <th>运行方向</th> <th>运行方向2</th> <th>充电状态</th> <th>故障状态</th> <th>故障码</th> </tr> </thead> <tbody> @@ -64,16 +60,16 @@ <tr> <th>四向穿梭车</th> <th>工作号</th> <th>状态</th> <th>源库位</th> <th>目标库位</th> <th>升降伺服速度</th> <th>行走伺服速度</th> <th>升降伺服负载</th> <th>行走伺服负载</th> <th>最高电芯电压</th> <th>最低电芯电压</th> <th>电池电压</th> <th>充放电循环次数</th> <th>剩余电量</th> <th>总电量</th> <th>总里程数</th> <th>作业标记</th> <th>库位号</th> <th>当前楼层</th> </tr> </thead> <tbody> @@ -274,7 +270,7 @@ pakMk: $('#pakMk').val(), }, function (res) { layer.msg("修改成功", {icon: 1,}); layer.close(layerIdx); layer.close(layerDetl); }) }) @@ -331,23 +327,19 @@ // $("#mode-"+table[i-1].shuttleNo).html(table[i-1].statusVal===0?'联机':'脱机'); let tr = tableEl.find("tr").eq(i); setVal(tr.children("td").eq(0), table[i-1].shuttleNo); setVal(tr.children("td").eq(1), table[i-1].status$); setVal(tr.children("td").eq(2), table[i-1].busyStatus); setVal(tr.children("td").eq(3), table[i-1].currentCode); setVal(tr.children("td").eq(4), table[i-1].batteryPower); setVal(tr.children("td").eq(5), table[i-1].batteryTemp); setVal(tr.children("td").eq(6), table[i-1].errorCode); setVal(tr.children("td").eq(7), table[i-1].plcOutputLift$);//顶升位 setVal(tr.children("td").eq(8), table[i-1].plcOutputTransfer$);//换向位 setVal(tr.children("td").eq(9), table[i-1].plcOutputBrake$);//抱闸位 setVal(tr.children("td").eq(10), table[i-1].plcOutputCharge$);//充电位 setVal(tr.children("td").eq(11), table[i-1].statusErrorCode); setVal(tr.children("td").eq(12), table[i-1].plcInputStatus); setVal(tr.children("td").eq(13), table[i-1].currentOrBeforeCode); setVal(tr.children("td").eq(14), table[i-1].codeOffsetX); setVal(tr.children("td").eq(15), table[i-1].codeOffsetY); setVal(tr.children("td").eq(16), table[i-1].currentVoltage$); setVal(tr.children("td").eq(17), table[i-1].currentAnalogValue); setVal(tr.children("td").eq(1), table[i-1].protocolStatus$); setVal(tr.children("td").eq(2), table[i-1].free$); setVal(tr.children("td").eq(3), table[i-1].point$); setVal(tr.children("td").eq(4), table[i-1].coord$); setVal(tr.children("td").eq(5), table[i-1].powerPercent$); setVal(tr.children("td").eq(6), table[i-1].speed); setVal(tr.children("td").eq(7), table[i-1].loadState$); setVal(tr.children("td").eq(8), table[i-1].liftPosition$); setVal(tr.children("td").eq(9), table[i-1].runDir$); setVal(tr.children("td").eq(10), table[i-1].runDir2$); setVal(tr.children("td").eq(11), table[i-1].chargState$); setVal(tr.children("td").eq(12), table[i-1].errState$); setVal(tr.children("td").eq(13), table[i-1].errCode); } } else if (res.code === 403){ window.location.href = baseUrl+"/login"; @@ -362,7 +354,7 @@ function getShuttleMsgInfo() { let tableEl = $('#shuttle-msg-table'); $.ajax({ url: baseUrl+ "/shuttle/table/shuttle/msg", url: baseUrl+ "/shuttle/table/shuttle/state", headers: {'token': localStorage.getItem('token')}, method: 'POST', success: function (res) { @@ -375,18 +367,17 @@ for (var i=1;i<=table.length;i++){ var tr = tableEl.find("tr").eq(i); setVal(tr.children("td").eq(0), table[i-1].shuttleNo); setVal(tr.children("td").eq(1), table[i-1].workNo); setVal(tr.children("td").eq(2), table[i-1].status); setVal(tr.children("td").eq(3), table[i-1].sourceLocNo); setVal(tr.children("td").eq(4), table[i-1].distLocNo); setVal(tr.children("td").eq(5), table[i-1].currentLiftServoSpeed); setVal(tr.children("td").eq(6), table[i-1].currentMoveServoSpeed); setVal(tr.children("td").eq(7), table[i-1].currentLiftServoLoad); setVal(tr.children("td").eq(8), table[i-1].currentMoveServoLoad); setVal(tr.children("td").eq(9), table[i-1].pakMk); setVal(tr.children("td").eq(10), table[i-1].locNo); setVal(tr.children("td").eq(11), table[i-1].lev); setVal(tr.children("td").eq(1), table[i-1].taskNo); setVal(tr.children("td").eq(2), table[i-1].sourceLocNo); setVal(tr.children("td").eq(3), table[i-1].locNo); setVal(tr.children("td").eq(4), table[i-1].maxCellVoltage$); setVal(tr.children("td").eq(5), table[i-1].minCellVoltage$); setVal(tr.children("td").eq(6), table[i-1].voltage$); setVal(tr.children("td").eq(7), table[i-1].chargeCycleTimes); setVal(tr.children("td").eq(8), table[i-1].surplusQuantity); setVal(tr.children("td").eq(9), table[i-1].countQuantity); setVal(tr.children("td").eq(10), table[i-1].statusSum.mileage); setVal(tr.children("td").eq(11), table[i-1].pakMk$); if (table[i-1].shuttleNo == parseInt($('input[name="shuttleSelect"]:checked').val())) { $("#runSpeedText").text(table[i-1].runSpeed) $("#chargeLineText").text(table[i-1].chargeLine + "%") @@ -554,7 +545,7 @@ content: $("#shuttle-detl"), success: function(layero, index){ $.ajax({ url: baseUrl+ "/shuttle/table/shuttle/msg", url: baseUrl+ "/shuttle/table/shuttle/state", headers: {'token': localStorage.getItem('token')}, method: 'POST', success: function (res) { @@ -563,8 +554,8 @@ for (var i=1;i<=table.length;i++){ if (shuttleNo == table[i-1].shuttleNo) { $('#shuttleNo').val(shuttleNo); $('#workNo').val(table[i-1].workNo); $('#pakMk').val(table[i-1].pakMk); $('#workNo').val(table[i-1].taskNo); $('#pakMk').val(table[i-1].pakMk$); } } } else if (res.code === 403){ src/main/webapp/views/shuttle_zs.html
New file @@ -0,0 +1,595 @@ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>四向穿梭车监控管理</title> <link rel="stylesheet" type="text/css" href="../static/css/normalize.css"> <link rel="stylesheet" type="text/css" href="../static/css/common.css"> <link rel="stylesheet" type="text/css" href="../static/layui/css/layui.css"> <link rel="stylesheet" href="../static/css/shuttle.css"> <script type="text/javascript" src="../static/js/jquery/jquery-3.3.1.min.js"></script> <script type="text/javascript" src="../static/js/layer/layer.js"></script> <script type="text/javascript" src="../static/layui/layui.js"></script> <script type="text/javascript" src="../static/js/common.js"></script> </head> <body> <div style="padding: 10px;height: 100%;float: left;width: 6%"> <div class="button-window"></div> </div> <div style="height: 100%;padding-left: 6%"> <div style="padding: 10px;height: 100%"> <!-- 日志监控板 --> <div class="log-board"> <div class="command-log" id="commandLogId" style="width: 5%;"> <!-- <div data-shuttleNo="1" class="shuttle-command-item">--> <!-- <label>1#</label>--> <!-- <button class="demoBtn pos-btn">数据维护</button>--> <!-- <button id="mode-1" class="demoBtn mode-btn" >设备信息</button>--> <!-- </div>--> </div> <!-- 堆垛机状态位信息 --> <div class="shuttle-state" style="width: 95%;"> <table id="shuttle-state-table"> <thead> <tr> <th>四向穿梭车</th> <th>任务状态</th> <th>小车状态</th> <th>当前二维码</th> <th>电量</th> <th>电池温度</th> <th>错误编号</th> <th>plc输出状态IO-顶升位</th> <th>plc输出状态IO-换向位</th> <th>plc输出状态IO-抱闸位</th> <th>plc输出状态IO-充电位</th> <th>错误信息码</th> <th>plc输入状态(光电有物)</th> <th>当前或之前二维码</th> <th>x偏移量</th> <th>y偏移量</th> <th>电压</th> <th>模拟量</th> </tr> </thead> <tbody> </tbody> </table> </div> </div> <!-- 穿梭车状态 --> <div class="shuttle-msg"> <table id="shuttle-msg-table"> <thead> <tr> <th>四向穿梭车</th> <th>工作号</th> <th>状态</th> <th>源库位</th> <th>目标库位</th> <th>升降伺服速度</th> <th>行走伺服速度</th> <th>升降伺服负载</th> <th>行走伺服负载</th> <th>作业标记</th> <th>库位号</th> <th>当前楼层</th> </tr> </thead> <tbody> </tbody> </table> </div> <!-- 手动操作 --> <div class="shuttle-operation"> <!-- 遮罩层 --> <div class="shuttle-operation-shade"> <span class="shuttle-operation-shade-span"> WCS 系统运行中,请停止后操作 </span> </div> <!-- 设备任务选择 --> <div class="task-select"> <!-- 选择 --> <div id="shuttle-select" class="operator-item"> <span class="select-title">四向穿梭车号</span> <div class="select-container" id="shuttleRadioBoxId"> <!-- <label><input type="radio" name="shuttleSelect" value="1" checked> 1号穿梭车</label>--> </div> </div> </div> <!-- 设备任务操作 --> <div class="task-operator"> <fieldset style="height: auto;padding-bottom: 20px;"> <legend>手动操作</legend> <div style="display: flex;"> <div style="width: 30%;"> <div class="operator-item" style="height: auto;width: 100%;"> <span class="select-title">源库位/目标库位</span> <div class="select-container" style="height: auto;padding: 30px 10px 20px 10px;"> <div class="select-container-item"> <span>源库位</span> <label><input id="sourceLocNo" type="text" name="sourceLocNo" /></label> </div> <div class="select-container-item"> <span>目标库位</span> <label><input id="distLocNo" type="text" name="distLocNo" /></label> </div> <div style="margin-top: 10px;"> <button class="item" onclick="shuttleOperator(1)">入库</button> <button class="item" onclick="shuttleOperator(2)">出库</button> <button class="item" onclick="shuttleOperator(14)">移动到目标库位</button> <button class="item" onclick="shuttleOperator(16)">移动到提升机</button> </div> </div> </div> </div> <div style="width: 40%;"> <div class="operator-item" style="height: auto;width: 100%;"> <span class="select-title">相关指令</span> <div class="select-container" style="height: auto;padding: 30px 10px 10px 10px;"> <div class="button-group"> <button class="item" onclick="shuttleOperator(3)">托盘顶升</button> <button class="item" onclick="shuttleOperator(4)">托盘下降</button> <button class="item" onclick="shuttleOperator(5)">左移</button> <button class="item" onclick="shuttleOperator(6)">右移</button> <button class="item" onclick="shuttleOperator(7)">后移</button> <button class="item" onclick="shuttleOperator(8)">前移</button> <button class="item" onclick="shuttleOperator(9)">复位</button> <button class="item" onclick="shuttleOperator(10)">正方向(右)寻库位</button> <button class="item" onclick="shuttleOperator(11)">负方向(左)寻库位</button> <button class="item" onclick="shuttleOperator(12)">正方向(前)寻库位</button> <button class="item" onclick="shuttleOperator(13)">负方向(后)寻库位</button> <button class="item" onclick="shuttleOperator(15)">充电开关</button> </div> </div> </div> </div> <div style="width: 20%;"> <div class="operator-item" style="height: auto;width: 100%;"> <span class="select-title">设置配置参数</span> <div class="select-container" style="height: auto;padding: 30px 10px 10px 10px;"> <div class="select-container-item"> <span>运行速度</span> <label><input id="runSpeed" type="text" name="runSpeed" /></label> </div> <div class="select-container-item"> <span>充电阈值</span> <label><input id="chargeLine" type="text" name="runSpeed" /></label> </div> <div> <button class="item" onclick="shuttleParamSave()">保存</button> </div> </div> </div> </div> <div style="width: 15%;"> <div class="operator-item" style="height: auto;width: 100%;"> <span class="select-title">配置参数</span> <div class="select-container" style="height: auto;padding: 30px 10px 10px 10px;"> <div>运行速度:<span id="runSpeedText"></span></div> <div>充电阈值:<span id="chargeLineText"></span></div> </div> </div> </div> </div> </fieldset> </div> </div> <!-- 穿梭车日志输出 --> <div class="shuttle-output-board"> <textarea id="shuttle-output"></textarea> </div> </div> </div> <div id="shuttle-detl" style="display: none"> <div> <div class="form-item"> <label class="form-label">穿梭车号:</label> <div class="form-input"> <input id="shuttleNo" name="shuttleNo" class="layui-input" lay-verify="required|number" autocomplete="off" disabled="disabled"> </div> </div> <div class="form-item"> <label class="form-label">工作号:</label> <div class="form-input"> <input id="workNo" name="workNo" type="number" class="layui-input" lay-verify="number" autocomplete="off"> </div> </div> <div class="form-item"> <label class="form-label">作业标记:</label> <div class="form-input"> <input id="pakMk" name="pakMk" type="text" class="layui-input" autocomplete="off"> </div> </div> <div class="form-item form-button-container"> <button class="form-button" id="save">保存</button> <button class="form-button" id="cancel" style="background-color: #D0D0D0">取消</button> </div> </div> </div> </body> </html> <script> // 空白行数 var shuttleStateTableBlankRows = 0; var shuttleMsgTableBlankRows = 0; // 实际行数 var shuttleStateTableFullRows = 0; var shuttleMsgTableFullRows = 0; // 初始化 var shuttleOutputDom = document.getElementById("shuttle-output"); $(document).ready(function() { initShuttleStateTable(); getShuttleStateInfo(); initShuttleMsgTable(); getShuttleMsgInfo(); operatorBlockShow(); setShuttleRadio(); }); setInterval(function () { getShuttleStateInfo() getShuttleMsgInfo(); },1000) setInterval(function () { getShuttleOutput(); operatorBlockShow(); },500); // 判断手动操作模块是否可用 function operatorBlockShow() { if (parent.systemRunning) { $('.shuttle-operation').css("opacity", "0.5"); $('.shuttle-operation-shade').show(); $('.shuttle-operation-shade-span').show(); } else { $('.shuttle-operation').css("opacity", "1"); $('.shuttle-operation-shade').hide(); $('.shuttle-operation-shade-span').hide(); } } function getColor(res,e){ $(e).val(res?"✔":"—"); if (res){ $(e).attr("style", "color: #FD482C;"); }else { $(e).attr("style", "color: #00FF00;"); } } $(document).on('click ','#save', function () { http.post(baseUrl+ "/shuttle/detl/update", { shuttleNo: $('#shuttleNo').val(), workNo: $('#workNo').val(), pakMk: $('#pakMk').val(), }, function (res) { layer.msg("修改成功", {icon: 1,}); layer.close(layerIdx); }) }) function setShuttleRadio() { $.ajax({ url: baseUrl+ "/shuttle/table/shuttle/state", headers: {'token': localStorage.getItem('token')}, method: 'POST', success: function (res) { if (res.code === 200){ let table = res.data; for (let i=1;i<=table.length;i++){ //渲染四向穿梭车选项html let shuttleRadioBox = '<label><input type="radio" name="shuttleSelect" '; if (i === 1) { shuttleRadioBox += 'checked ' } shuttleRadioBox += 'value="' + table[i - 1].shuttleNo + '"> ' + table[i - 1].shuttleNo + '号穿梭车</label>' $("#shuttleRadioBoxId").append(shuttleRadioBox) //渲染四向穿梭车数据维护和设备信息html let shuttleCommandLogBox = '<div class="shuttle-command-item" data-shuttleNo="' + table[i - 1].shuttleNo + '">\n' + '<label>' + table[i - 1].shuttleNo + '#</label>\n' + // '<button class="demoBtn pos-btn">数据维护</button>\n' + // '<button class="demoBtn mode-btn" id="mode-' + table[i - 1].shuttleNo + '">设备信息</button>\n' + '</div>' $("#commandLogId").append(shuttleCommandLogBox); } } else if (res.code === 403){ window.location.href = baseUrl+"/login"; } else { console.log(res.msg); } } }); } // 四向穿梭车信息表获取 ---- 表一 function getShuttleStateInfo() { let tableEl = $('#shuttle-state-table'); $.ajax({ url: baseUrl+ "/shuttle/table/shuttle/state", headers: {'token': localStorage.getItem('token')}, method: 'POST', success: function (res) { if (res.code === 200){ let table = res.data; if (table.length > shuttleStateTableBlankRows && table.length !== shuttleStateTableFullRows) { initShuttleStateTable(table.length-shuttleStateTableBlankRows); shuttleStateTableFullRows = table.length; } for (let i=1;i<=table.length;i++){ // $("#mode-"+table[i-1].shuttleNo).html(table[i-1].statusVal===0?'联机':'脱机'); let tr = tableEl.find("tr").eq(i); setVal(tr.children("td").eq(0), table[i-1].shuttleNo); setVal(tr.children("td").eq(1), table[i-1].status$); setVal(tr.children("td").eq(2), table[i-1].busyStatus); setVal(tr.children("td").eq(3), table[i-1].currentCode); setVal(tr.children("td").eq(4), table[i-1].batteryPower); setVal(tr.children("td").eq(5), table[i-1].batteryTemp); setVal(tr.children("td").eq(6), table[i-1].errorCode); setVal(tr.children("td").eq(7), table[i-1].plcOutputLift$);//顶升位 setVal(tr.children("td").eq(8), table[i-1].plcOutputTransfer$);//换向位 setVal(tr.children("td").eq(9), table[i-1].plcOutputBrake$);//抱闸位 setVal(tr.children("td").eq(10), table[i-1].plcOutputCharge$);//充电位 setVal(tr.children("td").eq(11), table[i-1].statusErrorCode); setVal(tr.children("td").eq(12), table[i-1].plcInputStatus); setVal(tr.children("td").eq(13), table[i-1].currentOrBeforeCode); setVal(tr.children("td").eq(14), table[i-1].codeOffsetX); setVal(tr.children("td").eq(15), table[i-1].codeOffsetY); setVal(tr.children("td").eq(16), table[i-1].currentVoltage$); setVal(tr.children("td").eq(17), table[i-1].currentAnalogValue); } } else if (res.code === 403){ window.location.href = baseUrl+"/login"; } else { console.log(res.msg); } } }); } // 四向穿梭车数据表获取 ---- 表二 function getShuttleMsgInfo() { let tableEl = $('#shuttle-msg-table'); $.ajax({ url: baseUrl+ "/shuttle/table/shuttle/msg", headers: {'token': localStorage.getItem('token')}, method: 'POST', success: function (res) { if (res.code === 200){ var table = res.data; if (table.length > shuttleMsgTableBlankRows && table.length !== shuttleMsgTableFullRows) { initShuttleMsgTable(table.length-shuttleMsgTableBlankRows); shuttleMsgTableFullRows = table.length; } for (var i=1;i<=table.length;i++){ var tr = tableEl.find("tr").eq(i); setVal(tr.children("td").eq(0), table[i-1].shuttleNo); setVal(tr.children("td").eq(1), table[i-1].workNo); setVal(tr.children("td").eq(2), table[i-1].status); setVal(tr.children("td").eq(3), table[i-1].sourceLocNo); setVal(tr.children("td").eq(4), table[i-1].distLocNo); setVal(tr.children("td").eq(5), table[i-1].currentLiftServoSpeed); setVal(tr.children("td").eq(6), table[i-1].currentMoveServoSpeed); setVal(tr.children("td").eq(7), table[i-1].currentLiftServoLoad); setVal(tr.children("td").eq(8), table[i-1].currentMoveServoLoad); setVal(tr.children("td").eq(9), table[i-1].pakMk); setVal(tr.children("td").eq(10), table[i-1].locNo); setVal(tr.children("td").eq(11), table[i-1].lev); if (table[i-1].shuttleNo == parseInt($('input[name="shuttleSelect"]:checked').val())) { $("#runSpeedText").text(table[i-1].runSpeed) $("#chargeLineText").text(table[i-1].chargeLine + "%") } } } else if (res.code === 403){ window.location.href = baseUrl+"/login"; } else { console.log(res.msg); } } }); } // 穿梭车日志输出 ----------------------------------------------------------------------- function getShuttleOutput() { $.ajax({ url: baseUrl + "/shuttle/output/shuttle", headers: {'token': localStorage.getItem('token')}, method: 'POST', success: function (res) { if (res.code === 200) { shuttleOutput(res.data); } else if (res.code === 403) { window.location.href = baseUrl + "/login"; } else { console.log(res.msg); } } }) } // 任务指令下发 function shuttleOperator(shuttleTaskMode) { http.post(baseUrl+"/shuttle/operator/shuttle", { shuttleNo: $('input[name="shuttleSelect"]:checked').val(), shuttleTaskMode: shuttleTaskMode, sourceLocNo: $("#sourceLocNo").val(), distLocNo: $("#distLocNo").val() }, function (res) { layer.msg(res.msg, {icon: 1}); }); } // ------------------------------------------------------------------------------------------------ // 四向穿梭车信息表获取 ----- 表一 function initShuttleStateTable(row) { let line; if (row === undefined){ let one = $('#shuttle-state-table thead').height(); let total = $('.shuttle-state').height(); let count = total / one; count = parseInt(count) - 1; shuttleStateTableBlankRows = count; line = count; } else { line = row; } let html = ""; for (let i = 0; i < line; i ++){ html += " <tr>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " </tr>\n"; } $('#shuttle-state-table tbody').after(html); } // 穿梭车数据表获取 ----- 表二 function initShuttleMsgTable(row) { let line; if (row === undefined){ let one = $('#shuttle-msg-table thead').height(); let total = $('.shuttle-msg').height(); let count = total / one; count = parseInt(count) - 1; shuttleMsgTableBlankRows = count; line = count; } else { line = row; } let html = ""; for (let i = 0; i < line; i ++){ html += " <tr>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " </tr>\n"; } $('#shuttle-msg-table tbody').after(html); } // 日志输出框 function shuttleOutput(content){ shuttleOutputDom.value += content; shuttleOutputDom.scrollTop = shuttleOutputDom.scrollHeight; } //四向穿梭车配置参数保存 function shuttleParamSave() { $.ajax({ url: baseUrl+ "/shuttle/runSpeed/" + $('input[name="shuttleSelect"]:checked').val(), headers: {'token': localStorage.getItem('token')}, method: 'POST', data: { runSpeed: $("#runSpeed").val(), chargeLine: $("#chargeLine").val(), }, success: function (res) { if (res.code === 200){ layer.msg("配置已保存", {icon: 1,}); } else if (res.code === 403){ window.location.href = baseUrl+"/login"; } else { console.log(res.msg); } } }); } // 详情操作 ------------------------------------------------------------------------- var layerDetl; $(document).on('dblclick ','#shuttle-msg-table tr', function () { var shuttleNo = $(this).children("td").eq(0).html(); if (shuttleNo !== null && shuttleNo !== "") { layerDetl = layer.open({ type: 1, title: false, shadeClose: true, offset: 'rt', anim: 5, shade: [0], area: ['340px', '255px'], closeBtn: 0, content: $("#shuttle-detl"), success: function(layero, index){ $.ajax({ url: baseUrl+ "/shuttle/table/shuttle/msg", headers: {'token': localStorage.getItem('token')}, method: 'POST', success: function (res) { if (res.code === 200){ var table = res.data; for (var i=1;i<=table.length;i++){ if (shuttleNo == table[i-1].shuttleNo) { $('#shuttleNo').val(shuttleNo); $('#workNo').val(table[i-1].workNo); $('#pakMk').val(table[i-1].pakMk); } } } else if (res.code === 403){ window.location.href = baseUrl+"/login"; } else { console.log(res.msg); } } }); }, end: function () { $('#shuttleNo').val(""); $('#workNo').val(""); $('#pakMk').val(""); } }) } }); $(document).on('click ','#cancel', function () { $('#shuttleNo').val(""); $('#workNo').val(""); $('#pakMk').val(""); layer.close(layerDetl); }) </script>