Skip to content
🤖 AI 助手 / 自动化工具:先读 《Agent 开发指引》 与 《生成前信息采集清单》;机器可读入口 /llms.txt;本页纯文本版:把网址中的 .html 换成 .md

点动与IO控制(综合示例) ​

本页把「连接 → 上电 → 点动 → 数字 IO」串成一个可独立运行的 Python 文件,适合作为最小闭环参考。各主题的细节说明见对应页面(本页末尾有链接)。

版本前提: 官方 Python 扩展库按解释器版本预编译——Windows = Python 3.10(64 位)、Linux = Python 3.8,其他版本无法加载(详见相关下载)。

⚠️ 安全警告

本示例包含真实的运动控制(点动会直接驱动机器人)。执行前必须确认:

  • 人员安全: 机器人工作空间内无人员或障碍物;
  • 急停可用: 急停按钮处于可用状态,并在操作人员可触及范围内;
  • 控制器状态: 控制器无未处理的安全报警,安全回路工作正常;
  • 参数核对: 控制器 IP、端口、点动轴号与方向已按现场核对;
  • 输出核对: 数字输出端口号与所接设备已核对,避免误触发。

建议先在无负载或仿真环境下验证,再连接真机。

功能 ​

程序按以下顺序执行(每一步失败即安全退出并断开连接):

  1. 连接控制器(修改文件顶部参数即可),等待连接就绪;
  2. 切换示教模式,按当前伺服状态执行上电(停止 → 就绪 → 上电 → 轮询到运行状态 3);
  3. 设置全局速度;
  4. 写数字输出端口并回读校验;
  5. 单轴点动:按 50ms 周期重发 robot_start_jogging(点动为保持式,必须在 200ms 内再次调用,否则控制器自动停止,见《基础连接与系统接口》§1.12),到时后调用 robot_stop_jogging;
  6. 数字输出复位、伺服下电、断开连接。

代码 ​

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 检查,失败即进入退出路径并断开连接。

下一步 ​

← 返回基础应用

🤖 AI 助手 / 自动化工具:先读 《Agent 开发指引》 与 《生成前信息采集清单》;机器可读入口 /llms.txt;本页纯文本版:把网址中的 .html 换成 .md