Windows(x64)架构使用示例

1. Modbus Rtu 使用示例

Python
import nrc_interface as nrc
import time

def set_modbus_master_parameter(self, master_id: int, param) -> int:
    """
    配置 Modbus 主站参数 (包含 RTU 串口/TCP 配置)
    :param master_id: 主站 ID,取值范围 [0, 8]
    :param param: 实例化的 nrc.ModbusMasterParameter 对象
    :return: 底层接口返回值 (0 代表成功,非 0 代表失败错误码,-1 代表断连异常)
    """
    # 【统一拦截】严格对齐常规指令通道 (socket_fd) 拦截流标准与失败返回值 -1
    if not self.socket_fd or self.socket_fd <= 0:
        print("错误: 配置 Modbus 参数失败,未建立有效网络连接 (socket_fd 无效)。")
        return -1

    try:
        # 调用底层核心接口
        ret = nrc.modbus_set_master_parameter(self.socket_fd, master_id, param)

        # 【统一日志】工业级标准化前缀输出
        if ret == 0:
            print(f"成功: Modbus 主站 [ID: {master_id}] 参数配置已成功下发。")
        else:
            print(f"错误: 配置 Modbus 主站参数失败,底层错误码: {ret}")
        return ret
    except Exception as e:
        print(f"异常: 配置 Modbus 主站参数发生未知异常: {e}")
        return -1

def open_modbus_master(self, master_id: int) -> int:
    """
    打开指定的 Modbus 主站
    :param master_id: 主站 ID,取值范围 [0, 8]
    :return: 底层接口返回值 (0 代表成功,非 0 代表失败错误码,-1 代表断连异常)
    """
    # 【统一拦截】严格对齐常规指令通道 (socket_fd) 拦截流标准与失败返回值 -1
    if not self.socket_fd or self.socket_fd <= 0:
        print("错误: 打开 Modbus 主站失败,未建立有效网络连接 (socket_fd 无效)。")
        return -1

    try:
        # 调用底层核心接口
        ret = nrc.modbus_open_master(self.socket_fd, master_id)

        # 【统一日志】工业级标准化前缀输出
        if ret == 0:
            print(f"成功: Modbus 主站 [ID: {master_id}] 已成功打开。")
        else:
            print(f"错误: 打开 Modbus 主站失败,底层错误码: {ret}")
        return ret
    except Exception as e:
        print(f"异常: 打开 Modbus 主站发生未知异常: {e}")
        return -1

def read_modbus_registers(self, master_id: int, address: int, quantity: int) -> list:
    """
    批量读取多个 Modbus 保持寄存器
    :param master_id: 主站 ID,取值范围 [0, 8]
    :param address: 读取的目标寄存器起始地址
    :param quantity: 需要连续读取的寄存器数量
    :return: 成功返回读取到的整型数据列表,失败或断连返回空列表 []
    """
    # 【统一拦截】严格对齐常规指令通道 (socket_fd) 拦截流标准与失败返回值 []
    if not self.socket_fd or self.socket_fd <= 0:
        print("错误: 批量读取 Modbus 寄存器失败,未建立有效网络连接 (socket_fd 无效)。")
        return []

    try:
        # 实例化底层所需的 VectorInt 接收容器,并根据读取数量预分配缓冲空间
        read_back = nrc.VectorInt()
        for _ in range(quantity):
            read_back.push_back(0)

        # 调用底层核心接口
        ret = nrc.modbus_read_holding_registers(self.socket_fd, master_id, address, quantity, read_back)

        # 【统一日志】工业级标准化前缀输出
        if ret == 0:
            res_list = list(read_back)
            print(f"成功: Modbus 主站 [ID: {master_id}] 批量读取寄存器成功 -> 起始地址: {address}, 数量: {quantity}, 数据: {res_list}")
            return res_list
        else:
            print(f"错误: 批量读取 Modbus 寄存器失败,起始地址: {address},底层错误码: {ret}")
            return []
    except Exception as e:
        print(f"异常: 批量读取 Modbus 寄存器发生未知异常: {e}")
        return []

def write_modbus_registers(self, master_id: int, address: int, data_list: list) -> int:
    """
    批量写入多个 Modbus 保持寄存器
    :param master_id: 主站 ID,取值范围 [0, 8]
    :param address: 写入的目标寄存器起始地址
    :param data_list: 待写入的 16 位整型数据列表
    :return: 底层接口返回值 (0 代表成功,非 0 代表失败错误码,-1 代表断连异常)
    """
    # 【统一拦截】严格对齐常规指令通道 (socket_fd) 拦截流标准与失败返回值 -1
    if not self.socket_fd or self.socket_fd <= 0:
        print("错误: 批量写入 Modbus 寄存器失败,未建立有效网络连接 (socket_fd 无效)。")
        return -1

    try:
        # 转换数据类型为底层所需的 VectorInt 类型
        arm_data = nrc.VectorInt()
        for val in data_list:
            arm_data.push_back(int(val))

        # 调用底层核心接口
        ret = nrc.modbus_write_multiple_holding_registers(self.socket_fd, master_id, address, arm_data)

        # 【统一日志】工业级标准化前缀输出
        if ret == 0:
            print(f"成功: Modbus 主站 [ID: {master_id}] 批量写入寄存器成功 -> 起始地址: {address}, 数据: {data_list}")
        else:
            print(f"错误: 批量写入 Modbus 寄存器失败,起始地址: {address},底层错误码: {ret}")
        return ret
    except Exception as e:
        print(f"异常: 批量写入 Modbus 寄存器发生未知异常: {e}")
        return -1

