Customize the Robot's Path
Ever since Pally v2.6.0, it has been possible to change the robot’s movements to fit your palletizing project!
This page describes the general outline of when and how to use the custom path feature:
In the sub-pages, important variables that must be used in the custom path are explained.
Using the custom path feature, Pally will still use the positions you have calibrated in the Pally program node; such as:
Pick up position(s) (primary and secondary)
Waiting position
Pallet positions (left and right)
However, after the robot has picked up the box from the pickup position, then your custom robot path can take over and move the robot to place the box in its target position1 on the pallet. Once the box has been placed on the pallet, your path must then move the robot back towards the pick up position.
To create your custom path, you must be able to program the robot using URScript commands. Refer to Universal Robot’s URScript API reference for more details: URScript API Reference (2018)
When to Use It?
If there are some problematic boxes in your palletizing routine where the robot crashes or the Pally robot movements do not achieve the desired result, then a solution could be to use the custom path feature.
By using the custom path feature, you are responsible for all the robot’s movements between the pick up position and the box’s position on the pallet (and back again).
It is possible to only use the custom path feature on certain problematic boxes, and then use the path provided by Pally for the remaining boxes. This can be achieved by setting the rf_custom_path
variable to False
/ True
. Refer to the page explaining this variable: https://rocketfarm.atlassian.net/wiki/spaces/PB/pages/899285346
How to Use It?
To actually use the custom path feature in Pally, you must use URScript commands and define two functions: (1) for moving the robot to the target position and (2) for moving the robot back towards the pick up position. These two functions need to be called in the Pally callbacks afterGrab and afterRelease respectively. The robot program should then look something like this:
A Pally program where a customized path is used
In the example above, the customPath.script
-file contains URScript code that defines the two functions, MoveToTarget()
and MoveBack()
; where MoveToTarget()
is used to move the robot from the pick up position to the target position and MoveBack()
(obviously) moves the robot back towards the pick up position. Here is an example of how the customPath.script
could be defined:
p_boxfree = p[0,0,0,0,0,0]
p_boxfree2= p[0,0,0,0,0,0]
p_boxfree3= p[0,0,0,0,0,0]
p_exit= p[0,0,0,0,0,0]
j_exit = [0,0,0,0,0,0]
p_approach = p[0,0,0,0,0,0]
p_waypoint = p[0,0,0,0,0,0]
rf_custom_path = True
def GetBlend(to_point, next_point):
this_point = get_actual_tcp_pose()
d1 = point_dist(this_point, to_point)
d2 = point_dist(to_point, next_point)
if (d1 < d2):
return d1 * 0.25
else:
return d2 * 0.25
end
end
def MoveToTarget():
if (rf_custom_path):
# move up
p_boxfree = pose_trans(get_actual_tcp_pose(), p[0,0,-rf_box_free,0,0,0])
# move closer to the robot
p_boxfree2= p_boxfree
d = sqrt(rf_camera[0] * rf_camera[0] + rf_camera[1] * rf_camera[1]) / sqrt(p_boxfree2[0] * p_boxfree2[0] + p_boxfree2[1] * p_boxfree2[1])
p_boxfree2[0] = p_boxfree2[0] * d
p_boxfree2[1] = p_boxfree2[1] * d
# move up
p_boxfree3= p_boxfree2
if (MoveTarget[2] + ProductHeight > p_boxfree3[2]):
p_boxfree3[2] = MoveTarget[2] + ProductHeight
end
# move away from the conveyor and rotate
if (PalletNr == 1): # right pallet
p_exit = pose_trans(p[-0.35, 0, 0, 0, 0, 0], p_boxfree3)
else: # left pallet
p_exit = pose_trans(p[0.35, 0, 0, 0, 0, 0], p_boxfree3)
end
p_exit[3] = MoveTarget[3]
p_exit[4] = MoveTarget[4]
p_exit[5] = MoveTarget[5]
# approach the pallet
if (PalletNr == 1): # right pallet
p_approach = pose_trans(p[0.05, -0.05, 0.05, 0, 0, 0], MoveTarget)
else: # left pallet
p_approach = pose_trans(p[-0.05, -0.05, 0.05, 0, 0, 0], MoveTarget)
end
# this may be actual for the top layer:
# the approach should be closer than usual to have enough reach
if (not is_within_safety_limits(p_approach)):
# should not use normally
p_approach = MoveTarget
end
# a waypoint before approach
p_waypoint = p_approach
if (p_waypoint[2] < p_boxfree[2]):
p_waypoint[2] = p_boxfree[2]
end
if (p_waypoint[2] < MoveTarget[2] + ProductHeight + rf_approach[2]):
p_waypoint[2] = MoveTarget[2] + ProductHeight + rf_approach[2]
end
movel(p_boxfree, a=rf_max_acceleration, v=rf_speed, r=GetBlend(p_boxfree, p_boxfree2))
movel(p_boxfree2, a=rf_max_acceleration, v=rf_speed, r=GetBlend(p_boxfree2, p_boxfree3))
movel(p_boxfree3, a=rf_max_acceleration, v=rf_speed, r=GetBlend(p_boxfree3, p_exit))
movel(p_exit, a=rf_max_acceleration, v=rf_speed, r=0.01)
j_exit = get_actual_joint_positions()
if (is_within_safety_limits(p_waypoint)):
movej(p_waypoint, a=rf_max_acceleration, v=rf_speed, r=0.01)
movel(p_approach, a=rf_max_acceleration, v=rf_speed, r=GetBlend(p_approach, MoveTarget))
else:
movej(p_approach, a=rf_max_acceleration, v=rf_speed, r=0.01)
end
movel(MoveTarget, a=rf_precise_acceleration, v=rf_precise_speed, r=0)
MovePerformed=True
end
end
def MoveBack():
if (rf_custom_path):
if (is_within_safety_limits(p_waypoint)):
movel(p_waypoint, a=rf_max_acceleration, v=rf_speed, r=GetBlend(p_waypoint, p_exit))
else:
movel(p_approach, a=rf_max_acceleration, v=rf_speed, r=GetBlend(p_approach, p_exit))
end
movej(j_exit, a=rf_max_acceleration, v=rf_speed, r=0.01)
movel(p_boxfree3, a=rf_max_acceleration, v=rf_speed, r=GetBlend(p_boxfree3, p_boxfree2))
movel(p_boxfree2, a=rf_max_acceleration, v=rf_speed, r=0)
MovePerformed=True
end
end
An example of how MoveToTarget()
and MoveBack()
functions can be defined in the customPath.script
To add these script commands, add a ‘Script’-node by pressing the ‘Script’-button in Polyscope:
Important Variables for Custom Path
Pally makes it easier for you to create a custom path by making all the necessary variables available through global variables. The important global variables you must use for the custom path feature are as follows:
Click on the links to be re-directed to the pages explaining each variable in more detail.
Footnotes: