フィーダーごとにロボット1台&フィーダーごとにパーツ1種類

プログラム例 1.1

例タイプ:
モーションにPF_Robot コールバックを使用する

構成

  • ロボットの数:1
  • フィーダーの数:1
  • フィーダー上のパーツの種類数:1
  • 配置場所の数:1
    カメラの向き:フィーダー#1上の固定下向きカメラ

解説
パーツは、フィーダーからボックスへ移動します。すべてのパーツが移動したとき、Controlコールバックは、パーツを要求します。オペレーター、またはホッパーにより、フィーダーにパーツが補充されると、移動サイクルを継続します。PF_Stopコマンドが実行されると、現在のサイクルが停止し、アプリケーションが終了します。(ただし、PF_Stopコマンドは、以下のサンプルコードでは使用していません。)

サンプルコード
Main.prg

Function main
    If Motor = Off Then
        Motor On
    EndIf
    Power Low
    Jump Park
    PF_Start 1
Fend

PartFeeding.prg

Function PF_Robot(PartID As Integer) As Integer
    Do While PF_QueLen(PartID) > 0
        P0 = PF_QueGet(PartID)
        Jump P0
        On Gripper; Wait 0.2
        Jump Place
        Off Gripper; Wait 0.2
        PF_QueRemove PartID
        If PF_IsStopRequested(PartID) = True Then
            Exit Do
        EndIf
    Loop
    PF_Robot = PF_CALLBACK_SUCCESS
 Fend

プログラム例 1.2

例タイプ:
マルチロボットシステム - フィーダーごとに1台のロボット&フィーダーごとに1種類のパーツ

構成

  • ロボットの数: 2
    ロボット1は、コントロールユニットに接続します。ロボット2は、ドライブユニットに接続します。
  • フィーダーの数: 2
  • フィーダー上のパーツの種類数: 1
  • 配置場所の数: 各ロボットに1
  • カメラの向き: 各フィーダーに固定下向きカメラを配置

解説
各ロボットが、それぞれパーツをピック&プレースします。ロボットごとに、専用のフィーダーとプレース場所があります。また、ロボット1とロボット2の動作範囲は重なりません。各ロボットには、それぞれのポイントファイルに、“Park”, “Pick”, “Place”と教示されたポイントがあります。

サンプルコード
Main.prg

Function main
    Robot 1
    If Motor = Off Then
         Motor On
    EndIf
    Power Low
    Jump Park

    Robot 2
    If Motor = Off Then Motor On
    Power Low
    Jump Park

    PF_Start 1
    PF_Start 2
Fend

PartFeeding.prg

Function PF_Robot(PartID As Integer) As Integer
    Integer gripperOutput

    Select PartID
        Case 1
            Robot 1
            gripperOutput = 1
        Case 2
            Robot 2
            gripperOutput = 2
    Send

    Do While PF_QueLen(PartID) > 0
        Pick = PF_QueGet(PartID)
        Jump pick
        On gripperOutput; Wait 0.2
        Jump Place
        Off gripperOutput; Wait 0.2
        PF_QueRemove PartID
        If PF_IsStopRequested(PartID) = True Then
            Exit Do
        EndIf
    Loop
    PF_Robot = PF_CALLBACK_SUCCESS

Fend

プログラム例 1.3

例タイプ:
ロボット動作によるビジョンと振動の並列処理

構成

  • ロボットの数:1
  • フィーダーの数:1
  • パーツの種類数:1
  • 配置場所の数:1
  • カメラの向き:固定下向きカメラ

解説
ロボットは、パーツフィーダーからパーツ#1をピックし、固定治具へプレースします。この動作は、すべての“表”パーツがフィーダーから移動されるまで続きます。最後のパーツがプレースされているとき(フィーダー動作の90%)、フィーダーが振動し、必要に応じてホッパーがフィーダーにパーツを補充します。
この例は、処理能力を最適化するため、ロボットのモーションと並行してフィーダー動作がどのように発生するかを示しています。

サンプルコード
Main.prg

Function main
    MemOff PartsToPick
    Off Gripper

    Robot 1
    If Motor = Off Then
        Motor On
    EndIf
    Power Low
    Jump Park

    PF_Start(1)

    Xqt RobotPickPlace
Fend

