ロボット2台 - パーツ1種類

プログラム例 3.1

例タイプ:
ロボット2台と物理パーツ1種類- PF_Robotコールバックでのモーション-特定の順序でのピッキング

構成

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

解説
2台のロボットと1つのフィーダーがあります。物理パーツは1種類のみです。各ロボットには独自のカメラキャリブレーションがあるため、2種類(ロボット1のパーツ1とロボット2のパーツ2)の論理パーツがあります。
ロボットはフィーダーから順番にピッキングします。このアプリケーションでは、ピックの順序が重要です。交互のピック順序は、“PF_ActivePart”で実行されます。
ロボットの動きは、PF_Robotコールバック内で実行されます。
この例には、フィーダーとロボット動作の並列処理はありません。コードは単純ですが、効率的ではありません。各ロボットには、“park”というラベルの付いたポイントと“place”というラベルの付いたポイントがあります。この例の重要な概念は、PF_Robotコールバックの戻り値“PF_CALLBACK_RESTART_ACTIVEPART”です。
この戻り値により、両方のパーツのキューでパーツが調整される可能性がなく、複数のロボットが同じフィーダーを使用できるようになります。戻り値により、PF_ActivePartのみの新しいイメージが強制的に取得され、PF_ActivePartのキューのみがロードされます。

サンプルコード
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_RESTART_ACTIVEPART
 
Fend

プログラム例 3.2

例タイプ:
ロボット2台と1種類の物理パーツ - 別タスクでのモーション- ピック順序は関係ありません - 特定の順序でピッキング

構成

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

解説
2つのロボットと1つのフィーダーがあります。物理パーツは1種類のみです。各ロボットには独自のカメラキャリブレーションがあるため、2種類(ロボット1のパーツ1とロボット2のパーツ2)の論理パーツがあります。ピック順序は関係ありません-先着順です。
この例での違いは、サイクルごとに各パーツのビジョンが取得されることです。これは、ピックアップ中に周囲のパーツが移動してしまう可能性がある場合に役立ちます。
PF_Robotコールバックの戻り値“PF_CALLBACK_RESTART”は、すべてのパーツに対してビジョンを強制的に再実行し、すべてのパーツキューが再ロードされます。
この方法は効率的ではありませんが、“PF_CALLBACK_RESTART”は特定の状況で役立ちます。

サンプルコード
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 PartsToPick
    PF_Start 1, 2
    Xqt Robot1PickPlace
    Xqt Robot2PickPlace
Fend
 
Function Robot1PickPlace
    Robot 1
 
    Do
        PF_AccessFeeder (1)
        Wait MemSw(PartsToPick) = On
        If PF_QueLen(1) > 0 Then
            P0 = PF_QueGet(1)
            PF_QueRemove (1)
            Jump P0 /R
            On 5
             Wait 0.5
            Jump Place ! D30; MemOff PartsToPick; PF_ReleaseFeeder 1 !
            Off 5
            Wait 0.25
        Else
            MemOff PartsToPick; PF_ReleaseFeeder 1
        EndIf
    Loop
Fend
 
Function Robot2PickPlace
    Robot 2
 
    Do
        PF_AccessFeeder (1)
        Wait MemSw(PartsToPick) = On
        If PF_QueLen(2) > 0 Then
            P0 = PF_QueGet(2)
            PF_QueRemove (2)
            Jump P0 /L
            On 2
            Wait 0.5
            Jump Place ! D30; MemOff PartsToPick; PF_ReleaseFeeder 1 !
            Off 2
            Wait 0.25
        Else
            MemOff PartsToPick; PF_ReleaseFeeder 1
        EndIf
    Loop
Fend

PartFeeding.prg

Function PF_Robot(PartID As Integer) As Integer
    MemOn PartsToPick
    Wait MemSw(PartsToPick) = Off
 
    PF_Robot = PF_CALLBACK_RESTART 'Force vision and vibration to refresh 
Fend

プログラム例 3.3

例タイプ:
ロボット2台と1種類の物理パーツ - 別タスクでのモーション -先着順-シミュレートされたプロセスの遅延

