123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Configuration;
- using System.Data.SqlClient;
- namespace AGV_WPF.TrafficDefine
- {
- public class TrafficManager
- {
- public List<TrafficArea> TrafficAreaList;
- public bool OfflineControlFlag = false;//掉线是否仍能管制其他AGV标志,默认不能
- public static TrafficManager Traffic;
- public TrafficManager()
- {
- Traffic = this;
- TrafficAreaList = new List<TrafficArea>();
- }
- void CheckColumn()
- {
- string strCon = ConfigurationManager.AppSettings["ConnString"];
- using (SqlConnection con = new SqlConnection(strCon))
- {
- try
- {
- string sql = string.Format("select count(1) from syscolumns where ID=OBJECT_ID('T_Traffic') and name='IsNeedKeyMark'");
- con.Open();
- using (SqlCommand com = new SqlCommand(sql, con))
- {
- object o = com.ExecuteScalar();
- if (int.Parse(o.ToString()) == 0)
- {
- sql = string.Format("alter table T_Traffic add IsNeedkeyMark bit");
- com.CommandText = sql;
- com.ExecuteNonQuery();
- }
- sql = string.Format("select count(1) from syscolumns where ID=OBJECT_ID('T_Traffic') and name='KeyMarkID'");
- com.CommandText = sql;
- o = com.ExecuteScalar();
- if (int.Parse(o.ToString()) == 0)
- {
- sql = string.Format("alter table T_Traffic add KeyMarkID bigint");
- com.CommandText = sql;
- com.ExecuteNonQuery();
- }
- }
- }
- catch (System.Exception ex)
- {
- throw ex;
- }
- }
- }
- public void InitTrafficAreas()
- {
- CheckColumn();
- string strCon = ConfigurationManager.AppSettings["ConnString"];
- using (SqlConnection con = new SqlConnection(strCon))
- {
- try
- {
- string sql = string.Format("select distinct TrafficNum from T_Traffic");
- con.Open();
- using (SqlCommand com = new SqlCommand(sql, con))
- {
- //1、先得到所有管制区编号
- SqlDataReader reader = com.ExecuteReader();
- List<int> totalTrafficNum = new List<int>();
- while (reader.Read())
- {
- totalTrafficNum.Add(int.Parse(reader["TrafficNum"].ToString()));
- }
- reader.Close();
- TrafficAreaList.Clear();//清空之前数据
- //2、填充管制区站点数据
- for (int i = 0; i < totalTrafficNum.Count;i++ )
- {
- TrafficArea area = new TrafficArea();
- area.TrafficNum = totalTrafficNum[i];
- area.IsNeedKeyMark = false;
- sql = string.Format("select top(1) IsNeedKeyMark from T_Traffic where TrafficNum={0}", totalTrafficNum[i]);//确定是否要关键点
- com.CommandText = sql;
- object isNeedOjbect = com.ExecuteScalar();
- if (isNeedOjbect != null && !string.IsNullOrEmpty(isNeedOjbect.ToString()) && bool.Parse(isNeedOjbect.ToString()))
- {
- area.IsNeedKeyMark = true;
- }
- sql = string.Format("select A.ID,A.TrafficNum,A.IsNeedKeyMark,A.Mark,A.WorkLine,A.XPos,A.YPos,B.Mark as KeyMark,B.WorkLine as KeyMarkWorkLine,B.XPos as KeyMarkXPos,B.YPos as KeyMarkYPos from (select T_Traffic.ID,T_Traffic.TrafficNum,T_Traffic.MarkID,T_Mark.Mark,T_Mark.WorkLine,T_Mark.XPos,T_Mark.YPos,T_Traffic.IsNeedKeyMark from T_Traffic left join T_Mark on T_Mark.ID=T_Traffic.MarkID) as A left join (select T_Traffic.ID,T_Traffic.TrafficNum,T_Traffic.KeyMarkID,T_Mark.Mark,T_Mark.WorkLine,T_Mark.XPos,T_Mark.YPos,T_Traffic.IsNeedKeyMark from T_Traffic left join T_Mark on T_Mark.ID=T_Traffic.KeyMarkID) as B on A.ID=B.ID where A.TrafficNum=B.TrafficNum and A.TrafficNum={0}", totalTrafficNum[i]);
- com.CommandText = sql;
- reader = com.ExecuteReader();
- while (reader.Read())
- {
- TrafficStation station = new TrafficStation();
- object markObject = reader["Mark"];
- object workLineObject = reader["WorkLine"];
- object keyMarkObject = reader["KeyMark"];
- object keyMarkWorkLineObject = reader["KeyMarkWorkLine"];
- //检测是否为空,如果为空则用默认的
- if (markObject != null && !string.IsNullOrEmpty(markObject.ToString()))
- station.CurrentMark.MarkNum = int.Parse(markObject.ToString());
- if (workLineObject != null && !string.IsNullOrEmpty(workLineObject.ToString()))
- station.CurrentMark.WorkLine = int.Parse(workLineObject.ToString());
- if (keyMarkObject != null && !string.IsNullOrEmpty(keyMarkObject.ToString()))
- station.NextMark.MarkNum = int.Parse(keyMarkObject.ToString());
- if (keyMarkWorkLineObject != null && !string.IsNullOrEmpty(keyMarkWorkLineObject.ToString()))
- station.NextMark.WorkLine = int.Parse(keyMarkWorkLineObject.ToString());
- area.StationList.Add(station);
- }
- reader.Close();
- TrafficAreaList.Add(area);
- }
- }
- }
- catch (System.Exception ex)
- {
- throw ex;
- }
- }
- }
- public bool UpdateAreaStatus(AgvStatus agv)
- {
- bool trafficFlag = false;//管制状态,true需要管制,false不需要管制
- //1、先备份之前管制区号
- int[] tempTrafficList = agv.TrafficNumList.ToArray();
- //2、再得到当前管制区号
- List<int> trafficIndexList = GetAgvTrafficIndexListEx(agv);
- List<bool> trafficFlagList = new List<bool>();
- for (int i = 0; i < trafficIndexList.Count;i++ )
- {
- trafficFlagList.Add(false);
- }
- //3、依次判断管制区状态并更新
- if(trafficIndexList.Count>0)
- {
- #region 在管制区中
- for (int i = 0; i < trafficIndexList.Count; i++)
- {
- TrafficArea area = TrafficAreaList[trafficIndexList[i]];
- if (area.Status)//已经有AGV占领此管制区
- {
- if (area.OccupyAgv == agv.AgvNum)//占领此区域的为自己
- {
- if (!agv.WirelessStaus)//掉线了
- {
- if (OfflineControlFlag)//掉线仍能管制其他AGV,不需要更新排队数据
- {
- trafficFlagList[i] = false;
- }
- else//否则从排队中选出占领AGV,需要更新排队数据
- {
- if (area.WaitAgvList.Count > 0)
- {
- area.OccupyAgv = area.WaitAgvList[0];
- area.WaitAgvList.Remove(area.OccupyAgv);
- }
- else
- {
- area.OccupyAgv = 0;
- area.Status = false;
- }
- trafficFlagList[i] = false;
- }
- }
- else
- {
- trafficFlagList[i] = false;
- }
- }
- else
- {
- if (!agv.WirelessStaus)
- {
- if (OfflineControlFlag)
- {
- trafficFlagList[i] = true;
- }
- else
- {
- area.WaitAgvList.Remove(agv.AgvNum);
- trafficFlagList[i] = false;
- }
- }
- else//没掉线
- {
- AddWaitAgv(area, agv.AgvNum);//向队列中添加
- trafficFlagList[i] = true;
- //if (area.IsNeedKeyMark)//如果是关键点,则需要判断下是否同向,同向不需管制
- //{
- // AgvStatus occupyAgvStatus = MainWindow.mainWindow.GetAgvStatus(area.OccupyAgv);
-
- // /*int tempIndex = area.StationList.FindIndex(c => (c.CurrentMark.WorkLine == occupyAgvStatus.WorkLine && c.CurrentMark.MarkNum == occupyAgvStatus.MarkNum && c.NextMark.WorkLine == agv.WorkLine && c.NextMark.MarkNum == agv.MarkNum) || (c.NextMark.WorkLine == occupyAgvStatus.WorkLine && c.NextMark.MarkNum == occupyAgvStatus.MarkNum && c.CurrentMark.WorkLine == agv.WorkLine && c.CurrentMark.MarkNum == agv.MarkNum));*/
- // bool flag = CheckAgvTraffic(agv, occupyAgvStatus, area);
- // if ((occupyAgvStatus.WorkLine == agv.WorkLine && occupyAgvStatus.MarkNum == agv.MarkNum)||flag)//管制AGV和当前AGV地标一样(管制AGV读完后,后面AGV跟上来),不需要管制
- // {
- // trafficFlagList[i] = false;
- // }
- //}
- }
- }
- }
- else//无AGV占领此管制区
- {
- if (!agv.WirelessStaus)//掉线
- {
- if (OfflineControlFlag)
- {
- area.OccupyAgv = agv.AgvNum;//占领
- area.Status = true;//置占领状态
- trafficFlagList[i] = false;//此AGV不需管制
- }
- }
- else
- {
- area.OccupyAgv = agv.AgvNum;//占领
- area.Status = true;//置占领状态
- trafficFlagList[i] = false;//此AGV不需管制
- }
- }
- }
- #endregion
- }
- //出管制区
- {
- int[] outArea = GetDifferentArea(tempTrafficList.ToList(), agv.TrafficNumList);
- UpdateOutofArea(agv, outArea);
-
- }
- if (trafficFlagList.Contains(true))
- {
- trafficFlag = true;
- }
- else
- trafficFlag = false;
- return trafficFlag;
- }
- int[] GetDifferentArea(List<int> oldList, List<int> newList)
- {
- List<int> result = new List<int>();
- if (newList.Count == 0)
- return oldList.ToArray();
- for (int i = 0; i < oldList.Count;i++ )
- {
- if (!newList.Contains(oldList[i]))
- {
- result.Add(oldList[i]);
- }
- }
- return result.ToArray();
- }
- /// <summary>
- /// 对出管制区的AGV更新各个管制区数据
- /// </summary>
- /// <param name="agv"></param>
- void UpdateOutofArea(AgvStatus agv,int[] trafficList)
- {
- if (trafficList.Length > 0)
- {
- for (int i = 0; i < trafficList.Length; i++)
- {
- TrafficArea area = GetTrafficArea(trafficList[i]);
- if (area.OccupyAgv == agv.AgvNum)
- {
- if (area.WaitAgvList.Count > 0)
- {
- area.OccupyAgv = area.WaitAgvList[0];
- area.WaitAgvList.Remove(area.OccupyAgv);
- }
- else
- {
- area.OccupyAgv = 0;
- area.Status = false;
- }
- }
- else
- {
- area.WaitAgvList.Remove(agv.AgvNum);
- }
- }
- }
- }
- public List<int> GetTrafficAgvList(AgvStatus agv)
- {
- List<int> result = new List<int>();
- List<int> areaList = agv.TrafficNumList;
- for (int i = 0; i < areaList.Count;i++ )
- {
- TrafficArea area = GetTrafficArea(areaList[i]);
- if (area.OccupyAgv != agv.AgvNum)
- result.Add(area.OccupyAgv);
- }
- //var v = from c in result
- result = result.Distinct().ToList();
- return result;
- }
- List<int> GetAgvTrafficIndexList(AgvStatus agv)
- {
- List<int> result = new List<int>();
- agv.TrafficNumList.Clear();
- for (int i = 0; i < TrafficAreaList.Count;i++ )
- {
- int index = TrafficAreaList[i].StationList.FindIndex(c => c.CurrentMark.MarkNum == agv.MarkNum && c.CurrentMark.WorkLine == agv.WorkLine);
- if (index != -1)
- {
- agv.TrafficNumList.Add(TrafficAreaList[i].TrafficNum);//更新AGV管制区编号列表
- result.Add(i);
- }
- }
- return result;
- }
- void AddToList(List<int> list, int value)
- {
- if (!list.Contains(value))
- list.Add(value);
- }
- /// <summary>
- /// 得到当前管制区号
- /// </summary>
- /// <param name="agv"></param>
- /// <returns></returns>
- List<int> GetAgvTrafficIndexListEx(AgvStatus agv)
- {
- List<int> result = new List<int>();
- List<int> trafficList = new List<int>();
-
- for (int i = 0; i < TrafficAreaList.Count; i++)
- {
- int index = TrafficAreaList[i].StationList.FindIndex(c => c.CurrentMark.MarkNum == agv.MarkNum && c.CurrentMark.WorkLine == agv.WorkLine);
- if (index != -1)
- {
- if (!TrafficAreaList[i].IsNeedKeyMark)//如果不需要关键点
- {
-
- //agv.TrafficNumList.Add(TrafficAreaList[index].TrafficNum);//更新AGV管制区编号列表
- AddToList(trafficList, TrafficAreaList[i].TrafficNum);
- AddToList(result, i);
- }
- else//需要关键点
- {
- MarkStation keyMark = TrafficAreaList[i].StationList[index].NextMark;
- if (CheckNodeOrder(keyMark, new MarkStation() { WorkLine = agv.WorkLine, MarkNum = agv.MarkNum }, agv.Route))//在同一路线且关键点在当前路线后面
- {
- //agv.TrafficNumList.Add(TrafficAreaList[index].TrafficNum);//更新AGV管制区编号列表
- //result.Add(index);
- AddToList(trafficList, TrafficAreaList[i].TrafficNum);
- AddToList(result, i);
- }
- }
- }
- }
- agv.TrafficNumList = trafficList;
- return result;
- }
- /// <summary>
- /// 检测在某条路线中节点1是否在节点2后面
- /// </summary>
- /// <param name="node1">节点1</param>
- /// <param name="node2">节点2</param>
- /// <param name="route">待检测路线</param>
- /// <returns></returns>
- bool CheckNodeOrder(MarkStation node1, MarkStation node2, int route)
- {
- bool result = false;
- string strCon = ConfigurationManager.AppSettings["ConnString"];
- using (SqlConnection con = new SqlConnection(strCon))
- {
- try
- {
- string sql = string.Format("select MarkOrder from T_Line left join T_Mark on T_Line.MarkID=T_Mark.ID where T_Mark.WorkLine={0} and T_Mark.Mark={1} and LineNum={2}",node1.WorkLine,node1.MarkNum,route);
- con.Open();
- using (SqlCommand com = new SqlCommand(sql, con))
- {
- object o1 = com.ExecuteScalar();
- sql = string.Format("select MarkOrder from T_Line left join T_Mark on T_Line.MarkID=T_Mark.ID where T_Mark.WorkLine={0} and T_Mark.Mark={1} and LineNum={2}", node2.WorkLine, node2.MarkNum,route);
- com.CommandText = sql;
- object o2 = com.ExecuteScalar();
- if (o1 == null || string.IsNullOrEmpty(o1.ToString()))
- {
- result = false;
- }
- else if (o2 == null || string.IsNullOrEmpty(o2.ToString()))
- {
- result = false;
- }
- else
- {
- if (int.Parse(o1.ToString()) >= int.Parse(o2.ToString()))//考虑同一个节点
- {
- result = true;
- }
- else
- result = false;
- }
- }
- }
- catch (System.Exception ex)
- {
- throw ex;
- }
- }
- return result;
- }
- public TrafficArea GetTrafficArea(int trafficNum)
- {
- TrafficArea area = null;
- int index = TrafficAreaList.FindIndex(c => c.TrafficNum == trafficNum);
- if (index != -1)
- {
- area = TrafficAreaList[index];
- }
- return area;
- }
- public void AddAgvTrafficNum(AgvStatus agv,int trafficNum)
- {
- int index = agv.TrafficNumList.FindIndex(c => c == trafficNum);
- if (index == -1)
- {
- agv.TrafficNumList.Add(trafficNum);
- }
- }
- public void AddWaitAgv(TrafficArea area, int agvNum)
- {
- int index = area.WaitAgvList.FindIndex(c => c == agvNum);
- if (index == -1)
- {
- area.WaitAgvList.Add(agvNum);
- }
- }
- /// <summary>
- /// 检测两车路径是否相同
- /// </summary>
- /// <param name="agv1">AGV1信息</param>
- /// <param name="agv2">AGV2信息</param>
- /// <returns>成功返回true,失败返回false</returns>
- bool CheckTheSamePath(AgvStatus agv1, AgvStatus agv2,MarkStation keyMark)
- {
- //bool result = false;
- string strCon = ConfigurationManager.AppSettings["ConnString"];
- using (SqlConnection con = new SqlConnection(strCon))
- {
- try
- {
- //判断三点是否在同一路径上
- string sql1 = string.Format("select count(1) from T_Line left join T_Mark on T_Line.MarkID=T_Mark.ID where T_Mark.WorkLine={0} and T_Mark.Mark={1} and LineNum={2}",agv1.WorkLine,agv1.MarkNum,agv1.Route);
- string sql2 = string.Format("select count(1) from T_Line left join T_Mark on T_Line.MarkID=T_Mark.ID where T_Mark.WorkLine={0} and T_Mark.Mark={1} and LineNum={2}", agv2.WorkLine, agv2.MarkNum, agv1.Route);
- string sql3 = string.Format("select count(1) from T_Line left join T_Mark on T_Line.MarkID=T_Mark.ID where T_Mark.WorkLine={0} and T_Mark.Mark={1} and LineNum={2}", keyMark.WorkLine, keyMark.MarkNum, agv1.Route);
- con.Open();
- using (SqlCommand com = new SqlCommand(sql1, con))
- {
- int temp1 = int.Parse(com.ExecuteScalar().ToString());
- com.CommandText = sql2;
- int temp2 = int.Parse(com.ExecuteScalar().ToString());
- com.CommandText = sql3;
- int temp3 = int.Parse(com.ExecuteScalar().ToString());
- sql1 = string.Format("select count(1) from T_Line left join T_Mark on T_Line.MarkID=T_Mark.ID where T_Mark.WorkLine={0} and T_Mark.Mark={1} and LineNum={2}", agv1.WorkLine, agv1.MarkNum, agv2.Route);
- sql2 = string.Format("select count(1) from T_Line left join T_Mark on T_Line.MarkID=T_Mark.ID where T_Mark.WorkLine={0} and T_Mark.Mark={1} and LineNum={2}", agv2.WorkLine, agv2.MarkNum, agv2.Route);
- sql3 = string.Format("select count(1) from T_Line left join T_Mark on T_Line.MarkID=T_Mark.ID where T_Mark.WorkLine={0} and T_Mark.Mark={1} and LineNum={2}", keyMark.WorkLine, keyMark.MarkNum, agv2.Route);
- com.CommandText = sql1;
- int temp4 = int.Parse(com.ExecuteScalar().ToString());
- com.CommandText = sql2;
- int temp5 = int.Parse(com.ExecuteScalar().ToString());
- com.CommandText = sql3;
- int temp6 = int.Parse(com.ExecuteScalar().ToString());
- if (temp1 > 0 && temp2 > 0 && temp3 > 0 && temp4 > 0 && temp5 > 0 && temp6 > 0)
- {
- return true;
- }
- else
- return false;
- }
- }
- catch (System.Exception ex)
- {
- throw ex;
- }
- }
- //return result;
- }
- /// <summary>
- /// 判断指定两点在管制区中是否有相同关键点
- /// </summary>
- /// <param name="node1">待判断节点1</param>
- /// <param name="node2">待判断节点2</param>
- /// <param name="area">管制区</param>
- /// <param name="keyNode">返回的关键点列表(可能两个节点对应多个关键点)</param>
- /// <returns>成功返回true</returns>
- bool GetSameKeyNode(AgvStatus node1, AgvStatus node2, TrafficArea area, ref List<MarkStation> keyNodeList)
- {
- bool result = false;
- List<TrafficStation> nodeList1 = area.StationList.FindAll(c => c.CurrentMark.WorkLine == node1.WorkLine && c.CurrentMark.MarkNum == node1.MarkNum);//节点1在管制区中所有满足条件的点
- List<TrafficStation> nodeList2 = area.StationList.FindAll(c => c.CurrentMark.WorkLine == node2.WorkLine && c.CurrentMark.MarkNum == node2.MarkNum);//节点2在管制区中所有满足条件的点
- int count = nodeList1.Count < nodeList2.Count ? nodeList1.Count : nodeList2.Count;
-
- if(nodeList1.Count>nodeList2.Count)
- {
- for (int i = 0; i < count; i++)
- {
- int index = nodeList1.FindIndex(c => c.NextMark.WorkLine == nodeList2[i].NextMark.WorkLine && c.NextMark.MarkNum == nodeList2[i].NextMark.MarkNum);
- if (index != -1)
- {
- keyNodeList.Add(new MarkStation() { WorkLine = nodeList2[i].NextMark.WorkLine, MarkNum = nodeList2[i].NextMark.MarkNum });
- }
- }
- }
- else
- {
- for (int i = 0; i < count; i++)
- {
- int index = nodeList2.FindIndex(c => c.NextMark.WorkLine == nodeList1[i].NextMark.WorkLine && c.NextMark.MarkNum == nodeList1[i].NextMark.MarkNum);
- if (index != -1)
- {
- keyNodeList.Add(new MarkStation() { WorkLine = nodeList1[i].NextMark.WorkLine, MarkNum = nodeList1[i].NextMark.MarkNum });
- }
- }
- }
- if (keyNodeList.Count > 0)
- return true;
- return result;
- }
- /// <summary>
- /// 判断两车是否需要管制,只适用于关键点管制区
- /// </summary>
- /// <param name="agv1"></param>
- /// <param name="agv2"></param>
- /// <returns>不需要管制返回true,否则返回false</returns>
- bool CheckAgvTraffic(AgvStatus agv1, AgvStatus agv2,TrafficArea area)
- {
- bool result = false;
- List<MarkStation> list = new List<MarkStation>();
- if (GetSameKeyNode(agv1, agv2, area,ref list))
- {
- for (int i = 0; i < list.Count;i++ )
- {
- bool b = CheckTheSamePath(agv1, agv2, list[i]);
- if (b)
- return b;
- }
- }
- return result;
- }
- }
- }
|