Function RobotPickPlace
    Do
        Wait MemSw(PartsToPick) = On
        If PF_QueLen(1) > 0 Then
             Do
                Pick = PF_QueGet(1)
                PF_QueRemove 1
                Jump pick
                On Gripper; Wait 0.2
                If PF_QueLen(1) = 0 Then
                    Jump Place ! D90; MemOff PartsToPick !
                    Off Gripper; Wait 0.2
                    Exit Do
                Else
                    Jump Place
                    Off Gripper; Wait 0.2
                EndIf
            Loop
        Else
            MemOff PartsToPick
        EndIf
    Loop
Fend

PartFeeding.prg

Function PF_Robot(PartID As Integer) As Integer
    MemOn PartsToPick
    Wait MemSw(PartsToPick) = Off

    PF_Robot = PF_CALLBACK_SUCCESS
Fend

プログラム例 1.4

例タイプ:
フィーダーごとに、ロボット1台, フィーダー2つ, パーツ1種類

構成

  • ロボットの数: 1
  • フィーダーの数: 2
  • 各フィーダー上のパーツの種類数: 1
  • 配置場所の数: 1
  • カメラの向き :各フィーダーに固定下向きカメラを配置

解説
ロボットは、フィーダー#1からパーツ#1をピックし、ボックスにプレースします。この動作は、すべての“表”パーツがフィーダー#1から移動されるまで続きます。そのあと、ロボットはフィーダー#2 から“表”パーツをピックし、ボックスへ移動します。カメラとフィーダーは、並行して動作します。

サンプルコード
Main.prg

Function main
    MemOff PartsToPick1; MemOff PartsToPick2
    Off Gripper

    Robot 1
    If Motor = Off Then
        Motor On
    EndIf
    Power Low
    Jump Park

    PF_Start(1)
    PF_Start(2)

    Xqt rbt1
Fend

Function rbt1
    Do
        Call RobotPickPlace(1)
        Call RobotPickPlace(2)
    Loop
Fend

Function RobotPickPlace(PartID As Integer)
    Integer partsToPickMembit

    Select PartID
        Case 1
            partsToPickMembit = IONumber("PartsToPick1")
        Case 2
            partsToPickMembit = IONumber("PartsToPick2")
    Send

    Wait MemSw(partsToPickMembit) = On
    If PF_QueLen(PartID) > 0 Then

         Do
            Pick = PF_QueGet(PartID)
            PF_QueRemove PartID
            Jump pick
            On Gripper; Wait 0.2
            If PF_QueLen(PartID) = 0 Then
                Jump Place ! D90; MemOff partsToPickMembit !
                Off Gripper; Wait 0.2
                Exit Do
            Else
                Jump Place
                Off Gripper; Wait 0.2
            EndIf

            If PF_IsStopRequested(PartID) = True Then
                MemOff partsToPickMembit
                Exit Do
            EndIf
        Loop
    Else
        MemOff partsToPickMembit
    EndIf
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

プログラム例 1.5

例タイプ:
フィーダーごとに、ロボット1台, フィーダー2つ, パーツ1種類 - モバイルマウントカメラ

構成

  • ロボットの数: 1
  • フィーダーの数: 2
  • フィーダー上のパーツの種類数: 1
  • 配置場所の数: 1
  • カメラの向き: 各フィーダーは、ロボットのモバイルマウントカメラを使用します。
    (この例では、固定下向きカメラは使用しません。)

解説
ロボットは、フィーダー#1上にモバイルマウントカメラを移動して画像を撮影します。ロボットは、フィーダー#1から各パーツをピックし、ボックスにプレースします。この動作は、すべての“表”パーツがフィーダーから移動されるまで続きます。ロボットは、フィーダー#2上にモバイルマウントカメラを移動して画像を撮影します。ロボットは、フィーダー#2から正しい向きのパーツをピックし、ボックスへプレースします。

キーポイント


バックライト付きの複数のフィーダーを搭載したモバイルカメラを使用する場合は、各フィーダーに紐づけられているパーツそれぞれに別のビジョンシーケンスを使用します。

サンプルコード
Main.prg

Function main
    MemOff PartsToPick1; MemOff PartsToPick2
    MemOff mobileCamBefore1; MemOff mobileCamAfter1
    MemOff mobileCamBefore2; MemOff mobileCamAfter2
    MemOff mobileCamInPos1; MemOff mobileCamInPos2

    Robot 1
    If Motor = Off Then
        Motor On
    EndIf
    Power Low
    Jump Park

    PF_Start(1)
    PF_Start(2)
    Xqt rbt1
