Interrupt, then Resume de-Palletizing program?

Is there a way to setup a de-palletizing program so that it can be interrupted and then resumed at the correct next part in the operation? We have a pick table that holds 240 parts (setup as 24 stacks of 10 parts) which we process one at a time through several remote TCP operations and then drop in a bin. If a router bit randomly breaks or gets dull during the cycle, can the program be setup so that it can be paused at any point; router bit or buffing wheel replaced; then resumed at the exact correct point in the cycle? Thanks for any advice on setting up correct logic.

Bruce

2 Likes

Short answer is yes, but how it’s done depends on how you are set up and what the robot is doing.

And I can only partially* help if you are using the teach pendant (polyscope) to run the robot. If it’s run remotely it will be different and someone smarter than me will have to chime in. :slight_smile:

Also, I’m only answering because I want to understand how, exactly, this works. I have two identical UR 10e’s and *only one of them can be started in the middle of a pallet and I have not been able to identify how or why.

What I already know:

If the robot is tending a machine that does the cutting you can simply hit PAUSE on the teach pendant at a good, safe place in the program where the arm is outside the machine. Then when the machine is stopped you can make your changes, re-calibrate if necessary, and then continue the robot.

If for some reason the robot has to be stopped (not just paused, but stopping and resetting the program) you will need to have a counter variable that can be used for restart. You will need to change that counter “for this run only” then when the pallet is done, reset it back to zero.

Sadly, I’m not sure how that counter variable is tied to the pallet, so I cannot help beyond that. Would be nice to be able to start in the middle of a pallet on both robots. :+1:

In the below image I opened the .txt files for programs from both robots so I could see the node tree side-by-side.

The left pane (Robot 2) starts in the middle of the pallet when I change partsPallet_cnt to something besides 0. If I change it to 24 and restart the program, it picks up the 24th part in the pallet and continues on from there.

The right pane (Robot 1) always starts at the beginning no matter what I change part_count_loc to. Might be something in the pallet logic, or maybe something in the Installation, I don’t know.

Hopefully someone can shed some light. Would help us both! :slight_smile:

1 Like

I also want to know the easiest way to do this. We have a customer that wants to setup many parts in trays and could very well get interrupted in the middle for whatever reason. How do we make starting from part # X convenient for them?

1 Like

Depending on how complicated your palletizing actions are, you may benefit from a script that can shift a feature manually. Polyscope’s built-in palletizing can be pretty handy, but it can also be a major pain to get right. This method will also require fixed distances between parts. This will not account for any irregular patterns:

1st step: Teach a feature. This should be taught to your pallet such that you can use the arrow keys to jog cartesionally along your pallet.

2nd step: Teach all templated moves relative to this feature. This is where an existing program is likely screwed. You can KINDA recover, by switching to the originally taught feature, jogging to a waypoint, switching your feature, and clicking “Set Position” again…for every waypoint. It sucks but can be done. Teach only the actions that you need to perform per part. For example, if I am depalletizing, my pick actions are going to need to shift around, but my place actions might be a fixed drop off point, maybe on a conveyer. For this example, only my pre-pick, pick, post-pick moves need to be taught to this feature.

3rd step: Create a script function to shift your feature. This is a pretty straightforward example for how to leverage the power of features. Instead of trying to add offsets to all waypoints, we can just programmatically move the feature around, and all the moves will adjust automatically.

Imagine I have a 3x4x5 box. That is, 3 units across my Feature’s Y-axis, 4 units across my Feature’s X-axis, and 5 units along my Feature’s Z-axis. Again this assumes that this is a uniform box, with the parts I’m depalletizing at regular intervals. Then all I need is those fixed distances: an x, y, and z offset. (These can be user input at the beginning of each program run, or hard-coded installation variables). You’ll also want current_part, total_parts, x_rows, and y_column variables. The current_part becomes something the user can input to determine where to begin the depalletizing program. total_parts would be how many parts are on a full pallet (or can also be user input if you’re doing some sort of half pallet). x_rows and y_columns contain the dimensions of your pallet. In my proposed example, the variables would be as follows: (remember all dimensions are in METERS!)