if __name__ == '__main__':
    # 1 地址通信
    arm_test = RobotArmTest(ip="192.168.1.13", dof=6)
    if arm_test._connect_robot() == 0:

        # 【步骤 1】配置工具手的物理通信参数 (RTU 模式、串口 2、波特率 115200)
        arm_param = nrc.ModbusMasterParameter()
        arm_param.type = "RTU"
        arm_param.startAddress = True
        arm_param.RTU.slaveId = 2        # 工具手出厂默认站号 (根据实际说明书修改)
        arm_param.RTU.port = 2           # 纳博特控制器物理串口 2
        arm_param.RTU.baudrate = 115200
        arm_param.RTU.checkBit = "None"
        arm_param.RTU.dataBit = 8
        arm_param.RTU.stopBit = 1

        arm_master_id = 0

        # 下发参数配置到内存
        ret_config = nrc.modbus_set_master_parameter(arm_test.socket_fd, arm_master_id, arm_param)

        if ret_config == 0:

            # 【步骤 2】通电并打开 Modbus 主站通道
            ret_open = arm_test.open_modbus_master(master_id=arm_master_id)

            if ret_open == 0:
                time.sleep(1) # 延时 1 秒,等待工具手协议栈握手稳定

                # 【步骤 3】向 1135 地址写入控制指令 (例如: 驱使工具手闭合/张开)
                arm_write_address = 1135
                arm_control_data = [0, 0, 40000, 40000, 0] # 动作目标参数
                ret_write = arm_test.write_modbus_registers(master_id=arm_master_id, address=arm_write_address, data_list=arm_control_data)

                if ret_write == 0:
                    time.sleep(1) # 延时 1 秒,留出工具手物理动作执行时间

                    # 【步骤 4】从 1155 地址读取寄存器,验证工具手是否抓取成功或获取当前位置
                    arm_read_address = 1155
                    arm_quantity = 5
                    arm_test.read_modbus_registers(master_id=arm_master_id, address=arm_read_address, quantity=arm_quantity)

2. 关节实时跟踪 servoJ 使用示例

Python
import nrc_interface as nrc
import time

def open_servo_joint(self, max_v: float, max_a: float, max_j: float) -> int:
    """
    打开标准关节跟踪模式 (精简中文输出版)
    :param max_v: 所有关节统一的最大速度约束 (°/s)
    :param max_a: 所有关节统一的最大加速度约束 (°/s²)
    :param max_j: 所有关节统一的最大加加速度约束 (°/s³)
    :return: 底层接口返回值 (0 代表成功,非 0 代表失败错误码,-2 代表断连异常)
    """
    # 【统一拦截】严格对齐常规指令通道 (socket_fd) 拦截流标准与原代码返回值 -2
    if not self.socket_fd or self.socket_fd <= 0:
        print("错误: 打开关节跟踪模式失败,未建立有效网络连接 (socket_fd 无效)。")
        return -2

    try:
        # 1. 实例化 C++ 向量容器,用以承载多轴独立的动力学约束
        vmax_vec = nrc.VectorDouble()
        amax_vec = nrc.VectorDouble()
        jmax_vec = nrc.VectorDouble()

        # 2. 根据机械臂自由度 (dof) 动态填充各个关节的限制边界
        for _ in range(self.dof):
            vmax_vec.push_back(float(max_v))
            amax_vec.push_back(float(max_a))
            jmax_vec.push_back(float(max_j))

        # 3. 调用底层核心控制原语,开启 ServoJ 通道
        ret = nrc.open_servoJ(self.socket_fd, vmax_vec, amax_vec, jmax_vec)

        # 【统一日志】工业级标准化前缀输出,扁平化分支
        if ret == 0:
            print("成功: 标准关节跟踪模式 (ServoJ) 已成功打开,系统进入高频流式监听状态。")
        else:
            print(f"错误: 打开标准关节跟踪模式失败,底层错误码: {ret}")
        return ret
    except Exception as e:
        print(f"异常: 打开标准关节跟踪模式发生未知异常: {e}")
        return -1

def close_servo_joint(self) -> int:
    """
    在 7000 端口关闭标准关节跟踪模式
    :return: 底层接口返回值 (0 代表成功,非 0 代表失败错误码,-2 代表断连异常)
    """
    # 【统一拦截】严格对齐特定高频实时通道 (robotarm7000) 拦截流标准与原代码返回值 -2
    if not self.robotarm7000 or self.robotarm7000 <= 0:
        print("错误: 关闭关节跟踪模式失败,7000 端口未建立有效连接。")
        return -2

    try:
        # 调用底层核心原语,显式传入 7000 端口句柄,注销 ServoJ 监听
        ret = nrc.close_servoJ(self.robotarm7000)

        # 【统一日志】工业级标准化前缀输出,扁平化分支
        if ret == 0:
            print("成功: 7000 端口标准关节跟踪模式已安全关闭,系统已恢复为常规轨迹就绪态。")
        else:
            print(f"错误: 关闭标准关节跟踪模式失败,底层错误码: {ret}")
        return ret
    except Exception as e:
        print(f"异常: 关闭标准关节跟踪模式发生未知异常: {e}")
        return -1