Fend

Function rbt1
    Do
        Wait MemSw(mobileCamBefore1) = On
        Jump MobileCamShotFeeder1; MemOn mobileCamInPos1
        Wait MemSw(mobileCamAfter1) = On
        MemOff mobileCamInPos1

        Call RobotPickPlace(1)

        Wait MemSw(mobileCamBefore2) = On
        Jump MobileCamShotFeeder2; MemOn mobileCamInPos2
        Wait MemSw(mobileCamAfter2) = On
        MemOff mobileCamInPos2

        Call RobotPickPlace(2)
    Loop
Fend

Function RobotPickPlace(PartID As Integer)
    Integer partsToPickMembit, partCnt, gripperOutput, toolNum

    Select PartID
        Case 1
            partsToPickMembit = IONumber("PartsToPick1")
        Case 2
            partsToPickMembit = IONumber("PartsToPick2")
    Send

    Wait MemSw(partsToPickMembit) = On
    Do While PF_QueLen(PartID) > 0
        P0 = PF_QueGet(PartID)
        Jump P0
        On Gripper; Wait 0.2
        Jump Place
        Off Gripper; Wait 0.2
        PF_QueRemove PartID
        If PF_IsStopRequested(PartID) = True Then
            Exit Do
        EndIf
    Loop
    MemOff partsToPickMembit
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

Function PF_MobileCam(PartID As Integer, Action As Integer) As Integer
    Integer mobileCamBeforeMembit, mobileCamAfterMembit, mobileCamInPosMembit

    Select PartID
        Case 1
            mobileCamBeforeMembit = IONumber("mobileCamBefore1")
            mobileCamAfterMembit = IONumber("mobileCamAfter1")
            mobileCamInPosMembit = IONumber("mobileCamInPos1")
        Case 2
            mobileCamBeforeMembit = IONumber("mobileCamBefore2")
            mobileCamAfterMembit = IONumber("mobileCamAfter2")
            mobileCamInPosMembit = IONumber("mobileCamInPos2")
    Send

    Select Action
        Case PF_MOBILECAM_BEFORE
            ' Request for robot move to camera position
            MemOff mobileCamAfterMembit
            MemOn mobileCamBeforeMembit
            Wait MemSw(mobileCamInPosMembit) = On
        Case PF_MOBILECAM_AFTER
            ' Request for robot move after part vision acquisition
            MemOff mobileCamBeforeMembit
            MemOn mobileCamAfterMembit
            Wait MemSw(mobileCamInPosMembit) = Off
    Send

    PF_MobileCam = PF_CALLBACK_SUCCESS
Fend

プログラム例 1.6

例タイプ:
ピックするパーツの数を指定する

構成

  • ロボットの数: 1
  • フィーダーの数: 2
  • 各フィーダー上のパーツの種類数: 1
  • 配置場所の数: 1
  • カメラの向き: 各フィーダーに固定下向きカメラを配置

解説
ロボットは、フィーダー#1からパーツ#1を4つピックし、それぞれプレースします。そのあと、ロボットはフィーダー#2からパーツ#2を5つピックし、プレースします。カメラとフィーダーは、並行して動作します。
この例では、ロボットが、各フィーダーから特定の数のパーツをピックする方法を説明しています。サンプルコードでは、numToPickパラメーターを“ALL_AVAILABLE”に設定することで、すべてのパーツをピックできます。
必要な量のパーツをピックした後で、どちらかのフィーダーに“表”パーツが残っている場合、フィーダーは振動しません。

サンプルコード
Main.prg

#define ALL_AVAILABLE -1

Function main
    MemOff PartsToPick1; MemOff PartsToPick2
    Off Gripper

    Robot 1
    If Motor = Off Then
        Motor On
    EndIf
    Power Low
    Jump Park

    PF_Start(1)
    PF_Start(2)

    Xqt rbt1
Fend

Function rbt1
    Do
        Call RobotPickPlace(1, 4) 'part 1...pick & place 4 times
        Call RobotPickPlace(2, 5) 'part 2...pick & place 5 times
    Loop
Fend