image

And the script required to pattern, or palletize anything is this: (you can omit the “global” modifiers on the variables, I included them so they are visible during program execution for debugging.)

def palletize(x_offset, y_offset, z_offset, current_part, feature):
global z_layer = floor(current_part / (y_columns * x_rows))
global row_number = floor(current_part / y_columns) - (z_layer * x_rows)
global column_number = floor(current_part % y_columns)
return pose_add(feature, p[row_number * x_offset, column_number * y_offset, z_layer * z_offset, 0, 0, 0])
end

Here is a Polyscope program I threw together that utilizes this script. It just takes the robot to a single pose, waits for half a second, and then shifts the feature. You will notice it takes the single taught waypoint and moves it to 60 different locations. That being my length x width x height of my imaginary box. The biggest stipulation here is understanding the difference between selecting your feature from the “Pose” dropdown, as opposed to the “Variables” dropdown. The one with the _const suffix is the pose set as soon as you teach the feature, and CANNOT be programmatically changed. The feature available via the “Variables” tab does not have this suffix, and can be changed programmatically. I am assigning this non-const version to the result of my palletizing function, and passing in the “const” version of the same feature. (Another thing to note is that this const feature MUST be selected from the dropdown. Typing it out manually does NOT work, for some reason.)

You’ll notice at the beginning you can prompt the operator for a part to start at, and the script will offset to this position in the “box.”

Then of course you could take this the extra mile and develop a URCAP that condenses all the nasty script into a clean user interface. (I originally wrote this for purely x-y shifting, but your question inspired me to add the Z dimension. I’ll have to update my CAP now lol)

image

Anyway sorry for the incredibly long-winded post. Hopefully you can pull something useful out of it, otherwise it will be decent documentation for myself when I go to update my CAP and inevitably forget everything I’d done.

2 Likes

Hi Eric,

Thanks for the information. I am just starting my URcap development journey now, and was planning on developing a similar, slightly simpler URcap than you have shown here. However, I am missing a trivial portion of variable assigning; in your program you have a Loop function, where you loop up until the total_parts variable. How do you assign the value in the ‘Total Parts’ text box within the URcap into the total_parts program variable?

You’ll likely benefit from diving into some of the URCap Samples that are on UR’s website. There’s quite a bit that goes into this, especially if you’re unfamiliar with Java. I’ll assume for now you’ve already got the UI passing the user’s inputs into Java variables. If not, definitely check out the example CAPs provided by UR.

To assign a Java variable to a URScript variable, you just do something like this in your generateScript() method:
image

This is assigning the local variable “Parts” to the result of my java method getPartsSetting().

Thanks Eric. I think this is the missing part for me. I appreciate the help!

-Mark

Actually, I noticed in the Palletizing Template, that it is possible to edit the value of the Item Counter Variable (in the Installation) to force the robot to execute from a particular item # in the palletizing/depalletizing operation… If there is a fault during a cycle, the robot will automatically proceed from the correct next item # (unless the fault occurs during the palletizing/depalletizing operation-then it wants to replay that item). Very cool!

Looked through this thread and all the answers seems quite complicated. With the right URCap this doesn’t have to be a complex task. With Pally URCap for palletizing (available in UR+: UR+ | Pally Palltizing Software - Universal Robots) the possibility to interrupt and then resume a pallet is a native feature with a graphical user interface to support the use of the feature. To see how it’s used, see here: https://rocketfarm.atlassian.net/wiki/spaces/PB/pages/386990093/Partial+Pallet

Best
Martin

Hi, plesae check this program try to implement an interruption without stopping cobot runtime.

eventTest.urp (1.9 KB)