Writing Maintainable TP Code

Filed under: FANUC TP Programming Workflow

Continuing with last week’s theme of best-practices, I’d like to discuss what makes certain programs maintainable and others impossible to work with. Eliminating as much jumping as possible is a good start, but there are a few other rules I always try to follow when working on a project.

1. Keep Programs Short and Focused

FANUC’s Teach Pendant doesn’t have much screen real estate. The default editor can only display 11 lines of code (LOC), and you only get 20 in the Double or Single Wide modes. That means that if you need to troubleshoot a 200 LOC routine on the floor, you can at best only see 10% of the program at any given time.

It’s probably not realistic to keep your programs to fewer than 20 lines, but I generally like to keep them shorter than 60 LOC. Any time you have a routine going much higher than 100 lines, you probably have a good candidate for refactoring.

Check out the GnuWin project, specifically the CureUtils for Windows. This will give you access to some great unix utilities such as wc, which you can use to see how long each of your programs is: > wc -l src/*.ls

2. Extract Conditionals into Subroutines

It’s pretty common to have to conditionally approach a given fixture differently depending on where you’re coming from. You might accomplish this with something like:


  ! UNLOAD_FIXTURE.LS ;
  ! ================= ;
   ;
  ! approach fixture ;
  SELECT R[1:last position]=1,JMP LBL[100] ;
         =2,JMP LBL[200] ;
         =3,JMP LBL[300] ;
   ;
  LBL[100] ;
  L P[1:approach 1] 2000mm/sec CNT100 ;
  JMP LBL[400] ;
   ;
  LBL[200] ;
  L P[2:approach 2] 2000mm/sec CNT100 ;
  JMP LBL[400] ;
   ;
  LBL[300] ;
  L P[3:approach 3] 2000mm/sec CNT100 ;
  JMP LBL[400] ;
   ;
  LBL[400] ;
  ! move to unload product ;

You pull up a routine called UNLOAD_FIXTURE, and all you see is a screen full of logic handling how the robot approaches the fixture. I tend to extract pretty much any conditional to it’s own subroutine. This way you end up with two shorter, more focused routines: APPROACH_FIXTURE and UNLOAD_FIXTURE.

3. Balance Indirection vs. Duplication

I talked about the DRY Principle (Don’t Repeat Yourself) in my previous article about Clean Code. I absolutely hate repeating myself: both in conversation and coding. Unfortunately there’s not much we can do about an unattentive listener or a loud restaurant, but we can generally avoid this annoyance when writing code.

Reducing duplication often comes at the expense of a little bit of indirection, and it’s up to you strike the delicate balance. Personally, I will almost always favor indirection over duplication. There’s nothing worse than having to go and make the same change in 100 different places when you could have just used a register in the first place.

4. Always Use Subroutines for Operating I/O

This is in direct correlation with the previous point. Imagine having to open or close your robot’s gripper in 20 different subroutines. Something changes and the open gripper output moves by one. If you had the foresight to put your gripper operation into its own subroutines, you only have to change those subroutines– not the 20 programs that use them.

5. Write Good Error Messages

Nothing ever runs perfectly. At some point your gripper is not going to close all the way or a part-presence sensor isn’t going to get made. You have to plan for these issues even if they only happen once a year. When they do happen, it’s important to help your customer troubleshoot and recover from the issue as quickly as possible.

Take the gripper issue for instance. The robot attempts to pick up a part, and the gripper open/close signals do not look correct. What could be the issue?

  1. The robot missed the part
  2. The inputs are broken
  3. The robot has only partially picked the product

What kind of error do you present to the user? Hopefully not “The gripper failed to close.” I would tend to present the user with the issue, what could have happened, and how to fix each issue.


  Failed to Pick a Part
  =====================

  Both the gripper open and overtravel signals should be off.

       ( X )            (   )
  RI[1:Overtravel]    RI[2:Open]

  1. Check to make sure the sensors are functional.
  2. If the robot has only partially picked a part, you
     can either remove the part from the gripper or adjust
     the part's position in the gripper before pressing
     CONTINUE.
  3. If the robot missed the product, press CONTINUE.

  [ CONTINUE ] [ OPEN GRIPPER ] [ CLOSE GRIPPER ]
  

Clear error messages should result in fewer service calls and happier customers. If you’ve kept your programs short and focused with little duplication you’ll hopefully avoid many bugs that can keep you from closing a project too.


Want posts like this delivered right to your inbox?

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