新增一個Windows Form Application專案

image

新增一個類別TrayAction.cs

image

新增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. 途中若有吸料失敗, 則繼續往下一個吸, 直到成功為止

 image

-----------------------------------------------------------------------------------------------------------------------------------

應用Factory Pattern和Singleton Pattern撰寫以上功能, 可參考:

image

   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端測試上面功能

image

<訊息>按鈕如下:

   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: }

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 me1237guy 的頭像
    me1237guy

    天天向上

    me1237guy 發表在 痞客邦 留言(0) 人氣()