<!-- Source: https://docs.captron.com/application-notes/tcp-recalibration-scara -->

# Performing TCP XYZ Recalibration with Kawasaki .AS Language

This application note describes how to find the offsets of the Tool Center Point (TCP) using a CAPTRON TCP measuring instrument with any industrial robot. The procedure uses the sensor's two perpendicular laser barriers and a circular motion path to calculate the X, Y, and Z offsets of the tool tip. The example code is written in Kawasaki .AS language.

:::info
The example code shown below is written in Kawasaki .AS language. The implementation on other robot brands will differ in syntax, but the underlying algorithm and measurement principle remain the same.
:::

## Overview

The recalibration procedure consists of three main phases:

1. **XY Recalibration** -- Determine the X and Y offsets by performing a circular motion through the laser barriers, recording 8 reference points, and computing the intersection of two lines.
2. **Z Recalibration** -- Determine the Z offset by moving the tool vertically through the laser barriers after XY correction.
3. **Apply offsets** -- Add the calculated offsets to the tool definition in the robot controller.

## XY Recalibration Procedure

### Step 1: Set the Center Position

Position the tool at the approximate center of the TCP measuring instrument -- where both lasers meet. Save the XYZ values for future reference. The center position does not have to be perfectly accurate; it serves as a reference baseline that is refined during recalibration.

![Circular path through X and Y axis lasers](./images/tcp-recal-circular-path.png)

*The TCP follows a circular path through both laser barriers. The X Axis Laser and Y Axis Laser are perpendicular to each other.*

### Step 2: Perform Circular Motion

Move the robot's TCP on a circular path through the sensor. The radius should be approximately half the size of the sensor aperture. For example, with an OGLW2-40 sensor (40 mm aperture), use a 20 mm diameter circular path.

![CAPTRON TCP measuring instrument with reference path overlay](./images/tcp-recal-instrument-photo.png)

*A CAPTRON TCP measuring instrument with X-Beam and Y-Beam laser barriers. The reference path (white ellipse) passes through both beams, generating reference points x&#x5F;ref1, x&#x5F;ref2, y&#x5F;ref1, and y&#x5F;ref2.*

### Step 3: Save 8 Reference Points

As the tool moves along the circular path, record the robot position each time the tool enters and exits a laser beam. This produces 8 reference points in total -- 4 for the X-axis laser and 4 for the Y-axis laser:

![8 reference points labeled v1 through v6 around the circular path](./images/tcp-recal-reference-points.png)

*Reference points are recorded at each laser beam crossing. Each laser is crossed twice per revolution (entering and exiting), yielding 4 positions per axis.*

### Step 4: Create Lines from Reference Points

At each end of each axis, average the two points where the tool entered and exited the laser. This gives two (x, y) positions that represent the center of the tool at that crossing:

![Line creation from averaged reference points](./images/tcp-recal-line-creation.png)

*For each pair of enter/exit points, calculate the midpoint. For example: pointOneX = (v1(x) + v2(x)) / 2, pointOneY = (v1(y) + v2(y)) / 2.*

The averaging is performed for all four crossing regions:

```
x_axis_x1_position = (x_axis_x1 + x_axis_x2) / 2
x_axis_x2_position = (x_axis_x3 + x_axis_x4) / 2
x_axis_y1_position = (x_axis_y1 + x_axis_y2) / 2
x_axis_y2_position = (x_axis_y3 + x_axis_y4) / 2
```

### Step 5: Create a Line for Each Axis

Using the two averaged points per axis, compute the slope and intercept for each laser line using the standard line equation Y = MX + B:

```
x_axis_slope = (x_axis_y2_position - x_axis_y1_position) /
               (x_axis_x2_position - x_axis_x1_position)
x_axis_b     = x_axis_y1_position - x_axis_slope * x_axis_x1_position
```

Repeat for the Y-axis laser line:

