Calibration with PLC¶
This document describes the complete technical specification for integrating a PLC with Pick[+] software for the Calibration routine.
Currently, the supported PLC communication protocols are:
- Modbus TCP
- Siemens
Standard Calibration Method
Once the PLC is configured, see Camera-Robot Calibration for the standard manual calibration process through the Pick[+] interface.
Related Documentation
For execution-specific PLC integration, see PLC Application.
Standards and Conventions¶
All poses use 6 consecutive registers with the following encoding:
| Setting | Value | Description |
|---|---|---|
| Endianness | Big-Endian | Network Byte Order |
| Pose Order | X, Y, Z, R, P, Y | 6 consecutive registers per pose |
| Translation Scale | 10000 | Tenths of millimeter (0.1 mm / 0.0001 m) |
| Rotation Scale | 10000 | 1/10,000th of a radian (0.0001 rad) |
Coordinate Format
All spatial coordinates use this default format. These values must be respected when sending position data to ensure correct interpretation by Pick[+]. The format can be modified if required.
The PLC acts as the server and hosts every register listed on this page. Pick[+] acts as the client: it opens the connection to the PLC IP address, polls these registers and writes back the results. The PLC program only reads and writes its own memory, it never initiates communication.
Communication is described from the PLC perspective:
| Direction | Description |
|---|---|
| PLC Inputs (Read-Only) | Registers written by Pick[+] and read by the PLC (status, flags, results) |
| PLC Outputs (Write) | Registers written by the PLC and read by Pick[+] (requests + parameters) |
General Registers¶
The following registers are required for proper communication with the Pick[+] platform.
Shared Registers
Registers marked as "Shared" (addresses 0-4) are global across all routines (Calibration, Execution, Scan). These registers use the same addresses regardless of which routine is active. See also: PLC Application for execution routine-specific registers.
Routine Status
- Access: Read-Only
- Register type:
uint16
Indicates which routine is currently running.
| Value | State | Description |
|---|---|---|
| 0 | Configuration | No routine is currently running |
| 1 | Scan | Scanning routine is running |
| 2 | Execution | Execution routine is running |
| 3 | Calibration | Calibration routine is running |
Life Bit / Heartbeat
- Access: Read-Only
- Register type:
bool
Pick[+] toggles the value of this register between 0 and 1 at regular intervals to indicate it is operating and connected. The default interval is 1 second and it can be configured.
Error Code
- Access: Read-Only
- Register type:
uint16
Sent together with the routine status. Indicates whether an error occurred during execution.
| Value | State | Description |
|---|---|---|
| 0 | No error | No error detected |
| 1 | Initialization Error | Error during initialization (e.g., hardware communication issues) |
| 2 | Runtime error | Error occurred during routine execution |
Controllable
- Access: Write
- Register type:
bool
This register indicates to Pick[+] that the robot is ready to be controlled. This is required in order to start the calibration or execution. This is a safety mechanism to prevent sending commands to the robot when the robot is not ready to be moved.
Calibration Routine Registers¶
- Routine Status:
3(Calibration)
Currently, only automatic calibration routines are supported. The calibration trajectory is predefined by Pick[+]. The registers below are required to perform calibration through a PLC.
PLC Inputs¶
General registers written by Pick[+] and read by the PLC.
| Name | Count | Type | Description |
|---|---|---|---|
TCP_POSE |
6 | int16 | TCP pose used when the tool reference frame is sent. When sending a robot trigger request, the pose must be expressed with respect to this TCP. |
SEND_TOOL_FLANGE |
1 | bool | Indicates whether poses should be expressed with respect to the tool flange (true) or the TCP (false). |
These trajectory parameters are written by Pick[+] and may change for each trajectory request based on results computed by Pick[+].
| Name | Count | Type | Description |
|---|---|---|---|
TRAJ_POSE |
6 | int16 | Target trajectory pose for the robot. |
TRAJ_TRIGGER |
1 | bool | Action Flag. 1: Move to point, Stop, & request a Trigger Photo from Pick[+]. 0: Move to point (Pass-through), do not trigger. |
TRAJ_LIGHT |
1 | bool | Optional required light state for calibration. Only when the robot includes light. |
COMPUTING_FLAG |
1 | uint16 | 0: Ready for next request. 1: Computing. 2: Error. 3: Finished. |
TOGGLE_FLAG_TRAJECTORY |
1 | bool | Toggles when a trajectory request has been completed and data is ready to be read. |
ROBOT_ID |
1 | uint16 | Numeric ID of the robot being calibrated. Required for multi-robot setup. |
TRAJ_POSE_REF |
1 | uint16 | Reference Frame for the trajectory pose. 0: tool frame. 2: Base frame. |
TOGGLE_FLAG_TRIGGER |
1 | bool | Toggled by Pick[+] once a Trigger request has been accepted and processing has started (does not guarantee results are ready yet). Shared with Execution routine. |
PLC Outputs¶
These registers are written by the PLC and read by Pick[+].
| Name | Count | Type | Description |
|---|---|---|---|
TRAJECTORY_REQ |
1 | bool | Toggle bit to request a new trajectory action from Pick[+]. |
TRIGGER_REQ |
1 | bool | Toggle bit to request a trigger action from Pick[+]. Shared with the Execution routine, so it uses the address defined in the execution block. |
ROBOT_POSE |
6 | int16 | Current robot pose. The reference frame depends on SEND_TOOL_FLANGE and TCP_POSE. This should be read before every trigger request. |
Proposed Memory Map¶
Addresses shown in this document are indicative and may be remapped to match your PLC memory layout. Keep related blocks consecutive.
Each address corresponds to one 16-bit Holding Register. Booleans are stored as 0 / 1 in a full register.
Memory Layout
- Addresses 0–4: Global registers shared across all routines
- Addresses 5–30: Calibration routine registers
- Addresses 31+: Reserved for Execution routine (see PLC Application)
- Address 32:
TRIGGER_REQ, inside the execution block and shared with the Execution routine
| Address | Name | Type | Access | Scope |
|---|---|---|---|---|
| Shared - Base Control & Status | ||||
| 0 | ROUTINE_STATUS |
uint16 |
Read-Only | Shared |
| 1 | LIFE_BIT |
bool |
Read-Only | Shared |
| 2 | ERROR_CODE |
uint16 |
Read-Only | Shared |
| 3 | CONTROLLABLE |
bool |
Write | Shared |
| 4 | TOGGLE_FLAG_TRIGGER |
bool |
Read-Only | Shared |
| Calibration Registers | ||||
| 5 | TRAJECTORY_REQ |
bool |
Write | Calibration |
| 6 | TOGGLE_FLAG_TRAJECTORY |
bool |
Read-Only | Calibration |
| 7-12 | TCP_POSE |
int16[6] |
Read-Only | Calibration |
| 13 | SEND_TOOL_FLANGE |
bool |
Read-Only | Calibration |
| 14-19 | TRAJ_POSE |
int16[6] |
Read-Only | Calibration |
| 20 | TRAJ_TRIGGER |
bool |
Read-Only | Calibration |
| 21 | TRAJ_LIGHT |
bool |
Read-Only | Calibration |
| 22 | COMPUTING_FLAG |
uint16 |
Read-Only | Calibration |
| 23 | ROBOT_ID |
uint16 |
Read-Only | Calibration |
| 24 | TRAJ_POSE_REF |
uint16 |
Read-Only | Calibration |
| 25-30 | ROBOT_POSE |
int16[6] |
Write | Calibration |
| Shared with Execution | ||||
| 32 | TRIGGER_REQ |
bool |
Write | Shared |
Addresses are byte offsets within a Data Block (DB). Booleans use bit notation (byte.bit) and each occupies one byte. INT/UINT occupy 2 bytes and padding is added automatically before them when needed for even-byte alignment.
Memory Layout
- Addresses 0–7: Global registers shared across all routines
- Addresses 8–55: Calibration routine registers
- Addresses 56+: Reserved for Execution routine (see PLC Application)
- Address 58.0:
TRIGGER_REQ, inside the execution block and shared with the Execution routine
| Address | Name | Type | Access | Scope |
|---|---|---|---|---|
| Shared - Base Control & Status | ||||
| 0 | ROUTINE_STATUS |
uint16 |
Read-Only | Shared |
| 2.0 | LIFE_BIT |
bool |
Read-Only | Shared |
| 4 | ERROR_CODE |
uint16 |
Read-Only | Shared |
| 6.0 | CONTROLLABLE |
bool |
Write | Shared |
| 7.0 | TOGGLE_FLAG_TRIGGER |
bool |
Read-Only | Shared |
| Calibration Registers | ||||
| 8.0 | TRAJECTORY_REQ |
bool |
Write | Calibration |
| 9.0 | TOGGLE_FLAG_TRAJECTORY |
bool |
Read-Only | Calibration |
| 10-21 | TCP_POSE |
int16[6] |
Read-Only | Calibration |
| 22.0 | SEND_TOOL_FLANGE |
bool |
Read-Only | Calibration |
| 24-35 | TRAJ_POSE |
int16[6] |
Read-Only | Calibration |
| 36.0 | TRAJ_TRIGGER |
bool |
Read-Only | Calibration |
| 37.0 | TRAJ_LIGHT |
bool |
Read-Only | Calibration |
| 38 | COMPUTING_FLAG |
uint16 |
Read-Only | Calibration |
| 40 | ROBOT_ID |
uint16 |
Read-Only | Calibration |
| 42 | TRAJ_POSE_REF |
uint16 |
Read-Only | Calibration |
| 44-55 | ROBOT_POSE |
int16[6] |
Write | Calibration |
| Shared with Execution | ||||
| 58.0 | TRIGGER_REQ |
bool |
Write | Shared |
Programming Guide¶
This section explains how a PLC should be programmed so that Pick[+] can drive and complete a calibration routine independent of PLC brand or protocol (Siemens, Modbus, etc.).
| Component | Responsibility |
|---|---|
| Pick[+] | Computes the calibration trajectory, determines when to capture images, and writes target poses and status flags |
| PLC | Owns robot motion execution, executes trajectory and reports the current robot pose |
The PLC program should follow this logical flow:
- Idle / Configuration
- Calibration Active
- Trajectory Execution Loop
- Trigger Handling (optional)
- Calibration End or Error
Calibration Sequence¶
The sequence operates as a loop where the PLC "pulls" trajectory points one by one.
Step 0 - Startup
- Monitor
LIFE_BITandERROR_CODEcontinuously. - Set
CONTROLLABLE = 1. - Wait until
ROUTINE_STATUS=3(Calibration Mode Active).
Step 1 - Trajectory Loop
Repeat this loop while ROUTINE_STATUS is 3.
1.A. Request Trajectory¶
- Invert (Toggle) the
TRAJECTORY_REQbit. -
Wait until
TOGGLE_FLAG_TRAJECTORYchanges value (Handshake complete).- This indicates Pick[+] has received your request and updated the registers.
1.B. Check Computing Status¶
Read COMPUTING_FLAG:
| Value | Action |
|---|---|
0 (Ready) |
Data is valid. Proceed to Step C. |
1 (Computing) |
Results aren't ready. Go back to Step A (Request again after 50-100ms). |
2 (Error) |
A calculation error occurred. Stop the loop and start again. |
3 (End) |
The calibration has ended succesfully. |
1.C. Read & Move¶
-
Read the trajectory data registers:
TRAJ_POSE,TRAJ_POSE_REF,TRAJ_TRIGGER,TCP_POSE,TRAJ_LIGHT
-
Execute Move:
-
IF
TRAJ_POSE_REF == 2(Base Frame):- Move the robot to the absolute coordinates defined in
TRAJ_POSErelative to the Robot Base.
- Move the robot to the absolute coordinates defined in
-
IF
TRAJ_POSE_REF == 0(TCP/Relative):- The pose is defined relative to the current tool.
- Apply
TCP_POSEto the current tool flange. - Move relative to this new TCP.
-
1.D. Handle Trigger¶
If TRAJ_TRIGGER == 1:
- Stop the robot completely.
- Read
SEND_TOOL_FLANGE:- If 1: Write current Flange Pose to
ROBOT_POSE. - If 0:
- Write the position of the Specific TCP defined by the
TCP_POSEregister. - Logic: Take the current Flange Position and apply the
TCP_POSEoffset (read in Step C). Report the resulting coordinate of this tip relative to the Robot Base. Write current TCP Pose toROBOT_POSE.
- Write the position of the Specific TCP defined by the
- If 1: Write current Flange Pose to
- Invert (Toggle)
TRIGGER_REQ. - Wait until
TOGGLE_FLAG_TRIGGERchanges value. - The photo is now captured.
If TRAJ_TRIGGER == 0:
No action required. Proceed to next request.
Step 2 - Finish
The loop continues as long as ROUTINE_STATUS = 3.
Multi-Routine Calibration
Eye-in-hand calibration often runs multiple routines sequentially. Keep requesting trajectories until ROUTINE_STATUS drops to 0.
When ROUTINE_STATUS = 0, you can set CONTROLLABLE = 0
Calibration Complete
When ROUTINE_STATUS returns to 0, the calibration process has finished successfully.