def set_servo_joint_position(self, joint_angles: list) -> int:
    """
    在 7000 端口发送实时跟踪关节位置
    :param joint_angles: 目标关节角度列表 (单位: °)
    :return: 底层接口返回值 (0代表成功, 非0代表失败)
    """
    if not self.robotarm7000 or self.robotarm7000 <= 0:
        print("错误: 发送实时关节位置失败,7000 端口未建立有效连接。")
        return -2

    try:
        # 1. 转换数据类型为底层所需的 VectorDouble
        q_vec = nrc.VectorDouble()
        for angle in joint_angles:
            q_vec.push_back(float(angle))

        # 2. 严谨处理特殊轴数补齐:如果是6轴机械臂且长度不足7,按照文档规范补0
        if self.dof == 6 and len(joint_angles) == 6:
            q_vec.push_back(0.0)

        # 3. 核心传参:严格限定传入 7000 端口句柄 self.robotarm7000
        ret = nrc.set_servoJ_pos(self.robotarm7000, q_vec)

        if ret != 0:
            print(f"错误: 发送实时关节位置失败。错误码: {ret}")
        return ret
    except Exception as e:
        print(f"异常: 发送实时关节位置发生异常: {e}")
        return -1

if __name__ == '__main__':
    # 1 地址通信
    arm_test = RobotArmTest(ip="192.168.1.13", dof=6)
    if arm_test._connect_robot() == 0:

        # 步骤一:在 7000 端口打开跟踪模式
        # 官方的约束很大(300°/s),代表不限制轴速,完全听从点位的移动增量
        arm_test.open_servo_joint(max_v=300.0, max_a=3000.0, max_j=50000.0)
        time.sleep(0.2)

        # 步骤二:模拟官方的 while 递增发点逻辑,初始化
        q = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]

        print("提示: 正在高频发送实时点位 (1轴 0° -> 60°)...")

        try:
            while q[0] < 60.0:
                q[0] += 0.1  # 每次递增 1 度

                # 核心发点(函数内部已封装:自动用 7000 端口,且自动把 6 轴补齐为 7 轴)
                arm_test.set_servo_joint_position(q)

                time.sleep(0.01)  # 维持官方的 10ms (100Hz) 发送频率

        except Exception as e:
            print(f"警告: 发点循环中途发生异常: {e}")

        # 保持 5 秒(对齐官方示例)
        time.sleep(5.0)

        # 步骤三:安全关闭关节跟踪模式(严格锁定 7000 端口)
        arm_test.close_servo_joint()
        print("=== 跟踪测试结束 ===")

3. 关节运动到目标点 robot_movej 使用示例

Python
import nrc_interface as nrc
import time

def move_joint(self, target_angles: list, velocity: int = 20, acc: int = 50, dec: int = 50, pl: int = 0) -> bool:
    """
    实时运动控制:让机械臂立刻以关节运动(MoveJ)奔向目标角度!
    :param target_angles: 目标关节角度列表,如 [10.0, 0.0, 0.0, 0.0, 0.0, 0.0]
    :param velocity: 实时运动速度 (1 ~ 100)
    :param pl: 实时到达平滑度
    :return: 成功返回 True,失败返回 False
    """
    # 【统一拦截】严格对齐常规指令通道 (socket_fd) 拦截流标准与日志
    if not self.socket_fd or self.socket_fd <= 0:
        print("错误: 机械臂未连接 (socket_fd 无效)。")
        return False

    try:
        move_cmd = nrc.MoveCmd()

        # 按照官方示例潜规则:实时指令通常固定开辟 7 个空间
        # 前 6 位为本体轴,第 7 位为外部轴(没有外部轴则填 0)
        cmd_len = 7
        move_cmd.targetPosValue.resize(cmd_len)

        # 逐个安全赋值,防止数组越界,不足 7 位的后面自动补 0.0
        for i in range(cmd_len):
            if i < len(target_angles):
                move_cmd.targetPosValue[i] = target_angles[i]
            else:
                move_cmd.targetPosValue[i] = 0.0

        # 设置实时运动必填参数
        move_cmd.coord = 0          # 0: 关节空间模式
        move_cmd.velocity = velocity
        move_cmd.acc = acc
        move_cmd.dec = dec
        move_cmd.pl = pl              # 实时到达平滑度

        # 核心底层知识:因为是直接发送裸数据给电机,不需要在示教器建表
        # 所以这里不需要像之前那样设置 targetPosType=1 和 targetPosName

        print("成功: 正在下发实时单步动作...")
        # 调用官方实时关节运动接口
        ret = nrc.robot_movej(self.socket_fd, move_cmd)

        # 【统一日志】对齐 "成功/错误" 的工业级日志前缀
        if ret == 0:
            print(f"成功: 机械臂正奔向 -> {target_angles}")
            return True
        else:
            print(f"错误: 实时运动指令下发失败,底层错误码: {ret} (提示: 请检查机械臂是否已正常上电)")
            return False
    except Exception as e:
        print(f"异常: 实时运动异常: {e}")
        return False

