一、核心本质
1. 全称与定义
- PR = Position Register(位置寄存器)
- 本质 :机器人控制系统中预定义的结构化复合变量 (类比C++的
struct),专门存储机器人TCP(末端执行器)的空间位置+姿态数据。 - 核心定位 :区别于静态位置点P (固化坐标,不可运算)、数值寄存器R (单精度浮点数,单值存储),PR是动态、可运算、可读写的核心位置单元,是机器人柔性运动控制的基础。
2. 核心特性
- 复合结构:不是单变量,是多字段打包的结构体;
- 双格式存储:支持直角坐标 、关节坐标两种核心格式;
- 带坐标系属性:绑定用户坐标系/工具坐标系,不是纯绝对坐标;
- 可运算:支持矢量偏移、坐标变换、姿态修正;
- 标准化:系统级全局变量,全程序共享,断电可保持(可配置)。
二、核心数据结构
PR的数据结构对应C++开发中的数据解析、协议通信、内存读写 。
FANUC PR寄存器有两种标准存储格式,互斥使用:
格式1:直角坐标型(Cartesian PR,90%场景使用)
存储机器人TCP在空间中的位置+姿态,对应C++结构体定义:
cpp
// 模拟FANUC PR寄存器 直角坐标格式 内存结构
struct CartesianPR {
// 1. 三维位置 (单位:mm)
float X; // X轴坐标
float Y; // Y轴坐标
float Z; // Z轴坐标
// 2. 三维姿态 (欧拉角,单位:deg)
float W; // 绕X轴旋转 (Roll)
float P; // 绕Y轴旋转 (Pitch)
float R; // 绕Z轴旋转 (Yaw)
// 3. 坐标系配置
uint8_t userFrame; // 用户坐标系编号 (0=世界坐标系, 1~10自定义)
uint8_t toolFrame; // 工具坐标系编号 (0=默认工具, 1~10自定义)
// 4. 姿态配置位 (CONFIG,决定机器人腕部姿态/前后手)
uint32_t config;
// 5. 有效标志位 (1=已赋值有效, 0=空寄存器,运动时会报警)
bool valid;
};
格式2:关节坐标型(Joint PR,特殊场景)
存储机器人各关节轴的旋转角度,适用于避免奇异点、关节运动,对应C++结构体:
cpp
// 模拟FANUC PR寄存器 关节坐标格式
struct JointPR {
// 6轴机器人关节角度 (单位:deg),7/8轴扩展轴追加即可
float J1;
float J2;
float J3;
float J4;
float J5;
float J6;
uint32_t config; // 关节配置位
bool valid; // 有效标志
};
基础规格
- 标准数量:
PR[1] ~ PR[100](可扩展至200+); - 内存大小:单个PR固定占用64字节(控制系统标准内存布局);
- 数据类型:全32位浮点数/无符号整型,无字符串。
三、PR寄存器的4种赋值方式
1. 示教赋值(基础,调试用)
通过示教器手动移动机器人到目标位置,一键写入PR,仅用于调试,不用于自动化开发。
操作时需先切换至"示教模式",移动机器人TCP至目标姿态(确保无碰撞、姿态合理),在示教器"位置寄存器"界面选择对应PR编号,执行"写入当前位置"操作即可。示教赋值的核心作用是标定基准位置(如工位原点、取料点),后续自动化开发可基于该基准做偏移。
注意:示教后需校验PR的有效性(valid=true),避免因示教过程中误触导致坐标偏差;且示教的PR会继承当前示教器的UF/TF,后续修改坐标系需重新示教或做坐标变换。
2. 机器人端指令赋值(TP/KAREL语言)
机器人本体程序直接赋值,工业现场最常用,无需上位机干预,可嵌入机器人运动程序中,实现动态赋值,适配批量作业、工位切换等场景:
! 1. 赋值当前机器人位置给PR[1] (直角坐标)
L PR[1] = LPOS; ! L前缀:直角坐标模式,LPOS是机器人当前TCP的直角坐标实时值
! 赋值后PR[1]自动继承当前UF/TF和config姿态配置
! 2. 赋值当前关节角度给PR[2] (关节坐标)
J PR[2] = JPOS; ! J前缀:关节坐标模式,JPOS是机器人各关节实时角度值
! 适用于避免奇异点、关节限位场景,赋值后PR[2]为关节格式
! 3. 复制PR[1]到PR[3](同格式复制,坐标系、姿态配置同步复制)
PR[3] = PR[1];
! 4. 赋值固定直角坐标给PR[4](直接指定坐标,无需移动机器人)
PR[4] = LPOS[X:500.0, Y:300.0, Z:200.0, W:0.0, P:0.0, R:0.0];
! 5. 赋值固定关节角度给PR[5](6轴机器人,依次为J1-J6角度)
PR[5] = JPOS[J1:0.0, J2:-90.0, J3:90.0, J4:0.0, J5:0.0, J6:0.0];
补充说明:TP语言(示教器编程)适合简单赋值场景,KAREL语言(机器人高级编程)适合复杂逻辑赋值(如循环赋值、条件赋值);赋值后需用CHECK PR[i]指令校验PR有效性,避免无效PR参与运动。
3. 偏移赋值(柔性控制)
在基准位置上做矢量偏移 ,类似于C++的向量加法,无需重新示教,仅通过偏移量调整位置,大幅提升开发效率,核心用于视觉定位、上下料补偿、工件偏差修正等场景:
! 示例1:固定偏移(直接指定X/Y轴偏移,Z轴不变)
PR[5] = PR[4] + LPOS[X:100, Y:50]; ! PR[4]为基准位置,PR[5]在其基础上X+100mm、Y+50mm
! 示例2:变量偏移(用R寄存器存储偏移量,适配动态调整)
R[1] = 80.0; ! R[1]存储X轴偏移量
R[2] = 30.0; ! R[2]存储Y轴偏移量
PR[6] = PR[4] + LPOS[X:R[1], Y:R[2]]; ! 动态读取R寄存器偏移量
! 示例3:姿态偏移(调整W/P/R姿态,位置不变)
PR[7] = PR[4] + LPOS[W:5.0, R:-3.0]; ! 绕X轴转5°,绕Z轴转-3°
偏移赋值的核心是同格式偏移------直角坐标PR只能加直角坐标偏移(LPOS[ ]),关节坐标PR只能加关节角度偏移(JPOS[ ]);偏移量单位与PR一致(位置mm、姿态deg);若需多轴偏移,可同时指定多个轴(如X、Y、Z同时偏移)。
实际开发中,视觉系统计算出的偏差值(如视觉定位后的X/Y偏差),可通过C++写入R寄存器,再通过偏移赋值同步到PR,实现柔性补偿。
4. C++上位机赋值
通过机器人SDK/以太网协议(Ethernet/IP、Profinet、Socket)直接写入PR内存,无需操作机器人本体,是C++机器人开发(上位机、视觉联动、自动化控制系统)的核心赋值方式:
-
核心API(FANUC Robot Interface):
WritePositionRegister(轴号, PR编号, 结构体数据);轴号默认为0(单机器人),多机器人联动时需指定对应轴号;结构体数据需严格匹配PR的内存布局(64字节,1字节对齐),否则会导致数据错位。
-
关键注意点1:C++端需严格匹配PR的64字节内存结构 ,必须用
#pragma pack(push,1)或__attribute__((packed))强制1字节对齐,避免编译器自动插入空白字节; -
关键注意点2:处理大端/小端字节序 ------机器人控制器(如FANUC)默认大端字节序,而x86架构PC默认小端字节序,C++端需通过字节序转换函数(如
htonl、htons)将结构体数据转为大端后再写入,否则坐标数值会出现异常(如500.0f变成乱码数值); -
关键注意点3:同步赋值UF/TF------写入PR结构体时,必须同步赋值
userFrame和toolFrame,否则机器人会使用默认坐标系,导致运动偏差; -
应用场景:视觉系统(如Halcon、OpenCV)计算出工件坐标后,通过C++解析坐标数据,封装为PR结构体,调用SDK写入PR,再触发机器人运动;多工位切换时,上位机批量写入不同工位的PR数据,无需机器人端修改程序;
批量赋值API------
WritePositionRegisters(起始PR编号, 数量, 结构体数组),可一次性写入多个PR,提升开发效率;读取PR的API为ReadPositionRegister(PR编号, &结构体数据),用于校验赋值是否成功。
四、PR核心运算
PR支持矢量级运算 ,是C++矩阵/向量运算在机器人控制中的直接落地,本质是对PR存储的位置/姿态数据进行数学运算,实现柔性运动控制,仅支持同格式运算(直角↔直角,关节↔关节),不同格式运算会直接触发机器人报警:
1. 基础算术运算
核心用于简单位置调整,运算逻辑与C++向量运算完全一致:
-
加法:
PR[目标] = PR[基准] + 偏移量(位置偏移)偏移量可是LPOS/JPOS固定值、其他PR、R寄存器变量;最常用场景是"基准点+固定偏移"(如上下料时,取料点PR[1] + 放料偏移PR[2] = 放料点PR[3]);
-
减法:
PR[目标] = PR[基准] - 偏移量(位置回退)用于复位、回原点场景,如机器人运动到PR[5]后,通过
PR[6] = PR[5] - LPOS[X:100]回退100mm,避免碰撞;也可用于计算两个PR之间的偏移量(如PR[7] = PR[6] - PR[5],得到两者的位置差); -
标量乘法:
PR[目标] = PR[基准] * 标量(关节角度缩放,极少用)仅适用于关节坐标PR,标量为0~1之间的浮点数,用于关节角度微调(如
PR[8] = PR[7] * 0.8,将关节角度缩小为原来的80%);直角坐标PR不建议使用标量乘法,会导致姿态异常。
2. 坐标变换运算
本质是通过矩阵运算实现PR的坐标转换、姿态修正,对应C++中的矩阵乘法、向量旋转,是视觉联动、多坐标系适配的核心技术:
-
坐标系切换:将PR从
用户坐标系1转换到用户坐标系2;机器人端指令
PR[目标] = PR[基准] IN UF[目标坐标系号],如PR[9] = PR[8] IN UF[2],将PR[8](UF1下的坐标)转换为UF2下的坐标;C++开发中,可通过SDK调用
TransformPositionRegister接口实现,无需手动写矩阵运算;核心场景:多工位切换(同一PR适配不同UF)、工件姿态调整;注意:目标坐标系必须提前标定,否则转换会出错。
-
姿态修正:旋转PR的W/P/R姿态,适配不同工件角度;
本质是对PR的姿态向量(W/P/R)进行旋转运算,可通过"偏移赋值"(如
PR[10] = PR[9] + LPOS[W:5.0])实现简单姿态修正,也可通过机器人端ROTATE指令实现复杂姿态旋转(如绕Z轴旋转30°);C++开发中,可通过姿态矩阵运算(如欧拉角转旋转矩阵)手动修正PR的W/P/R值,再写入机器人;
常用场景:工件倾斜、焊枪姿态调整。
-
逆解运算:直角坐标PR ↔ 关节坐标PR 互转(C++运动控制库核心功能);
正解(关节PR→直角PR):通过机器人运动学正解公式,将关节角度转换为TCP直角坐标;逆解(直角PR→关节PR):通过逆解公式,将直角坐标转换为关节角度,是机器人运动控制的核心;
C++开发中,可调用机器人SDK的
InverseKinematics(逆解)、ForwardKinematics(正解)接口,也可自己实现运动学算法;避坑点:逆解可能存在多解(如机器人腕部前后手),需通过PR的
config位指定姿态,避免运动异常。
3. 运算规则
-
运算时坐标系保持不变 (基准PR用什么坐标系,结果就用什么);
例如PR[1]绑定UF1、TF1,与LPOS[X:50](默认继承当前UF/TF,需手动指定与PR[1]一致)运算后,PR[目标]仍绑定UF1、TF1;若偏移量的坐标系与基准PR不一致,会导致运算结果错误,需先通过"坐标系切换"统一坐标系。
-
无效PR(valid=false)参与运算会直接触发机器人报警;
无效PR指未赋值、赋值失败或坐标超出机器人运动范围的PR;
C++开发中,运算前需通过
GetPRValid接口校验PR有效性,若无效,需重新赋值后再运算;报警后需复位机器人,清除无效PR,重新执行运算。
-
关节PR仅支持关节运算,不能与直角PR直接运算;
若需跨格式运算,需先通过逆解/正解转换为同格式,再进行运算(如直角PR→关节PR,运算后再转回直角PR);
直接跨格式运算(如
PR[11] = PR[1] + PR[2],PR[1]直角、PR[2]关节)会触发"格式不匹配"报警。 -
运算后PR的
config位(姿态配置)会自动继承基准PR,若需修改姿态,需单独赋值config位; -
偏移量的单位必须与PR一致(位置mm、姿态deg),否则会导致坐标偏差(如将deg作为mm偏移,会出现大幅运动错误)。
五、PR的坐标系属性
PR不是纯绝对坐标 ,它自带用户坐标系 (UF)和工具坐标系 (TF)绑定,这是运动控制的核心:PR寄存器内部会永久绑定一组坐标系编号,其存储的 X/Y/Z/W/P/R 本质是相对坐标,而非机器人基坐标系下的绝对笛卡尔值。机器人在解析 PR 执行运动时,会先读取 UF/TF 编号,通过内置坐标变换矩阵计算最终关节角,这也是 PR 能适配多工位、多工装柔性作业的核心原因。
- 世界坐标系(UF=0):机器人底座为原点,出厂默认;也称为基坐标系/世界坐标,原点固定在机器人底座安装中心,Z轴垂直向上,是机器人所有坐标的绝对基准。当 PR 的 userFrame=0 时,位置数据无额外坐标变换,直接基于底座基准计算,常用于标定、调试、绝对定位场景。
- 用户坐标系:工件坐标系,适配不同工位;也叫 User Frame,是为不同工位、不同姿态工件自定义的局部坐标系。例如产线左右双工位可分别设置 UF1、UF2,同一套 PR 坐标仅切换 UF 编号即可适配,无需修改数值。PR 中存储的 UF 编号,直接决定位置数据基于哪个工件基准解析。
- 工具坐标系:末端工具中心点,适配夹具/焊枪;也叫 Tool Frame,原点定义在末端执行器工作中心点(夹爪中心、焊枪尖端等)。TF=0 为机器人默认法兰中心,切换夹具/工具只需更新 TF 编号,PR 坐标无需改动即可保证 TCP 对准工件。
同一个 PR 数值,搭配不同 UF/TF 会让机器人运动到完全不同的空间位置;同一物理位置,在不同坐标系下的 PR 数值也完全不同。PR 不会自动继承示教器当前坐标系,若未显式赋值,控制系统会使用历史残留或默认值,直接导致轨迹偏移。
C++上位机写入PR时,必须同步写入userFrame/toolFrame,否则机器人会运动到错误位置。
六、C++开发与PR的交互全流程
工程化开发逻辑,标准流程:
- 定义PR结构体:严格匹配机器人内存布局;
- 协议通信:通过TCP/IP或现场总线连接机器人;
- 数据序列化:将C++结构体转为字节流,处理字节序;
- 读写PR:调用SDK接口读取/写入PR数据;
- 校验:读取PR有效位、坐标系,验证数据合法性;
- 运动控制 :机器人执行
J PR[]/L PR[]运动指令。
极简C++伪代码(PR写入)
cpp
#include <iostream>
#include "FkRobot.h" // FANUC 官方机器人头文件
// 真实 FANUC 直角坐标 PR 结构体(与机器人内存 1:1 对齐)
#pragma pack(push, 1) //强制 C++ 结构体,按照 1 字节紧凑排列,不允许插入多余的空白字节
typedef struct {
float x; // X 坐标 mm
float y; // Y 坐标 mm
float z; // Z 坐标 mm
float w; // 绕 X 旋转 deg
float p; // 绕 Y 旋转 deg
float r; // 绕 Z 旋转 deg
unsigned char uf; // 用户坐标系号 0~10
unsigned char tf; // 工具坐标系号 0~10
unsigned int cfg; // 机器人姿态配置
bool valid; // 有效标志
} CartesianPR;
#pragma pack(pop)
int main() {
// 1. 创建机器人句柄
FkRobot robot;
FkResult ret;
// 2. 连接机器人(IP 根据实际修改)
ret = robot.Connect("192.168.1.100", 60006);
if (ret != FK_SUCCESS) {
std::cerr << "机器人连接失败" << std::endl;
return -1;
}
std::cout << "机器人连接成功" << std::endl;
// ==============================================
// 3. 真实赋值 PR[10]
// ==============================================
CartesianPR pr10;
pr10.x = 500.0f;
pr10.y = 300.0f;
pr10.z = 200.0f;
pr10.w = 0.0f;
pr10.p = 0.0f;
pr10.r = 0.0f;
pr10.uf = 1; // 用户坐标系 1
pr10.tf = 1; // 工具坐标系 1
pr10.cfg = 0; // 标准姿态配置
pr10.valid = true;
// 4. 真实 SDK 写入 PR[10]
ret = robot.WritePositionRegister(10, pr10);
if (ret != FK_SUCCESS) {
std::cerr << "PR[10] 写入失败" << std::endl;
robot.Disconnect();
return -1;
}
std::cout << "PR[10] 写入成功" << std::endl;
// ==============================================
// 5. 真实直线运动到 PR[10]
// ==============================================
FkMotionTarget target;
target.type = FK_MOTION_TYPE_PR;
target.prNumber = 10;
target.speed = 500.0f; // 速度 mm/s
target.zone = 0; // 0=FINE 精准停止
target.coordType = FK_CARTESIAN;
ret = robot.MoveLinear(target);
if (ret != FK_SUCCESS) {
std::cerr << "运动失败" << std::endl;
} else {
std::cout << "已直线运动到 PR[10]" << std::endl;
}
// 6. 断开连接
robot.Disconnect();
return 0;
}
push:保存当前的对齐方式
1:强制改成 1 字节对齐
pop:用完恢复,不影响其他代码
七、常用指令/API
1. 机器人端运动指令(直接调用PR)
J PR[1] 100% FINE; ! 关节运动到PR[1]
L PR[2] 500mm/sec CNT10; ! 直线运动到PR[2]
2. 常用控制指令
| 指令 | 功能 |
|---|---|
PR[i] = LPOS |
赋值当前直角位置 |
PR[i] = JPOS |
赋值当前关节位置 |
PR[i] = PR[j] |
复制PR |
CHECK PR[i] |
校验PR是否有效 |
3. C++核心API
ReadPositionRegister(num, &pr):读取PRWritePositionRegister(num, pr):写入PRGetPRValid(num):获取有效标志
八、异常处理
- PR无效报警:未赋值的PR(valid=false)用于运动,解决:赋值前校验;
- 坐标系错误:绑定不存在的坐标系,解决:C++端校验坐标系编号;
- 超限报警:PR坐标超出机器人运动范围,解决:C++端做软限位判断;
- 格式错误:直角PR与关节PR混用,解决:运算前校验格式。
九、PR与其他位置数据的区别
| 类型 | 数据类型 | 可运算 | 坐标系 | 用途 |
|---|---|---|---|---|
| PR寄存器 | 结构体(位置+姿态) | ✅ 是 | 自带 | 动态位置、柔性控制 |
| P点 | 静态坐标 | ❌ 否 | 固定 | 固定工位、示教点 |
| R寄存器 | 单浮点数 | ✅ 是 | 无 | 数值计数、参数存储 |
| LPOS/JPOS | 实时位置 | ❌ 否 | 临时 | 获取当前机器人位置 |
十、工程实践
- 优先用直角坐标PR:95%自动化场景(视觉、上下料、搬运);
- C++端必做校验:写入PR前检查有效位、坐标系、坐标范围;
- 基准+偏移模式:用1个PR做基准,N个PR做偏移,简化调试;
- 断电保持:配置PR断电保存,避免重启后数据丢失;
- 字节序对齐:C++与机器人通信时,严格匹配大端字节序(FANUC默认)。
总结
- PR是结构化位置结构体 ,对应C++的
struct,是机器人柔性控制核心; - 分直角/关节两种格式,自带坐标系属性,支持矢量运算;
- 赋值分4种,C++上位机赋值+偏移运算是开发核心;
- 开发关键:内存结构对齐、坐标系绑定、异常校验。