Skip to content

Commit 90e12ef

Browse files
committed
FANUC: GRI for firmware release 25.10
## Overview This release brings full Protocol V1 support for FANUC robots integrating with Roboception vision systems. This implementation is compatible with Roboception firmware 25.10 and later, featuring the standardized message protocol (54-byte request, 80-byte response) for reliable communication and consistent pose handling across all FANUC robot programs. ## What's New **Standardized Protocol** - Full alignment with GRI Protocol V1 specification - Robust error handling with signed error codes - Reliable job status tracking from vision system responses - Compatible with Roboception firmware 25.10 and later **Improved Pose Handling** - Consistent world→flange frame convention across all programs - Automatic frame computation with no robot configuration side-effects - 1e6 precision scaling for accurate pose data **Better Documentation** - Clear integration guidelines for customers - Frame convention documentation - Updated examples with best practices ## Requirements - Roboception firmware version 25.10 or later - Generic Robot Interface license
1 parent 4804c9f commit 90e12ef

21 files changed

+832
-1066
lines changed

FANUC/README_FANUC.md

Lines changed: 55 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ This document describes the FANUC client implementation for Roboception's Generi
66

77
The FANUC GRI client provides a straightforward way to integrate Roboception vision capabilities into your FANUC robot programs. Instead of complex register manipulation, you can access vision functions through simple CALL statements and status checks.
88

9+
**This integration uses the GRI protocol version defined by Roboception firmware 25.10 and later**
10+
911
### Key Features
1012

1113
- **Vision Job Execution**: Trigger synchronous and asynchronous vision jobs
@@ -40,6 +42,7 @@ Load the following files onto your FANUC robot controller:
4042

4143
**TP Programs** (load .ls files):
4244
- `GRI_OPEN_COMMUNICATION.LS` - System initialization
45+
- `GRI_SETFRAMES.LS` - Utility to standardize frames (sets `UF:0` world and `UT:0` flange)
4346
- `GRI_TRIGGER_JOB_SYNC.LS` - Execute vision job (blocking)
4447
- `GRI_TRIGGER_JOB_ASYNC.LS` - Execute vision job (non-blocking)
4548
- `GRI_GET_JOB_STATUS.LS` - Check async job status
@@ -100,7 +103,7 @@ Optional example programs (load .ls files):
100103
- `R[143]` `gri param 1`: slot id (HEC_SET_POSE)
101104
- `R[144]` `gri param 2`: reserved
102105

103-
**Status Registers (KAREL → TP) - New uniform mapping:**
106+
**Status Registers (KAREL → TP) - Uniform mapping:**
104107
- `R[149]` `gri comm status`: handshake; 0 ready, -1 stopped
105108
- `R[150]` `gri error code`: signed GRI status (<0 error, 0 ok, >0 warning)
106109
- `R[151]` `module return`: `data_1` (module/vendor code; can be <0/0/>0)
@@ -115,19 +118,32 @@ Optional example programs (load .ls files):
115118
- Notes on `R[150]/R[151]`
116119
- Pose-returning calls (`GRI_TRIGGER_JOB_SYNC`, `GRI_GET_NEXT_GRASP`, `GRI_GET_RELATED_GRASP`):
117120
- On success: `R[150] = 0`; pose in `PR[53]`; counts in `R[152]/R[153]`
118-
- No poses: `R[150] = 1`
119-
- Errors: `R[150] < 0` (e.g., `-4` API_RESPONSE_ERROR; raw cause may be in `R[151]`)
120-
- Confirmation calls (`GRI_TRIGGER_JOB_ASYNC`, `GRI_HEC_*`): `R[150] = 0` on success; otherwise `<0` error, with detail possibly in `R[151]`
121+
- No poses: `R[150] = 1` (NO_POSES_FOUND)
122+
- Errors: `R[150] < 0` (e.g., `-4` API_RESPONSE_ERROR; raw in `R[151]`)
123+
- Confirmation calls (`GRI_TRIGGER_JOB_ASYNC`, `GRI_HEC_*`): `R[150] = 0` on success; on failure `R[150] < 0` with module/vendor detail in `R[151]`
121124
- Status call (`GRI_GET_JOB_STATUS`): `R[150] = 0` on success; `R[152] = 1|2|3|4` → INACTIVE|RUNNING|DONE|FAILED
122125

