package com.zy.common.utils;
|
|
import com.core.exception.CoolException;
|
import com.zy.asrs.entity.WrkCharge;
|
import com.zy.asrs.entity.WrkMast;
|
import com.zy.asrs.mapper.WrkChargeMapper;
|
import com.zy.asrs.mapper.WrkMastMapper;
|
import com.zy.asrs.service.WrkMastService;
|
import com.zy.asrs.utils.Utils;
|
import com.zy.common.model.NavigateNode;
|
import com.zy.common.model.enums.NavigationMapType;
|
import com.zy.common.service.CommonService;
|
import com.zy.core.News;
|
import com.zy.core.cache.SlaveConnection;
|
import com.zy.core.enums.SlaveType;
|
import com.zy.core.model.ShuttleSlave;
|
import com.zy.core.model.protocol.NyShuttleProtocol;
|
import com.zy.core.properties.SlaveProperties;
|
import com.zy.core.thread.NyShuttleThread;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
|
import java.util.ArrayList;
|
import java.util.Date;
|
import java.util.List;
|
|
/**
|
* 四向穿梭车调度工具
|
*/
|
@Service
|
public class ShuttleDispatchUtils {
|
|
@Autowired
|
private SlaveProperties slaveProperties;
|
@Autowired
|
private WrkMastService wrkMastService;
|
@Autowired
|
private WrkMastMapper wrkMastMapper;
|
@Autowired
|
private WrkChargeMapper wrkChargeMapper;
|
@Autowired
|
private CommonService commonService;
|
|
/**
|
* 调度车辆-调度指定穿梭车
|
*/
|
public boolean dispatchShuttle(Integer wrkNo, String locNo, Integer shuttleNo) {
|
return shuttleMoveGenerate(wrkNo, locNo, shuttleNo);
|
}
|
|
/**
|
* 调度车辆
|
*/
|
public boolean dispatchShuttle(Integer wrkNo, String locNo) {
|
ArrayList<NyShuttleThread> sameLev = new ArrayList<>();//相同楼层的穿梭车
|
ArrayList<NyShuttleThread> diffLev = new ArrayList<>();//不同楼层的穿梭车
|
|
for (ShuttleSlave shuttle : slaveProperties.getShuttle()) {
|
//获取四向穿梭车线程
|
NyShuttleThread shuttleThread = (NyShuttleThread) SlaveConnection.get(SlaveType.Shuttle, shuttle.getId());
|
NyShuttleProtocol shuttleProtocol = shuttleThread.getShuttleProtocol();
|
if (shuttleProtocol == null || shuttleProtocol.getShuttleNo() == null) {
|
continue;
|
}
|
|
if (!shuttleProtocol.isIdle()) {
|
continue;
|
}
|
|
int currentLev = shuttleProtocol.getPoint().getZ();//小车当前层高
|
String currentLocNo = shuttleProtocol.getCurrentLocNo();//小车当前库位号
|
|
if (currentLocNo.equals(locNo)) {
|
//车辆当前位置已经是目标库位,调度该车
|
shuttleMoveGenerate(wrkNo, locNo, shuttleProtocol.getShuttleNo().intValue());
|
break;
|
}
|
|
if (currentLev == Utils.getLev(locNo)) {
|
//工作档楼层相同的穿梭车
|
sameLev.add(shuttleThread);
|
}else {
|
//工作档不同楼层的穿梭车
|
diffLev.add(shuttleThread);
|
}
|
|
}
|
|
Integer recentAllDistance = 9999999;
|
NyShuttleThread recentShuttle = null;//当前距离最近的四向穿梭车线程
|
if (sameLev.size() > 0) {
|
//同一楼层有空闲穿梭车,则只在工作档楼层寻找
|
//寻找离任务最近的穿梭车
|
for (NyShuttleThread shuttleThread : sameLev) {
|
//当前穿梭车库位号
|
String currentLocNo = shuttleThread.getShuttleProtocol().getCurrentLocNo();
|
//当前穿梭车线程到目标地点距离
|
List<NavigateNode> currentShuttlePath = NavigateUtils.calc(currentLocNo, locNo, NavigationMapType.NORMAL.id, Utils.getShuttlePoints(shuttleThread.getSlave().getId(), Utils.getLev(currentLocNo)));//搜索空闲穿梭车,使用正常通道地图
|
if (currentShuttlePath == null) {
|
continue;
|
}
|
Integer currentAllDistance = NavigateUtils.getOriginPathAllDistance(currentShuttlePath);//计算当前路径行走总距离
|
if (currentAllDistance < recentAllDistance) {
|
//如果当前楼层的车路径更小,则更新最近穿梭车
|
recentShuttle = shuttleThread;
|
}
|
}
|
}else {
|
//同一楼层,没有空闲穿梭车,只能从其他楼层调度
|
//寻找离任务最近的穿梭车
|
for (NyShuttleThread shuttleThread : diffLev) {
|
|
//当前穿梭车库位号
|
String currentLocNo = shuttleThread.getShuttleProtocol().getCurrentLocNo();
|
int currentLev = Utils.getLev(currentLocNo);
|
List<WrkMast> wrkMasts1 = wrkMastService.selectNoShuttleWrkByLev(currentLev);//判断当前穿梭车楼层是否有待分配车辆的任务,如果有则不分配这辆车
|
if (wrkMasts1.size() > 0) {
|
//存在其他任务,跳过这辆车
|
continue;
|
}
|
|
//当前穿梭车线程到当前车子所在楼层的提升机口距离
|
List<NavigateNode> currentShuttlePath = NavigateUtils.calc(currentLocNo, Utils.levToOutInStaLocNo(currentLev), NavigationMapType.NORMAL.id, Utils.getShuttlePoints(shuttleThread.getSlave().getId(), currentLev));//搜索空闲穿梭车,使用正常通道地图
|
if (currentShuttlePath == null) {
|
continue;
|
}
|
|
Integer currentAllDistance = NavigateUtils.getOriginPathAllDistance(currentShuttlePath);//计算当前路径行走总距离
|
if (currentAllDistance < recentAllDistance) {
|
//如果当前楼层的车路径更小,则更新最近穿梭车
|
recentShuttle = shuttleThread;
|
}
|
}
|
}
|
|
if (recentShuttle == null) {//没有搜索到可用穿梭车
|
return false;
|
}
|
|
//搜索到可用穿梭车,调度该车
|
return shuttleMoveGenerate(wrkNo, locNo, recentShuttle.getSlave().getId());
|
}
|
|
/**
|
* 小车迁移任务生成
|
*/
|
@Transactional
|
private boolean shuttleMoveGenerate(Integer wrkNo, String locNo, Integer shuttleNo) {
|
Date now = new Date();
|
//获取四向穿梭车线程
|
NyShuttleThread shuttleThread = (NyShuttleThread) SlaveConnection.get(SlaveType.Shuttle, shuttleNo);
|
if (shuttleThread == null) {
|
return false;
|
}
|
NyShuttleProtocol shuttleProtocol = shuttleThread.getShuttleProtocol();
|
if (shuttleProtocol == null) {
|
return false;
|
}
|
|
//小车处于空闲状态
|
if (!shuttleProtocol.isIdleNoCharge()) {
|
return false;
|
}
|
|
//判断穿梭车是否存在未完成的小车移库任务
|
WrkMast hasMoveWorking = wrkMastMapper.selectShuttleHasMoveWorking(shuttleNo);
|
if (hasMoveWorking != null) {//小车存在移库任务,等待执行完成后再生成新的任务
|
return false;
|
}
|
|
//判断是否有其他任务正在使用穿梭车
|
WrkMast wrkMast2 = wrkMastMapper.selectShuttleWorking(shuttleNo);
|
if (wrkMast2 != null) {//小车存在其他工作档任务,等待执行完成后再生成新的任务
|
return false;
|
}
|
|
//判断是否有充电任务正在使用穿梭车
|
WrkCharge wrkCharge = wrkChargeMapper.selectWorking(shuttleNo);
|
if (wrkCharge != null) {//小车存在充电任务,等待执行完成后再生成新的任务
|
return false;
|
}
|
|
// 获取工作号
|
int workNo = commonService.getWorkNo(0);
|
// 保存工作档
|
WrkMast wrkMast = new WrkMast();
|
wrkMast.setWrkNo(workNo);
|
wrkMast.setIoTime(now);
|
wrkMast.setWrkSts(101L); // 工作状态:101.移动到近点等待迁出
|
wrkMast.setIoType(200); // 入出库状态: 200.小车移库
|
wrkMast.setIoPri(20D);
|
wrkMast.setShuttleNo(shuttleNo);//穿梭车号
|
wrkMast.setSourceLocNo(shuttleProtocol.getCurrentLocNo()); // 源库位 => 小车当前库位号
|
wrkMast.setLocNo(locNo); // 目标库位
|
wrkMast.setPicking("N"); // 拣料
|
wrkMast.setExitMk("N"); // 退出
|
wrkMast.setLinkMis("N");
|
wrkMast.setAppeTime(now);
|
wrkMast.setModiTime(now);
|
int res = wrkMastMapper.insert(wrkMast);
|
if (res == 0) {
|
News.error("小车迁移 --- 保存工作档失败! 穿梭车号:" + shuttleNo);
|
throw new CoolException("保存工作档失败");
|
}
|
|
//给工作档绑定小车号
|
WrkMast wrkMast1 = wrkMastMapper.selectByWorkNo(wrkNo);
|
if (wrkMast1 != null) {
|
wrkMast1.setShuttleNo(shuttleNo);
|
wrkMastMapper.updateById(wrkMast1);
|
}
|
|
return true;
|
}
|
|
}
|