```
y_axis_slope = (y_axis_y2_position - y_axis_y1_position) /
               (y_axis_x2_position - y_axis_x1_position)
y_axis_b     = y_axis_y1_position - y_axis_slope * y_axis_x1_position
```

### Step 6: Find the Intersection

Set the two line equations equal and solve for x and y. The intersection point is where the two laser lines meet -- this is the true center of the sensor as measured by the tool:

```
shifted_x = (y_axis_b - x_axis_b) / (x_axis_slope - y_axis_slope)
shifted_y = (x_axis_slope * shifted_x) + x_axis_b
```

Calculate the offsets by comparing to the original center position:

```
offset_x = curr_x - shifted_x
offset_y = curr_y - shifted_y
```

Apply these offsets to the tool and update the center waypoint:

```
new_x = curr_x + offset_x
new_y = curr_y + offset_y
```

:::warning
If the X or Y axis laser line is perfectly parallel to the robot's base coordinate system, the slope calculation will result in a division by zero. This is extremely unlikely in practice but should be handled with error checking in the robot program.
:::

## Z Recalibration Procedure

After recalibrating X and Y, the Z offset can be determined:

1. Move the tool to the corrected center position (using the new X and Y values).
2. Lower the tool into the sensor so it breaks both laser beams.
3. Slowly move the tool in the Z+ direction (upward) until both laser signals turn off (tool clears the beams).
4. Move the tool back down slightly (e.g. -1 mm) so it just barely breaks the lasers again.
5. Record this position and calculate the Z offset from the original center position.

```
; Move upward until both lasers are cleared
i = 0
while sig(x_laser) and sig(y_laser)
  POINT temp = SHIFT(lowered_center BY 0, 0, i)
  LMOVE temp
  TWAIT 0.01
  i = i + 1
END

; Move back down slightly to touch the lasers
POINT temp = SHIFT(temp BY 0, 0, -1)
LMOVE temp

; Record position and calculate offset
HERE temp_center
DECOMPOSE z_array[0] = temp_center
new_z = z_array[2]
offset_z = curr_z - new_z
```

## Example Code (Kawasaki)

The Kawasaki implementation uses three program files:

### 1. Circular Motion Program

This program defines the four cardinal points of the circular path and executes the motion while background programs record positions:

```
negative_rad = -1 * radius
POINT plus_x  = SHIFT(center BY radius, 0, 0)
POINT minus_y = SHIFT(center BY 0, negative_rad, 0)
POINT minus_x = SHIFT(center BY negative_rad, 0, 0)
POINT plus_y  = SHIFT(center BY 0, radius, 0)

JMOVE plus_x
PCEXECUTE readx.pc, -1    ;read positions
PCEXECUTE ready.pc, -1
C1MOVE minus_y
C2MOVE minus_x
C1MOVE plus_y
C2MOVE plus_x
ACCURACY 1 FINE
PCABORT 2:                 ;stop reading positions
LMOVE center
BREAK
TWAIT 0.1
```

### 2. Background Programs (Position Recording)

Two background programs run concurrently -- one monitors each laser axis. They use a state-machine loop to detect each signal transition and record the robot position using the `HERE` function:

**Y-axis reader (`ready.pc`):**

```
loop1:
  PRINT "Y"
  curr_state = sig(y_laser)
  if curr_state Then
    twait 0.01
    HERE y_pose1
    interrupts = interrupts + 1
    GOTO loop2
  ELSE
    GOTO loop1
  END

loop2:
  curr_state = sig(y_laser)
  if NOT curr_state THEN
    twait 0.01
    HERE y_pose2
    interrupts = interrupts + 1
    GOTO loop3
  ELSE
    GOTO loop2
  END

; ... loop3 and loop4 follow the same pattern for y_pose3, y_pose4
```

**X-axis reader (`readx.pc`):** Identical structure but monitors `sig(x_laser)` and saves `x_pose1` through `x_pose4`.

