4. 数据类型与变量工程应用

在RAPID中,数据类型决定了变量能保存什么、能参与哪些运算、能传给哪些指令。工程上最常见的错误不是“不会写指令”,而是把目标点、关节角、数值和字符串混用,导致程序能通过语法检查却在运行时报警或产生错误动作。本节围绕num、bool、string、robtarget、jointtarget五类核心类型,说明它们的定义方式、作用域选择以及命名规范,并给出可直接套用的工程写法。

一、五类核心数据类型的定义与适用对象

num用于保存实数,可正可负,常用于计数器、速度倍率、偏移量、阈值判断。例如 VAR num nCount := 0; 定义了一个初值为0的可变数值。num支持加减乘除和比较运算,但不能直接与robtarget相加,必须通过Offs等函数生成新目标。

bool只有TRUE和FALSE两个取值,用于标志位、条件判断、状态记忆。例如 VAR bool bGripOK := FALSE; 表示夹爪状态未确认。bool不能参与算术运算,工程中常与IF、WHILE配合,作为流程分支的开关。

string保存字符序列,用于显示信息、拼接日志、传递工位名称。例如 VAR string sMsg := "Station A";。string可用+拼接,也可用NumToStr把数值转成字符串后拼接,但字符串不能直接参与运动指令。

robtarget描述TCP在工件坐标系中的位姿,包含trans(x、y、z)、rot(四元数q1~q4)、robconf(轴配置)和extax(外部轴)四部分。它回答的是“工具要到达哪里、以什么姿态、用哪组轴配置”。例如:

CONST robtarget pPick :=
  [[320.5, -150.0, 480.0],
   [0.7071, 0, 0.7071, 0],
   [0, 0, 0, 0],
   [9E9, 9E9, 9E9, 9E9, 9E9, 9E9]];

其中robconf的四个值分别对应cfx、cf1、cf4、cf6,用于区分同一笛卡尔位姿下的不同关节解;extax为9E9表示该轴未使用。

jointtarget描述各关节角度,包含robax(6个机器人轴角度)和extax(外部轴角度)。它回答的是“每个轴转到多少度”,常用于回原点、避奇异、恢复已知姿态。例如:

CONST jointtarget jHome :=
  [[0, 0, 0, 0, 30, 0],
   [9E9, 9E9, 9E9, 9E9, 9E9, 9E9]];

robtarget与jointtarget的关键区别在于:前者面向任务空间,便于描述工件上的位置;后者面向关节空间,便于描述确定的机械姿态。MoveJ既接受robtarget也接受jointtarget,而MoveL通常使用robtarget,因为直线运动需要笛卡尔位姿约束。

RAPID 核心数据类型与作用域关系图 数据类型(决定“存什么”) num 实数 计数/倍率/偏移 支持算术运算 bool TRUE / FALSE 标志/条件 不参与算术 string 字符序列 显示/日志/拼接 不可直接运动 robtarget trans+rot robconf+extax 任务空间位姿 jointtarget robax+extax 6轴角度 关节空间姿态 作用域(决定“谁能访问”) VAR(局部变量) 仅当前模块可见 掉电不保持 适合临时计数、中间量 VAR num nTemp := 0; PERS(全局可保持) 跨模块可见 掉电保持当前值 适合产量、校准值 PERS num nTotal := 0; CONST(常量) 定义后不可修改 编译期确定 适合安全点、工具坐标 CONST robtarget pSafe := ...

二、作用域选择:VAR、PERS、CONST的工程取舍

RAPID的变量作用域由声明关键字决定。VAR声明的变量只在当前模块内有效,掉电后不保持,适合循环计数、临时偏移、中间计算结果。PERS声明的变量可跨模块访问,且掉电后保持当前值,适合累计产量、校准偏移、上次运行状态。CONST声明的常量在定义后不可修改,适合安全点、工具坐标、固定阈值。

选择原则可以概括为三句话:只在本模块用且不需要记忆的,用VAR;需要跨模块共享或掉电保持的,用PERS;一旦确定就不再改变的,用CONST。工程中常见的问题是“把该用CONST的安全点写成VAR”,结果程序运行中被意外改写,造成碰撞风险。安全点、工具坐标、工件坐标这类基准数据应优先使用CONST。

