フィーダーごとにロボット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を使用したマルチサーチの例
- 複数のパーツを検索するための、Blobなどのオブジェクトを作成します。
- BlobのCenterPointObjectを使用する、Polarなどの別のオブジェクトを作成します。
- CenterPntObjResultプロパティーをALLに設定します。
- シーケンスを実行します。見つかったBlobの結果ごとに、Polarオブジェクトのインスタンスが表示されます。
- Frameを使用したマルチサーチの例
- 複数のパーツを検索するための、Blobなどのオブジェクトを作成します。
- Frameオブジェクトを作成し、OriginPointプロパティーをBlobに設定します。
- OriginPntObjResult プロパティーをAllに設定します。
- Frameを使用する、Polarなどの別のオブジェクトを作成します。
- FrameResultプロパティーをAllに設定します。
- シーケンスを実行します。見つかった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