教學

本節將具體說明如何安裝多零件的應用程式和多零件、多機器人的應用程式。但僅針對大多應用案例簡單說明步驟,不詳細說明執行內容。本章節內容,則是以使用者已了解如何建立新零件、執行零件校準、以及如何編寫1台機器人/1種零件的應用程式為前提所提出的說明。
如需詳細資訊,請參閱以下內容。
開始使用

教學1:1台機器人、1台送料器、2種零件

本教學範例中,具有2種不同的零件同時傳送在同一個送料器上。因此零件會有不同的物理性質。此處使用的是零件#1和零件#2。並且有在送料器上方設置朝下固定的攝影機。機器人將會取放2個零件#1,接著再取放1個零件#2。並以迴圈持續執行此操作。

各個零件將使用不同的末端夾具(輸出位元)拾取。所以在此組裝應用程式中,零件數量和拾取順序非常重要。零件#1和零件#2之間的處理程序切換,則使用PF_ActivePart執行。首先,要在PF_Robot回呼函數內編寫執行機器人動作的程式碼。接著,透過個別的多工處理程序執行動作、平行處理送料器的振動,藉此提升機器人的總處理量。

  1. 建立Epson RC+的新專案。

  2. 對朝下固定的攝影機進行校準。

  3. 透過Vision Guide建立Part Blob序列。
    將「Part Blob序列」用於零件校準期間和執行時的回饋,藉此決定零件的最佳投入方法。Part Blob序列會在執行時檢測各個零件或零件群組。通常Part Blob序列當中會包含單一的Blob視覺物件。Part Blob序列則需要已分配給Calibration屬性的攝影機校準。
    將Blob物件的NumberToFind屬性設定為「All」。將Blob的ThresholdAuto屬性設定為「False」(預設值)。
    在平台上放置零件,開啟[直方圖]視窗,並持續調整ThresholdHigh和ThresholdLow直到檢測到零件。將Blob的MinArea設為零件區域之MinArea的0.9倍左右。若零件有正反面之別,則應設定MinArea,確保零件朝向任何方向都能被檢測到。(送料器上的)2種零件可各自設定個別的Part Blob序列,但通常可針對所有零件使用相同的Part Blob序列。
    確認Part Blob序列能檢測到傳送在此送料器上的每種零件。Blob物件的搜尋視窗必須盡可能地覆蓋到廣泛的平台區域。但重點在於讓Blob物件只檢測到零件,而不會檢測到送料器托盤本身。若Part Blob序列檢測到托盤的一部分,將使得系統無法正常運作。

  4. 透過Vision Guide為此送料器運作的2種零件各自建立零件序列。
    並確認各個序列都有設定Calibration屬性。一般而言,Geometric物件會在需要識別正面時使用(第2個Geometric物件則是在需要翻轉以識別零件的背面時才會使用)。而視覺物件的NumberToFind屬性,則設定為「All」。

  5. 顯示[工具] - [料件送料],並依照「零件精靈」的操作指示新增新零件。
    如需零件精靈的詳細資訊,請參閱以下內容。
    開始使用

  6. 點擊新零件的[校準] - [校準]按鈕,以開始「校準精靈」。
    如需校準精靈的詳細使用方法,請參閱以下內容。
    校準&測試

  7. 點擊零件#1的[拾取] - [教導]按鈕。
    使用點動操作將機器人移動至零件的拾取高度後,針對「Pick Z」進行教導。

  8. 點擊[料件送料] - [增加]按鈕,以新增零件#2。
    使用「零件精靈」設定零件。

  9. 點擊[校準] - [校準]按鈕,以開始校準精靈。

  10. 點擊零件#2的[拾取] - [教導]按鈕。
    使用點動操作將機器人移動至零件的拾取高度後,針對「Pick Z」進行教導。

  11. 關閉[料件送料]對話方塊。
    料件送料的範本程式碼(料件送料的回呼函數)將會自動建立。

  12. 接著教導機器人停止(park)和放置(place)的點位,將其分別命名為「park」和「place」。

  13. 依照下列內容針對範本程式碼進行修正:

Main.prg

Function Main
    Robot 1
    Motor On
    Power High
    Speed 50
    Accel 50, 50
    Jump Park

    PF_Start 1, 2
Fend

PartFeeding.prg

Global Integer numPicked ' number of parts that have been picked

