#### Discussion

Back to discussions page
Hi,
I have a task very similar to the example "Find Contact Offset" using #ForceCopilot.
The difference is  -  I find for the position of the blister with the components in the stack (20 pcs).
So I can't use a simple wizard from URCap - I created my own function using the built-in "rq_functions" to find the blister position in the current stack from three points and calculated the intersection from these points (crosspoint P0).
I verified the position of the calculated by movements on this point and then by tool reference in the X and Y axes accurately copied the edges of the blister.

First, I calibrate a default position where I have teached the corner pickup points on the pallet and determine the calibration point of intersection (calibr. crosspoint K0). Then, when I rotate and move the blister, I find a new intersection of the changed position of the blister P0.

To find new corner positions of the palette on a rotated blister, I used this typical transformation:
```pose_pal_curr = pose_trans(P0, pose_trans(pose_inv(K0), pose_pal_cal))
```
The problem is that this transformation does not work quite accurately - when the blister is shifted in the X or Y axis, it is correct;
I've already tried many variations of calculations - this transformation gives the best results however unusable.

Here is demo photo workplace: TCP at the starting position of the first point on the palette: TCP after transformation (see above) for the rotated and shifted palette (rotation Rz of tool is correct): Does anyone have any idea where I make a mistake?

Vlastimil

• edited May 5 Accepted Answer
Problem has solved, there was mistake in cross_point function, which returns the intersection of two lines from three detected points by searching the surface using a force sensor.
For everyone is functional version here:
```
# Calculate crosspoint from three points
def cross_point(posA, posB, posC):
pA = [posA, posA]
pB = [posB, posB]
pC = [posC, posC]
# directional vector line U
if posC>posA:
# line AB, U = B-A
pU = [pB-pA, pB-pA]
elif posC<posB:
# line BA, U = A-B
pU = [pA-pB, pA-pB]
else:
popup("The crosspoint of lines P1-P2 with the perpendicular at point P3 cannot be determined!",
"Error, program done!",error=True,blocking=True)
halt
end
# angle of rotation in the Z axis
rZ = atan2(pU,pU)
# N - Normal vector of AB line, (perpendicular to U)
if pU<0:
pN = [-pU, pU]
else:
pN = [pU, -pU]
end
# a ... parametric expression of the line A-B (t, s = real numbers)
t = 1
s = 1
aX = pA + t * pU
aY = pA + t * pU
# c ... parametric expression of the perpendicular on line A-B passing through point C
cX = pC + s * pN
cY = pC + s * pN
# crosspoint of lines a x c
pT = (pN*(pC-pA)+pN*(pA-pC))/(pU*pN-pU*pN)
pS = (pA+pT*pU-pC)/pN
tX = pA + pT * pU
tY = pA + pT * pU
# checking the correctness of the intersection of the perpendiculars
sX = pC + pS * pN
sY = pC + pS * pN
# it must hold that tX = sX and tY = sY
posT = p[tX, tY, posB, posB, posB, posB]
# finally transformation with Z - rotation
return pose_trans(posT, p[0,0,0,0,0,rZ])
end

```
The use of the function is clear from the above description of the problem.

So again sometime next time Vlastimil

• So it looks like I have a problem with calculating the intersection of the three points found by touching the surface of the blister.
The method used in the "Find Contact Offset" application does not suit for me, because I do not use the wizard. I need to calculate everything with a script, because I will find out the position in different layers of a stack of blisters.
I would like to modify the Robotiq used internal functions "relocate_orientation" or "relocate_1_touch", but I'm a bit lost in it.
In case of interest I would send how I calculate the intersection.
However, the calculation is not correct, with deviations (see the pictures above).

A schematic illustration of the problem is attached: Does anyone have experience with calculating the intersection of three points (incl. rotation)?

Vlastimil
• Here is a code for calculation crosspoint:
```# Calculate crosspoint from three points
def cross_point(posA, posB, posC):
pA = [posA, posA]
pB = [posB, posB]
pC = [posC, posC]
# directional vector line
if posC>posA:
# line AB, U = B-A
pU = [pB-pA, pB-pA]
elif posC<posB:
# line BA, U = A-B
pU = [pA-pB, pA-pB]
else:
popup("The crosspoint of lines P1-P2 with the perpendicular at point P3 cannot be determined!",
"Error, program done!",error=True,blocking=True)
halt
end
# angle of rotation in the Z axis
rZ = atan2(pU,pU)
# N - Normal vector of AB line, (perpendicular to U)
if pU<0:
pN = [-pU, pU]
else:
pN = [pU, -pU]
end
# a ... parametric expression of the line A-B (t, s = real numbers)
t = 1
s = 1
aX = pA + t * pU
aY = pA + t * pU
# c ... parametric expression of the perpendicular on line A-B passing through point C
cX = pC + s * pN
cY = pC + s * pN
# crosspoint of lines a x c
pT = (pN*(pC-pA-pN*pC)+pN*pA)/(pU*pN-pU*pN)
pS = ((pA+pT*pU)/pN)-pC
tX = pA + pT * pU
tY = pA + pT * pU
# checking the correctness of the intersection of the perpendiculars
sX = pC + pS * pN
sY = pC + pS * pN
# it must hold that tX = sX and tY = sY
posT = p[tX, tY, posB, posB, posB, posB]
# finally transformation with Z - rotation
return pose_trans(posT, p[0,0,0,0,0,rZ])
end```
I will be happy for any advice.

V.
• In this code is mistake, here is correction:
```	# directional vector line
if posC>posA:
# line AB, U = B-A
pU = [pB-pA, pB-pA]
elif posC<posB:
# line BA, U = A-B
pU = [pA-pB, pA-pB]
else:
popup("The crosspoint of lines P1-P2 with the perpendicular at point P3 cannot be determined!",
"Error, program done!",error=True,blocking=True)
halt
end```
... but the problem remains.

V.