Function RobotPickPlace(PartID As Integer, numToPick As Integer)
    Integer partsToPickMembit, partCnt

    Select PartID
        Case 1
            partsToPickMembit = IONumber("PartsToPick1")
        Case 2
            partsToPickMembit = IONumber("PartsToPick2")
    Send

    partCnt = 0
    Do
        Wait MemSw(partsToPickMembit) = On
        If PF_QueLen(PartID) > 0 Then
            Pick = PF_QueGet(PartID)
            PF_QueRemove PartID
            Jump pick
            On Gripper; Wait 0.2
            partCnt = partCnt + 1
            If PF_QueLen(PartID) = 0 Then
                Jump Place ! D90; MemOff partsToPickMembit !
                Off Gripper; Wait 0.2
                If (partCnt = numToPick) Or (numToPick = ALL_AVAILABLE) Then
                    Exit Do
                EndIf
            Else
                Jump Place
                Off Gripper; Wait 0.2
                If (partCnt = numToPick) Then
                     Exit Do
                EndIf
             EndIf
         Else
             MemOff partsToPickMembit
         EndIf
         If PF_IsStopRequested(PartID) = True Then
            MemOff partsToPickMembit
            Exit Do
         EndIf
    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

プログラム例 1.7

例タイプ:
ロボットがパーツに使用されたロボット番号と一致することを確認する

構成

  • フィーダーの数: 1以上
  • 各フィーダー上のパーツの種類数: 1
  • カメラの向き: 各フィーダーに固定下向きカメラを配置

解説
複数のフィーダーを使用する場合、ロボットはPF_Robotコールバック内ではなく、別タスクでロボットの動作を記述することが一般的です。つまり、PF_Robotコールバックは、パーツの場所(ポイント)をパーツ座標キューに入れるだけです。
ロボットのモーションタスクでは、パーツ座標キューの中でこれらのポイントを使用します。この方法でコードが構成されるときは、ロボットのモーションタスクで、現在のロボット番号とパーツに選択されたロボット番号が一致しているか確認してください。
この確認により、ロボットが誤ったポイントに移動したり、衝突することを防止できます。

サンプルコード
Main.prg

Function RobotPickPlace(PartID As Integer, numToPick As Integer)

    If PF_Info(PartID, PF_INFO_ID_ROBOT_NO) <> Robot Then
        Print "Robot does not match the robot # for the current part"
        Quit All
    EndIf

    'Robot Motion Code
Fend

プログラム例 1.8

例タイプ:
ピック後に、新しい画像を取得してキューをロードする

構成

  • ロボットの数:1
  • フィーダーの数:1
  • パーツの種類数:1
  • 配置場所の数:1
  • カメラの向き:固定下向きカメラ

解説
ロボットは、パーツフィーダーからパーツ#1をピックし、固定治具へプレースします。ピック&プレース操作後に、新しい画像が取得され、キューが再ロードされます。
この例では、ピックアップ中に周囲のパーツが移動してしまうことが懸念されます。PF_Robotコールバックの戻り値 “PF_CALLBACK_RESTART”は、すべてのパーツに対してビジョンを強制的に再実行し、すべてのパーツキューが再ロードされます。
この方法は効率的ではありませんが、“PF_CALLBACK_RESTART”は、サイクルごとに画像を取得するとパフォーマンスの精度が向上する特定の状況で役立ちます。ビジョンとフィーダーの振動は、ロボット動作と並行して発生します。

サンプルコード
Main.prg

Function main
    MemOff PartsToPick
    Off Gripper

    Robot 1
    If Motor = Off Then
        Motor On
    EndIf
    Power Low
    Jump Park

    PF_Start(1)

    Xqt RobotPickPlace
Fend

Function RobotPickPlace
    Do
        Wait MemSw(PartsToPick) = On
        If PF_QueLen(1) > 0 Then
            Pick = PF_QueGet(1)
            PF_QueRemove 1
            Jump pick
            On Gripper; Wait 0.2
            Jump Place ! D90; MemOff PartsToPick !
            Off Gripper; Wait 0.2
        Else
            MemOff PartsToPick
        EndIf
    Loop
Fend

PartFeeding.prg

Function PF_Robot(PartID As Integer) As Integer
    MemOn PartsToPick
    Wait MemSw(PartsToPick) = Off

    PF_Robot = PF_CALLBACK_RESTART
Fend

プログラム例 1.9

例タイプ:
パーツを表と裏で並べ替える