if __name__ == '__main__':
    # 1 地址通信
    arm_test = RobotArmTest(ip="192.168.1.13", dof=6)
    if arm_test._connect_robot() == 0:
        safe_target = [20.0, 10.0, 0.0, 0.0, 0.0, 0.0]
        arm_test.move_joint(target_angles=safe_target)

4. 直线运动到目标位置 robot_movel 使用示例

Python
import nrc_interface as nrc
import time

def move_linear(self, target_coords: list, velocity: int = 20, acc: int = 50, dec: int = 50, pl: int = 0) -> bool:
    """
    实时直线运动控制:让机械臂末端立刻沿直线奔向目标直角坐标!
    :param target_coords: 目标直角坐标列表,如 [320.5, -45.0, 180.0, 3.14, 0.0, 0.0]
    :param velocity: 实时运动速度百分比 (1 ~ 100)
    :param pl: 轨迹平滑度等级 (0 代表精准到位)
    :return: 成功返回 True, 失败返回 False
    """
    # 【统一拦截】严格对齐常规指令通道 (socket_fd) 拦截流标准
    if not self.socket_fd or self.socket_fd <= 0:
        print("错误: 机械臂未连接 (socket_fd 无效)。")
        return False

    try:
        move_cmd = nrc.MoveCmd()

        # 遵照官方实时指令潜规则:固定开辟 7 个空间
        # 前 6 位为直角坐标 [X, Y, Z, A, B, C],第 7 位为外部轴(填 0.0)
        cmd_len = 7
        move_cmd.targetPosValue.resize(cmd_len)

        # 逐个安全赋值
        for i in range(cmd_len):
            if i < len(target_coords):
                move_cmd.targetPosValue[i] = target_coords[i]
            else:
                move_cmd.targetPosValue[i] = 0.0

        # 设置实时直线运动参数
        move_cmd.coord = 0                      # 0: 官方示例指定的基坐标系
        move_cmd.velocity = velocity
        move_cmd.velocitySync = velocity       # 双保险控速参数
        move_cmd.acc = acc
        move_cmd.dec = dec
        move_cmd.pl = pl

        print(f"成功: 正在下发实时直线动作,目标坐标: {target_coords[:6]}...")
        # 调用官方实时直线运动接口
        ret = nrc.robot_movel(self.socket_fd, move_cmd)

        # 【统一日志】工业级标准化前缀输出
        if ret == 0:
            print("成功: 实时直线运动指令发送成功!")
            return True
        else:
            print(f"错误: 实时直线运动下发失败,底层错误码: {ret}")
            return False
    except Exception as e:
        print(f"异常: 实时直线运动异常: {e}")
        return False

if __name__ == '__main__':
    # 1 地址通信
    arm_test = RobotArmTest(ip="192.168.1.13", dof=6)
    if arm_test._connect_robot() == 0:
        safe_cartesian_target = [220.0, -0.065, 143.139, 3.141, 0.0, 0.0]
        arm_test.move_linear(target_coords=safe_cartesian_target)

5. 点动使用示例

Python
import nrc_interface as nrc
import time

def start_robot_jogging(self, axis: int, direction: int) -> bool:
    """
    启动机械臂点动连续运动
    :param axis: 轴号 (1~7 代表第 1~7 轴)
    :param direction: 方向 (1: 正向, 0 或 -1: 反向)
    :return: 成功返回True, 失败返回False
    """
    try:
        # 方向转换:1→正向(True),其他→反向(False)
        is_positive = direction == 1

        # 调用底层SDK接口
        ret = nrc.robot_start_jogging(self.socket_fd, axis, is_positive)

        if ret != 0:
            raise RuntimeError(f"SDK接口返回错误码 {ret}")

        print(f"成功:启动{axis}轴点动运动,方向:{'正向' if is_positive else '反向'}")
        return True

    except Exception as e:
        print(f"错误:启动点动连续运动失败,原因:{e}")
        return False

if __name__ == '__main__':
    # 1 地址通信
    arm_test = RobotArmTest(ip="192.168.1.13", dof=6)

    if arm_test._connect_robot() == 0:
        # 测试启动点动连续运动(速度控制每次转的角度)
        for _ in range(75):
            arm_test.start_robot_jogging(axis=4, direction=0)
            time.sleep(0.04)

6. 作业文件插入指令使用示例

Python
import nrc_interface as nrc
import time

def open_job(self, job_name: str) -> bool:
    """
    打开指定的作业文件 (相当于在示教器上选中并打开某个程序)
    :param job_name: 作业文件的名称 (比如 "TEST" 或 "TEST.JOB")
    :return: 成功返回 True, 失败返回 False
    """
    # 【统一拦截】严格对齐常规指令通道 (socket_fd) 拦截流标准与日志
    if not self.socket_fd or self.socket_fd <= 0:
        print("错误: 机械臂未连接 (socket_fd 无效)。")
        return False

    try:
        # 调用底层接口,告诉控制器我们要操作哪个文件
        ret = nrc.job_open(self.socket_fd, job_name)

        # 【统一日志】对齐 "成功/错误" 的工业级日志前缀
        if ret == 0:
            print(f"成功: 打开作业文件成功 -> {job_name}")
            return True
        else:
            print(f"错误: 打开作业文件失败,底层错误码: {ret}")
            return False
    except Exception as e:
        print(f"异常: 打开作业文件异常: {e}")
        return False