構成

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

解説
2つのロボットと1つのフィーダーがあります。物理パーツは1種類のみです。各ロボットには独自のカメラキャリブレーションがあるため、2つ(ロボット1のパーツ1とロボット2のパーツ2)の論理パーツがあります。この例では、各ロボットのプロセス時間が可変です(ランダムな待機時間でシミュレートされます)。
各ロボットは、フィーダーからパーツをピックした後、他の操作を実行するためビジー状態になっています。
メモリビット “Rbt1Complete”と “Rbt2Complete”は、ロボットがフィーダーからパーツをピックした後、他の操作を終了し、フィーダーから別のパーツをピックアップする準備ができたとき、信号を送信するために使用されます。PF_Robotコールバックは、希望のパーツ(PF_ActivePart)が現在のパーツと異なる場合(つまり、他のロボットがパーツをピックアップする場合)、 “PF_CALLBACK_RESTART_ACTIVEPART”という値を返します。これにより、ロボットキュー内のポイントの重複が防止されます。
PF_ActivePartの新しいイメージが取得され、PF_ActivePartのキューのみロードされます。ただし、次のパーツが現在のパーツと同じ場合(つまり、同じロボットがフィーダーからピックする場合)、PF_Robotコールバックの戻り値は “PF_CALLBACK_SUCCESS”になります。PF_AccessFeederおよびPF_ReleaseFeederは、フィーダーにアクセスするときにロボットが衝突しないようにします。

サンプルコード
Main.prg

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

    PF_Start 1, 2
    Xqt Robot1PickPlace
    Xqt Robot2PickPlace
Fend

Function Robot1PickPlace
    Integer randomTime

    Robot 1
    MemOn Rbt1Complete

    Do
        Wait MemSw(PartsToPick1) = On
        PF_AccessFeeder (1)
        MemOff Rbt1Complete
        P0 = PF_QueGet(1)
        PF_QueRemove (1)
        Jump P0 /R
        On rbt1Gripper
        Wait 0.25
        Jump Place ! D30; MemOff PartsToPick1; PF_ReleaseFeeder 1 !
        Off rbt1Gripper
        Wait 0.25
        'Test long process time - robot is doing something else
        Randomize
        randomTime = Int(Rnd(9)) + 1
        Wait randomTime
        MemOn Rbt1Complete
    Loop
Fend

Function Robot2PickPlace
    Integer randomTime

    Robot 2
    MemOn Rbt2Complete

    Do
        Wait MemSw(PartsToPick2) = On
        PF_AccessFeeder (1)
        MemOff Rbt2Complete
        P0 = PF_QueGet(2)
        PF_QueRemove (2)
        Jump P0 /L
        On rbt2Gripper
        Wait 0.25
        Jump Place ! D30; MemOff PartsToPick2; PF_ReleaseFeeder 1 !
        Off rbt2Gripper
        Wait 0.25
        'Test long process time - robot is doing something else
        Randomize
        randomTime = Int(Rnd(9)) + 1
        Wait randomTime
        MemOn Rbt2Complete
    Loop
Fend

PartFeeding.prg

Function PF_Robot(PartID As Integer) As Integer
    Integer nextPart

    Select PartID
        Case 1
            MemOn PartsToPick1
            Wait MemSw(PartsToPick1) = Off
        Case 2
            MemOn PartsToPick2
            Wait MemSw(PartsToPick2) = Off
    Send

    Wait MemSw(Rbt1Complete) = On Or MemSw(Rbt2Complete) = On
    If MemSw(Rbt1Complete) = On Then
        nextPart = 1
    ElseIf MemSw(Rbt2Complete) = On Then
        nextPart = 2
    EndIf

    PF_ActivePart nextPart

    If nextPart = PartID Then
        'Same part so no need to re-acquire an image and reload the queue
        PF_Robot = PF_CALLBACK_SUCCESS
    Else
        'Restart from vision -
        'Acquire image and load queue for only the Active Part
        PF_Robot = PF_CALLBACK_RESTART_ACTIVEPART
    EndIf

Fend