Function PF_Robot(PartID As Integer) As Integer

    Integer numRequired, gripperOutput

    Select PartID
        Case 1
            numRequired = 2 ' number of parts required
            gripperOutput = 1
        Case 2
            numRequired = 1
            gripperOutput = 2
    Send
    Do
        If PF_QueLen(PartID) > 0 Then
            P0 = PF_QueGet(PartID)
            PF_QueRemove (PartID)
            Jump P0
            On gripperOutput
            Wait 0.1
            Jump Place
            Off gripperOutput
            Wait 0.1
            numPicked = numPicked + 1
        Else
            ' Not enough parts were picked
            PF_ActivePart PartID ' No change in Active Part
            PF_Robot = PF_CALLBACK_SUCCESS
            Exit Function
        EndIf
    Loop Until numPicked = numRequired

    numPicked = 0
    ' select the next Active Part
    If PartID = 1 Then
        PF_ActivePart 2
    Else
        PF_ActivePart 1
    EndIf
    PF_Robot = PF_CALLBACK_SUCCESS
Fend

上述的範例程式碼當中,送料器會在機器人完成「放置」動作以及PF_Robot函數結束之後,視需要進行振動。而這段程式碼還能再進一步重組,讓送料器的振動與機器人動作一併執行。
並且使用PF_Robot回呼函數(例如:Function Main)來通知動作任務何時可以拾取。
當零件可使用時,則使用記憶體IO(命名為「PartsToPick1」、「PartsToPick2」)發送訊號。
當最後一個可使用的零件被放置時(在此範例中為動作完成80%的狀態),動作任務將會向PF_Robot函數發送訊號並結束,接著回傳數值。此回傳值,能讓系統得知已可擷取新影像、進行振動、以及透過料斗供應零件等。此處則再修改教學範例的程式碼,讓送料器動作和機器人動作能夠一併執行:

Main.prg

Function Main
    Integer numToPick1, numToPick2, numPicked

    Motor On
    Power High
    Speed 50
    Accel 50, 50
    Jump Park

    MemOff PartsToPick1
    MemOff PartsToPick2
    numToPick1 = 2
    numToPick2 = 1

    PF_Start 1, 2

    Do
        numPicked = 0

        Do
            Wait MemSw(PartsToPick1) = On
            pick = PF_QueGet(1)
            PF_QueRemove (1)
            Jump pick
            On gripper1
            Wait 0.1
            numPicked = numPicked + 1
            If numPicked < numToPick1 And PF_QueLen(1) > 0 Then
                Jump Place
            Else
                ' Last part or no more parts available to pick
                If numPicked = numToPick1 Then
                    ' Select the next part
                    PF_ActivePart 2
                EndIf
                Jump Place ! D80; MemOff PartsToPick1 !
            EndIf
            Off gripper1
            Wait 0.1
        Loop Until numPicked = numToPick1

        numPicked = 0
        Do
            Wait MemSw(PartsToPick2) = On
            pick = PF_QueGet(2)
            PF_QueRemove (2)
            Jump pick
            On gripper2
            Wait 0.1
            numPicked = numPicked + 1
            If numPicked < numToPick2 And PF_QueLen(2) > 0 Then
                Jump Place
            Else
                ' Last part or no more parts available to pick
                If numPicked = numToPick2 Then
                    ' Select the next part
                    PF_ActivePart 1
                EndIf
                Jump Place ! D80; MemOff PartsToPick2 !
            EndIf
            Off gripper2
            Wait 0.1
        Loop Until numPicked = numToPick2
    Loop
Fend

PartFeeding.prg

Function PF_Robot(PartID As Integer) As Integer
    Select PartID
        Case 1
            MemOn PartsToPick1
            Wait MemSw(PartsToPick1) = Off
        Case 2
            MemOn PartsToPick2
            Wait MemSw(PartsToPick2) = Off
    Send

    PF_Robot = PF_CALLBACK_SUCCESS
Fend

教學2:2台機器人、1台送料器、2種零件