此外,PERS变量虽然方便,但不宜滥用。过多PERS会让程序状态难以追踪,建议只保留真正需要保持的少量变量,并在模块头部集中声明,便于维护。

三、命名规范:让程序可读、可查、可维护

RAPID标识符区分大小写,长度有限制,且不能与关键字重名。工程命名建议遵循“前缀+含义”的方式,使类型和用途一眼可辨:

  • num类型以n开头,如nCount、nSpeed、nOffset;
  • bool类型以b开头,如bGripOK、bHomeDone;
  • string类型以s开头,如sMsg、sStation;
  • robtarget类型以p开头,如pPick、pPlace、pSafe;
  • jointtarget类型以j开头,如jHome、jWait。

命名还应避免拼音和缩写混用,例如用pPick而不是pQuJian。对于同一工位的多个点,可用pPick_A、pPick_B区分,但不要用p1、p2这类无意义编号。模块名、例行程序名同样建议采用“动作+对象”的结构,如PickPart、PlacePart,便于在示教器中快速定位。

命名时先想清楚“这个变量属于哪一类、用在哪里”,再决定前缀和单词。一个可读的变量名,比一段注释更有长期价值。

四、工程示例:一个抓取工位的变量声明

下面给出一个抓取工位的变量声明片段,覆盖五类类型和三种作用域,可直接作为模板参考。示例参数为教学假设值,实际使用时应根据现场标定结果替换。

MODULE PickStation

  ! 常量:安全点与工具坐标,定义后不可修改
  CONST robtarget pSafe :=
    [[400, 0, 600], [1, 0, 0, 0], [0, 0, 0, 0], [9E9, 9E9, 9E9, 9E9, 9E9, 9E9]];
  CONST jointtarget jHome :=
    [[0, 0, 0, 0, 30, 0], [9E9, 9E9, 9E9, 9E9, 9E9, 9E9]];

  ! 全局保持:累计产量与校准偏移
  PERS num nTotal := 0;
  PERS num nZOffset := 0;

  ! 局部变量:本次循环使用
  VAR num nCount := 0;
  VAR bool bGripOK := FALSE;
  VAR string sMsg := "";

  ! 目标点:抓取与放置
  VAR robtarget pPick :=
    [[320.5, -150.0, 480.0], [0.7071, 0, 0.7071, 0], [0, 0, 0, 0], [9E9, 9E9, 9E9, 9E9, 9E9, 9E9]];
  VAR robtarget pPlace :=
    [[520.0, 180.0, 460.0], [0.7071, 0, 0.7071, 0], [0, 0, 0, 0], [9E9, 9E9, 9E9, 9E9, 9E9, 9E9]];

ENDMODULE

在这个示例中,pSafe和jHome用CONST,保证安全基准不被改写;nTotal和nZOffset用PERS,掉电后仍能记住产量和校准值;nCount、bGripOK、sMsg用VAR,只在本次循环内有效;pPick和pPlace用VAR,因为它们在调试阶段可能需要重新示教。这样的划分既满足功能,又降低了误改风险。

五、常见错误与检查要点

第一类错误是类型混用,例如把num直接赋给robtarget,或把string传给MoveL。RAPID会在编译期报错,但初学者容易忽略错误提示。第二类错误是作用域误用,例如在模块A中用VAR声明,却在模块B中引用,导致“未定义”错误。第三类错误是命名冲突,例如变量名与关键字同名,或同一模块内两个变量仅大小写不同。

检查时可按以下顺序:先看声明关键字是否匹配用途,再看类型是否与指令要求一致,最后看命名是否唯一且可读。对于robtarget,还要确认robconf是否与当前姿态匹配,否则可能出现“目标可达但轴配置错误”的报警。对于jointtarget,要确认各轴角度在软限位范围内,避免回原点时超程。

修改CONST定义后必须重新编译并下载,否则机器人仍使用旧值。PERS变量在程序停止后仍保持,若需要复位,应在初始化例行程序中显式赋值。

掌握这五类数据类型、三种作用域和一套命名规范,是后续编写运动指令、逻辑判断和模块化程序的基础。实际工程中,建议在模块头部集中声明所有变量,按CONST、PERS、VAR的顺序排列,并为每个变量写一行简短注释,这样即使几个月后回看程序,也能快速理解每个变量的用途和边界。