|
@@ -57,17 +57,266 @@ namespace EfemDualSimulator.Views
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ public class Node<T>
|
|
|
+ {
|
|
|
+ private T data; //数据域
|
|
|
+ //构造器
|
|
|
+ public Node(T v)
|
|
|
+ {
|
|
|
+ data = v;
|
|
|
+ }
|
|
|
+ //数据域属性
|
|
|
+ public T Data
|
|
|
+ {
|
|
|
+ get
|
|
|
+ {
|
|
|
+ return data;
|
|
|
+ }
|
|
|
+ set
|
|
|
+ {
|
|
|
+ data = value;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public interface IGraph<T>
|
|
|
+ {
|
|
|
+ //获取顶点数
|
|
|
+ int GetNumOfVertex();
|
|
|
+ //获取边或弧的数目
|
|
|
+ int GetNumOfEdge();
|
|
|
+ //在两个顶点之间添加权为v的边或弧
|
|
|
+ void SetEdge(Node<T> v1, Node<T> v2, int v);
|
|
|
+ //删除两个顶点之间的边或弧
|
|
|
+ void DelEdge(Node<T> v1, Node<T> v2);
|
|
|
+ //判断两个顶点之间是否有边或弧
|
|
|
+ bool IsEdge(Node<T> v1, Node<T> v2);
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 无向图邻接矩阵类 GraphAdjMatrix<T>的实现
|
|
|
+ /// </summary>
|
|
|
+ /// <typeparam name="T"></typeparam>
|
|
|
+ public class GraphAdjMatrix<T> : IGraph<T>
|
|
|
+ {
|
|
|
+ private Node<T>[] nodes;//顶点数组
|
|
|
+ private float[,] matrix;//邻接矩阵数组
|
|
|
+ private int numEdges;//边的数目
|
|
|
+
|
|
|
+ public GraphAdjMatrix(int n)
|
|
|
+ {
|
|
|
+ nodes = new Node<T>[n];
|
|
|
+ matrix = new float[n, n];
|
|
|
+ numEdges = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ //获取索引为index的顶点的信息
|
|
|
+ public Node<T> GetNode(int index)
|
|
|
+ {
|
|
|
+ return nodes[index];
|
|
|
+ }
|
|
|
+
|
|
|
+ //设置索引为index的顶点的信息
|
|
|
+ public void SetNode(int index, Node<T> v)
|
|
|
+ {
|
|
|
+ nodes[index] = v;
|
|
|
+ }
|
|
|
+
|
|
|
+ //获取matrix[index1, index2]的值
|
|
|
+ public float GetMatrix(int index1, int index2)
|
|
|
+ {
|
|
|
+ return matrix[index1, index2];
|
|
|
+ }
|
|
|
+
|
|
|
+ //设置matrix[index1, index2]的值
|
|
|
+ public void SetMatrix(int index1, int index2, float weight)
|
|
|
+ {
|
|
|
+ if (weight <= 0)
|
|
|
+ return;
|
|
|
+ matrix[index1, index2] = weight;
|
|
|
+ }
|
|
|
+
|
|
|
+ //边的数目属性
|
|
|
+ public int NumEdges
|
|
|
+ {
|
|
|
+ get { return numEdges; }
|
|
|
+ set { numEdges = value; }
|
|
|
+ }
|
|
|
+
|
|
|
+ //获取顶点的数目
|
|
|
+ public int GetNumOfVertex()
|
|
|
+ {
|
|
|
+ return nodes.Length;
|
|
|
+ }
|
|
|
+
|
|
|
+ //获取边的数目
|
|
|
+ public int GetNumOfEdge()
|
|
|
+ {
|
|
|
+ return numEdges;
|
|
|
+ }
|
|
|
+
|
|
|
+ //判断v是否是图的顶点
|
|
|
+ public bool IsNode(Node<T> v)
|
|
|
+ {
|
|
|
+ //遍历顶点数组
|
|
|
+ foreach (Node<T> nd in nodes)
|
|
|
+ {
|
|
|
+ //如果顶点nd与v相等,则v是图的顶点,返回true
|
|
|
+ if (v.Equals(nd))
|
|
|
+ {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ //获取顶点v在顶点数组中的索引
|
|
|
+ public int GetIndex(Node<T> v)
|
|
|
+ {
|
|
|
+ int i = -1;
|
|
|
+ //遍历顶点数组
|
|
|
+ for (i = 0; i < nodes.Length; ++i)
|
|
|
+ {
|
|
|
+ //如果顶点v与nodes[i]相等,则v是图的顶点,返回索引值i。
|
|
|
+ if (nodes[i].Equals(v))
|
|
|
+ {
|
|
|
+ return i;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return i;
|
|
|
+ }
|
|
|
+
|
|
|
+ //在顶点v1和v2之间添加权值为v的边
|
|
|
+ public void SetEdge(Node<T> v1, Node<T> v2, int v)
|
|
|
+ {
|
|
|
+ if (!IsNode(v1) || !IsNode(v2))
|
|
|
+ {
|
|
|
+ Console.WriteLine("Node is not belong to Graph!");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ //矩阵是对称矩阵
|
|
|
+ matrix[GetIndex(v1), GetIndex(v2)] = v;
|
|
|
+ matrix[GetIndex(v2), GetIndex(v1)] = v;
|
|
|
+ ++numEdges;
|
|
|
+ }
|
|
|
+
|
|
|
+ //删除顶点v1和v2之间的边
|
|
|
+ public void DelEdge(Node<T> v1, Node<T> v2)
|
|
|
+ {
|
|
|
+ //v1或v2不是图的顶点
|
|
|
+ if (!IsNode(v1) || !IsNode(v2))
|
|
|
+ {
|
|
|
+ Console.WriteLine("Node is not belong to Graph!");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ //顶点v1与v2之间存在边
|
|
|
+ if (matrix[GetIndex(v1), GetIndex(v2)] == 1)
|
|
|
+ {
|
|
|
+ //矩阵是对称矩阵
|
|
|
+ matrix[GetIndex(v1), GetIndex(v2)] = 0;
|
|
|
+ matrix[GetIndex(v2), GetIndex(v1)] = 0;
|
|
|
+ --numEdges;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //判断顶点v1与v2之间是否存在边
|
|
|
+ public bool IsEdge(Node<T> v1, Node<T> v2)
|
|
|
+ {
|
|
|
+ //v1或v2不是图的顶点
|
|
|
+ if (!IsNode(v1) || !IsNode(v2))
|
|
|
+ {
|
|
|
+ Console.WriteLine("Node is not belong to Graph!");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ //顶点v1与v2之间存在边
|
|
|
+ if (matrix[GetIndex(v1), GetIndex(v2)] == 1)
|
|
|
+ {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ else //不存在边
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
public class TMSimulatorServer : SocketDeviceSimulator
|
|
|
{
|
|
|
|
|
|
private readonly Regex _check_load = new Regex(@"CHECK LOAD\s+(\d)+\s+(A|B)\s*");
|
|
|
private readonly Regex _move_arm = new Regex(@"(PLACE|PICK)\s+(\d+)\s+ARM\s+(A|B)\s+(\w{4})\s*");
|
|
|
private readonly Regex _move_wafer = new Regex(@"(PLACE|PICK)\s+(\d+)\s+ARM\s+(A|B)\s*");
|
|
|
+ private int _currentStation = 1;
|
|
|
+ private GraphAdjMatrix<int> _Graph = new GraphAdjMatrix<int>(10);
|
|
|
+ private Dictionary<int, int> station2node = new Dictionary<int, int>()
|
|
|
+ {
|
|
|
+ {5,1},
|
|
|
+ {9,2},
|
|
|
+ {2,3},
|
|
|
+ {3,4},
|
|
|
+ {4,5},
|
|
|
+ {12,6},
|
|
|
+ {13,8},
|
|
|
+ };
|
|
|
|
|
|
private PeriodicJob _HwThread;
|
|
|
public TMSimulatorServer() : base(1108, -1, "\r", ' ')
|
|
|
{
|
|
|
_HwThread = new PeriodicJob(500, OnSendEvent, "honghuRobot", true);
|
|
|
+ for (int i = 1; i <= 9; ++i)
|
|
|
+ {
|
|
|
+ _Graph.SetNode(i, new Node<int>(i));
|
|
|
+ _Graph.SetMatrix(i, i, 1);
|
|
|
+ }
|
|
|
+
|
|
|
+ _Graph.SetMatrix(1, 2, 1);
|
|
|
+ _Graph.SetMatrix(1, 3, 1);
|
|
|
+ _Graph.SetMatrix(1, 4, 2);
|
|
|
+ _Graph.SetMatrix(1, 5, 2);
|
|
|
+ _Graph.SetMatrix(1, 6, 1.5f);
|
|
|
+ _Graph.SetMatrix(1, 7, 2);
|
|
|
+ _Graph.SetMatrix(1, 8, 1.5f);
|
|
|
+ _Graph.SetMatrix(1, 9, 2);
|
|
|
+
|
|
|
+ _Graph.SetMatrix(2, 3, 2);
|
|
|
+ _Graph.SetMatrix(2, 4, 2);
|
|
|
+ _Graph.SetMatrix(2, 5, 1);
|
|
|
+ _Graph.SetMatrix(2, 6, 1.5f);
|
|
|
+ _Graph.SetMatrix(2, 7, 2);
|
|
|
+ _Graph.SetMatrix(2, 8, 1.5f);
|
|
|
+ _Graph.SetMatrix(2, 9, 2);
|
|
|
+
|
|
|
+ _Graph.SetMatrix(3, 4, 1);
|
|
|
+ _Graph.SetMatrix(3, 5, 1);
|
|
|
+ _Graph.SetMatrix(3, 6, 1.5f);
|
|
|
+ _Graph.SetMatrix(3, 7, 2);
|
|
|
+ _Graph.SetMatrix(3, 8, 1.5f);
|
|
|
+ _Graph.SetMatrix(3, 9, 2);
|
|
|
+
|
|
|
+ _Graph.SetMatrix(4, 5, 1);
|
|
|
+ _Graph.SetMatrix(4, 6, 2);
|
|
|
+ _Graph.SetMatrix(4, 7, 2.5f);
|
|
|
+ _Graph.SetMatrix(4, 8, 2);
|
|
|
+ _Graph.SetMatrix(4, 9, 2.5f);
|
|
|
+
|
|
|
+ _Graph.SetMatrix(5, 6, 2);
|
|
|
+ _Graph.SetMatrix(5, 7, 2.5f);
|
|
|
+ _Graph.SetMatrix(5, 8, 1);
|
|
|
+ _Graph.SetMatrix(5, 9, 1.5f);
|
|
|
+
|
|
|
+ _Graph.SetMatrix(6, 7, .5f);
|
|
|
+ _Graph.SetMatrix(6, 8, 1);
|
|
|
+ _Graph.SetMatrix(6, 9, 1.5f);
|
|
|
+
|
|
|
+ _Graph.SetMatrix(7, 8, 1.5f);
|
|
|
+ _Graph.SetMatrix(7, 9, 1f);
|
|
|
+
|
|
|
}
|
|
|
|
|
|
private bool OnSendEvent()
|
|
@@ -127,9 +376,11 @@ namespace EfemDualSimulator.Views
|
|
|
string slot = result.Groups[3].Value;
|
|
|
string arm = result.Groups[4].Value;
|
|
|
string dir = result.Groups[5].Value;
|
|
|
-
|
|
|
- Thread.Sleep(2000);
|
|
|
+ // 01 VCEA 02 VCEB 03 PMA 04 PMB 05 PMC 6/7 cooling1 8/9 cooling2
|
|
|
+ int sleepTime = Convert.ToInt32(_Graph.GetMatrix(_currentStation, station2node[Convert.ToInt32(station)]) * 4000);
|
|
|
+ Thread.Sleep(sleepTime);
|
|
|
OnWriteMessage("_RDY");
|
|
|
+ _currentStation = station2node[Convert.ToInt32(station)];
|
|
|
}
|
|
|
else if (_move_wafer.IsMatch(str))
|
|
|
{
|
|
@@ -141,9 +392,11 @@ namespace EfemDualSimulator.Views
|
|
|
string slot = result.Groups[3].Value;
|
|
|
string arm = result.Groups[4].Value;
|
|
|
|
|
|
- Thread.Sleep(2000);
|
|
|
+ int sleepTime = Convert.ToInt32(_Graph.GetMatrix(_currentStation, station2node[Convert.ToInt32(station)]) * 4000);
|
|
|
+ Thread.Sleep(sleepTime);
|
|
|
string msg = "_RDY";
|
|
|
OnWriteMessage(msg);
|
|
|
+ _currentStation = Convert.ToInt32(station2node[Convert.ToInt32(station)]);
|
|
|
}
|
|
|
else if (new Regex(@"RQ WAF_CEN DATA.*").IsMatch(str))
|
|
|
{
|