ロボット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