def insert_job_moveJ(self, line: int = 1, target_angles: list = None, velocity: int = 5, acc: int = 20, dec: int = 20, pos_name: str = "P0001") -> bool:
    """
    在作业文件指定行插入 MoveJ (关节运动) 指令 - 官方指定 P 变量模式
    :param line: 插入的行号
    :param target_angles: 目标关节角度列表
    :param velocity: 运行速度
    :param acc: 加速度
    :param dec: 减速度
    :param pos_name: 点位变量名,例如 "P0001"
    :return: 成功返回 True,失败返回 False
    """
    if not self.socket_fd or self.socket_fd <= 0:
        print("未连接,无法插入指令")
        return False

    if target_angles is None:
        target_angles = [0.0] * self.dof

    try:
        move_cmd = nrc.MoveCmd()

        # 1. 官方指定的数组赋值方式
        pos = nrc.VectorDouble(self.dof)
        for i in range(min(self.dof, len(target_angles))):
            pos[i] = target_angles[i]
        move_cmd.targetPosValue = pos

        # 2. 官方核心潜规则:使用点位变量 (P变量)
        move_cmd.targetPosType = 1              # 1 代表使用变量名
        move_cmd.targetPosName = pos_name       # 给这个点位起个名字,比如 "P0001"
        move_cmd.coord = 0                    # 0 代表关节坐标系

        # 3. 速度与平滑度设置
        move_cmd.velocity = velocity
        move_cmd.velocitySync = velocity       # 官方同步速度
        move_cmd.acc = acc
        move_cmd.dec = dec
        move_cmd.pl = 0                         # 精准到达先用 0

        # 4. 下发指令
        ret = nrc.job_insert_moveJ(self.socket_fd, line, move_cmd)

        if ret == 0:
            print(f"成功在第 {line} 行插入 MoveJ 指令!绑定点位: {pos_name}, 角度: {target_angles[:self.dof]}")
            return True
        else:
            print(f"插入 MoveJ 指令失败,错误码: {ret}")
            return False
    except Exception as e:
        print(f"插入 MoveJ 指令异常: {e}")
        return False

def insert_job_moveL(self, line: int = 1, target_coords: list = None, velocity: int = 20, acc: int = 20, dec: int = 20, pos_name: str = "P0001") -> bool:
    """
    在作业文件指定行插入 MoveL (笛卡尔空间直线运动) 指令 - 官方 P 变量版
    :param pos_name: 点位变量名,例如 "P0002"
    """
    if target_coords is None:
        target_coords = [0.0] * 6

    if self.socket_fd and self.socket_fd > 0:
        try:
            move_cmd = nrc.MoveCmd()

            # 1. 官方指定的数组赋值方式
            coord_len = len(target_coords)
            pos = nrc.VectorDouble(coord_len)
            for i in range(coord_len):
                pos[i] = target_coords[i]
            move_cmd.targetPosValue = pos

            # 2. 官方核心潜规则
            move_cmd.targetPosType = 1              # 使用点位变量
            move_cmd.targetPosName = pos_name       # 分配变量名
            move_cmd.coord = 1                    # 【关键】1 代表直角坐标系(笛卡尔)

            # 3. 运动参数
            move_cmd.velocity = velocity
            move_cmd.velocitySync = velocity
            move_cmd.acc = acc
            move_cmd.dec = dec
            move_cmd.pl = 0

            # 4. 下发指令
            ret = nrc.job_insert_moveL(self.socket_fd, line, move_cmd)

            if ret == 0:
                print(f"✅ 成功在第 {line} 行插入 MoveL 指令!绑定点位: {pos_name}, 坐标: {target_coords}")
                return True
            else:
                print(f"❌ 插入 MoveL 指令失败,错误码: {ret}")
                return False
        except Exception as e:
            print(f"❌ 插入 MoveL 指令异常: {e}")
            return False
    print("未连接,无法插入指令")
    return False

def insert_job_moveC(self, line: int = 1, target_coords: list = None, velocity: int = 20, acc: int = 20, dec: int = 20, pos_name: str = "P0003") -> bool:
    """
    在作业文件指定行插入 MoveC (笛卡尔空间圆弧运动) 指令 - 官方 P 变量版
    :param line: 插入的行号
    :param target_coords: 目标直角坐标列表
    :param velocity: 运行速度
    :param acc: 加速度
    :param dec: 减速度
    :param pos_name: 点位变量名,圆弧建议传入 "P0003" (中间点) 或 "P0004" (终点)
    :return: 成功返回 True,失败返回 False
    """
    # 【统一拦截】严格对齐常规指令通道 (socket_fd) 拦截流标准与日志
    if not self.socket_fd or self.socket_fd <= 0:
        print("错误: 机械臂未连接 (socket_fd 无效)。")
        return False

    if target_coords is None:
        target_coords = [0.0] * 6

    try:
        move_cmd = nrc.MoveCmd()

        # 1. 官方指定的数组赋值方式
        coord_len = len(target_coords)
        pos = nrc.VectorDouble(coord_len)
        for i in range(coord_len):
            pos[i] = target_coords[i]
        move_cmd.targetPosValue = pos

        # 2. 官方核心潜规则
        move_cmd.targetPosType = 1              # 使用点位变量
        move_cmd.targetPosName = pos_name       # 分配变量名
        move_cmd.coord = 1                    # 1 代表直角/笛卡尔坐标系

        # 3. 运动参数
        move_cmd.velocity = velocity
        move_cmd.velocitySync = velocity
        move_cmd.acc = acc
        move_cmd.dec = dec
        move_cmd.pl = 0                       # 圆弧通常要求精准过点,设为 0

        # 4. 下发指令
        ret = nrc.job_insert_moveC(self.socket_fd, line, move_cmd)

        # 【统一日志】对齐 "成功/错误" 的工业级日志前缀
        if ret == 0:
            print(f"成功: 在第 {line} 行插入 MoveC 指令!绑定点位: {pos_name}, 坐标: {target_coords}")
            return True
        else:
            print(f"错误: 插入 MoveC 指令失败,底层错误码: {ret}")
            return False
    except Exception as e:
        print(f"异常: 插入 MoveC 指令异常: {e}")
        return False

