点动与IO控制(综合示例)
本页把「连接 → 上电 → 点动 → 数字 IO」串成一个可独立运行的 Python 文件,适合作为最小闭环参考。各主题的细节说明见对应页面(本页末尾有链接)。
版本前提: 官方 Python 扩展库按解释器版本预编译——Windows = Python 3.10(64 位)、Linux = Python 3.8,其他版本无法加载(详见相关下载)。
⚠️ 安全警告
本示例包含真实的运动控制(点动会直接驱动机器人)。执行前必须确认:
- 人员安全: 机器人工作空间内无人员或障碍物;
- 急停可用: 急停按钮处于可用状态,并在操作人员可触及范围内;
- 控制器状态: 控制器无未处理的安全报警,安全回路工作正常;
- 参数核对: 控制器 IP、端口、点动轴号与方向已按现场核对;
- 输出核对: 数字输出端口号与所接设备已核对,避免误触发。
建议先在无负载或仿真环境下验证,再连接真机。
功能
程序按以下顺序执行(每一步失败即安全退出并断开连接):
- 连接控制器(修改文件顶部参数即可),等待连接就绪;
- 切换示教模式,按当前伺服状态执行上电(停止 → 就绪 → 上电 → 轮询到运行状态 3);
- 设置全局速度;
- 写数字输出端口并回读校验;
- 单轴点动:按 50ms 周期重发
robot_start_jogging(点动为保持式,必须在 200ms 内再次调用,否则控制器自动停止,见《基础连接与系统接口》§1.12),到时后调用robot_stop_jogging; - 数字输出复位、伺服下电、断开连接。
代码
python
"""
点动与IO控制(综合示例)——Python 单文件最小闭环
流程:连接 → 示教模式 → 上电(轮询到状态 3)→ 设速度 → 写数字输出并回读
→ 单轴点动(50ms 保持式重发)→ 停止 → 数字输出复位 → 下电 → 断开
依赖:nrc_interface.py + 扩展库(_nrc_host.so / nrc_host.pyd)。
注意:官方扩展库按解释器版本预编译——Windows = Python 3.10 x64,Linux = Python 3.8(见《相关下载》)。
"""
import time
import nrc_interface
# ── 现场参数(运行前必须核对)──
robot_ip = "192.168.1.15" # 控制器 IP
robot_port = "6001" # 上位机 SDK 端口
jog_axis = 1 # 点动轴号
jog_dir_positive = True # 点动方向:True 正方向
jog_hold_ms = 1000 # 按住点动总时长(首次建议改为 200 验证方向)
jog_resend_ms = 50 # 点动重发周期(必须小于 200ms)
do_port = 1 # 数字输出端口(从 1 开始)
wait_ready_timeout_s = 90 # 等待上电完成总超时
poll_interval_s = 0.5 # 伺服状态轮询间隔
def check_sdk_result(result, operation):
"""统一检查 SDK 接口返回值,仅 SUCCESS(0) 视为成功。"""
if result == nrc_interface.SUCCESS:
return True
print(f"{operation} 调用失败,错误码:{result}")
return False
def read_servo_state(fd):
"""读取伺服状态。getter 返回 (结果码, 状态值) 元组;失败返回 None。"""
status = 0 # 每次调用 getter 前重新初始化变量
result, status = nrc_interface.get_servo_state(fd, status)
return status if result == nrc_interface.SUCCESS else None
def wait_until_robot_ready(fd):
"""轮询伺服状态直到进入运行状态(3)。"""
deadline = time.time() + wait_ready_timeout_s
state = None
while time.time() < deadline:
state = read_servo_state(fd)
if state is None:
return False
if state == 3:
print("伺服已进入运行状态(3)")
return True
time.sleep(poll_interval_s)
print(f"等待伺服上电超时,最后状态:{state}")
return False
def power_on(fd):
"""按当前伺服状态执行上电(停止/就绪/报警/已在运行四种分支)。"""
state = read_servo_state(fd)
if state is None:
return False # 状态未知时不允许继续发送控制命令
print(f"当前伺服状态:{state}")
if state == 0: # 停止:先切换到就绪状态(1),再上电
if not check_sdk_result(nrc_interface.set_servo_state(fd, 1), "set_servo_state"):
return False
if not check_sdk_result(nrc_interface.set_servo_poweron(fd), "set_servo_poweron"):
return False
elif state == 1: # 就绪:直接上电
if not check_sdk_result(nrc_interface.set_servo_poweron(fd), "set_servo_poweron"):
return False
elif state == 2: # 报警:先清错,再重新切换到就绪状态并上电
if not check_sdk_result(nrc_interface.clear_error(fd), "clear_error"):
return False
if not check_sdk_result(nrc_interface.set_servo_state(fd, 1), "set_servo_state"):
return False
if not check_sdk_result(nrc_interface.set_servo_poweron(fd), "set_servo_poweron"):
return False
elif state == 3: # 已在运行状态,无需重复上电
return True
else:
print(f"未知伺服状态:{state}")
return False
return wait_until_robot_ready(fd)
def main():
# 1. 连接控制器并等待就绪(get_connection_status 返回 SUCCESS 表示已就绪)。
fd = nrc_interface.connect_robot(robot_ip, robot_port)
print(fd)
if fd <= 0:
print(f"控制器连接失败:{robot_ip}:{robot_port}")
return 1
print("控制器连接成功,SDK 版本:", nrc_interface.get_library_version())
while nrc_interface.get_connection_status(fd) != nrc_interface.SUCCESS:
time.sleep(0.2)
# 2. 示教模式 + 上电(点动须在已上电状态下进行)。
if not check_sdk_result(nrc_interface.set_current_mode(fd, 0), "set_current_mode"):
nrc_interface.disconnect_robot(fd)
return 1
if not power_on(fd):
nrc_interface.disconnect_robot(fd)
return 1
# 3. 全局速度(范围 0 < speed <= 100)。
if not check_sdk_result(nrc_interface.set_speed(fd, 30), "set_speed"):
nrc_interface.disconnect_robot(fd)
return 1
# 4. 写数字输出并回读校验(先写 1,再回读确认端口真实翻转)。
if check_sdk_result(nrc_interface.set_digital_output(fd, do_port, 1), "set_digital_output"):
outs = nrc_interface.VectorInt()
result = nrc_interface.get_digital_output(fd, outs)
if result == nrc_interface.SUCCESS:
print(f"DO 端口 {do_port} 回读值:{outs[do_port - 1]}")
# 5. 单轴点动:保持式——每 50ms 重发一次,结束显式停止。
before = nrc_interface.VectorDouble(7)
nrc_interface.get_current_position(fd, 0, before)
print(f"点动前 J1:{before[0]},开始点动(轴 {jog_axis},共 {jog_hold_ms}ms)")
jog_end = time.time() + jog_hold_ms / 1000.0
while time.time() < jog_end:
check_sdk_result(
nrc_interface.robot_start_jogging(fd, jog_axis, jog_dir_positive),
"robot_start_jogging",
)
time.sleep(jog_resend_ms / 1000.0)
check_sdk_result(nrc_interface.robot_stop_jogging(fd, jog_axis), "robot_stop_jogging")
after = nrc_interface.VectorDouble(7)
nrc_interface.get_current_position(fd, 0, after)
print(f"点动后 J1:{after[0]},点动结束")
# 6. 数字输出复位(可选)、下电并断开。
check_sdk_result(nrc_interface.set_digital_output(fd, do_port, 0), "set_digital_output")
check_sdk_result(nrc_interface.set_servo_poweroff(fd), "set_servo_poweroff") # 如需保持上电,注释本行
nrc_interface.disconnect_robot(fd)
print("已断开连接")
return 0
if __name__ == "__main__":
raise SystemExit(main())运行说明
- 按环境搭建配置好
nrc_interface.py与扩展库(_nrc_host.so/nrc_host.pyd),把本文件保存为jog_io_demo.py后运行:python jog_io_demo.py - 控制器 IP、端口、轴号、DO 端口等均可在文件顶部参数区修改;
- 首次运行建议把
jog_hold_ms改为200,点动一小段距离确认轴号与方向无误后,再恢复正常时长。
关键点说明
- 上电状态机:
set_servo_poweron返回成功仅表示命令已发送,需轮询get_servo_state直到状态 3 才算就绪; - 点动为保持式:必须在 200ms 内再次调用
robot_start_jogging(重复调用幂等),否则控制器自动停止——本示例按 50ms 重发即满足该要求; - IO 回读校验:写数字输出后建议回读确认,避免只看接口返回值;
- getter 与出口参数:Python 端 getter 返回
(结果码, 输出值)元组(如get_servo_state),每次调用前须重新初始化变量;vector 出口参数(如pos、outs)则先创建VectorDouble/VectorInt对象再传入,调用后从对象中读取; - 错误处理:所有 SDK 调用统一经
check_sdk_result检查,失败即进入退出路径并断开连接。
下一步
- 点动接口细节:基础连接与系统接口 §1.12
- Python API 参考:Python SDK API 参考
- 环境与版本:Python 环境搭建 · 相关下载(Python 版本匹配)
- 没有真机?见编译与验证指南