holosoma-inference 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- holosoma_inference-0.1.0/PKG-INFO +39 -0
- holosoma_inference-0.1.0/README.md +227 -0
- holosoma_inference-0.1.0/holosoma_inference/__init__.py +0 -0
- holosoma_inference-0.1.0/holosoma_inference/compat.py +10 -0
- holosoma_inference-0.1.0/holosoma_inference/config/__init__.py +11 -0
- holosoma_inference-0.1.0/holosoma_inference/config/config_types/__init__.py +13 -0
- holosoma_inference-0.1.0/holosoma_inference/config/config_types/inference.py +33 -0
- holosoma_inference-0.1.0/holosoma_inference/config/config_types/observation.py +53 -0
- holosoma_inference-0.1.0/holosoma_inference/config/config_types/robot.py +236 -0
- holosoma_inference-0.1.0/holosoma_inference/config/config_types/task.py +212 -0
- holosoma_inference-0.1.0/holosoma_inference/config/config_values/__init__.py +10 -0
- holosoma_inference-0.1.0/holosoma_inference/config/config_values/inference.py +120 -0
- holosoma_inference-0.1.0/holosoma_inference/config/config_values/observation.py +161 -0
- holosoma_inference-0.1.0/holosoma_inference/config/config_values/robot.py +264 -0
- holosoma_inference-0.1.0/holosoma_inference/config/config_values/task.py +67 -0
- holosoma_inference-0.1.0/holosoma_inference/config/tests/__init__.py +0 -0
- holosoma_inference-0.1.0/holosoma_inference/config/tests/test_task_config.py +123 -0
- holosoma_inference-0.1.0/holosoma_inference/config/utils.py +3 -0
- holosoma_inference-0.1.0/holosoma_inference/inputs/__init__.py +52 -0
- holosoma_inference-0.1.0/holosoma_inference/inputs/api/__init__.py +0 -0
- holosoma_inference-0.1.0/holosoma_inference/inputs/api/base.py +51 -0
- holosoma_inference-0.1.0/holosoma_inference/inputs/api/commands.py +61 -0
- holosoma_inference-0.1.0/holosoma_inference/inputs/impl/__init__.py +0 -0
- holosoma_inference-0.1.0/holosoma_inference/inputs/impl/interface.py +90 -0
- holosoma_inference-0.1.0/holosoma_inference/inputs/impl/joystick.py +27 -0
- holosoma_inference-0.1.0/holosoma_inference/inputs/impl/keyboard.py +176 -0
- holosoma_inference-0.1.0/holosoma_inference/inputs/impl/ros2.py +122 -0
- holosoma_inference-0.1.0/holosoma_inference/inputs/impl/usb_joystick.py +273 -0
- holosoma_inference-0.1.0/holosoma_inference/inputs/tests/__init__.py +0 -0
- holosoma_inference-0.1.0/holosoma_inference/inputs/tests/conftest.py +86 -0
- holosoma_inference-0.1.0/holosoma_inference/inputs/tests/test_dual_mode.py +81 -0
- holosoma_inference-0.1.0/holosoma_inference/inputs/tests/test_factory.py +155 -0
- holosoma_inference-0.1.0/holosoma_inference/inputs/tests/test_joystick.py +141 -0
- holosoma_inference-0.1.0/holosoma_inference/inputs/tests/test_keyboard.py +119 -0
- holosoma_inference-0.1.0/holosoma_inference/inputs/tests/test_providers.py +1155 -0
- holosoma_inference-0.1.0/holosoma_inference/inputs/tests/test_ros2.py +120 -0
- holosoma_inference-0.1.0/holosoma_inference/policies/__init__.py +6 -0
- holosoma_inference-0.1.0/holosoma_inference/policies/base.py +863 -0
- holosoma_inference-0.1.0/holosoma_inference/policies/dual_mode.py +195 -0
- holosoma_inference-0.1.0/holosoma_inference/policies/locomotion.py +122 -0
- holosoma_inference-0.1.0/holosoma_inference/policies/tests/__init__.py +1 -0
- holosoma_inference-0.1.0/holosoma_inference/policies/tests/test_select_policy_class.py +111 -0
- holosoma_inference-0.1.0/holosoma_inference/policies/tests/test_wbt_utils.py +250 -0
- holosoma_inference-0.1.0/holosoma_inference/policies/wbt.py +474 -0
- holosoma_inference-0.1.0/holosoma_inference/policies/wbt_utils.py +161 -0
- holosoma_inference-0.1.0/holosoma_inference/py.typed +0 -0
- holosoma_inference-0.1.0/holosoma_inference/run_policy.py +228 -0
- holosoma_inference-0.1.0/holosoma_inference/sdk/__init__.py +33 -0
- holosoma_inference-0.1.0/holosoma_inference/sdk/base/__init__.py +0 -0
- holosoma_inference-0.1.0/holosoma_inference/sdk/base/base_interface.py +186 -0
- holosoma_inference-0.1.0/holosoma_inference/sdk/booster/__init__.py +0 -0
- holosoma_inference-0.1.0/holosoma_inference/sdk/booster/booster_interface.py +102 -0
- holosoma_inference-0.1.0/holosoma_inference/sdk/booster/command_sender/__init__.py +34 -0
- holosoma_inference-0.1.0/holosoma_inference/sdk/booster/command_sender/base/__init__.py +9 -0
- holosoma_inference-0.1.0/holosoma_inference/sdk/booster/command_sender/base/basic_command_sender.py +121 -0
- holosoma_inference-0.1.0/holosoma_inference/sdk/booster/command_sender/booster/__init__.py +7 -0
- holosoma_inference-0.1.0/holosoma_inference/sdk/booster/command_sender/booster/booster_command_sender.py +106 -0
- holosoma_inference-0.1.0/holosoma_inference/sdk/booster/command_sender/booster/joystick_message.py +25 -0
- holosoma_inference-0.1.0/holosoma_inference/sdk/booster/command_sender/booster/remote_control_service.py +311 -0
- holosoma_inference-0.1.0/holosoma_inference/sdk/booster/state_processor/__init__.py +36 -0
- holosoma_inference-0.1.0/holosoma_inference/sdk/booster/state_processor/base/__init__.py +9 -0
- holosoma_inference-0.1.0/holosoma_inference/sdk/booster/state_processor/base/basic_state_processor.py +57 -0
- holosoma_inference-0.1.0/holosoma_inference/sdk/booster/state_processor/booster/__init__.py +7 -0
- holosoma_inference-0.1.0/holosoma_inference/sdk/booster/state_processor/booster/booster_state_processor.py +64 -0
- holosoma_inference-0.1.0/holosoma_inference/sdk/unitree/__init__.py +0 -0
- holosoma_inference-0.1.0/holosoma_inference/sdk/unitree/unitree_interface.py +135 -0
- holosoma_inference-0.1.0/holosoma_inference/sdk/unitree/unitree_interface_mp.py +212 -0
- holosoma_inference-0.1.0/holosoma_inference/sdk/unitree_high_level/__init__.py +37 -0
- holosoma_inference-0.1.0/holosoma_inference/sdk/unitree_high_level/arm_client/__init__.py +3 -0
- holosoma_inference-0.1.0/holosoma_inference/sdk/unitree_high_level/arm_client/arm_client.py +351 -0
- holosoma_inference-0.1.0/holosoma_inference/sdk/unitree_high_level/arm_client/const.py +236 -0
- holosoma_inference-0.1.0/holosoma_inference/sdk/unitree_high_level/loco_client/__init__.py +3 -0
- holosoma_inference-0.1.0/holosoma_inference/sdk/unitree_high_level/loco_client/loco_client.py +104 -0
- holosoma_inference-0.1.0/holosoma_inference/sdk/unitree_high_level/multiprocess_proxy/__init__.py +3 -0
- holosoma_inference-0.1.0/holosoma_inference/sdk/unitree_high_level/multiprocess_proxy/multiprocess_proxy.py +116 -0
- holosoma_inference-0.1.0/holosoma_inference/sensors/__init__.py +0 -0
- holosoma_inference-0.1.0/holosoma_inference/sensors/base.py +33 -0
- holosoma_inference-0.1.0/holosoma_inference/utils/__init__.py +0 -0
- holosoma_inference-0.1.0/holosoma_inference/utils/clock.py +141 -0
- holosoma_inference-0.1.0/holosoma_inference/utils/latency.py +118 -0
- holosoma_inference-0.1.0/holosoma_inference/utils/math/__init__.py +29 -0
- holosoma_inference-0.1.0/holosoma_inference/utils/math/misc.py +6 -0
- holosoma_inference-0.1.0/holosoma_inference/utils/math/quat.py +133 -0
- holosoma_inference-0.1.0/holosoma_inference/utils/misc.py +33 -0
- holosoma_inference-0.1.0/holosoma_inference/utils/network.py +22 -0
- holosoma_inference-0.1.0/holosoma_inference/utils/rate.py +130 -0
- holosoma_inference-0.1.0/holosoma_inference/utils/wandb.py +120 -0
- holosoma_inference-0.1.0/holosoma_inference.egg-info/PKG-INFO +39 -0
- holosoma_inference-0.1.0/holosoma_inference.egg-info/SOURCES.txt +93 -0
- holosoma_inference-0.1.0/holosoma_inference.egg-info/dependency_links.txt +1 -0
- holosoma_inference-0.1.0/holosoma_inference.egg-info/entry_points.txt +13 -0
- holosoma_inference-0.1.0/holosoma_inference.egg-info/requires.txt +31 -0
- holosoma_inference-0.1.0/holosoma_inference.egg-info/top_level.txt +1 -0
- holosoma_inference-0.1.0/setup.cfg +4 -0
- holosoma_inference-0.1.0/setup.py +71 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: holosoma-inference
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: holosoma-inference: inference components for humanoid robot policies
|
|
5
|
+
Author: Amazon FAR Team
|
|
6
|
+
Keywords: humanoid robotics inference policy onnx
|
|
7
|
+
Requires-Python: >=3.8
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
Requires-Dist: pydantic
|
|
10
|
+
Requires-Dist: loguru
|
|
11
|
+
Requires-Dist: netifaces
|
|
12
|
+
Requires-Dist: onnx
|
|
13
|
+
Requires-Dist: onnxruntime
|
|
14
|
+
Requires-Dist: scipy
|
|
15
|
+
Requires-Dist: sshkeyboard
|
|
16
|
+
Requires-Dist: termcolor
|
|
17
|
+
Requires-Dist: pyyaml
|
|
18
|
+
Requires-Dist: tyro>=0.10.0a4
|
|
19
|
+
Requires-Dist: wandb
|
|
20
|
+
Requires-Dist: zmq
|
|
21
|
+
Requires-Dist: defusedxml
|
|
22
|
+
Requires-Dist: evdev
|
|
23
|
+
Requires-Dist: importlib_metadata>=4.6; python_version < "3.12"
|
|
24
|
+
Requires-Dist: eval_type_backport; python_version < "3.10"
|
|
25
|
+
Provides-Extra: dev
|
|
26
|
+
Requires-Dist: pytest>=6.0; extra == "dev"
|
|
27
|
+
Requires-Dist: black>=22.0; extra == "dev"
|
|
28
|
+
Requires-Dist: flake8>=4.0; extra == "dev"
|
|
29
|
+
Provides-Extra: unitree
|
|
30
|
+
Requires-Dist: far-unitree-sdk==0.1.4; extra == "unitree"
|
|
31
|
+
Provides-Extra: booster
|
|
32
|
+
Requires-Dist: far-booster-sdk==0.1.0; extra == "booster"
|
|
33
|
+
Dynamic: author
|
|
34
|
+
Dynamic: description-content-type
|
|
35
|
+
Dynamic: keywords
|
|
36
|
+
Dynamic: provides-extra
|
|
37
|
+
Dynamic: requires-dist
|
|
38
|
+
Dynamic: requires-python
|
|
39
|
+
Dynamic: summary
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
# Holosoma Inference
|
|
2
|
+
|
|
3
|
+
Policy inference for humanoid robot policies.
|
|
4
|
+
|
|
5
|
+
## Supported Policies
|
|
6
|
+
|
|
7
|
+
| Robot | Locomotion | WBT |
|
|
8
|
+
|:----------:|:----------:|:---:|
|
|
9
|
+
| Unitree G1 | ✅ | ✅ |
|
|
10
|
+
| Booster T1 | ✅ | ❌ |
|
|
11
|
+
|
|
12
|
+
| Simulator | Locomotion | WBT |
|
|
13
|
+
|:-----------------------:|:----------:|:---:|
|
|
14
|
+
| IsaacGym | ✅ | ❌ |
|
|
15
|
+
| IsaacSim | ✅ | ✅ |
|
|
16
|
+
| MuJoCo (inference only) | ✅ | ✅ |
|
|
17
|
+
|
|
18
|
+
- ✅ (full support)
|
|
19
|
+
- 🚧 (in progress/partial support)
|
|
20
|
+
- ❌ (no support)
|
|
21
|
+
|
|
22
|
+
## Quick Start
|
|
23
|
+
|
|
24
|
+
### Setup the Environment
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
cd ~/holosoma
|
|
28
|
+
bash scripts/setup_inference.sh # Create a virtual environment with all dependencies
|
|
29
|
+
source scripts/source_inference_setup.sh # Activate the virtual environment
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Choose Your Workflow
|
|
33
|
+
|
|
34
|
+
Select the appropriate workflow guide based on your setup:
|
|
35
|
+
|
|
36
|
+
#### Real Robot Deployment
|
|
37
|
+
- **[Real Robot Locomotion](docs/workflows/real-robot-locomotion.md)** - Run locomotion policies on physical Unitree G1 or Booster T1 robots
|
|
38
|
+
- **[Real Robot Whole Body Tracking](docs/workflows/real-robot-wbt.md)** - Run WBT policies on physical Unitree G1 robots
|
|
39
|
+
|
|
40
|
+
#### Simulation (MuJoCo)
|
|
41
|
+
- **[Sim-to-Sim Locomotion](docs/workflows/sim-to-sim-locomotion.md)** - Test locomotion policies in MuJoCo simulation
|
|
42
|
+
- **[Sim-to-Sim Whole Body Tracking](docs/workflows/sim-to-sim-wbt.md)** - Test WBT policies in MuJoCo simulation
|
|
43
|
+
|
|
44
|
+
Each workflow guide includes:
|
|
45
|
+
- Hardware/environment setup instructions
|
|
46
|
+
- Step-by-step commands
|
|
47
|
+
- Control references
|
|
48
|
+
- Deployment options (offboard/onboard/Docker)
|
|
49
|
+
- Troubleshooting tips
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
# Policy Controls
|
|
54
|
+
|
|
55
|
+
Commands for controlling policies during execution.
|
|
56
|
+
|
|
57
|
+
**Important**: All policy controls that use keyboard should be entered in the **policy terminal** (where you ran `run_policy.py`), not in the MuJoCo window. MuJoCo has separate controls for simulation (see workflow docs).
|
|
58
|
+
|
|
59
|
+
## General Controls
|
|
60
|
+
|
|
61
|
+
| Action | Keyboard | Joystick |
|
|
62
|
+
|--------|----------|----------|
|
|
63
|
+
| Start the policy | `]` | A button |
|
|
64
|
+
| Stop the policy | `o` | B button |
|
|
65
|
+
| Set robot to default pose | `i` | Y button |
|
|
66
|
+
| Kill controller program | - | L1 (LB) + R1 (RB) |
|
|
67
|
+
|
|
68
|
+
## Locomotion (Velocity Tracking)
|
|
69
|
+
|
|
70
|
+
| Action | Keyboard | Joystick |
|
|
71
|
+
|--------|----------|----------|
|
|
72
|
+
| Switch walking/standing | `=` | Start button |
|
|
73
|
+
| Adjust linear velocity | `w` `a` `s` `d` | Left stick |
|
|
74
|
+
| Adjust angular velocity | `q` `e` | Right stick |
|
|
75
|
+
|
|
76
|
+
**Default pose**: Standing pose
|
|
77
|
+
|
|
78
|
+
## Whole-Body Tracking
|
|
79
|
+
|
|
80
|
+
| Action | Keyboard | Joystick |
|
|
81
|
+
|--------|----------|----------|
|
|
82
|
+
| Start the policy | `]` | A button |
|
|
83
|
+
| Start motion clip | `m` | Select+A |
|
|
84
|
+
|
|
85
|
+
**Default pose**: Standing with raised arms
|
|
86
|
+
|
|
87
|
+
## Joystick-Only Features
|
|
88
|
+
|
|
89
|
+
- **Select button**: Switch between policies (when multiple policies are loaded)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
# Configuration Overrides
|
|
93
|
+
|
|
94
|
+
## Loading ONNX Checkpoints from Wandb
|
|
95
|
+
|
|
96
|
+
You can load ONNX checkpoints directly from Wandb without manually downloading them first. This is useful for quickly testing models from training runs.
|
|
97
|
+
|
|
98
|
+
**Syntax:**
|
|
99
|
+
```bash
|
|
100
|
+
--task.model-path wandb://entity/project_name/run_id/model.onnx
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
**Example with G1 locomotion:**
|
|
104
|
+
```bash
|
|
105
|
+
source scripts/source_inference_setup.sh
|
|
106
|
+
python3 src/holosoma_inference/holosoma_inference/run_policy.py inference:g1-29dof-loco \
|
|
107
|
+
--task.model-path wandb://my-username/my-project/run-abc123/fastsac_g1_29dof.onnx \
|
|
108
|
+
--task.use-joystick \
|
|
109
|
+
--task.interface eth0
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
**Example with Wandb HTTPS URL:**
|
|
113
|
+
```bash
|
|
114
|
+
python3 src/holosoma_inference/holosoma_inference/run_policy.py inference:g1-29dof-loco \
|
|
115
|
+
--task.model-path https://wandb.ai/username/project/runs/abc123/files/model.onnx \
|
|
116
|
+
--task.use-joystick \
|
|
117
|
+
--task.interface eth0
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
The model will be automatically downloaded and cached locally. The entity is your Wandb username or organization name.
|
|
121
|
+
|
|
122
|
+
## Finding Your Network Interface
|
|
123
|
+
|
|
124
|
+
The `--task.interface` parameter specifies which network interface to use for communicating with the robot. The correct interface name varies by computer and network card.
|
|
125
|
+
|
|
126
|
+
**Common interface names:**
|
|
127
|
+
- `eth0` - Common Ethernet interface name
|
|
128
|
+
- `enp0s31f6` - Modern Linux Ethernet naming
|
|
129
|
+
- `lo` - Loopback interface (for sim2sim)
|
|
130
|
+
|
|
131
|
+
**To find your interface name:**
|
|
132
|
+
```bash
|
|
133
|
+
ifconfig
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Look for the interface connected to your robot's network. For real robot deployments, use the interface with an IP address on the same subnet as your robot. For sim2sim deployments, use `lo` (loopback).
|
|
137
|
+
|
|
138
|
+
## Observation History Length (> 1)
|
|
139
|
+
|
|
140
|
+
If a policy was trained with stacked observations (e.g., history length 4), you must pass the same history length at inference time so the observation tensor matches the model's expected input size.
|
|
141
|
+
|
|
142
|
+
Example:
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
python3 src/holosoma_inference/holosoma_inference/run_policy.py inference:g1-29dof-wbt \
|
|
146
|
+
--task.model-path <path-to-model>.onnx \
|
|
147
|
+
--task.interface eth0 \
|
|
148
|
+
--observation.history_length_dict.actor_obs=4
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
The override updates the `actor_obs` buffer before the ONNX session is initialized, so any policy (locomotion or WBT) can run with longer observation histories as long as the underlying model was trained that way.
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
## Input Sources
|
|
155
|
+
|
|
156
|
+
The policy supports two independent input channels that can each be set to `keyboard`, `joystick`, or `ros2`:
|
|
157
|
+
|
|
158
|
+
| Channel | What it controls | CLI flag |
|
|
159
|
+
|---------|-----------------|----------|
|
|
160
|
+
| `velocity_input` | Continuous velocity commands (linear/angular) | `--task.velocity-input` |
|
|
161
|
+
| `state_input` | Discrete commands: start/stop, walk/stand, kp tuning, policy switching | `--task.state-input` |
|
|
162
|
+
|
|
163
|
+
### Shortcuts (backwards compatible)
|
|
164
|
+
|
|
165
|
+
For the common case where both channels use the same source:
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
--task.use-joystick # Sets both channels to joystick
|
|
169
|
+
--task.use-keyboard # Sets both channels to keyboard (this is the default)
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Mixed input examples
|
|
173
|
+
|
|
174
|
+
**ROS2 `cmd_vel` with keyboard commands** — velocity from ROS2, operator uses keyboard for start/stop:
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
python3 src/holosoma_inference/holosoma_inference/run_policy.py inference:g1-29dof-loco \
|
|
178
|
+
--task.model-path <path-to-model>.onnx \
|
|
179
|
+
--task.velocity-input ros2 \
|
|
180
|
+
--task.state-input keyboard \
|
|
181
|
+
--task.interface eth0
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
**Fully autonomous** — both channels from ROS2:
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
python3 src/holosoma_inference/holosoma_inference/run_policy.py inference:g1-29dof-loco \
|
|
188
|
+
--task.model-path <path-to-model>.onnx \
|
|
189
|
+
--task.velocity-input ros2 \
|
|
190
|
+
--task.state-input ros2 \
|
|
191
|
+
--task.interface eth0
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### ROS2 topics
|
|
195
|
+
|
|
196
|
+
| Topic | Message type | Channel | Description |
|
|
197
|
+
|-------|-------------|---------|-------------|
|
|
198
|
+
| `cmd_vel` | `geometry_msgs/TwistStamped` | `velocity_input` | Linear (x, y) and angular (z) velocity, clamped to [-1, 1] |
|
|
199
|
+
| `holosoma/state_input` | `std_msgs/String` | `state_input` | Text commands: `walk`, `stand`, `start`, `stop`, `init` |
|
|
200
|
+
|
|
201
|
+
Topic names are configurable via `--task.ros-cmd-vel-topic` and `--task.ros-state-input-topic`.
|
|
202
|
+
|
|
203
|
+
**Note**: Shortcut flags (`--task.use-joystick`, `--task.use-keyboard`) cannot be combined with `--task.velocity-input` or `--task.state-input`.
|
|
204
|
+
|
|
205
|
+
## Overriding Control Gains
|
|
206
|
+
|
|
207
|
+
By default, control gains (kp/kd) are loaded from ONNX model metadata. You can override these values in your configuration:
|
|
208
|
+
|
|
209
|
+
### G1 29-DOF with Custom Control Gains
|
|
210
|
+
|
|
211
|
+
```bash
|
|
212
|
+
python3 src/holosoma_inference/holosoma_inference/run_policy.py inference:g1-29dof-loco \
|
|
213
|
+
--task.model-path src/holosoma_inference/holosoma_inference/models/loco/g1_29dof/fastsac_g1_29dof.onnx \
|
|
214
|
+
--robot.motor-kp 40.2 99.1 40.2 99.1 28.5 28.5 40.2 99.1 40.2 99.1 28.5 28.5 40.2 28.5 28.5 14.3 14.3 14.3 14.3 14.3 16.8 16.8 14.3 14.3 14.3 14.3 14.3 16.8 16.8 \
|
|
215
|
+
--robot.motor-kd 2.6 6.3 2.6 6.3 1.8 1.8 2.6 6.3 2.6 6.3 1.8 1.8 2.6 1.8 1.8 0.9 0.9 0.9 0.9 0.9 1.1 1.1 0.9 0.9 0.9 0.9 0.9 1.1 1.1
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### T1 29-DOF with Custom Control Gains
|
|
219
|
+
|
|
220
|
+
```bash
|
|
221
|
+
python3 src/holosoma_inference/holosoma_inference/run_policy.py inference:t1-29dof-loco \
|
|
222
|
+
--task.model-path src/holosoma_inference/holosoma_inference/models/loco/t1_29dof/ppo_t1_29dof.onnx \
|
|
223
|
+
--robot.motor-kp 5.0 5.0 20.0 20.0 20.0 20.0 20.0 20.0 20.0 20.0 20.0 20.0 20.0 20.0 20.0 20.0 200.0 200.0 200.0 200.0 200.0 50.0 50.0 200.0 200.0 200.0 200.0 50.0 50.0 \
|
|
224
|
+
--robot.motor-kd 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 5.0 5.0 5.0 5.0 5.0 3.0 3.0 5.0 5.0 5.0 5.0 3.0 3.0
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
**Note**: When control gains are not specified, they will be automatically loaded from the ONNX model metadata. This is the recommended approach as it ensures the gains match those used during training.
|
|
File without changes
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"""Tyro-based configuration system for holosoma_inference.
|
|
2
|
+
|
|
3
|
+
This module provides a type-safe configuration system using Pydantic dataclasses and Tyro CLI.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from . import config_types, config_values
|
|
7
|
+
|
|
8
|
+
__all__ = [
|
|
9
|
+
"config_types",
|
|
10
|
+
"config_values",
|
|
11
|
+
]
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"""Type definitions for holosoma_inference configuration system."""
|
|
2
|
+
|
|
3
|
+
from .inference import InferenceConfig
|
|
4
|
+
from .observation import ObservationConfig
|
|
5
|
+
from .robot import RobotConfig
|
|
6
|
+
from .task import TaskConfig
|
|
7
|
+
|
|
8
|
+
__all__ = [
|
|
9
|
+
"InferenceConfig",
|
|
10
|
+
"ObservationConfig",
|
|
11
|
+
"RobotConfig",
|
|
12
|
+
"TaskConfig",
|
|
13
|
+
]
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"""Top-level inference configuration types for holosoma_inference."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from pydantic.dataclasses import dataclass
|
|
6
|
+
|
|
7
|
+
from .observation import ObservationConfig
|
|
8
|
+
from .robot import RobotConfig
|
|
9
|
+
from .task import TaskConfig
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@dataclass(frozen=True)
|
|
13
|
+
class InferenceConfig:
|
|
14
|
+
"""Top-level configuration for policy inference.
|
|
15
|
+
|
|
16
|
+
Combines robot, observation, and task configurations
|
|
17
|
+
for running policies on real robots or in simulation.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
robot: RobotConfig
|
|
21
|
+
"""Robot hardware and control configuration."""
|
|
22
|
+
|
|
23
|
+
observation: ObservationConfig
|
|
24
|
+
"""Observation space configuration."""
|
|
25
|
+
|
|
26
|
+
task: TaskConfig
|
|
27
|
+
"""Task execution configuration."""
|
|
28
|
+
|
|
29
|
+
secondary: InferenceConfig | None = None
|
|
30
|
+
"""Secondary policy config for dual-mode (X-button switch).
|
|
31
|
+
When set, enables runtime switching between this (primary) policy and the secondary.
|
|
32
|
+
Override any field: --secondary.task.model-path, --secondary.task.rl-rate, etc.
|
|
33
|
+
Set to None to disable dual-mode."""
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"""Observation configuration types for holosoma_inference."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from pydantic.dataclasses import dataclass
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@dataclass(frozen=True)
|
|
9
|
+
class ObservationConfig:
|
|
10
|
+
"""Observation space configuration.
|
|
11
|
+
|
|
12
|
+
Defines which observations are used, their dimensions,
|
|
13
|
+
scaling factors, history lengths, etc. for policy inference.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
obs_dict: dict[str, list[str]]
|
|
17
|
+
"""Maps observation group names to lists of observation components.
|
|
18
|
+
|
|
19
|
+
Each key represents an observation group (e.g., "actor_obs", "critic_obs"),
|
|
20
|
+
and each value is a list of observation component names that belong to that group.
|
|
21
|
+
|
|
22
|
+
Example:
|
|
23
|
+
{"actor_obs": ["base_ang_vel", "projected_gravity", "dof_pos"]}
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
obs_dims: dict[str, int]
|
|
27
|
+
"""Dimension of each observation component.
|
|
28
|
+
|
|
29
|
+
Maps each observation component name to its dimensionality.
|
|
30
|
+
|
|
31
|
+
Example:
|
|
32
|
+
{"base_ang_vel": 3, "dof_pos": 29, "actions": 29}
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
obs_scales: dict[str, float]
|
|
36
|
+
"""Scaling factor applied to each observation component.
|
|
37
|
+
|
|
38
|
+
Maps each observation component name to a scaling factor that will be
|
|
39
|
+
multiplied with the raw observation values during preprocessing.
|
|
40
|
+
|
|
41
|
+
Example:
|
|
42
|
+
{"base_ang_vel": 0.25, "dof_vel": 0.05, "projected_gravity": 1.0}
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
history_length_dict: dict[str, int]
|
|
46
|
+
"""Number of timesteps to keep in history for each observation group.
|
|
47
|
+
|
|
48
|
+
Maps each observation group name to the number of historical timesteps
|
|
49
|
+
to maintain. A value of 1 means only the current observation is used.
|
|
50
|
+
|
|
51
|
+
Example:
|
|
52
|
+
{"actor_obs": 1, "critic_obs": 3}
|
|
53
|
+
"""
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
"""Robot configuration types for holosoma_inference."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import typing
|
|
6
|
+
from typing import Any
|
|
7
|
+
|
|
8
|
+
from pydantic.dataclasses import dataclass
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@dataclass(frozen=True)
|
|
12
|
+
class RobotConfig:
|
|
13
|
+
"""Robot hardware and control configuration.
|
|
14
|
+
|
|
15
|
+
Defines all robot-specific parameters including kinematics,
|
|
16
|
+
control gains, limits, and SDK configuration.
|
|
17
|
+
|
|
18
|
+
Examples
|
|
19
|
+
--------
|
|
20
|
+
G1 29-DOF robot configuration:
|
|
21
|
+
>>> robot_config = RobotConfig(
|
|
22
|
+
... robot_type="g1_29dof",
|
|
23
|
+
... robot="g1",
|
|
24
|
+
... num_motors=29,
|
|
25
|
+
... num_joints=29,
|
|
26
|
+
... default_dof_angles=(...), # 29 values
|
|
27
|
+
... motor_kp=(...), # 29 values
|
|
28
|
+
... # ... other required fields
|
|
29
|
+
... )
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
# =========================================================================
|
|
33
|
+
# Identity (REQUIRED - no defaults)
|
|
34
|
+
# =========================================================================
|
|
35
|
+
|
|
36
|
+
robot_type: str
|
|
37
|
+
"""Robot identifier (e.g., 'g1_29dof', 't1_29dof')."""
|
|
38
|
+
|
|
39
|
+
robot: str
|
|
40
|
+
"""Robot family name (e.g., 'g1', 't1')."""
|
|
41
|
+
|
|
42
|
+
# =========================================================================
|
|
43
|
+
# Default Positions (REQUIRED - immutable tuples, no defaults)
|
|
44
|
+
# =========================================================================
|
|
45
|
+
|
|
46
|
+
default_dof_angles: tuple[float, ...]
|
|
47
|
+
"""Default joint angles in radians (length: num_joints).
|
|
48
|
+
|
|
49
|
+
These are the target positions when the robot is in its default standing pose.
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
default_motor_angles: tuple[float, ...]
|
|
53
|
+
"""Default motor angles in radians (length: num_motors).
|
|
54
|
+
|
|
55
|
+
Typically identical to default_dof_angles unless there's a motor-to-joint mapping.
|
|
56
|
+
"""
|
|
57
|
+
|
|
58
|
+
# =========================================================================
|
|
59
|
+
# Mappings (REQUIRED - no defaults)
|
|
60
|
+
# =========================================================================
|
|
61
|
+
|
|
62
|
+
motor2joint: tuple[int, ...]
|
|
63
|
+
"""Motor index to joint index mapping (length: num_motors).
|
|
64
|
+
|
|
65
|
+
Maps motor indices to their corresponding joint indices.
|
|
66
|
+
For most robots, this is an identity mapping [0, 1, 2, ..., n-1].
|
|
67
|
+
"""
|
|
68
|
+
|
|
69
|
+
joint2motor: tuple[int, ...]
|
|
70
|
+
"""Joint index to motor index mapping (length: num_joints).
|
|
71
|
+
|
|
72
|
+
Inverse of motor2joint mapping.
|
|
73
|
+
"""
|
|
74
|
+
|
|
75
|
+
dof_names: tuple[str, ...]
|
|
76
|
+
"""Joint names in order (length: num_joints).
|
|
77
|
+
|
|
78
|
+
Example: ('left_hip_pitch_joint', 'left_hip_roll_joint', ...)
|
|
79
|
+
"""
|
|
80
|
+
|
|
81
|
+
# =========================================================================
|
|
82
|
+
# Deprecation candidates with no defaults
|
|
83
|
+
# =========================================================================
|
|
84
|
+
|
|
85
|
+
dof_names_upper_body: tuple[str, ...]
|
|
86
|
+
"""Upper body joint names (length: num_upper_body_joints).
|
|
87
|
+
|
|
88
|
+
Subset of dof_names containing only upper body joints.
|
|
89
|
+
"""
|
|
90
|
+
|
|
91
|
+
dof_names_lower_body: tuple[str, ...]
|
|
92
|
+
"""Lower body joint names (length: num_joints - num_upper_body_joints).
|
|
93
|
+
|
|
94
|
+
Subset of dof_names containing only lower body joints (legs + waist).
|
|
95
|
+
"""
|
|
96
|
+
|
|
97
|
+
# =========================================================================
|
|
98
|
+
# Control Gains (OPTIONAL - can be loaded from ONNX metadata)
|
|
99
|
+
# =========================================================================
|
|
100
|
+
|
|
101
|
+
motor_kp: tuple[float, ...] | None = None
|
|
102
|
+
"""Proportional gains for PD control (length: num_motors).
|
|
103
|
+
|
|
104
|
+
These gains are applied in the motor-space PD controller:
|
|
105
|
+
tau = kp * (q_target - q_current) + kd * (dq_target - dq_current)
|
|
106
|
+
|
|
107
|
+
If None, values will be loaded from ONNX model metadata during inference.
|
|
108
|
+
If provided, these values override the ONNX metadata.
|
|
109
|
+
"""
|
|
110
|
+
|
|
111
|
+
motor_kd: tuple[float, ...] | None = None
|
|
112
|
+
"""Derivative gains for PD control (length: num_motors).
|
|
113
|
+
|
|
114
|
+
These gains are applied in the motor-space PD controller.
|
|
115
|
+
|
|
116
|
+
If None, values will be loaded from ONNX model metadata during inference.
|
|
117
|
+
If provided, these values override the ONNX metadata.
|
|
118
|
+
"""
|
|
119
|
+
|
|
120
|
+
default_per_joint_action_scale: tuple[float, ...] | None = None
|
|
121
|
+
"""Fallback per-joint action scales used when ONNX metadata is missing."""
|
|
122
|
+
|
|
123
|
+
# =========================================================================
|
|
124
|
+
# WBT Stiff Startup Configuration (OPTIONAL - for WBT policies)
|
|
125
|
+
# =========================================================================
|
|
126
|
+
|
|
127
|
+
stiff_startup_pos: tuple[float, ...] | None = None
|
|
128
|
+
"""Stiff startup joint positions for WBT policy (length: num_joints).
|
|
129
|
+
|
|
130
|
+
Target positions used during stiff hold mode before policy activation.
|
|
131
|
+
Only used by WholeBodyTracking policy.
|
|
132
|
+
"""
|
|
133
|
+
|
|
134
|
+
stiff_startup_kp: tuple[float, ...] | None = None
|
|
135
|
+
"""Stiff startup position gains for WBT policy (length: num_joints).
|
|
136
|
+
|
|
137
|
+
Proportional gains used during stiff hold mode before policy activation.
|
|
138
|
+
Only used by WholeBodyTracking policy.
|
|
139
|
+
"""
|
|
140
|
+
|
|
141
|
+
stiff_startup_kd: tuple[float, ...] | None = None
|
|
142
|
+
"""Stiff startup velocity gains for WBT policy (length: num_joints).
|
|
143
|
+
|
|
144
|
+
Derivative gains used during stiff hold mode before policy activation.
|
|
145
|
+
Only used by WholeBodyTracking policy.
|
|
146
|
+
"""
|
|
147
|
+
|
|
148
|
+
# =========================================================================
|
|
149
|
+
# SDK Configuration (OPTIONAL - with defaults)
|
|
150
|
+
# =========================================================================
|
|
151
|
+
|
|
152
|
+
sdk_type: str = "unitree"
|
|
153
|
+
"""SDK type for robot communication.
|
|
154
|
+
|
|
155
|
+
Built-in types: 'unitree', 'booster'.
|
|
156
|
+
Extensions can register additional SDK types.
|
|
157
|
+
"""
|
|
158
|
+
|
|
159
|
+
motor_type: typing.Literal["serial", "parallel"] = "serial"
|
|
160
|
+
"""Motor communication type."""
|
|
161
|
+
|
|
162
|
+
message_type: typing.Literal["HG", "GO2"] = "HG"
|
|
163
|
+
"""Message protocol type."""
|
|
164
|
+
|
|
165
|
+
# =========================================================================
|
|
166
|
+
# Dimensions (OPTIONAL - with defaults)
|
|
167
|
+
# =========================================================================
|
|
168
|
+
|
|
169
|
+
num_motors: int = 29
|
|
170
|
+
"""Number of motors in the robot."""
|
|
171
|
+
|
|
172
|
+
num_joints: int = 29
|
|
173
|
+
"""Number of joints in the robot."""
|
|
174
|
+
|
|
175
|
+
# =========================================================================
|
|
176
|
+
# Link Names (OPTIONAL - with defaults)
|
|
177
|
+
# =========================================================================
|
|
178
|
+
|
|
179
|
+
torso_link_name: str = "torso_link"
|
|
180
|
+
"""Name of the torso/base link in the robot model."""
|
|
181
|
+
|
|
182
|
+
left_hand_link_name: str | None = None
|
|
183
|
+
"""Name of the left hand/end-effector link (if applicable)."""
|
|
184
|
+
|
|
185
|
+
right_hand_link_name: str | None = None
|
|
186
|
+
"""Name of the right hand/end-effector link (if applicable)."""
|
|
187
|
+
|
|
188
|
+
# =========================================================================
|
|
189
|
+
# SDK-Specific Configuration (optional)
|
|
190
|
+
# =========================================================================
|
|
191
|
+
|
|
192
|
+
unitree_legged_const: dict[str, Any] | None = None
|
|
193
|
+
"""Unitree SDK-specific constants.
|
|
194
|
+
|
|
195
|
+
Contains protocol-specific values like HIGHLEVEL, LOWLEVEL, etc.
|
|
196
|
+
Only used when sdk_type='unitree'.
|
|
197
|
+
"""
|
|
198
|
+
|
|
199
|
+
weak_motor_joint_index: dict[str, int] | None = None
|
|
200
|
+
"""Mapping of joint names to their weak motor indices.
|
|
201
|
+
|
|
202
|
+
Used for robots with weak motors that need special handling.
|
|
203
|
+
"""
|
|
204
|
+
|
|
205
|
+
motion: dict[str, list[str]] | None = None
|
|
206
|
+
"""Motion reference configuration.
|
|
207
|
+
|
|
208
|
+
Specifies body names used for motion tracking/reference.
|
|
209
|
+
Example: {'body_name_ref': ['torso_link']}
|
|
210
|
+
"""
|
|
211
|
+
|
|
212
|
+
# =========================================================================
|
|
213
|
+
# Deprecation candidates
|
|
214
|
+
# (I'm moving for parity with hydra, but I'd like to remove in the future)
|
|
215
|
+
# =========================================================================
|
|
216
|
+
|
|
217
|
+
dof_names_parallel_mech: tuple[str, ...] = ()
|
|
218
|
+
"""Parallel mechanism joint names (optional, booster specific)."""
|
|
219
|
+
|
|
220
|
+
use_sensor: bool = False
|
|
221
|
+
"""Whether to use sensor feedback instead of joint states."""
|
|
222
|
+
|
|
223
|
+
num_upper_body_joints: int = 14
|
|
224
|
+
"""Number of upper body degrees of freedom."""
|
|
225
|
+
|
|
226
|
+
# =========================================================================
|
|
227
|
+
# Per-Robot Calibration
|
|
228
|
+
# =========================================================================
|
|
229
|
+
|
|
230
|
+
joint_offsets_deg: tuple[float, ...] | None = None
|
|
231
|
+
"""Per-joint offsets in degrees applied to lowcmd (action-space only).
|
|
232
|
+
|
|
233
|
+
These offsets correct for per-robot motor calibration differences without
|
|
234
|
+
affecting the observation/state space. Converted to radians at init time.
|
|
235
|
+
Length must equal num_joints when provided.
|
|
236
|
+
"""
|