Embrace the END Statement

Filed under: FANUC TP Programming

What do you think this line of code does?

JMP LBL[9999] ;

If you’ve been programming FANUC robots for a while, you probably guessed that this statement jumps to the end of the program. It comes in many variants: JMP LBL[999], JMP LBL[10000], etc., but the intent is almost always the same: end this routine.

The problem is that there’s no guarantee that LBL[9999] or LBL[10000] or whatever actually ends the routine. That label may not even exist. You may be reasonably sure as to what will happen if you wrote the program, but I’m willing to bet that someday your LBL[10000] won’t be the last line of your routine.

Maybe someone simply turned a bit off after your label. Maybe he or she added a conditional or a motion statement. This might work 99.9% of the time, but maybe there’s a rare execution path that will cause the robot to crash if the stars align just right.

You wanted the routine to end, but you did an unconditional jump. Why not just use the END statement if that’s what you wanted to do?

! bad ;
JMP LBL[9999] ;
 ;
! good ;
END ;

You should be able to safely replace all of your JMP LBL[999]-type statements with END statements, but you will run into some limitations with the language itself if you want to end the routine conditionally.

For example, you can’t end a routine from a one-line IF statement:IF R[1]=1,END ;. You can’t end the routine as a result of a SELECT case either: SELECT R[1]=1,END ;.

This is not meant to a be a post about the limitations of TP (though there are plenty). I tried to fix many of those with TP+ and wrote about how unconditional jumps are harmful a couple years ago.

We finally got IF-THEN blocks with the R-30iB controller. If you’re lucky enough to be working on a newer robot, you could conditionally end a routine like this:

IF (R[1]=1) THEN ;
  END ;
ENDIF ;

A one-liner would be nice, but this is the best we can do for now. The SELECT statement is a bit trickier.

One option is to use the ELSE branch of the statement to jump to a label used for ending the routine, but we’re pretty much back to square one at that point. It might be better to place an END statement after any SELECT and also be sure to END any places we’ve jumped to e.g.:

SELECT R[1]=1,JMP LBL[100] ;
       =2,CALL ROUTINE_TWO ;
       ELSE,JMP LBL[500] ;
END ;
 ;
LBL[100] ;
! do something for R[1]=1 ;
END ;
 ;
LBL[500] ;
! invalid R[1] value? ;
END ;

This guarantees that the task will end no matter how the SELECT condition was evaluated. (You have to remember that task execution will return to the line immediately following a CALL case. This is quite different than the other JMP cases.)

While TP lacks the many conveniences of a modern programming language, it does have an END statement, so use it when you can. Your programs should lose a label (the fewer labels the better) and you’ll know your programs will end when you want them to with no side effects.


Want posts like this delivered right to your inbox?

If you liked this post, please sign up for my mailing list!