- 选型指南
- 概述
- 入门指南
- 机械臂参数
- 示教器使用
-
二次开发
-
API(C++)
- 快速开始
- 接口说明
- 7000端口接口说明
- 使用示例
- 返回值说明
-
API(Python)
- 快速开始
- 接口说明
- 7000端口接口说明
- 使用示例
- 返回值说明
- ROS2开发
-
API(C++)
- 相关下载
X86架构下使用示例
1 Modbus Rtu使用示例
Python
import nrc_interface as nrc
import time
class ArmTest:
def demo_finger_modbus_rtu(self, socketFd):
"""
Modbus RTU 控制灵巧手 Demo(Python版)
:param socketFd: 套接字文件描述符
串口号是2
"""
master_id = 1 # 主站ID(0~8均可)
# =================================================
# 1 配置 Modbus RTU 参数
# =================================================
param = nrc.ModbusMasterParameter()
param.type = "RTU"
param.startAddress = True # False=地址从1开始
# RTU 串口参数
param.RTU.slaveId = 2 # 从站ID
param.RTU.port = 2 # 串口号
param.RTU.baudrate = 115200 # 波特率
param.RTU.checkBit = "None" # 校验位
param.RTU.dataBit = 8 # 数据位
param.RTU.stopBit = 1 # 停止位
# =================================================
# 2 写入主站参数
# =================================================
ret = nrc.modbus_set_master_parameter(socketFd, master_id, param)
if ret != nrc.SUCCESS:
print("设置Modbus RTU参数失败")
return
print("设置Modbus RTU参数成功")
# =================================================
# 3 打开 Modbus 主站
# =================================================
ret = nrc.modbus_open_master(socketFd, master_id)
if ret != nrc.SUCCESS:
print("打开Modbus主站失败")
return
print("打开Modbus主站成功")
time.sleep(1)
# =================================================
# 4 写多个寄存器(控制灵巧手)
# =================================================
control_data = [20000, 0, 0, 0, 0]
ret = nrc.modbus_write_multiple_holding_registers(
socketFd,
master_id,
1135, # 起始地址
control_data # 数据
)
if ret != nrc.SUCCESS:
print("写多个寄存器失败")
return
print("写多个寄存器成功")
time.sleep(1)
# =================================================
# 5 读取寄存器验证
# =================================================
read_back = nrc.VectorInt()
ret = nrc.modbus_read_holding_registers(
socketFd,
master_id,
1155, # 起始地址
5, # 读取数量
read_back
)
if ret != nrc.SUCCESS:
print("读取寄存器失败")
return
print("\n[结果] 读取数据:", end="")
for v in read_back:
print(v, end=" ")
print()
print("\n[完成] 灵巧手 Modbus RTU Demo 执行完毕!")
if __name__ == '__main__':
# 建立连接
arm_test = ArmTest()
socket_fd = nrc.connect_robot("192.168.1.13", "6001")
arm_test.demo_finger_modbus_rtu(socket_fd) #调用modbus_demo
2 关节信息查询使用示例
Python
import nrc_interface as nrc
import time
class ArmTest:
# 查询关节信息
def demo_get_joint_info(self, socketFd, joint_id):
joint_param = nrc.RobotJointParam()
ret = nrc.get_robot_joint_param(socketFd, joint_id, joint_param)
if ret != nrc.SUCCESS:
print(f"查询轴{joint_id}失败")
return
print(f"=== 轴{joint_id} ===")
print(f"减速比 : {joint_param.reducRatio}")
print(f"编码器分辨率 : {joint_param.encoderResolution}")
print(f"软正限位 : {joint_param.posSWLimit}")
print(f"软负限位 : {joint_param.negSWLimit}")
print(f"额定转速 : {joint_param.ratedRotSpeed}")
print(f"最大转速 : {joint_param.maxRotSpeed}")
print(f"额定速度 : {joint_param.ratedVel}")
print(f"最大加速度 : {joint_param.maxAcc}")
print(f"最大减速度 : {joint_param.maxDecel}")
print(f"电机方向 : {joint_param.direction}")
if __name__ == '__main__':
# 建立连接
arm_test = ArmTest()
socket_fd = nrc.connect_robot("192.168.1.13", "6001")
3 关节实时跟踪servoJ使用示例
Python
import nrc_interface as nrc
import time
class ArmTest:
#关节跟踪模式
def demo_servoJ(self, socket_fd):
vmax = [300, 300, .300, 300, 300, 300, 300]
amax = [3000, 3000, 3000, 3000, 3000, 3000, 3000]
jmax = [50000, 50000, 50000, 50000, 50000, 50000, 50000]
nrc.open_servoJ(socket_fd, vmax, amax, jmax)
print("打开关节跟踪模式")
print(f"> 速度约束: {vmax} °/s")
print(f"> 加速度约束: {amax} °/s²")
print(f"> 加加速度约束: {jmax} °/s³")
print("=== 高频小增量关节跟踪启动 ===")
time.sleep(0.2)
q = [0, 0, 0, 0, 0, 0, 0] #目标位置,关节一从0到100度
while q[0] < 60:
q[0] += 1
nrc.set_servoJ_pos(socket_fd, q)
time.sleep(0.01) #发送频率,10ms/次,可以改
time.sleep(5) #确保停下来
nrc.close_servoJ(socket_fd)
print("=== 跟踪结束 ===")
if __name__ == '__main__':
# 建立连接
arm_test = ArmTest()
socket_fd = nrc.connect_robot("192.168.1.13", "6001")
socket_fd_7000 = nrc.connect_robot("192.168.1.13", "7000")
nrc.set_servo_state(socket_fd, 1) #就绪状态
time.sleep(1)
nrc.set_current_mode(socket_fd, 2) #运行模式
nrc.set_speed(socket_fd,30) #30%速度
nrc.set_servo_poweron(socket_fd) #上电
arm_test.demo_servoJ(socket_fd_7000) #开始追踪,示例是从零点坐标 #开始追踪,示例是从零点坐标(使用时请回零点),给一关节以10ms每次的频率发送0到60度 ,速度很快
#使用此功能一定要注意安全!!!!!!!!
4 关节运动到目标点robot_movej使用示例
Python
import nrc_interface as nrc
import time
class ArmTest:
def demo_arm_movej(self, socket_fd):
"""
七轴机械臂 MoveJ 运动 Demo
"""
print("开始伺服上电...")
nrc.set_servo_state(socket_fd, 1)
nrc.set_servo_poweron(socket_fd)
print("伺服已上电")
time.sleep(1)
moveCmd = nrc.MoveCmd()
target = [50, 0, 0, 0, 0, 0, 0]
moveCmd.targetPosValue.resize(7)
for i in range(7):
moveCmd.targetPosValue[i] = target[i]
moveCmd.coord = 0#关节坐标系
moveCmd.velocity = 20
moveCmd.acc = 100
moveCmd.dec = 100
moveCmd.pl = 5
ret = nrc.robot_movej(socket_fd, moveCmd)
print(f"调用返回值(ret) = {ret}")
time.sleep(10)
print("指令发送完成")
if __name__ == '__main__':
# 建立连接
arm_test = ArmTest()
socket_fd = nrc.connect_robot("192.168.1.13", "6001")
arm_test.demo_arm_movej(socket_fd)
5 直线运动到目标位置robot_movel使用示例
Python
import nrc_interface as nrc
import time
class ArmTest:
# 直线运动 movel
def demo_arm_movel(self, socket_fd):
print("开始伺服上电...")
nrc.set_servo_state(socket_fd, 1)
nrc.set_servo_poweron(socket_fd)
print("伺服已上电")
time.sleep(1)
moveCmd = nrc.MoveCmd()
target = [140, 199, 243, 3.14, 0, 0, -1]#目标位置,直角坐标系
moveCmd.targetPosValue.resize(7)
for i in range(7):
moveCmd.targetPosValue[i] = target[i]
moveCmd.coord = 1#直角坐标系
moveCmd.velocity = 100
moveCmd.acc = 100
moveCmd.dec = 100
ret = nrc.robot_movel(socket_fd, moveCmd)
print(f"直线运动调用返回值(ret) = {ret}")
time.sleep(10)
print("直线运动完成")
if __name__ == '__main__':
# 建立连接
arm_test = ArmTest()
socket_fd = nrc.connect_robot("192.168.1.13", "6001")
# 执行直线运动
arm_test.demo_arm_movel(socket_fd)
#使用时一定要注意安全!!!!!!!!
6 点动使用示例
Python
import nrc_interface as nrc
import time
class ArmTest:
# ==================== 单轴点动 ====================
def demo_arm_start_jogging(self, socket_fd):
print("开始伺服上电...")
nrc.set_servo_state(socket_fd, 1)
nrc.set_servo_poweron(socket_fd)
print("伺服已上电")
time.sleep(1)
# 点动参数
axis = 1 # 轴号 1~6
dir = True # 方向 True=正 / False=负
# 调用点动
ret = nrc.robot_start_jogging(socket_fd, axis, dir)
print(f"单轴点动启动返回值(ret) = {ret}")
print("单轴点动已开始(需手动停止)")
# ==================== 停止点动====================
def demo_arm_stop_jogging(self, socket_fd):
axis = 1 # 要停止的轴号(必须和启动时一致)
ret = nrc.robot_stop_jogging(socket_fd, axis)
print(f"停止点动返回值(ret) = {ret}")
print("点动已停止")
if __name__ == '__main__':
# 建立连接
arm_test = ArmTest()
socket_fd = nrc.connect_robot("192.168.1.13", "6001")
# 1. 启动点动
arm_test.demo_arm_start_jogging(socket_fd) #一轴点动一次
time.sleep(2) # 运动2秒
# 2. 停止点动
arm_test.demo_arm_stop_jogging(socket_fd)
7 作业文件插入指令使用示例
Python
import nrc_interface as nrc
import time
class ArmTest:
def job_moveJ(self,socket_fd):
# 创建指令
moveCmd = nrc.MoveCmd()
# 设置参数
moveCmd.targetPosType = 1
#如果targetPosType=0为自定义数组,需要设置该向量值,前7位为本体值,后7位为外部轴
#如果targetPosType=1,需要设置targetPosName为"P0001"
moveCmd.targetPosName = "P0001"#每次插入应该使用不同name的点存储点位信息,例如插入第二个可以用"P0002"
# 位置向量
pos = nrc.VectorDouble(6)#6轴为例,7轴第7个pos填0
pos[0] = 8.0
pos[1] = 0.0
pos[2] = 0.0
pos[3] = 0.0
pos[4] = 0.0
pos[5] = 0.0
moveCmd.targetPosValue = pos
moveCmd.coord = 0
moveCmd.velocity = 20
moveCmd.velocitySync = 20
moveCmd.acc = 20
moveCmd.dec = 20
moveCmd.pl = 5
# 下发
nrc.job_open(socket_fd, "TTT")#打开一个作业文件TTT,没有的话先创建
time.sleep(1)
ret = nrc.job_insert_moveJ(socket_fd, 1, moveCmd)#插入指令
print("执行结果:", ret)
if __name__ == '__main__':
# 建立连接
arm_test = ArmTest()
socket_fd = nrc.connect_robot("192.168.1.13", "6001")
arm_test.job_moveJ(socket_fd)
#这样就在作业文件TTT的第一行插入了一条moveJ,和示教器使用基本一样。重新打开示教器会自动同步作业文件,就可以看见示教器的TTT工作文件插入了一条moveJ
8 队列运动指令使用示例
Python
import nrc_interface as nrc
import time
class ArmTest:
def queue_moveJ(self, pos_list, socket_fd=None, coord=0, velocity=10, acc=20, dec=20, pl=0):
"""
队列运动模式:插入 MoveJ 并发送
:param socket_fd: 可选,优先使用传入的,没有则用实例默认的
"""
fd = socket_fd
pos = nrc.VectorDouble(len(pos_list))
for i, val in enumerate(pos_list):
pos[i] = val
moveCmd = nrc.MoveCmd()
moveCmd.coord = coord
moveCmd.targetPosType = nrc.PosType_data
moveCmd.targetPosValue = pos
moveCmd.velocity = velocity
moveCmd.acc = acc
moveCmd.dec = dec
moveCmd.pl = pl
nrc.queue_motion_push_back_moveJ(fd, moveCmd)
ret = nrc.queue_motion_get_status(fd, True)
print(f"队列 MoveJ 返回值(ret) = {ret}")
return ret
# ====================== 队列控制:MoveC ======================
def queue_moveC(self, pos_list, socket_fd=None, coord=0, velocity=10, acc=100, dec=100, pl=5):
"""
队列运动模式:插入 MoveC 并发送
:param socket_fd: 可选,优先使用传入的,没有则用实例默认的
"""
fd = socket_fd
pos = nrc.VectorDouble(len(pos_list))
for i, val in enumerate(pos_list):
pos[i] = val
moveCmd = nrc.MoveCmd()
moveCmd.coord = coord
moveCmd.targetPosType = nrc.PosType_data
moveCmd.targetPosValue = pos
moveCmd.velocity = velocity
moveCmd.acc = acc
moveCmd.dec = dec
moveCmd.pl = pl
nrc.queue_motion_push_back_moveC(fd, moveCmd)
ret = nrc.queue_motion_get_status(fd, True)
print(f"队列 MoveC 返回值(ret) = {ret}")
return ret
def queue_moveS(self, pos_list, socket_fd=None, coord=0, velocity=10, acc=20, dec=20, pl=0):
"""
队列运动模式:插入 MoveS 并发送
:param socket_fd: 可选,优先使用传入的,没有则用实例默认的
"""
fd = socket_fd
pos = nrc.VectorDouble(len(pos_list))
for i, val in enumerate(pos_list):
pos[i] = val
moveCmd = nrc.MoveCmd()
moveCmd.coord = coord
moveCmd.targetPosType = nrc.PosType_data
moveCmd.targetPosValue = pos
moveCmd.velocity = velocity
moveCmd.acc = acc
moveCmd.dec = dec
moveCmd.pl = pl
nrc.queue_motion_push_back_moveC(fd, moveCmd)
ret = nrc.queue_motion_get_status(fd, True)
print(f"队列 MoveS 返回值(ret) = {ret}")
return ret
if __name__ == '__main__':
# 建立连接
arm_test = ArmTest()
socket_fd = nrc.connect_robot("192.168.1.13", "6001")
nrc.queue_motion_set_status(socket_fd, True)#打开队列模式
time,sleep(2)
nrc.set_speed(socket_fd,40)#运行速度
arm_test.queue_moveJ(socket_fd=socket_fd,pos_list=[50.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0])#本示例从零点开始运动,到j1=50度,回零点
arm_test.queue_moveJ(socket_fd=socket_fd,pos_list=[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0])
nrc.queue_motion_send_to_controller(socket_fd,2)#发送二个目标位置
time.sleep(20)
nrc.queue_motion_set_status(socket_fd, False)#关闭队列模式
9 欧拉角,四元素,位姿矩阵,旋转矩阵相互转化使用示例
Python
import nrc_interface as nrc
import time
class ArmTest:
# ====================== 四元数 转 欧拉角 ======================
def get_quat2rpy(self, qx, qy, qz, qw, socket_fd=None):
# 1. 创建输入四元数 vector(长度4)
fd = socket_fd
quat_vec = nrc.VectorDouble(4)
quat_vec[0] = qx
quat_vec[1] = qy
quat_vec[2] = qz
quat_vec[3] = qw
# 2. 创建输出欧拉角 vector(长度3)
rpy_vec = nrc.VectorDouble(3)
# 3. 调用接口
ret = nrc.get_quat2rpy(fd, quat_vec, rpy_vec)
# 4. 读取结果
rx = rpy_vec[0]
ry = rpy_vec[1]
rz = rpy_vec[2]
print(f"转换返回值 ret = {ret}")
print(f"欧拉角 Rx={rx:.3f}, Ry={ry:.3f}, Rz={rz:.3f}")
return ret, rx, ry, rz
# ====================== 欧拉角 转 四元数 ======================
def get_rpy2quat(self, rx, ry, rz, socket_fd=None):
fd = socket_fd
# 输入:欧拉角 RPY 长度 3
rpy_vec = nrc.VectorDouble(3)
rpy_vec[0] = rx
rpy_vec[1] = ry
rpy_vec[2] = rz
# 输出:四元数 长度 4
quat_vec = nrc.VectorDouble(4)
# 调用接口
ret = nrc.get_rpy2quat(fd, rpy_vec, quat_vec)
# 取出四元数结果
qx = quat_vec[0]
qy = quat_vec[1]
qz = quat_vec[2]
qw = quat_vec[3]
print(f"rpy2quat 返回值: {ret}")
print(f"四元数结果: qx={qx:.3f}, qy={qy:.3f}, qz={qz:.3f}, qw={qw:.3f}")
return ret, qx, qy, qz, qw
# 欧拉角 转 旋转矩阵
def get_rpy2r(self, rx, ry, rz, socket_fd=None):
fd = socket_fd
# 输入:欧拉角 RPY 长度 3
rpy_vec = nrc.VectorDouble(3)
rpy_vec[0] = rx
rpy_vec[1] = ry
rpy_vec[2] = rz
# 输出:旋转矩阵 长度 9(行主序)
r_vec = nrc.VectorDouble(9)
# 调用官方接口
ret = nrc.get_rpy2r(fd, rpy_vec, r_vec)
# 取出旋转矩阵 9 个值
r00 = r_vec[0]
r01 = r_vec[1]
r02 = r_vec[2]
r10 = r_vec[3]
r11 = r_vec[4]
r12 = r_vec[5]
r20 = r_vec[6]
r21 = r_vec[7]
r22 = r_vec[8]
# 打印
print(f"rpy2r 返回值: {ret}")
print(f"旋转矩阵结果: r00={r00:.3f}, r01={r01:.3f}, r02={r02:.3f}")
print(f" r10={r10:.3f}, r11={r11:.3f}, r12={r12:.3f}")
print(f" r20={r20:.3f}, r21={r21:.3f}, r22={r22:.3f}")
# 返回:ret + 9个矩阵值
return ret, r00, r01, r02, r10, r11, r12, r20, r21, r22
#位姿 转 旋转矩阵
def get_rt2r(self, tr_matrix, socket_fd=None):
fd = socket_fd
# 输入:位姿矩阵 长度 16(行主序)
tr_vec = nrc.VectorDouble(16)
for i in range(16):
tr_vec[i] = tr_matrix[i]
# 输出:旋转矩阵 长度 9(行主序)
r_vec = nrc.VectorDouble(9)
# 调用接口
ret = nrc.get_tr2r(fd, tr_vec, r_vec)
# 取出旋转矩阵 9 个值
r00 = r_vec[0]
r01 = r_vec[1]
r02 = r_vec[2]
r10 = r_vec[3]
r11 = r_vec[4]
r12 = r_vec[5]
r20 = r_vec[6]
r21 = r_vec[7]
r22 = r_vec[8]
# 打印
print(f"rt2r 返回值: {ret}")
print(f"旋转矩阵结果: r00={r00:.3f}, r01={r01:.3f}, r02={r02:.3f}")
print(f" r10={r10:.3f}, r11={r11:.3f}, r12={r12:.3f}")
print(f" r20={r20:.3f}, r21={r21:.3f}, r22={r22:.3f}")
# 返回格式ret + 9个矩阵值
return ret, r00, r01, r02, r10, r11, r12, r20, r21, r22
# 旋转矩阵 转 位姿矩阵
def get_r2tr(self, r00, r01, r02, r10, r11, r12, r20, r21, r22, socket_fd=None):
fd = socket_fd
# 输入:旋转矩阵 长度9(行主序)
r_vec = nrc.VectorDouble(9)
r_vec[0] = r00
r_vec[1] = r01
r_vec[2] = r02
r_vec[3] = r10
r_vec[4] = r11
r_vec[5] = r12
r_vec[6] = r20
r_vec[7] = r21
r_vec[8] = r22
# 输出:位姿矩阵 长度16(行主序)
tr_res = nrc.VectorDouble(16)
# 调用接口
ret = nrc.get_r2tr(fd, r_vec, tr_res)
# 取出位姿矩阵16个值
tr00 = tr_res[0]
tr01 = tr_res[1]
tr02 = tr_res[2]
tr03 = tr_res[3]
tr10 = tr_res[4]
tr11 = tr_res[5]
tr12 = tr_res[6]
tr13 = tr_res[7]
tr20 = tr_res[8]
tr21 = tr_res[9]
tr22 = tr_res[10]
tr23 = tr_res[11]
tr30 = tr_res[12]
tr31 = tr_res[13]
tr32 = tr_res[14]
tr33 = tr_res[15]
# 打印
print(f"r2tr 返回值: {ret}")
print(f"位姿矩阵结果: tr00={tr00:.3f}, tr01={tr01:.3f}, tr02={tr02:.3f}, tr03={tr03:.3f}")
print(f" tr10={tr10:.3f}, tr11={tr11:.3f}, tr12={tr12:.3f}, tr13={tr13:.3f}")
print(f" tr20={tr20:.3f}, tr21={tr21:.3f}, tr22={tr22:.3f}, tr23={tr23:.3f}")
print(f" tr30={tr30:.3f}, tr31={tr31:.3f}, tr32={tr32:.3f}, tr33={tr33:.3f}")
# 返回:ret + 16个位姿值
return ret, tr00, tr01, tr02, tr03, tr10, tr11, tr12, tr13, tr20, tr21, tr22, tr23, tr30, tr31, tr32, tr33
if __name__ == '__main__':
# 建立连接
arm_test = ArmTest()
socket_fd = nrc.connect_robot("192.168.1.13", "6001")
arm_test.get_rpy2quat(-2.9,0.167,-0.777,socket_fd)
arm_test.get_quat2rpy(-0.080, 0.919, 0.365, 0.122,socket_fd)
arm_test.get_rpy2r(-2.9,0.167,-0.777,socket_fd)
arm_test.get_r2tr(0.703, 0.691, 0.166, 0.652, -0.720, 0.236, 0.283, -0.057, -0.957, socket_fd)
tr = [
0.703, 0.691, 0.166, 0.000,
0.652, -0.720, 0.236, 0.000,
0.283, -0.057, -0.957, 0.000,
0.000, 0.000, 0.000, 1.000
]
arm_test.get_rt2r(tr, socket_fd )
关注天链机器人
公众号
视频号
抖音号
哔哩哔哩
新浪微博
今日头条
小红书
百度
1688店铺
这里是占位文字