構成

  • ロボットの数:1

  • フィーダーの数:1

  • フィーダー上のパーツの種類数:1

  • 配置場所の数:2 (1つは “表”向き、もう1つは “裏”向き)

  • カメラの向き:フィーダー#1上の固定下向きカメラ

  • パーツ 1 全般:

  • パーツ 1 ビジョン:

解説
このアプリケーションでは、ロボットはパーツの “表”と “裏”の向きによってパーツを並べ替えます。表向きのパーツは “PlaceFront”というラベルのついたポイントに配置され、裏向きのパーツは “PlaceBack”というラベルのついた別のポイントに配置されます。
このアプリケーションではピックの順番は重要ではありません。ロボットは、できるだけ多くの表向きのパーツをピック&プレースし、できるだけ多くの裏向きのパーツをピック&プレースします。
“フリップが必要”のチェックボックスが未チェックで、“表パーツを検出するオブジェクト”と“裏パーツを検出するオブジェクト”のビジョンオブジェクトが選択されている場合、システムは表と裏向きパーツ両方を座標キューにロードし、それによりPart Orientationの値を設定します。
“フリップが必要”設定は、パーツを特定の向きにしたいことをシステムに伝えます。“フリップが必要”チェックボックスをチェックしないと、パーツを表と裏の両方の向きにしたいことをシステムに伝えます。

この場合、表向きパーツは、向きのデータ(パーツ座標キュー内)が自動的に定数“PF_PARTORIENT_FRONT”に設定されます。
裏向きパーツのデータは、自動的に定数“PF_PARTORIENT_BACK”に設定されます。

サンプルコード
Main.prg

Function main
    If Motor = Off Then
        Motor On
    EndIf
    Power Low
    Jump Park
    PF_Start 1
Fend

PartFeeding.prg

Function PF_Robot(PartID As Integer) As Integer
    Do While PF_QueLen(PartID) > 0
        P0 = PF_QueGet(PartID)
        Jump P0
        On Gripper; Wait 0.2
        If PF_QuePartOrient(PartID) = PF_PARTORIENT_FRONT Then
            Jump PlaceFront
        ElseIf PF_QuePartOrient(PartID) = PF_PARTORIENT_BACK Then
            Jump PlaceBack
        EndIf
        Off Gripper; Wait 0.2
        PF_QueRemove PartID
        If PF_IsStopRequested(PartID) = True Then
            Exit Do
        EndIf
    Loop
    PF_Robot = PF_CALLBACK_SUCCESS

Fend

プログラム例 1.10

例タイプ:
PF_Vision コールバックを使用する

構成

  • ロボットの数:1
  • フィーダーの数:1
  • フィーダー上のパーツの種類数:1
  • 配置場所の数:1
  • カメラの向き:フィーダー#1上の固定下向きカメラ

解説
この例は、PF_Visionコールバックを使用して画像を取得し、ビジョン結果を含むパーツ座標キューをロードする方法を示しています。この機能を使用するには、Epson RC+ 8.0メニュー - [ツール] - [パーツフィーディング] - [ビジョン]で[PF_Vision callbackでビジョン処理を行う]を選択します。

サンプルコード
Main.prg

Function main
    If Motor = Off Then
        Motor On
    EndIf
    Power Low
    Jump Park
    PF_Start 1
Fend

PartFeeding.prg

Function PF_Robot(PartID As Integer) As Integer
    Do While PF_QueLen(PartID) > 0
        P0 = PF_QueGet(PartID)
        Jump P0
        On Gripper; Wait 0.2
        Jump Place
        Off Gripper; Wait 0.2
        PF_QueRemove PartID
        If PF_IsStopRequested(PartID) = True Then
            Exit Do
        EndIf
    Loop
    PF_Robot = PF_CALLBACK_SUCCESS

Fend

Function PF_Vision(PartID As Integer, ByRef numBack As Integer) As Integer
    Boolean found
    Integer i, numFront
    Real RB_X, RB_Y, RB_U, RB_Z

    ' Pick Z coordinate
    RB_Z = -132.0

    ' Initialize coordinates queue
    PF_QueRemove PartID, All

    PF_Backlight 1, On

    ' Detect the parts
    VRun UsrVisionSeq
    PF_Backlight 1, Off

    VGet UsrVisionSeq.Geom01.NumberFound, numFront 'Front Parts
    VGet UsrVisionSeq.Geom02.NumberFound, numBack 'Back Parts
    If numFront <> 0 Then
        For i = 1 To numFront
            VGet UsrVisionSeq.Geom01.RobotXYU(i), found, RB_X, RB_Y, RB_U
            If found Then
                PF_QueAdd PartID, XY(RB_X, RB_Y, RB_Z, RB_U)
            EndIf
        Next
    EndIf

    PF_Vision = PF_CALLBACK_SUCCESS