if __name__ == '__main__':
    # 1 地址通信
    arm_test = RobotArmTest(ip="192.168.1.13", dof=6)
    if arm_test._connect_robot() == 0:

        target_open_name = "TEST2"
        arm_test.open_job(job_name=target_open_name)

        # 测试在作业文件中插入 MoveJ 运动指令,在第 1 行插入一个指令
        my_target_angles = [10.0, 10.0, 0.0, 0.0, 0.0, 0.0]
        arm_test.insert_job_moveJ(line=1, target_angles=my_target_angles, velocity=10)

        # 测试在作业文件中插入 MoveL 直线运动指令,[X, Y, Z, A, B, C],单位通常是 mm 和 rad(弧度)
        my_coords = [320.5, -45.0, 0.0, 0, 3.14, 0.0]
        arm_test.insert_job_moveL(line=1, target_coords=my_coords, velocity=20)

        # 测试在作业文件中插入 MoveC 圆弧运动指令,作为圆弧的途经点或终点
        arc_target_coords = [350.0, 0.0, 200.0, 3.14, 0.0, 0.0]
        arm_test.insert_job_moveC(line=2, target_coords=arc_target_coords, velocity=20)

7. 队列运动指令使用示例

Python
import nrc_interface as nrc
import time

def set_queue_motion_status(self, status: bool) -> int:
    """
    设置队列运动模式状态
    :param status: True 为打开队列运动, False 为关闭队列运动
    :return: 底层接口返回值 (0 代表成功,非 0 代表失败错误码,-1 代表断连异常)
    """
    # 【统一拦截】严格对齐常规指令通道 (socket_fd) 拦截流标准与失败返回值 -1
    if not self.socket_fd or self.socket_fd <= 0:
        print("错误: 机械臂未连接 (socket_fd 无效)。")
        return -1

    try:
        # 调用标准底层接口
        ret = nrc.queue_motion_set_status(self.socket_fd, status)

        status_name = "打开" if status else "关闭"
        # 【统一日志】工业级标准化前缀输出,扁平化分支逻辑
        if ret == 0:
            print(f"成功: 队列运动模式 [{status_name}] 执行完毕。")
        else:
            print(f"错误: 队列运动模式 [{status_name}] 失败,底层错误码: {ret}")
        return ret
    except Exception as e:
        print(f"异常: 设置队列运动模式状态发生未知异常: {e}")
        return -1

def execute_queue(self, size: int, is_continue: bool = False) -> int:
    """
    将本地队列数据发送到控制器并执行
    :param size: 要发送的队列大小, 0 代表发送全部指令,有效范围 [0, 31]
    :param is_continue: 是否继续执行未完成的队列,默认为 False
    :return: 底层接口返回值 (0 代表成功,非 0 代表失败错误码,-2 代表断连异常)
    """
    # 【统一拦截】严格对齐常规指令通道 (socket_fd) 拦截流标准与原代码返回值 -2
    if not self.socket_fd or self.socket_fd <= 0:
        print("错误: 激活队列执行失败,未建立有效网络连接 (socket_fd 无效)。")
        return -2

    try:
        # 调用底层标准接口
        ret = nrc.queue_motion_send_to_controller(self.socket_fd, size, is_continue)

        # 【统一日志】工业级标准化前缀输出,扁平化逻辑分支
        if ret == 0:
            target_desc = "全部" if size == 0 else f"前 {size} 个"
            print(f"成功: 已将 {target_desc} 队列数据发送至控制器并开始执行。")
        else:
            print(f"错误: 队列下发失败,底层错误码: {ret}")
        return ret
    except Exception as e:
        print(f"异常: 激活队列执行发生未知异常: {e}")
        return -1