123126

124127

128+
### Frame Convention
129+
130+
- KAREL always exchanges poses on the wire as world/base → flange (mm/deg).
131+
- All LS examples standardize frames at program start by calling:
132+
- `CALL GRI_SETFRAMES` (sets `UF:0` world and `UT:0` flange)
133+
- Tool 0 must be the identity (flange). If Tool 0 was modified, correct it or transform poses accordingly.
134+
135+
Changing the convention (advanced):
136+
- If you must use a different UF/UT, update `FANUC/TP/GRI_SETFRAMES.LS` accordingly, or manage frames yourself and remove the helper call from your program.
137+
- Alternatively, keep world→flange in `PR[53]` and transform it to your chosen UF before moving.
138+
125139
### Simple Vision-Guided Picking
126140

127141
```fanuc
128142
/PROG VISION_PICK_EXAMPLE
129143
/MN
130-
! Start vision system
144+
! Standardize frames: UF:0 (world), UT:0 (flange)
145+
CALL GRI_SETFRAMES ;
146+
! Start GRI communication
131147
CALL GRI_OPEN_COMMUNICATION ;
132148
133149
! Execute vision job
@@ -139,7 +155,9 @@ Optional example programs (load .ls files):
139155
JMP LBL[cleanup] ;
140156
141157
LBL[pick_object] ;
142-
! Move to detected pose (in PR[53])
158+
! Move to detected pose (in PR[53]) using world/base and flange
159+
UFRAME_NUM=0 ;
160+
UTOOL_NUM=0 ;
143161
L PR[53:gri pose] 200mm/sec FINE ;
144162
! Execute gripper close
145163
DO[1:Gripper]=ON ;
@@ -154,7 +172,6 @@ Optional example programs (load .ls files):
154172
```fanuc
155173
/PROG PROCESS_MULTIPLE_OBJECTS
156174
/MN
157-
CALL GRI_OPEN_COMMUNICATION ;
158175
159176
! Process objects until none remain
160177
LBL[next_object] ;
@@ -183,7 +200,7 @@ Optional example programs (load .ls files):
183200
### Asynchronous Processing
184201

