# Working with path_offset_set

Hello

I am helping a customer program an application that involves a plasma cutter on the robot. The cutter is able to send an analog signal to associate how big the flame is currently. The idea is to take that value and convert it into a distance for the robot to be able to adjust the Z of the active TCP to compensate. I thought that the path_offset_set command would work perfectly for that but it doesn’t seem to be functioning how I thought it would. The tool is on a 45 degree from the tool flange. Maybe I should be asking if there is a better way to adjust the Z of the tool on the fly than using this script command?

here is some test code
path_offset_enable()
path_offset_set_alpha_filter(0.0006)

if (get_digital_in(2) == True):
plas_on=1
path_offset_set([0,0,0.051,0,0,.00],2)
end

if (get_digital_in(1) == True):
plas_on=2
path_offset_set([0,0,-0.050,0,0,0],2)
end

sync()

Thanks in advance

1 Like

We had a similar problem with our welding CAP. The welding torch is off-center of the flange. Despite what the documentation says, path offset does NOT go by TCP, it only goes by the flange (at least it had when we first started this project). My coworker who did the early development was in contact with UR and they provided him the following URScript code:

# MOTION FUNCTIONS

def FrameDef(Origin,p2,p3):
v1=[0,0,0]
v2=[0,0,0]
epsilon =[0,0,0]
RotVector= [0,0,0]
v1=p2-Origin
v1=p2-Origin
v1=p2-Origin
v2=p3-Origin
v2=p3-Origin
v2=p3-Origin
Norm1 = norm(v1)
Norm2 = norm(v2)
if ((Norm1==0) or (Norm2==0)):
popup(“No distance between p2(p3) and the Origin!”, “Frame generation failed!”)
halt
end
v1=v1/Norm1
v1=v1/Norm1
v1=v1/Norm1
v2=v2/Norm2
v2=v2/Norm2
v2=v2/Norm2
if norm(cross_product(v1,v2))<0.1:
popup(“The 3 points are aligned!”, “Frame generation failed!”)
halt
end
Xvers = v1
Zvers = cross_product(v1,v2)
Znorm = norm(Zvers)
Zvers = Zvers/Znorm
Zvers = Zvers/Znorm
Zvers = Zvers/Znorm
Yvers = cross_product(Zvers,Xvers)
Ynorm = norm(Yvers)
Yvers = Yvers/Ynorm
Yvers = Yvers/Ynorm
Yvers = Yvers/Ynorm
eta = 0.5sqrt(norm(Xvers+Yvers+Zvers+1))
epsilon = 0.5
sign(Yvers-Zvers)sqrt(norm(Xvers-Yvers-Zvers+1))
epsilon = 0.5
sign(Zvers-Xvers)sqrt(norm(Yvers-Zvers-Xvers+1))
epsilon = 0.5
sign(Xvers-Yvers)sqrt(norm(Zvers-Xvers-Yvers+1))
if(norm(eta)==1):
RotVector=0
RotVector=0
RotVector=0
else:
theta = 2
acos(eta)
RotVector = epsilon*theta/sin(theta/2)
RotVector = epsilon*theta/sin(theta/2)
RotVector = epsilon*theta/sin(theta/2)
end
return p[Origin,Origin,Origin,RotVector,RotVector,RotVector]
end

def get_motion_frame():
sync()
P0=get_target_tcp_pose_along_path()
TargetSpeed=get_target_tcp_speed_along_path()
while(norm([TargetSpeed,TargetSpeed,TargetSpeed])<0.0015):
TargetSpeed=get_target_tcp_speed_along_path()
sleep(0.01)
end
Xmotion=pose_add(P0, TargetSpeed)
Ztool=pose_trans(P0,p[0,0,1,0,0,0])
dX=pose_trans(pose_inv(P0),Xmotion)
dZ=pose_trans(pose_inv(P0),Ztool)
dY=cross_product(dZ,dX)
Ymotion=pose_trans(P0,p[dY,dY,dY,0,0,0])
MotionFrame=FrameDef(P0,Xmotion,Ymotion)
return MotionFrame
end

def path_offset_tcp(offset, type):
global tcpOffset = get_motion_frame()
global pathOffset = pose_trans( p[0.0, 0.0, 0.0, tcpOffset, tcpOffset, tcpOffset],p[offset, offset,offset,offset,offset,offset])
global pathOffsetRot = pose_trans(p[0.0, 0.0, 0.0, tcpOffset, tcpOffset, tcpOffset], p[offset, offset, offset, 0.0, 0.0, 0.0])
pathOffset = pathOffsetRot
pathOffset = pathOffsetRot
pathOffset = pathOffsetRot
path_offset_set(pose2list(pathOffset), type)
end

Again, I won’t pretend to know what any of this is really doing, but suffice it to say, if you want to use path_offset with a tool whose TCP is not the flange, write these functions into your URScript and instead call path_offset_tcp(offset, type). You may have to change the type of offset to 1 instead of 2 as well.

If this doesn’t work for you, just get rid of it and I wish you the best of luck!