def queue_moveJ(self, pos_list: list, velocity: int = 30, acc: int = 20, dec: int = 20, coord: int = 0) -> int:
    """
    向本地运动队列尾部插入一条 MoveJ 指令
    :param pos_list: 目标位置列表 (关节系为各轴度数,直角系为 X/Y/Z/RX/RY/RZ)
    :param coord: 坐标系类型 (0: 关节坐标系, 1: 直角坐标系),默认 0
    :return: 底层接口返回值 (0 代表成功,非 0 代表失败错误码,-2 代表断连异常)
    """
    # 【统一拦截】严格对齐常规指令通道 (socket_fd) 拦截流标准与原代码返回值 -2
    if not self.socket_fd or self.socket_fd <= 0:
        print("错误: 压入队列 MoveJ 指令失败,未建立有效网络连接 (socket_fd 无效)。")
        return -2

    try:
        # 1. 将 Python 列表转换为底层所需的 VectorDouble 类型
        pos = nrc.VectorDouble(len(pos_list))
        for i, val in enumerate(pos_list):
            pos[i] = float(val)

        # 2. 实例化并配置底层的运动命令结构体
        move_cmd = nrc.MoveCmd()
        move_cmd.coord = coord
        move_cmd.targetPosType = nrc.PosType_data  # 固定为数据点位模式
        move_cmd.targetPosValue = pos
        move_cmd.velocity = velocity
        move_cmd.acc = acc
        move_cmd.dec = dec
        move_cmd.pl = 0                         # 队列平滑过渡等级 (通常由队列机制自动融合)

        # 3. 调用底层接口压入本地队列尾部
        ret = nrc.queue_motion_push_back_moveJ(self.socket_fd, move_cmd)

        # 【统一日志】工业级标准化前缀输出
        if ret == 0:
            print(f"成功: MoveJ 轨迹点已成功压入本地运动队列尾部 -> 目标点: {pos_list}")
        else:
            print(f"错误: 压入队列 MoveJ 指令失败,底层错误码: {ret}")
        return ret
    except Exception as e:
        print(f"异常: 压入队列 MoveJ 发生未知异常: {e}")
        return -1

def queue_moveL(self, pos_list: list, velocity: int = 10, acc: int = 20, dec: int = 20, coord: int = 1) -> int:
    """
    向本地运动队列尾部插入一条 MoveL 直线指令
    :param pos_list: 目标直角坐标列表 [X, Y, Z, RX, RY, RZ]
    :param coord: 坐标系类型 (直线运动通常默认为 1: 基座直角坐标系)
    :return: 底层接口返回值 (0 代表成功,非 0 代表失败错误码,-2 代表断连异常)
    """
    # 【统一拦截】严格对齐常规指令通道 (socket_fd) 拦截流标准与原代码返回值 -2
    if not self.socket_fd or self.socket_fd <= 0:
        print("错误: 压入队列 MoveL 指令失败,未建立有效网络连接 (socket_fd 无效)。")
        return -2

    try:
        # 1. 将 Python 列表转换为底层所需的 VectorDouble 类型
        pos = nrc.VectorDouble(len(pos_list))
        for i, val in enumerate(pos_list):
            pos[i] = float(val)

        # 2. 实例化并配置底层的运动命令结构体
        move_cmd = nrc.MoveCmd()
        move_cmd.coord = coord
        move_cmd.targetPosType = nrc.PosType_data  # 固定为数据点位模式
        move_cmd.targetPosValue = pos
        move_cmd.velocity = velocity
        move_cmd.acc = acc
        move_cmd.dec = dec
        move_cmd.pl = 0                         # 队列平滑过渡等级 (通常由队列机制自动融合)

        # 3. 调用底层 MoveL 接口压入本地队列尾部
        ret = nrc.queue_motion_push_back_moveL(self.socket_fd, move_cmd)

        # 【统一日志】工业级标准化前缀输出
        if ret == 0:
            print(f"成功: MoveL 直线轨迹点已成功压入本地运动队列尾部 -> 目标点: {pos_list}")
        else:
            print(f"错误: 压入队列 MoveL 指令失败,底层错误码: {ret}")
        return ret
    except Exception as e:
        print(f"异常: 压入队列 MoveL 发生未知异常: {e}")
        return -1

def queue_moveC(self, pos_list: list, velocity: int = 10, acc: int = 20, dec: int = 20, coord: int = 1) -> int:
    """
    向本地运动队列尾部插入一条 MoveC 三点圆弧指令
    :param pos_list: 包含中间点和终点的 12 维直角坐标列表 [中间点 X/Y/Z/RX/RY/RZ, 终点 X/Y/Z/RX/RY/RZ]
    :param coord: 坐标系类型 (圆弧运动通常默认为 1: 基座直角坐标系)
    :return: 底层接口返回值 (0 代表成功,非 0 代表失败错误码,-2 代表断连异常)
    """
    # 【统一拦截】严格对齐常规指令通道 (socket_fd) 拦截流标准与原代码返回值 -2
    if not self.socket_fd or self.socket_fd <= 0:
        print("错误: 压入队列 MoveC 指令失败,未建立有效网络连接 (socket_fd 无效)。")
        return -2

    try:
        # 1. 将 12 维 Python 列表转换为底层所需的 VectorDouble 类型
        pos = nrc.VectorDouble(len(pos_list))
        for i, val in enumerate(pos_list):
            pos[i] = float(val)

        # 2. 实例化并配置底层的运动命令结构体
        move_cmd = nrc.MoveCmd()
        move_cmd.coord = coord
        move_cmd.targetPosType = nrc.PosType_data  # 固定为数据点位模式
        move_cmd.targetPosValue = pos
        move_cmd.velocity = velocity
        move_cmd.acc = acc
        move_cmd.dec = dec
        move_cmd.pl = 0                         # 队列平滑过渡等级 (通常由队列机制自动融合)

        # 3. 调用底层 MoveC 接口压入本地队列尾部
        ret = nrc.queue_motion_push_back_moveC(self.socket_fd, move_cmd)

        # 【统一日志】工业级标准化前缀输出
        if ret == 0:
            print("成功: MoveC 圆弧轨迹点已成功压入本地运动队列尾部 -> 包含 12 维中间点与终点数据。")
        else:
            print(f"错误: 压入队列 MoveC 指令失败,底层错误码: {ret}")
        return ret
    except Exception as e:
        print(f"异常: 压入队列 MoveC 发生未知异常: {e}")
        return -1

