primary 的使用

一、简介

primary类提供读取指定数据包、注册异常回调、向机器人发送脚本等功能

二、操作流程

1、安装elite python sdk,确保sdk安装正确、解释器使用python版本正确
2、进入示例代码所在文件夹,打开cmd
3、执行这行代码:python example_dashboard_client.py --ip 192.168.0.1 ,请注意,这里example_dashboard_client.py是文件名,需要替换成真实文件名,--ip参数后输入的是机器人的ip地址,也需要根据实际ip输入

三、常见问题

1、Q:为什么sdk安装后,ide却提示找不到这个库呢?
A:首先请确认安装的python wheel基于什么版本编译的,和使用的版本是否有差异,其次,需要确认当前环境变量里优先级最高的python版本和pip版本,与ide中的解释器使用的是否是同一版本,如果不是可以修改环境变量后重新安装sdk,也可以修改解释器版本
2、只能通过控制台执行这个文件吗?能否通过ide直接执行?
A:这里使用了argparse解析参数,所以只需要将这里参数解析部分删除,直接指定ip, port即可

四、代码和附件

  1. 解析参数 --ip(必传)和 --port(默认 30001)
  2. PrimaryClientInterface() 构造接口对象
  3. connect(ip, port) 连 Primary Port
  4. 自定义 CartesianInfoPackage(4) 继承 PrimaryPackageparser() 里用 struct.unpack_from 解析 TCP 位姿(x/y/z/rot)及偏移量(offset)共 14 个字段
  5. getPackage(robot_conf, 1000) 获取并解析笛卡尔信息包
  6. getPackage(kine, 1000) 获取运动学信息包,读出 DH 参数 dh_a_ / dh_d_ / dh_alpha_
  7. registerRobotExceptionCallback(exceptionCb) 注册异常回调,回调里区分 RobotError(错误码)和 RobotRuntimeException(运行时消息)
  8. sendScript(b"def hello():...") 发送正常脚本(示教器弹 “hello world”)→ sleep(3)
  9. sendScript(b"def func():\n abcd(123)...") 发送故意写错的脚本触发异常回调 → sleep(3)
  10. disconnect() 断开
#!/usr/bin/env python3
"""
Example script for using the elite_cs_sdk PrimaryClientInterface.

中文说明:
这个示例展示如何连接机器人的 Primary 端口,
读取指定数据包、注册异常回调,并向机器人发送脚本。

Usage:
    python example_primary_client.py --ip 192.168.0.58
"""

import argparse
import elite_cs_sdk as cs
import time
import struct
import sys


class CartesianInfoPackage(cs.PrimaryPackage):
    # 自定义主接口数据包解析器,用于解析 TCP 位姿及相关偏移数据。
    def __init__(self):
        super().__init__(4)

    def parser(self, data: bytes):
        vars = [
            "msg_len", "msg_type", "tcp_x", "tcp_y", "tcp_z",
            "rot_x", "rot_y", "rot_z", "offset_px", "offset_py",
            "offset_pz", "offset_rotx", "offset_roty", "offset_rotz"
        ]
        values = struct.unpack_from('>iBdddddddddddd', data)

        for name, value in zip(vars, values):
            print(f"{name}: {value}")


def exceptionCb(ex):
    # 机器人异常回调:统一打印异常类型及附加信息。
    print(f"Exception: {ex.getType()}")
    print(f"\ttimestamp: {ex.getTimeStamp()}")
    if isinstance(ex, cs.RobotError):
        print(f"\terror code: {ex.getErrorCode()}")
        print(f"\terror sub-code: {ex.getSubErrorCode()}")
    elif isinstance(ex, cs.RobotRuntimeException):
        print(f"\tmessage: {ex.getMessage()}")


def main():
    parser = argparse.ArgumentParser(
        description="Connect to a robot's primary port and perform basic operations."
    )
    parser.add_argument(
        "--ip",
        required=True,
        help="IP address of the robot's primary port"
    )
    parser.add_argument(
        "--port",
        type=int,
        default=30001,
        help="Port number of the Robot Primary Port (default: 30001)"
    )
    args = parser.parse_args()

    ip, port = args.ip, args.port

    pr = cs.PrimaryClientInterface()

    if pr.connect(ip, port):
        print("Success connected robot")
    else:
        print("Connect robot fail")
        exit(1)

    print("Wait get robot cartesian info")
    robot_conf = CartesianInfoPackage()
    pr.getPackage(robot_conf, 1000)

    # 读取运动学参数信息。
    kine = cs.KinematicsInfo()
    pr.getPackage(kine, 1000)
    print(f"DH A: {kine.dh_a_}")
    print(f"DH D: {kine.dh_d_}")
    print(f"DH Alpha: {kine.dh_alpha_}")

    # 注册机器人异常回调函数。
    pr.registerRobotExceptionCallback(exceptionCb)

    print("Send \"hello\" script to robot")
    pr.sendScript(b"def hello():\n\ttextmsg(\"hello world\")\nend\n")
    print("Sended \"hello\" script to robot")
    time.sleep(3)

    # 再发送一个包含错误调用的脚本,用于触发异常回调示例。
    print("Send a script with anomalies to the robot")
    pr.sendScript(b"def func():\n\tabcd(123)\nend\n")
    print("Sended a script with anomalies to the robot")
    time.sleep(3)

    pr.disconnect()


if __name__ == "__main__":
    try:
        main()
    except Exception as e:
        print(f"[ERROR] {e}", file=sys.stderr)
        sys.exit(1)