using CommLayerFactory; using CommonLib; using DBFactory; using ICommLayer; using System; using System.Collections.Generic; using System.Data; using System.Text; using System.Text.RegularExpressions; namespace WcfControlMonitorLib { /// /// Creator:ZCY /// 世仓穿梭板通用函数类库 SCShuttle /// public class CCommonFunctionFINS { string _DisassembleTaskError; public string DisassembleTaskError { get { return _DisassembleTaskError; } set { _DisassembleTaskError = value; } } DBOperator dboM = CStaticClass.dboM; DBOperator dbo = CStaticClass.dbo; static CGetState cgs = new CGetState(); CCommonFunction ccf = new CCommonFunction(); Model.MDevice devinfo; StringBuilder sql = new StringBuilder(); public static event CDataSourceChangeEventHandler DataChange; public static void OnDataChange(object sender, CDataChangeEventArgs e) { if (DataChange != null) { DataChange(sender, e); } } public static event RefreshMonitorEventHandler RefreshMonitor; public static void OnRefreshMonitor(object sender, RefreshMonitorEventArgs e) { if (RefreshMonitor != null) { RefreshMonitor(e); } } public CCommonFunctionFINS() { } #region 核心部分(废弃) //获取出库任务相关,将给定的任务,找出所有排列层相同,且终点相同的任务,同时获取 public int[] GetAllMutexTaskAndSameEndFromIOControl_OderbyFFirstInputLocat(int Fid, string startdevicecell, string enddevice, string startwarehouse) { DataView dv = new DataView(); try { string inputlogic = GetFFirstInputLocatFromCell(startdevicecell); string orderby = string.Empty; if (inputlogic == "small") { orderby = "desc"; //入库先入小的货位,则出库时,先出大的货位,应按降序排列 } if (inputlogic == "big") { orderby = "asc"; //入库先入大的货位,则出库时,先出小的货位,应按升序排列 } List allcells = GetAllSameGroupCell(startdevicecell); string cells = CellsToSql(allcells); dv = dboM.ExceSQL(string.Format("SELECT CONTROL_ID FROM IO_CONTROL WHERE CONTROL_STATUS=0 and (START_DEVICE_CODE in {0}) and START_WAREHOUSE_CODE = '{1}' and END_DEVICE_CODE = '{2}' order by START_DEVICE_CODE {3}", cells, startwarehouse, enddevice, orderby)).Tables[0].DefaultView; if (dv.Count > 0) { int[] allfid = new int[dv.Count]; for (int i = 0; i < dv.Count; i++) { allfid[i] = Convert.ToInt32(dv[i]["CONTROL_ID"]); } return allfid; } return null; } catch (Exception ex) { //CObtainTaskError = string.Format("获取任务时,GetChuanRGVIfHaveMutexTaskFromIOControl:{0}", ex.StackTrace + ex.Message); throw ex; } finally { dv.Dispose(); } } //倒库用 public int[] GetAllMutexTaskAndSameEndFromIOControl_OderbyFFirstInputLocat_YIKU(int Fid, string startdevicecell, string startwarehouse) { DataView dv = new DataView(); try { string inputlogic = GetFFirstInputLocatFromCell(startdevicecell); string orderby = string.Empty; if (inputlogic == "small") { orderby = "desc"; //入库先入小的货位,则出库时,先出大的货位,应按降序排列 } if (inputlogic == "big") { orderby = "asc"; //入库先入大的货位,则出库时,先出小的货位,应按升序排列 } List allcells = GetAllSameGroupCell(startdevicecell); string cells = CellsToSql(allcells); dv = dboM.ExceSQL(string.Format("SELECT CONTROL_ID FROM IO_CONTROL WHERE CONTROL_STATUS=0 and (START_DEVICE_CODE in {0}) and START_WAREHOUSE_CODE = '{1}' order by START_DEVICE_CODE {2}", cells, startwarehouse, orderby)).Tables[0].DefaultView; if (dv.Count > 0) { int[] allfid = new int[dv.Count]; for (int i = 0; i < dv.Count; i++) { allfid[i] = Convert.ToInt32(dv[i]["CONTROL_ID"]); } return allfid; } return null; } catch (Exception ex) { //CObtainTaskError = string.Format("获取任务时,GetChuanRGVIfHaveMutexTaskFromIOControl:{0}", ex.StackTrace + ex.Message); throw ex; } finally { dv.Dispose(); } } //拆分任务相关,查找相同排列层任务中,位坐标最小的,或最大的(如果有已拆分的任务,存在穿梭车指令,则不拆分) public int GetShuttleMinMutexTaskFromManage_OderbyFFirstInputLocat(int Fid) { DataView dv = new DataView(); int minfid = Fid; try { { string cell = GetStartCellFromManage(Fid); string inputlogic = GetFFirstInputLocatFromCell(cell); string orderby = string.Empty; if (inputlogic == "small") { orderby = "desc"; //入库先入小的货位,则出库时,先出大的货位,应按降序排列 } if (inputlogic == "big") { orderby = "asc"; //入库先入大的货位,则出库时,先出小的货位,应按升序排列 } List allcells = GetAllSameGroupCell(cell); string cells = CellsToSql(allcells); dv = dbo.ExceSQL(string.Format("SELECT fid FROM T_Manage_Task WHERE FIntoStepOK=0 and (FSTARTCELL in {0}) order by FSTARTCELL {1}", cells, orderby)).Tables[0].DefaultView; if (dv.Count > 0) { minfid = Convert.ToInt32(dv[0]["fid"]); } } return minfid; } catch (Exception ex) { DisassembleTaskError = string.Format("获取任务时,GetShuttleIfHaveMutexTaskFromIOControl:{0}", ex.StackTrace + ex.Message); return 0; } finally { dv.Dispose(); } } //拆分移车的任务,FID,选择的世仓穿梭板,目标位置 //自动换边,上车,取车,送车,自动换边 // // public bool DisassembleSameStackMoveSCShuttle(int Mankind, int ManFID, int SCShuttle, int[] Coor) { int virtualSCShuttle = SCShuttle;//virtualSCShuttle //int stack = GetStackFromManage(ManFID); int lane = GetLaneFromSCShuttle(SCShuttle); int stack = GetStackFromLane(lane); int stackrouteIDSub = GetRouteSubFromStack(stack); int SCShuttlerouteIDSub = GetRouteSubFromShuttle(virtualSCShuttle); int routeIDSub = 0; int keydevice = 0; int SCShuttle_Up = 3; int SCShuttle_Down = 4; int Stack_Get = 7; //堆垛机取车 (堆垛机指令) int Stack_Send = 8; //堆垛机送车 (堆垛机指令) int SCShuttle_ToBSide = 7; int SCShuttle_ToASide = 12; int SCShuttle_Change_AB = 10; // int SCShuttle_FobidMove = 11; //禁止世仓穿梭板动作 int SCShuttle_AllowMove = 13; //允许世仓穿梭板动作 int SCShuttle_ToBettey = 30; int order = 0; int level = 1; StringBuilder AheadDetect = new StringBuilder(); StringBuilder RunningLock = new StringBuilder(); string palletcode = ccf.GetBarCodeFromManageTask(ManFID, Mankind); //起点是车的坐标 int[] tempCoor = new int[CoorNum]; { tempCoor[0] = 0; tempCoor[1] = 0; tempCoor[2] = 0; tempCoor[3] = Coor[3]; tempCoor[4] = Coor[4]; tempCoor[5] = Coor[5]; } int fcontrol = ccf.GetFCONTROLTASKTYPEFromManageTask(Mankind, ManFID); //生成自动换边指令(在上堆垛机前,下堆垛机后,进行自动换边,不能检测指令是否已存在) //if (CDisassembleTask.DeviceAndOrderExitInMonitor(Mankind, ManFID, virtualRGV, RGV_Change_AB, 0, tempCoor) == false) { keydevice = virtualSCShuttle; order = SCShuttle_Change_AB; routeIDSub = SCShuttlerouteIDSub; RunningLock.Clear(); RunningLock.Append(virtualSCShuttle); AheadDetect.Clear(); AheadDetect.Append(";FL15010") //允许动作, .Append(";FA15010") //自动检测AB边, .Append(";FC-15010") .Append(";FI15010") //世仓穿梭板空闲/坐标 .Append(";FR15010") //预约锁, .Append(";FZ11000"); //堆垛机状态 int mindex = ccf.GetMonitorIndex(); Model.Monitor_Task ob = new Model.Monitor_Task { _manfid = ManFID, _mankind = Mankind, _mindex = mindex, _level = level.ToString(), _device = keydevice.ToString(), _command = order.ToString(), _routeid = routeIDSub.ToString(), _status = 0.ToString(), _param1 = tempCoor[0].ToString(), _param2 = tempCoor[1].ToString(), _param3 = tempCoor[2].ToString(), _param4 = tempCoor[3].ToString(), _param5 = tempCoor[4].ToString(), _param6 = tempCoor[5].ToString(), _aheaddetect = AheadDetect.ToString(), _runningLock = RunningLock.ToString(), _txtparam = palletcode, _agvNo = stack.ToString() }; ccf.InsertWCS_T_Monitor_Task(ob); } //生成RGV上车指令 if (CDisassembleTask.DeviceAndOrderExitInMonitor(Mankind, ManFID, virtualSCShuttle, SCShuttle_Up, 0, tempCoor) == false) { keydevice = virtualSCShuttle; order = SCShuttle_Up; routeIDSub = SCShuttlerouteIDSub; RunningLock.Clear(); AheadDetect.Clear(); AheadDetect.Append(";FL15010") //允许动作, .Append(";FA15010") //自动检测AB边, .Append(";FC-15010") .Append(";FI15010") //世仓穿梭板空闲/坐标 .Append(";FR15010") //预约锁, .Append(";FZ11000"); //堆垛机状态 int mindex = ccf.GetMonitorIndex(); Model.Monitor_Task ob = new Model.Monitor_Task { _manfid = ManFID, _mankind = Mankind, _mindex = mindex, _level = level.ToString(), _device = keydevice.ToString(), _command = order.ToString(), _routeid = routeIDSub.ToString(), _status = 0.ToString(), _param1 = tempCoor[0].ToString(), _param2 = tempCoor[1].ToString(), _param3 = tempCoor[2].ToString(), _param4 = tempCoor[3].ToString(), _param5 = tempCoor[4].ToString(), _param6 = tempCoor[5].ToString(), _aheaddetect = AheadDetect.ToString(), _runningLock = RunningLock.ToString(), _txtparam = palletcode }; ccf.InsertWCS_T_Monitor_Task(ob); } //生成禁止RGV动作指令 (发送取车指令之前判断,自动发) //生成取车指令 if (CDisassembleTask.DeviceAndOrderExitInMonitor(Mankind, ManFID, stack, Stack_Get, 0, tempCoor) == false) { keydevice = stack; order = Stack_Get; routeIDSub = stackrouteIDSub; RunningLock.Clear(); RunningLock.Append(virtualSCShuttle); AheadDetect.Clear(); AheadDetect.Append(";FA15010") //自动检测AB边 .Append(";FD15010") //车上无货 .Append(";FE15010") //终点无车 .Append(";FI15010") //穿梭车空闲/坐标 .Append(";FR15010") //预约锁 .Append(";FS-15010") //起点货位有车 .Append(";FT15010") // .Append(";FL-15010"); //禁止车动作,在最后 AheadDetect.Append(";I").Append(keydevice).Append(";D").Append(keydevice).Append(".0"); int mindex = ccf.GetMonitorIndex(); Model.Monitor_Task ob = new Model.Monitor_Task { _manfid = ManFID, _mankind = Mankind, _mindex = mindex, _level = level.ToString(), _device = keydevice.ToString(), _command = order.ToString(), _routeid = routeIDSub.ToString(), _status = 0.ToString(), _param1 = tempCoor[0].ToString(), _param2 = tempCoor[1].ToString(), _param3 = tempCoor[2].ToString(), _param4 = tempCoor[3].ToString(), _param5 = tempCoor[4].ToString(), _param6 = tempCoor[5].ToString(), _aheaddetect = AheadDetect.ToString(), _runningLock = RunningLock.ToString(), _txtparam = palletcode, _agvNo = virtualSCShuttle.ToString() }; ccf.InsertWCS_T_Monitor_Task(ob); } //生成送车指令 if (CDisassembleTask.DeviceAndOrderExitInMonitor(Mankind, ManFID, stack, Stack_Send, 0, tempCoor) == false) { keydevice = stack; order = Stack_Send; routeIDSub = stackrouteIDSub; RunningLock.Clear(); RunningLock.Append(virtualSCShuttle); AheadDetect.Clear(); AheadDetect.Append(";FE15010") //终点货位无车 .Append(";FL-15010"); //禁止动作 AheadDetect.Append(";I").Append(keydevice).Append(";D-").Append(keydevice).Append(".0"); int mindex = ccf.GetMonitorIndex(); Model.Monitor_Task ob = new Model.Monitor_Task { _manfid = ManFID, _mankind = Mankind, _mindex = mindex, _level = level.ToString(), _device = keydevice.ToString(), _command = order.ToString(), _routeid = routeIDSub.ToString(), _status = 0.ToString(), _param1 = tempCoor[0].ToString(), _param2 = tempCoor[1].ToString(), _param3 = tempCoor[2].ToString(), _param4 = tempCoor[3].ToString(), _param5 = tempCoor[4].ToString(), _param6 = tempCoor[5].ToString(), _aheaddetect = AheadDetect.ToString(), _runningLock = RunningLock.ToString(), _txtparam = palletcode, _agvNo = virtualSCShuttle.ToString() }; ccf.InsertWCS_T_Monitor_Task(ob); } //生成自动换边指令(在上堆垛机前,下堆垛机后,进行自动换边,不能检测指令是否已存在) //if (Order == 1 || Order == 2)//只有入库或出库任务,下堆垛机后才需要换边,充电不需要 { //if (CDisassembleTask.DeviceAndOrderExitInMonitor(Mankind, ManFID, virtualRGV, RGV_Change_AB, 0, tempCoor) == false) { keydevice = virtualSCShuttle; order = SCShuttle_Change_AB; routeIDSub = SCShuttlerouteIDSub; RunningLock.Clear(); RunningLock.Append(virtualSCShuttle); AheadDetect.Clear(); //自动检测AB边,穿梭车空闲/坐标,允许动作,预约锁,堆垛机状态(允许车动作在最前面) AheadDetect.Append(";FL15010") .Append(";FA15010") .Append(";FC-15010") .Append(";FI15010") .Append(";FR15010") .Append(";FZ11000"); int mindex = ccf.GetMonitorIndex(); Model.Monitor_Task ob = new Model.Monitor_Task { _manfid = ManFID, _mankind = Mankind, _mindex = mindex, _level = level.ToString(), _device = keydevice.ToString(), _command = order.ToString(), _routeid = routeIDSub.ToString(), _status = 0.ToString(), _param1 = tempCoor[0].ToString(), _param2 = tempCoor[1].ToString(), _param3 = tempCoor[2].ToString(), _param4 = tempCoor[3].ToString(), _param5 = tempCoor[4].ToString(), _param6 = tempCoor[5].ToString(), _aheaddetect = AheadDetect.ToString(), _runningLock = RunningLock.ToString(), _txtparam = palletcode, _agvNo = stack.ToString() }; ccf.InsertWCS_T_Monitor_Task(ob); } } //生成RGV下车指令 //入库选车成功时生产下车指令 { if (CDisassembleTask.DeviceAndOrderExitInMonitor(Mankind, ManFID, keydevice, SCShuttle_Down, 0, tempCoor) == false) { routeIDSub = SCShuttlerouteIDSub; keydevice = virtualSCShuttle; order = SCShuttle_Down; AheadDetect.Clear(); AheadDetect.Append(";FO15010"); //是出库任务 //自动检测AB边,不在充电位,穿梭车空闲/坐标,允许动作,预约锁,堆垛机状态 AheadDetect.Append(";FL15010").Append(";FA15010").Append(";FC-15010").Append(";FI15010") .Append(";FR15010").Append(";FZ11000"); int mindex = ccf.GetMonitorIndex(); Model.Monitor_Task ob = new Model.Monitor_Task { _manfid = ManFID, _mankind = Mankind, _mindex = mindex, _level = level.ToString(), _device = keydevice.ToString(), _command = order.ToString(), _routeid = routeIDSub.ToString(), _status = 0.ToString(), _param1 = tempCoor[0].ToString(), _param2 = tempCoor[1].ToString(), _param3 = tempCoor[2].ToString(), _param4 = tempCoor[3].ToString(), _param5 = tempCoor[4].ToString(), _param6 = tempCoor[5].ToString(), _aheaddetect = AheadDetect.ToString(), _txtparam = palletcode }; ccf.InsertWCS_T_Monitor_Task(ob); } } return true; } //充电任务拆分 //Coor:z,x,y //参数:Order,30-移去充电 public bool DisassembleToBettey(int Mankind, int ManFID, int DeviceIndex) { int virtualRGV = DeviceIndex;//virtualRGV int stack = GetStackFromManage(ManFID); int stackrouteIDSub = GetRouteSubFromStack(stack); int rgvrouteIDSub = GetRouteSubFromShuttle(virtualRGV); int routeIDSub = 0; int keydevice = 0; int Shuttle_Up = 3; int Shuttle_Down = 4; int Stack_Get = 7; //堆垛机取车 (堆垛机指令) int Stack_Send = 8; //堆垛机送车 (堆垛机指令) int Shuttle_ToBSide = 7; int Shuttle_ToASide = 12; int Shuttle_Change_AB = 10; // int RGV_FobidMove = 11; //禁止RGV动作 int RGV_AllowMove = 13; //允许RGV动作 int RGV_ToBettey = 30; int order = 0; int level = 1; StringBuilder AheadDetect = new StringBuilder(); StringBuilder RunningLock = new StringBuilder(); string palletcode = ccf.GetBarCodeFromManageTask(ManFID, Mankind); int[] tempCoor = new int[CoorNum]; { //tempCoor[0] = Coor[0]; //tempCoor[1] = Coor[1]; //tempCoor[2] = Coor[2]; //tempCoor[3] = Coor[3]; //tempCoor[4] = Coor[4]; //tempCoor[5] = Coor[5]; level = 10; } //生成去B边 if (CDisassembleTask.DeviceAndOrderExitInMonitor(Mankind, ManFID, virtualRGV, Shuttle_ToBSide, 0, tempCoor) == false) { keydevice = virtualRGV; order = Shuttle_ToBSide; routeIDSub = rgvrouteIDSub; RunningLock.Clear(); RunningLock.Append(virtualRGV); AheadDetect.Clear(); //在充电位,穿梭车空闲/坐标,允许动作,预约锁,叉车模式,堆垛机状态 AheadDetect.Append(";FL15010").Append(";FC15010").Append(";FI15010").Append(";FR15010").Append(";FT15010").Append(";FZ11000"); int mindex = ccf.GetMonitorIndex(); Model.Monitor_Task ob = new Model.Monitor_Task { _manfid = ManFID, _mankind = Mankind, _mindex = mindex, _level = level.ToString(), _device = keydevice.ToString(), _command = order.ToString(), _routeid = routeIDSub.ToString(), _status = 0.ToString(), _param1 = tempCoor[0].ToString(), _param2 = tempCoor[1].ToString(), _param3 = tempCoor[2].ToString(), _param4 = tempCoor[3].ToString(), _param5 = tempCoor[4].ToString(), _param6 = tempCoor[5].ToString(), _aheaddetect = AheadDetect.ToString(), _runningLock = RunningLock.ToString(), _txtparam = palletcode, _agvNo = stack.ToString() }; ccf.InsertWCS_T_Monitor_Task(ob); } //生成去A边 if (CDisassembleTask.DeviceAndOrderExitInMonitor(Mankind, ManFID, virtualRGV, Shuttle_ToASide, 0, tempCoor) == false) { keydevice = virtualRGV; order = Shuttle_ToASide; routeIDSub = rgvrouteIDSub; RunningLock.Clear(); RunningLock.Append(virtualRGV); AheadDetect.Clear(); //在充电位,穿梭车空闲/坐标,允许动作,预约锁,叉车模式,堆垛机状态 AheadDetect.Append(";FL15010").Append(";FC15010").Append(";FI15010").Append(";FR15010").Append(";FT15010").Append(";FZ11000"); int mindex = ccf.GetMonitorIndex(); Model.Monitor_Task ob = new Model.Monitor_Task { _manfid = ManFID, _mankind = Mankind, _mindex = mindex, _level = level.ToString(), _device = keydevice.ToString(), _command = order.ToString(), _routeid = routeIDSub.ToString(), _status = 0.ToString(), _param1 = tempCoor[0].ToString(), _param2 = tempCoor[1].ToString(), _param3 = tempCoor[2].ToString(), _param4 = tempCoor[3].ToString(), _param5 = tempCoor[4].ToString(), _param6 = tempCoor[5].ToString(), _aheaddetect = AheadDetect.ToString(), _runningLock = RunningLock.ToString(), _txtparam = palletcode, _agvNo = stack.ToString() }; ccf.InsertWCS_T_Monitor_Task(ob); } //生成充电指令 if (CDisassembleTask.DeviceAndOrderExitInMonitor(Mankind, ManFID, keydevice, RGV_ToBettey, 0, tempCoor) == false) { routeIDSub = rgvrouteIDSub; keydevice = DeviceIndex;//充电不能是虚拟车号 AheadDetect.Append(";FC15010"); //在充电位置 AheadDetect.Clear(); //在A边,在充电位,穿梭车空闲/坐标,预约锁,叉车模式,堆垛机状态 AheadDetect.Append(";FL15010").Append(";FB-15010").Append(";FC15010").Append(";FI15010").Append(";FR15010").Append(";FT15010").Append(";FZ11000") ; order = RGV_ToBettey; int mindex = ccf.GetMonitorIndex(); Model.Monitor_Task ob = new Model.Monitor_Task { _manfid = ManFID, _mankind = Mankind, _mindex = mindex, _level = level.ToString(), _device = keydevice.ToString(), _command = order.ToString(), _routeid = routeIDSub.ToString(), _status = 0.ToString(), _param1 = tempCoor[0].ToString(), _param2 = tempCoor[1].ToString(), _param3 = tempCoor[2].ToString(), _param4 = tempCoor[3].ToString(), _param5 = tempCoor[4].ToString(), _param6 = tempCoor[5].ToString(), _aheaddetect = AheadDetect.ToString(), _txtparam = palletcode }; ccf.InsertWCS_T_Monitor_Task(ob); { string betteygatecell = GetOutestCellFromZXY(tempCoor[3], tempCoor[4], tempCoor[5], 0); //充電位不需要提供堆垛機參數 sql.Clear(); sql.Append("update t_manage_task set fendcell = '").Append(betteygatecell).Append("' where fid =").Append(ManFID); dbo.ExceSQL(sql.ToString()); } } return true; } //发送指令相关 //根据目标货位,选择合适的穿梭板,如果没有合适的,则返回-1 public int SelectRGV(string targetcell, int fid, out StringBuilder err) { int selectrgv = -1; DataView dvs = new DataView(); DataView dv = new DataView(); Dictionary rgvs = new Dictionary(); err = new StringBuilder(); #region 已经预分车了,直接返回该车 sql.Clear(); sql.Append("select * from t_manage_task where FID = ").Append(fid); dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; if (dv.Count > 0) { int rgvt = 0; if (int.TryParse(dv[0]["goods_barcode"].ToString(), out rgvt) == true) { if (rgvt != 0 && rgvt != -1) { selectrgv = rgvt; return selectrgv; } } else if (dv[0]["goods_barcode"].ToString().Contains(";") == true) { } } #endregion #region 获取目标货位的坐标 int[] target = new int[4] { 0, 0, 0, 0 }; //zxy target[0] = Convert.ToInt32(targetcell.Split('-')[0]); target[1] = Convert.ToInt32(targetcell.Split('-')[1]); target[2] = Convert.ToInt32(targetcell.Split('-')[2]); target[3] = Convert.ToInt32(targetcell.Split('-')[3]); if (target[0] == 0 && target[1] == 0 && target[2] == 0) { err.Clear(); err.Append("目标地址不正确,无法选车!"); return selectrgv; } #endregion #region 1.第一分车原则:在同组货位任务中,找已分的车(如果车被搬走了呢???电量过低,取充电了) int mti = 0; sql.Remove(0, sql.Length); sql.Append("SELECT F_ManageTaskKindIndex FROM t_manage_task WHERE (fid = ").Append(fid).Append(")"); dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; if (dv.Count > 0) { mti = Convert.ToInt32(dv[0]["F_ManageTaskKindIndex"]); } else { return -1; } int fcontroltype = ccf.GetFCONTROLTASKTYPEFromManageTask(mti, fid) ; //sql.Append("select * from T_Monitor_Task where F_DeviceIndex in (select F_DeviceIndex from V_RGVINFO ) and F_ManageTaskIndex in (" + // "select fid from t_manage_task where (FCONTROLTASKTYPE = 2 and FSTARTCELL like '").Append(targetcell).Append("%') or(FCONTROLTASKTYPE = 1 and FENDCELL like '").Append(targetcell).Append("%')) "); sql.Clear(); sql.Append("select Goods_barcode from t_manage_task where Goods_barcode in (select F_DeviceIndex from V_RGVINFO ) AND FCONTROLTASKTYPE = ").Append(fcontroltype).Append(" and (FSTARTUCODE = '").Append(targetcell).Append("' or FENDUCODE = '").Append(targetcell).Append("' )"); dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; if (dv.Count > 0) { selectrgv = Convert.ToInt32(dv[0]["Goods_barcode"]); if (SelectedShuttleStatueIsOk(selectrgv) == false) { err.Clear(); err.Append("第一分车原则:待选车辆" + selectrgv.ToString() + "不可用!"); //选择的车不可用 selectrgv = -1; } else { sql.Clear(); sql.Append("select * from t_manage_task where fenddevice = 17001 and fPalletbarcode = ").Append(selectrgv); dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; if (dv.Count > 0) { err.Append("第一分车原则:" + selectrgv.ToString() + "存在充电任务"); selectrgv = -1; } else { err.Clear(); err.Append("第一分车原则:" + selectrgv.ToString()); //移到了SelectedRGVUpdateMonitorCoor中 //选车可用,删除挪车的指令 //sql.Clear(); //sql.Append("delete t_monitor_task where F_ManageTaskIndex =").Append(fid) // .Append(" and f_numParam1 = 0 and f_numParam2 = 0 and f_numParam3 = 0 "); //dbo.ExceSQL(sql.ToString()); } } #region 该巷道只有一个入库任务时,且该任务未拆分,第一分车原则、第二分车原则不适用。 int lanee = GetLaneFromManage(fid); sql.Remove(0, sql.Length); sql.Append("SELECT * FROM T_Manage_Task WHERE (FLANEWAY = ").Append(lanee).Append(") AND (FCONTROLTASKTYPE = 1) "); dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; if (dv.Count == 1) { int FIntoStepOK = Convert.ToInt32(dv[0]["FIntoStepOK"]); if (FIntoStepOK == 0 && fcontroltype == 2) { err.Clear(); err.Append("存在入库任务未分车,出库任务第一分车原则失败" + selectrgv.ToString()); //选择的车不可用 selectrgv = -1; } } #endregion return selectrgv; } #endregion selectrgv = FINSTCPIP.SHICANGProtocol.LaneCoorAlreadyHaveRGV(targetcell); if (selectrgv != -1) { if (SelectedShuttleStatueIsOk(selectrgv) == false) { err.Clear(); err.Append("第二分车原则:待选车辆" + selectrgv.ToString() + "状态不可用!"); //选择的车不可用 selectrgv = -1; } else if (SelectedRGVSQLStatusIsOk(selectrgv, out err) == false) { //err.Clear(); //err.Append("第二分车原则:待选车辆" + selectrgv.ToString() + "状态不可用!"); selectrgv = -1; } else { err.Clear(); err.Append("第二分车原则:" + selectrgv.ToString()); } #region 该巷道只有一个入库任务时,且该任务未拆分,第一分车原则、第二分车原则不适用。 int lanee = GetLaneFromManage(fid); sql.Remove(0, sql.Length); sql.Append("SELECT * FROM T_Manage_Task WHERE (FLANEWAY = ").Append(lanee).Append(") AND (FCONTROLTASKTYPE = 1) "); dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; if (dv.Count == 1) { int FIntoStepOK = Convert.ToInt32(dv[0]["FIntoStepOK"]); if (FIntoStepOK == 0 && fcontroltype == 2) { err.Clear(); err.Append("存在入库任务未分车,出库任务第二分车原则失败" + selectrgv.ToString()); //选择的车不可用 selectrgv = -1; } } #endregion return selectrgv; } #region 2.找到该巷道内所有的车,空闲、充电(锁定,故障,monitor中有指令的除外) int lane = GetLaneFromManage(fid); sql.Clear(); sql.Append("select * from V_RGVINFO where (f_rgvz <> 0 and f_rgvx <> 0 and f_rgvy <> 0) and f_cur_lane = ").Append(lane); dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; for (int i = 0; i < dv.Count; i++) { int dev = Convert.ToInt32(dv[i]["f_deviceindex"]); #region 穿梭板坐标 int z = Convert.ToInt32(dv[i]["F_RgvZ"]); int x = Convert.ToInt32(dv[i]["F_RgvX"]); int y = Convert.ToInt32(dv[i]["F_RgvY"]); int w = Convert.ToInt32(dv[i]["F_RgvW"]); string rgvzxyw = string.Format("{0:D2}-{1:D2}-{2:D2}-{3:D2}", z, x, y, w); #endregion #region 3.第二分车原则,车坐标与目标位置相同(当故障,停用,断线,缺电时,也不选其他可用车辆) if (rgvzxyw == targetcell) { selectrgv = dev; if (SelectedShuttleStatueIsOk(selectrgv) == false) { err.Clear(); err.Append("第二分车原则:待选车辆" + selectrgv.ToString() + "状态不可用!"); //选择的车不可用 selectrgv = -1; } else if (SelectedRGVSQLStatusIsOk(selectrgv, out err) == false) { //err.Clear(); //err.Append("第二分车原则:待选车辆" + selectrgv.ToString() + "状态不可用!"); selectrgv = -1; } else { err.Clear(); err.Append("第二分车原则:" + selectrgv.ToString()); } return selectrgv; } #endregion // 第三选车原则从 rgvs 中挑选 #region 车状态不可用,则不会选车 if (SelectedShuttleStatueIsOk(dev) == false) { err.Clear(); //车不可用,第三选车原则中不会被选择 continue; } if (SelectedRGVSQLStatusIsOk(dev, out err) == false) { err.Clear(); //车不可用,第三选车原则中不会被选择 continue; } //如果存在车指令,该指令的任务起点或终点,与车坐标相同,则不选择(防止任务没完成,车换巷道时和堆垛机货叉相撞) sql.Clear(); sql.Append("select * from t_monitor_task where f_deviceindex = ").Append(dev); dvs = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; if (dvs.Count > 0) { err.Clear(); //车还存在未完成的指令,第三选车原则中不会被选择 continue; } #endregion rgvs.Add(dev, new int[4] { z, x, y, w }); } #endregion #region 4.第三分车原则,计算目标货位和所有穿梭板的距离,选择最小的 if (selectrgv == -1 && rgvs.Count != 0) { //rgvs中的所有车都是可用的! double smalllength = 1000000; foreach (var rgv in rgvs.Keys) { double r = GetRGVToTargetLength(target, rgvs[rgv]); #region 充电中,则降低先选的优先级(认为最远) devinfo = Model.CGetInfo.GetDeviceInfo(rgv); if (devinfo.SplitByte_3 == 1) { r = 70.0; } #endregion if (r < smalllength) { smalllength = r; selectrgv = rgv; } } err.Clear(); err.Append("第三分车原则:" + selectrgv.ToString()); } else { err.Clear(); err.Append("无可用车辆"); } #endregion return selectrgv; } //移库需要两台车,重新写了选车的方法,非移库任务尽量使用另一个方法,这个方法专门用来移库的,测试较少,可能存在问题。 public int SelectRGV_YIKU(string startTargetCell, string endTargetCell, int fid, out StringBuilder err) { int selectrgv = -1; DataView dvs = new DataView(); DataView dv = new DataView(); Dictionary rgvs = new Dictionary(); err = new StringBuilder(); #region 已经预分车了,直接返回该车 sql.Clear(); sql.Append("select * from t_manage_task where FID = ").Append(fid); dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; if (dv.Count > 0) { int rgvt = 0; if (int.TryParse(dv[0]["goods_barcode"].ToString(), out rgvt) == true) { if (rgvt != 0 && rgvt != -1) { selectrgv = rgvt; return selectrgv; } } else if (dv[0]["goods_barcode"].ToString().Contains(";") == true) { } } #endregion #region 同一起点和终点的,且均需要车时,选同车 if (startTargetCell != String.Empty && endTargetCell != String.Empty) { sql.Clear(); sql.Append("select BOK.GOODS_BARCODE from T_Manage_Task as A, T_Manage_Task as BOK where A.FID = ").Append(fid).Append(" AND A.FID <> BOK.FID " + " AND A.FSTARTUCODE = BOK.FSTARTUCODE AND A.FENDUCODE = BOK.FENDUCODE AND" + " A.FSTARTUCODE <> A.FSTARTCELL AND A.FENDUCODE <> A.FENDCELL AND BOK.FSTARTUCODE <> BOK.FSTARTCELL AND BOK.FENDUCODE <> BOK.FENDCELL AND" + " BOK.FIntoStepOK = 1 AND BOK.GOODS_BARCODE IS NOT NULL"); dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; if (dv.Count > 0) { String shuttle_two = dv[0]["Goods_barcode"].ToString(); if (shuttle_two.Contains("15010") == false) { selectrgv = Convert.ToInt32(dv[0]["Goods_barcode"]); return selectrgv; } } } #endregion int startShuttle = -1; int endShuttle = -1; #region 起点和终点不需要车时 if (startTargetCell == String.Empty) { startShuttle = 15010; } if (endTargetCell == String.Empty) { endShuttle = 15010; } #endregion #region 起点和终点货位里有车 int[] startTarget = new int[4] { 0, 0, 0, 0 }; //zxy if (startShuttle == -1) { startTarget[0] = Convert.ToInt32(startTargetCell.Split('-')[0]); startTarget[1] = Convert.ToInt32(startTargetCell.Split('-')[1]); startTarget[2] = Convert.ToInt32(startTargetCell.Split('-')[2]); startTarget[3] = Convert.ToInt32(startTargetCell.Split('-')[3]); if (startTarget[0] == 0 && startTarget[1] == 0 && startTarget[2] == 0) { err.Clear(); err.Append("起点地址不正确,无法选车!"); return -1; } startShuttle = FINSTCPIP.SHICANGProtocol.LaneCoorAlreadyHaveRGV(startTargetCell); if (startShuttle != -1) { //if (SelectedShuttleStatueIsOk(startShuttle) == false) //{ // err.Clear(); // err.Append("第二分车原则:待选车辆" + startShuttle.ToString() + "状态不可用!"); // //选择的车不可用 // startShuttle = -1; //} //else if (SelectedRGVSQLStatusIsOk(startShuttle, out err) == false) { //err.Clear(); //err.Append("第二分车原则:待选车辆" + selectrgv.ToString() + "状态不可用!"); startShuttle = -1; } else { err.Clear(); err.Append("第二分车原则:" + startShuttle.ToString()); } if (startShuttle == -1) { return -1; } } } int[] endTarget = new int[4] { 0, 0, 0, 0 }; //zxy if (endShuttle == -1) { endTarget[0] = Convert.ToInt32(endTargetCell.Split('-')[0]); endTarget[1] = Convert.ToInt32(endTargetCell.Split('-')[1]); endTarget[2] = Convert.ToInt32(endTargetCell.Split('-')[2]); endTarget[3] = Convert.ToInt32(endTargetCell.Split('-')[3]); if (endTarget[0] == 0 && endTarget[1] == 0 && endTarget[2] == 0) { err.Clear(); err.Append("终点地址不正确,无法选车!"); return -1; } endShuttle = FINSTCPIP.SHICANGProtocol.LaneCoorAlreadyHaveRGV(endTargetCell); if (endShuttle != -1) { //if (SelectedShuttleStatueIsOk(endShuttle) == false) //{ // err.Clear(); // err.Append("第二分车原则:待选车辆" + endShuttle.ToString() + "状态不可用!"); // //选择的车不可用 // endShuttle = -1; //} //else if (SelectedRGVSQLStatusIsOk(endShuttle, out err) == false) { //err.Clear(); //err.Append("第二分车原则:待选车辆" + selectrgv.ToString() + "状态不可用!"); endShuttle = -1; } else { err.Clear(); err.Append("第二分车原则:" + endShuttle.ToString()); } if (endShuttle == -1) { return -1; } } } #endregion #region 起点车号获取 if (startShuttle == -1) { #region 3.找到该巷道内所有的车,空闲、充电(锁定,故障,monitor中有指令的除外) //int lane = GetLaneFromManage(fid); int lane = ccf.GetLanewayFromCellCode(startTargetCell, 1); sql.Clear(); sql.Append("select * from V_RGVINFO where (f_rgvz <> 0 and f_rgvx <> 0 and f_rgvy <> 0) and f_cur_lane = ").Append(lane); dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; for (int i = 0; i < dv.Count; i++) { int dev = Convert.ToInt32(dv[i]["f_deviceindex"]); if (dev == endShuttle) { continue;//起点和终点不能是同一个车 } #region 穿梭板坐标 int z = Convert.ToInt32(dv[i]["F_RgvZ"]); int x = Convert.ToInt32(dv[i]["F_RgvX"]); int y = Convert.ToInt32(dv[i]["F_RgvY"]); int w = Convert.ToInt32(dv[i]["F_RgvW"]); string rgvzxyw = string.Format("{0:D2}-{1:D2}-{2:D2}-{3:D2}", z, x, y, w); #endregion #region 4.第二分车原则-2,车坐标与目标位置相同(当故障,停用,断线,缺电时,也不选其他可用车辆) if (rgvzxyw == startTargetCell) { startShuttle = dev; //if (SelectedShuttleStatueIsOk(startShuttle) == false) //{ // err.Clear(); // err.Append("第二分车原则:待选车辆" + startShuttle.ToString() + "状态不可用!"); // //选择的车不可用 // startShuttle = -1; //} //else if (SelectedRGVSQLStatusIsOk(startShuttle, out err) == false) { //err.Clear(); //err.Append("第二分车原则:待选车辆" + selectrgv.ToString() + "状态不可用!"); startShuttle = -1; } else { err.Clear(); err.Append("第二分车原则:" + startShuttle.ToString()); } //if (startShuttle == -1) //{ // return -1; //} } #endregion if (startShuttle == -1) { // 第三选车原则从 rgvs 中挑选 #region 车状态不可用,则不会选车 //if (SelectedShuttleStatueIsOk(dev) == false) //{ // err.Clear(); // //车不可用,第三选车原则中不会被选择 // continue; //} if (SelectedRGVSQLStatusIsOk(dev, out err) == false) { err.Clear(); //车不可用,第三选车原则中不会被选择 continue; } //如果存在车指令,该指令的任务起点或终点,与车坐标相同,则不选择(防止任务没完成,车换巷道时和堆垛机货叉相撞) sql.Clear(); sql.Append("select * from t_monitor_task where f_deviceindex = ").Append(dev); dvs = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; if (dvs.Count > 0) { err.Clear(); //车还存在未完成的指令,第三选车原则中不会被选择 continue; } #endregion rgvs.Add(dev, new int[4] { z, x, y, w }); } } #endregion #region 4.第三分车原则,计算目标货位和所有穿梭板的距离,选择最小的 if (startShuttle == -1 && rgvs.Count != 0) { //rgvs中的所有车都是可用的! double smalllength = 1000000; foreach (var rgv in rgvs.Keys) { double r = GetRGVToTargetLength(startTarget, rgvs[rgv]); #region 充电中,则降低先选的优先级(认为最远) devinfo = Model.CGetInfo.GetDeviceInfo(rgv); if (devinfo.SplitByte_3 == 1) { r = 70.0; } #endregion if (r < smalllength) { smalllength = r; startShuttle = rgv; } } err.Clear(); err.Append("第三分车原则:" + startShuttle.ToString()); } else { err.Clear(); err.Append("无可用车辆"); } #endregion } #endregion rgvs.Clear(); //清空起点的可选车 #region 终点车号获取 #region 2.第二分车原则-1 if (endShuttle == -1) { } #endregion if (endShuttle == -1) { #region 3.找到该巷道内所有的车,空闲、充电(锁定,故障,monitor中有指令的除外) int lane = ccf.GetLanewayFromCellCode(endTargetCell, 1); sql.Clear(); sql.Append("select * from V_RGVINFO where (f_rgvz <> 0 and f_rgvx <> 0 and f_rgvy <> 0) and f_cur_lane = ").Append(lane); dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; for (int i = 0; i < dv.Count; i++) { int dev = Convert.ToInt32(dv[i]["f_deviceindex"]); if (dev == startShuttle) { continue;//起点和终点不能是同一个车 } #region 穿梭板坐标 int z = Convert.ToInt32(dv[i]["F_RgvZ"]); int x = Convert.ToInt32(dv[i]["F_RgvX"]); int y = Convert.ToInt32(dv[i]["F_RgvY"]); int w = Convert.ToInt32(dv[i]["F_RgvW"]); string rgvzxyw = string.Format("{0:D2}-{1:D2}-{2:D2}-{3:D2}", z, x, y, w); #endregion #region 3.第二分车原则,车坐标与目标位置相同(当故障,停用,断线,缺电时,也不选其他可用车辆) if (rgvzxyw == endTargetCell) { endShuttle = dev; //if (SelectedShuttleStatueIsOk(endShuttle) == false) //{ // err.Clear(); // err.Append("第二分车原则:待选车辆" + endShuttle.ToString() + "状态不可用!"); // //选择的车不可用 // endShuttle = -1; //} //else if (SelectedRGVSQLStatusIsOk(endShuttle, out err) == false) { //err.Clear(); //err.Append("第二分车原则:待选车辆" + selectrgv.ToString() + "状态不可用!"); endShuttle = -1; } else { err.Clear(); err.Append("第二分车原则:" + endShuttle.ToString()); } if (endShuttle == -1) { return -1; } } #endregion if (endShuttle == -1) { // 第三选车原则从 rgvs 中挑选 #region 车状态不可用,则不会选车 //if (SelectedShuttleStatueIsOk(dev) == false) //{ // err.Clear(); // //车不可用,第三选车原则中不会被选择 // continue; //} if (SelectedRGVSQLStatusIsOk(dev, out err) == false) { err.Clear(); //车不可用,第三选车原则中不会被选择 continue; } //如果存在车指令,该指令的任务起点或终点,与车坐标相同,则不选择(防止任务没完成,车换巷道时和堆垛机货叉相撞) sql.Clear(); sql.Append("select * from t_monitor_task where f_deviceindex = ").Append(dev); dvs = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; if (dvs.Count > 0) { err.Clear(); //车还存在未完成的指令,第三选车原则中不会被选择 continue; } #endregion rgvs.Add(dev, new int[4] { z, x, y, w }); } } #endregion #region 4.第三分车原则,计算目标货位和所有穿梭板的距离,选择最小的 if (endShuttle == -1 && rgvs.Count != 0) { //rgvs中的所有车都是可用的! double smalllength = 1000000; foreach (var rgv in rgvs.Keys) { double r = GetRGVToTargetLength(endTarget, rgvs[rgv]); #region 充电中,则降低先选的优先级(认为最远) devinfo = Model.CGetInfo.GetDeviceInfo(rgv); if (devinfo.SplitByte_3 == 1) { r = 70.0; } #endregion if (r < smalllength) { smalllength = r; endShuttle = rgv; } } err.Clear(); err.Append("第三分车原则:" + endShuttle.ToString()); } else { err.Clear(); err.Append("无可用车辆"); } #endregion } #endregion if (startShuttle != -1 && endShuttle != -1) { selectrgv = startShuttle * 100000 + endShuttle; } return selectrgv; } #endregion //发送穿梭板指令前,不能有其他任务已发送或执行中(停止充电和故障复位除外) public bool RGVOneTaskAheadDetect(int deviceIdx, int deviceKind, int MonitorIndex, out StringBuilder err) { DataView dv = new DataView(); err = new StringBuilder(); try { if (deviceKind == 44 && deviceIdx != 15010) { #region 故障复位,停止充电,不需要检测其他任务的状态 sql.Clear(); sql.Append("select * from t_Monitor_task where ( F_DeviceCommandIndex = 6 or F_DeviceCommandIndex = 50 or F_DeviceCommandIndex = 5 ) and F_MonitorIndex = ").Append(MonitorIndex); dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; if (dv.Count > 0) { return true; } #endregion sql.Clear(); sql.Append("select * from t_monitor_task where f_status >0 and f_deviceIndex =").Append(deviceIdx).Append(" and f_monitorIndex <>").Append(MonitorIndex); dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; if (dv.Count > 0) { err.Append(deviceIdx.ToString() + "存在其他任务未处理,不能执行!"); return false; } } return true; } catch (Exception ex) { throw ex; } finally { dv.Dispose(); } } public const int CoorNum = 6; //选择的车辆状态可用 public bool SelectedShuttleStatueIsOk(int rgv) { if (rgv == -1) { return false; } devinfo = Model.CGetInfo.GetDeviceInfo(rgv); //穿梭板必须在线 if (FINSTCPIP.SHICANGProtocol.ShuttleConnected(devinfo.RemoteIP) == false) { return false; } // 穿梭板不故障,电量可用 if (devinfo.RunState > 1) { return false; } //选车时,电量低 if (devinfo.SplitByte < FINSTCPIP.SHICANGProtocol.NeedToBettey) { return false; } return true; } public void OneClickToBattey() { //所有可工作的车,且无充电任务存在 StringBuilder sql = new StringBuilder(); sql.Append("select * from V_RGVINFO where F_DeviceIndex not in") .Append("(select FREMARK from T_Manage_Task where FREMARK in (select f_deviceIndex from t_base_device where f_devicekindIndex = 44) and FREMARK <> 15010 and FENDDEVICE = 17001 and ( FCONTROLTASKTYPE = 3 or FCONTROLTASKTYPE = 4) )"); DataView dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; for (int i = 0; i < dv.Count; i++) { int rgv = Convert.ToInt32(dv[i]["F_DeviceIndex"]); string ip = dv[i]["F_remoteIP"].ToString(); if (FINSTCPIP.SHICANGProtocol.ShuttleConnected(ip) == false) { continue; } if (FINSTCPIP.SHICANGProtocol.ShuttleInBetteyLane(rgv) == true) { //在充电货位中,且充电中 devinfo = Model.CGetInfo.GetDeviceInfo(rgv); if (devinfo.SplitByte_3 == 1) { continue; } } devinfo = Model.CGetInfo.GetDeviceInfo(rgv); if (devinfo.SplitByte == 100) { //continue; } sql.Clear(); sql.Append("select * from t_monitor_task where f_deviceindex = ").Append(rgv); DataView dvs = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; if (dvs.Count > 0) { CommonClassLib.CCarryConvert.WriteDarkCasket("Client", "已有任务,不生成充电任务", rgv.ToString(), ""); continue; } //生成充电任务 Model.Manage_Task ob = GetToBetteyManageTaskParam(rgv); ccf.InsertWCS_T_Manage_Task(ob); CommonClassLib.CCarryConvert.WriteDarkCasket("Client", "生成充电任务", rgv.ToString(), ""); } } //选择的车辆数据库中可用,未锁定,未预约锁,Monitor中无任务 public bool SelectedRGVSQLStatusIsOk(int rgv, out StringBuilder err) { DataView dv = new DataView(); err = new StringBuilder(); err.Clear(); bool flag = true; if (ccf.GetManTaskReserve(rgv) != 0) { err.Append("第二选车原则:" + rgv.ToString() + "被其他任务锁定!"); //选择的车有预约锁 flag = false; } if (ccf.GetDeviceLockedState(rgv) != 0) { err.Append("第二分车原则:" + rgv.ToString() + "被其他指令锁定!"); //选择的车被锁定 flag = false; } sql.Clear(); sql.Append("select * from T_Monitor_Task where F_DeviceIndex =").Append(rgv); dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; if (dv.Count > 0) { err.Append("第二分车原则:" + rgv.ToString() + "存在其他指令未完成!"); //选择的车有任务 flag = false; } sql.Clear(); sql.Append("select * from t_manage_task where fenddevice = 17001 and fPalletbarcode = ").Append(rgv); dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; if (dv.Count > 0) { err.Append("第二分车原则:" + rgv.ToString() + "存在充电任务"); flag = false; } #region 车已被预选 sql.Clear(); sql.Append("select * from t_manage_task where goods_barcode = ").Append(rgv); dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; if (dv.Count > 0) { err.Append("第二分车原则:" + rgv.ToString() + "车已被选"); flag = false; } #endregion return flag; } //根据选择的车,更新移车的相关指令坐标,如果不需要移车,则删除移车指令 //如果在充电位置,则将换边指令改为停止充电,将上车指令改为去B边 public bool SelectedRGVUpdateMonitorCoor(int fid, int rgv) { DataView dvs = new DataView(); int[] rgvCoor = new int[3]; try { #region 充电位置,则先替换指令 if (FINSTCPIP.SHICANGProtocol.ShuttleInBetteyLane(rgv) == true) { sql.Clear(); sql.Append("update t_monitor_task set f_devicecommandIndex = 50, F_AheadDetect = '' where f_devicecommandIndex = 10 and f_monitorIndex = (select top 1 f_monitorIndex from t_monitor_task where f_devicecommandIndex = 10 and F_ManageTaskIndex = ").Append(fid).Append(")"); sql.Append(" "); sql.Append("update t_monitor_task set f_devicecommandIndex = 7, F_AheadDetect = '' where f_devicecommandIndex = 3 and F_DeviceIndex in (select F_DeviceIndex from T_Base_Device where F_DeviceKindIndex = 44) and F_ManageTaskIndex = ").Append(fid); dbo.ExceSQL(sql.ToString()); } #endregion int Managefid = fid; sql.Clear(); sql.Append("select * from t_base_RGVInfo where F_RgvIndex = ").Append(rgv); dvs = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; if (dvs.Count > 0) { rgvCoor[0] = Convert.ToInt32(dvs[0]["F_RgvZ"]); rgvCoor[1] = Convert.ToInt32(dvs[0]["F_RgvX"]); rgvCoor[2] = Convert.ToInt32(dvs[0]["F_RgvY"]); } sql.Clear(); sql.Append("select * from t_monitor_task where F_ManageTaskIndex = ").Append(Managefid) .Append(" and F_NumParam4 = ").Append(rgvCoor[0]).Append(" and F_NumParam5 = ").Append(rgvCoor[1]).Append(" and F_NumParam6 =").Append(rgvCoor[2]); dvs = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; if (dvs.Count > 0) {//车和目标地址相同,删除所有0,0,0,r[0],r[1],r[2]的指令 sql.Clear(); sql.Append("delete t_monitor_task where F_ManageTaskIndex =").Append(Managefid) .Append(" and f_numParam1 = 0 and f_numParam2 = 0 and f_numParam3 = 0 and ") .Append(" f_numparam4 = ").Append(rgvCoor[0]).Append(" and f_numParam5 = ").Append(rgvCoor[1]).Append(" and f_numParam6 = ").Append(rgvCoor[2]); dbo.ExceSQL(sql.ToString()); } sql.Clear(); sql.Append("select distinct F_RouteIDSub from T_Base_Route_Device where F_DeviceIndex = ").Append(rgv); //.Append(" and F_Routeid = 1"); dvs = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; if (dvs.Count > 0) { string routesubid = dvs[0]["F_RouteIDSub"].ToString(); //更新车号 sql.Remove(0, sql.Length); sql.Append("UPDATE T_Monitor_Task SET F_DeviceIndex = ").Append(rgv.ToString()).Append(" WHERE (F_ManageTaskIndex = ").Append(Managefid).Append(" AND F_DeviceIndex in (select f_deviceIndex from t_base_device where f_devicekindIndex = 44) AND F_deviceIndex <> ").Append(rgv.ToString()).Append(")"); //dbo.ExceSQL(sql.ToString()); //更新路径 //sql.Clear(); sql.Append(" "); sql.Append("update t_monitor_task set f_routeid = ").Append(routesubid).Append(" WHERE F_deviceIndex in (select f_deviceIndex from t_base_device where f_devicekindIndex = 44) and F_ManageTaskIndex = ").Append(Managefid); //dbo.ExceSQL(sql.ToString()); //更新起点坐标 //sql.Clear(); sql.Append(" "); sql.Append("update t_monitor_task set f_NumParam1 = ").Append(rgvCoor[0]) .Append(", F_NumParam2 = ").Append(rgvCoor[1]).Append(", F_NumParam3 = ").Append(rgvCoor[2]) .Append(" WHERE F_ManageTaskIndex = ").Append(Managefid).Append(" and f_NumParam1 = 0 AND F_NumParam2 = 0 AND F_NumParam3=0"); //dbo.ExceSQL(sql.ToString()); //更新Runinglock //sql.Remove(0, sql.Length); sql.Append(" "); sql.Append("UPDATE T_Monitor_Task SET F_RunningLock = ").Append(rgv.ToString()).Append(" WHERE (F_ManageTaskIndex = ").Append(Managefid).Append(" AND F_RunningLock in (select f_deviceIndex from t_base_device where f_devicekindIndex = 44) AND F_deviceIndex <> ").Append(rgv.ToString()).Append(")"); //dbo.ExceSQL(sql.ToString()); //更新送货指令F_rgvno,用来添加将送 //sql.Remove(0, sql.Length); sql.Append(" "); sql.Append("UPDATE T_Monitor_Task SET F_agvno = ").Append(rgv.ToString()).Append(" WHERE (F_ManageTaskIndex = ").Append(Managefid).Append(" AND F_deviceIndex in (select f_deviceIndex from t_base_device where f_devicekindIndex = 1 or f_devicekindindex = 44) )"); dbo.ExceSQL(sql.ToString()); //SetStackSendConveyorManReserve(MonirotIdx, rgv); } return true; } catch (Exception ex) { throw ex; } finally { dvs.Dispose(); } } public bool SelectedRGVUpdateMonitorCoor_YIKU(int fid, int rgv) { DataView dvs = new DataView(); int startShuttle = rgv / 100000; int endShuttle = rgv % 100000; int[] rgvCoor = new int[3]; try { #region 充电位置,则先替换指令 if (FINSTCPIP.SHICANGProtocol.ShuttleInBetteyLane(rgv) == true) { sql.Clear(); sql.Append("update t_monitor_task set f_devicecommandIndex = 50, F_AheadDetect = '' where f_devicecommandIndex = 10 and f_monitorIndex = (select top 1 f_monitorIndex from t_monitor_task where f_devicecommandIndex = 10 and F_ManageTaskIndex = ").Append(fid).Append(")"); sql.Append(" "); sql.Append("update t_monitor_task set f_devicecommandIndex = 7, F_AheadDetect = '' where f_devicecommandIndex = 3 and F_DeviceIndex in (select F_DeviceIndex from T_Base_Device where F_DeviceKindIndex = 44) and F_ManageTaskIndex = ").Append(fid); dbo.ExceSQL(sql.ToString()); } #endregion int Managefid = fid; for (int i = 0; i < 2; i++) { if (i == 0) rgv = startShuttle; if (i == 1) rgv = endShuttle; sql.Clear(); sql.Append("select * from t_base_RGVInfo where F_RgvIndex = ").Append(rgv); dvs = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; if (dvs.Count > 0) { rgvCoor[0] = Convert.ToInt32(dvs[0]["F_RgvZ"]); rgvCoor[1] = Convert.ToInt32(dvs[0]["F_RgvX"]); rgvCoor[2] = Convert.ToInt32(dvs[0]["F_RgvY"]); } sql.Clear(); sql.Append("select * from t_monitor_task where F_ManageTaskIndex = ").Append(Managefid) .Append(" and F_NumParam4 = ").Append(rgvCoor[0]).Append(" and F_NumParam5 = ").Append(rgvCoor[1]).Append(" and F_NumParam6 =").Append(rgvCoor[2]); dvs = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; if (dvs.Count > 0) {//车和目标地址相同,删除所有0,0,0,r[0],r[1],r[2]的指令 sql.Clear(); sql.Append("delete t_monitor_task where F_ManageTaskIndex =").Append(Managefid) .Append(" and f_numParam1 = f_numparam4 and f_numParam2 = f_numParam5 and f_numParam3 = f_numParam6 and ") .Append(" f_numparam4 = ").Append(rgvCoor[0]).Append(" and f_numParam5 = ").Append(rgvCoor[1]).Append(" and f_numParam6 = ").Append(rgvCoor[2]) .Append(" and ((f_deviceindex =").Append(rgv).Append(" and f_devicecommandindex not in (1,2)) or (F_DeviceCommandIndex in (7,8)))"); dbo.ExceSQL(sql.ToString()); } } return true; } catch (Exception ex) { throw ex; } finally { dvs.Dispose(); } } //A,B为空间的两个点,A0,A1,A2为三维坐标 public double GetRGVToTargetLength(int[] A, int[] B) { if (A[0] == 0 && A[1] == 0 && A[2] == 0) { return -1; } if (B[0] == 0 && B[1] == 0 && B[2] == 0) { return -1; } double length1 = Math.Pow((A[0] - B[0]), 2) + Math.Pow((A[1] - B[1]), 2) + Math.Pow((A[2] - B[2]), 2); return Math.Sqrt(length1); } //返回所有可以取到穿梭板的堆垛机(未考虑堆垛机禁用/故障) public List GetAllUsefulStackFromRGVLocat(string rgvcell) { List stacks = new List(); try { char[] cc = new char[1] { '-' }; string[] split = rgvcell.Split(cc); int z = Convert.ToInt32(split[0]); if (z == 1) { stacks.Add(11001); } if (z == 2) { stacks.Add(11001); stacks.Add(11002); } if (z == 3) { stacks.Add(11002); stacks.Add(11003); } if (z == 4) { stacks.Add(11003); } return stacks; } catch (Exception ex) { throw ex; } } //获得可用充电位的坐标 public int[] GetbetteyCoordinateFromRGV(int rgv) { char[] cc = new char[1] { '-' }; string[] split; int[] rt = new int[8] { 0, 0, 0, 0, 0, 0, 0, 0 }; #region 车在充电货位中,直接选该充电位 string rgvcell = FINSTCPIP.SHICANGProtocol.GetShuttleLocation(rgv); if (FINSTCPIP.SHICANGProtocol.ShuttleInBetteyLane(rgv) == true) { split = rgvcell.Split(cc); rt[3] = Convert.ToInt32(split[0]);//排Z rt[4] = Convert.ToInt32(split[1]);//列X rt[5] = Convert.ToInt32(split[2]);//层Y //rt[7] = Convert.ToInt32(split[3]);//位W return rt; } #endregion DataView dv = new DataView(); try { sql.Remove(0, sql.Length); sql.Append("select F_DeviceIndex, F_BindingDevice from T_Base_Device, T_Base_RGVInfo,T_Base_Lane_Gate where F_DeviceKindIndex = 9 and F_LockedState <> -1 and F_BindingDevice NOT IN (select FENDCELL from T_Manage_Task ) and f_cur_lane = F_LaneIndex and F_LaneGateDeviceIndex = F_DeviceIndex and F_RgvIndex = ").Append(rgv); dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; for (int i = 0; i < dv.Count; i++) { string betteygatecell = dv[i]["F_BindingDevice"].ToString(); if (FINSTCPIP.SHICANGProtocol.LaneCoorAlreadyHaveRGV(betteygatecell) != -1) { continue; } split = betteygatecell.Split(cc); rt[3] = Convert.ToInt32(split[0]);//排Z rt[4] = Convert.ToInt32(split[1]);//列X rt[5] = Convert.ToInt32(split[2]);//层Y //rt[7] = Convert.ToInt32(split[3]);//位W break; } return rt; } catch (Exception ex) { throw ex; } finally { cc = null; split = null; rt = null; dv.Dispose(); } } public int GetStackFromManage(int fid) { DataView dv = new DataView(); try { sql.Clear(); sql.Append(" select fstack from t_manage_task where fid = '").Append(fid).Append("'"); dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; if (dv.Count > 0) { return Convert.ToInt32(dv[0]["fstack"]); } return -1; } catch (Exception ex) { throw ex; } finally { dv.Dispose(); } } public int GetLaneFromManage(int fid) { DataView dv = new DataView(); try { sql.Clear(); sql.Append(" select FLANEWAY from t_manage_task where fid = ").Append(fid); dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; if (dv.Count > 0) { return Convert.ToInt32(dv[0]["FLANEWAY"]); } return -1; } catch (Exception ex) { RefreshMonitorEventArgs rmea = new RefreshMonitorEventArgs("tsStatus", "向管理申请入库任务时发生错误:" + ex.StackTrace + ex.Message); //OnRefreshMonitor(rmea); return -1; //20140218 } finally { dv.Dispose(); } } public int GetRouteSubFromStack(int stack) { DataView dv = new DataView(); try { int lane = ccf.GetLaneWayFromLaneInfo(stack); sql.Clear(); sql.Append(" select f_routeid from t_base_route where f_startdevice = 15010 and f_enddevice = ").Append(lane); dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; if (dv.Count > 0) { return Convert.ToInt32(dv[0]["f_routeid"]) * 1000 + 1; } return -1; } catch (Exception ex) { throw ex; } finally { dv.Dispose(); } } public int GetRouteSubFromShuttle(int rgv) { DataView dv = new DataView(); try { sql.Clear(); sql.Append(" select f_routeid from t_base_route where f_startdevice = ").Append(rgv); dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; if (dv.Count > 0) { return Convert.ToInt32(dv[0]["f_routeid"]) * 1000 + 1; } return -1; } catch (Exception ex) { throw ex; } finally { dv.Dispose(); } } public int GetLaneFromSCShuttle(int rgv) { DataView dv = new DataView(); try { sql.Clear(); sql.Append(" select * from t_base_rgvInfo where f_rgvindex = '").Append(rgv).Append("'"); dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; if (dv.Count > 0) { return Convert.ToInt32(dv[0]["f_cur_lane"]); } return 0; } catch (Exception ex) { throw ex; } finally { dv.Dispose(); } } //更新RGV所在的巷道(当RGV可以被两个堆垛机搬运时,有一个当前巷道) //每次堆垛机取穿梭板后更改 public void UpdateRGVLane(int rgv, int stack) { DataView dv = new DataView(); try { sql.Clear(); sql.Append("update t_base_rgvinfo set f_cur_lane = (select F_LaneNo from T_Base_StackInfo where F_StackIndex = ").Append(stack).Append(") where F_RgvIndex =").Append(rgv); dbo.ExceSQL(sql.ToString()); } catch (Exception ex) { throw ex; } finally { dv.Dispose(); } } public int GetStackFromLane(int lane) { DataView dv = new DataView(); try { sql.Clear(); sql.Append(" select * from t_base_stackinfo where f_laneno = '").Append(lane).Append("'"); dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; if (dv.Count > 0) { return Convert.ToInt32(dv[0]["F_StackIndex"]); } return 0; } catch (Exception ex) { throw ex; } finally { dv.Dispose(); } } //返回该任务已分的车辆 public int GetRGVFromManage(int fid) { DataView dv = new DataView(); try { sql.Clear(); sql.Append("select Goods_barcode from t_manage_task where fid =").Append(fid).Append(" and GOODS_BARCODE like '1501%'"); dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; if (dv.Count > 0) { return Convert.ToInt32(dv[0]["Goods_barcode"]); } else { return -1; } } catch (Exception ex) { RefreshMonitorEventArgs rmea = new RefreshMonitorEventArgs(System.Reflection.MethodBase.GetCurrentMethod().Name, ":" + ex.StackTrace + ex.Message); return -1; //20140218 } finally { dv.Dispose(); } } #region 货位的相关方法 //给定一个货位,返回在改组中的位置,1-(最后一个存,不使用穿梭板),2-(倒数第二个存,存完需要把板取走),0-里面的货位 public int GetCellFlag_OneTwoZero(string cell) { DataView dv = new DataView(); try { sql.Clear(); sql.Append("select fcellflag from st_cell where fcellcode = '").Append(cell).Append("'"); dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; if (dv.Count > 0) { return Convert.ToInt32(dv[0]["fcellflag"]); } else { return -1; } #region 动态寻找当前货位的标志,sql 有点卡 //string[] cellzxy = cell.Split('-'); //int z = Convert.ToInt32(cellzxy[0]); //int x = Convert.ToInt32(cellzxy[1]); //int y = Convert.ToInt32(cellzxy[2]); //int w = Convert.ToInt32(cellzxy[3]); ////这个sql好乱,找出同一组(zxy相同)的货位,且在给定货位的外侧(根据存储方式,small则是大位,big则是小位) //sql.Clear(); //sql.Append("select Count(fid) as OutSideCellCount from ST_CELL where f_z = ").Append(z) // .Append(" and f_x = ").Append(x).Append(" and f_y = ").Append(y).Append(" and F_W <> ").Append(w). // Append(" and FFirstInputLocat = (select FFirstInputLocat from st_cell where FCELLCODE = '").Append(cell). // Append("' ) and ((FFirstInputLocat = 'small' and F_W > ").Append(w).Append(") or (FFirstInputLocat = 'big' and F_W < ").Append( w ).Append("))"); //dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; //if (dv.Count > 0) //{ // int cellCount = Convert.ToInt32(dv[0]["OutSideCellCount"]); // if (cellCount == 0) // return 1; //外侧没有货位,返回1,表示该货位是最后一个入库位置 // else if (cellCount == 1) // return 2; //外侧有一个货位,返回2,表示该货位是倒数第二个入库位置 // else // return 0; //外侧有两个以上货位(含两个),返回0,穿梭板常规入库 //} //return -1; #endregion } catch (Exception ex) { throw ex; } finally { dv.Dispose(); } } //给一个货位,返回所有同组的货位(相同排列层也不一定同组) public List GetAllSameGroupCell(string cell) { DataView dv = new DataView(); List allcells = new List(); try { sql.Clear(); sql.Append(string.Format(" select FCELLCODE, F_W, FFirstInputLocat from st_cell where FCELLCODE like '{0}%' and FFirstInputLocat = " + "(select FFirstInputLocat from ST_CELL where FCELLCODE = '{1}') order by F_W", cell.Substring(0, 8), cell)); dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; for (int i = 0; i < dv.Count; i++) { allcells.Add(dv[i]["FCELLCODE"].ToString()); } return allcells; } catch (Exception ex) { throw ex; } finally { dv.Dispose(); } } //给一个货位,返回所有外侧货位 public List GetAllOutSideCell(string cell) { DataView dv = new DataView(); List allcells = new List(); try { int fw = GetWFromCell(cell); sql.Clear(); sql.Append(string.Format(" select FCELLCODE, F_W, FFirstInputLocat from st_cell where FCELLCODE like '{0}%' and FFirstInputLocat = " + "(select FFirstInputLocat from ST_CELL where FCELLCODE = '{1}') and FCELLCODE <> '{1}'", cell.Substring(0, 8), cell)); dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; for (int i = 0; i < dv.Count; i++) { //找出所有同组货位中,位坐标大于当前货位的 if (Convert.ToInt32(dv[i]["F_W"]) > fw) { allcells.Add(dv[i]["FCELLCODE"].ToString()); } } return allcells; } catch (Exception ex) { throw ex; } finally { dv.Dispose(); } } //给一个货位,返回所有内侧货位 public List GetAllInSideCell(string cell) { DataView dv = new DataView(); List allcells = new List(); try { int fw = GetWFromCell(cell); sql.Clear(); sql.Append(string.Format(" select FCELLCODE, F_W, FFirstInputLocat from st_cell where FCELLCODE like '{0}%' and FFirstInputLocat = " + "(select FFirstInputLocat from ST_CELL where FCELLCODE = '{1}') and FCELLCODE <> '{1}'", cell.Substring(0, 8), cell)); dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; for (int i = 0; i < dv.Count; i++) { //找出所有同组货位中,位坐标小于当前货位的 if (Convert.ToInt32(dv[i]["F_W"]) < fw) { allcells.Add(dv[i]["FCELLCODE"].ToString()); } } return allcells; } catch (Exception ex) { throw ex; } finally { dv.Dispose(); } } //给一个货位,返回同组最外侧的货位 public string GetOutestCell(string cell) { DataView dv = new DataView(); string outestcell = string.Empty; try { //int fw = GetWFromCell(cell); sql.Clear(); sql.Append(string.Format(" select FCELLCODE, F_W, FFirstInputLocat from st_cell where fcellflag = 1 and FCELLCODE like '{0}%' and FFirstInputLocat = " + "(select FFirstInputLocat from ST_CELL where FCELLCODE = '{1}') ", cell.Substring(0, 8), cell)); dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; if (dv.Count > 0) { outestcell = dv[0]["FCELLCODE"].ToString(); } return outestcell; } catch (Exception ex) { throw ex; } finally { dv.Dispose(); } } //给一个货位组的三维坐标和堆垛机,返回该组最外侧货位 public string GetOutestCellFromZXY(int z, int x, int y, int stack) { DataView dv = new DataView(); string zxycell = FINSTCPIP.SHICANGProtocol.ToLaneCoorZXY(z, x, y); string outestcell = zxycell; try { if (FINSTCPIP.SHICANGProtocol.IsBetteyCoor(zxycell) == true || FINSTCPIP.SHICANGProtocol.IsChangeLaneCell(zxycell) == true) { return outestcell; } //int fw = GetWFromCell(zxycell); sql.Clear(); sql.Append(string.Format(" select FCELLCODE, F_W, FFirstInputLocat from st_cell where fcellflag = 1 and FCELLCODE like '{0}%' and FStack = {1}", zxycell.Substring(0, 8), stack)); dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; if (dv.Count == 1) { outestcell = dv[0]["FCELLCODE"].ToString(); } return outestcell; } catch (Exception ex) { throw ex; } finally { dv.Dispose(); } } //存在外侧货位的任务(在出库完成,入库删除时调用),返回所有任务的 fid public List IfExistOutSideCellTaskFromManage(int Managetaskkind, int Managetaskindex) { DataView dv = new DataView(); List result = new List(); try { string cell = string.Empty; StringBuilder sql = new StringBuilder(); int controltype = ccf.GetFCONTROLTASKTYPEFromManageTask(Managetaskkind, Managetaskindex); if (controltype == 2) { cell = GetStartCellFromManage(Managetaskindex); } else { cell = GetEndCellFromManage(Managetaskindex); } //获取所有外侧的货位 List allcells = GetAllOutSideCell(cell); #region 将所有的货位拼接成字符串 StringBuilder notion = new StringBuilder(); if (controltype == 1) { notion.Append(" and FENDCELL in ").Append(CellsToSql(allcells)); } else if (controltype == 2) { notion.Append(" and FSTARTCELL in ").Append(CellsToSql(allcells)); } #endregion sql.Clear(); sql.Append("select * from T_Manage_Task where 1=1").Append(notion); dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; for (int i = 0; i < dv.Count; i++) { //MessageBox.Show("存在相同货位大位的出库任务" + dv[i]["fid"] + ",不能完成", "", MessageBoxButtons.OK, MessageBoxIcon.Error); result.Add(Convert.ToInt32(dv[i]["fid"])); ; } return result; } catch (Exception ex) { throw ex; } finally { dv.Dispose(); } } //存在里侧货位的任务(在出库删除,入库完成时调用)返回任意一个任务的 fid public List IfExistInSideCellTaskFromManage(int Managetaskkind, int Managetaskindex) { DataView dv = new DataView(); List result = new List(); try { string cell = string.Empty; StringBuilder sql = new StringBuilder(); int controltype = ccf.GetFCONTROLTASKTYPEFromManageTask(Managetaskkind, Managetaskindex); if (controltype == 2) { cell = GetStartCellFromManage(Managetaskindex); } else { cell = GetEndCellFromManage(Managetaskindex); } //获取所有外侧的货位 List allcells = GetAllInSideCell(cell); #region 将所有的货位拼接成字符串 StringBuilder notion = new StringBuilder(); if (controltype == 1) { notion.Append(" and FENDCELL in ").Append(CellsToSql(allcells)); } else if (controltype == 2) { notion.Append(" and FSTARTCELL in ").Append(CellsToSql(allcells)); } #endregion sql.Clear(); sql.Append("select * from T_Manage_Task where 1=1").Append(notion); dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; for (int i = 0; i < dv.Count; i++) { //MessageBox.Show("存在相同货位大位的出库任务" + dv[i]["fid"] + ",不能完成", "", MessageBoxButtons.OK, MessageBoxIcon.Error); result.Add(Convert.ToInt32(dv[i]["fid"])); ; } return result; } catch (Exception ex) { throw ex; } finally { dv.Dispose(); } } //存在外侧货位的任务(在出库完成,入库删除时调用),返回所有任务的 fid public List IfExistOutSideCellTaskFromIOCONTROL(int Managetaskkind, int Managetaskindex) { DataView dv = new DataView(); List result = new List(); try { string cell = string.Empty; StringBuilder sql = new StringBuilder(); int controltype = ccf.GetFCONTROLTASKTYPEFromManageTask(Managetaskkind, Managetaskindex); if (controltype == 2) { cell = GetStartCellFromManage(Managetaskindex); } else { cell = GetEndCellFromManage(Managetaskindex); } //获取所有外侧的货位 List allcells = GetAllOutSideCell(cell); #region 将所有的货位拼接成字符串 StringBuilder notion = new StringBuilder(); if (controltype == 1) { notion.Append(" and END_DEVICE_CODE in ").Append(CellsToSql(allcells)); } else if (controltype == 2) { notion.Append(" and START_DEVICE_CODE in ").Append(CellsToSql(allcells)); } #endregion sql.Clear(); sql.Append("select * from IO_CONTROL where 1=1").Append(notion); dv = dboM.ExceSQL(sql.ToString()).Tables[0].DefaultView; for (int i = 0; i < dv.Count; i++) { //MessageBox.Show("存在相同货位大位的出库任务" + dv[i]["fid"] + ",不能完成", "", MessageBoxButtons.OK, MessageBoxIcon.Error); result.Add(Convert.ToInt32(dv[i]["CONTROL_ID"])); ; } return result; } catch (Exception ex) { throw ex; } finally { dv.Dispose(); } } public List IfExistInSideCellTaskFromIOCONTROL(int Managetaskkind, int Managetaskindex) { DataView dv = new DataView(); List result = new List(); try { string cell = string.Empty; StringBuilder sql = new StringBuilder(); int controltype = ccf.GetFCONTROLTASKTYPEFromManageTask(Managetaskkind, Managetaskindex); if (controltype == 2) { cell = GetStartCellFromManage(Managetaskindex); } else { cell = GetEndCellFromManage(Managetaskindex); } //获取所有外侧的货位 List allcells = GetAllInSideCell(cell); #region 将所有的货位拼接成字符串 StringBuilder notion = new StringBuilder(); if (controltype == 1) { notion.Append(" and END_DEVICE_CODE in ").Append(CellsToSql(allcells)); } else if (controltype == 2) { notion.Append(" and START_DEVICE_CODE in ").Append(CellsToSql(allcells)); } #endregion sql.Clear(); sql.Append("select * from IO_CONTROL where 1=1").Append(notion); dv = dboM.ExceSQL(sql.ToString()).Tables[0].DefaultView; for (int i = 0; i < dv.Count; i++) { //MessageBox.Show("存在相同货位大位的出库任务" + dv[i]["fid"] + ",不能完成", "", MessageBoxButtons.OK, MessageBoxIcon.Error); result.Add(Convert.ToInt32(dv[i]["control_id"])); ; } return result; } catch (Exception ex) { throw ex; } finally { dv.Dispose(); } } //IOCONTROL中该货位的任务是最外侧的未获取任务 public bool IsOutSideTaskINIOCONTROL(string cell) { DataView dv = new DataView(); try { List alloutcells = GetAllOutSideCell(cell); string cells = CellsToSql(alloutcells); sql.Clear(); sql.Append("select * from IO_CONTROL where CONTROL_STATUS = 0 AND START_DEVICE_CODE in").Append(cells); dv = dboM.ExceSQL(sql.ToString()).Tables[0].DefaultView; if (dv.Count == 0) { return true; } else { return false; } } catch (Exception ex) { throw ex; } finally { dv.Dispose(); } } //完成或删除任务时,如果存在里侧货位或者外侧货位,不能执行 public bool IsOkForDeleteOrCompleteTask(int fid) { DataView dv = new DataView(); try { sql.Clear(); sql.Append("select * from t_manage_task where fid =").Append(fid); return true; } catch (Exception ex) { throw ex; } finally { dv.Dispose(); } } //将所有的货位拼接成字符串,返回格式(包括括号):('01-01-01-01','01-01-01-02','') public string CellsToSql(List allcells) { StringBuilder notion = new StringBuilder(); notion.Append(" ("); foreach (var temp in allcells) { notion.Append("'").Append(temp).Append("',"); } notion.Append("'' )"); return notion.ToString(); } //返回车当前货位中,逻辑上应该在A边还是B边 //充电位置一定是B,1排是B,4排是A。 public string GetLogicAB(int rgv) { string rgvcell = FINSTCPIP.SHICANGProtocol.GetShuttleLocation(rgv); string correctAB = string.Empty; if (FINSTCPIP.SHICANGProtocol.ShuttleInBetteyLane(rgv) == true) { correctAB = "B";//充电货位,返回B边 } else if (FINSTCPIP.SHICANGProtocol.ShuttleInChangeLane(rgv) == true) { correctAB = "";//在交换巷道中,AB边混乱,没弄好 } else { correctAB = GetLogicABFromCellAndLane(rgvcell); } return correctAB; } public int GetWFromCell(string cell) { char[] cc = new char[1] { '-' }; string[] ss = cell.Split(cc); if (ss.Length == 4) { return Convert.ToInt32(ss[3]); } else { return 0; } } public string GetFFirstInputLocatFromCell(string cell) { DataView dv = new DataView(); try { sql.Clear(); sql.Append("select FFirstInputLocat from ST_CELL where FCELLCODE ='").Append(cell).Append("'"); dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; if (dv.Count > 0) { return dv[0]["FFirstInputLocat"].ToString(); ; } return string.Empty; } catch (Exception ex) { throw ex; } finally { dv.Dispose(); } } // private string GetLogicABFromCellAndLane(string cell) { if (cell.Length != 11) { return ""; } DataView dv = new DataView(); try { sql.Clear(); sql.Append("select FLogicAB from ST_CELL where FCELLCODE ='").Append(cell).Append("'"); dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; if (dv.Count > 0) { return dv[0]["FLogicAB"].ToString(); ; } return string.Empty; } catch (Exception ex) { throw ex; } finally { dv.Dispose(); } } #endregion #region 充电 public Model.Manage_Task GetToBetteyManageTaskParam(int rgv) { int controltype = 4;//站台间移库 int managetaskkind = 2; //自动任务 int lane = GetLaneFromSCShuttle(rgv); int stack = GetStackFromLane(lane); string rgvcell = FINSTCPIP.SHICANGProtocol.GetShuttleLocation(rgv); string time = ccf.GetDateTime(); //生成充电任务 Model.Manage_Task ob = new Model.Manage_Task { _fid = ccf.GetTempManageIdx(), _mantaskkindid = managetaskkind, _palletcode = rgv.ToString(), _relativeid = "-1", _mantasktype = 2.ToString(), _controltype = controltype.ToString(), _tasklevel = 0.ToString(), _startdevice = lane.ToString(), _startcell = rgvcell, _enddevice = 17001.ToString(), _endcell = "0", //GetBetteyLocation(rgv),//此处的位置是虚拟的站台,实际的充电在拆分时指定 _begintime = time, _remark = rgv.ToString(), _laneway = lane.ToString(), _stack = stack.ToString(), _goodbarcode = rgv.ToString() }; return ob; } #endregion #region 车相关的提前检测 //检测设备的预约锁,是否和当前要执行的指令相同 public bool FRAheadDetectOk(int device, int mtifid, out string err) { err = string.Empty; int devmanageid = ccf.GetManTaskReserve(device);//设备的预约锁 if (devmanageid != mtifid && devmanageid != 0) { err = "车被任务:" + mtifid + "预约。"; return false; } return true; } //检测穿梭板的空闲,坐标正确,空闲,无货, public bool CheckRGVIdle(int device, int mtifid, out string err) { err = string.Empty; return false; } StringBuilder aheaderr = new StringBuilder(); //检测堆垛机可能干涉的情况 public bool FZAheadDetectOk(string ahead, int rgv, out string err) { DataView dv = new DataView(); aheaderr.Clear(); int s = 0; string rgvcell = FINSTCPIP.SHICANGProtocol.GetShuttleLocation(rgv); //堆垛机状态(此处应该根据车坐标获取所有堆垛机) List stacks = GetAllUsefulStackFromRGVLocat(rgvcell); for (int i = 0; i < stacks.Count; i++) { devinfo = Model.CGetInfo.GetDeviceInfo(stacks[i]); #region 堆垛机列和层与穿梭板位置相同 char[] dd = new char[1] { '-' }; string[] rgvzxy = rgvcell.Split(dd); if (rgvzxy[1] == devinfo.XCoor.ToString() && rgvzxy[2] == devinfo.YCoor.ToString()) { if (devinfo.RunState != 0) { if (devinfo.RunState != 1) { aheaderr.Append("堆垛机位置可能会影响到穿梭板!"); s += 1; } else { //堆垛机运行时,根据堆垛机任务来判断,如果任务无法获取坐标,则所有车不许动 int stacktaskid = devinfo.TaskNo; sql.Clear(); sql.Append("select * from t_monitor_task where f_monitorIndex = ").Append(stacktaskid); dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; if (dv.Count == 0) { aheaderr.Append("堆垛机位置可能会影响到穿梭板!"); s += 1; } else if (dv.Count > 0) { //堆垛机取货坐标和穿梭车相同 int z = Convert.ToInt32(dv[0]["F_NumParam1"]); int x = Convert.ToInt32(dv[0]["F_NumParam2"]); int y = Convert.ToInt32(dv[0]["F_NumParam3"]); string startcell = GetOutestCellFromZXY(z, x, y, stacks[i]); if (rgvcell == startcell) { aheaderr.Append("堆垛机正在执行同货位任务!"); s += 1; } //堆垛机送货坐标和穿梭车相同 z = Convert.ToInt32(dv[0]["F_NumParam4"]); x = Convert.ToInt32(dv[0]["F_NumParam5"]); y = Convert.ToInt32(dv[0]["F_NumParam6"]); string endcell = GetOutestCellFromZXY(z, x, y, stacks[i]); if (rgvcell == endcell) { aheaderr.Append("堆垛机正在执行同货位任务!"); s += 1; } } } #region 存在堆垛机手工指令时,不能给穿梭板发任务指令 sql.Clear(); sql.Append("select * from t_monitor_task where F_ManageTASKKINDINDEX = 4 and F_deviceIndex = ").Append(stacks[i]); dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; if (dv.Count > 0) { aheaderr.Append("存在堆垛机手工指令!"); s += 1; } #endregion } } #endregion } err = aheaderr.ToString(); if (s > 0) { return false; } else { return true; } } public bool InsertRGVMonitor(int rgv, int order, int OldMonitorIndex, string aheadDetect = "") { int mti = ccf.GetManageTaskKindIndexFromMonitor(OldMonitorIndex); int fid = ccf.GetManageTaskIndexfromMonitor(OldMonitorIndex); int[] Coor = ccf.GetCoordinatesFromMonitorTask(OldMonitorIndex); if (CDisassembleTask.DeviceAndOrderExitInMonitor(mti, fid, rgv, order, 0, Coor) == false) { int mindex = OldMonitorIndex - 1; Model.Monitor_Task ob = new Model.Monitor_Task { _manfid = fid, _mankind = mti, _mindex = mindex, _level = "10", _device = rgv.ToString(), _command = order.ToString(), _routeid = ccf.GetRouteIDsub(rgv).ToString(), _status = 0.ToString(), _param1 = Coor[0].ToString(), _param2 = Coor[1].ToString(), _param3 = Coor[2].ToString(), _param4 = Coor[3].ToString(), _param5 = Coor[4].ToString(), _param6 = Coor[5].ToString(), _aheaddetect = aheadDetect.ToString(), //_runningLock = RunningLock.ToString(), //_txtparam = drv["FPALLETBARCODE"].ToString(), //_useAwayFork = drv["FUseAwayFork"].ToString(), //_priorMonitor = lifterUP.ToString(), //_agvTask = snextq.ToString(), //_aGVNextTask = snexts.ToString() }; return ccf.InsertWCS_T_Monitor_Task(ob); } return false; } public bool insertJIANGSONG(int DeviceIdx, int rgv, int TaskIdx, out string err) { DataView dv = new DataView(); devinfo = Model.CGetInfo.GetDeviceInfo(rgv); if (devinfo.ControlMode != 1 || devinfo.RunState != 0 || devinfo.SplitByte_0 != 0) { //当入库送货时,穿梭板不空闲、有货、叉车模式时,插入将送指令 sql.Clear(); sql.Append("select * from T_Monitor_Task where F_agvNo in (select F_DeviceIndex from t_base_device where F_DeviceKindIndex = 44) and f_monitorIndex =").Append(TaskIdx); dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; if (dv.Count > 0) { int insertmonitor = Convert.ToInt32(dv[0]["F_AGVTask"]); { //送货时,穿梭板未就绪,插入将送指令 sql.Clear(); sql.Append("INSERT INTO T_Monitor_Task ").Append( "(F_ManageTaskIndex, F_ManageTASKKINDINDEX, F_MonitorIndex,F_MonitorTaskLevel,").Append( " F_DeviceIndex, F_DeviceCommandIndex, F_RouteID, F_Status,F_NumParam1, F_NumParam2,").Append( " F_NumParam3, F_NumParam4,F_NumParam5, F_NumParam6,F_AheadDetect,F_RunningLock,F_TxtParam,F_UseAwayFork,F_PriorMonitor,F_AGVTask,F_AGVNextTask)").Append( "VALUES (").Append(dv[0]["F_ManageTaskIndex"]).Append(",").Append(dv[0]["F_ManageTASKKINDINDEX"]).Append(",").Append(insertmonitor).Append(",").Append(dv[0]["F_MonitorTaskLevel"] ).Append(",").Append(DeviceIdx).Append(",3,").Append(dv[0]["F_RouteID"]).Append(",").Append(0).Append(",").Append(dv[0]["F_NumParam1"]).Append(",").Append(dv[0]["F_NumParam2"] ).Append(",").Append(dv[0]["F_NumParam3"]).Append(",").Append(dv[0]["F_NumParam4"]).Append(",").Append(dv[0]["F_NumParam5"]).Append(",") .Append(dv[0]["F_NumParam6"]).Append(",'").Append(string.Empty).Append("','").Append(string.Empty).Append("','") .Append(dv[0]["F_TxtParam"]).Append("','").Append(dv[0]["F_UseAwayFork"]).Append("',").Append(0).Append(",").Append(0).Append(",").Append(0).Append(")"); dbo.ExceSQL(sql.ToString()); sql.Clear(); sql.Append("update t_monitor_task set f_agvNo = '' where f_monitorindex = ").Append(TaskIdx); dbo.ExceSQL(sql.ToString()); err = "穿梭板未就绪,已插入将送指令!"; return false; } } else { err = "穿梭板未就绪!"; return false; } } err = string.Empty; return true; } //检测货位内有车 参数:cty-调度任务类型,order-堆垛机指令,rgv-车号,cellflag-货位是否是最外侧货位(1-是最外侧货位) public bool GetAheadDetectError(int cty, int order, string checkcellhavergv, int cellflag, out int rgv, out string err) { //err = string.Empty; //bool flag = true; //rgv = FINSTCPIP.SHICANGProtocol.LaneCoorAlreadyHaveRGV(checkcellhavergv); //if (order == 7 && rgv == -1) //{ // err = LaneCoorNoRGV; //取车 =》无车 // flag = false; //} //else if (order == 8 && rgv != -1) //{ // err = LaneCoorHaveRGV; //送车 =》有车 // flag = false; //} //else if (cty == 1 && order == 4 && cellflag == 1 && rgv != -1) //{ // err = LaneCoorHaveRGV; //入库,取货,外侧 =》有车 // flag = false; //} //else if (cty == 1 && order == 4 && cellflag != 1 && rgv == -1) //{ // err = LaneCoorNoRGV; //入库,取货,非外侧 =》无车 // flag = false; //} //else if (cty == 1 && order == 5 && cellflag == 1 && rgv != -1) //{ // err = LaneCoorHaveRGV; //入库,送货,外侧 =》有车 // flag = false; //} //else if (cty == 1 && order == 5 && cellflag != 1 && rgv == -1) //{ // err = LaneCoorNoRGV; //入库,送货,非外侧 =》无车 // flag = false; //} //else if (cty == 2 && order == 4 && cellflag == 1) //{ // //出库,取货,外侧 //} //else if (cty == 2 && order == 4 && cellflag != 1) //{ // //出库,取货,非外侧 //} //else if (cty == 2 && order == 5 && cellflag == 1) //{ // //出库,送货,外侧 //} //else if (cty == 2 && order == 5 && cellflag != 1) //{ // //出库,送货,非外侧 //} //return flag; err = string.Empty; rgv = -1; return false; } public const string LaneCoorHaveRGV = "巷道内有车。"; public const string LaneCoorNoRGV = "巷道内无车。"; /// /// 生成堆垛机和穿梭板相关指令的提前检测条件 /// /// author:zcy /// /// /// Monitor 指令的提前检测条件 public string CreateStackAheadDetect(List KeyDevice, List PriorDevice, List NextDevice, int CommandType, bool needRGV = true) { StringBuilder AheadDetect = new StringBuilder(); //int controltype = ccf.GetFCONTROLTASKTYPEFromManageTask(mti,fid); //string startcell = string.Empty; //string endcell = string.Empty; if (NextDevice[1] == 2 && PriorDevice[1] == 10 && CommandType == 4) //出库取货 { //int cellflag = GetCellFlag_OneTwoZero(startcell); //if (cellflag == 1) if (needRGV == false) { AheadDetect.Append(";FS15010"); //最外侧货位,起点无车 } else { AheadDetect.Append(";FS-15010"); //非最外侧货位,起点有车 AheadDetect.Append(";FT-15010"); //非最外侧货位,堆垛模式 AheadDetect.Append(";FI15010"); //非最外侧货位,车空闲 AheadDetect.Append(";FR15010"); //非最外侧货位,预约锁正确(不正确可能会导致穿梭板冲撞堆垛机货叉) } } if (NextDevice[1] == 2 && PriorDevice[1] == 10 && CommandType == 5) //出库送货 { //不需要检测穿梭板状态 } if (NextDevice[1] == 10 && PriorDevice[1] == 2 && CommandType == 4) //入库取货 { //int cellflag = GetCellFlag_OneTwoZero(endcell); //if (cellflag == 1) if (needRGV == false) { AheadDetect.Append(";FE15010"); //最外侧货位,终点无车 } else { AheadDetect.Append(";FE-15010"); //非最外侧货位,终点有车 } } if (NextDevice[1] == 10 && PriorDevice[1] == 2 && CommandType == 5) //入库送货 { //int cellflag = GetCellFlag_OneTwoZero(endcell); //if (cellflag == 1) if (needRGV == false) { AheadDetect.Append(";FE15010"); //最外侧货位,终点无车 } else { AheadDetect.Append(";FE-15010"); //非最外侧货位,终点有车 AheadDetect.Append(";FT-15010"); //非最外侧货位,堆垛模式 AheadDetect.Append(";FI15010"); //非最外侧货位,车空闲 AheadDetect.Append(";FR15010"); //非最外侧货位,预约锁正确 } } return AheadDetect.ToString(); } #endregion //获取当前指令所涉及的穿梭板(如果是穿梭板指令,则返回F_deviceIndex,如果是堆垛机指令,则返回F_AgvNo) public int GetShuttleFromMonitor(int MonitorIndex) { //2021 DataView dv = new DataView(); try { //20101124 sql.Remove(0, sql.Length); sql.Append("select F_deviceIndex, F_AgvNo from T_Monitor_Task where (F_DeviceCommandIndex IS NOT NULL) and F_MonitorIndex=").Append(MonitorIndex); dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; if (dv.Count > 0) { int device = Convert.ToInt32(dv[0]["F_deviceIndex"]); int devkind = ccf.GetDeviceKindIdx(device); if (devkind == 44) { return device; } if (devkind == 1) { int.TryParse(dv[0]["F_AgvNo"].ToString(), out device); return device; } } return -1; } catch (Exception ex) { throw ex; } finally { dv.Dispose(); } } public string GetStartCellFromManage(int Fid) { DataView dv = new DataView(); try { sql.Clear(); sql.Append("select fstartcell from t_manage_task where fid = ").Append(Fid); dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; if (dv.Count > 0) { return dv[0]["fstartcell"].ToString(); } return ""; } catch (Exception ex) { throw ex; } finally { dv.Dispose(); } } public string GetEndCellFromManage(int Fid) { DataView dv = new DataView(); try { sql.Clear(); sql.Append("select fEndcell from t_manage_task where fid = ").Append(Fid); dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; if (dv.Count > 0) { return dv[0]["fEndcell"].ToString(); } return ""; } catch (Exception ex) { throw ex; } finally { dv.Dispose(); } } public string GetStartCellFromIOControl(int Fid) { DataView dv = new DataView(); try { sql.Clear(); sql.Append("select start_device_code from IO_Control where CONTROL_ID = ").Append(Fid); dv = dboM.ExceSQL(sql.ToString()).Tables[0].DefaultView; if (dv.Count > 0) { return dv[0]["start_device_code"].ToString(); } return ""; } catch (Exception ex) { throw ex; } finally { dv.Dispose(); } } #region 获取任务 // 获取倒库任务(已废弃,改为获取所有任务,在发送时限制) //public void GetManagerMoveTask() //{ // DataView dvIOC = new DataView(); // try // { // sql.Clear(); // sql.Append("select * from IO_CONTROL where CONTROL_TASK_TYPE = 3 AND CONTROL_STATUS=0"); // dvIOC = dboM.ExceSQL(sql.ToString()).Tables[0].DefaultView; // for (int inew = 0; inew < dvIOC.Count; inew++) // { // #region 穿梭板任务,获取排列层相同,终点相同的的所有出库任务,根据该组的出库逻辑,排好序 // { // int controlId = Convert.ToInt32(dvIOC[inew]["CONTROL_ID"]); // string startDeviceCell = Convert.ToString(dvIOC[inew]["START_DEVICE_CODE"]); // string startWareHouse = Convert.ToString(dvIOC[inew]["START_WAREHOUSE_CODE"]); // string endDeviceCell = Convert.ToString(dvIOC[inew]["END_DEVICE_CODE"]); // List allCells = GetAllSameGroupCell(startDeviceCell); // string cells = CellsToSql(allCells); // int[] allIds = GetAllMutexTaskAndSameEndFromIOControl_OderbyFFirstInputLocat_YIKU(controlId, startDeviceCell, startWareHouse); // if (allIds != null) // { // for (int j = 0; j < allIds.Length; j++) // { // string cell = GetStartCellFromIOControl(allIds[j]); // if (IsOutSideTaskINIOCONTROL(cell) == true) // { // //ObtainDoubleForkTask(allid[j], "0"); // #region 获取任务(待添加) // #endregion // } // else // { // //因为 allid 已经是按照顺序排列的了,如果某一个任务不是最外侧的未获取任务,则后续的任务也不是 // break; // } // } // } // else // { // //ObtainDoubleForkTask(controlid, "0"); // #region 获取任务(待添加) // #endregion // } // } // #endregion // } // } // catch (Exception ex) // { // } // finally // { // dvIOC.Dispose(); // } //} // 获取出库任务(已废弃,改为获取所有任务,在发送时限制) //public void GetManageOutputTask() //{ // DataView dv = new DataView(); // try // { // #region 到此终点的任务按照巷道等待执行和执行中任务数由小到大依次出叉数量的任务 // // SQL 从 T_Base_Route 找到该终点的起点 // // aaa 是每个起点在 T_Manage_Task + T_Monitor_Task(仅计算出库任务) 中的任务数量之和(等待执行和执行中),升序 // dv = dbo.ExceSQL(string.Format("SELECT F_StartDevice,(SELECT COUNT(FID) FROM T_Manage_Task where FSTARTDEVICE=F_StartDevice)+(SELECT count(F_MonitorIndex) FROM T_Monitor_Task where F_DeviceIndex =convert(int,'11'+ substring(convert(varchar,F_StartDevice),3,3)) and F_DeviceCommandIndex=5) as aaa FROM T_Base_Route where F_EndDevice={0} order by aaa asc", Convert.ToInt32(dvc[i]["F_DeviceIndex"]))).Tables[0].DefaultView; // for (int xd = 0; xd < dv.Count; xd++) // { // int forkcount = 1; // int freach = 1; // //obj = dbo.GetSingle(string.Format("SELECT F_ForkAmount from T_Base_StackInfo where F_LaneNo like '%{0}%'", dvnew[xd]["F_StartDevice"])); // dvmi = dbo.ExceSQL(string.Format("SELECT F_ForkAmount,F_Reach from T_Base_StackInfo where F_LaneNo like '%{0}%'", dvnew[xd]["F_StartDevice"])).Tables[0].DefaultView; // if (dvmi.Count > 0) // { // forkcount = Convert.ToInt32(dvmi[0]["F_ForkAmount"]); // freach = Convert.ToInt32(dvmi[0]["F_Reach"]); // } // #region SQL 从 IO_CONTROL 中找到此终点的等待任务,挑选货叉数量个任务 // sbs.Remove(0, sbs.Length); // if (CStaticClass.ManDBFactory == "OracleDBFactory") // {//20151120调度系统oracle的特殊语句 // sbs.Append("select CONTROL_ID from IO_CONTROL where rownum<=").Append(forkcount); // } // else // { // sbs.Append("select top ").Append(forkcount).Append(" CONTROL_ID,START_DEVICE_CODE,START_WAREHOUSE_CODE from IO_CONTROL where 1=1 "); // } // sbs.Append(" and CONTROL_STATUS=").Append(Model.CGeneralFunction.TASKWAIT.ToString()); // sbs.Append(" and END_DEVICE_CODE='").Append(dvc[i]["F_DeviceIndex"]).Append("'"); // sbs.Append(" and CONTROL_TASK_TYPE=2"); //20211225,LYJL 此处只获取出库的任务 // sbs.Append(" order by CONTROL_TASK_LEVEL desc,CONTROL_BEGIN_TIME asc,CONTROL_ID asc "); // #endregion // dvIOC = dboM.ExceSQL(sbs.ToString()).Tables[0].DefaultView; // for (int inew = 0; inew < dvIOC.Count; inew++) // { //// // int controlid = Convert.ToInt32(dvIOC[inew]["CONTROL_ID"]); // string startdevicecell = Convert.ToString(dvIOC[inew]["START_DEVICE_CODE"]); // string startwarehouse = Convert.ToString(dvIOC[inew]["START_WAREHOUSE_CODE"]); // string enddevicecell = Convert.ToString(dvIOC[inew]["END_DEVICE_CODE"]); // if (freach == 2) // { // //controlid= //查找是否有如果是1,4排的任务,是否有2,3排的任务没被获取,优先获得2,3排 // controlid = GetReachIfHaveMutexTaskFromIOControl(controlid, startdevicecell, startwarehouse);//20181028 // } // #region 穿梭板任务,获取排列层相同,终点相同的的所有出库任务,根据该组的出库逻辑,排好序 // if (CStaticClass.T_Warehouse == "LYJL") // { // int[] allid = ccff.GetAllMutexTaskAndSameEndFromIOControl_OderbyFFirstInputLocat(controlid, startdevicecell, enddevicecell, startwarehouse); // if (allid != null) // { // for (int j = 0; j < allid.Length; j++) // { // string cell = ccff.GetStartCellFromIOControl(allid[j]); // if (ccff.IsOutSideTaskINIOCONTROL(cell) == true) // { // ObtainDoubleForkTask(allid[j], "0"); // } // else // { // //因为 allid 已经是按照顺序排列的了,如果某一个任务不是最外侧的未获取任务,则后续的任务也不是 // break; // } // } // } // else // #endregion // { // ObtainDoubleForkTask(controlid, "0"); // } // } // else // { // ObtainDoubleForkTask(controlid, "0"); // } // } // leftTask = leftTask - dvIOC.Count; // if (leftTask <= 0) break; // } // #endregion // } // catch (Exception ex) // { // throw ex; // } // finally // { // dv.Dispose(); // } //} #endregion #region 获取所有任务 public void GetManageTask() { DataView dv = new DataView(); try { sql.Remove(0, sql.Length); sql.Append("select * from IO_CONTROL where ((CONTROL_STATUS="); sql.Append(Model.CGeneralFunction.TASKWAIT.ToString()); //sql.Append(") or (CONTROL_STATUS=").Append(Model.CGeneralFunction.TASKSINGLEFORKRUN.ToString()).Append(") or (CONTROL_STATUS="); //sql.Append(Model.CGeneralFunction.TASKALTERROUTEREPLY.ToString()); sql.Append(")) ");//20151120 sql.Append(" order by CONTROL_TASK_LEVEL desc,CONTROL_ID asc");//20151120 dv = dboM.ExceSQL(sql.ToString()).Tables[0].DefaultView; if (dv.Count > 0) { for (int i = 0; i < dv.Count; i++) { //ObtainDoubleForkTask(controlid, "0"); #region 获取任务(待添加) #endregion } } } catch (Exception ex) { throw ex; } finally { dv.Dispose(); } } #endregion #region 拆分任务 //出库任务,所有可以拆分的最外侧货位的出库任务 public List GetAllCanDisassembleTask_Output(int stack) { List canDisassembleTaskIds = new List(); DataView dv1 = new DataView(); try { //倒库任务按起点进行分组,找到每组中未拆分的最外侧的任务。 //根据终点的任务限制,把所有可拆分的最外侧任务,按优先级、时间倒序排列 int lane = ccf.GetLaneWayNoFromStack(stack); sql.Clear(); sql.Append("select max(FSTARTCELL) max, min(fstartcell) min, CELL_MODEL from t_manage_task where fstartdevice = ") .Append(lane).Append(" AND (FSTATUS = 0) AND (FCONTROLTASKTYPE = 2) AND (FIntoStepOK = '0') group by FSTARTUCODE,CELL_MODEL "); dv1 = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; for (int j = 0; j < dv1.Count; j++) { #region 根据货位组的入库模式,找到本组的最外侧任务 string outcell = string.Empty; if (dv1[j]["cell_model"].ToString().ToUpper() == "SMALL") { outcell = dv1[j]["max"].ToString(); //货位组先入小位原则,则大货位在外侧 } else if (dv1[j]["cell_model"].ToString().ToUpper() == "BIG") { outcell = dv1[j]["min"].ToString(); //货位组先入大位原则,则小货位在外侧 } else { outcell = dv1[j]["abc"].ToString(); //此else不应该进入,抛出异常,卡住 } #endregion //如果同组内有已拆分的任务,且存在穿梭板指令,则跳过 if (SameGroupCellEnableDissableTask(outcell) == false) { continue; } sql.Clear(); sql.Append("select fid from t_manage_task where FSTARTCELL = '").Append(outcell).Append("'"); int fid = Convert.ToInt32(dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView[0]["fid"]); canDisassembleTaskIds.Add(fid); } return canDisassembleTaskIds; } catch (Exception ex) { throw ex; } finally { dv1.Dispose(); } } //拆分任务相关,同组货位有已拆分的任务,且存在穿梭板的任务,则不能拆分新的任务(立柱未考虑) private bool SameGroupCellEnableDissableTask(string cell) { DataView dv = new DataView(); bool enable = true; try { string inputlogic = GetFFirstInputLocatFromCell(cell); dv = dbo.ExceSQL(string.Format("select 调度任务索引 from V_Monitor_Task where 设备类型 = 44 and 调度任务索引 in (select fid from T_Manage_Task where FIntoStepOK = 1 and FSTARTCELL like '{0}%')", cell.Substring(0, 9))).Tables[0].DefaultView; if (dv.Count > 0)//出库大于0,移库大于1 { enable = false; } //不使用穿梭版的货位任务,有堆垛机指令时不能拆分 dv = dbo.ExceSQL(string.Format("select f_monitorIndex from T_Monitor_Task where F_ManageTaskIndex = (SELECT FID FROM T_Manage_Task WHERE FIntoStepOK = 1 AND FSTARTCELL = (select FCELLCODE from ST_CELL where FCELLCODE like '{0}%' and FCellFlag = 1 and FFirstInputLocat = '{1}')) and F_DeviceIndex like '110%'", cell.Substring(0, 9), inputlogic)).Tables[0].DefaultView; if (dv.Count > 0) { enable = false; } return enable; } catch (Exception ex) { throw ex; } finally { dv.Dispose(); } } //倒库任务,所有可以拆分的最外侧货位的倒库任务 public List GetAllCanDisassembleTask_YIKU(int startStack) { List canDisassembleTaskIds = new List(); DataView dv1 = new DataView(); try { //倒库任务按起点进行分组,找到每组中未拆分的最外侧的任务。 //根据终点的任务限制,把所有可拆分的最外侧任务,按优先级、时间倒序排列 int lane = ccf.GetLaneWayNoFromStack(startStack); sql.Clear(); sql.Append("select max(FSTARTCELL) max, min(fstartcell) min, CELL_MODEL from t_manage_task where fstartdevice = ") .Append(lane).Append(" AND (FSTATUS = 0) AND (FCONTROLTASKTYPE = 3) AND (FIntoStepOK = '0') group by FSTARTUCODE,CELL_MODEL "); dv1 = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; for (int j = 0; j < dv1.Count; j++) { #region 根据货位组的入库模式,找到本组的最外侧任务 string outcell = string.Empty; if (dv1[j]["cell_model"].ToString().ToUpper() == "SMALL") { outcell = dv1[j]["max"].ToString(); //货位组先入小位原则,则大货位在外侧 } else if (dv1[j]["cell_model"].ToString().ToUpper() == "BIG") { outcell = dv1[j]["min"].ToString(); //货位组先入大位原则,则小货位在外侧 } else { outcell = dv1[j]["abc"].ToString(); //此else不应该进入,抛出异常,卡住 } #endregion //如果同组内有已拆分的任务,且存在穿梭板指令,则跳过 if (SameGroupCellEnableDissableTask_YIKU(outcell) == false) { continue; } sql.Clear(); sql.Append("select fid from t_manage_task where FSTARTCELL = '").Append(outcell).Append("'"); int fid = Convert.ToInt32(dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView[0]["fid"]); canDisassembleTaskIds.Add(fid); } return canDisassembleTaskIds; } catch (Exception ex) { throw ex; } finally { dv1.Dispose(); } } //移库任务第一个车完成任务时,即可拆分第二个 private bool SameGroupCellEnableDissableTask_YIKU(string cell) { DataView dv = new DataView(); bool enable = true; try { string inputlogic = GetFFirstInputLocatFromCell(cell); dv = dbo.ExceSQL(string.Format("select 设备索引 from V_Monitor_Task where 设备类型 = 44 and 调度任务索引 in (select fid from T_Manage_Task where FIntoStepOK = 1 and FSTARTCELL like '{0}%') group by 设备索引", cell.Substring(0, 9))).Tables[0].DefaultView; if (dv.Count > 1)//出库大于0,移库大于1 { enable = false; } //不使用穿梭版的货位任务,有堆垛机指令时不能拆分 dv = dbo.ExceSQL(string.Format("select f_monitorIndex from T_Monitor_Task where F_ManageTaskIndex = (SELECT FID FROM T_Manage_Task WHERE FIntoStepOK = 1 AND FSTARTCELL = (select FCELLCODE from ST_CELL where FCELLCODE like '{0}%' and FCellFlag = 1 and FFirstInputLocat = '{1}')) and F_DeviceIndex like '110%'", cell.Substring(0, 9), inputlogic)).Tables[0].DefaultView; if (dv.Count > 0) { enable = false; } return enable; } catch (Exception ex) { throw ex; } finally { dv.Dispose(); } } //将可拆分的任务排序,每个项目出库的逻辑不同,可在此重写 public DataView SortCanDisassembleTask_Out(List taskIds) { DataView dv = new DataView(); try { StringBuilder canDisassemFID = new StringBuilder(); canDisassemFID.Append("fid in (''"); foreach (int id in taskIds) { canDisassemFID.Append(",").Append(id); } canDisassemFID.Append(")"); sql.Clear(); sql.Append("select * from t_manage_task where ").Append(canDisassemFID).Append(" order by FTASKLEVEL desc, FBEGTIME desc"); dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; return dv; } catch (Exception ex) { throw ex; } finally { dv.Dispose(); } } /// /// 出库优先附带符合运行条件的入库任务 /// 具体实现:在收到出库任务的完成时,挑选一个可以执行的入库任务把优先级设成最高9 /// public void SelectTask_SCShuttle() { DataView dvM = new DataView(); DataView dv = new DataView(); DataView dv112 = new DataView(); DataView dv0 = new DataView(); DataView dv1 = new DataView(); DataView dvv = new DataView(); try { sql.Remove(0, sql.Length); sql.Append("SELECT F_StackIndex FROM T_Base_StackInfo"); dvM = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; for (int i = 0; i < dvM.Count; i++) { int stack = Convert.ToInt32(dvM[i]["F_StackIndex"]); #region 倒库任务拆分 List moveTaskIds = GetAllCanDisassembleTask_YIKU(stack); dv = SortCanDisassembleTask_Out(moveTaskIds); for (int j = 0; j < dv.Count; j++) { //选择最短调度路径并且判断此路径上是否有设备发生故障 int routeid = CDisassembleTask.MinRouteID(Convert.ToInt32(dv[j]["FSTARTDEVICE"]), Convert.ToInt32(dv[j]["FENDDEVICE"]), dv[j]["FUseAwayFork"]); if (routeid == -1) { continue; } int minFid = Convert.ToInt32(dv[j]["FID"]); int manKind = Convert.ToInt32(dv[j]["F_ManageTaskKindIndex"]); if (CDisassembleTask.CreateMonitor(manKind, minFid, routeid, dv[j], 0) > 0) { sql.Remove(0, sql.Length); sql.Append("update T_Manage_Task set FIntoStepOK='1' where FID=").Append(minFid ).Append(" and F_ManageTaskKindIndex=").Append(manKind); dbo.ExceSQL(sql.ToString()); //20161219 添加以下四行代码,出库任务优先级默认是9,解决出库任务不执行的问题(因任务依次按优先级、拆分时间优先执行) sql.Remove(0, sql.Length); sql.Append("update T_Monitor_Task set F_MonitorTaskLevel=9 where F_MonitorTaskLevel<>100 and F_ManageTASKKINDINDEX=").Append( manKind).Append(" and F_ManageTaskIndex=").Append(minFid); dbo.ExceSQL(sql.ToString()); } } #endregion #region 出库任务拆分 List outTaskIds = GetAllCanDisassembleTask_Output(stack); dv = SortCanDisassembleTask_Out(outTaskIds); for (int j = 0; j 0) { sql.Remove(0, sql.Length); sql.Append("update T_Manage_Task set FIntoStepOK='1' where FID=").Append(minFid ).Append(" and F_ManageTaskKindIndex=").Append(manKind); dbo.ExceSQL(sql.ToString()); //20161219 添加以下四行代码,出库任务优先级默认是9,解决出库任务不执行的问题(因任务依次按优先级、拆分时间优先执行) sql.Remove(0, sql.Length); sql.Append("update T_Monitor_Task set F_MonitorTaskLevel=9 where F_MonitorTaskLevel<>100 and F_ManageTASKKINDINDEX=").Append( manKind).Append(" and F_ManageTaskIndex=").Append(minFid); dbo.ExceSQL(sql.ToString()); } } #endregion #region 入库任务拆分 sql.Remove(0, sql.Length); sql.Append("SELECT * FROM T_Manage_Task WHERE (FSTATUS = 0) AND (FSTACK = ").Append(stack).Append(") AND (FCONTROLTASKTYPE = 1) AND (FIntoStepOK = '0') order by FTASKLEVEL desc,FBEGTIME asc"); dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; for (int j = 0; j < dv.Count; j++)//有这个堆垛机的入库任务等待拆分 { //选择最短调度路径并且判断此路径上是否有设备发生故障 int routeid = CDisassembleTask.MinRouteID(Convert.ToInt32(dv[j]["FSTARTDEVICE"]), Convert.ToInt32(dv[j]["FENDDEVICE"]), dv[j]["FUseAwayFork"]); if (routeid == -1) { continue; } int minFid = Convert.ToInt32(dv[j]["FID"]); int manKind = Convert.ToInt32(dv[j]["F_ManageTaskKindIndex"]); if (CDisassembleTask.CreateMonitor(manKind, minFid, routeid, dv[j], 0) > 0) { //分解完成,修改T_Manage_Task表FIntoStepOK=1,未修改优先级 sql.Remove(0, sql.Length); sql.Append("update T_Manage_Task set FIntoStepOK='1' where FID=").Append(minFid ).Append(" and F_ManageTaskKindIndex=").Append(manKind); dbo.ExceSQL(sql.ToString()); } } #endregion } #region 无堆垛机任务拆分 sql.Remove(0, sql.Length); sql.Append("SELECT * FROM T_Manage_Task WHERE ((FSTACK <= 0) or (FCONTROLTASKTYPE=4)) AND (FIntoStepOK = '0') order by FTASKLEVEL desc, FCONTROLTASKTYPE asc,FBEGTIME asc"); dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; for (int j = 0; j < dv.Count; j++) { //选择最短调度路径并且判断此路径上是否有设备发生故障 int routeid = CDisassembleTask.MinRouteID(Convert.ToInt32(dv[j]["FSTARTDEVICE"]), Convert.ToInt32(dv[j]["FENDDEVICE"]), dv[j]["FUseAwayFork"]); if (routeid == -1) { continue; } int minFid = Convert.ToInt32(dv[j]["FID"]); int manKind = Convert.ToInt32(dv[j]["F_ManageTaskKindIndex"]); if (CDisassembleTask.CreateMonitor(manKind, minFid, routeid, dv[j], 0) > 0) { //分解完成,修改T_Manage_Task表FIntoStepOK=1,未修改优先级 sql.Remove(0, sql.Length); sql.Append("update T_Manage_Task set FIntoStepOK='1' where FID=").Append(minFid ).Append(" and F_ManageTaskKindIndex=").Append(manKind); dbo.ExceSQL(sql.ToString()); } } #endregion } catch (Exception ex) { //DisassembleTaskError = "ControlSystem.CDisassembleTask.SelectTask_OutSubjoinIn时发生错误:" + ex.StackTrace + ex.Message; } finally { dv.Dispose(); dv0.Dispose(); dv1.Dispose(); dv112.Dispose(); dvM.Dispose(); dvv.Dispose(); } } #endregion } }