├── unitree_sdk2py ├── core │ ├── __init__.py │ ├── channel_name.py │ └── channel_config.py ├── go2 │ ├── __init__.py │ ├── sport │ │ ├── __init__.py │ │ └── sport_api.py │ ├── video │ │ ├── __init__.py │ │ ├── video_api.py │ │ └── video_client.py │ ├── vui │ │ ├── __init__.py │ │ ├── vui_api.py │ │ └── vui_client.py │ ├── robot_state │ │ ├── __init__.py │ │ ├── robot_state_api.py │ │ └── robot_state_client.py │ └── obstacles_avoid │ │ ├── __init__.py │ │ ├── obstacles_avoid_api.py │ │ └── obstacles_avoid_client.py ├── rpc │ ├── __init__.py │ ├── internal.py │ ├── server_base.py │ ├── request_future.py │ ├── client_stub.py │ ├── server_stub.py │ └── lease_client.py ├── utils │ ├── __init__.py │ ├── lib │ │ ├── crc_amd64.so │ │ └── crc_aarch64.so │ ├── singleton.py │ ├── clib_lookup.py │ ├── hz_sample.py │ ├── timerfd.py │ ├── bqueue.py │ ├── thread.py │ └── future.py ├── comm │ └── motion_switcher │ │ ├── __init__.py │ │ ├── motion_switcher_api.py │ │ └── motion_switcher_client.py ├── __init__.py ├── test │ ├── helloworld │ │ ├── helloworld.py │ │ ├── subscriber.py │ │ └── publisher.py │ ├── rpc │ │ ├── test_api.py │ │ ├── test_server_example.py │ │ └── test_client_example.py │ ├── lowlevel │ │ ├── unitree_go2_const.py │ │ ├── sub_lowstate.py │ │ ├── read_lowstate.py │ │ └── lowlevel_control.py │ ├── crc │ │ └── test_crc.py │ └── client │ │ ├── video_client_example.py │ │ ├── robot_service_client_example.py │ │ ├── vui_client_example.py │ │ ├── obstacles_avoid_client_example.py │ │ └── sport_client_example.py ├── idl │ ├── nav_msgs │ │ ├── __init__.py │ │ └── msg │ │ │ ├── __init__.py │ │ │ └── dds_ │ │ │ ├── __init__.py │ │ │ ├── _OccupancyGrid_.py │ │ │ ├── _Odometry_.py │ │ │ └── _MapMetaData_.py │ ├── std_msgs │ │ ├── __init__.py │ │ └── msg │ │ │ ├── __init__.py │ │ │ └── dds_ │ │ │ ├── __init__.py │ │ │ ├── _String_.py │ │ │ └── _Header_.py │ ├── sensor_msgs │ │ ├── __init__.py │ │ └── msg │ │ │ ├── __init__.py │ │ │ └── dds_ │ │ │ ├── __init__.py │ │ │ ├── PointField_Constants │ │ │ ├── __init__.py │ │ │ └── _PointField_.py │ │ │ ├── _PointField_.py │ │ │ └── _PointCloud2_.py │ ├── unitree_api │ │ ├── __init__.py │ │ └── msg │ │ │ ├── __init__.py │ │ │ └── dds_ │ │ │ ├── __init__.py │ │ │ ├── _RequestLease_.py │ │ │ ├── _ResponseStatus_.py │ │ │ ├── _RequestPolicy_.py │ │ │ ├── _RequestIdentity_.py │ │ │ ├── _Request_.py │ │ │ ├── _Response_.py │ │ │ ├── _ResponseHeader_.py │ │ │ └── _RequestHeader_.py │ ├── unitree_go │ │ ├── __init__.py │ │ └── msg │ │ │ ├── __init__.py │ │ │ └── dds_ │ │ │ ├── _Req_.py │ │ │ ├── _UwbSwitch_.py │ │ │ ├── _Error_.py │ │ │ ├── _MotorCmds_.py │ │ │ ├── _MotorStates_.py │ │ │ ├── _TimeSpec_.py │ │ │ ├── _BmsCmd_.py │ │ │ ├── _Res_.py │ │ │ ├── _AudioData_.py │ │ │ ├── _InterfaceConfig_.py │ │ │ ├── _WirelessController_.py │ │ │ ├── _PathPoint_.py │ │ │ ├── _MotorCmd_.py │ │ │ ├── _Go2FrontVideoData_.py │ │ │ ├── _IMUState_.py │ │ │ ├── _HeightMap_.py │ │ │ ├── _BmsState_.py │ │ │ ├── _MotorState_.py │ │ │ ├── _UwbState_.py │ │ │ ├── _LowCmd_.py │ │ │ ├── _LidarState_.py │ │ │ ├── __init__.py │ │ │ ├── _SportModeState_.py │ │ │ └── _LowState_.py │ ├── unitree_hg │ │ ├── __init__.py │ │ ├── msg │ │ │ ├── __init__.py │ │ │ ├── .idlpy_manifest │ │ │ └── dds_ │ │ │ │ ├── .idlpy_manifest │ │ │ │ ├── _BmsCmd_.py │ │ │ │ ├── __init__.py │ │ │ │ ├── _HandCmd_.py │ │ │ │ ├── _MotorCmd_.py │ │ │ │ ├── _PressSensorState_.py │ │ │ │ ├── _MainBoardState_.py │ │ │ │ ├── _LowCmd_.py │ │ │ │ ├── _IMUState_.py │ │ │ │ ├── _MotorState_.py │ │ │ │ ├── _LowState_.py │ │ │ │ ├── _BmsState_.py │ │ │ │ └── _HandState_.py │ │ └── .idlpy_manifest │ ├── geometry_msgs │ │ ├── __init__.py │ │ └── msg │ │ │ ├── __init__.py │ │ │ └── dds_ │ │ │ ├── _Point_.py │ │ │ ├── _Point32_.py │ │ │ ├── _Pose2D_.py │ │ │ ├── _Vector3_.py │ │ │ ├── _Quaternion_.py │ │ │ ├── _Pose_.py │ │ │ ├── _Twist_.py │ │ │ ├── _PoseWithCovariance_.py │ │ │ ├── _TwistWithCovariance_.py │ │ │ ├── _PointStamped_.py │ │ │ ├── _PoseStamped_.py │ │ │ ├── _TwistStamped_.py │ │ │ ├── _QuaternionStamped_.py │ │ │ ├── _PoseWithCovarianceStamped_.py │ │ │ ├── _TwistWithCovarianceStamped_.py │ │ │ └── __init__.py │ ├── builtin_interfaces │ │ ├── __init__.py │ │ └── msg │ │ │ ├── __init__.py │ │ │ └── dds_ │ │ │ ├── __init__.py │ │ │ └── _Time_.py │ └── __init__.py ├── b2 │ ├── back_video │ │ ├── back_video_api.py │ │ └── back_video_client.py │ ├── front_video │ │ ├── front_video_api.py │ │ └── front_video_client.py │ ├── vui │ │ ├── vui_api.py │ │ └── vui_client.py │ ├── robot_state │ │ ├── robot_state_api.py │ │ └── robot_state_client.py │ └── sport │ │ └── sport_api.py ├── g1 │ ├── arm │ │ ├── g1_arm_action_api.py │ │ └── g1_arm_action_client.py │ ├── audio │ │ ├── g1_audio_api.py │ │ └── g1_audio_client.py │ └── loco │ │ ├── g1_loco_api.py │ │ └── g1_loco_client.py └── h1 │ └── loco │ ├── h1_loco_api.py │ └── h1_loco_client.py ├── pyproject.toml ├── example ├── g1 │ ├── audio │ │ ├── test.wav │ │ ├── g1_audio_client_play_wav.py │ │ └── g1_audio_client_example.py │ └── readme.md ├── h1 │ ├── low_level │ │ └── unitree_legged_const.py │ └── high_level │ │ └── h1_loco_client_example.py ├── helloworld │ ├── user_data.py │ ├── subscriber.py │ └── publisher.py ├── b2 │ ├── low_level │ │ └── unitree_legged_const.py │ ├── camera │ │ ├── capture_image.py │ │ └── camera_opencv.py │ └── high_level │ │ └── b2_sport_client.py ├── go2 │ ├── low_level │ │ └── unitree_legged_const.py │ ├── front_camera │ │ ├── capture_image.py │ │ └── camera_opencv.py │ └── high_level │ │ └── go2_utlidar_switch.py ├── b2w │ ├── low_level │ │ └── unitree_legged_const.py │ ├── camera │ │ ├── capture_image.py │ │ └── camera_opencv.py │ └── high_level │ │ └── b2w_sport_client.py ├── go2w │ ├── low_level │ │ └── unitree_legged_const.py │ └── high_level │ │ └── go2w_sport_client.py ├── motionSwitcher │ └── motion_switcher_example.py ├── obstacles_avoid │ ├── obstacles_avoid_move.py │ └── obstacles_avoid_switch.py └── vui_client │ └── vui_client_example.py ├── .gitignore ├── setup.py ├── LICENSE └── README zh.md /unitree_sdk2py/core/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /unitree_sdk2py/go2/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /unitree_sdk2py/rpc/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /unitree_sdk2py/utils/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /unitree_sdk2py/go2/sport/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /unitree_sdk2py/go2/video/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /unitree_sdk2py/go2/vui/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /unitree_sdk2py/go2/robot_state/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /unitree_sdk2py/comm/motion_switcher/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /unitree_sdk2py/go2/obstacles_avoid/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["setuptools", "wheel"] 3 | build-backend = "setuptools.build_meta" -------------------------------------------------------------------------------- /example/g1/audio/test.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unitreerobotics/unitree_sdk2_python/HEAD/example/g1/audio/test.wav -------------------------------------------------------------------------------- /unitree_sdk2py/utils/lib/crc_amd64.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unitreerobotics/unitree_sdk2_python/HEAD/unitree_sdk2py/utils/lib/crc_amd64.so -------------------------------------------------------------------------------- /unitree_sdk2py/utils/lib/crc_aarch64.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unitreerobotics/unitree_sdk2_python/HEAD/unitree_sdk2py/utils/lib/crc_aarch64.so -------------------------------------------------------------------------------- /example/h1/low_level/unitree_legged_const.py: -------------------------------------------------------------------------------- 1 | HIGHLEVEL = 0xEE 2 | LOWLEVEL = 0xFF 3 | TRIGERLEVEL = 0xF0 4 | PosStopF = 2.146e9 5 | VelStopF = 16000.0 6 | -------------------------------------------------------------------------------- /unitree_sdk2py/__init__.py: -------------------------------------------------------------------------------- 1 | from . import idl, utils, core, rpc, go2, b2 2 | 3 | __all__ = [ 4 | "idl" 5 | "utils" 6 | "core", 7 | "rpc", 8 | "go2", 9 | "b2", 10 | ] 11 | -------------------------------------------------------------------------------- /example/g1/readme.md: -------------------------------------------------------------------------------- 1 | This example is a test of Unitree G1/H1-2 robot. 2 | 3 | **Note:** 4 | idl/unitree_go is used for Unitree Go2/B2/H1/B2w/Go2w robots 5 | idl/unitree_hg is used for Unitree G1/H1-2 robots 6 | -------------------------------------------------------------------------------- /unitree_sdk2py/test/helloworld/helloworld.py: -------------------------------------------------------------------------------- 1 | from dataclasses import dataclass 2 | from cyclonedds.idl import IdlStruct 3 | 4 | @dataclass 5 | class HelloWorld(IdlStruct, typename="HelloWorld"): 6 | data: str -------------------------------------------------------------------------------- /unitree_sdk2py/test/rpc/test_api.py: -------------------------------------------------------------------------------- 1 | # service name 2 | TEST_SERVICE_NAME = "test" 3 | 4 | # api version 5 | TEST_API_VERSION = "1.0.0.1" 6 | 7 | # api id 8 | TEST_API_ID_MOVE = 1008 9 | TEST_API_ID_STOP = 1002 -------------------------------------------------------------------------------- /unitree_sdk2py/idl/nav_msgs/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: nav_msgs 5 | 6 | """ 7 | 8 | from . import msg 9 | __all__ = ["msg", ] 10 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/std_msgs/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: std_msgs 5 | 6 | """ 7 | 8 | from . import msg 9 | __all__ = ["msg", ] 10 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/sensor_msgs/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: sensor_msgs 5 | 6 | """ 7 | 8 | from . import msg 9 | __all__ = ["msg", ] 10 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_api/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.10.2 4 | Module: unitree_api 5 | 6 | """ 7 | 8 | from . import msg 9 | __all__ = ["msg", ] 10 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_go/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: unitree_go 5 | 6 | """ 7 | 8 | from . import msg 9 | __all__ = ["msg", ] 10 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_hg/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: unitree_hg 5 | 6 | """ 7 | 8 | from . import msg 9 | __all__ = ["msg", ] 10 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/geometry_msgs/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: geometry_msgs 5 | 6 | """ 7 | 8 | from . import msg 9 | __all__ = ["msg", ] 10 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/nav_msgs/msg/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: nav_msgs.msg 5 | 6 | """ 7 | 8 | from . import dds_ 9 | __all__ = ["dds_", ] 10 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/std_msgs/msg/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: std_msgs.msg 5 | 6 | """ 7 | 8 | from . import dds_ 9 | __all__ = ["dds_", ] 10 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/sensor_msgs/msg/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: sensor_msgs.msg 5 | 6 | """ 7 | 8 | from . import dds_ 9 | __all__ = ["dds_", ] 10 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_api/msg/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.10.2 4 | Module: unitree_api.msg 5 | 6 | """ 7 | 8 | from . import dds_ 9 | __all__ = ["dds_", ] 10 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_go/msg/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: unitree_go.msg 5 | 6 | """ 7 | 8 | from . import dds_ 9 | __all__ = ["dds_", ] 10 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_hg/msg/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: unitree_hg.msg 5 | 6 | """ 7 | 8 | from . import dds_ 9 | __all__ = ["dds_", ] 10 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/builtin_interfaces/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: builtin_interfaces 5 | 6 | """ 7 | 8 | from . import msg 9 | __all__ = ["msg", ] 10 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/geometry_msgs/msg/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: geometry_msgs.msg 5 | 6 | """ 7 | 8 | from . import dds_ 9 | __all__ = ["dds_", ] 10 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/builtin_interfaces/msg/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: builtin_interfaces.msg 5 | 6 | """ 7 | 8 | from . import dds_ 9 | __all__ = ["dds_", ] 10 | -------------------------------------------------------------------------------- /unitree_sdk2py/go2/video/video_api.py: -------------------------------------------------------------------------------- 1 | """ 2 | " service name 3 | """ 4 | VIDEO_SERVICE_NAME = "videohub" 5 | 6 | 7 | """ 8 | " service api version 9 | """ 10 | VIDEO_API_VERSION = "1.0.0.1" 11 | 12 | 13 | """ 14 | " api id 15 | """ 16 | VIDEO_API_ID_GETIMAGESAMPLE = 1001 17 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/builtin_interfaces/msg/dds_/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: builtin_interfaces.msg.dds_ 5 | 6 | """ 7 | 8 | from ._Time_ import Time_ 9 | __all__ = ["Time_", ] 10 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/std_msgs/msg/dds_/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: std_msgs.msg.dds_ 5 | 6 | """ 7 | 8 | from ._Header_ import Header_ 9 | from ._String_ import String_ 10 | __all__ = ["Header_", "String_", ] 11 | -------------------------------------------------------------------------------- /example/helloworld/user_data.py: -------------------------------------------------------------------------------- 1 | from dataclasses import dataclass 2 | from cyclonedds.idl import IdlStruct 3 | 4 | 5 | # This class defines user data consisting of a float data and a string data 6 | @dataclass 7 | class UserData(IdlStruct, typename="UserData"): 8 | string_data: str 9 | float_data: float 10 | -------------------------------------------------------------------------------- /unitree_sdk2py/b2/back_video/back_video_api.py: -------------------------------------------------------------------------------- 1 | """ 2 | " service name 3 | """ 4 | ROBOT_BACK_VIDEO_SERVICE_NAME = "back_videohub" 5 | 6 | 7 | """ 8 | " service api version 9 | """ 10 | ROBOT_BACK_VIDEO_API_VERSION = "1.0.0.0" 11 | 12 | 13 | """ 14 | " api id 15 | """ 16 | ROBOT_BACK_VIDEO_API_ID_GETIMAGESAMPLE = 1001 17 | -------------------------------------------------------------------------------- /unitree_sdk2py/utils/singleton.py: -------------------------------------------------------------------------------- 1 | class Singleton: 2 | __instance = None 3 | 4 | def __new__(cls, *args, **kwargs): 5 | if cls.__instance is None: 6 | cls.__instance = super(Singleton, cls).__new__(cls) 7 | return cls.__instance 8 | 9 | def __init__(self): 10 | pass 11 | 12 | -------------------------------------------------------------------------------- /unitree_sdk2py/b2/front_video/front_video_api.py: -------------------------------------------------------------------------------- 1 | """ 2 | " service name 3 | """ 4 | ROBOT_FRONT_VIDEO_SERVICE_NAME = "front_videohub" 5 | 6 | 7 | """ 8 | " service api version 9 | """ 10 | ROBOT_FRONT_VIDEO_API_VERSION = "1.0.0.0" 11 | 12 | 13 | """ 14 | " api id 15 | """ 16 | ROBOT_FRONT_VIDEO_API_ID_GETIMAGESAMPLE = 1001 17 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/__init__.py: -------------------------------------------------------------------------------- 1 | from .default import * 2 | from . import builtin_interfaces, geometry_msgs, sensor_msgs, std_msgs, unitree_go, unitree_api 3 | 4 | __all__ = [ 5 | "builtin_interfaces", 6 | "geometry_msgs", 7 | "sensor_msgs", 8 | "std_msgs", 9 | "unitree_go", 10 | "unitree_hg", 11 | "unitree_api", 12 | ] 13 | -------------------------------------------------------------------------------- /unitree_sdk2py/g1/arm/g1_arm_action_api.py: -------------------------------------------------------------------------------- 1 | """ 2 | " service name 3 | """ 4 | ARM_ACTION_SERVICE_NAME = "arm" 5 | 6 | """ 7 | " service api version 8 | """ 9 | ARM_ACTION_API_VERSION = "1.0.0.14" 10 | 11 | """ 12 | " api id 13 | """ 14 | ROBOT_API_ID_ARM_ACTION_EXECUTE_ACTION = 7106 15 | ROBOT_API_ID_ARM_ACTION_GET_ACTION_LIST = 7107 16 | 17 | """ 18 | " error code 19 | """ -------------------------------------------------------------------------------- /unitree_sdk2py/idl/nav_msgs/msg/dds_/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: nav_msgs.msg.dds_ 5 | 6 | """ 7 | 8 | from ._MapMetaData_ import MapMetaData_ 9 | from ._OccupancyGrid_ import OccupancyGrid_ 10 | from ._Odometry_ import Odometry_ 11 | __all__ = ["MapMetaData_", "OccupancyGrid_", "Odometry_", ] 12 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/sensor_msgs/msg/dds_/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: sensor_msgs.msg.dds_ 5 | 6 | """ 7 | 8 | from . import PointField_Constants 9 | from ._PointCloud2_ import PointCloud2_ 10 | from ._PointField_ import PointField_ 11 | __all__ = ["PointField_Constants", "PointCloud2_", "PointField_", ] 12 | -------------------------------------------------------------------------------- /unitree_sdk2py/b2/vui/vui_api.py: -------------------------------------------------------------------------------- 1 | """ 2 | " service name 3 | """ 4 | VUI_SERVICE_NAME = "vui" 5 | 6 | 7 | """ 8 | " service api version 9 | """ 10 | VUI_API_VERSION = "1.0.0.1" 11 | 12 | 13 | """ 14 | " api id 15 | """ 16 | VUI_API_ID_SETSWITCH = 1001 17 | VUI_API_ID_GETSWITCH = 1002 18 | VUI_API_ID_SETVOLUME = 1003 19 | VUI_API_ID_GETVOLUME = 1004 20 | VUI_API_ID_SETBRIGHTNESS = 1005 21 | VUI_API_ID_GETBRIGHTNESS = 1006 22 | -------------------------------------------------------------------------------- /unitree_sdk2py/go2/vui/vui_api.py: -------------------------------------------------------------------------------- 1 | """ 2 | " service name 3 | """ 4 | VUI_SERVICE_NAME = "vui" 5 | 6 | 7 | """ 8 | " service api version 9 | """ 10 | VUI_API_VERSION = "1.0.0.1" 11 | 12 | 13 | """ 14 | " api id 15 | """ 16 | VUI_API_ID_SETSWITCH = 1001 17 | VUI_API_ID_GETSWITCH = 1002 18 | VUI_API_ID_SETVOLUME = 1003 19 | VUI_API_ID_GETVOLUME = 1004 20 | VUI_API_ID_SETBRIGHTNESS = 1005 21 | VUI_API_ID_GETBRIGHTNESS = 1006 22 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_hg/.idlpy_manifest: -------------------------------------------------------------------------------- 1 | BmsCmd_ 2 | msg 3 | 4 | 5 | BmsState_ 6 | msg 7 | 8 | 9 | HandCmd_ 10 | msg 11 | 12 | 13 | HandState_ 14 | msg 15 | 16 | 17 | IMUState_ 18 | msg 19 | 20 | 21 | LowCmd_ 22 | msg 23 | 24 | 25 | LowState_ 26 | msg 27 | 28 | 29 | MainBoardState_ 30 | msg 31 | 32 | 33 | MotorCmd_ 34 | msg 35 | 36 | 37 | MotorState_ 38 | msg 39 | 40 | 41 | PressSensorState_ 42 | msg 43 | 44 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/sensor_msgs/msg/dds_/PointField_Constants/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: sensor_msgs.msg.dds_.PointField_Constants 5 | 6 | """ 7 | 8 | from ._PointField_ import FLOAT32_, FLOAT64_, INT16_, INT32_, INT8_, UINT16_, UINT32_, UINT8_ 9 | __all__ = ["FLOAT32_", "FLOAT64_", "INT16_", "INT32_", "INT8_", "UINT16_", "UINT32_", "UINT8_", ] 10 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_hg/msg/.idlpy_manifest: -------------------------------------------------------------------------------- 1 | BmsCmd_ 2 | dds_ 3 | 4 | 5 | BmsState_ 6 | dds_ 7 | 8 | 9 | HandCmd_ 10 | dds_ 11 | 12 | 13 | HandState_ 14 | dds_ 15 | 16 | 17 | IMUState_ 18 | dds_ 19 | 20 | 21 | LowCmd_ 22 | dds_ 23 | 24 | 25 | LowState_ 26 | dds_ 27 | 28 | 29 | MainBoardState_ 30 | dds_ 31 | 32 | 33 | MotorCmd_ 34 | dds_ 35 | 36 | 37 | MotorState_ 38 | dds_ 39 | 40 | 41 | PressSensorState_ 42 | dds_ 43 | 44 | -------------------------------------------------------------------------------- /unitree_sdk2py/go2/obstacles_avoid/obstacles_avoid_api.py: -------------------------------------------------------------------------------- 1 | """ 2 | " service name 3 | """ 4 | OBSTACLES_AVOID_SERVICE_NAME = "obstacles_avoid" 5 | 6 | 7 | """ 8 | " service api version 9 | """ 10 | OBSTACLES_AVOID_API_VERSION = "1.0.0.2" 11 | 12 | 13 | """ 14 | " api id 15 | """ 16 | OBSTACLES_AVOID_API_ID_SWITCH_SET = 1001 17 | OBSTACLES_AVOID_API_ID_SWITCH_GET = 1002 18 | OBSTACLES_AVOID_API_ID_MOVE = 1003 19 | OBSTACLES_AVOID_API_ID_USE_REMOTE_COMMAND_FROM_API = 1004 -------------------------------------------------------------------------------- /example/b2/low_level/unitree_legged_const.py: -------------------------------------------------------------------------------- 1 | LegID = { 2 | "FR_0": 0, # Front right hip 3 | "FR_1": 1, # Front right thigh 4 | "FR_2": 2, # Front right calf 5 | "FL_0": 3, 6 | "FL_1": 4, 7 | "FL_2": 5, 8 | "RR_0": 6, 9 | "RR_1": 7, 10 | "RR_2": 8, 11 | "RL_0": 9, 12 | "RL_1": 10, 13 | "RL_2": 11, 14 | } 15 | 16 | HIGHLEVEL = 0xEE 17 | LOWLEVEL = 0xFF 18 | TRIGERLEVEL = 0xF0 19 | PosStopF = 2.146e9 20 | VelStopF = 16000.0 21 | -------------------------------------------------------------------------------- /example/go2/low_level/unitree_legged_const.py: -------------------------------------------------------------------------------- 1 | LegID = { 2 | "FR_0": 0, # Front right hip 3 | "FR_1": 1, # Front right thigh 4 | "FR_2": 2, # Front right calf 5 | "FL_0": 3, 6 | "FL_1": 4, 7 | "FL_2": 5, 8 | "RR_0": 6, 9 | "RR_1": 7, 10 | "RR_2": 8, 11 | "RL_0": 9, 12 | "RL_1": 10, 13 | "RL_2": 11, 14 | } 15 | 16 | HIGHLEVEL = 0xEE 17 | LOWLEVEL = 0xFF 18 | TRIGERLEVEL = 0xF0 19 | PosStopF = 2.146e9 20 | VelStopF = 16000.0 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Generated by MacOS 2 | .DS_Store 3 | 4 | # Generated by Windows 5 | Thumbs.db 6 | 7 | # Applications 8 | *.app 9 | *.exe 10 | *.war 11 | 12 | # Large media files 13 | *.mp4 14 | *.tiff 15 | *.avi 16 | *.flv 17 | *.mov 18 | *.wmv 19 | *.jpg 20 | *.png 21 | 22 | # VS Code 23 | .vscode 24 | 25 | # other 26 | *.egg-info 27 | __pycache__ 28 | 29 | # IDEs 30 | .idea 31 | 32 | # cache 33 | .pytest_cache 34 | 35 | # JetBrains IDE 36 | .idea/ 37 | 38 | # python 39 | dist/ -------------------------------------------------------------------------------- /unitree_sdk2py/test/lowlevel/unitree_go2_const.py: -------------------------------------------------------------------------------- 1 | LegID = { 2 | "FR_0": 0, # Front right hip 3 | "FR_1": 1, # Front right thigh 4 | "FR_2": 2, # Front right calf 5 | "FL_0": 3, 6 | "FL_1": 4, 7 | "FL_2": 5, 8 | "RR_0": 6, 9 | "RR_1": 7, 10 | "RR_2": 8, 11 | "RL_0": 9, 12 | "RL_1": 10, 13 | "RL_2": 11, 14 | } 15 | 16 | HIGHLEVEL = 0xEE 17 | LOWLEVEL = 0xFF 18 | TRIGERLEVEL = 0xF0 19 | PosStopF = 2.146e9 20 | VelStopF = 16000.0 21 | -------------------------------------------------------------------------------- /unitree_sdk2py/test/helloworld/subscriber.py: -------------------------------------------------------------------------------- 1 | import time 2 | 3 | from unitree_sdk2py.core.channel import ChannelSubscriber, ChannelFactoryInitialize 4 | from helloworld import HelloWorld 5 | 6 | ChannelFactoryInitialize() 7 | 8 | sub = ChannelSubscriber("topic", HelloWorld) 9 | sub.Init() 10 | 11 | while True: 12 | msg = sub.Read() 13 | 14 | if msg is None: 15 | print("subscribe error.") 16 | else: 17 | print("subscribe success. msg:", msg) 18 | 19 | pub.Close() -------------------------------------------------------------------------------- /unitree_sdk2py/utils/clib_lookup.py: -------------------------------------------------------------------------------- 1 | import os 2 | import ctypes 3 | 4 | clib = ctypes.CDLL(None, use_errno=True) 5 | 6 | def CLIBCheckError(ret, func, args): 7 | if ret < 0: 8 | code = ctypes.get_errno() 9 | raise OSError(code, os.strerror(code)) 10 | return ret 11 | 12 | def CLIBLookup(name, resType, argTypes): 13 | func = clib[name] 14 | func.restye = resType 15 | func.argtypes = argTypes 16 | func.errcheck = CLIBCheckError 17 | return func 18 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_hg/msg/dds_/.idlpy_manifest: -------------------------------------------------------------------------------- 1 | BmsCmd_ 2 | 3 | BmsCmd_ 4 | 5 | BmsState_ 6 | 7 | BmsState_ 8 | 9 | HandCmd_ 10 | 11 | HandCmd_ 12 | 13 | HandState_ 14 | 15 | HandState_ 16 | 17 | IMUState_ 18 | 19 | IMUState_ 20 | 21 | LowCmd_ 22 | 23 | LowCmd_ 24 | 25 | LowState_ 26 | 27 | LowState_ 28 | 29 | MainBoardState_ 30 | 31 | MainBoardState_ 32 | 33 | MotorCmd_ 34 | 35 | MotorCmd_ 36 | 37 | MotorState_ 38 | 39 | MotorState_ 40 | 41 | PressSensorState_ 42 | 43 | PressSensorState_ 44 | -------------------------------------------------------------------------------- /unitree_sdk2py/b2/robot_state/robot_state_api.py: -------------------------------------------------------------------------------- 1 | """ 2 | " service name 3 | """ 4 | ROBOT_STATE_SERVICE_NAME = "robot_state" 5 | 6 | 7 | """ 8 | " service api version 9 | """ 10 | ROBOT_STATE_API_VERSION = "1.0.0.1" 11 | 12 | 13 | """ 14 | " api id 15 | """ 16 | ROBOT_STATE_API_ID_SERVICE_SWITCH = 1001 17 | ROBOT_STATE_API_ID_REPORT_FREQ = 1002 18 | ROBOT_STATE_API_ID_SERVICE_LIST = 1003 19 | 20 | 21 | """ 22 | " error code 23 | """ 24 | ROBOT_STATE_ERR_SERVICE_SWITCH = 5201 25 | ROBOT_STATE_ERR_SERVICE_PROTECTED = 5202 26 | -------------------------------------------------------------------------------- /unitree_sdk2py/go2/robot_state/robot_state_api.py: -------------------------------------------------------------------------------- 1 | """ 2 | " service name 3 | """ 4 | ROBOT_STATE_SERVICE_NAME = "robot_state" 5 | 6 | 7 | """ 8 | " service api version 9 | """ 10 | ROBOT_STATE_API_VERSION = "1.0.0.1" 11 | 12 | 13 | """ 14 | " api id 15 | """ 16 | ROBOT_STATE_API_ID_SERVICE_SWITCH = 1001 17 | ROBOT_STATE_API_ID_REPORT_FREQ = 1002 18 | ROBOT_STATE_API_ID_SERVICE_LIST = 1003 19 | 20 | 21 | """ 22 | " error code 23 | """ 24 | ROBOT_STATE_ERR_SERVICE_SWITCH = 5201 25 | ROBOT_STATE_ERR_SERVICE_PROTECTED = 5202 26 | -------------------------------------------------------------------------------- /unitree_sdk2py/g1/audio/g1_audio_api.py: -------------------------------------------------------------------------------- 1 | """ 2 | " service name 3 | """ 4 | AUDIO_SERVICE_NAME = "voice" 5 | 6 | """ 7 | " service api version 8 | """ 9 | AUDIO_API_VERSION = "1.0.0.0" 10 | 11 | """ 12 | " api id 13 | """ 14 | ROBOT_API_ID_AUDIO_TTS = 1001 15 | ROBOT_API_ID_AUDIO_ASR = 1002 16 | ROBOT_API_ID_AUDIO_START_PLAY = 1003 17 | ROBOT_API_ID_AUDIO_STOP_PLAY = 1004 18 | ROBOT_API_ID_AUDIO_GET_VOLUME = 1005 19 | ROBOT_API_ID_AUDIO_SET_VOLUME = 1006 20 | ROBOT_API_ID_AUDIO_SET_RGB_LED = 1010 21 | 22 | """ 23 | " error code 24 | """ -------------------------------------------------------------------------------- /unitree_sdk2py/test/lowlevel/sub_lowstate.py: -------------------------------------------------------------------------------- 1 | import time 2 | from unitree_sdk2py.core.channel import ChannelSubscriber, ChannelFactoryInitialize 3 | from unitree_sdk2py.idl.default import unitree_go_msg_dds__LowState_ 4 | from unitree_sdk2py.idl.unitree_go.msg.dds_ import LowState_ 5 | 6 | def LowStateHandler(msg: LowState_): 7 | print(msg.motor_state) 8 | 9 | 10 | ChannelFactoryInitialize(0, "enp2s0") 11 | sub = ChannelSubscriber("rt/lowstate", LowState_) 12 | sub.Init(LowStateHandler, 10) 13 | 14 | while True: 15 | time.sleep(10.0) -------------------------------------------------------------------------------- /unitree_sdk2py/go2/video/video_client.py: -------------------------------------------------------------------------------- 1 | import json 2 | 3 | from ...rpc.client import Client 4 | from .video_api import * 5 | 6 | 7 | """ 8 | " class VideoClient 9 | """ 10 | class VideoClient(Client): 11 | def __init__(self): 12 | super().__init__(VIDEO_SERVICE_NAME, False) 13 | 14 | 15 | def Init(self): 16 | # set api version 17 | self._SetApiVerson(VIDEO_API_VERSION) 18 | # regist api 19 | self._RegistApi(VIDEO_API_ID_GETIMAGESAMPLE, 0) 20 | 21 | # 1001 22 | def GetImageSample(self): 23 | return self._CallBinary(VIDEO_API_ID_GETIMAGESAMPLE, []) 24 | -------------------------------------------------------------------------------- /example/b2w/low_level/unitree_legged_const.py: -------------------------------------------------------------------------------- 1 | LegID = { 2 | "FR_0": 0, # Front right hip 3 | "FR_1": 1, # Front right thigh 4 | "FR_2": 2, # Front right calf 5 | "FL_0": 3, 6 | "FL_1": 4, 7 | "FL_2": 5, 8 | "RR_0": 6, 9 | "RR_1": 7, 10 | "RR_2": 8, 11 | "RL_0": 9, 12 | "RL_1": 10, 13 | "RL_2": 11, 14 | "FR_w": 12, # Front right wheel 15 | "FL_w": 13, # Front left wheel 16 | "RR_w": 14, # Rear right wheel 17 | "RL_w": 15, # Rear left wheel 18 | } 19 | 20 | HIGHLEVEL = 0xEE 21 | LOWLEVEL = 0xFF 22 | TRIGERLEVEL = 0xF0 23 | PosStopF = 2.146e9 24 | VelStopF = 16000.0 25 | -------------------------------------------------------------------------------- /example/go2w/low_level/unitree_legged_const.py: -------------------------------------------------------------------------------- 1 | LegID = { 2 | "FR_0": 0, # Front right hip 3 | "FR_1": 1, # Front right thigh 4 | "FR_2": 2, # Front right calf 5 | "FL_0": 3, 6 | "FL_1": 4, 7 | "FL_2": 5, 8 | "RR_0": 6, 9 | "RR_1": 7, 10 | "RR_2": 8, 11 | "RL_0": 9, 12 | "RL_1": 10, 13 | "RL_2": 11, 14 | "FR_w": 12, # Front right wheel 15 | "FL_w": 13, # Front left wheel 16 | "RR_w": 14, # Rear right wheel 17 | "RL_w": 15, # Rear left wheel 18 | } 19 | 20 | HIGHLEVEL = 0xEE 21 | LOWLEVEL = 0xFF 22 | TRIGERLEVEL = 0xF0 23 | PosStopF = 2.146e9 24 | VelStopF = 16000.0 25 | -------------------------------------------------------------------------------- /unitree_sdk2py/test/helloworld/publisher.py: -------------------------------------------------------------------------------- 1 | import time 2 | 3 | from unitree_sdk2py.core.channel import ChannelPublisher, ChannelFactoryInitialize 4 | from helloworld import HelloWorld 5 | 6 | ChannelFactoryInitialize() 7 | 8 | pub = ChannelPublisher("topic", HelloWorld) 9 | pub.Init() 10 | 11 | for i in range(30): 12 | msg = HelloWorld("Hello world. time:" + str(time.time())) 13 | # msg.data = "Hello world. time:" + str(time.time()) 14 | 15 | if pub.Write(msg, 0.5): 16 | print("publish success. msg:", msg) 17 | else: 18 | print("publish error.") 19 | 20 | time.sleep(1) 21 | 22 | pub.Close() -------------------------------------------------------------------------------- /example/helloworld/subscriber.py: -------------------------------------------------------------------------------- 1 | import time 2 | 3 | from unitree_sdk2py.core.channel import ChannelSubscriber, ChannelFactoryInitialize 4 | from user_data import * 5 | 6 | 7 | if __name__ == "__main__": 8 | ChannelFactoryInitialize() 9 | # Create a subscriber to subscribe the data defined in UserData class 10 | sub = ChannelSubscriber("topic", UserData) 11 | sub.Init() 12 | 13 | while True: 14 | msg = sub.Read() 15 | if msg is not None: 16 | print("Subscribe success. msg:", msg) 17 | else: 18 | print("No data subscribed.") 19 | break 20 | sub.Close() 21 | -------------------------------------------------------------------------------- /unitree_sdk2py/b2/back_video/back_video_client.py: -------------------------------------------------------------------------------- 1 | import json 2 | 3 | from ...rpc.client import Client 4 | from .back_video_api import * 5 | 6 | 7 | """ 8 | " class FrontVideoClient 9 | """ 10 | class BackVideoClient(Client): 11 | def __init__(self): 12 | super().__init__(ROBOT_BACK_VIDEO_SERVICE_NAME, False) 13 | 14 | 15 | def Init(self): 16 | # set api version 17 | self._SetApiVerson(ROBOT_BACK_VIDEO_API_VERSION) 18 | # regist api 19 | self._RegistApi(ROBOT_BACK_VIDEO_API_ID_GETIMAGESAMPLE, 0) 20 | 21 | # 1001 22 | def GetImageSample(self): 23 | return self._CallBinary(ROBOT_BACK_VIDEO_API_ID_GETIMAGESAMPLE, []) 24 | -------------------------------------------------------------------------------- /unitree_sdk2py/b2/front_video/front_video_client.py: -------------------------------------------------------------------------------- 1 | import json 2 | 3 | from ...rpc.client import Client 4 | from .front_video_api import * 5 | 6 | 7 | """ 8 | " class FrontVideoClient 9 | """ 10 | class FrontVideoClient(Client): 11 | def __init__(self): 12 | super().__init__(ROBOT_FRONT_VIDEO_SERVICE_NAME, False) 13 | 14 | 15 | def Init(self): 16 | # set api version 17 | self._SetApiVerson(ROBOT_FRONT_VIDEO_API_VERSION) 18 | # regist api 19 | self._RegistApi(ROBOT_FRONT_VIDEO_API_ID_GETIMAGESAMPLE, 0) 20 | 21 | # 1001 22 | def GetImageSample(self): 23 | return self._CallBinary(ROBOT_FRONT_VIDEO_API_ID_GETIMAGESAMPLE, []) 24 | -------------------------------------------------------------------------------- /unitree_sdk2py/comm/motion_switcher/motion_switcher_api.py: -------------------------------------------------------------------------------- 1 | """ 2 | " service name 3 | """ 4 | MOTION_SWITCHER_SERVICE_NAME = "motion_switcher" 5 | 6 | 7 | """ 8 | " service api version 9 | """ 10 | MOTION_SWITCHER_API_VERSION = "1.0.0.1" 11 | 12 | 13 | """ 14 | " api id 15 | """ 16 | MOTION_SWITCHER_API_ID_CHECK_MODE = 1001 17 | MOTION_SWITCHER_API_ID_SELECT_MODE = 1002 18 | MOTION_SWITCHER_API_ID_RELEASE_MODE = 1003 19 | MOTION_SWITCHER_API_ID_SET_SILENT = 1004 20 | MOTION_SWITCHER_API_ID_GET_SILENT = 1005 21 | 22 | # """ 23 | # " error code 24 | # """ 25 | # # client side 26 | # SPORT_ERR_CLIENT_POINT_PATH = 4101 27 | # # server side 28 | # SPORT_ERR_SERVER_OVERTIME = 4201 29 | # SPORT_ERR_SERVER_NOT_INIT = 4202 30 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_api/msg/dds_/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.10.2 4 | Module: unitree_api.msg.dds_ 5 | 6 | """ 7 | 8 | from ._RequestHeader_ import RequestHeader_ 9 | from ._RequestIdentity_ import RequestIdentity_ 10 | from ._RequestLease_ import RequestLease_ 11 | from ._RequestPolicy_ import RequestPolicy_ 12 | from ._Request_ import Request_ 13 | from ._ResponseHeader_ import ResponseHeader_ 14 | from ._ResponseStatus_ import ResponseStatus_ 15 | from ._Response_ import Response_ 16 | __all__ = ["RequestHeader_", "RequestIdentity_", "RequestLease_", "RequestPolicy_", "Request_", "ResponseHeader_", "ResponseStatus_", "Response_", ] 17 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/std_msgs/msg/dds_/_String_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: std_msgs.msg.dds_ 5 | IDL file: String_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import std_msgs 19 | 20 | 21 | @dataclass 22 | @annotate.final 23 | @annotate.autoid("sequential") 24 | class String_(idl.IdlStruct, typename="std_msgs.msg.dds_.String_"): 25 | data: str 26 | 27 | 28 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/sensor_msgs/msg/dds_/PointField_Constants/_PointField_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: sensor_msgs.msg.dds_.PointField_Constants 5 | IDL file: PointField_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import sensor_msgs 19 | 20 | INT8_ = 1 21 | UINT8_ = 2 22 | INT16_ = 3 23 | UINT16_ = 4 24 | INT32_ = 5 25 | UINT32_ = 6 26 | FLOAT32_ = 7 27 | FLOAT64_ = 8 28 | 29 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_go/msg/dds_/_Req_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: unitree_go.msg.dds_ 5 | IDL file: Req_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import unitree_go 19 | 20 | 21 | @dataclass 22 | @annotate.final 23 | @annotate.autoid("sequential") 24 | class Req_(idl.IdlStruct, typename="unitree_go.msg.dds_.Req_"): 25 | uuid: str 26 | body: str 27 | 28 | 29 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_go/msg/dds_/_UwbSwitch_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: unitree_go.msg.dds_ 5 | IDL file: UwbSwitch_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import unitree_go 19 | 20 | 21 | @dataclass 22 | @annotate.final 23 | @annotate.autoid("sequential") 24 | class UwbSwitch_(idl.IdlStruct, typename="unitree_go.msg.dds_.UwbSwitch_"): 25 | enabled: types.uint8 26 | 27 | 28 | -------------------------------------------------------------------------------- /unitree_sdk2py/h1/loco/h1_loco_api.py: -------------------------------------------------------------------------------- 1 | """ 2 | " service name 3 | """ 4 | LOCO_SERVICE_NAME = "loco" 5 | 6 | 7 | """ 8 | " service api version 9 | """ 10 | LOCO_API_VERSION = "2.0.0.0" 11 | 12 | 13 | """ 14 | " api id 15 | """ 16 | ROBOT_API_ID_LOCO_GET_FSM_ID = 8001 17 | ROBOT_API_ID_LOCO_GET_FSM_MODE = 8002 18 | ROBOT_API_ID_LOCO_GET_BALANCE_MODE = 8003 19 | ROBOT_API_ID_LOCO_GET_SWING_HEIGHT = 8004 20 | ROBOT_API_ID_LOCO_GET_STAND_HEIGHT = 8005 21 | ROBOT_API_ID_LOCO_GET_PHASE = 8006 # deprecated 22 | 23 | ROBOT_API_ID_LOCO_SET_FSM_ID = 8101 24 | ROBOT_API_ID_LOCO_SET_BALANCE_MODE = 8102 25 | ROBOT_API_ID_LOCO_SET_SWING_HEIGHT = 8103 26 | ROBOT_API_ID_LOCO_SET_STAND_HEIGHT = 8104 27 | ROBOT_API_ID_LOCO_SET_VELOCITY = 8105 28 | 29 | """ 30 | " error code 31 | """ -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_api/msg/dds_/_RequestLease_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.10.2 4 | Module: unitree_api.msg.dds_ 5 | IDL file: RequestLease_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import unitree_api 19 | 20 | 21 | @dataclass 22 | @annotate.final 23 | @annotate.autoid("sequential") 24 | class RequestLease_(idl.IdlStruct, typename="unitree_api.msg.dds_.RequestLease_"): 25 | id: types.int64 26 | 27 | 28 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_go/msg/dds_/_Error_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: unitree_go.msg.dds_ 5 | IDL file: Error_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import unitree_go 19 | 20 | 21 | @dataclass 22 | @annotate.final 23 | @annotate.autoid("sequential") 24 | class Error_(idl.IdlStruct, typename="unitree_go.msg.dds_.Error_"): 25 | source: types.uint32 26 | state: types.uint32 27 | 28 | 29 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_go/msg/dds_/_MotorCmds_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: unitree_go.msg.dds_ 5 | IDL file: MotorCmds_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass, field 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | @dataclass 18 | @annotate.final 19 | @annotate.autoid("sequential") 20 | class MotorCmds_(idl.IdlStruct, typename="unitree_go.msg.dds_.MotorCmds_"): 21 | cmds: types.sequence['unitree_sdk2py.idl.unitree_go.msg.dds_.MotorCmd_'] = field(default_factory=lambda: []) 22 | 23 | 24 | -------------------------------------------------------------------------------- /unitree_sdk2py/utils/hz_sample.py: -------------------------------------------------------------------------------- 1 | import time 2 | from threading import Lock 3 | from .thread import RecurrentThread 4 | 5 | class HZSample: 6 | def __init__(self, interval: float = 1.0): 7 | self.__count = 0 8 | self.__inter = interval if interval > 0.0 else 1.0 9 | self.__lock = Lock() 10 | self.__thread = RecurrentThread(self.__inter, target=self.TimerFunc) 11 | 12 | def Start(self): 13 | self.__thread.Start() 14 | 15 | def Sample(self): 16 | with self.__lock: 17 | self.__count += 1 18 | 19 | def TimerFunc(self): 20 | count = 0 21 | with self.__lock: 22 | count = self.__count 23 | self.__count = 0 24 | print("HZ: {}".format(count/self.__inter)) 25 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_api/msg/dds_/_ResponseStatus_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.10.2 4 | Module: unitree_api.msg.dds_ 5 | IDL file: ResponseStatus_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import unitree_api 19 | 20 | 21 | @dataclass 22 | @annotate.final 23 | @annotate.autoid("sequential") 24 | class ResponseStatus_(idl.IdlStruct, typename="unitree_api.msg.dds_.ResponseStatus_"): 25 | code: types.int32 26 | 27 | 28 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_go/msg/dds_/_MotorStates_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: unitree_go.msg.dds_ 5 | IDL file: MotorStates_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass, field 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | @dataclass 18 | @annotate.final 19 | @annotate.autoid("sequential") 20 | class MotorStates_(idl.IdlStruct, typename="unitree_go.msg.dds_.MotorStates_"): 21 | states: types.sequence['unitree_sdk2py.idl.unitree_go.msg.dds_.MotorState_'] = field(default_factory=lambda: []) 22 | 23 | 24 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_go/msg/dds_/_TimeSpec_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: unitree_go.msg.dds_ 5 | IDL file: TimeSpec_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import unitree_go 19 | 20 | 21 | @dataclass 22 | @annotate.final 23 | @annotate.autoid("sequential") 24 | class TimeSpec_(idl.IdlStruct, typename="unitree_go.msg.dds_.TimeSpec_"): 25 | sec: types.int32 26 | nanosec: types.uint32 27 | 28 | 29 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_go/msg/dds_/_BmsCmd_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: unitree_go.msg.dds_ 5 | IDL file: BmsCmd_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import unitree_go 19 | 20 | 21 | @dataclass 22 | @annotate.final 23 | @annotate.autoid("sequential") 24 | class BmsCmd_(idl.IdlStruct, typename="unitree_go.msg.dds_.BmsCmd_"): 25 | off: types.uint8 26 | reserve: types.array[types.uint8, 3] 27 | 28 | 29 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_go/msg/dds_/_Res_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: unitree_go.msg.dds_ 5 | IDL file: Res_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import unitree_go 19 | 20 | 21 | @dataclass 22 | @annotate.final 23 | @annotate.autoid("sequential") 24 | class Res_(idl.IdlStruct, typename="unitree_go.msg.dds_.Res_"): 25 | uuid: str 26 | data: types.sequence[types.uint8] 27 | body: str 28 | 29 | 30 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_hg/msg/dds_/_BmsCmd_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: unitree_hg.msg.dds_ 5 | IDL file: BmsCmd_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import unitree_hg 19 | 20 | 21 | @dataclass 22 | @annotate.final 23 | @annotate.autoid("sequential") 24 | class BmsCmd_(idl.IdlStruct, typename="unitree_hg.msg.dds_.BmsCmd_"): 25 | cmd: types.uint8 26 | reserve: types.array[types.uint8, 40] 27 | 28 | 29 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup(name='unitree_sdk2py', 4 | version='1.0.1', 5 | author='UnitreeRobotics', 6 | author_email='unitree@unitree.com', 7 | long_description=open('README.md').read(), 8 | long_description_content_type="text/markdown", 9 | license="BSD-3-Clause", 10 | packages=find_packages(include=['unitree_sdk2py','unitree_sdk2py.*']), 11 | description='Unitree robot sdk version 2 for python', 12 | project_urls={ 13 | "Source Code": "https://github.com/unitreerobotics/unitree_sdk2_python", 14 | }, 15 | python_requires='>=3.8', 16 | install_requires=[ 17 | "cyclonedds==0.10.2", 18 | "numpy", 19 | "opencv-python", 20 | ], 21 | ) -------------------------------------------------------------------------------- /unitree_sdk2py/idl/builtin_interfaces/msg/dds_/_Time_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: builtin_interfaces.msg.dds_ 5 | IDL file: Time_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import builtin_interfaces 19 | 20 | 21 | @dataclass 22 | @annotate.final 23 | @annotate.autoid("sequential") 24 | class Time_(idl.IdlStruct, typename="builtin_interfaces.msg.dds_.Time_"): 25 | sec: types.int32 26 | nanosec: types.uint32 27 | 28 | 29 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/geometry_msgs/msg/dds_/_Point_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: geometry_msgs.msg.dds_ 5 | IDL file: Point_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import geometry_msgs 19 | 20 | 21 | @dataclass 22 | @annotate.final 23 | @annotate.autoid("sequential") 24 | class Point_(idl.IdlStruct, typename="geometry_msgs.msg.dds_.Point_"): 25 | x: types.float64 26 | y: types.float64 27 | z: types.float64 28 | 29 | 30 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_api/msg/dds_/_RequestPolicy_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.10.2 4 | Module: unitree_api.msg.dds_ 5 | IDL file: RequestPolicy_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import unitree_api 19 | 20 | 21 | @dataclass 22 | @annotate.final 23 | @annotate.autoid("sequential") 24 | class RequestPolicy_(idl.IdlStruct, typename="unitree_api.msg.dds_.RequestPolicy_"): 25 | priority: types.int32 26 | noreply: bool 27 | 28 | 29 | -------------------------------------------------------------------------------- /unitree_sdk2py/g1/loco/g1_loco_api.py: -------------------------------------------------------------------------------- 1 | """ 2 | " service name 3 | """ 4 | LOCO_SERVICE_NAME = "sport" 5 | 6 | 7 | """ 8 | " service api version 9 | """ 10 | LOCO_API_VERSION = "1.0.0.0" 11 | 12 | 13 | """ 14 | " api id 15 | """ 16 | ROBOT_API_ID_LOCO_GET_FSM_ID = 7001 17 | ROBOT_API_ID_LOCO_GET_FSM_MODE = 7002 18 | ROBOT_API_ID_LOCO_GET_BALANCE_MODE = 7003 19 | ROBOT_API_ID_LOCO_GET_SWING_HEIGHT = 7004 20 | ROBOT_API_ID_LOCO_GET_STAND_HEIGHT = 7005 21 | ROBOT_API_ID_LOCO_GET_PHASE = 7006 # deprecated 22 | 23 | ROBOT_API_ID_LOCO_SET_FSM_ID = 7101 24 | ROBOT_API_ID_LOCO_SET_BALANCE_MODE = 7102 25 | ROBOT_API_ID_LOCO_SET_SWING_HEIGHT = 7103 26 | ROBOT_API_ID_LOCO_SET_STAND_HEIGHT = 7104 27 | ROBOT_API_ID_LOCO_SET_VELOCITY = 7105 28 | ROBOT_API_ID_LOCO_SET_ARM_TASK = 7106 29 | 30 | """ 31 | " error code 32 | """ -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_go/msg/dds_/_AudioData_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: unitree_go.msg.dds_ 5 | IDL file: AudioData_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import unitree_go 19 | 20 | 21 | @dataclass 22 | @annotate.final 23 | @annotate.autoid("sequential") 24 | class AudioData_(idl.IdlStruct, typename="unitree_go.msg.dds_.AudioData_"): 25 | time_frame: types.uint64 26 | data: types.sequence[types.uint8] 27 | 28 | 29 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/geometry_msgs/msg/dds_/_Point32_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: geometry_msgs.msg.dds_ 5 | IDL file: Point32_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import geometry_msgs 19 | 20 | 21 | @dataclass 22 | @annotate.final 23 | @annotate.autoid("sequential") 24 | class Point32_(idl.IdlStruct, typename="geometry_msgs.msg.dds_.Point32_"): 25 | x: types.float32 26 | y: types.float32 27 | z: types.float32 28 | 29 | 30 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/geometry_msgs/msg/dds_/_Pose2D_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: geometry_msgs.msg.dds_ 5 | IDL file: Pose2D_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import geometry_msgs 19 | 20 | 21 | @dataclass 22 | @annotate.final 23 | @annotate.autoid("sequential") 24 | class Pose2D_(idl.IdlStruct, typename="geometry_msgs.msg.dds_.Pose2D_"): 25 | x: types.float64 26 | y: types.float64 27 | theta: types.float64 28 | 29 | 30 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/geometry_msgs/msg/dds_/_Vector3_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: geometry_msgs.msg.dds_ 5 | IDL file: Vector3_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import geometry_msgs 19 | 20 | 21 | @dataclass 22 | @annotate.final 23 | @annotate.autoid("sequential") 24 | class Vector3_(idl.IdlStruct, typename="geometry_msgs.msg.dds_.Vector3_"): 25 | x: types.float64 26 | y: types.float64 27 | z: types.float64 28 | 29 | 30 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_api/msg/dds_/_RequestIdentity_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.10.2 4 | Module: unitree_api.msg.dds_ 5 | IDL file: RequestIdentity_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import unitree_api 19 | 20 | 21 | @dataclass 22 | @annotate.final 23 | @annotate.autoid("sequential") 24 | class RequestIdentity_(idl.IdlStruct, typename="unitree_api.msg.dds_.RequestIdentity_"): 25 | id: types.int64 26 | api_id: types.int64 27 | 28 | 29 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_hg/msg/dds_/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: unitree_hg.msg.dds_ 5 | 6 | """ 7 | 8 | from ._BmsCmd_ import BmsCmd_ 9 | from ._BmsState_ import BmsState_ 10 | from ._HandCmd_ import HandCmd_ 11 | from ._HandState_ import HandState_ 12 | from ._IMUState_ import IMUState_ 13 | from ._LowCmd_ import LowCmd_ 14 | from ._LowState_ import LowState_ 15 | from ._MainBoardState_ import MainBoardState_ 16 | from ._MotorCmd_ import MotorCmd_ 17 | from ._MotorState_ import MotorState_ 18 | from ._PressSensorState_ import PressSensorState_ 19 | __all__ = ["BmsCmd_", "BmsState_", "HandCmd_", "HandState_", "IMUState_", "LowCmd_", "LowState_", "MainBoardState_", "MotorCmd_", "MotorState_", "PressSensorState_", ] 20 | -------------------------------------------------------------------------------- /unitree_sdk2py/core/channel_name.py: -------------------------------------------------------------------------------- 1 | from enum import Enum 2 | 3 | """ 4 | " Enum ChannelType 5 | """ 6 | class ChannelType(Enum): 7 | SEND = 0 8 | RECV = 1 9 | 10 | """ 11 | " function GetClientChannelName 12 | """ 13 | def GetClientChannelName(serviceName: str, channelType: ChannelType): 14 | name = "rt/api/" + serviceName 15 | 16 | if channelType == ChannelType.SEND: 17 | name += "/request" 18 | else: 19 | name += "/response" 20 | 21 | return name 22 | 23 | """ 24 | " function GetClientChannelName 25 | """ 26 | def GetServerChannelName(serviceName: str, channelType: ChannelType): 27 | name = "rt/api/" + serviceName 28 | 29 | if channelType == ChannelType.SEND: 30 | name += "/response" 31 | else: 32 | name += "/request" 33 | 34 | return name -------------------------------------------------------------------------------- /example/helloworld/publisher.py: -------------------------------------------------------------------------------- 1 | import time 2 | 3 | from unitree_sdk2py.core.channel import ChannelPublisher, ChannelFactoryInitialize 4 | from user_data import * 5 | 6 | 7 | if __name__ == "__main__": 8 | ChannelFactoryInitialize() 9 | 10 | # Create a publisher to publish the data defined in UserData class 11 | pub = ChannelPublisher("topic", UserData) 12 | pub.Init() 13 | 14 | for i in range(30): 15 | # Create a Userdata message 16 | msg = UserData(" ", 0) 17 | msg.string_data = "Hello world" 18 | msg.float_data = time.time() 19 | 20 | # Publish message 21 | if pub.Write(msg, 0.5): 22 | print("Publish success. msg:", msg) 23 | else: 24 | print("Waitting for subscriber.") 25 | 26 | time.sleep(1) 27 | 28 | pub.Close() 29 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/geometry_msgs/msg/dds_/_Quaternion_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: geometry_msgs.msg.dds_ 5 | IDL file: Quaternion_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import geometry_msgs 19 | 20 | 21 | @dataclass 22 | @annotate.final 23 | @annotate.autoid("sequential") 24 | class Quaternion_(idl.IdlStruct, typename="geometry_msgs.msg.dds_.Quaternion_"): 25 | x: types.float64 26 | y: types.float64 27 | z: types.float64 28 | w: types.float64 29 | 30 | 31 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/sensor_msgs/msg/dds_/_PointField_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: sensor_msgs.msg.dds_ 5 | IDL file: PointField_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import sensor_msgs 19 | 20 | 21 | @dataclass 22 | @annotate.final 23 | @annotate.autoid("sequential") 24 | class PointField_(idl.IdlStruct, typename="sensor_msgs.msg.dds_.PointField_"): 25 | name: str 26 | offset: types.uint32 27 | datatype: types.uint8 28 | count: types.uint32 29 | 30 | 31 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_go/msg/dds_/_InterfaceConfig_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: unitree_go.msg.dds_ 5 | IDL file: InterfaceConfig_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import unitree_go 19 | 20 | 21 | @dataclass 22 | @annotate.final 23 | @annotate.autoid("sequential") 24 | class InterfaceConfig_(idl.IdlStruct, typename="unitree_go.msg.dds_.InterfaceConfig_"): 25 | mode: types.uint8 26 | value: types.uint8 27 | reserve: types.array[types.uint8, 2] 28 | 29 | 30 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_hg/msg/dds_/_HandCmd_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: unitree_hg.msg.dds_ 5 | IDL file: HandCmd_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import unitree_hg 19 | 20 | 21 | @dataclass 22 | @annotate.final 23 | @annotate.autoid("sequential") 24 | class HandCmd_(idl.IdlStruct, typename="unitree_hg.msg.dds_.HandCmd_"): 25 | motor_cmd: types.sequence['unitree_sdk2py.idl.unitree_hg.msg.dds_.MotorCmd_'] 26 | reserve: types.array[types.uint32, 4] 27 | 28 | 29 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_api/msg/dds_/_Request_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.10.2 4 | Module: unitree_api.msg.dds_ 5 | IDL file: Request_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import unitree_api 19 | 20 | 21 | @dataclass 22 | @annotate.final 23 | @annotate.autoid("sequential") 24 | class Request_(idl.IdlStruct, typename="unitree_api.msg.dds_.Request_"): 25 | header: 'unitree_sdk2py.idl.unitree_api.msg.dds_.RequestHeader_' 26 | parameter: str 27 | binary: types.sequence[types.uint8] 28 | 29 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_api/msg/dds_/_Response_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.10.2 4 | Module: unitree_api.msg.dds_ 5 | IDL file: Response_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import unitree_api 19 | 20 | @dataclass 21 | @annotate.final 22 | @annotate.autoid("sequential") 23 | class Response_(idl.IdlStruct, typename="unitree_api.msg.dds_.Response_"): 24 | header: 'unitree_sdk2py.idl.unitree_api.msg.dds_.ResponseHeader_' 25 | data: str 26 | binary: types.sequence[types.uint8] 27 | 28 | 29 | -------------------------------------------------------------------------------- /unitree_sdk2py/test/crc/test_crc.py: -------------------------------------------------------------------------------- 1 | from unitree_sdk2py.idl.default import unitree_go_msg_dds__LowCmd_, unitree_go_msg_dds__LowState_ 2 | from unitree_sdk2py.idl.default import unitree_hg_msg_dds__LowCmd_, unitree_hg_msg_dds__LowState_ 3 | from unitree_sdk2py.utils.crc import CRC 4 | 5 | crc = CRC() 6 | 7 | """ 8 | " LowCmd/LowState CRC 9 | """ 10 | cmd = unitree_go_msg_dds__LowCmd_() 11 | cmd.crc = crc.Crc(cmd) 12 | 13 | state = unitree_go_msg_dds__LowState_() 14 | state.crc = crc.Crc(state) 15 | 16 | print("CRC[LowCmd, LowState]: {}, {}".format(cmd.crc, state.crc)) 17 | 18 | """ 19 | " LowCmd/LowState for HG CRC. () 20 | """ 21 | cmd = unitree_hg_msg_dds__LowCmd_() 22 | cmd.crc = crc.Crc(cmd) 23 | 24 | state = unitree_hg_msg_dds__LowState_() 25 | state.crc = crc.Crc(state) 26 | 27 | print("CRC[HGLowCmd, HGLowState]: {}, {}".format(cmd.crc, state.crc)) 28 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/geometry_msgs/msg/dds_/_Pose_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: geometry_msgs.msg.dds_ 5 | IDL file: Pose_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import geometry_msgs 19 | 20 | 21 | @dataclass 22 | @annotate.final 23 | @annotate.autoid("sequential") 24 | class Pose_(idl.IdlStruct, typename="geometry_msgs.msg.dds_.Pose_"): 25 | position: 'unitree_sdk2py.idl.geometry_msgs.msg.dds_.Point_' 26 | orientation: 'unitree_sdk2py.idl.geometry_msgs.msg.dds_.Quaternion_' 27 | 28 | 29 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/geometry_msgs/msg/dds_/_Twist_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: geometry_msgs.msg.dds_ 5 | IDL file: Twist_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import geometry_msgs 19 | 20 | 21 | @dataclass 22 | @annotate.final 23 | @annotate.autoid("sequential") 24 | class Twist_(idl.IdlStruct, typename="geometry_msgs.msg.dds_.Twist_"): 25 | linear: 'unitree_sdk2py.idl.geometry_msgs.msg.dds_.Vector3_' 26 | angular: 'unitree_sdk2py.idl.geometry_msgs.msg.dds_.Vector3_' 27 | 28 | 29 | -------------------------------------------------------------------------------- /unitree_sdk2py/test/client/video_client_example.py: -------------------------------------------------------------------------------- 1 | import time 2 | import os 3 | 4 | from unitree_sdk2py.core.channel import ChannelFactoryInitialize 5 | from unitree_sdk2py.go2.video.video_client import VideoClient 6 | 7 | if __name__ == "__main__": 8 | ChannelFactoryInitialize(0, "enp2s0") 9 | 10 | client = VideoClient() 11 | client.SetTimeout(3.0) 12 | client.Init() 13 | 14 | print("##################GetImageSample###################") 15 | code, data = client.GetImageSample() 16 | 17 | if code != 0: 18 | print("get image sample error. code:", code) 19 | else: 20 | imageName = os.path.dirname(__file__) + time.strftime('/%Y%m%d%H%M%S.jpg',time.localtime()) 21 | print("ImageName:", imageName) 22 | 23 | with open(imageName, "+wb") as f: 24 | f.write(bytes(data)) 25 | 26 | time.sleep(1) 27 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/std_msgs/msg/dds_/_Header_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: std_msgs.msg.dds_ 5 | IDL file: Header_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import std_msgs 19 | 20 | # if TYPE_CHECKING: 21 | # import builtin_interfaces.msg.dds_ 22 | 23 | 24 | 25 | @dataclass 26 | @annotate.final 27 | @annotate.autoid("sequential") 28 | class Header_(idl.IdlStruct, typename="std_msgs.msg.dds_.Header_"): 29 | stamp: 'unitree_sdk2py.idl.builtin_interfaces.msg.dds_.Time_' 30 | frame_id: str 31 | 32 | 33 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/geometry_msgs/msg/dds_/_PoseWithCovariance_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: geometry_msgs.msg.dds_ 5 | IDL file: PoseWithCovariance_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import geometry_msgs 19 | 20 | 21 | @dataclass 22 | @annotate.final 23 | @annotate.autoid("sequential") 24 | class PoseWithCovariance_(idl.IdlStruct, typename="geometry_msgs.msg.dds_.PoseWithCovariance_"): 25 | pose: 'unitree_sdk2py.idl.geometry_msgs.msg.dds_.Pose_' 26 | covariance: types.array[types.float64, 36] 27 | 28 | 29 | -------------------------------------------------------------------------------- /example/go2/front_camera/capture_image.py: -------------------------------------------------------------------------------- 1 | import time 2 | import os 3 | import sys 4 | 5 | from unitree_sdk2py.core.channel import ChannelFactoryInitialize 6 | from unitree_sdk2py.go2.video.video_client import VideoClient 7 | 8 | if __name__ == "__main__": 9 | if len(sys.argv)>1: 10 | ChannelFactoryInitialize(0, sys.argv[1]) 11 | else: 12 | ChannelFactoryInitialize(0) 13 | 14 | client = VideoClient() 15 | client.SetTimeout(3.0) 16 | client.Init() 17 | 18 | print("##################GetImageSample###################") 19 | code, data = client.GetImageSample() 20 | 21 | if code != 0: 22 | print("get image sample error. code:", code) 23 | else: 24 | imageName = "./img.jpg" 25 | print("ImageName:", imageName) 26 | 27 | with open(imageName, "+wb") as f: 28 | f.write(bytes(data)) 29 | 30 | time.sleep(1) 31 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/geometry_msgs/msg/dds_/_TwistWithCovariance_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: geometry_msgs.msg.dds_ 5 | IDL file: TwistWithCovariance_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import geometry_msgs 19 | 20 | 21 | @dataclass 22 | @annotate.final 23 | @annotate.autoid("sequential") 24 | class TwistWithCovariance_(idl.IdlStruct, typename="geometry_msgs.msg.dds_.TwistWithCovariance_"): 25 | twist: 'unitree_sdk2py.idl.geometry_msgs.msg.dds_.Twist_' 26 | covariance: types.array[types.float64, 36] 27 | 28 | 29 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_go/msg/dds_/_WirelessController_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: unitree_go.msg.dds_ 5 | IDL file: WirelessController_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import unitree_go 19 | 20 | 21 | @dataclass 22 | @annotate.final 23 | @annotate.autoid("sequential") 24 | class WirelessController_(idl.IdlStruct, typename="unitree_go.msg.dds_.WirelessController_"): 25 | lx: types.float32 26 | ly: types.float32 27 | rx: types.float32 28 | ry: types.float32 29 | keys: types.uint16 30 | 31 | 32 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_api/msg/dds_/_ResponseHeader_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.10.2 4 | Module: unitree_api.msg.dds_ 5 | IDL file: ResponseHeader_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import unitree_api 19 | 20 | 21 | @dataclass 22 | @annotate.final 23 | @annotate.autoid("sequential") 24 | class ResponseHeader_(idl.IdlStruct, typename="unitree_api.msg.dds_.ResponseHeader_"): 25 | identity: 'unitree_sdk2py.idl.unitree_api.msg.dds_.RequestIdentity_' 26 | status: 'unitree_sdk2py.idl.unitree_api.msg.dds_.ResponseStatus_' 27 | 28 | 29 | -------------------------------------------------------------------------------- /unitree_sdk2py/rpc/internal.py: -------------------------------------------------------------------------------- 1 | # internal api id max 2 | RPC_INTERNAL_API_ID_MAX = 100 3 | 4 | # internal api id 5 | RPC_API_ID_INTERNAL_API_VERSION = 1 6 | 7 | # lease api id 8 | RPC_API_ID_LEASE_APPLY = 101 9 | RPC_API_ID_LEASE_RENEWAL = 102 10 | 11 | # lease term default 12 | RPC_LEASE_TERM = 1.0 13 | 14 | # internal error 15 | RPC_OK = 0 16 | # client error 17 | RPC_ERR_UNKNOWN = 3001 18 | RPC_ERR_CLIENT_SEND = 3102 19 | RPC_ERR_CLIENT_API_NOT_REG = 3103 20 | RPC_ERR_CLIENT_API_TIMEOUT = 3104 21 | RPC_ERR_CLIENT_API_NOT_MATCH = 3105 22 | RPC_ERR_CLIENT_API_DATA = 3106 23 | RPC_ERR_CLIENT_LEASE_INVALID = 3107 24 | # server error 25 | RPC_ERR_SERVER_SEND = 3201 26 | RPC_ERR_SERVER_INTERNAL = 3202 27 | RPC_ERR_SERVER_API_NOT_IMPL = 3203 28 | RPC_ERR_SERVER_API_PARAMETER = 3204 29 | RPC_ERR_SERVER_LEASE_DENIED = 3205 30 | RPC_ERR_SERVER_LEASE_NOT_EXIST = 3206 31 | RPC_ERR_SERVER_LEASE_EXIST = 3207 32 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_hg/msg/dds_/_MotorCmd_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: unitree_hg.msg.dds_ 5 | IDL file: MotorCmd_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import unitree_hg 19 | 20 | 21 | @dataclass 22 | @annotate.final 23 | @annotate.autoid("sequential") 24 | class MotorCmd_(idl.IdlStruct, typename="unitree_hg.msg.dds_.MotorCmd_"): 25 | mode: types.uint8 26 | q: types.float32 27 | dq: types.float32 28 | tau: types.float32 29 | kp: types.float32 30 | kd: types.float32 31 | reserve: types.uint32 32 | 33 | 34 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_hg/msg/dds_/_PressSensorState_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: unitree_hg.msg.dds_ 5 | IDL file: PressSensorState_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import unitree_hg 19 | 20 | 21 | @dataclass 22 | @annotate.final 23 | @annotate.autoid("sequential") 24 | class PressSensorState_(idl.IdlStruct, typename="unitree_hg.msg.dds_.PressSensorState_"): 25 | pressure: types.array[types.float32, 12] 26 | temperature: types.array[types.float32, 12] 27 | lost: types.uint32 28 | reserve: types.uint32 29 | 30 | 31 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_go/msg/dds_/_PathPoint_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: unitree_go.msg.dds_ 5 | IDL file: PathPoint_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import unitree_go 19 | 20 | 21 | @dataclass 22 | @annotate.final 23 | @annotate.autoid("sequential") 24 | class PathPoint_(idl.IdlStruct, typename="unitree_go.msg.dds_.PathPoint_"): 25 | t_from_start: types.float32 26 | x: types.float32 27 | y: types.float32 28 | yaw: types.float32 29 | vx: types.float32 30 | vy: types.float32 31 | vyaw: types.float32 32 | 33 | 34 | -------------------------------------------------------------------------------- /unitree_sdk2py/test/lowlevel/read_lowstate.py: -------------------------------------------------------------------------------- 1 | import time 2 | from unitree_sdk2py.core.channel import ChannelSubscriber, ChannelFactoryInitialize 3 | from unitree_sdk2py.idl.default import unitree_go_msg_dds__LowState_ 4 | from unitree_sdk2py.idl.unitree_go.msg.dds_ import LowState_ 5 | 6 | import unitree_go2_const as go2 7 | 8 | 9 | def LowStateHandler(msg: LowState_): 10 | 11 | # print front right hip motor states 12 | print("FR_0 motor state: ", msg.motor_state[go2.LegID["FR_0"]]) 13 | print("IMU state: ", msg.imu_state) 14 | print("Battery state: voltage: ", msg.power_v, "current: ", msg.power_a) 15 | 16 | 17 | if __name__ == "__main__": 18 | # Modify "enp2s0" to the actual network interface 19 | ChannelFactoryInitialize(0, "enp2s0") 20 | sub = ChannelSubscriber("rt/lowstate", LowState_) 21 | sub.Init(LowStateHandler, 10) 22 | 23 | while True: 24 | time.sleep(10.0) 25 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_go/msg/dds_/_MotorCmd_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: unitree_go.msg.dds_ 5 | IDL file: MotorCmd_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import unitree_go 19 | 20 | 21 | @dataclass 22 | @annotate.final 23 | @annotate.autoid("sequential") 24 | class MotorCmd_(idl.IdlStruct, typename="unitree_go.msg.dds_.MotorCmd_"): 25 | mode: types.uint8 26 | q: types.float32 27 | dq: types.float32 28 | tau: types.float32 29 | kp: types.float32 30 | kd: types.float32 31 | reserve: types.array[types.uint32, 3] 32 | 33 | 34 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_go/msg/dds_/_Go2FrontVideoData_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: unitree_go.msg.dds_ 5 | IDL file: Go2FrontVideoData_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import unitree_go 19 | 20 | 21 | @dataclass 22 | @annotate.final 23 | @annotate.autoid("sequential") 24 | class Go2FrontVideoData_(idl.IdlStruct, typename="unitree_go.msg.dds_.Go2FrontVideoData_"): 25 | time_frame: types.uint64 26 | video720p: types.sequence[types.uint8] 27 | video360p: types.sequence[types.uint8] 28 | video180p: types.sequence[types.uint8] 29 | 30 | 31 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_hg/msg/dds_/_MainBoardState_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: unitree_hg.msg.dds_ 5 | IDL file: MainBoardState_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import unitree_hg 19 | 20 | 21 | @dataclass 22 | @annotate.final 23 | @annotate.autoid("sequential") 24 | class MainBoardState_(idl.IdlStruct, typename="unitree_hg.msg.dds_.MainBoardState_"): 25 | fan_state: types.array[types.uint16, 6] 26 | temperature: types.array[types.int16, 6] 27 | value: types.array[types.float32, 6] 28 | state: types.array[types.uint32, 6] 29 | 30 | 31 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_hg/msg/dds_/_LowCmd_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: unitree_hg.msg.dds_ 5 | IDL file: LowCmd_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import unitree_hg 19 | 20 | 21 | @dataclass 22 | @annotate.final 23 | @annotate.autoid("sequential") 24 | class LowCmd_(idl.IdlStruct, typename="unitree_hg.msg.dds_.LowCmd_"): 25 | mode_pr: types.uint8 26 | mode_machine: types.uint8 27 | motor_cmd: types.array['unitree_sdk2py.idl.unitree_hg.msg.dds_.MotorCmd_', 35] 28 | reserve: types.array[types.uint32, 4] 29 | crc: types.uint32 30 | 31 | 32 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/geometry_msgs/msg/dds_/_PointStamped_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: geometry_msgs.msg.dds_ 5 | IDL file: PointStamped_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import geometry_msgs 19 | 20 | # if TYPE_CHECKING: 21 | # import std_msgs.msg.dds_ 22 | 23 | 24 | @dataclass 25 | @annotate.final 26 | @annotate.autoid("sequential") 27 | class PointStamped_(idl.IdlStruct, typename="geometry_msgs.msg.dds_.PointStamped_"): 28 | header: 'unitree_sdk2py.idl.std_msgs.msg.dds_.Header_' 29 | point: 'unitree_sdk2py.idl.geometry_msgs.msg.dds_.Point_' 30 | 31 | 32 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/geometry_msgs/msg/dds_/_PoseStamped_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: geometry_msgs.msg.dds_ 5 | IDL file: PoseStamped_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import geometry_msgs 19 | 20 | # if TYPE_CHECKING: 21 | # import std_msgs.msg.dds_ 22 | 23 | 24 | 25 | @dataclass 26 | @annotate.final 27 | @annotate.autoid("sequential") 28 | class PoseStamped_(idl.IdlStruct, typename="geometry_msgs.msg.dds_.PoseStamped_"): 29 | header: 'unitree_sdk2py.idl.std_msgs.msg.dds_.Header_' 30 | pose: 'unitree_sdk2py.idl.geometry_msgs.msg.dds_.Pose_' 31 | 32 | 33 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/geometry_msgs/msg/dds_/_TwistStamped_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: geometry_msgs.msg.dds_ 5 | IDL file: TwistStamped_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import geometry_msgs 19 | 20 | # if TYPE_CHECKING: 21 | # import std_msgs.msg.dds_ 22 | 23 | 24 | 25 | @dataclass 26 | @annotate.final 27 | @annotate.autoid("sequential") 28 | class TwistStamped_(idl.IdlStruct, typename="geometry_msgs.msg.dds_.TwistStamped_"): 29 | header: 'unitree_sdk2py.idl.std_msgs.msg.dds_.Header_' 30 | twist: 'unitree_sdk2py.idl.geometry_msgs.msg.dds_.Twist_' 31 | 32 | 33 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_go/msg/dds_/_IMUState_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: unitree_go.msg.dds_ 5 | IDL file: IMUState_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import unitree_go 19 | 20 | 21 | @dataclass 22 | @annotate.final 23 | @annotate.autoid("sequential") 24 | class IMUState_(idl.IdlStruct, typename="unitree_go.msg.dds_.IMUState_"): 25 | quaternion: types.array[types.float32, 4] 26 | gyroscope: types.array[types.float32, 3] 27 | accelerometer: types.array[types.float32, 3] 28 | rpy: types.array[types.float32, 3] 29 | temperature: types.uint8 30 | 31 | 32 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_hg/msg/dds_/_IMUState_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: unitree_hg.msg.dds_ 5 | IDL file: IMUState_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import unitree_hg 19 | 20 | 21 | @dataclass 22 | @annotate.final 23 | @annotate.autoid("sequential") 24 | class IMUState_(idl.IdlStruct, typename="unitree_hg.msg.dds_.IMUState_"): 25 | quaternion: types.array[types.float32, 4] 26 | gyroscope: types.array[types.float32, 3] 27 | accelerometer: types.array[types.float32, 3] 28 | rpy: types.array[types.float32, 3] 29 | temperature: types.int16 30 | 31 | 32 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_go/msg/dds_/_HeightMap_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: unitree_go.msg.dds_ 5 | IDL file: HeightMap_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import unitree_go 19 | 20 | 21 | @dataclass 22 | @annotate.final 23 | @annotate.autoid("sequential") 24 | class HeightMap_(idl.IdlStruct, typename="unitree_go.msg.dds_.HeightMap_"): 25 | stamp: types.float64 26 | frame_id: str 27 | resolution: types.float32 28 | width: types.uint32 29 | height: types.uint32 30 | origin: types.array[types.float32, 2] 31 | data: types.sequence[types.float32] 32 | 33 | 34 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_api/msg/dds_/_RequestHeader_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.10.2 4 | Module: unitree_api.msg.dds_ 5 | IDL file: RequestHeader_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import unitree_api 19 | 20 | 21 | @dataclass 22 | @annotate.final 23 | @annotate.autoid("sequential") 24 | class RequestHeader_(idl.IdlStruct, typename="unitree_api.msg.dds_.RequestHeader_"): 25 | identity: 'unitree_sdk2py.idl.unitree_api.msg.dds_.RequestIdentity_' 26 | lease: 'unitree_sdk2py.idl.unitree_api.msg.dds_.RequestLease_' 27 | policy: 'unitree_sdk2py.idl.unitree_api.msg.dds_.RequestPolicy_' 28 | 29 | 30 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/geometry_msgs/msg/dds_/_QuaternionStamped_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: geometry_msgs.msg.dds_ 5 | IDL file: QuaternionStamped_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import geometry_msgs 19 | 20 | # if TYPE_CHECKING: 21 | # import std_msgs.msg.dds_ 22 | 23 | 24 | 25 | @dataclass 26 | @annotate.final 27 | @annotate.autoid("sequential") 28 | class QuaternionStamped_(idl.IdlStruct, typename="geometry_msgs.msg.dds_.QuaternionStamped_"): 29 | header: 'unitree_sdk2py.idl.std_msgs.msg.dds_.Header_' 30 | quaternion: 'unitree_sdk2py.idl.geometry_msgs.msg.dds_.Quaternion_' 31 | 32 | 33 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/nav_msgs/msg/dds_/_OccupancyGrid_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: nav_msgs.msg.dds_ 5 | IDL file: OccupancyGrid_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import nav_msgs 19 | 20 | # if TYPE_CHECKING: 21 | # import std_msgs.msg.dds_ 22 | 23 | 24 | 25 | @dataclass 26 | @annotate.final 27 | @annotate.autoid("sequential") 28 | class OccupancyGrid_(idl.IdlStruct, typename="nav_msgs.msg.dds_.OccupancyGrid_"): 29 | header: 'unitree_sdk2py.idl.std_msgs.msg.dds_.Header_' 30 | info: 'unitree_sdk2py.idl.nav_msgs.msg.dds_.MapMetaData_' 31 | data: types.sequence[types.uint8] 32 | 33 | 34 | -------------------------------------------------------------------------------- /unitree_sdk2py/core/channel_config.py: -------------------------------------------------------------------------------- 1 | ChannelConfigHasInterface = ''' 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | config 11 | /tmp/cdds.LOG 12 | 13 | 14 | ''' 15 | 16 | ChannelConfigAutoDetermine = ''' 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | ''' 26 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/geometry_msgs/msg/dds_/_PoseWithCovarianceStamped_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: geometry_msgs.msg.dds_ 5 | IDL file: PoseWithCovarianceStamped_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import geometry_msgs 19 | 20 | # if TYPE_CHECKING: 21 | # import std_msgs.msg.dds_ 22 | 23 | 24 | 25 | @dataclass 26 | @annotate.final 27 | @annotate.autoid("sequential") 28 | class PoseWithCovarianceStamped_(idl.IdlStruct, typename="geometry_msgs.msg.dds_.PoseWithCovarianceStamped_"): 29 | header: 'unitree_sdk2py.idl.std_msgs.msg.dds_.Header_' 30 | pose: 'unitree_sdk2py.idl.geometry_msgs.msg.dds_.PoseWithCovariance_' 31 | 32 | 33 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/geometry_msgs/msg/dds_/_TwistWithCovarianceStamped_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: geometry_msgs.msg.dds_ 5 | IDL file: TwistWithCovarianceStamped_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import geometry_msgs 19 | 20 | # if TYPE_CHECKING: 21 | # import std_msgs.msg.dds_ 22 | 23 | 24 | 25 | @dataclass 26 | @annotate.final 27 | @annotate.autoid("sequential") 28 | class TwistWithCovarianceStamped_(idl.IdlStruct, typename="geometry_msgs.msg.dds_.TwistWithCovarianceStamped_"): 29 | header: 'unitree_sdk2py.idl.std_msgs.msg.dds_.Header_' 30 | twist: 'unitree_sdk2py.idl.geometry_msgs.msg.dds_.TwistWithCovariance_' 31 | 32 | 33 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_go/msg/dds_/_BmsState_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: unitree_go.msg.dds_ 5 | IDL file: BmsState_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import unitree_go 19 | 20 | 21 | @dataclass 22 | @annotate.final 23 | @annotate.autoid("sequential") 24 | class BmsState_(idl.IdlStruct, typename="unitree_go.msg.dds_.BmsState_"): 25 | version_high: types.uint8 26 | version_low: types.uint8 27 | status: types.uint8 28 | soc: types.uint8 29 | current: types.int32 30 | cycle: types.uint16 31 | bq_ntc: types.array[types.uint8, 2] 32 | mcu_ntc: types.array[types.uint8, 2] 33 | cell_vol: types.array[types.uint16, 15] 34 | 35 | 36 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_go/msg/dds_/_MotorState_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: unitree_go.msg.dds_ 5 | IDL file: MotorState_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import unitree_go 19 | 20 | 21 | @dataclass 22 | @annotate.final 23 | @annotate.autoid("sequential") 24 | class MotorState_(idl.IdlStruct, typename="unitree_go.msg.dds_.MotorState_"): 25 | mode: types.uint8 26 | q: types.float32 27 | dq: types.float32 28 | ddq: types.float32 29 | tau_est: types.float32 30 | q_raw: types.float32 31 | dq_raw: types.float32 32 | ddq_raw: types.float32 33 | temperature: types.uint8 34 | lost: types.uint32 35 | reserve: types.array[types.uint32, 2] 36 | 37 | 38 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_hg/msg/dds_/_MotorState_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: unitree_hg.msg.dds_ 5 | IDL file: MotorState_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import unitree_hg 19 | 20 | 21 | @dataclass 22 | @annotate.final 23 | @annotate.autoid("sequential") 24 | class MotorState_(idl.IdlStruct, typename="unitree_hg.msg.dds_.MotorState_"): 25 | mode: types.uint8 26 | q: types.float32 27 | dq: types.float32 28 | ddq: types.float32 29 | tau_est: types.float32 30 | temperature: types.array[types.int16, 2] 31 | vol: types.float32 32 | sensor: types.array[types.uint32, 2] 33 | motorstate: types.uint32 34 | reserve: types.array[types.uint32, 4] 35 | 36 | 37 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/nav_msgs/msg/dds_/_Odometry_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: nav_msgs.msg.dds_ 5 | IDL file: Odometry_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import nav_msgs 19 | 20 | # if TYPE_CHECKING: 21 | # import geometry_msgs.msg.dds_ 22 | # import std_msgs.msg.dds_ 23 | 24 | 25 | 26 | @dataclass 27 | @annotate.final 28 | @annotate.autoid("sequential") 29 | class Odometry_(idl.IdlStruct, typename="nav_msgs.msg.dds_.Odometry_"): 30 | header: 'unitree_sdk2py.idl.std_msgs.msg.dds_.Header_' 31 | child_frame_id: str 32 | pose: 'unitree_sdk2py.idl.geometry_msgs.msg.dds_.PoseWithCovariance_' 33 | twist: 'unitree_sdk2py.idl.geometry_msgs.msg.dds_.TwistWithCovariance_' 34 | 35 | 36 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/nav_msgs/msg/dds_/_MapMetaData_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: nav_msgs.msg.dds_ 5 | IDL file: MapMetaData_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import nav_msgs 19 | 20 | # if TYPE_CHECKING: 21 | # import builtin_interfaces.msg.dds_ 22 | # import geometry_msgs.msg.dds_ 23 | 24 | 25 | 26 | @dataclass 27 | @annotate.final 28 | @annotate.autoid("sequential") 29 | class MapMetaData_(idl.IdlStruct, typename="nav_msgs.msg.dds_.MapMetaData_"): 30 | map_load_time: 'unitree_sdk2py.idl.builtin_interfaces.msg.dds_.Time_' 31 | resolution: types.float32 32 | width: types.uint32 33 | height: types.uint32 34 | origin: 'unitree_sdk2py.idl.geometry_msgs.msg.dds_.Pose_' 35 | 36 | -------------------------------------------------------------------------------- /example/motionSwitcher/motion_switcher_example.py: -------------------------------------------------------------------------------- 1 | import time 2 | import sys 3 | 4 | from unitree_sdk2py.core.channel import ChannelFactoryInitialize 5 | from unitree_sdk2py.comm.motion_switcher.motion_switcher_client import MotionSwitcherClient 6 | 7 | 8 | class Custom: 9 | def __init__(self): 10 | self.msc = MotionSwitcherClient() 11 | self.msc.SetTimeout(5.0) 12 | self.msc.Init() 13 | 14 | def selectMode(self,name): 15 | ret = self.msc.SelectMode(name) 16 | return ret 17 | 18 | 19 | if __name__ == '__main__': 20 | 21 | print("WARNING: Please ensure there are no obstacles around the robot while running this example.") 22 | input("Press Enter to continue...") 23 | 24 | if len(sys.argv)>1: 25 | ChannelFactoryInitialize(0, sys.argv[1]) 26 | else: 27 | ChannelFactoryInitialize(0) 28 | 29 | custom = Custom() 30 | selectMode = "ai" 31 | # selectMode = "normal" 32 | # selectMode = "advanced" 33 | # selectMode = "ai-w" # for wheeled robot 34 | ret = custom.selectMode(selectMode) 35 | print("ret: ",ret) 36 | 37 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_hg/msg/dds_/_LowState_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: unitree_hg.msg.dds_ 5 | IDL file: LowState_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import unitree_hg 19 | 20 | 21 | @dataclass 22 | @annotate.final 23 | @annotate.autoid("sequential") 24 | class LowState_(idl.IdlStruct, typename="unitree_hg.msg.dds_.LowState_"): 25 | version: types.array[types.uint32, 2] 26 | mode_pr: types.uint8 27 | mode_machine: types.uint8 28 | tick: types.uint32 29 | imu_state: 'unitree_sdk2py.idl.unitree_hg.msg.dds_.IMUState_' 30 | motor_state: types.array['unitree_sdk2py.idl.unitree_hg.msg.dds_.MotorState_', 35] 31 | wireless_remote: types.array[types.uint8, 40] 32 | reserve: types.array[types.uint32, 4] 33 | crc: types.uint32 34 | 35 | 36 | -------------------------------------------------------------------------------- /unitree_sdk2py/rpc/server_base.py: -------------------------------------------------------------------------------- 1 | import time 2 | 3 | from typing import Callable, Any 4 | 5 | from ..idl.unitree_api.msg.dds_ import Request_ as Request 6 | from ..idl.unitree_api.msg.dds_ import Response_ as Response 7 | 8 | from .server_stub import ServerStub 9 | 10 | 11 | """ 12 | " class ServerBase 13 | """ 14 | class ServerBase: 15 | def __init__(self, name: str): 16 | self.__name = name 17 | self.__serverRequestHandler = None 18 | self.__serverStub = ServerStub(self.__name) 19 | 20 | def GetName(self): 21 | return self.__name 22 | 23 | def _Start(self, enablePrioQueue: bool = False): 24 | self.__serverStub.Init(self.__serverRequestHandler, enablePrioQueue) 25 | print("[ServerBase] server started. name:", self.__name, ", enable proirity queue:", enablePrioQueue) 26 | 27 | def _SetServerRequestHandler(self, serverRequestHandler: Callable): 28 | self.__serverRequestHandler = serverRequestHandler 29 | 30 | def _SendResponse(self, response: Response): 31 | if not self.__serverStub.Send(response, 1.0): 32 | print("[ServerBase] send response error.") 33 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/geometry_msgs/msg/dds_/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: geometry_msgs.msg.dds_ 5 | 6 | """ 7 | 8 | from ._Point32_ import Point32_ 9 | from ._Point_ import Point_ 10 | from ._PointStamped_ import PointStamped_ 11 | from ._Pose2D_ import Pose2D_ 12 | from ._Pose_ import Pose_ 13 | from ._PoseStamped_ import PoseStamped_ 14 | from ._PoseWithCovariance_ import PoseWithCovariance_ 15 | from ._PoseWithCovarianceStamped_ import PoseWithCovarianceStamped_ 16 | from ._Quaternion_ import Quaternion_ 17 | from ._QuaternionStamped_ import QuaternionStamped_ 18 | from ._Twist_ import Twist_ 19 | from ._TwistStamped_ import TwistStamped_ 20 | from ._TwistWithCovariance_ import TwistWithCovariance_ 21 | from ._TwistWithCovarianceStamped_ import TwistWithCovarianceStamped_ 22 | from ._Vector3_ import Vector3_ 23 | __all__ = ["Point32_", "Point_", "PointStamped_", "Pose2D_", "Pose_", "PoseStamped_", "PoseWithCovariance_", "PoseWithCovarianceStamped_", "Quaternion_", "QuaternionStamped_", "Twist_", "TwistStamped_", "TwistWithCovariance_", "TwistWithCovarianceStamped_", "Vector3_", ] 24 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/sensor_msgs/msg/dds_/_PointCloud2_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: sensor_msgs.msg.dds_ 5 | IDL file: PointCloud2_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import sensor_msgs 19 | 20 | # if TYPE_CHECKING: 21 | # import std_msgs.msg.dds_ 22 | 23 | 24 | 25 | @dataclass 26 | @annotate.final 27 | @annotate.autoid("sequential") 28 | class PointCloud2_(idl.IdlStruct, typename="sensor_msgs.msg.dds_.PointCloud2_"): 29 | header: 'unitree_sdk2py.idl.std_msgs.msg.dds_.Header_' 30 | height: types.uint32 31 | width: types.uint32 32 | fields: types.sequence['unitree_sdk2py.idl.sensor_msgs.msg.dds_.PointField_'] 33 | is_bigendian: bool 34 | point_step: types.uint32 35 | row_step: types.uint32 36 | data: types.sequence[types.uint8] 37 | is_dense: bool 38 | 39 | 40 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_hg/msg/dds_/_BmsState_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: unitree_hg.msg.dds_ 5 | IDL file: BmsState_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import unitree_hg 19 | 20 | 21 | @dataclass 22 | @annotate.final 23 | @annotate.autoid("sequential") 24 | class BmsState_(idl.IdlStruct, typename="unitree_hg.msg.dds_.BmsState_"): 25 | version_high: types.uint8 26 | version_low: types.uint8 27 | fn: types.uint8 28 | cell_vol: types.array[types.uint16, 40] 29 | bmsvoltage: types.array[types.uint32, 3] 30 | current: types.int32 31 | soc: types.uint8 32 | soh: types.uint8 33 | temperature: types.array[types.int16, 12] 34 | cycle: types.uint16 35 | manufacturer_date: types.uint16 36 | bmsstate: types.array[types.uint32, 5] 37 | reserve: types.array[types.uint32, 3] 38 | 39 | 40 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_hg/msg/dds_/_HandState_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: unitree_hg.msg.dds_ 5 | IDL file: HandState_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import unitree_hg 19 | 20 | 21 | @dataclass 22 | @annotate.final 23 | @annotate.autoid("sequential") 24 | class HandState_(idl.IdlStruct, typename="unitree_hg.msg.dds_.HandState_"): 25 | motor_state: types.sequence['unitree_sdk2py.idl.unitree_hg.msg.dds_.MotorState_'] 26 | press_sensor_state: types.sequence['unitree_sdk2py.idl.unitree_hg.msg.dds_.PressSensorState_'] 27 | imu_state: 'unitree_sdk2py.idl.unitree_hg.msg.dds_.IMUState_' 28 | power_v: types.float32 29 | power_a: types.float32 30 | system_v: types.float32 31 | device_v: types.float32 32 | error: types.array[types.uint32, 2] 33 | reserve: types.array[types.uint32, 2] 34 | 35 | 36 | -------------------------------------------------------------------------------- /unitree_sdk2py/test/rpc/test_server_example.py: -------------------------------------------------------------------------------- 1 | import time 2 | import json 3 | 4 | from unitree_sdk2py.core.channel import ChannelFactoryInitialize 5 | from unitree_sdk2py.rpc.server import Server 6 | 7 | from test_api import * 8 | 9 | 10 | """ 11 | " class TestServer 12 | """ 13 | class TestServer(Server): 14 | def __init__(self): 15 | super().__init__("test") 16 | 17 | def Init(self): 18 | self._RegistHandler(TEST_API_ID_MOVE, self.Move, 1) 19 | self._RegistHandler(TEST_API_ID_STOP, self.Stop, 0) 20 | self._SetApiVersion(TEST_API_VERSION) 21 | 22 | def Move(self, parameter: str): 23 | p = json.loads(parameter) 24 | x = p["vx"] 25 | y = p["vy"] 26 | yaw = p["vyaw"] 27 | print("Move Called. vx:", x, ", vy:", y, ", vyaw:", yaw) 28 | return 0, "" 29 | 30 | def Stop(self, parameter: str): 31 | print("Stop Called.") 32 | return 0, "" 33 | 34 | if __name__ == "__main__": 35 | # initialize channel factory. 36 | ChannelFactoryInitialize(0) 37 | 38 | # create server 39 | server = TestServer() 40 | server.Init() 41 | server.StartLease(1.0) 42 | server.Start(False) 43 | 44 | while True: 45 | time.sleep(10) -------------------------------------------------------------------------------- /example/obstacles_avoid/obstacles_avoid_move.py: -------------------------------------------------------------------------------- 1 | import time 2 | import sys 3 | 4 | from unitree_sdk2py.core.channel import ChannelFactoryInitialize 5 | from unitree_sdk2py.go2.obstacles_avoid.obstacles_avoid_client import ObstaclesAvoidClient 6 | 7 | if __name__ == "__main__": 8 | if len(sys.argv)>1: 9 | ChannelFactoryInitialize(0, sys.argv[1]) 10 | else: 11 | ChannelFactoryInitialize(0) 12 | 13 | try: 14 | client = ObstaclesAvoidClient() 15 | client.SetTimeout(3.0) 16 | client.Init() 17 | 18 | while not client.SwitchGet()[1]: 19 | client.SwitchSet(True) 20 | time.sleep(0.1) 21 | 22 | print("obstacles avoid switch on") 23 | 24 | client.UseRemoteCommandFromApi(True) 25 | time.sleep(0.5) 26 | client.Move(0.5, 0.0, 0.0) 27 | time.sleep(1.0) # move 1s 28 | client.Move(0.0, 0.0, 0.0) 29 | client.UseRemoteCommandFromApi(False) 30 | time.sleep(1.0) 31 | client.MoveToAbsolutePosition(0.0, 0.0, 0.0) 32 | client.MoveToIncrementPosition(0.0, 0.0, 0.0) 33 | 34 | except KeyboardInterrupt: 35 | client.Move(0.0, 0.0, 0.0) 36 | client.UseRemoteCommandFromApi(False) 37 | print("exit!!") 38 | -------------------------------------------------------------------------------- /example/g1/audio/g1_audio_client_play_wav.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from unitree_sdk2py.core.channel import ChannelFactoryInitialize 3 | from unitree_sdk2py.g1.audio.g1_audio_client import AudioClient 4 | from wav import read_wav, play_pcm_stream 5 | 6 | def main(): 7 | if len(sys.argv) < 3: 8 | print(f"Usage: python3 {sys.argv[0]} ") 9 | sys.exit(1) 10 | 11 | net_interface = sys.argv[1] 12 | wav_path = sys.argv[2] 13 | 14 | ChannelFactoryInitialize(0, net_interface) 15 | audioClient = AudioClient() 16 | audioClient.SetTimeout(10.0) 17 | audioClient.Init() 18 | 19 | pcm_list, sample_rate, num_channels, is_ok = read_wav(wav_path) 20 | print(f"[DEBUG] Read success: {is_ok}") 21 | print(f"[DEBUG] Sample rate: {sample_rate} Hz") 22 | print(f"[DEBUG] Channels: {num_channels}") 23 | print(f"[DEBUG] PCM byte length: {len(pcm_list)}") 24 | 25 | if not is_ok or sample_rate != 16000 or num_channels != 1: 26 | print("[ERROR] Failed to read WAV file or unsupported format (must be 16kHz mono)") 27 | return 28 | 29 | play_pcm_stream(audioClient, pcm_list, "example") 30 | 31 | audioClient.PlayStop("example") 32 | 33 | if __name__ == "__main__": 34 | main() 35 | 36 | -------------------------------------------------------------------------------- /example/go2/front_camera/camera_opencv.py: -------------------------------------------------------------------------------- 1 | from unitree_sdk2py.core.channel import ChannelFactoryInitialize 2 | from unitree_sdk2py.go2.video.video_client import VideoClient 3 | import cv2 4 | import numpy as np 5 | import sys 6 | 7 | 8 | if __name__ == "__main__": 9 | if len(sys.argv)>1: 10 | ChannelFactoryInitialize(0, sys.argv[1]) 11 | else: 12 | ChannelFactoryInitialize(0) 13 | 14 | client = VideoClient() # Create a video client 15 | client.SetTimeout(3.0) 16 | client.Init() 17 | 18 | code, data = client.GetImageSample() 19 | 20 | # Request normal when code==0 21 | while code == 0: 22 | # Get Image data from Go2 robot 23 | code, data = client.GetImageSample() 24 | 25 | # Convert to numpy image 26 | image_data = np.frombuffer(bytes(data), dtype=np.uint8) 27 | image = cv2.imdecode(image_data, cv2.IMREAD_COLOR) 28 | 29 | # Display image 30 | cv2.imshow("front_camera", image) 31 | # Press ESC to stop 32 | if cv2.waitKey(20) == 27: 33 | break 34 | 35 | if code != 0: 36 | print("Get image sample error. code:", code) 37 | else: 38 | # Capture an image 39 | cv2.imwrite("front_image.jpg", image) 40 | 41 | cv2.destroyWindow("front_camera") 42 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_go/msg/dds_/_UwbState_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: unitree_go.msg.dds_ 5 | IDL file: UwbState_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import unitree_go 19 | 20 | 21 | @dataclass 22 | @annotate.final 23 | @annotate.autoid("sequential") 24 | class UwbState_(idl.IdlStruct, typename="unitree_go.msg.dds_.UwbState_"): 25 | version: types.array[types.uint8, 2] 26 | channel: types.uint8 27 | joy_mode: types.uint8 28 | orientation_est: types.float32 29 | pitch_est: types.float32 30 | distance_est: types.float32 31 | yaw_est: types.float32 32 | tag_roll: types.float32 33 | tag_pitch: types.float32 34 | tag_yaw: types.float32 35 | base_roll: types.float32 36 | base_pitch: types.float32 37 | base_yaw: types.float32 38 | joystick: types.array[types.float32, 2] 39 | error_state: types.uint8 40 | buttons: types.uint8 41 | enabled_from_app: types.uint8 42 | 43 | 44 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_go/msg/dds_/_LowCmd_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: unitree_go.msg.dds_ 5 | IDL file: LowCmd_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import unitree_go 19 | 20 | 21 | @dataclass 22 | @annotate.final 23 | @annotate.autoid("sequential") 24 | class LowCmd_(idl.IdlStruct, typename="unitree_go.msg.dds_.LowCmd_"): 25 | head: types.array[types.uint8, 2] 26 | level_flag: types.uint8 27 | frame_reserve: types.uint8 28 | sn: types.array[types.uint32, 2] 29 | version: types.array[types.uint32, 2] 30 | bandwidth: types.uint16 31 | motor_cmd: types.array['unitree_sdk2py.idl.unitree_go.msg.dds_.MotorCmd_', 20] 32 | bms_cmd: 'unitree_sdk2py.idl.unitree_go.msg.dds_.BmsCmd_' 33 | wireless_remote: types.array[types.uint8, 40] 34 | led: types.array[types.uint8, 12] 35 | fan: types.array[types.uint8, 2] 36 | gpio: types.uint8 37 | reserve: types.uint32 38 | crc: types.uint32 39 | 40 | 41 | -------------------------------------------------------------------------------- /example/go2/high_level/go2_utlidar_switch.py: -------------------------------------------------------------------------------- 1 | import time 2 | import sys 3 | 4 | from unitree_sdk2py.core.channel import ChannelPublisher, ChannelFactoryInitialize 5 | from unitree_sdk2py.core.channel import ChannelSubscriber, ChannelFactoryInitialize 6 | from unitree_sdk2py.idl.std_msgs.msg.dds_ import String_ 7 | from unitree_sdk2py.idl.default import std_msgs_msg_dds__String_ 8 | 9 | class Custom: 10 | def __init__(self): 11 | # create publisher # 12 | self.publisher = ChannelPublisher("rt/utlidar/switch", String_) 13 | self.publisher.Init() 14 | self.low_cmd = std_msgs_msg_dds__String_() 15 | 16 | def go2_utlidar_switch(self,status): 17 | if status == "OFF": 18 | self.low_cmd.data = "OFF" 19 | elif status == "ON": 20 | self.low_cmd.data = "ON" 21 | 22 | self.publisher.Write(self.low_cmd) 23 | 24 | 25 | if __name__ == '__main__': 26 | 27 | print("WARNING: Please ensure there are no obstacles around the robot while running this example.") 28 | input("Press Enter to continue...") 29 | 30 | if len(sys.argv)>1: 31 | ChannelFactoryInitialize(0, sys.argv[1]) 32 | else: 33 | ChannelFactoryInitialize(0) 34 | 35 | custom = Custom() 36 | custom.go2_utlidar_switch("OFF") 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_go/msg/dds_/_LidarState_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: unitree_go.msg.dds_ 5 | IDL file: LidarState_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import unitree_go 19 | 20 | 21 | @dataclass 22 | @annotate.final 23 | @annotate.autoid("sequential") 24 | class LidarState_(idl.IdlStruct, typename="unitree_go.msg.dds_.LidarState_"): 25 | stamp: types.float64 26 | firmware_version: str 27 | software_version: str 28 | sdk_version: str 29 | sys_rotation_speed: types.float32 30 | com_rotation_speed: types.float32 31 | error_state: types.uint8 32 | cloud_frequency: types.float32 33 | cloud_packet_loss_rate: types.float32 34 | cloud_size: types.uint32 35 | cloud_scan_num: types.uint32 36 | imu_frequency: types.float32 37 | imu_packet_loss_rate: types.float32 38 | imu_rpy: types.array[types.float32, 3] 39 | serial_recv_stamp: types.float64 40 | serial_buffer_size: types.uint32 41 | serial_buffer_read: types.uint32 42 | 43 | 44 | -------------------------------------------------------------------------------- /unitree_sdk2py/rpc/request_future.py: -------------------------------------------------------------------------------- 1 | from threading import Condition, Lock 2 | from enum import Enum 3 | 4 | from ..idl.unitree_api.msg.dds_ import Response_ as Response 5 | from ..utils.future import Future, FutureResult 6 | 7 | 8 | """ 9 | " class RequestFuture 10 | """ 11 | class RequestFuture(Future): 12 | def __init__(self): 13 | self.__requestId = None 14 | super().__init__() 15 | 16 | def SetRequestId(self, requestId: int): 17 | self.__requestId = requestId 18 | 19 | def GetRequestId(self): 20 | return self.__requestId 21 | 22 | 23 | class RequestFutureQueue: 24 | def __init__(self): 25 | self.__data = {} 26 | self.__lock = Lock() 27 | 28 | def Set(self, requestId: int, future: RequestFuture): 29 | if future is None: 30 | return False 31 | with self.__lock: 32 | self.__data[requestId] = future 33 | return True 34 | 35 | def Get(self, requestId: int): 36 | future = None 37 | with self.__lock: 38 | future = self.__data.get(requestId) 39 | if future is not None: 40 | self.__data.pop(requestId) 41 | return future 42 | 43 | def Remove(self, requestId: int): 44 | with self.__lock: 45 | if id in self.__data: 46 | self.__data.pop(requestId) -------------------------------------------------------------------------------- /example/g1/audio/g1_audio_client_example.py: -------------------------------------------------------------------------------- 1 | import time 2 | import sys 3 | from unitree_sdk2py.core.channel import ChannelSubscriber, ChannelFactoryInitialize 4 | from unitree_sdk2py.g1.audio.g1_audio_client import AudioClient 5 | from unitree_sdk2py.g1.loco.g1_loco_client import LocoClient 6 | 7 | if __name__ == "__main__": 8 | if len(sys.argv) < 2: 9 | print(f"Usage: python3 {sys.argv[0]} networkInterface") 10 | sys.exit(-1) 11 | 12 | ChannelFactoryInitialize(0, sys.argv[1]) 13 | 14 | audio_client = AudioClient() 15 | audio_client.SetTimeout(10.0) 16 | audio_client.Init() 17 | 18 | sport_client = LocoClient() 19 | sport_client.SetTimeout(10.0) 20 | sport_client.Init() 21 | 22 | ret = audio_client.GetVolume() 23 | print("debug GetVolume: ",ret) 24 | 25 | audio_client.SetVolume(85) 26 | 27 | ret = audio_client.GetVolume() 28 | print("debug GetVolume: ",ret) 29 | 30 | sport_client.WaveHand() 31 | 32 | audio_client.TtsMaker("大家好!我是宇树科技人形机器人。语音开发测试例程运行成功! 很高兴认识你!",0) 33 | time.sleep(8) 34 | audio_client.TtsMaker("接下来测试灯带开发例程!",0) 35 | time.sleep(1) 36 | audio_client.LedControl(255,0,0) 37 | time.sleep(1) 38 | audio_client.LedControl(0,255,0) 39 | time.sleep(1) 40 | audio_client.LedControl(0,0,255) 41 | 42 | time.sleep(3) 43 | audio_client.TtsMaker("测试完毕,谢谢大家!",0) 44 | 45 | -------------------------------------------------------------------------------- /unitree_sdk2py/b2/sport/sport_api.py: -------------------------------------------------------------------------------- 1 | """ 2 | " service name 3 | """ 4 | SPORT_SERVICE_NAME = "sport" 5 | 6 | 7 | """ 8 | " service api version 9 | """ 10 | SPORT_API_VERSION = "1.0.0.1" 11 | 12 | 13 | """ 14 | " api id 15 | """ 16 | ROBOT_SPORT_API_ID_DAMP = 1001 17 | ROBOT_SPORT_API_ID_BALANCESTAND = 1002 18 | ROBOT_SPORT_API_ID_STOPMOVE = 1003 19 | ROBOT_SPORT_API_ID_STANDUP = 1004 20 | ROBOT_SPORT_API_ID_STANDDOWN = 1005 21 | ROBOT_SPORT_API_ID_RECOVERYSTAND = 1006 22 | ROBOT_SPORT_API_ID_MOVE = 1008 23 | ROBOT_SPORT_API_ID_SWITCHGAIT = 1011 24 | ROBOT_SPORT_API_ID_BODYHEIGHT = 1013 25 | ROBOT_SPORT_API_ID_SPEEDLEVEL = 1015 26 | ROBOT_SPORT_API_ID_TRAJECTORYFOLLOW = 1018 27 | ROBOT_SPORT_API_ID_CONTINUOUSGAIT = 1019 28 | ROBOT_SPORT_API_ID_MOVETOPOS = 1036 29 | ROBOT_SPORT_API_ID_SWITCHMOVEMODE = 1038 30 | ROBOT_SPORT_API_ID_VISIONWALK = 1101 31 | ROBOT_SPORT_API_ID_HANDSTAND = 1039 32 | ROBOT_SPORT_API_ID_AUTORECOVERY_SET = 1040 33 | ROBOT_SPORT_API_ID_FREEWALK = 1045 34 | ROBOT_SPORT_API_ID_CLASSICWALK = 1049 35 | ROBOT_SPORT_API_ID_FASTWALK = 1050 36 | ROBOT_SPORT_API_ID_FREEEULER = 1051 37 | 38 | """ 39 | " error code 40 | """ 41 | # client side 42 | SPORT_ERR_CLIENT_POINT_PATH = 4101 43 | # server side 44 | SPORT_ERR_SERVER_OVERTIME = 4201 45 | SPORT_ERR_SERVER_NOT_INIT = 4202 46 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_go/msg/dds_/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: unitree_go.msg.dds_ 5 | 6 | """ 7 | 8 | from ._AudioData_ import AudioData_ 9 | from ._BmsCmd_ import BmsCmd_ 10 | from ._BmsState_ import BmsState_ 11 | from ._Error_ import Error_ 12 | from ._Go2FrontVideoData_ import Go2FrontVideoData_ 13 | from ._HeightMap_ import HeightMap_ 14 | from ._IMUState_ import IMUState_ 15 | from ._InterfaceConfig_ import InterfaceConfig_ 16 | from ._LidarState_ import LidarState_ 17 | from ._LowCmd_ import LowCmd_ 18 | from ._LowState_ import LowState_ 19 | from ._MotorCmd_ import MotorCmd_ 20 | from ._MotorCmds_ import MotorCmds_ 21 | from ._MotorState_ import MotorState_ 22 | from ._MotorStates_ import MotorStates_ 23 | from ._Req_ import Req_ 24 | from ._Res_ import Res_ 25 | from ._SportModeState_ import SportModeState_ 26 | from ._TimeSpec_ import TimeSpec_ 27 | from ._PathPoint_ import PathPoint_ 28 | from ._UwbState_ import UwbState_ 29 | from ._UwbSwitch_ import UwbSwitch_ 30 | from ._WirelessController_ import WirelessController_ 31 | __all__ = ["AudioData_", "BmsCmd_", "BmsState_", "Error_", "Go2FrontVideoData_", "HeightMap_", "IMUState_", "InterfaceConfig_", "LidarState_", "LowCmd_", "LowState_", "MotorCmd_", "MotorCmds_", "MotorState_", "MotorStates_", "Req_", "Res_", "SportModeState_", "TimeSpec_", "PathPoint_", "UwbState_", "UwbSwitch_", "WirelessController_", ] 32 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_go/msg/dds_/_SportModeState_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: unitree_go.msg.dds_ 5 | IDL file: SportModeState_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import unitree_go 19 | 20 | 21 | @dataclass 22 | @annotate.final 23 | @annotate.autoid("sequential") 24 | class SportModeState_(idl.IdlStruct, typename="unitree_go.msg.dds_.SportModeState_"): 25 | stamp: 'unitree_sdk2py.idl.unitree_go.msg.dds_.TimeSpec_' 26 | error_code: types.uint32 27 | imu_state: 'unitree_sdk2py.idl.unitree_go.msg.dds_.IMUState_' 28 | mode: types.uint8 29 | progress: types.float32 30 | gait_type: types.uint8 31 | foot_raise_height: types.float32 32 | position: types.array[types.float32, 3] 33 | body_height: types.float32 34 | velocity: types.array[types.float32, 3] 35 | yaw_speed: types.float32 36 | range_obstacle: types.array[types.float32, 4] 37 | foot_force: types.array[types.int16, 4] 38 | foot_position_body: types.array[types.float32, 12] 39 | foot_speed_body: types.array[types.float32, 12] 40 | path_point: types.array['unitree_sdk2py.idl.unitree_go.msg.dds_.PathPoint_', 10] 41 | 42 | 43 | -------------------------------------------------------------------------------- /unitree_sdk2py/utils/timerfd.py: -------------------------------------------------------------------------------- 1 | import math 2 | import ctypes 3 | from .clib_lookup import CLIBLookup 4 | 5 | class timespec(ctypes.Structure): 6 | _fields_ = [("sec", ctypes.c_long), ("nsec", ctypes.c_long)] 7 | __slots__ = [name for name,type in _fields_] 8 | 9 | @classmethod 10 | def from_seconds(cls, secs): 11 | c = cls() 12 | c.seconds = secs 13 | return c 14 | 15 | @property 16 | def seconds(self): 17 | return self.sec + self.nsec / 1000000000 18 | 19 | @seconds.setter 20 | def seconds(self, secs): 21 | x, y = math.modf(secs) 22 | self.sec = int(y) 23 | self.nsec = int(x * 1000000000) 24 | 25 | 26 | class itimerspec(ctypes.Structure): 27 | _fields_ = [("interval", timespec),("value", timespec)] 28 | __slots__ = [name for name,type in _fields_] 29 | 30 | @classmethod 31 | def from_seconds(cls, interval, value): 32 | spec = cls() 33 | spec.interval.seconds = interval 34 | spec.value.seconds = value 35 | return spec 36 | 37 | 38 | # function timerfd_create 39 | timerfd_create = CLIBLookup("timerfd_create", ctypes.c_int, (ctypes.c_long, ctypes.c_int)) 40 | 41 | # function timerfd_settime 42 | timerfd_settime = CLIBLookup("timerfd_settime", ctypes.c_int, (ctypes.c_int, ctypes.c_int, ctypes.POINTER(itimerspec), ctypes.POINTER(itimerspec))) 43 | 44 | # function timerfd_gettime 45 | timerfd_gettime = CLIBLookup("timerfd_gettime", ctypes.c_int, (ctypes.c_int, ctypes.POINTER(itimerspec))) 46 | -------------------------------------------------------------------------------- /unitree_sdk2py/g1/arm/g1_arm_action_client.py: -------------------------------------------------------------------------------- 1 | import json 2 | 3 | from ...rpc.client import Client 4 | from .g1_arm_action_api import * 5 | 6 | action_map = { 7 | "release arm": 99, 8 | "two-hand kiss": 11, 9 | "left kiss": 12, 10 | "right kiss": 13, 11 | "hands up": 15, 12 | "clap": 17, 13 | "high five": 18, 14 | "hug": 19, 15 | "heart": 20, 16 | "right heart": 21, 17 | "reject": 22, 18 | "right hand up": 23, 19 | "x-ray": 24, 20 | "face wave": 25, 21 | "high wave": 26, 22 | "shake hand": 27, 23 | } 24 | 25 | 26 | """ 27 | " class SportClient 28 | """ 29 | class G1ArmActionClient(Client): 30 | def __init__(self): 31 | super().__init__(ARM_ACTION_SERVICE_NAME, False) 32 | 33 | def Init(self): 34 | # set api version 35 | self._SetApiVerson(ARM_ACTION_API_VERSION) 36 | 37 | # regist api 38 | self._RegistApi(ROBOT_API_ID_ARM_ACTION_EXECUTE_ACTION, 0) 39 | self._RegistApi(ROBOT_API_ID_ARM_ACTION_GET_ACTION_LIST, 0) 40 | 41 | ## API Call ## 42 | def ExecuteAction(self, action_id: int): 43 | p = {} 44 | p["data"] = action_id 45 | parameter = json.dumps(p) 46 | code, data = self._Call(ROBOT_API_ID_ARM_ACTION_EXECUTE_ACTION, parameter) 47 | return code 48 | 49 | def GetActionList(self): 50 | p = {} 51 | parameter = json.dumps(p) 52 | code, data = self._Call(ROBOT_API_ID_ARM_ACTION_GET_ACTION_LIST, parameter) 53 | if code == 0: 54 | return code, json.loads(data) 55 | else: 56 | return code, None -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2016-2024 HangZhou YuShu TECHNOLOGY CO.,LTD. ("Unitree Robotics") 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /unitree_sdk2py/comm/motion_switcher/motion_switcher_client.py: -------------------------------------------------------------------------------- 1 | import json 2 | 3 | from ...rpc.client import Client 4 | from .motion_switcher_api import * 5 | 6 | """ 7 | " class MotionSwitcherClient 8 | """ 9 | class MotionSwitcherClient(Client): 10 | def __init__(self): 11 | super().__init__(MOTION_SWITCHER_SERVICE_NAME, False) 12 | 13 | 14 | def Init(self): 15 | # set api version 16 | self._SetApiVerson(MOTION_SWITCHER_API_VERSION) 17 | 18 | # regist api 19 | self._RegistApi(MOTION_SWITCHER_API_ID_CHECK_MODE, 0) 20 | self._RegistApi(MOTION_SWITCHER_API_ID_SELECT_MODE, 0) 21 | self._RegistApi(MOTION_SWITCHER_API_ID_RELEASE_MODE, 0) 22 | self._RegistApi(MOTION_SWITCHER_API_ID_SET_SILENT, 0) 23 | self._RegistApi(MOTION_SWITCHER_API_ID_GET_SILENT, 0) 24 | 25 | # 1001 26 | def CheckMode(self): 27 | p = {} 28 | parameter = json.dumps(p) 29 | code, data = self._Call(MOTION_SWITCHER_API_ID_CHECK_MODE, parameter) 30 | if code == 0: 31 | return code, json.loads(data) 32 | else: 33 | return code, None 34 | 35 | # 1002 36 | def SelectMode(self, nameOrAlias): 37 | p = {} 38 | p["name"] = nameOrAlias 39 | parameter = json.dumps(p) 40 | code, data = self._Call(MOTION_SWITCHER_API_ID_SELECT_MODE, parameter) 41 | 42 | return code, None 43 | 44 | # 1003 45 | def ReleaseMode(self): 46 | p = {} 47 | parameter = json.dumps(p) 48 | code, data = self._Call(MOTION_SWITCHER_API_ID_RELEASE_MODE, parameter) 49 | 50 | return code, None 51 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_go/msg/dds_/_LowState_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.11.0 4 | Module: unitree_go.msg.dds_ 5 | IDL file: LowState_.idl 6 | 7 | """ 8 | 9 | from enum import auto 10 | from typing import TYPE_CHECKING, Optional 11 | from dataclasses import dataclass 12 | 13 | import cyclonedds.idl as idl 14 | import cyclonedds.idl.annotations as annotate 15 | import cyclonedds.idl.types as types 16 | 17 | # root module import for resolving types 18 | # import unitree_go 19 | 20 | 21 | @dataclass 22 | @annotate.final 23 | @annotate.autoid("sequential") 24 | class LowState_(idl.IdlStruct, typename="unitree_go.msg.dds_.LowState_"): 25 | head: types.array[types.uint8, 2] 26 | level_flag: types.uint8 27 | frame_reserve: types.uint8 28 | sn: types.array[types.uint32, 2] 29 | version: types.array[types.uint32, 2] 30 | bandwidth: types.uint16 31 | imu_state: 'unitree_sdk2py.idl.unitree_go.msg.dds_.IMUState_' 32 | motor_state: types.array['unitree_sdk2py.idl.unitree_go.msg.dds_.MotorState_', 20] 33 | bms_state: 'unitree_sdk2py.idl.unitree_go.msg.dds_.BmsState_' 34 | foot_force: types.array[types.int16, 4] 35 | foot_force_est: types.array[types.int16, 4] 36 | tick: types.uint32 37 | wireless_remote: types.array[types.uint8, 40] 38 | bit_flag: types.uint8 39 | adc_reel: types.float32 40 | temperature_ntc1: types.uint8 41 | temperature_ntc2: types.uint8 42 | power_v: types.float32 43 | power_a: types.float32 44 | fan_frequency: types.array[types.uint16, 4] 45 | reserve: types.uint32 46 | crc: types.uint32 47 | 48 | 49 | -------------------------------------------------------------------------------- /unitree_sdk2py/go2/sport/sport_api.py: -------------------------------------------------------------------------------- 1 | """ 2 | " service name 3 | """ 4 | SPORT_SERVICE_NAME = "sport" 5 | 6 | 7 | """ 8 | " service api version 9 | """ 10 | SPORT_API_VERSION = "1.0.0.1" 11 | 12 | 13 | """ 14 | " api id 15 | """ 16 | SPORT_API_ID_DAMP = 1001 17 | SPORT_API_ID_BALANCESTAND = 1002 18 | SPORT_API_ID_STOPMOVE = 1003 19 | SPORT_API_ID_STANDUP = 1004 20 | SPORT_API_ID_STANDDOWN = 1005 21 | SPORT_API_ID_RECOVERYSTAND = 1006 22 | SPORT_API_ID_EULER = 1007 23 | SPORT_API_ID_MOVE = 1008 24 | SPORT_API_ID_SIT = 1009 25 | SPORT_API_ID_RISESIT = 1010 26 | SPORT_API_ID_SPEEDLEVEL = 1015 27 | SPORT_API_ID_HELLO = 1016 28 | SPORT_API_ID_STRETCH = 1017 29 | SPORT_API_ID_CONTENT = 1020 30 | SPORT_API_ID_DANCE1 = 1022 31 | SPORT_API_ID_DANCE2 = 1023 32 | SPORT_API_ID_SWITCHJOYSTICK = 1027 33 | SPORT_API_ID_POSE = 1028 34 | SPORT_API_ID_SCRAPE = 1029 35 | SPORT_API_ID_FRONTFLIP = 1030 36 | SPORT_API_ID_FRONTJUMP = 1031 37 | SPORT_API_ID_FRONTPOUNCE = 1032 38 | SPORT_API_ID_HEART = 1036 39 | SPORT_API_ID_STATICWALK = 1061 40 | SPORT_API_ID_TROTRUN = 1062 41 | SPORT_API_ID_ECONOMICGAIT = 1063 42 | SPORT_API_ID_LEFTFLIP = 2041 43 | SPORT_API_ID_BACKFLIP = 2043 44 | SPORT_API_ID_HANDSTAND = 2044 45 | SPORT_API_ID_FREEWALK = 2045 46 | SPORT_API_ID_FREEBOUND = 2046 47 | SPORT_API_ID_FREEJUMP = 2047 48 | SPORT_API_ID_FREEAVOID = 2048 49 | SPORT_API_ID_CLASSICWALK = 2049 50 | SPORT_API_ID_WALKUPRIGHT = 2050 51 | SPORT_API_ID_CROSSSTEP = 2051 52 | SPORT_API_ID_AUTORECOVERY_SET = 2054 53 | SPORT_API_ID_AUTORECOVERY_GET = 2055 54 | SPORT_API_ID_SWITCHAVOIDMODE = 2058 55 | 56 | """ 57 | " error code 58 | """ 59 | # client side 60 | SPORT_ERR_CLIENT_POINT_PATH = 4101 61 | # server side 62 | SPORT_ERR_SERVER_OVERTIME = 4201 63 | SPORT_ERR_SERVER_NOT_INIT = 4202 64 | -------------------------------------------------------------------------------- /example/b2/camera/capture_image.py: -------------------------------------------------------------------------------- 1 | import time 2 | import os 3 | import sys 4 | 5 | from unitree_sdk2py.core.channel import ChannelFactoryInitialize 6 | from unitree_sdk2py.b2.front_video.front_video_client import FrontVideoClient 7 | from unitree_sdk2py.b2.back_video.back_video_client import BackVideoClient 8 | 9 | if __name__ == "__main__": 10 | if len(sys.argv) > 1: 11 | ChannelFactoryInitialize(0, sys.argv[1]) 12 | else: 13 | ChannelFactoryInitialize(0) 14 | 15 | # 创建前置相机客户端 16 | front_client = FrontVideoClient() 17 | front_client.SetTimeout(3.0) 18 | front_client.Init() 19 | 20 | # 创建后置相机客户端 21 | back_client = BackVideoClient() 22 | back_client.SetTimeout(3.0) 23 | back_client.Init() 24 | 25 | print("##################Get Front Camera Image###################") 26 | # 获取前置相机图像 27 | front_code, front_data = front_client.GetImageSample() 28 | 29 | if front_code != 0: 30 | print("Get front camera image error. Code:", front_code) 31 | else: 32 | front_image_name = "./front_img.jpg" 33 | print("Front Image Saved as:", front_image_name) 34 | 35 | with open(front_image_name, "+wb") as f: 36 | f.write(bytes(front_data)) 37 | 38 | print("##################Get Back Camera Image###################") 39 | # 获取后置相机图像 40 | back_code, back_data = back_client.GetImageSample() 41 | 42 | if back_code != 0: 43 | print("Get back camera image error. Code:", back_code) 44 | else: 45 | back_image_name = "./back_img.jpg" 46 | print("Back Image Saved as:", back_image_name) 47 | 48 | with open(back_image_name, "+wb") as f: 49 | f.write(bytes(back_data)) 50 | 51 | time.sleep(1) 52 | -------------------------------------------------------------------------------- /example/b2w/camera/capture_image.py: -------------------------------------------------------------------------------- 1 | import time 2 | import os 3 | import sys 4 | 5 | from unitree_sdk2py.core.channel import ChannelFactoryInitialize 6 | from unitree_sdk2py.b2.front_video.front_video_client import FrontVideoClient 7 | from unitree_sdk2py.b2.back_video.back_video_client import BackVideoClient 8 | 9 | if __name__ == "__main__": 10 | if len(sys.argv) > 1: 11 | ChannelFactoryInitialize(0, sys.argv[1]) 12 | else: 13 | ChannelFactoryInitialize(0) 14 | 15 | # 创建前置相机客户端 16 | front_client = FrontVideoClient() 17 | front_client.SetTimeout(3.0) 18 | front_client.Init() 19 | 20 | # 创建后置相机客户端 21 | back_client = BackVideoClient() 22 | back_client.SetTimeout(3.0) 23 | back_client.Init() 24 | 25 | print("##################Get Front Camera Image###################") 26 | # 获取前置相机图像 27 | front_code, front_data = front_client.GetImageSample() 28 | 29 | if front_code != 0: 30 | print("Get front camera image error. Code:", front_code) 31 | else: 32 | front_image_name = "./front_img.jpg" 33 | print("Front Image Saved as:", front_image_name) 34 | 35 | with open(front_image_name, "+wb") as f: 36 | f.write(bytes(front_data)) 37 | 38 | print("##################Get Back Camera Image###################") 39 | # 获取后置相机图像 40 | back_code, back_data = back_client.GetImageSample() 41 | 42 | if back_code != 0: 43 | print("Get back camera image error. Code:", back_code) 44 | else: 45 | back_image_name = "./back_img.jpg" 46 | print("Back Image Saved as:", back_image_name) 47 | 48 | with open(back_image_name, "+wb") as f: 49 | f.write(bytes(back_data)) 50 | 51 | time.sleep(1) 52 | -------------------------------------------------------------------------------- /unitree_sdk2py/test/rpc/test_client_example.py: -------------------------------------------------------------------------------- 1 | import time 2 | import json 3 | 4 | from unitree_sdk2py.core.channel import ChannelFactoryInitialize 5 | from unitree_sdk2py.rpc.client import Client 6 | 7 | from test_api import * 8 | 9 | """ 10 | " class TestClient 11 | """ 12 | class TestClient(Client): 13 | def __init__(self, enableLease: bool = False): 14 | super().__init__("test", enableLease) 15 | 16 | def Init(self): 17 | self._RegistApi(TEST_API_ID_MOVE, 0) 18 | self._RegistApi(TEST_API_ID_STOP, 1) 19 | self._SetApiVerson(TEST_API_VERSION) 20 | 21 | def Move(self, vx: float, vy: float, vyaw: float): 22 | parameter = {} 23 | parameter["vx"] = vx 24 | parameter["vy"] = vy 25 | parameter["vyaw"] = vyaw 26 | p = json.dumps(parameter) 27 | 28 | c, d = self._Call(TEST_API_ID_MOVE, p) 29 | return c 30 | 31 | def Stop(self): 32 | parameter = {} 33 | p = json.dumps(parameter) 34 | 35 | c, d = self._Call(TEST_API_ID_STOP, p) 36 | return c 37 | 38 | if __name__ == "__main__": 39 | # initialize channel factory. 40 | ChannelFactoryInitialize(0) 41 | 42 | # create client 43 | client = TestClient(True) 44 | client.Init() 45 | client.SetTimeout(5.0) 46 | 47 | # get server version 48 | code, serverApiVersion = client.GetServerApiVersion() 49 | print("server api version:", serverApiVersion) 50 | 51 | # wait lease applied 52 | client.WaitLeaseApplied() 53 | 54 | # test api 55 | while True: 56 | code = client.Move(0.2, 0, 0) 57 | print("client move ret:", code) 58 | time.sleep(1.0) 59 | 60 | code = client.Stop() 61 | print("client stop ret:", code) 62 | time.sleep(1.0) 63 | -------------------------------------------------------------------------------- /unitree_sdk2py/test/client/robot_service_client_example.py: -------------------------------------------------------------------------------- 1 | import time 2 | from unitree_sdk2py.core.channel import ChannelFactoryInitialize 3 | from unitree_sdk2py.go2.robot_state.robot_state_client import RobotStateClient 4 | 5 | if __name__ == "__main__": 6 | ChannelFactoryInitialize(0, "enx000ec6768747") 7 | rsc = RobotStateClient() 8 | rsc.SetTimeout(3.0) 9 | rsc.Init() 10 | 11 | while True: 12 | print("##################GetServerApiVersion###################") 13 | code, serverAPiVersion = rsc.GetServerApiVersion() 14 | 15 | if code != 0: 16 | print("get server api error. code:", code) 17 | else: 18 | print("get server api version:", serverAPiVersion) 19 | 20 | time.sleep(3) 21 | 22 | print("##################ServiceList###################") 23 | code, lst = rsc.ServiceList() 24 | 25 | if code != 0: 26 | print("list sevrice error. code:", code) 27 | else: 28 | print("list service success. len:", len(lst)) 29 | for s in lst: 30 | print("name:", s.name, ", protect:", s.protect, ", status:", s.status) 31 | 32 | time.sleep(3) 33 | 34 | print("##################ServiceSwitch###################") 35 | code = rsc.ServiceSwitch("sport_mode", False) 36 | if code != 0: 37 | print("service stop sport_mode error. code:", code) 38 | else: 39 | print("service stop sport_mode success. code:", code) 40 | 41 | time.sleep(1) 42 | 43 | code = rsc.ServiceSwitch("sport_mode", True) 44 | if code != 0: 45 | print("service start sport_mode error. code:", code) 46 | else: 47 | print("service start sport_mode success. code:", code) 48 | 49 | time.sleep(3) 50 | 51 | -------------------------------------------------------------------------------- /example/b2/camera/camera_opencv.py: -------------------------------------------------------------------------------- 1 | from unitree_sdk2py.core.channel import ChannelFactoryInitialize 2 | from unitree_sdk2py.b2.front_video.front_video_client import FrontVideoClient 3 | from unitree_sdk2py.b2.back_video.back_video_client import BackVideoClient 4 | import cv2 5 | import numpy as np 6 | import sys 7 | 8 | def display_image(window_name, data): 9 | # If data is a list, we need to convert it to a bytes object 10 | if isinstance(data, list): 11 | data = bytes(data) 12 | 13 | # Now convert to numpy image 14 | image_data = np.frombuffer(data, dtype=np.uint8) 15 | image = cv2.imdecode(image_data, cv2.IMREAD_COLOR) 16 | if image is not None: 17 | cv2.imshow(window_name, image) 18 | 19 | if __name__ == "__main__": 20 | if len(sys.argv) > 1: 21 | ChannelFactoryInitialize(0, sys.argv[1]) 22 | else: 23 | ChannelFactoryInitialize(0) 24 | 25 | frontCameraClient = FrontVideoClient() # Create a front camera video client 26 | frontCameraClient.SetTimeout(3.0) 27 | frontCameraClient.Init() 28 | 29 | backCameraClient = BackVideoClient() # Create a back camera video client 30 | backCameraClient.SetTimeout(3.0) 31 | backCameraClient.Init() 32 | 33 | # Loop to continuously fetch images 34 | while True: 35 | # Get front camera image 36 | front_code, front_data = frontCameraClient.GetImageSample() 37 | if front_code == 0: 38 | display_image("Front Camera", front_data) 39 | 40 | # Get back camera image 41 | back_code, back_data = backCameraClient.GetImageSample() 42 | if back_code == 0: 43 | display_image("Back Camera", back_data) 44 | 45 | # Press ESC to stop 46 | if cv2.waitKey(20) == 27: 47 | break 48 | 49 | # Clean up windows 50 | cv2.destroyAllWindows() 51 | 52 | -------------------------------------------------------------------------------- /example/b2w/camera/camera_opencv.py: -------------------------------------------------------------------------------- 1 | from unitree_sdk2py.core.channel import ChannelFactoryInitialize 2 | from unitree_sdk2py.b2.front_video.front_video_client import FrontVideoClient 3 | from unitree_sdk2py.b2.back_video.back_video_client import BackVideoClient 4 | import cv2 5 | import numpy as np 6 | import sys 7 | 8 | def display_image(window_name, data): 9 | # If data is a list, we need to convert it to a bytes object 10 | if isinstance(data, list): 11 | data = bytes(data) 12 | 13 | # Now convert to numpy image 14 | image_data = np.frombuffer(data, dtype=np.uint8) 15 | image = cv2.imdecode(image_data, cv2.IMREAD_COLOR) 16 | if image is not None: 17 | cv2.imshow(window_name, image) 18 | 19 | if __name__ == "__main__": 20 | if len(sys.argv) > 1: 21 | ChannelFactoryInitialize(0, sys.argv[1]) 22 | else: 23 | ChannelFactoryInitialize(0) 24 | 25 | frontCameraClient = FrontVideoClient() # Create a front camera video client 26 | frontCameraClient.SetTimeout(3.0) 27 | frontCameraClient.Init() 28 | 29 | backCameraClient = BackVideoClient() # Create a back camera video client 30 | backCameraClient.SetTimeout(3.0) 31 | backCameraClient.Init() 32 | 33 | # Loop to continuously fetch images 34 | while True: 35 | # Get front camera image 36 | front_code, front_data = frontCameraClient.GetImageSample() 37 | if front_code == 0: 38 | display_image("Front Camera", front_data) 39 | 40 | # Get back camera image 41 | back_code, back_data = backCameraClient.GetImageSample() 42 | if back_code == 0: 43 | display_image("Back Camera", back_data) 44 | 45 | # Press ESC to stop 46 | if cv2.waitKey(20) == 27: 47 | break 48 | 49 | # Clean up windows 50 | cv2.destroyAllWindows() 51 | 52 | -------------------------------------------------------------------------------- /unitree_sdk2py/utils/bqueue.py: -------------------------------------------------------------------------------- 1 | from typing import Any 2 | from collections import deque 3 | from threading import Condition 4 | 5 | class BQueue: 6 | def __init__(self, maxLen: int = 10): 7 | self.__curLen = 0 8 | self.__maxLen = maxLen 9 | self.__queue = deque() 10 | self.__condition = Condition() 11 | 12 | def Put(self, x: Any, replace: bool = False): 13 | noReplaced = True 14 | with self.__condition: 15 | if self.__curLen >= self.__maxLen: 16 | if not replace: 17 | return False 18 | else: 19 | noReplaced = False 20 | self.__queue.popleft() 21 | self.__curLen -= 1 22 | 23 | self.__queue.append(x) 24 | self.__curLen += 1 25 | self.__condition.notify() 26 | 27 | return noReplaced 28 | 29 | def Get(self, timeout: float = None): 30 | with self.__condition: 31 | if not self.__queue: 32 | try: 33 | self.__condition.wait(timeout) 34 | except: 35 | return None 36 | 37 | if not self.__queue: 38 | return None 39 | 40 | self.__curLen -= 1 41 | return self.__queue.popleft() 42 | 43 | def Clear(self): 44 | with self.__condition: 45 | if self.__queue: 46 | self.__queue.clear() 47 | self.__curLen = 0 48 | 49 | def Size(self): 50 | with self.__condition: 51 | return self.__curLen 52 | 53 | def Interrupt(self, notifyAll: bool = False): 54 | with self.__condition: 55 | if notifyAll: 56 | self.__condition.notify() 57 | else: 58 | self.__condition.notify_all() 59 | -------------------------------------------------------------------------------- /unitree_sdk2py/test/lowlevel/lowlevel_control.py: -------------------------------------------------------------------------------- 1 | import time 2 | 3 | from unitree_sdk2py.core.channel import ChannelPublisher, ChannelFactoryInitialize 4 | from unitree_sdk2py.core.channel import ChannelSubscriber, ChannelFactoryInitialize 5 | from unitree_sdk2py.idl.default import unitree_go_msg_dds__LowCmd_ 6 | from unitree_sdk2py.idl.unitree_go.msg.dds_ import LowCmd_ 7 | from unitree_sdk2py.utils.crc import CRC 8 | from unitree_sdk2py.utils.thread import Thread 9 | import unitree_go2_const as go2 10 | 11 | crc = CRC() 12 | lowCmdThreadPtr=Thread() 13 | 14 | if __name__ == '__main__': 15 | 16 | ChannelFactoryInitialize(1, "enp2s0") 17 | # Create a publisher to publish the data defined in UserData class 18 | pub = ChannelPublisher("lowcmd", LowCmd_) 19 | pub.Init() 20 | 21 | while True: 22 | # Create a Userdata message 23 | cmd = unitree_go_msg_dds__LowCmd_() 24 | 25 | # Toque controle, set RL_2 toque 26 | cmd.motor_cmd[go2.LegID["RL_2"]].mode = 0x01 27 | cmd.motor_cmd[go2.LegID["RL_2"]].q = go2.PosStopF # Set to stop position(rad) 28 | cmd.motor_cmd[go2.LegID["RL_2"]].kp = 0 29 | cmd.motor_cmd[go2.LegID["RL_2"]].dq = go2.VelStopF # Set to stop angular velocity(rad/s) 30 | cmd.motor_cmd[go2.LegID["RL_2"]].kd = 0 31 | cmd.motor_cmd[go2.LegID["RL_2"]].tau = 1 # target toque is set to 1N.m 32 | 33 | # Poinstion(rad) control, set RL_0 rad 34 | cmd.motor_cmd[go2.LegID["RL_0"]].mode = 0x01 35 | cmd.motor_cmd[go2.LegID["RL_0"]].q = 0 # Taregt angular(rad) 36 | cmd.motor_cmd[go2.LegID["RL_0"]].kp = 10 # Poinstion(rad) control kp gain 37 | cmd.motor_cmd[go2.LegID["RL_0"]].dq = 0 # Taregt angular velocity(rad/ss) 38 | cmd.motor_cmd[go2.LegID["RL_0"]].kd = 1 # Poinstion(rad) control kd gain 39 | cmd.motor_cmd[go2.LegID["RL_0"]].tau = 0 # Feedforward toque 1N.m 40 | 41 | cmd.crc = crc.Crc(cmd) 42 | 43 | #Publish message 44 | if pub.Write(cmd): 45 | print("Publish success. msg:", cmd.crc) 46 | else: 47 | print("Waitting for subscriber.") 48 | 49 | time.sleep(0.002) 50 | 51 | pub.Close() 52 | -------------------------------------------------------------------------------- /unitree_sdk2py/test/client/vui_client_example.py: -------------------------------------------------------------------------------- 1 | import time 2 | import os 3 | 4 | from unitree_sdk2py.core.channel import ChannelFactoryInitialize 5 | from unitree_sdk2py.go2.vui.vui_client import VuiClient 6 | 7 | if __name__ == "__main__": 8 | ChannelFactoryInitialize(0, "enp2s0") 9 | 10 | client = VuiClient() 11 | client.SetTimeout(3.0) 12 | client.Init() 13 | 14 | for i in range(1, 11): 15 | print("#################GetBrightness####################") 16 | code, level = client.GetBrightness() 17 | 18 | if code != 0: 19 | print("get brightness error. code:", code) 20 | else: 21 | print("get brightness success. level:", level) 22 | 23 | time.sleep(1) 24 | 25 | print("#################SetBrightness####################") 26 | 27 | code = client.SetBrightness(i) 28 | 29 | if code != 0: 30 | print("set brightness error. code:", code) 31 | else: 32 | print("set brightness success. level:", i) 33 | 34 | time.sleep(1) 35 | 36 | print("#################SetBrightness 0####################") 37 | 38 | code = client.SetBrightness(0) 39 | 40 | if code != 0: 41 | print("set brightness error. code:", code) 42 | else: 43 | print("set brightness 0 success.") 44 | 45 | for i in range(1, 11): 46 | print("#################GetVolume####################") 47 | code, level = client.GetVolume() 48 | 49 | if code != 0: 50 | print("get volume error. code:", code) 51 | else: 52 | print("get volume success. level:", level) 53 | 54 | time.sleep(1) 55 | 56 | print("#################SetVolume####################") 57 | 58 | code = client.SetVolume(i) 59 | 60 | if code != 0: 61 | print("set volume error. code:", code) 62 | else: 63 | print("set volume success. level:", i) 64 | 65 | time.sleep(1) 66 | 67 | print("#################SetVolume 0####################") 68 | 69 | code = client.SetVolume(0) 70 | 71 | if code != 0: 72 | print("set volume error. code:", code) 73 | else: 74 | print("set volume 0 success.") 75 | -------------------------------------------------------------------------------- /example/vui_client/vui_client_example.py: -------------------------------------------------------------------------------- 1 | import time 2 | import sys 3 | 4 | from unitree_sdk2py.core.channel import ChannelFactoryInitialize 5 | from unitree_sdk2py.go2.vui.vui_client import VuiClient 6 | 7 | if __name__ == "__main__": 8 | if len(sys.argv)>1: 9 | ChannelFactoryInitialize(0, sys.argv[1]) 10 | else: 11 | ChannelFactoryInitialize(0) 12 | 13 | client = VuiClient() 14 | client.SetTimeout(3.0) 15 | client.Init() 16 | 17 | for i in range(1, 11): 18 | print("#################GetBrightness####################") 19 | code, level = client.GetBrightness() 20 | 21 | if code != 0: 22 | print("get brightness error. code:", code) 23 | else: 24 | print("get brightness success. level:", level) 25 | 26 | time.sleep(1) 27 | 28 | print("#################SetBrightness####################") 29 | 30 | code = client.SetBrightness(i) 31 | 32 | if code != 0: 33 | print("set brightness error. code:", code) 34 | else: 35 | print("set brightness success. level:", i) 36 | 37 | time.sleep(1) 38 | 39 | print("#################SetBrightness 0####################") 40 | 41 | code = client.SetBrightness(0) 42 | 43 | if code != 0: 44 | print("set brightness error. code:", code) 45 | else: 46 | print("set brightness 0 success.") 47 | 48 | for i in range(1, 11): 49 | print("#################GetVolume####################") 50 | code, level = client.GetVolume() 51 | 52 | if code != 0: 53 | print("get volume error. code:", code) 54 | else: 55 | print("get volume success. level:", level) 56 | 57 | time.sleep(1) 58 | 59 | print("#################SetVolume####################") 60 | 61 | code = client.SetVolume(i) 62 | 63 | if code != 0: 64 | print("set volume error. code:", code) 65 | else: 66 | print("set volume success. level:", i) 67 | 68 | time.sleep(1) 69 | 70 | print("#################SetVolume 0####################") 71 | 72 | code = client.SetVolume(0) 73 | 74 | if code != 0: 75 | print("set volume error. code:", code) 76 | else: 77 | print("set volume 0 success.") 78 | -------------------------------------------------------------------------------- /unitree_sdk2py/go2/robot_state/robot_state_client.py: -------------------------------------------------------------------------------- 1 | import json 2 | 3 | from ...rpc.client import Client 4 | from ...rpc.internal import * 5 | from .robot_state_api import * 6 | 7 | 8 | """ 9 | " class ServiceState 10 | """ 11 | class ServiceState: 12 | def __init__(self, name: str = None, status: int = None, protect: bool = None): 13 | self.name = name 14 | self.status = status 15 | self.protect = protect 16 | 17 | """ 18 | " class RobotStateClient 19 | """ 20 | class RobotStateClient(Client): 21 | def __init__(self): 22 | super().__init__(ROBOT_STATE_SERVICE_NAME, False) 23 | 24 | def Init(self): 25 | # set api version 26 | self._SetApiVerson(ROBOT_STATE_API_VERSION) 27 | # regist api 28 | self._RegistApi(ROBOT_STATE_API_ID_SERVICE_SWITCH, 0) 29 | self._RegistApi(ROBOT_STATE_API_ID_REPORT_FREQ, 0) 30 | self._RegistApi(ROBOT_STATE_API_ID_SERVICE_LIST, 0) 31 | 32 | def ServiceList(self): 33 | p = {} 34 | parameter = json.dumps(p) 35 | 36 | code, data = self._Call(ROBOT_STATE_API_ID_SERVICE_LIST, parameter) 37 | 38 | if code != 0: 39 | return code, None 40 | 41 | lst = [] 42 | 43 | d = json.loads(data) 44 | for t in d: 45 | s = ServiceState() 46 | s.name = t["name"] 47 | s.status = t["status"] 48 | s.protect = t["protect"] 49 | lst.append(s) 50 | 51 | return code, lst 52 | 53 | 54 | def ServiceSwitch(self, name: str, switch: bool): 55 | p = {} 56 | p["name"] = name 57 | p["switch"] = int(switch) 58 | parameter = json.dumps(p) 59 | 60 | code, data = self._Call(ROBOT_STATE_API_ID_SERVICE_SWITCH, parameter) 61 | 62 | if code != 0: 63 | return code 64 | 65 | d = json.loads(data) 66 | 67 | status = d["status"] 68 | 69 | if status == 5: 70 | return ROBOT_STATE_ERR_SERVICE_PROTECTED 71 | 72 | if status != 0 and status != 1: 73 | return ROBOT_STATE_ERR_SERVICE_SWITCH 74 | 75 | return code 76 | 77 | def SetReportFreq(self, interval: int, duration: int): 78 | p = {} 79 | p["interval"] = interval 80 | p["duration"] = duration 81 | parameter = json.dumps(p) 82 | 83 | code, data = self._Call(ROBOT_STATE_API_ID_REPORT_FREQ, p) 84 | return code 85 | -------------------------------------------------------------------------------- /unitree_sdk2py/b2/robot_state/robot_state_client.py: -------------------------------------------------------------------------------- 1 | import json 2 | 3 | from ...rpc.client import Client 4 | from ...rpc.client_internal import * 5 | from .robot_state_api import * 6 | 7 | 8 | """ 9 | " class ServiceState 10 | """ 11 | class ServiceState: 12 | def __init__(self, name: str = None, status: int = None, protect: bool = None): 13 | self.name = name 14 | self.status = status 15 | self.protect = protect 16 | 17 | """ 18 | " class RobotStateClient 19 | """ 20 | class RobotStateClient(Client): 21 | def __init__(self): 22 | super().__init__(ROBOT_STATE_SERVICE_NAME, False) 23 | 24 | def Init(self): 25 | # set api version 26 | self._SetApiVerson(ROBOT_STATE_API_VERSION) 27 | # regist api 28 | self._RegistApi(ROBOT_STATE_API_ID_SERVICE_SWITCH, 0) 29 | self._RegistApi(ROBOT_STATE_API_ID_REPORT_FREQ, 0) 30 | self._RegistApi(ROBOT_STATE_API_ID_SERVICE_LIST, 0) 31 | 32 | def ServiceList(self): 33 | p = {} 34 | parameter = json.dumps(p) 35 | 36 | code, data = self._Call(ROBOT_STATE_API_ID_SERVICE_LIST, parameter) 37 | 38 | if code != 0: 39 | return code, None 40 | 41 | lst = [] 42 | 43 | d = json.loads(data) 44 | for t in d: 45 | s = ServiceState() 46 | s.name = t["name"] 47 | s.status = t["status"] 48 | s.protect = t["protect"] 49 | lst.append(s) 50 | 51 | return code, lst 52 | 53 | 54 | def ServiceSwitch(self, name: str, switch: bool): 55 | p = {} 56 | p["name"] = name 57 | p["switch"] = int(switch) 58 | parameter = json.dumps(p) 59 | 60 | code, data = self._Call(ROBOT_STATE_API_ID_SERVICE_SWITCH, parameter) 61 | 62 | if code != 0: 63 | return code 64 | 65 | d = json.loads(data) 66 | 67 | status = d["status"] 68 | 69 | if status == 5: 70 | return ROBOT_STATE_ERR_SERVICE_PROTECTED 71 | 72 | if status != 0 and status != 1: 73 | return ROBOT_STATE_ERR_SERVICE_SWITCH 74 | 75 | return code 76 | 77 | def SetReportFreq(self, interval: int, duration: int): 78 | p = {} 79 | p["interval"] = interval 80 | p["duration"] = duration 81 | parameter = json.dumps(p) 82 | 83 | code, data = self._Call(ROBOT_STATE_API_ID_REPORT_FREQ, p) 84 | return code 85 | -------------------------------------------------------------------------------- /unitree_sdk2py/b2/vui/vui_client.py: -------------------------------------------------------------------------------- 1 | import json 2 | 3 | from ...rpc.client import Client 4 | from .vui_api import * 5 | 6 | 7 | """ 8 | " class VideoClient 9 | """ 10 | class VuiClient(Client): 11 | def __init__(self): 12 | super().__init__(VUI_SERVICE_NAME, False) 13 | 14 | def Init(self): 15 | # set api version 16 | self._SetApiVerson(VUI_API_VERSION) 17 | # regist api 18 | self._RegistApi(VUI_API_ID_SETSWITCH, 0) 19 | self._RegistApi(VUI_API_ID_GETSWITCH, 0) 20 | self._RegistApi(VUI_API_ID_SETVOLUME, 0) 21 | self._RegistApi(VUI_API_ID_GETVOLUME, 0) 22 | self._RegistApi(VUI_API_ID_SETBRIGHTNESS, 0) 23 | self._RegistApi(VUI_API_ID_GETBRIGHTNESS, 0) 24 | 25 | # 1001 26 | def SetSwitch(self, enable: int): 27 | p = {} 28 | p["enable"] = enable 29 | parameter = json.dumps(p) 30 | 31 | code, data = self._Call(VUI_API_ID_SETSWITCH, parameter) 32 | return code 33 | 34 | # 1002 35 | def GetSwitch(self): 36 | p = {} 37 | parameter = json.dumps(p) 38 | 39 | code, data = self._Call(VUI_API_ID_GETSWITCH, parameter) 40 | if code == 0: 41 | d = json.loads(data) 42 | return code, d["enable"] 43 | else: 44 | return code, None 45 | 46 | # 1003 47 | def SetVolume(self, level: int): 48 | p = {} 49 | p["volume"] = level 50 | parameter = json.dumps(p) 51 | 52 | code, data = self._Call(VUI_API_ID_SETVOLUME, parameter) 53 | return code 54 | 55 | # 1006 56 | def GetVolume(self): 57 | p = {} 58 | parameter = json.dumps(p) 59 | 60 | code, data = self._Call(VUI_API_ID_GETVOLUME, parameter) 61 | if code == 0: 62 | d = json.loads(data) 63 | return code, d["volume"] 64 | else: 65 | return code, None 66 | 67 | # 1005 68 | def SetBrightness(self, level: int): 69 | p = {} 70 | p["brightness"] = level 71 | parameter = json.dumps(p) 72 | 73 | code, data = self._Call(VUI_API_ID_SETBRIGHTNESS, parameter) 74 | return code 75 | 76 | # 1006 77 | def GetBrightness(self): 78 | p = {} 79 | parameter = json.dumps(p) 80 | 81 | code, data = self._Call(VUI_API_ID_GETBRIGHTNESS, parameter) 82 | if code == 0: 83 | d = json.loads(data) 84 | return code, d["brightness"] 85 | else: 86 | return code, None -------------------------------------------------------------------------------- /unitree_sdk2py/go2/vui/vui_client.py: -------------------------------------------------------------------------------- 1 | import json 2 | 3 | from ...rpc.client import Client 4 | from .vui_api import * 5 | 6 | 7 | """ 8 | " class VideoClient 9 | """ 10 | class VuiClient(Client): 11 | def __init__(self): 12 | super().__init__(VUI_SERVICE_NAME, False) 13 | 14 | def Init(self): 15 | # set api version 16 | self._SetApiVerson(VUI_API_VERSION) 17 | # regist api 18 | self._RegistApi(VUI_API_ID_SETSWITCH, 0) 19 | self._RegistApi(VUI_API_ID_GETSWITCH, 0) 20 | self._RegistApi(VUI_API_ID_SETVOLUME, 0) 21 | self._RegistApi(VUI_API_ID_GETVOLUME, 0) 22 | self._RegistApi(VUI_API_ID_SETBRIGHTNESS, 0) 23 | self._RegistApi(VUI_API_ID_GETBRIGHTNESS, 0) 24 | 25 | # 1001 26 | def SetSwitch(self, enable: int): 27 | p = {} 28 | p["enable"] = enable 29 | parameter = json.dumps(p) 30 | 31 | code, data = self._Call(VUI_API_ID_SETSWITCH, parameter) 32 | return code 33 | 34 | # 1002 35 | def GetSwitch(self): 36 | p = {} 37 | parameter = json.dumps(p) 38 | 39 | code, data = self._Call(VUI_API_ID_GETSWITCH, parameter) 40 | if code == 0: 41 | d = json.loads(data) 42 | return code, d["enable"] 43 | else: 44 | return code, None 45 | 46 | # 1003 47 | def SetVolume(self, level: int): 48 | p = {} 49 | p["volume"] = level 50 | parameter = json.dumps(p) 51 | 52 | code, data = self._Call(VUI_API_ID_SETVOLUME, parameter) 53 | return code 54 | 55 | # 1006 56 | def GetVolume(self): 57 | p = {} 58 | parameter = json.dumps(p) 59 | 60 | code, data = self._Call(VUI_API_ID_GETVOLUME, parameter) 61 | if code == 0: 62 | d = json.loads(data) 63 | return code, d["volume"] 64 | else: 65 | return code, None 66 | 67 | # 1005 68 | def SetBrightness(self, level: int): 69 | p = {} 70 | p["brightness"] = level 71 | parameter = json.dumps(p) 72 | 73 | code, data = self._Call(VUI_API_ID_SETBRIGHTNESS, parameter) 74 | return code 75 | 76 | # 1006 77 | def GetBrightness(self): 78 | p = {} 79 | parameter = json.dumps(p) 80 | 81 | code, data = self._Call(VUI_API_ID_GETBRIGHTNESS, parameter) 82 | if code == 0: 83 | d = json.loads(data) 84 | return code, d["brightness"] 85 | else: 86 | return code, None -------------------------------------------------------------------------------- /unitree_sdk2py/g1/audio/g1_audio_client.py: -------------------------------------------------------------------------------- 1 | import json 2 | 3 | from ...rpc.client import Client 4 | from .g1_audio_api import * 5 | 6 | """ 7 | " class SportClient 8 | """ 9 | class AudioClient(Client): 10 | def __init__(self): 11 | super().__init__(AUDIO_SERVICE_NAME, False) 12 | self.tts_index = 0 13 | 14 | def Init(self): 15 | # set api version 16 | self._SetApiVerson(AUDIO_API_VERSION) 17 | 18 | # regist api 19 | self._RegistApi(ROBOT_API_ID_AUDIO_TTS, 0) 20 | self._RegistApi(ROBOT_API_ID_AUDIO_ASR, 0) 21 | self._RegistApi(ROBOT_API_ID_AUDIO_START_PLAY, 0) 22 | self._RegistApi(ROBOT_API_ID_AUDIO_STOP_PLAY, 0) 23 | self._RegistApi(ROBOT_API_ID_AUDIO_GET_VOLUME, 0) 24 | self._RegistApi(ROBOT_API_ID_AUDIO_SET_VOLUME, 0) 25 | self._RegistApi(ROBOT_API_ID_AUDIO_SET_RGB_LED, 0) 26 | 27 | ## API Call ## 28 | def TtsMaker(self, text: str, speaker_id: int): 29 | self.tts_index += self.tts_index 30 | p = {} 31 | p["index"] = self.tts_index 32 | p["text"] = text 33 | p["speaker_id"] = speaker_id 34 | parameter = json.dumps(p) 35 | code, data = self._Call(ROBOT_API_ID_AUDIO_TTS, parameter) 36 | return code 37 | 38 | def GetVolume(self): 39 | p = {} 40 | parameter = json.dumps(p) 41 | code, data = self._Call(ROBOT_API_ID_AUDIO_GET_VOLUME, parameter) 42 | if code == 0: 43 | return code, json.loads(data) 44 | else: 45 | return code, None 46 | 47 | def SetVolume(self, volume: int): 48 | p = {} 49 | p["volume"] = volume 50 | parameter = json.dumps(p) 51 | code, data = self._Call(ROBOT_API_ID_AUDIO_SET_VOLUME, parameter) 52 | return code 53 | 54 | def LedControl(self, R: int, G: int, B: int): 55 | p = {} 56 | p["R"] = R 57 | p["G"] = G 58 | p["B"] = B 59 | parameter = json.dumps(p) 60 | code, data = self._Call(ROBOT_API_ID_AUDIO_SET_RGB_LED, parameter) 61 | return code 62 | 63 | def PlayStream(self, app_name: str, stream_id: str, pcm_data: bytes): 64 | param = json.dumps({"app_name": app_name, "stream_id": stream_id}) 65 | pcm_list = list(pcm_data) 66 | return self._CallRequestWithParamAndBin(ROBOT_API_ID_AUDIO_START_PLAY, param, pcm_list) 67 | 68 | def PlayStop(self, app_name: str): 69 | parameter = json.dumps({"app_name": app_name}) 70 | self._Call(ROBOT_API_ID_AUDIO_STOP_PLAY, parameter) 71 | return 0 72 | -------------------------------------------------------------------------------- /unitree_sdk2py/rpc/client_stub.py: -------------------------------------------------------------------------------- 1 | import time 2 | 3 | from enum import Enum 4 | from threading import Thread, Condition 5 | 6 | from ..idl.unitree_api.msg.dds_ import Request_ as Request 7 | from ..idl.unitree_api.msg.dds_ import Response_ as Response 8 | 9 | from ..core.channel import ChannelFactory 10 | from ..core.channel_name import ChannelType, GetClientChannelName 11 | from .request_future import RequestFuture, RequestFutureQueue 12 | 13 | 14 | """ 15 | " class ClientStub 16 | """ 17 | class ClientStub: 18 | def __init__(self, serviceName: str): 19 | self.__serviceName = serviceName 20 | self.__futureQueue = None 21 | 22 | self.__sendChannel = None 23 | self.__recvChannel = None 24 | 25 | def Init(self): 26 | factory = ChannelFactory() 27 | self.__futureQueue = RequestFutureQueue() 28 | 29 | # create channel 30 | self.__sendChannel = factory.CreateSendChannel(GetClientChannelName(self.__serviceName, ChannelType.SEND), Request) 31 | self.__recvChannel = factory.CreateRecvChannel(GetClientChannelName(self.__serviceName, ChannelType.RECV), Response, 32 | self.__ResponseHandler,10) 33 | time.sleep(0.5) 34 | 35 | 36 | def Send(self, request: Request, timeout: float): 37 | if self.__sendChannel.Write(request, timeout): 38 | return True 39 | else: 40 | print("[ClientStub] send error. id:", request.header.identity.id) 41 | return False 42 | 43 | def SendRequest(self, request: Request, timeout: float): 44 | id = request.header.identity.id 45 | 46 | future = RequestFuture() 47 | future.SetRequestId(id) 48 | self.__futureQueue.Set(id, future) 49 | 50 | if self.__sendChannel.Write(request, timeout): 51 | return future 52 | else: 53 | print("[ClientStub] send request error. id:", request.header.identity.id) 54 | self.__futureQueue.Remove(id) 55 | return None 56 | 57 | def RemoveFuture(self, requestId: int): 58 | self.__futureQueue.Remove(requestId) 59 | 60 | def __ResponseHandler(self, response: Response): 61 | id = response.header.identity.id 62 | # apiId = response.header.identity.api_id 63 | # print("[ClientStub] responseHandler recv response id:", id, ", apiId:", apiId) 64 | future = self.__futureQueue.Get(id) 65 | if future is None: 66 | # print("[ClientStub] get future from queue error. id:", id) 67 | pass 68 | elif not future.Ready(response): 69 | print("[ClientStub] set future ready error.") 70 | -------------------------------------------------------------------------------- /unitree_sdk2py/go2/obstacles_avoid/obstacles_avoid_client.py: -------------------------------------------------------------------------------- 1 | import json 2 | 3 | from ...rpc.client import Client 4 | from .obstacles_avoid_api import * 5 | 6 | 7 | """ 8 | " class ObstaclesAvoidClient 9 | """ 10 | class ObstaclesAvoidClient(Client): 11 | def __init__(self): 12 | super().__init__(OBSTACLES_AVOID_SERVICE_NAME, False) 13 | 14 | def Init(self): 15 | # set api version 16 | self._SetApiVerson(OBSTACLES_AVOID_API_VERSION) 17 | # regist api 18 | self._RegistApi(OBSTACLES_AVOID_API_ID_SWITCH_SET, 0) 19 | self._RegistApi(OBSTACLES_AVOID_API_ID_SWITCH_GET, 0) 20 | self._RegistApi(OBSTACLES_AVOID_API_ID_MOVE, 0) 21 | self._RegistApi(OBSTACLES_AVOID_API_ID_USE_REMOTE_COMMAND_FROM_API, 0) 22 | 23 | # 1001 24 | def SwitchSet(self, on: bool): 25 | p = {} 26 | p["enable"] = on 27 | parameter = json.dumps(p) 28 | 29 | code, data = self._Call(OBSTACLES_AVOID_API_ID_SWITCH_SET, parameter) 30 | return code 31 | 32 | # 1002 33 | def SwitchGet(self): 34 | p = {} 35 | parameter = json.dumps(p) 36 | 37 | code, data = self._Call(OBSTACLES_AVOID_API_ID_SWITCH_GET, parameter) 38 | if code == 0: 39 | d = json.loads(data) 40 | return code, d["enable"] 41 | else: 42 | return code, None 43 | 44 | # 1003 45 | def Move(self, vx: float, vy: float, vyaw: float): 46 | p = {} 47 | p["x"] = vx 48 | p["y"] = vy 49 | p["yaw"] = vyaw 50 | p["mode"] = 0 51 | parameter = json.dumps(p) 52 | code = self._CallNoReply(OBSTACLES_AVOID_API_ID_MOVE, parameter) 53 | return code 54 | 55 | def UseRemoteCommandFromApi(self, isRemoteCommandsFromApi: bool): 56 | p = {} 57 | p["is_remote_commands_from_api"] = isRemoteCommandsFromApi 58 | parameter = json.dumps(p) 59 | code, data = self._Call(OBSTACLES_AVOID_API_ID_USE_REMOTE_COMMAND_FROM_API, parameter) 60 | return code 61 | 62 | def MoveToAbsolutePosition(self, vx: float, vy: float, vyaw: float): 63 | p = {} 64 | p["x"] = vx 65 | p["y"] = vy 66 | p["yaw"] = vyaw 67 | p["mode"] = 2 68 | parameter = json.dumps(p) 69 | code = self._CallNoReply(OBSTACLES_AVOID_API_ID_MOVE, parameter) 70 | return code 71 | 72 | def MoveToIncrementPosition(self, vx: float, vy: float, vyaw: float): 73 | p = {} 74 | p["x"] = vx 75 | p["y"] = vy 76 | p["yaw"] = vyaw 77 | p["mode"] = 1 78 | parameter = json.dumps(p) 79 | code = self._CallNoReply(OBSTACLES_AVOID_API_ID_MOVE, parameter) 80 | return code -------------------------------------------------------------------------------- /unitree_sdk2py/h1/loco/h1_loco_client.py: -------------------------------------------------------------------------------- 1 | import json 2 | 3 | from ...rpc.client import Client 4 | from .h1_loco_api import * 5 | 6 | """ 7 | " class SportClient 8 | """ 9 | class LocoClient(Client): 10 | def __init__(self): 11 | super().__init__(LOCO_SERVICE_NAME, False) 12 | 13 | 14 | def Init(self): 15 | # set api version 16 | self._SetApiVerson(LOCO_API_VERSION) 17 | 18 | # regist api 19 | self._RegistApi(ROBOT_API_ID_LOCO_GET_FSM_ID, 0) 20 | self._RegistApi(ROBOT_API_ID_LOCO_GET_FSM_MODE, 0) 21 | self._RegistApi(ROBOT_API_ID_LOCO_GET_BALANCE_MODE, 0) 22 | self._RegistApi(ROBOT_API_ID_LOCO_GET_SWING_HEIGHT, 0) 23 | self._RegistApi(ROBOT_API_ID_LOCO_GET_STAND_HEIGHT, 0) 24 | self._RegistApi(ROBOT_API_ID_LOCO_GET_PHASE, 0) # deprecated 25 | 26 | self._RegistApi(ROBOT_API_ID_LOCO_SET_FSM_ID, 0) 27 | self._RegistApi(ROBOT_API_ID_LOCO_SET_BALANCE_MODE, 0) 28 | self._RegistApi(ROBOT_API_ID_LOCO_SET_SWING_HEIGHT, 0) 29 | self._RegistApi(ROBOT_API_ID_LOCO_SET_STAND_HEIGHT, 0) 30 | self._RegistApi(ROBOT_API_ID_LOCO_SET_VELOCITY, 0) 31 | 32 | # 8101 33 | def SetFsmId(self, fsm_id: int): 34 | p = {} 35 | p["data"] = fsm_id 36 | parameter = json.dumps(p) 37 | code, data = self._Call(ROBOT_API_ID_LOCO_SET_FSM_ID, parameter) 38 | return code 39 | 40 | # 8104 41 | def SetStandHeight(self, stand_height: float): 42 | p = {} 43 | p["data"] = stand_height 44 | parameter = json.dumps(p) 45 | code, data = self._Call(ROBOT_API_ID_LOCO_SET_STAND_HEIGHT, parameter) 46 | return code 47 | 48 | # 8105 49 | def SetVelocity(self, vx: float, vy: float, omega: float, duration: float = 1.0): 50 | p = {} 51 | velocity = [vx,vy,omega] 52 | p["velocity"] = velocity 53 | p["duration"] = duration 54 | parameter = json.dumps(p) 55 | code, data = self._Call(ROBOT_API_ID_LOCO_SET_VELOCITY, parameter) 56 | return code 57 | 58 | def Damp(self): 59 | self.SetFsmId(1) 60 | 61 | def Start(self): 62 | self.SetFsmId(204) 63 | 64 | def StandUp(self): 65 | self.SetFsmId(2) 66 | 67 | def ZeroTorque(self): 68 | self.SetFsmId(0) 69 | 70 | def StopMove(self): 71 | self.SetVelocity(0., 0., 0.) 72 | 73 | def HighStand(self): 74 | UINT32_MAX = (1 << 32) - 1 75 | self.SetStandHeight(UINT32_MAX) 76 | 77 | def LowStand(self): 78 | UINT32_MIN = 0 79 | self.SetStandHeight(UINT32_MIN) 80 | 81 | def Move(self, vx: float, vy: float, vyaw: float, continous_move: bool = False): 82 | duration = 864000.0 if continous_move else 1 83 | self.SetVelocity(vx, vy, vyaw, duration) -------------------------------------------------------------------------------- /unitree_sdk2py/rpc/server_stub.py: -------------------------------------------------------------------------------- 1 | import time 2 | 3 | from enum import Enum 4 | from threading import Thread, Condition 5 | from typing import Callable, Any 6 | 7 | from ..utils.bqueue import BQueue 8 | from ..idl.unitree_api.msg.dds_ import Request_ as Request 9 | from ..idl.unitree_api.msg.dds_ import Response_ as Response 10 | 11 | from ..core.channel import ChannelFactory 12 | from ..core.channel_name import ChannelType, GetServerChannelName 13 | 14 | 15 | """ 16 | " class ServerStub 17 | """ 18 | class ServerStub: 19 | def __init__(self, serviceName: str): 20 | self.__serviceName = serviceName 21 | self.__serverRquestHandler = None 22 | self.__sendChannel = None 23 | self.__recvChannel = None 24 | self.__enablePriority = None 25 | self.__queue = None 26 | self.__prioQueue = None 27 | self.__queueThread = None 28 | self.__prioQueueThread = None 29 | 30 | def Init(self, serverRequestHander: Callable, enablePriority: bool = False): 31 | self.__serverRquestHandler = serverRequestHander 32 | self.__enablePriority = enablePriority 33 | 34 | factory = ChannelFactory() 35 | 36 | # create channel 37 | self.__sendChannel = factory.CreateSendChannel(GetServerChannelName(self.__serviceName, ChannelType.SEND), Response) 38 | self.__recvChannel = factory.CreateRecvChannel(GetServerChannelName(self.__serviceName, ChannelType.RECV), Request, self.__Enqueue, 10) 39 | 40 | # start priority request thread 41 | self.__queue = BQueue(10) 42 | self.__queueThread = Thread(target=self.__QueueThreadFunc, name="server_queue", daemon=True) 43 | self.__queueThread.start() 44 | 45 | if enablePriority: 46 | self.__prioQueue = BQueue(5) 47 | self.__prioQueueThread = Thread(target=self.__PrioQueueThreadFunc, name="server_prio_queue", daemon=True) 48 | self.__prioQueueThread.start() 49 | 50 | # wait thread started 51 | time.sleep(0.5) 52 | 53 | def Send(self, response: Response, timeout: float): 54 | if self.__sendChannel.Write(response, timeout): 55 | return True 56 | else: 57 | print("[ServerStub] send error. id:", response.header.identity.id) 58 | return False 59 | 60 | def __Enqueue(self, request: Request): 61 | if self.__enablePriority and request.header.policy.priority > 0: 62 | self.__prioQueue.Put(request, True) 63 | else: 64 | self.__queue.Put(request, True) 65 | 66 | def __QueueThreadFunc(self): 67 | while True: 68 | request = self.__queue.Get() 69 | if request is None: 70 | continue 71 | self.__serverRquestHandler(request) 72 | 73 | def __PrioQueueThreadFunc(self): 74 | while True: 75 | request = self.__prioQueue.Get() 76 | if request is None: 77 | continue 78 | self.__serverRquestHandler(request) 79 | -------------------------------------------------------------------------------- /unitree_sdk2py/utils/thread.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | import errno 4 | import ctypes 5 | import struct 6 | import threading 7 | 8 | from .future import Future 9 | from .timerfd import * 10 | 11 | class Thread(Future): 12 | def __init__(self, target = None, name = None, args = (), kwargs = None): 13 | super().__init__() 14 | self.__target = target 15 | self.__args = args 16 | self.__kwargs = {} if kwargs is None else kwargs 17 | self.__thread = threading.Thread(target=self.__ThreadFunc, name=name, daemon=True) 18 | 19 | def Start(self): 20 | return self.__thread.start() 21 | 22 | def GetId(self): 23 | return self.__thread.ident 24 | 25 | def GetNativeId(self): 26 | return self.__thread.native_id 27 | 28 | def __ThreadFunc(self): 29 | value = None 30 | try: 31 | value = self.__target(*self.__args, **self.__kwargs) 32 | self.Ready(value) 33 | except: 34 | info = sys.exc_info() 35 | self.Fail(f"[Thread] target func raise exception: name={info[0].__name__}, args={str(info[1].args)}") 36 | 37 | class RecurrentThread(Thread): 38 | def __init__(self, interval: float = 1.0, target = None, name = None, args = (), kwargs = None): 39 | self.__quit = False 40 | self.__inter = interval 41 | self.__loopTarget = target 42 | self.__loopArgs = args 43 | self.__loopKwargs = {} if kwargs is None else kwargs 44 | 45 | if interval is None or interval <= 0.0: 46 | super().__init__(target=self.__LoopFunc_0, name=name) 47 | else: 48 | super().__init__(target=self.__LoopFunc, name=name) 49 | 50 | def Wait(self, timeout: float = None): 51 | self.__quit = True 52 | super().Wait(timeout) 53 | 54 | def __LoopFunc(self): 55 | # clock type CLOCK_MONOTONIC = 1 56 | tfd = timerfd_create(1, 0) 57 | spec = itimerspec.from_seconds(self.__inter, self.__inter) 58 | timerfd_settime(tfd, 0, ctypes.byref(spec), None) 59 | 60 | while not self.__quit: 61 | try: 62 | self.__loopTarget(*self.__loopArgs, **self.__loopKwargs) 63 | except: 64 | info = sys.exc_info() 65 | print(f"[RecurrentThread] target func raise exception: name={info[0].__name__}, args={str(info[1].args)}") 66 | 67 | try: 68 | buf = os.read(tfd, 8) 69 | # print(struct.unpack("Q", buf)[0]) 70 | except OSError as e: 71 | if e.errno != errno.EAGAIN: 72 | raise e 73 | 74 | os.close(tfd) 75 | 76 | def __LoopFunc_0(self): 77 | while not self.__quit: 78 | try: 79 | self.__loopTarget(*self.__args, **self.__kwargs) 80 | except: 81 | info = sys.exc_info() 82 | print(f"[RecurrentThread] target func raise exception: name={info[0].__name__}, args={str(info[1].args)}") 83 | 84 | -------------------------------------------------------------------------------- /unitree_sdk2py/test/client/obstacles_avoid_client_example.py: -------------------------------------------------------------------------------- 1 | import time 2 | import os 3 | 4 | from unitree_sdk2py.core.channel import ChannelFactoryInitialize 5 | from unitree_sdk2py.go2.obstacles_avoid.obstacles_avoid_client import ObstaclesAvoidClient 6 | 7 | if __name__ == "__main__": 8 | ChannelFactoryInitialize(0, "enp3s0") 9 | 10 | client = ObstaclesAvoidClient() 11 | client.SetTimeout(3.0) 12 | client.Init() 13 | 14 | while True: 15 | print("##################GetServerApiVersion###################") 16 | code, serverAPiVersion = client.GetServerApiVersion() 17 | if code != 0: 18 | print("get server api error. code:", code) 19 | else: 20 | print("get server api version:", serverAPiVersion) 21 | 22 | if serverAPiVersion != client.GetApiVersion(): 23 | print("api version not equal.") 24 | 25 | time.sleep(3) 26 | 27 | print("##################SwitchGet###################") 28 | code, enable = client.SwitchGet() 29 | if code != 0: 30 | print("switch get error. code:", code) 31 | else: 32 | print("switch get success. enable:", enable) 33 | 34 | time.sleep(3) 35 | 36 | print("##################SwitchSet (on)###################") 37 | code = client.SwitchSet(True) 38 | if code != 0: 39 | print("switch set error. code:", code) 40 | else: 41 | print("switch set success.") 42 | 43 | time.sleep(3) 44 | 45 | print("##################SwitchGet###################") 46 | code, enable1 = client.SwitchGet() 47 | if code != 0: 48 | print("switch get error. code:", code) 49 | else: 50 | print("switch get success. enable:", enable1) 51 | 52 | time.sleep(3) 53 | 54 | print("##################SwitchSet (off)###################") 55 | code = client.SwitchSet(False) 56 | if code != 0: 57 | print("switch set error. code:", code) 58 | else: 59 | print("switch set success.") 60 | 61 | time.sleep(3) 62 | 63 | print("##################SwitchGet###################") 64 | code, enable1 = client.SwitchGet() 65 | if code != 0: 66 | print("switch get error. code:", code) 67 | else: 68 | print("switch get success. enable:", enable1) 69 | 70 | time.sleep(3) 71 | 72 | 73 | print("##################SwitchSet (enable)###################") 74 | 75 | code = client.SwitchSet(enable) 76 | if code != 0: 77 | print("switch set error. code:", code) 78 | else: 79 | print("switch set success. enable:", enable) 80 | 81 | time.sleep(3) 82 | 83 | print("##################SwitchGet###################") 84 | code, enable = client.SwitchGet() 85 | if code != 0: 86 | print("switch get error. code:", code) 87 | else: 88 | print("switch get success. enable:", enable) 89 | 90 | time.sleep(3) 91 | -------------------------------------------------------------------------------- /example/obstacles_avoid/obstacles_avoid_switch.py: -------------------------------------------------------------------------------- 1 | import time 2 | import sys 3 | 4 | from unitree_sdk2py.core.channel import ChannelFactoryInitialize 5 | from unitree_sdk2py.go2.obstacles_avoid.obstacles_avoid_client import ObstaclesAvoidClient 6 | 7 | if __name__ == "__main__": 8 | if len(sys.argv)>1: 9 | ChannelFactoryInitialize(0, sys.argv[1]) 10 | else: 11 | ChannelFactoryInitialize(0) 12 | 13 | client = ObstaclesAvoidClient() 14 | client.SetTimeout(3.0) 15 | client.Init() 16 | 17 | while True: 18 | print("##################GetServerApiVersion###################") 19 | code, serverAPiVersion = client.GetServerApiVersion() 20 | if code != 0: 21 | print("get server api error. code:", code) 22 | else: 23 | print("get server api version:", serverAPiVersion) 24 | 25 | if serverAPiVersion != client.GetApiVersion(): 26 | print("api version not equal.") 27 | 28 | time.sleep(3) 29 | 30 | print("##################SwitchGet###################") 31 | code, enable = client.SwitchGet() 32 | if code != 0: 33 | print("switch get error. code:", code) 34 | else: 35 | print("switch get success. enable:", enable) 36 | 37 | time.sleep(3) 38 | 39 | print("##################SwitchSet (on)###################") 40 | code = client.SwitchSet(True) 41 | if code != 0: 42 | print("switch set error. code:", code) 43 | else: 44 | print("switch set success.") 45 | 46 | time.sleep(3) 47 | 48 | print("##################SwitchGet###################") 49 | code, enable1 = client.SwitchGet() 50 | if code != 0: 51 | print("switch get error. code:", code) 52 | else: 53 | print("switch get success. enable:", enable1) 54 | 55 | time.sleep(3) 56 | 57 | print("##################SwitchSet (off)###################") 58 | code = client.SwitchSet(False) 59 | if code != 0: 60 | print("switch set error. code:", code) 61 | else: 62 | print("switch set success.") 63 | 64 | time.sleep(3) 65 | 66 | print("##################SwitchGet###################") 67 | code, enable1 = client.SwitchGet() 68 | if code != 0: 69 | print("switch get error. code:", code) 70 | else: 71 | print("switch get success. enable:", enable1) 72 | 73 | time.sleep(3) 74 | 75 | 76 | print("##################SwitchSet (enable)###################") 77 | 78 | code = client.SwitchSet(enable) 79 | if code != 0: 80 | print("switch set error. code:", code) 81 | else: 82 | print("switch set success. enable:", enable) 83 | 84 | time.sleep(3) 85 | 86 | print("##################SwitchGet###################") 87 | code, enable = client.SwitchGet() 88 | if code != 0: 89 | print("switch get error. code:", code) 90 | else: 91 | print("switch get success. enable:", enable) 92 | 93 | time.sleep(3) 94 | -------------------------------------------------------------------------------- /example/h1/high_level/h1_loco_client_example.py: -------------------------------------------------------------------------------- 1 | import time 2 | import sys 3 | from unitree_sdk2py.core.channel import ChannelSubscriber, ChannelFactoryInitialize 4 | from unitree_sdk2py.idl.default import unitree_go_msg_dds__SportModeState_ 5 | from unitree_sdk2py.idl.unitree_go.msg.dds_ import SportModeState_ 6 | from unitree_sdk2py.h1.loco.h1_loco_client import LocoClient 7 | import math 8 | from dataclasses import dataclass 9 | 10 | @dataclass 11 | class TestOption: 12 | name: str 13 | id: int 14 | 15 | option_list = [ 16 | TestOption(name="damp", id=0), 17 | TestOption(name="stand_up", id=1), 18 | TestOption(name="move forward", id=3), 19 | TestOption(name="move lateral", id=4), 20 | TestOption(name="move rotate", id=5), 21 | TestOption(name="low stand", id=6), 22 | TestOption(name="high stand", id=7), 23 | TestOption(name="zero torque", id=8) 24 | ] 25 | 26 | class UserInterface: 27 | def __init__(self): 28 | self.test_option_ = None 29 | 30 | def convert_to_int(self, input_str): 31 | try: 32 | return int(input_str) 33 | except ValueError: 34 | return None 35 | 36 | def terminal_handle(self): 37 | input_str = input("Enter id or name: \n") 38 | 39 | if input_str == "list": 40 | self.test_option_.name = None 41 | self.test_option_.id = None 42 | for option in option_list: 43 | print(f"{option.name}, id: {option.id}") 44 | return 45 | 46 | for option in option_list: 47 | if input_str == option.name or self.convert_to_int(input_str) == option.id: 48 | self.test_option_.name = option.name 49 | self.test_option_.id = option.id 50 | print(f"Test: {self.test_option_.name}, test_id: {self.test_option_.id}") 51 | return 52 | 53 | print("No matching test option found.") 54 | 55 | if __name__ == "__main__": 56 | 57 | print("WARNING: Please ensure there are no obstacles around the robot while running this example.") 58 | input("Press Enter to continue...") 59 | 60 | if len(sys.argv)>1: 61 | ChannelFactoryInitialize(0, sys.argv[1]) 62 | else: 63 | ChannelFactoryInitialize(0) 64 | 65 | test_option = TestOption(name=None, id=None) 66 | user_interface = UserInterface() 67 | user_interface.test_option_ = test_option 68 | 69 | sport_client = LocoClient() 70 | sport_client.SetTimeout(10.0) 71 | sport_client.Init() 72 | 73 | while True: 74 | 75 | user_interface.terminal_handle() 76 | 77 | print(f"Updated Test Option: Name = {test_option.name}, ID = {test_option.id}\n") 78 | 79 | if test_option.id == 0: 80 | sport_client.Damp() 81 | elif test_option.id == 1: 82 | sport_client.StandUp() 83 | elif test_option.id == 3: 84 | sport_client.Move(0.3,0,0) 85 | elif test_option.id == 4: 86 | sport_client.Move(0,0.3,0) 87 | elif test_option.id == 5: 88 | sport_client.Move(0,0,0.3) 89 | elif test_option.id == 6: 90 | sport_client.LowStand() 91 | elif test_option.id == 7: 92 | sport_client.HighStand() 93 | elif test_option.id == 8: 94 | sport_client.ZeroTorque() 95 | 96 | time.sleep(1) -------------------------------------------------------------------------------- /unitree_sdk2py/rpc/lease_client.py: -------------------------------------------------------------------------------- 1 | import time 2 | import socket 3 | import os 4 | import json 5 | 6 | from threading import Thread, Lock 7 | 8 | from .client_base import ClientBase 9 | from .internal import * 10 | 11 | 12 | """ 13 | " class LeaseContext 14 | """ 15 | class LeaseContext: 16 | def __init__(self): 17 | self.id = 0 18 | self.term = RPC_LEASE_TERM 19 | 20 | def Update(self, id, term): 21 | self.id = id 22 | self.term = term 23 | 24 | def Reset(self): 25 | self.id = 0 26 | self.term = RPC_LEASE_TERM 27 | 28 | def Valid(self): 29 | return self.id != 0 30 | 31 | 32 | """ 33 | " class LeaseClient 34 | """ 35 | class LeaseClient(ClientBase): 36 | def __init__(self, name: str): 37 | self.__name = name + "_lease" 38 | self.__contextName = socket.gethostname() + "/" + name + "/" + str(os.getpid()) 39 | self.__context = LeaseContext() 40 | self.__thread = None 41 | self.__lock = Lock() 42 | super().__init__(self.__name) 43 | print("[LeaseClient] lease name:", self.__name, ", context name:", self.__contextName) 44 | 45 | def Init(self): 46 | self.SetTimeout(1.0) 47 | self.__thread = Thread(target=self.__ThreadFunc, name=self.__name, daemon=True) 48 | self.__thread.start() 49 | 50 | def WaitApplied(self): 51 | while True: 52 | with self.__lock: 53 | if self.__context.Valid(): 54 | break 55 | time.sleep(0.1) 56 | 57 | def GetId(self): 58 | with self.__lock: 59 | return self.__context.id 60 | 61 | def Applied(self): 62 | with self.__lock: 63 | return self.__context.Valid() 64 | 65 | def __Apply(self): 66 | parameter = {} 67 | parameter["name"] = self.__contextName 68 | p = json.dumps(parameter) 69 | 70 | c, d = self._CallBase(RPC_API_ID_LEASE_APPLY, p) 71 | if c != 0: 72 | print("[LeaseClient] apply lease error. code:", c) 73 | return 74 | 75 | data = json.loads(d) 76 | 77 | id = data["id"] 78 | term = data["term"] 79 | 80 | print("[LeaseClient] lease applied id:", id, ", term:", term) 81 | 82 | with self.__lock: 83 | self.__context.Update(id, float(term/1000000)) 84 | 85 | def __Renewal(self): 86 | parameter = {} 87 | p = json.dumps(parameter) 88 | 89 | c, d = self._CallBase(RPC_API_ID_LEASE_RENEWAL, p, 0, self.__context.id) 90 | if c != 0: 91 | print("[LeaseClient] renewal lease error. code:", c) 92 | if c == RPC_ERR_SERVER_LEASE_NOT_EXIST: 93 | with self.__lock: 94 | self.__context.Reset() 95 | 96 | def __GetWaitSec(self): 97 | waitsec = 0.0 98 | if self.__context.Valid(): 99 | waitsec = self.__context.term 100 | 101 | if waitsec <= 0: 102 | waitsec = RPC_LEASE_TERM 103 | 104 | return waitsec * 0.3 105 | 106 | def __ThreadFunc(self): 107 | while True: 108 | if self.__context.Valid(): 109 | self.__Renewal() 110 | else: 111 | self.__Apply() 112 | # sleep waitsec 113 | time.sleep(self.__GetWaitSec()) 114 | -------------------------------------------------------------------------------- /unitree_sdk2py/utils/future.py: -------------------------------------------------------------------------------- 1 | from threading import Condition 2 | from typing import Any 3 | from enum import Enum 4 | 5 | """ 6 | " Enum RequtestFutureState 7 | """ 8 | class FutureState(Enum): 9 | DEFER = 0 10 | READY = 1 11 | FAILED = 2 12 | 13 | """ 14 | " class FutureException 15 | """ 16 | class FutureResult: 17 | FUTURE_SUCC = 0 18 | FUTUTE_ERR_TIMEOUT = 1 19 | FUTURE_ERR_FAILED = 2 20 | FUTURE_ERR_UNKNOWN = 3 21 | 22 | def __init__(self, code: int, msg: str, value: Any = None): 23 | self.code = code 24 | self.msg = msg 25 | self.value = value 26 | 27 | def __str__(self): 28 | return f"FutureResult(code={str(self.code)}, msg='{self.msg}', value={self.value})" 29 | 30 | class Future: 31 | def __init__(self): 32 | self.__state = FutureState.DEFER 33 | self.__msg = None 34 | self.__condition = Condition() 35 | 36 | def GetResult(self, timeout: float = None): 37 | with self.__condition: 38 | return self.__WaitResult(timeout) 39 | 40 | def Wait(self, timeout: float = None): 41 | with self.__condition: 42 | return self.__Wait(timeout) 43 | 44 | def Ready(self, value): 45 | with self.__condition: 46 | ready = self.__Ready(value) 47 | self.__condition.notify() 48 | return ready 49 | 50 | def Fail(self, reason: str): 51 | with self.__condition: 52 | fail = self.__Fail(reason) 53 | self.__condition.notify() 54 | return fail 55 | 56 | def __Wait(self, timeout: float = None): 57 | if not self.__IsDeferred(): 58 | return True 59 | try: 60 | if timeout is None: 61 | return self.__condition.wait() 62 | else: 63 | return self.__condition.wait(timeout) 64 | except: 65 | print("[Future] future wait error") 66 | return False 67 | 68 | def __WaitResult(self, timeout: float = None): 69 | if not self.__Wait(timeout): 70 | return FutureResult(FutureResult.FUTUTE_ERR_TIMEOUT, "future wait timeout") 71 | 72 | if self.__IsReady(): 73 | return FutureResult(FutureResult.FUTURE_SUCC, "success", self.__value) 74 | elif self.__IsFailed(): 75 | return FutureResult(FutureResult.FUTURE_ERR_FAILED, self.__msg) 76 | else: 77 | return FutureResult(FutureResult.FUTURE_ERR_UNKNOWN, "future state error:" + str(self.__state)) 78 | 79 | def __Ready(self, value): 80 | if not self.__IsDeferred(): 81 | print("[Future] futrue state is not defer") 82 | return False 83 | else: 84 | self.__value = value 85 | self.__state = FutureState.READY 86 | return True 87 | 88 | def __Fail(self, message: str): 89 | if not self.__IsDeferred(): 90 | print("[Future] futrue state is not DEFER") 91 | return False 92 | else: 93 | self.__msg = message 94 | self.__state = FutureState.FAILED 95 | return True 96 | 97 | def __IsDeferred(self): 98 | return self.__state == FutureState.DEFER 99 | 100 | def __IsReady(self): 101 | return self.__state == FutureState.READY 102 | 103 | def __IsFailed(self): 104 | return self.__state == FutureState.FAILED -------------------------------------------------------------------------------- /example/go2w/high_level/go2w_sport_client.py: -------------------------------------------------------------------------------- 1 | import time 2 | import sys 3 | from unitree_sdk2py.core.channel import ChannelSubscriber, ChannelFactoryInitialize 4 | from unitree_sdk2py.idl.default import unitree_go_msg_dds__SportModeState_ 5 | from unitree_sdk2py.idl.unitree_go.msg.dds_ import SportModeState_ 6 | from unitree_sdk2py.go2.sport.sport_client import SportClient 7 | import math 8 | from dataclasses import dataclass 9 | 10 | @dataclass 11 | class TestOption: 12 | name: str 13 | id: int 14 | 15 | option_list = [ 16 | TestOption(name="damp", id=0), 17 | TestOption(name="stand_up", id=1), 18 | TestOption(name="stand_down", id=2), 19 | TestOption(name="move", id=3), 20 | TestOption(name="stop_move", id=4), 21 | TestOption(name="speed_level", id=5), 22 | TestOption(name="switch_gait", id=6), 23 | TestOption(name="get_state", id=7), 24 | TestOption(name="recovery", id=8), 25 | TestOption(name="balance", id=9) 26 | ] 27 | 28 | class UserInterface: 29 | def __init__(self): 30 | self.test_option_ = None 31 | 32 | def convert_to_int(self, input_str): 33 | try: 34 | return int(input_str) 35 | except ValueError: 36 | return None 37 | 38 | def terminal_handle(self): 39 | input_str = input("Enter id or name: \n") 40 | 41 | if input_str == "list": 42 | self.test_option_.name = None 43 | self.test_option_.id = None 44 | for option in option_list: 45 | print(f"{option.name}, id: {option.id}") 46 | return 47 | 48 | for option in option_list: 49 | if input_str == option.name or self.convert_to_int(input_str) == option.id: 50 | self.test_option_.name = option.name 51 | self.test_option_.id = option.id 52 | print(f"Test: {self.test_option_.name}, test_id: {self.test_option_.id}") 53 | return 54 | 55 | print("No matching test option found.") 56 | 57 | if __name__ == "__main__": 58 | if len(sys.argv) < 2: 59 | print(f"Usage: python3 {sys.argv[0]} networkInterface") 60 | sys.exit(-1) 61 | 62 | print("WARNING: Please ensure there are no obstacles around the robot while running this example.") 63 | input("Press Enter to continue...") 64 | 65 | ChannelFactoryInitialize(0, sys.argv[1]) 66 | 67 | test_option = TestOption(name=None, id=None) 68 | user_interface = UserInterface() 69 | user_interface.test_option_ = test_option 70 | 71 | sport_client = SportClient() 72 | sport_client.SetTimeout(10.0) 73 | sport_client.Init() 74 | 75 | while True: 76 | user_interface.terminal_handle() 77 | 78 | print(f"Updated Test Option: Name = {test_option.name}, ID = {test_option.id}\n") 79 | 80 | if test_option.id == 0: 81 | sport_client.Damp() 82 | elif test_option.id == 1: 83 | sport_client.StandUp() 84 | elif test_option.id == 2: 85 | sport_client.StandDown() 86 | elif test_option.id == 3: 87 | sport_client.Move(0.5,0,0) 88 | elif test_option.id == 4: 89 | sport_client.StopMove() 90 | elif test_option.id == 5: 91 | sport_client.SpeedLevel(1) 92 | elif test_option.id == 6: 93 | sport_client.SwitchGait(1) 94 | elif test_option.id == 8: 95 | sport_client.RecoveryStand() 96 | elif test_option.id == 9: 97 | sport_client.BalanceStand() 98 | 99 | time.sleep(1) 100 | -------------------------------------------------------------------------------- /example/b2w/high_level/b2w_sport_client.py: -------------------------------------------------------------------------------- 1 | import time 2 | import sys 3 | from unitree_sdk2py.core.channel import ChannelSubscriber, ChannelFactoryInitialize 4 | from unitree_sdk2py.b2.sport.sport_client import SportClient 5 | import math 6 | from dataclasses import dataclass 7 | 8 | @dataclass 9 | class TestOption: 10 | name: str 11 | id: int 12 | 13 | option_list = [ 14 | TestOption(name="damp", id=0), 15 | TestOption(name="stand_up", id=1), 16 | TestOption(name="stand_down", id=2), 17 | TestOption(name="move forward", id=3), 18 | TestOption(name="move lateral", id=4), 19 | TestOption(name="move rotate", id=5), 20 | TestOption(name="stop_move", id=6), 21 | TestOption(name="switch_gait", id=7), 22 | TestOption(name="switch_gait", id=8), 23 | TestOption(name="recovery", id=9) 24 | ] 25 | 26 | class UserInterface: 27 | def __init__(self): 28 | self.test_option_ = None 29 | 30 | def convert_to_int(self, input_str): 31 | try: 32 | return int(input_str) 33 | except ValueError: 34 | return None 35 | 36 | def terminal_handle(self): 37 | input_str = input("Enter id or name: \n") 38 | 39 | if input_str == "list": 40 | self.test_option_.name = None 41 | self.test_option_.id = None 42 | for option in option_list: 43 | print(f"name: {option.name}, id: {option.id}") 44 | return 45 | 46 | for option in option_list: 47 | if input_str == option.name or self.convert_to_int(input_str) == option.id: 48 | self.test_option_.name = option.name 49 | self.test_option_.id = option.id 50 | print(f"Test: {self.test_option_.name}, test_id: {self.test_option_.id}") 51 | return 52 | 53 | print("No matching test option found.") 54 | 55 | if __name__ == "__main__": 56 | if len(sys.argv) < 2: 57 | print(f"Usage: python3 {sys.argv[0]} networkInterface") 58 | sys.exit(-1) 59 | 60 | print("WARNING: Please ensure there are no obstacles around the robot while running this example.") 61 | input("Press Enter to continue...") 62 | 63 | ChannelFactoryInitialize(0, sys.argv[1]) 64 | 65 | test_option = TestOption(name=None, id=None) 66 | user_interface = UserInterface() 67 | user_interface.test_option_ = test_option 68 | 69 | sport_client = SportClient() 70 | sport_client.SetTimeout(10.0) 71 | sport_client.Init() 72 | 73 | print("Input \"list\" to list all test option ...") 74 | 75 | while True: 76 | user_interface.terminal_handle() 77 | 78 | print(f"Updated Test Option: Name = {test_option.name}, ID = {test_option.id}\n") 79 | 80 | if test_option.id == 0: 81 | sport_client.Damp() 82 | elif test_option.id == 1: 83 | sport_client.StandUp() 84 | elif test_option.id == 2: 85 | sport_client.StandDown() 86 | elif test_option.id == 3: 87 | sport_client.Move(0.3,0,0) 88 | elif test_option.id == 4: 89 | sport_client.Move(0,0.3,0) 90 | elif test_option.id == 5: 91 | sport_client.Move(0,0,0.5) 92 | elif test_option.id == 6: 93 | sport_client.StopMove() 94 | elif test_option.id == 7: 95 | sport_client.SwitchGait(0) 96 | elif test_option.id == 8: 97 | sport_client.SwitchGait(1) 98 | elif test_option.id == 9: 99 | sport_client.RecoveryStand() 100 | 101 | time.sleep(1) 102 | -------------------------------------------------------------------------------- /unitree_sdk2py/test/client/sport_client_example.py: -------------------------------------------------------------------------------- 1 | import time 2 | from unitree_sdk2py.core.channel import ChannelFactoryInitialize 3 | from unitree_sdk2py.go2.sport.sport_client import SportClient, PathPoint, SPORT_PATH_POINT_SIZE 4 | 5 | if __name__ == "__main__": 6 | ChannelFactoryInitialize(0, "enp2s0") 7 | client = SportClient() 8 | client.SetTimeout(10.0) 9 | client.Init() 10 | 11 | print("##################GetServerApiVersion###################") 12 | code, serverAPiVersion = client.GetServerApiVersion() 13 | if code != 0: 14 | print("get server api error. code:", code) 15 | else: 16 | print("get server api version:", serverAPiVersion) 17 | 18 | if serverAPiVersion != client.GetApiVersion(): 19 | print("api version not equal.") 20 | 21 | time.sleep(3) 22 | 23 | print("##################Trigger###################") 24 | code = client.Trigger() 25 | if code != 0: 26 | print("sport trigger error. code:", code) 27 | else: 28 | print("sport trigger success.") 29 | 30 | time.sleep(3) 31 | 32 | while True: 33 | print("##################RecoveryStand###################") 34 | code = client.RecoveryStand() 35 | 36 | if code != 0: 37 | print("sport recovery stand error. code:", code) 38 | else: 39 | print("sport recovery stand success.") 40 | 41 | time.sleep(3) 42 | 43 | print("##################StandDown###################") 44 | code = client.StandDown() 45 | if code != 0: 46 | print("sport stand down error. code:", code) 47 | else: 48 | print("sport stand down success.") 49 | 50 | time.sleep(3) 51 | 52 | print("##################Damp###################") 53 | code = client.Damp() 54 | if code != 0: 55 | print("sport damp error. code:", code) 56 | else: 57 | print("sport damp down success.") 58 | 59 | time.sleep(3) 60 | 61 | print("##################RecoveryStand###################") 62 | code = client.RecoveryStand() 63 | 64 | if code != 0: 65 | print("sport recovery stand error. code:", code) 66 | else: 67 | print("sport recovery stand success.") 68 | 69 | time.sleep(3) 70 | 71 | print("##################Sit###################") 72 | code = client.Sit() 73 | if code != 0: 74 | print("sport stand down error. code:", code) 75 | else: 76 | print("sport stand down success.") 77 | 78 | time.sleep(3) 79 | 80 | print("##################RiseSit###################") 81 | code = client.RiseSit() 82 | 83 | if code != 0: 84 | print("sport rise sit error. code:", code) 85 | else: 86 | print("sport rise sit success.") 87 | 88 | time.sleep(3) 89 | 90 | print("##################SetBodyHight###################") 91 | code = client.BodyHeight(0.18) 92 | 93 | if code != 0: 94 | print("sport body hight error. code:", code) 95 | else: 96 | print("sport body hight success.") 97 | 98 | time.sleep(3) 99 | 100 | print("##################GetState#################") 101 | keys = ["state", "bodyHeight", "footRaiseHeight", "speedLevel", "gait"] 102 | code, data = client.GetState(keys) 103 | 104 | if code != 0: 105 | print("sport get state error. code:", code) 106 | else: 107 | print("sport get state success. data:", data) 108 | 109 | time.sleep(3) 110 | -------------------------------------------------------------------------------- /README zh.md: -------------------------------------------------------------------------------- 1 | # unitree_sdk2_python 2 | unitree_sdk2 python 接口 3 | 4 | # 安装 5 | ## 依赖 6 | - python>=3.8 7 | - cyclonedds==0.10.2 8 | - numpy 9 | - opencv-python 10 | 11 | ## 安装 unitree_sdk2_python 12 | 在终端中执行: 13 | ```bash 14 | cd ~ 15 | sudo apt install python3-pip 16 | git clone https://github.com/unitreerobotics/unitree_sdk2_python.git 17 | cd unitree_sdk2_python 18 | pip3 install -e . 19 | ``` 20 | ## FAQ 21 | ##### 1. `pip3 install -e .` 遇到报错 22 | ```bash 23 | Could not locate cyclonedds. Try to set CYCLONEDDS_HOME or CMAKE_PREFIX_PATH 24 | ``` 25 | 该错误提示找不到 cyclonedds 路径。首先编译安装cyclonedds: 26 | ```bash 27 | cd ~ 28 | git clone https://github.com/eclipse-cyclonedds/cyclonedds -b releases/0.10.x 29 | cd cyclonedds && mkdir build install && cd build 30 | cmake .. -DCMAKE_INSTALL_PREFIX=../install 31 | cmake --build . --target install 32 | ``` 33 | 进入 unitree_sdk2_python 目录,设置 `CYCLONEDDS_HOME` 为刚刚编译好的 cyclonedds 所在路径,再安装 unitree_sdk2_python 34 | ```bash 35 | cd ~/unitree_sdk2_python 36 | export CYCLONEDDS_HOME="~/cyclonedds/install" 37 | pip3 install -e . 38 | ``` 39 | 40 | 详细见: 41 | https://pypi.org/project/cyclonedds/#installing-with-pre-built-binaries 42 | 43 | # 使用 44 | python sdk2 接口与 unitree_skd2的接口保持一致,通过请求响应或订阅发布topic实现机器人的状态获取和控制。相应的例程位于`/example`目录下。在运行例程前,需要根据文档 https://support.unitree.com/home/zh/developer/Quick_start 配置好机器人的网络连接。 45 | ## DDS通讯 46 | 在终端中执行: 47 | ```bash 48 | python3 ./example/helloworld/publisher.py 49 | ``` 50 | 打开新的终端,执行: 51 | ```bash 52 | python3 ./example/helloworld/subscriber.py 53 | ``` 54 | 可以看到终端输出的数据信息。`publisher.py` 和 `subscriber.py` 传输的数据定义在 `user_data.py` 中,用户可以根据需要自行定义需要传输的数据结构。 55 | 56 | ## 高层状态和控制 57 | 高层接口的数据结构和控制方式与unitree_sdk2一致。具体可见:https://support.unitree.com/home/zh/developer/sports_services 58 | ### 高层状态 59 | 终端中执行: 60 | ```bash 61 | python3 ./example/high_level/read_highstate.py enp2s0 62 | ``` 63 | 其中 `enp2s0` 为机器人所连接的网卡名称,请根据实际情况修改。 64 | ### 高层控制 65 | 终端中执行: 66 | ```bash 67 | python3 ./example/high_level/sportmode_test.py enp2s0 68 | ``` 69 | 其中 `enp2s0` 为机器人所连接的网卡名称,请根据实际情况修改。 70 | 该例程提供了几种测试方法,可根据测试需要选择: 71 | ```python 72 | test.StandUpDown() # 站立趴下 73 | # test.VelocityMove() # 速度控制 74 | # test.BalanceAttitude() # 姿态控制 75 | # test.TrajectoryFollow() # 轨迹跟踪 76 | # test.SpecialMotions() # 特殊动作 77 | 78 | ``` 79 | ## 底层状态和控制 80 | 底层接口的数据结构和控制方式与unitree_sdk2一致。具体可见:https://support.unitree.com/home/zh/developer/Basic_services 81 | ### 底层状态 82 | 终端中执行: 83 | ```bash 84 | python3 ./example/low_level/lowlevel_control.py enp2s0 85 | ``` 86 | 其中 `enp2s0` 为机器人所连接的网卡名称,请根据实际情况修改。程序会输出右前腿hip关节的状态、IMU和电池电压信息。 87 | 88 | ### 底层电机控制 89 | 首先使用 app 关闭高层运动服务(sport_mode),否则会导致指令冲突。 90 | 终端中执行: 91 | ```bash 92 | python3 ./example/low_level/lowlevel_control.py enp2s0 93 | ``` 94 | 其中 `enp2s0` 为机器人所连接的网卡名称,请根据实际情况修改。左后腿 hip 关节会保持在0角度 (安全起见,这里设置 kp=10, kd=1),左后腿 calf 关节将持续输出 1Nm 的转矩。 95 | 96 | ## 遥控器状态获取 97 | 终端中执行: 98 | ```bash 99 | python3 ./example/wireless_controller/wireless_controller.py enp2s0 100 | ``` 101 | 其中 `enp2s0` 为机器人所连接的网卡名称,请根据实际情况修改。 102 | 终端将输出每一个按键的状态。对于遥控器按键的定义和数据结构可见: https://support.unitree.com/home/zh/developer/Get_remote_control_status 103 | 104 | ## 前置摄像头 105 | 使用opencv获取前置摄像头(确保在有图形界面的系统下运行, 按 ESC 退出程序): 106 | ```bash 107 | python3 ./example/front_camera/camera_opencv.py enp2s0 108 | ``` 109 | 其中 `enp2s0` 为机器人所连接的网卡名称,请根据实际情况修改。 110 | 111 | ## 避障开关 112 | ```bash 113 | python3 ./example/obstacles_avoid_switch/obstacles_avoid_switch.py enp2s0 114 | ``` 115 | 其中 `enp2s0` 为机器人所连接的网卡名称,请根据实际情况修改。机器人将循环开启和关闭避障功能。关于避障服务,详细见 https://support.unitree.com/home/zh/developer/ObstaclesAvoidClient 116 | 117 | ## 灯光音量控制 118 | ```bash 119 | python3 ./example/vui_client/vui_client_example.py enp2s0 120 | ``` 121 | 其中 `enp2s0` 为机器人所连接的网卡名称,请根据实际情况修改。机器人将循环调节音量和灯光亮度。该接口详细见 https://support.unitree.com/home/zh/developer/VuiClient 122 | -------------------------------------------------------------------------------- /example/b2/high_level/b2_sport_client.py: -------------------------------------------------------------------------------- 1 | import time 2 | import sys 3 | from unitree_sdk2py.core.channel import ChannelSubscriber, ChannelFactoryInitialize 4 | from unitree_sdk2py.b2.sport.sport_client import SportClient 5 | import math 6 | from dataclasses import dataclass 7 | 8 | @dataclass 9 | class TestOption: 10 | name: str 11 | id: int 12 | 13 | option_list = [ 14 | TestOption(name="Damp", id=0), 15 | TestOption(name="BalanceStand", id=1), 16 | TestOption(name="StopMove", id=2), 17 | TestOption(name="StandUp", id=3), 18 | TestOption(name="StandDown", id=4), 19 | TestOption(name="RecoveryStand", id=5), 20 | TestOption(name="Move", id=6), 21 | TestOption(name="FreeWalk", id=7), 22 | TestOption(name="ClassicWalk", id=8) 23 | ] 24 | 25 | class UserInterface: 26 | def __init__(self): 27 | self.test_option_ = None 28 | 29 | def convert_to_int(self, input_str): 30 | try: 31 | return int(input_str) 32 | except ValueError: 33 | return None 34 | 35 | def terminal_handle(self): 36 | input_str = input("Enter id or name: \n") 37 | 38 | if input_str == "list": 39 | self.test_option_.name = None 40 | self.test_option_.id = None 41 | for option in option_list: 42 | print(f"{option.name}, id: {option.id}") 43 | return 44 | 45 | for option in option_list: 46 | if input_str == option.name or self.convert_to_int(input_str) == option.id: 47 | self.test_option_.name = option.name 48 | self.test_option_.id = option.id 49 | print(f"Test: {self.test_option_.name}, test_id: {self.test_option_.id}") 50 | return 51 | 52 | print("No matching test option found.") 53 | 54 | if __name__ == "__main__": 55 | 56 | if len(sys.argv) < 2: 57 | print(f"Usage: python3 {sys.argv[0]} networkInterface") 58 | sys.exit(-1) 59 | 60 | print("WARNING: Please ensure there are no obstacles around the robot while running this example.\n" 61 | "NOTE: Some interfaces are not demonstrated in this example for safety reasons. " 62 | "If you need to use them, please contact technical support: https://serviceconsole.unitree.com/index.html#/") 63 | input("Press Enter to continue...") 64 | 65 | ChannelFactoryInitialize(0, sys.argv[1]) 66 | 67 | test_option = TestOption(name=None, id=None) 68 | user_interface = UserInterface() 69 | user_interface.test_option_ = test_option 70 | 71 | sport_client = SportClient() 72 | sport_client.SetTimeout(10.0) 73 | sport_client.Init() 74 | 75 | print("Input \"list\" to list all test option ...") 76 | 77 | while True: 78 | user_interface.terminal_handle() 79 | 80 | print(f"Updated Test Option: Name = {test_option.name}, ID = {test_option.id}") 81 | 82 | if test_option.id == 0: 83 | print(f"ret:{sport_client.Damp()}") 84 | elif test_option.id == 1: 85 | print(f"ret:{sport_client.BalanceStand()}") 86 | elif test_option.id == 2: 87 | print(f"ret:{sport_client.StopMove()}") 88 | elif test_option.id == 3: 89 | print(f"ret:{sport_client.StandUp()}") 90 | elif test_option.id == 4: 91 | print(f"ret:{sport_client.StandDown()}") 92 | elif test_option.id == 5: 93 | print(f"ret:{sport_client.RecoveryStand()}") 94 | elif test_option.id == 6: 95 | print(f"ret:{sport_client.Move(0.5,0.0,0.0)}") 96 | elif test_option.id == 7: 97 | print(f"ret:{sport_client.FreeWalk()}") 98 | elif test_option.id == 8: 99 | print(f"ret:{sport_client.ClassicWalk(True)}") 100 | print(f"ret:{sport_client.Move(0.1,0.0,0.0)}") 101 | time.sleep(2) 102 | print(f"ret:{sport_client.ClassicWalk(False)}") 103 | print(f"ret:{sport_client.Move(-0.3,0.0,0.0)}") 104 | time.sleep(2) 105 | 106 | time.sleep(1) 107 | -------------------------------------------------------------------------------- /unitree_sdk2py/g1/loco/g1_loco_client.py: -------------------------------------------------------------------------------- 1 | import json 2 | 3 | from ...rpc.client import Client 4 | from .g1_loco_api import * 5 | 6 | """ 7 | " class SportClient 8 | """ 9 | class LocoClient(Client): 10 | def __init__(self): 11 | super().__init__(LOCO_SERVICE_NAME, False) 12 | self.first_shake_hand_stage_ = -1 13 | 14 | def Init(self): 15 | # set api version 16 | self._SetApiVerson(LOCO_API_VERSION) 17 | 18 | # regist api 19 | self._RegistApi(ROBOT_API_ID_LOCO_GET_FSM_ID, 0) 20 | self._RegistApi(ROBOT_API_ID_LOCO_GET_FSM_MODE, 0) 21 | self._RegistApi(ROBOT_API_ID_LOCO_GET_BALANCE_MODE, 0) 22 | self._RegistApi(ROBOT_API_ID_LOCO_GET_SWING_HEIGHT, 0) 23 | self._RegistApi(ROBOT_API_ID_LOCO_GET_STAND_HEIGHT, 0) 24 | self._RegistApi(ROBOT_API_ID_LOCO_GET_PHASE, 0) # deprecated 25 | 26 | self._RegistApi(ROBOT_API_ID_LOCO_SET_FSM_ID, 0) 27 | self._RegistApi(ROBOT_API_ID_LOCO_SET_BALANCE_MODE, 0) 28 | self._RegistApi(ROBOT_API_ID_LOCO_SET_SWING_HEIGHT, 0) 29 | self._RegistApi(ROBOT_API_ID_LOCO_SET_STAND_HEIGHT, 0) 30 | self._RegistApi(ROBOT_API_ID_LOCO_SET_VELOCITY, 0) 31 | self._RegistApi(ROBOT_API_ID_LOCO_SET_ARM_TASK, 0) 32 | 33 | # 7101 34 | def SetFsmId(self, fsm_id: int): 35 | p = {} 36 | p["data"] = fsm_id 37 | parameter = json.dumps(p) 38 | code, data = self._Call(ROBOT_API_ID_LOCO_SET_FSM_ID, parameter) 39 | return code 40 | 41 | # 7102 42 | def SetBalanceMode(self, balance_mode: int): 43 | p = {} 44 | p["data"] = balance_mode 45 | parameter = json.dumps(p) 46 | code, data = self._Call(ROBOT_API_ID_LOCO_SET_BALANCE_MODE, parameter) 47 | return code 48 | 49 | # 7104 50 | def SetStandHeight(self, stand_height: float): 51 | p = {} 52 | p["data"] = stand_height 53 | parameter = json.dumps(p) 54 | code, data = self._Call(ROBOT_API_ID_LOCO_SET_STAND_HEIGHT, parameter) 55 | return code 56 | 57 | # 7105 58 | def SetVelocity(self, vx: float, vy: float, omega: float, duration: float = 1.0): 59 | p = {} 60 | velocity = [vx,vy,omega] 61 | p["velocity"] = velocity 62 | p["duration"] = duration 63 | parameter = json.dumps(p) 64 | code, data = self._Call(ROBOT_API_ID_LOCO_SET_VELOCITY, parameter) 65 | return code 66 | 67 | # 7106 68 | def SetTaskId(self, task_id: float): 69 | p = {} 70 | p["data"] = task_id 71 | parameter = json.dumps(p) 72 | code, data = self._Call(ROBOT_API_ID_LOCO_SET_ARM_TASK, parameter) 73 | return code 74 | 75 | def Damp(self): 76 | self.SetFsmId(1) 77 | 78 | def Start(self): 79 | self.SetFsmId(200) 80 | 81 | def Squat2StandUp(self): 82 | self.SetFsmId(706) 83 | 84 | def Lie2StandUp(self): 85 | self.SetFsmId(702) 86 | 87 | def Sit(self): 88 | self.SetFsmId(3) 89 | 90 | def StandUp2Squat(self): 91 | self.SetFsmId(706) 92 | 93 | def ZeroTorque(self): 94 | self.SetFsmId(0) 95 | 96 | def StopMove(self): 97 | self.SetVelocity(0., 0., 0.) 98 | 99 | def HighStand(self): 100 | UINT32_MAX = (1 << 32) - 1 101 | self.SetStandHeight(UINT32_MAX) 102 | 103 | def LowStand(self): 104 | UINT32_MIN = 0 105 | self.SetStandHeight(UINT32_MIN) 106 | 107 | def Move(self, vx: float, vy: float, vyaw: float, continous_move: bool = False): 108 | duration = 864000.0 if continous_move else 1 109 | self.SetVelocity(vx, vy, vyaw, duration) 110 | 111 | def BalanceStand(self, balance_mode: int): 112 | self.SetBalanceMode(balance_mode) 113 | 114 | def WaveHand(self, turn_flag: bool = False): 115 | self.SetTaskId(1 if turn_flag else 0) 116 | 117 | def ShakeHand(self, stage: int = -1): 118 | if stage == 0: 119 | self.first_shake_hand_stage_ = False 120 | self.SetTaskId(2) 121 | elif stage == 1: 122 | self.first_shake_hand_stage_ = True 123 | self.SetTaskId(3) 124 | else: 125 | self.first_shake_hand_stage_ = not self.first_shake_hand_stage_ 126 | return self.SetTaskId(3 if self.first_shake_hand_stage_ else 2) 127 | --------------------------------------------------------------------------------