One Robot Per Feeder & One Part Per Feeder
Program Example 1.1
Example Type:
Using the PF_Robot Callback for motion
Configuration
- Number of Robots: 1
- Number of Feeders: 1
- Number of Parts Types on the Feeder: 1
- Number of Placement Positions: 1
Camera Orientation: Fixed Downward Camera over Feeder#1
Description
Parts are removed from the feeder and placed into a box. When all the parts have been removed, the Control callback will request more parts. When the operator or hopper replenishes the feeder with more parts, the cycle continues. If the PF_Stop command is executed, the current cycle ends and then the application will terminate. (PF_Stop command is not used in the following sample code.)
Sample Code
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
Program Example 1.2
Example Type:
Multiple robot system - 1 robot per feeder & 1 part per feeder
Configuration
- Number of Robots: 2
Robot 1 is connected to the Control Unit. Robot 2 is connected to the Drive Unit. - Number of Feeders: 2
- Number of Parts Types on each Feeder: 1
- Number of Placement Positions: 1 per robot
- Camera Orientation: Each Feeder has its own Fixed Downward Camera
Description
Both robots independently pick and place parts. The robots do not share feeders or placement position. The robot work envelopes do not overlap. Both robots have points that are labeled "Park", "Pick" and "Place" in their respective point files.
Sample Code
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
Program Example 1.3
Example Type:
Parallel processing vision & vibration with robot motion
Configuration
- Number of Robots: 1
- Number of Feeders: 1
- Number of Parts Types: 1
- Number of Placement Positions: 1
- Camera Orientation: Fixed Downward Camera
Description
The robot picks up a Part#1 from the parts feeder and places it into a fixture. This continues until all the "Front" parts are removed from the Feeder. When the last available part is being placed (90% of the way through the motion), the feeder will vibrate, the hopper will replenish the feeder if necessary, etc.
This example demonstrates how the feeder action can occur in parallel with the robot motion to optimize throughput.
Sample Code
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
Program Example 1.4
Example Type:
1 Robot, 2 Feeders and 1 Part Per Feeder
Configuration
- Number of Robots: 1
- Number of Feeders: 2
- Number of Parts Types on each Feeder: 1
- Number of Placement Positions: 1
- Camera Orientation: Each Feeder has its own Fixed Downward Camera
Description
The robot picks up each part#1 from Feeder#1 and places it into a box. This continues until all the "Front" parts are removed from the Feeder #1. Then the robot picks up each "Front" part from Feeder#2 and places them into the box. The Cameras and Feeders work in parallel with one another.
Sample Code
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
Program Example 1.5
Example Type:
1 Robot, 2 Feeders and 1 Part Per Feeder - Mobile Mounted Camera
Configuration
- Number of Robots: 1
- Number of Feeders: 2
- Number of Parts Types on each Feeder: 1
- Number of Placement Positions: 1
- Camera Orientation: Each Feeder will use the Mobile Mounted Camera on the robot.
(there are no Fixed Downward cameras for this example)
Description
Then the robot moves the Mobile Mounted camera over Feeder#1 and takes a picture. The robot picks up each part from Feeder#1 and places it into a box. This continues until all the "Front" parts are removed from the Feeder. Then the robot moves the Mobile Mounted camera over Feeder#2 and takes a picture. The robot picks up each correctly oriented part from Feeder#2 and places them into the box.
KEY POINTS
If you use a mobile camera equipped with multiple feeders with backlights, a separate vision sequence is used for each part associated with each feeder.
Sample Code
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 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
Program Example 1.6
Example Type:
Specifying the number of parts to pick
Configuration
- Number of Robots: 1
- Number of Feeders: 2
- Number of Parts Types on each Feeder: 1
- Number of Placement Positions: 1
- Camera Orientation: Each Feeder has its own Fixed Downward Camera
Description
The robot picks up four Part#1 from Feeder#1 and place them individually. The robot will then pick up five Part#2 from Feeder#2 and place them. The Cameras and Feeders work in parallel with one another.
This example illustrates how the robot can pick up a specific number of parts from each feeder. The sample code also supports picking all available parts by setting the numToPick parameter to "ALL_AVAILABLE".
If "Front" parts remain on either feeder after picking the desired quantity, the feeder will not vibrate unnecessarily.
Sample Code
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
Program Example 1.7
Example Type:
Ensuring that the Robot matches the Robot # that was used for the Part
Configuration
- Number of Feeders: More than 1
- Number of Parts Types on each Feeder: 1
- Camera Orientation: Each Feeder has its own Fixed Downward Camera
Description
When using multiple feeders, it is common that the robot makes motion in a multitask rather than inside the PF_Robot callback. In other words, the PF_Robot callback simply loads part locations (points) into the Part Feeding Queue.
A robot motion task uses the points in the queue. When the code is structured in this fashion, it is recommended that the robot motion task verifies that current robot # matches the robot # that was selected for the part.
This additional check will ensure that the robot does not use the wrong points and cannot crash the robot.
Sample Code
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
Program Example 1.8
Example Type:
Acquiring a new image and loading the queue after every pick
Configuration
- Number of Robots: 1
- Number of Feeders: 1
- Number of Parts Types: 1
- Number of Placement Positions: 1
- Camera Orientation: Fixed Downward Camera
Description
The robot picks up a Part#1 from the parts feeder and places it into a fixture. After each pick and place operation, a new image will be acquired and the queue will be reloaded.
For this example, we are concerned that surrounding parts may be disturbed during pick up. The PF_Robot callback return value "PF_CALLBACKRESTART" will force vision to re-run for all parts and all part queues will be reloaded.
This method is not efficient but "PF_CALLBACKRESTART" can be useful in certain circumstances where acquiring an image every cycle can improve performance accuracy. The vision and feeder vibration occurs in parallel with robot motion.
Sample Code
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
Program Example 1.9
Example Type:
Sorting a Part by Front and Back orientation
Configuration
Number of Robots: 1
Number of Feeders: 1
Number of Parts Types on the Feeder: 1
Number of Placement Positions: 2 (one for the Front side and one for the Back side)
Camera Orientation: Fixed Downward Camera over Feeder#1
Part 1 General Page:
Part 1 Vision Page:
Description
For this application, the robot will sort the parts based upon their Front and Back orientation. Front side parts will be placed at a point labeled "PlaceFront" and Back side parts will be placed in another point labeled "PlaceBack".
The pick order does not matter for this application. The robot will pick / place as many Front parts as it can and then pick / place as many Back parts as it can.
When "Needs Flip" is uncheck but vision objects have been selected in "Vision object for front of part" and "Vision object for back of part", the system will load both the Front & Back parts into the coordinate queue and set the Part Orientation value accordingly.
Remember that the "Needs Flip" setting tells the system that you want parts in a certain orientation. By Unchecking this setting, you are telling the system that you want both orientations.
In this case, the Front parts will automatically have their orientation data (in the part coordinate queue) set to constant "PF_PARTORIENT_FRONT".
The Back parts will automatically have their orientations set to constant "PF_PARTORIENT_BACK".
Sample Code
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
Program Example 1.10
Example Type:
Using the PF_Vision Callback
Configuration
- Number of Robots: 1
- Number of Feeders: 1
- Number of Parts Types on the Feeder: 1
- Number of Placement Positions: 1
- Camera Orientation: Fixed Downward Camera over Feeder#1
Description
This example illustrates how to use the PF_Vision callback to acquire an image and load the parts coordinate queue with the vision results. To use this function, select "User processes vision for part via PF_Vision callback" in Epson RC+ 8.0 Menu - [Tools] - [Part Feeding] - [Vision].
Sample Code
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
Program Example 1.11
Example Type:
Picking a Multi-sided Part
Configuration
- Number of Robots: 1
- Number of Feeders: 1
- Number of Parts Types on the Feeder: 1
- Number of Unique Sides on the Part: 3
- Number of Placement Positions: 3 (one placement position for each side of the part)
- Camera Orientation: Fixed Downward Camera over Feeder#1
Description
For this example, there is 1 physical part type on the feeder. The part has 3 unique sides (Right side, Left side and Top side). The robot can pick up the part in any one of the 3 orientations.
From the perspective of the vision system, each side is a different part (even though it is actually 1 physical part). Part Feeding supports 4 unique parts running on the same feeder at the same time. Consequently, we are going to create a separate Part for each side. We will make 3 Part Vision sequences and name them "Left", "Right" and "Top".
Each vision sequence will use a Geometric object to locate the part in its specific orientation. In the Part Feeding dialog, we will create 3 Parts - Part 1, 2 and 3.
Part 1 will locate the part in the "Left" side orientation.
Part 2 will locate the part in the "Right" side orientation.
Part 3 will locate the part in the "Top" side orientation.
"Needs Flip" will be unchecked for all 3 Parts. All 3 parts will use the same Part Blob Vision Sequence called "PartBlob".
Teach the Pick Z for each Part (the pick height may be different for each side of the part). Left side parts will be placed at a point labeled "PlaceLeft". Right side parts will be placed at a point labeled "PlaceRight". Top side parts will be placed at a point labeled "PlaceTop". The robot will pick / place all the parts in the Left orientation, then pick / place all the parts in the Right orientation and lastly it will pick / place all the parts in the Top orientation.
Sample Code
Main.prg
Function main
If Motor = Off Then
Motor On
EndIf
Power Low
Jump Park
PF_Start 1, 1, 2
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
KEY POINTS
This example illustrates a simple method of handling a multi-side part by using the Multi-Part functionality. Another method is for the "User to Process Vision" via the PF_Vision callback. When using PF_QueAdd, User Data can be included with the part coordinates. The user data could be a numerical value that represents the part orientation (i.e., 1 = Left, 2=Right, 3=Top). The PF_QueUserData function would be used to get the orientation value so that the part can be placed in the correct location. The code would also need to account for height differences in the part sides.
Program Example 1.12
Example Type:
Using the PF_Vision Callback and the Part Sequence uses Multi-Search
Configuration
- Number of Robots: 1
- Number of Feeders: 1
- Number of Parts Types on each Feeder: 1
- Number of Placement Positions: 1
- Camera Orientation: Fixed Downward Camera over Feeder#1
Description
The PF_Vision callback is used when the Part Sequence vision processing is difficult (i.e., the application requires multiple vision sequences to detect the part or several different lighting controls are required etc…).
This example illustrates how to use the PF_Vision callback to acquire an image and load the parts coordinate queue with the vision results. To use this function, select "User processes vision for part via PF_Vision callback" in Epson RC+ 8.0 Menu - [Tools] - [Part Feeding] - [Vision].
This example uses multi-search for the Part Sequence. Multi-search is a feature where an object will search for each result of the CenterPointObject property or a Frame object. In multi-search, the found results may not be found sequentially. PF_Vision shows how to iterate through all the results to find the found results.
- Example of multi-search with CenterPointObject:
- Create an object to find multiple parts, such as a Blob
- Create another object, such as a Polar, that will use the Blob as its CenterPointObject.
- Set the CenterPntObjResult property to All.
- Run the sequence. You will see an instance of the Polar object for each Blob result that was found.
- Example of multi-search with Frame:
- Create an object to find multiple parts, such as a Blob
- Create a Frame object and set the OriginPoint property to the Blob.
- Set the OriginPntObjResult property to All.
- Create another object, such as a Polar, that will use the Frame.
- Set the FrameResult property to All.
- Run the sequence. You will see an instance of the Frame object for each Blob result that was found, and an instance of the Polar object for each Frame result.
Sample Code
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