├── .gitignore ├── requirements.txt ├── sounds ├── sound.wav ├── attention.wav ├── fire_wea.wav └── lv_no_sr.wav ├── images └── dashboard.png ├── static ├── dashboard.png ├── joystick-base.png ├── joystick-blue.png └── joystick-red.png ├── scripts └── test.py ├── unitree_sdk2py ├── sdk │ ├── __pycache__ │ │ ├── sdk.cpython-310.pyc │ │ └── robot.cpython-310.pyc │ ├── robot.py │ └── sdk.py ├── __pycache__ │ └── __init__.cpython-310.pyc ├── core │ ├── __pycache__ │ │ ├── topics.cpython-310.pyc │ │ └── channel_name.cpython-310.pyc │ ├── dds │ │ ├── __pycache__ │ │ │ ├── channel.cpython-310.pyc │ │ │ └── channel_config.cpython-310.pyc │ │ └── channel_config.py │ ├── channel_name.py │ └── topics.py ├── idl │ ├── __pycache__ │ │ ├── __init__.cpython-310.pyc │ │ └── idl_dataclass.cpython-310.pyc │ ├── std_msgs │ │ ├── __pycache__ │ │ │ └── __init__.cpython-310.pyc │ │ ├── msg │ │ │ ├── __pycache__ │ │ │ │ └── __init__.cpython-310.pyc │ │ │ ├── dds_ │ │ │ │ ├── __pycache__ │ │ │ │ │ ├── _Header_.cpython-310.pyc │ │ │ │ │ ├── _String_.cpython-310.pyc │ │ │ │ │ └── __init__.cpython-310.pyc │ │ │ │ ├── __init__.py │ │ │ │ ├── _String_.py │ │ │ │ └── _Header_.py │ │ │ └── __init__.py │ │ └── __init__.py │ ├── sensor_msgs │ │ ├── __pycache__ │ │ │ └── __init__.cpython-310.pyc │ │ ├── msg │ │ │ ├── __pycache__ │ │ │ │ └── __init__.cpython-310.pyc │ │ │ ├── dds_ │ │ │ │ ├── __pycache__ │ │ │ │ │ ├── __init__.cpython-310.pyc │ │ │ │ │ ├── _PointField_.cpython-310.pyc │ │ │ │ │ └── _PointCloud2_.cpython-310.pyc │ │ │ │ ├── PointField_Constants │ │ │ │ │ ├── __pycache__ │ │ │ │ │ │ ├── __init__.cpython-310.pyc │ │ │ │ │ │ └── _PointField_.cpython-310.pyc │ │ │ │ │ ├── __init__.py │ │ │ │ │ └── _PointField_.py │ │ │ │ ├── __init__.py │ │ │ │ ├── _PointField_.py │ │ │ │ └── _PointCloud2_.py │ │ │ └── __init__.py │ │ └── __init__.py │ ├── unitree_api │ │ ├── __pycache__ │ │ │ └── __init__.cpython-310.pyc │ │ ├── msg │ │ │ ├── __pycache__ │ │ │ │ └── __init__.cpython-310.pyc │ │ │ ├── dds_ │ │ │ │ ├── __pycache__ │ │ │ │ │ ├── _Request_.cpython-310.pyc │ │ │ │ │ ├── __init__.cpython-310.pyc │ │ │ │ │ ├── _Response_.cpython-310.pyc │ │ │ │ │ ├── _RequestLease_.cpython-310.pyc │ │ │ │ │ ├── _RequestHeader_.cpython-310.pyc │ │ │ │ │ ├── _RequestIdentity_.cpython-310.pyc │ │ │ │ │ ├── _RequestPolicy_.cpython-310.pyc │ │ │ │ │ ├── _ResponseHeader_.cpython-310.pyc │ │ │ │ │ └── _ResponseStatus_.cpython-310.pyc │ │ │ │ ├── __init__.py │ │ │ │ ├── _RequestLease_.py │ │ │ │ ├── _ResponseStatus_.py │ │ │ │ ├── _RequestPolicy_.py │ │ │ │ ├── _RequestIdentity_.py │ │ │ │ ├── _Request_.py │ │ │ │ ├── _Response_.py │ │ │ │ ├── _ResponseHeader_.py │ │ │ │ └── _RequestHeader_.py │ │ │ └── __init__.py │ │ └── __init__.py │ ├── unitree_go │ │ ├── __pycache__ │ │ │ └── __init__.cpython-310.pyc │ │ ├── msg │ │ │ ├── __pycache__ │ │ │ │ └── __init__.cpython-310.pyc │ │ │ ├── dds_ │ │ │ │ ├── __pycache__ │ │ │ │ │ ├── _Req_.cpython-310.pyc │ │ │ │ │ ├── _Res_.cpython-310.pyc │ │ │ │ │ ├── _BmsCmd_.cpython-310.pyc │ │ │ │ │ ├── _Error_.cpython-310.pyc │ │ │ │ │ ├── _LowCmd_.cpython-310.pyc │ │ │ │ │ ├── __init__.cpython-310.pyc │ │ │ │ │ ├── _BmsState_.cpython-310.pyc │ │ │ │ │ ├── _IMUState_.cpython-310.pyc │ │ │ │ │ ├── _LowState_.cpython-310.pyc │ │ │ │ │ ├── _MotorCmd_.cpython-310.pyc │ │ │ │ │ ├── _TimeSpec_.cpython-310.pyc │ │ │ │ │ ├── _UwbState_.cpython-310.pyc │ │ │ │ │ ├── _AudioData_.cpython-310.pyc │ │ │ │ │ ├── _HeightMap_.cpython-310.pyc │ │ │ │ │ ├── _LidarState_.cpython-310.pyc │ │ │ │ │ ├── _MotorState_.cpython-310.pyc │ │ │ │ │ ├── _PathPoint_.cpython-310.pyc │ │ │ │ │ ├── _UwbSwitch_.cpython-310.pyc │ │ │ │ │ ├── _InterfaceConfig_.cpython-310.pyc │ │ │ │ │ ├── _SportModeState_.cpython-310.pyc │ │ │ │ │ ├── _Go2FrontVideoData_.cpython-310.pyc │ │ │ │ │ └── _WirelessController_.cpython-310.pyc │ │ │ │ ├── _Req_.py │ │ │ │ ├── _UwbSwitch_.py │ │ │ │ ├── _Error_.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 │ │ │ │ ├── __init__.py │ │ │ │ ├── _LidarState_.py │ │ │ │ ├── _SportModeState_.py │ │ │ │ └── _LowState_.py │ │ │ └── __init__.py │ │ └── __init__.py │ ├── geometry_msgs │ │ ├── __pycache__ │ │ │ └── __init__.cpython-310.pyc │ │ ├── msg │ │ │ ├── __pycache__ │ │ │ │ └── __init__.cpython-310.pyc │ │ │ ├── dds_ │ │ │ │ ├── __pycache__ │ │ │ │ │ ├── _Point_.cpython-310.pyc │ │ │ │ │ ├── _Pose_.cpython-310.pyc │ │ │ │ │ ├── _Twist_.cpython-310.pyc │ │ │ │ │ ├── _Point32_.cpython-310.pyc │ │ │ │ │ ├── _Pose2D_.cpython-310.pyc │ │ │ │ │ ├── _Vector3_.cpython-310.pyc │ │ │ │ │ ├── __init__.cpython-310.pyc │ │ │ │ │ ├── _Quaternion_.cpython-310.pyc │ │ │ │ │ ├── _PointStamped_.cpython-310.pyc │ │ │ │ │ ├── _PoseStamped_.cpython-310.pyc │ │ │ │ │ ├── _TwistStamped_.cpython-310.pyc │ │ │ │ │ ├── _PoseWithCovariance_.cpython-310.pyc │ │ │ │ │ ├── _QuaternionStamped_.cpython-310.pyc │ │ │ │ │ ├── _TwistWithCovariance_.cpython-310.pyc │ │ │ │ │ ├── _PoseWithCovarianceStamped_.cpython-310.pyc │ │ │ │ │ └── _TwistWithCovarianceStamped_.cpython-310.pyc │ │ │ │ ├── _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 │ │ │ └── __init__.py │ │ └── __init__.py │ ├── builtin_interfaces │ │ ├── __pycache__ │ │ │ └── __init__.cpython-310.pyc │ │ ├── msg │ │ │ ├── __pycache__ │ │ │ │ └── __init__.cpython-310.pyc │ │ │ ├── dds_ │ │ │ │ ├── __pycache__ │ │ │ │ │ ├── _Time_.cpython-310.pyc │ │ │ │ │ └── __init__.cpython-310.pyc │ │ │ │ ├── __init__.py │ │ │ │ └── _Time_.py │ │ │ └── __init__.py │ │ └── __init__.py │ ├── nav_msgs │ │ ├── __init__.py │ │ └── msg │ │ │ ├── __init__.py │ │ │ └── dds_ │ │ │ ├── __init__.py │ │ │ ├── _OccupancyGrid_.py │ │ │ ├── _Odometry_.py │ │ │ └── _MapMetaData_.py │ ├── __init__.py │ └── idl_dataclass.py ├── rpc │ ├── __pycache__ │ │ ├── client.cpython-310.pyc │ │ ├── internal.cpython-310.pyc │ │ ├── client_base.cpython-310.pyc │ │ ├── client_stub.cpython-310.pyc │ │ ├── lease_client.cpython-310.pyc │ │ └── request_future.cpython-310.pyc │ ├── internal.py │ ├── server_base.py │ ├── request_future.py │ ├── client_stub.py │ ├── server_stub.py │ ├── client.py │ ├── lease_client.py │ ├── client_base.py │ ├── server.py │ └── lease_server.py ├── utils │ ├── __pycache__ │ │ ├── bqueue.cpython-310.pyc │ │ ├── future.cpython-310.pyc │ │ ├── logger.cpython-310.pyc │ │ └── singleton.cpython-310.pyc │ ├── singleton.py │ ├── clib_lookup.py │ ├── hz_sample.py │ ├── timerfd.py │ ├── bqueue.py │ ├── logger.py │ ├── thread.py │ ├── future.py │ └── crc.py ├── go2 │ ├── gpt │ │ ├── __pycache__ │ │ │ ├── gpt_api.cpython-310.pyc │ │ │ └── gpt_client.cpython-310.pyc │ │ ├── gpt_api.py │ │ └── gpt_client.py │ ├── vui │ │ ├── __pycache__ │ │ │ ├── vui_api.cpython-310.pyc │ │ │ └── vui_client.cpython-310.pyc │ │ ├── vui_api.py │ │ └── vui_client.py │ ├── sport │ │ ├── __pycache__ │ │ │ ├── sport_api.cpython-310.pyc │ │ │ └── sport_client.cpython-310.pyc │ │ └── sport_api.py │ ├── video │ │ ├── __pycache__ │ │ │ ├── video_api.cpython-310.pyc │ │ │ └── video_client.cpython-310.pyc │ │ ├── video_api.py │ │ └── video_client.py │ ├── audiohub │ │ ├── __pycache__ │ │ │ ├── audiohub_api.cpython-310.pyc │ │ │ └── audiohub_client.cpython-310.pyc │ │ └── audiohub_api.py │ ├── robot_state │ │ ├── __pycache__ │ │ │ ├── robot_state_api.cpython-310.pyc │ │ │ └── robot_state_client.cpython-310.pyc │ │ ├── robot_state_api.py │ │ └── robot_state_client.py │ ├── motion_switcher │ │ ├── __pycache__ │ │ │ ├── motion_switcher_api.cpython-310.pyc │ │ │ └── motion_switcher_client.cpython-310.pyc │ │ ├── motion_switcher_api.py │ │ └── motion_switcher_client.py │ └── obstacles_avoid │ │ ├── __pycache__ │ │ ├── obstacles_avoid_api.cpython-310.pyc │ │ └── obstacles_avoid_client.cpython-310.pyc │ │ ├── obstacles_avoid_api.py │ │ └── obstacles_avoid_client.py ├── __init__.py └── test │ ├── helloworld │ ├── helloworld.py │ ├── subscriber.py │ └── publisher.py │ ├── rpc │ ├── test_api.py │ ├── test_server_example.py │ └── test_client_example.py │ ├── crc │ └── test_crc.py │ ├── lowlevel │ ├── unitree_go2_const.py │ ├── sub_lowstate.py │ ├── read_lowstate.py │ └── lowlevel_control.py │ └── client │ ├── video_client_example.py │ ├── robot_service_client_example.py │ ├── vui_client_example.py │ ├── obstacles_avoid_client_example.py │ └── sport_client_example.py └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | *venv* 2 | .env 3 | .vscode 4 | 5 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/requirements.txt -------------------------------------------------------------------------------- /sounds/sound.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/sounds/sound.wav -------------------------------------------------------------------------------- /images/dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/images/dashboard.png -------------------------------------------------------------------------------- /sounds/attention.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/sounds/attention.wav -------------------------------------------------------------------------------- /sounds/fire_wea.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/sounds/fire_wea.wav -------------------------------------------------------------------------------- /sounds/lv_no_sr.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/sounds/lv_no_sr.wav -------------------------------------------------------------------------------- /static/dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/static/dashboard.png -------------------------------------------------------------------------------- /static/joystick-base.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/static/joystick-base.png -------------------------------------------------------------------------------- /static/joystick-blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/static/joystick-blue.png -------------------------------------------------------------------------------- /static/joystick-red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/static/joystick-red.png -------------------------------------------------------------------------------- /scripts/test.py: -------------------------------------------------------------------------------- 1 | import time 2 | 3 | print("START TEST SCRIPT") 4 | 5 | while True: 6 | print("RUNNING TEST SCRIPT " + str(time.time())) 7 | 8 | -------------------------------------------------------------------------------- /unitree_sdk2py/sdk/__pycache__/sdk.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/sdk/__pycache__/sdk.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/__pycache__/__init__.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/__pycache__/__init__.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/sdk/__pycache__/robot.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/sdk/__pycache__/robot.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/core/__pycache__/topics.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/core/__pycache__/topics.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/__pycache__/__init__.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/__pycache__/__init__.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/rpc/__pycache__/client.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/rpc/__pycache__/client.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/rpc/__pycache__/internal.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/rpc/__pycache__/internal.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/utils/__pycache__/bqueue.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/utils/__pycache__/bqueue.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/utils/__pycache__/future.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/utils/__pycache__/future.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/utils/__pycache__/logger.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/utils/__pycache__/logger.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/core/__pycache__/channel_name.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/core/__pycache__/channel_name.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/core/dds/__pycache__/channel.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/core/dds/__pycache__/channel.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/go2/gpt/__pycache__/gpt_api.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/go2/gpt/__pycache__/gpt_api.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/go2/vui/__pycache__/vui_api.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/go2/vui/__pycache__/vui_api.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/__pycache__/idl_dataclass.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/__pycache__/idl_dataclass.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/rpc/__pycache__/client_base.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/rpc/__pycache__/client_base.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/rpc/__pycache__/client_stub.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/rpc/__pycache__/client_stub.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/rpc/__pycache__/lease_client.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/rpc/__pycache__/lease_client.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/utils/__pycache__/singleton.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/utils/__pycache__/singleton.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/__init__.py: -------------------------------------------------------------------------------- 1 | from . import idl, utils, core, rpc, go2 2 | 3 | __all__ = [ 4 | "idl" 5 | "utils" 6 | "core", 7 | "rpc", 8 | "go2", 9 | ] 10 | -------------------------------------------------------------------------------- /unitree_sdk2py/go2/gpt/__pycache__/gpt_client.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/go2/gpt/__pycache__/gpt_client.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/go2/sport/__pycache__/sport_api.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/go2/sport/__pycache__/sport_api.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/go2/video/__pycache__/video_api.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/go2/video/__pycache__/video_api.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/go2/vui/__pycache__/vui_client.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/go2/vui/__pycache__/vui_client.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/rpc/__pycache__/request_future.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/rpc/__pycache__/request_future.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/go2/sport/__pycache__/sport_client.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/go2/sport/__pycache__/sport_client.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/go2/video/__pycache__/video_client.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/go2/video/__pycache__/video_client.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/std_msgs/__pycache__/__init__.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/std_msgs/__pycache__/__init__.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/core/dds/__pycache__/channel_config.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/core/dds/__pycache__/channel_config.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/sensor_msgs/__pycache__/__init__.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/sensor_msgs/__pycache__/__init__.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_api/__pycache__/__init__.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/unitree_api/__pycache__/__init__.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_go/__pycache__/__init__.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/unitree_go/__pycache__/__init__.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/go2/audiohub/__pycache__/audiohub_api.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/go2/audiohub/__pycache__/audiohub_api.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/geometry_msgs/__pycache__/__init__.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/geometry_msgs/__pycache__/__init__.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/std_msgs/msg/__pycache__/__init__.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/std_msgs/msg/__pycache__/__init__.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_go/msg/__pycache__/__init__.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/unitree_go/msg/__pycache__/__init__.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/go2/audiohub/__pycache__/audiohub_client.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/go2/audiohub/__pycache__/audiohub_client.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/sensor_msgs/msg/__pycache__/__init__.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/sensor_msgs/msg/__pycache__/__init__.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_api/msg/__pycache__/__init__.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/unitree_api/msg/__pycache__/__init__.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_go/msg/dds_/__pycache__/_Req_.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/unitree_go/msg/dds_/__pycache__/_Req_.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_go/msg/dds_/__pycache__/_Res_.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/unitree_go/msg/dds_/__pycache__/_Res_.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/go2/robot_state/__pycache__/robot_state_api.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/go2/robot_state/__pycache__/robot_state_api.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/builtin_interfaces/__pycache__/__init__.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/builtin_interfaces/__pycache__/__init__.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/geometry_msgs/msg/__pycache__/__init__.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/geometry_msgs/msg/__pycache__/__init__.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/std_msgs/msg/dds_/__pycache__/_Header_.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/std_msgs/msg/dds_/__pycache__/_Header_.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/std_msgs/msg/dds_/__pycache__/_String_.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/std_msgs/msg/dds_/__pycache__/_String_.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/std_msgs/msg/dds_/__pycache__/__init__.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/std_msgs/msg/dds_/__pycache__/__init__.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_go/msg/dds_/__pycache__/_BmsCmd_.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/unitree_go/msg/dds_/__pycache__/_BmsCmd_.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_go/msg/dds_/__pycache__/_Error_.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/unitree_go/msg/dds_/__pycache__/_Error_.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_go/msg/dds_/__pycache__/_LowCmd_.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/unitree_go/msg/dds_/__pycache__/_LowCmd_.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_go/msg/dds_/__pycache__/__init__.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/unitree_go/msg/dds_/__pycache__/__init__.cpython-310.pyc -------------------------------------------------------------------------------- /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/go2/robot_state/__pycache__/robot_state_client.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/go2/robot_state/__pycache__/robot_state_client.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/geometry_msgs/msg/dds_/__pycache__/_Point_.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/geometry_msgs/msg/dds_/__pycache__/_Point_.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/geometry_msgs/msg/dds_/__pycache__/_Pose_.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/geometry_msgs/msg/dds_/__pycache__/_Pose_.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/geometry_msgs/msg/dds_/__pycache__/_Twist_.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/geometry_msgs/msg/dds_/__pycache__/_Twist_.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/sensor_msgs/msg/dds_/__pycache__/__init__.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/sensor_msgs/msg/dds_/__pycache__/__init__.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_api/msg/dds_/__pycache__/_Request_.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/unitree_api/msg/dds_/__pycache__/_Request_.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_api/msg/dds_/__pycache__/__init__.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/unitree_api/msg/dds_/__pycache__/__init__.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_go/msg/dds_/__pycache__/_BmsState_.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/unitree_go/msg/dds_/__pycache__/_BmsState_.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_go/msg/dds_/__pycache__/_IMUState_.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/unitree_go/msg/dds_/__pycache__/_IMUState_.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_go/msg/dds_/__pycache__/_LowState_.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/unitree_go/msg/dds_/__pycache__/_LowState_.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_go/msg/dds_/__pycache__/_MotorCmd_.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/unitree_go/msg/dds_/__pycache__/_MotorCmd_.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_go/msg/dds_/__pycache__/_TimeSpec_.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/unitree_go/msg/dds_/__pycache__/_TimeSpec_.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_go/msg/dds_/__pycache__/_UwbState_.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/unitree_go/msg/dds_/__pycache__/_UwbState_.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/builtin_interfaces/msg/__pycache__/__init__.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/builtin_interfaces/msg/__pycache__/__init__.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/geometry_msgs/msg/dds_/__pycache__/_Point32_.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/geometry_msgs/msg/dds_/__pycache__/_Point32_.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/geometry_msgs/msg/dds_/__pycache__/_Pose2D_.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/geometry_msgs/msg/dds_/__pycache__/_Pose2D_.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/geometry_msgs/msg/dds_/__pycache__/_Vector3_.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/geometry_msgs/msg/dds_/__pycache__/_Vector3_.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/geometry_msgs/msg/dds_/__pycache__/__init__.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/geometry_msgs/msg/dds_/__pycache__/__init__.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/sensor_msgs/msg/dds_/__pycache__/_PointField_.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/sensor_msgs/msg/dds_/__pycache__/_PointField_.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_api/msg/dds_/__pycache__/_Response_.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/unitree_api/msg/dds_/__pycache__/_Response_.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_go/msg/dds_/__pycache__/_AudioData_.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/unitree_go/msg/dds_/__pycache__/_AudioData_.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_go/msg/dds_/__pycache__/_HeightMap_.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/unitree_go/msg/dds_/__pycache__/_HeightMap_.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_go/msg/dds_/__pycache__/_LidarState_.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/unitree_go/msg/dds_/__pycache__/_LidarState_.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_go/msg/dds_/__pycache__/_MotorState_.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/unitree_go/msg/dds_/__pycache__/_MotorState_.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_go/msg/dds_/__pycache__/_PathPoint_.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/unitree_go/msg/dds_/__pycache__/_PathPoint_.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_go/msg/dds_/__pycache__/_UwbSwitch_.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/unitree_go/msg/dds_/__pycache__/_UwbSwitch_.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/go2/motion_switcher/__pycache__/motion_switcher_api.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/go2/motion_switcher/__pycache__/motion_switcher_api.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/go2/obstacles_avoid/__pycache__/obstacles_avoid_api.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/go2/obstacles_avoid/__pycache__/obstacles_avoid_api.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/builtin_interfaces/msg/dds_/__pycache__/_Time_.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/builtin_interfaces/msg/dds_/__pycache__/_Time_.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/geometry_msgs/msg/dds_/__pycache__/_Quaternion_.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/geometry_msgs/msg/dds_/__pycache__/_Quaternion_.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/sensor_msgs/msg/dds_/__pycache__/_PointCloud2_.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/sensor_msgs/msg/dds_/__pycache__/_PointCloud2_.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_api/msg/dds_/__pycache__/_RequestLease_.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/unitree_api/msg/dds_/__pycache__/_RequestLease_.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/go2/motion_switcher/__pycache__/motion_switcher_client.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/go2/motion_switcher/__pycache__/motion_switcher_client.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/go2/obstacles_avoid/__pycache__/obstacles_avoid_client.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/go2/obstacles_avoid/__pycache__/obstacles_avoid_client.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/builtin_interfaces/msg/dds_/__pycache__/__init__.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/builtin_interfaces/msg/dds_/__pycache__/__init__.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/geometry_msgs/msg/dds_/__pycache__/_PointStamped_.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/geometry_msgs/msg/dds_/__pycache__/_PointStamped_.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/geometry_msgs/msg/dds_/__pycache__/_PoseStamped_.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/geometry_msgs/msg/dds_/__pycache__/_PoseStamped_.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/geometry_msgs/msg/dds_/__pycache__/_TwistStamped_.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/geometry_msgs/msg/dds_/__pycache__/_TwistStamped_.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_api/msg/dds_/__pycache__/_RequestHeader_.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/unitree_api/msg/dds_/__pycache__/_RequestHeader_.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_api/msg/dds_/__pycache__/_RequestIdentity_.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/unitree_api/msg/dds_/__pycache__/_RequestIdentity_.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_api/msg/dds_/__pycache__/_RequestPolicy_.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/unitree_api/msg/dds_/__pycache__/_RequestPolicy_.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_api/msg/dds_/__pycache__/_ResponseHeader_.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/unitree_api/msg/dds_/__pycache__/_ResponseHeader_.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_api/msg/dds_/__pycache__/_ResponseStatus_.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/unitree_api/msg/dds_/__pycache__/_ResponseStatus_.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_go/msg/dds_/__pycache__/_InterfaceConfig_.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/unitree_go/msg/dds_/__pycache__/_InterfaceConfig_.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_go/msg/dds_/__pycache__/_SportModeState_.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/unitree_go/msg/dds_/__pycache__/_SportModeState_.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_go/msg/dds_/__pycache__/_Go2FrontVideoData_.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/unitree_go/msg/dds_/__pycache__/_Go2FrontVideoData_.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/unitree_go/msg/dds_/__pycache__/_WirelessController_.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/unitree_go/msg/dds_/__pycache__/_WirelessController_.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/geometry_msgs/msg/dds_/__pycache__/_PoseWithCovariance_.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/geometry_msgs/msg/dds_/__pycache__/_PoseWithCovariance_.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/idl/geometry_msgs/msg/dds_/__pycache__/_QuaternionStamped_.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/geometry_msgs/msg/dds_/__pycache__/_QuaternionStamped_.cpython-310.pyc -------------------------------------------------------------------------------- /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/geometry_msgs/msg/dds_/__pycache__/_TwistWithCovariance_.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/geometry_msgs/msg/dds_/__pycache__/_TwistWithCovariance_.cpython-310.pyc -------------------------------------------------------------------------------- /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/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/geometry_msgs/msg/dds_/__pycache__/_PoseWithCovarianceStamped_.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/geometry_msgs/msg/dds_/__pycache__/_PoseWithCovarianceStamped_.cpython-310.pyc -------------------------------------------------------------------------------- /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/sensor_msgs/msg/dds_/PointField_Constants/__pycache__/__init__.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/sensor_msgs/msg/dds_/PointField_Constants/__pycache__/__init__.cpython-310.pyc -------------------------------------------------------------------------------- /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/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/geometry_msgs/msg/dds_/__pycache__/_TwistWithCovarianceStamped_.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/geometry_msgs/msg/dds_/__pycache__/_TwistWithCovarianceStamped_.cpython-310.pyc -------------------------------------------------------------------------------- /unitree_sdk2py/go2/gpt/gpt_api.py: -------------------------------------------------------------------------------- 1 | """ 2 | " service name 3 | """ 4 | GPT_SERVICE_NAME = "gpt" 5 | 6 | 7 | """ 8 | " service api version 9 | """ 10 | GPT_API_VERSION = "1.0.0.1" 11 | 12 | 13 | """ 14 | " api id 15 | """ 16 | 17 | GPT_API_ID_COMMAND = 1001 -------------------------------------------------------------------------------- /unitree_sdk2py/idl/sensor_msgs/msg/dds_/PointField_Constants/__pycache__/_PointField_.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bentheperson1/go2_dashboard/HEAD/unitree_sdk2py/idl/sensor_msgs/msg/dds_/PointField_Constants/__pycache__/_PointField_.cpython-310.pyc -------------------------------------------------------------------------------- /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/__init__.py: -------------------------------------------------------------------------------- 1 | from . import builtin_interfaces, geometry_msgs, sensor_msgs, std_msgs, unitree_go, unitree_api 2 | 3 | __all__ = [ 4 | "builtin_interfaces", 5 | "geometry_msgs", 6 | "sensor_msgs", 7 | "std_msgs", 8 | "unitree_go", 9 | "unitree_api", 10 | ] 11 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/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.1" 11 | 12 | 13 | """ 14 | " api id 15 | """ 16 | OBSTACLES_AVOID_API_ID_SWITCH_SET = 1001 17 | OBSTACLES_AVOID_API_ID_SWITCH_GET = 1002 18 | -------------------------------------------------------------------------------- /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/test/crc/test_crc.py: -------------------------------------------------------------------------------- 1 | from unitree_sdk2py.idl.default import * 2 | from unitree_sdk2py.utils.crc import CRC 3 | 4 | crc = CRC() 5 | 6 | """ 7 | " LowCmd CRC 8 | """ 9 | cmd = unitree_go_msg_dds__LowCmd_() 10 | cmd.crc = crc.Crc(cmd) 11 | 12 | state = unitree_go_msg_dds__LowState_() 13 | state.crc = crc.Crc(state) 14 | 15 | print("CRC[LowCmd, LowState]: {}, {}".format(cmd.crc, state.crc)) 16 | -------------------------------------------------------------------------------- /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/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/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/test/helloworld/subscriber.py: -------------------------------------------------------------------------------- 1 | import time 2 | 3 | from unitree_sdk2py.core.dds.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/go2/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_GET_MODE = 1001 17 | MOTION_SWITCHER_API_ID_SET_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 | -------------------------------------------------------------------------------- /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/test/lowlevel/sub_lowstate.py: -------------------------------------------------------------------------------- 1 | import time 2 | from unitree_sdk2py.core.dds.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/test/helloworld/publisher.py: -------------------------------------------------------------------------------- 1 | import time 2 | 3 | from unitree_sdk2py.core.dds.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() -------------------------------------------------------------------------------- /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/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/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_/_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/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/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/go2/vui/vui_api.py: -------------------------------------------------------------------------------- 1 | from dataclasses import dataclass 2 | """ 3 | " service name 4 | """ 5 | VUI_SERVICE_NAME = "vui" 6 | 7 | 8 | """ 9 | " service api version 10 | """ 11 | VUI_API_VERSION = "1.0.0.1" 12 | 13 | 14 | """ 15 | " api id 16 | """ 17 | VUI_API_ID_SETSWITCH = 1001 18 | VUI_API_ID_GETSWITCH = 1002 19 | VUI_API_ID_SETVOLUME = 1003 20 | VUI_API_ID_GETVOLUME = 1004 21 | VUI_API_ID_SETBRIGHTNESS = 1005 22 | VUI_API_ID_GETBRIGHTNESS = 1006 23 | VUI_API_ID_LED_SET = 1007 24 | VUI_API_ID_LED_QUIT = 1008 25 | 26 | """ 27 | " color 28 | """ 29 | @dataclass(frozen=True) 30 | class VUI_COLOR: 31 | WHITE: str = 'white' 32 | RED: str = 'red' 33 | YELLOW: str = 'yellow' 34 | BLUE: str = 'blue' 35 | GREEN: str = 'green' 36 | CYAN: str = 'cyan' 37 | PURPLE: str = 'purple' 38 | -------------------------------------------------------------------------------- /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/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_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/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/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/test/client/video_client_example.py: -------------------------------------------------------------------------------- 1 | import time 2 | import os 3 | 4 | from unitree_sdk2py.core.dds.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/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 | -------------------------------------------------------------------------------- /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_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/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/test/lowlevel/read_lowstate.py: -------------------------------------------------------------------------------- 1 | import time 2 | from unitree_sdk2py.core.dds.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_/_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/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_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/dds/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/go2/video/video_client.py: -------------------------------------------------------------------------------- 1 | import json 2 | 3 | from ...rpc.client import Client 4 | from .video_api import * 5 | 6 | import logging 7 | 8 | """ 9 | " class VideoClient 10 | """ 11 | class VideoClient(Client): 12 | default_service_name = VIDEO_SERVICE_NAME 13 | 14 | def __init__(self, communicator, logger: logging.Logger = None, *args, **kwargs): 15 | self.logger = logger.getChild(self.__class__.__name__) if logger else logging.getLogger(self.__class__.__name__) 16 | self.service_name = VideoClient.default_service_name 17 | super().__init__(communicator=communicator, serviceName=self.service_name, enabaleLease=False, logger=self.logger) 18 | 19 | def Init(self): 20 | # set api version 21 | self._SetApiVerson(VIDEO_API_VERSION) 22 | # regist api 23 | self._RegistApi(VIDEO_API_ID_GETIMAGESAMPLE, 0) 24 | 25 | # 1001 26 | def GetImageSample(self): 27 | return self._CallBinary(VIDEO_API_ID_GETIMAGESAMPLE, []) 28 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /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/go2/gpt/gpt_client.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import json 3 | 4 | from ...rpc.client import Client 5 | from .gpt_api import * 6 | 7 | from pydub import AudioSegment 8 | import base64 9 | import time 10 | import uuid 11 | 12 | """ 13 | " class GPTClient 14 | """ 15 | class GPTClient(Client): 16 | default_service_name = GPT_SERVICE_NAME 17 | 18 | def __init__(self, communicator, logger: logging.Logger = None, *args, **kwargs): 19 | self.logger = logger.getChild(self.__class__.__name__) if logger else logging.getLogger(self.__class__.__name__) 20 | self.communicator = communicator 21 | self.serviceName = GPTClient.default_service_name 22 | super().__init__(self.communicator, serviceName=self.serviceName, enabaleLease=False, logger=self.logger) 23 | 24 | def Init(self): 25 | # set api version 26 | self._SetApiVerson(GPT_API_VERSION) 27 | 28 | # regist api 29 | self._RegistApi(GPT_API_ID_COMMAND, 0) 30 | 31 | # 1002 32 | # Listen rt/gptflowfeedback for response 33 | def GPTSendCommand(self, command): 34 | parameter = command 35 | code, data = self._Call(GPT_API_ID_COMMAND, parameter) 36 | return code -------------------------------------------------------------------------------- /unitree_sdk2py/test/rpc/test_server_example.py: -------------------------------------------------------------------------------- 1 | import time 2 | import json 3 | 4 | from unitree_sdk2py.core.dds.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) -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 ._MotorState_ import MotorState_ 21 | from ._Req_ import Req_ 22 | from ._Res_ import Res_ 23 | from ._SportModeState_ import SportModeState_ 24 | from ._TimeSpec_ import TimeSpec_ 25 | from ._PathPoint_ import PathPoint_ 26 | from ._UwbState_ import UwbState_ 27 | from ._UwbSwitch_ import UwbSwitch_ 28 | from ._WirelessController_ import WirelessController_ 29 | __all__ = ["AudioData_", "BmsCmd_", "BmsState_", "Error_", "Go2FrontVideoData_", "HeightMap_", "IMUState_", "InterfaceConfig_", "LidarState_", "LowCmd_", "LowState_", "MotorCmd_", "MotorState_", "Req_", "Res_", "SportModeState_", "TimeSpec_", "PathPoint_", "UwbState_", "UwbSwitch_", "WirelessController_", ] 30 | -------------------------------------------------------------------------------- /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) -------------------------------------------------------------------------------- /unitree_sdk2py/core/channel_name.py: -------------------------------------------------------------------------------- 1 | from enum import Enum 2 | from .topics import DDS_TOPICS, WEBRTC_TOPICS 3 | 4 | """ 5 | " Enum ChannelType 6 | """ 7 | class ChannelType(Enum): 8 | SEND = 0 9 | RECV = 1 10 | 11 | """ 12 | " function GetClientChannelName 13 | """ 14 | def GetClientReqResChannelName(channel_name: str, serviceName: str, channelType: ChannelType): 15 | name = "rt/api/" + serviceName 16 | 17 | if channelType == ChannelType.SEND: 18 | name += "/request" 19 | else: 20 | name += "/response" 21 | 22 | if channel_name == 'DDS': 23 | return name 24 | elif channel_name == 'WEBRTC': 25 | if serviceName in WEBRTC_TOPICS: 26 | return name 27 | else: 28 | raise ValueError(f"WEBRTC doesnt support this topic: {name}") 29 | 30 | """ 31 | " function GetClientChannelName 32 | """ 33 | def GetServerReqResChannelName(channel_name: str, serviceName: str, channelType: ChannelType): 34 | name = "rt/api/" + serviceName 35 | 36 | if channelType == ChannelType.SEND: 37 | name += "/response" 38 | else: 39 | name += "/request" 40 | 41 | if channel_name == 'DDS': 42 | return name 43 | elif channel_name == 'WEBRTC': 44 | if serviceName in WEBRTC_TOPICS: 45 | return name 46 | else: 47 | raise ValueError(f"WEBRTC doesnt support this topic: {name}") -------------------------------------------------------------------------------- /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/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 | import logging 7 | 8 | """ 9 | " class ObstaclesAvoidClient 10 | """ 11 | class ObstaclesAvoidClient(Client): 12 | default_service_name = OBSTACLES_AVOID_SERVICE_NAME 13 | 14 | def __init__(self, communicator, logger: logging.Logger = None, *args, **kwargs): 15 | self.logger = logger.getChild(self.__class__.__name__) if logger else logging.getLogger(self.__class__.__name__) 16 | self.service_name = ObstaclesAvoidClient.default_service_name 17 | super().__init__(communicator=communicator, serviceName=self.service_name, enabaleLease=False, logger=self.logger) 18 | 19 | def Init(self): 20 | # set api version 21 | self._SetApiVerson(OBSTACLES_AVOID_API_VERSION) 22 | # regist api 23 | self._RegistApi(OBSTACLES_AVOID_API_ID_SWITCH_SET, 0) 24 | self._RegistApi(OBSTACLES_AVOID_API_ID_SWITCH_GET, 0) 25 | 26 | # 1001 27 | def SwitchSet(self, on: bool): 28 | p = {} 29 | p["enable"] = on 30 | parameter = json.dumps(p) 31 | 32 | code, data = self._Call(OBSTACLES_AVOID_API_ID_SWITCH_SET, parameter) 33 | return code 34 | 35 | # 1002 36 | def SwitchGet(self): 37 | p = {} 38 | parameter = json.dumps(p) 39 | 40 | code, data = self._Call(OBSTACLES_AVOID_API_ID_SWITCH_GET, parameter) 41 | if code == 0: 42 | d = json.loads(data) 43 | return code, d["enable"] 44 | else: 45 | return code, None -------------------------------------------------------------------------------- /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/test/rpc/test_client_example.py: -------------------------------------------------------------------------------- 1 | import time 2 | import json 3 | 4 | from unitree_sdk2py.core.dds.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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Go2 Dashboard 2 | 3 | ![](images/dashboard.png) 4 | 5 | A nice little dashboard to access your Unitree Go2 through a web interface that allows you to: 6 | - See stats about the dog like velocity or yaw speed 7 | - Get a live camera feed 8 | - Remotely start/stop scripts on your computer 9 | - Upload and play sound effects through the dog 10 | - Control the dog's movement using virtual joysticks 11 | - Run actions like standing up, laying down, or wave 12 | 13 | To Do: 14 | - Add WebRTC support: In progress on [Develop](https://github.com/bentheperson1/go2_dashboard/tree/develop) 15 | - Add support for running the dashboard on the dog itself 16 | 17 | Uses [Legion1381's fork of the Unitree Python SDK](https://github.com/legion1581/go2_python_sdk2/tree/dev) 18 | 19 | ## Code Setup (Local Machine) 20 | 21 | ### Note: This dashboard currently only works over ethernet. Use [This guide](https://support.unitree.com/home/en/developer/Quick_start) to configure your networking correctly. 22 | 23 | **Prerequisites:** 24 | Ensure CMake and Python 3 are installed on your system. 25 | 26 | **Install CycloneDDS:** 27 | ```bash 28 | cd ~ 29 | git clone https://github.com/eclipse-cyclonedds/cyclonedds -b releases/0.10.x 30 | cd cyclonedds && mkdir build install && cd build 31 | cmake .. -DCMAKE_INSTALL_PREFIX="~/cyclonedds/install" 32 | cmake --build . --target install 33 | export CYCLONEDDS_HOME="~/cyclonedds/install" 34 | ``` 35 | 36 | **Create and Activate a Virtual Environment:** 37 | - **Windows:** 38 | ```bash 39 | python -m venv .venv 40 | .venv/Scripts/activate 41 | ``` 42 | - **Linux:** 43 | ```bash 44 | python3 -m venv .venv 45 | source .venv/bin/activate 46 | ``` 47 | 48 | **Install Dependencies:** 49 | ```bash 50 | pip install -r requirements.txt 51 | ``` 52 | 53 | **Start Dashboard:** 54 | ```bash 55 | python app.py 56 | ``` 57 | -------------------------------------------------------------------------------- /unitree_sdk2py/test/client/robot_service_client_example.py: -------------------------------------------------------------------------------- 1 | import time 2 | from unitree_sdk2py.core.dds.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 | -------------------------------------------------------------------------------- /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/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_SWITCHGAIT = 1011 27 | SPORT_API_ID_TRIGGER = 1012 28 | SPORT_API_ID_BODYHEIGHT = 1013 29 | SPORT_API_ID_FOOTRAISEHEIGHT = 1014 30 | SPORT_API_ID_SPEEDLEVEL = 1015 31 | SPORT_API_ID_HELLO = 1016 32 | SPORT_API_ID_STRETCH = 1017 33 | SPORT_API_ID_TRAJECTORYFOLLOW = 1018 34 | SPORT_API_ID_CONTINUOUSGAIT = 1019 35 | SPORT_API_ID_CONTENT = 1020 36 | SPORT_API_ID_WALLOW = 1021 37 | SPORT_API_ID_DANCE1 = 1022 38 | SPORT_API_ID_DANCE2 = 1023 39 | SPORT_API_ID_GETBODYHEIGHT = 1024 40 | SPORT_API_ID_GETFOOTRAISEHEIGHT = 1025 41 | SPORT_API_ID_GETSPEEDLEVEL = 1026 42 | SPORT_API_ID_SWITCHJOYSTICK = 1027 43 | SPORT_API_ID_POSE = 1028 44 | SPORT_API_ID_SCRAPE = 1029 45 | SPORT_API_ID_FRONTFLIP = 1030 46 | SPORT_API_ID_FRONTJUMP = 1031 47 | SPORT_API_ID_FRONTPOUNCE = 1032 48 | SPORT_API_ID_WIGGLEHIPS = 1033 49 | SPORT_API_ID_GETSTATE = 1034 50 | SPORT_API_ID_ECONOMICGAIT = 1035 51 | SPORT_API_ID_HEART = 1036 52 | SPORT_API_ID_LEADFOLLOW = 1045 53 | 54 | # works only in advanced mode 55 | SPORT_API_ID_HANDSTAND = 1301 56 | SPORT_API_ID_CROSSSTEP = 1302 57 | SPORT_API_ID_ONESIDEDSTEP = 1303 58 | SPORT_API_ID_BOUND = 1304 59 | 60 | # works only in ai mode 61 | SPORT_API_ID_AUTO_SWITCH_MOVE_MODE = 1038 62 | SPORT_API_ID_STANDOUT = 1039 63 | SPORT_API_ID_SET_AUTO_ROLL_RECOVERY = 1040 64 | SPORT_API_ID_GET_AUTO_ROLL_RECOVERY = 1041 65 | 66 | 67 | 68 | """ 69 | " error code 70 | """ 71 | # client side 72 | SPORT_ERR_CLIENT_POINT_PATH = 4101 73 | # server side 74 | SPORT_ERR_SERVER_OVERTIME = 4201 75 | SPORT_ERR_SERVER_NOT_INIT = 4202 76 | -------------------------------------------------------------------------------- /unitree_sdk2py/test/lowlevel/lowlevel_control.py: -------------------------------------------------------------------------------- 1 | import time 2 | 3 | from unitree_sdk2py.core.dds.channel import ChannelPublisher, ChannelFactoryInitialize 4 | from unitree_sdk2py.idl.default import unitree_go_msg_dds__LowCmd_ 5 | from unitree_sdk2py.idl.unitree_go.msg.dds_ import LowCmd_ 6 | from unitree_sdk2py.utils.crc import CRC 7 | from unitree_sdk2py.utils.thread import Thread 8 | import unitree_go2_const as go2 9 | 10 | crc = CRC() 11 | lowCmdThreadPtr=Thread() 12 | 13 | if __name__ == '__main__': 14 | 15 | ChannelFactoryInitialize(1, "enp2s0") 16 | # Create a publisher to publish the data defined in UserData class 17 | pub = ChannelPublisher("lowcmd", LowCmd_) 18 | pub.Init() 19 | 20 | while True: 21 | # Create a Userdata message 22 | cmd = unitree_go_msg_dds__LowCmd_() 23 | 24 | # Toque controle, set RL_2 toque 25 | cmd.motor_cmd[go2.LegID["RL_2"]].mode = 0x01 26 | cmd.motor_cmd[go2.LegID["RL_2"]].q = go2.PosStopF # Set to stop position(rad) 27 | cmd.motor_cmd[go2.LegID["RL_2"]].kp = 0 28 | cmd.motor_cmd[go2.LegID["RL_2"]].dq = go2.VelStopF # Set to stop angular velocity(rad/s) 29 | cmd.motor_cmd[go2.LegID["RL_2"]].kd = 0 30 | cmd.motor_cmd[go2.LegID["RL_2"]].tau = 1 # target toque is set to 1N.m 31 | 32 | # Poinstion(rad) control, set RL_0 rad 33 | cmd.motor_cmd[go2.LegID["RL_0"]].mode = 0x01 34 | cmd.motor_cmd[go2.LegID["RL_0"]].q = 0 # Taregt angular(rad) 35 | cmd.motor_cmd[go2.LegID["RL_0"]].kp = 10 # Poinstion(rad) control kp gain 36 | cmd.motor_cmd[go2.LegID["RL_0"]].dq = 0 # Taregt angular velocity(rad/ss) 37 | cmd.motor_cmd[go2.LegID["RL_0"]].kd = 1 # Poinstion(rad) control kd gain 38 | cmd.motor_cmd[go2.LegID["RL_0"]].tau = 0 # Feedforward toque 1N.m 39 | 40 | cmd.crc = crc.Crc(cmd) 41 | 42 | #Publish message 43 | if pub.Write(cmd): 44 | print("Publish success. msg:", cmd.crc) 45 | else: 46 | print("Waitting for subscriber.") 47 | 48 | time.sleep(0.002) 49 | 50 | pub.Close() 51 | -------------------------------------------------------------------------------- /unitree_sdk2py/utils/logger.py: -------------------------------------------------------------------------------- 1 | import logging 2 | 3 | def get_logger(): 4 | return logging.getLogger() 5 | 6 | 7 | def setup_logging(verbose=False, include_dedup_filter=False, 8 | always_print_logger_levels={logging.CRITICAL, logging.ERROR}): 9 | """Set up a basic streaming console handler at the root logger. 10 | 11 | Args: 12 | verbose (bool): if False (default) show messages at INFO level and above, 13 | if True show messages at DEBUG level and above. 14 | include_dedup_filter (bool): If true, the logger includes a filter which 15 | will prevent repeated duplicated messages 16 | from being logged. 17 | always_print_logger_levels (set[logging.Level]): A set of logging levels which 18 | any logged message at that level will 19 | always be logged. 20 | """ 21 | logger = get_logger() 22 | 23 | if verbose: 24 | level = logging.DEBUG 25 | else: 26 | level = logging.INFO 27 | 28 | if not logger.handlers: 29 | stream_handler = logging.StreamHandler() 30 | stream_handler.setLevel(level) 31 | formatter = logging.Formatter('%(asctime)s - %(levelname)s - [%(filename)s:%(funcName)s:%(lineno)d] - %(message)s') 32 | stream_handler.setFormatter(formatter) 33 | logger.addHandler(stream_handler) 34 | 35 | logger.setLevel(level) 36 | 37 | if include_dedup_filter: 38 | class DeduplicationFilter(logging.Filter): 39 | def __init__(self): 40 | self.logged_messages = set() 41 | 42 | def filter(self, record): 43 | log_entry = (record.levelno, record.getMessage()) 44 | if log_entry in self.logged_messages and record.levelno not in always_print_logger_levels: 45 | return False 46 | self.logged_messages.add(log_entry) 47 | return True 48 | 49 | dedup_filter = DeduplicationFilter() 50 | logger.addFilter(dedup_filter) 51 | 52 | -------------------------------------------------------------------------------- /unitree_sdk2py/test/client/vui_client_example.py: -------------------------------------------------------------------------------- 1 | import time 2 | import os 3 | 4 | from unitree_sdk2py.core.dds.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 | -------------------------------------------------------------------------------- /unitree_sdk2py/sdk/robot.py: -------------------------------------------------------------------------------- 1 | import logging 2 | 3 | class Robot: 4 | def __init__(self, communicator, serialNumber=None, name=None): 5 | self._name = name 6 | self.serialNumber = serialNumber 7 | self.logger = logging.getLogger(self.__class__.__name__) 8 | self.communicator = communicator 9 | self.client_name = None 10 | 11 | # Updated from sdk object 12 | self.service_client_instance_by_name = {} 13 | self.service_client_factories_by_name={} 14 | 15 | def ensure_client(self, service_name, *args, **kwargs): 16 | """ 17 | Ensure a Client for a given service. If the client does not exist, create it using the factory. 18 | 19 | Args: 20 | service_name (str): The name of the service. 21 | client_factory (callable): A factory function or lambda to create a new client if one does not exist. 22 | 23 | Returns: 24 | The client instance associated with the given service name. 25 | 26 | Raises: 27 | ValueError: If the client_factory is not provided and the client does not exist. 28 | """ 29 | client = self.service_client_instance_by_name.get(service_name) 30 | if not client: 31 | client_factory = self.service_client_factories_by_name.get(service_name) 32 | if client_factory: 33 | client = client_factory(self.communicator, self.logger, *args, **kwargs) 34 | self.service_client_instance_by_name[service_name] = client 35 | self.logger.debug(f'Created client for {service_name}') 36 | else: 37 | raise ValueError(f"No client factory available for {service_name}") 38 | 39 | return client 40 | 41 | def update_from(self, other): 42 | """ 43 | Update this robot's service clients and configuration from another robot or a similar object. 44 | 45 | Args: 46 | other (Robot): Another robot object whose configurations and clients will be copied. 47 | """ 48 | self.service_client_factories_by_name.update(other.service_client_factories_by_name) 49 | self.logger = other.logger.getChild(self.serialNumber or __class__.__name__) 50 | self.client_name = other.client_name 51 | 52 | -------------------------------------------------------------------------------- /unitree_sdk2py/core/topics.py: -------------------------------------------------------------------------------- 1 | 2 | #Topics only available through WebRTC (however will work through DDS) 3 | 4 | WEBRTC_TOPICS = [ 5 | # General Device Control and Configuration 6 | "rt/rtc_status", 7 | "rt/rtc/state", 8 | "rt/servicestate", 9 | "rt/servicestateactivate", 10 | "rt/public_network_status", 11 | 12 | # API Requests and Responses 13 | "rt/videohub/inner", 14 | "rt/api/videohub/request", 15 | "rt/api/videohub/response", 16 | "rt/api/uwbswitch/request", 17 | "rt/api/uwbswitch/response", 18 | "rt/api/bashrunner/request", 19 | "rt/api/bashrunner/response", 20 | "rt/api/obstacles_avoid/request", 21 | "rt/api/obstacles_avoid/response", 22 | "rt/api/vui/request", 23 | "rt/api/vui/response", 24 | "rt/api/gpt/request", 25 | "rt/api/gpt/response", 26 | "rt/api/sport/request", 27 | "rt/api/sport/response", 28 | "rt/api/robot_state/request", 29 | "rt/api/robot_state/response", 30 | "rt/api/audiohub/request", 31 | "rt/api/audiohub/response", 32 | "rt/api/config/request", 33 | "rt/api/config/response", 34 | "rt/api/motion_switcher/request", 35 | "rt/api/motion_switcher/response", 36 | "rt/api/gas_sensor/request", 37 | "rt/api/gas_sensor/response", 38 | 39 | # SLAM and Mapping 40 | "rt/qt_command", 41 | "rt/qt_add_node", 42 | "rt/qt_add_edge", 43 | "rt/qt_notice", 44 | "rt/pctoimage_local", 45 | "rt/lio_sam_ros2/mapping/odometry", 46 | 47 | # Query and Feedback 48 | "rt/query_result_node", 49 | "rt/query_result_edge", 50 | "rt/gptflowfeedback", 51 | 52 | # Sensor Data 53 | "rt/utlidar/switch", 54 | "rt/utlidar/voxel_map_compressed", 55 | "rt/utlidar/lidar_state", 56 | "rt/utlidar/robot_pose", 57 | "rt/uwbstate", 58 | 59 | # Device State 60 | "rt/multiplestate", 61 | "rt/lf/lowstate", 62 | "rt/lf/sportmodestate", 63 | "rt/audiohub/player/state", 64 | "rt/selftest", 65 | "rt/gas_sensor", 66 | 67 | # Arm Commands and Feedback 68 | "rt/arm_Command", 69 | "rt/arm_Feedback", 70 | 71 | # Wireless Controller 72 | "rt/wirelesscontroller", 73 | ] 74 | 75 | 76 | DDS_ONLY_TOPICS = [ 77 | "rt/sportmodestate", 78 | "rt/mf/sportmodestate", 79 | "rt/utlidar/voxel_map", 80 | "rt/lowstate", 81 | "rt/lowcmd" 82 | ] 83 | 84 | # Combine WebRTC topics with DDS-specific topics for comprehensive DDS topics 85 | DDS_TOPICS = WEBRTC_TOPICS + DDS_ONLY_TOPICS 86 | -------------------------------------------------------------------------------- /unitree_sdk2py/go2/robot_state/robot_state_client.py: -------------------------------------------------------------------------------- 1 | import json 2 | 3 | from ...rpc.client import Client 4 | from .robot_state_api import * 5 | 6 | import logging 7 | 8 | 9 | """ 10 | " class ServiceState 11 | """ 12 | class ServiceState: 13 | def __init__(self, name: str = None, status: int = None, protect: bool = None): 14 | self.name = name 15 | self.status = status 16 | self.protect = protect 17 | 18 | """ 19 | " class RobotStateClient 20 | """ 21 | class RobotStateClient(Client): 22 | default_service_name = ROBOT_STATE_SERVICE_NAME 23 | 24 | def __init__(self, logger: logging.Logger = None, *args, **kwargs): 25 | self.logger = logger.getChild(self.__class__.__name__) if logger else logging.getLogger(self.__class__.__name__) 26 | super().__init__(self.service_name, enabaleLease=False, logger=self.logger) 27 | 28 | 29 | def Init(self): 30 | # set api version 31 | self._SetApiVerson(ROBOT_STATE_API_VERSION) 32 | # regist api 33 | self._RegistApi(ROBOT_STATE_API_ID_SERVICE_SWITCH, 0) 34 | self._RegistApi(ROBOT_STATE_API_ID_REPORT_FREQ, 0) 35 | self._RegistApi(ROBOT_STATE_API_ID_SERVICE_LIST, 0) 36 | 37 | def ServiceList(self): 38 | p = {} 39 | parameter = json.dumps(p) 40 | 41 | code, data = self._Call(ROBOT_STATE_API_ID_SERVICE_LIST, parameter) 42 | 43 | if code != 0: 44 | return code, None 45 | 46 | lst = [] 47 | 48 | d = json.loads(data) 49 | for t in d: 50 | s = ServiceState() 51 | s.name = t["name"] 52 | s.status = t["status"] 53 | s.protect = t["protect"] 54 | lst.append(s) 55 | 56 | return code, lst 57 | 58 | 59 | def ServiceSwitch(self, name: str, switch: bool): 60 | p = {} 61 | p["name"] = name 62 | p["switch"] = int(switch) 63 | parameter = json.dumps(p) 64 | 65 | code, data = self._Call(ROBOT_STATE_API_ID_SERVICE_SWITCH, parameter) 66 | 67 | if code != 0: 68 | return code 69 | 70 | d = json.loads(data) 71 | 72 | status = d["status"] 73 | 74 | if status == 5: 75 | return ROBOT_STATE_ERR_SERVICE_PROTECTED 76 | 77 | if status != 0 and status != 1: 78 | return ROBOT_STATE_ERR_SERVICE_SWITCH 79 | 80 | return code 81 | 82 | def SetReportFreq(self, interval: int, duration: int): 83 | p = {} 84 | p["interval"] = interval 85 | p["duration"] = duration 86 | parameter = json.dumps(p) 87 | 88 | code, data = self._Call(ROBOT_STATE_API_ID_REPORT_FREQ, p) 89 | return code 90 | -------------------------------------------------------------------------------- /unitree_sdk2py/go2/motion_switcher/motion_switcher_client.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import json 3 | 4 | from ...rpc.client import Client 5 | from .motion_switcher_api import * 6 | 7 | """ 8 | " class MotionSwitcherClient 9 | """ 10 | class MotionSwitcherClient(Client): 11 | default_service_name = MOTION_SWITCHER_SERVICE_NAME 12 | 13 | def __init__(self, communicator, logger: logging.Logger = None, *args, **kwargs): 14 | self.logger = logger.getChild(self.__class__.__name__) if logger else logging.getLogger(self.__class__.__name__) 15 | self.serviceName = MotionSwitcherClient.default_service_name 16 | super().__init__(communicator, serviceName=self.serviceName, enabaleLease=False, logger=self.logger) 17 | 18 | def Init(self): 19 | # set api version 20 | self._SetApiVerson(MOTION_SWITCHER_API_VERSION) 21 | 22 | # regist api 23 | self._RegistApi(MOTION_SWITCHER_API_ID_GET_MODE, 0) 24 | self._RegistApi(MOTION_SWITCHER_API_ID_SET_MODE, 0) 25 | self._RegistApi(MOTION_SWITCHER_API_ID_RELEASE_MODE, 0) 26 | self._RegistApi(MOTION_SWITCHER_API_ID_GET_SILENT, 0) 27 | self._RegistApi(MOTION_SWITCHER_API_ID_SET_SILENT, 0) 28 | 29 | # 1001 30 | # Get current sport mode: normal or advanced or ai 31 | def GetMode(self): 32 | p = {} 33 | parameter = json.dumps(p) 34 | code, data = self._Call(MOTION_SWITCHER_API_ID_GET_MODE, parameter) 35 | return code 36 | 37 | # 1002 38 | # Set current sport mode: normal or advanced or ai 39 | def SetMode(self, mode: str): 40 | p = {} 41 | p["name"] = mode 42 | parameter = json.dumps(p) 43 | code, data = self._Call(MOTION_SWITCHER_API_ID_SET_MODE, parameter) 44 | return code 45 | 46 | # 1003 47 | # Disables both services: advanced and normal and ai 48 | # If flag set to True then dumps imediatly, otherwise does a soft StandDown movement 49 | def ReleaseMode(self, flag: bool): 50 | p = {} 51 | p["sample"] = flag 52 | parameter = json.dumps(p) 53 | code, data = self._Call(MOTION_SWITCHER_API_ID_RELEASE_MODE, parameter) 54 | return code 55 | 56 | # 1004 57 | # If true after the boot up none of the sport services would be launched. Perfect for developing 58 | def SetSilent(self, flag: bool): 59 | p = {} 60 | p["silent"] = flag 61 | parameter = json.dumps(p) 62 | code, data = self._Call(MOTION_SWITCHER_API_ID_SET_SILENT, parameter) 63 | return code 64 | 65 | # 1005 66 | def GetSilent(self, flag: bool): 67 | p = {} 68 | parameter = json.dumps(p) 69 | code, data = self._Call(MOTION_SWITCHER_API_ID_GET_SILENT, parameter) 70 | return code -------------------------------------------------------------------------------- /unitree_sdk2py/go2/audiohub/audiohub_api.py: -------------------------------------------------------------------------------- 1 | """ 2 | " service name 3 | """ 4 | AUDIOHUB_SERVICE_NAME = "audiohub" 5 | 6 | 7 | """ 8 | " service api version 9 | """ 10 | AUDIOHUB_API_VERSION = "1.0.0.1" 11 | 12 | 13 | """ 14 | " api id 15 | """ 16 | # API ID | FUNCTION 17 | # 1001 | audio list 18 | # 1002 | select a recording and start playing it 19 | # 1003 | pause 20 | # 1004 | unsuspend 21 | # 1005 | select the previous recording and start playing 22 | # 1006 | select the next recording and start playing 23 | # 1007 | set play mode (no cycle, single cycle, list loop) 24 | # 1008 | select a recording and rename it 25 | # 1009 | select a recording and delete it. (If the recording is being played, 26 | # a pop-up message is displayed to confirm that the recording cannot 27 | # be played after deletion.) 28 | # 1010 | get play mode (no cycle, single cycle, list loop) 29 | 30 | 31 | AUDIOHUB_API_ID_AUDIO_PLAYER_AUDIO_LIST = 1001 32 | AUDIOHUB_API_ID_AUDIO_PLAYER_SELECT_START_PLAY = 1002 33 | AUDIOHUB_API_ID_AUDIO_PLAYER_PAUSE = 1003 34 | AUDIOHUB_API_ID_AUDIO_PLAYER_UNSUSPEND = 1004 35 | AUDIOHUB_API_ID_AUDIO_PLAYER_SELECT_PREV_START_PLAY = 1005 36 | AUDIOHUB_API_ID_AUDIO_PLAYER_SELECT_NEXT_START_PLAY = 1006 37 | AUDIOHUB_API_ID_AUDIO_PLAYER_SET_PLAY_MODE = 1007 38 | AUDIOHUB_API_ID_AUDIO_PLAYER_SELECT_RENAME = 1008 39 | AUDIOHUB_API_ID_AUDIO_PLAYER_SELECT_DELETE = 1009 40 | AUDIOHUB_API_ID_AUDIO_PLAYER_GET_PLAY_MODE = 1010 41 | 42 | # API ID | FUNCTION 43 | # 2001 | upload audio file 44 | 45 | AUDIOHUB_API_ID_AUDIO_PLAYER_UPLOAD_AUDIO_FILE = 2001 46 | 47 | # API ID | FUNCTION 48 | # 3001 | play start_obstacle_avoidance audio 49 | # 3002 | play exit_obstacle_avoidance audio 50 | # 3003 | play start_companion_mode audio 51 | # 3004 | play exit_companion_mode audio 52 | 53 | AUDIOHUB_INTERNAL_CORPUS_BASE = 3000 54 | AUDIOHUB_API_ID_INTERNAL_CORPUS_PLAY_START_OBSTACLE_AVOIDANCE = 1 55 | AUDIOHUB_API_ID_INTERNAL_CORPUS_PLAY_EXIT_OBSTACLE_AVOIDANCE = 2 56 | AUDIOHUB_API_ID_INTERNAL_CORPUS_PLAY_START_COMPANION_MODE = 3 57 | AUDIOHUB_API_ID_INTERNAL_CORPUS_PLAY_EXIT_COMPANION_MODE = 4 58 | 59 | # API ID | FUNCTION 60 | # 4001 | enter megaphone 61 | # 4002 | exit megaphone 62 | # 4003 | upload 63 | 64 | AUDIOHUB_API_ID_ENTER_MEGAPHONE = 4001 65 | AUDIOHUB_API_ID_EXIT_MEGAPHONE = 4002 66 | AUDIOHUB_API_ID_UPLOAD_MEGAPHONE = 4003 67 | 68 | # API ID | FUNCTION 69 | # 5001 Select internal long corpus to play 70 | # 5002 Internal long corpus playback completed notification 71 | # 5003 Stops playing current internal long corpus 72 | 73 | AUDIOHUB_API_ID_INTERNAL_LONG_CORPUS_SELECT_TO_PLAY = 5001 74 | AUDIOHUB_API_ID_INTERNAL_LONG_CORPUS_PLAYBACK_COMPLETED = 5002 75 | AUDIOHUB_API_ID_INTERNAL_LONG_CORPUS_STOP_PLAYING = 5003 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /unitree_sdk2py/rpc/client_stub.py: -------------------------------------------------------------------------------- 1 | import time 2 | 3 | from enum import Enum 4 | from threading import Thread, Condition 5 | 6 | from ..core.channel_name import ChannelType, GetClientReqResChannelName 7 | from .request_future import RequestFuture, RequestFutureQueue 8 | 9 | import logging 10 | 11 | """ 12 | " class ClientStub 13 | """ 14 | class ClientStub: 15 | def __init__(self, communicator, serviceName: str, logger: logging.Logger = None): 16 | self.logger = logger.getChild(self.__class__.__name__) if logger else logging.getLogger(self.__class__.__name__) 17 | self.__serviceName = serviceName 18 | self.__futureQueue = None 19 | 20 | self.__sendChannel = None 21 | self.__recvChannel = None 22 | self.__communicator = communicator 23 | 24 | def Init(self): 25 | factory = self.__communicator.ChannelFactory() 26 | self.__futureQueue = RequestFutureQueue() 27 | 28 | self.Request = factory.dataclass.get_data_class('Request_') 29 | self.Response = factory.dataclass.get_data_class('Response_') 30 | 31 | # create channel 32 | self.__sendChannel = factory.CreateSendChannel(GetClientReqResChannelName(factory.channel_name, self.__serviceName, ChannelType.SEND), self.Request) 33 | self.__recvChannel = factory.CreateRecvChannel(GetClientReqResChannelName(factory.channel_name, self.__serviceName, ChannelType.RECV), self.Response, 34 | self.__ResponseHandler,10) 35 | time.sleep(0.5) 36 | 37 | 38 | def Send(self, request, timeout: float): 39 | if self.__sendChannel.Write(request, timeout): 40 | return True 41 | else: 42 | self.logger.error("[ClientStub] send error. id: %s", request.header.identity.id) 43 | return False 44 | 45 | def SendRequest(self, request, timeout: float): 46 | id = request.header.identity.id 47 | 48 | future = RequestFuture() 49 | future.SetRequestId(id) 50 | self.__futureQueue.Set(id, future) 51 | 52 | if self.__sendChannel.Write(request, timeout): 53 | return future 54 | else: 55 | self.logger.error("[ClientStub] send request error. id: %s", request.header.identity.id) 56 | self.__futureQueue.Remove(id) 57 | return None 58 | 59 | def RemoveFuture(self, requestId: int): 60 | self.__futureQueue.Remove(requestId) 61 | 62 | def __ResponseHandler(self, response): 63 | id = response.header.identity.id 64 | # apiId = response.header.identity.api_id 65 | # self.logger.info("[ClientStub] responseHandler recv response id:", id, ", apiId:", apiId) 66 | future = self.__futureQueue.Get(id) 67 | if future is None: 68 | # self.logger.error("[ClientStub] get future from queue error. id:", id) 69 | pass 70 | elif not future.Ready(response): 71 | self.logger.error("[ClientStub] set future ready error.") 72 | -------------------------------------------------------------------------------- /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.dds.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.dds.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 | -------------------------------------------------------------------------------- /unitree_sdk2py/rpc/client.py: -------------------------------------------------------------------------------- 1 | from .client_base import ClientBase 2 | from .lease_client import LeaseClient 3 | from .internal import * 4 | import logging 5 | 6 | """ 7 | " class Client 8 | """ 9 | class Client(ClientBase): 10 | def __init__(self, communicator, serviceName: str, enabaleLease: bool = False, logger: logging.Logger = None): 11 | self.logger = logger.getChild(self.__class__.__name__) if logger else logging.getLogger(self.__class__.__name__) 12 | super().__init__(communicator, serviceName, self.logger) 13 | 14 | self.__apiMapping = {} 15 | self.__apiVersion = None 16 | self.__leaseClient = None 17 | self.__enableLease = enabaleLease 18 | 19 | if (self.__enableLease): 20 | self.__leaseClient = LeaseClient(communicator, serviceName, self.logger) 21 | self.__leaseClient.Init() 22 | 23 | def WaitLeaseApplied(self): 24 | if self.__enableLease: 25 | self.__leaseClient.WaitApplied() 26 | 27 | def GetLeaseId(self): 28 | if self.__enableLease: 29 | return self.__leaseClient.GetId() 30 | else: 31 | return None 32 | 33 | def GetApiVersion(self): 34 | return self.__apiVersion 35 | 36 | def GetServerApiVersion(self): 37 | code, apiVerson = self._CallBase(RPC_API_ID_INTERNAL_API_VERSION, "{}", 0, 0) 38 | if code != 0: 39 | self.logger.error(f"[Client] get server api version error: {code}") 40 | return code, None 41 | else: 42 | return code, apiVerson 43 | 44 | def _SetApiVerson(self, apiVersion: str): 45 | self.__apiVersion = apiVersion 46 | 47 | def _Call(self, apiId: int, parameter: str): 48 | ret, proirity, leaseId = self.__CheckApi(apiId) 49 | if ret == 0: 50 | return self._CallBase(apiId, parameter, proirity, leaseId) 51 | else: 52 | return RPC_ERR_CLIENT_API_NOT_REG, None 53 | 54 | def _CallNoReply(self, apiId: int, parameter: str): 55 | ret, proirity, leaseId = self.__CheckApi(apiId) 56 | if ret == 0: 57 | return self._CallNoReplyBase(apiId, parameter, proirity, leaseId) 58 | else: 59 | return RPC_ERR_CLIENT_API_NOT_REG 60 | 61 | def _CallBinary(self, apiId: int, parameter: list): 62 | ret, proirity, leaseId = self.__CheckApi(apiId) 63 | if ret == 0: 64 | return self._CallBinaryBase(apiId, parameter, proirity, leaseId) 65 | else: 66 | return RPC_ERR_CLIENT_API_NOT_REG, None 67 | 68 | def _CallBinaryNoReply(self, apiId: int, parameter: list): 69 | ret, proirity, leaseId = self.__CheckApi(apiId) 70 | if ret == 0: 71 | return self._CallBinaryNoReplyBase(apiId, parameter, proirity, leaseId) 72 | else: 73 | return RPC_ERR_CLIENT_API_NOT_REG 74 | 75 | def _RegistApi(self, apiId: int, proirity: int): 76 | self.__apiMapping[apiId] = proirity 77 | 78 | def __CheckApi(self, apiId: int): 79 | proirity = 0 80 | leaseId = 0 81 | 82 | if apiId > RPC_INTERNAL_API_ID_MAX: 83 | proirity = self.__apiMapping.get(apiId) 84 | 85 | if proirity is None: 86 | return RPC_ERR_CLIENT_API_NOT_REG, proirity, leaseId 87 | 88 | if self.__enableLease: 89 | leaseId = self.__leaseClient.GetId() 90 | 91 | return 0, proirity, leaseId -------------------------------------------------------------------------------- /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 -------------------------------------------------------------------------------- /unitree_sdk2py/go2/vui/vui_client.py: -------------------------------------------------------------------------------- 1 | import json 2 | 3 | from ...rpc.client import Client 4 | from .vui_api import * 5 | import logging 6 | 7 | 8 | """ 9 | " class VideoClient 10 | """ 11 | class VuiClient(Client): 12 | default_service_name = VUI_SERVICE_NAME 13 | 14 | def __init__(self, communicator, logger: logging.Logger = None, *args, **kwargs): 15 | self.service_name = VuiClient.default_service_name 16 | self.logger = logger.getChild(self.__class__.__name__) if logger else logging.getLogger(self.__class__.__name__) 17 | super().__init__(communicator=communicator, serviceName=self.service_name, enabaleLease=False, logger=self.logger) 18 | 19 | def Init(self): 20 | # set api version 21 | self._SetApiVerson(VUI_API_VERSION) 22 | # regist api 23 | self._RegistApi(VUI_API_ID_SETSWITCH, 0) 24 | self._RegistApi(VUI_API_ID_GETSWITCH, 0) 25 | self._RegistApi(VUI_API_ID_SETVOLUME, 0) 26 | self._RegistApi(VUI_API_ID_GETVOLUME, 0) 27 | self._RegistApi(VUI_API_ID_SETBRIGHTNESS, 0) 28 | self._RegistApi(VUI_API_ID_GETBRIGHTNESS, 0) 29 | self._RegistApi(VUI_API_ID_LED_SET, 0) 30 | self._RegistApi(VUI_API_ID_LED_QUIT, 0) 31 | 32 | # 1001 33 | def SetSwitch(self, enable: int): 34 | p = {} 35 | p["enable"] = enable 36 | parameter = json.dumps(p) 37 | 38 | code, data = self._Call(VUI_API_ID_SETSWITCH, parameter) 39 | return code 40 | 41 | # 1002 42 | def GetSwitch(self): 43 | p = {} 44 | parameter = json.dumps(p) 45 | 46 | code, data = self._Call(VUI_API_ID_GETSWITCH, parameter) 47 | if code == 0: 48 | d = json.loads(data) 49 | return code, d["enable"] 50 | else: 51 | return code, None 52 | 53 | # 1003 54 | def SetVolume(self, level: int): 55 | p = {} 56 | p["volume"] = level 57 | parameter = json.dumps(p) 58 | 59 | code, data = self._Call(VUI_API_ID_SETVOLUME, parameter) 60 | return code 61 | 62 | # 1006 63 | def GetVolume(self): 64 | p = {} 65 | parameter = json.dumps(p) 66 | 67 | code, data = self._Call(VUI_API_ID_GETVOLUME, parameter) 68 | if code == 0: 69 | d = json.loads(data) 70 | return code, d["volume"] 71 | else: 72 | return code, None 73 | 74 | # 1005 75 | def SetBrightness(self, level: int): 76 | p = {} 77 | p["brightness"] = level 78 | parameter = json.dumps(p) 79 | 80 | code, data = self._Call(VUI_API_ID_SETBRIGHTNESS, parameter) 81 | return code 82 | 83 | # 1006 84 | def GetBrightness(self): 85 | p = {} 86 | parameter = json.dumps(p) 87 | 88 | code, data = self._Call(VUI_API_ID_GETBRIGHTNESS, parameter) 89 | if code == 0: 90 | d = json.loads(data) 91 | return code, d["brightness"] 92 | else: 93 | return code, None 94 | 95 | # 1007 96 | def SetLed(self, color: VUI_COLOR, time=5, flash_cycle=None): 97 | p = {} 98 | p["color"] = color 99 | p["time"] = time 100 | if flash_cycle: 101 | p["flash_cycle"] = flash_cycle 102 | parameter = json.dumps(p) 103 | code, data = self._Call(VUI_API_ID_LED_SET, parameter) 104 | return code 105 | 106 | # 1008 107 | def QuitLed(self, level: int): 108 | p = {} 109 | parameter = json.dumps(p) 110 | code, data = self._Call(VUI_API_ID_LED_QUIT, parameter) 111 | return code -------------------------------------------------------------------------------- /unitree_sdk2py/rpc/lease_client.py: -------------------------------------------------------------------------------- 1 | import time 2 | import socket 3 | import os 4 | import json 5 | import logging 6 | 7 | from threading import Thread, Lock 8 | 9 | from .client_base import ClientBase 10 | from .internal import * 11 | 12 | 13 | """ 14 | " class LeaseContext 15 | """ 16 | class LeaseContext: 17 | def __init__(self): 18 | self.id = 0 19 | self.term = RPC_LEASE_TERM 20 | 21 | def Update(self, id, term): 22 | self.id = id 23 | self.term = term 24 | 25 | def Reset(self): 26 | self.id = 0 27 | self.term = RPC_LEASE_TERM 28 | 29 | def Valid(self): 30 | return self.id != 0 31 | 32 | 33 | """ 34 | " class LeaseClient 35 | """ 36 | class LeaseClient(ClientBase): 37 | def __init__(self, communicator, name: str, logger: logging.Logger = None): 38 | self.logger = logger.getChild(self.__class__.__name__) if logger else logging.getLogger(self.__class__.__name__) 39 | self.__name = name + "_lease" 40 | self.__contextName = socket.gethostname() + "/" + name + "/" + str(os.getpid()) 41 | self.__context = LeaseContext() 42 | self.__thread = None 43 | self.__lock = Lock() 44 | super().__init__(communicator, self.__name) 45 | self.logger.debug(f"[LeaseClient] lease name: {self.__name}, context name: {self.__contextName}") 46 | 47 | def Init(self): 48 | self.SetTimeout(1.0) 49 | self.__thread = Thread(target=self.__ThreadFunc, name=self.__name, daemon=True) 50 | self.__thread.start() 51 | 52 | def WaitApplied(self): 53 | while True: 54 | with self.__lock: 55 | if self.__context.Valid(): 56 | break 57 | time.sleep(0.1) 58 | 59 | def GetId(self): 60 | with self.__lock: 61 | return self.__context.id 62 | 63 | def Applied(self): 64 | with self.__lock: 65 | return self.__context.Valid() 66 | 67 | def __Apply(self): 68 | parameter = {} 69 | parameter["name"] = self.__contextName 70 | p = json.dumps(parameter) 71 | 72 | c, d = self._CallBase(RPC_API_ID_LEASE_APPLY, p) 73 | if c != 0: 74 | self.logger.error(f"[LeaseClient] apply lease error. code: {c}") 75 | return 76 | 77 | data = json.loads(d) 78 | 79 | id = data["id"] 80 | term = data["term"] 81 | 82 | self.logger.debug(f"[LeaseClient] lease applied id: {id}, term: {term}") 83 | 84 | with self.__lock: 85 | self.__context.Update(id, float(term/1000000)) 86 | 87 | def __Renewal(self): 88 | parameter = {} 89 | p = json.dumps(parameter) 90 | 91 | c, d = self._CallBase(RPC_API_ID_LEASE_RENEWAL, p, 0, self.__context.id) 92 | if c != 0: 93 | self.logger.error(f"[LeaseClient] renewal lease error. code: {c}") 94 | if c == RPC_ERR_SERVER_LEASE_NOT_EXIST: 95 | with self.__lock: 96 | self.__context.Reset() 97 | 98 | def __GetWaitSec(self): 99 | waitsec = 0.0 100 | if self.__context.Valid(): 101 | waitsec = self.__context.term 102 | 103 | if waitsec <= 0: 104 | waitsec = RPC_LEASE_TERM 105 | 106 | return waitsec * 0.3 107 | 108 | def __ThreadFunc(self): 109 | while True: 110 | if self.__context.Valid(): 111 | self.__Renewal() 112 | else: 113 | self.__Apply() 114 | # sleep waitsec 115 | time.sleep(self.__GetWaitSec()) 116 | -------------------------------------------------------------------------------- /unitree_sdk2py/test/client/sport_client_example.py: -------------------------------------------------------------------------------- 1 | import time 2 | from unitree_sdk2py.core.dds.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 | -------------------------------------------------------------------------------- /unitree_sdk2py/rpc/client_base.py: -------------------------------------------------------------------------------- 1 | import time 2 | 3 | from ..idl.unitree_api.msg.dds_ import Request_ as Request 4 | from ..idl.unitree_api.msg.dds_ import RequestHeader_ as RequestHeader 5 | from ..idl.unitree_api.msg.dds_ import RequestLease_ as RequestLease 6 | from ..idl.unitree_api.msg.dds_ import RequestIdentity_ as RequestIdentity 7 | from ..idl.unitree_api.msg.dds_ import RequestPolicy_ as RequestPolicy 8 | 9 | from ..utils.future import FutureResult 10 | 11 | from .client_stub import ClientStub 12 | from .internal import * 13 | import logging 14 | 15 | 16 | """ 17 | " class ClientBase 18 | """ 19 | class ClientBase: 20 | def __init__(self, comminicator, serviceName: str, logger: logging.Logger = None): 21 | self.logger = logger.getChild(self.__class__.__name__) if logger else logging.getLogger(self.__class__.__name__) 22 | self.__timeout = 1.0 23 | self.__stub = ClientStub(comminicator, serviceName, self.logger) 24 | self.__stub.Init() 25 | 26 | def SetTimeout(self, timeout: float): 27 | self.__timeout = timeout 28 | 29 | def _CallBase(self, apiId: int, parameter: str, proirity: int = 0, leaseId: int = 0): 30 | # self.logger.info("[CallBase] call apiId:", apiId, ", proirity:", proirity, ", leaseId:", leaseId) 31 | header = self.__SetHeader(apiId, leaseId, proirity, False) 32 | request = Request(header, parameter, []) 33 | 34 | future = self.__stub.SendRequest(request, self.__timeout) 35 | if future is None: 36 | return RPC_ERR_CLIENT_SEND, None 37 | 38 | result = future.GetResult(self.__timeout) 39 | 40 | if result.code != FutureResult.FUTURE_SUCC: 41 | self.__stub.RemoveFuture(request.header.identity.id) 42 | code = RPC_ERR_CLIENT_API_TIMEOUT if result.code == FutureResult.FUTUTE_ERR_TIMEOUT else RPC_ERR_UNKNOWN 43 | return code, None 44 | 45 | response = result.value 46 | 47 | if response.header.identity.api_id != apiId: 48 | return RPC_ERR_CLIENT_API_NOT_MATCH, None 49 | else: 50 | return response.header.status.code, response.data 51 | 52 | def _CallNoReplyBase(self, apiId: int, parameter: str, proirity: int, leaseId: int): 53 | header = self.__SetHeader(apiId, leaseId, proirity, True) 54 | request = Request(header, parameter, []) 55 | 56 | if self.__stub.Send(request, self.__timeout): 57 | return 0 58 | else: 59 | return RPC_ERR_CLIENT_SEND 60 | 61 | def _CallBinaryBase(self, apiId: int, parameter: list, proirity: int, leaseId: int): 62 | header = self.__SetHeader(apiId, leaseId, proirity, False) 63 | request = Request(header, "", parameter) 64 | 65 | future = self.__stub.SendRequest(request, self.__timeout) 66 | if future is None: 67 | return RPC_ERR_CLIENT_SEND, None 68 | 69 | result = future.GetResult(self.__timeout) 70 | if result.code != FutureResult.FUTURE_SUCC: 71 | self.__stub.RemoveFuture(request.header.identity.id) 72 | code = RPC_ERR_CLIENT_API_TIMEOUT if result.code == FutureResult.FUTUTE_ERR_TIMEOUT else RPC_ERR_UNKNOWN 73 | return code, None 74 | 75 | response = result.value 76 | 77 | if response.header.identity.api_id != apiId: 78 | return RPC_ERR_CLIENT_API_NOT_MATCH, None 79 | else: 80 | return response.header.status.code, response.binary 81 | 82 | def _CallBinaryNoReplyBase(self, apiId: int, parameter: list, proirity: int, leaseId: int): 83 | header = self.__SetHeader(apiId, leaseId, proirity, True) 84 | request = Request(header, "", parameter) 85 | 86 | if self.__stub.Send(request, self.__timeout): 87 | return 0 88 | else: 89 | return RPC_ERR_CLIENT_SEND 90 | 91 | def __SetHeader(self, apiId: int, leaseId: int, priority: int, noReply: bool): 92 | identity = RequestIdentity(time.monotonic_ns(), apiId) 93 | lease = RequestLease(leaseId) 94 | policy = RequestPolicy(priority, noReply) 95 | return RequestHeader(identity, lease, policy) 96 | -------------------------------------------------------------------------------- /unitree_sdk2py/sdk/sdk.py: -------------------------------------------------------------------------------- 1 | import logging 2 | from ..sdk.robot import Robot 3 | from ..go2.sport.sport_client import SportClient 4 | from ..go2.obstacles_avoid.obstacles_avoid_client import ObstaclesAvoidClient 5 | from ..go2.robot_state.robot_state_client import RobotStateClient 6 | from ..go2.video.video_client import VideoClient 7 | from ..go2.vui.vui_client import VuiClient 8 | from ..go2.motion_switcher.motion_switcher_client import MotionSwitcherClient 9 | from ..go2.audiohub.audiohub_client import AudioHubClient 10 | from ..go2.gpt.gpt_client import GPTClient 11 | 12 | __LOGGER = logging.getLogger(__name__) 13 | 14 | _DEFAULT_SERVICE_CLIENTS = [ 15 | SportClient, 16 | MotionSwitcherClient, 17 | ObstaclesAvoidClient, 18 | RobotStateClient, 19 | # BashRunnerClient, ! 20 | VuiClient, 21 | # HandheldRemoteControllerClient, 22 | # UWBClient, 23 | # LidarClient, 24 | # FaultClient, 25 | # ConfigClient, 26 | # WebRTCClient, 27 | # SLAMClient, 28 | # ArmClient, 29 | GPTClient, 30 | AudioHubClient, 31 | VideoClient 32 | # NetworkClient 33 | ] 34 | 35 | def create_standard_sdk(client_name_prefix, service_clients=None): 36 | __LOGGER.debug("Creating standard SDK") 37 | sdk = Sdk(name=client_name_prefix) 38 | 39 | all_service_clients = list(_DEFAULT_SERVICE_CLIENTS) 40 | if service_clients: 41 | all_service_clients.extend(service_clients) 42 | for client_class in all_service_clients: 43 | sdk.register_service_client(client_class) 44 | return sdk 45 | 46 | class Sdk: 47 | """ 48 | Repository for settings typically common to a single developer and/or robot fleet. 49 | """ 50 | def __init__(self, name=None, logger=None): 51 | self.logger = logger or logging.getLogger(name or self.__class__.__name__) 52 | self.client_name = name 53 | self.service_client_factories_by_name={} 54 | self.robots = {} 55 | 56 | def create_robot(self, communicator, serialNumber=None, name=None): 57 | # Placeholder for implementation to create a robot instance 58 | self.logger.debug(f"Creating robot {serialNumber}") 59 | if not serialNumber: 60 | raise ValueError("Robot serial cannot be None") 61 | 62 | if serialNumber in self.robots: 63 | return self.robots[serialNumber] 64 | 65 | robot = Robot(communicator, serialNumber, name) 66 | 67 | robot.update_from(self) 68 | self.robots[serialNumber] = robot 69 | 70 | return robot 71 | 72 | 73 | def delete_robot(self, name): 74 | """ 75 | Deletes a robot instance from the SDK by its name. 76 | 77 | Args: 78 | name (str): The name of the robot to be deleted. 79 | 80 | Raises: 81 | ValueError: If the name is None or empty. 82 | KeyError: If no robot with the given name exists in the registry. 83 | """ 84 | self.logger.debug(f"Attempting to delete robot {name}") 85 | if not name: 86 | raise ValueError("Robot name cannot be None or empty") # Check for empty string too 87 | 88 | if name in self.robots: 89 | del self.robots[name] 90 | self.logger.debug(f"Robot {name} deleted successfully") 91 | else: 92 | # Optionally raise an error if trying to delete a robot that does not exist 93 | self.logger.error(f"No robot found with the name {name}") 94 | raise KeyError(f"No robot found with the name {name}") 95 | 96 | 97 | def clear_robots(self): 98 | """Remove all cached Robot instances. 99 | Subsequent calls to create_robot() will return newly created Robots. 100 | Existing robot instances will continue to work, but their time sync and token refresh 101 | threads will be stopped. 102 | """ 103 | self.robots = {} 104 | 105 | 106 | def register_service_client(self, client_class): 107 | """Registers a service client in the SDK.""" 108 | service_name = getattr(client_class, 'default_service_name', None) 109 | if service_name and service_name not in self.service_client_factories_by_name: 110 | self.service_client_factories_by_name[service_name] = client_class 111 | self.logger.debug(f"Registered service client factory for {service_name}") 112 | else: 113 | self.logger.warning(f"Service client {service_name} is already registered or has no default service name.") 114 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /unitree_sdk2py/rpc/server.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 ResponseStatus_ as ResponseStatus 7 | from ..idl.unitree_api.msg.dds_ import ResponseHeader_ as ResponseHeader 8 | from ..idl.unitree_api.msg.dds_ import Response_ as Response 9 | 10 | from .server_base import ServerBase 11 | from .lease_server import LeaseServer 12 | from .internal import * 13 | 14 | """ 15 | " class Server 16 | """ 17 | class Server(ServerBase): 18 | def __init__(self, name: str): 19 | self.__apiVersion = "" 20 | self.__apiHandlerMapping = {} 21 | self.__apiBinaryHandlerMapping = {} 22 | self.__apiBinarySet = {} 23 | self.__enableLease = False 24 | self.__leaseServer = None 25 | super().__init__(name) 26 | 27 | def Init(self): 28 | pass 29 | 30 | def StartLease(self, term: float = 1.0): 31 | self.__enableLease = True 32 | self.__leaseServer = LeaseServer(self.GetName(), term) 33 | self.__leaseServer.Init() 34 | self.__leaseServer.Start(False) 35 | 36 | def Start(self, enablePrioQueue: bool = False): 37 | super()._SetServerRequestHandler(self.__ServerRequestHandler) 38 | super()._Start(enablePrioQueue) 39 | 40 | def GetApiVersion(self): 41 | return self.__apiVersion 42 | 43 | def _SetApiVersion(self, apiVersion: str): 44 | self.__apiVersion = apiVersion 45 | print("[Server] set api version:", self.__apiVersion) 46 | 47 | def _RegistHandler(self, apiId: int, handler: Callable, checkLease: bool): 48 | self.__apiHandlerMapping[apiId] = (handler, checkLease) 49 | 50 | def _RegistBinaryHandler(self, apiId: int, handler: Callable, checkLease: bool): 51 | self.__apiBinaryHandlerMapping[apiId] = (handler, checkLease) 52 | self.__apiBinarySet.add(apiId) 53 | 54 | def __GetHandler(self, apiId: int): 55 | if apiId in self.__apiHandlerMapping: 56 | return self.__apiHandlerMapping.get(apiId) 57 | else: 58 | return None, False 59 | 60 | def __GetBinaryHandler(self, apiId: int): 61 | if apiId in self.__apiBinaryHandlerMapping: 62 | return self.__apiBinaryHandlerMapping.get(apiId) 63 | else: 64 | return None, False 65 | 66 | def __IsBinary(self, apiId): 67 | return apiId in self.__apiBinarySet 68 | 69 | def __CheckLeaseDenied(self, leaseId: int): 70 | if (self.__enableLease): 71 | return self.__leaseServer.CheckRequestLeaseDenied(leaseId) 72 | else: 73 | return False 74 | 75 | def __ServerRequestHandler(self, request: Request): 76 | parameter = request.parameter 77 | parameterBinary = request.binary 78 | 79 | identity = request.header.identity 80 | leaseId = request.header.lease.id 81 | apiId = identity.api_id 82 | 83 | code = 0 84 | data = "" 85 | dataBinary = [] 86 | 87 | if apiId == RPC_API_ID_INTERNAL_API_VERSION: 88 | data = self.__apiVersion 89 | else: 90 | requestHandler = None 91 | binaryRequestHandler = None 92 | checkLease = False 93 | 94 | if self.__IsBinary(apiId): 95 | binaryRequestHandler, checkLease = self.__GetBinaryHandler(apiId) 96 | else: 97 | requestHandler, checkLease = self.__GetHandler(apiId) 98 | 99 | if requestHandler is None and binaryRequestHandler is None: 100 | code = RPC_ERR_SERVER_API_NOT_IMPL 101 | elif checkLease and self.__CheckLeaseDenied(leaseId): 102 | code = RPC_ERR_SERVER_LEASE_DENIED 103 | else: 104 | try: 105 | if binaryRequestHandler is None: 106 | code, data = requestHandler(parameter) 107 | if code != 0: 108 | data = "" 109 | else: 110 | code, dataBinary = binaryRequestHandler(parameterBinary) 111 | if code != 0: 112 | dataBinary = [] 113 | except: 114 | code = RPC_ERR_SERVER_INTERNAL 115 | 116 | if request.header.policy.noreply: 117 | return 118 | 119 | status = ResponseStatus(code) 120 | response = Response(ResponseHeader(identity, status), data, dataBinary) 121 | 122 | self._SendResponse(response) -------------------------------------------------------------------------------- /unitree_sdk2py/rpc/lease_server.py: -------------------------------------------------------------------------------- 1 | import time 2 | import json 3 | 4 | from threading import Lock 5 | 6 | from ..idl.unitree_api.msg.dds_ import Request_ as Request 7 | from ..idl.unitree_api.msg.dds_ import ResponseHeader_ as ResponseHeader 8 | from ..idl.unitree_api.msg.dds_ import ResponseStatus_ as ResponseStatus 9 | from ..idl.unitree_api.msg.dds_ import Response_ as Response 10 | 11 | from .internal import * 12 | from .server_base import ServerBase 13 | 14 | 15 | """ 16 | " class LeaseCache 17 | """ 18 | class LeaseCache: 19 | def __init__(self): 20 | self.lastModified = 0 21 | self.id = 0 22 | self.name = None 23 | 24 | def Set(self, id: int, name: str, lastModified: int) : 25 | self.id = id 26 | self.name = name 27 | self.lastModified = lastModified 28 | 29 | def Renewal(self, lastModified: int): 30 | self.lastModified = lastModified 31 | 32 | def Clear(self): 33 | self.id = 0 34 | self.lastModified = 0 35 | self.name = None 36 | 37 | 38 | """ 39 | " class LeaseServer 40 | """ 41 | class LeaseServer(ServerBase): 42 | def __init__(self, name: str, term: float): 43 | self.__term = int(term * 1000000) 44 | self.__lock = Lock() 45 | self.__cache = LeaseCache() 46 | super().__init__(name + "_lease") 47 | 48 | def Init(self): 49 | pass 50 | 51 | def Start(self, enablePrioQueue: bool = False): 52 | super()._SetServerRequestHandler(self.__ServerRequestHandler) 53 | super()._Start(enablePrioQueue) 54 | 55 | def CheckRequestLeaseDenied(self, leaseId: int): 56 | with self.__lock: 57 | if self.__cache.id == 0: 58 | return self.__cache.id != leaseId 59 | 60 | now = self.__Now() 61 | if now > self.__cache.lastModified + self.__term: 62 | self.__cache.Clear() 63 | return False 64 | else: 65 | return self.__cache.id != leaseId 66 | 67 | def __Apply(self, parameter: str): 68 | name = "" 69 | data = "" 70 | 71 | try: 72 | p = json.loads(parameter) 73 | name = p.get("name") 74 | 75 | except: 76 | print("[LeaseServer] apply json loads error. parameter:", parameter) 77 | return RPC_ERR_SERVER_API_PARAMETER, data 78 | 79 | if not name: 80 | name = "anonymous" 81 | 82 | id = 0 83 | lastModified = 0 84 | setted = False 85 | 86 | now = self.__Now() 87 | 88 | with self.__lock: 89 | id = self.__cache.id 90 | lastModified = self.__cache.lastModified 91 | 92 | if id == 0 or now > lastModified + self.__term: 93 | if id != 0: 94 | print("[LeaseServer] id expired:", id, ", name:", self.__cache.name) 95 | 96 | id = self.__GenerateId() 97 | self.__cache.Set(id, name, now) 98 | setted = True 99 | 100 | print("[LeaseServer] id stored:", id, ", name:", name) 101 | 102 | if setted: 103 | d = {} 104 | d["id"] = id 105 | d["term"] = self.__term 106 | data = json.dumps(d) 107 | return 0, data 108 | else: 109 | return RPC_ERR_SERVER_LEASE_EXIST, data 110 | 111 | 112 | def __Renewal(self, id: int): 113 | now = self.__Now() 114 | 115 | with self.__lock: 116 | if self.__cache.id != id: 117 | return RPC_ERR_SERVER_LEASE_NOT_EXIST 118 | 119 | if now > self.__cache.lastModified + self.__term: 120 | self.__cache.Clear() 121 | return RPC_ERR_SERVER_LEASE_NOT_EXIST 122 | else: 123 | self.__cache.Renewal(now) 124 | return 0 125 | 126 | def __ServerRequestHandler(self, request: Request): 127 | identity = request.header.identity 128 | parameter = request.parameter 129 | apiId = identity.api_id 130 | code = RPC_ERR_SERVER_API_NOT_IMPL 131 | data = "" 132 | 133 | if apiId == RPC_API_ID_LEASE_APPLY: 134 | code, data = self.__Apply(parameter) 135 | elif apiId == RPC_API_ID_LEASE_RENEWAL: 136 | code = self.__Renewal(request.header.lease.id) 137 | else: 138 | print("[LeaseServer] api is not implemented. apiId", apiId) 139 | 140 | if request.header.policy.noreply: 141 | return 142 | 143 | status = ResponseStatus(code) 144 | response = Response(ResponseHeader(identity, status), data, []) 145 | self._SendResponse(response) 146 | 147 | def __GenerateId(self): 148 | return self.__Now() 149 | 150 | def __Now(self): 151 | return int(time.time_ns()/1000) -------------------------------------------------------------------------------- /unitree_sdk2py/utils/crc.py: -------------------------------------------------------------------------------- 1 | import struct 2 | import cyclonedds 3 | import cyclonedds.idl as idl 4 | 5 | from .singleton import Singleton 6 | from ..idl.unitree_go.msg.dds_ import LowCmd_ as LowCmd 7 | from ..idl.unitree_go.msg.dds_ import LowState_ as LowState 8 | 9 | class CRC(Singleton): 10 | def __init__(self): 11 | #4 bytes aligned, little-endian format. 12 | #size 812 13 | self.__packFmtLowCmd = '<4B4IH2x' + 'B3x5f3I' * 20 + '4B' + '55Bx2I' 14 | #size 1180 15 | self.__packFmtLowState = '<4B4IH2x' + '13fb3x' + 'B3x7fb3x3I' * 20 + '4BiH4b15H' + '8hI41B3xf2b2x2f4h2I' 16 | 17 | def Crc(self, msg: idl.IdlStruct): 18 | if msg.__idl_typename__ == 'unitree_go.msg.dds_.LowCmd_': 19 | return self.__Crc32(self.__PackLowCmd(msg)) 20 | elif msg.__idl_typename__ == 'unitree_go.msg.dds_.LowState_': 21 | return self.__Crc32(self.__PackLowState(msg)) 22 | else: 23 | raise TypeError('unknown IDL message type to crc') 24 | 25 | def __PackLowCmd(self, cmd: LowCmd): 26 | origData = [] 27 | origData.extend(cmd.head) 28 | origData.append(cmd.level_flag) 29 | origData.append(cmd.frame_reserve) 30 | origData.extend(cmd.sn) 31 | origData.extend(cmd.version) 32 | origData.append(cmd.bandwidth) 33 | 34 | for i in range(20): 35 | origData.append(cmd.motor_cmd[i].mode) 36 | origData.append(cmd.motor_cmd[i].q) 37 | origData.append(cmd.motor_cmd[i].dq) 38 | origData.append(cmd.motor_cmd[i].tau) 39 | origData.append(cmd.motor_cmd[i].kp) 40 | origData.append(cmd.motor_cmd[i].kd) 41 | origData.extend(cmd.motor_cmd[i].reserve) 42 | 43 | origData.append(cmd.bms_cmd.off) 44 | origData.extend(cmd.bms_cmd.reserve) 45 | 46 | origData.extend(cmd.wireless_remote) 47 | origData.extend(cmd.led) 48 | origData.extend(cmd.fan) 49 | origData.append(cmd.gpio) 50 | origData.append(cmd.reserve) 51 | origData.append(cmd.crc) 52 | 53 | return self.__Trans(struct.pack(self.__packFmtLowCmd, *origData)) 54 | 55 | def __PackLowState(self, state: LowState): 56 | origData = [] 57 | origData.extend(state.head) 58 | origData.append(state.level_flag) 59 | origData.append(state.frame_reserve) 60 | origData.extend(state.sn) 61 | origData.extend(state.version) 62 | origData.append(state.bandwidth) 63 | 64 | origData.extend(state.imu_state.quaternion) 65 | origData.extend(state.imu_state.gyroscope) 66 | origData.extend(state.imu_state.accelerometer) 67 | origData.extend(state.imu_state.rpy) 68 | origData.append(state.imu_state.temperature) 69 | 70 | for i in range(20): 71 | origData.append(state.motor_state[i].mode) 72 | origData.append(state.motor_state[i].q) 73 | origData.append(state.motor_state[i].dq) 74 | origData.append(state.motor_state[i].ddq) 75 | origData.append(state.motor_state[i].tau_est) 76 | origData.append(state.motor_state[i].q_raw) 77 | origData.append(state.motor_state[i].dq_raw) 78 | origData.append(state.motor_state[i].ddq_raw) 79 | origData.append(state.motor_state[i].temperature) 80 | origData.append(state.motor_state[i].lost) 81 | origData.extend(state.motor_state[i].reserve) 82 | 83 | origData.append(state.bms_state.version_high) 84 | origData.append(state.bms_state.version_low) 85 | origData.append(state.bms_state.status) 86 | origData.append(state.bms_state.soc) 87 | origData.append(state.bms_state.current) 88 | origData.append(state.bms_state.cycle) 89 | origData.extend(state.bms_state.bq_ntc) 90 | origData.extend(state.bms_state.mcu_ntc) 91 | origData.extend(state.bms_state.cell_vol) 92 | 93 | origData.extend(state.foot_force) 94 | origData.extend(state.foot_force_est) 95 | origData.append(state.tick) 96 | origData.extend(state.wireless_remote) 97 | origData.append(state.bit_flag) 98 | origData.append(state.adc_reel) 99 | origData.append(state.temperature_ntc1) 100 | origData.append(state.temperature_ntc2) 101 | origData.append(state.power_v) 102 | origData.append(state.power_a) 103 | origData.extend(state.fan_frequency) 104 | origData.append(state.reserve) 105 | origData.append(state.crc) 106 | 107 | return self.__Trans(struct.pack(self.__packFmtLowState, *origData)) 108 | 109 | def __Trans(self, packData): 110 | calcData = [] 111 | calcLen = ((len(packData)>>2)-1) 112 | 113 | for i in range(calcLen): 114 | d = ((packData[i*4+3] << 24) | (packData[i*4+2] << 16) | (packData[i*4+1] << 8) | (packData[i*4])) 115 | calcData.append(d) 116 | 117 | return calcData 118 | 119 | def __Crc32(self, data): 120 | bit = 0 121 | crc = 0xFFFFFFFF 122 | polynomial = 0x04c11db7 123 | 124 | for i in range(len(data)): 125 | bit = 1 << 31 126 | current = data[i] 127 | 128 | for b in range(32): 129 | if crc & 0x80000000: 130 | crc = (crc << 1) & 0xFFFFFFFF 131 | crc ^= polynomial 132 | else: 133 | crc = (crc << 1) & 0xFFFFFFFF 134 | 135 | if current & bit: 136 | crc ^= polynomial 137 | 138 | bit >>= 1 139 | 140 | return crc 141 | -------------------------------------------------------------------------------- /unitree_sdk2py/idl/idl_dataclass.py: -------------------------------------------------------------------------------- 1 | from typing import Type, cast, Any 2 | import importlib 3 | 4 | import cyclonedds.idl._type_helper as _th 5 | 6 | import dataclasses 7 | import typing 8 | import logging 9 | 10 | 11 | class IDLDataClass: 12 | _data_class_cache = {} 13 | _path = 'unitree_sdk2py.idl' 14 | 15 | unitree_api = { 16 | 'Request_': f'{_path}.unitree_api.msg.dds_', 17 | 'RequestHeader_': f'{_path}.unitree_api.msg.dds_', 18 | 'RequestIdentity_': f'{_path}.unitree_api.msg.dds_', 19 | 'RequestLease_': f'{_path}.unitree_api.msg.dds_', 20 | 'RequestPolicy_': f'{_path}.unitree_api.msg.dds_', 21 | 'Response_': f'{_path}.unitree_api.msg.dds_', 22 | 'ResponseHeader_': f'{_path}.unitree_api.msg.dds_', 23 | 'ResponseStatus_': f'{_path}.unitree_api.msg.dds_', 24 | } 25 | 26 | 27 | unitree_go = { 28 | 'AudioData_': f'{_path}.unitree_go.msg.dds_', 29 | 'BmsCmd_': f'{_path}.unitree_go.msg.dds_', 30 | 'BmsState_': f'{_path}.unitree_go.msg.dds_', 31 | 'Error_': f'{_path}.unitree_go.msg.dds_', 32 | 'Go2FrontVideoData_': f'{_path}.unitree_go.msg.dds_', 33 | 'HeightMap_': f'{_path}.unitree_go.msg.dds_', 34 | 'IMUState_': f'{_path}.unitree_go.msg.dds_', 35 | 'InterfaceConfig_': f'{_path}.unitree_go.msg.dds_', 36 | 'LidarState_': f'{_path}.unitree_go.msg.dds_', 37 | 'LowCmd_': f'{_path}.unitree_go.msg.dds_', 38 | 'LowState_': f'{_path}.unitree_go.msg.dds_', 39 | 'MotorCmd_': f'{_path}.unitree_go.msg.dds_', 40 | 'MotorState_': f'{_path}.unitree_go.msg.dds_', 41 | 'PathPoint_': f'{_path}.unitree_go.msg.dds_', 42 | 'Req_': f'{_path}.unitree_go.msg.dds_', 43 | 'Res_': f'{_path}.unitree_go.msg.dds_', 44 | 'SportModeCmd_': f'{_path}.unitree_go.msg.dds_', 45 | 'SportModeState_': f'{_path}.unitree_go.msg.dds_', 46 | 'TimeSpec_': f'{_path}.unitree_go.msg.dds_', 47 | 'UwbState_': f'{_path}.unitree_go.msg.dds_', 48 | 'UwbSwitch_': f'{_path}.unitree_go.msg.dds_', 49 | 'WirelessController_': f'{_path}.unitree_go.msg.dds_', 50 | } 51 | 52 | 53 | std_msgs = { 54 | 'Header_': f'{_path}.std_msgs.msg.dds_', 55 | 'String_': f'{_path}.std_msgs.msg.dds_', 56 | } 57 | 58 | 59 | geometry_msgs = { 60 | 'Point32_': f'{_path}.geometry_msgs.msg.dds_', 61 | 'Point_': f'{_path}.geometry_msgs.msg.dds_', 62 | 'PointStamped_': f'{_path}.geometry_msgs.msg.dds_', 63 | 'Pose2D_': f'{_path}.geometry_msgs.msg.dds_', 64 | 'Pose_': f'{_path}.geometry_msgs.msg.dds_', 65 | 'PoseStamped_': f'{_path}.geometry_msgs.msg.dds_', 66 | 'PoseWithCovariance_': f'{_path}.geometry_msgs.msg.dds_', 67 | 'PoseWithCovarianceStamped_': f'{_path}.geometry_msgs.msg.dds_', 68 | 'Quaternion_': f'{_path}.geometry_msgs.msg.dds_', 69 | 'QuaternionStamped_': f'{_path}.geometry_msgs.msg.dds_', 70 | 'Twist_': f'{_path}.geometry_msgs.msg.dds_', 71 | 'TwistStamped_': f'{_path}.geometry_msgs.msg.dds_', 72 | 'TwistWithCovariance_': f'{_path}.geometry_msgs.msg.dds_', 73 | 'TwistWithCovarianceStamped_': f'{_path}.geometry_msgs.msg.dds_', 74 | 'Vector3_': f'{_path}.geometry_msgs.msg.dds_', 75 | } 76 | 77 | builtin_interfaces = { 78 | 'Time_': f'{_path}.builtin_interfaces.msg.dds_', 79 | } 80 | 81 | nav_msgs = { 82 | 'MapMetaData_': f'{_path}.nav_msgs.msg.dds_', 83 | 'OccupancyGrid_': f'{_path}.nav_msgs.msg.dds_', 84 | 'Odometry_': f'{_path}.nav_msgs.msg.dds_', 85 | } 86 | 87 | sensor_msgs = { 88 | 'PointCloud2_': f'{_path}.sensor_msgs.msg.dds_', 89 | 'PointField_': f'{_path}.sensor_msgs.msg.dds_', 90 | } 91 | 92 | @classmethod 93 | def get_package_path(cls, class_name): 94 | for category in [cls.unitree_api, cls.unitree_go, cls.std_msgs, cls.geometry_msgs, cls.builtin_interfaces, cls.nav_msgs, cls.sensor_msgs]: 95 | if class_name in category: 96 | return category[class_name] 97 | return None 98 | 99 | @classmethod 100 | def get_data_class(cls, class_name): 101 | """ 102 | Dynamically imports and returns a data class based on its name. 103 | """ 104 | if class_name in cls._data_class_cache: 105 | return cls._data_class_cache[class_name] 106 | 107 | module_name = cls.get_package_path(class_name) 108 | if not module_name: 109 | raise ImportError(f"No module found for class {class_name}") 110 | 111 | module = importlib.import_module(module_name) 112 | data_class = getattr(module, class_name, None) 113 | if not data_class: 114 | raise ImportError(f"Class {class_name} not found in module {module_name}") 115 | 116 | cls._data_class_cache[class_name] = data_class 117 | return cast(Type[Any], data_class) 118 | 119 | 120 | 121 | def create_zeroed_dataclass(self, cls: type) -> any: 122 | """Create an instance of a dataclass with all fields set to default 'zero' values based on their type.""" 123 | field_defaults = {} 124 | for field in dataclasses.fields(cls): 125 | field_type = field.type 126 | 127 | # Get the base type and annotations if it's an annotated type 128 | if _th.get_origin(field_type) is _th.Annotated: 129 | base_type, *annotations = _th.get_args(field_type) 130 | custom_type = annotations[0] if annotations else base_type 131 | else: 132 | base_type, custom_type = field_type, field_type 133 | 134 | # Debugging 135 | # print(f"Zero out Field: {field.name}, Base type: {base_type}, Custom type: {custom_type}, misc: {base_type}") 136 | 137 | #check if the field is array 138 | if base_type is int: 139 | default_value = 0 140 | elif base_type is float: 141 | default_value = 0.0 142 | elif isinstance(base_type, str): 143 | #Check if we have dataclass instance, Idn why the dataclass name goes as a string, a bit confusing 144 | dataclass_name = base_type.rsplit('.', 1)[-1] 145 | dataclass_factory = self.get_data_class(dataclass_name) 146 | default_value = self.create_zeroed_dataclass(dataclass_factory) 147 | 148 | elif issubclass(_th.get_origin(base_type), typing.Sequence): 149 | 150 | custom_element_subtype = custom_type.subtype 151 | custom_element_length = custom_type.length 152 | element_type = _th.get_args(base_type)[0] 153 | 154 | if _th.get_origin(element_type) is _th.Annotated: 155 | element_type = _th.get_args(element_type)[0] 156 | 157 | # print (f"ARRAY: element_type: {element_type}, length: {custom_element_length}") 158 | 159 | if element_type is int: 160 | element_default = [0 for _ in range(custom_element_length)] 161 | default_value = element_default 162 | elif element_type is float: 163 | element_default = [0.0 for _ in range(custom_element_length)] 164 | default_value = element_default 165 | elif isinstance(base_type, str): 166 | element_default = ["" for _ in range(custom_element_length)] 167 | default_value = element_default 168 | 169 | #this part will recursively zero out the included dataclasses 170 | elif isinstance(element_type, typing.ForwardRef): 171 | print(type(custom_element_subtype)) 172 | # dataclass_name = custom_element_subtype.rsplit('.', 1)[-1] 173 | # dataclass_factory = self.get_data_class(dataclass_name) 174 | dataclass_factory = custom_element_subtype 175 | default_value = [self.create_zeroed_dataclass(dataclass_factory) for _ in range(custom_element_length)] 176 | else: 177 | default_value= None 178 | 179 | field_defaults[field.name] = default_value 180 | 181 | return cls(**field_defaults) 182 | 183 | 184 | --------------------------------------------------------------------------------