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 ; ! payload_a.ls ; PAYLOAD ; ! payload_b.ls ; PAYLOAD ; ! payload_ab.ls ; PAYLOAD ;
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
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
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_sub for the unload and load programs respectively.
Let’s write some code for
! 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 ;
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 ;
payload_sub program and associated
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.