185202
```fanuc
186-
! Start vision job in background
203+
! Start background job
187204
CALL GRI_TRIGGER_JOB_ASYNC(1) ;
188205
IF R[150:gri error code]<>0, JMP LBL[async_failed] ;
189206
@@ -193,13 +210,15 @@ CALL OTHER_ROBOT_OPERATIONS ;
193210
! Poll job status until done
194211
LBL[poll] ;
195212
CALL GRI_GET_JOB_STATUS(1) ;
196-
IF R[152:gri data 1]=2, JMP LBL[poll] ; -- RUNNING
197-
IF R[152:gri data 1]<>3, JMP LBL[async_failed] ; -- not DONE
213+
IF R[152:data 2]=2, JMP LBL[poll] ; -- RUNNING
214+
IF R[152:data 2]<>3, JMP LBL[async_failed] ; -- not DONE
198215
199216
! Job is DONE → fetch results
200217
LBL[next] ;
201218
CALL GRI_GET_NEXT_GRASP(1) ;
202219
IF R[150:gri error code]<>0, JMP LBL[finished] ;
220+
UFRAME_NUM=0 ;
221+
UTOOL_NUM=0 ;
203222
L PR[53:gri pose] 150mm/sec FINE ;
204223
IF R[152:gri data 1]>0, JMP LBL[next] ;
205224
LBL[finished] ;
@@ -212,7 +231,13 @@ LBL[after] ;
212231

213232
## Status Codes
214233

215-
R[150] carries signed status: `<0` error, `0` ok, `>0` warning. For pose-returning calls, success (`0`) means a pose is available in `PR[53]`. For job status (`GRI_GET_JOB_STATUS`), `R[150]=0` on success and the job state is in `R[152]` (1..4).
234+
`R[150]` semantics are uniform across functions:
235+
236+
- `R[150] = 0`: success
237+
- `R[150] < 0`: error (see `R[151]` for module/vendor detail)
238+
- `R[150] > 0`: warning/non-fatal (e.g., `1` = NO_POSES_FOUND)
239+
240+
For job status (`GRI_GET_JOB_STATUS`): `R[150] = 0` on success and `R[152] ∈ {1,2,3,4}` → INACTIVE|RUNNING|DONE|FAILED.
216241

217242
## Hand-Eye Calibration
218243

@@ -296,7 +321,7 @@ CALL GRI_QUIT ;
296321

297322
### No Objects Detected
298323

299-
- If the pose-returning call does not find a pose, `R[150]` will be `23` and `R[151] = 13` (no poses found). Check scene and job configuration.
324+
- If the pose-returning call does not find a pose, `R[150]` will be `1` (NO_POSES_FOUND). Check scene and job configuration.
300325
- Check scene lighting and part visibility
301326
- Verify vision job configuration on vision system
302327
- Confirm camera positioning and focus
@@ -310,12 +335,6 @@ The FANUC GRI client uses a layered architecture:
310335
- **Background Module**: Compiled KAREL `.pc` (`gri_comm_background.pc`) handling socket/protocol and register bridging
311336
- **TCP Socket**: Binary protocol communication with vision system
312337

313-
### Pose Frame Behavior
314-
315-
- The background module reads the current robot pose for protocol exchange as base (UF[0]) to flange (UT[0]).
316-
- Implementation detail: it temporarily saves and sets `$MNUFRAMENUM[1]`/`$MNUTOOLNUM[1]` to `0` only for the `CURPOS(0,0)` call, then restores the previous values immediately. This guarantees a deterministic world→flange pose independent of the active user/tool frames.
317-
- Future versions may replace this with a math-based conversion that avoids any temporary frame changes.
318-
319338
## Deployment Checklist
320339

321340
- [ ] `gri_comm_background.pc` loaded
@@ -353,14 +372,25 @@ Integrate GRI error handling with your existing error management:
353372

354373
```fanuc
355374
CALL GRI_TRIGGER_JOB_SYNC(1) ;
356-
SELECT R[150:gri error code] OF
357-
CASE(20):
358-
CALL PROCESS_OBJECT ;
359-
CASE(23):
360-
CALL HANDLE_VISION_ERROR ;
361-
ENDSELECT ;
375+
IF R[150:gri error code]=0, CALL PROCESS_OBJECT ;
376+
IF R[150:gri error code]<0, CALL HANDLE_VISION_ERROR ;
377+
IF R[150:gri error code]>0, CALL HANDLE_NO_POSE_OR_WARNING ;
362378
```
363379

364-
Note: In this implementation, a "no object" situation is signaled as `R[150]=23` with `R[151]=13` (no poses found). Consider branching on `R[151]` to distinguish causes of errors if needed.
380+
Note: A "no object" situation is signaled as `R[150]=1` (NO_POSES_FOUND). Consider branching on `R[151]` for module/vendor specific details when needed.
365381

366382
The system provides consistent, reliable communication with Roboception vision systems while maintaining the familiar FANUC programming environment.
383+
384+
## Protocol Notes (Fixed by Server)
385+
386+
- Protocol: Version 1 (V1)
387+
- Header: 8 bytes (ASCII "GRI\0", version, length, pose_format, action)
388+
- Lengths: request 54 bytes, response 80 bytes
389+
- Job ID: uint16 (LE); Error code: int16 with sign semantics
390+
- Pose format: EULER_ZYX_B_DEG (26) fixed for FANUC
391+
- rot_1 = R (roll/X), rot_2 = P (pitch/Y), rot_3 = W (yaw/Z)
392+
- Mapped to XYZWPR in `PR[53]` as R→R, P→P, W→W
393+
- Scaling: All pose components are int32 scaled by 1e6
394+
- Job status: returned in `data_2` (mapped to `R[152]`)
395+
396+
See `karel/gri_common_const.kl` for the exact packing/unpacking.

FANUC/TP/GRI_EXAMPLE_ASYNC.LS

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/PROG GRI_EXAMPLE_ASYNC Macro
2+
/ATTR
3+
OWNER = MNEDITOR;
4+
COMMENT = "Async job example";
5+
PROG_SIZE = 1400;
6+
CREATE = DATE 25-01-07 TIME 18:00:00;
7+
MODIFIED = DATE 25-01-07 TIME 18:00:00;
8+
FILE_NAME = ;
9+
VERSION = 0;
10+
LINE_COUNT = 34;
11+
MEMORY_SIZE = 2000;
12+
PROTECT = READ_WRITE;
13+
TCD: STACK_SIZE = 0,
14+
TASK_PRIORITY = 50,
15+
TIME_SLICE = 0,
16+
BUSY_LAMP_OFF = 0,
17+
ABORT_REQUEST = 0,
18+
PAUSE_REQUEST = 0;
19+
DEFAULT_GROUP = 1,*,*,*,*;
20+
CONTROL_CODE = 00000000 00000000;
21+
/MN
22+
1: !GRI Async Example - Trigger, poll status, fetch pose ;
23+
2: MESSAGE[Starting GRI Async Example] ;
24+
3: ! Standardize frames: UF:0 (world), UT:0 (flange)
25+
4: CALL GRI_SETFRAMES ;
26+
5: !--- Open Communication --- ;
27+
6: CALL GRI_OPEN_COMMUNICATION ;
28+
7: MESSAGE[GRI Communication Started] ;
29+
8: ! Trigger async job with ID 1 ;
30+
9: CALL GRI_TRIGGER_JOB_ASYNC(1) ;
31+
10: IF R[150:gri error code]=0,JMP LBL[10] ;
32+
11: MESSAGE[Async start failed] ;
33+
12: JMP LBL[90] ;
34+
13: LBL[10] ;
35+
14: MESSAGE[Async started OK] ;
36+
15: ! Poll job status until DONE ;
37+
16: LBL[20] ;
38+
17: CALL GRI_GET_JOB_STATUS(1) ;
39+
18: IF R[150:gri error code]<>0,JMP LBL[90] ;
40+
19: IF R[152:gri data 2]=2,JMP LBL[20] ;
41+
20: IF R[152:gri data 2]=4,JMP LBL[90] ;
42+
21: IF R[152:gri data 2]<>3,JMP LBL[20] ;
43+
22: MESSAGE[Job DONE] ;
44+
23: ! Fetch next pose ;
45+
24: CALL GRI_GET_NEXT_GRASP(1) ;
46+
25: IF R[150:gri error code]=0,JMP LBL[30] ;
47+
26: MESSAGE[No pose available] ;
48+
27: JMP LBL[90] ;
49+
28: LBL[30] ;
50+
29: MESSAGE[Pose received - PR[53]] ;
51+
30: LBL[90] ;
52+
31: CALL GRI_QUIT ;
53+
32: MESSAGE[GRI Async Example Failed] ;
54+
33: JMP LBL[100] ;
55+
34: LBL[100] ;
56+
/POS
57+
/END
58+

FANUC/TP/GRI_EXAMPLE_HEC.LS

Lines changed: 60 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ CREATE = DATE 25-07-10 TIME 18:05:34;
77
MODIFIED = DATE 25-07-10 TIME 18:05:56;
88
FILE_NAME = AAAGRIHE;
99
VERSION = 0;
10-
LINE_COUNT = 74;
10+
LINE_COUNT = 62;
1111
MEMORY_SIZE = 3036;
1212
PROTECT = READ_WRITE;
1313
TCD: STACK_SIZE = 0,
@@ -20,77 +20,65 @@ DEFAULT_GROUP = 1,*,*,*,*;
2020
CONTROL_CODE = 00000000 00000000;
2121
/MN
2222
1: !================================ ;
23-
2: ! GRI HAND-EYE CALIBRATION EXAMPL ;
24-
3: ! 8-Pose Calibration for Maximum ;
25-
4: ! Uses direct positions with touc ;
26-
5: !================================ ;
27-
6: ;
28-
7: !--- INSTRUCTIONS FOR ROBOT PROGR ;
29-
8: MESSAGE[HEC 8-Pose Calibration] ;
30-
9: MESSAGE[Use TOUCHUP on P[1] to P[8]] ;
31-
10: PAUSE ;
32-
11: ;
33-
12: !--- START CALIBRATION PROCESS -- ;
34-
13: MESSAGE[Starting HEC Calibration] ;
35-
14: ;
36-
15: !--- Open Communication --- ;
37-
16: CALL GRI_OPEN_COMMUNICATION ;
38-
17: MESSAGE[Communication ready] ;
39-
18: ;
40-
19: !--- Initialize HEC Pipeline 0 -- ;
41-
20: MESSAGE[Init HEC Pipeline 0] ;
42-
21: CALL GRI_HEC_INIT(0) ;
43-
22: WAIT R[141:gri_command]=(-1) ;
44-
23: WAIT .20(sec) ;
45-
24: MESSAGE[HEC Pipeline ready] ;
46-
25: ;
47-
26: !--- CALIBRATION POSES 1-8 --- ;
48-
27: MESSAGE[Move to Pose 1] ;
49-
28:J P[1] 100% FINE ;
23+
2: ! GRI HEC EXAMPLE ;
24+
3: ! 8-Pose Calibration ;
25+
4: !================================ ;
26+
5: !--- INSTRUCTIONS FOR ROBOT PROGR ;
27+
6: MESSAGE[HEC 8-Pose Calibration] ;
28+
7: MESSAGE[Use TOUCHUP on P[1] to P[8]] ;
29+
8: PAUSE ;
30+
9: !--- START CALIBRATION PROCESS -- ;
31+
10: MESSAGE[Starting HEC Calibration] ;
32+
11: ! Standardize frames: UF:0 (world), UT:0 (flange)
33+
12: CALL GRI_SETFRAMES ;
34+
13: !--- Open Communication --- ;
35+
14: CALL GRI_OPEN_COMMUNICATION ;
36+
15: MESSAGE[Communication ready] ;
37+
16: !--- Initialize HEC Pipeline 0 -- ;
38+
17: MESSAGE[Init HEC Pipeline 0] ;
39+
18: CALL GRI_HEC_INIT(0) ;
40+
19: WAIT R[141:gri_command]=(-1) ;
41+
20: WAIT .20(sec) ;
42+
21: MESSAGE[HEC Pipeline ready] ;
43+
22: !--- CALIBRATION POSES 1-8 --- ;
44+
23: MESSAGE[Move to Pose 1] ;
45+
24:J P[1] 100% FINE ;
46+
25: WAIT 2.00(sec) ;
47+
26: CALL GRI_HEC_SET_POSE(0,1) ;
48+
27: MESSAGE[Move to Pose 2] ;
49+
28:J P[2] 100% FINE ;
5050
29: WAIT 2.00(sec) ;
51-
30: CALL GRI_HEC_SET_POSE(0,1) ;
52-
31: ;
53-
32: MESSAGE[Move to Pose 2] ;
54-
33:J P[2] 100% FINE ;
55-
34: WAIT 2.00(sec) ;
56-
35: CALL GRI_HEC_SET_POSE(0,2) ;
57-
36: ;
58-
37: MESSAGE[Move to Pose 3] ;
59-
38:J P[3] 100% FINE ;
60-
39: WAIT 2.00(sec) ;
61-
40: CALL GRI_HEC_SET_POSE(0,3) ;
62-
41: ;
63-
42: MESSAGE[Move to Pose 4] ;
64-
43:J P[4] 100% FINE ;
65-
44: WAIT 2.00(sec) ;
66-
45: CALL GRI_HEC_SET_POSE(0,4) ;
67-
46: ;
68-
47: MESSAGE[Move to Pose 5] ;
69-
48:J P[5] 100% FINE ;
51+
30: CALL GRI_HEC_SET_POSE(0,2) ;
52+
31: MESSAGE[Move to Pose 3] ;
53+
32:J P[3] 100% FINE ;
54+
33: WAIT 2.00(sec) ;
55+
34: CALL GRI_HEC_SET_POSE(0,3) ;
56+
35: MESSAGE[Move to Pose 4] ;
57+
36:J P[4] 100% FINE ;
58+
37: WAIT 2.00(sec) ;
59+
38: CALL GRI_HEC_SET_POSE(0,4) ;
60+
39: MESSAGE[Move to Pose 5] ;
61+
40:J P[5] 100% FINE ;
62+
41: WAIT 2.00(sec) ;
63+
42: CALL GRI_HEC_SET_POSE(0,5) ;
64+
43: MESSAGE[Move to Pose 6] ;
65+
44:J P[6] 100% FINE ;
66+
45: WAIT 2.00(sec) ;
67+
46: CALL GRI_HEC_SET_POSE(0,6) ;
68+
47: MESSAGE[Move to Pose 7] ;
69+
48:J P[7] 100% FINE ;
7070
49: WAIT 2.00(sec) ;
71-
50: CALL GRI_HEC_SET_POSE(0,5) ;
72-
51: ;
73-
52: MESSAGE[Move to Pose 6] ;
74-
53:J P[6] 100% FINE ;
75-
54: WAIT 2.00(sec) ;
76-
55: CALL GRI_HEC_SET_POSE(0,6) ;
77-
56: ;
78-
57: MESSAGE[Move to Pose 7] ;
79-
58:J P[7] 100% FINE ;
80-
59: WAIT 2.00(sec) ;
81-
60: CALL GRI_HEC_SET_POSE(0,7) ;
82-
61: ;
83-
62: MESSAGE[Move to Pose 8] ;
84-
63:J P[8] 100% FINE ;
85-
64: WAIT 2.00(sec) ;
86-
65: CALL GRI_HEC_SET_POSE(0,8) ;
87-
66: ;
88-
67: !--- PERFORM CALIBRATION --- ;
89-
68: MESSAGE[All poses set] ;
90-
69: MESSAGE[Calibrating...] ;
91-
70: CALL GRI_HEC_CALIBRATE(0) ;
92-
71: MESSAGE[HEC Complete] ;
93-
72: LBL[99] ;
94-
73: !--- CLEANUP --- ;
95-
74: CALL GRI_QUIT ;
71+
50: CALL GRI_HEC_SET_POSE(0,7) ;
72+
51: MESSAGE[Move to Pose 8] ;
73+
52:J P[8] 100% FINE ;
74+
53: WAIT 2.00(sec) ;
75+
54: CALL GRI_HEC_SET_POSE(0,8) ;
76+
55: !--- PERFORM CALIBRATION --- ;
77+
56: MESSAGE[All poses set] ;
78+
57: MESSAGE[Calibrating...] ;
79+
58: CALL GRI_HEC_CALIBRATE(0) ;
80+
59: MESSAGE[HEC Complete] ;
81+
60: LBL[99] ;
82+
61: !--- CLEANUP --- ;
83+
62: CALL GRI_QUIT ;
9684
/END

0 commit comments

Comments
 (0)