├── .gitignore ├── LICENSE ├── README.md ├── clients ├── __init__.py ├── motion_switcher_client.py └── sport_client.py ├── communicator ├── __init__.py ├── communicatorWrapper.py ├── constants.py ├── cyclonedds │ ├── cyclonedds.xml │ └── ddsCommunicator.py ├── idl │ ├── __init__.py │ ├── builtin_interfaces │ │ ├── .idlpy_manifest │ │ ├── __init__.py │ │ └── msg │ │ │ ├── .idlpy_manifest │ │ │ ├── __init__.py │ │ │ └── dds_ │ │ │ ├── .idlpy_manifest │ │ │ ├── _Time_.py │ │ │ └── __init__.py │ ├── geometry_msgs │ │ ├── .idlpy_manifest │ │ ├── __init__.py │ │ └── msg │ │ │ ├── .idlpy_manifest │ │ │ ├── __init__.py │ │ │ └── dds_ │ │ │ ├── .idlpy_manifest │ │ │ ├── _Point32_.py │ │ │ ├── _PointStamped_.py │ │ │ ├── _Point_.py │ │ │ ├── _Pose2D_.py │ │ │ ├── _PoseStamped_.py │ │ │ ├── _PoseWithCovarianceStamped_.py │ │ │ ├── _PoseWithCovariance_.py │ │ │ ├── _Pose_.py │ │ │ ├── _QuaternionStamped_.py │ │ │ ├── _Quaternion_.py │ │ │ ├── _TwistStamped_.py │ │ │ ├── _TwistWithCovarianceStamped_.py │ │ │ ├── _TwistWithCovariance_.py │ │ │ ├── _Twist_.py │ │ │ ├── _Vector3_.py │ │ │ └── __init__.py │ ├── std_msgs │ │ ├── .idlpy_manifest │ │ ├── __init__.py │ │ └── msg │ │ │ ├── .idlpy_manifest │ │ │ ├── __init__.py │ │ │ └── dds_ │ │ │ ├── .idlpy_manifest │ │ │ ├── _Header_.py │ │ │ ├── _String_.py │ │ │ └── __init__.py │ ├── unitree_api │ │ ├── .idlpy_manifest │ │ ├── __init__.py │ │ └── msg │ │ │ ├── .idlpy_manifest │ │ │ ├── __init__.py │ │ │ └── dds_ │ │ │ ├── .idlpy_manifest │ │ │ ├── _RequestHeader_.py │ │ │ ├── _RequestIdentity_.py │ │ │ ├── _RequestLease_.py │ │ │ ├── _RequestPolicy_.py │ │ │ ├── _Request_.py │ │ │ ├── _ResponseHeader_.py │ │ │ ├── _ResponseStatus_.py │ │ │ ├── _Response_.py │ │ │ └── __init__.py │ └── unitree_go │ │ ├── .idlpy_manifest │ │ ├── __init__.py │ │ └── msg │ │ ├── .idlpy_manifest │ │ ├── __init__.py │ │ └── dds_ │ │ ├── .idlpy_manifest │ │ ├── _AudioData_.py │ │ ├── _BmsCmd_.py │ │ ├── _BmsState_.py │ │ ├── _Error_.py │ │ ├── _Go2FrontVideoData_.py │ │ ├── _HeightMap_.py │ │ ├── _IMUState_.py │ │ ├── _InterfaceConfig_.py │ │ ├── _LidarState_.py │ │ ├── _LowCmd_.py │ │ ├── _LowState_.py │ │ ├── _MotorCmd_.py │ │ ├── _MotorState_.py │ │ ├── _PathPoint_.py │ │ ├── _Req_.py │ │ ├── _Res_.py │ │ ├── _SportModeCmd_.py │ │ ├── _SportModeState_.py │ │ ├── _String_.py │ │ ├── _TimeSpec_.py │ │ ├── _Time_.py │ │ ├── _UwbState_.py │ │ ├── _UwbSwitch_.py │ │ ├── _WirelessController_.py │ │ └── __init__.py └── webrtc │ └── webrtcCommunicator.py ├── examples └── high_level │ ├── sportmode_commands_test.py │ ├── sportmode_getstate_test.py │ └── sportmode_swith_test.py └── requirements.txt /.gitignore: -------------------------------------------------------------------------------- 1 | RE/ 2 | __pycache__/ 3 | test/ 4 | log/ 5 | trajectory_follow.py 6 | basic_client.py -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 2-Clause License 2 | 3 | Copyright (c) 2024, Konstantin Severov 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 19 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 22 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Unofficial Python SDK for Unitree Go2 2 | 3 | This is an unofficial Python SDK designed to interface with the Unitree Go2 robots, supporting various models including AIR, PRO, and EDU. It provides a high-level API for interacting with the robots using CycloneDDS middleware or WebRTC, ensuring broad compatibility and easy integration. Note that WebRTC is not yet implemented. 4 | 5 | ### CycloneDDS Driver(Implemented) 6 | 7 | CycloneDDS is an open-source implementation of the Data Distribution Service (DDS) standard, which is a middleware protocol used by Unitree Go2. 8 | 9 | * CycloneDDS works out of the box only with the EDU version. 10 | * For use with AIR/PRO models, a custom firmware upgrade is required. Please visit theroboverse.com and our Discord group for more details. 11 | 12 | ### WebRTC Driver (Not yet implemented) 13 | 14 | WebRTC (Web Real-Time Communication) is an open-source project and technology that enables real-time communication of audio, video, and data directly within web browsers and mobile applications. Internally, the robot includes a webrtc_bridge that converts WebRTC to DDS. The Unitree Go2 app uses WebRTC as a transport layer. 15 | 16 | * Works with AIR, PRO, and EDU models out of the box, but is limited to topics when publishing/subscribing. For example, low-level commands would not work fully as rt/lowcmd is not supported. Reading is only supported through rt/lf/lowstate (lf for low frequency). 17 | 18 | 19 | ## Features 20 | 21 | - **Multiple Client Support**: Includes `sport_client`, `basic_client`, `vui_client`, `robotstate_client`, and `lidar_client` to cover a wide range of functionalities. 22 | - **Compatibility**: Works with AIR, PRO, and EDU models, ensuring a broad usage scope. 23 | - **Flexible Communication**: Supports cycloneDDS middleware and Webrtc for communication, providing options based on your project needs. 24 | 25 | ## Roadmap 26 | 27 | - [x] `sport_client` - Control and manage robot movements. 28 | - [x] `motion_swither_client` - Support for switching between normal and advanced sport modes 29 | - [ ] `basic_client` - Support for lowlevel commands. 30 | - [ ] `vui_client` - Voice control interfaces. 31 | - [ ] `robotstate_client` - Stop/launch robot services . 32 | - [ ] `audio_client` - Audio interfaces. 33 | - [ ] `photo_client` - Photo interfaces. 34 | - [ ] `lidar_client` - Interface with the robot's LiDAR system for mapping and navigation. 35 | 36 | ### Installation 37 | 38 | Follow these step-by-step instructions to install the SDK: 39 | 40 | ```bash 41 | git clone https://github.com/legion1581/go2_python_sdk.git 42 | cd go2_python_sdk 43 | pip install -r requirements.txt 44 | ``` 45 | 46 | ### Thanks 47 | 48 | To TheRoboVerse community! Visit us at theroboverse.com for more information and support. -------------------------------------------------------------------------------- /clients/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/legion1581/go2_python_sdk/72be31ea45a3d1831c7c795a56219587d898e110/clients/__init__.py -------------------------------------------------------------------------------- /clients/motion_switcher_client.py: -------------------------------------------------------------------------------- 1 | import json 2 | import logging 3 | from communicator.constants import SPORT_MODE_SWITCH_API_ID 4 | 5 | logger = logging.getLogger(__name__) 6 | 7 | class MotionSwitcher: 8 | """ 9 | SportModeSwitcher: This class manages switching the high-level operational mode between normal and advanced. 10 | Certain maneuvers like Handstand, CrossStep, OnesidedStep, and Bound are only supported in the advanced mode, 11 | which requires firmware version 1.0.23 or later. 12 | """ 13 | def __init__(self, communicator): 14 | self.communicator = communicator 15 | self.sport_topic = self.communicator.get_topic_by_name("SPORT_MODE_SWITCHER") 16 | 17 | async def doRequest(self, api_id, parameter=None, priority=0, noreply=False): 18 | requestData = { 19 | 'api_id': api_id, 20 | 'parameter': parameter, 21 | 'priority': priority, 22 | 'noreply': noreply 23 | } 24 | 25 | # Send the request and wait for a response if noreply is False 26 | response = await self.communicator.publishReq(self.sport_topic, requestData, timeout=2) 27 | 28 | # If noreply is True, just indicate that the request was sent 29 | if noreply: 30 | logger.info("Request sent with no reply expected.") 31 | return True 32 | 33 | # For reply-expected requests, directly return the response which is either None or contains the response data 34 | return response 35 | 36 | async def getSportMode(self): 37 | """ 38 | Retrieve the current sport mode from the device and parse the mode details. 39 | """ 40 | action_id = SPORT_MODE_SWITCH_API_ID["GetMode"] 41 | response = await self.doRequest(action_id, noreply=False) 42 | parsed_parameters = {} 43 | 44 | if response: 45 | try: 46 | # Parse the JSON string within the 'data' attribute of the response 47 | response_data = json.loads(response.data) 48 | 49 | # Extract the 'form' and 'name' parameters 50 | parsed_parameters['form'] = response_data.get('form') 51 | parsed_parameters['name'] = response_data.get('name') 52 | 53 | logger.info(f"Successfully retrieved sport mode: {parsed_parameters}") 54 | return parsed_parameters 55 | except json.JSONDecodeError as e: 56 | logger.error(f"Failed to parse response data: {e}") 57 | raise Exception(f"Failed to parse response data: {e}") 58 | else: 59 | logger.error("Failed to retrieve state or no response received.") 60 | return None 61 | 62 | async def setSportMode(self, mode): 63 | """ 64 | Sends a request to set the sport mode of the device. 65 | Args: 66 | mode (str): The desired sport mode (e.g., 'normal', 'advanced'). 67 | Returns: 68 | bool: True if the command was successful, False otherwise. 69 | """ 70 | # Retrieve the API ID for setting the sport mode 71 | action_id = SPORT_MODE_SWITCH_API_ID["SetMode"] 72 | 73 | # Prepare the parameter to be sent; specify the mode name 74 | para = {"name": mode} 75 | 76 | # Send the request to the device and await the response 77 | response = await self.doRequest(action_id, parameter=para, noreply=False) 78 | 79 | # Check if the response was successful 80 | if response: 81 | # Log success with the action ID and mode set 82 | logger.info(f"Command to set mode to '{mode}' with api_id: {action_id} succeeded.") 83 | return True 84 | else: 85 | # Log failure with the action ID 86 | logger.error(f"Command with api_id: {action_id} failed or no response received.") 87 | return False 88 | 89 | async def releaseSportMode(self, flag=False, ack=False): 90 | """ 91 | Disables both services: advanced_sport and sport_mode, If True then dumps imediatly, otherwise does a soft StandDown movement and proceed 92 | """ 93 | 94 | # Convert the boolean flag to an integer to match the expected data format 95 | flag_int = 1 if flag else 0 96 | 97 | # Prepare the parameter for the control message 98 | para = {'sample': flag_int} 99 | 100 | action_id = SPORT_MODE_SWITCH_API_ID["ReleaseMode"] 101 | 102 | # Send the request to the device and await the response 103 | response = await self.doRequest(action_id, parameter=para, noreply=False) 104 | # Check if the response was successful 105 | if response: 106 | # Log success with the action ID and mode set 107 | logger.info(f"Command with api_id: {action_id} succeeded.") 108 | return True 109 | else: 110 | # Log failure with the action ID 111 | logger.error(f"Command with api_id: {action_id} failed or no response received.") 112 | return False 113 | 114 | async def setSilent(self, flag, ack=False): 115 | """ 116 | Sets the silent mode. If true after the boot up none of the sport services would be launched. Perfect for developing stage 117 | 118 | Args: 119 | flag (bool): True to enable silent mode, False to disable it. 120 | ack (bool): If True, waits for an acknowledgment from the server. 121 | 122 | Returns: 123 | bool: True if the command was successful, False otherwise. 124 | """ 125 | # Convert the boolean flag to an integer to match the expected data format 126 | flag_int = 1 if flag else 0 127 | 128 | # Prepare the parameter for the control message 129 | para = {'silent': flag_int} 130 | 131 | # Retrieve the action ID for the 'SetSilent' command from the API dictionary 132 | action_id = SPORT_MODE_SWITCH_API_ID["SetSilent"] 133 | 134 | # Send the request and check for an acknowledgment if required 135 | response = await self.doRequest(action_id, parameter=para, noreply=not ack) 136 | if response: 137 | # Log success with the action ID 138 | logger.info(f"Silent mode set command with api_id: {action_id} succeeded") 139 | return True 140 | else: 141 | # Log failure with the action ID 142 | logger.error(f"Command with api_id: {action_id} failed or no response received") 143 | return False 144 | 145 | async def getSilent(self): 146 | """ 147 | Retrieves the current state of the silent mode from the device. Have no clue what the silent mode is 148 | """ 149 | action_id = SPORT_MODE_SWITCH_API_ID["GetSilent"] 150 | response = await self.doRequest(action_id, noreply=False) 151 | parsed_parameters = {} 152 | 153 | if response: 154 | try: 155 | # Parse the JSON string within the 'data' attribute of the response 156 | response_data = json.loads(response.data) 157 | 158 | parsed_parameters['silent'] = response_data.get("silent") 159 | 160 | logger.info(f"Successfully retrieved silent mode state: {parsed_parameters}") 161 | return parsed_parameters 162 | 163 | except json.JSONDecodeError as e: 164 | logger.error(f"Failed to parse response data: {e}") 165 | raise Exception(f"Failed to parse response data: {e}") 166 | else: 167 | logger.error("Failed to retrieve silent state or no response received.") 168 | return False -------------------------------------------------------------------------------- /clients/sport_client.py: -------------------------------------------------------------------------------- 1 | import json 2 | import logging 3 | import math 4 | import asyncio 5 | from communicator.constants import SPORT_CLIENT_API_ID, SPORT_MODE_SWITCH_API_ID 6 | from communicator.idl.unitree_go.msg.dds_ import SportModeState_ 7 | 8 | logger = logging.getLogger(__name__) 9 | 10 | ''' 11 | The sport_client is divided into three main components: SportClient, SportState, and SportModeSwitcher. 12 | 13 | - SportClient: This class is used to send high-level commands and actions, as well as to follow trajectories. 14 | - SportState: This class is designed to obtain high-level motion states of the Go2, such as position, speed, and posture. 15 | - SportModeSwitcher: This class manages switching the high-level operational mode between normal and advanced. 16 | Certain maneuvers like Handstand, CrossStep, OnesidedStep, and Bound are only supported in the advanced mode, 17 | which requires firmware version 1.0.23 or later. 18 | ''' 19 | 20 | class SportClient(): 21 | """ 22 | SportClient: This class is used to send high-level commands and actions, as well as to follow trajectories 23 | """ 24 | def __init__(self, communicator): 25 | # Instantiate communication interface (either DDS or WebRTC) 26 | self.communicator = communicator 27 | self.sport_topic = self.communicator.get_topic_by_name("SPORT_MOD") 28 | 29 | async def doRequest(self, api_id, parameter=None, priority=0, noreply=True): 30 | 31 | requestData = { 32 | 'api_id': api_id, 33 | 'parameter': parameter, 34 | 'priority': priority, 35 | 'noreply' : noreply 36 | } 37 | 38 | # Send the request and wait for a response if noreply is False 39 | response = await self.communicator.publishReq(self.sport_topic, requestData, timeout=2) 40 | 41 | # If noreply is True, just indicate that the request was sent 42 | if noreply: 43 | logger.info("Request sent with no reply expected.") 44 | return True 45 | 46 | # For reply-expected requests, directly return the response which is either None or contains the response data 47 | return response 48 | 49 | 50 | async def Damp(self, ack=True): 51 | """ 52 | All motor joints stop moving and enter a damping state. 53 | This mode has the highest priority and is used for emergency stops in unexpected situations 54 | """ 55 | action_id = SPORT_CLIENT_API_ID["Damp"] 56 | response = await self.doRequest(action_id, priority=1, noreply=not ack) 57 | if response: 58 | # Use f-string for variable interpolation 59 | logger.info(f"Command with api_id: {action_id} succeeded") 60 | return True 61 | else: 62 | # Use f-string for variable interpolation 63 | logger.error(f"Command with api_id: {action_id} failed or no response received") 64 | return False 65 | 66 | async def BalanceStand(self, ack=False): 67 | """ 68 | Unlock the joint motor and switch from normal standing mode to balanced standing mode. 69 | In this mode, the attitude and height of the fuselage will always remain balanced, independent of the terrain. 70 | You can control the font and height of the body by calling the Euler() and BodyHeight() 71 | interfaces (see the corresponding section of the table for details) 72 | """ 73 | action_id = SPORT_CLIENT_API_ID["BalanceStand"] 74 | response = await self.doRequest(action_id, noreply=not ack) 75 | if response: 76 | # Use f-string for variable interpolation 77 | logger.info(f"Command with api_id: {action_id} succeeded") 78 | return True 79 | else: 80 | # Use f-string for variable interpolation 81 | logger.error(f"Command with api_id: {action_id} failed or no response received") 82 | return False 83 | 84 | async def StopMove(self, ack=False): 85 | """ 86 | Stop the current motion and restore the internal motion parameters of Go2 to the default values 87 | """ 88 | action_id = SPORT_CLIENT_API_ID["StopMove"] 89 | response = await self.doRequest(action_id, priority=1, noreply=not ack) 90 | if response: 91 | # Use f-string for variable interpolation 92 | logger.info(f"Command with api_id: {action_id} succeeded") 93 | return True 94 | else: 95 | # Use f-string for variable interpolation 96 | logger.error(f"Command with api_id: {action_id} failed or no response received") 97 | return False 98 | 99 | async def StandUp(self, ack=False): 100 | """ 101 | The machine dog is standing tall normally, and the motor joint remains locked. 102 | Compared to the balanced standing mode, the posture of the robotic dog in this mode will not always maintain balance. 103 | The default standing height is 0.33m 104 | """ 105 | action_id = SPORT_CLIENT_API_ID["StandUp"] 106 | response = await self.doRequest(action_id, noreply=not ack) 107 | if response: 108 | # Use f-string for variable interpolation 109 | logger.info(f"Command with api_id: {action_id} succeeded") 110 | return True 111 | else: 112 | # Use f-string for variable interpolation 113 | logger.error(f"Command with api_id: {action_id} failed or no response received") 114 | return False 115 | 116 | async def StandDown(self, ack=False): 117 | """ 118 | The robotic dog lies down and the motor joint remains locked 119 | """ 120 | action_id = SPORT_CLIENT_API_ID["StandDown"] 121 | response = await self.doRequest(action_id, noreply=not ack) 122 | if response: 123 | # Use f-string for variable interpolation 124 | logger.info(f"Command with api_id: {action_id} succeeded") 125 | return True 126 | else: 127 | # Use f-string for variable interpolation 128 | logger.error(f"Command with api_id: {action_id} failed or no response received") 129 | return False 130 | 131 | async def RecoveryStand(self, ack=False): 132 | """ 133 | Restore from a overturned or lying state to a balanced standing state. 134 | Whether it is overturned or not, it will return to standing 135 | """ 136 | action_id = SPORT_CLIENT_API_ID["RecoveryStand"] 137 | response = await self.doRequest(action_id, noreply=not ack) 138 | if response: 139 | # Use f-string for variable interpolation 140 | logger.info(f"Command with api_id: {action_id} succeeded") 141 | return True 142 | else: 143 | # Use f-string for variable interpolation 144 | logger.error(f"Command with api_id: {action_id} failed or no response received") 145 | return False 146 | 147 | async def Euler(self, args, units='degrees', ack=False): 148 | """ 149 | Set the body posture angle for Go2 balance when standing or moving. 150 | The Euler angle is represented by the rotation order around the relative axis of the body and z-y-x 151 | 152 | Parameters: 153 | args (dict): A dictionary containing the roll, pitch, and yaw angles. 154 | - roll: Rotation around the front-to-back axis. 155 | - pitch: Rotation around the side-to-side axis. 156 | - yaw: Rotation around the vertical axis. 157 | units (str): The unit of the angles ('degrees' or 'radians'). Defaults to 'degrees'. 158 | When using radians, the value range is: 159 | - roll: [-0.75, 0.75] 160 | - pitch: [-0.75, 0.75] 161 | - yaw: [-0.6, 0.6] 162 | """ 163 | 164 | # Ensure roll, pitch, and yaw keys exist in args with a default value of 0 if absent 165 | roll = float(args.get('roll', 0)) 166 | pitch = float(args.get('pitch', 0)) 167 | yaw = float(args.get('yaw', 0)) 168 | 169 | # Convert degrees to radians if necessary 170 | if units == 'degrees': 171 | roll = math.radians(roll) 172 | pitch = math.radians(pitch) 173 | yaw = math.radians(yaw) 174 | else: # Validate ranges for radians 175 | if not (-0.75 <= roll <= 0.75): 176 | raise ValueError("Roll angle is out of the valid range [-0.75, 0.75] radians.") 177 | if not (-0.75 <= pitch <= 0.75): 178 | raise ValueError("Pitch angle is out of the valid range [-0.75, 0.75] radians.") 179 | if not (-0.6 <= yaw <= 0.6): 180 | raise ValueError("Yaw angle is out of the valid range [-0.6, 0.6] radians.") 181 | 182 | para = { 183 | 'x': roll, # roll angle in radians 184 | 'y': pitch, # pitch angle in radians 185 | 'z': yaw # yaw angle in radians 186 | } 187 | 188 | action_id = SPORT_CLIENT_API_ID["Euler"] 189 | response = await self.doRequest(action_id, parameter=para, noreply=not ack) 190 | if response: 191 | # Use f-string for variable interpolation 192 | logger.info(f"Command with api_id: {action_id} succeeded") 193 | return True 194 | else: 195 | # Use f-string for variable interpolation 196 | logger.error(f"Command with api_id: {action_id} failed or no response received") 197 | return False 198 | 199 | async def Move(self, args, ack=False): 200 | """ 201 | Control movement speed. The set speed is the speed represented by the body coordinate system 202 | 203 | Parameters: 204 | args (dict): A dictionary containing the x, y, z speeds. 205 | - x: Linear velocity in the x direction (m/s). Value range: [-2.5, 5]. 206 | - y: Linear velocity in the y direction (m/s). Value range: [-2.5, 5]. 207 | - z: Angular velocity around the z-axis (rad/s). Value range: [-4, 4]. 208 | """ 209 | # Ensure x, y, and z keys exist in args with a default value of 0 if absent 210 | x = float(args.get('x', 0)) 211 | y = float(args.get('y', 0)) 212 | z = float(args.get('z', 0)) 213 | 214 | # Validate the speed ranges 215 | if not (-2.5 <= x <= 5): 216 | raise ValueError("x speed is out of the valid range [-2.5, 5].") 217 | if not (-2.5 <= y <= 5): 218 | raise ValueError("y speed is out of the valid range [-2.5, 5].") 219 | if not (-4 <= z <= 4): 220 | raise ValueError("z speed is out of the valid range [-4, 4].") 221 | 222 | # Speed parameters 223 | para = { 224 | 'x': x, # Linear velocity in the x direction 225 | 'y': y, # Linear velocity in the y direction 226 | 'z': z # Angular velocity around the z-axis 227 | } 228 | 229 | action_id = SPORT_CLIENT_API_ID["Move"] 230 | response = await self.doRequest(action_id, parameter=para, noreply=not ack) 231 | if response: 232 | # Use f-string for variable interpolation 233 | logger.info(f"Command with api_id: {action_id} succeeded") 234 | return True 235 | else: 236 | # Use f-string for variable interpolation 237 | logger.error(f"Command with api_id: {action_id} failed or no response received") 238 | return False 239 | 240 | async def Sit(self, ack=False): 241 | """ 242 | Special action, robot dog sitting down. 243 | It should be noted that special actions need to be executed after the previous action is completed, otherwise it may result in abnormal actions 244 | """ 245 | action_id = SPORT_CLIENT_API_ID["Sit"] 246 | response = await self.doRequest(action_id, noreply=not ack) 247 | if response: 248 | # Use f-string for variable interpolation 249 | logger.info(f"Command with api_id: {action_id} succeeded") 250 | return True 251 | else: 252 | # Use f-string for variable interpolation 253 | logger.error(f"Command with api_id: {action_id} failed or no response received") 254 | return False 255 | 256 | async def RiseSit(self, ack=False): 257 | """ 258 | Restore from sitting to balanced standing 259 | """ 260 | action_id = SPORT_CLIENT_API_ID["RiseSit"] 261 | response = await self.doRequest(action_id, noreply=not ack) 262 | if response: 263 | # Use f-string for variable interpolation 264 | logger.info(f"Command with api_id: {action_id} succeeded") 265 | return True 266 | else: 267 | # Use f-string for variable interpolation 268 | logger.error(f"Command with api_id: {action_id} failed or no response received") 269 | return False 270 | 271 | async def SwitchGait(self, d, ack=False): 272 | """ 273 | The forward climbing mode is for the robot to face the stairs, 274 | while the reverse climbing mode is for the robot to face the stairs with its back. 275 | 276 | Parameters: 277 | d (int): Gait enumeration value, with values ranging from 0 to 4, where 278 | 0 is idle, 1 is trot, 2 is trot running, 3 is forward climbing mode, 279 | and 4 is reverse climbing mode. 280 | """ 281 | # Ensure 'd' is within the valid range 282 | if not 0 <= d <= 4: 283 | raise ValueError("Gait enumeration value 'd' must be between 0 and 4.") 284 | 285 | para = {'data': d} 286 | 287 | action_id = SPORT_CLIENT_API_ID["SwitchGait"] 288 | response = await self.doRequest(action_id, parameter=para, noreply=not ack) 289 | if response: 290 | # Use f-string for variable interpolation 291 | logger.info(f"Command with api_id: {action_id} succeeded") 292 | return True 293 | else: 294 | # Use f-string for variable interpolation 295 | logger.error(f"Command with api_id: {action_id} failed or no response received") 296 | return False 297 | 298 | async def Trigger(self, ack=False): 299 | """ 300 | Have no clue what the method does 301 | """ 302 | action_id = SPORT_CLIENT_API_ID["Trigger"] 303 | response = await self.doRequest(action_id, noreply=not ack) 304 | if response: 305 | # Use f-string for variable interpolation 306 | logger.info(f"Command with api_id: {action_id} succeeded") 307 | return True 308 | else: 309 | # Use f-string for variable interpolation 310 | logger.error(f"Command with api_id: {action_id} failed or no response received") 311 | return False 312 | 313 | async def BodyHeight(self, height_cm, ack=False): 314 | """ 315 | Adjust the body height of the robot to an absolute height specified in centimeters. 316 | The input height is mapped from a range of [20, 35] centimeters to a corresponding 317 | relative adjustment range in meters [-0.18, 0.03]. 318 | 319 | Parameter: 320 | height_cm (float): Absolute height value in centimeters, within the range [20, 35]. 321 | """ 322 | # Define the mapping from centimeters to the corresponding meter range for height adjustment 323 | min_cm, max_cm = 20, 35 324 | min_height_m, max_height_m = -0.18, 0.03 325 | 326 | # Check if the input height is within the acceptable range 327 | if not min_cm <= height_cm <= max_cm: 328 | raise ValueError("Height must be between 20 and 35 centimeters.") 329 | 330 | # Perform linear interpolation from cm to meter range 331 | height_m = min_height_m + (max_height_m - min_height_m) * ((height_cm - min_cm) / (max_cm - min_cm)) 332 | 333 | # Prepare the parameter for the command 334 | para = {'data': height_m} 335 | 336 | # Get the action ID for BodyHeight command 337 | action_id = SPORT_CLIENT_API_ID["BodyHeight"] 338 | response = await self.doRequest(action_id, parameter=para, noreply=not ack) 339 | if response: 340 | # Use f-string for variable interpolation 341 | logger.info(f"Command with api_id: {action_id} succeeded") 342 | return True 343 | else: 344 | # Use f-string for variable interpolation 345 | logger.error(f"Command with api_id: {action_id} failed or no response received") 346 | return False 347 | 348 | async def FootRaiseHeight(self, height_cm, ack=False): 349 | """ 350 | Adjust the foot raise height of the robot to an absolute height specified in centimeters. 351 | The input height is mapped from a range of [5, 12] centimeters to a corresponding 352 | relative adjustment range in meters [-0.06, 0.03]. 353 | 354 | Parameter: 355 | height_cm (float): Absolute height value in centimeters, within the range [5, 12]. 356 | """ 357 | # Define the mapping from centimeters to the corresponding meter range for height adjustment 358 | min_cm, max_cm = 5, 12 359 | min_height_m, max_height_m = -0.06, 0.03 360 | 361 | # Check if the input height is within the acceptable range 362 | if not min_cm <= height_cm <= max_cm: 363 | raise ValueError("Height must be between 5 and 12 centimeters.") 364 | 365 | # Perform linear interpolation from cm to meter range 366 | height_m = min_height_m + (max_height_m - min_height_m) * ((height_cm - min_cm) / (max_cm - min_cm)) 367 | 368 | # Prepare the parameter for the command 369 | para = {'data': height_m} 370 | 371 | # Get the action ID for the FootRaiseHeight command 372 | action_id = SPORT_CLIENT_API_ID["FootRaiseHeight"] 373 | response = await self.doRequest(action_id, parameter=para, noreply=not ack) 374 | if response: 375 | # Use f-string for variable interpolation 376 | logger.info(f"Command with api_id: {action_id} succeeded") 377 | return True 378 | else: 379 | # Use f-string for variable interpolation 380 | logger.error(f"Command with api_id: {action_id} failed or no response received") 381 | return False 382 | 383 | async def SpeedLevel(self, level, ack=False): 384 | """ 385 | Set the speed level of the robot dog in the walking gait mode 386 | Parameter: 387 | level (int): Speed range enumeration value, with values of -1 for slow speed, 0 for normal speed, and 1 for fast speed. 388 | """ 389 | # Ensure 'level' is within the valid range 390 | if not -1 <= level <= 1: 391 | raise ValueError("Level must be -1 (slow speed), 0 (normal speed), or 1 (fast speed).") 392 | 393 | para = {'data': level} 394 | 395 | action_id = SPORT_CLIENT_API_ID["SpeedLevel"] 396 | response = await self.doRequest(action_id, parameter=para, noreply=not ack) 397 | if response: 398 | # Use f-string for variable interpolation 399 | logger.info(f"Command with api_id: {action_id} succeeded") 400 | return True 401 | else: 402 | # Use f-string for variable interpolation 403 | logger.error(f"Command with api_id: {action_id} failed or no response received") 404 | return False 405 | 406 | async def Hello(self, ack=False): 407 | """ 408 | Shakes hand in a way that signifies saying hello. 409 | """ 410 | action_id = SPORT_CLIENT_API_ID["Hello"] 411 | response = await self.doRequest(action_id, noreply=not ack) 412 | if response: 413 | # Use f-string for variable interpolation 414 | logger.info(f"Command with api_id: {action_id} succeeded") 415 | return True 416 | else: 417 | # Use f-string for variable interpolation 418 | logger.error(f"Command with api_id: {action_id} failed or no response received") 419 | return False 420 | 421 | async def Stretch(self, ack=False): 422 | """ 423 | Streaches a few times. 424 | """ 425 | action_id = SPORT_CLIENT_API_ID["Stretch"] 426 | response = await self.doRequest(action_id, noreply=not ack) 427 | if response: 428 | # Use f-string for variable interpolation 429 | logger.info(f"Command with api_id: {action_id} succeeded") 430 | return True 431 | else: 432 | # Use f-string for variable interpolation 433 | logger.error(f"Command with api_id: {action_id} failed or no response received") 434 | return False 435 | 436 | async def TrajectoryFollow(self, path_points, ack=False): 437 | """ 438 | Sends a trajectory consisting of multiple points to the robot for it to follow. 439 | """ 440 | if len(path_points) != 30: 441 | raise ValueError("Exactly 30 path points are required.") 442 | 443 | action_id = SPORT_CLIENT_API_ID["TrajectoryFollow"] 444 | js_path = [point.__dict__ for point in path_points] # Convert each PathPoint to dictionary 445 | 446 | # Convert the path list to a JSON formatted string 447 | para = json.dumps(js_path) 448 | 449 | # Send the request and await the response 450 | response = await self.doRequest(action_id, parameter=para, noreply=not ack) 451 | 452 | if response: 453 | logger.info(f"Command with api_id: {action_id} succeeded") 454 | return True 455 | else: 456 | logger.error(f"Command with api_id: {action_id} failed or no response received") 457 | return False 458 | 459 | async def ContinuousGait(self, flag, ack=False): 460 | """ 461 | Activates or deactivates continuous gait mode. In continuous gait mode, the robot dog 462 | will maintain its gait state even when the current speed is 0, allowing for smoother transitions 463 | between movements. 464 | 465 | Parameters: 466 | flag (bool): Set to True to activate continuous gait mode, or False to deactivate. 467 | """ 468 | # Convert the boolean flag to an integer to match the expected data format 469 | flag_int = 1 if flag else 0 470 | 471 | para = {'data': flag_int} 472 | 473 | action_id = SPORT_CLIENT_API_ID["ContinuousGait"] 474 | response = await self.doRequest(action_id, parameter=para, noreply=not ack) 475 | if response: 476 | # Use f-string for variable interpolation 477 | logger.info(f"Command with api_id: {action_id} succeeded") 478 | return True 479 | else: 480 | # Use f-string for variable interpolation 481 | logger.error(f"Command with api_id: {action_id} failed or no response received") 482 | return False 483 | 484 | 485 | async def Content(self, ack=False): 486 | """ 487 | [NOT WORKING!!!!] 488 | 489 | Happy 490 | """ 491 | action_id = SPORT_CLIENT_API_ID["Content"] 492 | response = await self.doRequest(action_id, noreply=not ack) 493 | if response: 494 | # Use f-string for variable interpolation 495 | logger.info(f"Command with api_id: {action_id} succeeded") 496 | return True 497 | else: 498 | # Use f-string for variable interpolation 499 | logger.error(f"Command with api_id: {action_id} failed or no response received") 500 | return False 501 | 502 | 503 | async def Wallow(self, ack=False): 504 | """ 505 | Wallow on the floor 506 | """ 507 | action_id = SPORT_CLIENT_API_ID["Wallow"] 508 | response = await self.doRequest(action_id, noreply=not ack) 509 | if response: 510 | # Use f-string for variable interpolation 511 | logger.info(f"Command with api_id: {action_id} succeeded") 512 | return True 513 | else: 514 | # Use f-string for variable interpolation 515 | logger.error(f"Command with api_id: {action_id} failed or no response received") 516 | return False 517 | 518 | 519 | async def Dance1(self, ack=False): 520 | """ 521 | Performs a Dance1 522 | """ 523 | action_id = SPORT_CLIENT_API_ID["Dance1"] 524 | response = await self.doRequest(action_id, noreply=not ack) 525 | if response: 526 | # Use f-string for variable interpolation 527 | logger.info(f"Command with api_id: {action_id} succeeded") 528 | return True 529 | else: 530 | # Use f-string for variable interpolation 531 | logger.error(f"Command with api_id: {action_id} failed or no response received") 532 | return False 533 | 534 | async def Dance2(self, ack=False): 535 | """ 536 | Performs a Dance2 537 | """ 538 | action_id = SPORT_CLIENT_API_ID["Dance2"] 539 | response = await self.doRequest(action_id, noreply=not ack) 540 | if response: 541 | # Use f-string for variable interpolation 542 | logger.info(f"Command with api_id: {action_id} succeeded") 543 | return True 544 | else: 545 | # Use f-string for variable interpolation 546 | logger.error(f"Command with api_id: {action_id} failed or no response received") 547 | return False 548 | 549 | async def GetBodyHeight(self, ack=False): 550 | """ 551 | GetBodyHeight. !!!API not implemented on the server!!! 552 | """ 553 | action_id = SPORT_CLIENT_API_ID["GetBodyHeight"] 554 | response = await self.doRequest(action_id, noreply=not ack) 555 | if response: 556 | # Use f-string for variable interpolation 557 | logger.info(f"Command with api_id: {action_id} succeeded") 558 | return True 559 | else: 560 | # Use f-string for variable interpolation 561 | logger.error(f"Command with api_id: {action_id} failed or no response received") 562 | return False 563 | 564 | async def GetFootRaiseHeight(self, ack=False): 565 | """ 566 | GetFootRaiseHeight. !!!API not implemented on the server!!! 567 | """ 568 | action_id = SPORT_CLIENT_API_ID["GetFootRaiseHeight"] 569 | response = await self.doRequest(action_id, noreply=not ack) 570 | if response: 571 | # Use f-string for variable interpolation 572 | logger.info(f"Command with api_id: {action_id} succeeded") 573 | return True 574 | else: 575 | # Use f-string for variable interpolation 576 | logger.error(f"Command with api_id: {action_id} failed or no response received") 577 | return False 578 | 579 | 580 | async def GetSpeedLevel(self, ack=False): 581 | """ 582 | GetSpeedLevel. !!!API not implemented on the server!!! 583 | """ 584 | action_id = SPORT_CLIENT_API_ID["GetSpeedLevel"] 585 | response = await self.doRequest(action_id, noreply=not ack) 586 | if response: 587 | # Use f-string for variable interpolation 588 | logger.info(f"Command with api_id: {action_id} succeeded") 589 | return True 590 | else: 591 | # Use f-string for variable interpolation 592 | logger.error(f"Command with api_id: {action_id} failed or no response received") 593 | return False 594 | 595 | 596 | async def SwitchJoystick(self, flag, ack=False): 597 | """ 598 | [!!NOT WORKING!! Use bash_runner_client instead] 599 | 600 | After turning off the remote control response, the remote control commands will not interfere with the current program operation. 601 | 602 | Parameters: 603 | flag (bool): Set true to respond to the native remote control, and false to not respond to the remote control. 604 | """ 605 | # Convert the boolean flag to an integer to comply with expected data format 606 | flag_int = 1 if flag else 0 607 | 608 | para = {'data': flag_int} 609 | 610 | action_id = SPORT_CLIENT_API_ID["SwitchJoystick"] 611 | response = await self.doRequest(action_id, parameter=para, noreply=not ack) 612 | if response: 613 | # Use f-string for variable interpolation 614 | logger.info(f"Command with api_id: {action_id} succeeded") 615 | return True 616 | else: 617 | # Use f-string for variable interpolation 618 | logger.error(f"Command with api_id: {action_id} failed or no response received") 619 | return False 620 | 621 | 622 | async def Pose(self, flag, ack=False): 623 | """ 624 | Activates or deactivates pose mode. In pose mode, the robot maintains its position while joystick controls can change its Euler angles (roll, pitch, yaw). 625 | 626 | Parameters: 627 | flag (bool): If True, activates pose mode. If False, deactivates pose mode and restores normal operation. 628 | """ 629 | # Convert the boolean flag to an integer to match the expected data format 630 | flag_int = 1 if flag else 0 631 | 632 | # Prepare the parameter for the control message 633 | para = {'data': flag_int} 634 | 635 | # Retrieve the action ID for the 'Pose' command from the SPORT_CMD dictionary 636 | action_id = SPORT_CLIENT_API_ID["Pose"] 637 | 638 | response = await self.doRequest(action_id, parameter=para, noreply=not ack) 639 | if response: 640 | # Use f-string for variable interpolation 641 | logger.info(f"Command with api_id: {action_id} succeeded") 642 | return True 643 | else: 644 | # Use f-string for variable interpolation 645 | logger.error(f"Command with api_id: {action_id} failed or no response received") 646 | return False 647 | 648 | async def Scrape(self, ack=False): 649 | """ 650 | Balances on the hind legs and performs a gesture with the front limbs. 651 | """ 652 | action_id = SPORT_CLIENT_API_ID["Scrape"] 653 | response = await self.doRequest(action_id, noreply=not ack) 654 | if response: 655 | # Use f-string for variable interpolation 656 | logger.info(f"Command with api_id: {action_id} succeeded") 657 | return True 658 | else: 659 | # Use f-string for variable interpolation 660 | logger.error(f"Command with api_id: {action_id} failed or no response received") 661 | return False 662 | 663 | async def FrontFlip(self, ack=False): 664 | """ 665 | Performs a Front Flip 666 | """ 667 | action_id = SPORT_CLIENT_API_ID["FrontFlip"] 668 | response = await self.doRequest(action_id, noreply=not ack) 669 | if response: 670 | # Use f-string for variable interpolation 671 | logger.info(f"Command with api_id: {action_id} succeeded") 672 | return True 673 | else: 674 | # Use f-string for variable interpolation 675 | logger.error(f"Command with api_id: {action_id} failed or no response received") 676 | return False 677 | 678 | async def FrontJump(self, ack=False): 679 | """ 680 | Performs a Front Jump 681 | """ 682 | action_id = SPORT_CLIENT_API_ID["FrontJump"] 683 | response = await self.doRequest(action_id, noreply=not ack) 684 | if response: 685 | # Use f-string for variable interpolation 686 | logger.info(f"Command with api_id: {action_id} succeeded") 687 | return True 688 | else: 689 | # Use f-string for variable interpolation 690 | logger.error(f"Command with api_id: {action_id} failed or no response received") 691 | return False 692 | 693 | async def FrontPounce(self, ack=False): 694 | """ 695 | Performs a Front Pounce 696 | """ 697 | action_id = SPORT_CLIENT_API_ID["FrontPounce"] 698 | response = await self.doRequest(action_id, noreply=not ack) 699 | if response: 700 | # Use f-string for variable interpolation 701 | logger.info(f"Command with api_id: {action_id} succeeded") 702 | return True 703 | else: 704 | # Use f-string for variable interpolation 705 | logger.error(f"Command with api_id: {action_id} failed or no response received") 706 | return False 707 | 708 | 709 | async def WiggleHips(self, ack=False): 710 | """ 711 | Performs a WiggleHips 712 | """ 713 | action_id = SPORT_CLIENT_API_ID["WiggleHips"] 714 | response = await self.doRequest(action_id, noreply=not ack) 715 | if response: 716 | # Use f-string for variable interpolation 717 | logger.info(f"Command with api_id: {action_id} succeeded") 718 | return True 719 | else: 720 | # Use f-string for variable interpolation 721 | logger.error(f"Command with api_id: {action_id} failed or no response received") 722 | return False 723 | 724 | async def GetState(self, parameters): 725 | """ 726 | Retrieve the current status of the robot by sending a request for specific parameters. 727 | This method allows for querying various attributes of the robot, such as motion status, body height, 728 | leg lift height, speed gear, gait pattern, joystick control status, dance activity, 729 | continuous gait mode, and economic gait mode. 730 | 731 | Parameters: 732 | parameters (list of str): A list of parameter names to query. Possible values are: 733 | - "state" 734 | - "bodyHeight" 735 | - "footRaiseHeight" 736 | - "speedLevel" 737 | - "gait" 738 | - "joystick" 739 | - "dance" 740 | - "continuousGait" 741 | - "economicGait" 742 | 743 | Returns: 744 | dict: A dictionary with the requested parameters and their values if the request is successful. 745 | If a parameter is not found, it will not be included in the dictionary. 746 | """ 747 | 748 | action_id = SPORT_CLIENT_API_ID["GetState"] 749 | 750 | # Ensure doRequest can handle a data dict correctly 751 | response = await self.doRequest(action_id, parameter=parameters, noreply=False) 752 | 753 | # Initialize an empty dictionary to store the parsed parameters 754 | parsed_parameters = {} 755 | 756 | # if response and response.header.status == 0: 757 | if response: 758 | try: 759 | # Assuming 'response' is the JSON string with the data 760 | response_data = json.loads(response.data) 761 | for param in parameters: 762 | if param in response_data: 763 | param_value_json = response_data[param] 764 | # Parse the JSON string of the parameter value to a dictionary 765 | param_value_dict = json.loads(param_value_json) if isinstance(param_value_json, str) else param_value_json 766 | # Extract the 'data' key from the parsed JSON of each parameter 767 | parsed_parameters[param] = param_value_dict.get('data', None) 768 | return parsed_parameters 769 | except json.JSONDecodeError as e: 770 | logger.error(f"Failed to parse response data: {e}") 771 | raise Exception(f"Failed to parse response data: {e}") 772 | else: 773 | logger.error("Failed to retrieve state or no response received.") 774 | 775 | 776 | async def EconomicGait(self, flag, ack=False): 777 | """ 778 | Activates or deactivates Economic Gait, other name is Endurance mode, the bettery last for longer 779 | 780 | Parameters: 781 | flag (bool): If True, activates pose mode. If False, deactivates pose mode and restores normal operation. 782 | """ 783 | # Convert the boolean flag to an integer to match the expected data format 784 | flag_int = 1 if flag else 0 785 | 786 | # Prepare the parameter for the control message 787 | para = {'data': flag_int} 788 | 789 | # Retrieve the action ID for the 'Pose' command from the SPORT_CMD dictionary 790 | action_id = SPORT_CLIENT_API_ID["EconomicGait"] 791 | 792 | response = await self.doRequest(action_id, parameter=para, noreply=not ack) 793 | if response: 794 | # Use f-string for variable interpolation 795 | logger.info(f"Command with api_id: {action_id} succeeded") 796 | return True 797 | else: 798 | # Use f-string for variable interpolation 799 | logger.error(f"Command with api_id: {action_id} failed or no response received") 800 | return False 801 | 802 | async def FingerHeart(self, ack=False): 803 | """ 804 | Performs a FingerHeart 805 | """ 806 | action_id = SPORT_CLIENT_API_ID["FingerHeart"] 807 | response = await self.doRequest(action_id, noreply=not ack) 808 | if response: 809 | # Use f-string for variable interpolation 810 | logger.info(f"Command with api_id: {action_id} succeeded") 811 | return True 812 | else: 813 | # Use f-string for variable interpolation 814 | logger.error(f"Command with api_id: {action_id} failed or no response received") 815 | return False 816 | 817 | async def Handstand(self, ack=False): 818 | """ 819 | Do a Handstand. Only available in advanced mode! 820 | """ 821 | action_id = SPORT_CLIENT_API_ID["Handstand"] 822 | response = await self.doRequest(action_id, noreply=not ack) 823 | if response: 824 | # Use f-string for variable interpolation 825 | logger.info(f"Command with api_id: {action_id} succeeded") 826 | return True 827 | else: 828 | # Use f-string for variable interpolation 829 | logger.error(f"Command with api_id: {action_id} failed or no response received") 830 | return False 831 | 832 | async def CrossStep(self, ack=False): 833 | """ 834 | Do a CrossStep. Only available in advanced mode! 835 | """ 836 | action_id = SPORT_CLIENT_API_ID["CrossStep"] 837 | response = await self.doRequest(action_id, noreply=not ack) 838 | if response: 839 | # Use f-string for variable interpolation 840 | logger.info(f"Command with api_id: {action_id} succeeded") 841 | return True 842 | else: 843 | # Use f-string for variable interpolation 844 | logger.error(f"Command with api_id: {action_id} failed or no response received") 845 | return False 846 | 847 | async def OnesidedStep(self, ack=False): 848 | """ 849 | Do a OnesidedStep. Only available in advanced mode! 850 | """ 851 | action_id = SPORT_CLIENT_API_ID["OnesidedStep"] 852 | response = await self.doRequest(action_id, noreply=not ack) 853 | if response: 854 | # Use f-string for variable interpolation 855 | logger.info(f"Command with api_id: {action_id} succeeded") 856 | return True 857 | else: 858 | # Use f-string for variable interpolation 859 | logger.error(f"Command with api_id: {action_id} failed or no response received") 860 | return False 861 | 862 | async def Bound(self, ack=False): 863 | """ 864 | Do a Bound. Only available in advanced mode! 865 | """ 866 | action_id = SPORT_CLIENT_API_ID["Bound"] 867 | response = await self.doRequest(action_id, noreply=not ack) 868 | if response: 869 | # Use f-string for variable interpolation 870 | logger.info(f"Command with api_id: {action_id} succeeded") 871 | return True 872 | else: 873 | # Use f-string for variable interpolation 874 | logger.error(f"Command with api_id: {action_id} failed or no response received") 875 | return False 876 | 877 | async def LeadFollow(self, flag, ack=False): 878 | """ 879 | Activates or deactivates LeadFollow mode 880 | 881 | Parameters: 882 | flag (bool): Set to True to activate LeadFollow mode, or False to deactivate. 883 | """ 884 | # Convert the boolean flag to an integer to match the expected data format 885 | flag_int = 1 if flag else 0 886 | 887 | para = {'data': flag_int} 888 | action_id = SPORT_CLIENT_API_ID["LeadFollow"] 889 | response = await self.doRequest(action_id, parameter=para, noreply=not ack) 890 | if response: 891 | # Use f-string for variable interpolation 892 | logger.info(f"Command with api_id: {action_id} succeeded") 893 | return True 894 | else: 895 | # Use f-string for variable interpolation 896 | logger.error(f"Command with api_id: {action_id} failed or no response received") 897 | return False 898 | 899 | class SportState: 900 | """ 901 | SportState: This class is designed to obtain high-level motion states of the Go2, such as position, speed, and posture. 902 | """ 903 | _instance = None 904 | 905 | def __new__(cls, communicator, frequency='lf'): 906 | # Ensuring only one instance of SportState is created 907 | if cls._instance is None: 908 | cls._instance = super(SportState, cls).__new__(cls) 909 | cls._instance.initialized = False 910 | return cls._instance 911 | 912 | def __init__(self, communicator, frequency='lf'): 913 | if not self.initialized: 914 | self.communicator = communicator 915 | self.frequency = frequency 916 | self.topic = self._get_topic_name(frequency) 917 | self.sport_state = None 918 | self.callbacks = set() 919 | self.listening = False 920 | self.initialized = True 921 | 922 | def _get_topic_name(self, frequency): 923 | return { 924 | 'lf': self.communicator.get_topic_by_name("SPORT_MOD_STATE_LF"), 925 | 'mf': self.communicator.get_topic_by_name("SPORT_MOD_STATE_MF") 926 | }.get(frequency, self.communicator.get_topic_by_name("SPORT_MOD_STATE")) 927 | 928 | def add_callback(self, callback): 929 | """ Registers a callback to be called when new data arrives. """ 930 | self.callbacks.add(callback) 931 | if not self.listening: 932 | asyncio.create_task(self._start_listening()) 933 | 934 | def remove_callback(self, callback): 935 | """ Remove a specific callback and stop listening if no callbacks remain. """ 936 | self.callbacks.discard(callback) 937 | if not self.callbacks and self.listening: 938 | asyncio.create_task(self._stop_listening()) 939 | 940 | async def _process_data(self, data): 941 | """ Process incoming data and execute callbacks. """ 942 | if isinstance(data, SportModeState_): 943 | self.sport_state = data 944 | await asyncio.gather(*(callback(data) for callback in self.callbacks)) 945 | else: 946 | logger.error("Incorrect data type received.") 947 | 948 | async def _start_listening(self): 949 | """Start listening to the topic only if not already listening.""" 950 | if not self.listening: 951 | self.communicator.subscribe(self.topic, SportModeState_, self._process_data) 952 | self.listening = True 953 | logger.info(f"Subscribed to {self.topic}") 954 | 955 | async def _stop_listening(self): 956 | """Stop listening to the topic.""" 957 | if self.listening: 958 | self.communicator.unsubscribe(self.topic) 959 | self.listening = False 960 | logger.info(f"Unsubscribed from {self.topic}") 961 | 962 | # Usage example 963 | if __name__ == "__main__": 964 | asyncio.run(main()) 965 | 966 | -------------------------------------------------------------------------------- /communicator/__init__.py: -------------------------------------------------------------------------------- 1 | # communicator/__init__.py 2 | import os 3 | import sys 4 | import logging 5 | 6 | logger = logging.getLogger(__name__) 7 | 8 | def setup_import_paths(): 9 | # Get the root of the project based on this file's directory 10 | project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 11 | idl_path = os.path.join(project_root, 'communicator', 'idl') 12 | if idl_path not in sys.path: 13 | sys.path.insert(0, idl_path) 14 | # logger.info(f"Added {idl_path} to sys.path") 15 | print(f"Added {idl_path} to sys.path") 16 | 17 | setup_import_paths() 18 | -------------------------------------------------------------------------------- /communicator/communicatorWrapper.py: -------------------------------------------------------------------------------- 1 | # Common base class for PubSub and ReqRes communication 2 | class CommunicatorWrapper: 3 | def publish(self, topic, data, data_type): 4 | raise NotImplementedError 5 | 6 | def subscribe(self, topic, data_type, callback): 7 | raise NotImplementedError 8 | 9 | def unsubscribe(self, topic): 10 | raise NotImplementedError 11 | 12 | async def publishReq (self, topic, requestData, timeout=5): 13 | raise NotImplementedError 14 | 15 | def get_topic_by_name(self, name): 16 | raise NotImplementedError -------------------------------------------------------------------------------- /communicator/constants.py: -------------------------------------------------------------------------------- 1 | DDS_ERROR_DESCRIPTIONS = { 2 | 3001: "Unknown error", 3 | 3102: "Request sending error", 4 | 3103: "API not registered", 5 | 3104: "Request timeout", 6 | 3105: "Request and response data do not match", 7 | 3106: "Invalid response data", 8 | 3107: "Invalid lease", 9 | 3201: "Response sending error", 10 | 3202: "Internal server error", 11 | 3203: "API not implemented on the server", 12 | 3204: "API parameter error", 13 | 3205: "Request rejected", 14 | 3206: "Invalid lease", 15 | 3207: "Lease already exists", 16 | } 17 | 18 | SPORT_CLIENT_API_ID = { 19 | "Damp": 1001, 20 | "BalanceStand": 1002, 21 | "StopMove": 1003, 22 | "StandUp": 1004, 23 | "StandDown": 1005, 24 | "RecoveryStand": 1006, 25 | "Euler": 1007, 26 | "Move": 1008, 27 | "Sit": 1009, 28 | "RiseSit": 1010, 29 | "SwitchGait": 1011, 30 | "Trigger": 1012, 31 | "BodyHeight": 1013, 32 | "FootRaiseHeight": 1014, 33 | "SpeedLevel": 1015, 34 | "Hello": 1016, 35 | "Stretch": 1017, 36 | "TrajectoryFollow": 1018, 37 | "ContinuousGait": 1019, 38 | "Content": 1020, #API not implemented on the server 39 | "Wallow": 1021, 40 | "Dance1": 1022, 41 | "Dance2": 1023, 42 | "GetBodyHeight": 1024, #API not implemented on the server 43 | "GetFootRaiseHeight": 1025, #API not implemented on the server 44 | "GetSpeedLevel": 1026, #API not implemented on the server 45 | "SwitchJoystick": 1027, #NOT WORKING use bash_runner_client instead!!! 46 | "Pose": 1028, 47 | "Scrape": 1029, 48 | "FrontFlip": 1030, 49 | "FrontJump": 1031, 50 | "FrontPounce": 1032, 51 | "WiggleHips": 1033, 52 | "GetState": 1034, 53 | "EconomicGait": 1035, 54 | "FingerHeart": 1036, 55 | "Handstand": 1301, 56 | "CrossStep": 1302, 57 | "OnesidedStep": 1303, 58 | "Bound": 1304, 59 | "LeadFollow": 1045 60 | } 61 | 62 | SPORT_MODE_SWITCH_API_ID = { 63 | "GetMode": 1001, 64 | "SetMode": 1002, 65 | "ReleaseMode": 1003, 66 | "SetSilent": 1004, 67 | "GetSilent": 1005 68 | } 69 | 70 | #Topics only available through WebRTC (however will work through DDS) 71 | 72 | WEBRTC_TOPICS = { 73 | # General Device Control and Configuration 74 | "RTC_STATUS": "rt/rtc_status", 75 | "RTC_STATE": "rt/rtc/state", 76 | "SERVICE_STATE": "rt/servicestate", 77 | "SERVICE_STATE_ACTIVATE": "rt/servicestateactivate", 78 | "PUBLIC_NETWORK_STATUS": "rt/public_network_status", 79 | 80 | # API Requests and Responses 81 | "VIDEOHUB_INNER": "rt/videohub/inner", 82 | "FRONT_PHOTO_REQ": "rt/api/videohub/request", 83 | "VIDEOHUB_RESPONSE": "rt/api/videohub/response", 84 | "UWB_REQ": "rt/api/uwbswitch/request", 85 | "UWB_RESPONSE": "rt/api/uwbswitch/response", 86 | "BASH_REQ": "rt/api/bashrunner/request", 87 | "BASH_RESPONSE": "rt/api/bashrunner/response", 88 | "OBSTACLES_AVOID": "rt/api/obstacles_avoid/request", 89 | "OBSTACLES_AVOID_RESPONSE": "rt/api/obstacles_avoid/response", 90 | "VUI": "rt/api/vui/request", 91 | "VUI_RESPONSE": "rt/api/vui/response", 92 | "GPT": "rt/api/gpt/request", 93 | "GPT_RESPONSE": "rt/api/gpt/response", 94 | "SPORT_MOD": "rt/api/sport/request", 95 | "SPORT_RESPONSE": "rt/api/sport/response", 96 | "ROBOT_STATE_REQ": "rt/api/robot_state/request", 97 | "ROBOT_STATE_RESPONSE": "rt/api/robot_state/response", 98 | "AUDIO_HUB_REQ": "rt/api/audiohub/request", 99 | "AUDIO_HUB_RESPONSE": "rt/api/audiohub/response", 100 | "CONFIG_REQ": "rt/api/config/request", 101 | "CONFIG_RESPONSE": "rt/api/config/response", 102 | "SPORT_MODE_SWITCHER": "rt/api/motion_switcher/request", 103 | "SPORT_MODE_SWITCHER_RESPONSE": "rt/api/motion_switcher/response", 104 | "GAS_SENSOR_REQ": "rt/api/gas_sensor/request", 105 | "GAS_SENSOR_RESPONSE": "rt/api/gas_sensor/response", 106 | 107 | # SLAM and Mapping 108 | "SLAM_QT_COMMAND": "rt/qt_command", 109 | "SLAM_ADD_NODE": "rt/qt_add_node", 110 | "SLAM_ADD_EDGE": "rt/qt_add_edge", 111 | "SLAM_QT_NOTICE": "rt/qt_notice", 112 | "SLAM_PC_TO_IMAGE_LOCAL": "rt/pctoimage_local", 113 | "SLAM_ODOMETRY": "rt/lio_sam_ros2/mapping/odometry", 114 | 115 | # Query and Feedback 116 | "QUERY_RESULT_NODE": "rt/query_result_node", 117 | "QUERY_RESULT_EDGE": "rt/query_result_edge", 118 | "GPT_FEEDBACK": "rt/gptflowfeedback", 119 | 120 | # Sensor Data 121 | "ULIDAR_SWITCH": "rt/utlidar/switch", 122 | "ULIDAR_ARRAY": "rt/utlidar/voxel_map_compressed", 123 | "ULIDAR_STATE": "rt/utlidar/lidar_state", 124 | "ROBOTODOM": "rt/utlidar/robot_pose", 125 | "UWB_STATE": "rt/uwbstate", 126 | 127 | # Device State 128 | "MULTIPLE_STATE": "rt/multiplestate", 129 | "LOW_STATE_LF": "rt/lf/lowstate", 130 | "SPORT_MOD_STATE_LF": "rt/lf/sportmodestate", 131 | "AUDIO_HUB_PLAY_STATE": "rt/audiohub/player/state", 132 | "SELF_TEST": "rt/selftest", 133 | "GAS_SENSOR": "rt/gas_sensor", 134 | 135 | # Arm Commands and Feedback 136 | "ARM_COMMAND": "rt/arm_Command", 137 | "ARM_FEEDBACK": "rt/arm_Feedback", 138 | 139 | # Wireless Controller 140 | "WIRELESS_CONTROLLER": "rt/wirelesscontroller", 141 | } 142 | 143 | 144 | DDS_ONLY_TOPICS = { 145 | "SPORT_MOD_STATE": "rt/sportmodestate", 146 | "SPORT_MOD_STATE_MF": "rt/mf/sportmodestate", 147 | "ULIDAR": "rt/utlidar/voxel_map", 148 | "LOW_STATE": "rt/lowstate", 149 | } 150 | 151 | # Combine WebRTC topics with DDS-specific topics for comprehensive DDS topics 152 | DDS_TOPICS = {**WEBRTC_TOPICS, **DDS_ONLY_TOPICS} -------------------------------------------------------------------------------- /communicator/cyclonedds/cyclonedds.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | true 10 | 11 | 12 | -------------------------------------------------------------------------------- /communicator/cyclonedds/ddsCommunicator.py: -------------------------------------------------------------------------------- 1 | import os 2 | import time 3 | import random 4 | import asyncio 5 | import json 6 | import logging 7 | from communicator.constants import DDS_TOPICS, DDS_ERROR_DESCRIPTIONS 8 | from cyclonedds.domain import DomainParticipant 9 | from cyclonedds.sub import DataReader 10 | from cyclonedds.pub import DataWriter 11 | from cyclonedds.topic import Topic 12 | from cyclonedds.core import Listener, Qos, Policy, Entity 13 | from cyclonedds.util import duration 14 | from communicator.communicatorWrapper import CommunicatorWrapper 15 | import xml.etree.ElementTree as ET 16 | 17 | from communicator.idl.unitree_api.msg.dds_ import RequestIdentity_, RequestLease_, RequestPolicy_, RequestHeader_, Request_, Response_ 18 | from communicator.idl.std_msgs.msg.dds_ import String_ 19 | 20 | logger = logging.getLogger(__name__) 21 | 22 | class DDSCommunicator(CommunicatorWrapper): 23 | # Class variable to hold the DomainParticipant instance 24 | _participant = None 25 | 26 | def __init__(self, interface="eth0"): 27 | self.name = "DDS" 28 | self._set_network(interface) 29 | 30 | # If a DomainParticipant has not been created, do so with the updated configuration 31 | if DDSCommunicator._participant is None: 32 | # Directly use the path to the XML configuration file when creating the Domain 33 | DDSCommunicator._participant = DomainParticipant(domain_id=0) 34 | 35 | self.participant = DDSCommunicator._participant 36 | self.current_id = random.randint(0, 2147483647) 37 | self.readers = {} # Use a dictionary to manage readers by topic name 38 | self.topics = {} # Cache topics to avoid recreating them 39 | self.writers = {} # Cache for DataWriter instances 40 | self.callbacks = {} # Cache for callback instances 41 | self.deferred_unsubscriptions = {} # Manage deferred unsubscriptions 42 | self.main_loop = asyncio.get_event_loop() 43 | 44 | def _create_topic(self, topic, data_type): 45 | 46 | if topic not in self.topics: 47 | self.topics[topic] = Topic(self.participant, topic, data_type) 48 | # time.sleep(2) 49 | return self.topics[topic] 50 | 51 | def publish(self, topic, data, data_type): 52 | 53 | topic_instance = self._create_topic(topic, data_type) 54 | 55 | # Check if a writer for this topic already exists, if not, create it 56 | if topic not in self.writers: 57 | self.writers[topic] = DataWriter(self.participant, topic_instance) 58 | time.sleep(0.5) #Wait a bit after topic creation 59 | 60 | writer = self.writers[topic] 61 | 62 | logger.debug(f"Data to publish: {data}") 63 | writer.write(data) 64 | 65 | def subscribe(self, topic, data_type, callback=None): 66 | # Initialize callback list for the topic if it does not exist 67 | if topic not in self.callbacks: 68 | self.callbacks[topic] = [] 69 | 70 | # Add the callback to the list of callbacks for this topic if it's not already present 71 | if callback not in self.callbacks[topic]: 72 | self.callbacks[topic].append(callback) 73 | logger.debug(f"Added new callback for {topic}") 74 | 75 | if topic not in self.readers: 76 | topic_instance = self._create_topic(topic, data_type) 77 | current_loop = asyncio.get_running_loop() 78 | 79 | class CustomListener(Listener): 80 | def __init__(self, callbacks, topic, current_loop): 81 | super().__init__() 82 | self.callbacks = callbacks 83 | self.topic = topic 84 | self.current_loop = current_loop 85 | 86 | def on_data_available(self, reader): 87 | samples = reader.take(N=100) 88 | for sample in samples: 89 | if sample.sample_info.valid_data: 90 | for cb in self.callbacks.get(self.topic, []): 91 | asyncio.run_coroutine_threadsafe(cb(sample), self.current_loop) 92 | else: 93 | logger.error("Received invalid data.") 94 | 95 | # Create the listener and data reader 96 | listener = CustomListener(self.callbacks, topic, current_loop) 97 | reader = DataReader(self.participant, topic_instance, listener=listener) 98 | self.readers[topic] = reader 99 | logger.info(f"Subscribed to {topic}") 100 | 101 | def unsubscribe(self, topic, callback=None): 102 | """Unsubscribe from a topic immediately without deferred actions.""" 103 | if topic not in self.readers: 104 | logger.warning(f"Not subscribed to {topic}, cannot unsubscribe") 105 | return 106 | 107 | # Remove callback if specified, or all callbacks if not 108 | if callback: 109 | if callback in self.callbacks.get(topic, []): 110 | self.callbacks[topic].remove(callback) 111 | logger.info(f"Callback removed from {topic}, callback: {callback}") 112 | else: 113 | logger.warning(f"Callback not found for {topic}") 114 | 115 | # If no callbacks remain, or no specific callback was specified, clean up immediately 116 | if not callback or not self.callbacks[topic]: 117 | """Clean up reader and callback resources for a topic.""" 118 | if topic in self.readers: 119 | del self.readers[topic] # Clean up the data reader 120 | if topic in self.callbacks: 121 | del self.callbacks[topic] # Remove all callbacks associated with the topic 122 | logger.info(f"Unsubscribed from {topic}") 123 | 124 | 125 | async def publishReq(self, topic, requestData, timeout=5): 126 | if not topic.endswith("/request"): 127 | logger.error("The request should end with '/request'") 128 | return 129 | 130 | # Prepare the request message 131 | self.current_id += 1 132 | request_id = requestData.get('request_id', self.current_id) 133 | identity = RequestIdentity_(request_id, requestData.get('api_id', 0)) 134 | lease = RequestLease_(requestData.get('lease', 0)) 135 | policy = RequestPolicy_(priority=requestData.get('priority', 0), noreply=requestData.get('noreply', False)) 136 | header = RequestHeader_(identity=identity, lease=lease, policy=policy) 137 | parameter = json.dumps(requestData.get('parameter'), ensure_ascii=False) if requestData.get('parameter') is not None else '' 138 | request = Request_(header=header, parameter=parameter, binary=[]) 139 | 140 | if not requestData.get('noreply', False): 141 | response_topic_name = topic.replace("/request", "/response") 142 | # Make sure the topic and reader are ready 143 | topic_instance = self._create_topic(response_topic_name, Response_) 144 | if response_topic_name not in self.readers: 145 | self.readers[response_topic_name] = DataReader(self.participant, topic_instance) 146 | 147 | # Send the request 148 | self.publish(topic, request, Request_) 149 | logger.info(f"Request sent to {topic} with id: {request_id}") 150 | 151 | # Polling for response 152 | start_time = time.time() 153 | while (time.time() - start_time) < timeout: 154 | samples = self.readers[response_topic_name].take(N=1) 155 | for sample in samples: 156 | if sample.sample_info.valid_data and sample.header.identity.id == request_id: 157 | if sample.header.status.code == 0: 158 | logger.info("Request successful with status code 0.") 159 | return sample # Return the whole response object if successful 160 | else: 161 | error_description = DDS_ERROR_DESCRIPTIONS.get(sample.header.status.code, "Unknown error code") 162 | logger.error(f"Request failed with status code {sample.header.status.code}: {error_description}") 163 | return None 164 | 165 | logger.error(f"Response from {response_topic_name} timed out") 166 | else: 167 | # Send the request without expecting a response 168 | self.publish(topic, request, Request_) 169 | logger.info(f"Request sent with no reply expected to {topic} with id: {request_id}") 170 | return None 171 | 172 | return None 173 | 174 | 175 | def get_topic_by_name(self, name): 176 | return DDS_TOPICS[name] 177 | 178 | def _set_network(self, interface): 179 | 180 | current_path = os.path.dirname(os.path.abspath(__file__)) 181 | cyclonedds_config_path = os.path.join(current_path, "cyclonedds.xml") 182 | tree = ET.parse(cyclonedds_config_path) 183 | root = tree.getroot() 184 | 185 | # Find the NetworkInterface element and change its name attribute 186 | for network_interface in root.findall(".//NetworkInterface"): 187 | network_interface.set("name", interface) # Change the interface name 188 | 189 | # Save the modified XML back to the file 190 | tree.write(cyclonedds_config_path) 191 | 192 | # Set the CYCLONEDDS_URI environment variable to point to the updated config file 193 | os.environ['CYCLONEDDS_URI'] = cyclonedds_config_path 194 | logger.info(f"CYCLONEDDS_URI set to: {cyclonedds_config_path}") 195 | 196 | logger.info(f"DDS Domain configured with network interface {interface}") 197 | 198 | 199 | 200 | -------------------------------------------------------------------------------- /communicator/idl/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.10.2 4 | Module: builtin_interfaces 5 | 6 | """ 7 | 8 | from . import builtin_interfaces 9 | from . import geometry_msgs 10 | from . import std_msgs 11 | from . import unitree_api 12 | from . import unitree_go 13 | __all__ = ["builtin_interfaces","geometry_msgs", "std_msgs", "unitree_api", "unitree_go"] 14 | -------------------------------------------------------------------------------- /communicator/idl/builtin_interfaces/.idlpy_manifest: -------------------------------------------------------------------------------- 1 | Time_ 2 | msg 3 | 4 | -------------------------------------------------------------------------------- /communicator/idl/builtin_interfaces/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.10.2 4 | Module: builtin_interfaces 5 | 6 | """ 7 | 8 | from . import msg 9 | __all__ = ["msg", ] 10 | -------------------------------------------------------------------------------- /communicator/idl/builtin_interfaces/msg/.idlpy_manifest: -------------------------------------------------------------------------------- 1 | Time_ 2 | dds_ 3 | 4 | -------------------------------------------------------------------------------- /communicator/idl/builtin_interfaces/msg/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.10.2 4 | Module: builtin_interfaces.msg 5 | 6 | """ 7 | 8 | from . import dds_ 9 | __all__ = ["dds_", ] 10 | -------------------------------------------------------------------------------- /communicator/idl/builtin_interfaces/msg/dds_/.idlpy_manifest: -------------------------------------------------------------------------------- 1 | Time_ 2 | 3 | Time_ 4 | -------------------------------------------------------------------------------- /communicator/idl/builtin_interfaces/msg/dds_/_Time_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.10.2 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 | -------------------------------------------------------------------------------- /communicator/idl/builtin_interfaces/msg/dds_/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.10.2 4 | Module: builtin_interfaces.msg.dds_ 5 | 6 | """ 7 | 8 | from ._Time_ import Time_ 9 | __all__ = ["Time_", ] 10 | -------------------------------------------------------------------------------- /communicator/idl/geometry_msgs/.idlpy_manifest: -------------------------------------------------------------------------------- 1 | Point32_ 2 | msg 3 | 4 | 5 | Point_ 6 | msg 7 | 8 | 9 | PointStamped_ 10 | msg 11 | 12 | 13 | Pose2D_ 14 | msg 15 | 16 | 17 | Pose_ 18 | msg 19 | 20 | 21 | PoseStamped_ 22 | msg 23 | 24 | 25 | PoseWithCovariance_ 26 | msg 27 | 28 | 29 | PoseWithCovarianceStamped_ 30 | msg 31 | 32 | 33 | Quaternion_ 34 | msg 35 | 36 | 37 | QuaternionStamped_ 38 | msg 39 | 40 | 41 | Twist_ 42 | msg 43 | 44 | 45 | TwistStamped_ 46 | msg 47 | 48 | 49 | TwistWithCovariance_ 50 | msg 51 | 52 | 53 | TwistWithCovarianceStamped_ 54 | msg 55 | 56 | 57 | Vector3_ 58 | msg 59 | 60 | -------------------------------------------------------------------------------- /communicator/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 | -------------------------------------------------------------------------------- /communicator/idl/geometry_msgs/msg/.idlpy_manifest: -------------------------------------------------------------------------------- 1 | Point32_ 2 | dds_ 3 | 4 | 5 | Point_ 6 | dds_ 7 | 8 | 9 | PointStamped_ 10 | dds_ 11 | 12 | 13 | Pose2D_ 14 | dds_ 15 | 16 | 17 | Pose_ 18 | dds_ 19 | 20 | 21 | PoseStamped_ 22 | dds_ 23 | 24 | 25 | PoseWithCovariance_ 26 | dds_ 27 | 28 | 29 | PoseWithCovarianceStamped_ 30 | dds_ 31 | 32 | 33 | Quaternion_ 34 | dds_ 35 | 36 | 37 | QuaternionStamped_ 38 | dds_ 39 | 40 | 41 | Twist_ 42 | dds_ 43 | 44 | 45 | TwistStamped_ 46 | dds_ 47 | 48 | 49 | TwistWithCovariance_ 50 | dds_ 51 | 52 | 53 | TwistWithCovarianceStamped_ 54 | dds_ 55 | 56 | 57 | Vector3_ 58 | dds_ 59 | 60 | -------------------------------------------------------------------------------- /communicator/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 | -------------------------------------------------------------------------------- /communicator/idl/geometry_msgs/msg/dds_/.idlpy_manifest: -------------------------------------------------------------------------------- 1 | Point32_ 2 | 3 | Point32_ 4 | 5 | Point_ 6 | 7 | Point_ 8 | 9 | PointStamped_ 10 | 11 | PointStamped_ 12 | 13 | Pose2D_ 14 | 15 | Pose2D_ 16 | 17 | Pose_ 18 | 19 | Pose_ 20 | 21 | PoseStamped_ 22 | 23 | PoseStamped_ 24 | 25 | PoseWithCovariance_ 26 | 27 | PoseWithCovariance_ 28 | 29 | PoseWithCovarianceStamped_ 30 | 31 | PoseWithCovarianceStamped_ 32 | 33 | Quaternion_ 34 | 35 | Quaternion_ 36 | 37 | QuaternionStamped_ 38 | 39 | QuaternionStamped_ 40 | 41 | Twist_ 42 | 43 | Twist_ 44 | 45 | TwistStamped_ 46 | 47 | TwistStamped_ 48 | 49 | TwistWithCovariance_ 50 | 51 | TwistWithCovariance_ 52 | 53 | TwistWithCovarianceStamped_ 54 | 55 | TwistWithCovarianceStamped_ 56 | 57 | Vector3_ 58 | 59 | Vector3_ 60 | -------------------------------------------------------------------------------- /communicator/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 | -------------------------------------------------------------------------------- /communicator/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 | 25 | @dataclass 26 | @annotate.final 27 | @annotate.autoid("sequential") 28 | class PointStamped_(idl.IdlStruct, typename="geometry_msgs.msg.dds_.PointStamped_"): 29 | header: 'std_msgs.msg.dds_.Header_' 30 | point: 'geometry_msgs.msg.dds_.Point_' 31 | 32 | 33 | -------------------------------------------------------------------------------- /communicator/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 | -------------------------------------------------------------------------------- /communicator/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 | -------------------------------------------------------------------------------- /communicator/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: 'std_msgs.msg.dds_.Header_' 30 | pose: 'geometry_msgs.msg.dds_.Pose_' 31 | 32 | 33 | -------------------------------------------------------------------------------- /communicator/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: 'std_msgs.msg.dds_.Header_' 30 | pose: 'geometry_msgs.msg.dds_.PoseWithCovariance_' 31 | 32 | 33 | -------------------------------------------------------------------------------- /communicator/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: 'geometry_msgs.msg.dds_.Pose_' 26 | covariance: types.array[types.float64, 36] 27 | 28 | 29 | -------------------------------------------------------------------------------- /communicator/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: 'geometry_msgs.msg.dds_.Point_' 26 | orientation: 'geometry_msgs.msg.dds_.Quaternion_' 27 | 28 | 29 | -------------------------------------------------------------------------------- /communicator/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: 'std_msgs.msg.dds_.Header_' 30 | quaternion: 'geometry_msgs.msg.dds_.Quaternion_' 31 | 32 | 33 | -------------------------------------------------------------------------------- /communicator/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 | -------------------------------------------------------------------------------- /communicator/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: 'std_msgs.msg.dds_.Header_' 30 | twist: 'geometry_msgs.msg.dds_.Twist_' 31 | 32 | 33 | -------------------------------------------------------------------------------- /communicator/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: 'std_msgs.msg.dds_.Header_' 30 | twist: 'geometry_msgs.msg.dds_.TwistWithCovariance_' 31 | 32 | 33 | -------------------------------------------------------------------------------- /communicator/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: 'geometry_msgs.msg.dds_.Twist_' 26 | covariance: types.array[types.float64, 36] 27 | 28 | 29 | -------------------------------------------------------------------------------- /communicator/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: 'geometry_msgs.msg.dds_.Vector3_' 26 | angular: 'geometry_msgs.msg.dds_.Vector3_' 27 | 28 | 29 | -------------------------------------------------------------------------------- /communicator/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 | -------------------------------------------------------------------------------- /communicator/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 | -------------------------------------------------------------------------------- /communicator/idl/std_msgs/.idlpy_manifest: -------------------------------------------------------------------------------- 1 | Header_ 2 | msg 3 | 4 | 5 | String_ 6 | msg 7 | 8 | -------------------------------------------------------------------------------- /communicator/idl/std_msgs/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.10.2 4 | Module: std_msgs 5 | 6 | """ 7 | 8 | from . import msg 9 | __all__ = ["msg", ] 10 | -------------------------------------------------------------------------------- /communicator/idl/std_msgs/msg/.idlpy_manifest: -------------------------------------------------------------------------------- 1 | Header_ 2 | dds_ 3 | 4 | 5 | String_ 6 | dds_ 7 | 8 | -------------------------------------------------------------------------------- /communicator/idl/std_msgs/msg/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.10.2 4 | Module: std_msgs.msg 5 | 6 | """ 7 | 8 | from . import dds_ 9 | __all__ = ["dds_", ] 10 | -------------------------------------------------------------------------------- /communicator/idl/std_msgs/msg/dds_/.idlpy_manifest: -------------------------------------------------------------------------------- 1 | Header_ 2 | 3 | Header_ 4 | 5 | String_ 6 | 7 | String_ 8 | -------------------------------------------------------------------------------- /communicator/idl/std_msgs/msg/dds_/_Header_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.10.2 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: 'builtin_interfaces.msg.dds_.Time_' 30 | frame_id: str 31 | 32 | 33 | -------------------------------------------------------------------------------- /communicator/idl/std_msgs/msg/dds_/_String_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.10.2 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 | -------------------------------------------------------------------------------- /communicator/idl/std_msgs/msg/dds_/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.10.2 4 | Module: std_msgs.msg.dds_ 5 | 6 | """ 7 | 8 | from ._Header_ import Header_ 9 | from ._String_ import String_ 10 | __all__ = ["Header_", "String_", ] 11 | -------------------------------------------------------------------------------- /communicator/idl/unitree_api/.idlpy_manifest: -------------------------------------------------------------------------------- 1 | RequestHeader_ 2 | msg 3 | 4 | 5 | RequestIdentity_ 6 | msg 7 | 8 | 9 | RequestLease_ 10 | msg 11 | 12 | 13 | RequestPolicy_ 14 | msg 15 | 16 | 17 | Request_ 18 | msg 19 | 20 | 21 | ResponseHeader_ 22 | msg 23 | 24 | 25 | ResponseStatus_ 26 | msg 27 | 28 | 29 | Response_ 30 | msg 31 | 32 | -------------------------------------------------------------------------------- /communicator/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 | -------------------------------------------------------------------------------- /communicator/idl/unitree_api/msg/.idlpy_manifest: -------------------------------------------------------------------------------- 1 | RequestHeader_ 2 | dds_ 3 | 4 | 5 | RequestIdentity_ 6 | dds_ 7 | 8 | 9 | RequestLease_ 10 | dds_ 11 | 12 | 13 | RequestPolicy_ 14 | dds_ 15 | 16 | 17 | Request_ 18 | dds_ 19 | 20 | 21 | ResponseHeader_ 22 | dds_ 23 | 24 | 25 | ResponseStatus_ 26 | dds_ 27 | 28 | 29 | Response_ 30 | dds_ 31 | 32 | -------------------------------------------------------------------------------- /communicator/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 | -------------------------------------------------------------------------------- /communicator/idl/unitree_api/msg/dds_/.idlpy_manifest: -------------------------------------------------------------------------------- 1 | RequestHeader_ 2 | 3 | RequestHeader_ 4 | 5 | RequestIdentity_ 6 | 7 | RequestIdentity_ 8 | 9 | RequestLease_ 10 | 11 | RequestLease_ 12 | 13 | RequestPolicy_ 14 | 15 | RequestPolicy_ 16 | 17 | Request_ 18 | 19 | Request_ 20 | 21 | ResponseHeader_ 22 | 23 | ResponseHeader_ 24 | 25 | ResponseStatus_ 26 | 27 | ResponseStatus_ 28 | 29 | Response_ 30 | 31 | Response_ 32 | -------------------------------------------------------------------------------- /communicator/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_api.msg.dds_.RequestIdentity_' 26 | lease: 'unitree_api.msg.dds_.RequestLease_' 27 | policy: 'unitree_api.msg.dds_.RequestPolicy_' 28 | 29 | 30 | -------------------------------------------------------------------------------- /communicator/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 | -------------------------------------------------------------------------------- /communicator/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 | -------------------------------------------------------------------------------- /communicator/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 | -------------------------------------------------------------------------------- /communicator/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_api.msg.dds_.RequestHeader_' 26 | parameter: str 27 | binary: types.sequence[types.uint8] 28 | 29 | 30 | -------------------------------------------------------------------------------- /communicator/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_api.msg.dds_.RequestIdentity_' 26 | status: 'unitree_api.msg.dds_.ResponseStatus_' 27 | 28 | 29 | -------------------------------------------------------------------------------- /communicator/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 | -------------------------------------------------------------------------------- /communicator/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 | 21 | @dataclass 22 | @annotate.final 23 | @annotate.autoid("sequential") 24 | class Response_(idl.IdlStruct, typename="unitree_api.msg.dds_.Response_"): 25 | header: 'unitree_api.msg.dds_.ResponseHeader_' 26 | data: str 27 | binary: types.sequence[types.uint8] 28 | 29 | 30 | -------------------------------------------------------------------------------- /communicator/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 | -------------------------------------------------------------------------------- /communicator/idl/unitree_go/.idlpy_manifest: -------------------------------------------------------------------------------- 1 | AudioData_ 2 | msg 3 | 4 | 5 | BmsCmd_ 6 | msg 7 | 8 | 9 | BmsState_ 10 | msg 11 | 12 | 13 | Error_ 14 | msg 15 | 16 | 17 | Go2FrontVideoData_ 18 | msg 19 | 20 | 21 | HeightMap_ 22 | msg 23 | 24 | 25 | IMUState_ 26 | msg 27 | 28 | 29 | InterfaceConfig_ 30 | msg 31 | 32 | 33 | LidarState_ 34 | msg 35 | 36 | 37 | LowCmd_ 38 | msg 39 | 40 | 41 | LowState_ 42 | msg 43 | 44 | 45 | MotorCmd_ 46 | msg 47 | 48 | 49 | MotorState_ 50 | msg 51 | 52 | 53 | PathPoint_ 54 | msg 55 | 56 | 57 | Req_ 58 | msg 59 | 60 | 61 | Res_ 62 | msg 63 | 64 | 65 | SportModeCmd_ 66 | msg 67 | 68 | 69 | SportModeState_ 70 | msg 71 | 72 | 73 | TimeSpec_ 74 | msg 75 | 76 | 77 | UwbState_ 78 | msg 79 | 80 | 81 | UwbSwitch_ 82 | msg 83 | 84 | 85 | WirelessController_ 86 | msg 87 | 88 | -------------------------------------------------------------------------------- /communicator/idl/unitree_go/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.10.2 4 | Module: unitree_go 5 | 6 | """ 7 | 8 | from . import msg 9 | __all__ = ["msg", ] 10 | -------------------------------------------------------------------------------- /communicator/idl/unitree_go/msg/.idlpy_manifest: -------------------------------------------------------------------------------- 1 | AudioData_ 2 | dds_ 3 | 4 | 5 | BmsCmd_ 6 | dds_ 7 | 8 | 9 | BmsState_ 10 | dds_ 11 | 12 | 13 | Error_ 14 | dds_ 15 | 16 | 17 | Go2FrontVideoData_ 18 | dds_ 19 | 20 | 21 | HeightMap_ 22 | dds_ 23 | 24 | 25 | IMUState_ 26 | dds_ 27 | 28 | 29 | InterfaceConfig_ 30 | dds_ 31 | 32 | 33 | LidarState_ 34 | dds_ 35 | 36 | 37 | LowCmd_ 38 | dds_ 39 | 40 | 41 | LowState_ 42 | dds_ 43 | 44 | 45 | MotorCmd_ 46 | dds_ 47 | 48 | 49 | MotorState_ 50 | dds_ 51 | 52 | 53 | PathPoint_ 54 | dds_ 55 | 56 | 57 | Req_ 58 | dds_ 59 | 60 | 61 | Res_ 62 | dds_ 63 | 64 | 65 | SportModeCmd_ 66 | dds_ 67 | 68 | 69 | SportModeState_ 70 | dds_ 71 | 72 | 73 | TimeSpec_ 74 | dds_ 75 | 76 | 77 | UwbState_ 78 | dds_ 79 | 80 | 81 | UwbSwitch_ 82 | dds_ 83 | 84 | 85 | WirelessController_ 86 | dds_ 87 | 88 | -------------------------------------------------------------------------------- /communicator/idl/unitree_go/msg/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.10.2 4 | Module: unitree_go.msg 5 | 6 | """ 7 | 8 | from . import dds_ 9 | __all__ = ["dds_", ] 10 | -------------------------------------------------------------------------------- /communicator/idl/unitree_go/msg/dds_/.idlpy_manifest: -------------------------------------------------------------------------------- 1 | AudioData_ 2 | 3 | AudioData_ 4 | 5 | BmsCmd_ 6 | 7 | BmsCmd_ 8 | 9 | BmsState_ 10 | 11 | BmsState_ 12 | 13 | Error_ 14 | 15 | Error_ 16 | 17 | Go2FrontVideoData_ 18 | 19 | Go2FrontVideoData_ 20 | 21 | HeightMap_ 22 | 23 | HeightMap_ 24 | 25 | IMUState_ 26 | 27 | IMUState_ 28 | 29 | InterfaceConfig_ 30 | 31 | InterfaceConfig_ 32 | 33 | LidarState_ 34 | 35 | LidarState_ 36 | 37 | LowCmd_ 38 | 39 | LowCmd_ 40 | 41 | LowState_ 42 | 43 | LowState_ 44 | 45 | MotorCmd_ 46 | 47 | MotorCmd_ 48 | 49 | MotorState_ 50 | 51 | MotorState_ 52 | 53 | PathPoint_ 54 | 55 | PathPoint_ 56 | 57 | Req_ 58 | 59 | Req_ 60 | 61 | Res_ 62 | 63 | Res_ 64 | 65 | SportModeCmd_ 66 | 67 | SportModeCmd_ 68 | 69 | SportModeState_ 70 | 71 | SportModeState_ 72 | 73 | TimeSpec_ 74 | 75 | TimeSpec_ 76 | 77 | UwbState_ 78 | 79 | UwbState_ 80 | 81 | UwbSwitch_ 82 | 83 | UwbSwitch_ 84 | 85 | WirelessController_ 86 | 87 | WirelessController_ 88 | -------------------------------------------------------------------------------- /communicator/idl/unitree_go/msg/dds_/_AudioData_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.10.2 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 | -------------------------------------------------------------------------------- /communicator/idl/unitree_go/msg/dds_/_BmsCmd_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.10.2 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 | -------------------------------------------------------------------------------- /communicator/idl/unitree_go/msg/dds_/_BmsState_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.10.2 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 | -------------------------------------------------------------------------------- /communicator/idl/unitree_go/msg/dds_/_Error_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.10.2 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 | -------------------------------------------------------------------------------- /communicator/idl/unitree_go/msg/dds_/_Go2FrontVideoData_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.10.2 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 | -------------------------------------------------------------------------------- /communicator/idl/unitree_go/msg/dds_/_HeightMap_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.10.2 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 | -------------------------------------------------------------------------------- /communicator/idl/unitree_go/msg/dds_/_IMUState_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.10.2 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 | -------------------------------------------------------------------------------- /communicator/idl/unitree_go/msg/dds_/_InterfaceConfig_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.10.2 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 | -------------------------------------------------------------------------------- /communicator/idl/unitree_go/msg/dds_/_LidarState_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.10.2 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 | -------------------------------------------------------------------------------- /communicator/idl/unitree_go/msg/dds_/_LowCmd_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.10.2 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_go.msg.dds_.MotorCmd_', 20] 32 | bms_cmd: '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 | -------------------------------------------------------------------------------- /communicator/idl/unitree_go/msg/dds_/_LowState_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.10.2 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_go.msg.dds_.IMUState_' 32 | motor_state: types.array['unitree_go.msg.dds_.MotorState_', 20] 33 | bms_state: '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 | -------------------------------------------------------------------------------- /communicator/idl/unitree_go/msg/dds_/_MotorCmd_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.10.2 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 | -------------------------------------------------------------------------------- /communicator/idl/unitree_go/msg/dds_/_MotorState_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.10.2 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 | -------------------------------------------------------------------------------- /communicator/idl/unitree_go/msg/dds_/_PathPoint_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.10.2 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 | -------------------------------------------------------------------------------- /communicator/idl/unitree_go/msg/dds_/_Req_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.10.2 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 | -------------------------------------------------------------------------------- /communicator/idl/unitree_go/msg/dds_/_Res_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.10.2 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 | -------------------------------------------------------------------------------- /communicator/idl/unitree_go/msg/dds_/_SportModeCmd_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.10.2 4 | Module: unitree_go.msg.dds_ 5 | IDL file: SportModeCmd_.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 SportModeCmd_(idl.IdlStruct, typename="unitree_go.msg.dds_.SportModeCmd_"): 25 | mode: types.uint8 26 | gait_type: types.uint8 27 | speed_level: types.uint8 28 | foot_raise_height: types.float32 29 | body_height: types.float32 30 | position: types.array[types.float32, 2] 31 | euler: types.array[types.float32, 3] 32 | velocity: types.array[types.float32, 2] 33 | yaw_speed: types.float32 34 | bms_cmd: 'unitree_go.msg.dds_.BmsCmd_' 35 | path_point: types.array['unitree_go.msg.dds_.PathPoint_', 30] 36 | 37 | 38 | -------------------------------------------------------------------------------- /communicator/idl/unitree_go/msg/dds_/_SportModeState_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.10.2 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_go.msg.dds_.TimeSpec_' 26 | error_code: types.uint32 27 | imu_state: '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_go.msg.dds_.PathPoint_', 10] 41 | 42 | 43 | -------------------------------------------------------------------------------- /communicator/idl/unitree_go/msg/dds_/_String_.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: String_.idl 6 | 7 | """ 8 | 9 | from dataclasses import dataclass 10 | from enum import auto 11 | from typing import TYPE_CHECKING, Optional 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 String_(idl.IdlStruct, typename="unitree_go.msg.dds_.String_"): 25 | data: str 26 | 27 | 28 | -------------------------------------------------------------------------------- /communicator/idl/unitree_go/msg/dds_/_TimeSpec_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.10.2 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 | -------------------------------------------------------------------------------- /communicator/idl/unitree_go/msg/dds_/_Time_.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: 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 unitree_go 19 | 20 | 21 | @dataclass 22 | @annotate.final 23 | @annotate.autoid("sequential") 24 | class Time_(idl.IdlStruct, typename="unitree_go.msg.dds_.Time_"): 25 | sec: types.int32 26 | nanosec: types.uint32 27 | 28 | 29 | -------------------------------------------------------------------------------- /communicator/idl/unitree_go/msg/dds_/_UwbState_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.10.2 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 | -------------------------------------------------------------------------------- /communicator/idl/unitree_go/msg/dds_/_UwbSwitch_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.10.2 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 | -------------------------------------------------------------------------------- /communicator/idl/unitree_go/msg/dds_/_WirelessController_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Generated by Eclipse Cyclone DDS idlc Python Backend 3 | Cyclone DDS IDL version: v0.10.2 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 | -------------------------------------------------------------------------------- /communicator/idl/unitree_go/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_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 ._PathPoint_ import PathPoint_ 22 | from ._Req_ import Req_ 23 | from ._Res_ import Res_ 24 | from ._SportModeCmd_ import SportModeCmd_ 25 | from ._SportModeState_ import SportModeState_ 26 | from ._TimeSpec_ import TimeSpec_ 27 | from ._UwbState_ import UwbState_ 28 | from ._UwbSwitch_ import UwbSwitch_ 29 | from ._WirelessController_ import WirelessController_ 30 | __all__ = ["AudioData_", "BmsCmd_", "BmsState_", "Error_", "Go2FrontVideoData_", "HeightMap_", "IMUState_", "InterfaceConfig_", "LidarState_", "LowCmd_", "LowState_", "MotorCmd_", "MotorState_", "PathPoint_", "Req_", "Res_", "SportModeCmd_", "SportModeState_", "TimeSpec_", "UwbState_", "UwbSwitch_", "WirelessController_", ] 31 | -------------------------------------------------------------------------------- /communicator/webrtc/webrtcCommunicator.py: -------------------------------------------------------------------------------- 1 | from communicator.constants import WEBRTC_TOPICS 2 | from communicator.communicatorWrapper import CommunicatorWrapper 3 | 4 | class WebRTCCommunictor(CommunicatorWrapper): 5 | def __init__(self): 6 | pass 7 | def get_topic_by_name(self, name): 8 | return WEBRTC_TOPICS[name] 9 | -------------------------------------------------------------------------------- /examples/high_level/sportmode_commands_test.py: -------------------------------------------------------------------------------- 1 | # Add clients and communicator directory to sys path 2 | import sys, os 3 | sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..')) 4 | 5 | import asyncio 6 | import logging 7 | from communicator.cyclonedds.ddsCommunicator import DDSCommunicator 8 | from clients.sport_client import SportClient 9 | 10 | logging.basicConfig(level=logging.INFO) # Set the desired level 11 | 12 | async def main(): 13 | communicator = DDSCommunicator(interface="eth0") 14 | client = SportClient(communicator) 15 | 16 | #awaiting for response 17 | await client.Dance1(ack=True) 18 | 19 | #not awaiting for response 20 | await client.FrontPounce(ack=False) 21 | 22 | # change Gait, no response 23 | await client.SwitchGait(0) # 0 is idle, 1 is trot, 2 is trot running, 3 is forward climbing mode, and 4 is reverse climbing mode. 24 | 25 | ### TODO add more examples here 26 | 27 | 28 | # Usage example 29 | if __name__ == "__main__": 30 | asyncio.run(main()) -------------------------------------------------------------------------------- /examples/high_level/sportmode_getstate_test.py: -------------------------------------------------------------------------------- 1 | # Add clients and communicator directory to sys path 2 | import sys, os 3 | sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..')) 4 | 5 | import asyncio 6 | import logging 7 | from communicator.cyclonedds.ddsCommunicator import DDSCommunicator 8 | from clients.sport_client import SportClient 9 | 10 | logging.basicConfig(level=logging.WARNING) # Set the desired level 11 | 12 | async def main(): 13 | communicator = DDSCommunicator(interface="eth0") 14 | client = SportClient(communicator) 15 | 16 | while True: 17 | try: 18 | parameters = ["state", "gait", "dance", "continuousGait", "economicGait"] 19 | result = await client.GetState(parameters) 20 | if result: 21 | print("Robot state parameters retrieved successfully:") 22 | for param, value in result.items(): 23 | print(f"{param}: {value}") 24 | except Exception as e: 25 | print(f"Failed to retrieve robot state parameters: {e}") 26 | 27 | await asyncio.sleep(1) 28 | 29 | 30 | # Usage example 31 | if __name__ == "__main__": 32 | asyncio.run(main()) 33 | -------------------------------------------------------------------------------- /examples/high_level/sportmode_swith_test.py: -------------------------------------------------------------------------------- 1 | # Add clients and communicator directory to sys path 2 | import sys, os 3 | sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..')) 4 | 5 | import asyncio 6 | import logging 7 | from communicator.cyclonedds.ddsCommunicator import DDSCommunicator 8 | from clients.motion_switcher_client import MotionSwitcher 9 | 10 | logging.basicConfig(level=logging.INFO) # Set the desired level 11 | 12 | async def main(): 13 | communicator = DDSCommunicator(interface="eth0") 14 | client = MotionSwitcher(communicator) 15 | 16 | # Read the current sport mode (normal or advanced) 17 | response = await client.getSportMode() 18 | if response: 19 | print(response) 20 | 21 | # Switch the sport mode to advanced 22 | await client.setSportMode("advanced") 23 | 24 | #Switch the sport mode to normal 25 | await client.setSportMode("normal") 26 | 27 | 28 | # Usage example 29 | if __name__ == "__main__": 30 | asyncio.run(main()) -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | cyclonedds==0.10.2 --------------------------------------------------------------------------------