def queue_moveS(self, pos_list: list, velocity: int = 10, acc: int = 20, dec: int = 20, coord: int = 1) -> int:
    """
    向本地运动队列尾部插入一条 MoveS 样条曲线指令
    :param pos_list: 目标直角坐标列表 [X, Y, Z, RX, RY, RZ]
    :param coord: 坐标系类型 (曲线运动通常默认为 1: 基座直角坐标系)
    :return: 底层接口返回值 (0 代表成功,非 0 代表失败错误码,-2 代表断连异常)
    """
    # 【统一拦截】严格对齐常规指令通道 (socket_fd) 拦截流标准与原代码返回值 -2
    if not self.socket_fd or self.socket_fd <= 0:
        print("错误: 压入队列 MoveS 指令失败,未建立有效网络连接 (socket_fd 无效)。")
        return -2

    try:
        # 1. 将 Python 列表转换为底层所需的 VectorDouble 类型
        pos = nrc.VectorDouble(len(pos_list))
        for i, val in enumerate(pos_list):
            pos[i] = float(val)

        # 2. 实例化并配置底层的运动命令结构体
        move_cmd = nrc.MoveCmd()
        move_cmd.coord = coord
        move_cmd.targetPosType = nrc.PosType_data  # 固定为数据点位模式
        move_cmd.targetPosValue = pos
        move_cmd.velocity = velocity
        move_cmd.acc = acc
        move_cmd.dec = dec
        move_cmd.pl = 0                         # 队列平滑过渡等级 (通常由队列机制自动融合)

        # 3. 调用底层 MoveS 接口压入本地队列尾部
        ret = nrc.queue_motion_push_back_moveS(self.socket_fd, move_cmd)

        # 【统一日志】工业级标准化前缀输出
        if ret == 0:
            print(f"成功: MoveS 样条曲线路点已成功压入本地运动队列尾部 -> 目标点: {pos_list}")
        else:
            print(f"错误: 压入队列 MoveS 指令失败,底层错误码: {ret}")
        return ret
    except Exception as e:
        print(f"异常: 压入队列 MoveS 发生未知异常: {e}")
        return -1

if __name__ == '__main__':
    # 1 地址通信
    arm_test = RobotArmTest(ip="192.168.1.13", dof=6)

    if arm_test._connect_robot() == 0:

        # 1. 设置全局运动运行速度(安全低速)
        nrc.set_speed(arm_test.socket_fd, 20)
        time.sleep(1.0)

        # 2. 步骤一:打开队列运动模式
        # 此时控制器开始建立 FIFO 缓存,机械臂保持静止
        arm_test.set_queue_motion_status(status=True)
        time.sleep(2.0)

        # 3. 步骤二:向本地队列不间断地"灌入"连续点位数据
        # 这里的点位以 6 轴机械臂为例(如果是 7 轴请自行补齐一位),控制 A1 轴进行来回摆动
        point_start = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]   # 起点(初始回零位置)
        point_left  = [30.0, 0.0, 0.0, 0.0, 0.0, 0.0]  # 途经点A(A1轴转动30度)
        point_right = [-30.0, 0.0, 0.0, 0.0, 0.0, 0.0] # 途经点B(A1轴转动-30度)
        point_movel1 = [197.0, -115.0, 140.0, -3.14, 0.0, 0]

        # 依次压入队列尾部,此时仅做数据写入,机械臂依然保持静止
        arm_test.queue_moveJ(pos_list=point_start)
        arm_test.queue_moveJ(pos_list=point_left)
        arm_test.queue_moveJ(pos_list=point_right)
        arm_test.queue_moveL(pos_list=point_movel1, velocity=20)
        arm_test.queue_moveJ(pos_list=point_start) # 最终回到起点

        # 4. 步骤三:批量发送数据并激活执行
        # size=0 代表将当前写入缓冲区的 4 个点位指令全部一次性发送
        arm_test.execute_queue(size=0, is_continue=False)

        # 5. 步骤四:物理运动保持延时
        # 队列下发后,Python 脚本会继续向下执行。为了防止脚本立刻关闭连接,
        # 必须主观挂起线程,预留充足的时间给机器人硬件跑完这段连续轨迹。
        print("提示: 机械臂正在执行连续队列运动")
        time.sleep(40.0)

        # 6. 步骤五:完成运动后清理并关闭队列模式
        # 恢复常规控制模式,确保安全
        arm_test.set_queue_motion_status(status=False)