Fend

プログラム例 1.11

例タイプ:
マルチサイドパーツの選択

構成

  • ロボットの数:1
  • フィーダーの数:1
  • フィーダー上のパーツの種類数:1
  • パーツの姿勢の数:3
  • 配置場所の数:3 (パーツの各方向に1つの配置位置)
  • カメラの向き:フィーダー#1上の固定下向きカメラ

解説
この例では、フィーダーに1種類の物理パーツがあります。パーツには、3つの姿勢(右, 左, 上)があります。ロボットは、3つの姿勢のいずれかでパーツをピックアップできます。
実際には1つのパーツですが、ビジョンシステムの観点で見ると、各姿勢はそれぞれ異なるパーツになります。パーツフィーディングは、同じフィーダーで同時に実行される4つのパーツをサポートします。したがって、各姿勢に別々のパーツを作成します。3つのパーツビジョンシーケンスを作成し、“Left”, “Right”, “Top”という名前をつけます。
各ビジョンシーケンスは、Geometricオブジェクトを使用して、パーツを特定の姿勢に配置します。[パーツフィーディング]ダイアログでは、パーツ1, 2, 3の3つのパーツを作成します。
パーツ1は、パーツを「左側」の姿勢に配置します。
パーツ2は、パーツを「右側」の姿勢に配置します。
パーツ3は、パーツを「上側」の姿勢に配置します。
3つのパーツすべてで、 “フリップが必要”チェックボックスはチェックされません。3つのパーツはすべて、“PartBlob”という名称の同じパーツブローブビジョンシーケンスを使用します。



各パーツのピックZをティーチします(ピックの高さはパーツの各姿勢で異なる場合があります)。左側のパーツは、 “PlaceLeft”というラベルの付いたポイントに配置されます。右側のパーツは、“PlaceRight”というラベルの付いたポイントに配置されます。上側のパーツは、“PlaceTop”というラベルの付いたポイントに配置されます。ロボットはすべてのパーツを左方向にピック&プレースし、次にすべてのパーツを右方向にピック&プレースし、最後にすべてのパーツを上方向にピック&プレースします。

サンプルコード
Main.prg

Function main
    If Motor = Off Then
        Motor On
    EndIf
    Power Low
    Jump Park
    PF_Start 1, 2, 3
Fend

PartFeeding.prg

Function PF_Robot(PartID As Integer) As Integer

    Do While PF_QueLen(PartID) > 0
        P10 = PF_QueGet(PartID)
        Jump P10
        On Vacuum; Wait 0.2
        Select PartID
            Case 1
                Jump PlaceLeft
            Case 2
                Jump PlaceRight
            Case 3
                Jump PlaceTop
        Send
        Off Vacuum; Wait 0.2
        PF_QueRemove PartID
    Loop

    PartID = PartID + 1
    If PartID > 3 Then PartID = 1
    PF_ActivePart PartID
    PF_Robot = PF_CALLBACK_SUCCESS

Fend

キーポイント


この例は、マルチパーツ機能を使用してマルチサイドパーツを処理する簡単な方法を示しています。もう1つの方法は、PF_Visionコールバックを介して “User to Process Vision” を行う方法です。PF_QueAddを使用すると、ユーザーデータをパーツ座標に含めることができます。ユーザーデータは、パーツの姿勢を表す数値(1 =左、2 =右、3 =上)にすることができます。PF_QueUserData関数を使用して方向の値を取得し、パーツを正しい場所に配置できるようにします。このコードでは、パーツの側面の高さの違いも考慮する必要があります。

プログラム例 1.12

例タイプ:
PF_Visionコールバックと、マルチサーチを使用したパーツ検出ビジョンシーケンス

構成

  • ロボットの数: 1
  • フィーダーの数: 1
  • フィーダー上のパーツの種類数: 1
  • 配置場所の数: 1
  • カメラの向き: フィーダー#1上の固定下向きカメラ

解説
PF_Visionコールバックは、パーツ検出ビジョンシーケンスでは処理が困難な場合(例えば、パーツを検出するために複数のビジョンシーケンスを必要とする場合や、特殊な外部照明制御が必要な場合)に使用されます。

