新增一個Windows Form Application專案
新增一個類別TrayAction.cs
新增TrayAction.cs
以下功能及架構說明:
1. Tray盤入料順序: 進料區2 –> 進料區1
2. 兩組Pick and Place(以下簡稱PP), 每次一組吸真空( 1 ), 另一組不動作( 0 )
3. 一開始, PP移至進料區2(1,1)位置, PP1吸真空( 1 ), PP2不動作( 0 );
4. 接著, PP移置進料區2(1,2)位置, 換PP1不動作( 0 ), PP2吸真空( 1 ),
5. 接著, 將PP移置入料檢測, 將PP上面兩個料片放片(破真空), 完成一個cycle
6. 重複步驟 3~5,
7. PP移動走ZigZag方式 即(1,1) –> (1,2) –> (1,3) –> (2,3) –> (2, 2) –> (2,1) –>(3 ,1)…(9,3) 接續進料區1 (1,3) –> (1, 2) …(9,3)->(9,2) –>(9, 1)
8. 途中若有吸料失敗, 則繼續往下一個吸, 直到成功為止
-----------------------------------------------------------------------------------------------------------------------------------
應用Factory Pattern和Singleton Pattern撰寫以上功能, 可參考:
1: enum PP_STATUS { PP_IDLE, PP_WORK };
2: public abstract class Tray
3: {
4: public int m_rows, m_cols; // 總共列數和行數
5: public int m_row, m_col; // 目前在第幾列, 第幾行
6: public int m_index; // 吸/放料的索引(PP1或PP2)
7: public int m_colDir; // column 前進方向
8: public int m_countMax; // 一盤計數上限值
9: public int m_count; // 一盤計數器
10: public int m_countTray; // Tray盤計數器
11: public int m_countTrayMax; // Tray盤計數器上限值
12: public int m_countTotal; //一個回合內進料片數計數器
13: #region 宣告抽象方法, 所繼承的類別必須實作之
14: public abstract void UpdatePPPosition(); // 更新PP吸/放料位置
15: public abstract void UpdateColDir(); // 更新column 前進方向
16: public abstract void UpdatePPIndex(); // 更新PP(吸/放)索引
17: #endregion
18: }
1: public class TrayAction : Tray
2: {
3: #region Singleton Pattern
4: public static TrayAction manager;
5: public static TrayAction Instance
6: {
7: get
8: {
9: if (manager == null)
10: {
11: int rows = 9; // 總共列數 for single tray
12: int cols = 3; // 總共行數 for single tray
13: int countTrayMax = 2; // 一回合最多幾盤
14: manager = new TrayAction(rows, cols, countTrayMax);
15: }
16: return manager;
17: }
18: }
19: #endregion
20: //-------------------------------------------------------------
21: // 預設建構子
22: public TrayAction() { }
23: // 有參數建構子
24: /// <summary>
25: /// Tray動作
26: /// </summary>
27: /// <param name="rows">總共列數</param>
28: /// <param name="cols">總共行數</param>
29: /// <param name="countTrayMax">一回合最多幾盤</param>
30: public TrayAction(int rows, int cols, int countTrayMax)
31: {
32: m_cols = cols;
33: m_rows = rows;
34: m_row = 1;
35: m_col = 1;
36: m_index = 1;
37: m_colDir = 1; // 1:正的方向, 1->2->3 -1:負的方向 3->2->1
38: m_countMax = m_cols * m_rows;
39: m_count = 1;
40: m_countTray = 1; // tray盤計數器
41: m_countTrayMax = countTrayMax; // tray盤計數器上限值
42: m_countTotal = 1; // 一個回合內進料片數計數器
43: }
44: //-------------------------------------------------------------
45: #region 公開方法
46: public void Reset()
47: {
48: m_row = 1;
49: m_col = 1;
50: m_index = 1;
51: m_colDir = 1; // 1:正的方向, 1->2->3 -1:負的方向 3->2->1
52: m_countMax = m_cols * m_rows;
53: m_count = 1; // 料片計數器
54: m_countTray = 1; // tray盤計數器
55: m_countTotal = 1; // 一回合可以進料的總片數
56: }
57: public int cols
58: {
59: get { return m_cols; }
60: set
61: {
62: m_cols = value;
63: m_countMax = m_rows * m_cols;
64: }
65: }
66: public int rows
67: {
68: get { return m_rows; }
69: set
70: {
71: m_rows = value;
72: m_countMax = m_rows * m_cols;
73: }
74: }
75: public int row
76: {
77: get { return m_row; }
78: set { m_row = value; }
79: }
80: public int col
81: {
82: get { return m_col; }
83: set { m_col = value; }
84: }
85: public void PPInfo(out int PP1, out int PP2)
86: {
87: if (m_index == 1)
88: {
89: PP1 = 1;
90: PP2 = 0;
91: }
92: else
93: {
94: PP1 = 0;
95: PP2 = 1;
96: }
97: }
98: public void TrayInfo(out int countTray, out int count, out int row, out int col, out int PP1, out int PP2)
99: {
100: PPInfo(out PP1, out PP2); // PP1 or PP2
101: row = m_row; // 列
102: col = m_col; // 行
103: countTray = m_countTray; // Tray盤計數器
104: count = m_count; // 料片計數器
105: }
106: public int countTray
107: {
108: get { return m_countTray; }
109: }
110: #endregion
111:
112:
113: // 更新PP吸/放料位置
114: public override void UpdatePPPosition()
115: {
116: MoveStep();
117: UpdateColDir(); // 更新column 前進方向
118: UpdatePPIndex(); // 更新PP索引動作
119: }
120: public void TryNextPPPosition()
121: {
122: MoveStep();
123: UpdateColDir(); // 更新column 前進方向
124: }
125: private void MoveStep()
126: {
127: if (m_colDir == 1)
128: {
129: m_col++;
130: }
131: else if (m_colDir == -1)
132: {
133: m_col--;
134: }
135: m_count++;
136: m_countTotal++;
137: }
138: // 更新PP(吸/放)索引
139: public override void UpdatePPIndex()
140: {
141: if (m_index == 1)
142: {
143: m_index = 2; // PP2
144: }
145: else
146: {
147: m_index = 1; // PP1
148: }
149: }
150: public bool bSingleLoopDone
151: {
152: get
153: {
154: if (m_countTotal == (m_countTrayMax * m_rows * m_cols))
155: {
156: return true;
157: }
158: else
159: {
160: return false;
161: }
162: }
163: }
164: // 更新column 前進方向
165: public override void UpdateColDir()
166: {
167: if (m_col > m_cols)
168: {
169: m_colDir = -1;
170: m_col = m_cols;
171: if( m_row < m_rows)
172: m_row++;
173: }
174: else if (m_col < 1)
175: {
176: m_colDir = 1;
177: m_col = 1;
178: if (m_row < m_rows)
179: m_row++;
180: }
181: // 一盤滿了
182: if( m_count > m_countMax)
183: {
184: m_row = 1;
185: m_count = 1;
186: m_countTray++; // 下一盤
187: if (m_countTray > m_countTrayMax) // 一個回合結束
188: {
189: m_countTray = 1; // reset m_countTray
190: m_countTotal = 1; // reset 一個回合總進料片計數器
191: }
192: }
193: }
194:
195: }
196: }
-------------------------------------------------------------------------------------------------------------------------------------------
撰寫一個client端測試上面功能
<訊息>按鈕如下:
1: private void button1_Click(object sender, EventArgs e)
2: {
3: int rows = TrayAction.Instance.rows;
4: int cols = TrayAction.Instance.cols;
5: int row, col, count, countTray;
6: int PP1, PP2;
7: bool bSingleLoopDone = TrayAction.Instance.bSingleLoopDone;
8: TrayAction.Instance.TrayInfo(out countTray, out count, out row, out col, out PP1, out PP2);
9: TrayAction.Instance.PPInfo(out PP1,out PP2);
10: toolStripStatusLabel1.Text = string.Format("第 {0} 盤 第 {1} 片,第 {2} 列,第 {3} 行, PP1: {4}, PP2: {5}", countTray, count, row, col, PP1, PP2);
11: toolStripStatusLabel2.Text = string.Format("Tray盤:列和行的個數 ({0}, {1})", rows, cols);
12: toolStripStatusLabel3.Text = string.Format("一個回合結束{0}", bSingleLoopDone);
13: }
<下一個>按鈕
1: private void button2_Click(object sender, EventArgs e)
2: {
3: TrayAction.Instance.UpdatePPPosition(); // 下一片位置
4: button1_Click(button1, null); // 訊息按鈕
5: }
留言列表