The `HERE` function call saves the tool position in space at the moment the laser signal transitions. The `interrupts` variable is used for error checking -- every time the sensor output changes, it increments. If the robot does not pass through all the lasers, the calculations cannot be performed. Check if interrupts are not equal to 4 to detect an incomplete pass.

### 3. XYZ Recalibration Program

This program decomposes the recorded positions, calculates the averaged reference points, computes the line equations, finds the intersection, and produces the offsets:

```
; Decompose recorded positions into coordinate arrays
DECOMPOSE x_laser_enter1[0] = x_pose1
DECOMPOSE x_laser_exit1[0]  = x_pose2
DECOMPOSE x_laser_enter2[0] = x_pose3
DECOMPOSE x_laser_exit2[0]  = x_pose4

; Extract X and Y values for each reference point
x_axis_x1 = x_laser_enter1[0]   ;x position when entering x
x_axis_x2 = x_laser_exit1[0]    ;x position when exiting
x_axis_x3 = x_laser_enter2[0]   ;x position when entering x second time
x_axis_x4 = x_laser_exit2[0]    ;x position when exiting x second time
x_axis_y1 = x_laser_enter1[1]   ;y position when entering x
x_axis_y2 = x_laser_exit1[1]    ;y when exiting
x_axis_y3 = x_laser_enter2[1]   ;y when entering second
x_axis_y4 = x_laser_exit2[1]    ;y when exiting second

; Average reference points for X-axis line
x_axis_x1_position = (x_axis_x1 + x_axis_x2) / 2
x_axis_x2_position = (x_axis_x3 + x_axis_x4) / 2
x_axis_y1_position = (x_axis_y1 + x_axis_y2) / 2
x_axis_y2_position = (x_axis_y3 + x_axis_y4) / 2

; Calculate slope and intercept for X-axis laser line
x_axis_slope = (x_axis_y2_position - x_axis_y1_position) /
               (x_axis_x2_position - x_axis_x1_position)
x_axis_b = x_axis_y1_position - x_axis_slope * x_axis_x1_position

; Repeat for Y-axis laser (same structure with y_laser_enter/exit)
; ...

; Find intersection point of both lines (center of laser barrier)
shifted_x = (y_axis_b - x_axis_b) / (x_axis_slope - y_axis_slope)
shifted_y = (x_axis_slope * shifted_x) + x_axis_b

; Calculate offsets for TCP recalibration
offset_x = curr_x - shifted_x
offset_y = curr_y - shifted_y

; New coordinates in coordinate space
new_x = curr_x + x_offset
new_y = curr_y + y_offset
```

## Important Considerations

1. **Untested on physical hardware** -- The example code has been tested in Kawasaki simulation software only. Real-world testing is required before production use.

2. **Center position accuracy** -- If the initial center position is not accurate, the calculated offsets will be less accurate. Error checking at the start verifies that both laser outputs are active when the tool is at the center position. For the most accurate results (especially for Z), the very tip of the tool should be touching the lasers.

3. **Division by zero** -- If a laser axis line happens to be perfectly parallel to the robot base, the slope calculation divides by zero. While extremely unlikely in practice, this edge case should be handled in the robot program.

4. **Other robot brands** -- The algorithm is universal, but the robot language, motion commands, and signal handling will differ depending on the robot brand. Key functions to map:
   - `HERE` (save current position) → equivalent position capture function
   - `sig()` (read digital signal) → digital I/O read function
   - `SHIFT` (offset a point) → point offset function
   - `DECOMPOSE` (extract XYZ from point) → coordinate extraction function
   - `C1MOVE` / `C2MOVE` (circular motion) → circular interpolation commands

---

For general information about TCP calibration principles, see [Robot Calibration with TCP Measuring Instruments](./tcp.md).

If you have questions about our products and the integration into your processes, please contact us at [techsupport.americas@captron.com](mailto:techsupport.americas@captron.com).