本教學範例中,具有2種不同的零件同時傳送在同一個送料器上。因此零件會有不同的物理性質。此處使用的是零件#1和零件#2。並且有在送料器上方設置朝下固定的攝影機。2台機器人將共享同一個送料器。2台機器人會交替從送料器上拾取。各個機器人將會取放各自的零件。機器人#1會先拾取1個零件#1,機器人#2則接著拾取1個零件#2。
在此應用場合中,拾取的順序很重要。拾取順序則可透過「PF_ActivePart」來切換。首先,要在PF_Robot回呼函數內編寫執行機器人動作的程式碼。在此應用案例中,機器人動作將會依序進行。一次只會有1台機器人行動。
接著,在個別的多工處理程序中執行動作,以提升機器人的總處理量。修改後的教學範例中也包含PF_AccessFeeder / PF_ReleaseFeeder。PF_AccessFeeder / PF_ReleaseFeeder可用來防止機器人從送料器拾取時發生碰撞。

  1. 建立Epson RC+的新專案。
  2. 對用於機器人#1的朝下固定的攝影機進行校準。
  3. 對用於機器人#2的朝下固定的攝影機進行校準。
  4. 從Vision Guide建立零件#1的Part Blob序列。通常Part Blob序列當中會包含單一的Blob視覺物件。序列需要對已分配給Calibration屬性的機器人#1執行的攝影機校準。將Blob物件的NumberToFind屬性設定為「All」。
    將Blob的ThresholdAuto屬性設定為「False」(預設值)。在平台上放置零件,開啟[直方圖]視窗,並持續調整ThresholdHigh和ThresholdLow直到檢測到零件。將Blob的MinArea設為零件區域之MinArea的0.9倍左右。
    若零件有正反面之別,則應設定MinArea,確保零件朝向任何方向都能被檢測到。確認Part Blob序列能檢測到零件#1。
    Blob物件的搜尋視窗必須盡可能地覆蓋到廣泛的平台區域。但重點在於讓Blob物件只檢測到零件,而不會檢測到送料器托盤本身。
  5. 從Vision Guide建立零件#2的Part Blob序列。通常Part Blob序列當中會包含單一的Blob視覺物件。序列需要對已分配給Calibration屬性的機器人#2執行的攝影機校準。將Blob物件的NumberToFind屬性設定為「All」。
    將Blob的ThresholdAuto屬性設定為「False」(預設值)。
    在平台上放置零件,開啟[直方圖]視窗,並持續調整ThresholdHigh和ThresholdLow直到檢測到零件。
    將Blob的MinArea設為零件區域之MinArea的0.9倍左右。
    若零件有正反面之別,則應設定MinArea,確保零件朝向任何方向都能被檢測到。確認Part Blob序列能檢測到零件#2。Blob物件的搜尋視窗必須盡可能地覆蓋到廣泛的平台區域。
    但重點在於讓Blob物件只檢測到零件,而不會檢測到送料器托盤本身。
  6. 透過Vision Guide建立用於檢測零件#1的零件序列。
    請確認Calibration屬性設定為針對機器人#1執行的校準。
    一般而言,Geometric物件會在需要識別正面時使用。(第2個Geometric物件則是在需要翻轉以識別零件的背面時才會使用。)將視覺物件的NumberToFind屬性設定為「All」。
  7. 透過Vision Guide建立用於檢測零件#2的零件序列。
    請確認Calibration屬性設定為針對機器人#2執行的校準。
    一般而言,Geometric物件會在需要識別正面時使用。(第2個Geometric物件則是在需要翻轉以識別零件的背面時才會使用。)將視覺物件的NumberToFind屬性設定為「All」。
  8. 顯示[工具] - [料件送料],新增零件#1的新零件。依照「零件精靈」的操作指示新增零件。確認在零件精靈的第一頁已選擇機器人#1。
    如需零件精靈的詳細資訊,請參閱以下內容。
    開始使用
  9. 點擊新零件#1的[校準] - [校準]按鈕,以開始「校準精靈」。
    如需校準精靈的詳細使用方法,請參閱以下內容。
    校準&測試
  10. 點擊零件#1的[拾取] - [教導]按鈕。
    使用點動操作將機器人#1移動至零件的拾取高度後,針對「Pick Z」進行教導。
  11. 點擊[料件送料] - [增加]按鈕,以新增零件#2。使用「零件精靈」設定零件。
    確認在零件精靈的第一頁已選擇機器人#2。
  12. 點擊[校準] - [校準]按鈕,以開始校準精靈。
  13. 點擊零件#2的[拾取] - [教導]按鈕。使用點動操作將機器人#2移動至零件的拾取高度後,針對「Pick Z」進行教導。
  14. 關閉[料件送料]對話方塊。
    零件送料的範本程式碼(Part Feeding的回呼函數)將會自動建立。
  15. 依照下列內容針對範本程式碼進行修正:

