3. KAREL程序结构与语法基础
KAREL 是 FANUC 机器人控制器上用于编写自定义逻辑、通信协议、坐标运算和外围设备控制的强类型语言。它的程序文件不是“想到哪写到哪”的脚本,而是有固定骨架的编译单元。理解这个骨架,是后续写运动指令、处理 I/O、做离线计算的前提。一个 KAREL 源文件通常由程序头、声明区、执行体三大部分组成,常量与变量定义、数据类型选择、注释与命名规范则贯穿其中。
程序头:告诉控制器“这是什么程序”
程序头位于文件最上方,用 PROGRAM 关键字开始,后跟程序名,并以 END 结束整个程序。程序名必须与文件名一致(不区分大小写,但建议统一大写),且不能与系统保留字冲突。例如一个用于抓取工件并计算偏移量的程序,可以命名为 PICK_OFFSET:
PROGRAM PICK_OFFSET
-- 程序头:声明程序名称,必须与文件名 PICK_OFFSET.KL 一致
程序头之后、第一个可执行语句之前,是声明区。KAREL 要求所有常量、变量、类型、例程在使用前先声明,这与 C 语言类似,但语法更接近 Pascal。声明区不是可有可无的“注释区”,它决定了编译器如何分配内存、检查类型,也决定了程序能否通过编译。
声明区:常量、变量与类型定义
常量用 CONST 段声明,语法为 名称 = 值,值必须是编译期可确定的字面量或常量表达式。常量一旦定义,执行体中不能修改。例如定义安全高度和抓取偏移:
CONST
SAFE_Z = 350.0 -- 安全高度,单位 mm
GRIP_OFFSET = 12.5 -- 夹爪中心到法兰的偏移,单位 mm
MAX_RETRY = 3 -- 最大重试次数
变量用 VAR 段声明,语法为 名称 : 类型,可同时声明多个同类型变量。KAREL 的基本数据类型包括:
INTEGER:32 位有符号整数,用于计数、索引、状态码;REAL:浮点数,用于坐标、速度、偏移量等连续量;BOOLEAN:TRUE或FALSE,用于条件判断和标志位;STRING[n]:定长字符串,n 为最大字符数,用于名称、报文、日志;XYZWPRELT:位置类型,包含 X、Y、Z、W、P、R 六个分量,是机器人运动的核心数据类型;JOINTPOS:关节位置类型,包含各轴角度,用于关节运动;POSITION:笛卡尔位置,通常与XYZWPRELT配合使用。
例如声明一组变量:
VAR
retry_count : INTEGER
current_pos : XYZWPRELT
target_pos : XYZWPRELT
is_gripped : BOOLEAN
msg_buf : STRING[80]
声明区还可以用 TYPE 定义自定义类型,例如把一组相关参数打包成结构体,便于传递和复用。KAREL 不支持任意嵌套的复杂结构,但支持数组和记录类型,足以表达大多数工程数据。
执行体:从 BEGIN 到 END 的语句序列
执行体以 BEGIN 开始,以 END 结束,中间是顺序执行的语句。KAREL 的语句以换行或分号分隔,赋值用 :=,条件用 IF...THEN...ELSE...ENDIF,循环用 FOR...ENDFOR 或 WHILE...ENDWHILE。下面是一个完整的、可编译的示例程序,它读取当前位置,计算带偏移的目标位置,并模拟抓取重试逻辑:
PROGRAM PICK_OFFSET
CONST
SAFE_Z = 350.0
GRIP_OFFSET = 12.5
MAX_RETRY = 3
VAR
retry_count : INTEGER
current_pos : XYZWPRELT
target_pos : XYZWPRELT
is_gripped : BOOLEAN
BEGIN
retry_count := 0
is_gripped := FALSE
-- 读取当前笛卡尔位置
current_pos := CURPOS(0, 0)
-- 在 Z 方向抬升到安全高度,并叠加夹爪偏移
target_pos := current_pos
target_pos.z := SAFE_Z + GRIP_OFFSET
-- 重试循环:最多尝试 MAX_RETRY 次
WHILE (retry_count < MAX_RETRY) AND (NOT is_gripped) DO
retry_count := retry_count + 1
-- 此处可插入实际抓取指令与传感器判断
IF retry_count >= 2 THEN
is_gripped := TRUE
ENDIF
ENDWHILE
-- 输出结果到日志
IF is_gripped THEN
WRITE('Grip success after ', retry_count, ' attempts', CR)
ELSE
WRITE('Grip failed', CR)
ENDIF
END PICK_OFFSET
这段代码展示了 KAREL 的典型结构:常量区给出不可变的工程参数,变量区声明运行期状态,执行体完成“读取—计算—判断—输出”的闭环。注意 CURPOS(0,0) 返回的是当前笛卡尔位置,参数含义与坐标系选择有关,实际使用时需根据控制器配置确认。
注释与代码规范
KAREL 使用 -- 作为行注释,从 -- 到行尾的内容都会被编译器忽略。注释应说明“为什么这样做”,而不是重复代码字面意思。例如 target_pos.z := SAFE_Z + GRIP_OFFSET 上方应注释“抬升到安全高度并补偿夹爪长度”,而不是“给 z 赋值”。
代码规范方面,建议遵循以下约定:程序名和常量名用大写加下划线,变量名用小写加下划线;每行只写一条语句;缩进统一用两个空格;BEGIN 与 END 对齐;复杂表达式拆成多行并加括号明确优先级。这些规范不会改变程序功能,但会显著降低后续排障和交接成本。
把上述结构记牢后,写 KAREL 程序时就不会出现“变量未声明”“类型不匹配”“END 缺失”这类低级编译错误。实际工程中,建议先在纸面或编辑器中把程序头、常量、变量、执行体四块列清楚,再逐段填充逻辑,这样比直接敲代码再反复编译要高效得多。