Staggered Grid Patterns

Is it possible to have a grid pattern that staggers parts?

Most of my grids are the same distance between all parts in X and Y axis.

Some parts are odd shapes and I’d like to use a staggered grid pattern to get more parts on the grid instead of making new grid plates.

Can I do this…


…or do I have to do this?


I think the Palletizing node has “irregular” as an option. I’m not the biggest fan of the Palletizing node though, so I can’t really say what it can do. Typically when I want to do something like this, I just teach the part to a Feature, and then use script to shift the Feature when/how I want. In that regard, yes it is totally possible.

1 Like

99% of my stuff is done from the TP using pre-defined nodes. I have only done a little script stuff and am a long ways from being able to do something like this manually. :slight_smile:

Seems the more time I spend on these robots the more I realize how few people seem to use the TP.

Woefully inadequate. :smiley:

Oh don’t get me wrong, 99% of the work is still just teaching the points via the teach pendant. The shifting/gridding is just a single Assignment command.


So if you teach everything to (in this example) Plane_1, then I can do all the moves I need to program the part, then use a simple pose_add() command to shift the whole Feature in whatever direction you want. So in this case, the program will do part 1, shift 1 meter in the x direction, and do the same moves again.

According to your picture, your left-right offset is fixed. So you could either program a whole row, and simply shift in one direction, or you can up your script game slightly and program only 1 part, offsetting left-right 4 times for every 1 shift up-down.

I’ve already got the script for fixed offsetting. Let me stare at it for a little bit and I should be able to modify it to create your pattern there. I’m assuming at least that the large up-down offsets are the same, and the small up-down offsets are the same, correct?

1 Like

That would be awesome.

Yes, the large AND small up/down offsets are the same. Basically what I’m doing is loading parts in a grid plate that’s made for bigger parts. In the past I’ve been putting one part in each square but that eliminates half my capacity.

Does this map to X and Y? Like you’re shifting a fixed value in the X, and switching offsets in the Y?

If I understand you correctly, yes.


OK. It LOOKS like it’s working correctly in my simulator, but we shipped all our robots to Detroit for a tradeshow, so I can’t verify in reality lol.

Here’s the Polyscope I was using to test it:


The Waypoints are just a simple up-down motion so I could easily see what was “one part.” They are also taught to Plane_1. You’d replace everything in the loop with your programmed part. Making it a subprogram call might be a really clean way of implementing that. You’ll want to ensure that all those moves are taught to a Feature though (And I’d just teach that Feature with the same orientation as Base so it doesn’t get confusing).

So basically, just throw the script in at the top, use an Assignment node to create a “currentPart” variable and assign it to 1. (That naming is important. You can name it whatever you want, but you’ll have to change it in the script as well.)

When constructing the Assignment node at line 10, manually type the “shiftPlane(” part, then select the POSE version of your Feature (should come with the “_const” already attached to it) and then pass the VARIABLE version of the same Feature (won’t have the “_const” part). The last argument is the number of columns. From your picture, you had 4, so I put 4.

In the program, the robot dips down then back up. Then shifts in X direction. Dips down then up. Shift in X. It does that 4 times. Then it shifts a large amount in y, and resets its X offset. Then it dips down and up 4 more times, then shifts a small amount in y. It does this for as long as currentPart is less than TOTAL_PARTS. So you’ll have to decide how to terminate that loop. You can assign TOTAL_PARTS in the before start, or make it an installation variable, or just hard-code 40 parts or whatever.

Finally, after the loop, I reassigned the VARIABLE version of the Feature to the POSE version of the Feature. I’ve had some issues in the past if I forget to do this, otherwise subsequent runs of the program can start at the last offset point. Which is no bueno.

Here’s the script to try out:

global x_offset = 0.01
global y_offset_small = 0.01
global y_offset_large = 0.1

def shiftPlane(plane_const, plane_var, columns):

#check to see if you've reached the end of the row. If you have, reset your x position back to its original value. Otherwise, shift it
  if(currentPart % columns == 0):
    plane_var[0] = plane_const[0]
    plane_var[0] = plane_var[0] + x_offset

#check to see if you've run 2 rows of parts. If you have, shift Y by the small amount. Otherwise, shift by the large amount
  if((currentPart) % (2 * columns) == 0):
    plane_var[1] = plane_var[1] + y_offset_small
  elif(currentPart % columns == 0):
    plane_var[1] = plane_var[1] + y_offset_large
  currentPart = currentPart + 1
  return plane_var

I’ve got the offsets hardcoded at the top, so you would just replace those values with whatever your x and y offsets are (in METERS). If you need/want these to be more modular, you can add them as arguments to the shiftPlane() function, and pass them in from the main program.

Give it a go (preferably at less than 100% speed lol) and let me know if something isn’t working right/doesn’t make sense.

1 Like

Super slammed right now, will give this a go when I get a moment to take a deep breath. Thanks much!