Main.prg

Function Main
    Robot 1
    Motor On
    Power High
    Speed 50
    Accel 50, 50
    Jump Park
    Robot 2
    Motor On
    Power High
    Speed 50
    Accel 50, 50
    Jump Park

    PF_Start 1, 2
Fend

PartFeeding.prg

Function PF_Robot(PartID As Integer) As Integer
    If PF_QueLen(PartID) > 0 Then
        Select PartID
            Case 1
                Robot 1
                P0 = PF_QueGet(1)
                PF_QueRemove (1)
                Jump P0 /R
                On rbt1Gripper
                Wait 0.25
                Jump Place
                Off rbt1Gripper
                Wait 0.25
                PF_ActivePart 2
            Case 2
                Robot 2
                P0 = PF_QueGet(2)
                PF_QueRemove (2)
                Jump P0 /L
                On rbt2Gripper
                Wait 0.25
                Jump Place
                Off rbt2Gripper
                Wait 0.25
                PF_ActivePart 1
        Send

    EndIf

    PF_Robot = PF_CALLBACK_SUCCESS

Fend

此處將會修正範例程式碼,讓機器人動作在另外的多工處理程序中執行。當1台機器人離開送料器時,另一台機器人將可以開始朝送料器移動。要讓多台機器人使用並行動作共享1台送料器時,使用PF_AccessFeeder命令和PF_ReleaseFeeder命令來防止機器人碰撞非常重要。
此外,修改後的程式碼可平行處理送料器振動和機器人動作。在本教學中,當各機器人達到其放置位置的80%之處時,機器人將會清除攝影機的視野,並且可擷取影像。
此外,當各機器人達到其放置位置的80%之處時,另一台機器人可以安全地開始朝送料器移動。實際動作的百分比取決於機器人在特定情況下的速度和相對定位。各機器人都有「park」點和「place」點。在本教學範例中,機器人#1是以右手姿態從送料器拾取,機器人#2則是以左手姿態從送料器拾取。
修改後的範本程式碼則如以下所示:

Main.prg

Function Main
    Robot 1
    Motor On
    Power High
    Speed 50
    Accel 50, 50
    Jump Park
    Robot 2
    Motor On
    Power High
    Speed 50
    Accel 50, 50
    Jump Park
    MemOff PartsToPick1
    MemOff PartsToPick2

    PF_Start 1, 2
    Xqt Robot1PickPlace
    Xqt Robot2PickPlace
Fend

Function Robot1PickPlace
    Robot 1
    Do
        Wait MemSw(PartsToPick1) = On
        PF_AccessFeeder 1
        P0 = PF_QueGet(1)
        PF_QueRemove (1)
        Jump P0 /R
        On rbt1Gripper
        Wait 0.25
        Jump Place ! D80; MemOff PartsToPick1; PF_ReleaseFeeder 1 !
        Off rbt1Gripper
        Wait 0.25
    Loop
Fend

Function Robot2PickPlace
    Robot 2
    Do
        Wait MemSw(PartsToPick2) = On
        PF_AccessFeeder 1
        P0 = PF_QueGet(2)
        PF_QueRemove (2)
        Jump P0 /L
        On rbt2Gripper
        Wait 0.25
        Jump Place ! D80; MemOff PartsToPick2; PF_ReleaseFeeder 1 !
        Off rbt2Gripper
        Wait 0.25
    Loop
Fend

PartFeeding.prg

Function PF_Robot(PartID As Integer) As Integer
    Select PartID
        Case 1
            If PF_QueLen(1) > 0 Then
                MemOn PartsToPick1
                Wait MemSw(PartsToPick1) = Off
                PF_ActivePart 2
            Else
                PF_ActivePart 1
            EndIf
        Case 2
            If PF_QueLen(2) > 0 Then
                MemOn PartsToPick2
                Wait MemSw(PartsToPick2) = Off
                PF_ActivePart 1
            Else
                PF_ActivePart 2
            EndIf
    Send
    PF_Robot = PF_CALLBACK_SUCCESS
Fend