My last project was a machine load/unload application where the robot had two basically identical grippers. Either gripper could be used to load or unload any station. Here’s how I handled the payload switching and grip/ungrip logic in the load/unload programs.
Start with four basic PAYLOAD
programs, one for each possible condition: empty gripper, part on A side, part on B side and a part on both sides.
! payload_empty.ls ;
PAYLOAD[1] ;
! payload_a.ls ;
PAYLOAD[2] ;
! payload_b.ls ;
PAYLOAD[3] ;
! payload_ab.ls ;
PAYLOAD[4] ;
If you think using small one-line programs is silly, read my post on Small Programs and see if it changes your mind.
We don’t want to create different load and unload routines for both grippers, so we will have to keep track of which gripper is active somewhere. Let’s use F[1:A Active]
.
We’ll also have to keep track of which grippers are currently gripping parts. This could be done a number of ways, but let’s just use F[2:GripA full]
and F[3:GripB full]
.
Now the goal will be to simply call one program in our load and unload programs just like we normally would with a single gripper. We also want the name of this program to have good semantics. Since we are essentially adding and removing parts from the robot end-of-arm tool, I chose the names payload_add
and payload_sub
for the unload and load programs respectively.
Let’s write some code for payload_add
:
! payload_add.ls ;
IF (F[1:A Active]) THEN ;
IF (F[3:GripB full]) THEN ;
CALL PAYLOAD_AB ;
ELSE ;
CALL PAYLOAD_A ;
ENDIF ;
ELSE ;
IF (F[2:GripA full]) THEN ;
CALL PAYLOAD_AB ;
ELSE ;
CALL PAYLOAD_B ;
ENDIF ;
ENDIF ;
These nested if
-statements look nice here, but they will be difficult to read on the teach pendant. This is why I will extract some of this logic into a couple more small programs:
! payload_add_a.ls
IF (F[3:GripB full]) THEN ;
CALL PAYLOAD_AB ;
ELSE ;
CALL PAYLOAD_A ;
ENDIF ;
! payload_add_b.ls
IF (F[2:GripA full]) THEN ;
CALL PAYLOAD_AB ;
ELSE ;
CALL PAYLOAD_B ;
ENDIF ;
! payload_add ;
IF (F[1:GripA Active]) THEN ;
CALL PAYLOAD_ADD_A ;
ELSE ;
CALL PAYLOAD_ADD_B ;
ENDIF ;
The payload_sub
program and associated payload_sub_a
and payload_sub_b
routines will look very similar.
The idea here is to hide the logic that selects the correct payload from the load and unload routines. A load routine should only worry about loading. Modifying the PAYLOAD
should be a small detail, even if you have a complex situation with multiple states.
Next time you have some IF-ELSE
logic in a program, think about whether or not that logic is the main job of your current routine. If the answer is no, you should probably extract that into another program.