この例では、PF_Visionコールバックを使用して画像を取得し、パーツ座標キューにビジョン結果をロードする方法を示しています。この機能を使用するには、Epson RC+ 8.0メニュー - [ツール] - [パーツフィーディング] - [ビジョン]の「PF_Vision callback でビジョン処理を行う」を選択します。

この例では、ビジョンのマルチサーチを使用しています。マルチサーチは、オブジェクトのCenterPointObjectプロパティー、またはFrameオブジェクトの各リザルトを検索する機能です。マルチサーチでは、見つかったリザルトが意図した順番にならない場合があります。 PF_Visionは、すべてのリザルトを反復処理して、見つかったリザルトを処理する方法を示しています。

  • CenterPointObjectを使用したマルチサーチの例
  1. 複数のパーツを検索するための、Blobなどのオブジェクトを作成します。
  2. BlobのCenterPointObjectを使用する、Polarなどの別のオブジェクトを作成します。
  3. CenterPntObjResultプロパティーをALLに設定します。
  4. シーケンスを実行します。見つかったBlobの結果ごとに、Polarオブジェクトのインスタンスが表示されます。
  • Frameを使用したマルチサーチの例
  1. 複数のパーツを検索するための、Blobなどのオブジェクトを作成します。
  2. Frameオブジェクトを作成し、OriginPointプロパティーをBlobに設定します。
  3. OriginPntObjResult プロパティーをAllに設定します。
  4. Frameを使用する、Polarなどの別のオブジェクトを作成します。
  5. FrameResultプロパティーをAllに設定します。
  6. シーケンスを実行します。見つかったBlobのリザルトごとにFrameオブジェクトのインスタンスが表示され、Frameの結果ごとにPolarオブジェクトのインスタンスが表示されます。

サンプルコード
Main.prg

Function main
    If Motor = Off Then
        Motor On
    EndIf
    Power Low
    Jump Park
    PF_Start 1
Fend

PartFeeding.prg

Function PF_Robot(PartID As Integer) As Integer

    Do While PF_QueLen(PartID) > 0
        P10 = PF_QueGet(PartID)

        Select PF_QuePartOrient(PartID)
            Case PF_PARTORIENT_FRONT ' Front
                Tool 1 ' Tool to pick Front
                ' Pick
                Jump P10 ! D90; On Vacuum !
                Wait 0.1
                ' Place
                Jump FrontPlace
                Off Vacuum
                Wait 0.1
            Case PF_PARTORIENT_BACK ' Back
                Tool 2 ' Tool to pick Back
                ' Pick
                Jump P10 ! D90; On Vacuum !
                Wait 0.1
                ' Place
                Jump BackPlace
                Off Vacuum
                Wait 0.1
        Send

        PF_QueRemove PartID

        If PF_IsStopRequested(PartID) = True Then
            Exit Do
        EndIf

    Loop

    PF_Robot = PF_CALLBACK_SUCCESS

Fend


Function PF_Vision(PartID As Integer, ByRef numBack As Integer) As Integer

    Integer i, numFront, numBack, numResults, count
    Boolean found
    Real x, y, z, u

    z = -170 ' Set the pick Z coordinate to the desired height for your application

    PF_QueRemove 1, All

    PF_Backlight 1, On
    VRun FindPart

    VGet FindPart.Front.NumberFound, numFront
    VGet FindPart.Front.NumberOfResults, numResults
    count = 0
    For i = 1 To numResults
        VGet FindPart.Front.RobotXYU(i), found, x, y, u
        If found Then
            count = count + 1
            P999 = XY(x, y, z, u) /R
            PF_QueAdd 1, P999, PF_PARTORIENT_FRONT
        EndIf
        If count = numFront Then
            Exit For
        EndIf
    Next

    VGet FindPart.Back.NumberFound, numBack
    VGet FindPart.Back.NumberOfResults, numResults
    count = 0
    For i = 1 To numResults
        VGet FindPart.Back.RobotXYU(i), found, x, y, u
        If found Then
            count = count + 1
            P999 = XY(x, y, z, u) /R
            PF_QueAdd 1, P999, PF_PARTORIENT_BACK
        EndIf
        If count = numBack Then
            Exit For
        EndIf
    Next

    PF_Backlight 1, Off
    PF_Vision = PF_CALLBACK_SUCCESS

Fend